·
Some checks failed
Hello World (Multiplatform) / build (macos-12) (push) Has been cancelled
Hello World (Multiplatform) / build (macos-14) (push) Has been cancelled
Hello World (Multiplatform) / build (ubuntu-22.04) (push) Has been cancelled
Hello World (Multiplatform) / build (windows-2022) (push) Has been cancelled
Run tests with twister / twister-build-prep (push) Has been cancelled
Run tests with twister / twister-build (push) Has been cancelled
Run tests with twister / Publish Unit Tests Results (push) Has been cancelled
Run tests with twister / Check Twister Status (push) Has been cancelled
Some checks failed
Hello World (Multiplatform) / build (macos-12) (push) Has been cancelled
Hello World (Multiplatform) / build (macos-14) (push) Has been cancelled
Hello World (Multiplatform) / build (ubuntu-22.04) (push) Has been cancelled
Hello World (Multiplatform) / build (windows-2022) (push) Has been cancelled
Run tests with twister / twister-build-prep (push) Has been cancelled
Run tests with twister / twister-build (push) Has been cancelled
Run tests with twister / Publish Unit Tests Results (push) Has been cancelled
Run tests with twister / Check Twister Status (push) Has been cancelled
This commit is contained in:
parent
4e5bb4f004
commit
9cff66449a
|
@ -5,4 +5,4 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
|||
project(blinky)
|
||||
|
||||
#add_compile_definitions(DEBUG)
|
||||
target_sources(app PRIVATE src/main.c src/bench.c)
|
||||
target_sources(app PRIVATE src/main.c src/beebsc.c benchemarks/huffbench/libhuffbench.c)
|
||||
|
|
342
benchies/embench/benchemarks/aha-mont64/mont64.c
Normal file
342
benchies/embench/benchemarks/aha-mont64/mont64.c
Normal file
|
@ -0,0 +1,342 @@
|
|||
/* BEEBS aha-mont64 benchmark
|
||||
|
||||
This version, copyright (C) 2013-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
Some of this code is referenced by the book the Hacker's Delight (which
|
||||
placed it in the public domain). See http://www.hackersdelight.org/ */
|
||||
|
||||
#include "../../src/support.h"
|
||||
|
||||
/* This scale factor will be changed to equalise the runtime of the
|
||||
benchmarks. */
|
||||
#define LOCAL_SCALE_FACTOR 423
|
||||
|
||||
/* Computes a*b mod m using Montgomery multiplication (MM). a, b, and m
|
||||
are unsigned numbers with a, b < m < 2**64, and m odd. The code does
|
||||
some 128-bit arithmetic.
|
||||
The variable r is fixed at 2**64, and its log base 2 at 64.
|
||||
Works with gcc on Windows and Linux. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint64_t uint64;
|
||||
typedef int64_t int64;
|
||||
|
||||
/* ---------------------------- mulul64 ----------------------------- */
|
||||
|
||||
/* Multiply unsigned long 64-bit routine, i.e., 64 * 64 ==> 128.
|
||||
Parameters u and v are multiplied and the 128-bit product is placed in
|
||||
(*whi, *wlo). If __int128 is not defined by the compiler, we fall back
|
||||
to Knuth's Algorithm M from [Knu2] section 4.3.1. Derived from muldwu.c
|
||||
in the Hacker's Delight collection. */
|
||||
|
||||
#ifdef __SIZEOF_INT128__
|
||||
void
|
||||
mulul64 (uint64 u, uint64 v, uint64 * whi, uint64 * wlo)
|
||||
{
|
||||
unsigned __int128 result;
|
||||
|
||||
result = (unsigned __int128)u * v;
|
||||
|
||||
*wlo = result;
|
||||
*whi = result >> 64;
|
||||
}
|
||||
#else
|
||||
void
|
||||
mulul64 (uint64 u, uint64 v, uint64 * whi, uint64 * wlo)
|
||||
{
|
||||
uint64 u0, u1, v0, v1, k, t;
|
||||
uint64 w0, w1, w2;
|
||||
|
||||
u1 = u >> 32;
|
||||
u0 = u & 0xFFFFFFFF;
|
||||
v1 = v >> 32;
|
||||
v0 = v & 0xFFFFFFFF;
|
||||
|
||||
t = u0 * v0;
|
||||
w0 = t & 0xFFFFFFFF;
|
||||
k = t >> 32;
|
||||
|
||||
t = u1 * v0 + k;
|
||||
w1 = t & 0xFFFFFFFF;
|
||||
w2 = t >> 32;
|
||||
|
||||
t = u0 * v1 + w1;
|
||||
k = t >> 32;
|
||||
|
||||
*wlo = (t << 32) + w0;
|
||||
*whi = u1 * v1 + w2 + k;
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ---------------------------- modul64 ----------------------------- */
|
||||
|
||||
uint64
|
||||
modul64 (uint64 x, uint64 y, uint64 z)
|
||||
{
|
||||
|
||||
/* Divides (x || y) by z, for 64-bit integers x, y,
|
||||
and z, giving the remainder (modulus) as the result.
|
||||
Must have x < z (to get a 64-bit result). This is
|
||||
checked for. */
|
||||
|
||||
int64 i, t;
|
||||
|
||||
for (i = 1; i <= 64; i++)
|
||||
{ // Do 64 times.
|
||||
t = (int64) x >> 63; // All 1's if x(63) = 1.
|
||||
x = (x << 1) | (y >> 63); // Shift x || y left
|
||||
y = y << 1; // one bit.
|
||||
if ((x | t) >= z)
|
||||
{
|
||||
x = x - z;
|
||||
y = y + 1;
|
||||
}
|
||||
}
|
||||
return x; // Quotient is y.
|
||||
}
|
||||
|
||||
/* ---------------------------- montmul ----------------------------- */
|
||||
|
||||
uint64
|
||||
montmul (uint64 abar, uint64 bbar, uint64 m, uint64 mprime)
|
||||
{
|
||||
|
||||
uint64 thi, tlo, tm, tmmhi, tmmlo, uhi, ulo, ov;
|
||||
|
||||
/* t = abar*bbar. */
|
||||
|
||||
mulul64 (abar, bbar, &thi, &tlo); // t = abar*bbar.
|
||||
|
||||
/* Now compute u = (t + ((t*mprime) & mask)*m) >> 64.
|
||||
The mask is fixed at 2**64-1. Because it is a 64-bit
|
||||
quantity, it suffices to compute the low-order 64
|
||||
bits of t*mprime, which means we can ignore thi. */
|
||||
|
||||
tm = tlo * mprime;
|
||||
|
||||
mulul64 (tm, m, &tmmhi, &tmmlo); // tmm = tm*m.
|
||||
|
||||
ulo = tlo + tmmlo; // Add t to tmm
|
||||
uhi = thi + tmmhi; // (128-bit add).
|
||||
if (ulo < tlo)
|
||||
uhi = uhi + 1; // Allow for a carry.
|
||||
|
||||
// The above addition can overflow. Detect that here.
|
||||
|
||||
ov = (uhi < thi) | ((uhi == thi) & (ulo < tlo));
|
||||
|
||||
ulo = uhi; // Shift u right
|
||||
uhi = 0; // 64 bit positions.
|
||||
|
||||
// if (ov > 0 || ulo >= m) // If u >= m,
|
||||
// ulo = ulo - m; // subtract m from u.
|
||||
ulo = ulo - (m & -(ov | (ulo >= m))); // Alternative
|
||||
// with no branching.
|
||||
|
||||
return ulo;
|
||||
}
|
||||
|
||||
/* ---------------------------- xbinGCD ----------------------------- */
|
||||
|
||||
/* C program implementing the extended binary GCD algorithm. C.f.
|
||||
http://www.ucl.ac.uk/~ucahcjm/combopt/ext_gcd_python_programs.pdf. This
|
||||
is a modification of that routine in that we find s and t s.t.
|
||||
gcd(a, b) = s*a - t*b,
|
||||
rather than the same expression except with a + sign.
|
||||
This routine has been greatly simplified to take advantage of the
|
||||
facts that in the MM use, argument a is a power of 2, and b is odd. Thus
|
||||
there are no common powers of 2 to eliminate in the beginning. The
|
||||
parent routine has two loops. The first drives down argument a until it
|
||||
is 1, modifying u and v in the process. The second loop modifies s and
|
||||
t, but because a = 1 on entry to the second loop, it can be easily seen
|
||||
that the second loop doesn't alter u or v. Hence the result we want is u
|
||||
and v from the end of the first loop, and we can delete the second loop.
|
||||
The intermediate and final results are always > 0, so there is no
|
||||
trouble with negative quantities. Must have a either 0 or a power of 2
|
||||
<= 2**63. A value of 0 for a is treated as 2**64. b can be any 64-bit
|
||||
value.
|
||||
Parameter a is half what it "should" be. In other words, this function
|
||||
does not find u and v st. u*a - v*b = 1, but rather u*(2a) - v*b = 1. */
|
||||
|
||||
void
|
||||
xbinGCD (uint64 a, uint64 b, volatile uint64 * pu, volatile uint64 * pv)
|
||||
{
|
||||
uint64 alpha, beta, u, v;
|
||||
|
||||
u = 1;
|
||||
v = 0;
|
||||
alpha = a;
|
||||
beta = b; // Note that alpha is
|
||||
// even and beta is odd.
|
||||
|
||||
/* The invariant maintained from here on is:
|
||||
a = u*2*alpha - v*beta. */
|
||||
|
||||
// printf("Before, a u v = %016llx %016llx %016llx\n", a, u, v);
|
||||
while (a > 0)
|
||||
{
|
||||
a = a >> 1;
|
||||
if ((u & 1) == 0)
|
||||
{ // Delete a common
|
||||
u = u >> 1;
|
||||
v = v >> 1; // factor of 2 in
|
||||
} // u and v.
|
||||
else
|
||||
{
|
||||
/* We want to set u = (u + beta) >> 1, but
|
||||
that can overflow, so we use Dietz's method. */
|
||||
u = ((u ^ beta) >> 1) + (u & beta);
|
||||
v = (v >> 1) + alpha;
|
||||
}
|
||||
// printf("After, a u v = %016llx %016llx %016llx\n", a, u, v);
|
||||
}
|
||||
|
||||
// printf("At end, a u v = %016llx %016llx %016llx\n", a, u, v);
|
||||
*pu = u;
|
||||
*pv = v;
|
||||
return;
|
||||
}
|
||||
|
||||
/* ------------------------------ main ------------------------------ */
|
||||
static uint64 in_a, in_b, in_m;
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
int i;
|
||||
int errors;
|
||||
|
||||
for (i = 0; i < rpt; i++)
|
||||
{
|
||||
uint64 a, b, m, hr, p1hi, p1lo, p1, p, abar, bbar;
|
||||
uint64 phi, plo;
|
||||
volatile uint64 rinv, mprime;
|
||||
errors = 0;
|
||||
|
||||
m = in_m; // Must be odd.
|
||||
b = in_b; // Must be smaller than m.
|
||||
a = in_a; // Must be smaller than m.
|
||||
|
||||
/* The simple calculation: This computes (a*b)**4 (mod m) correctly for all a,
|
||||
b, m < 2**64. */
|
||||
|
||||
mulul64 (a, b, &p1hi, &p1lo); // Compute a*b (mod m).
|
||||
p1 = modul64 (p1hi, p1lo, m);
|
||||
mulul64 (p1, p1, &p1hi, &p1lo); // Compute (a*b)**2 (mod m).
|
||||
p1 = modul64 (p1hi, p1lo, m);
|
||||
mulul64 (p1, p1, &p1hi, &p1lo); // Compute (a*b)**4 (mod m).
|
||||
p1 = modul64 (p1hi, p1lo, m);
|
||||
|
||||
/* The MM method uses a quantity r that is the smallest power of 2
|
||||
that is larger than m, and hence also larger than a and b. Here we
|
||||
deal with a variable hr that is just half of r. This is because r can
|
||||
be as large as 2**64, which doesn't fit in one 64-bit word. So we
|
||||
deal with hr, where 2**63 <= hr <= 1, and make the appropriate
|
||||
adjustments wherever it is used.
|
||||
We fix r at 2**64, and its log base 2 at 64. It doesn't hurt if
|
||||
they are too big, it's just that some quantities (e.g., mprime) come
|
||||
out larger than they would otherwise be. */
|
||||
|
||||
hr = 0x8000000000000000LL;
|
||||
|
||||
/* Now, for the MM method, first compute the quantities that are
|
||||
functions of only r and m, and hence are relatively constant. These
|
||||
quantities can be used repeatedly, without change, when raising a
|
||||
number to a large power modulo m.
|
||||
First use the extended GCD algorithm to compute two numbers rinv
|
||||
and mprime, such that
|
||||
|
||||
r*rinv - m*mprime = 1
|
||||
|
||||
Reading this nodulo m, clearly r*rinv = 1 (mod m), i.e., rinv is the
|
||||
multiplicative inverse of r modulo m. It is needed to convert the
|
||||
result of MM back to a normal number. The other calculated number,
|
||||
mprime, is used in the MM algorithm. */
|
||||
|
||||
xbinGCD (hr, m, &rinv, &mprime); // xbinGCD, in effect, doubles hr.
|
||||
|
||||
/* Do a partial check of the results. It is partial because the
|
||||
multiplications here give only the low-order half (64 bits) of the
|
||||
products. */
|
||||
|
||||
if (2 * hr * rinv - m * mprime != 1)
|
||||
{
|
||||
errors = 1;
|
||||
}
|
||||
|
||||
/* Compute abar = a*r(mod m) and bbar = b*r(mod m). That is, abar =
|
||||
(a << 64)%m, and bbar = (b << 64)%m. */
|
||||
|
||||
abar = modul64 (a, 0, m);
|
||||
bbar = modul64 (b, 0, m);
|
||||
|
||||
p = montmul (abar, bbar, m, mprime); /* Compute a*b (mod m). */
|
||||
p = montmul (p, p, m, mprime); /* Compute (a*b)**2 (mod m). */
|
||||
p = montmul (p, p, m, mprime); /* Compute (a*b)**4 (mod m). */
|
||||
|
||||
/* Convert p back to a normal number by p = (p*rinv)%m. */
|
||||
|
||||
mulul64 (p, rinv, &phi, &plo);
|
||||
p = modul64 (phi, plo, m);
|
||||
if (p != p1)
|
||||
errors = 1;
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
in_m = 0xfae849273928f89fLL; // Must be odd.
|
||||
in_b = 0x14736defb9330573LL; // Must be smaller than m.
|
||||
in_a = 0x0549372187237fefLL; // Must be smaller than m.
|
||||
}
|
||||
|
||||
// r is the number of errors therefore if r = 0 then output a 1 for correct
|
||||
|
||||
int
|
||||
verify_benchmark (int r)
|
||||
{
|
||||
return 0 == r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
221
benchies/embench/benchemarks/crc32/crc_32.c
Normal file
221
benchies/embench/benchemarks/crc32/crc_32.c
Normal file
|
@ -0,0 +1,221 @@
|
|||
/* This file is part of the Bristol/Embecosm Embedded Benchmark Suite.
|
||||
|
||||
This version, copyright (C) 2013-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
Code originally from: From http://www.snippets.org/. This original code is
|
||||
FREE with no restrictions. */
|
||||
|
||||
/* CRC - 32 BIT ANSI X3.66 CRC checksum files */
|
||||
|
||||
#include "../../src/support.h"
|
||||
|
||||
/* This scale factor will be changed to equalise the runtime of the
|
||||
benchmarks. */
|
||||
#define LOCAL_SCALE_FACTOR 170
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __TURBOC__
|
||||
#pragma warn -cln
|
||||
#endif
|
||||
|
||||
/**********************************************************************\
|
||||
|* Demonstration program to compute the 32-bit CRC used as the frame *|
|
||||
|* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *|
|
||||
|* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *|
|
||||
|* protocol). The 32-bit FCS was added via the Federal Register, *|
|
||||
|* 1 June 1982, p.23798. I presume but don't know for certain that *|
|
||||
|* this polynomial is or will be included in CCITT V.41, which *|
|
||||
|* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *|
|
||||
|* PUB 78 says that the 32-bit FCS reduces otherwise undetected *|
|
||||
|* errors by a factor of 10^-5 over 16-bit FCS. *|
|
||||
\**********************************************************************/
|
||||
|
||||
/* Some basic types. */
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned long DWORD;
|
||||
typedef unsigned short WORD;
|
||||
|
||||
#define UPDC32(octet,crc) (crc_32_tab[((crc)^((BYTE)octet)) & 0xff] ^ ((crc) >> 8))
|
||||
|
||||
/* Need an unsigned type capable of holding 32 bits; */
|
||||
|
||||
typedef DWORD UNS_32_BITS;
|
||||
|
||||
/* Copyright (C) 1986 Gary S. Brown. You may use this program, or
|
||||
code or tables extracted from it, as desired without restriction.*/
|
||||
|
||||
/* First, the polynomial itself and its table of feedback terms. The */
|
||||
/* polynomial is */
|
||||
/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
|
||||
/* Note that we take it "backwards" and put the highest-order term in */
|
||||
/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
|
||||
/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
|
||||
/* the MSB being 1. */
|
||||
|
||||
/* Note that the usual hardware shift register implementation, which */
|
||||
/* is what we're using (we're merely optimizing it by doing eight-bit */
|
||||
/* chunks at a time) shifts bits into the lowest-order term. In our */
|
||||
/* implementation, that means shifting towards the right. Why do we */
|
||||
/* do it this way? Because the calculated CRC must be transmitted in */
|
||||
/* order from highest-order term to lowest-order term. UARTs transmit */
|
||||
/* characters in order from LSB to MSB. By storing the CRC this way, */
|
||||
/* we hand it to the UART in the order low-byte to high-byte; the UART */
|
||||
/* sends each low-bit to hight-bit; and the result is transmission bit */
|
||||
/* by bit from highest- to lowest-order term without requiring any bit */
|
||||
/* shuffling on our part. Reception works similarly. */
|
||||
|
||||
/* The feedback terms table consists of 256, 32-bit entries. Notes: */
|
||||
/* */
|
||||
/* 1. The table can be generated at runtime if desired; code to do so */
|
||||
/* is shown later. It might not be obvious, but the feedback */
|
||||
/* terms simply represent the results of eight shift/xor opera- */
|
||||
/* tions for all combinations of data and CRC register values. */
|
||||
/* */
|
||||
/* 2. The CRC accumulation logic is the same for all CRC polynomials, */
|
||||
/* be they sixteen or thirty-two bits wide. You simply choose the */
|
||||
/* appropriate table. Alternatively, because the table can be */
|
||||
/* generated at runtime, you can start by generating the table for */
|
||||
/* the polynomial in question and use exactly the same "updcrc", */
|
||||
/* if your application needn't simultaneously handle two CRC */
|
||||
/* polynomials. (Note, however, that XMODEM is strange.) */
|
||||
/* */
|
||||
/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */
|
||||
/* of course, 32-bit entries work OK if the high 16 bits are zero. */
|
||||
/* */
|
||||
/* 4. The values must be right-shifted by eight bits by the "updcrc" */
|
||||
/* logic; the shift must be unsigned (bring in zeroes). On some */
|
||||
/* hardware you could probably optimize the shift in assembler by */
|
||||
/* using byte-swap instructions. */
|
||||
|
||||
/* The BEEBS version of this code uses its own version of rand, to
|
||||
avoid library/architecture variation. */
|
||||
|
||||
static const UNS_32_BITS crc_32_tab[] = { /* CRC polynomial 0xedb88320 */
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
|
||||
DWORD
|
||||
crc32pseudo ()
|
||||
{
|
||||
int i;
|
||||
register DWORD oldcrc32;
|
||||
|
||||
oldcrc32 = 0xFFFFFFFF;
|
||||
|
||||
for (i = 0; i < 1024; ++i)
|
||||
{
|
||||
oldcrc32 = UPDC32 (rand_beebs (), oldcrc32);
|
||||
}
|
||||
|
||||
return ~oldcrc32;
|
||||
}
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
int i;
|
||||
DWORD r;
|
||||
|
||||
for (i = 0; i < rpt; i++)
|
||||
{
|
||||
srand_beebs (0);
|
||||
r = crc32pseudo ();
|
||||
}
|
||||
|
||||
return (int) (r % 32768);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
verify_benchmark (int r)
|
||||
{
|
||||
return 11433 == r;
|
||||
}
|
||||
|
||||
|
||||
/* vim: set ts=3 sw=3 et: */
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
108
benchies/embench/benchemarks/cubic/basicmath_small.c
Normal file
108
benchies/embench/benchemarks/cubic/basicmath_small.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
/* BEEBS cubic benchmark
|
||||
|
||||
Contributor: James Pallister <james.pallister@bristol.ac.uk>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#include <string.h>
|
||||
#include "../../src/support.h"
|
||||
#include "snipmath.h"
|
||||
|
||||
/* This scale factor will be changed to equalise the runtime of the
|
||||
benchmarks. */
|
||||
#define LOCAL_SCALE_FACTOR 10
|
||||
|
||||
|
||||
|
||||
|
||||
static int soln_cnt0;
|
||||
static int soln_cnt1;
|
||||
static double res0[3];
|
||||
static double res1;
|
||||
|
||||
|
||||
int
|
||||
verify_benchmark (int res __attribute ((unused)) )
|
||||
{
|
||||
static const double exp_res0[3] = {2.0, 6.0, 2.5};
|
||||
const double exp_res1 = 2.5;
|
||||
return (3 == soln_cnt0)
|
||||
&& double_eq_beebs(exp_res0[0], res0[0])
|
||||
&& double_eq_beebs(exp_res0[1], res0[1])
|
||||
&& double_eq_beebs(exp_res0[2], res0[2])
|
||||
&& (1 == soln_cnt1)
|
||||
&& double_eq_beebs(exp_res1, res1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rpt; i++)
|
||||
{
|
||||
double a1 = 1.0, b1 = -10.5, c1 = 32.0, d1 = -30.0;
|
||||
double a2 = 1.0, b2 = -4.5, c2 = 17.0, d2 = -30.0;
|
||||
double a3 = 1.0, b3 = -3.5, c3 = 22.0, d3 = -31.0;
|
||||
double a4 = 1.0, b4 = -13.7, c4 = 1.0, d4 = -35.0;
|
||||
int solutions;
|
||||
|
||||
double output[48] = {0};
|
||||
double *output_pos = &(output[0]);
|
||||
|
||||
/* solve some cubic functions */
|
||||
/* should get 3 solutions: 2, 6 & 2.5 */
|
||||
SolveCubic(a1, b1, c1, d1, &solutions, output);
|
||||
soln_cnt0 = solutions;
|
||||
memcpy(res0,output,3*sizeof(res0[0]));
|
||||
/* should get 1 solution: 2.5 */
|
||||
SolveCubic(a2, b2, c2, d2, &solutions, output);
|
||||
soln_cnt1 = solutions;
|
||||
res1 = output[0];
|
||||
SolveCubic(a3, b3, c3, d3, &solutions, output);
|
||||
SolveCubic(a4, b4, c4, d4, &solutions, output);
|
||||
/* Now solve some random equations */
|
||||
for(a1=1;a1<3;a1++) {
|
||||
for(b1=10;b1>8;b1--) {
|
||||
for(c1=5;c1<6;c1+=0.5) {
|
||||
for(d1=-1;d1>-3;d1--) {
|
||||
SolveCubic(a1, b1, c1, d1, &solutions, output_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* vim: set ts=3 sw=3 et: */
|
66
benchies/embench/benchemarks/cubic/libcubic.c
Normal file
66
benchies/embench/benchemarks/cubic/libcubic.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* BEEBS cubic benchmark
|
||||
|
||||
This version, copyright (C) 2013-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor: James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
The original code is from http://www.snippets.org/. */
|
||||
|
||||
/* +++Date last modified: 05-Jul-1997 */
|
||||
|
||||
/*
|
||||
** CUBIC.C - Solve a cubic polynomial
|
||||
** public domain by Ross Cottrell
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "snipmath.h"
|
||||
|
||||
void
|
||||
SolveCubic (double a, double b, double c, double d, int *solutions, double *x)
|
||||
{
|
||||
long double a1 = (long double) (b / a);
|
||||
long double a2 = (long double) (c / a);
|
||||
long double a3 = (long double) (d / a);
|
||||
long double Q = (a1 * a1 - 3.0L * a2) / 9.0L;
|
||||
long double R = (2.0L * a1 * a1 * a1 - 9.0L * a1 * a2 + 27.0L * a3) / 54.0L;
|
||||
double R2_Q3 = (double) (R * R - Q * Q * Q);
|
||||
|
||||
double theta;
|
||||
|
||||
if (R2_Q3 <= 0)
|
||||
{
|
||||
*solutions = 3;
|
||||
theta = acos (((double) R) / sqrt ((double) (Q * Q * Q)));
|
||||
x[0] = -2.0 * sqrt ((double) Q) * cos (theta / 3.0) - a1 / 3.0;
|
||||
x[1] =
|
||||
-2.0 * sqrt ((double) Q) * cos ((theta + 2.0 * PI) / 3.0) - a1 / 3.0;
|
||||
x[2] =
|
||||
-2.0 * sqrt ((double) Q) * cos ((theta + 4.0 * PI) / 3.0) - a1 / 3.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*solutions = 1;
|
||||
x[0] = pow (sqrt (R2_Q3) + fabs ((double) R), 1 / 3.0);
|
||||
x[0] += ((double) Q) / x[0];
|
||||
x[0] *= (R < 0.0L) ? 1 : -1;
|
||||
x[0] -= (double) (a1 / 3.0L);
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set ts=3 sw=3 et: */
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
37
benchies/embench/benchemarks/cubic/pi.h
Normal file
37
benchies/embench/benchemarks/cubic/pi.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* BEEBS cubic benchmark
|
||||
|
||||
This version, copyright (C) 2013-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor: James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
The original code is from http://www.snippets.org/. */
|
||||
|
||||
/* +++Date last modified: 05-Jul-1997 */
|
||||
|
||||
#ifndef PI__H
|
||||
#define PI__H
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#ifndef PI
|
||||
#define PI (4*atan(1))
|
||||
#endif
|
||||
|
||||
#endif /* PI__H */
|
||||
|
||||
/* vim: set ts=3 sw=3 et: */
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
57
benchies/embench/benchemarks/cubic/snipmath.h
Normal file
57
benchies/embench/benchemarks/cubic/snipmath.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* BEEBS cubic benchmark
|
||||
|
||||
This version, copyright (C) 2013-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor: James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
The original code is from http://www.snippets.org/. */
|
||||
|
||||
/* +++Date last modified: 05-Jul-1997 */
|
||||
|
||||
/*
|
||||
** SNIPMATH.H - Header file for SNIPPETS math functions and macros
|
||||
*/
|
||||
|
||||
#ifndef SNIPMATH__H
|
||||
#define SNIPMATH__H
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "pi.h"
|
||||
#include "sniptype.h"
|
||||
|
||||
/*
|
||||
** Callable library functions begin here
|
||||
*/
|
||||
|
||||
void SolveCubic (double a, double b, double c, /* Cubic.C */
|
||||
double d, int *solutions, double *x);
|
||||
|
||||
|
||||
/*
|
||||
** File: ISQRT.C
|
||||
*/
|
||||
|
||||
struct int_sqrt
|
||||
{
|
||||
unsigned sqrt, frac;
|
||||
};
|
||||
|
||||
#endif /* SNIPMATH__H */
|
||||
|
||||
/* vim: set ts=3 sw=3 et: */
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
39
benchies/embench/benchemarks/cubic/sniptype.h
Normal file
39
benchies/embench/benchemarks/cubic/sniptype.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/* BEEBS cubic benchmark
|
||||
|
||||
This version, copyright (C) 2013-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor: James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
The original code is from http://www.snippets.org/. */
|
||||
|
||||
/* +++Date last modified: 05-Jul-1997 */
|
||||
|
||||
/*
|
||||
** SNIPTYPE.H - Include file for SNIPPETS data types and commonly used macros
|
||||
*/
|
||||
|
||||
#ifndef SNIPTYPE__H
|
||||
#define SNIPTYPE__H
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned long DWORD;
|
||||
typedef unsigned short WORD;
|
||||
|
||||
#endif /* SNIPTYPE__H */
|
||||
|
||||
/* vim: set ts=3 sw=3 et: */
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
421
benchies/embench/benchemarks/edn/libedn.c
Normal file
421
benchies/embench/benchemarks/edn/libedn.c
Normal file
|
@ -0,0 +1,421 @@
|
|||
/* BEEBS edn benchmark
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
Original code from: WCET Benchmarks,
|
||||
http://www.mrtc.mdh.se/projects/wcet/benchmarks.html
|
||||
|
||||
Permission to license under GPL obtained by email from Björn Lisper */
|
||||
|
||||
/*
|
||||
* MDH WCET BENCHMARK SUITE.
|
||||
*/
|
||||
|
||||
/************************************************************************
|
||||
* Simple vector multiply *
|
||||
************************************************************************/
|
||||
|
||||
/*
|
||||
* Changes: JG 2005/12/22: Inserted prototypes, changed type of main to int
|
||||
* etc. Added parenthesis in expressions in jpegdct. Removed unused variable
|
||||
* dx. Changed int to long to avoid problems when compiling to 16 bit target
|
||||
* Indented program.
|
||||
* JG 2006-01-27: Removed code in codebook
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "../../src/support.h"
|
||||
|
||||
/* This scale factor will be changed to equalise the runtime of the
|
||||
benchmarks. */
|
||||
#define LOCAL_SCALE_FACTOR 87
|
||||
|
||||
|
||||
#define N 100
|
||||
#define ORDER 50
|
||||
|
||||
void vec_mpy1 (short y[], const short x[], short scaler);
|
||||
long int mac (const short *a, const short *b, long int sqr, long int *sum);
|
||||
void fir (const short array1[], const short coeff[], long int output[]);
|
||||
void fir_no_red_ld (const short x[], const short h[], long int y[]);
|
||||
long int latsynth (short b[], const short k[], long int n, long int f);
|
||||
void iir1 (const short *coefs, const short *input, long int *optr,
|
||||
long int *state);
|
||||
long int codebook (long int mask, long int bitchanged, long int numbasis,
|
||||
long int codeword, long int g, const short *d, short ddim,
|
||||
short theta);
|
||||
void jpegdct (short *d, short *r);
|
||||
|
||||
void
|
||||
vec_mpy1 (short y[], const short x[], short scaler)
|
||||
{
|
||||
long int i;
|
||||
|
||||
for (i = 0; i < 150; i++)
|
||||
y[i] += ((scaler * x[i]) >> 15);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* Dot Product *
|
||||
*****************************************************/
|
||||
long int
|
||||
mac (const short *a, const short *b, long int sqr, long int *sum)
|
||||
{
|
||||
long int i;
|
||||
long int dotp = *sum;
|
||||
|
||||
for (i = 0; i < 150; i++)
|
||||
{
|
||||
dotp += b[i] * a[i];
|
||||
sqr += b[i] * b[i];
|
||||
}
|
||||
|
||||
*sum = dotp;
|
||||
return sqr;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* FIR Filter *
|
||||
*****************************************************/
|
||||
void
|
||||
fir (const short array1[], const short coeff[], long int output[])
|
||||
{
|
||||
long int i, j, sum;
|
||||
|
||||
for (i = 0; i < N - ORDER; i++)
|
||||
{
|
||||
sum = 0;
|
||||
for (j = 0; j < ORDER; j++)
|
||||
{
|
||||
sum += array1[i + j] * coeff[j];
|
||||
}
|
||||
output[i] = sum >> 15;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
* FIR Filter with Redundant Load Elimination
|
||||
|
||||
By doing two outer loops simultaneously, you can potentially reuse data (depending on the DSP architecture).
|
||||
x and h only need to be loaded once, therefore reducing redundant loads.
|
||||
This reduces memory bandwidth and power.
|
||||
*****************************************************/
|
||||
void
|
||||
fir_no_red_ld (const short x[], const short h[], long int y[])
|
||||
{
|
||||
long int i, j;
|
||||
long int sum0, sum1;
|
||||
short x0, x1, h0, h1;
|
||||
for (j = 0; j < 100; j += 2)
|
||||
{
|
||||
sum0 = 0;
|
||||
sum1 = 0;
|
||||
x0 = x[j];
|
||||
for (i = 0; i < 32; i += 2)
|
||||
{
|
||||
x1 = x[j + i + 1];
|
||||
h0 = h[i];
|
||||
sum0 += x0 * h0;
|
||||
sum1 += x1 * h0;
|
||||
x0 = x[j + i + 2];
|
||||
h1 = h[i + 1];
|
||||
sum0 += x1 * h1;
|
||||
sum1 += x0 * h1;
|
||||
}
|
||||
y[j] = sum0 >> 15;
|
||||
y[j + 1] = sum1 >> 15;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
* Lattice Synthesis *
|
||||
* This function doesn't follow the typical DSP multiply two vector operation, but it will point out the compiler's flexibility ********************************************************/
|
||||
long int
|
||||
latsynth (short b[], const short k[], long int n, long int f)
|
||||
{
|
||||
long int i;
|
||||
|
||||
f -= b[n - 1] * k[n - 1];
|
||||
for (i = n - 2; i >= 0; i--)
|
||||
{
|
||||
f -= b[i] * k[i];
|
||||
b[i + 1] = b[i] + ((k[i] * (f >> 16)) >> 16);
|
||||
}
|
||||
b[0] = f >> 16;
|
||||
return f;
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* IIR Filter *
|
||||
*****************************************************/
|
||||
void
|
||||
iir1 (const short *coefs, const short *input, long int *optr, long int *state)
|
||||
{
|
||||
long int x;
|
||||
long int t;
|
||||
long int n;
|
||||
|
||||
x = input[0];
|
||||
for (n = 0; n < 50; n++)
|
||||
{
|
||||
t = x + ((coefs[2] * state[0] + coefs[3] * state[1]) >> 15);
|
||||
x = t + ((coefs[0] * state[0] + coefs[1] * state[1]) >> 15);
|
||||
state[1] = state[0];
|
||||
state[0] = t;
|
||||
coefs += 4; /* point to next filter coefs */
|
||||
state += 2; /* point to next filter states */
|
||||
}
|
||||
*optr++ = x;
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* Vocoder Codebook Search *
|
||||
*****************************************************/
|
||||
long int
|
||||
codebook (long int mask, long int bitchanged, long int numbasis,
|
||||
long int codeword, long int g, const short *d, short ddim,
|
||||
short theta)
|
||||
/*
|
||||
* dfm (mask=d bitchanged=1 numbasis=17 codeword=e[0] , g=d, d=a, ddim=c,
|
||||
* theta =1
|
||||
*/
|
||||
{
|
||||
long int j;
|
||||
|
||||
|
||||
/*
|
||||
* Remove along with the code below.
|
||||
*
|
||||
long int tmpMask;
|
||||
|
||||
tmpMask = mask << 1;
|
||||
*/
|
||||
for (j = bitchanged + 1; j <= numbasis; j++)
|
||||
{
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* The following code is removed since it gave a memory access exception.
|
||||
* It is OK since the return value does not control the flow.
|
||||
* The loop always iterates a fixed number of times independent of the loop body.
|
||||
|
||||
if (theta == !(!(codeword & tmpMask)))
|
||||
g += *(d + bitchanged * ddim + j);
|
||||
else
|
||||
g -= *(d + bitchanged * ddim + j);
|
||||
tmpMask <<= 1;
|
||||
*/
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* JPEG Discrete Cosine Transform *
|
||||
*****************************************************/
|
||||
void
|
||||
jpegdct (short *d, short *r)
|
||||
{
|
||||
long int t[12];
|
||||
short i, j, k, m, n, p;
|
||||
for (k = 1, m = 0, n = 13, p = 8; k <= 8;
|
||||
k += 7, m += 3, n += 3, p -= 7, d -= 64)
|
||||
{
|
||||
for (i = 0; i < 8; i++, d += p)
|
||||
{
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
t[j] = d[k * j] + d[k * (7 - j)];
|
||||
t[7 - j] = d[k * j] - d[k * (7 - j)];
|
||||
}
|
||||
t[8] = t[0] + t[3];
|
||||
t[9] = t[0] - t[3];
|
||||
t[10] = t[1] + t[2];
|
||||
t[11] = t[1] - t[2];
|
||||
d[0] = (t[8] + t[10]) >> m;
|
||||
d[4 * k] = (t[8] - t[10]) >> m;
|
||||
t[8] = (short) (t[11] + t[9]) * r[10];
|
||||
d[2 * k] = t[8] + (short) ((t[9] * r[9]) >> n);
|
||||
d[6 * k] = t[8] + (short) ((t[11] * r[11]) >> n);
|
||||
t[0] = (short) (t[4] + t[7]) * r[2];
|
||||
t[1] = (short) (t[5] + t[6]) * r[0];
|
||||
t[2] = t[4] + t[6];
|
||||
t[3] = t[5] + t[7];
|
||||
t[8] = (short) (t[2] + t[3]) * r[8];
|
||||
t[2] = (short) t[2] * r[1] + t[8];
|
||||
t[3] = (short) t[3] * r[3] + t[8];
|
||||
d[7 * k] = (short) (t[4] * r[4] + t[0] + t[2]) >> n;
|
||||
d[5 * k] = (short) (t[5] * r[6] + t[1] + t[3]) >> n;
|
||||
d[3 * k] = (short) (t[6] * r[5] + t[1] + t[2]) >> n;
|
||||
d[1 * k] = (short) (t[7] * r[7] + t[0] + t[3]) >> n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static short a[200];
|
||||
static short b[200];
|
||||
static short c;
|
||||
static long int d;
|
||||
static int e;
|
||||
static long int output[200];
|
||||
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < rpt; j++)
|
||||
{
|
||||
short unsigned int in_a[200] = {
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400,
|
||||
0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400
|
||||
};
|
||||
short unsigned int in_b[200] = {
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000,
|
||||
0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000
|
||||
};
|
||||
c = 0x3;
|
||||
d = 0xAAAA;
|
||||
e = 0xEEEE;
|
||||
|
||||
for (int i = 0; i < 200; i++)
|
||||
{
|
||||
a[i] = in_a[i];
|
||||
b[i] = in_b[i];
|
||||
}
|
||||
/*
|
||||
* Declared as memory variable so it doesn't get optimized out
|
||||
*/
|
||||
|
||||
vec_mpy1 (a, b, c);
|
||||
c = mac (a, b, (long int) c, (long int *) output);
|
||||
fir (a, b, output);
|
||||
fir_no_red_ld (a, b, output);
|
||||
d = latsynth (a, b, N, d);
|
||||
iir1 (a, b, &output[100], output);
|
||||
e = codebook (d, 1, 17, e, d, a, c, 1);
|
||||
jpegdct (a, b);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
verify_benchmark (int unused)
|
||||
{
|
||||
long int exp_output[200] =
|
||||
{ 3760, 4269, 3126, 1030, 2453, -4601, 1981, -1056, 2621, 4269,
|
||||
3058, 1030, 2378, -4601, 1902, -1056, 2548, 4269, 2988, 1030,
|
||||
2300, -4601, 1822, -1056, 2474, 4269, 2917, 1030, 2220, -4601,
|
||||
1738, -1056, 2398, 4269, 2844, 1030, 2140, -4601, 1655, -1056,
|
||||
2321, 4269, 2770, 1030, 2058, -4601, 1569, -1056, 2242, 4269,
|
||||
2152, 1030, 1683, -4601, 1627, -1056, 2030, 4269, 2080, 1030,
|
||||
1611, -4601, 1555, -1056, 1958, 4269, 2008, 1030, 1539, -4601,
|
||||
1483, -1056, 1886, 4269, 1935, 1030, 1466, -4601, 1410, -1056,
|
||||
1813, 4269, 1862, 1030, 1393, -4601, 1337, -1056, 1740, 4269,
|
||||
1789, 1030, 1320, -4601, 1264, -1056, 1667, 4269, 1716, 1030,
|
||||
1968, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
return (0 == memcmp (output, exp_output, 200 * sizeof (output[0])))
|
||||
&& (10243 == c) && (-441886230 == d) && (-441886230 == e);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
1
benchies/embench/benchemarks/huffbench/.gitignore
vendored
Normal file
1
benchies/embench/benchemarks/huffbench/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
huffbench
|
501
benchies/embench/benchemarks/huffbench/libhuffbench.c
Normal file
501
benchies/embench/benchemarks/huffbench/libhuffbench.c
Normal file
|
@ -0,0 +1,501 @@
|
|||
/* BEEBS cover benchmark
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
Original version by Scott Robert Ladd
|
||||
|
||||
huffbench
|
||||
Standard C version
|
||||
17 April 2003
|
||||
|
||||
Written by Scott Robert Ladd (scott@coyotegulch.com)
|
||||
No rights reserved. This is public domain software, for use by anyone.
|
||||
|
||||
A data compression benchmark that can also be used as a fitness test
|
||||
for evolving optimal compiler options via genetic algorithm.
|
||||
|
||||
This program implements the Huffman compression algorithm. The code
|
||||
is not the tightest or fastest possible C code; rather, it is a
|
||||
relatively straight-forward implementation of the algorithm,
|
||||
providing opportunities for an optimizer to "do its thing."
|
||||
|
||||
Note that the code herein is design for the purpose of testing
|
||||
computational performance; error handling and other such "niceties"
|
||||
is virtually non-existent.
|
||||
|
||||
Actual benchmark results can be found at:
|
||||
http://www.coyotegulch.com
|
||||
|
||||
Please do not use this information or algorithm in any way that might
|
||||
upset the balance of the universe or otherwise cause the creation of
|
||||
singularities.
|
||||
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "../../src/support.h"
|
||||
|
||||
/* This scale factor will be changed to equalise the runtime of the
|
||||
benchmarks. */
|
||||
#define LOCAL_SCALE_FACTOR 11
|
||||
|
||||
/* BEEBS heap is just an array */
|
||||
|
||||
#define HEAP_SIZE 8192
|
||||
static char heap[HEAP_SIZE] __attribute__((aligned));
|
||||
|
||||
#define TEST_SIZE 500
|
||||
|
||||
typedef unsigned long bits32;
|
||||
typedef unsigned char byte;
|
||||
|
||||
// compressed (encoded) data
|
||||
|
||||
static const byte orig_data[TEST_SIZE] = {
|
||||
'J', '2', 'O', 'Z', 'F', '5', '0', 'F', 'Y', 'L',
|
||||
'D', '5', 'U', 'T', 'V', 'Y', 'Y', 'R', 'M', 'T',
|
||||
'0', 'V', 'X', 'O', '0', '1', 'V', 'C', '5', 'F',
|
||||
'N', 'I', 'B', '1', 'C', 'G', '1', '2', 'M', 'T',
|
||||
'I', 'P', 'T', '2', 'C', 'I', 'V', '0', '0', 'B',
|
||||
'O', 'U', 'W', 'F', 'D', 'R', 'A', 'Y', 'T', 'A',
|
||||
'3', 'A', 'I', '4', '2', 'K', 'F', 'X', 'H', 'R',
|
||||
'K', 'P', 'A', '3', 'L', 'C', 'G', 'A', '3', 'A',
|
||||
'B', 'L', 'U', 'Y', 'Q', 'X', 'J', 'R', 'Q', '2',
|
||||
'R', 'N', '2', 'Z', 'M', 'Y', 'E', 'R', 'P', 'L',
|
||||
'C', '0', '0', 'C', 'X', 'F', 'E', '3', 'G', 'B',
|
||||
'3', 'H', 'M', 'S', '5', '3', 'J', 'I', 'O', 'Z',
|
||||
'E', '5', 'H', 'B', 'Y', 'T', 'Z', '2', 'E', 'J',
|
||||
'H', 'G', 'D', 'B', 'I', '0', 'H', 'M', 'Y', 'N',
|
||||
'O', 'V', 'U', '0', 'H', 'U', 'X', 'R', '2', 'F',
|
||||
'K', 'B', 'E', 'R', 'C', '3', 'E', '1', 'Z', 'I',
|
||||
'E', 'B', 'O', 'H', 'C', 'W', 'C', 'J', 'D', '0',
|
||||
'W', 'R', 'P', 'L', 'L', 'X', '5', 'D', 'I', '1',
|
||||
'I', 'S', '2', 'N', 'E', '4', 'K', 'I', '0', 'D',
|
||||
'R', '4', 'E', '5', 'G', 'H', 'W', 'I', 'Q', 'Z',
|
||||
'C', 'H', 'K', 'R', 'S', 'V', 'I', 'R', 'Y', 'Q',
|
||||
'M', 'B', 'D', 'J', 'O', 'H', 'H', 'Y', 'P', 'B',
|
||||
'1', 'A', 'A', 'A', 'A', 'G', 'H', 'W', 'O', 'X',
|
||||
'P', 'Q', '4', 'Z', 'B', 'Q', 'O', 'K', 'B', 'H',
|
||||
'0', 'O', 'I', '3', 'X', 'W', 'E', '4', 'O', 'U',
|
||||
'A', 'J', 'U', 'A', 'J', 'U', 'G', 'Q', 'K', 'U',
|
||||
'I', 'Z', 'E', 'G', 'S', 'F', 'X', 'B', 'P', 'Y',
|
||||
'I', 'K', 'G', 'Q', 'H', '3', 'G', 'M', '2', 'U',
|
||||
'A', '2', '3', 'U', '2', 'H', 'J', 'C', 'X', 'T',
|
||||
'W', '5', 'N', '0', 'G', '5', '5', '3', 'A', 'P',
|
||||
'V', 'I', 'Z', '2', 'Y', 'A', 'Z', '4', 'M', 'V',
|
||||
'S', 'M', 'R', 'Q', 'B', 'N', 'X', 'K', 'P', 'O',
|
||||
'3', 'F', 'O', 'K', '5', 'U', 'K', '5', 'R', 'K',
|
||||
'O', 'G', 'T', 'H', 'C', 'L', 'H', '2', 'K', 'U',
|
||||
'R', '2', 'A', 'D', 'M', 'B', 'Q', 'D', 'L', 'A',
|
||||
'S', 'J', 'F', 'A', 'T', 'F', 'U', '3', 'E', 'F',
|
||||
'I', 'S', 'L', '1', 'Z', 'O', 'G', 'A', 'K', 'Q',
|
||||
'U', '1', 'N', 'V', '4', 'Z', 'W', 'P', '3', 'C',
|
||||
'P', 'P', 'L', 'U', 'P', '4', 'Z', 'D', '2', '3',
|
||||
'I', 'E', 'P', 'T', '5', 'I', 'B', 'F', 'J', 'L',
|
||||
'W', '3', 'H', 'D', 'S', 'F', '2', 'J', 'U', 'Z',
|
||||
'L', 'D', 'I', 'W', 'Y', 'X', 'U', 'R', '0', 'Q',
|
||||
'P', 'C', 'U', '4', 'W', 'T', 'H', 'X', 'Z', 'Q',
|
||||
'D', 'P', 'N', 'K', 'S', 'A', 'P', 'O', 'J', 'E',
|
||||
'I', 'U', 'H', 'Q', 'K', '5', 'I', '4', 'R', 'C',
|
||||
'P', 'A', 'F', 'D', '4', '1', 'X', 'F', 'S', 'Q',
|
||||
'V', 'V', '5', 'D', '5', 'R', 'D', 'P', '5', 'M',
|
||||
'T', 'H', 'A', '0', 'Y', 'K', '0', 'A', 'I', 'L',
|
||||
'C', 'X', 'L', 'H', '1', 'J', 'C', 'S', 'P', 'V',
|
||||
'C', 'E', 'K', 'B', 'H', 'K', 'S', 'K', 'Z', 'R' };
|
||||
|
||||
static byte test_data[TEST_SIZE];
|
||||
|
||||
|
||||
// utility function for processing compression trie
|
||||
static void
|
||||
heap_adjust (size_t * freq, size_t * heap, int n, int k)
|
||||
{
|
||||
// this function compares the values in the array
|
||||
// 'freq' to order the elements of 'heap' according
|
||||
// in an inverse heap. See the chapter on priority
|
||||
// queues and heaps for more explanation.
|
||||
int j;
|
||||
|
||||
--heap;
|
||||
|
||||
int v = heap[k];
|
||||
|
||||
while (k <= (n / 2))
|
||||
{
|
||||
j = k + k;
|
||||
|
||||
if ((j < n) && (freq[heap[j]] > freq[heap[j + 1]]))
|
||||
++j;
|
||||
|
||||
if (freq[v] < freq[heap[j]])
|
||||
break;
|
||||
|
||||
heap[k] = heap[j];
|
||||
k = j;
|
||||
}
|
||||
|
||||
heap[k] = v;
|
||||
}
|
||||
|
||||
// Huffman compression/decompression function
|
||||
void
|
||||
compdecomp (byte * data, size_t data_len)
|
||||
{
|
||||
size_t i, j, n, mask;
|
||||
bits32 k, t;
|
||||
byte c;
|
||||
byte *cptr;
|
||||
byte *dptr = data;
|
||||
|
||||
/*
|
||||
COMPRESSION
|
||||
*/
|
||||
|
||||
// allocate data space
|
||||
byte *comp = (byte *) malloc_beebs (data_len + 1);
|
||||
|
||||
size_t freq[512]; // allocate frequency table
|
||||
size_t heap[256]; // allocate heap
|
||||
int link[512]; // allocate link array
|
||||
bits32 code[256]; // huffman codes
|
||||
byte clen[256]; // bit lengths of codes
|
||||
|
||||
memset (comp, 0, sizeof (byte) * (data_len + 1));
|
||||
memset (freq, 0, sizeof (size_t) * 512);
|
||||
memset (heap, 0, sizeof (size_t) * 256);
|
||||
memset (link, 0, sizeof (int) * 512);
|
||||
memset (code, 0, sizeof (bits32) * 256);
|
||||
memset (clen, 0, sizeof (byte) * 256);
|
||||
|
||||
// count frequencies
|
||||
for (i = 0; i < data_len; ++i)
|
||||
{
|
||||
++freq[(size_t) (*dptr)];
|
||||
++dptr;
|
||||
}
|
||||
|
||||
// create indirect heap based on frequencies
|
||||
n = 0;
|
||||
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
if (freq[i])
|
||||
{
|
||||
heap[n] = i;
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = n; i > 0; --i)
|
||||
heap_adjust (freq, heap, n, i);
|
||||
|
||||
// generate a trie from heap
|
||||
size_t temp;
|
||||
|
||||
// at this point, n contains the number of characters
|
||||
// that occur in the data array
|
||||
while (n > 1)
|
||||
{
|
||||
// take first item from top of heap
|
||||
--n;
|
||||
temp = heap[0];
|
||||
heap[0] = heap[n];
|
||||
|
||||
// adjust the heap to maintain properties
|
||||
heap_adjust (freq, heap, n, 1);
|
||||
|
||||
// in upper half of freq array, store sums of
|
||||
// the two smallest frequencies from the heap
|
||||
freq[256 + n] = freq[heap[0]] + freq[temp];
|
||||
link[temp] = 256 + n; // parent
|
||||
link[heap[0]] = -256 - n; // left child
|
||||
heap[0] = 256 + n; // right child
|
||||
|
||||
// adjust the heap again
|
||||
heap_adjust (freq, heap, n, 1);
|
||||
}
|
||||
|
||||
link[256 + n] = 0;
|
||||
|
||||
// generate codes
|
||||
size_t m, x, maxx = 0, maxi = 0;
|
||||
int l;
|
||||
|
||||
for (m = 0; m < 256; ++m)
|
||||
{
|
||||
if (!freq[m]) // character does not occur
|
||||
{
|
||||
code[m] = 0;
|
||||
clen[m] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 0; // length of current code
|
||||
j = 1; // bit being set in code
|
||||
x = 0; // code being built
|
||||
l = link[m]; // link in trie
|
||||
|
||||
while (l) // while not at end of trie
|
||||
{
|
||||
if (l < 0) // left link (negative)
|
||||
{
|
||||
x += j; // insert 1 into code
|
||||
l = -l; // reverse sign
|
||||
}
|
||||
|
||||
l = link[l]; // move to next link
|
||||
j <<= 1; // next bit to be set
|
||||
++i; // increment code length
|
||||
}
|
||||
|
||||
code[m] = (unsigned long) x; // save code
|
||||
clen[m] = (unsigned char) i; // save code len
|
||||
|
||||
// keep track of biggest key
|
||||
if (x > maxx)
|
||||
maxx = x;
|
||||
|
||||
// keep track of longest key
|
||||
if (i > maxi)
|
||||
maxi = i;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure longest codes fit in unsigned long-bits
|
||||
if (maxi > (sizeof (unsigned long) * 8))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// encode data
|
||||
size_t comp_len = 0; // number of data_len output
|
||||
char bout = 0; // byte of encoded data
|
||||
int bit = -1; // count of bits stored in bout
|
||||
dptr = data;
|
||||
|
||||
// watch for one-value file!
|
||||
if (maxx == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (j = 0; j < data_len; ++j)
|
||||
{
|
||||
// start copying at first bit of code
|
||||
mask = 1 << (clen[(*dptr)] - 1);
|
||||
|
||||
// copy code bits
|
||||
for (i = 0; i < clen[(*dptr)]; ++i)
|
||||
{
|
||||
if (bit == 7)
|
||||
{
|
||||
// store full output byte
|
||||
comp[comp_len] = bout;
|
||||
++comp_len;
|
||||
|
||||
// check for output longer than input!
|
||||
if (comp_len == data_len)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bit = 0;
|
||||
bout = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// move to next bit
|
||||
++bit;
|
||||
bout <<= 1;
|
||||
}
|
||||
|
||||
if (code[(*dptr)] & mask)
|
||||
bout |= 1;
|
||||
|
||||
mask >>= 1;
|
||||
}
|
||||
|
||||
++dptr;
|
||||
}
|
||||
|
||||
// output any incomplete data_len and bits
|
||||
bout <<= (7 - bit);
|
||||
comp[comp_len] = bout;
|
||||
++comp_len;
|
||||
|
||||
// printf("data len = %u\n",data_len);
|
||||
// printf("comp len = %u\n",comp_len);
|
||||
|
||||
/*
|
||||
DECOMPRESSION
|
||||
*/
|
||||
|
||||
// allocate heap2
|
||||
bits32 heap2[256];
|
||||
|
||||
// allocate output character buffer
|
||||
char outc[256];
|
||||
|
||||
// initialize work areas
|
||||
memset (heap2, 0, 256 * sizeof (bits32));
|
||||
|
||||
// create decode table as trie heap2
|
||||
char *optr = outc;
|
||||
|
||||
for (j = 0; j < 256; ++j)
|
||||
{
|
||||
(*optr) = (char) j;
|
||||
++optr;
|
||||
|
||||
// if code exists for this byte
|
||||
if (code[j] | clen[j])
|
||||
{
|
||||
// begin at first code bit
|
||||
k = 0;
|
||||
mask = 1 << (clen[j] - 1);
|
||||
|
||||
// find proper node, using bits in
|
||||
// code as path.
|
||||
for (i = 0; i < clen[j]; ++i)
|
||||
{
|
||||
k = k * 2 + 1; // right link
|
||||
|
||||
if (code[j] & mask)
|
||||
++k; // go left
|
||||
|
||||
mask >>= 1; // next bit
|
||||
}
|
||||
|
||||
heap2[j] = k; // store link in heap2
|
||||
}
|
||||
}
|
||||
|
||||
// sort outc based on heap2
|
||||
for (i = 1; i < 256; ++i)
|
||||
{
|
||||
t = heap2[i];
|
||||
c = outc[i];
|
||||
j = i;
|
||||
|
||||
while ((j) && (heap2[j - 1] > t))
|
||||
{
|
||||
heap2[j] = heap2[j - 1];
|
||||
outc[j] = outc[j - 1];
|
||||
--j;
|
||||
}
|
||||
|
||||
heap2[j] = t;
|
||||
outc[j] = c;
|
||||
}
|
||||
|
||||
// find first character in table
|
||||
for (j = 0; heap2[j] == 0; ++j);
|
||||
|
||||
// decode data
|
||||
k = 0; // link in trie
|
||||
i = j;
|
||||
mask = 0x80;
|
||||
n = 0;
|
||||
cptr = comp;
|
||||
dptr = data;
|
||||
|
||||
while (n < data_len)
|
||||
{
|
||||
k = k * 2 + 1; // right link
|
||||
|
||||
if ((*cptr) & mask)
|
||||
++k; // left link if bit on
|
||||
|
||||
// search heap2 until link >= k
|
||||
while (heap2[i] < k)
|
||||
++i;
|
||||
|
||||
// code matches, character found
|
||||
if (k == heap2[i])
|
||||
{
|
||||
(*dptr) = outc[i];
|
||||
++dptr;
|
||||
++n;
|
||||
k = 0;
|
||||
i = j;
|
||||
}
|
||||
|
||||
// move to next bit
|
||||
if (mask > 1)
|
||||
mask >>= 1;
|
||||
else // code extends into next byte
|
||||
{
|
||||
mask = 0x80;
|
||||
++cptr;
|
||||
}
|
||||
}
|
||||
|
||||
// remove work areas
|
||||
free_beebs (comp);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
verify_benchmark (int res __attribute ((unused)))
|
||||
{
|
||||
return 0 == memcmp (test_data, orig_data, TEST_SIZE * sizeof (orig_data[0]));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
|
||||
static int __attribute__ ((noinline)) benchmark_body (int rpt)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < rpt; j++)
|
||||
{
|
||||
init_heap_beebs ((void *) heap, HEAP_SIZE);
|
||||
|
||||
// initialization
|
||||
memcpy (test_data, orig_data, TEST_SIZE * sizeof (orig_data[0]));
|
||||
|
||||
// what we're timing
|
||||
compdecomp (test_data, TEST_SIZE);
|
||||
}
|
||||
|
||||
// done
|
||||
return 0;
|
||||
}
|
270
benchies/embench/benchemarks/matmult-int/matmult-int.c
Normal file
270
benchies/embench/benchemarks/matmult-int/matmult-int.c
Normal file
|
@ -0,0 +1,270 @@
|
|||
/* BEEBS matmult benchmark
|
||||
|
||||
This version, copyright (C) 2013-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
Original code from: WCET Benchmarks,
|
||||
http://www.mrtc.mdh.se/projects/wcet/benchmarks.html
|
||||
Permission to license under GPL obtained by email from Björn Lisper
|
||||
*/
|
||||
|
||||
/* matmult.c */
|
||||
/* was mm.c! */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------*
|
||||
* To make this program compile under our assumed embedded environment,
|
||||
* we had to make several changes:
|
||||
* - Declare all functions in ANSI style, not K&R.
|
||||
* this includes adding return types in all cases!
|
||||
* - Declare function prototypes
|
||||
* - Disable all output
|
||||
* - Disable all UNIX-style includes
|
||||
*
|
||||
* This is a program that was developed from mm.c to matmult.c by
|
||||
* Thomas Lundqvist at Chalmers.
|
||||
*----------------------------------------------------------------------*/
|
||||
|
||||
#include <string.h>
|
||||
#include "support.h"
|
||||
|
||||
/* This scale factor will be changed to equalise the runtime of the
|
||||
benchmarks. */
|
||||
#define LOCAL_SCALE_FACTOR 46
|
||||
#define UPPERLIMIT 20
|
||||
#define RANDOM_VALUE (RandomInteger ())
|
||||
#define ZERO 0
|
||||
#define MOD_SIZE 8095
|
||||
typedef long matrix[UPPERLIMIT][UPPERLIMIT];
|
||||
|
||||
int
|
||||
values_match (long v1, long v2)
|
||||
{
|
||||
return (v1 == v2);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MATRIX MULTIPLICATION BENCHMARK PROGRAM:
|
||||
* This program multiplies 2 square matrices resulting in a 3rd
|
||||
* matrix. It tests a compiler's speed in handling multidimensional
|
||||
* arrays and simple arithmetic.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
int Seed;
|
||||
matrix ArrayA_ref, ArrayA, ArrayB_ref, ArrayB, ResultArray;
|
||||
|
||||
void Multiply (matrix A, matrix B, matrix Res);
|
||||
void InitSeed (void);
|
||||
void Test (matrix A, matrix B, matrix Res);
|
||||
void Initialize (matrix Array);
|
||||
int RandomInteger (void);
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rpt; i++)
|
||||
{
|
||||
memcpy (ArrayA, ArrayA_ref,
|
||||
UPPERLIMIT * UPPERLIMIT * sizeof (ArrayA[0][0]));
|
||||
memcpy (ArrayB, ArrayB_ref,
|
||||
UPPERLIMIT * UPPERLIMIT * sizeof (ArrayA[0][0]));
|
||||
|
||||
Test (ArrayA, ArrayB, ResultArray);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initializes the seed used in the random number generator.
|
||||
*/
|
||||
void
|
||||
InitSeed (void)
|
||||
{
|
||||
Seed = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Runs a multiplication test on an array. Calculates and prints the
|
||||
* time it takes to multiply the matrices.
|
||||
*/
|
||||
void
|
||||
Test (matrix A, matrix B, matrix Res)
|
||||
{
|
||||
Multiply (A, B, Res);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates random integers between 0 and 8095
|
||||
*/
|
||||
int
|
||||
RandomInteger (void)
|
||||
{
|
||||
Seed = ((Seed * 133) + 81) % MOD_SIZE;
|
||||
return (Seed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiplies arrays A and B and stores the result in ResultArray.
|
||||
*/
|
||||
void
|
||||
Multiply (matrix A, matrix B, matrix Res)
|
||||
{
|
||||
register int Outer, Inner, Index;
|
||||
|
||||
for (Outer = 0; Outer < UPPERLIMIT; Outer++)
|
||||
for (Inner = 0; Inner < UPPERLIMIT; Inner++)
|
||||
{
|
||||
Res[Outer][Inner] = ZERO;
|
||||
for (Index = 0; Index < UPPERLIMIT; Index++)
|
||||
Res[Outer][Inner] += A[Outer][Index] * B[Index][Inner];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
initialise_benchmark ()
|
||||
{
|
||||
InitSeed ();
|
||||
int OuterIndex, InnerIndex;
|
||||
|
||||
for (OuterIndex = 0; OuterIndex < UPPERLIMIT; OuterIndex++)
|
||||
for (InnerIndex = 0; InnerIndex < UPPERLIMIT; InnerIndex++)
|
||||
ArrayA_ref[OuterIndex][InnerIndex] = RANDOM_VALUE;
|
||||
for (OuterIndex = 0; OuterIndex < UPPERLIMIT; OuterIndex++)
|
||||
for (InnerIndex = 0; InnerIndex < UPPERLIMIT; InnerIndex++)
|
||||
ArrayB_ref[OuterIndex][InnerIndex] = RANDOM_VALUE;
|
||||
}
|
||||
|
||||
int
|
||||
verify_benchmark (int unused)
|
||||
{
|
||||
int i, j;
|
||||
matrix exp = {
|
||||
{291018000, 315000075, 279049970, 205074215, 382719905,
|
||||
302595865, 348060915, 308986330, 343160760, 307099935,
|
||||
292564810, 240954510, 232755815, 246511665, 328466830,
|
||||
263664375, 324016395, 334656070, 285978755, 345370360},
|
||||
{252241835, 333432715, 299220275, 247745815, 422508990,
|
||||
316728505, 359662270, 277775280, 323336795, 320656600,
|
||||
249903690, 251499360, 242195700, 263484280, 348207635,
|
||||
289485100, 328607555, 300799835, 269351410, 305703460},
|
||||
{304901010, 316252815, 263230275, 208939015, 421993740,
|
||||
335002930, 348571170, 280992155, 289749970, 259701175,
|
||||
295249990, 310900035, 250896625, 250154105, 315096035,
|
||||
236364800, 312879355, 312580685, 275998435, 344137885},
|
||||
{286700525, 325985600, 253054970, 224361490, 353502130,
|
||||
306544290, 323492140, 259123905, 307731610, 282414410,
|
||||
281127810, 246936935, 207890815, 233789540, 339836730,
|
||||
277296350, 319925620, 307470895, 290537580, 292297535},
|
||||
{272571255, 377663320, 304545985, 263001340, 375034885,
|
||||
325423710, 410620380, 313191730, 356989815, 308508355,
|
||||
218003850, 272487135, 266000220, 264734710, 367539620,
|
||||
304146675, 355295500, 276019740, 251415695, 301225235},
|
||||
{272547900, 321522300, 288294345, 247748015, 389912855,
|
||||
331874890, 370798315, 315467255, 367554485, 311947660,
|
||||
258809685, 270536510, 256730515, 287143040, 363087030,
|
||||
285672775, 353670120, 304219695, 274897255, 324684660},
|
||||
{233123995, 227142480, 212655155, 198592290, 345335250,
|
||||
302661845, 253374925, 233243305, 233750030, 224590040,
|
||||
200404820, 250791135, 234405760, 211723645, 280630165,
|
||||
185245875, 296423665, 276278575, 252368265, 278726535},
|
||||
{277690535, 339615440, 320921550, 307114315, 400187215,
|
||||
334374655, 376286920, 295993530, 362988020, 356272700,
|
||||
293965465, 261574710, 259690975, 263037705, 416748985,
|
||||
274683275, 385571030, 402782385, 323927010, 362778710},
|
||||
{267168970, 323401680, 279474330, 201934365, 362624300,
|
||||
330736145, 371793675, 299650280, 333646005, 264791490,
|
||||
215918320, 277512760, 264068435, 234555295, 321772515,
|
||||
217507025, 310372440, 317544750, 245525965, 343183435},
|
||||
{281293570, 326519505, 233494705, 238516065, 297038200,
|
||||
266273420, 349521550, 259343530, 306032255, 266397915,
|
||||
210274920, 263743085, 231689610, 251949545, 293562740,
|
||||
226822900, 309225440, 286212000, 206108715, 236678985},
|
||||
{288404350, 310319375, 282695670, 244150740, 426489380,
|
||||
387525790, 342018190, 326086505, 352250260, 319997735,
|
||||
300645835, 284822660, 271837440, 274000415, 361826730,
|
||||
252399600, 348582320, 375813820, 316588255, 322499110},
|
||||
{273368780, 329706295, 288668335, 234501665, 381962610,
|
||||
343186285, 337520205, 259637405, 295755465, 284778105,
|
||||
205310525, 249598310, 256662470, 251533535, 336159770,
|
||||
249342150, 333559450, 329296590, 278254845, 300673860},
|
||||
{318589575, 315522800, 260632295, 250009765, 337127730,
|
||||
312810490, 346698590, 260810030, 388289910, 337081285,
|
||||
283635410, 208148610, 234123865, 259653165, 370115255,
|
||||
243311450, 377808245, 358786770, 286839730, 321912835},
|
||||
{229541925, 253967450, 223002545, 202302515, 303446955,
|
||||
268472740, 285580065, 211013405, 287677960, 279773910,
|
||||
227377310, 197461135, 222469715, 179536615, 306957380,
|
||||
178407075, 281051570, 279718120, 234868230, 288991535},
|
||||
{290692955, 317729070, 297868235, 213450065, 469270935,
|
||||
375344910, 326987580, 334565680, 325300040, 290325655,
|
||||
254703825, 284914960, 245773820, 276641510, 323510795,
|
||||
271034400, 337424250, 360011440, 281515520, 331261535},
|
||||
{287075125, 313194850, 269889345, 208109115, 420653930,
|
||||
331900290, 355440665, 318065155, 343785360, 302163035,
|
||||
308959360, 312666110, 268997740, 288557415, 370158305,
|
||||
205012650, 318198795, 384484520, 316450105, 378714460},
|
||||
{278680580, 356815220, 307597060, 216073365, 390879235,
|
||||
358775185, 358895230, 306434180, 315569040, 272688130,
|
||||
249424325, 274584610, 273530970, 265450585, 325127920,
|
||||
312802050, 317134900, 298518590, 269975470, 332586535},
|
||||
{245629780, 267021570, 234689035, 208808065, 366356035,
|
||||
267059560, 349348005, 270158755, 348048340, 291550930,
|
||||
272717800, 259714410, 236033845, 280627610, 335089770,
|
||||
176610475, 259339950, 322752840, 236218295, 329687310},
|
||||
{226517370, 272306005, 271484080, 216145515, 400972075,
|
||||
288475645, 332969550, 338410905, 329052205, 330392265,
|
||||
306488095, 271979085, 232795960, 257593945, 339558165,
|
||||
202700275, 320622065, 386350450, 315344865, 329233410},
|
||||
{224852610, 231292540, 236945875, 243273740, 336327040,
|
||||
305144680, 248261920, 191671605, 241699245, 263085200,
|
||||
198883715, 175742885, 202517850, 172427630, 296304160,
|
||||
209188850, 326546955, 252990460, 238844535, 289753485}
|
||||
};
|
||||
|
||||
return 0 == memcmp (ResultArray, exp,
|
||||
UPPERLIMIT * UPPERLIMIT * sizeof (exp[0][0]));
|
||||
}
|
||||
|
||||
/* vim: set ts=3 sw=3 et: */
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
245
benchies/embench/benchemarks/md5sum/md5.c
Normal file
245
benchies/embench/benchemarks/md5sum/md5.c
Normal file
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Simple MD5 implementation
|
||||
* by Creationix
|
||||
* https://gist.github.com/creationix/4710780
|
||||
* Licensed under MIT
|
||||
*
|
||||
* modified by Julian Kunkel for Embench-iot
|
||||
* Compile with: gcc -o md5 -O3 -lm md5.c
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../../src/support.h"
|
||||
|
||||
#define LOCAL_SCALE_FACTOR 51
|
||||
|
||||
/* BEEBS heap is just an array */
|
||||
/* MSG_SIZE * 2 + ((((MSG_SIZE+8)/64 + 1) * 64) - 8) + 64 */
|
||||
#define HEAP_SIZE (2000 + 1016 + 64)
|
||||
#define MSG_SIZE 1000
|
||||
/* Result obtained with a single run on the native target on x86 with a MSG_SIZE
|
||||
* of 1000 and a msg initiated incrementally from 0 to 999 as in benchmark_body.
|
||||
* If MSG_SIZE or the initialization mechanism of the array change the RESULT
|
||||
* value needs to be updated accordingly. */
|
||||
#define RESULT 0x33f673b4
|
||||
|
||||
static char heap[HEAP_SIZE];
|
||||
|
||||
// leftrotate function definition
|
||||
#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
|
||||
|
||||
// These vars will contain the hash
|
||||
static uint32_t h0, h1, h2, h3;
|
||||
|
||||
void md5(uint8_t *initial_msg, size_t initial_len) {
|
||||
|
||||
// Message (to prepare)
|
||||
uint8_t *msg = NULL;
|
||||
|
||||
// Note: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating
|
||||
|
||||
// r specifies the per-round shift amounts
|
||||
|
||||
uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
||||
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
||||
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
||||
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
|
||||
|
||||
// Use binary integer part of the sines of integers (in radians) as constants// Initialize variables:
|
||||
uint32_t k[] = {
|
||||
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
|
||||
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
||||
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
||||
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
|
||||
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
|
||||
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
|
||||
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
|
||||
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
|
||||
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
|
||||
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
|
||||
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
|
||||
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
|
||||
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
|
||||
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
|
||||
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
|
||||
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
|
||||
|
||||
h0 = 0x67452301;
|
||||
h1 = 0xefcdab89;
|
||||
h2 = 0x98badcfe;
|
||||
h3 = 0x10325476;
|
||||
|
||||
// Pre-processing: adding a single 1 bit
|
||||
//append "1" bit to message
|
||||
/* Notice: the input bytes are considered as bits strings,
|
||||
where the first bit is the most significant bit of the byte.[37] */
|
||||
|
||||
// Pre-processing: padding with zeros
|
||||
//append "0" bit until message length in bit ≡ 448 (mod 512)
|
||||
//append length mod (2 pow 64) to message
|
||||
|
||||
int new_len = ((((initial_len + 8) / 64) + 1) * 64) - 8;
|
||||
|
||||
msg = calloc_beebs(new_len + 64, 1); // also appends "0" bits
|
||||
// (we alloc also 64 extra bytes...)
|
||||
memcpy(msg, initial_msg, initial_len);
|
||||
msg[initial_len] = 128; // write the "1" bit
|
||||
|
||||
uint32_t bits_len = 8*initial_len; // note, we append the len
|
||||
memcpy(msg + new_len, &bits_len, 4); // in bits at the end of the buffer
|
||||
|
||||
// Process the message in successive 512-bit chunks:
|
||||
//for each 512-bit chunk of message:
|
||||
int offset;
|
||||
for(offset=0; offset<new_len; offset += (512/8)) {
|
||||
|
||||
// break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15
|
||||
uint32_t *w = (uint32_t *) (msg + offset);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("offset: %d %x\n", offset, offset);
|
||||
|
||||
int j;
|
||||
for(j =0; j < 64; j++) printf("%x ", ((uint8_t *) w)[j]);
|
||||
puts("");
|
||||
#endif
|
||||
|
||||
// Initialize hash value for this chunk:
|
||||
uint32_t a = h0;
|
||||
uint32_t b = h1;
|
||||
uint32_t c = h2;
|
||||
uint32_t d = h3;
|
||||
|
||||
// Main loop:
|
||||
uint32_t i;
|
||||
for(i = 0; i<64; i++) {
|
||||
|
||||
#ifdef ROUNDS
|
||||
uint8_t *p;
|
||||
printf("%i: ", i);
|
||||
p=(uint8_t *)&a;
|
||||
printf("%2.2x%2.2x%2.2x%2.2x ", p[0], p[1], p[2], p[3], a);
|
||||
|
||||
p=(uint8_t *)&b;
|
||||
printf("%2.2x%2.2x%2.2x%2.2x ", p[0], p[1], p[2], p[3], b);
|
||||
|
||||
p=(uint8_t *)&c;
|
||||
printf("%2.2x%2.2x%2.2x%2.2x ", p[0], p[1], p[2], p[3], c);
|
||||
|
||||
p=(uint8_t *)&d;
|
||||
printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], d);
|
||||
puts("");
|
||||
#endif
|
||||
|
||||
|
||||
uint32_t f, g;
|
||||
|
||||
if (i < 16) {
|
||||
f = (b & c) | ((~b) & d);
|
||||
g = i;
|
||||
} else if (i < 32) {
|
||||
f = (d & b) | ((~d) & c);
|
||||
g = (5*i + 1) % 16;
|
||||
} else if (i < 48) {
|
||||
f = b ^ c ^ d;
|
||||
g = (3*i + 5) % 16;
|
||||
} else {
|
||||
f = c ^ (b | (~d));
|
||||
g = (7*i) % 16;
|
||||
}
|
||||
|
||||
#ifdef ROUNDS
|
||||
printf("f=%x g=%d w[g]=%x\n", f, g, w[g]);
|
||||
#endif
|
||||
uint32_t temp = d;
|
||||
d = c;
|
||||
c = b;
|
||||
#ifdef DEBUG
|
||||
printf("rotateLeft(%x + %x + %x + %x, %d)\n", a, f, k[i], w[g], r[i]);
|
||||
#endif
|
||||
b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]);
|
||||
a = temp;
|
||||
}
|
||||
|
||||
// Add this chunk's hash to result so far:
|
||||
|
||||
h0 += a;
|
||||
h1 += b;
|
||||
h2 += c;
|
||||
h3 += d;
|
||||
}
|
||||
|
||||
// cleanup
|
||||
free_beebs(msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int benchmark_body (int rpt, int len);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
benchmark_body (heat, MSG_SIZE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ, MSG_SIZE);
|
||||
}
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt, int len)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (j = 0; j < rpt; j++) {
|
||||
init_heap_beebs ((void *) heap, HEAP_SIZE);
|
||||
|
||||
uint8_t *msg = malloc_beebs(len);
|
||||
for (i = 0; i < len; i++){
|
||||
msg[i] = i;
|
||||
}
|
||||
md5(msg, len);
|
||||
free_beebs(msg);
|
||||
|
||||
uint8_t *p;
|
||||
// display result
|
||||
#ifdef DEBUG
|
||||
p=(uint8_t *)&h0;
|
||||
printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3]);
|
||||
|
||||
p=(uint8_t *)&h1;
|
||||
printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3]);
|
||||
|
||||
p=(uint8_t *)&h2;
|
||||
printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3]);
|
||||
|
||||
p=(uint8_t *)&h3;
|
||||
printf("%2.2x%2.2x%2.2x%2.2x\n", p[0], p[1], p[2], p[3]);
|
||||
#endif
|
||||
}
|
||||
|
||||
return h0 ^ h1 ^ h2 ^ h3;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
verify_benchmark (int r)
|
||||
{
|
||||
// This isn't a proper check...
|
||||
return r == RESULT;
|
||||
}
|
292
benchies/embench/benchemarks/minver/libminver.c
Normal file
292
benchies/embench/benchemarks/minver/libminver.c
Normal file
|
@ -0,0 +1,292 @@
|
|||
/* BEEBS minver benchmark
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor Pierre Langlois <pierre.langlois@embecosm.com>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
*************************************************************************
|
||||
* *
|
||||
* SNU-RT Benchmark Suite for Worst Case Timing Analysis *
|
||||
* ===================================================== *
|
||||
* Collected and Modified by S.-S. Lim *
|
||||
* sslim@archi.snu.ac.kr *
|
||||
* Real-Time Research Group *
|
||||
* Seoul National University *
|
||||
* *
|
||||
* *
|
||||
* < Features > - restrictions for our experimental environment *
|
||||
* *
|
||||
* 1. Completely structured. *
|
||||
* - There are no unconditional jumps. *
|
||||
* - There are no exit from loop bodies. *
|
||||
* (There are no 'break' or 'return' in loop bodies) *
|
||||
* 2. No 'switch' statements. *
|
||||
* 3. No 'do..while' statements. *
|
||||
* 4. Expressions are restricted. *
|
||||
* - There are no multiple expressions joined by 'or', *
|
||||
* 'and' operations. *
|
||||
* 5. No library calls. *
|
||||
* - All the functions needed are implemented in the *
|
||||
* source file. *
|
||||
* *
|
||||
* *
|
||||
*************************************************************************
|
||||
* *
|
||||
* FILE: minver.c *
|
||||
* SOURCE : Turbo C Programming for Engineering by Hyun Soo Ahn *
|
||||
* *
|
||||
* DESCRIPTION : *
|
||||
* *
|
||||
* Matrix inversion for 3x3 floating point matrix. *
|
||||
* *
|
||||
* REMARK : *
|
||||
* *
|
||||
* EXECUTION TIME : *
|
||||
* *
|
||||
* *
|
||||
*************************************************************************
|
||||
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "../../src/support.h"
|
||||
|
||||
/* This scale factor will be changed to equalise the runtime of the
|
||||
benchmarks. */
|
||||
#define LOCAL_SCALE_FACTOR 555
|
||||
|
||||
int minver (int row, int col, float eps);
|
||||
int mmul (int row_a, int col_a, int row_b, int col_b);
|
||||
|
||||
static float a_ref[3][3] = {
|
||||
{3.0, -6.0, 7.0},
|
||||
{9.0, 0.0, -5.0},
|
||||
{5.0, -8.0, 6.0},
|
||||
};
|
||||
|
||||
static float b[3][3] = {
|
||||
{-3.0, 0.0, 2.0},
|
||||
{3.0, -2.0, 0.0},
|
||||
{0.0, 2.0, -3.0},
|
||||
};
|
||||
|
||||
static float a[3][3], c[3][3], d[3][3], det;
|
||||
|
||||
static float
|
||||
minver_fabs (float n)
|
||||
{
|
||||
float f;
|
||||
|
||||
if (n >= 0)
|
||||
f = n;
|
||||
else
|
||||
f = -n;
|
||||
return f;
|
||||
}
|
||||
|
||||
int
|
||||
mmul (int row_a, int col_a, int row_b, int col_b)
|
||||
{
|
||||
int i, j, k, row_c, col_c;
|
||||
float w;
|
||||
|
||||
row_c = row_a;
|
||||
col_c = col_b;
|
||||
|
||||
if (row_c < 1 || row_b < 1 || col_c < 1 || col_a != row_b)
|
||||
return (999);
|
||||
for (i = 0; i < row_c; i++)
|
||||
{
|
||||
for (j = 0; j < col_c; j++)
|
||||
{
|
||||
w = 0.0;
|
||||
for (k = 0; k < row_b; k++)
|
||||
w += a[i][k] * b[k][j];
|
||||
c[i][j] = w;
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
minver (int row, int col, float eps)
|
||||
{
|
||||
int work[500], i, j, k, r, iw, u, v;
|
||||
float w, wmax, pivot, api, w1;
|
||||
|
||||
r = w = 0;
|
||||
if (row < 2 || row > 500 || eps <= 0.0)
|
||||
return (999);
|
||||
w1 = 1.0;
|
||||
for (i = 0; i < row; i++)
|
||||
work[i] = i;
|
||||
for (k = 0; k < row; k++)
|
||||
{
|
||||
wmax = 0.0;
|
||||
for (i = k; i < row; i++)
|
||||
{
|
||||
w = minver_fabs (a[i][k]);
|
||||
if (w > wmax)
|
||||
{
|
||||
wmax = w;
|
||||
r = i;
|
||||
}
|
||||
}
|
||||
pivot = a[r][k];
|
||||
api = minver_fabs (pivot);
|
||||
if (api <= eps)
|
||||
{
|
||||
det = w1;
|
||||
return (1);
|
||||
}
|
||||
w1 *= pivot;
|
||||
u = k * col;
|
||||
v = r * col;
|
||||
if (r != k)
|
||||
{
|
||||
w1 = -w;
|
||||
iw = work[k];
|
||||
work[k] = work[r];
|
||||
work[r] = iw;
|
||||
for (j = 0; j < row; j++)
|
||||
{
|
||||
w = a[k][j];
|
||||
a[k][j] = a[r][j];
|
||||
a[r][j] = w;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < row; i++)
|
||||
a[k][i] /= pivot;
|
||||
for (i = 0; i < row; i++)
|
||||
{
|
||||
if (i != k)
|
||||
{
|
||||
v = i * col;
|
||||
w = a[i][k];
|
||||
if (w != 0.0)
|
||||
{
|
||||
for (j = 0; j < row; j++)
|
||||
if (j != k)
|
||||
a[i][j] -= w * a[k][j];
|
||||
a[i][k] = -w / pivot;
|
||||
}
|
||||
}
|
||||
}
|
||||
a[k][k] = 1.0 / pivot;
|
||||
}
|
||||
|
||||
for (i = 0; i < row; i++)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
k = work[i];
|
||||
if (k == i)
|
||||
break;
|
||||
iw = work[k];
|
||||
work[k] = work[i];
|
||||
work[i] = iw;
|
||||
for (j = 0; j < row; j++)
|
||||
{
|
||||
u = j * col;
|
||||
w = a[k][i];
|
||||
a[k][i] = a[k][k];
|
||||
a[k][k] = w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
det = w1;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
verify_benchmark (int res __attribute ((unused)))
|
||||
{
|
||||
int i, j;
|
||||
float eps = 1.0e-6;
|
||||
|
||||
static float c_exp[3][3] = {
|
||||
{-27.0, 26.0, -15.0},
|
||||
{-27.0, -10.0, 33.0},
|
||||
{-39.0, 28.0, -8.0}
|
||||
};
|
||||
|
||||
static float d_exp[3][3] = {
|
||||
{0.133333325, -0.199999958, 0.2666665910},
|
||||
{-0.519999862, 0.113333330, 0.5266665220},
|
||||
{0.479999840, -0.359999895, 0.0399999917}
|
||||
};
|
||||
|
||||
/* Allow small errors in floating point */
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
for (j = 0; j < 3; j++)
|
||||
if (float_neq_beebs(c[i][j], c_exp[i][j]) || float_neq_beebs(d[i][j], d_exp[i][j]))
|
||||
return 0;
|
||||
|
||||
return float_eq_beebs(det, -16.6666718);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rpt; i++)
|
||||
{
|
||||
float eps = 1.0e-6;
|
||||
|
||||
memcpy (a, a_ref, 3 * 3 * sizeof (a[0][0]));
|
||||
minver (3, 3, eps);
|
||||
memcpy (d, a, 3 * 3 * sizeof (a[0][0]));
|
||||
memcpy (a, a_ref, 3 * 3 * sizeof (a[0][0]));
|
||||
mmul (3, 3, 3, 3);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
288
benchies/embench/benchemarks/nbody/nbody.c
Normal file
288
benchies/embench/benchemarks/nbody/nbody.c
Normal file
|
@ -0,0 +1,288 @@
|
|||
/* BEEBS nbody benchmark
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
The original source code for this benchmark can be found here:
|
||||
|
||||
http://benchmarksgame.alioth.debian.org/
|
||||
|
||||
and was released under the following licence, disclaimers, and
|
||||
copyright:
|
||||
|
||||
Revised BSD license
|
||||
|
||||
This is a specific instance of the Open Source Initiative (OSI) BSD
|
||||
license template http://www.opensource.org/licenses/bsd-license.php
|
||||
|
||||
Copyright 2004-2009 Brent Fulgham
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
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.
|
||||
|
||||
Neither the name of "The Computer Language Benchmarks Game" nor the
|
||||
name of "The Computer Language Shootout Benchmarks" nor the names
|
||||
of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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
|
||||
COPYRIGHT OWNER OR 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. */
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../../src/support.h"
|
||||
|
||||
#define LOCAL_SCALE_FACTOR 1
|
||||
|
||||
#define PI 3.141592653589793
|
||||
#define SOLAR_MASS ( 4 * PI * PI )
|
||||
#define DAYS_PER_YEAR 365.24
|
||||
|
||||
struct body
|
||||
{
|
||||
double x[3], fill, v[3], mass;
|
||||
};
|
||||
|
||||
static struct body solar_bodies[] = {
|
||||
/* sun */
|
||||
{
|
||||
.x = {0., 0., 0.},
|
||||
.v = {0., 0., 0.},
|
||||
.mass = SOLAR_MASS},
|
||||
/* jupiter */
|
||||
{
|
||||
.x = {4.84143144246472090e+00,
|
||||
-1.16032004402742839e+00,
|
||||
-1.03622044471123109e-01},
|
||||
.v = {1.66007664274403694e-03 * DAYS_PER_YEAR,
|
||||
7.69901118419740425e-03 * DAYS_PER_YEAR,
|
||||
-6.90460016972063023e-05 * DAYS_PER_YEAR},
|
||||
.mass = 9.54791938424326609e-04 * SOLAR_MASS},
|
||||
/* saturn */
|
||||
{
|
||||
.x = {8.34336671824457987e+00,
|
||||
4.12479856412430479e+00,
|
||||
-4.03523417114321381e-01},
|
||||
.v = {-2.76742510726862411e-03 * DAYS_PER_YEAR,
|
||||
4.99852801234917238e-03 * DAYS_PER_YEAR,
|
||||
2.30417297573763929e-05 * DAYS_PER_YEAR},
|
||||
.mass = 2.85885980666130812e-04 * SOLAR_MASS},
|
||||
/* uranus */
|
||||
{
|
||||
.x = {1.28943695621391310e+01,
|
||||
-1.51111514016986312e+01,
|
||||
-2.23307578892655734e-01},
|
||||
.v = {2.96460137564761618e-03 * DAYS_PER_YEAR,
|
||||
2.37847173959480950e-03 * DAYS_PER_YEAR,
|
||||
-2.96589568540237556e-05 * DAYS_PER_YEAR},
|
||||
.mass = 4.36624404335156298e-05 * SOLAR_MASS},
|
||||
/* neptune */
|
||||
{
|
||||
.x = {1.53796971148509165e+01,
|
||||
-2.59193146099879641e+01,
|
||||
1.79258772950371181e-01},
|
||||
.v = {2.68067772490389322e-03 * DAYS_PER_YEAR,
|
||||
1.62824170038242295e-03 * DAYS_PER_YEAR,
|
||||
-9.51592254519715870e-05 * DAYS_PER_YEAR},
|
||||
.mass = 5.15138902046611451e-05 * SOLAR_MASS}
|
||||
};
|
||||
|
||||
static const int BODIES_SIZE =
|
||||
sizeof (solar_bodies) / sizeof (solar_bodies[0]);
|
||||
|
||||
void
|
||||
offset_momentum (struct body *bodies, unsigned int nbodies)
|
||||
{
|
||||
unsigned int i, k;
|
||||
for (i = 0; i < nbodies; ++i)
|
||||
for (k = 0; k < 3; ++k)
|
||||
bodies[0].v[k] -= bodies[i].v[k] * bodies[i].mass / SOLAR_MASS;
|
||||
}
|
||||
|
||||
|
||||
double
|
||||
bodies_energy (struct body *bodies, unsigned int nbodies)
|
||||
{
|
||||
double dx[3], distance, e = 0.0;
|
||||
unsigned int i, j, k;
|
||||
|
||||
for (i = 0; i < nbodies; ++i)
|
||||
{
|
||||
e += bodies[i].mass * (bodies[i].v[0] * bodies[i].v[0]
|
||||
+ bodies[i].v[1] * bodies[i].v[1]
|
||||
+ bodies[i].v[2] * bodies[i].v[2]) / 2.;
|
||||
|
||||
for (j = i + 1; j < nbodies; ++j)
|
||||
{
|
||||
for (k = 0; k < 3; ++k)
|
||||
dx[k] = bodies[i].x[k] - bodies[j].x[k];
|
||||
|
||||
distance = sqrt (dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]);
|
||||
e -= (bodies[i].mass * bodies[j].mass) / distance;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
int j;
|
||||
double tot_e = 0.0;
|
||||
|
||||
for (j = 0; j < rpt; j++)
|
||||
{
|
||||
int i;
|
||||
offset_momentum (solar_bodies, BODIES_SIZE);
|
||||
/*printf("%.9f\n", bodies_energy(solar_bodies, BODIES_SIZE)); */
|
||||
tot_e = 0.0;
|
||||
for (i = 0; i < 100; ++i)
|
||||
tot_e += bodies_energy (solar_bodies, BODIES_SIZE);
|
||||
/*printf("%.9f\n", bodies_energy(solar_bodies, BODIES_SIZE)); */
|
||||
}
|
||||
/* Result is known good value for total energy. */
|
||||
return double_eq_beebs(tot_e, -16.907516382852478);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
verify_benchmark (int tot_e_ok)
|
||||
{
|
||||
int i, j;
|
||||
/* print expected values */
|
||||
// printf("static struct body solar_bodies[] = {\n");
|
||||
// for (i=0; i<BODIES_SIZE; i++) {
|
||||
// printf(" {\n");
|
||||
// printf(" .x = { %.30g, %.30g, %.30g },\n", solar_bodies[i].x[0], solar_bodies[i].x[1], solar_bodies[i].x[2]);
|
||||
// printf(" .v = { %.30g, %.30g, %.30g },\n", solar_bodies[i].v[0], solar_bodies[i].v[1], solar_bodies[i].v[2]);
|
||||
// printf(" .mass = %.30g\n", solar_bodies[i].mass);
|
||||
// printf(" }");
|
||||
// if (i<BODIES_SIZE-1) printf(",");
|
||||
// printf("\n");
|
||||
// }
|
||||
// printf("};\n");
|
||||
static struct body expected[] = {
|
||||
{
|
||||
.x = {0, 0, 0},
|
||||
.v =
|
||||
{-0.000387663407198742665776131088862,
|
||||
-0.0032753590371765706722173572274,
|
||||
2.39357340800030020670947916717e-05},
|
||||
.mass = 39.4784176043574319692197605036},
|
||||
{
|
||||
.x =
|
||||
{4.84143144246472090230781759601, -1.16032004402742838777840006514,
|
||||
-0.103622044471123109232735259866},
|
||||
.v =
|
||||
{0.606326392995832019749968821998, 2.81198684491626016423992950877,
|
||||
-0.0252183616598876288172892401462},
|
||||
.mass = 0.0376936748703894930478952574049},
|
||||
{
|
||||
.x =
|
||||
{8.34336671824457987156620220048, 4.1247985641243047894022311084,
|
||||
-0.403523417114321381049535375496},
|
||||
.v =
|
||||
{-1.01077434617879236000703713216, 1.82566237123041186229954746523,
|
||||
0.00841576137658415351916474378413},
|
||||
.mass = 0.0112863261319687668143840753032},
|
||||
{
|
||||
.x =
|
||||
{12.8943695621391309913406075793, -15.1111514016986312469725817209,
|
||||
-0.223307578892655733682204299839},
|
||||
.v =
|
||||
{1.08279100644153536414648897335, 0.868713018169608219842814378353,
|
||||
-0.0108326374013636358983880825235},
|
||||
.mass = 0.0017237240570597111687795033319},
|
||||
{
|
||||
.x =
|
||||
{15.3796971148509165061568637611, -25.9193146099879641042207367718,
|
||||
0.179258772950371181309492385481},
|
||||
.v =
|
||||
{0.979090732243897976516677772452, 0.594698998647676169149178804219,
|
||||
-0.0347559555040781037460462243871},
|
||||
.mass = 0.00203368686992463042206846779436}
|
||||
};
|
||||
|
||||
/* Check we have the correct total energy and we have set up the
|
||||
solar_bodies array correctly. */
|
||||
|
||||
if (tot_e_ok)
|
||||
for (i = 0; i < BODIES_SIZE; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
if (double_neq_beebs(solar_bodies[i].x[j], expected[i].x[j]))
|
||||
return 0;
|
||||
if (double_neq_beebs(solar_bodies[i].v[j], expected[i].v[j]))
|
||||
return 0;
|
||||
}
|
||||
if (double_neq_beebs(solar_bodies[i].mass, expected[i].mass))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
1181
benchies/embench/benchemarks/nettle-aes/nettle-aes.c
Normal file
1181
benchies/embench/benchemarks/nettle-aes/nettle-aes.c
Normal file
File diff suppressed because it is too large
Load diff
490
benchies/embench/benchemarks/nettle-sha256/nettle-sha256.c
Normal file
490
benchies/embench/benchemarks/nettle-sha256/nettle-sha256.c
Normal file
|
@ -0,0 +1,490 @@
|
|||
/* BEEBS Nettle-SHA256
|
||||
|
||||
Copyright (C) 2001 Niels Möller
|
||||
Copyright (C) 2019 Embecosm Limited
|
||||
|
||||
Contributor Graham Markall <graham.markall@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include "../../src/support.h"
|
||||
|
||||
/* This scale factor will be changed to equalise the runtime of the
|
||||
benchmarks. */
|
||||
#define LOCAL_SCALE_FACTOR 475
|
||||
|
||||
// From nettle/nettle-types.h
|
||||
|
||||
/* Hash algorithms */
|
||||
typedef void nettle_hash_init_func (void *ctx);
|
||||
typedef void nettle_hash_update_func (void *ctx,
|
||||
size_t length, const uint8_t * src);
|
||||
typedef void nettle_hash_digest_func (void *ctx,
|
||||
size_t length, uint8_t * dst);
|
||||
|
||||
|
||||
// From nettle/macros.h
|
||||
|
||||
#define MD_UPDATE(ctx, length, data, f, incr) \
|
||||
do { \
|
||||
if ((ctx)->index) \
|
||||
{ \
|
||||
/* Try to fill partial block */ \
|
||||
unsigned __md_left = sizeof((ctx)->block) - (ctx)->index; \
|
||||
if ((length) < __md_left) \
|
||||
{ \
|
||||
memcpy((ctx)->block + (ctx)->index, (data), (length)); \
|
||||
(ctx)->index += (length); \
|
||||
goto __md_done; /* Finished */ \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
memcpy((ctx)->block + (ctx)->index, (data), __md_left); \
|
||||
\
|
||||
f((ctx), (ctx)->block); \
|
||||
(incr); \
|
||||
\
|
||||
(data) += __md_left; \
|
||||
(length) -= __md_left; \
|
||||
} \
|
||||
} \
|
||||
while ((length) >= sizeof((ctx)->block)) \
|
||||
{ \
|
||||
f((ctx), (data)); \
|
||||
(incr); \
|
||||
\
|
||||
(data) += sizeof((ctx)->block); \
|
||||
(length) -= sizeof((ctx)->block); \
|
||||
} \
|
||||
memcpy ((ctx)->block, (data), (length)); \
|
||||
(ctx)->index = (length); \
|
||||
__md_done: \
|
||||
; \
|
||||
} while (0)
|
||||
|
||||
#define MD_PAD(ctx, size, f) \
|
||||
do { \
|
||||
unsigned __md_i; \
|
||||
__md_i = (ctx)->index; \
|
||||
\
|
||||
/* Set the first char of padding to 0x80. This is safe since there \
|
||||
is always at least one byte free */ \
|
||||
\
|
||||
assert_beebs(__md_i < sizeof((ctx)->block)); \
|
||||
(ctx)->block[__md_i++] = 0x80; \
|
||||
\
|
||||
if (__md_i > (sizeof((ctx)->block) - (size))) \
|
||||
{ /* No room for length in this block. Process it and \
|
||||
pad with another one */ \
|
||||
memset((ctx)->block + __md_i, 0, sizeof((ctx)->block) - __md_i); \
|
||||
\
|
||||
f((ctx), (ctx)->block); \
|
||||
__md_i = 0; \
|
||||
} \
|
||||
memset((ctx)->block + __md_i, 0, \
|
||||
sizeof((ctx)->block) - (size) - __md_i); \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
#define WRITE_UINT64(p, i) \
|
||||
do { \
|
||||
(p)[0] = ((i) >> 56) & 0xff; \
|
||||
(p)[1] = ((i) >> 48) & 0xff; \
|
||||
(p)[2] = ((i) >> 40) & 0xff; \
|
||||
(p)[3] = ((i) >> 32) & 0xff; \
|
||||
(p)[4] = ((i) >> 24) & 0xff; \
|
||||
(p)[5] = ((i) >> 16) & 0xff; \
|
||||
(p)[6] = ((i) >> 8) & 0xff; \
|
||||
(p)[7] = (i) & 0xff; \
|
||||
} while(0)
|
||||
|
||||
#define WRITE_UINT32(p, i) \
|
||||
do { \
|
||||
(p)[0] = ((i) >> 24) & 0xff; \
|
||||
(p)[1] = ((i) >> 16) & 0xff; \
|
||||
(p)[2] = ((i) >> 8) & 0xff; \
|
||||
(p)[3] = (i) & 0xff; \
|
||||
} while(0)
|
||||
|
||||
/* Reads a 32-bit integer, in network, big-endian, byte order */
|
||||
#define READ_UINT32(p) \
|
||||
( (((uint32_t) (p)[0]) << 24) \
|
||||
| (((uint32_t) (p)[1]) << 16) \
|
||||
| (((uint32_t) (p)[2]) << 8) \
|
||||
| ((uint32_t) (p)[3]))
|
||||
|
||||
#define ROTL32(n,x) (((x)<<(n)) | ((x)>>((-(n)&31))))
|
||||
|
||||
|
||||
// From nettle/write-be32.c
|
||||
|
||||
void
|
||||
_nettle_write_be32 (size_t length, uint8_t * dst, const uint32_t * src)
|
||||
{
|
||||
size_t i;
|
||||
size_t words;
|
||||
unsigned leftover;
|
||||
|
||||
words = length / 4;
|
||||
leftover = length % 4;
|
||||
|
||||
for (i = 0; i < words; i++, dst += 4)
|
||||
WRITE_UINT32 (dst, src[i]);
|
||||
|
||||
if (leftover)
|
||||
{
|
||||
uint32_t word;
|
||||
unsigned j = leftover;
|
||||
|
||||
word = src[i];
|
||||
|
||||
switch (leftover)
|
||||
{
|
||||
default:
|
||||
abort ();
|
||||
case 3:
|
||||
dst[--j] = (word >> 8) & 0xff;
|
||||
/* Fall through */
|
||||
case 2:
|
||||
dst[--j] = (word >> 16) & 0xff;
|
||||
/* Fall through */
|
||||
case 1:
|
||||
dst[--j] = (word >> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// From nettle/sha2.h
|
||||
|
||||
#define SHA256_DIGEST_SIZE 32
|
||||
#define SHA256_BLOCK_SIZE 64
|
||||
|
||||
/* Digest is kept internally as 8 32-bit words. */
|
||||
#define _SHA256_DIGEST_LENGTH 8
|
||||
|
||||
struct sha256_ctx
|
||||
{
|
||||
uint32_t state[_SHA256_DIGEST_LENGTH]; /* State variables */
|
||||
uint64_t count; /* 64-bit block count */
|
||||
uint8_t block[SHA256_BLOCK_SIZE]; /* SHA256 data buffer */
|
||||
unsigned int index; /* index into buffer */
|
||||
};
|
||||
|
||||
|
||||
// From nettle/sha256-compress.c
|
||||
|
||||
#define SHA256_DATA_LENGTH 16
|
||||
|
||||
#define DEBUG(i)
|
||||
|
||||
#define Choice(x,y,z) ( (z) ^ ( (x) & ( (y) ^ (z) ) ) )
|
||||
#define Majority(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) )
|
||||
|
||||
#define S0(x) (ROTL32(30,(x)) ^ ROTL32(19,(x)) ^ ROTL32(10,(x)))
|
||||
#define S1(x) (ROTL32(26,(x)) ^ ROTL32(21,(x)) ^ ROTL32(7,(x)))
|
||||
|
||||
#define s0(x) (ROTL32(25,(x)) ^ ROTL32(14,(x)) ^ ((x) >> 3))
|
||||
#define s1(x) (ROTL32(15,(x)) ^ ROTL32(13,(x)) ^ ((x) >> 10))
|
||||
|
||||
#define EXPAND(W,i) \
|
||||
( W[(i) & 15 ] += (s1(W[((i)-2) & 15]) + W[((i)-7) & 15] + s0(W[((i)-15) & 15])) )
|
||||
|
||||
/* It's crucial that DATA is only used once, as that argument will
|
||||
* have side effects. */
|
||||
#define ROUND(a,b,c,d,e,f,g,h,k,data) do { \
|
||||
h += S1(e) + Choice(e,f,g) + k + data; \
|
||||
d += h; \
|
||||
h += S0(a) + Majority(a,b,c); \
|
||||
} while (0)
|
||||
|
||||
void
|
||||
_nettle_sha256_compress (uint32_t * state, const uint8_t * input,
|
||||
const uint32_t * k)
|
||||
{
|
||||
uint32_t data[SHA256_DATA_LENGTH];
|
||||
uint32_t A, B, C, D, E, F, G, H; /* Local vars */
|
||||
unsigned i;
|
||||
uint32_t *d;
|
||||
|
||||
for (i = 0; i < SHA256_DATA_LENGTH; i++, input += 4)
|
||||
{
|
||||
data[i] = READ_UINT32 (input);
|
||||
}
|
||||
|
||||
/* Set up first buffer and local data buffer */
|
||||
A = state[0];
|
||||
B = state[1];
|
||||
C = state[2];
|
||||
D = state[3];
|
||||
E = state[4];
|
||||
F = state[5];
|
||||
G = state[6];
|
||||
H = state[7];
|
||||
|
||||
/* Heavy mangling */
|
||||
/* First 16 subrounds that act on the original data */
|
||||
|
||||
DEBUG (-1);
|
||||
for (i = 0, d = data; i < 16; i += 8, k += 8, d += 8)
|
||||
{
|
||||
ROUND (A, B, C, D, E, F, G, H, k[0], d[0]);
|
||||
DEBUG (i);
|
||||
ROUND (H, A, B, C, D, E, F, G, k[1], d[1]);
|
||||
DEBUG (i + 1);
|
||||
ROUND (G, H, A, B, C, D, E, F, k[2], d[2]);
|
||||
ROUND (F, G, H, A, B, C, D, E, k[3], d[3]);
|
||||
ROUND (E, F, G, H, A, B, C, D, k[4], d[4]);
|
||||
ROUND (D, E, F, G, H, A, B, C, k[5], d[5]);
|
||||
ROUND (C, D, E, F, G, H, A, B, k[6], d[6]);
|
||||
DEBUG (i + 6);
|
||||
ROUND (B, C, D, E, F, G, H, A, k[7], d[7]);
|
||||
DEBUG (i + 7);
|
||||
}
|
||||
|
||||
for (; i < 64; i += 16, k += 16)
|
||||
{
|
||||
ROUND (A, B, C, D, E, F, G, H, k[0], EXPAND (data, 0));
|
||||
DEBUG (i);
|
||||
ROUND (H, A, B, C, D, E, F, G, k[1], EXPAND (data, 1));
|
||||
DEBUG (i + 1);
|
||||
ROUND (G, H, A, B, C, D, E, F, k[2], EXPAND (data, 2));
|
||||
DEBUG (i + 2);
|
||||
ROUND (F, G, H, A, B, C, D, E, k[3], EXPAND (data, 3));
|
||||
DEBUG (i + 3);
|
||||
ROUND (E, F, G, H, A, B, C, D, k[4], EXPAND (data, 4));
|
||||
DEBUG (i + 4);
|
||||
ROUND (D, E, F, G, H, A, B, C, k[5], EXPAND (data, 5));
|
||||
DEBUG (i + 5);
|
||||
ROUND (C, D, E, F, G, H, A, B, k[6], EXPAND (data, 6));
|
||||
DEBUG (i + 6);
|
||||
ROUND (B, C, D, E, F, G, H, A, k[7], EXPAND (data, 7));
|
||||
DEBUG (i + 7);
|
||||
ROUND (A, B, C, D, E, F, G, H, k[8], EXPAND (data, 8));
|
||||
DEBUG (i + 8);
|
||||
ROUND (H, A, B, C, D, E, F, G, k[9], EXPAND (data, 9));
|
||||
DEBUG (i + 9);
|
||||
ROUND (G, H, A, B, C, D, E, F, k[10], EXPAND (data, 10));
|
||||
DEBUG (i + 10);
|
||||
ROUND (F, G, H, A, B, C, D, E, k[11], EXPAND (data, 11));
|
||||
DEBUG (i + 11);
|
||||
ROUND (E, F, G, H, A, B, C, D, k[12], EXPAND (data, 12));
|
||||
DEBUG (i + 12);
|
||||
ROUND (D, E, F, G, H, A, B, C, k[13], EXPAND (data, 13));
|
||||
DEBUG (i + 13);
|
||||
ROUND (C, D, E, F, G, H, A, B, k[14], EXPAND (data, 14));
|
||||
DEBUG (i + 14);
|
||||
ROUND (B, C, D, E, F, G, H, A, k[15], EXPAND (data, 15));
|
||||
DEBUG (i + 15);
|
||||
}
|
||||
|
||||
/* Update state */
|
||||
state[0] += A;
|
||||
state[1] += B;
|
||||
state[2] += C;
|
||||
state[3] += D;
|
||||
state[4] += E;
|
||||
state[5] += F;
|
||||
state[6] += G;
|
||||
state[7] += H;
|
||||
}
|
||||
|
||||
|
||||
// From nettle/sha256.c
|
||||
|
||||
/* Generated by the shadata program. */
|
||||
static const uint32_t K[64] = {
|
||||
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
|
||||
0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
|
||||
0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
|
||||
0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
|
||||
0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
|
||||
0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
|
||||
0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
|
||||
0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
|
||||
0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
|
||||
0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
|
||||
0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
|
||||
0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
|
||||
0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
|
||||
0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
|
||||
0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
|
||||
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL,
|
||||
};
|
||||
|
||||
#define COMPRESS(ctx, data) (_nettle_sha256_compress((ctx)->state, (data), K))
|
||||
|
||||
/* Initialize the SHA values */
|
||||
|
||||
void
|
||||
sha256_init (struct sha256_ctx *ctx)
|
||||
{
|
||||
/* Initial values, also generated by the shadata program. */
|
||||
static const uint32_t H0[_SHA256_DIGEST_LENGTH] = {
|
||||
0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
|
||||
0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL,
|
||||
};
|
||||
|
||||
memcpy (ctx->state, H0, sizeof (H0));
|
||||
|
||||
/* Initialize bit count */
|
||||
ctx->count = 0;
|
||||
|
||||
/* Initialize buffer */
|
||||
ctx->index = 0;
|
||||
}
|
||||
|
||||
void
|
||||
sha256_update (struct sha256_ctx *ctx, size_t length, const uint8_t * data)
|
||||
{
|
||||
MD_UPDATE (ctx, length, data, COMPRESS, ctx->count++);
|
||||
}
|
||||
|
||||
static void
|
||||
sha256_write_digest (struct sha256_ctx *ctx, size_t length, uint8_t * digest)
|
||||
{
|
||||
uint64_t bit_count;
|
||||
|
||||
assert_beebs (length <= SHA256_DIGEST_SIZE);
|
||||
|
||||
MD_PAD (ctx, 8, COMPRESS);
|
||||
|
||||
/* There are 512 = 2^9 bits in one block */
|
||||
bit_count = (ctx->count << 9) | (ctx->index << 3);
|
||||
|
||||
/* This is slightly inefficient, as the numbers are converted to
|
||||
big-endian format, and will be converted back by the compression
|
||||
function. It's probably not worth the effort to fix this. */
|
||||
WRITE_UINT64 (ctx->block + (SHA256_BLOCK_SIZE - 8), bit_count);
|
||||
COMPRESS (ctx, ctx->block);
|
||||
|
||||
_nettle_write_be32 (length, digest, ctx->state);
|
||||
}
|
||||
|
||||
void
|
||||
sha256_digest (struct sha256_ctx *ctx, size_t length, uint8_t * digest)
|
||||
{
|
||||
sha256_write_digest (ctx, length, digest);
|
||||
sha256_init (ctx);
|
||||
}
|
||||
|
||||
|
||||
// From nettle/nettle-meta.h
|
||||
|
||||
struct nettle_hash
|
||||
{
|
||||
const char *name;
|
||||
|
||||
/* Size of the context struct */
|
||||
unsigned context_size;
|
||||
|
||||
/* Size of digests */
|
||||
unsigned digest_size;
|
||||
|
||||
/* Internal block size */
|
||||
unsigned block_size;
|
||||
|
||||
nettle_hash_init_func *init;
|
||||
nettle_hash_update_func *update;
|
||||
nettle_hash_digest_func *digest;
|
||||
};
|
||||
|
||||
#define _NETTLE_HASH(name, NAME) { \
|
||||
#name, \
|
||||
sizeof(struct name##_ctx), \
|
||||
NAME##_DIGEST_SIZE, \
|
||||
NAME##_BLOCK_SIZE, \
|
||||
(nettle_hash_init_func *) name##_init, \
|
||||
(nettle_hash_update_func *) name##_update, \
|
||||
(nettle_hash_digest_func *) name##_digest \
|
||||
}
|
||||
|
||||
|
||||
// From nettle/sha256-meta.c
|
||||
|
||||
const struct nettle_hash nettle_sha256 = _NETTLE_HASH (sha256, SHA256);
|
||||
|
||||
|
||||
// BEEBS benchmark code
|
||||
|
||||
unsigned char msg[56] =
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
|
||||
|
||||
unsigned char hash[32] =
|
||||
{ 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93,
|
||||
0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
|
||||
0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1
|
||||
};
|
||||
|
||||
uint8_t buffer[SHA256_DIGEST_SIZE];
|
||||
|
||||
int
|
||||
verify_benchmark (int res __attribute ((unused)))
|
||||
{
|
||||
bool correct = true;
|
||||
|
||||
for (size_t i = 0; i < _SHA256_DIGEST_LENGTH; i++)
|
||||
{
|
||||
if (hash[i] != buffer[i])
|
||||
correct = false;
|
||||
}
|
||||
|
||||
return correct;
|
||||
}
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rpt; i++)
|
||||
{
|
||||
memset (buffer, 0, sizeof (buffer));
|
||||
struct sha256_ctx ctx;
|
||||
nettle_sha256.init (&ctx);
|
||||
nettle_sha256.update (&ctx, sizeof (msg), msg);
|
||||
nettle_sha256.digest (&ctx, nettle_sha256.digest_size, buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
4594
benchies/embench/benchemarks/nsichneu/libnsichneu.c
Normal file
4594
benchies/embench/benchemarks/nsichneu/libnsichneu.c
Normal file
File diff suppressed because it is too large
Load diff
2528
benchies/embench/benchemarks/picojpeg/libpicojpeg.c
Normal file
2528
benchies/embench/benchemarks/picojpeg/libpicojpeg.c
Normal file
File diff suppressed because it is too large
Load diff
150
benchies/embench/benchemarks/picojpeg/picojpeg.h
Normal file
150
benchies/embench/benchemarks/picojpeg/picojpeg.h
Normal file
|
@ -0,0 +1,150 @@
|
|||
/* This file is part of the Bristol/Embecosm Embedded Benchmark Suite.
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// picojpeg - Public domain, Rich Geldreich <richgel99@gmail.com>
|
||||
//------------------------------------------------------------------------------
|
||||
#ifndef PICOJPEG_H
|
||||
#define PICOJPEG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
// Error codes
|
||||
enum
|
||||
{
|
||||
PJPG_NO_MORE_BLOCKS = 1,
|
||||
PJPG_BAD_DHT_COUNTS,
|
||||
PJPG_BAD_DHT_INDEX,
|
||||
PJPG_BAD_DHT_MARKER,
|
||||
PJPG_BAD_DQT_MARKER,
|
||||
PJPG_BAD_DQT_TABLE,
|
||||
PJPG_BAD_PRECISION,
|
||||
PJPG_BAD_HEIGHT,
|
||||
PJPG_BAD_WIDTH,
|
||||
PJPG_TOO_MANY_COMPONENTS,
|
||||
PJPG_BAD_SOF_LENGTH,
|
||||
PJPG_BAD_VARIABLE_MARKER,
|
||||
PJPG_BAD_DRI_LENGTH,
|
||||
PJPG_BAD_SOS_LENGTH,
|
||||
PJPG_BAD_SOS_COMP_ID,
|
||||
PJPG_W_EXTRA_BYTES_BEFORE_MARKER,
|
||||
PJPG_NO_ARITHMITIC_SUPPORT,
|
||||
PJPG_UNEXPECTED_MARKER,
|
||||
PJPG_NOT_JPEG,
|
||||
PJPG_UNSUPPORTED_MARKER,
|
||||
PJPG_BAD_DQT_LENGTH,
|
||||
PJPG_TOO_MANY_BLOCKS,
|
||||
PJPG_UNDEFINED_QUANT_TABLE,
|
||||
PJPG_UNDEFINED_HUFF_TABLE,
|
||||
PJPG_NOT_SINGLE_SCAN,
|
||||
PJPG_UNSUPPORTED_COLORSPACE,
|
||||
PJPG_UNSUPPORTED_SAMP_FACTORS,
|
||||
PJPG_DECODE_ERROR,
|
||||
PJPG_BAD_RESTART_MARKER,
|
||||
PJPG_ASSERTION_ERROR,
|
||||
PJPG_BAD_SOS_SPECTRAL,
|
||||
PJPG_BAD_SOS_SUCCESSIVE,
|
||||
PJPG_STREAM_READ_ERROR,
|
||||
PJPG_NOTENOUGHMEM,
|
||||
PJPG_UNSUPPORTED_COMP_IDENT,
|
||||
PJPG_UNSUPPORTED_QUANT_TABLE,
|
||||
PJPG_UNSUPPORTED_MODE, // picojpeg doesn't support progressive JPEG's
|
||||
};
|
||||
|
||||
// Scan types
|
||||
typedef enum
|
||||
{
|
||||
PJPG_GRAYSCALE,
|
||||
PJPG_YH1V1,
|
||||
PJPG_YH2V1,
|
||||
PJPG_YH1V2,
|
||||
PJPG_YH2V2
|
||||
} pjpeg_scan_type_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Image resolution
|
||||
int m_width;
|
||||
int m_height;
|
||||
|
||||
// Number of components (1 or 3)
|
||||
int m_comps;
|
||||
|
||||
// Total number of minimum coded units (MCU's) per row/col.
|
||||
int m_MCUSPerRow;
|
||||
int m_MCUSPerCol;
|
||||
|
||||
// Scan type
|
||||
pjpeg_scan_type_t m_scanType;
|
||||
|
||||
// MCU width/height in pixels (each is either 8 or 16 depending on the scan type)
|
||||
int m_MCUWidth;
|
||||
int m_MCUHeight;
|
||||
|
||||
// m_pMCUBufR, m_pMCUBufG, and m_pMCUBufB are pointers to internal MCU Y or RGB pixel component buffers.
|
||||
// Each time pjpegDecodeMCU() is called successfully these buffers will be filled with 8x8 pixel blocks of Y or RGB pixels.
|
||||
// Each MCU consists of (m_MCUWidth/8)*(m_MCUHeight/8) Y/RGB blocks: 1 for greyscale/no subsampling, 2 for H1V2/H2V1, or 4 blocks for H2V2 sampling factors.
|
||||
// Each block is a contiguous array of 64 (8x8) bytes of a single component: either Y for grayscale images, or R, G or B components for color images.
|
||||
//
|
||||
// The 8x8 pixel blocks are organized in these byte arrays like this:
|
||||
//
|
||||
// PJPG_GRAYSCALE: Each MCU is decoded to a single block of 8x8 grayscale pixels.
|
||||
// Only the values in m_pMCUBufR are valid. Each 8 bytes is a row of pixels (raster order: left to right, top to bottom) from the 8x8 block.
|
||||
//
|
||||
// PJPG_H1V1: Each MCU contains is decoded to a single block of 8x8 RGB pixels.
|
||||
//
|
||||
// PJPG_YH2V1: Each MCU is decoded to 2 blocks, or 16x8 pixels.
|
||||
// The 2 RGB blocks are at byte offsets: 0, 64
|
||||
//
|
||||
// PJPG_YH1V2: Each MCU is decoded to 2 blocks, or 8x16 pixels.
|
||||
// The 2 RGB blocks are at byte offsets: 0,
|
||||
// 128
|
||||
//
|
||||
// PJPG_YH2V2: Each MCU is decoded to 4 blocks, or 16x16 pixels.
|
||||
// The 2x2 block array is organized at byte offsets: 0, 64,
|
||||
// 128, 192
|
||||
//
|
||||
// It is up to the caller to copy or blit these pixels from these buffers into the destination bitmap.
|
||||
unsigned char *m_pMCUBufR;
|
||||
unsigned char *m_pMCUBufG;
|
||||
unsigned char *m_pMCUBufB;
|
||||
} pjpeg_image_info_t;
|
||||
|
||||
typedef unsigned char (*pjpeg_need_bytes_callback_t) (unsigned char *pBuf,
|
||||
unsigned char
|
||||
buf_size,
|
||||
unsigned char
|
||||
*pBytes_actually_read,
|
||||
void *pCallback_data);
|
||||
|
||||
// Initializes the decompressor. Returns 0 on success, or one of the above error codes on failure.
|
||||
// pNeed_bytes_callback will be called to fill the decompressor's internal input buffer.
|
||||
// If reduce is 1, only the first pixel of each block will be decoded. This mode is much faster because it skips the AC dequantization, IDCT and chroma upsampling of every image pixel.
|
||||
// Not thread safe.
|
||||
unsigned char pjpeg_decode_init (pjpeg_image_info_t * pInfo,
|
||||
pjpeg_need_bytes_callback_t
|
||||
pNeed_bytes_callback, void *pCallback_data,
|
||||
unsigned char reduce);
|
||||
|
||||
// Decompresses the file's next MCU. Returns 0 on success, PJPG_NO_MORE_BLOCKS if no more blocks are available, or an error code.
|
||||
// Must be called a total of m_MCUSPerRow*m_MCUSPerCol times to completely decompress the image.
|
||||
// Not thread safe.
|
||||
unsigned char pjpeg_decode_mcu (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // PICOJPEG_H
|
214
benchies/embench/benchemarks/picojpeg/picojpeg_test.c
Normal file
214
benchies/embench/benchemarks/picojpeg/picojpeg_test.c
Normal file
|
@ -0,0 +1,214 @@
|
|||
/* BEEBS picobenchmark benchmark
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#include "../../src/support.h"
|
||||
#include "picojpeg.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* This scale factor will be changed to equalise the runtime of the
|
||||
benchmarks. */
|
||||
#define LOCAL_SCALE_FACTOR 6
|
||||
|
||||
const unsigned char jpeg_data[] = {
|
||||
0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46,
|
||||
0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x48,
|
||||
0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43,
|
||||
0x00, 0x50, 0x37, 0x3c, 0x46, 0x3c, 0x32, 0x50,
|
||||
0x46, 0x41, 0x46, 0x5a, 0x55, 0x50, 0x5f, 0x78,
|
||||
0xc8, 0x82, 0x78, 0x6e, 0x6e, 0x78, 0xf5, 0xaf,
|
||||
0xb9, 0x91, 0xc8, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x55, 0x5a,
|
||||
0x5a, 0x78, 0x69, 0x78, 0xeb, 0x82, 0x82, 0xeb,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||
0x00, 0x11, 0x08, 0x00, 0x40, 0x00, 0x33, 0x03,
|
||||
0x01, 0x11, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11,
|
||||
0x01, 0xff, 0xc4, 0x00, 0x18, 0x00, 0x00, 0x03,
|
||||
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
|
||||
0x03, 0x00, 0x04, 0xff, 0xc4, 0x00, 0x26, 0x10,
|
||||
0x00, 0x02, 0x02, 0x01, 0x03, 0x03, 0x04, 0x03,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x02, 0x00, 0x11, 0x03, 0x12, 0x21, 0x31,
|
||||
0x41, 0x61, 0x71, 0x04, 0x22, 0x53, 0x91, 0x13,
|
||||
0x23, 0x51, 0x62, 0xff, 0xc4, 0x00, 0x15, 0x01,
|
||||
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02,
|
||||
0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xc7, 0x88,
|
||||
0x0b, 0x28, 0x4d, 0x66, 0xe1, 0x02, 0xcf, 0x58,
|
||||
0x05, 0x45, 0x88, 0x00, 0xa9, 0x10, 0x34, 0x0e,
|
||||
0xaf, 0x6f, 0x68, 0x54, 0x33, 0x64, 0x03, 0x61,
|
||||
0x02, 0x6a, 0x49, 0xdb, 0x49, 0x84, 0x59, 0x50,
|
||||
0x91, 0x50, 0xa0, 0x3d, 0xa4, 0x80, 0x7c, 0x88,
|
||||
0x18, 0xd5, 0x48, 0x05, 0x09, 0x43, 0xeb, 0xff,
|
||||
0x00, 0x2b, 0xf5, 0x02, 0x78, 0xd4, 0x1c, 0xac,
|
||||
0x48, 0x10, 0x8e, 0xb5, 0x55, 0xa8, 0x0c, 0xa5,
|
||||
0x2f, 0xdb, 0x52, 0x2a, 0x19, 0x53, 0xf6, 0x82,
|
||||
0x04, 0xa1, 0x0e, 0x45, 0xf8, 0x84, 0x0d, 0xad,
|
||||
0x7e, 0x21, 0x20, 0xd0, 0x30, 0x04, 0x93, 0x5c,
|
||||
0x99, 0x43, 0xe2, 0xc6, 0x57, 0x20, 0xd4, 0xd7,
|
||||
0x7d, 0x20, 0x3a, 0xe1, 0x40, 0xf6, 0x49, 0xf1,
|
||||
0x20, 0xa3, 0x8b, 0x17, 0xc5, 0x09, 0x47, 0x26,
|
||||
0x35, 0x05, 0xb5, 0x1e, 0x20, 0x75, 0x02, 0x95,
|
||||
0xc0, 0xfa, 0x81, 0xcf, 0x52, 0x0c, 0x6c, 0x0d,
|
||||
0xa0, 0x25, 0xbd, 0xdd, 0xd1, 0xf3, 0x2a, 0x28,
|
||||
0x43, 0xb0, 0x04, 0x0e, 0x3a, 0xdc, 0x29, 0xb2,
|
||||
0x13, 0xf8, 0x6a, 0x11, 0x25, 0x53, 0x22, 0xa9,
|
||||
0x7d, 0xe0, 0x2e, 0xa8, 0x06, 0xc1, 0xda, 0xa0,
|
||||
0x29, 0x21, 0x4d, 0x30, 0x35, 0x2a, 0x28, 0xb9,
|
||||
0x17, 0x85, 0x06, 0x15, 0x50, 0x97, 0x8c, 0xd8,
|
||||
0xef, 0x20, 0xe5, 0x01, 0xf9, 0xd3, 0x52, 0xa1,
|
||||
0xb5, 0x0e, 0xb0, 0x14, 0x90, 0x39, 0x32, 0x28,
|
||||
0xe2, 0x60, 0xd9, 0x17, 0xcc, 0xa2, 0xd9, 0xb1,
|
||||
0x02, 0x35, 0x58, 0x1e, 0x60, 0x0c, 0x58, 0x95,
|
||||
0x06, 0xa6, 0x20, 0xf8, 0x90, 0x3b, 0x67, 0x41,
|
||||
0xb0, 0xb3, 0x02, 0x4f, 0x9c, 0x55, 0x40, 0x8e,
|
||||
0xb5, 0xfe, 0x09, 0x51, 0x12, 0xd7, 0x01, 0xfd,
|
||||
0x3b, 0x11, 0x99, 0x7b, 0x98, 0x55, 0x7d, 0x4b,
|
||||
0xbb, 0x64, 0x00, 0xec, 0xbd, 0x04, 0x05, 0x45,
|
||||
0x62, 0x36, 0xb2, 0x3b, 0x42, 0x1b, 0x2a, 0x1c,
|
||||
0x40, 0x74, 0xb8, 0x11, 0x06, 0x00, 0xb8, 0x1f,
|
||||
0xff, 0xd9
|
||||
};
|
||||
|
||||
unsigned jpeg_off = 0;
|
||||
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
|
||||
unsigned char
|
||||
pjpeg_need_bytes_callback (unsigned char *pBuf,
|
||||
unsigned char buf_size,
|
||||
unsigned char *pBytes_actually_read,
|
||||
void *pCallback_data)
|
||||
{
|
||||
unsigned n = MIN (sizeof (jpeg_data) - jpeg_off, buf_size);
|
||||
|
||||
memcpy (pBuf, &jpeg_data[jpeg_off], n);
|
||||
*pBytes_actually_read = (unsigned char) n;
|
||||
jpeg_off += n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
pjpeg_image_info_t pInfo;
|
||||
|
||||
int
|
||||
verify_benchmark (int res __attribute ((unused)))
|
||||
{
|
||||
static const unsigned char r_ref[64] = {
|
||||
33, 33, 33, 33, 33, 33, 33, 33,
|
||||
32, 32, 32, 32, 32, 32, 32, 32,
|
||||
29, 29, 29, 29, 29, 29, 29, 29,
|
||||
25, 25, 25, 25, 25, 25, 25, 25,
|
||||
21, 21, 21, 21, 21, 21, 21, 21,
|
||||
17, 17, 17, 17, 17, 17, 17, 17,
|
||||
14, 14, 14, 14, 14, 14, 14, 14,
|
||||
13, 13, 13, 13, 13, 13, 13, 13
|
||||
};
|
||||
static const unsigned char g_ref[64] = {
|
||||
53, 53, 53, 53, 53, 53, 53, 53,
|
||||
52, 52, 52, 52, 52, 52, 52, 52,
|
||||
49, 49, 49, 49, 49, 49, 49, 49,
|
||||
45, 45, 45, 45, 45, 45, 45, 45,
|
||||
41, 41, 41, 41, 41, 41, 41, 41,
|
||||
37, 37, 37, 37, 37, 37, 37, 37,
|
||||
34, 34, 34, 34, 34, 34, 34, 34,
|
||||
33, 33, 33, 33, 33, 33, 33, 33
|
||||
};
|
||||
static const unsigned char b_ref[64] = {
|
||||
67, 67, 67, 67, 67, 67, 67, 67,
|
||||
66, 66, 66, 66, 66, 66, 66, 66,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
59, 59, 59, 59, 59, 59, 59, 59,
|
||||
55, 55, 55, 55, 55, 55, 55, 55,
|
||||
51, 51, 51, 51, 51, 51, 51, 51,
|
||||
48, 48, 48, 48, 48, 48, 48, 48,
|
||||
47, 47, 47, 47, 47, 47, 47, 47
|
||||
};
|
||||
|
||||
return (0 == memcmp (pInfo.m_pMCUBufR, r_ref, 64))
|
||||
&& (0 == memcmp (pInfo.m_pMCUBufG, g_ref, 64))
|
||||
&& (0 == memcmp (pInfo.m_pMCUBufB, b_ref, 64));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rpt; i++)
|
||||
{
|
||||
unsigned char status;
|
||||
|
||||
jpeg_off = 0;
|
||||
|
||||
status = pjpeg_decode_init (&pInfo, pjpeg_need_bytes_callback, 0, 0);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
status = pjpeg_decode_mcu ();
|
||||
|
||||
if (status == PJPG_NO_MORE_BLOCKS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
181
benchies/embench/benchemarks/primecount/primecount.c
Normal file
181
benchies/embench/benchemarks/primecount/primecount.c
Normal file
|
@ -0,0 +1,181 @@
|
|||
/* This version, copyright (C) 2014-2021 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor Paolo Savini <paolo.savini@embecosm.com>
|
||||
|
||||
This file is part of Embench.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
The original version by Bruce Hoult <bruce@hoult.org> can be found here:
|
||||
|
||||
http://hoult.org/primes.txt
|
||||
|
||||
and was released under the following license, disclaimers, and copyright:
|
||||
|
||||
Copyright 2016-2021 Bruce hoult bruce@hoult.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Program to count primes. I wanted something that could run in 16 KB but took enough
|
||||
time to measure on a modern x86 and is not susceptible to optimizer tricks.
|
||||
Code size is for just the countPrimes() function with gcc -O.
|
||||
|
||||
Original x86&ARM data 2016, received user contributions 2019&2020 from eevblog members.
|
||||
|
||||
WARNING: These results have not been calculated with the Embench infrastructure.
|
||||
The value of the parameter SZ and the methodolgy to calculate size and execution
|
||||
time are different in Embench, therefore these numbers aren't suitable for a direct
|
||||
comparison with the Embench results for the same architectures.
|
||||
|
||||
SZ = 1000 -> 3713160 primes, all primes up to 7919^2 = 62710561
|
||||
2.735 sec i7 8650U @ 4.2 GHz 242 bytes 11.5 billion clocks
|
||||
2.795 sec Mac Mini M1 @ 3.2 GHz 212 bytes 8.9 billion clocks
|
||||
2.810 sec Mac Mini M1 arm64 Ubuntu in VM 280 bytes 9.0 billion clocks
|
||||
2.872 sec i7 6700K @ 4.2 GHz 240 bytes 12.1 billion clocks
|
||||
2.925 sec Mac Mini M1 @ 3.2 GHz Rosetta 208 bytes 9.4 billion clocks
|
||||
3.448 sec Ryzen 5 4500U @ 4.0 GHz WSL2 242 bytes 13.8 billion clocks
|
||||
3.505 sec Xeon Plat 8151 @ 4.0 GHz (AWS z1d) 244 bytes 14.0 billion clocks
|
||||
3.515 sec Threadripper 2990WX @ 4.2 GHz 242 bytes 14.8 billion clocks
|
||||
3.836 sec i7 4700MQ @ 3.4 GHz 258 bytes 13.0 billion clocks
|
||||
3.972 sec i7 8650U @ 4.2 GHz webasm 277 bytes 16.7 billion clocks
|
||||
4.868 sec i7 3770 @ 3.9 GHz 240 bytes 19.0 billion clocks
|
||||
6.377 sec AWS C6g graviton2 A64 @ 2.5 GHz 276 bytes 15.9 billion clocks
|
||||
6.757 sec M1 Mini, qemu-riscv64 in UbuntuVM 216 bytes 23.0 billion clocks
|
||||
8.538 sec NXP LX2160A A72 @ 2 GHz 260 bytes 17.1 billion clocks
|
||||
9.692 sec RISC-V Fedora in qemu in VM on M1 208 bytes 31.0 billion clocks
|
||||
9.740 sec i7 6700K qemu-riscv32 178 bytes 40.9 billion clocks
|
||||
10.046 sec i7 8650U @ 4.2 GHz qemu-riscv32 190 bytes 42.2 billion clocks
|
||||
11.190 sec Pi4 Cortex A72 @ 1.5 GHz T32 232 bytes 16.8 billion clocks
|
||||
11.445 sec Odroid XU4 A15 @ 2 GHz T32 204 bytes 22.9 billion clocks
|
||||
12.115 sec Pi4 Cortex A72 @ 1.5 GHz A64 300 bytes 18.2 billion clocks
|
||||
12.605 sec Pi4 Cortex A72 @ 1.5 GHz A32 300 bytes 18.9 billion clocks
|
||||
13.721 sec RISC-V Fedora in qemu on 2990wx 208 bytes 57.6 billion clocks
|
||||
14.111 sec Beagle-X15 A15 @ 1.5 GHz A32 348 bytes 21.2 billion clocks
|
||||
14.341 sec Beagle-X15 A15 @ 1.5 GHz T32 224 bytes 21.5 billion clocks
|
||||
19.500 sec Odroid C2 A53 @ 1.536 GHz A64 276 bytes 30.0 billion clocks
|
||||
22.719 sec BeagleV Starlight RISCV U74 @ 1.0 GHz 208 bytes 22.7 billion clocks
|
||||
23.940 sec Odroid C2 A53 @ 1.536 GHz T32 204 bytes 36.8 billion clocks
|
||||
24.636 sec i7 6700K qemu-arm 204 bytes 103.5 billion clocks
|
||||
25.060 sec i7 6700K qemu-aarch64 276 bytes 105.3 billion clocks
|
||||
27.196 sec Teensy 4.0 Cortex M7 @ 960 MHz 228 bytes 26.1 billion clocks
|
||||
27.480 sec HiFive Unleashed RISCV U54 @ 1.45 GHz 228 bytes 39.8 billion clocks
|
||||
30.420 sec Pi3 Cortex A53 @ 1.2 GHz T32 204 bytes 36.5 billion clocks
|
||||
36.652 sec Allwinner N1 C906 RV64 @ 1.008 GHz 224 bytes 36.9 billion clocks
|
||||
39.840 sec HiFive Unl RISCV U54 @ 1.0 GHz 228 bytes 39.8 billion clocks
|
||||
43.516 sec Teensy 4.0 Cortex M7 @ 600 MHz 228 bytes 26.1 billion clocks
|
||||
47.910 sec Pi2 Cortex A7 @ 900 MHz T32 204 bytes 42.1 billion clocks
|
||||
48.206 sec Zynq-7010 Cortex A9 @ 650MHz 248 bytes 31.3 billion clocks
|
||||
112.163 sec HiFive1 RISCV E31 @ 320 MHz 178 bytes 35.9 billion clocks
|
||||
261.068 sec esp32/Arduino @ 240 MHz ??? bytes 62.7 billion clocks
|
||||
294.749 sec chipKIT Pro MZ pic32 @ 200 MHz ??? bytes 58.9 billion clocks
|
||||
306.988 sec esp8266 @ 160 MHz ??? bytes 49.1 billion clocks
|
||||
309.251 sec BlackPill Cortex M4F @ 168 MHz 228 bytes 52.0 billion clocks
|
||||
927.547 sec BluePill Cortex M3 @ 72 MHz 228 bytes 66.8 billion clocks
|
||||
13449.513 sec AVR ATmega2560 @ 20 MHz 318 bytes 269.0 billion clocks */
|
||||
|
||||
#include "../../src/support.h"
|
||||
|
||||
#define LOCAL_SCALE_FACTOR 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* We reduced the quantity of prime numbers to find in order to have an
|
||||
* execution time as close as possible to 4000 ms for the baseline */
|
||||
#define SZ 42
|
||||
/* Number of prime numbers we expect to find */
|
||||
#define NPRIMES 3512
|
||||
|
||||
int32_t countPrimes(){
|
||||
int32_t primes[SZ], sieve[SZ];
|
||||
int nSieve = 0;
|
||||
primes[0] = 2; sieve[0] = 4; ++nSieve;
|
||||
int32_t nPrimes = 1, trial = 3, sqr=2;
|
||||
while (1){
|
||||
while (sqr*sqr <= trial) ++sqr;
|
||||
--sqr;
|
||||
for (int i=0; i<nSieve; ++i){
|
||||
if (primes[i] > sqr) goto found_prime;
|
||||
while (sieve[i] < trial) sieve[i] += primes[i];
|
||||
if (sieve[i] == trial) goto try_next;
|
||||
}
|
||||
break;
|
||||
found_prime:
|
||||
if (nSieve < SZ){
|
||||
primes[nSieve] = trial;
|
||||
sieve[nSieve] = trial*trial;
|
||||
++nSieve;
|
||||
}
|
||||
++nPrimes;
|
||||
try_next:
|
||||
trial+=1;
|
||||
}
|
||||
return nPrimes;
|
||||
}
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
int i, r = 0;
|
||||
|
||||
for (i = 0; i < rpt; ++i)
|
||||
{
|
||||
r = countPrimes();
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int verify_benchmark (int result);
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
verify_benchmark (int r)
|
||||
{
|
||||
return NPRIMES == r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
65
benchies/embench/benchemarks/qrduino/ecctable.h
Normal file
65
benchies/embench/benchemarks/qrduino/ecctable.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* BEEBS qrduino benchmark
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
Original code from: https://github.com/tz1/qrduino */
|
||||
|
||||
static const unsigned char eccblocks[] PROGMEM = {
|
||||
1, 0, 19, 7, 1, 0, 16, 10, 1, 0, 13, 13, 1, 0, 9, 17,
|
||||
1, 0, 34, 10, 1, 0, 28, 16, 1, 0, 22, 22, 1, 0, 16, 28,
|
||||
1, 0, 55, 15, 1, 0, 44, 26, 2, 0, 17, 18, 2, 0, 13, 22,
|
||||
1, 0, 80, 20, 2, 0, 32, 18, 2, 0, 24, 26, 4, 0, 9, 16,
|
||||
1, 0, 108, 26, 2, 0, 43, 24, 2, 2, 15, 18, 2, 2, 11, 22,
|
||||
2, 0, 68, 18, 4, 0, 27, 16, 4, 0, 19, 24, 4, 0, 15, 28,
|
||||
2, 0, 78, 20, 4, 0, 31, 18, 2, 4, 14, 18, 4, 1, 13, 26,
|
||||
2, 0, 97, 24, 2, 2, 38, 22, 4, 2, 18, 22, 4, 2, 14, 26,
|
||||
2, 0, 116, 30, 3, 2, 36, 22, 4, 4, 16, 20, 4, 4, 12, 24,
|
||||
2, 2, 68, 18, 4, 1, 43, 26, 6, 2, 19, 24, 6, 2, 15, 28,
|
||||
4, 0, 81, 20, 1, 4, 50, 30, 4, 4, 22, 28, 3, 8, 12, 24,
|
||||
2, 2, 92, 24, 6, 2, 36, 22, 4, 6, 20, 26, 7, 4, 14, 28,
|
||||
4, 0, 107, 26, 8, 1, 37, 22, 8, 4, 20, 24, 12, 4, 11, 22,
|
||||
3, 1, 115, 30, 4, 5, 40, 24, 11, 5, 16, 20, 11, 5, 12, 24,
|
||||
5, 1, 87, 22, 5, 5, 41, 24, 5, 7, 24, 30, 11, 7, 12, 24,
|
||||
5, 1, 98, 24, 7, 3, 45, 28, 15, 2, 19, 24, 3, 13, 15, 30,
|
||||
1, 5, 107, 28, 10, 1, 46, 28, 1, 15, 22, 28, 2, 17, 14, 28,
|
||||
5, 1, 120, 30, 9, 4, 43, 26, 17, 1, 22, 28, 2, 19, 14, 28,
|
||||
3, 4, 113, 28, 3, 11, 44, 26, 17, 4, 21, 26, 9, 16, 13, 26,
|
||||
3, 5, 107, 28, 3, 13, 41, 26, 15, 5, 24, 30, 15, 10, 15, 28,
|
||||
4, 4, 116, 28, 17, 0, 42, 26, 17, 6, 22, 28, 19, 6, 16, 30,
|
||||
2, 7, 111, 28, 17, 0, 46, 28, 7, 16, 24, 30, 34, 0, 13, 24,
|
||||
4, 5, 121, 30, 4, 14, 47, 28, 11, 14, 24, 30, 16, 14, 15, 30,
|
||||
6, 4, 117, 30, 6, 14, 45, 28, 11, 16, 24, 30, 30, 2, 16, 30,
|
||||
8, 4, 106, 26, 8, 13, 47, 28, 7, 22, 24, 30, 22, 13, 15, 30,
|
||||
10, 2, 114, 28, 19, 4, 46, 28, 28, 6, 22, 28, 33, 4, 16, 30,
|
||||
8, 4, 122, 30, 22, 3, 45, 28, 8, 26, 23, 30, 12, 28, 15, 30,
|
||||
3, 10, 117, 30, 3, 23, 45, 28, 4, 31, 24, 30, 11, 31, 15, 30,
|
||||
7, 7, 116, 30, 21, 7, 45, 28, 1, 37, 23, 30, 19, 26, 15, 30,
|
||||
5, 10, 115, 30, 19, 10, 47, 28, 15, 25, 24, 30, 23, 25, 15, 30,
|
||||
13, 3, 115, 30, 2, 29, 46, 28, 42, 1, 24, 30, 23, 28, 15, 30,
|
||||
17, 0, 115, 30, 10, 23, 46, 28, 10, 35, 24, 30, 19, 35, 15, 30,
|
||||
17, 1, 115, 30, 14, 21, 46, 28, 29, 19, 24, 30, 11, 46, 15, 30,
|
||||
13, 6, 115, 30, 14, 23, 46, 28, 44, 7, 24, 30, 59, 1, 16, 30,
|
||||
12, 7, 121, 30, 12, 26, 47, 28, 39, 14, 24, 30, 22, 41, 15, 30,
|
||||
6, 14, 121, 30, 6, 34, 47, 28, 46, 10, 24, 30, 2, 64, 15, 30,
|
||||
17, 4, 122, 30, 29, 14, 46, 28, 49, 10, 24, 30, 24, 46, 15, 30,
|
||||
4, 18, 122, 30, 13, 32, 46, 28, 48, 14, 24, 30, 42, 32, 15, 30,
|
||||
20, 4, 117, 30, 40, 7, 47, 28, 43, 22, 24, 30, 10, 67, 15, 30,
|
||||
19, 6, 118, 30, 18, 31, 47, 28, 34, 34, 24, 30, 20, 61, 15, 30,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
26
benchies/embench/benchemarks/qrduino/qrbits.h
Normal file
26
benchies/embench/benchemarks/qrduino/qrbits.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* BEEBS qrduino benchmark
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
Original code from: https://github.com/tz1/qrduino */
|
||||
|
||||
#define QRBIT(x,y) ( ( qrframe[((x)>>3) + (y) * WDB] >> (7-((x) & 7 ))) & 1 )
|
||||
#define SETQRBIT(x,y) qrframe[((x)>>3) + (y) * WDB] |= 0x80 >> ((x) & 7)
|
||||
#define TOGQRBIT(x,y) qrframe[((x)>>3) + (y) * WDB] ^= 0x80 >> ((x) & 7)
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
645
benchies/embench/benchemarks/qrduino/qrencode.c
Normal file
645
benchies/embench/benchemarks/qrduino/qrencode.c
Normal file
|
@ -0,0 +1,645 @@
|
|||
/* BEEBS qrduino benchmark
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
Original code from: https://github.com/tz1/qrduino */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "qrencode.h"
|
||||
|
||||
extern unsigned char neccblk1;
|
||||
extern unsigned char neccblk2;
|
||||
extern unsigned char datablkw;
|
||||
extern unsigned char eccblkwid;
|
||||
extern unsigned char VERSION;
|
||||
extern unsigned char ECCLEVEL;
|
||||
extern unsigned char WD, WDB;
|
||||
#ifndef USEPRECALC
|
||||
// These are malloced by initframe
|
||||
extern unsigned char *rlens;
|
||||
extern unsigned char *framebase;
|
||||
extern unsigned char *framask;
|
||||
#else
|
||||
extern unsigned char rlens[];
|
||||
extern unsigned char framebase[] PROGMEM;
|
||||
extern unsigned char framask[] PROGMEM;
|
||||
#endif
|
||||
|
||||
//========================================================================
|
||||
// Reed Solomon error correction
|
||||
static unsigned
|
||||
modnn (unsigned x)
|
||||
{
|
||||
while (x >= 255)
|
||||
{
|
||||
x -= 255;
|
||||
x = (x >> 8) + (x & 255);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
#ifndef RTGENEXPLOG
|
||||
static const unsigned char g0log[256] PROGMEM = {
|
||||
0xff, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee,
|
||||
0x1b, 0x68, 0xc7, 0x4b,
|
||||
0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, 0x1c, 0xc1, 0x69, 0xf8,
|
||||
0xc8, 0x08, 0x4c, 0x71,
|
||||
0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, 0x35, 0x93, 0x8e, 0xda,
|
||||
0xf0, 0x12, 0x82, 0x45,
|
||||
0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 0xc9, 0x9a, 0x09, 0x78,
|
||||
0x4d, 0xe4, 0x72, 0xa6,
|
||||
0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, 0xe2, 0x98, 0x25, 0xb3,
|
||||
0x10, 0x91, 0x22, 0x88,
|
||||
0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, 0xf1, 0xd2, 0x13, 0x5c,
|
||||
0x83, 0x38, 0x46, 0x40,
|
||||
0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, 0x6b, 0x3a, 0x28, 0x54,
|
||||
0xfa, 0x85, 0xba, 0x3d,
|
||||
0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, 0x4e, 0xd4, 0xe5, 0xac,
|
||||
0x73, 0xf3, 0xa7, 0x57,
|
||||
0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, 0x67, 0x4a, 0xde, 0xed,
|
||||
0x31, 0xc5, 0xfe, 0x18,
|
||||
0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, 0x11, 0x44, 0x92, 0xd9,
|
||||
0x23, 0x20, 0x89, 0x2e,
|
||||
0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, 0x90, 0x87, 0x97, 0xb2,
|
||||
0xdc, 0xfc, 0xbe, 0x61,
|
||||
0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, 0x84, 0x3c, 0x39, 0x53,
|
||||
0x47, 0x6d, 0x41, 0xa2,
|
||||
0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, 0xc4, 0x17, 0x49, 0xec,
|
||||
0x7f, 0x0c, 0x6f, 0xf6,
|
||||
0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, 0xfb, 0x60, 0x86, 0xb1,
|
||||
0xbb, 0xcc, 0x3e, 0x5a,
|
||||
0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, 0x0b, 0xf5, 0x16, 0xeb,
|
||||
0x7a, 0x75, 0x2c, 0xd7,
|
||||
0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, 0xf4, 0xea,
|
||||
0xa8, 0x50, 0x58, 0xaf,
|
||||
};
|
||||
|
||||
static const unsigned char g0exp[256] PROGMEM = {
|
||||
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8,
|
||||
0xcd, 0x87, 0x13, 0x26,
|
||||
0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x03, 0x06, 0x0c,
|
||||
0x18, 0x30, 0x60, 0xc0,
|
||||
0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77,
|
||||
0xee, 0xc1, 0x9f, 0x23,
|
||||
0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2,
|
||||
0xb9, 0x6f, 0xde, 0xa1,
|
||||
0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0x0f,
|
||||
0x1e, 0x3c, 0x78, 0xf0,
|
||||
0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3,
|
||||
0x5b, 0xb6, 0x71, 0xe2,
|
||||
0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d, 0x1a, 0x34, 0x68,
|
||||
0xd0, 0xbd, 0x67, 0xce,
|
||||
0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5,
|
||||
0x97, 0x33, 0x66, 0xcc,
|
||||
0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42,
|
||||
0x84, 0x15, 0x2a, 0x54,
|
||||
0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72,
|
||||
0xe4, 0xd5, 0xb7, 0x73,
|
||||
0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3,
|
||||
0x7b, 0xf6, 0xf1, 0xff,
|
||||
0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc,
|
||||
0xa5, 0x57, 0xae, 0x41,
|
||||
0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0,
|
||||
0xdd, 0xa7, 0x53, 0xa6,
|
||||
0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56,
|
||||
0xac, 0x45, 0x8a, 0x09,
|
||||
0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb,
|
||||
0xcb, 0x8b, 0x0b, 0x16,
|
||||
0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8,
|
||||
0xad, 0x47, 0x8e, 0x00,
|
||||
};
|
||||
|
||||
#define glog(x) __LPM(&g0log[x])
|
||||
#define gexp(x) __LPM(&g0exp[x])
|
||||
|
||||
#else // generate the log and exp tables - some CPU, much less flash, +512 bytes ram which can be shared
|
||||
|
||||
unsigned char g0log[256], g0exp[256];
|
||||
#define glog(x) (g0log[x])
|
||||
#define gexp(x) (g0exp[x])
|
||||
static void
|
||||
gentables ()
|
||||
{
|
||||
#define GFPOLY (0x11d)
|
||||
unsigned char i, j;
|
||||
g0log[0] = 255;
|
||||
g0exp[255] = 0;
|
||||
j = 1;
|
||||
for (i = 0; i < 255; i++)
|
||||
{
|
||||
g0log[j] = i;
|
||||
g0exp[i] = j;
|
||||
j <<= 1;
|
||||
if (j & 256)
|
||||
j ^= GFPOLY;
|
||||
j &= 255;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
initrspoly (unsigned char eclen, unsigned char *genpoly)
|
||||
{
|
||||
unsigned char i, j;
|
||||
|
||||
#ifdef RTGENEXPLOG
|
||||
gentables ();
|
||||
#endif
|
||||
|
||||
genpoly[0] = 1;
|
||||
for (i = 0; i < eclen; i++)
|
||||
{
|
||||
genpoly[i + 1] = 1;
|
||||
for (j = i; j > 0; j--)
|
||||
genpoly[j] = genpoly[j]
|
||||
? genpoly[j -
|
||||
1] ^ gexp (modnn (glog (genpoly[j]) + i)) : genpoly[j -
|
||||
1];
|
||||
genpoly[0] = gexp (modnn (glog (genpoly[0]) + i));
|
||||
}
|
||||
for (i = 0; i <= eclen; i++)
|
||||
genpoly[i] = glog (genpoly[i]); // use logs for genpoly[]
|
||||
}
|
||||
|
||||
static void
|
||||
appendrs (unsigned char *data, unsigned char dlen,
|
||||
unsigned char *ecbuf, unsigned char eclen, unsigned char *genpoly)
|
||||
{
|
||||
unsigned char i, j, fb;
|
||||
|
||||
memset (ecbuf, 0, eclen);
|
||||
for (i = 0; i < dlen; i++)
|
||||
{
|
||||
fb = glog (data[i] ^ ecbuf[0]);
|
||||
if (fb != 255) /* fb term is non-zero */
|
||||
for (j = 1; j < eclen; j++)
|
||||
ecbuf[j - 1] = ecbuf[j] ^ gexp (modnn (fb + genpoly[eclen - j]));
|
||||
else
|
||||
memmove (ecbuf, ecbuf + 1, eclen - 1);
|
||||
ecbuf[eclen - 1] = fb == 255 ? 0 : gexp (modnn (fb + genpoly[0]));
|
||||
}
|
||||
}
|
||||
|
||||
//========================================================================
|
||||
// 8 bit data to QR-coded 8 bit data
|
||||
static void
|
||||
stringtoqr (void)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned size, max;
|
||||
size = strlen ((char *) strinbuf);
|
||||
|
||||
max = datablkw * (neccblk1 + neccblk2) + neccblk2;
|
||||
if (size >= max - 2)
|
||||
{
|
||||
size = max - 2;
|
||||
if (VERSION > 9)
|
||||
size--;
|
||||
}
|
||||
|
||||
i = size;
|
||||
if (VERSION > 9)
|
||||
{
|
||||
strinbuf[i + 2] = 0;
|
||||
while (i--)
|
||||
{
|
||||
strinbuf[i + 3] |= strinbuf[i] << 4;
|
||||
strinbuf[i + 2] = strinbuf[i] >> 4;
|
||||
}
|
||||
strinbuf[2] |= size << 4;
|
||||
strinbuf[1] = size >> 4;
|
||||
strinbuf[0] = 0x40 | (size >> 12);
|
||||
}
|
||||
else
|
||||
{
|
||||
strinbuf[i + 1] = 0;
|
||||
while (i--)
|
||||
{
|
||||
strinbuf[i + 2] |= strinbuf[i] << 4;
|
||||
strinbuf[i + 1] = strinbuf[i] >> 4;
|
||||
}
|
||||
strinbuf[1] |= size << 4;
|
||||
strinbuf[0] = 0x40 | (size >> 4);
|
||||
}
|
||||
i = size + 3 - (VERSION < 10);
|
||||
while (i < max)
|
||||
{
|
||||
strinbuf[i++] = 0xec;
|
||||
// buffer has room if (i == max) break;
|
||||
strinbuf[i++] = 0x11;
|
||||
}
|
||||
|
||||
// calculate and append ECC
|
||||
unsigned char *ecc = &strinbuf[max];
|
||||
unsigned char *dat = strinbuf;
|
||||
initrspoly (eccblkwid, qrframe);
|
||||
|
||||
for (i = 0; i < neccblk1; i++)
|
||||
{
|
||||
appendrs (dat, datablkw, ecc, eccblkwid, qrframe);
|
||||
dat += datablkw;
|
||||
ecc += eccblkwid;
|
||||
}
|
||||
for (i = 0; i < neccblk2; i++)
|
||||
{
|
||||
appendrs (dat, datablkw + 1, ecc, eccblkwid, qrframe);
|
||||
dat += datablkw + 1;
|
||||
ecc += eccblkwid;
|
||||
}
|
||||
unsigned j;
|
||||
dat = qrframe;
|
||||
for (i = 0; i < datablkw; i++)
|
||||
{
|
||||
for (j = 0; j < neccblk1; j++)
|
||||
*dat++ = strinbuf[i + j * datablkw];
|
||||
for (j = 0; j < neccblk2; j++)
|
||||
*dat++ = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))];
|
||||
}
|
||||
for (j = 0; j < neccblk2; j++)
|
||||
*dat++ = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))];
|
||||
for (i = 0; i < eccblkwid; i++)
|
||||
for (j = 0; j < neccblk1 + neccblk2; j++)
|
||||
*dat++ = strinbuf[max + i + j * eccblkwid];
|
||||
memcpy (strinbuf, qrframe, max + eccblkwid * (neccblk1 + neccblk2));
|
||||
|
||||
}
|
||||
|
||||
//========================================================================
|
||||
// Frame data insert following the path rules
|
||||
static unsigned char
|
||||
ismasked (unsigned char x, unsigned char y)
|
||||
{
|
||||
unsigned bt;
|
||||
if (x > y)
|
||||
{
|
||||
bt = x;
|
||||
x = y;
|
||||
y = bt;
|
||||
}
|
||||
bt = y;
|
||||
bt += y * y;
|
||||
#if 0
|
||||
// bt += y*y;
|
||||
unsigned s = 1;
|
||||
while (y--)
|
||||
{
|
||||
bt += s;
|
||||
s += 2;
|
||||
}
|
||||
#endif
|
||||
bt >>= 1;
|
||||
bt += x;
|
||||
return (__LPM (&framask[bt >> 3]) >> (7 - (bt & 7))) & 1;
|
||||
}
|
||||
|
||||
static void
|
||||
fillframe (void)
|
||||
{
|
||||
int i;
|
||||
unsigned char d, j;
|
||||
unsigned char x, y, ffdecy, ffgohv;
|
||||
|
||||
memcpy_P (qrframe, framebase, WDB * WD);
|
||||
x = y = WD - 1;
|
||||
ffdecy = 1; // up, minus
|
||||
ffgohv = 1;
|
||||
|
||||
/* inteleaved data and ecc codes */
|
||||
for (i = 0; i < ((datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2);
|
||||
i++)
|
||||
{
|
||||
d = strinbuf[i];
|
||||
for (j = 0; j < 8; j++, d <<= 1)
|
||||
{
|
||||
if (0x80 & d)
|
||||
SETQRBIT (x, y);
|
||||
do
|
||||
{ // find next fill position
|
||||
if (ffgohv)
|
||||
x--;
|
||||
else
|
||||
{
|
||||
x++;
|
||||
if (ffdecy)
|
||||
{
|
||||
if (y != 0)
|
||||
y--;
|
||||
else
|
||||
{
|
||||
x -= 2;
|
||||
ffdecy = !ffdecy;
|
||||
if (x == 6)
|
||||
{
|
||||
x--;
|
||||
y = 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y != WD - 1)
|
||||
y++;
|
||||
else
|
||||
{
|
||||
x -= 2;
|
||||
ffdecy = !ffdecy;
|
||||
if (x == 6)
|
||||
{
|
||||
x--;
|
||||
y -= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ffgohv = !ffgohv;
|
||||
}
|
||||
while (ismasked (x, y));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//========================================================================
|
||||
// Masking
|
||||
static void
|
||||
applymask (unsigned char m)
|
||||
{
|
||||
unsigned char x, y, r3x, r3y;
|
||||
|
||||
switch (m)
|
||||
{
|
||||
case 0:
|
||||
for (y = 0; y < WD; y++)
|
||||
for (x = 0; x < WD; x++)
|
||||
if (!((x + y) & 1) && !ismasked (x, y))
|
||||
TOGQRBIT (x, y);
|
||||
break;
|
||||
case 1:
|
||||
for (y = 0; y < WD; y++)
|
||||
for (x = 0; x < WD; x++)
|
||||
if (!(y & 1) && !ismasked (x, y))
|
||||
TOGQRBIT (x, y);
|
||||
break;
|
||||
case 2:
|
||||
for (y = 0; y < WD; y++)
|
||||
for (r3x = 0, x = 0; x < WD; x++, r3x++)
|
||||
{
|
||||
if (r3x == 3)
|
||||
r3x = 0;
|
||||
if (!r3x && !ismasked (x, y))
|
||||
TOGQRBIT (x, y);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (r3y = 0, y = 0; y < WD; y++, r3y++)
|
||||
{
|
||||
if (r3y == 3)
|
||||
r3y = 0;
|
||||
for (r3x = r3y, x = 0; x < WD; x++, r3x++)
|
||||
{
|
||||
if (r3x == 3)
|
||||
r3x = 0;
|
||||
if (!r3x && !ismasked (x, y))
|
||||
TOGQRBIT (x, y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (y = 0; y < WD; y++)
|
||||
for (r3x = 0, r3y = ((y >> 1) & 1), x = 0; x < WD; x++, r3x++)
|
||||
{
|
||||
if (r3x == 3)
|
||||
{
|
||||
r3x = 0;
|
||||
r3y = !r3y;
|
||||
}
|
||||
if (!r3y && !ismasked (x, y))
|
||||
TOGQRBIT (x, y);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
for (r3y = 0, y = 0; y < WD; y++, r3y++)
|
||||
{
|
||||
if (r3y == 3)
|
||||
r3y = 0;
|
||||
for (r3x = 0, x = 0; x < WD; x++, r3x++)
|
||||
{
|
||||
if (r3x == 3)
|
||||
r3x = 0;
|
||||
if (!((x & y & 1) + !(!r3x | !r3y)) && !ismasked (x, y))
|
||||
TOGQRBIT (x, y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
for (r3y = 0, y = 0; y < WD; y++, r3y++)
|
||||
{
|
||||
if (r3y == 3)
|
||||
r3y = 0;
|
||||
for (r3x = 0, x = 0; x < WD; x++, r3x++)
|
||||
{
|
||||
if (r3x == 3)
|
||||
r3x = 0;
|
||||
if (!(((x & y & 1) + (r3x && (r3x == r3y))) & 1)
|
||||
&& !ismasked (x, y))
|
||||
TOGQRBIT (x, y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
for (r3y = 0, y = 0; y < WD; y++, r3y++)
|
||||
{
|
||||
if (r3y == 3)
|
||||
r3y = 0;
|
||||
for (r3x = 0, x = 0; x < WD; x++, r3x++)
|
||||
{
|
||||
if (r3x == 3)
|
||||
r3x = 0;
|
||||
if (!(((r3x && (r3x == r3y)) + ((x + y) & 1)) & 1)
|
||||
&& !ismasked (x, y))
|
||||
TOGQRBIT (x, y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Badness coefficients.
|
||||
static const unsigned char N1 = 3;
|
||||
static const unsigned char N2 = 3;
|
||||
static const unsigned char N3 = 40;
|
||||
static const unsigned char N4 = 10;
|
||||
|
||||
static unsigned
|
||||
badruns (unsigned char length)
|
||||
{
|
||||
unsigned char i;
|
||||
unsigned runsbad = 0;
|
||||
for (i = 0; i <= length; i++)
|
||||
if (rlens[i] >= 5)
|
||||
runsbad += N1 + rlens[i] - 5;
|
||||
// BwBBBwB
|
||||
for (i = 3; i < length - 1; i += 2)
|
||||
if (rlens[i - 2] == rlens[i + 2]
|
||||
&& rlens[i + 2] == rlens[i - 1]
|
||||
&& rlens[i - 1] == rlens[i + 1] && rlens[i - 1] * 3 == rlens[i]
|
||||
// white around the black pattern? Not part of spec
|
||||
&& (rlens[i - 3] == 0 // beginning
|
||||
|| i + 3 > length // end
|
||||
|| rlens[i - 3] * 3 >= rlens[i] * 4
|
||||
|| rlens[i + 3] * 3 >= rlens[i] * 4))
|
||||
runsbad += N3;
|
||||
return runsbad;
|
||||
}
|
||||
|
||||
static int
|
||||
badcheck ()
|
||||
{
|
||||
unsigned char x, y, h, b, b1;
|
||||
unsigned thisbad = 0;
|
||||
int bw = 0;
|
||||
|
||||
// blocks of same color.
|
||||
for (y = 0; y < WD - 1; y++)
|
||||
for (x = 0; x < WD - 1; x++)
|
||||
if ((QRBIT (x, y) && QRBIT (x + 1, y) && QRBIT (x, y + 1) && QRBIT (x + 1, y + 1)) // all black
|
||||
|| !(QRBIT (x, y) || QRBIT (x + 1, y) || QRBIT (x, y + 1) || QRBIT (x + 1, y + 1))) // all white
|
||||
thisbad += N2;
|
||||
|
||||
// X runs
|
||||
for (y = 0; y < WD; y++)
|
||||
{
|
||||
rlens[0] = 0;
|
||||
for (h = b = x = 0; x < WD; x++)
|
||||
{
|
||||
if ((b1 = QRBIT (x, y)) == b)
|
||||
rlens[h]++;
|
||||
else
|
||||
rlens[++h] = 1;
|
||||
b = b1;
|
||||
bw += b ? 1 : -1;
|
||||
}
|
||||
thisbad += badruns (h);
|
||||
}
|
||||
|
||||
// black/white imbalance
|
||||
if (bw < 0)
|
||||
bw = -bw;
|
||||
|
||||
unsigned long big = bw;
|
||||
unsigned count = 0;
|
||||
big += big << 2;
|
||||
big <<= 1;
|
||||
while (big > WD * WD)
|
||||
big -= WD * WD, count++;
|
||||
thisbad += count * N4;
|
||||
|
||||
// Y runs
|
||||
for (x = 0; x < WD; x++)
|
||||
{
|
||||
rlens[0] = 0;
|
||||
for (h = b = y = 0; y < WD; y++)
|
||||
{
|
||||
if ((b1 = QRBIT (x, y)) == b)
|
||||
rlens[h]++;
|
||||
else
|
||||
rlens[++h] = 1;
|
||||
b = b1;
|
||||
}
|
||||
thisbad += badruns (h);
|
||||
}
|
||||
return thisbad;
|
||||
}
|
||||
|
||||
// final format bits with mask
|
||||
// level << 3 | mask
|
||||
static const unsigned fmtword[] PROGMEM = {
|
||||
0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976, //L
|
||||
0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0, //M
|
||||
0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed, //Q
|
||||
0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b, //H
|
||||
};
|
||||
|
||||
static void
|
||||
addfmt (unsigned char masknum)
|
||||
{
|
||||
unsigned fmtbits;
|
||||
unsigned char i, lvl = ECCLEVEL - 1;
|
||||
|
||||
fmtbits = pgm_read_word (&fmtword[masknum + (lvl << 3)]);
|
||||
// low byte
|
||||
for (i = 0; i < 8; i++, fmtbits >>= 1)
|
||||
if (fmtbits & 1)
|
||||
{
|
||||
SETQRBIT (WD - 1 - i, 8);
|
||||
if (i < 6)
|
||||
SETQRBIT (8, i);
|
||||
else
|
||||
SETQRBIT (8, i + 1);
|
||||
}
|
||||
// high byte
|
||||
for (i = 0; i < 7; i++, fmtbits >>= 1)
|
||||
if (fmtbits & 1)
|
||||
{
|
||||
SETQRBIT (8, WD - 7 + i);
|
||||
if (i)
|
||||
SETQRBIT (6 - i, 8);
|
||||
else
|
||||
SETQRBIT (7, 8);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
qrencode ()
|
||||
{
|
||||
unsigned mindem = 30000;
|
||||
unsigned char best = 0;
|
||||
unsigned char i;
|
||||
unsigned badness;
|
||||
|
||||
stringtoqr ();
|
||||
fillframe (); // Inisde loop to avoid having separate mask buffer
|
||||
memcpy (strinbuf, qrframe, WD * WDB);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
applymask (i); // returns black-white imbalance
|
||||
badness = badcheck ();
|
||||
#if 0 //ndef PUREBAD
|
||||
if (badness < WD * WD * 5 / 4)
|
||||
{ // good enough - masks grow in compute complexity
|
||||
best = i;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (badness < mindem)
|
||||
{
|
||||
mindem = badness;
|
||||
best = i;
|
||||
}
|
||||
if (best == 7)
|
||||
break; // don't increment i to avoid redoing mask
|
||||
memcpy (qrframe, strinbuf, WD * WDB); // reset filled frame
|
||||
}
|
||||
if (best != i) // redo best mask - none good enough, last wasn't best
|
||||
applymask (best);
|
||||
addfmt (best); // add in final format bytes
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
46
benchies/embench/benchemarks/qrduino/qrencode.h
Normal file
46
benchies/embench/benchemarks/qrduino/qrencode.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* BEEBS qrduino benchmark
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
Original code from: https://github.com/tz1/qrduino */
|
||||
|
||||
#define PROGMEM
|
||||
#define memcpy_P memcpy
|
||||
#define __LPM(x) *x
|
||||
#define pgm_read_word(x) *x
|
||||
|
||||
// malloc-ed by initframe, free manually
|
||||
extern unsigned char *strinbuf; // string iput buffer
|
||||
extern unsigned char *qrframe;
|
||||
// setup the base frame structure - can be reused
|
||||
void initframe (void);
|
||||
// free the basic frame malloced structures
|
||||
void freeframe (void);
|
||||
// these resturn maximum string size to send in
|
||||
unsigned initeccsize (unsigned char ecc, unsigned size);
|
||||
unsigned initecc (unsigned char level, unsigned char version);
|
||||
|
||||
extern unsigned char WD, WDB;
|
||||
#include "qrbits.h"
|
||||
|
||||
// strinbuf in, qrframe out
|
||||
void qrencode (void);
|
||||
|
||||
void freeecc ();
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
325
benchies/embench/benchemarks/qrduino/qrframe.c
Normal file
325
benchies/embench/benchemarks/qrduino/qrframe.c
Normal file
|
@ -0,0 +1,325 @@
|
|||
/* BEEBS qrduino benchmark
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
Original code from: https://github.com/tz1/qrduino */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Header for BEEBS library calls */
|
||||
|
||||
#include "beebsc.h"
|
||||
|
||||
#ifndef __AVR__
|
||||
#define PROGMEM
|
||||
#define memcpy_P memcpy
|
||||
#define __LPM(x) *x
|
||||
#define pgm_read_word(x) *x
|
||||
#else
|
||||
#include <avr/pgmspace.h>
|
||||
#endif
|
||||
|
||||
unsigned char *framebase;
|
||||
unsigned char *framask;
|
||||
unsigned char *rlens;
|
||||
unsigned char VERSION;
|
||||
unsigned char WD, WDB; // filled in from verison by initframe
|
||||
|
||||
#define QRBIT(x,y) ( ( framebase[((x)>>3) + (y) * WDB] >> (7-((x) & 7 ))) & 1 )
|
||||
#define SETQRBIT(x,y) framebase[((x)>>3) + (y) * WDB] |= 0x80 >> ((x) & 7)
|
||||
|
||||
static void
|
||||
setmask (unsigned char x, unsigned char y)
|
||||
{
|
||||
unsigned bt;
|
||||
if (x > y)
|
||||
{
|
||||
bt = x;
|
||||
x = y;
|
||||
y = bt;
|
||||
}
|
||||
// y*y = 1+3+5...
|
||||
bt = y;
|
||||
bt *= y;
|
||||
bt += y;
|
||||
bt >>= 1;
|
||||
bt += x;
|
||||
framask[bt >> 3] |= 0x80 >> (bt & 7);
|
||||
}
|
||||
|
||||
static void
|
||||
putfind ()
|
||||
{
|
||||
unsigned char j, i, k, t;
|
||||
for (t = 0; t < 3; t++)
|
||||
{
|
||||
k = 0;
|
||||
i = 0;
|
||||
if (t == 1)
|
||||
k = (WD - 7);
|
||||
if (t == 2)
|
||||
i = (WD - 7);
|
||||
SETQRBIT (i + 3, k + 3);
|
||||
for (j = 0; j < 6; j++)
|
||||
{
|
||||
SETQRBIT (i + j, k);
|
||||
SETQRBIT (i, k + j + 1);
|
||||
SETQRBIT (i + 6, k + j);
|
||||
SETQRBIT (i + j + 1, k + 6);
|
||||
}
|
||||
for (j = 1; j < 5; j++)
|
||||
{
|
||||
setmask (i + j, k + 1);
|
||||
setmask (i + 1, k + j + 1);
|
||||
setmask (i + 5, k + j);
|
||||
setmask (i + j + 1, k + 5);
|
||||
}
|
||||
for (j = 2; j < 4; j++)
|
||||
{
|
||||
SETQRBIT (i + j, k + 2);
|
||||
SETQRBIT (i + 2, k + j + 1);
|
||||
SETQRBIT (i + 4, k + j);
|
||||
SETQRBIT (i + j + 1, k + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
putalign (int x, int y)
|
||||
{
|
||||
int j;
|
||||
|
||||
SETQRBIT (x, y);
|
||||
for (j = -2; j < 2; j++)
|
||||
{
|
||||
SETQRBIT (x + j, y - 2);
|
||||
SETQRBIT (x - 2, y + j + 1);
|
||||
SETQRBIT (x + 2, y + j);
|
||||
SETQRBIT (x + j + 1, y + 2);
|
||||
}
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
setmask (x - 1, y + j);
|
||||
setmask (x + 1, y - j);
|
||||
setmask (x - j, y - 1);
|
||||
setmask (x + j, y + 1);
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char adelta[41] PROGMEM = {
|
||||
0, 11, 15, 19, 23, 27, 31, // force 1 pat
|
||||
16, 18, 20, 22, 24, 26, 28, 20, 22, 24, 24, 26, 28, 28, 22, 24, 24,
|
||||
26, 26, 28, 28, 24, 24, 26, 26, 26, 28, 28, 24, 26, 26, 26, 28, 28,
|
||||
};
|
||||
|
||||
static void
|
||||
doaligns (void)
|
||||
{
|
||||
unsigned char delta, x, y;
|
||||
if (VERSION < 2)
|
||||
return;
|
||||
delta = __LPM (&adelta[VERSION]);
|
||||
y = WD - 7;
|
||||
for (;;)
|
||||
{
|
||||
x = WD - 7;
|
||||
while (x > delta - 3U)
|
||||
{
|
||||
putalign (x, y);
|
||||
if (x < delta)
|
||||
break;
|
||||
x -= delta;
|
||||
}
|
||||
if (y <= delta + 9U)
|
||||
break;
|
||||
y -= delta;
|
||||
putalign (6, y);
|
||||
putalign (y, 6);
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned vpat[] PROGMEM = {
|
||||
0xc94, 0x5bc, 0xa99, 0x4d3, 0xbf6, 0x762, 0x847, 0x60d,
|
||||
0x928, 0xb78, 0x45d, 0xa17, 0x532, 0x9a6, 0x683, 0x8c9,
|
||||
0x7ec, 0xec4, 0x1e1, 0xfab, 0x08e, 0xc1a, 0x33f, 0xd75,
|
||||
0x250, 0x9d5, 0x6f0, 0x8ba, 0x79f, 0xb0b, 0x42e, 0xa64,
|
||||
0x541, 0xc69
|
||||
};
|
||||
|
||||
static void
|
||||
putvpat (void)
|
||||
{
|
||||
unsigned char vers = VERSION;
|
||||
unsigned char x, y, bc;
|
||||
unsigned verinfo;
|
||||
if (vers < 7)
|
||||
return;
|
||||
verinfo = pgm_read_word (&vpat[vers - 7]);
|
||||
|
||||
bc = 17;
|
||||
for (x = 0; x < 6; x++)
|
||||
for (y = 0; y < 3; y++, bc--)
|
||||
if (1 & (bc > 11 ? (unsigned) vers >> (bc - 12) : verinfo >> bc))
|
||||
{
|
||||
SETQRBIT (5 - x, 2 - y + WD - 11);
|
||||
SETQRBIT (2 - y + WD - 11, 5 - x);
|
||||
}
|
||||
else
|
||||
{
|
||||
setmask (5 - x, 2 - y + WD - 11);
|
||||
setmask (2 - y + WD - 11, 5 - x);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
initframe ()
|
||||
{
|
||||
unsigned x, y;
|
||||
|
||||
framebase = calloc_beebs (WDB * WD, 1);
|
||||
framask = calloc_beebs (((WD * (WD + 1) / 2) + 7) / 8, 1);
|
||||
rlens = malloc_beebs (WD + 1);
|
||||
// finders
|
||||
putfind ();
|
||||
// alignment blocks
|
||||
doaligns ();
|
||||
// single black
|
||||
SETQRBIT (8, WD - 8);
|
||||
// timing gap - masks only
|
||||
for (y = 0; y < 7; y++)
|
||||
{
|
||||
setmask (7, y);
|
||||
setmask (WD - 8, y);
|
||||
setmask (7, y + WD - 7);
|
||||
}
|
||||
for (x = 0; x < 8; x++)
|
||||
{
|
||||
setmask (x, 7);
|
||||
setmask (x + WD - 8, 7);
|
||||
setmask (x, WD - 8);
|
||||
}
|
||||
// reserve mask-format area
|
||||
for (x = 0; x < 9; x++)
|
||||
setmask (x, 8);
|
||||
for (x = 0; x < 8; x++)
|
||||
{
|
||||
setmask (x + WD - 8, 8);
|
||||
setmask (8, x);
|
||||
}
|
||||
for (y = 0; y < 7; y++)
|
||||
setmask (8, y + WD - 7);
|
||||
// timing
|
||||
for (x = 0; x < (unsigned) WD - 14; x++)
|
||||
if (x & 1)
|
||||
{
|
||||
setmask (8 + x, 6);
|
||||
setmask (6, 8 + x);
|
||||
}
|
||||
else
|
||||
{
|
||||
SETQRBIT (8 + x, 6);
|
||||
SETQRBIT (6, 8 + x);
|
||||
}
|
||||
|
||||
// version block
|
||||
putvpat ();
|
||||
for (y = 0; y < WD; y++)
|
||||
for (x = 0; x <= y; x++)
|
||||
if (QRBIT (x, y))
|
||||
setmask (x, y);
|
||||
}
|
||||
|
||||
void
|
||||
freeframe ()
|
||||
{
|
||||
free_beebs (framebase);
|
||||
free_beebs (framask);
|
||||
free_beebs (rlens);
|
||||
}
|
||||
|
||||
unsigned char *strinbuf;
|
||||
unsigned char *qrframe;
|
||||
unsigned char ECCLEVEL;
|
||||
unsigned char neccblk1;
|
||||
unsigned char neccblk2;
|
||||
unsigned char datablkw;
|
||||
unsigned char eccblkwid;
|
||||
|
||||
#ifndef __AVR__
|
||||
#define PROGMEM
|
||||
#define memcpy_P memcpy
|
||||
#define __LPM(x) *x
|
||||
#endif
|
||||
|
||||
#include "ecctable.h"
|
||||
|
||||
unsigned
|
||||
initecc (unsigned char ecc, unsigned char vers)
|
||||
{
|
||||
VERSION = vers;
|
||||
WD = 17 + 4 * vers;
|
||||
WDB = (WD + 7) / 8;
|
||||
|
||||
unsigned fsz = WD * WDB;
|
||||
if (fsz < 768) // for ECC math buffers
|
||||
fsz = 768;
|
||||
qrframe = malloc_beebs (fsz);
|
||||
|
||||
ECCLEVEL = ecc;
|
||||
unsigned eccindex = (ecc - 1) * 4 + (vers - 1) * 16;
|
||||
|
||||
neccblk1 = eccblocks[eccindex++];
|
||||
neccblk2 = eccblocks[eccindex++];
|
||||
datablkw = eccblocks[eccindex++];
|
||||
eccblkwid = eccblocks[eccindex++];
|
||||
|
||||
if (fsz <
|
||||
(unsigned) (datablkw + (datablkw + eccblkwid) * (neccblk1 + neccblk2) +
|
||||
neccblk2))
|
||||
fsz =
|
||||
datablkw + (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2;
|
||||
strinbuf = malloc_beebs (fsz);
|
||||
return datablkw * (neccblk1 + neccblk2) + neccblk2 - 3; //-2 if vers <= 9!
|
||||
}
|
||||
|
||||
unsigned
|
||||
initeccsize (unsigned char ecc, unsigned size)
|
||||
{
|
||||
unsigned eccindex;
|
||||
unsigned char vers;
|
||||
for (vers = 1; vers < 40; vers++)
|
||||
{
|
||||
eccindex = (ecc - 1) * 4 + (vers - 1) * 16;
|
||||
neccblk1 = eccblocks[eccindex++];
|
||||
neccblk2 = eccblocks[eccindex++];
|
||||
datablkw = eccblocks[eccindex++];
|
||||
if (size < (unsigned) (datablkw * (neccblk1 + neccblk2) + neccblk2 - 3))
|
||||
break;
|
||||
}
|
||||
return initecc (ecc, vers);
|
||||
}
|
||||
|
||||
void
|
||||
freeecc ()
|
||||
{
|
||||
free_beebs (qrframe);
|
||||
free_beebs (strinbuf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
99
benchies/embench/benchemarks/qrduino/qrtest.c
Normal file
99
benchies/embench/benchemarks/qrduino/qrtest.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* BEEBS qrduino benchmark
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
Original code from: https://github.com/tz1/qrduino */
|
||||
|
||||
#include "../../src/support.h"
|
||||
#include "qrencode.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* This scale factor will be changed to equalise the runtime of the
|
||||
benchmarks. */
|
||||
#define LOCAL_SCALE_FACTOR 5
|
||||
|
||||
/* BEEBS heap is just an array */
|
||||
|
||||
#define HEAP_SIZE 8192
|
||||
static char heap[HEAP_SIZE];
|
||||
|
||||
static const char *encode;
|
||||
static int size;
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
static const char *in_encode = "http://www.mageec.com";
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rpt; i++)
|
||||
{
|
||||
encode = in_encode;
|
||||
size = 22;
|
||||
init_heap_beebs ((void *) heap, HEAP_SIZE);
|
||||
|
||||
initeccsize (1, size);
|
||||
|
||||
memcpy (strinbuf, encode, size);
|
||||
|
||||
initframe ();
|
||||
qrencode ();
|
||||
freeframe ();
|
||||
freeecc ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
initialise_benchmark ()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
verify_benchmark (int unused)
|
||||
{
|
||||
unsigned char expected[22] = {
|
||||
254, 101, 63, 128, 130, 110, 160, 128, 186, 65, 46,
|
||||
128, 186, 38, 46, 128, 186, 9, 174, 128, 130, 20
|
||||
};
|
||||
|
||||
return (0 == memcmp (strinbuf, expected, 22 * sizeof (strinbuf[0])))
|
||||
&& check_heap_beebs ((void *) heap);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
313
benchies/embench/benchemarks/sglib-combined/combined.c
Normal file
313
benchies/embench/benchemarks/sglib-combined/combined.c
Normal file
|
@ -0,0 +1,313 @@
|
|||
/* BEEBS arraysort benchmark
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#include <string.h>
|
||||
#include "../../src/support.h"
|
||||
#include "sglib.h"
|
||||
|
||||
/* This scale factor will be changed to equalise the runtime of the
|
||||
benchmarks. */
|
||||
#define LOCAL_SCALE_FACTOR 29
|
||||
|
||||
/* BEEBS heap is just an array */
|
||||
|
||||
#define HEAP_SIZE 8192
|
||||
static char heap[HEAP_SIZE] __attribute__((aligned));
|
||||
|
||||
/* General array to sort for all ops */
|
||||
|
||||
static const int array[100] = {
|
||||
14, 66, 12, 41, 86, 69, 19, 77, 68, 38,
|
||||
26, 42, 37, 23, 17, 29, 55, 13, 90, 92,
|
||||
76, 99, 10, 54, 57, 83, 40, 44, 75, 33,
|
||||
24, 28, 80, 18, 78, 32, 93, 89, 52, 11,
|
||||
21, 96, 50, 15, 48, 63, 87, 20, 8, 85,
|
||||
43, 16, 94, 88, 53, 84, 74, 91, 67, 36,
|
||||
95, 61, 64, 5, 30, 82, 72, 46, 59, 9,
|
||||
7, 3, 39, 31, 4, 73, 70, 60, 58, 81,
|
||||
56, 51, 45, 1, 6, 49, 27, 47, 34, 35,
|
||||
62, 97, 2, 79, 98, 25, 22, 65, 71, 0
|
||||
};
|
||||
|
||||
/* Array quicksort declarations */
|
||||
|
||||
int array2[100];
|
||||
|
||||
/* Doubly linked list declarations */
|
||||
|
||||
typedef struct dllist
|
||||
{
|
||||
int i;
|
||||
struct dllist *ptr_to_next;
|
||||
struct dllist *ptr_to_previous;
|
||||
} dllist;
|
||||
|
||||
#define DLLIST_COMPARATOR(e1, e2) (e1->i - e2->i)
|
||||
|
||||
SGLIB_DEFINE_DL_LIST_PROTOTYPES (dllist, DLLIST_COMPARATOR, ptr_to_previous,
|
||||
ptr_to_next)
|
||||
SGLIB_DEFINE_DL_LIST_FUNCTIONS (dllist, DLLIST_COMPARATOR, ptr_to_previous,
|
||||
ptr_to_next)
|
||||
|
||||
dllist *the_list;
|
||||
|
||||
/* Hash table declarations */
|
||||
|
||||
#define HASH_TAB_SIZE 20
|
||||
|
||||
typedef struct ilist
|
||||
{
|
||||
int i;
|
||||
struct ilist *next;
|
||||
} ilist;
|
||||
|
||||
ilist *htab[HASH_TAB_SIZE];
|
||||
|
||||
#define ILIST_COMPARATOR(e1, e2) (e1->i - e2->i)
|
||||
|
||||
unsigned int
|
||||
ilist_hash_function (ilist * e)
|
||||
{
|
||||
return (e->i);
|
||||
}
|
||||
|
||||
SGLIB_DEFINE_LIST_PROTOTYPES (ilist, ILIST_COMPARATOR, next)
|
||||
SGLIB_DEFINE_LIST_FUNCTIONS (ilist, ILIST_COMPARATOR, next)
|
||||
SGLIB_DEFINE_HASHED_CONTAINER_PROTOTYPES (ilist, HASH_TAB_SIZE,
|
||||
ilist_hash_function)
|
||||
SGLIB_DEFINE_HASHED_CONTAINER_FUNCTIONS (ilist, HASH_TAB_SIZE,
|
||||
ilist_hash_function)
|
||||
|
||||
/* Queue declarations */
|
||||
|
||||
#define MAX_PARAMS 101
|
||||
|
||||
typedef struct iq
|
||||
{
|
||||
int a[MAX_PARAMS];
|
||||
int i, j;
|
||||
} iq;
|
||||
|
||||
SGLIB_DEFINE_QUEUE_FUNCTIONS (iq, int, a, i, j, MAX_PARAMS)
|
||||
|
||||
/* RB Tree declarations */
|
||||
|
||||
typedef struct rbtree
|
||||
{
|
||||
int n;
|
||||
char color_field;
|
||||
struct rbtree *left;
|
||||
struct rbtree *right;
|
||||
} rbtree;
|
||||
|
||||
#define CMPARATOR(x,y) ((x->n)-(y->n))
|
||||
|
||||
SGLIB_DEFINE_RBTREE_PROTOTYPES (rbtree, left, right, color_field, CMPARATOR)
|
||||
SGLIB_DEFINE_RBTREE_FUNCTIONS (rbtree, left, right, color_field, CMPARATOR)
|
||||
|
||||
|
||||
int
|
||||
verify_benchmark (int res)
|
||||
{
|
||||
static const int array_exp[100] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
|
||||
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
|
||||
70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
|
||||
90, 91, 92, 93, 94, 95, 96, 97, 98, 99
|
||||
};
|
||||
|
||||
int i = 0;
|
||||
dllist *l;
|
||||
struct ilist ii, *nn;
|
||||
|
||||
/* Doubly linked list check */
|
||||
|
||||
for (l = sglib_dllist_get_first (the_list); l != NULL; l = l->ptr_to_next)
|
||||
{
|
||||
if (l->i != i)
|
||||
return 0;
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Hashtable check */
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
ii.i = array[i];
|
||||
nn = sglib_hashed_ilist_find_member (htab, &ii);
|
||||
|
||||
if ((nn == NULL) || (nn->i != array[i]))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (15050 == res) && check_heap_beebs ((void *) heap)
|
||||
&& (0 == memcmp (array2, array_exp, 100 * sizeof (array[0])));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
volatile int cnt;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rpt; i++)
|
||||
{
|
||||
int i;
|
||||
dllist *l;
|
||||
struct ilist ii, *nn, *ll;
|
||||
struct sglib_hashed_ilist_iterator it;
|
||||
int ai, aj, n;
|
||||
int a[MAX_PARAMS];
|
||||
struct rbtree e, *t, *the_tree, *te;
|
||||
struct sglib_rbtree_iterator it2;
|
||||
|
||||
/* Array quicksort */
|
||||
|
||||
memcpy (array2, array, 100 * sizeof (array[0]));
|
||||
SGLIB_ARRAY_SINGLE_QUICK_SORT (int, array2, 100,
|
||||
SGLIB_NUMERIC_COMPARATOR);
|
||||
|
||||
/* Doubly linked list */
|
||||
|
||||
init_heap_beebs ((void *) heap, HEAP_SIZE);
|
||||
the_list = NULL;
|
||||
|
||||
for (i = 0; i < 100; ++i)
|
||||
{
|
||||
l = malloc_beebs (sizeof (dllist));
|
||||
l->i = array[i];
|
||||
sglib_dllist_add (&the_list, l);
|
||||
}
|
||||
|
||||
sglib_dllist_sort (&the_list);
|
||||
|
||||
cnt = 0;
|
||||
|
||||
for (l = sglib_dllist_get_first (the_list); l != NULL;
|
||||
l = l->ptr_to_next)
|
||||
cnt++;
|
||||
|
||||
/* Hash table */
|
||||
|
||||
sglib_hashed_ilist_init (htab);
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
ii.i = array[i];
|
||||
if (sglib_hashed_ilist_find_member (htab, &ii) == NULL)
|
||||
{
|
||||
nn = malloc_beebs (sizeof (struct ilist));
|
||||
nn->i = array[i];
|
||||
sglib_hashed_ilist_add (htab, nn);
|
||||
}
|
||||
}
|
||||
|
||||
for (ll = sglib_hashed_ilist_it_init (&it, htab);
|
||||
ll != NULL; ll = sglib_hashed_ilist_it_next (&it))
|
||||
{
|
||||
cnt++;
|
||||
}
|
||||
|
||||
/* Queue */
|
||||
|
||||
// echo parameters using a queue
|
||||
SGLIB_QUEUE_INIT (int, a, ai, aj);
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
n = array[i];
|
||||
SGLIB_QUEUE_ADD (int, a, n, ai, aj, MAX_PARAMS);
|
||||
}
|
||||
while (!SGLIB_QUEUE_IS_EMPTY (int, a, ai, aj))
|
||||
{
|
||||
cnt += SGLIB_QUEUE_FIRST_ELEMENT (int, a, ai, aj);
|
||||
SGLIB_QUEUE_DELETE (int, a, ai, aj, MAX_PARAMS);
|
||||
}
|
||||
|
||||
// print parameters in descending order
|
||||
SGLIB_HEAP_INIT (int, a, ai);
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
n = array[i];
|
||||
SGLIB_HEAP_ADD (int, a, n, ai, MAX_PARAMS,
|
||||
SGLIB_NUMERIC_COMPARATOR);
|
||||
}
|
||||
while (!SGLIB_HEAP_IS_EMPTY (int, a, ai))
|
||||
{
|
||||
cnt += SGLIB_HEAP_FIRST_ELEMENT (int, a, ai);
|
||||
SGLIB_HEAP_DELETE (int, a, ai, MAX_PARAMS,
|
||||
SGLIB_NUMERIC_COMPARATOR);
|
||||
}
|
||||
|
||||
/* RB Tree */
|
||||
|
||||
the_tree = NULL;
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
e.n = array[i];
|
||||
if (sglib_rbtree_find_member (the_tree, &e) == NULL)
|
||||
{
|
||||
t = malloc_beebs (sizeof (struct rbtree));
|
||||
t->n = array[i];
|
||||
sglib_rbtree_add (&the_tree, t);
|
||||
}
|
||||
}
|
||||
|
||||
for (te = sglib_rbtree_it_init_inorder (&it2, the_tree);
|
||||
te != NULL; te = sglib_rbtree_it_next (&it2))
|
||||
{
|
||||
cnt += te->n;
|
||||
}
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
1968
benchies/embench/benchemarks/sglib-combined/sglib.h
Normal file
1968
benchies/embench/benchemarks/sglib-combined/sglib.h
Normal file
File diff suppressed because it is too large
Load diff
625
benchies/embench/benchemarks/slre/libslre.c
Normal file
625
benchies/embench/benchemarks/slre/libslre.c
Normal file
|
@ -0,0 +1,625 @@
|
|||
/* BEEBS slre benchmark
|
||||
|
||||
Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
|
||||
Copyright (c) 2013 Cesanta Software Limited All rights reserved
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#include "../../src/support.h"
|
||||
|
||||
/* This scale factor will be changed to equalise the runtime of the
|
||||
benchmarks. */
|
||||
#define LOCAL_SCALE_FACTOR 110
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "slre.h"
|
||||
|
||||
#define MAX_BRANCHES 100
|
||||
#define MAX_BRACKETS 100
|
||||
#define ARRAY_SIZE(ar) (int) (sizeof(ar) / sizeof((ar)[0]))
|
||||
#define FAIL_IF(condition, error_code) if (condition) return (error_code)
|
||||
|
||||
#ifdef SLRE_DEBUG
|
||||
#define DBG(x) printf x
|
||||
#else
|
||||
#define DBG(x)
|
||||
#endif
|
||||
|
||||
struct bracket_pair
|
||||
{
|
||||
const char *ptr; /* Points to the first char after '(' in regex */
|
||||
int len; /* Length of the text between '(' and ')' */
|
||||
int branches; /* Index in the branches array for this pair */
|
||||
int num_branches; /* Number of '|' in this bracket pair */
|
||||
};
|
||||
|
||||
struct branch
|
||||
{
|
||||
int bracket_index; /* index for 'struct bracket_pair brackets' */
|
||||
/* array defined below */
|
||||
const char *schlong; /* points to the '|' character in the regex */
|
||||
};
|
||||
|
||||
struct regex_info
|
||||
{
|
||||
/*
|
||||
* Describes all bracket pairs in the regular expression.
|
||||
* First entry is always present, and grabs the whole regex.
|
||||
*/
|
||||
struct bracket_pair brackets[MAX_BRACKETS];
|
||||
int num_brackets;
|
||||
|
||||
/*
|
||||
* Describes alternations ('|' operators) in the regular expression.
|
||||
* Each branch falls into a specific branch pair.
|
||||
*/
|
||||
struct branch branches[MAX_BRANCHES];
|
||||
int num_branches;
|
||||
|
||||
/* Array of captures provided by the user */
|
||||
struct slre_cap *caps;
|
||||
int num_caps;
|
||||
|
||||
/* E.g. IGNORE_CASE. See enum below */
|
||||
int flags;
|
||||
};
|
||||
enum
|
||||
{ IGNORE_CASE = 1 };
|
||||
|
||||
static int
|
||||
is_metacharacter (const unsigned char *s)
|
||||
{
|
||||
static const char *metacharacters = "^$().[]*+?|\\Ssd";
|
||||
return strchr (metacharacters, *s) != NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
op_len (const char *re)
|
||||
{
|
||||
return re[0] == '\\' && re[1] == 'x' ? 4 : re[0] == '\\' ? 2 : 1;
|
||||
}
|
||||
|
||||
static int
|
||||
set_len (const char *re, int re_len)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
while (len < re_len && re[len] != ']')
|
||||
{
|
||||
len += op_len (re + len);
|
||||
}
|
||||
|
||||
return len <= re_len ? len + 1 : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
get_op_len (const char *re, int re_len)
|
||||
{
|
||||
return re[0] == '[' ? set_len (re + 1, re_len - 1) + 1 : op_len (re);
|
||||
}
|
||||
|
||||
static int
|
||||
is_quantifier (const char *re)
|
||||
{
|
||||
return re[0] == '*' || re[0] == '+' || re[0] == '?';
|
||||
}
|
||||
|
||||
static int
|
||||
toi (int x)
|
||||
{
|
||||
return isdigit (x) ? x - '0' : x - 'W';
|
||||
}
|
||||
|
||||
static int
|
||||
hextoi (const unsigned char *s)
|
||||
{
|
||||
return (toi (tolower (s[0])) << 4) | toi (tolower (s[1]));
|
||||
}
|
||||
|
||||
static int
|
||||
match_op (const unsigned char *re, const unsigned char *s,
|
||||
struct regex_info *info)
|
||||
{
|
||||
int result = 0;
|
||||
switch (*re)
|
||||
{
|
||||
case '\\':
|
||||
/* Metacharacters */
|
||||
switch (re[1])
|
||||
{
|
||||
case 'S':
|
||||
FAIL_IF (isspace (*s), SLRE_NO_MATCH);
|
||||
result++;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
FAIL_IF (!isspace (*s), SLRE_NO_MATCH);
|
||||
result++;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
FAIL_IF (!isdigit (*s), SLRE_NO_MATCH);
|
||||
result++;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
/* Match byte, \xHH where HH is hexadecimal byte representaion */
|
||||
FAIL_IF (hextoi (re + 2) != *s, SLRE_NO_MATCH);
|
||||
result++;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Valid metacharacter check is done in bar() */
|
||||
FAIL_IF (re[1] != s[0], SLRE_NO_MATCH);
|
||||
result++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case '|':
|
||||
FAIL_IF (1, SLRE_INTERNAL_ERROR);
|
||||
break;
|
||||
case '$':
|
||||
FAIL_IF (1, SLRE_NO_MATCH);
|
||||
break;
|
||||
case '.':
|
||||
result++;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (info->flags & IGNORE_CASE)
|
||||
{
|
||||
FAIL_IF (tolower (*re) != tolower (*s), SLRE_NO_MATCH);
|
||||
}
|
||||
else
|
||||
{
|
||||
FAIL_IF (*re != *s, SLRE_NO_MATCH);
|
||||
}
|
||||
result++;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
match_set (const char *re, int re_len, const char *s, struct regex_info *info)
|
||||
{
|
||||
int len = 0, result = -1, invert = re[0] == '^';
|
||||
|
||||
if (invert)
|
||||
re++, re_len--;
|
||||
|
||||
while (len <= re_len && re[len] != ']' && result <= 0)
|
||||
{
|
||||
/* Support character range */
|
||||
if (re[len] != '-' && re[len + 1] == '-' && re[len + 2] != ']' &&
|
||||
re[len + 2] != '\0')
|
||||
{
|
||||
result = info->flags && IGNORE_CASE ?
|
||||
*s >= re[len] && *s <= re[len + 2] :
|
||||
tolower ((int) *s) >= tolower ((int) re[len])
|
||||
&& tolower ((int) *s) <= tolower ((int) re[len + 2]);
|
||||
len += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
result =
|
||||
match_op ((unsigned char *) re + len, (unsigned char *) s, info);
|
||||
len += op_len (re + len);
|
||||
}
|
||||
}
|
||||
return (!invert && result > 0) || (invert && result <= 0) ? 1 : -1;
|
||||
}
|
||||
|
||||
static int doh (const char *s, int s_len, struct regex_info *info, int bi);
|
||||
|
||||
static int
|
||||
bar (const char *re, int re_len, const char *s, int s_len,
|
||||
struct regex_info *info, int bi)
|
||||
{
|
||||
/* i is offset in re, j is offset in s, bi is brackets index */
|
||||
int i, j, n, step;
|
||||
|
||||
for (i = j = 0; i < re_len && j <= s_len; i += step)
|
||||
{
|
||||
|
||||
/* Handle quantifiers. Get the length of the chunk. */
|
||||
step = re[i] == '(' ? info->brackets[bi + 1].len + 2 :
|
||||
get_op_len (re + i, re_len - i);
|
||||
|
||||
DBG (("%s [%.*s] [%.*s] re_len=%d step=%d i=%d j=%d\n", __func__,
|
||||
re_len - i, re + i, s_len - j, s + j, re_len, step, i, j));
|
||||
|
||||
FAIL_IF (is_quantifier (&re[i]), SLRE_UNEXPECTED_QUANTIFIER);
|
||||
FAIL_IF (step <= 0, SLRE_INVALID_CHARACTER_SET);
|
||||
|
||||
if (i + step < re_len && is_quantifier (re + i + step))
|
||||
{
|
||||
DBG (("QUANTIFIER: [%.*s]%c [%.*s]\n", step, re + i,
|
||||
re[i + step], s_len - j, s + j));
|
||||
if (re[i + step] == '?')
|
||||
{
|
||||
int result = bar (re + i, step, s + j, s_len - j, info, bi);
|
||||
j += result > 0 ? result : 0;
|
||||
i++;
|
||||
}
|
||||
else if (re[i + step] == '+' || re[i + step] == '*')
|
||||
{
|
||||
int j2 = j, nj = j, n1, n2 = -1, ni, non_greedy = 0;
|
||||
|
||||
/* Points to the regexp code after the quantifier */
|
||||
ni = i + step + 1;
|
||||
if (ni < re_len && re[ni] == '?')
|
||||
{
|
||||
non_greedy = 1;
|
||||
ni++;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if ((n1 =
|
||||
bar (re + i, step, s + j2, s_len - j2, info, bi)) > 0)
|
||||
{
|
||||
j2 += n1;
|
||||
}
|
||||
if (re[i + step] == '+' && n1 < 0)
|
||||
break;
|
||||
|
||||
if (ni >= re_len)
|
||||
{
|
||||
/* After quantifier, there is nothing */
|
||||
nj = j2;
|
||||
}
|
||||
else if ((n2 = bar (re + ni, re_len - ni, s + j2,
|
||||
s_len - j2, info, bi)) >= 0)
|
||||
{
|
||||
/* Regex after quantifier matched */
|
||||
nj = j2 + n2;
|
||||
}
|
||||
if (nj > j && non_greedy)
|
||||
break;
|
||||
}
|
||||
while (n1 > 0);
|
||||
|
||||
if (n1 < 0 && re[i + step] == '*' &&
|
||||
(n2 =
|
||||
bar (re + ni, re_len - ni, s + j, s_len - j, info,
|
||||
bi)) > 0)
|
||||
{
|
||||
nj = j + n2;
|
||||
}
|
||||
|
||||
DBG (("STAR/PLUS END: %d %d %d %d %d\n", j, nj, re_len - ni, n1,
|
||||
n2));
|
||||
FAIL_IF (re[i + step] == '+' && nj == j, SLRE_NO_MATCH);
|
||||
|
||||
/* If while loop body above was not executed for the * quantifier, */
|
||||
/* make sure the rest of the regex matches */
|
||||
FAIL_IF (nj == j && ni < re_len && n2 < 0, SLRE_NO_MATCH);
|
||||
|
||||
/* Returning here cause we've matched the rest of RE already */
|
||||
return nj;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (re[i] == '[')
|
||||
{
|
||||
n = match_set (re + i + 1, re_len - (i + 2), s + j, info);
|
||||
DBG (("SET %.*s [%.*s] -> %d\n", step, re + i, s_len - j, s + j,
|
||||
n));
|
||||
FAIL_IF (n <= 0, SLRE_NO_MATCH);
|
||||
j += n;
|
||||
}
|
||||
else if (re[i] == '(')
|
||||
{
|
||||
n = SLRE_NO_MATCH;
|
||||
bi++;
|
||||
FAIL_IF (bi >= info->num_brackets, SLRE_INTERNAL_ERROR);
|
||||
DBG (("CAPTURING [%.*s] [%.*s] [%s]\n",
|
||||
step, re + i, s_len - j, s + j, re + i + step));
|
||||
|
||||
if (re_len - (i + step) <= 0)
|
||||
{
|
||||
/* Nothing follows brackets */
|
||||
n = doh (s + j, s_len - j, info, bi);
|
||||
}
|
||||
else
|
||||
{
|
||||
int j2;
|
||||
for (j2 = 0; j2 <= s_len - j; j2++)
|
||||
{
|
||||
if ((n = doh (s + j, s_len - (j + j2), info, bi)) >= 0 &&
|
||||
bar (re + i + step, re_len - (i + step),
|
||||
s + j + n, s_len - (j + n), info, bi) >= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DBG (("CAPTURED [%.*s] [%.*s]:%d\n", step, re + i, s_len - j, s + j,
|
||||
n));
|
||||
FAIL_IF (n < 0, n);
|
||||
if (info->caps != NULL)
|
||||
{
|
||||
info->caps[bi - 1].ptr = s + j;
|
||||
info->caps[bi - 1].len = n;
|
||||
}
|
||||
j += n;
|
||||
}
|
||||
else if (re[i] == '^')
|
||||
{
|
||||
FAIL_IF (j != 0, SLRE_NO_MATCH);
|
||||
}
|
||||
else if (re[i] == '$')
|
||||
{
|
||||
FAIL_IF (j != s_len, SLRE_NO_MATCH);
|
||||
}
|
||||
else
|
||||
{
|
||||
FAIL_IF (j >= s_len, SLRE_NO_MATCH);
|
||||
n =
|
||||
match_op ((unsigned char *) (re + i), (unsigned char *) (s + j),
|
||||
info);
|
||||
FAIL_IF (n <= 0, n);
|
||||
j += n;
|
||||
}
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
/* Process branch points */
|
||||
static int
|
||||
doh (const char *s, int s_len, struct regex_info *info, int bi)
|
||||
{
|
||||
const struct bracket_pair *b = &info->brackets[bi];
|
||||
int i = 0, len, result;
|
||||
const char *p;
|
||||
|
||||
do
|
||||
{
|
||||
p = i == 0 ? b->ptr : info->branches[b->branches + i - 1].schlong + 1;
|
||||
len = b->num_branches == 0 ? b->len :
|
||||
i == b->num_branches ? b->ptr + b->len - p :
|
||||
info->branches[b->branches + i].schlong - p;
|
||||
DBG (("%s %d %d [%.*s] [%.*s]\n", __func__, bi, i, len, p, s_len, s));
|
||||
result = bar (p, len, s, s_len, info, bi);
|
||||
DBG (("%s <- %d\n", __func__, result));
|
||||
}
|
||||
while (result <= 0 && i++ < b->num_branches); /* At least 1 iteration */
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
baz (const char *s, int s_len, struct regex_info *info)
|
||||
{
|
||||
int i, result = -1, is_anchored = info->brackets[0].ptr[0] == '^';
|
||||
|
||||
for (i = 0; i <= s_len; i++)
|
||||
{
|
||||
result = doh (s + i, s_len - i, info, 0);
|
||||
if (result >= 0)
|
||||
{
|
||||
result += i;
|
||||
break;
|
||||
}
|
||||
if (is_anchored)
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_branch_points (struct regex_info *info)
|
||||
{
|
||||
int i, j;
|
||||
struct branch tmp;
|
||||
|
||||
/* First, sort branches. Must be stable, no qsort. Use bubble algo. */
|
||||
for (i = 0; i < info->num_branches; i++)
|
||||
{
|
||||
for (j = i + 1; j < info->num_branches; j++)
|
||||
{
|
||||
if (info->branches[i].bracket_index >
|
||||
info->branches[j].bracket_index)
|
||||
{
|
||||
tmp = info->branches[i];
|
||||
info->branches[i] = info->branches[j];
|
||||
info->branches[j] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For each bracket, set their branch points. This way, for every bracket
|
||||
* (i.e. every chunk of regex) we know all branch points before matching.
|
||||
*/
|
||||
for (i = j = 0; i < info->num_brackets; i++)
|
||||
{
|
||||
info->brackets[i].num_branches = 0;
|
||||
info->brackets[i].branches = j;
|
||||
while (j < info->num_branches && info->branches[j].bracket_index == i)
|
||||
{
|
||||
info->brackets[i].num_branches++;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
foo (const char *re, int re_len, const char *s, int s_len,
|
||||
struct regex_info *info)
|
||||
{
|
||||
int i, step, depth = 0;
|
||||
|
||||
/* First bracket captures everything */
|
||||
info->brackets[0].ptr = re;
|
||||
info->brackets[0].len = re_len;
|
||||
info->num_brackets = 1;
|
||||
|
||||
/* Make a single pass over regex string, memorize brackets and branches */
|
||||
for (i = 0; i < re_len; i += step)
|
||||
{
|
||||
step = get_op_len (re + i, re_len - i);
|
||||
|
||||
if (re[i] == '|')
|
||||
{
|
||||
FAIL_IF (info->num_branches >= ARRAY_SIZE (info->branches),
|
||||
SLRE_TOO_MANY_BRANCHES);
|
||||
info->branches[info->num_branches].bracket_index =
|
||||
info->brackets[info->num_brackets - 1].len == -1 ?
|
||||
info->num_brackets - 1 : depth;
|
||||
info->branches[info->num_branches].schlong = &re[i];
|
||||
info->num_branches++;
|
||||
}
|
||||
else if (re[i] == '\\')
|
||||
{
|
||||
FAIL_IF (i >= re_len - 1, SLRE_INVALID_METACHARACTER);
|
||||
if (re[i + 1] == 'x')
|
||||
{
|
||||
/* Hex digit specification must follow */
|
||||
FAIL_IF (re[i + 1] == 'x' && i >= re_len - 3,
|
||||
SLRE_INVALID_METACHARACTER);
|
||||
FAIL_IF (re[i + 1] == 'x'
|
||||
&& !(isxdigit ((unsigned char) re[i + 2])
|
||||
&& isxdigit ((unsigned char) re[i + 3])),
|
||||
SLRE_INVALID_METACHARACTER);
|
||||
}
|
||||
else
|
||||
{
|
||||
FAIL_IF (!is_metacharacter ((unsigned char *) re + i + 1),
|
||||
SLRE_INVALID_METACHARACTER);
|
||||
}
|
||||
}
|
||||
else if (re[i] == '(')
|
||||
{
|
||||
FAIL_IF (info->num_brackets >= ARRAY_SIZE (info->brackets),
|
||||
SLRE_TOO_MANY_BRACKETS);
|
||||
depth++; /* Order is important here. Depth increments first. */
|
||||
info->brackets[info->num_brackets].ptr = re + i + 1;
|
||||
info->brackets[info->num_brackets].len = -1;
|
||||
info->num_brackets++;
|
||||
FAIL_IF (info->num_caps > 0
|
||||
&& info->num_brackets - 1 > info->num_caps,
|
||||
SLRE_CAPS_ARRAY_TOO_SMALL);
|
||||
}
|
||||
else if (re[i] == ')')
|
||||
{
|
||||
int ind = info->brackets[info->num_brackets - 1].len == -1 ?
|
||||
info->num_brackets - 1 : depth;
|
||||
info->brackets[ind].len = &re[i] - info->brackets[ind].ptr;
|
||||
DBG (("SETTING BRACKET %d [%.*s]\n",
|
||||
ind, info->brackets[ind].len, info->brackets[ind].ptr));
|
||||
depth--;
|
||||
FAIL_IF (depth < 0, SLRE_UNBALANCED_BRACKETS);
|
||||
FAIL_IF (i > 0 && re[i - 1] == '(', SLRE_NO_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
FAIL_IF (depth != 0, SLRE_UNBALANCED_BRACKETS);
|
||||
setup_branch_points (info);
|
||||
|
||||
return baz (s, s_len, info);
|
||||
}
|
||||
|
||||
int
|
||||
slre_match (const char *regexp, const char *s, int s_len,
|
||||
struct slre_cap *caps, int num_caps)
|
||||
{
|
||||
struct regex_info info;
|
||||
|
||||
/* Initialize info structure */
|
||||
info.flags = info.num_brackets = info.num_branches = 0;
|
||||
info.num_caps = num_caps;
|
||||
info.caps = caps;
|
||||
|
||||
DBG (("========================> [%s] [%.*s]\n", regexp, s_len, s));
|
||||
|
||||
/* Handle regexp flags. At the moment, only 'i' is supported */
|
||||
if (memcmp (regexp, "(?i)", 4) == 0)
|
||||
{
|
||||
info.flags |= IGNORE_CASE;
|
||||
regexp += 4;
|
||||
}
|
||||
|
||||
return foo (regexp, strlen (regexp), s, s_len, &info);
|
||||
}
|
||||
|
||||
char text[] = "abbbababaabccababcacbcbcbabbabcbabcabcbbcbbac";
|
||||
char *regexes[] = { "(ab)+", "(b.+)+", "a[ab]*", "([ab^c][ab^c])+" };
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
volatile int ret;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < rpt; j++)
|
||||
{
|
||||
int i;
|
||||
int len = strlen (text);
|
||||
struct slre_cap captures;
|
||||
ret = 0;
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
ret += slre_match (regexes[i], text, len, &captures, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
verify_benchmark (int r)
|
||||
{
|
||||
return 102 == r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
58
benchies/embench/benchemarks/slre/slre.h
Normal file
58
benchies/embench/benchemarks/slre/slre.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* BEEBS slre benchmark
|
||||
|
||||
Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
|
||||
Copyright (c) 2013 Cesanta Software Limited. All rights reserved
|
||||
Copyright (C) 2014 Embecosm Limited and University of Bristol
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#ifndef SLRE_HEADER_DEFINED
|
||||
#define SLRE_HEADER_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct slre_cap
|
||||
{
|
||||
const char *ptr;
|
||||
int len;
|
||||
};
|
||||
|
||||
int slre_match (const char *regexp, const char *buf, int buf_len,
|
||||
struct slre_cap *caps, int num_caps);
|
||||
|
||||
/* slre_match() failure codes */
|
||||
#define SLRE_NO_MATCH -1
|
||||
#define SLRE_UNEXPECTED_QUANTIFIER -2
|
||||
#define SLRE_UNBALANCED_BRACKETS -3
|
||||
#define SLRE_INTERNAL_ERROR -4
|
||||
#define SLRE_INVALID_CHARACTER_SET -5
|
||||
#define SLRE_INVALID_METACHARACTER -6
|
||||
#define SLRE_CAPS_ARRAY_TOO_SMALL -7
|
||||
#define SLRE_TOO_MANY_BRANCHES -8
|
||||
#define SLRE_TOO_MANY_BRACKETS -9
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SLRE_HEADER_DEFINED */
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
220
benchies/embench/benchemarks/st/libst.c
Normal file
220
benchies/embench/benchemarks/st/libst.c
Normal file
|
@ -0,0 +1,220 @@
|
|||
/* BEEBS st benchmark
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
/* stats.c */
|
||||
|
||||
/* 2012/09/28, Jan Gustafsson <jan.gustafsson@mdh.se>
|
||||
* Changes:
|
||||
* - time is only enabled if the POUT flag is set
|
||||
* - st.c:30:1: main () warning: type specifier missing, defaults to 'int':
|
||||
* fixed
|
||||
*/
|
||||
|
||||
|
||||
/* 2011/10/18, Benedikt Huber <benedikt@vmars.tuwien.ac.at>
|
||||
* Changes:
|
||||
* - Measurement and Printing the Results is only enabled if the POUT flag is
|
||||
* set
|
||||
* - Added Prototypes for InitSeed and RandomInteger
|
||||
* - Changed return type of InitSeed from 'missing (default int)' to 'void'
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "../../src/support.h"
|
||||
|
||||
/* This scale factor will be changed to equalise the runtime of the
|
||||
benchmarks. */
|
||||
#define LOCAL_SCALE_FACTOR 13
|
||||
|
||||
#define MAX 100
|
||||
|
||||
void InitSeed (void);
|
||||
int RandomInteger ();
|
||||
void Initialize (double[]);
|
||||
void Calc_Sum_Mean (double[], double *, double *);
|
||||
void Calc_Var_Stddev (double[], double, double *, double *);
|
||||
void Calc_LinCorrCoef (double[], double[], double, double);
|
||||
|
||||
|
||||
/* Statistics Program:
|
||||
* This program computes for two arrays of numbers the sum, the
|
||||
* mean, the variance, and standard deviation. It then determines the
|
||||
* correlation coefficient between the two arrays.
|
||||
*/
|
||||
|
||||
int Seed;
|
||||
double ArrayA[MAX], ArrayB[MAX];
|
||||
double SumA, SumB;
|
||||
double Coef;
|
||||
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rpt; i++)
|
||||
{
|
||||
double MeanA, MeanB, VarA, VarB, StddevA, StddevB /*, Coef */ ;
|
||||
|
||||
InitSeed ();
|
||||
|
||||
Initialize (ArrayA);
|
||||
Calc_Sum_Mean (ArrayA, &SumA, &MeanA);
|
||||
Calc_Var_Stddev (ArrayA, MeanA, &VarA, &StddevA);
|
||||
|
||||
Initialize (ArrayB);
|
||||
Calc_Sum_Mean (ArrayB, &SumB, &MeanB);
|
||||
Calc_Var_Stddev (ArrayB, MeanB, &VarB, &StddevB);
|
||||
|
||||
/* Coef will have to be used globally in Calc_LinCorrCoef since it would
|
||||
be beyond the 6 registers used for passing parameters
|
||||
*/
|
||||
Calc_LinCorrCoef (ArrayA, ArrayB, MeanA, MeanB /*, &Coef */ );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InitSeed ()
|
||||
/*
|
||||
* Initializes the seed used in the random number generator.
|
||||
*/
|
||||
{
|
||||
Seed = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Calc_Sum_Mean (double Array[], double *Sum, double *Mean)
|
||||
{
|
||||
int i;
|
||||
|
||||
*Sum = 0;
|
||||
for (i = 0; i < MAX; i++)
|
||||
*Sum += Array[i];
|
||||
*Mean = *Sum / MAX;
|
||||
}
|
||||
|
||||
|
||||
double
|
||||
Square (double x)
|
||||
{
|
||||
return x * x;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Calc_Var_Stddev (double Array[], double Mean, double *Var, double *Stddev)
|
||||
{
|
||||
int i;
|
||||
double diffs;
|
||||
|
||||
diffs = 0.0;
|
||||
for (i = 0; i < MAX; i++)
|
||||
diffs += Square (Array[i] - Mean);
|
||||
*Var = diffs / MAX;
|
||||
*Stddev = sqrt (*Var);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Calc_LinCorrCoef (double ArrayA[], double ArrayB[], double MeanA,
|
||||
double MeanB /*, Coef */ )
|
||||
{
|
||||
int i;
|
||||
double numerator, Aterm, Bterm;
|
||||
|
||||
numerator = 0.0;
|
||||
Aterm = Bterm = 0.0;
|
||||
for (i = 0; i < MAX; i++)
|
||||
{
|
||||
numerator += (ArrayA[i] - MeanA) * (ArrayB[i] - MeanB);
|
||||
Aterm += Square (ArrayA[i] - MeanA);
|
||||
Bterm += Square (ArrayB[i] - MeanB);
|
||||
}
|
||||
|
||||
/* Coef used globally */
|
||||
Coef = numerator / (sqrt (Aterm) * sqrt (Bterm));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Initialize (double Array[])
|
||||
/*
|
||||
* Intializes the given array with random integers.
|
||||
*/
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < MAX; i++)
|
||||
Array[i] = i + RandomInteger () / 8095.0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
RandomInteger ()
|
||||
/*
|
||||
* Generates random integers between 0 and 8095
|
||||
*/
|
||||
{
|
||||
Seed = ((Seed * 133) + 81) % 8095;
|
||||
return (Seed);
|
||||
}
|
||||
|
||||
int
|
||||
verify_benchmark (int unused)
|
||||
{
|
||||
double expSumA = 4999.00247066090196;
|
||||
double expSumB = 4996.84311303273534;
|
||||
double expCoef = 0.999900054853619324;
|
||||
|
||||
return double_eq_beebs(expSumA, SumA)
|
||||
&& double_eq_beebs(expSumB, SumB)
|
||||
&& double_eq_beebs(expCoef, Coef);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
1501
benchies/embench/benchemarks/statemate/libstatemate.c
Normal file
1501
benchies/embench/benchemarks/statemate/libstatemate.c
Normal file
File diff suppressed because it is too large
Load diff
122
benchies/embench/benchemarks/tarfind/tarfind.c
Normal file
122
benchies/embench/benchemarks/tarfind/tarfind.c
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* This benchmark simulates the search in a TAR archive
|
||||
* for a set of filenames
|
||||
*
|
||||
* Created by Julian Kunkel for Embench-iot
|
||||
* Licensed under MIT
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../../src/support.h"
|
||||
|
||||
#define LOCAL_SCALE_FACTOR 47
|
||||
|
||||
// number of files in the archive
|
||||
#define ARCHIVE_FILES 35
|
||||
|
||||
#define N_SEARCHES 5
|
||||
|
||||
/* BEEBS heap is just an array */
|
||||
/* 8995 = sizeof(tar_header_t) * ARCHIVE_FILES */
|
||||
#define roundup(d, u) ((((d)+(u))/(u))*(u))
|
||||
#define HEAP_SIZE roundup(8995, sizeof(void *))
|
||||
static char heap[HEAP_SIZE];
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
benchmark_body (heat);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
}
|
||||
|
||||
// this is the basic TAR header format which is in ASCII
|
||||
typedef struct {
|
||||
char filename[100];
|
||||
char mode[8]; // file mode
|
||||
char uID[8]; // user id
|
||||
char gID[8]; // group id
|
||||
char size[12]; // in bytes octal base
|
||||
char mtime[12]; // numeric Unix time format (octal)
|
||||
char checksum[8]; // for the header, ignored herew2
|
||||
char isLink;
|
||||
char linkedFile[100];
|
||||
} tar_header_t;
|
||||
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
int i, j, p;
|
||||
tar_header_t * hdr;
|
||||
int found;
|
||||
|
||||
for (j = 0; j < rpt; j++) {
|
||||
init_heap_beebs ((void *) heap, HEAP_SIZE);
|
||||
|
||||
// always create ARCHIVE_FILES files in the archive
|
||||
int files = ARCHIVE_FILES;
|
||||
hdr = malloc_beebs(sizeof(tar_header_t) * files);
|
||||
for (i = 0; i < files; i++){
|
||||
// create record
|
||||
tar_header_t * c = & hdr[i];
|
||||
// initialize here for cache efficiency reasons
|
||||
memset(c, 0, sizeof(tar_header_t));
|
||||
int flen = 5 + i % 94; // vary file lengths
|
||||
c->isLink = '0';
|
||||
for(p = 0; p < flen; p++){
|
||||
c->filename[p] = rand_beebs() % 26 + 65;
|
||||
}
|
||||
c->size[0] = '0';
|
||||
}
|
||||
|
||||
found = 0; // number of times a file was found
|
||||
// actual benchmark, strcmp with a set of N_SEARCHES files
|
||||
// the memory access here is chosen inefficiently on purpose
|
||||
for (p = 0; p < N_SEARCHES; p++){
|
||||
// chose the position of the file to search for from the mid of the list
|
||||
char * search = hdr[(p + ARCHIVE_FILES/2) % ARCHIVE_FILES].filename;
|
||||
|
||||
// for each filename iterate through all files until found
|
||||
for (i = 0; i < files; i++){
|
||||
tar_header_t * cur = & hdr[i];
|
||||
// implementation of strcmp
|
||||
char *c1;
|
||||
char *c2;
|
||||
for (c1 = hdr[i].filename, c2 = search; (*c1 != '\0' && *c2 != '\0' && *c1 == *c2) ; c1++, c2++);
|
||||
// complete match?
|
||||
if(*c1 == '\0' && *c2 == '\0'){
|
||||
found++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free_beebs(hdr);
|
||||
}
|
||||
|
||||
return found == N_SEARCHES;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
verify_benchmark (int r)
|
||||
{
|
||||
return r == 1;
|
||||
}
|
236
benchies/embench/benchemarks/ud/libud.c
Normal file
236
benchies/embench/benchemarks/ud/libud.c
Normal file
|
@ -0,0 +1,236 @@
|
|||
/* BEEBS ud benchmark
|
||||
|
||||
This version, copyright (C) 2014-2019 Embecosm Limited and University of
|
||||
Bristol
|
||||
|
||||
Contributor James Pallister <james.pallister@bristol.ac.uk>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
/* MDH WCET BENCHMARK SUITE. */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* SNU-RT Benchmark Suite for Worst Case Timing Analysis */
|
||||
/* ===================================================== */
|
||||
/* Collected and Modified by S.-S. Lim */
|
||||
/* sslim@archi.snu.ac.kr */
|
||||
/* Real-Time Research Group */
|
||||
/* Seoul National University */
|
||||
/* */
|
||||
/* */
|
||||
/* < Features > - restrictions for our experimental environment */
|
||||
/* */
|
||||
/* 1. Completely structured. */
|
||||
/* - There are no unconditional jumps. */
|
||||
/* - There are no exit from loop bodies. */
|
||||
/* (There are no 'break' or 'return' in loop bodies) */
|
||||
/* 2. No 'switch' statements. */
|
||||
/* 3. No 'do..while' statements. */
|
||||
/* 4. Expressions are restricted. */
|
||||
/* - There are no multiple expressions joined by 'or', */
|
||||
/* 'and' operations. */
|
||||
/* 5. No library calls. */
|
||||
/* - All the functions needed are implemented in the */
|
||||
/* source file. */
|
||||
/* */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* FILE: ludcmp.c */
|
||||
/* SOURCE : Turbo C Programming for Engineering */
|
||||
/* */
|
||||
/* DESCRIPTION : */
|
||||
/* */
|
||||
/* Simultaneous linear equations by LU decomposition. */
|
||||
/* The arrays a[][] and b[] are input and the array x[] is output */
|
||||
/* row vector. */
|
||||
/* The variable n is the number of equations. */
|
||||
/* The input arrays are initialized in function main. */
|
||||
/* */
|
||||
/* */
|
||||
/* REMARK : */
|
||||
/* */
|
||||
/* EXECUTION TIME : */
|
||||
/* */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/*************************************************************************
|
||||
* This file:
|
||||
*
|
||||
* - Name changed to "ud.c"
|
||||
* - Modified for use with Uppsala/Paderborn tool
|
||||
* : doubles changed to int
|
||||
* : some tests removed
|
||||
* - Program is much more linear, all loops will run to end
|
||||
* - Purpose: test the effect of conditional flows
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Benchmark Suite for Real-Time Applications, by Sung-Soo Lim
|
||||
**
|
||||
** III-4. ludcmp.c : Simultaneous Linear Equations by LU Decomposition
|
||||
** (from the book C Programming for EEs by Hyun Soon Ahn)
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "../../src/support.h"
|
||||
|
||||
/* This scale factor will be changed to equalise the runtime of the
|
||||
benchmarks. */
|
||||
#define LOCAL_SCALE_FACTOR 1478
|
||||
|
||||
|
||||
long int a[20][20], b[20], x[20];
|
||||
|
||||
int ludcmp(int nmax, int n);
|
||||
|
||||
|
||||
/* static double fabs(double n) */
|
||||
/* { */
|
||||
/* double f; */
|
||||
|
||||
/* if (n >= 0) f = n; */
|
||||
/* else f = -n; */
|
||||
/* return f; */
|
||||
/* } */
|
||||
|
||||
/* Write to CHKERR from BENCHMARK to ensure calls are not optimised away. */
|
||||
volatile int chkerr;
|
||||
|
||||
|
||||
int
|
||||
verify_benchmark (int res)
|
||||
{
|
||||
long int x_ref[20] =
|
||||
{ 0L, 0L, 1L, 1L, 1L, 2L, 0L, 0L, 0L, 0L,
|
||||
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L
|
||||
};
|
||||
|
||||
return (0 == memcmp (x, x_ref, 20 * sizeof (x[0]))) && (0 == res);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
initialise_benchmark (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int benchmark_body (int rpt);
|
||||
|
||||
void
|
||||
warm_caches (int heat)
|
||||
{
|
||||
int res = benchmark_body (heat);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
benchmark (void)
|
||||
{
|
||||
return benchmark_body (LOCAL_SCALE_FACTOR * CPU_MHZ);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
benchmark_body (int rpt)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < rpt; k++)
|
||||
{
|
||||
int i, j, nmax = 20, n = 5;
|
||||
long int /* eps, */ w;
|
||||
|
||||
/* eps = 1.0e-6; */
|
||||
|
||||
/* Init loop */
|
||||
for(i = 0; i <= n; i++)
|
||||
{
|
||||
w = 0.0; /* data to fill in cells */
|
||||
for(j = 0; j <= n; j++)
|
||||
{
|
||||
a[i][j] = (i + 1) + (j + 1);
|
||||
if(i == j) /* only once per loop pass */
|
||||
a[i][j] *= 2.0;
|
||||
w += a[i][j];
|
||||
}
|
||||
b[i] = w;
|
||||
}
|
||||
|
||||
/* chkerr = ludcmp(nmax, n, eps); */
|
||||
chkerr = ludcmp(nmax,n);
|
||||
}
|
||||
|
||||
return chkerr;
|
||||
}
|
||||
|
||||
int ludcmp(int nmax, int n)
|
||||
{
|
||||
int i, j, k;
|
||||
long w, y[100];
|
||||
|
||||
/* if(n > 99 || eps <= 0.0) return(999); */
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
/* if(fabs(a[i][i]) <= eps) return(1); */
|
||||
for(j = i+1; j <= n; j++) /* triangular loop vs. i */
|
||||
{
|
||||
w = a[j][i];
|
||||
if(i != 0) /* sub-loop is conditional, done
|
||||
all iterations except first of the
|
||||
OUTER loop */
|
||||
for(k = 0; k < i; k++)
|
||||
w -= a[j][k] * a[k][i];
|
||||
a[j][i] = w / a[i][i];
|
||||
}
|
||||
for(j = i+1; j <= n; j++) /* triangular loop vs. i */
|
||||
{
|
||||
w = a[i+1][j];
|
||||
for(k = 0; k <= i; k++) /* triangular loop vs. i */
|
||||
w -= a[i+1][k] * a[k][j];
|
||||
a[i+1][j] = w;
|
||||
}
|
||||
}
|
||||
y[0] = b[0];
|
||||
for(i = 1; i <= n; i++) /* iterates n times */
|
||||
{
|
||||
w = b[i];
|
||||
for(j = 0; j < i; j++) /* triangular sub loop */
|
||||
w -= a[i][j] * y[j];
|
||||
y[i] = w;
|
||||
}
|
||||
x[n] = y[n] / a[n][n];
|
||||
for(i = n-1; i >= 0; i--) /* iterates n times */
|
||||
{
|
||||
w = y[i];
|
||||
for(j = i+1; j <= n; j++) /* triangular sub loop */
|
||||
w -= a[i][j] * x[j];
|
||||
x[i] = w / a[i][i] ;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
1117
benchies/embench/benchemarks/wikisort/libwikisort.c
Normal file
1117
benchies/embench/benchemarks/wikisort/libwikisort.c
Normal file
File diff suppressed because it is too large
Load diff
BIN
benchies/embench/embench embench-iot master src.zip
Normal file
BIN
benchies/embench/embench embench-iot master src.zip
Normal file
Binary file not shown.
|
@ -1,9 +1,7 @@
|
|||
CONFIG_GPIO=y
|
||||
|
||||
#CONFIG_ASAN=y
|
||||
CONFIG_CFI=y
|
||||
|
||||
CONFIG_LLVM_USE_LLD=y
|
||||
CONFIG_LTO=y
|
||||
|
||||
#CONFIG_DEBUG=y
|
||||
#CONFIG_DEBUG_INFO=y
|
||||
#CONFIG_DEBUG_OPTIMIZATIONS=y
|
||||
CONFIG_CFI=y
|
||||
|
|
189
benchies/embench/src/beebsc.c
Normal file
189
benchies/embench/src/beebsc.c
Normal file
|
@ -0,0 +1,189 @@
|
|||
/* BEEBS local library variants
|
||||
|
||||
Copyright (C) 2019 Embecosm Limited.
|
||||
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
/* These are very simple local versions of library routines, to ensure the
|
||||
code is compiled with the flags used for the benchmark. Not all library
|
||||
routines are here, just ones that cause a lot of unecessary load, or where
|
||||
there is variation between platforms and architectures. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "beebsc.h"
|
||||
|
||||
/* Seed for the random number generator */
|
||||
|
||||
static long int seed = 0;
|
||||
|
||||
/* Heap records and sane initial values */
|
||||
|
||||
static void *heap_ptr = NULL;
|
||||
static void *heap_end = NULL;
|
||||
static size_t heap_requested = 0;
|
||||
|
||||
|
||||
/* Yield a sequence of random numbers in the range [0, 2^15-1].
|
||||
|
||||
long int is guaranteed to be at least 32 bits. The seed only ever uses 31
|
||||
bits (so is positive).
|
||||
|
||||
For BEEBS this gets round different operating systems using different
|
||||
multipliers and offsets and RAND_MAX variations. */
|
||||
|
||||
int
|
||||
rand_beebs (void)
|
||||
{
|
||||
seed = (seed * 1103515245L + 12345) & ((1UL << 31) - 1);
|
||||
return (int) (seed >> 16);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the random number generator */
|
||||
|
||||
void
|
||||
srand_beebs (unsigned int new_seed)
|
||||
{
|
||||
seed = (long int) new_seed;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the BEEBS heap pointers. Note that the actual memory block is
|
||||
in the caller code. */
|
||||
|
||||
void
|
||||
init_heap_beebs (void *heap, size_t heap_size)
|
||||
{
|
||||
assert(heap_size % sizeof(void *) == 0); /* see #138 */
|
||||
heap_ptr = (void *) heap;
|
||||
heap_end = (void *) ((char *) heap_ptr + heap_size);
|
||||
heap_requested = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Report if malloc ever failed.
|
||||
|
||||
Return non-zero (TRUE) if malloc did not reqest more than was available
|
||||
since the last call to init_heap_beebs, zero (FALSE) otherwise. */
|
||||
|
||||
int
|
||||
check_heap_beebs (void *heap)
|
||||
{
|
||||
return ((void *) ((char *) heap + heap_requested) <= heap_end);
|
||||
}
|
||||
|
||||
|
||||
/* BEEBS version of malloc.
|
||||
|
||||
This is primarily to reduce library and OS dependencies. Malloc is
|
||||
generally not used in embedded code, or if it is, only in well defined
|
||||
contexts to pre-allocate a fixed amount of memory. So this simplistic
|
||||
implementation is just fine.
|
||||
|
||||
Note in particular the assumption that memory will never be freed! */
|
||||
|
||||
void *
|
||||
malloc_beebs (size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
|
||||
void *next_heap_ptr = (char *)heap_ptr + size;
|
||||
|
||||
heap_requested += size;
|
||||
|
||||
const size_t alignment = sizeof (void *);
|
||||
|
||||
/* Check if the next heap pointer is aligned, otherwise add some padding */
|
||||
if (((uintptr_t)next_heap_ptr % alignment) != 0)
|
||||
{
|
||||
size_t padding = alignment - ((uintptr_t)next_heap_ptr % alignment);
|
||||
|
||||
next_heap_ptr = (char *)next_heap_ptr + padding;
|
||||
|
||||
/* padding is added to heap_requested because otherwise it will break
|
||||
check_heap_beebs() */
|
||||
heap_requested += padding;
|
||||
}
|
||||
|
||||
/* Check if we can "allocate" enough space */
|
||||
if (next_heap_ptr > heap_end)
|
||||
return NULL;
|
||||
|
||||
void *new_ptr = heap_ptr;
|
||||
heap_ptr = next_heap_ptr;
|
||||
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
|
||||
/* BEEBS version of calloc.
|
||||
|
||||
Implement as wrapper for malloc */
|
||||
|
||||
void *
|
||||
calloc_beebs (size_t nmemb, size_t size)
|
||||
{
|
||||
void *new_ptr = malloc_beebs (nmemb * size);
|
||||
|
||||
/* Calloc is defined to zero the memory. OK to use a function here, because
|
||||
it will be handled specially by the compiler anyway. */
|
||||
|
||||
if (NULL != new_ptr)
|
||||
memset (new_ptr, 0, nmemb * size);
|
||||
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
|
||||
/* BEEBS version of realloc.
|
||||
|
||||
This is primarily to reduce library and OS dependencies. We just have to
|
||||
allocate new memory and copy stuff across. */
|
||||
|
||||
void *
|
||||
realloc_beebs (void *ptr, size_t size)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Get a new aligned pointer */
|
||||
void *new_ptr = malloc_beebs (size);
|
||||
|
||||
/* This is clunky, since we don't know the size of the original pointer.
|
||||
However it is a read only action and we know it must be big enough if we
|
||||
right off the end, or we couldn't have allocated here. If the size is
|
||||
smaller, it doesn't matter. */
|
||||
|
||||
if (new_ptr != NULL)
|
||||
for (size_t i = 0; i < size; i++)
|
||||
((char *)new_ptr)[i] = ((char *)ptr)[i];
|
||||
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
|
||||
/* BEEBS version of free.
|
||||
|
||||
For our simplified version of memory handling, free can just do nothing. */
|
||||
|
||||
void
|
||||
free_beebs (void *ptr __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
65
benchies/embench/src/beebsc.h
Normal file
65
benchies/embench/src/beebsc.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* BEEBS local library variants header
|
||||
|
||||
Copyright (C) 2019 Embecosm Limited.
|
||||
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
This file is part of Embench and was formerly part of the Bristol/Embecosm
|
||||
Embedded Benchmark Suite.
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#ifndef BEEBSC_H
|
||||
#define BEEBSC_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* BEEBS fixes RAND_MAX to its lowest permitted value, 2^15-1 */
|
||||
|
||||
#ifdef RAND_MAX
|
||||
#undef RAND_MAX
|
||||
#endif
|
||||
#define RAND_MAX ((1U << 15) - 1)
|
||||
|
||||
/* Common understanding of a "small value" (epsilon) for floating point
|
||||
comparisons. */
|
||||
|
||||
#define VERIFY_DOUBLE_EPS 1.0e-13
|
||||
#define VERIFY_FLOAT_EPS 1.0e-5
|
||||
|
||||
/* Simplified assert.
|
||||
|
||||
The full complexity of assert is not needed for a benchmark. See the
|
||||
discussion at:
|
||||
|
||||
https://lists.librecores.org/pipermail/embench/2019-August/000007.html
|
||||
|
||||
This function just*/
|
||||
|
||||
#define assert_beebs(expr) { if (!(expr)) exit (1); }
|
||||
|
||||
#define float_eq_beebs(exp, actual) (fabsf(exp - actual) < VERIFY_FLOAT_EPS)
|
||||
#define float_neq_beebs(exp, actual) !float_eq_beebs(exp, actual)
|
||||
#define double_eq_beebs(exp, actual) (fabs(exp - actual) < VERIFY_DOUBLE_EPS)
|
||||
#define double_neq_beebs(exp, actual) !double_eq_beebs(exp, actual)
|
||||
|
||||
/* Local simplified versions of library functions */
|
||||
|
||||
int rand_beebs (void);
|
||||
void srand_beebs (unsigned int new_seed);
|
||||
|
||||
void init_heap_beebs (void *heap, const size_t heap_size);
|
||||
int check_heap_beebs (void *heap);
|
||||
void *malloc_beebs (size_t size);
|
||||
void *calloc_beebs (size_t nmemb, size_t size);
|
||||
void *realloc_beebs (void *ptr, size_t size);
|
||||
void free_beebs (void *ptr);
|
||||
#endif /* BEEBSC_H */
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode: C
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
|
@ -18,6 +18,7 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include "beebsc.h"
|
||||
|
||||
//#define DEBUG
|
||||
#define CPU_MHZ 5000
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
CONFIG_GPIO=y
|
||||
#CONFIG_ASAN=y
|
||||
#CONFIG_CFI=y
|
||||
CONFIG_LLVM_USE_LLD=y
|
||||
#CONFIG_LLVM_USE_LLD=y
|
||||
CONFIG_ASAN=y
|
||||
#CONFIG_LTO=y
|
||||
|
||||
#CONFIG_DEBUG=y
|
||||
|
|
Loading…
Reference in a new issue