Add wasm tacle-bench targets
This commit is contained in:
29
targets/wasm-tacle/kernel/sha/CMakeLists.txt
Normal file
29
targets/wasm-tacle/kernel/sha/CMakeLists.txt
Normal file
@ -0,0 +1,29 @@
|
||||
# ~~~
|
||||
# SPDX-License-Identifier: MIT
|
||||
# SPDX-FileCopyrightText: 2026, Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU)
|
||||
# ~~~
|
||||
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
project(sha)
|
||||
|
||||
set(TACLEBENCH_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../..")
|
||||
set(REPOSITORY_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../../..")
|
||||
|
||||
set(APP_TARGET_NAME "${CMAKE_PROJECT_NAME}")
|
||||
|
||||
if(DEFINED TACLEBENCH_VARIANT AND "${TACLEBENCH_VARIANT}" STREQUAL "inline")
|
||||
set(APP_SOURCE_FILE_PATH
|
||||
"generated/modified_sources/inline/sha.c")
|
||||
else()
|
||||
set(APP_SOURCE_FILE_PATH
|
||||
"generated/modified_sources/default/sha.c"
|
||||
"generated/modified_sources/default/input_small.c"
|
||||
"generated/modified_sources/default/memcpy.c"
|
||||
"generated/modified_sources/default/memhelper.c"
|
||||
"generated/modified_sources/default/memset.c")
|
||||
endif()
|
||||
|
||||
include(${REPOSITORY_ROOT_PATH}/cmake/taclebench_wasm.cmake)
|
||||
|
||||
|
||||
108
targets/wasm-tacle/kernel/sha/Changelog.txt
Executable file
108
targets/wasm-tacle/kernel/sha/Changelog.txt
Executable file
@ -0,0 +1,108 @@
|
||||
File: sha.c
|
||||
Original provenience:
|
||||
|
||||
2017-04-18:
|
||||
- Annotated sha_main as entry-point for timing analysis
|
||||
|
||||
2015-03-30:
|
||||
- Remove comment on line 1
|
||||
- Added generic TACLeBench header to line 1
|
||||
- Removed IFDEF lines
|
||||
- Added main functionality from sha_driver.c
|
||||
- Added prefix to functions (sha_functionname)
|
||||
- Added sha_main, sha_init, sha_return functions
|
||||
- Changed local to global variable for the init function
|
||||
- Added checksum in return to return 0 when calculated correctly
|
||||
- Applied Code Style
|
||||
|
||||
File: sha.h
|
||||
Original provenience:
|
||||
|
||||
2015-03-30:
|
||||
- Remove comment on line 1
|
||||
- Added generic TACLeBench header to line 1
|
||||
- Add forward declaration of functions
|
||||
- Applied Code Style
|
||||
|
||||
File: glibc_common.h
|
||||
Original provenience:
|
||||
|
||||
2015-03-30:
|
||||
- Removed file and copy to sha.h
|
||||
|
||||
File: my_file.h
|
||||
Original provenience:
|
||||
|
||||
2015-03-30:
|
||||
- Removed file and copy to sha.h
|
||||
|
||||
File: my_file.c
|
||||
Original provenience:
|
||||
|
||||
2015-03-30:
|
||||
- Remove file and copy to sha.c
|
||||
|
||||
File: input_small.c
|
||||
Original provenience:
|
||||
|
||||
2015-03-30:
|
||||
- Remove comment on line 1
|
||||
- reformatted data to 20 chars per line
|
||||
- Added generic TACLeBench header to line 1
|
||||
- Applied Code Style
|
||||
|
||||
File: memhelper.h
|
||||
Original provenience:
|
||||
|
||||
2015-03-30:
|
||||
- Remove comment on line 1
|
||||
- Added generic TACLeBench header to line 1
|
||||
- Removed unnecessary #IFNDEF
|
||||
- Applied Code Style
|
||||
|
||||
File: memhelper.c
|
||||
Original provenience:
|
||||
|
||||
2015-03-30:
|
||||
- Remove comment on line 1
|
||||
- Added generic TACLeBench header to line 1
|
||||
- Added break; to switch statement
|
||||
- Applied Code Style
|
||||
|
||||
|
||||
File: memset.h
|
||||
Original provenience:
|
||||
|
||||
2015-03-30:
|
||||
- Remove comment on line 1
|
||||
- Added generic TACLeBench header to line 1
|
||||
- Applied Code Style
|
||||
|
||||
|
||||
File: memset.c
|
||||
Original provenience:
|
||||
|
||||
2015-03-30:
|
||||
- Remove comment on line 1
|
||||
- Added generic TACLeBench header to line 1
|
||||
- Applied Code Style
|
||||
|
||||
|
||||
File: memcpy.h
|
||||
Original provenience:
|
||||
|
||||
2015-03-30:
|
||||
- Remove comment on line 1
|
||||
- Added generic TACLeBench header to line 1
|
||||
- Added prefix to functions (sha_functionname)
|
||||
- Applied Code Style
|
||||
|
||||
|
||||
File: memcpy.c
|
||||
Original provenience:
|
||||
|
||||
2015-03-30:
|
||||
- Remove comment on line 1
|
||||
- Added generic TACLeBench header to line 1
|
||||
- Added prefix to functions (sha_functionname)
|
||||
- Applied Code Style
|
||||
BIN
targets/wasm-tacle/kernel/sha/generated/default/sha.wasm
Executable file
BIN
targets/wasm-tacle/kernel/sha/generated/default/sha.wasm
Executable file
Binary file not shown.
2591
targets/wasm-tacle/kernel/sha/generated/default/sha.wat
Normal file
2591
targets/wasm-tacle/kernel/sha/generated/default/sha.wat
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,78 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: memcpy.c
|
||||
|
||||
Author: Torbjorn Granlund
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Copy memory to memory until the specified number of bytes
|
||||
has been copied. Overlap is NOT handled correctly.
|
||||
|
||||
Source: GNU C Library
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: Copyright (C) 1991, 1997, 2003 Free Software Foundation, Inc.
|
||||
*/
|
||||
|
||||
#include "memcpy.h"
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
void *
|
||||
sha_glibc_memcpy(void *dstpp, const void *srcpp, size_t len) {
|
||||
unsigned long int dstp = (long int) dstpp;
|
||||
unsigned long int srcp = (long int) srcpp;
|
||||
size_t __nbytes;
|
||||
|
||||
/* Copy from the beginning to the end. */
|
||||
|
||||
/* If there not too few bytes to copy, use word copy. */
|
||||
if (len >= OP_T_THRES) {
|
||||
/* Copy just a few bytes to make DSTP aligned. */
|
||||
len -= (-dstp) % OPSIZ;
|
||||
|
||||
__nbytes = (-dstp) % OPSIZ;
|
||||
__pragma_loopbound(0, 0);
|
||||
while (__nbytes > 0) {
|
||||
BYTE __x = ((BYTE *) srcp)[0];
|
||||
srcp += 1;
|
||||
__nbytes -= 1;
|
||||
((BYTE *) dstp)[0] = __x;
|
||||
dstp += 1;
|
||||
}
|
||||
|
||||
/* Copy whole pages from SRCP to DSTP by virtual address manipulation,
|
||||
as much as possible. */
|
||||
|
||||
PAGE_COPY_FWD_MAYBE(dstp, srcp, len, len);
|
||||
|
||||
/* Copy from SRCP to DSTP taking advantage of the known alignment of
|
||||
DSTP. Number of bytes remaining is put in the third argument,
|
||||
i.e. in LEN. This number may vary from machine to machine. */
|
||||
|
||||
WORD_COPY_FWD(dstp, srcp, len, len);
|
||||
|
||||
/* Fall out and copy the tail. */
|
||||
}
|
||||
|
||||
/* There are just a few bytes to copy. Use byte memory operations. */
|
||||
__nbytes = len;
|
||||
__pragma_loopbound(0, 7);
|
||||
while (__nbytes > 0) {
|
||||
BYTE __x = ((BYTE *) srcp)[0];
|
||||
srcp += 1;
|
||||
__nbytes -= 1;
|
||||
((BYTE *) dstp)[0] = __x;
|
||||
dstp += 1;
|
||||
}
|
||||
|
||||
return dstpp;
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: memcpy.c
|
||||
|
||||
Author: Torbjorn Granlund
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Copy memory to memory until the specified number of bytes
|
||||
has been copied. Overlap is NOT handled correctly.
|
||||
|
||||
Source: GNU C Library
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: Copyright (C) 1991, 1997, 2003 Free Software Foundation, Inc.
|
||||
*/
|
||||
|
||||
#include "memhelper.h"
|
||||
#include "sha.h"
|
||||
|
||||
void *sha_glibc_memcpy(void *dstpp, const void *srcpp, size_t len);
|
||||
@ -0,0 +1,151 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: memhelper.c
|
||||
|
||||
Author: Torbjorn Granlund
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Copy block beginning at SRCP to
|
||||
block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
|
||||
Both SRCP and DSTP should be aligned for memory operations on `op_t's.
|
||||
|
||||
Source: GNU C Library
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: Copyright (C) 1991, 1997, 2003 Free Software Foundation, Inc.
|
||||
*/
|
||||
|
||||
#include "memhelper.h"
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
int printf(const char *restrict format, ...);
|
||||
/* sha_wordcopy_fwd_aligned -- Copy block beginning at SRCP to
|
||||
block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
|
||||
Both SRCP and DSTP should be aligned for memory operations on `op_t's.
|
||||
*/
|
||||
|
||||
void
|
||||
sha_wordcopy_fwd_aligned(long int dstp, long int srcp, size_t len) {
|
||||
op_t a0 = 0;
|
||||
op_t a1 = 0;
|
||||
char switch_target;
|
||||
|
||||
switch (len % 8) {
|
||||
case 2:
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
srcp -= 6 * OPSIZ;
|
||||
dstp -= 7 * OPSIZ;
|
||||
len += 6;
|
||||
switch_target = 1;
|
||||
break;
|
||||
case 3:
|
||||
a1 = ((op_t *) srcp)[0];
|
||||
srcp -= 5 * OPSIZ;
|
||||
dstp -= 6 * OPSIZ;
|
||||
len += 5;
|
||||
switch_target = 2;
|
||||
break;
|
||||
case 4:
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
srcp -= 4 * OPSIZ;
|
||||
dstp -= 5 * OPSIZ;
|
||||
len += 4;
|
||||
switch_target = 3;
|
||||
break;
|
||||
case 5:
|
||||
a1 = ((op_t *) srcp)[0];
|
||||
srcp -= 3 * OPSIZ;
|
||||
dstp -= 4 * OPSIZ;
|
||||
len += 3;
|
||||
switch_target = 4;
|
||||
break;
|
||||
case 6:
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
srcp -= 2 * OPSIZ;
|
||||
dstp -= 3 * OPSIZ;
|
||||
len += 2;
|
||||
switch_target = 5;
|
||||
break;
|
||||
case 7:
|
||||
a1 = ((op_t *) srcp)[0];
|
||||
srcp -= 1 * OPSIZ;
|
||||
dstp -= 2 * OPSIZ;
|
||||
len += 1;
|
||||
switch_target = 6;
|
||||
break;
|
||||
case 0:
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
return;
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
srcp -= 0 * OPSIZ;
|
||||
dstp -= 1 * OPSIZ;
|
||||
switch_target = 7;
|
||||
break;
|
||||
case 1:
|
||||
a1 = ((op_t *) srcp)[0];
|
||||
srcp -= -1 * OPSIZ;
|
||||
dstp -= 0 * OPSIZ;
|
||||
len -= 1;
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0) {
|
||||
((op_t *) dstp)[0] = a1;
|
||||
return;
|
||||
} else {
|
||||
switch_target = 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__pragma_loopbound(1, 2); // max 1
|
||||
do {
|
||||
switch (switch_target) {
|
||||
case 8:
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
((op_t *) dstp)[0] = a1;
|
||||
break;
|
||||
case 7:
|
||||
a1 = ((op_t *) srcp)[1];
|
||||
((op_t *) dstp)[1] = a0;
|
||||
break;
|
||||
case 6:
|
||||
a0 = ((op_t *) srcp)[2];
|
||||
((op_t *) dstp)[2] = a1;
|
||||
break;
|
||||
case 5:
|
||||
a1 = ((op_t *) srcp)[3];
|
||||
((op_t *) dstp)[3] = a0;
|
||||
break;
|
||||
case 4:
|
||||
a0 = ((op_t *) srcp)[4];
|
||||
((op_t *) dstp)[4] = a1;
|
||||
break;
|
||||
case 3:
|
||||
a1 = ((op_t *) srcp)[5];
|
||||
((op_t *) dstp)[5] = a0;
|
||||
break;
|
||||
case 2:
|
||||
a0 = ((op_t *) srcp)[6];
|
||||
((op_t *) dstp)[6] = a1;
|
||||
break;
|
||||
case 1:
|
||||
a1 = ((op_t *) srcp)[7];
|
||||
((op_t *) dstp)[7] = a0;
|
||||
break;
|
||||
}
|
||||
|
||||
srcp += 8 * OPSIZ;
|
||||
dstp += 8 * OPSIZ;
|
||||
len -= 8;
|
||||
switch_target = 8;
|
||||
} while (len != 0);
|
||||
|
||||
((op_t *) dstp)[0] = a1;
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: memhelper.h
|
||||
|
||||
Author: Peter C. Gutmann's (heavily modified by Uwe Hollerbach)
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Source: Peter C. Gutmann's implementation as found in Applied Cryptography by
|
||||
Bruce Schneier
|
||||
|
||||
License: GNU Lesser General Public License
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
*/
|
||||
|
||||
#ifndef MEM_HELPER_H
|
||||
#define MEM_HELPER_H
|
||||
|
||||
#include "sha.h"
|
||||
|
||||
void sha_wordcopy_fwd_aligned(long int dstp, long int srcp, size_t len);
|
||||
|
||||
/* Type to use for aligned memory operations.
|
||||
This should normally be the biggest type supported by a single load
|
||||
and store. */
|
||||
#define op_t unsigned long int
|
||||
#define OPSIZ (sizeof(op_t))
|
||||
|
||||
/* Threshold value for when to enter the unrolled loops. */
|
||||
#define OP_T_THRES 16
|
||||
|
||||
#define PAGE_COPY_FWD_MAYBE(dstp, srcp, nbytes_left, nbytes)
|
||||
#define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
|
||||
|
||||
/* Copy *up to* NBYTES bytes from SRC_BP to DST_BP, with
|
||||
the assumption that DST_BP is aligned on an OPSIZ multiple. If
|
||||
not all bytes could be easily copied, store remaining number of bytes
|
||||
in NBYTES_LEFT, otherwise store 0. */
|
||||
#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \
|
||||
{ \
|
||||
if (src_bp % OPSIZ == 0) \
|
||||
sha_wordcopy_fwd_aligned(dst_bp, src_bp, (nbytes) / OPSIZ); \
|
||||
else \
|
||||
src_bp += (nbytes) & -OPSIZ; \
|
||||
dst_bp += (nbytes) & -OPSIZ; \
|
||||
(nbytes_left) = (nbytes) % OPSIZ; \
|
||||
}
|
||||
|
||||
#endif // MEM_HELPER_H
|
||||
@ -0,0 +1,92 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: menset.h
|
||||
|
||||
Author: Torbjorn Granlund
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Copy memory to memory until the specified number of bytes
|
||||
has been copied. Overlap is NOT handled correctly.
|
||||
|
||||
Source: GNU C Library
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: GNU Lesser General Public License
|
||||
*/
|
||||
#include "memset.h"
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
int printf(const char *restrict format, ...);
|
||||
|
||||
void *
|
||||
sha_glibc_memset(void *dstpp, int c, size_t len) {
|
||||
long int dstp = (long int) dstpp;
|
||||
|
||||
if (len >= 8) {
|
||||
size_t xlen;
|
||||
op_t cccc;
|
||||
|
||||
cccc = (unsigned char) c;
|
||||
cccc |= cccc << 8;
|
||||
cccc |= cccc << 16;
|
||||
if (OPSIZ > 4)
|
||||
/* Do the shift in two steps to avoid warning if long has 32 bits.
|
||||
*/
|
||||
cccc |= (cccc << 16) << 16;
|
||||
|
||||
/* There are at least some bytes to set.
|
||||
No need to test for LEN == 0 in this alignment loop. */
|
||||
__pragma_loopbound(3, 3);
|
||||
while (dstp % OPSIZ != 0) {
|
||||
((BYTE *) dstp)[0] = c;
|
||||
dstp += 1;
|
||||
len -= 1;
|
||||
}
|
||||
|
||||
/* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */
|
||||
xlen = len / (OPSIZ * 8);
|
||||
__pragma_loopbound(0, 1);
|
||||
while (xlen > 0) {
|
||||
((op_t *) dstp)[0] = cccc;
|
||||
((op_t *) dstp)[1] = cccc;
|
||||
((op_t *) dstp)[2] = cccc;
|
||||
((op_t *) dstp)[3] = cccc;
|
||||
((op_t *) dstp)[4] = cccc;
|
||||
((op_t *) dstp)[5] = cccc;
|
||||
((op_t *) dstp)[6] = cccc;
|
||||
((op_t *) dstp)[7] = cccc;
|
||||
dstp += 8 * OPSIZ;
|
||||
xlen -= 1;
|
||||
}
|
||||
len %= OPSIZ * 8;
|
||||
|
||||
/* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */
|
||||
xlen = len / OPSIZ;
|
||||
__pragma_loopbound(1, 2);
|
||||
while (xlen > 0) {
|
||||
((op_t *) dstp)[0] = cccc;
|
||||
dstp += OPSIZ;
|
||||
xlen -= 1;
|
||||
}
|
||||
len %= OPSIZ;
|
||||
}
|
||||
|
||||
/* Write the last few bytes. */
|
||||
__pragma_loopbound(0, 0);
|
||||
while (len > 0) {
|
||||
((BYTE *) dstp)[0] = c;
|
||||
dstp += 1;
|
||||
len -= 1;
|
||||
}
|
||||
|
||||
return (void *) dstpp;
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: menset.h
|
||||
|
||||
Author: Torbjorn Granlund
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Copy memory to memory until the specified number of bytes
|
||||
has been copied. Overlap is NOT handled correctly.
|
||||
|
||||
Source: GNU C Library
|
||||
|
||||
License: GNU Lesser General Public License
|
||||
|
||||
Changes: no major functional changes
|
||||
*/
|
||||
#include "memhelper.h"
|
||||
|
||||
void *sha_glibc_memset(void *dstpp, int c, size_t len);
|
||||
@ -0,0 +1,232 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: sha.c
|
||||
|
||||
Author: Peter C. Gutmann's (heavily modified by Uwe Hollerbach)
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Source: Peter C. Gutmann's implementation as found in Applied Cryptography by
|
||||
Bruce Schneier
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: GNU Lesser General Public License
|
||||
|
||||
*/
|
||||
|
||||
#include "sha.h"
|
||||
#include "memcpy.h"
|
||||
#include "memset.h"
|
||||
|
||||
/*
|
||||
Declaration of global variables
|
||||
*/
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
struct SHA_INFO sha_info;
|
||||
|
||||
/* SHA f()-functions */
|
||||
#define f1(x, y, z) ((x & y) | (~x & z))
|
||||
#define f2(x, y, z) (x ^ y ^ z)
|
||||
#define f3(x, y, z) ((x & y) | (x & z) | (y & z))
|
||||
#define f4(x, y, z) (x ^ y ^ z)
|
||||
|
||||
/* SHA constants */
|
||||
#define CONST1 0x5a827999L
|
||||
#define CONST2 0x6ed9eba1L
|
||||
#define CONST3 0x8f1bbcdcL
|
||||
#define CONST4 0xca62c1d6L
|
||||
|
||||
#define BLOCK_SIZE 8192
|
||||
|
||||
/* 32-bit rotate */
|
||||
|
||||
#define ROT32(x, n) ((x << n) | (x >> (32 - n)))
|
||||
|
||||
#define FUNC(n, i) \
|
||||
temp = ROT32(A, 5) + f##n(B, C, D) + E + W[i] + CONST##n; \
|
||||
E = D; \
|
||||
D = C; \
|
||||
C = ROT32(B, 30); \
|
||||
B = A; \
|
||||
A = temp
|
||||
|
||||
/* do SHA transformation */
|
||||
void
|
||||
sha_transform(struct SHA_INFO *sha_info) {
|
||||
int i;
|
||||
LONG temp, A, B, C, D, E, W[80];
|
||||
|
||||
__pragma_loopbound(16, 16);
|
||||
for (i = 0; i < 16; ++i)
|
||||
W[i] = sha_info->data[i];
|
||||
__pragma_loopbound(64, 64);
|
||||
for (i = 16; i < 80; ++i)
|
||||
W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
|
||||
|
||||
A = sha_info->digest[0];
|
||||
B = sha_info->digest[1];
|
||||
C = sha_info->digest[2];
|
||||
D = sha_info->digest[3];
|
||||
E = sha_info->digest[4];
|
||||
|
||||
__pragma_loopbound(20, 20);
|
||||
for (i = 0; i < 20; ++i) {
|
||||
FUNC(1, i);
|
||||
}
|
||||
__pragma_loopbound(20, 20);
|
||||
for (i = 20; i < 40; ++i) {
|
||||
FUNC(2, i);
|
||||
}
|
||||
__pragma_loopbound(20, 20);
|
||||
for (i = 40; i < 60; ++i) {
|
||||
FUNC(3, i);
|
||||
}
|
||||
__pragma_loopbound(20, 20);
|
||||
for (i = 60; i < 80; ++i) {
|
||||
FUNC(4, i);
|
||||
}
|
||||
sha_info->digest[0] += A;
|
||||
sha_info->digest[1] += B;
|
||||
sha_info->digest[2] += C;
|
||||
sha_info->digest[3] += D;
|
||||
sha_info->digest[4] += E;
|
||||
}
|
||||
|
||||
/* change endianness of data */
|
||||
void
|
||||
sha_byte_reverse(LONG *buffer, int count) {
|
||||
int i;
|
||||
BYTE ct[4], *cp;
|
||||
|
||||
count /= sizeof(LONG);
|
||||
cp = (BYTE *) buffer;
|
||||
__pragma_loopbound(16, 16);
|
||||
for (i = 0; i < count; ++i) {
|
||||
ct[0] = cp[0];
|
||||
ct[1] = cp[1];
|
||||
ct[2] = cp[2];
|
||||
ct[3] = cp[3];
|
||||
cp[0] = ct[3];
|
||||
cp[1] = ct[2];
|
||||
cp[2] = ct[1];
|
||||
cp[3] = ct[0];
|
||||
cp += sizeof(LONG);
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize the SHA digest */
|
||||
void
|
||||
sha_init(void) {
|
||||
int i;
|
||||
sha_info.digest[0] = 0x67452301L;
|
||||
sha_info.digest[1] = 0xefcdab89L;
|
||||
sha_info.digest[2] = 0x98badcfeL;
|
||||
sha_info.digest[3] = 0x10325476L;
|
||||
sha_info.digest[4] = 0xc3d2e1f0L;
|
||||
sha_info.count_lo = 0L;
|
||||
sha_info.count_hi = 0L;
|
||||
for (i = 0; i < 16; i++)
|
||||
sha_info.data[i] = 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
sha_fread(void *ptr, size_t size, size_t count, struct SHA_MY_FILE *stream) {
|
||||
unsigned i = stream->cur_pos, i2 = 0;
|
||||
size_t number_of_chars_to_read =
|
||||
stream->size - stream->cur_pos >= size * count
|
||||
? size * count
|
||||
: stream->size - stream->cur_pos;
|
||||
__pragma_loopbound(0, 8192);
|
||||
while (i < stream->cur_pos + number_of_chars_to_read)
|
||||
((unsigned char *) ptr)[i2++] = stream->data[i++];
|
||||
stream->cur_pos += number_of_chars_to_read;
|
||||
return (number_of_chars_to_read);
|
||||
}
|
||||
|
||||
/* update the SHA digest */
|
||||
void
|
||||
sha_update(struct SHA_INFO *sha_info, BYTE *buffer, int count) {
|
||||
if ((sha_info->count_lo + ((LONG) count << 3)) < sha_info->count_lo)
|
||||
++sha_info->count_hi;
|
||||
sha_info->count_lo += (LONG) count << 3;
|
||||
sha_info->count_hi += (LONG) count >> 29;
|
||||
__pragma_loopbound(8, 128);
|
||||
while (count >= SHA_BLOCKSIZE) {
|
||||
sha_glibc_memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
|
||||
sha_byte_reverse(sha_info->data, SHA_BLOCKSIZE);
|
||||
sha_transform(sha_info);
|
||||
buffer += SHA_BLOCKSIZE;
|
||||
count -= SHA_BLOCKSIZE;
|
||||
}
|
||||
|
||||
sha_glibc_memcpy(sha_info->data, buffer, count);
|
||||
}
|
||||
|
||||
/* finish computing the SHA digest */
|
||||
void
|
||||
sha_final(struct SHA_INFO *sha_info) {
|
||||
int count;
|
||||
LONG lo_bit_count, hi_bit_count;
|
||||
|
||||
lo_bit_count = sha_info->count_lo;
|
||||
hi_bit_count = sha_info->count_hi;
|
||||
count = (int) ((lo_bit_count >> 3) & 0x3f);
|
||||
((BYTE *) sha_info->data)[count++] = 0x80;
|
||||
if (count > 56) {
|
||||
sha_glibc_memset((BYTE *) &sha_info->data + count, 0, 64 - count);
|
||||
sha_byte_reverse(sha_info->data, SHA_BLOCKSIZE);
|
||||
sha_transform(sha_info);
|
||||
sha_glibc_memset(&sha_info->data, 0, 56);
|
||||
} else
|
||||
sha_glibc_memset((BYTE *) &sha_info->data + count, 0, 56 - count);
|
||||
|
||||
sha_byte_reverse(sha_info->data, SHA_BLOCKSIZE);
|
||||
sha_info->data[14] = hi_bit_count;
|
||||
sha_info->data[15] = lo_bit_count;
|
||||
sha_transform(sha_info);
|
||||
}
|
||||
|
||||
/* compute the SHA digest of a FILE stream */
|
||||
|
||||
void
|
||||
sha_stream(struct SHA_INFO *sha_info, struct SHA_MY_FILE *fin) {
|
||||
int i;
|
||||
BYTE data[BLOCK_SIZE];
|
||||
__pragma_loopbound(5, 5);
|
||||
while ((i = sha_fread(data, 1, BLOCK_SIZE, fin)) > 0)
|
||||
sha_update(sha_info, data, i);
|
||||
|
||||
sha_final(sha_info);
|
||||
}
|
||||
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
||||
sha_main(void) {
|
||||
struct SHA_MY_FILE fin;
|
||||
fin.data = sha_data;
|
||||
fin.size = 32743; // set size = 3247552 for input_large
|
||||
fin.cur_pos = 0;
|
||||
sha_stream(&sha_info, &fin);
|
||||
}
|
||||
|
||||
int
|
||||
sha_return(void) {
|
||||
int sum = 0;
|
||||
sum = sha_info.data[14] + sha_info.data[15];
|
||||
return (sum - 261944 != 0);
|
||||
}
|
||||
|
||||
__attribute__((noinline)) __attribute__((export_name("main"))) int
|
||||
main(void) {
|
||||
sha_init();
|
||||
sha_main();
|
||||
return (sha_return());
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: sha.h
|
||||
|
||||
Author: Peter C. Gutmann's (heavily modified by Uwe Hollerbach)
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Source: Peter C. Gutmann's implementation as found in Applied Cryptography by
|
||||
Bruce Schneier
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: May be used, modified, and re-distributed freely.
|
||||
*/
|
||||
|
||||
#ifndef SHA_H
|
||||
#define SHA_H
|
||||
|
||||
/* Useful defines & typedefs */
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned long LONG;
|
||||
typedef unsigned size_t;
|
||||
|
||||
/* Type to use for unaligned operations. */
|
||||
#define SHA_BLOCKSIZE 64
|
||||
#define SHA_DIGESTSIZE 20
|
||||
#define LITTLE_ENDIAN
|
||||
#define NULL ((void *) 0)
|
||||
|
||||
extern unsigned volatile char sha_data[32743];
|
||||
|
||||
struct SHA_MY_FILE {
|
||||
unsigned volatile char *data;
|
||||
size_t size;
|
||||
unsigned cur_pos;
|
||||
};
|
||||
|
||||
struct SHA_INFO {
|
||||
LONG digest[5]; /* message digest */
|
||||
LONG count_lo, count_hi; /* 64-bit bit count */
|
||||
LONG data[16]; /* SHA data buffer */
|
||||
};
|
||||
|
||||
/*
|
||||
Forward declaration of functions
|
||||
*/
|
||||
void sha_transform(struct SHA_INFO *);
|
||||
void sha_byte_reverse(LONG *buffer, int count);
|
||||
void sha_init(void);
|
||||
size_t sha_fread(void *, size_t, size_t, struct SHA_MY_FILE *);
|
||||
void sha_update(struct SHA_INFO *, BYTE *, int);
|
||||
void sha_final(struct SHA_INFO *);
|
||||
void sha_stream(struct SHA_INFO *, struct SHA_MY_FILE *);
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
||||
sha_main(void);
|
||||
int sha_return(void);
|
||||
__attribute__((noinline)) __attribute__((export_name("main"))) int main(void);
|
||||
|
||||
#endif // SHA_H
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,78 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: memcpy.c
|
||||
|
||||
Author: Torbjorn Granlund
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Copy memory to memory until the specified number of bytes
|
||||
has been copied. Overlap is NOT handled correctly.
|
||||
|
||||
Source: GNU C Library
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: Copyright (C) 1991, 1997, 2003 Free Software Foundation, Inc.
|
||||
*/
|
||||
|
||||
#include "memcpy.h"
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
__attribute__((always_inline)) static inline void *
|
||||
sha_glibc_memcpy(void *dstpp, const void *srcpp, size_t len) {
|
||||
unsigned long int dstp = (long int) dstpp;
|
||||
unsigned long int srcp = (long int) srcpp;
|
||||
size_t __nbytes;
|
||||
|
||||
/* Copy from the beginning to the end. */
|
||||
|
||||
/* If there not too few bytes to copy, use word copy. */
|
||||
if (len >= OP_T_THRES) {
|
||||
/* Copy just a few bytes to make DSTP aligned. */
|
||||
len -= (-dstp) % OPSIZ;
|
||||
|
||||
__nbytes = (-dstp) % OPSIZ;
|
||||
__pragma_loopbound(0, 0);
|
||||
while (__nbytes > 0) {
|
||||
BYTE __x = ((BYTE *) srcp)[0];
|
||||
srcp += 1;
|
||||
__nbytes -= 1;
|
||||
((BYTE *) dstp)[0] = __x;
|
||||
dstp += 1;
|
||||
}
|
||||
|
||||
/* Copy whole pages from SRCP to DSTP by virtual address manipulation,
|
||||
as much as possible. */
|
||||
|
||||
PAGE_COPY_FWD_MAYBE(dstp, srcp, len, len);
|
||||
|
||||
/* Copy from SRCP to DSTP taking advantage of the known alignment of
|
||||
DSTP. Number of bytes remaining is put in the third argument,
|
||||
i.e. in LEN. This number may vary from machine to machine. */
|
||||
|
||||
WORD_COPY_FWD(dstp, srcp, len, len);
|
||||
|
||||
/* Fall out and copy the tail. */
|
||||
}
|
||||
|
||||
/* There are just a few bytes to copy. Use byte memory operations. */
|
||||
__nbytes = len;
|
||||
__pragma_loopbound(0, 7);
|
||||
while (__nbytes > 0) {
|
||||
BYTE __x = ((BYTE *) srcp)[0];
|
||||
srcp += 1;
|
||||
__nbytes -= 1;
|
||||
((BYTE *) dstp)[0] = __x;
|
||||
dstp += 1;
|
||||
}
|
||||
|
||||
return dstpp;
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: memcpy.c
|
||||
|
||||
Author: Torbjorn Granlund
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Copy memory to memory until the specified number of bytes
|
||||
has been copied. Overlap is NOT handled correctly.
|
||||
|
||||
Source: GNU C Library
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: Copyright (C) 1991, 1997, 2003 Free Software Foundation, Inc.
|
||||
*/
|
||||
|
||||
#include "memhelper.h"
|
||||
#include "sha.h"
|
||||
|
||||
__attribute__((always_inline)) static inline void *
|
||||
sha_glibc_memcpy(void *dstpp, const void *srcpp, size_t len);
|
||||
@ -0,0 +1,151 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: memhelper.c
|
||||
|
||||
Author: Torbjorn Granlund
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Copy block beginning at SRCP to
|
||||
block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
|
||||
Both SRCP and DSTP should be aligned for memory operations on `op_t's.
|
||||
|
||||
Source: GNU C Library
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: Copyright (C) 1991, 1997, 2003 Free Software Foundation, Inc.
|
||||
*/
|
||||
|
||||
#include "memhelper.h"
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
int printf(const char *restrict format, ...);
|
||||
/* sha_wordcopy_fwd_aligned -- Copy block beginning at SRCP to
|
||||
block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
|
||||
Both SRCP and DSTP should be aligned for memory operations on `op_t's.
|
||||
*/
|
||||
|
||||
__attribute__((always_inline)) static inline void
|
||||
sha_wordcopy_fwd_aligned(long int dstp, long int srcp, size_t len) {
|
||||
op_t a0 = 0;
|
||||
op_t a1 = 0;
|
||||
char switch_target;
|
||||
|
||||
switch (len % 8) {
|
||||
case 2:
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
srcp -= 6 * OPSIZ;
|
||||
dstp -= 7 * OPSIZ;
|
||||
len += 6;
|
||||
switch_target = 1;
|
||||
break;
|
||||
case 3:
|
||||
a1 = ((op_t *) srcp)[0];
|
||||
srcp -= 5 * OPSIZ;
|
||||
dstp -= 6 * OPSIZ;
|
||||
len += 5;
|
||||
switch_target = 2;
|
||||
break;
|
||||
case 4:
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
srcp -= 4 * OPSIZ;
|
||||
dstp -= 5 * OPSIZ;
|
||||
len += 4;
|
||||
switch_target = 3;
|
||||
break;
|
||||
case 5:
|
||||
a1 = ((op_t *) srcp)[0];
|
||||
srcp -= 3 * OPSIZ;
|
||||
dstp -= 4 * OPSIZ;
|
||||
len += 3;
|
||||
switch_target = 4;
|
||||
break;
|
||||
case 6:
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
srcp -= 2 * OPSIZ;
|
||||
dstp -= 3 * OPSIZ;
|
||||
len += 2;
|
||||
switch_target = 5;
|
||||
break;
|
||||
case 7:
|
||||
a1 = ((op_t *) srcp)[0];
|
||||
srcp -= 1 * OPSIZ;
|
||||
dstp -= 2 * OPSIZ;
|
||||
len += 1;
|
||||
switch_target = 6;
|
||||
break;
|
||||
case 0:
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
return;
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
srcp -= 0 * OPSIZ;
|
||||
dstp -= 1 * OPSIZ;
|
||||
switch_target = 7;
|
||||
break;
|
||||
case 1:
|
||||
a1 = ((op_t *) srcp)[0];
|
||||
srcp -= -1 * OPSIZ;
|
||||
dstp -= 0 * OPSIZ;
|
||||
len -= 1;
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0) {
|
||||
((op_t *) dstp)[0] = a1;
|
||||
return;
|
||||
} else {
|
||||
switch_target = 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__pragma_loopbound(1, 2); // max 1
|
||||
do {
|
||||
switch (switch_target) {
|
||||
case 8:
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
((op_t *) dstp)[0] = a1;
|
||||
break;
|
||||
case 7:
|
||||
a1 = ((op_t *) srcp)[1];
|
||||
((op_t *) dstp)[1] = a0;
|
||||
break;
|
||||
case 6:
|
||||
a0 = ((op_t *) srcp)[2];
|
||||
((op_t *) dstp)[2] = a1;
|
||||
break;
|
||||
case 5:
|
||||
a1 = ((op_t *) srcp)[3];
|
||||
((op_t *) dstp)[3] = a0;
|
||||
break;
|
||||
case 4:
|
||||
a0 = ((op_t *) srcp)[4];
|
||||
((op_t *) dstp)[4] = a1;
|
||||
break;
|
||||
case 3:
|
||||
a1 = ((op_t *) srcp)[5];
|
||||
((op_t *) dstp)[5] = a0;
|
||||
break;
|
||||
case 2:
|
||||
a0 = ((op_t *) srcp)[6];
|
||||
((op_t *) dstp)[6] = a1;
|
||||
break;
|
||||
case 1:
|
||||
a1 = ((op_t *) srcp)[7];
|
||||
((op_t *) dstp)[7] = a0;
|
||||
break;
|
||||
}
|
||||
|
||||
srcp += 8 * OPSIZ;
|
||||
dstp += 8 * OPSIZ;
|
||||
len -= 8;
|
||||
switch_target = 8;
|
||||
} while (len != 0);
|
||||
|
||||
((op_t *) dstp)[0] = a1;
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: memhelper.h
|
||||
|
||||
Author: Peter C. Gutmann's (heavily modified by Uwe Hollerbach)
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Source: Peter C. Gutmann's implementation as found in Applied Cryptography by
|
||||
Bruce Schneier
|
||||
|
||||
License: GNU Lesser General Public License
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
*/
|
||||
|
||||
#ifndef MEM_HELPER_H
|
||||
#define MEM_HELPER_H
|
||||
|
||||
#include "sha.h"
|
||||
|
||||
__attribute__((always_inline)) static inline void
|
||||
sha_wordcopy_fwd_aligned(long int dstp, long int srcp, size_t len);
|
||||
|
||||
/* Type to use for aligned memory operations.
|
||||
This should normally be the biggest type supported by a single load
|
||||
and store. */
|
||||
#define op_t unsigned long int
|
||||
#define OPSIZ (sizeof(op_t))
|
||||
|
||||
/* Threshold value for when to enter the unrolled loops. */
|
||||
#define OP_T_THRES 16
|
||||
|
||||
#define PAGE_COPY_FWD_MAYBE(dstp, srcp, nbytes_left, nbytes)
|
||||
#define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
|
||||
|
||||
/* Copy *up to* NBYTES bytes from SRC_BP to DST_BP, with
|
||||
the assumption that DST_BP is aligned on an OPSIZ multiple. If
|
||||
not all bytes could be easily copied, store remaining number of bytes
|
||||
in NBYTES_LEFT, otherwise store 0. */
|
||||
#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \
|
||||
{ \
|
||||
if (src_bp % OPSIZ == 0) \
|
||||
sha_wordcopy_fwd_aligned(dst_bp, src_bp, (nbytes) / OPSIZ); \
|
||||
else \
|
||||
src_bp += (nbytes) & -OPSIZ; \
|
||||
dst_bp += (nbytes) & -OPSIZ; \
|
||||
(nbytes_left) = (nbytes) % OPSIZ; \
|
||||
}
|
||||
|
||||
#endif // MEM_HELPER_H
|
||||
@ -0,0 +1,92 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: menset.h
|
||||
|
||||
Author: Torbjorn Granlund
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Copy memory to memory until the specified number of bytes
|
||||
has been copied. Overlap is NOT handled correctly.
|
||||
|
||||
Source: GNU C Library
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: GNU Lesser General Public License
|
||||
*/
|
||||
#include "memset.h"
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
int printf(const char *restrict format, ...);
|
||||
|
||||
__attribute__((always_inline)) static inline void *
|
||||
sha_glibc_memset(void *dstpp, int c, size_t len) {
|
||||
long int dstp = (long int) dstpp;
|
||||
|
||||
if (len >= 8) {
|
||||
size_t xlen;
|
||||
op_t cccc;
|
||||
|
||||
cccc = (unsigned char) c;
|
||||
cccc |= cccc << 8;
|
||||
cccc |= cccc << 16;
|
||||
if (OPSIZ > 4)
|
||||
/* Do the shift in two steps to avoid warning if long has 32 bits.
|
||||
*/
|
||||
cccc |= (cccc << 16) << 16;
|
||||
|
||||
/* There are at least some bytes to set.
|
||||
No need to test for LEN == 0 in this alignment loop. */
|
||||
__pragma_loopbound(3, 3);
|
||||
while (dstp % OPSIZ != 0) {
|
||||
((BYTE *) dstp)[0] = c;
|
||||
dstp += 1;
|
||||
len -= 1;
|
||||
}
|
||||
|
||||
/* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */
|
||||
xlen = len / (OPSIZ * 8);
|
||||
__pragma_loopbound(0, 1);
|
||||
while (xlen > 0) {
|
||||
((op_t *) dstp)[0] = cccc;
|
||||
((op_t *) dstp)[1] = cccc;
|
||||
((op_t *) dstp)[2] = cccc;
|
||||
((op_t *) dstp)[3] = cccc;
|
||||
((op_t *) dstp)[4] = cccc;
|
||||
((op_t *) dstp)[5] = cccc;
|
||||
((op_t *) dstp)[6] = cccc;
|
||||
((op_t *) dstp)[7] = cccc;
|
||||
dstp += 8 * OPSIZ;
|
||||
xlen -= 1;
|
||||
}
|
||||
len %= OPSIZ * 8;
|
||||
|
||||
/* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */
|
||||
xlen = len / OPSIZ;
|
||||
__pragma_loopbound(1, 2);
|
||||
while (xlen > 0) {
|
||||
((op_t *) dstp)[0] = cccc;
|
||||
dstp += OPSIZ;
|
||||
xlen -= 1;
|
||||
}
|
||||
len %= OPSIZ;
|
||||
}
|
||||
|
||||
/* Write the last few bytes. */
|
||||
__pragma_loopbound(0, 0);
|
||||
while (len > 0) {
|
||||
((BYTE *) dstp)[0] = c;
|
||||
dstp += 1;
|
||||
len -= 1;
|
||||
}
|
||||
|
||||
return (void *) dstpp;
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: menset.h
|
||||
|
||||
Author: Torbjorn Granlund
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Copy memory to memory until the specified number of bytes
|
||||
has been copied. Overlap is NOT handled correctly.
|
||||
|
||||
Source: GNU C Library
|
||||
|
||||
License: GNU Lesser General Public License
|
||||
|
||||
Changes: no major functional changes
|
||||
*/
|
||||
#include "memhelper.h"
|
||||
|
||||
__attribute__((always_inline)) static inline void *
|
||||
sha_glibc_memset(void *dstpp, int c, size_t len);
|
||||
@ -0,0 +1,241 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: sha.c
|
||||
|
||||
Author: Peter C. Gutmann's (heavily modified by Uwe Hollerbach)
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Source: Peter C. Gutmann's implementation as found in Applied Cryptography by
|
||||
Bruce Schneier
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: GNU Lesser General Public License
|
||||
|
||||
*/
|
||||
|
||||
#include "sha.h"
|
||||
#include "memcpy.h"
|
||||
#include "memset.h"
|
||||
|
||||
/*
|
||||
Declaration of global variables
|
||||
*/
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
|
||||
#include "input_small.c"
|
||||
#include "memcpy.c"
|
||||
#include "memhelper.c"
|
||||
#include "memset.c"
|
||||
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
struct SHA_INFO sha_info;
|
||||
|
||||
/* SHA f()-functions */
|
||||
#define f1(x, y, z) ((x & y) | (~x & z))
|
||||
#define f2(x, y, z) (x ^ y ^ z)
|
||||
#define f3(x, y, z) ((x & y) | (x & z) | (y & z))
|
||||
#define f4(x, y, z) (x ^ y ^ z)
|
||||
|
||||
/* SHA constants */
|
||||
#define CONST1 0x5a827999L
|
||||
#define CONST2 0x6ed9eba1L
|
||||
#define CONST3 0x8f1bbcdcL
|
||||
#define CONST4 0xca62c1d6L
|
||||
|
||||
#define BLOCK_SIZE 8192
|
||||
|
||||
/* 32-bit rotate */
|
||||
|
||||
#define ROT32(x, n) ((x << n) | (x >> (32 - n)))
|
||||
|
||||
#define FUNC(n, i) \
|
||||
temp = ROT32(A, 5) + f##n(B, C, D) + E + W[i] + CONST##n; \
|
||||
E = D; \
|
||||
D = C; \
|
||||
C = ROT32(B, 30); \
|
||||
B = A; \
|
||||
A = temp
|
||||
|
||||
/* do SHA transformation */
|
||||
__attribute__((always_inline)) static inline void
|
||||
sha_transform(struct SHA_INFO *sha_info) {
|
||||
int i;
|
||||
LONG temp, A, B, C, D, E, W[80];
|
||||
|
||||
__pragma_loopbound(16, 16);
|
||||
for (i = 0; i < 16; ++i)
|
||||
W[i] = sha_info->data[i];
|
||||
__pragma_loopbound(64, 64);
|
||||
for (i = 16; i < 80; ++i)
|
||||
W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
|
||||
|
||||
A = sha_info->digest[0];
|
||||
B = sha_info->digest[1];
|
||||
C = sha_info->digest[2];
|
||||
D = sha_info->digest[3];
|
||||
E = sha_info->digest[4];
|
||||
|
||||
__pragma_loopbound(20, 20);
|
||||
for (i = 0; i < 20; ++i) {
|
||||
FUNC(1, i);
|
||||
}
|
||||
__pragma_loopbound(20, 20);
|
||||
for (i = 20; i < 40; ++i) {
|
||||
FUNC(2, i);
|
||||
}
|
||||
__pragma_loopbound(20, 20);
|
||||
for (i = 40; i < 60; ++i) {
|
||||
FUNC(3, i);
|
||||
}
|
||||
__pragma_loopbound(20, 20);
|
||||
for (i = 60; i < 80; ++i) {
|
||||
FUNC(4, i);
|
||||
}
|
||||
sha_info->digest[0] += A;
|
||||
sha_info->digest[1] += B;
|
||||
sha_info->digest[2] += C;
|
||||
sha_info->digest[3] += D;
|
||||
sha_info->digest[4] += E;
|
||||
}
|
||||
|
||||
/* change endianness of data */
|
||||
__attribute__((always_inline)) static inline void
|
||||
sha_byte_reverse(LONG *buffer, int count) {
|
||||
int i;
|
||||
BYTE ct[4], *cp;
|
||||
|
||||
count /= sizeof(LONG);
|
||||
cp = (BYTE *) buffer;
|
||||
__pragma_loopbound(16, 16);
|
||||
for (i = 0; i < count; ++i) {
|
||||
ct[0] = cp[0];
|
||||
ct[1] = cp[1];
|
||||
ct[2] = cp[2];
|
||||
ct[3] = cp[3];
|
||||
cp[0] = ct[3];
|
||||
cp[1] = ct[2];
|
||||
cp[2] = ct[1];
|
||||
cp[3] = ct[0];
|
||||
cp += sizeof(LONG);
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize the SHA digest */
|
||||
__attribute__((always_inline)) static inline void
|
||||
sha_init(void) {
|
||||
int i;
|
||||
sha_info.digest[0] = 0x67452301L;
|
||||
sha_info.digest[1] = 0xefcdab89L;
|
||||
sha_info.digest[2] = 0x98badcfeL;
|
||||
sha_info.digest[3] = 0x10325476L;
|
||||
sha_info.digest[4] = 0xc3d2e1f0L;
|
||||
sha_info.count_lo = 0L;
|
||||
sha_info.count_hi = 0L;
|
||||
for (i = 0; i < 16; i++)
|
||||
sha_info.data[i] = 0;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline size_t
|
||||
sha_fread(void *ptr, size_t size, size_t count, struct SHA_MY_FILE *stream) {
|
||||
unsigned i = stream->cur_pos, i2 = 0;
|
||||
size_t number_of_chars_to_read =
|
||||
stream->size - stream->cur_pos >= size * count
|
||||
? size * count
|
||||
: stream->size - stream->cur_pos;
|
||||
__pragma_loopbound(0, 8192);
|
||||
while (i < stream->cur_pos + number_of_chars_to_read)
|
||||
((unsigned char *) ptr)[i2++] = stream->data[i++];
|
||||
stream->cur_pos += number_of_chars_to_read;
|
||||
return (number_of_chars_to_read);
|
||||
}
|
||||
|
||||
/* update the SHA digest */
|
||||
__attribute__((always_inline)) static inline void
|
||||
sha_update(struct SHA_INFO *sha_info, BYTE *buffer, int count) {
|
||||
if ((sha_info->count_lo + ((LONG) count << 3)) < sha_info->count_lo)
|
||||
++sha_info->count_hi;
|
||||
sha_info->count_lo += (LONG) count << 3;
|
||||
sha_info->count_hi += (LONG) count >> 29;
|
||||
__pragma_loopbound(8, 128);
|
||||
while (count >= SHA_BLOCKSIZE) {
|
||||
sha_glibc_memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
|
||||
sha_byte_reverse(sha_info->data, SHA_BLOCKSIZE);
|
||||
sha_transform(sha_info);
|
||||
buffer += SHA_BLOCKSIZE;
|
||||
count -= SHA_BLOCKSIZE;
|
||||
}
|
||||
|
||||
sha_glibc_memcpy(sha_info->data, buffer, count);
|
||||
}
|
||||
|
||||
/* finish computing the SHA digest */
|
||||
__attribute__((always_inline)) static inline void
|
||||
sha_final(struct SHA_INFO *sha_info) {
|
||||
int count;
|
||||
LONG lo_bit_count, hi_bit_count;
|
||||
|
||||
lo_bit_count = sha_info->count_lo;
|
||||
hi_bit_count = sha_info->count_hi;
|
||||
count = (int) ((lo_bit_count >> 3) & 0x3f);
|
||||
((BYTE *) sha_info->data)[count++] = 0x80;
|
||||
if (count > 56) {
|
||||
sha_glibc_memset((BYTE *) &sha_info->data + count, 0, 64 - count);
|
||||
sha_byte_reverse(sha_info->data, SHA_BLOCKSIZE);
|
||||
sha_transform(sha_info);
|
||||
sha_glibc_memset(&sha_info->data, 0, 56);
|
||||
} else
|
||||
sha_glibc_memset((BYTE *) &sha_info->data + count, 0, 56 - count);
|
||||
|
||||
sha_byte_reverse(sha_info->data, SHA_BLOCKSIZE);
|
||||
sha_info->data[14] = hi_bit_count;
|
||||
sha_info->data[15] = lo_bit_count;
|
||||
sha_transform(sha_info);
|
||||
}
|
||||
|
||||
/* compute the SHA digest of a FILE stream */
|
||||
|
||||
__attribute__((always_inline)) static inline void
|
||||
sha_stream(struct SHA_INFO *sha_info, struct SHA_MY_FILE *fin) {
|
||||
int i;
|
||||
BYTE data[BLOCK_SIZE];
|
||||
__pragma_loopbound(5, 5);
|
||||
while ((i = sha_fread(data, 1, BLOCK_SIZE, fin)) > 0)
|
||||
sha_update(sha_info, data, i);
|
||||
|
||||
sha_final(sha_info);
|
||||
}
|
||||
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
||||
sha_main(void) {
|
||||
struct SHA_MY_FILE fin;
|
||||
fin.data = sha_data;
|
||||
fin.size = 32743; // set size = 3247552 for input_large
|
||||
fin.cur_pos = 0;
|
||||
sha_stream(&sha_info, &fin);
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline int
|
||||
sha_return(void) {
|
||||
int sum = 0;
|
||||
sum = sha_info.data[14] + sha_info.data[15];
|
||||
return (sum - 261944 != 0);
|
||||
}
|
||||
|
||||
__attribute__((noinline)) __attribute__((export_name("main")))
|
||||
__attribute__((noinline)) __attribute__((export_name("main"))) int
|
||||
main(void) {
|
||||
sha_init();
|
||||
sha_main();
|
||||
return (sha_return());
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: sha.h
|
||||
|
||||
Author: Peter C. Gutmann's (heavily modified by Uwe Hollerbach)
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Source: Peter C. Gutmann's implementation as found in Applied Cryptography by
|
||||
Bruce Schneier
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: May be used, modified, and re-distributed freely.
|
||||
*/
|
||||
|
||||
#ifndef SHA_H
|
||||
#define SHA_H
|
||||
|
||||
/* Useful defines & typedefs */
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned long LONG;
|
||||
typedef unsigned size_t;
|
||||
|
||||
/* Type to use for unaligned operations. */
|
||||
#define SHA_BLOCKSIZE 64
|
||||
#define SHA_DIGESTSIZE 20
|
||||
#define LITTLE_ENDIAN
|
||||
#define NULL ((void *) 0)
|
||||
|
||||
extern unsigned volatile char sha_data[32743];
|
||||
|
||||
struct SHA_MY_FILE {
|
||||
unsigned volatile char *data;
|
||||
size_t size;
|
||||
unsigned cur_pos;
|
||||
};
|
||||
|
||||
struct SHA_INFO {
|
||||
LONG digest[5]; /* message digest */
|
||||
LONG count_lo, count_hi; /* 64-bit bit count */
|
||||
LONG data[16]; /* SHA data buffer */
|
||||
};
|
||||
|
||||
/*
|
||||
Forward declaration of functions
|
||||
*/
|
||||
__attribute__((always_inline)) static inline void
|
||||
sha_transform(struct SHA_INFO *);
|
||||
__attribute__((always_inline)) static inline void sha_byte_reverse(LONG *buffer,
|
||||
int count);
|
||||
__attribute__((always_inline)) static inline void sha_init(void);
|
||||
__attribute__((always_inline)) static inline size_t
|
||||
sha_fread(void *, size_t, size_t, struct SHA_MY_FILE *);
|
||||
__attribute__((always_inline)) static inline void sha_update(struct SHA_INFO *,
|
||||
BYTE *, int);
|
||||
__attribute__((always_inline)) static inline void sha_final(struct SHA_INFO *);
|
||||
__attribute__((always_inline)) static inline void
|
||||
sha_stream(struct SHA_INFO *, struct SHA_MY_FILE *);
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
||||
sha_main(void);
|
||||
__attribute__((always_inline)) static inline int sha_return(void);
|
||||
__attribute__((noinline)) __attribute__((export_name("main")))
|
||||
__attribute__((noinline)) __attribute__((export_name("main"))) int
|
||||
main(void);
|
||||
|
||||
#endif // SHA_H
|
||||
1657
targets/wasm-tacle/kernel/sha/input_small.c
Executable file
1657
targets/wasm-tacle/kernel/sha/input_small.c
Executable file
File diff suppressed because it is too large
Load Diff
74
targets/wasm-tacle/kernel/sha/memcpy.c
Executable file
74
targets/wasm-tacle/kernel/sha/memcpy.c
Executable file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: memcpy.c
|
||||
|
||||
Author: Torbjorn Granlund
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Copy memory to memory until the specified number of bytes
|
||||
has been copied. Overlap is NOT handled correctly.
|
||||
|
||||
Source: GNU C Library
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: Copyright (C) 1991, 1997, 2003 Free Software Foundation, Inc.
|
||||
*/
|
||||
|
||||
#include "memcpy.h"
|
||||
|
||||
void *sha_glibc_memcpy( void *dstpp, const void *srcpp, size_t len )
|
||||
{
|
||||
unsigned long int dstp = ( long int ) dstpp;
|
||||
unsigned long int srcp = ( long int ) srcpp;
|
||||
size_t __nbytes;
|
||||
|
||||
/* Copy from the beginning to the end. */
|
||||
|
||||
/* If there not too few bytes to copy, use word copy. */
|
||||
if ( len >= OP_T_THRES ) {
|
||||
/* Copy just a few bytes to make DSTP aligned. */
|
||||
len -= ( -dstp ) % OPSIZ;
|
||||
|
||||
__nbytes = ( -dstp ) % OPSIZ;
|
||||
_Pragma( "loopbound min 0 max 0" )
|
||||
while ( __nbytes > 0 ) {
|
||||
BYTE __x = ( ( BYTE * ) srcp )[ 0 ];
|
||||
srcp += 1;
|
||||
__nbytes -= 1;
|
||||
( ( BYTE * ) dstp )[ 0 ] = __x;
|
||||
dstp += 1;
|
||||
}
|
||||
|
||||
/* Copy whole pages from SRCP to DSTP by virtual address manipulation,
|
||||
as much as possible. */
|
||||
|
||||
PAGE_COPY_FWD_MAYBE ( dstp, srcp, len, len );
|
||||
|
||||
/* Copy from SRCP to DSTP taking advantage of the known alignment of
|
||||
DSTP. Number of bytes remaining is put in the third argument,
|
||||
i.e. in LEN. This number may vary from machine to machine. */
|
||||
|
||||
WORD_COPY_FWD ( dstp, srcp, len, len );
|
||||
|
||||
/* Fall out and copy the tail. */
|
||||
}
|
||||
|
||||
/* There are just a few bytes to copy. Use byte memory operations. */
|
||||
__nbytes = len;
|
||||
_Pragma( "loopbound min 0 max 7" )
|
||||
while ( __nbytes > 0 ) {
|
||||
BYTE __x = ( ( BYTE * ) srcp )[ 0 ];
|
||||
srcp += 1;
|
||||
__nbytes -= 1;
|
||||
( ( BYTE * ) dstp )[ 0 ] = __x;
|
||||
dstp += 1;
|
||||
}
|
||||
|
||||
return dstpp;
|
||||
}
|
||||
|
||||
26
targets/wasm-tacle/kernel/sha/memcpy.h
Executable file
26
targets/wasm-tacle/kernel/sha/memcpy.h
Executable file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: memcpy.c
|
||||
|
||||
Author: Torbjorn Granlund
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Copy memory to memory until the specified number of bytes
|
||||
has been copied. Overlap is NOT handled correctly.
|
||||
|
||||
Source: GNU C Library
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: Copyright (C) 1991, 1997, 2003 Free Software Foundation, Inc.
|
||||
*/
|
||||
|
||||
#include "memhelper.h"
|
||||
#include "sha.h"
|
||||
|
||||
void *sha_glibc_memcpy( void *dstpp, const void *srcpp, size_t len );
|
||||
|
||||
146
targets/wasm-tacle/kernel/sha/memhelper.c
Executable file
146
targets/wasm-tacle/kernel/sha/memhelper.c
Executable file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: memhelper.c
|
||||
|
||||
Author: Torbjorn Granlund
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Copy block beginning at SRCP to
|
||||
block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
|
||||
Both SRCP and DSTP should be aligned for memory operations on `op_t's.
|
||||
|
||||
Source: GNU C Library
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: Copyright (C) 1991, 1997, 2003 Free Software Foundation, Inc.
|
||||
*/
|
||||
|
||||
#include "memhelper.h"
|
||||
int printf(const char * restrict format, ... );
|
||||
/* sha_wordcopy_fwd_aligned -- Copy block beginning at SRCP to
|
||||
block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
|
||||
Both SRCP and DSTP should be aligned for memory operations on `op_t's.
|
||||
*/
|
||||
|
||||
void sha_wordcopy_fwd_aligned( long int dstp, long int srcp, size_t len )
|
||||
{
|
||||
op_t a0 = 0;
|
||||
op_t a1 = 0;
|
||||
char switch_target;
|
||||
|
||||
switch ( len % 8 ) {
|
||||
case 2:
|
||||
a0 = ( ( op_t * ) srcp )[ 0 ];
|
||||
srcp -= 6 * OPSIZ;
|
||||
dstp -= 7 * OPSIZ;
|
||||
len += 6;
|
||||
switch_target = 1;
|
||||
break;
|
||||
case 3:
|
||||
a1 = ( ( op_t * ) srcp )[ 0 ];
|
||||
srcp -= 5 * OPSIZ;
|
||||
dstp -= 6 * OPSIZ;
|
||||
len += 5;
|
||||
switch_target = 2;
|
||||
break;
|
||||
case 4:
|
||||
a0 = ( ( op_t * ) srcp )[ 0 ];
|
||||
srcp -= 4 * OPSIZ;
|
||||
dstp -= 5 * OPSIZ;
|
||||
len += 4;
|
||||
switch_target = 3;
|
||||
break;
|
||||
case 5:
|
||||
a1 = ( ( op_t * ) srcp )[ 0 ];
|
||||
srcp -= 3 * OPSIZ;
|
||||
dstp -= 4 * OPSIZ;
|
||||
len += 3;
|
||||
switch_target = 4;
|
||||
break;
|
||||
case 6:
|
||||
a0 = ( ( op_t * ) srcp )[ 0 ];
|
||||
srcp -= 2 * OPSIZ;
|
||||
dstp -= 3 * OPSIZ;
|
||||
len += 2;
|
||||
switch_target = 5;
|
||||
break;
|
||||
case 7:
|
||||
a1 = ( ( op_t * ) srcp )[ 0 ];
|
||||
srcp -= 1 * OPSIZ;
|
||||
dstp -= 2 * OPSIZ;
|
||||
len += 1;
|
||||
switch_target = 6;
|
||||
break;
|
||||
case 0:
|
||||
if ( OP_T_THRES <= 3 * OPSIZ && len == 0 )
|
||||
return;
|
||||
a0 = ( ( op_t * ) srcp )[ 0 ];
|
||||
srcp -= 0 * OPSIZ;
|
||||
dstp -= 1 * OPSIZ;
|
||||
switch_target = 7;
|
||||
break;
|
||||
case 1:
|
||||
a1 = ( ( op_t * ) srcp )[ 0 ];
|
||||
srcp -= -1 * OPSIZ;
|
||||
dstp -= 0 * OPSIZ;
|
||||
len -= 1;
|
||||
if ( OP_T_THRES <= 3 * OPSIZ && len == 0 ) {
|
||||
( ( op_t * ) dstp )[ 0 ] = a1;
|
||||
return;
|
||||
} else {
|
||||
switch_target = 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_Pragma( "loopbound min 1 max 2" ) //max 1
|
||||
do {
|
||||
switch ( switch_target ) {
|
||||
case 8:
|
||||
a0 = ( ( op_t * ) srcp )[ 0 ];
|
||||
( ( op_t * ) dstp )[ 0 ] = a1;
|
||||
break;
|
||||
case 7:
|
||||
a1 = ( ( op_t * ) srcp )[ 1 ];
|
||||
( ( op_t * ) dstp )[ 1 ] = a0;
|
||||
break;
|
||||
case 6:
|
||||
a0 = ( ( op_t * ) srcp )[ 2 ];
|
||||
( ( op_t * ) dstp )[ 2 ] = a1;
|
||||
break;
|
||||
case 5:
|
||||
a1 = ( ( op_t * ) srcp )[ 3 ];
|
||||
( ( op_t * ) dstp )[ 3 ] = a0;
|
||||
break;
|
||||
case 4:
|
||||
a0 = ( ( op_t * ) srcp )[ 4 ];
|
||||
( ( op_t * ) dstp )[ 4 ] = a1;
|
||||
break;
|
||||
case 3:
|
||||
a1 = ( ( op_t * ) srcp )[ 5 ];
|
||||
( ( op_t * ) dstp )[ 5 ] = a0;
|
||||
break;
|
||||
case 2:
|
||||
a0 = ( ( op_t * ) srcp )[ 6 ];
|
||||
( ( op_t * ) dstp )[ 6 ] = a1;
|
||||
break;
|
||||
case 1:
|
||||
a1 = ( ( op_t * ) srcp )[ 7 ];
|
||||
( ( op_t * ) dstp )[ 7 ] = a0;
|
||||
break;
|
||||
}
|
||||
|
||||
srcp += 8 * OPSIZ;
|
||||
dstp += 8 * OPSIZ;
|
||||
len -= 8;
|
||||
switch_target = 8;
|
||||
} while ( len != 0 );
|
||||
|
||||
( ( op_t * ) dstp )[ 0 ] = a1;
|
||||
}
|
||||
|
||||
55
targets/wasm-tacle/kernel/sha/memhelper.h
Executable file
55
targets/wasm-tacle/kernel/sha/memhelper.h
Executable file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: memhelper.h
|
||||
|
||||
Author: Peter C. Gutmann's (heavily modified by Uwe Hollerbach)
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Source: Peter C. Gutmann's implementation as found in Applied Cryptography by Bruce Schneier
|
||||
|
||||
License: GNU Lesser General Public License
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
*/
|
||||
|
||||
#ifndef MEM_HELPER_H
|
||||
#define MEM_HELPER_H
|
||||
|
||||
#include "sha.h"
|
||||
|
||||
void sha_wordcopy_fwd_aligned( long int dstp, long int srcp, size_t len );
|
||||
|
||||
/* Type to use for aligned memory operations.
|
||||
This should normally be the biggest type supported by a single load
|
||||
and store. */
|
||||
#define op_t unsigned long int
|
||||
#define OPSIZ (sizeof(op_t))
|
||||
|
||||
/* Threshold value for when to enter the unrolled loops. */
|
||||
#define OP_T_THRES 16
|
||||
|
||||
#define PAGE_COPY_FWD_MAYBE(dstp, srcp, nbytes_left, nbytes)
|
||||
#define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
|
||||
|
||||
|
||||
/* Copy *up to* NBYTES bytes from SRC_BP to DST_BP, with
|
||||
the assumption that DST_BP is aligned on an OPSIZ multiple. If
|
||||
not all bytes could be easily copied, store remaining number of bytes
|
||||
in NBYTES_LEFT, otherwise store 0. */
|
||||
#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \
|
||||
{ \
|
||||
if (src_bp % OPSIZ == 0) \
|
||||
sha_wordcopy_fwd_aligned (dst_bp, src_bp, (nbytes) / OPSIZ); \
|
||||
else \
|
||||
src_bp += (nbytes) & -OPSIZ; \
|
||||
dst_bp += (nbytes) & -OPSIZ; \
|
||||
(nbytes_left) = (nbytes) % OPSIZ; \
|
||||
}
|
||||
|
||||
#endif // MEM_HELPER_H
|
||||
|
||||
86
targets/wasm-tacle/kernel/sha/memset.c
Executable file
86
targets/wasm-tacle/kernel/sha/memset.c
Executable file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: menset.h
|
||||
|
||||
Author: Torbjorn Granlund
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Copy memory to memory until the specified number of bytes
|
||||
has been copied. Overlap is NOT handled correctly.
|
||||
|
||||
Source: GNU C Library
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: GNU Lesser General Public License
|
||||
*/
|
||||
#include "memset.h"
|
||||
int printf(const char * restrict format, ... );
|
||||
|
||||
void *sha_glibc_memset( void *dstpp, int c, size_t len )
|
||||
{
|
||||
long int dstp = ( long int ) dstpp;
|
||||
|
||||
if ( len >= 8 ) {
|
||||
size_t xlen;
|
||||
op_t cccc;
|
||||
|
||||
cccc = ( unsigned char ) c;
|
||||
cccc |= cccc << 8;
|
||||
cccc |= cccc << 16;
|
||||
if ( OPSIZ > 4 )
|
||||
/* Do the shift in two steps to avoid warning if long has 32 bits. */
|
||||
cccc |= ( cccc << 16 ) << 16;
|
||||
|
||||
/* There are at least some bytes to set.
|
||||
No need to test for LEN == 0 in this alignment loop. */
|
||||
_Pragma( "loopbound min 3 max 3" )
|
||||
while ( dstp % OPSIZ != 0 ) {
|
||||
( ( BYTE * ) dstp )[ 0 ] = c;
|
||||
dstp += 1;
|
||||
len -= 1;
|
||||
}
|
||||
|
||||
/* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */
|
||||
xlen = len / ( OPSIZ * 8 );
|
||||
_Pragma( "loopbound min 0 max 1" )
|
||||
while ( xlen > 0 ) {
|
||||
( ( op_t * ) dstp )[ 0 ] = cccc;
|
||||
( ( op_t * ) dstp )[ 1 ] = cccc;
|
||||
( ( op_t * ) dstp )[ 2 ] = cccc;
|
||||
( ( op_t * ) dstp )[ 3 ] = cccc;
|
||||
( ( op_t * ) dstp )[ 4 ] = cccc;
|
||||
( ( op_t * ) dstp )[ 5 ] = cccc;
|
||||
( ( op_t * ) dstp )[ 6 ] = cccc;
|
||||
( ( op_t * ) dstp )[ 7 ] = cccc;
|
||||
dstp += 8 * OPSIZ;
|
||||
xlen -= 1;
|
||||
}
|
||||
len %= OPSIZ * 8;
|
||||
|
||||
/* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */
|
||||
xlen = len / OPSIZ;
|
||||
_Pragma( "loopbound min 1 max 2" )
|
||||
while ( xlen > 0 ) {
|
||||
( ( op_t * ) dstp )[ 0 ] = cccc;
|
||||
dstp += OPSIZ;
|
||||
xlen -= 1;
|
||||
}
|
||||
len %= OPSIZ;
|
||||
}
|
||||
|
||||
/* Write the last few bytes. */
|
||||
_Pragma( "loopbound min 0 max 0" )
|
||||
while ( len > 0 ) {
|
||||
( ( BYTE * ) dstp )[ 0 ] = c;
|
||||
dstp += 1;
|
||||
len -= 1;
|
||||
}
|
||||
|
||||
return ( void * )dstpp;
|
||||
}
|
||||
|
||||
24
targets/wasm-tacle/kernel/sha/memset.h
Executable file
24
targets/wasm-tacle/kernel/sha/memset.h
Executable file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: menset.h
|
||||
|
||||
Author: Torbjorn Granlund
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Copy memory to memory until the specified number of bytes
|
||||
has been copied. Overlap is NOT handled correctly.
|
||||
|
||||
Source: GNU C Library
|
||||
|
||||
License: GNU Lesser General Public License
|
||||
|
||||
Changes: no major functional changes
|
||||
*/
|
||||
#include "memhelper.h"
|
||||
|
||||
void *sha_glibc_memset( void *dstpp, int c, size_t len );
|
||||
|
||||
223
targets/wasm-tacle/kernel/sha/sha.c
Executable file
223
targets/wasm-tacle/kernel/sha/sha.c
Executable file
@ -0,0 +1,223 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: sha.c
|
||||
|
||||
Author: Peter C. Gutmann's (heavily modified by Uwe Hollerbach)
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Source: Peter C. Gutmann's implementation as found in Applied Cryptography by Bruce Schneier
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: GNU Lesser General Public License
|
||||
|
||||
*/
|
||||
|
||||
#include "memcpy.h"
|
||||
#include "memset.h"
|
||||
#include "sha.h"
|
||||
|
||||
/*
|
||||
Declaration of global variables
|
||||
*/
|
||||
struct SHA_INFO sha_info;
|
||||
|
||||
/* SHA f()-functions */
|
||||
#define f1(x,y,z) ((x & y) | (~x & z))
|
||||
#define f2(x,y,z) (x ^ y ^ z)
|
||||
#define f3(x,y,z) ((x & y) | (x & z) | (y & z))
|
||||
#define f4(x,y,z) (x ^ y ^ z)
|
||||
|
||||
/* SHA constants */
|
||||
#define CONST1 0x5a827999L
|
||||
#define CONST2 0x6ed9eba1L
|
||||
#define CONST3 0x8f1bbcdcL
|
||||
#define CONST4 0xca62c1d6L
|
||||
|
||||
#define BLOCK_SIZE 8192
|
||||
|
||||
/* 32-bit rotate */
|
||||
|
||||
#define ROT32(x,n) ((x << n) | (x >> (32 - n)))
|
||||
|
||||
#define FUNC(n,i) \
|
||||
temp = ROT32(A,5) + f##n(B,C,D) + E + W[ i ] + CONST##n; \
|
||||
E = D; D = C; C = ROT32(B,30); B = A; A = temp
|
||||
|
||||
/* do SHA transformation */
|
||||
void sha_transform( struct SHA_INFO *sha_info )
|
||||
{
|
||||
int i;
|
||||
LONG temp, A, B, C, D, E, W[ 80 ];
|
||||
|
||||
_Pragma( "loopbound min 16 max 16" )
|
||||
for ( i = 0; i < 16; ++i )
|
||||
W[ i ] = sha_info->data[ i ];
|
||||
_Pragma( "loopbound min 64 max 64" )
|
||||
for ( i = 16; i < 80; ++i )
|
||||
W[ i ] = W[ i - 3 ] ^ W[ i - 8 ] ^ W[ i - 14 ] ^ W[ i - 16 ];
|
||||
|
||||
A = sha_info->digest[ 0 ];
|
||||
B = sha_info->digest[ 1 ];
|
||||
C = sha_info->digest[ 2 ];
|
||||
D = sha_info->digest[ 3 ];
|
||||
E = sha_info->digest[ 4 ];
|
||||
|
||||
|
||||
_Pragma( "loopbound min 20 max 20" )
|
||||
for ( i = 0; i < 20; ++i ) {
|
||||
FUNC( 1, i );
|
||||
}
|
||||
_Pragma( "loopbound min 20 max 20" )
|
||||
for ( i = 20; i < 40; ++i ) {
|
||||
FUNC( 2, i );
|
||||
}
|
||||
_Pragma( "loopbound min 20 max 20" )
|
||||
for ( i = 40; i < 60; ++i ) {
|
||||
FUNC( 3, i );
|
||||
}
|
||||
_Pragma( "loopbound min 20 max 20" )
|
||||
for ( i = 60; i < 80; ++i ) {
|
||||
FUNC( 4, i );
|
||||
}
|
||||
sha_info->digest[ 0 ] += A;
|
||||
sha_info->digest[ 1 ] += B;
|
||||
sha_info->digest[ 2 ] += C;
|
||||
sha_info->digest[ 3 ] += D;
|
||||
sha_info->digest[ 4 ] += E;
|
||||
}
|
||||
|
||||
|
||||
/* change endianness of data */
|
||||
void sha_byte_reverse( LONG *buffer, int count )
|
||||
{
|
||||
int i;
|
||||
BYTE ct[ 4 ], *cp;
|
||||
|
||||
count /= sizeof( LONG );
|
||||
cp = ( BYTE * ) buffer;
|
||||
_Pragma( "loopbound min 16 max 16" )
|
||||
for ( i = 0; i < count; ++i ) {
|
||||
ct[ 0 ] = cp[ 0 ];
|
||||
ct[ 1 ] = cp[ 1 ];
|
||||
ct[ 2 ] = cp[ 2 ];
|
||||
ct[ 3 ] = cp[ 3 ];
|
||||
cp[ 0 ] = ct[ 3 ];
|
||||
cp[ 1 ] = ct[ 2 ];
|
||||
cp[ 2 ] = ct[ 1 ];
|
||||
cp[ 3 ] = ct[ 0 ];
|
||||
cp += sizeof( LONG );
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize the SHA digest */
|
||||
void sha_init( void )
|
||||
{
|
||||
int i;
|
||||
sha_info.digest[ 0 ] = 0x67452301L;
|
||||
sha_info.digest[ 1 ] = 0xefcdab89L;
|
||||
sha_info.digest[ 2 ] = 0x98badcfeL;
|
||||
sha_info.digest[ 3 ] = 0x10325476L;
|
||||
sha_info.digest[ 4 ] = 0xc3d2e1f0L;
|
||||
sha_info.count_lo = 0L;
|
||||
sha_info.count_hi = 0L;
|
||||
for ( i = 0; i < 16; i++ )
|
||||
sha_info.data[ i ] = 0;
|
||||
}
|
||||
|
||||
size_t sha_fread( void *ptr, size_t size, size_t count,
|
||||
struct SHA_MY_FILE *stream )
|
||||
{
|
||||
unsigned i = stream->cur_pos, i2 = 0;
|
||||
size_t number_of_chars_to_read =
|
||||
stream->size - stream->cur_pos >= size * count ?
|
||||
size * count : stream->size - stream->cur_pos;
|
||||
_Pragma( "loopbound min 0 max 8192" )
|
||||
while ( i < stream->cur_pos + number_of_chars_to_read )
|
||||
( ( unsigned char * )ptr )[ i2++ ] = stream->data[ i++ ];
|
||||
stream->cur_pos += number_of_chars_to_read;
|
||||
return ( number_of_chars_to_read );
|
||||
}
|
||||
|
||||
/* update the SHA digest */
|
||||
void sha_update( struct SHA_INFO *sha_info, BYTE *buffer, int count )
|
||||
{
|
||||
if ( ( sha_info->count_lo + ( ( LONG ) count << 3 ) ) < sha_info->count_lo )
|
||||
++sha_info->count_hi;
|
||||
sha_info->count_lo += ( LONG ) count << 3;
|
||||
sha_info->count_hi += ( LONG ) count >> 29;
|
||||
_Pragma( "loopbound min 8 max 128" )
|
||||
while ( count >= SHA_BLOCKSIZE ) {
|
||||
sha_glibc_memcpy( sha_info->data, buffer, SHA_BLOCKSIZE );
|
||||
sha_byte_reverse( sha_info->data, SHA_BLOCKSIZE );
|
||||
sha_transform( sha_info );
|
||||
buffer += SHA_BLOCKSIZE;
|
||||
count -= SHA_BLOCKSIZE;
|
||||
}
|
||||
|
||||
sha_glibc_memcpy( sha_info->data, buffer, count );
|
||||
}
|
||||
|
||||
/* finish computing the SHA digest */
|
||||
void sha_final( struct SHA_INFO *sha_info )
|
||||
{
|
||||
int count;
|
||||
LONG lo_bit_count, hi_bit_count;
|
||||
|
||||
lo_bit_count = sha_info->count_lo;
|
||||
hi_bit_count = sha_info->count_hi;
|
||||
count = ( int ) ( ( lo_bit_count >> 3 ) & 0x3f );
|
||||
( ( BYTE * ) sha_info->data )[ count++ ] = 0x80;
|
||||
if ( count > 56 ) {
|
||||
sha_glibc_memset( ( BYTE * ) &sha_info->data + count, 0, 64 - count );
|
||||
sha_byte_reverse( sha_info->data, SHA_BLOCKSIZE );
|
||||
sha_transform( sha_info );
|
||||
sha_glibc_memset( &sha_info->data, 0, 56 );
|
||||
} else
|
||||
sha_glibc_memset( ( BYTE * ) &sha_info->data + count, 0, 56 - count );
|
||||
|
||||
sha_byte_reverse( sha_info->data, SHA_BLOCKSIZE );
|
||||
sha_info->data[ 14 ] = hi_bit_count;
|
||||
sha_info->data[ 15 ] = lo_bit_count;
|
||||
sha_transform( sha_info );
|
||||
}
|
||||
|
||||
/* compute the SHA digest of a FILE stream */
|
||||
|
||||
void sha_stream( struct SHA_INFO *sha_info, struct SHA_MY_FILE *fin )
|
||||
{
|
||||
int i;
|
||||
BYTE data[ BLOCK_SIZE ];
|
||||
_Pragma( "loopbound min 5 max 5" )
|
||||
while ( ( i = sha_fread( data, 1, BLOCK_SIZE, fin ) ) > 0 )
|
||||
sha_update( sha_info, data, i );
|
||||
|
||||
sha_final( sha_info );
|
||||
}
|
||||
|
||||
void _Pragma( "entrypoint" ) sha_main( void )
|
||||
{
|
||||
struct SHA_MY_FILE fin;
|
||||
fin.data = sha_data;
|
||||
fin.size = 32743; // set size = 3247552 for input_large
|
||||
fin.cur_pos = 0;
|
||||
sha_stream( &sha_info, &fin );
|
||||
}
|
||||
|
||||
int sha_return( void )
|
||||
{
|
||||
int sum = 0;
|
||||
sum = sha_info.data[ 14 ] + sha_info.data[ 15 ];
|
||||
return ( sum - 261944 != 0 );
|
||||
}
|
||||
|
||||
int main ( void )
|
||||
{
|
||||
sha_init();
|
||||
sha_main();
|
||||
return ( sha_return() );
|
||||
}
|
||||
63
targets/wasm-tacle/kernel/sha/sha.h
Executable file
63
targets/wasm-tacle/kernel/sha/sha.h
Executable file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 1.x
|
||||
|
||||
Name: sha.h
|
||||
|
||||
Author: Peter C. Gutmann's (heavily modified by Uwe Hollerbach)
|
||||
|
||||
NIST Secure Hash Algorithm
|
||||
|
||||
Source: Peter C. Gutmann's implementation as found in Applied Cryptography by Bruce Schneier
|
||||
|
||||
Changes: no major functional changes
|
||||
|
||||
License: May be used, modified, and re-distributed freely.
|
||||
*/
|
||||
|
||||
#ifndef SHA_H
|
||||
#define SHA_H
|
||||
|
||||
/* Useful defines & typedefs */
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned long LONG;
|
||||
typedef unsigned size_t;
|
||||
|
||||
/* Type to use for unaligned operations. */
|
||||
#define SHA_BLOCKSIZE 64
|
||||
#define SHA_DIGESTSIZE 20
|
||||
#define LITTLE_ENDIAN
|
||||
#define NULL ((void*)0)
|
||||
|
||||
extern unsigned volatile char sha_data[ 32743 ];
|
||||
|
||||
struct SHA_MY_FILE {
|
||||
unsigned volatile char *data;
|
||||
size_t size;
|
||||
unsigned cur_pos;
|
||||
};
|
||||
|
||||
struct SHA_INFO {
|
||||
LONG digest[ 5 ]; /* message digest */
|
||||
LONG count_lo, count_hi; /* 64-bit bit count */
|
||||
LONG data[ 16 ]; /* SHA data buffer */
|
||||
};
|
||||
|
||||
/*
|
||||
Forward declaration of functions
|
||||
*/
|
||||
void sha_transform( struct SHA_INFO * );
|
||||
void sha_byte_reverse( LONG *buffer, int count );
|
||||
void sha_init( void );
|
||||
size_t sha_fread( void *, size_t, size_t, struct SHA_MY_FILE * );
|
||||
void sha_update( struct SHA_INFO *, BYTE *, int );
|
||||
void sha_final( struct SHA_INFO * );
|
||||
void sha_stream( struct SHA_INFO *, struct SHA_MY_FILE * );
|
||||
void sha_main( void );
|
||||
int sha_return ( void );
|
||||
int main( void );
|
||||
|
||||
#endif // SHA_H
|
||||
|
||||
Reference in New Issue
Block a user