Add wasm tacle-bench targets
This commit is contained in:
@ -0,0 +1,649 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version 2.0
|
||||
|
||||
Name: anagram
|
||||
|
||||
Author: Raymond Chen
|
||||
|
||||
Function: A program that computes anagrams.
|
||||
|
||||
Source: See below.
|
||||
|
||||
Original name: anagram
|
||||
|
||||
Changes: See ChangeLog.txt
|
||||
|
||||
License: See below.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Anagram program by Raymond Chen,
|
||||
inspired by a similar program by Brian Scearce
|
||||
|
||||
This program is Copyright 1991 by Raymond Chen.
|
||||
(rjc@math.princeton.edu)
|
||||
|
||||
This program may be freely distributed provided all alterations
|
||||
to the original are clearly indicated as such.
|
||||
*/
|
||||
|
||||
/* There are two tricks. First is the Basic Idea:
|
||||
|
||||
When the user types in a phrase, the phrase is first preprocessed to
|
||||
determine how many of each letter appears. A bit field is then constructed
|
||||
dynamically, such that each field is large enough to hold the next power
|
||||
of two larger than the number of times the character appears. For example,
|
||||
if the phrase is hello, world, the bit field would be
|
||||
|
||||
00 00 00 000 000 00 00
|
||||
d e h l o r w
|
||||
|
||||
The phrase hello, world, itself would be encoded as
|
||||
|
||||
01 01 01 011 010 01 01
|
||||
d e h l o r w
|
||||
|
||||
and the word hollow would be encoded as
|
||||
|
||||
00 00 01 010 010 00 01
|
||||
d e h l o r w
|
||||
|
||||
The top bit of each field is set in a special value called the sign.
|
||||
Here, the sign would be
|
||||
|
||||
10 10 10 100 100 10 10
|
||||
d e h l o r w
|
||||
|
||||
|
||||
The reason for packing the values into a bit field is that the operation
|
||||
of subtracting out the letters of a word from the current phrase can be
|
||||
carried out in parallel. for example, subtracting the word hello from
|
||||
the phrase hello, world, is merely
|
||||
|
||||
d e h l o r w
|
||||
01 01 01 011 010 01 01 (dehllloorw)
|
||||
- 00 00 01 010 010 00 01 (hlloow)
|
||||
========================
|
||||
01 01 00 001 000 01 00 (delr)
|
||||
|
||||
Since none of the sign bits is set, the word fits, and we can continue.
|
||||
Suppose the next word we tried was hood.
|
||||
|
||||
d e h l o r w
|
||||
01 01 00 001 000 01 00 (delr)
|
||||
- 01 00 01 000 010 00 00 (hood)
|
||||
========================
|
||||
00 00 11 000 110 01 00
|
||||
^ ^
|
||||
A sign bit is set. (Two, actually.) This means that hood does not
|
||||
fit in delr, so we skip it and try another word. (Observe that
|
||||
when a sign bit becomes set, it screws up the values for the letters to
|
||||
the left of that bit, but that's not important.)
|
||||
|
||||
The inner loop of an anagram program is testing to see if a
|
||||
word fits in the collection of untried letters. Traditional methods
|
||||
keep an array of 26 integers, which are then compared in turn. This
|
||||
means that there are 26 comparisons per word.
|
||||
|
||||
This method reduces the number of comparisons to MAX_QUAD, typically 2.
|
||||
Instead of looping through an array, we merely perform the indicated
|
||||
subtraction and test if any of the sign bits is set.
|
||||
*/
|
||||
|
||||
/* The nuts and bolts:
|
||||
|
||||
The dictionary is loaded and preprocessed. The preprocessed dictionary
|
||||
is a concatenation of copies of the structure:
|
||||
|
||||
struct dictword {
|
||||
char bStructureSize; -- size of this structure
|
||||
char cLetters; -- number of letters in the word
|
||||
char achWord[]; -- the word itself (0-terminated)
|
||||
}
|
||||
|
||||
Since this is a variable-sized structure, we keep its size in the structure
|
||||
itself for rapid stepping through the table.
|
||||
|
||||
When a phrase is typed in, it is first preprocessed as described in the
|
||||
Basic Idea. We then go through the dictionary, testing each word. If
|
||||
the word fits in our phrase, we build the bit field for its frequency
|
||||
table and add it to the list of candidates.
|
||||
*/
|
||||
|
||||
/*
|
||||
The Second Trick:
|
||||
|
||||
Before diving into our anagram search, we then tabulate how many times
|
||||
each letter appears in our list of candidates, and sort the table, with
|
||||
the rarest letter first.
|
||||
|
||||
We then do our anagram search.
|
||||
|
||||
Like most anagram programs, this program does a depth-first search.
|
||||
Although most anagram programs do some sort of heuristics to decide what
|
||||
order to place words in the list_of_candidates, the search itself proceeds
|
||||
according to a greedy algorithm. That is, once you find a word that fits,
|
||||
subtract it and recurse.
|
||||
|
||||
This anagram program exercises some restraint and does not march down
|
||||
every branch that shows itself. Instead, it only goes down branches
|
||||
that use the rarest unused letter. This helps to find dead ends faster.
|
||||
|
||||
FindAnagram(unused_letters, list_of_candidates) {
|
||||
l = the rarest letter as yet unused
|
||||
For word in list_of_candidates {
|
||||
if word does not fit in unused_letters, go on to the next word.
|
||||
if word does not contain l, defer.
|
||||
FindAnagram(unused_letters - word, list_of_candidates[word,...])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
The heuristic of the Second Trick can probably be improved. I invite
|
||||
anyone willing to improve it to do so.
|
||||
*/
|
||||
|
||||
/* Before compiling, make sure Quad and MASK_BITS are set properly. For best
|
||||
results, make Quad the largest integer size supported on your machine.
|
||||
So if your machine has long longs, make Quad an unsigned long long.
|
||||
(I called it Quad because on most machines, the largest integer size
|
||||
supported is a four-byte unsigned long.)
|
||||
|
||||
If you need to be able to anagram larger phrases, increase MAX_QUADS.
|
||||
If you increase it beyond 4, you'll have to add a few more loop unrolling
|
||||
steps to FindAnagram.
|
||||
*/
|
||||
#include "anagram_ctype.h"
|
||||
#include "anagram_stdlib.h"
|
||||
#include "anagram_strings.h"
|
||||
|
||||
#include "anagram_compare.h"
|
||||
|
||||
/*
|
||||
Defines
|
||||
*/
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
#define anagram_DICTWORDS 2279
|
||||
#define anagram_MASK_BITS 32 /* number of bits in a Quad */
|
||||
#define anagram_MAX_QUADS 2 /* controls largest phrase */
|
||||
#define anagram_MAXCAND 100 /* candidates */
|
||||
#define anagram_MAXSOL 51 /* words in the solution */
|
||||
#define anagram_ALPHABET 26 /* letters in the alphabet */
|
||||
|
||||
#define anagram_OneStep(i) \
|
||||
if ((aqNext[i] = pqMask[i] - pw->aqMask[i]) & anagram_aqMainSign[i]) { \
|
||||
ppwStart++; \
|
||||
continue; \
|
||||
}
|
||||
|
||||
/*
|
||||
Type definitions
|
||||
*/
|
||||
|
||||
typedef unsigned int anagram_Quad; /* for building our bit mask */
|
||||
|
||||
/* A Word remembers the information about a candidate word. */
|
||||
typedef struct {
|
||||
char *pchWord; /* the word itself */
|
||||
anagram_Quad aqMask[anagram_MAX_QUADS]; /* the word's mask */
|
||||
unsigned cchLength; /* letters in the word */
|
||||
char padding[4];
|
||||
} anagram_Word;
|
||||
typedef anagram_Word *anagram_PWord;
|
||||
typedef anagram_Word **anagram_PPWord;
|
||||
|
||||
/* A Letter remembers information about each letter in the phrase to
|
||||
be anagrammed. */
|
||||
typedef struct {
|
||||
unsigned uFrequency; /* how many times it appears */
|
||||
unsigned uShift; /* how to mask */
|
||||
unsigned uBits; /* the bit mask itself */
|
||||
unsigned iq; /* which Quad to inspect? */
|
||||
} anagram_Letter;
|
||||
typedef anagram_Letter *anagram_PLetter;
|
||||
|
||||
/*
|
||||
Forward declaration of functions
|
||||
*/
|
||||
|
||||
void anagram_init(void);
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
||||
anagram_main(void);
|
||||
int anagram_return(void);
|
||||
int anagram_ch2i(int ch);
|
||||
void anagram_AddWords(void);
|
||||
void anagram_BuildMask(char const *pchPhrase);
|
||||
void anagram_BuildWord(char *pchWord);
|
||||
void anagram_DumpWords(void);
|
||||
void anagram_FindAnagram(anagram_Quad *pqMask, anagram_PPWord ppwStart,
|
||||
int iLetter);
|
||||
anagram_PWord anagram_NewWord(void);
|
||||
anagram_PWord anagram_NextWord(void);
|
||||
void anagram_ReadDict(void);
|
||||
void anagram_Reset(void);
|
||||
void anagram_SortCandidates(void);
|
||||
|
||||
/*
|
||||
Declaration of global variables
|
||||
*/
|
||||
|
||||
extern char const *anagram_achPhrase[3];
|
||||
extern char const *anagram_dictionary[anagram_DICTWORDS];
|
||||
|
||||
/* candidates we've found so far */
|
||||
static anagram_PWord anagram_apwCand[anagram_MAXCAND];
|
||||
/* how many of them? */
|
||||
static unsigned anagram_cpwCand;
|
||||
|
||||
/* statistics on the current phrase */
|
||||
static anagram_Letter anagram_alPhrase[anagram_ALPHABET];
|
||||
|
||||
/* number of letters in phrase */
|
||||
static int anagram_cchPhraseLength;
|
||||
|
||||
/* the bit field for the full phrase */
|
||||
static anagram_Quad anagram_aqMainMask[anagram_MAX_QUADS];
|
||||
/* where the sign bits are */
|
||||
static anagram_Quad anagram_aqMainSign[anagram_MAX_QUADS];
|
||||
|
||||
static const int anagram_cchMinLength = 3;
|
||||
|
||||
/* auGlobalFrequency counts the number of times each letter appears,
|
||||
summed over all candidate words. This is used to decide which letter
|
||||
to attack first. */
|
||||
static unsigned anagram_auGlobalFrequency[anagram_ALPHABET];
|
||||
static int anagram_achByFrequency[anagram_ALPHABET]; /* for sorting */
|
||||
|
||||
/* the dictionary is read here */
|
||||
static char *anagram_pchDictionary;
|
||||
|
||||
/* the answers */
|
||||
static anagram_PWord anagram_apwSol[anagram_MAXSOL];
|
||||
static int anagram_cpwLast;
|
||||
|
||||
/* buffer to write an answer */
|
||||
static char anagram_buffer[30];
|
||||
|
||||
/*
|
||||
Initialization- and return-value-related functions
|
||||
*/
|
||||
|
||||
/* ReadDict -- read the dictionary file into memory and preprocess it
|
||||
|
||||
A word of length cch in the dictionary is encoded as follows:
|
||||
|
||||
byte 0 = cch + 3
|
||||
byte 1 = number of letters in the word
|
||||
byte 2... = the word itself, null-terminated
|
||||
|
||||
Observe that cch+3 is the length of the total encoding. These
|
||||
byte streams are concatenated, and terminated with a 0.
|
||||
*/
|
||||
void
|
||||
anagram_ReadDict(void) {
|
||||
char *pch;
|
||||
char *pchBase;
|
||||
unsigned len;
|
||||
unsigned cWords = 0;
|
||||
unsigned cLetters;
|
||||
int i;
|
||||
volatile char bitmask = 0;
|
||||
|
||||
len = 0;
|
||||
__pragma_loopbound(2279, 2279);
|
||||
for (i = 0; i < anagram_DICTWORDS; i++) {
|
||||
unsigned strlen = 0;
|
||||
__pragma_loopbound(1, 5);
|
||||
while (anagram_dictionary[i][strlen] != 0)
|
||||
strlen++;
|
||||
len += strlen + 3;
|
||||
}
|
||||
|
||||
len++;
|
||||
pchBase = anagram_pchDictionary = (char *) anagram_malloc(len);
|
||||
|
||||
__pragma_loopbound(2279, 2279);
|
||||
for (i = 0; i < anagram_DICTWORDS; i++) {
|
||||
int index = 0;
|
||||
pch = pchBase + 2; /* reserve for length */
|
||||
cLetters = 0;
|
||||
|
||||
__pragma_loopbound(1, 5);
|
||||
while (anagram_dictionary[i][index] != '\0') {
|
||||
if (anagram_isalpha(anagram_dictionary[i][index]))
|
||||
cLetters++;
|
||||
*pch++ = anagram_dictionary[i][index];
|
||||
index++;
|
||||
*(pch - 1) ^= bitmask;
|
||||
}
|
||||
*pch++ = '\0';
|
||||
*pchBase = (char) (pch - pchBase);
|
||||
pchBase[1] = (char) cLetters;
|
||||
pchBase = pch;
|
||||
cWords++;
|
||||
}
|
||||
|
||||
*pchBase++ = 0;
|
||||
}
|
||||
|
||||
void
|
||||
anagram_init(void) {
|
||||
anagram_ReadDict();
|
||||
}
|
||||
|
||||
int
|
||||
anagram_return(void) {
|
||||
int i;
|
||||
char const *answer = "duke yip arm";
|
||||
|
||||
_Pragma(
|
||||
"loopbound min 12 max 12") for (i = 0; i < 12;
|
||||
i++) if (answer[i] !=
|
||||
anagram_buffer[i]) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Core benchmark functions
|
||||
*/
|
||||
|
||||
/* convert letter to index */
|
||||
int
|
||||
anagram_ch2i(int ch) {
|
||||
return ch - 'a';
|
||||
}
|
||||
|
||||
int
|
||||
anagram_CompareFrequency(char *pch1, char *pch2) {
|
||||
return anagram_auGlobalFrequency[(*(int *) pch1)] <
|
||||
anagram_auGlobalFrequency[(*(int *) pch2)]
|
||||
? -1
|
||||
: anagram_auGlobalFrequency[(*(int *) pch1)] ==
|
||||
anagram_auGlobalFrequency[(*(int *) pch2)]
|
||||
? 0
|
||||
: 1;
|
||||
}
|
||||
|
||||
void
|
||||
anagram_Reset(void) {
|
||||
anagram_bzero((char *) anagram_alPhrase,
|
||||
sizeof(anagram_Letter) * anagram_ALPHABET);
|
||||
anagram_bzero((char *) anagram_aqMainMask,
|
||||
sizeof(anagram_Quad) * anagram_MAX_QUADS);
|
||||
anagram_bzero((char *) anagram_aqMainSign,
|
||||
sizeof(anagram_Quad) * anagram_MAX_QUADS);
|
||||
anagram_bzero((char *) anagram_auGlobalFrequency,
|
||||
sizeof(unsigned) * anagram_ALPHABET);
|
||||
anagram_bzero((char *) anagram_achByFrequency,
|
||||
sizeof(int) * anagram_ALPHABET);
|
||||
anagram_bzero((char *) anagram_apwCand,
|
||||
sizeof(anagram_PWord) * anagram_MAXCAND);
|
||||
anagram_cchPhraseLength = 0;
|
||||
anagram_cpwCand = 0;
|
||||
}
|
||||
|
||||
void
|
||||
anagram_BuildMask(char const *pchPhrase) {
|
||||
int i;
|
||||
int ch;
|
||||
unsigned iq; /* which Quad? */
|
||||
unsigned int cbtUsed; /* bits used in the current Quad */
|
||||
unsigned int cbtNeed; /* bits needed for current letter */
|
||||
anagram_Quad qNeed; /* used to build the mask */
|
||||
|
||||
/* Tabulate letter frequencies in the phrase */
|
||||
anagram_cchPhraseLength = 0;
|
||||
__pragma_loopbound(11, 11);
|
||||
while ((ch = *pchPhrase++) != '\0') {
|
||||
if (anagram_isalpha(ch)) {
|
||||
ch = anagram_tolower(ch);
|
||||
anagram_alPhrase[anagram_ch2i(ch)].uFrequency++;
|
||||
anagram_cchPhraseLength++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Build masks */
|
||||
iq = 0; /* which quad being used */
|
||||
cbtUsed = 0; /* bits used so far */
|
||||
|
||||
__pragma_loopbound(26, 26);
|
||||
for (i = 0; i < anagram_ALPHABET; i++) {
|
||||
if (anagram_alPhrase[i].uFrequency == 0) {
|
||||
anagram_auGlobalFrequency[i] = ~0u; /* to make it sort last */
|
||||
} else {
|
||||
anagram_auGlobalFrequency[i] = 0u;
|
||||
_Pragma(
|
||||
"loopbound min 1 max 2") for (cbtNeed = 1, qNeed = 1;
|
||||
anagram_alPhrase[i].uFrequency >=
|
||||
qNeed;
|
||||
cbtNeed++, qNeed <<= 1);
|
||||
if (cbtUsed + cbtNeed > anagram_MASK_BITS)
|
||||
cbtUsed = 0;
|
||||
anagram_alPhrase[i].uBits = qNeed - 1;
|
||||
if (cbtUsed)
|
||||
qNeed <<= cbtUsed;
|
||||
anagram_aqMainSign[iq] |= qNeed;
|
||||
anagram_aqMainMask[iq] |=
|
||||
(anagram_Quad) anagram_alPhrase[i].uFrequency << cbtUsed;
|
||||
anagram_alPhrase[i].uShift = cbtUsed;
|
||||
anagram_alPhrase[i].iq = iq;
|
||||
cbtUsed += cbtNeed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
anagram_PWord
|
||||
anagram_NewWord(void) {
|
||||
anagram_PWord pw;
|
||||
|
||||
pw = (anagram_Word *) anagram_malloc(sizeof(anagram_Word));
|
||||
return pw;
|
||||
}
|
||||
|
||||
/* NextWord -- get another candidate entry, creating if necessary */
|
||||
anagram_PWord
|
||||
anagram_NextWord(void) {
|
||||
anagram_PWord pw;
|
||||
pw = anagram_apwCand[anagram_cpwCand++];
|
||||
if (pw != 0)
|
||||
return pw;
|
||||
anagram_apwCand[anagram_cpwCand - 1] = anagram_NewWord();
|
||||
return anagram_apwCand[anagram_cpwCand - 1];
|
||||
}
|
||||
|
||||
/* BuildWord -- build a Word structure from an ASCII word
|
||||
If the word does not fit, then do nothing. */
|
||||
void
|
||||
anagram_BuildWord(char *pchWord) {
|
||||
unsigned char cchFrequency[anagram_ALPHABET];
|
||||
int i;
|
||||
char *pch = pchWord;
|
||||
anagram_PWord pw;
|
||||
unsigned int cchLength = 0;
|
||||
|
||||
anagram_bzero((char *) cchFrequency,
|
||||
sizeof(unsigned char) * anagram_ALPHABET);
|
||||
|
||||
/* Build frequency table */
|
||||
__pragma_loopbound(3, 5);
|
||||
while ((i = *pch++) != '\0') {
|
||||
if (!anagram_isalpha(i))
|
||||
continue;
|
||||
i = anagram_ch2i(anagram_tolower(i));
|
||||
if (++cchFrequency[i] > anagram_alPhrase[i].uFrequency)
|
||||
return;
|
||||
++cchLength;
|
||||
}
|
||||
|
||||
/* Update global count */
|
||||
__pragma_loopbound(26, 26);
|
||||
for (i = 0; i < anagram_ALPHABET; i++)
|
||||
anagram_auGlobalFrequency[i] += cchFrequency[i];
|
||||
|
||||
/* Create a Word structure and fill it in, including building the
|
||||
bitfield of frequencies. */
|
||||
pw = anagram_NextWord();
|
||||
anagram_bzero((char *) (pw->aqMask),
|
||||
sizeof(anagram_Quad) * anagram_MAX_QUADS);
|
||||
|
||||
pw->pchWord = pchWord;
|
||||
pw->cchLength = cchLength;
|
||||
__pragma_loopbound(26, 26);
|
||||
for (i = 0; i < anagram_ALPHABET; i++) {
|
||||
pw->aqMask[anagram_alPhrase[i].iq] |= (anagram_Quad) cchFrequency[i]
|
||||
<< anagram_alPhrase[i].uShift;
|
||||
}
|
||||
}
|
||||
|
||||
/* AddWords -- build the list of candidates */
|
||||
void
|
||||
anagram_AddWords(void) {
|
||||
char *pch = anagram_pchDictionary; /* walk through the dictionary */
|
||||
|
||||
anagram_cpwCand = 0;
|
||||
|
||||
__pragma_loopbound(1967, 1967);
|
||||
while (*pch) {
|
||||
if ((pch[1] >= anagram_cchMinLength &&
|
||||
pch[1] + anagram_cchMinLength <= anagram_cchPhraseLength) ||
|
||||
pch[1] == anagram_cchPhraseLength)
|
||||
anagram_BuildWord(pch + 2);
|
||||
pch += *pch;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
anagram_DumpWords(void) {
|
||||
int i, j;
|
||||
int offset = 0;
|
||||
__pragma_loopbound(3, 3);
|
||||
for (i = 0; i < anagram_cpwLast; i++) {
|
||||
__pragma_loopbound(3, 5);
|
||||
for (j = 0; anagram_apwSol[i]->pchWord[j] != '\0'; j++)
|
||||
anagram_buffer[offset + j] = anagram_apwSol[i]->pchWord[j];
|
||||
offset += j;
|
||||
|
||||
anagram_buffer[offset++] = ' ';
|
||||
}
|
||||
anagram_buffer[offset++] = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
anagram_FindAnagram(anagram_Quad *pqMask, anagram_PPWord ppwStart,
|
||||
int iLetter) {
|
||||
anagram_Quad aqNext[anagram_MAX_QUADS];
|
||||
register anagram_PWord pw;
|
||||
anagram_Quad qMask;
|
||||
unsigned iq;
|
||||
anagram_PPWord ppwEnd = &anagram_apwCand[0];
|
||||
ppwEnd += anagram_cpwCand;
|
||||
|
||||
__pragma_loopbound(0, 6);
|
||||
while (1) {
|
||||
iq = anagram_alPhrase[anagram_achByFrequency[iLetter]].iq;
|
||||
qMask = anagram_alPhrase[anagram_achByFrequency[iLetter]].uBits
|
||||
<< anagram_alPhrase[anagram_achByFrequency[iLetter]].uShift;
|
||||
if (pqMask[iq] & qMask)
|
||||
break;
|
||||
iLetter++;
|
||||
}
|
||||
|
||||
__pragma_loopbound(0, 11);
|
||||
while (ppwStart < ppwEnd) {
|
||||
pw = *ppwStart;
|
||||
|
||||
#if anagram_MAX_QUADS > 0
|
||||
anagram_OneStep(0);
|
||||
#endif
|
||||
|
||||
#if anagram_MAX_QUADS > 1
|
||||
anagram_OneStep(1);
|
||||
#endif
|
||||
|
||||
#if anagram_MAX_QUADS > 2
|
||||
anagram_OneStep(2);
|
||||
#endif
|
||||
|
||||
#if anagram_MAX_QUADS > 3
|
||||
anagram_OneStep(3);
|
||||
#endif
|
||||
|
||||
#if anagram_MAX_QUADS > 4
|
||||
@@"Add more unrolling steps here, please." @ @
|
||||
#endif
|
||||
|
||||
/* If the pivot letter isn't present, defer this word until later */
|
||||
if ((pw->aqMask[iq] & qMask) == 0) {
|
||||
*ppwStart = *(--ppwEnd);
|
||||
*ppwEnd = pw;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If we get here, this means the word fits. */
|
||||
anagram_apwSol[anagram_cpwLast++] = pw;
|
||||
if (anagram_cchPhraseLength -= pw->cchLength) { /* recurse */
|
||||
/* The recursive call scrambles the tail, so we have to be
|
||||
pessimistic. */
|
||||
ppwEnd = &anagram_apwCand[0];
|
||||
ppwEnd += anagram_cpwCand;
|
||||
anagram_FindAnagram(&aqNext[0], ppwStart, iLetter);
|
||||
} else /* found one */
|
||||
anagram_DumpWords();
|
||||
anagram_cchPhraseLength += pw->cchLength;
|
||||
--anagram_cpwLast;
|
||||
ppwStart++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
anagram_SortCandidates(void) {
|
||||
int i;
|
||||
|
||||
/* Sort the letters by frequency */
|
||||
__pragma_loopbound(26, 26);
|
||||
for (i = 0; i < anagram_ALPHABET; i++)
|
||||
anagram_achByFrequency[i] = i;
|
||||
anagram_qsort(anagram_achByFrequency, anagram_ALPHABET, sizeof(int));
|
||||
}
|
||||
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
||||
anagram_main(void) {
|
||||
int i;
|
||||
|
||||
__pragma_loopbound(3, 3);
|
||||
for (i = 0; i < 3; i++) {
|
||||
anagram_Reset();
|
||||
anagram_BuildMask(anagram_achPhrase[i]);
|
||||
anagram_AddWords();
|
||||
if (anagram_cpwCand == 0 || anagram_cchPhraseLength == 0)
|
||||
continue;
|
||||
|
||||
anagram_cpwLast = 0;
|
||||
anagram_SortCandidates();
|
||||
_Pragma("marker call_find")
|
||||
anagram_FindAnagram(anagram_aqMainMask, anagram_apwCand, 0);
|
||||
_Pragma("flowrestriction 1*anagram_FindAnagram <= 51*call_find");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Main function
|
||||
*/
|
||||
|
||||
__attribute__((noinline)) __attribute__((export_name("main"))) int
|
||||
main(void) {
|
||||
anagram_init();
|
||||
anagram_main();
|
||||
|
||||
return anagram_return();
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
/*
|
||||
|
||||
This header is part of the TACLeBench benchmark suite.
|
||||
Version 2.0
|
||||
|
||||
Name: anagram_compare.h
|
||||
|
||||
Author: Raymond Chen
|
||||
|
||||
Function: This header contains the comparison functions used by anagram.
|
||||
|
||||
Source: unknown
|
||||
|
||||
Original name: anagram
|
||||
|
||||
Changes: See ChangeLog.txt
|
||||
|
||||
License: See anagram.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef ANAGRAM_COMPARE_H
|
||||
#define ANAGRAM_COMPARE_H
|
||||
|
||||
int anagram_CompareFrequency(char *pch1, char *pch2);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,45 @@
|
||||
/*
|
||||
|
||||
This header is part of the TACLeBench benchmark suite.
|
||||
Version 2.0
|
||||
|
||||
Name: anagram_ctype.h
|
||||
|
||||
Author: Raymond Chen
|
||||
|
||||
Function: This header contains some C library functions used by anagram.
|
||||
|
||||
Source: unknown
|
||||
|
||||
Original name: anagram
|
||||
|
||||
Changes: See ChangeLog.txt
|
||||
|
||||
License: See anagram.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef ANAGRAM_CTYPE_H
|
||||
#define ANAGRAM_CTYPE_H
|
||||
|
||||
int
|
||||
anagram_islower(int c) {
|
||||
return 'a' <= c && c <= 'z';
|
||||
}
|
||||
|
||||
int
|
||||
anagram_isupper(int c) {
|
||||
return 'A' <= c && c <= 'Z';
|
||||
}
|
||||
|
||||
int
|
||||
anagram_isalpha(int c) {
|
||||
return anagram_isupper(c) || anagram_islower(c);
|
||||
}
|
||||
|
||||
int
|
||||
anagram_tolower(int c) {
|
||||
return anagram_isupper(c) ? c + ('a' - 'A') : c;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,320 @@
|
||||
/*
|
||||
|
||||
This file is part of the TACLeBench benchmark suite.
|
||||
Version 2.0
|
||||
|
||||
Name: anagram_input.c
|
||||
|
||||
Author: Raymond Chen
|
||||
|
||||
Function: This file contains the input data used by anagram.
|
||||
|
||||
Source: anagram
|
||||
|
||||
Original name: anagram
|
||||
|
||||
Changes: See ChangeLog.txt
|
||||
|
||||
License: See anagram.c
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Forward declaration of global variables
|
||||
*/
|
||||
|
||||
extern char const *anagram_achPhrase[3];
|
||||
extern char const *anagram_dictionary[2279];
|
||||
|
||||
/*
|
||||
Definition of global variables
|
||||
*/
|
||||
char const *anagram_achPhrase[3] = {"todd austin", "john alledy",
|
||||
"mary updike"};
|
||||
|
||||
char const *anagram_dictionary[2279] = {
|
||||
"2nd", "4th", "8th", "a", "ABA", "aback", "abash", "abbas",
|
||||
"abbey", "abed", "abet", "abort", "abut", "Accra", "ACM", "acorn",
|
||||
"Acts", "Ada", "adapt", "added", "addle", "Adele", "Aden", "admix",
|
||||
"adore", "adult", "affix", "afire", "aft", "agate", "agave", "Agee",
|
||||
"agent", "agile", "Agnew", "agone", "ahoy", "Aida", "aim", "Ainu",
|
||||
"airy", "Ajax", "Alamo", "alarm", "alb", "Alcoa", "alder", "Aleck",
|
||||
"alert", "algae", "alia", "alike", "alive", "allay", "alley", "Allis",
|
||||
"allow", "ally", "Allyn", "aloe", "aloha", "along", "aloud", "also",
|
||||
"alter", "Alton", "Alva", "amaze", "amber", "ami", "amigo", "amiss",
|
||||
"Amman", "Amoco", "amok", "Amos", "ample", "amra", "amy", "Andes",
|
||||
"angel", "Angie", "angry", "Angus", "Anne", "annex", "annoy", "annul",
|
||||
"ante", "any", "apex", "apple", "apron", "apt", "arch", "argue",
|
||||
"Aries", "arm", "army", "aroma", "array", "arrow", "Artie", "arty",
|
||||
"arum", "a's", "ash", "ashen", "ashy", "askew", "assai", "Assam",
|
||||
"Astor", "ate", "atlas", "atone", "audit", "Aug", "augur", "auk",
|
||||
"aural", "avid", "avoid", "avow", "awash", "awe", "awn", "awry",
|
||||
"axe", "axial", "axis", "axon", "Ayers", "Aztec", "b", "babe",
|
||||
"Bach", "bad", "bait", "baldy", "balm", "balsa", "bam", "ban",
|
||||
"bane", "banjo", "barb", "barn", "baron", "basal", "Basel", "basil",
|
||||
"bassi", "baste", "batch", "Bates", "batik", "Bator", "bawd", "bay",
|
||||
"bayed", "bayou", "be", "beak", "bean", "beard", "beat", "beck",
|
||||
"Becky", "bed", "bedim", "bee", "beech", "beep", "beet", "befit",
|
||||
"beg", "begin", "beige", "Bela", "belch", "belt", "beman", "bench",
|
||||
"Benny", "bent", "Benz", "berth", "beset", "bet", "betel", "Bette",
|
||||
"bevy", "Bible", "bide", "big", "bile", "bilk", "binge", "bit",
|
||||
"bite", "black", "blanc", "bland", "blare", "blat", "blaze", "bled",
|
||||
"blest", "blind", "Blinn", "bliss", "blitz", "blob", "blond", "blood",
|
||||
"bloom", "blot", "blown", "blue", "bluff", "Blum", "blur", "board",
|
||||
"boat", "bock", "bog", "bogy", "boil", "Boise", "bomb", "bon",
|
||||
"bong", "bonus", "bonze", "booby", "book", "booky", "boon", "booze",
|
||||
"bore", "Boris", "boron", "Bosch", "bosom", "bound", "bourn", "bowel",
|
||||
"boy", "Boyce", "bract", "Brady", "brag", "brake", "brant", "brass",
|
||||
"Braun", "bravo", "bread", "bream", "breve", "brew", "briar", "Brice",
|
||||
"brief", "bring", "briny", "broad", "broth", "brunt", "BSTJ", "bub",
|
||||
"buck", "Budd", "buddy", "Buick", "built", "bulge", "bulky", "bum",
|
||||
"bump", "bunch", "bundy", "bunk", "Burch", "burg", "burl", "Burma",
|
||||
"burnt", "Burr", "bury", "bush", "bushy", "bust", "busy", "butte",
|
||||
"butyl", "buyer", "by", "bylaw", "Byrd", "byte", "cab", "cable",
|
||||
"cacao", "cacti", "Cairo", "Caleb", "call", "calm", "canal", "canoe",
|
||||
"canon", "can't", "cap", "caper", "capo", "card", "Carey", "Carib",
|
||||
"Carla", "carol", "carve", "cash", "caste", "catch", "cater", "caulk",
|
||||
"cause", "CBS", "cedar", "cent", "Cetus", "Chad", "chaff", "chair",
|
||||
"champ", "char", "chasm", "chaw", "cheat", "cheer", "chef", "Chen",
|
||||
"chew", "chick", "chief", "Chile", "chill", "chine", "chip", "chock",
|
||||
"choir", "chomp", "chose", "Chris", "chuff", "chum", "chump", "CIA",
|
||||
"cinch", "cite", "city", "clad", "clan", "clank", "Clara", "Claus",
|
||||
"claw", "clean", "cleat", "clerk", "clime", "cling", "clink", "Clio",
|
||||
"clod", "clomp", "cloth", "clove", "cluck", "clump", "clung", "Clyde",
|
||||
"cobra", "coco", "coda", "Cody", "Cohn", "coin", "col", "Colby",
|
||||
"coney", "Congo", "cony", "cool", "coon", "copra", "copy", "Corey",
|
||||
"corn", "corps", "cos", "cosy", "couch", "cough", "count", "coup",
|
||||
"cove", "cowry", "coy", "CPA", "crack", "craft", "Craig", "crank",
|
||||
"crash", "crate", "crawl", "craze", "creak", "cream", "credo", "creek",
|
||||
"Creon", "crept", "crest", "crew", "crib", "crime", "crimp", "crisp",
|
||||
"crock", "croft", "crone", "crook", "crowd", "CRT", "crumb", "crump",
|
||||
"crush", "crux", "cub", "cube", "cuff", "cup", "Cupid", "cur",
|
||||
"curb", "curie", "cusp", "cute", "cycad", "cynic", "d", "daffy",
|
||||
"dairy", "daisy", "dally", "dame", "Damon", "Dan", "dance", "Dane",
|
||||
"dank", "Dante", "Dar", "darn", "dart", "dash", "davit", "day",
|
||||
"De", "deaf", "deal", "death", "debit", "Dec", "decal", "Dee",
|
||||
"Deere", "deify", "deity", "Della", "delta", "demur", "den", "Denny",
|
||||
"dense", "deny", "depth", "desk", "deus", "devil", "dewar", "Dhabi",
|
||||
"diary", "dick", "dicta", "did", "die", "Diego", "diety", "dill",
|
||||
"din", "dine", "dirty", "disc", "ditch", "dive", "DNA", "dock",
|
||||
"Dodd", "doff", "dogma", "dolce", "doll", "dolly", "done", "door",
|
||||
"dope", "Doric", "dose", "dote", "doubt", "Doug", "dove", "dowel",
|
||||
"doze", "Dr", "Draco", "drama", "drape", "drawl", "dread", "dreg",
|
||||
"dress", "drew", "drib", "drier", "drill", "drip", "dross", "drown",
|
||||
"druid", "drunk", "dry", "du", "Duane", "ducat", "duct", "duel",
|
||||
"duff", "Duffy", "Dugan", "duke", "dull", "dulse", "duly", "dump",
|
||||
"dumpy", "dunce", "dunk", "dupe", "dusky", "dwarf", "dwelt", "Dwyer",
|
||||
"dyer", "Dyke", "dyne", "each", "eager", "ear", "earn", "ease",
|
||||
"eat", "eater", "Eben", "Ecole", "Eden", "edge", "edgy", "edict",
|
||||
"Edith", "EDT", "eel", "eft", "egg", "Egypt", "eject", "el",
|
||||
"elan", "elate", "elect", "elfin", "elide", "elk", "Ella", "Ellis",
|
||||
"Elmer", "else", "Elton", "elude", "elves", "ember", "Emile", "Emory",
|
||||
"Eng", "Engle", "Enid", "Enos", "enter", "envoy", "epoxy", "equal",
|
||||
"erase", "ere", "erg", "Erich", "Ernst", "Eros", "err", "Errol",
|
||||
"Ervin", "e's", "essay", "ester", "Ethan", "Ethel", "ethic", "ethos",
|
||||
"etude", "Eva", "Evans", "event", "evict", "exact", "exam", "excel",
|
||||
"exit", "eye", "f", "Faber", "fable", "facet", "fad", "faery",
|
||||
"fag", "fail", "faint", "fairy", "fake", "fang", "fare", "faro",
|
||||
"fatal", "fatty", "fault", "faun", "Faust", "fay", "FBI", "fee",
|
||||
"feed", "feign", "Felix", "Fermi", "ferry", "fest", "fetch", "fetus",
|
||||
"few", "fiend", "fiery", "fifth", "fig", "fight", "filet", "film",
|
||||
"finch", "fine", "finny", "fire", "first", "fish", "Fisk", "fist",
|
||||
"Fitch", "flack", "flak", "flaky", "flame", "flank", "flare", "flat",
|
||||
"flax", "flea", "fled", "flee", "fleet", "flint", "flit", "flock",
|
||||
"flog", "flow", "Floyd", "flub", "fluke", "flute", "Flynn", "FM",
|
||||
"foal", "focal", "Foley", "folk", "fond", "food", "foot", "fop",
|
||||
"fore", "forge", "form", "fort", "forth", "forty", "Foss", "foul",
|
||||
"fowl", "FPC", "frame", "Franz", "Frau", "fray", "freed", "fresh",
|
||||
"friar", "fro", "frog", "from", "frost", "frown", "fry", "fuel",
|
||||
"full", "fun", "fur", "furry", "fussy", "g", "gaff", "gag",
|
||||
"Gail", "Galen", "gall", "game", "gamma", "gap", "gar", "garb",
|
||||
"gas", "gasp", "gate", "gauge", "gaur", "gavel", "gawk", "gay",
|
||||
"gecko", "gel", "gem", "Gemma", "gene", "genie", "genre", "genus",
|
||||
"germ", "Gerry", "get", "giant", "gibby", "gig", "gild", "gilt",
|
||||
"gin", "Gino", "given", "glare", "gleam", "glee", "glib", "glint",
|
||||
"gloat", "glow", "glut", "GMT", "gnaw", "gnome", "GNP", "god",
|
||||
"Goff", "gogo", "golf", "Goode", "goof", "goose", "gore", "gory",
|
||||
"got", "gourd", "GPO", "grace", "Graff", "grape", "grasp", "grate",
|
||||
"gravy", "graze", "grebe", "greed", "Greek", "Gregg", "grew", "grid",
|
||||
"grime", "Grimm", "gripe", "grit", "groan", "gross", "grout", "grow",
|
||||
"grown", "grub", "grunt", "GSA", "guano", "guess", "guide", "guile",
|
||||
"guise", "gules", "gull", "gulp", "gumbo", "gun", "gunky", "guru",
|
||||
"gush", "gust", "gusto", "guy", "Gwyn", "gyp", "gyro", "Habib",
|
||||
"hack", "had", "Hades", "Hagen", "Hahn", "haiku", "hale", "halma",
|
||||
"ham", "Haney", "Hans", "hard", "hare", "hark", "harm", "harsh",
|
||||
"haste", "hasty", "hatch", "hater", "hawk", "Haydn", "hazel", "he",
|
||||
"Healy", "hear", "heart", "heave", "heavy", "hedge", "heel", "hefty",
|
||||
"Heinz", "held", "he'll", "hemp", "hertz", "hew", "hex", "hi",
|
||||
"hick", "Hicks", "hike", "hilum", "hind", "hip", "hippy", "hire",
|
||||
"his", "hive", "hobby", "hoc", "Hoff", "hogan", "Hokan", "hole",
|
||||
"Holm", "holt", "home", "homo", "hondo", "hood", "hook", "hoop",
|
||||
"hoot", "hope", "horn", "hose", "hot", "hound", "hovel", "how",
|
||||
"howdy", "hub", "hubby", "hue", "huff", "huge", "huh", "hull",
|
||||
"human", "Hun", "hung", "hunk", "hurt", "hurty", "hutch", "hydra",
|
||||
"hyena", "hymen", "i", "ibid", "IBM", "icon", "I'd", "Idaho",
|
||||
"ideal", "idiot", "idol", "IEEE", "iffy", "igloo", "iii", "ileum",
|
||||
"Iliad", "ill", "Ilona", "image", "in", "inapt", "Inca", "incur",
|
||||
"India", "inert", "infer", "infra", "Inman", "inn", "input", "ionic",
|
||||
"Iowa", "ipso", "IR", "Iran", "irate", "Irene", "Irish", "Irma",
|
||||
"is", "Ising", "Islam", "isle", "Italy", "it'd", "Ito", "iv",
|
||||
"ivy", "j", "JACM", "jag", "James", "Jane", "Janos", "Japan",
|
||||
"Jason", "jaw", "jean", "jeep", "Jeres", "jerky", "jess", "jet",
|
||||
"jewel", "jig", "jilt", "Jo", "job", "jog", "join", "joke",
|
||||
"jolt", "Jonas", "joule", "joust", "joy", "Juan", "judge", "judo",
|
||||
"Judy", "juju", "juke", "julep", "jump", "junco", "junky", "junta",
|
||||
"jure", "jut", "Kafka", "kapok", "Karp", "Kathy", "Kay", "Keats",
|
||||
"keel", "keg", "kelly", "Kemp", "Kent", "Kenya", "kerry", "Kevin",
|
||||
"keyed", "khaki", "Khmer", "kick", "Kiev", "kin", "Kiowa", "kirk",
|
||||
"kiss", "kite", "kiva", "Klan", "Kline", "knee", "Knott", "Knox",
|
||||
"koala", "Kong", "Korea", "kraft", "kraut", "Kuhn", "Kurd", "lac",
|
||||
"lack", "lad", "ladle", "lag", "lain", "laity", "lam", "lame",
|
||||
"lamp", "lance", "lane", "Lange", "Laos", "lapel", "lard", "Lares",
|
||||
"Lars", "last", "late", "Latin", "latus", "law", "lay", "layup",
|
||||
"lazy", "leach", "leafy", "leak", "leapt", "learn", "leash", "leave",
|
||||
"ledge", "leech", "left", "leg", "leggy", "Leila", "lemma", "Lena",
|
||||
"lens", "Leo", "Leona", "lest", "level", "levy", "lewd", "liar",
|
||||
"lice", "lick", "lie", "lien", "life", "lift", "liken", "lilac",
|
||||
"Lilly", "lily", "limb", "limit", "line", "lingo", "link", "Linus",
|
||||
"Lise", "lisp", "live", "livre", "load", "loam", "loan", "lob",
|
||||
"lobby", "local", "lock", "Loeb", "Logan", "logic", "loin", "Loki",
|
||||
"loll", "Lomb", "long", "loon", "loose", "loot", "lope", "lord",
|
||||
"Loren", "lose", "lossy", "Lotte", "loud", "lousy", "low", "Lowe",
|
||||
"loy", "l's", "LTV", "Lucas", "lucky", "luge", "Luis", "lumen",
|
||||
"lumpy", "lunar", "Lund", "Lura", "lure", "lurk", "lusty", "Lydia",
|
||||
"lying", "Lynn", "Lyon", "Lyra", "m", "Mabel", "mace", "macho",
|
||||
"macro", "madam", "magi", "magna", "mail", "main", "make", "Malay",
|
||||
"male", "mall", "malt", "mamma", "mane", "mania", "manic", "manna",
|
||||
"Mans", "Mao", "map", "mar", "Mardi", "maria", "Marin", "Mario",
|
||||
"Mars", "Mary", "mask", "mast", "mat", "mate", "mater", "matte",
|
||||
"maul", "Mavis", "maxim", "Maya", "Mayer", "Mayo", "mayst", "maze",
|
||||
"me", "meal", "meaty", "media", "meet", "meld", "melt", "men",
|
||||
"Menlo", "merge", "Merle", "merry", "mesh", "messy", "metro", "mew",
|
||||
"Meyer", "mezzo", "mica", "midst", "mien", "mig", "mila", "milk",
|
||||
"Mills", "milt", "Mimi", "mince", "mine", "mini", "mink", "minor",
|
||||
"minot", "minus", "Mira", "mire", "mirth", "Missy", "misty", "mite",
|
||||
"mitre", "mixup", "mob", "Mobil", "mock", "model", "Moen", "Mohr",
|
||||
"moist", "molar", "mole", "month", "moody", "Moore", "moral", "Moran",
|
||||
"morn", "Moser", "moss", "most", "motel", "moth", "motif", "motor",
|
||||
"motto", "mousy", "Moyer", "Mrs", "m's", "mud", "muggy", "Muir",
|
||||
"mulch", "mule", "mull", "mum", "mummy", "muon", "mural", "murre",
|
||||
"mushy", "musk", "must", "Muzo", "my", "Myers", "mynah", "Myra",
|
||||
"NAACP", "Nagy", "naive", "name", "Nancy", "nap", "nary", "nasal",
|
||||
"natal", "NATO", "navy", "Nazi", "NBC", "NCR", "ne", "near",
|
||||
"neath", "Ned", "need", "needy", "Nehru", "Nell", "neon", "Nero",
|
||||
"net", "Neva", "neve", "new", "nice", "niche", "Niger", "night",
|
||||
"Nikko", "Nile", "Niobe", "nitty", "NJ", "no", "Noah", "Nobel",
|
||||
"nodal", "noise", "Nolan", "nolo", "noon", "nor", "nose", "notch",
|
||||
"Nov", "now", "n's", "NTIS", "nude", "numb", "nurse", "NY",
|
||||
"oaf", "oaken", "oar", "oasis", "oath", "obey", "objet", "ocean",
|
||||
"Oct", "ode", "o'er", "off", "often", "ogle", "Okay", "old",
|
||||
"oldy", "olive", "Olson", "omit", "once", "only", "onset", "onus",
|
||||
"onyx", "ooze", "opera", "opium", "opt", "opus", "orb", "Orin",
|
||||
"Orion", "osier", "ought", "our", "out", "ovate", "over", "Ovid",
|
||||
"owing", "ox", "oxeye", "oxide", "Ozark", "p", "Pablo", "pace",
|
||||
"pack", "pact", "padre", "pagan", "Paine", "pale", "palm", "pane",
|
||||
"pansy", "Paoli", "papa", "papaw", "pappy", "parch", "pare", "Paris",
|
||||
"park", "Parks", "parse", "Paso", "passe", "past", "path", "Patsy",
|
||||
"Paul", "Pauli", "pax", "PBS", "peace", "peak", "Pease", "peck",
|
||||
"pedal", "pee", "peek", "peep", "pen", "penny", "pep", "Pepsi",
|
||||
"Perez", "perk", "Perle", "Perth", "peste", "Pete", "petri", "petty",
|
||||
"pewee", "PhD", "phi", "phon", "phony", "phyla", "piano", "piece",
|
||||
"pilot", "pinch", "ping", "pink", "pinto", "pious", "pipe", "pique",
|
||||
"piss", "pithy", "pity", "pixy", "place", "plain", "plane", "plate",
|
||||
"Plato", "play", "plaza", "plead", "pluck", "plug", "plump", "plunk",
|
||||
"plus", "pod", "podia", "Poe", "poesy", "pogo", "poi", "poise",
|
||||
"poke", "polis", "Polk", "poll", "polo", "Ponce", "pond", "pool",
|
||||
"poop", "pop", "porch", "pork", "Porte", "Porto", "posh", "posse",
|
||||
"post", "pour", "pow", "Prado", "Pratt", "pray", "press", "prey",
|
||||
"price", "pride", "prig", "prime", "prior", "probe", "Prof", "prone",
|
||||
"p's", "psych", "pub", "puck", "puffy", "Pugh", "pull", "puma",
|
||||
"pun", "punky", "puny", "pupal", "puppy", "pure", "purl", "pus",
|
||||
"PVC", "Pyle", "Pyrex", "Qatar", "quack", "quaff", "quash", "queen",
|
||||
"quell", "query", "queue", "quick", "quill", "quint", "quirt", "quo",
|
||||
"quote", "rabat", "rabbi", "radar", "radio", "radix", "Rae", "rag",
|
||||
"rail", "rajah", "Ralph", "Ramo", "ran", "Rand", "randy", "Raoul",
|
||||
"rape", "rare", "rasp", "rata", "rater", "rave", "raven", "razor",
|
||||
"R&D", "reach", "ready", "real", "reb", "reck", "reedy", "reek",
|
||||
"Reese", "regal", "Reid", "relax", "reman", "Rena", "rend", "ret",
|
||||
"retch", "Rhea", "rheum", "rhino", "Rhoda", "rib", "rice", "rick",
|
||||
"rid", "rifle", "rig", "rigid", "rill", "rim", "rimy", "rink",
|
||||
"Rio", "rip", "ripen", "rise", "risk", "rite", "rival", "river",
|
||||
"road", "roar", "rob", "robe", "robin", "rodeo", "roe", "roil",
|
||||
"role", "Roman", "Rome", "romp", "roof", "room", "roost", "Rosen",
|
||||
"rot", "rouge", "round", "rout", "rove", "Roy", "Royce", "r's",
|
||||
"Ruben", "ruby", "rude", "Rudy", "rug", "rule", "rummy", "run",
|
||||
"rung", "runt", "rupee", "ruse", "rusk", "Russo", "rusty", "Ruth",
|
||||
"rutty", "Ryan", "rye", "sa", "sabra", "sad", "sag", "sage",
|
||||
"sake", "sale", "Salk", "salty", "salve", "Sam", "same", "Samoa",
|
||||
"sane", "sank", "Santa", "Sao", "sappy", "Sarah", "sari", "satyr",
|
||||
"Saudi", "Sault", "save", "savvy", "SC", "scald", "scalp", "scarf",
|
||||
"scat", "SCM", "scold", "scoot", "Scot", "scram", "scrub", "scud",
|
||||
"scull", "scum", "SD", "seal", "seamy", "sect", "sedge", "seedy",
|
||||
"seen", "seize", "semi", "sepal", "Sepoy", "septa", "serge", "serif",
|
||||
"servo", "set", "Seton", "setup", "sewn", "shad", "shag", "shah",
|
||||
"shaky", "shall", "shank", "shard", "Shari", "shaw", "Shea", "shed",
|
||||
"sheer", "shied", "shift", "shill", "shin", "shirk", "shish", "shoo",
|
||||
"shore", "shout", "shrew", "shrub", "shunt", "SIAM", "sib", "sibyl",
|
||||
"side", "sigh", "sigma", "silk", "silly", "silt", "Simon", "since",
|
||||
"sinew", "singe", "sinh", "Sioux", "sir", "siva", "sixty", "skeet",
|
||||
"skew", "skid", "skimp", "skulk", "Skye", "slab", "slag", "slake",
|
||||
"slap", "slay", "sleep", "sleet", "slick", "slim", "slimy", "slog",
|
||||
"slosh", "sloth", "slow", "slug", "slum", "slung", "slurp", "sly",
|
||||
"small", "smile", "smith", "smog", "smoky", "snack", "snark", "sneer",
|
||||
"snell", "snip", "snoop", "snore", "snow", "snub", "snug", "so",
|
||||
"soap", "soar", "soft", "soggy", "sold", "sole", "solid", "Solon",
|
||||
"solve", "some", "son", "sonny", "soon", "sorb", "sore", "sort",
|
||||
"south", "sow", "spa", "spade", "spare", "spark", "spasm", "spate",
|
||||
"spawn", "spear", "speed", "spell", "Spica", "spicy", "spiky", "spire",
|
||||
"Spiro", "splay", "spoil", "spook", "spool", "spore", "spout", "spree",
|
||||
"sprue", "spur", "spy", "squaw", "s's", "St", "stag", "staid",
|
||||
"stair", "stale", "stall", "stamp", "stand", "stark", "stash", "state",
|
||||
"stay", "stead", "steak", "steam", "steed", "Steen", "steer", "stern",
|
||||
"stew", "stile", "stilt", "stock", "stole", "stone", "stood", "stool",
|
||||
"stop", "storm", "story", "stove", "strap", "straw", "strip", "strum",
|
||||
"stud", "study", "stung", "stunt", "Sturm", "styli", "suave", "such",
|
||||
"sud", "sue", "Suez", "suit", "sulky", "sung", "sunny", "sup",
|
||||
"supra", "surge", "Sus", "sushi", "swank", "swap", "swear", "swelt",
|
||||
"swig", "swine", "swish", "swiss", "sword", "swung", "Syria", "syrup",
|
||||
"tab", "tabu", "tacit", "taffy", "Tahoe", "take", "tale", "talk",
|
||||
"tamp", "tang", "tango", "tanh", "Tanya", "tap", "tape", "tapir",
|
||||
"tappa", "tar", "tardy", "tarry", "task", "tasty", "tate", "tawny",
|
||||
"taxi", "teach", "tease", "tecum", "Telex", "tempt", "tenon", "tense",
|
||||
"tepid", "terry", "Tess", "Texas", "Thai", "than", "that", "Thea",
|
||||
"thee", "them", "then", "theta", "they", "thick", "thigh", "thin",
|
||||
"thing", "third", "three", "threw", "thug", "thus", "ti", "tibet",
|
||||
"tic", "tid", "tidy", "tied", "tift", "til", "tile", "tilt",
|
||||
"Timex", "Timon", "tinge", "tipsy", "tire", "tit", "tithe", "title",
|
||||
"TNT", "toad", "today", "tog", "Togo", "toil", "token", "told",
|
||||
"tome", "tommy", "tonal", "tong", "Toni", "tonk", "tony", "tool",
|
||||
"tooth", "top", "tor", "torch", "tori", "torr", "torso", "torus",
|
||||
"total", "totem", "tout", "tower", "town", "toxin", "track", "Tracy",
|
||||
"trag", "trail", "trait", "tramp", "trap", "tread", "tree", "trend",
|
||||
"tress", "trial", "tribe", "trill", "tripe", "troll", "troop", "trout",
|
||||
"truck", "Trudy", "trunk", "trust", "TRW", "t's", "TTL", "tub",
|
||||
"tube", "tuck", "Tudor", "tuft", "tulle", "tum", "tuna", "tune",
|
||||
"tunic", "Turin", "turk", "turn", "tusk", "tutu", "tweak", "twice",
|
||||
"twill", "twine", "twirl", "twit", "two", "tying", "ugly", "ultra",
|
||||
"umbra", "uncle", "union", "unite", "upend", "upper", "upset", "Upton",
|
||||
"urban", "urine", "us", "usage", "use", "USGS", "USIA", "usual",
|
||||
"usurp", "Utah", "utile", "v", "vade", "vague", "vain", "valid",
|
||||
"valve", "van", "vase", "vast", "Veda", "veer", "vein", "Vella",
|
||||
"venom", "Venus", "verb", "Verde", "versa", "vest", "vetch", "vex",
|
||||
"via", "vicar", "Vichy", "Vida", "vie", "Viet", "vigil", "viii",
|
||||
"villa", "vise", "visor", "vitae", "Vito", "viva", "vixen", "vocal",
|
||||
"voice", "Volta", "vowel", "v's", "w", "wack", "wacky", "wad",
|
||||
"wade", "wafer", "wag", "wah", "wail", "wait", "waive", "waken",
|
||||
"wale", "wally", "wan", "war", "ward", "ware", "warm", "warp",
|
||||
"warty", "was", "washy", "water", "watt", "Watts", "way", "Wayne",
|
||||
"weal", "wean", "wear", "web", "weber", "we'd", "wedge", "weed",
|
||||
"week", "Wei", "weird", "Welch", "well", "welsh", "wept", "were",
|
||||
"west", "wet", "wharf", "whee", "whelm", "when", "which", "whim",
|
||||
"whir", "whisk", "white", "whiz", "whoa", "whole", "whoop", "whop",
|
||||
"whose", "why", "widen", "widow", "wield", "Wier", "wile", "will",
|
||||
"Wilma", "wilt", "win", "winch", "wino", "wipe", "wise", "wispy",
|
||||
"witch", "withy", "witty", "woe", "wok", "wolve", "womb", "Wong",
|
||||
"Woods", "wool", "wop", "wordy", "work", "worm", "worse", "worst",
|
||||
"wove", "wow", "wreck", "wrest", "wrist", "Wu", "Wyatt", "Wylie",
|
||||
"Wyner", "x", "xenon", "x's", "yacht", "Yale", "yam", "yang",
|
||||
"yarn", "Yates", "year", "yeast", "Yeats", "Yemen", "yield", "yip",
|
||||
"yodel", "yoga", "yoke", "yore", "you'd", "y's", "Yves", "YWCA",
|
||||
"Zeiss", "zest", "zig", "zing", "zip", "Zoe", "zoo"};
|
||||
@ -0,0 +1,157 @@
|
||||
/*
|
||||
|
||||
This file is part of the TACLeBench benchmark suite.
|
||||
Version 2.0
|
||||
|
||||
Name: anagram_stdlib.c
|
||||
|
||||
Author: Raymond Chen
|
||||
|
||||
Function: This file contains the C standard library functions used by anagram.
|
||||
|
||||
Source: anagram
|
||||
|
||||
Original name: anagram
|
||||
|
||||
Changes: See ChangeLog.txt
|
||||
|
||||
License: See anagram.c
|
||||
|
||||
*/
|
||||
#include "anagram_stdlib.h"
|
||||
#include "anagram_strings.h"
|
||||
|
||||
/* Includes anagram_CompareFrequency */
|
||||
/* This function is included here because the WCC does not */
|
||||
/* support function pointers */
|
||||
#include "anagram_compare.h"
|
||||
|
||||
void
|
||||
anagram_swapi(char *ii, char *ij, unsigned long es) {
|
||||
char *i, *j, c;
|
||||
|
||||
i = (char *) ii;
|
||||
j = (char *) ij;
|
||||
_Pragma("loopbound min 4 max 4") do {
|
||||
c = *i;
|
||||
*i++ = *j;
|
||||
*j++ = c;
|
||||
es -= sizeof(char);
|
||||
}
|
||||
while (es != 0)
|
||||
;
|
||||
}
|
||||
|
||||
char *
|
||||
anagram_pivot(char *a, unsigned long n, unsigned long es) {
|
||||
unsigned long j;
|
||||
char *pi, *pj, *pk;
|
||||
|
||||
j = n / 6 * es;
|
||||
pi = a + j; /* 1/6 */
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
__attribute__((import_module("__pragma"),
|
||||
import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
j += j;
|
||||
pj = pi + j; /* 1/2 */
|
||||
pk = pj + j; /* 5/6 */
|
||||
if (anagram_CompareFrequency(pi, pj) < 0) {
|
||||
if (anagram_CompareFrequency(pi, pk) < 0) {
|
||||
if (anagram_CompareFrequency(pj, pk) < 0)
|
||||
return pj;
|
||||
return pk;
|
||||
}
|
||||
return pi;
|
||||
}
|
||||
if (anagram_CompareFrequency(pj, pk) < 0) {
|
||||
if (anagram_CompareFrequency(pi, pk) < 0)
|
||||
return pi;
|
||||
return pk;
|
||||
}
|
||||
return pj;
|
||||
}
|
||||
|
||||
void
|
||||
anagram_qsorts(char *a, unsigned long n, unsigned long es) {
|
||||
unsigned long j;
|
||||
char *pi, *pj, *pn;
|
||||
volatile unsigned int flowfactdummy = 0;
|
||||
__pragma_loopbound(0, 3);
|
||||
while (n > 1) {
|
||||
if (n > 10)
|
||||
pi = anagram_pivot(a, n, es);
|
||||
else
|
||||
pi = a + (n >> 1) * es;
|
||||
|
||||
anagram_swapi(a, pi, es);
|
||||
pi = a;
|
||||
pn = a + n * es;
|
||||
pj = pn;
|
||||
__pragma_loopbound(0, 10);
|
||||
while (1) {
|
||||
/* wcc note: this assignment expression was added to avoid
|
||||
assignment of multiple loop bound annotations to same loop (cf.
|
||||
Ticket #0002323). */
|
||||
flowfactdummy++;
|
||||
__pragma_loopbound(1, 6);
|
||||
do {
|
||||
pi += es;
|
||||
} while (pi < pn && anagram_CompareFrequency(pi, a) < 0);
|
||||
__pragma_loopbound(1, 7);
|
||||
do {
|
||||
pj -= es;
|
||||
} while (pj > a && anagram_CompareFrequency(pj, a) > 0);
|
||||
if (pj < pi)
|
||||
break;
|
||||
anagram_swapi(pi, pj, es);
|
||||
}
|
||||
anagram_swapi(a, pj, es);
|
||||
j = (unsigned long) (pj - a) / es;
|
||||
n = n - j - 1;
|
||||
if (j >= n) {
|
||||
anagram_qsorts(a, j, es);
|
||||
a += (j + 1) * es;
|
||||
} else {
|
||||
anagram_qsorts(a + (j + 1) * es, n, es);
|
||||
n = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
anagram_qsort(void *va, unsigned long n, unsigned long es) {
|
||||
_Pragma("marker call_qsorts") anagram_qsorts((char *) va, n, es);
|
||||
_Pragma("flowrestriction 1*anagram_qsorts <= 17*call_qsorts");
|
||||
}
|
||||
|
||||
/* This must be redefined for each new benchmark */
|
||||
#define ANAGRAM_HEAP_SIZE 21000
|
||||
|
||||
static char anagram_simulated_heap[ANAGRAM_HEAP_SIZE];
|
||||
static unsigned int anagram_freeHeapPos;
|
||||
|
||||
void *
|
||||
anagram_malloc(unsigned int numberOfBytes) {
|
||||
void *currentPos = (void *) &anagram_simulated_heap[anagram_freeHeapPos];
|
||||
/* Get a 4-byte address for alignment purposes */
|
||||
// anagram_freeHeapPos += ( ( numberOfBytes + 4 ) & ( unsigned int
|
||||
// )0xfffffffc );
|
||||
unsigned int rem = (numberOfBytes & (unsigned int) 0x3);
|
||||
unsigned int adjustment = rem ? 4 - rem : 0;
|
||||
anagram_freeHeapPos += numberOfBytes + adjustment;
|
||||
return currentPos;
|
||||
}
|
||||
|
||||
void
|
||||
anagram_bzero(char *p, unsigned long len) {
|
||||
unsigned long i;
|
||||
|
||||
__pragma_loopbound(8, 800);
|
||||
for (i = 0; i < len; ++i) {
|
||||
*p++ = '\0';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
/*
|
||||
|
||||
This header is part of the TACLeBench benchmark suite.
|
||||
Version 2.0
|
||||
|
||||
Name: anagram_stdlib.h
|
||||
|
||||
Author: Raymond Chen
|
||||
|
||||
Function: This header contains some C standard library functions used by
|
||||
anagram.
|
||||
|
||||
Source: unknown
|
||||
|
||||
Original name: anagram
|
||||
|
||||
Changes: See ChangeLog.txt
|
||||
|
||||
License: See anagram.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef ANAGRAM_STDLIB_H
|
||||
#define ANAGRAM_STDLIB_H
|
||||
|
||||
void *anagram_malloc(unsigned int numberOfBytes);
|
||||
|
||||
void anagram_qsort(void *va, unsigned long n, unsigned long es);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,28 @@
|
||||
/*
|
||||
|
||||
This header is part of the TACLeBench benchmark suite.
|
||||
Version 2.0
|
||||
|
||||
Name: anagram_strings.h
|
||||
|
||||
Author: Raymond Chen
|
||||
|
||||
Function: This header contains some C standard library functions used by
|
||||
anagram.
|
||||
|
||||
Source: unknown
|
||||
|
||||
Original name: anagram
|
||||
|
||||
Changes: See ChangeLog.txt
|
||||
|
||||
License: See anagram.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef ANAGRAM_STRINGS_H
|
||||
#define ANAGRAM_STRINGS_H
|
||||
|
||||
void anagram_bzero(char *p, unsigned long len);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user