# /VEX/pub/
/VEX/pub/libvex_guest_offsets.h
-# /VEX/switchback/
-/VEX/switchback/switchback
-
*.vgtest*.trs
*.vgtest*.log
/test-suite-overall.log
+++ /dev/null
-
-CC=aarch64-linux-gnu-gcc
-
-all: switchback.c linker.c linker.h
- $CC -m64 -Wall -O -g -o switchback switchback.c linker.c \
- ../libvex_ppc64_linux.a
-
-test_ppc:
- $CC -Wall -m64 -mregnames -O -c test_ppc_jm1.c
-
-clean:
- rm -f switchback switchback.o linker.o
+++ /dev/null
-#!/usr/bin/env perl
-use strict;
-use warnings;
-
-######################################################
-# Binary search script for switchback
-# Finds bad basic block for seg faults and bad output.
-#
-# To test output, you need to create test_ref
-# test_ref should hold the correct output for running the test_xxx program:
-# - Everything between (not including) /^---START---$/ and /^---STOP---$/
-# - But NOT including output from /^---begin SWITCHBACK/
-# to /^--- end SWITCHBACK/ inclusive
-#
-# This script can't handle other vex output,
-# so e.g switchback.c::DEBUG_TRACE_FLAGS should be 0
-#
-
-######################################################
-# Global consts, vars
-use constant DEBUG => 0;
-use constant CONST_N_MAX => 10000000000;
-use constant CONST_N_MUL => 2;
-
-my $SWITCHBACK = "./switchback";
-my $N_START = 0;
-my $N_LAST_GOOD = 0;
-my $N_LAST_BAD = -1;
-my $GIVEN_LAST_GOOD = -1;
-my $GIVEN_LAST_BAD = -1;
-my $TEST_REF;
-
-
-
-######################################################
-# Helper functions
-
-sub Exit {
- exit $_[0];
-}
-
-sub Usage {
- print "Usage: binary_switchback.pl test_ref [last_good [last_bad]]\n";
- print "where:\n";
- print " test_ref = reference output from test_xxx\n";
- print " last_good = last known good bb (search space minimum)\n";
- print " last_bad = last known bad bb (search space maximum)\n";
- print "\n";
-}
-
-sub QuitUsage {
- print $_[0]."\n";
- Usage();
- Exit 1;
-}
-
-
-######################################################
-# Get & check cmdline args
-# - if given, override global vars.
-
-if (@ARGV < 1 || @ARGV > 3) {
- QuitUsage "Error: Bad num args\n";
-}
-
-$TEST_REF = $ARGV[0];
-
-if ( ! -x "$SWITCHBACK" ) {
- QuitUsage "File doesn't exist | not executable: '$SWITCHBACK'\n";
-}
-
-if (@ARGV >1) {
- $N_LAST_GOOD = $ARGV[1];
- $GIVEN_LAST_GOOD = $N_LAST_GOOD;
- if (! ($N_LAST_GOOD =~ /^\d*$/)) {
- QuitUsage "Error: bad arg for #last_good\n";
- }
- if ($N_LAST_GOOD >= CONST_N_MAX) {
- QuitUsage "Error: #last_good >= N_MAX(".CONST_N_MAX.")\n";
- }
-}
-if (@ARGV >2) {
- $N_LAST_BAD = $ARGV[2];
- $GIVEN_LAST_BAD = $N_LAST_BAD;
- if (! ($N_LAST_BAD =~ /^\d*$/)) {
- QuitUsage "Error: bad arg for 'last_bad'\n";
- }
-}
-
-# Setup N_START
-if ($N_LAST_BAD != -1) {
- # Start halfway:
- my $diff = $N_LAST_BAD - $N_LAST_GOOD;
- $N_START = $N_LAST_GOOD + ($diff - ($diff % 2)) / 2;
-} else {
- # No known end: Start at beginning:
- if ($N_LAST_GOOD > 0) { # User-given last_good
- $N_START = $N_LAST_GOOD;
- } else {
- $N_START = 100; # Some reasonable number.
- }
-}
-
-######################################################
-# Sanity checks (shouldn't ever happen)
-
-if ($N_START < $N_LAST_GOOD) {
- print "Program Error: start < last_good\n";
- exit 1;
-}
-if ($N_LAST_BAD != -1 && $N_START >= $N_LAST_BAD) {
- print "Program Error: start >= last_bad\n";
- exit 1;
-}
-if ($N_START < 1 || $N_START > CONST_N_MAX) {
- print "Program Error: Bad N_START: '$N_START'\n";
- exit 1;
-}
-if ($N_LAST_GOOD < 0 || $N_LAST_GOOD > CONST_N_MAX) {
- print "Program Error: Bad N_LAST_GOOD: '$N_LAST_GOOD'\n";
- exit 1;
-}
-if ($N_LAST_BAD < -1 || $N_LAST_BAD > CONST_N_MAX) {
- print "Program Error: Bad N_LAST_BAD: '$N_LAST_BAD'\n";
- exit 1;
-}
-
-
-
-
-
-
-######################################################
-# Helper functions
-
-# Run switchback for test, for N bbs
-# returns output results
-sub SwitchBack {
- my $n = $_[0];
- if ($n < 0 || $n > CONST_N_MAX) {
- print "Error SwitchBack: Bad N: '$n'\n";
- Exit 1;
- }
- my $TMPFILE = ".switchback_output.$n";
-
- print "=== Calling switchback for bb $n ===\n";
-
- system("$SWITCHBACK $n >& $TMPFILE");
- my $ret = $?;
-
- if ($ret == 256) {
- print "Error running switchback - Quitting...\n---\n";
- open(INFILE, "$TMPFILE");
- print <INFILE>;
- close(INFILE);
-
- unlink($TMPFILE) if (! DEBUG);
- exit 0;
- }
-
- if ($ret & 127) {
- print "Ctrl-C pressed - Quitting...\n";
- unlink($TMPFILE) if (! DEBUG);
- exit 0;
- }
-
- if (DEBUG) {
- if ($ret == -1) {
- print "failed to execute: $!\n";
- }
- elsif ($ret & 127) {
- printf "child died with signal %d, %s coredump\n",
- ($ret & 127), ($ret & 128) ? 'with' : 'without';
- }
- else {
- printf "child exited with value %d\n", $ret >> 8;
- }
- }
- if ($ret != 0) { # Err: maybe seg fault
- open(INFILE, "$TMPFILE");
- my @results = <INFILE>;
- close(INFILE);
-
- while (@results && !((shift @results) =~ /^---START---/)) {}
- print @results;
-
- unlink($TMPFILE) if (! DEBUG);
- return;
- }
-
- open(INFILE, "$TMPFILE");
- my @results = <INFILE>;
- close(INFILE);
-
- unlink($TMPFILE) if (! DEBUG);
- return @results;
-}
-
-# Returns N simulated bbs from output lines
-sub get_N_simulated {
- my @lines = @{$_[0]};
- pop @lines; # not the first...
- my $line = pop @lines; # ...but the second line.
-
- chomp $line;
- my $n;
- if (($n) = ($line =~ /^(\d*) bbs simulated$/)) {
- return $n;
- }
- print "Error: Didn't find N bbs simultated, from output lines\n";
- Exit 1;
-}
-
-# Calls test script to compare current output lines with a reference.
-# Returns 1 on success, 0 on failure
-sub TestOutput {
- my @lines = @{$_[0]};
- my $n = $_[1];
- my $ref_output = "$TEST_REF";
-
- # Get the current section we want to compare:
- my @newlines;
- my $ok=0;
- my $halfline = "";
- foreach my $line(@lines) {
- chomp $line;
- if ($line =~ /^---STOP---$/) { last; } # we're done
-
- # output might be messed up here...
- if ($line =~ /^.*---begin SWITCHBACK/) {
- ($halfline) = ($line =~ /^(.*)---begin SWITCHBACK/);
- $ok = 0; # stop on prev line
- }
-
- # A valid line:
- if ($ok) {
- if ($halfline ne "") { # Fix broken line
- $line = $halfline.$line;
- $halfline = "";
- }
-
- # Ignore Vex output
- if ($line =~ /^vex /) { next; }
-
- push(@newlines, $line);
- }
-
- if ($line =~ /^---START---$/) { # start on next line
- $ok = 1;
- }
-
- if ($line =~ /^--- end SWITCHBACK/) { # start on next line
- $ok = 1;
-
- }
- }
-
- if (DEBUG) {
- open(OUTFILE, ">.filtered_output.$n");
- print OUTFILE join("\n",@newlines);
- close(OUTFILE);
- }
-
- # Read in reference lines
- open(REFERENCE, "$ref_output") || die "Error: Couldn't open $ref_output\n";
- my @ref_lines = <REFERENCE>;
- close(REFERENCE);
-
- # Compare reference lines with current:
- my $match = 1;
- my $i = 0;
- foreach my $ref_line(@ref_lines) {
- chomp $ref_line;
- my $line = $newlines[$i++];
- chomp $line;
- if ($ref_line ne $line) {
- print "\nMismatch on output:\n";
- print "ref: '$ref_line'\n";
- print "new: '$line'\n\n";
- $match = 0;
- last;
- }
- }
- return $match;
-}
-
-
-
-
-
-
-######################################################
-# Do the search
-
-if (DEBUG) {
- print "\n------------\n";
- print "START: N=$N_START\n";
- print "START: lg=$N_LAST_GOOD\n";
- print "START: lb=$N_LAST_BAD\n";
- print "START: GIVEN_LAST_GOOD=$GIVEN_LAST_GOOD\n";
- print "START: GIVEN_LAST_BAD =$GIVEN_LAST_BAD\n";
- print "\n";
-}
-
-my $N = $N_START;
-my $success = 0;
-my @sb_output;
-while (1) {
- if (DEBUG) {
- print "\n------------\n";
- print "SOL: lg=$N_LAST_GOOD\n";
- print "SOL: lb=$N_LAST_BAD\n";
- print "SOL: N=$N\n";
- }
- if ($N < 0) {
- print "Error: $N<0\n";
- Exit 1;
- }
-
- my $ok = 1;
- # Run switchback:
- @sb_output = SwitchBack($N);
-
- if (@sb_output == 0) { # Switchback failed - maybe seg fault
- $ok = 0;
- }
-
- if (DEBUG) {
- open(fileOUT, ">.retrieved_output.$N") or die("Can't open file for writing: $!");
- print fileOUT @sb_output;
- close(fileOUT);
- }
-
- # If we're ok so far (no seg faults) then test for correct output
- if ($ok) {
- $ok = TestOutput( \@sb_output, $N );
- }
-
- if ($ok) {
- if (get_N_simulated(\@sb_output) < $N) { # Done: No bad bbs
- $success = 1;
- last;
- }
- if ($N_LAST_BAD == -1) {
- # No upper bound for search space
- # Try again with a bigger N
-
- $N_LAST_GOOD = $N;
- $N *= CONST_N_MUL;
- if ($N > CONST_N_MAX) {
- print "\nError: Maxed out N($N): N_MAX=".CONST_N_MAX."\n";
- print "\nWe're either in a loop, or this is a big test program (increase N_MAX)\n\n";
- Exit 1;
- }
- if (DEBUG) {
- print "Looks good so far: Trying bigger N...\n\n";
- }
- next;
- }
- }
-
- # Narrow the search space:
- if ($ok) { $N_LAST_GOOD = $N; }
- else { $N_LAST_BAD = $N; }
-
- # Calculate next step:
- my $diff = $N_LAST_BAD - $N_LAST_GOOD;
- $diff = $diff - ($diff % 2);
- my $step = $diff / 2;
-
- if ($step < 0) {
- print "Error: step = $step\n";
- Exit 1;
- }
-
- # This our last run-through?
- if ($step!=0) {
- $N = $N_LAST_GOOD + $step; # Keep on going...
- } else {
- last; # Get outta here
- }
-
- if (DEBUG) {
- print "\nEOL: ok=$ok\n";
- print "EOL: lg=$N_LAST_GOOD\n";
- print "EOL: lb=$N_LAST_BAD\n";
- print "EOL: s=$step\n";
- print "EOL: N=$N\n";
- }
-}
-
-
-
-######################################################
-# Done: Report results
-
-print "\n============================================\n";
-print "Done searching.\n\n";
-
-if ($N_LAST_BAD != -1 && $N != $N_LAST_BAD) {
- print "Getting output for last bad bb:\n";
- @sb_output = SwitchBack($N_LAST_BAD);
-}
-
-print @sb_output;
-print "\n\n";
-if ($success) {
- print "*** Success! No bad bbs found. ***\n";
-} else {
- if ($N_LAST_BAD == $GIVEN_LAST_BAD) {
- print "*** No failures detected within given bb range ***\n";
- print " - check given 'last_bad' argument\n";
- } else {
- if ($N_LAST_BAD == $GIVEN_LAST_GOOD) {
- print "*** Failed on bb given as last_good ***\n";
- print " - decrease the 'last_good' argument\n";
- } else {
- print "*** Failure: Last failed switchback bb: $N_LAST_BAD ***\n";
- print "Hence bad bb: ". ($N_LAST_BAD - 1) ."\n";
- }
- }
-}
-print "\n";
-if (DEBUG) {
- print "END: N=$N\n";
- print "END: lg=$N_LAST_GOOD\n";
- print "END: lb=$N_LAST_BAD\n";
- print "END: GIVEN_LAST_BAD=$GIVEN_LAST_BAD\n";
- print "\n";
-}
-Exit 0;
+++ /dev/null
-/*
- 13 Dec '05
- Linker no longer used - apart from mymalloc().
- Instead, simply compile and link switchback.c with test_xxx.c, e.g.:
- ./> (cd .. && make EXTRA_CFLAGS="-m64" libvex_ppc64_linux.a) && gcc -m64 -Wall -O -g -o switchback switchback.c linker.c ../libvex_ppc64_linux.a test_bzip2.c
-*/
-
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <elf.h>
-#include <fcntl.h>
-#include <string.h>
-//#include <malloc.h>
-
-#include "linker.h"
-
-#include "../pub/libvex_basictypes.h"
-
-#if 0
-#define IF_DEBUG(x,y) /* */
-static int debug_linker = 0;
-#endif
-
-
-#if defined(__x86_64__)
-# define x86_64_TARGET_ARCH
-#elif defined(__i386__)
-# define i386_TARGET_ARCH
-#elif defined (__powerpc__)
-# define ppc32_TARGET_ARCH
-#elif defined(__aarch64__)
-# define arm64_TARGET_ARCH
-#else
-# error "Unknown arch"
-#endif
-
-
-#if 0
-#define CALLOC_MAX 10000000
-static HChar calloc_area[CALLOC_MAX];
-static UInt calloc_used = 0;
-static void* calloc_below2G ( Int n, Int m )
-{
- void* p;
- int i;
- while ((calloc_used % 16) > 0) calloc_used++;
- assert(calloc_used + n*m < CALLOC_MAX);
- p = &calloc_area[calloc_used];
- for (i = 0; i < n*m; i++)
- calloc_area[calloc_used+i] = 0;
- calloc_used += n*m;
- return p;
-}
-#endif
-
-#define MYMALLOC_MAX 50*1000*1000
-static HChar mymalloc_area[MYMALLOC_MAX];
-static UInt mymalloc_used = 0;
-void* mymalloc ( Int n )
-{
- void* p;
-#if defined(__powerpc64__) || defined(__aarch64__)
- while ((ULong)(mymalloc_area+mymalloc_used) & 0xFFF)
-#else
- while ((UInt)(mymalloc_area+mymalloc_used) & 0xFFF)
-#endif
- mymalloc_used++;
- assert(mymalloc_used+n < MYMALLOC_MAX);
- p = (void*)(&mymalloc_area[mymalloc_used]);
- mymalloc_used += n;
- // printf("mymalloc(%d) = %p\n", n, p);
- return p;
-}
-
-void myfree ( void* p )
-{
-}
-
-
-
-
-
-
-
-#if 0
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-//
-// TYPES
-
-#define FALSE 0
-#define TRUE 1
-
-typedef enum { OBJECT_LOADED, OBJECT_RESOLVED } OStatus;
-
-
-#define N_FIXUP_PAGES 1
-
-
-/* Indication of section kinds for loaded objects. Needed by
- the GC for deciding whether or not a pointer on the stack
- is a code pointer.
-*/
-typedef
- enum { SECTIONKIND_CODE_OR_RODATA,
- SECTIONKIND_RWDATA,
- SECTIONKIND_OTHER,
- SECTIONKIND_NOINFOAVAIL }
- SectionKind;
-
-typedef
- struct _Section {
- void* start;
- void* end;
- SectionKind kind;
- struct _Section* next;
- }
- Section;
-
-typedef
- struct _ProddableBlock {
- void* start;
- int size;
- struct _ProddableBlock* next;
- }
- ProddableBlock;
-
-/* Top-level structure for an object module. One of these is allocated
- * for each object file in use.
- */
-typedef struct _ObjectCode {
- OStatus status;
- char* fileName;
- int fileSize;
- char* formatName; /* eg "ELF32", "DLL", "COFF", etc. */
-
- /* An array containing ptrs to all the symbol names copied from
- this object into the global symbol hash table. This is so that
- we know which parts of the latter mapping to nuke when this
- object is removed from the system. */
- char** symbols;
- int n_symbols;
-
- /* ptr to malloc'd lump of memory holding the obj file */
- void* image;
-
- /* Fixup area for long-distance jumps. */
- char* fixup;
- int fixup_used;
- int fixup_size;
-
- /* The section-kind entries for this object module. Linked
- list. */
- Section* sections;
-
- /* A private hash table for local symbols. */
- /* HashTable* */ void* lochash;
-
- /* Allow a chain of these things */
- struct _ObjectCode * next;
-
- /* SANITY CHECK ONLY: a list of the only memory regions which may
- safely be prodded during relocation. Any attempt to prod
- outside one of these is an error in the linker. */
- ProddableBlock* proddables;
-
-} ObjectCode;
-
-/*
- * Define a set of types which can be used for both ELF32 and ELF64
- */
-
-#if VEX_HOST_WORDSIZE == 8
-#define ELFCLASS ELFCLASS64
-#define Elf_Addr Elf64_Addr
-#define Elf_Word Elf64_Word
-#define Elf_Sword Elf64_Sword
-#define Elf_Ehdr Elf64_Ehdr
-#define Elf_Phdr Elf64_Phdr
-#define Elf_Shdr Elf64_Shdr
-#define Elf_Sym Elf64_Sym
-#define Elf_Rel Elf64_Rel
-#define Elf_Rela Elf64_Rela
-#define ELF_ST_TYPE ELF64_ST_TYPE
-#define ELF_ST_BIND ELF64_ST_BIND
-#define ELF_R_TYPE ELF64_R_TYPE
-#define ELF_R_SYM ELF64_R_SYM
-#else
-#define ELFCLASS ELFCLASS32
-#define Elf_Addr Elf32_Addr
-#define Elf_Word Elf32_Word
-#define Elf_Sword Elf32_Sword
-#define Elf_Ehdr Elf32_Ehdr
-#define Elf_Phdr Elf32_Phdr
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Rel Elf32_Rel
-#define Elf_Rela Elf32_Rela
-#ifndef ELF_ST_TYPE
-#define ELF_ST_TYPE ELF32_ST_TYPE
-#endif
-#ifndef ELF_ST_BIND
-#define ELF_ST_BIND ELF32_ST_BIND
-#endif
-#ifndef ELF_R_TYPE
-#define ELF_R_TYPE ELF32_R_TYPE
-#endif
-#ifndef ELF_R_SYM
-#define ELF_R_SYM ELF32_R_SYM
-#endif
-#endif
-
-
-
-
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-//
-// PARANOIA
-
-/* -----------------------------------------------------------------------
- * Sanity checking. For each ObjectCode, maintain a list of address ranges
- * which may be prodded during relocation, and abort if we try and write
- * outside any of these.
- */
-static void addProddableBlock ( ObjectCode* oc, void* start, int size )
-{
- ProddableBlock* pb
- = mymalloc(sizeof(ProddableBlock));
- if (debug_linker)
- fprintf(stderr, "aPB oc=%p %p %d (%p .. %p)\n", oc, start, size,
- start, ((char*)start)+size-1 );
- assert(size > 0);
- pb->start = start;
- pb->size = size;
- pb->next = oc->proddables;
- oc->proddables = pb;
-}
-
-static void checkProddableBlock ( ObjectCode* oc, void* addr )
-{
- ProddableBlock* pb;
- for (pb = oc->proddables; pb != NULL; pb = pb->next) {
- char* s = (char*)(pb->start);
- char* e = s + pb->size - 1;
- char* a = (char*)addr;
- /* Assumes that the biggest fixup involves a 4-byte write. This
- probably needs to be changed to 8 (ie, +7) on 64-bit
- plats. */
- if (a >= s && (a+3) <= e) return;
- }
- fprintf(stderr,
- "checkProddableBlock: invalid fixup %p in runtime linker\n",
- addr);
- exit(1);
-}
-
-
-
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-//
-// String->Addr mappings
-
-typedef
- struct { char* mp_name; void* mp_addr; }
- Maplet;
-
-typedef
- struct {
- int sm_size;
- int sm_used;
- Maplet* maplets;
- }
- StringMap;
-
-static StringMap* new_StringMap ( void )
-{
- StringMap* sm = mymalloc(sizeof(StringMap));
- sm->sm_size = 10;
- sm->sm_used = 0;
- sm->maplets = mymalloc(10 * sizeof(Maplet));
- return sm;
-}
-
-static void delete_StringMap ( StringMap* sm )
-{
- assert(sm->maplets != NULL);
- myfree(sm->maplets);
- sm->maplets = NULL;
- myfree(sm);
-}
-
-static void ensure_StringMap ( StringMap* sm )
-{
- int i;
- Maplet* mp2;
- assert(sm->maplets != NULL);
- if (sm->sm_used < sm->sm_size)
- return;
- sm->sm_size *= 2;
- mp2 = mymalloc(sm->sm_size * sizeof(Maplet));
- for (i = 0; i < sm->sm_used; i++)
- mp2[i] = sm->maplets[i];
- myfree(sm->maplets);
- sm->maplets = mp2;
-}
-
-static void* search_StringMap ( StringMap* sm, char* name )
-{
- int i;
- for (i = 0; i < sm->sm_used; i++)
- if (0 == strcmp(name, sm->maplets[i].mp_name))
- return sm->maplets[i].mp_addr;
- return NULL;
-}
-
-static void addto_StringMap ( StringMap* sm, char* name, void* addr )
-{
- ensure_StringMap(sm);
- sm->maplets[sm->sm_used].mp_name = name;
- sm->maplets[sm->sm_used].mp_addr = addr;
- sm->sm_used++;
-}
-
-static void paranoid_addto_StringMap ( StringMap* sm, char* name, void* addr )
-{
- if (0)
- fprintf(stderr, "paranoid_addto_StringMap(%s,%p)\n", name, addr);
- if (search_StringMap(sm,name) != NULL) {
- fprintf(stderr, "duplicate: paranoid_addto_StringMap(%s,%p)\n", name, addr);
- exit(1);
- }
- addto_StringMap(sm,name,addr);
-}
-
-
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-//
-// Top-level linker control.
-
-StringMap* global_symbol_table = NULL;
-ObjectCode* global_object_list = NULL;
-
-static void initLinker ( void )
-{
- if (global_symbol_table != NULL)
- return;
- global_symbol_table = new_StringMap();
-}
-
-
-
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-//
-// SYMBOL TABLE(s)
-
-/* -----------------------------------------------------------------
- * lookup a symbol in the global symbol table
- */
-static
-void * lookupSymbol( char *lbl )
-{
- void *val;
- initLinker() ;
- assert(global_symbol_table != NULL);
- val = search_StringMap(global_symbol_table, lbl);
- return val;
-}
-
-
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-//
-// HELPERS
-
-/*
- * Generic ELF functions
- */
-
-static char *
-findElfSection ( void* objImage, Elf_Word sh_type )
-{
- char* ehdrC = (char*)objImage;
- Elf_Ehdr* ehdr = (Elf_Ehdr*)ehdrC;
- Elf_Shdr* shdr = (Elf_Shdr*)(ehdrC + ehdr->e_shoff);
- char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
- char* ptr = NULL;
- int i;
-
- for (i = 0; i < ehdr->e_shnum; i++) {
- if (shdr[i].sh_type == sh_type
- /* Ignore the section header's string table. */
- && i != ehdr->e_shstrndx
- /* Ignore string tables named .stabstr, as they contain
- debugging info. */
- && 0 != memcmp(".stabstr", sh_strtab + shdr[i].sh_name, 8)
- ) {
- ptr = ehdrC + shdr[i].sh_offset;
- break;
- }
- }
- return ptr;
-}
-
-#ifdef arm_TARGET_ARCH
-static
-char* alloc_fixup_bytes ( ObjectCode* oc, int nbytes )
-{
- char* res;
- assert(nbytes % 4 == 0);
- assert(nbytes > 0);
- res = &(oc->fixup[oc->fixup_used]);
- oc->fixup_used += nbytes;
- if (oc->fixup_used >= oc->fixup_size) {
- fprintf(stderr, "fixup area too small for %s\n", oc->fileName);
- exit(1);
- }
- return res;
-}
-#endif
-
-
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-//
-// RESOLVE
-
-static
-void* lookup_magic_hacks ( char* sym )
-{
- if (0==strcmp(sym, "printf")) return (void*)(&printf);
- return NULL;
-}
-
-#ifdef arm_TARGET_ARCH
-static
-void arm_notify_new_code ( char* start, int length )
-{
- __asm __volatile ("mov r1, %0\n\t"
- "mov r2, %1\n\t"
- "mov r3, %2\n\t"
- "swi 0x9f0002\n\t"
- :
- : "ir" (start), "ir" (length), "ir" (0) );
-}
-
-
-static
-void gen_armle_goto ( char* fixup, char* dstP )
-{
- Elf_Word w = (Elf_Word)dstP;
- /*
- 2 .text
- 3 0000 04F01FE5 ldr pc, value
- 4 0004 44332211 value: .word 0x11223344
- */
- fprintf(stderr,"at %p generating jump to %p\n", fixup, dstP );
- fixup[0] = 0x04; fixup[1] = 0xF0; fixup[2] = 0x1F; fixup[3] = 0xE5;
- fixup[4] = w & 0xFF; w >>= 8;
- fixup[5] = w & 0xFF; w >>= 8;
- fixup[6] = w & 0xFF; w >>= 8;
- fixup[7] = w & 0xFF; w >>= 8;
- arm_notify_new_code(fixup, 8);
-}
-#endif /* arm_TARGET_ARCH */
-
-
-#ifdef ppc32_TARGET_ARCH
-static void invalidate_icache(void *ptr, int nbytes)
-{
- unsigned long startaddr = (unsigned long) ptr;
- unsigned long endaddr = startaddr + nbytes;
- unsigned long addr;
- unsigned long cls = 16; //VG_(cache_line_size);
-
- startaddr &= ~(cls - 1);
- for (addr = startaddr; addr < endaddr; addr += cls)
- asm volatile("dcbst 0,%0" : : "r" (addr));
- asm volatile("sync");
- for (addr = startaddr; addr < endaddr; addr += cls)
- asm volatile("icbi 0,%0" : : "r" (addr));
- asm volatile("sync; isync");
-}
-
-static UInt compute_ppc_HA ( UInt x ) {
- return 0xFFFF & ( (x >> 16) + ((x & 0x8000) ? 1 : 0) );
-}
-static UInt compute_ppc_LO ( UInt x ) {
- return 0xFFFF & x;
-}
-static UInt compute_ppc_HI ( UInt x ) {
- return 0xFFFF & (x >> 16);
-}
-#endif /* ppc32_TARGET_ARCH */
-
-
-/* Do ELF relocations which lack an explicit addend. All x86-linux
- relocations appear to be of this form. */
-static int
-do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
- Elf_Shdr* shdr, int shnum,
- Elf_Sym* stab, char* strtab )
-{
- int j;
- char *symbol = NULL;
- Elf_Word* targ;
- Elf_Rel* rtab = (Elf_Rel*) (ehdrC + shdr[shnum].sh_offset);
- int nent = shdr[shnum].sh_size / sizeof(Elf_Rel);
- int target_shndx = shdr[shnum].sh_info;
- int symtab_shndx = shdr[shnum].sh_link;
-
- stab = (Elf_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
- targ = (Elf_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
- IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
- target_shndx, symtab_shndx ));
-
- for (j = 0; j < nent; j++) {
- Elf_Addr offset = rtab[j].r_offset;
- Elf_Addr info = rtab[j].r_info;
-
- Elf_Addr P = ((Elf_Addr)targ) + offset;
- Elf_Word* pP = (Elf_Word*)P;
- Elf_Addr A = *pP;
- Elf_Addr S;
- Elf_Addr value;
-
- IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p)",
- j, (void*)offset, (void*)info ));
- if (!info) {
- IF_DEBUG(linker,belch( " ZERO" ));
- S = 0;
- } else {
- Elf_Sym sym = stab[ELF_R_SYM(info)];
- /* First see if it is a local symbol. */
- if (ELF_ST_BIND(sym.st_info) == STB_LOCAL) {
- /* Yes, so we can get the address directly from the ELF symbol
- table. */
- symbol = sym.st_name==0 ? "(noname)" : strtab+sym.st_name;
- S = (Elf_Addr)
- (ehdrC + shdr[ sym.st_shndx ].sh_offset
- + stab[ELF_R_SYM(info)].st_value);
-
- } else {
- /* No, so look up the name in our global table. */
- symbol = strtab + sym.st_name;
- S = (Elf_Addr)lookupSymbol( symbol );
- }
- if (!S) {
- S = (Elf_Addr)lookup_magic_hacks(symbol);
- }
- if (!S) {
- fprintf(stderr,"%s: unknown symbol `%s'\n",
- oc->fileName, symbol);
- return 0;
- }
- if (debug_linker>1)
- fprintf(stderr, "\n`%s' resolves to %p\n", symbol, (void*)S );
- }
-
- if (debug_linker>1)
- fprintf(stderr, "Reloc: P = %p S = %p A = %p\n",
- (void*)P, (void*)S, (void*)A );
- checkProddableBlock ( oc, pP );
-
- value = S + A;
-
- switch (ELF_R_TYPE(info)) {
-# ifdef i386_TARGET_ARCH
- case R_386_32: *pP = value; break;
- case R_386_PC32: *pP = value - P; break;
-# endif
-# ifdef arm_TARGET_ARCH
- case R_ARM_PC24: {
- Elf_Word w, delta, deltaTop8;
- /* Generate a jump sequence into the fixup area
- and branch to that instead. */
- char* fixup = alloc_fixup_bytes(oc, 8);
- /* First of all, figure out where we're really trying to
- jump to. */
- // compensate for pc+8 bias
- Elf_Word real_dst = (A & 0x00FFFFFF) + 2;
- // sign-extend 24-to-32 of real_dst
- if (real_dst & 0x00800000)
- real_dst |= 0xFF000000;
- else
- real_dst &= 0x00FFFFFF;
-
- real_dst <<= 2;
- real_dst += S;
-
- gen_armle_goto(fixup, (char*)real_dst);
-
- /* Delta is in bytes .. */
- delta = (((Elf_Word)fixup) - ((Elf_Word)pP) - 8);
- deltaTop8 = (delta >> 24) & 0xFF;
- if (deltaTop8 != 0 && deltaTop8 != 0xFF) {
- fprintf(stderr,"R_ARM_PC24: out of range delta 0x%x for %s\n",
- delta, symbol);
- exit(1);
- }
- delta >>= 2;
- w = *pP;
- w &= 0xFF000000;
- w |= (0x00FFFFFF & delta );
- *pP = w;
- break;
- }
- case R_ARM_ABS32:
- *pP = value;
- break;
-# endif
- default:
- fprintf(stderr,
- "%s: unhandled ELF relocation(Rel) type %d\n\n",
- oc->fileName, (Int)ELF_R_TYPE(info));
- return 0;
- }
-
- }
- return 1;
-}
-
-/* Do ELF relocations for which explicit addends are supplied.
- sparc-solaris relocations appear to be of this form. */
-static int
-do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
- Elf_Shdr* shdr, int shnum,
- Elf_Sym* stab, char* strtab )
-{
- int j;
- char *symbol;
- Elf_Addr targ;
- Elf_Rela* rtab = (Elf_Rela*) (ehdrC + shdr[shnum].sh_offset);
- int nent = shdr[shnum].sh_size / sizeof(Elf_Rela);
- int target_shndx = shdr[shnum].sh_info;
- int symtab_shndx = shdr[shnum].sh_link;
-
- stab = (Elf_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
- targ = (Elf_Addr) (ehdrC + shdr[ target_shndx ].sh_offset);
- IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
- target_shndx, symtab_shndx ));
-
- for (j = 0; j < nent; j++) {
-#if defined(DEBUG) || defined(sparc_TARGET_ARCH) \
- || defined(ia64_TARGET_ARCH) \
- || defined(x86_64_TARGET_ARCH) \
- || defined(ppc32_TARGET_ARCH)
- /* This #ifdef only serves to avoid unused-var warnings. */
- Elf_Addr offset = rtab[j].r_offset;
- Elf_Addr P = targ + offset;
-#endif
- Elf_Addr info = rtab[j].r_info;
- Elf_Addr A = rtab[j].r_addend;
- Elf_Addr S =0;
- Elf_Addr value;
-# if defined(sparc_TARGET_ARCH)
- Elf_Word* pP = (Elf_Word*)P;
- Elf_Word w1, w2;
-# endif
-# if defined(ia64_TARGET_ARCH)
- Elf64_Xword *pP = (Elf64_Xword *)P;
- Elf_Addr addr;
-# endif
-# if defined(x86_64_TARGET_ARCH)
- ULong* pP = (ULong*)P;
-# endif
-# if defined(ppc32_TARGET_ARCH)
- Int sI, sI2;
- Elf_Word* pP = (Elf_Word*)P;
-# endif
-
- IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p %6p) ",
- j, (void*)offset, (void*)info,
- (void*)A ));
- if (!info) {
- IF_DEBUG(linker,belch( " ZERO" ));
- S = 0;
- } else {
- Elf_Sym sym = stab[ELF_R_SYM(info)];
- /* First see if it is a local symbol. */
- if (ELF_ST_BIND(sym.st_info) == STB_LOCAL) {
- /* Yes, so we can get the address directly from the ELF symbol
- table. */
- symbol = sym.st_name==0 ? "(noname)" : strtab+sym.st_name;
- S = (Elf_Addr)
- (ehdrC + shdr[ sym.st_shndx ].sh_offset
- + stab[ELF_R_SYM(info)].st_value);
-#ifdef ELF_FUNCTION_DESC
- /* Make a function descriptor for this function */
- if (S && ELF_ST_TYPE(sym.st_info) == STT_FUNC) {
- S = allocateFunctionDesc(S + A);
- A = 0;
- }
-#endif
- } else {
- /* No, so look up the name in our global table. */
- symbol = strtab + sym.st_name;
- S = (Elf_Addr)lookupSymbol( symbol );
-
-#ifdef ELF_FUNCTION_DESC
- /* If a function, already a function descriptor - we would
- have to copy it to add an offset. */
- if (S && (ELF_ST_TYPE(sym.st_info) == STT_FUNC) && (A != 0))
- belch("%s: function %s with addend %p", oc->fileName, symbol, (void *)A);
-#endif
- }
- if (!S) {
- fprintf(stderr,"%s: unknown symbol `%s'\n", oc->fileName, symbol);
- return 0;
- }
- if (0)
- fprintf(stderr, "`%s' resolves to %p\n", symbol, (void*)S );
- }
-
-#if 0
- fprintf ( stderr, "Reloc: offset = %p P = %p S = %p A = %p\n",
- (void*)offset, (void*)P, (void*)S, (void*)A );
-#endif
-
- /* checkProddableBlock ( oc, (void*)P ); */
-
- value = S + A;
-
- switch (ELF_R_TYPE(info)) {
-# if defined(sparc_TARGET_ARCH)
- case R_SPARC_WDISP30:
- w1 = *pP & 0xC0000000;
- w2 = (Elf_Word)((value - P) >> 2);
- ASSERT((w2 & 0xC0000000) == 0);
- w1 |= w2;
- *pP = w1;
- break;
- case R_SPARC_HI22:
- w1 = *pP & 0xFFC00000;
- w2 = (Elf_Word)(value >> 10);
- ASSERT((w2 & 0xFFC00000) == 0);
- w1 |= w2;
- *pP = w1;
- break;
- case R_SPARC_LO10:
- w1 = *pP & ~0x3FF;
- w2 = (Elf_Word)(value & 0x3FF);
- ASSERT((w2 & ~0x3FF) == 0);
- w1 |= w2;
- *pP = w1;
- break;
- /* According to the Sun documentation:
- R_SPARC_UA32
- This relocation type resembles R_SPARC_32, except it refers to an
- unaligned word. That is, the word to be relocated must be treated
- as four separate bytes with arbitrary alignment, not as a word
- aligned according to the architecture requirements.
-
- (JRS: which means that freeloading on the R_SPARC_32 case
- is probably wrong, but hey ...)
- */
- case R_SPARC_UA32:
- case R_SPARC_32:
- w2 = (Elf_Word)value;
- *pP = w2;
- break;
-# endif
-# if defined(ia64_TARGET_ARCH)
- case R_IA64_DIR64LSB:
- case R_IA64_FPTR64LSB:
- *pP = value;
- break;
- case R_IA64_PCREL64LSB:
- *pP = value - P;
- break;
- case R_IA64_SEGREL64LSB:
- addr = findElfSegment(ehdrC, value);
- *pP = value - addr;
- break;
- case R_IA64_GPREL22:
- ia64_reloc_gprel22(P, value);
- break;
- case R_IA64_LTOFF22:
- case R_IA64_LTOFF22X:
- case R_IA64_LTOFF_FPTR22:
- addr = allocateGOTEntry(value);
- ia64_reloc_gprel22(P, addr);
- break;
- case R_IA64_PCREL21B:
- ia64_reloc_pcrel21(P, S, oc);
- break;
- case R_IA64_LDXMOV:
- /* This goes with R_IA64_LTOFF22X and points to the load to
- convert into a move. We don't implement relaxation. */
- break;
-# endif
-# if defined(x86_64_TARGET_ARCH)
- case R_X86_64_64: /* 1 *//* Direct 64 bit */
- *((ULong*)pP) = (ULong)(S + A);
- break;
- case R_X86_64_PC32: /* 2 *//* PC relative 32 bit signed */
- *((UInt*)pP) = (UInt)(S + A - P);
- break;
- case R_X86_64_32: /* 10 *//* Direct 32 bit zero extended */
- *((UInt*)pP) = (UInt)(S + A);
- break;
- case R_X86_64_32S: /* 11 *//* Direct 32 bit sign extended */
- *((UInt*)pP) = (UInt)(S + A);
- break;
-# endif
-# if defined(ppc32_TARGET_ARCH)
- case R_PPC_ADDR32: /* 1 *//* 32bit absolute address */
- *((UInt*)pP) = S+A;
- invalidate_icache(pP,4);
- break;
- case R_PPC_ADDR16_LO: /* 4 *//* lower 16bit of absolute address */
- *((UInt*)pP) &= 0x0000FFFF;
- *((UInt*)pP) |= 0xFFFF0000 & (compute_ppc_LO(S+A) << 16);
- invalidate_icache(pP,4);
- break;
- case R_PPC_ADDR16_HA: /* 6 *//* adjusted high 16bit */
- *((UInt*)pP) &= 0x0000FFFF;
- *((UInt*)pP) |= 0xFFFF0000 & (compute_ppc_HA(S+A) << 16);
- invalidate_icache(pP,4);
- break;
- case R_PPC_REL24: /* 10 *//* PC relative 26 bit */
- sI = S+A-P;
- sI >>= 2;
- /* the top 9 bits of sI must be the same (all 0s or
- all 1s) for this to be valid; else we have to fail. */
- sI2 = sI >> 23; /* 23 == 32 - 9 */
- if (sI2 != 0 && sI2 != 0xFFFFFFFF) {
- fprintf(stderr, "%s: R_PPC_REL24 relocation failed\n", oc->fileName );
- return 0;
- }
- *((UInt*)pP) &= ~(0x00FFFFFF << 2);
- *((UInt*)pP) |= (0xFFFFFF & sI) << 2;
- invalidate_icache(pP,4);
- break;
- case R_PPC_REL32: /* 26 */
- *((UInt*)pP) = S+A-P;
- invalidate_icache(pP,4);
- break;
-# endif
- default:
- fprintf(stderr,
- "%s: unhandled ELF relocation(RelA) type %d\n",
- oc->fileName, (Int)ELF_R_TYPE(info));
- return 0;
- }
-
- }
- return 1;
-}
-
-
-static int
-ocResolve_ELF ( ObjectCode* oc )
-{
- char *strtab;
- int shnum, ok;
- Elf_Sym* stab = NULL;
- char* ehdrC = (char*)(oc->image);
- Elf_Ehdr* ehdr = (Elf_Ehdr*) ehdrC;
- Elf_Shdr* shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff);
- char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
-
- /* first find "the" symbol table */
- stab = (Elf_Sym*) findElfSection ( ehdrC, SHT_SYMTAB );
-
- /* also go find the string table */
- strtab = findElfSection ( ehdrC, SHT_STRTAB );
-
- if (stab == NULL || strtab == NULL) {
- fprintf(stderr,"%s: can't find string or symbol table\n", oc->fileName);
- return 0;
- }
-
- /* Process the relocation sections. */
- for (shnum = 0; shnum < ehdr->e_shnum; shnum++) {
-
- /* Skip sections called ".rel.stab". These appear to contain
- relocation entries that, when done, make the stabs debugging
- info point at the right places. We ain't interested in all
- dat jazz, mun. */
- if (0 == memcmp(".rel.stab", sh_strtab + shdr[shnum].sh_name, 9))
- continue;
-
- if (shdr[shnum].sh_type == SHT_REL ) {
- ok = do_Elf_Rel_relocations ( oc, ehdrC, shdr,
- shnum, stab, strtab );
- if (!ok) return ok;
- }
- else
- if (shdr[shnum].sh_type == SHT_RELA) {
- ok = do_Elf_Rela_relocations ( oc, ehdrC, shdr,
- shnum, stab, strtab );
- if (!ok) return ok;
- }
- }
-
- /* Free the local symbol table; we won't need it again. */
- delete_StringMap(oc->lochash);
- oc->lochash = NULL;
-
- return 1;
-}
-
-
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-//
-// VERIFY
-
-static int
-ocVerifyImage_ELF ( ObjectCode* oc )
-{
- Elf_Shdr* shdr;
- Elf_Sym* stab;
- int i, j, nent, nstrtab, nsymtabs;
- char* sh_strtab;
- char* strtab;
-
- char* ehdrC = (char*)(oc->image);
- Elf_Ehdr* ehdr = (Elf_Ehdr*)ehdrC;
-
- if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
- ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
- ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
- ehdr->e_ident[EI_MAG3] != ELFMAG3) {
- fprintf(stderr,"%s: not an ELF object\n", oc->fileName);
- return 0;
- }
-
- if (ehdr->e_ident[EI_CLASS] != ELFCLASS) {
- fprintf(stderr,"%s: unsupported ELF format\n", oc->fileName);
- return 0;
- }
-
- if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
- if (debug_linker)
- fprintf(stderr, "Is little-endian\n" );
- } else
- if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
- if (debug_linker)
- fprintf(stderr, "Is big-endian\n" );
- } else {
- fprintf(stderr,"%s: unknown endiannness\n", oc->fileName);
- return 0;
- }
-
- if (ehdr->e_type != ET_REL) {
- fprintf(stderr,"%s: not a relocatable object (.o) file\n", oc->fileName);
- return 0;
- }
- if (debug_linker)
- fprintf(stderr, "Is a relocatable object (.o) file\n" );
-
- if (debug_linker)
- fprintf(stderr, "Architecture is " );
- switch (ehdr->e_machine) {
- case EM_386: if (debug_linker) fprintf(stderr, "x86\n" ); break;
- case EM_SPARC: if (debug_linker) fprintf(stderr, "sparc\n" ); break;
- case EM_ARM: if (debug_linker) fprintf(stderr, "arm\n" ); break;
-#ifdef EM_IA_64
- case EM_IA_64: if (debug_linker) fprintf(stderr, "ia64\n" ); break;
-#endif
- case EM_X86_64: if (debug_linker) fprintf(stderr, "x86_64\n" ); break;
- case EM_PPC: if (debug_linker) fprintf(stderr, "ppc\n" ); break;
- default: if (debug_linker) fprintf(stderr, "unknown\n" );
- fprintf(stderr,"%s: unknown architecture\n", oc->fileName);
- return 0;
- }
-
- if (debug_linker>1) fprintf(stderr,
- "\nSection header table: start %lld, n_entries %d, ent_size %d\n",
- (Long)ehdr->e_shoff,
- ehdr->e_shnum, ehdr->e_shentsize );
-
- assert (ehdr->e_shentsize == sizeof(Elf_Shdr));
-
- shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff);
-
- if (ehdr->e_shstrndx == SHN_UNDEF) {
- fprintf(stderr,"%s: no section header string table\n", oc->fileName);
- return 0;
- } else {
- if (debug_linker>1)
- fprintf(stderr, "Section header string table is section %d\n",
- ehdr->e_shstrndx);
- sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
- }
-
- for (i = 0; i < ehdr->e_shnum; i++) {
- if (debug_linker>1) fprintf(stderr, "%2d: ", i );
- if (debug_linker>1) fprintf(stderr, "type=%2d ", (int)shdr[i].sh_type );
- if (debug_linker>1) fprintf(stderr, "size=%4d ", (int)shdr[i].sh_size );
- if (debug_linker>1) fprintf(stderr, "offs=%4d ", (int)shdr[i].sh_offset );
- if (debug_linker>1) fprintf(stderr, " (%p .. %p) ",
- ehdrC + shdr[i].sh_offset,
- ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1);
-
- if (shdr[i].sh_type == SHT_REL) {
- if (debug_linker>1) fprintf(stderr, "Rel " );
- } else if (shdr[i].sh_type == SHT_RELA) {
- if (debug_linker>1) fprintf(stderr, "RelA " );
- } else {
- if (debug_linker>1) fprintf(stderr," ");
- }
- if (sh_strtab) {
- if (debug_linker>1) fprintf(stderr, "sname=%s\n",
- sh_strtab + shdr[i].sh_name );
- }
- }
-
- if (debug_linker>1) fprintf(stderr, "\nString tables\n" );
- strtab = NULL;
- nstrtab = 0;
- for (i = 0; i < ehdr->e_shnum; i++) {
- if (shdr[i].sh_type == SHT_STRTAB
- /* Ignore the section header's string table. */
- && i != ehdr->e_shstrndx
- /* Ignore string tables named .stabstr, as they contain
- debugging info. */
- && 0 != memcmp(".stabstr", sh_strtab + shdr[i].sh_name, 8)
- ) {
- if (debug_linker>1)
- fprintf(stderr," section %d is a normal string table\n", i );
- strtab = ehdrC + shdr[i].sh_offset;
- nstrtab++;
- }
- }
- if (nstrtab != 1) {
- fprintf(stderr,"%s: no string tables, or too many\n", oc->fileName);
- return 0;
- }
-
- nsymtabs = 0;
- if (debug_linker>1) fprintf(stderr, "\nSymbol tables\n" );
- for (i = 0; i < ehdr->e_shnum; i++) {
- if (shdr[i].sh_type != SHT_SYMTAB) continue;
- if (debug_linker>1) fprintf(stderr, "section %d is a symbol table\n", i );
- nsymtabs++;
- stab = (Elf_Sym*) (ehdrC + shdr[i].sh_offset);
- nent = shdr[i].sh_size / sizeof(Elf_Sym);
- if (debug_linker>1) fprintf(stderr,
- " number of entries is apparently %d (%lld rem)\n",
- nent,
- (Long)(shdr[i].sh_size % sizeof(Elf_Sym))
- );
- if (0 != shdr[i].sh_size % sizeof(Elf_Sym)) {
- fprintf(stderr,"%s: non-integral number of symbol table entries\n",
- oc->fileName);
- return 0;
- }
- for (j = 0; j < nent; j++) {
- if (debug_linker>1) fprintf(stderr, " %2d ", j );
- if (debug_linker>1) fprintf(stderr, " sec=%-5d size=%-3d val=%5p ",
- (int)stab[j].st_shndx,
- (int)stab[j].st_size,
- (char*)stab[j].st_value );
-
- if (debug_linker>1) fprintf(stderr, "type=" );
- switch (ELF_ST_TYPE(stab[j].st_info)) {
- case STT_NOTYPE: if (debug_linker>1) fprintf(stderr, "notype " ); break;
- case STT_OBJECT: if (debug_linker>1) fprintf(stderr, "object " ); break;
- case STT_FUNC : if (debug_linker>1) fprintf(stderr, "func " ); break;
- case STT_SECTION: if (debug_linker>1) fprintf(stderr, "section" ); break;
- case STT_FILE: if (debug_linker>1) fprintf(stderr, "file " ); break;
- default: if (debug_linker>1) fprintf(stderr, "? " ); break;
- }
- if (debug_linker>1) fprintf(stderr, " " );
-
- if (debug_linker>1) fprintf(stderr, "bind=" );
- switch (ELF_ST_BIND(stab[j].st_info)) {
- case STB_LOCAL : if (debug_linker>1) fprintf(stderr, "local " ); break;
- case STB_GLOBAL: if (debug_linker>1) fprintf(stderr, "global" ); break;
- case STB_WEAK : if (debug_linker>1) fprintf(stderr, "weak " ); break;
- default: if (debug_linker>1) fprintf(stderr, "? " ); break;
- }
- if (debug_linker>1) fprintf(stderr, " " );
-
- if (debug_linker>1) fprintf(stderr, "name=%s\n", strtab + stab[j].st_name );
- }
- }
-
- if (nsymtabs == 0) {
- fprintf(stderr,"%s: didn't find any symbol tables\n", oc->fileName);
- return 0;
- }
-
- return 1;
-}
-
-
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-//
-// GETNAMES
-
-static int
-ocGetNames_ELF ( ObjectCode* oc )
-{
- int i, j, k, nent;
- Elf_Sym* stab;
-
- char* ehdrC = (char*)(oc->image);
- Elf_Ehdr* ehdr = (Elf_Ehdr*)ehdrC;
- char* strtab = findElfSection ( ehdrC, SHT_STRTAB );
- Elf_Shdr* shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff);
-
- char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
- char* sec_name;
-
- assert(global_symbol_table != NULL);
-
- if (!strtab) {
- fprintf(stderr,"%s: no strtab\n", oc->fileName);
- return 0;
- }
-
- k = 0;
- for (i = 0; i < ehdr->e_shnum; i++) {
- /* Figure out what kind of section it is. Logic derived from
- Figure 1.14 ("Special Sections") of the ELF document
- ("Portable Formats Specification, Version 1.1"). */
- Elf_Shdr hdr = shdr[i];
- SectionKind kind = SECTIONKIND_OTHER;
- int is_bss = FALSE;
-
- if (hdr.sh_type == SHT_PROGBITS
- && (hdr.sh_flags & SHF_ALLOC) && (hdr.sh_flags & SHF_EXECINSTR)) {
- /* .text-style section */
- kind = SECTIONKIND_CODE_OR_RODATA;
- }
- else
- if (hdr.sh_type == SHT_PROGBITS
- && (hdr.sh_flags & SHF_ALLOC) && (hdr.sh_flags & SHF_WRITE)) {
- /* .data-style section */
- kind = SECTIONKIND_RWDATA;
- }
- else
- if (hdr.sh_type == SHT_PROGBITS
- && (hdr.sh_flags & SHF_ALLOC) && !(hdr.sh_flags & SHF_WRITE)) {
- /* .rodata-style section */
- kind = SECTIONKIND_CODE_OR_RODATA;
- }
- else
- if (hdr.sh_type == SHT_NOBITS
- && (hdr.sh_flags & SHF_ALLOC) && (hdr.sh_flags & SHF_WRITE)) {
- /* .bss-style section */
- kind = SECTIONKIND_RWDATA;
- is_bss = TRUE;
- }
-
- if (is_bss && shdr[i].sh_size > 0) {
- /* This is a non-empty .bss section. Allocate zeroed space for
- it, and set its .sh_offset field such that
- ehdrC + .sh_offset == addr_of_zeroed_space. */
- char* zspace = calloc(1, shdr[i].sh_size);
- shdr[i].sh_offset = ((char*)zspace) - ((char*)ehdrC);
- if (1)
- fprintf(stderr, "BSS section at %p, size %lld\n",
- zspace, (Long)shdr[i].sh_size);
- }
-
- /* When loading objects compiled with -g, it seems there are
- relocations in various debug-info sections. So we'd better
- tell addProddableBlock to allow those bits to be prodded. */
- //fprintf(stderr, "ZZZZZZZZZZ %s\n", sh_strtab + hdr.sh_name);
- sec_name = sh_strtab + shdr[i].sh_name;
- if (kind == SECTIONKIND_OTHER
- && (0 == strcmp(".debug_info", sec_name)
- || 0 == strcmp(".debug_line", sec_name)
- || 0 == strcmp(".debug_pubnames", sec_name)
- || 0 == strcmp(".debug_aranges", sec_name)
- || 0 == strcmp(".debug_frame", sec_name))) {
- kind = SECTIONKIND_CODE_OR_RODATA;
- }
-
- /* fill in the section info */
- if (kind != SECTIONKIND_OTHER && shdr[i].sh_size > 0) {
- addProddableBlock(oc, ehdrC + shdr[i].sh_offset, shdr[i].sh_size);
- //addSection(oc, kind, ehdrC + shdr[i].sh_offset,
- // ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1);
- }
-
- if (shdr[i].sh_type != SHT_SYMTAB) continue;
-
- /* copy stuff into this module's object symbol table */
- stab = (Elf_Sym*) (ehdrC + shdr[i].sh_offset);
- nent = shdr[i].sh_size / sizeof(Elf_Sym);
-
- oc->n_symbols = nent;
- oc->symbols = mymalloc(oc->n_symbols * sizeof(char*));
-
- for (j = 0; j < nent; j++) {
-
- char isLocal = FALSE; /* avoids uninit-var warning */
- char* ad = NULL;
- char* nm = strtab + stab[j].st_name;
- int secno = stab[j].st_shndx;
-
- /* Figure out if we want to add it; if so, set ad to its
- address. Otherwise leave ad == NULL. */
-
- if (secno == SHN_COMMON) {
- isLocal = FALSE;
-# if defined(__x86_64__)
- ad = calloc_below2G(1, stab[j].st_size);
-# else
- ad = calloc(1, stab[j].st_size);
-# endif
- // assert( (Addr)ad < 0xF0000000ULL );
-
- if (0)
- fprintf(stderr, "COMMON symbol, size %lld name %s allocd %p\n",
- (Long)stab[j].st_size, nm, ad);
- /* Pointless to do addProddableBlock() for this area,
- since the linker should never poke around in it. */
- }
- else
- if ( ( ELF_ST_BIND(stab[j].st_info)==STB_GLOBAL
- || ELF_ST_BIND(stab[j].st_info)==STB_LOCAL
- )
- /* and not an undefined symbol */
- && stab[j].st_shndx != SHN_UNDEF
- /* and not in a "special section" */
- && stab[j].st_shndx < SHN_LORESERVE
- &&
- /* and it's a not a section or string table or anything silly */
- ( ELF_ST_TYPE(stab[j].st_info)==STT_FUNC ||
- ELF_ST_TYPE(stab[j].st_info)==STT_OBJECT ||
- ELF_ST_TYPE(stab[j].st_info)==STT_NOTYPE
- )
- ) {
- /* Section 0 is the undefined section, hence > and not >=. */
- assert(secno > 0 && secno < ehdr->e_shnum);
- /*
- if (shdr[secno].sh_type == SHT_NOBITS) {
- fprintf(stderr, " BSS symbol, size %d off %d name %s\n",
- stab[j].st_size, stab[j].st_value, nm);
- }
- */
- ad = ehdrC + shdr[ secno ].sh_offset + stab[j].st_value;
- if (ELF_ST_BIND(stab[j].st_info)==STB_LOCAL) {
- isLocal = TRUE;
- } else {
-#ifdef ELF_FUNCTION_DESC
- /* dlsym() and the initialisation table both give us function
- * descriptors, so to be consistent we store function descriptors
- * in the symbol table */
- if (ELF_ST_TYPE(stab[j].st_info) == STT_FUNC)
- ad = (char *)allocateFunctionDesc((Elf_Addr)ad);
-#endif
- if (0|| debug_linker)
- fprintf(stderr, "addOTabName(GLOB): %10p %s %s\n",
- ad, oc->fileName, nm );
- isLocal = FALSE;
- }
- }
-
- /* And the decision is ... */
-
- if (ad != NULL) {
- assert(nm != NULL);
- oc->symbols[j] = nm;
- /* Acquire! */
- if (isLocal) {
- /* Ignore entirely. */
- } else {
- //ghciInsertStrHashTable(oc->fileName, global_symbol_table, nm, ad);
- paranoid_addto_StringMap(global_symbol_table, nm, ad);
- }
- } else {
- /* Skip. */
- if (debug_linker>1) fprintf(stderr, "skipping `%s'\n",
- strtab + stab[j].st_name );
- /*
- fprintf(stderr,
- "skipping bind = %d, type = %d, shndx = %d `%s'\n",
- (int)ELF_ST_BIND(stab[j].st_info),
- (int)ELF_ST_TYPE(stab[j].st_info),
- (int)stab[j].st_shndx,
- strtab + stab[j].st_name
- );
- */
- oc->symbols[j] = NULL;
- }
-
- }
- }
-
- return 1;
-}
-
-
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-//
-// TOP-LEVEL CONTROL OF THE LINKER
-
-
-/* ---------------------------------------------------------------------
- * Load an obj (populate the global symbol table, but don't resolve yet)
- *
- * Returns: 1 if ok, 0 on error.
- */
-static
-int loadObj( char *path )
-{
- ObjectCode* oc;
- struct stat st;
- int r;
- int fd, pagesize;
- char* p;
-
- initLinker();
-
- fprintf(stderr, "==== loadObj %s ====\n", path );
-
- /* Check that we haven't already loaded this object. */
- {
- ObjectCode *o;
- int is_dup = 0;
- for (o = global_object_list; o; o = o->next) {
- if (0 == strcmp(o->fileName, path))
- is_dup = 1;
- }
- if (is_dup) {
- fprintf(stderr,
- "\n\n"
- "GHCi runtime linker: warning: looks like you're trying to load the\n"
- "same object file twice:\n"
- " %s\n"
- , path);
- exit(1);
- }
- }
-
- oc = mymalloc(sizeof(ObjectCode));
-
- oc->formatName = "ELF";
-
- r = stat(path, &st);
- if (r == -1) { return 0; }
-
- /* sigh, strdup() isn't a POSIX function, so do it the long way */
- oc->fileName = mymalloc( strlen(path)+1 );
- strcpy(oc->fileName, path);
-
- oc->fileSize = st.st_size;
- oc->symbols = NULL;
- oc->sections = NULL;
- oc->lochash = new_StringMap();
- oc->proddables = NULL;
- oc->fixup = NULL;
- oc->fixup_used = 0;
- oc->fixup_size = 0;
-
- /* chain it onto the list of objects */
- oc->next = global_object_list;
- global_object_list = oc;
-
- fd = open(path, O_RDONLY);
- if (fd == -1) {
- fprintf(stderr,"loadObj: can't open `%s'\n", path);
- exit(1);
- }
-
- /* Allocate a 1-page area just prior to the image, so we can put
- fixup code fragments there. Used for doing R_ARM_PC24
- relocations for jump distances > 64M. */
-
- pagesize = getpagesize();
- // p = memalign(pagesize, N_FIXUP_PAGES * pagesize
- // + oc->fileSize);
- p = mymalloc(N_FIXUP_PAGES * pagesize + oc->fileSize);
- if (0) fprintf(stderr,"XXXX p = %p\n", p);
- if (p == NULL) {
- fprintf(stderr,"loadObj: failed to allocate space for `%s'\n", path);
- exit(1);
- }
-
- oc->fixup = p;
- oc->fixup_size = N_FIXUP_PAGES * pagesize;
- oc->fixup_used = 0;
- oc->image = &(p[ oc->fixup_size ]);
-
- r = read(fd, oc->image, oc->fileSize);
- if (r != oc->fileSize) {
- fprintf(stderr,"loadObj: failed to read `%s'\n", path);
- exit(1);
- }
-
- fprintf(stderr, "loaded %s at %p (fixup = %p)\n",
- oc->fileName, oc->image, oc->fixup );
-
- close(fd);
-
- /* verify the in-memory image */
- r = ocVerifyImage_ELF ( oc );
- if (!r) { return r; }
-
- /* build the symbol list for this image */
- r = ocGetNames_ELF ( oc );
- if (!r) { return r; }
-
- /* loaded, but not resolved yet */
- oc->status = OBJECT_LOADED;
-
-#ifdef ppc32_TARGET_ARCH
- invalidate_icache(oc->image, oc->fileSize);
-#endif
-
- return 1;
-}
-
-
-
-/* ---------------------------------------------------------------------------
- * resolve all the currently unlinked objects in memory
- *
- * Returns: 1 if ok, 0 on error.
- */
-static
-int resolveObjs( void )
-{
- ObjectCode *oc;
- int r;
-
- initLinker();
-
- for (oc = global_object_list; oc; oc = oc->next) {
- if (oc->status != OBJECT_RESOLVED) {
- r = ocResolve_ELF ( oc );
- if (!r) { return r; }
- oc->status = OBJECT_RESOLVED;
- }
- }
- return 1;
-}
-
-
-/* ---------------------------------------------------------------------------
- * Top-level linker.
- */
-
-/* Load and link a bunch of .o's, and return the address of
- 'entry'. Or NULL if something borks.
-*/
-void* linker_top_level_LINK ( int n_object_names, char** object_names )
-{
- int r, i;
- void* mainp;
-
- initLinker();
- for (i = 0; i < n_object_names; i++) {
- //fprintf(stderr, "linkloop %d %s\n", i, object_names[i] );
- r = loadObj( object_names[i] );
- if (r != 1) return NULL;
- }
- r = resolveObjs();
- if (r != 1) return NULL;
- mainp = search_StringMap ( global_symbol_table, "entry" );
- if (mainp == NULL) return NULL;
- printf("switchback: Linker: success!\n");
- return mainp;
-}
-
-
-#endif
+++ /dev/null
-
-extern
-void* linker_top_level_LINK ( int n_object_names, char** object_names );
-
-extern void* mymalloc ( int );
+++ /dev/null
-
-/* HOW TO USE
-
-13 Dec '05 - Linker no longer used (apart from mymalloc)
-Simply compile and link switchback.c with test_xxx.c,
-e.g. for ppc64:
-$ (cd .. && make EXTRA_CFLAGS="-m64" libvex_ppc64_linux.a) && gcc -m64 -mregnames -Wall -Wshadow -Wno-long-long -Winline -O -g -o switchback switchback.c linker.c ../libvex_ppc64_linux.a test_xxx.c
-
-Test file test_xxx.c must have an entry point called "entry",
-which expects to take a single argument which is a function pointer
-(to "serviceFn").
-
-Test file may not reference any other symbols.
-
-NOTE: POWERPC: it is critical, when using this on ppc, to set
-CacheLineSize to the right value. Values we currently know of:
-
- imac (G3): 32
- G5 (ppc970): 128
-
-ARM64:
- (cd .. && make -f Makefile-gcc libvex-arm64-linux.a) \
- && $CC -Wall -O -g -o switchback switchback.c linker.c \
- ../libvex-arm64-linux.a test_emfloat.c
-*/
-
-#include <stdio.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "../pub/libvex_basictypes.h"
-#include "../pub/libvex_guest_x86.h"
-#include "../pub/libvex_guest_amd64.h"
-#include "../pub/libvex_guest_ppc32.h"
-#include "../pub/libvex_guest_ppc64.h"
-#include "../pub/libvex_guest_arm64.h"
-#include "../pub/libvex.h"
-#include "../pub/libvex_trc_values.h"
-#include "linker.h"
-
-static ULong n_bbs_done = 0;
-static Int n_translations_made = 0;
-
-
-#if defined(__i386__)
-# define VexGuestState VexGuestX86State
-# define LibVEX_Guest_initialise LibVEX_GuestX86_initialise
-# define VexArch VexArchX86
-# define VexSubArch VexSubArchX86_sse1
-# define GuestPC guest_EIP
-# define CacheLineSize 0/*irrelevant*/
-
-#elif defined(__aarch64__) && !defined(__arm__)
-# define VexGuestState VexGuestARM64State
-# define LibVEX_Guest_initialise LibVEX_GuestARM64_initialise
-# define VexArch VexArchARM64
-# define VexSubArch VexSubArch_NONE
-# define GuestPC guest_PC
-# define CacheLineSize 0/*irrelevant*/
-
-#else
-# error "Unknown arch"
-#endif
-
-/* 7: show conversion into IR */
-/* 6: show after initial opt */
-/* 5: show after instrumentation */
-/* 4: show after second opt */
-/* 3: show after tree building */
-/* 2: show selected insns */
-/* 1: show after reg-alloc */
-/* 0: show final assembly */
-#define TEST_FLAGS ((1<<7)|(1<<3)|(1<<2)|(1<<1)|(1<<0))
-#define DEBUG_TRACE_FLAGS ((0<<7)|(0<<6)|(0<<5)|(0<<4)| \
- (0<<3)|(0<<2)|(0<<1)|(0<<0))
-
-typedef unsigned long int Addr;
-
-
-/* guest state */
-ULong gstack[64000] __attribute__((aligned(16)));
-VexGuestState gst;
-VexControl vcon;
-
-/* only used for the switchback transition */
-/* i386: helper1 = &gst, helper2 = %EFLAGS */
-/* amd64: helper1 = &gst, helper2 = %EFLAGS */
-/* ppc32: helper1 = &gst, helper2 = %CR, helper3 = %XER */
-/* arm64: helper1 = &gst, helper2 = 32x0:NZCV:28x0 */
-HWord sb_helper1 = 0;
-HWord sb_helper2 = 0;
-HWord sb_helper3 = 0;
-
-/* translation cache */
-#define N_TRANS_CACHE 1000000
-#define N_TRANS_TABLE 10000
-
-ULong trans_cache[N_TRANS_CACHE];
-VexGuestExtents trans_table [N_TRANS_TABLE];
-ULong* trans_tableP[N_TRANS_TABLE];
-
-Int trans_cache_used = 0;
-Int trans_table_used = 0;
-
-static Bool chase_into_ok ( void* opaque, Addr64 dst ) {
- return False;
-}
-
-static UInt needs_self_check ( void* opaque, const VexGuestExtents* vge ) {
- return 0;
-}
-
-
-/* For providing services. */
-static HWord serviceFn ( HWord arg1, HWord arg2 )
-{
- switch (arg1) {
- case 0: /* EXIT */
- printf("---STOP---\n");
- printf("serviceFn:EXIT\n");
- printf("%llu bbs simulated\n", n_bbs_done);
- printf("%d translations made, %d tt bytes\n",
- n_translations_made, 8*trans_cache_used);
- exit(0);
- case 1: /* PUTC */
- putchar(arg2);
- return 0;
- case 2: /* MALLOC */
- return (HWord)malloc(arg2);
- case 3: /* FREE */
- free((void*)arg2);
- return 0;
- default:
- assert(0);
- }
-}
-
-
-// needed for arm64 ?
-static void invalidate_icache(void *ptr, unsigned long nbytes)
-{
- // This function, invalidate_icache, for arm64_linux,
- // is copied from
- // https://github.com/armvixl/vixl/blob/master/src/a64/cpu-a64.cc
- // which has the following copyright notice:
- /*
- Copyright 2013, ARM Limited
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * Neither the name of ARM Limited nor the names of its contributors may be
- used to endorse or promote products derived from this software without
- specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- // Ask what the I and D line sizes are
- UInt cache_type_register;
- // Copy the content of the cache type register to a core register.
- __asm__ __volatile__ ("mrs %[ctr], ctr_el0" // NOLINT
- : [ctr] "=r" (cache_type_register));
-
- const Int kDCacheLineSizeShift = 16;
- const Int kICacheLineSizeShift = 0;
- const UInt kDCacheLineSizeMask = 0xf << kDCacheLineSizeShift;
- const UInt kICacheLineSizeMask = 0xf << kICacheLineSizeShift;
-
- // The cache type register holds the size of the I and D caches as a power of
- // two.
- const UInt dcache_line_size_power_of_two =
- (cache_type_register & kDCacheLineSizeMask) >> kDCacheLineSizeShift;
- const UInt icache_line_size_power_of_two =
- (cache_type_register & kICacheLineSizeMask) >> kICacheLineSizeShift;
-
- const UInt dcache_line_size_ = 1 << dcache_line_size_power_of_two;
- const UInt icache_line_size_ = 1 << icache_line_size_power_of_two;
-
- Addr start = (Addr)ptr;
- // Sizes will be used to generate a mask big enough to cover a pointer.
- Addr dsize = (Addr)dcache_line_size_;
- Addr isize = (Addr)icache_line_size_;
-
- // Cache line sizes are always a power of 2.
- Addr dstart = start & ~(dsize - 1);
- Addr istart = start & ~(isize - 1);
- Addr end = start + nbytes;
-
- __asm__ __volatile__ (
- // Clean every line of the D cache containing the target data.
- "0: \n\t"
- // dc : Data Cache maintenance
- // c : Clean
- // va : by (Virtual) Address
- // u : to the point of Unification
- // The point of unification for a processor is the point by which the
- // instruction and data caches are guaranteed to see the same copy of a
- // memory location. See ARM DDI 0406B page B2-12 for more information.
- "dc cvau, %[dline] \n\t"
- "add %[dline], %[dline], %[dsize] \n\t"
- "cmp %[dline], %[end] \n\t"
- "b.lt 0b \n\t"
- // Barrier to make sure the effect of the code above is visible to the rest
- // of the world.
- // dsb : Data Synchronisation Barrier
- // ish : Inner SHareable domain
- // The point of unification for an Inner Shareable shareability domain is
- // the point by which the instruction and data caches of all the processors
- // in that Inner Shareable shareability domain are guaranteed to see the
- // same copy of a memory location. See ARM DDI 0406B page B2-12 for more
- // information.
- "dsb ish \n\t"
- // Invalidate every line of the I cache containing the target data.
- "1: \n\t"
- // ic : instruction cache maintenance
- // i : invalidate
- // va : by address
- // u : to the point of unification
- "ic ivau, %[iline] \n\t"
- "add %[iline], %[iline], %[isize] \n\t"
- "cmp %[iline], %[end] \n\t"
- "b.lt 1b \n\t"
- // Barrier to make sure the effect of the code above is visible to the rest
- // of the world.
- "dsb ish \n\t"
- // Barrier to ensure any prefetching which happened before this code is
- // discarded.
- // isb : Instruction Synchronisation Barrier
- "isb \n\t"
- : [dline] "+r" (dstart),
- [iline] "+r" (istart)
- : [dsize] "r" (dsize),
- [isize] "r" (isize),
- [end] "r" (end)
- // This code does not write to memory but without the dependency gcc might
- // move this code before the code is generated.
- : "cc", "memory"
- );
-
-}
-
-
-/* -------------------- */
-/* continue execution on the real CPU (never returns) */
-
-#if defined(__i386__)
-
-extern void switchback_asm(void);
-asm(
-"switchback_asm:\n"
-" movl sb_helper1, %eax\n" // eax = guest state ptr
-" movl 16(%eax), %esp\n" // switch stacks
-" pushl 56(%eax)\n" // push continuation addr
-" movl sb_helper2, %ebx\n" // get eflags
-" pushl %ebx\n" // eflags:CA
-" pushl 0(%eax)\n" // EAX:eflags:CA
-" movl 4(%eax), %ecx\n"
-" movl 8(%eax), %edx\n"
-" movl 12(%eax), %ebx\n"
-" movl 20(%eax), %ebp\n"
-" movl 24(%eax), %esi\n"
-" movl 28(%eax), %edi\n"
-" popl %eax\n"
-" popfl\n"
-" ret\n"
-);
-void switchback ( void )
-{
- sb_helper1 = (HWord)&gst;
- sb_helper2 = LibVEX_GuestX86_get_eflags(&gst);
- switchback_asm(); // never returns
-}
-
-#elif defined(__aarch64__)
-
-extern void switchback_asm(HWord x0_gst, HWord x1_pstate);
-asm(
-"switchback_asm:"
-" mrs x30, nzcv" "\n"
-" and x30, x30, #0xFFFFFFFF0FFFFFFF" "\n"
-" and x1, x1, #0x00000000F0000000" "\n"
-" orr x30, x30, x1" "\n"
-" msr nzcv, x30" "\n"
-
-" ldr x30, [x0, #16 + 8*37]" "\n"
-" msr tpidr_el0, x30" "\n"
-
-" ldr x30, [x0, #16 + 8*31]" "\n"
-" mov sp, x30" "\n"
-
-" add x30, x0, #(16 + 8*38 + 16*0)" "\n"
-" ldr q0, [x30], #16" "\n"
-" ldr q1, [x30], #16" "\n"
-" ldr q2, [x30], #16" "\n"
-" ldr q3, [x30], #16" "\n"
-" ldr q4, [x30], #16" "\n"
-" ldr q5, [x30], #16" "\n"
-" ldr q6, [x30], #16" "\n"
-" ldr q7, [x30], #16" "\n"
-" ldr q8, [x30], #16" "\n"
-" ldr q9, [x30], #16" "\n"
-" ldr q10, [x30], #16" "\n"
-" ldr q11, [x30], #16" "\n"
-" ldr q12, [x30], #16" "\n"
-" ldr q13, [x30], #16" "\n"
-" ldr q14, [x30], #16" "\n"
-" ldr q15, [x30], #16" "\n"
-" ldr q16, [x30], #16" "\n"
-" ldr q17, [x30], #16" "\n"
-" ldr q18, [x30], #16" "\n"
-" ldr q19, [x30], #16" "\n"
-" ldr q20, [x30], #16" "\n"
-" ldr q21, [x30], #16" "\n"
-" ldr q22, [x30], #16" "\n"
-" ldr q23, [x30], #16" "\n"
-" ldr q24, [x30], #16" "\n"
-" ldr q25, [x30], #16" "\n"
-" ldr q26, [x30], #16" "\n"
-" ldr q27, [x30], #16" "\n"
-" ldr q28, [x30], #16" "\n"
-" ldr q29, [x30], #16" "\n"
-" ldr q30, [x30], #16" "\n"
-" ldr q31, [x30], #16" "\n"
-
-" ldr x30, [x0, #16+8*30]" "\n"
-" ldr x29, [x0, #16+8*29]" "\n"
-" ldr x28, [x0, #16+8*28]" "\n"
-" ldr x27, [x0, #16+8*27]" "\n"
-" ldr x26, [x0, #16+8*26]" "\n"
-" ldr x25, [x0, #16+8*25]" "\n"
-" ldr x24, [x0, #16+8*24]" "\n"
-" ldr x23, [x0, #16+8*23]" "\n"
-" ldr x22, [x0, #16+8*22]" "\n"
-" ldr x21, [x0, #16+8*21]" "\n"
-" ldr x20, [x0, #16+8*20]" "\n"
-" ldr x19, [x0, #16+8*19]" "\n"
-" ldr x18, [x0, #16+8*18]" "\n"
-" ldr x17, [x0, #16+8*17]" "\n"
-" ldr x16, [x0, #16+8*16]" "\n"
-" ldr x15, [x0, #16+8*15]" "\n"
-" ldr x14, [x0, #16+8*14]" "\n"
-" ldr x13, [x0, #16+8*13]" "\n"
-" ldr x12, [x0, #16+8*12]" "\n"
-" ldr x11, [x0, #16+8*11]" "\n"
-" ldr x10, [x0, #16+8*10]" "\n"
-" ldr x9, [x0, #16+8*9]" "\n"
-" ldr x8, [x0, #16+8*8]" "\n"
-" ldr x7, [x0, #16+8*7]" "\n"
-" ldr x6, [x0, #16+8*6]" "\n"
-" ldr x5, [x0, #16+8*5]" "\n"
-" ldr x4, [x0, #16+8*4]" "\n"
-" ldr x3, [x0, #16+8*3]" "\n"
-" ldr x2, [x0, #16+8*2]" "\n"
-" ldr x1, [x0, #16+8*1]" "\n"
-" ldr x0, [x0, #16+8*0]" "\n"
-
-"nop_start_point:" "\n"
-" nop" "\n" // this will be converted into a relative jump
-"nop_end_point:" "\n"
-);
-
-extern void nop_start_point(void);
-extern void nop_end_point(void);
-
-void switchback ( void )
-{
- assert(offsetof(VexGuestARM64State, guest_X0) == 16 + 8*0);
- assert(offsetof(VexGuestARM64State, guest_X30) == 16 + 8*30);
- assert(offsetof(VexGuestARM64State, guest_SP) == 16 + 8*31);
- assert(offsetof(VexGuestARM64State, guest_TPIDR_EL0) == 16 + 8*37);
- assert(offsetof(VexGuestARM64State, guest_Q0) == 16 + 8*38 + 16*0);
-
- HWord arg0 = (HWord)&gst;
- HWord arg1 = LibVEX_GuestARM64_get_nzcv(&gst);
-
- /* Copy the entire switchback_asm procedure into writable and
- executable memory. */
-
- UChar* sa_start = (UChar*)&switchback_asm;
- UChar* sa_nop_start = (UChar*)&nop_start_point;
- UChar* sa_end = (UChar*)&nop_end_point;
-
- Int i;
- Int nbytes = sa_end - sa_start;
- Int off_nopstart = sa_nop_start - sa_start;
- if (0)
- printf("nbytes = %d, nopstart = %d\n", nbytes, off_nopstart);
-
- /* copy it into mallocville */
- UChar* copy = mymalloc(nbytes);
- assert(copy);
- for (i = 0; i < nbytes; i++)
- copy[i] = sa_start[i];
-
- UInt* p = (UInt*)(©[off_nopstart]);
-
- Addr addr_of_nop = (Addr)p;
- Addr where_to_go = gst.guest_PC;
- Long diff = ((Long)where_to_go) - ((Long)addr_of_nop);
-
- if (0) {
- printf("addr of first nop = 0x%llx\n", addr_of_nop);
- printf("where to go = 0x%llx\n", where_to_go);
- printf("diff = 0x%llx\n", diff);
- }
-
- if (diff < -0x8000000LL || diff >= 0x8000000LL) {
- // we're hosed. Give up
- printf("hosed -- offset too large\n");
- assert(0);
- }
-
- /* stay sane ... */
- assert(p[0] == 0xd503201f); /* nop */
-
- /* branch to diff */
- p[0] = 0x14000000 | ((diff >> 2) & 0x3FFFFFF);
-
- invalidate_icache( copy, nbytes );
-
- ( (void(*)(HWord,HWord))copy )(arg0, arg1);
-}
-
-#else
-# error "Unknown plat"
-#endif
-
-
-
-/* -------------------- */
-// f holds is the host code address
-// gp holds the guest state pointer to use
-// res is to hold the result. Or some such.
-static HWord block[2]; // f, gp;
-extern HWord run_translation_asm(void);
-
-extern void disp_chain_assisted(void);
-
-#if defined(__aarch64__)
-asm(
-"run_translation_asm:" "\n"
-" stp x29, x30, [sp, #-16]!" "\n"
-" stp x27, x28, [sp, #-16]!" "\n"
-" stp x25, x26, [sp, #-16]!" "\n"
-" stp x23, x24, [sp, #-16]!" "\n"
-" stp x21, x22, [sp, #-16]!" "\n"
-" stp x19, x20, [sp, #-16]!" "\n"
-" stp x0, xzr, [sp, #-16]!" "\n"
-" adrp x0, block" "\n"
-" add x0, x0, :lo12:block" "\n"
-" ldr x21, [x0, #8]" "\n" // load GSP
-" ldr x1, [x0, #0]" "\n" // Host address
-" br x1" "\n" // go (we wind up at disp_chain_assisted)
-
-"disp_chain_assisted:" "\n" // x21 holds the trc. Return it.
-" mov x1, x21" "\n"
- /* Restore int regs, but not x1. */
-" ldp x0, xzr, [sp], #16" "\n"
-" ldp x19, x20, [sp], #16" "\n"
-" ldp x21, x22, [sp], #16" "\n"
-" ldp x23, x24, [sp], #16" "\n"
-" ldp x25, x26, [sp], #16" "\n"
-" ldp x27, x28, [sp], #16" "\n"
-" ldp x29, x30, [sp], #16" "\n"
-" mov x0, x1" "\n"
-" ret" "\n"
-);
-
-#elif defined(__i386__)
-
-asm(
-"run_translation_asm:\n"
-" pushal\n"
-" movl gp, %ebp\n"
-" movl f, %eax\n"
-" call *%eax\n"
-" movl %eax, res\n"
-" popal\n"
-" ret\n"
-);
-
-#else
-# error "Unknown arch"
-#endif
-
-
-/* Run a translation at host address 'translation' and return the TRC.
-*/
-HWord run_translation ( HWord translation )
-{
- if (0 && DEBUG_TRACE_FLAGS) {
- printf(" run translation %p\n", (void*)translation );
- printf(" simulated bb: %llu\n", n_bbs_done);
- }
- block[0] = translation;
- block[1] = (HWord)&gst;
- HWord trc = run_translation_asm();
- n_bbs_done ++;
- return trc;
-}
-
-HWord find_translation ( Addr guest_addr )
-{
- Int i;
- HWord __res;
- if (0)
- printf("find translation %p ... ", (void *)(guest_addr));
- for (i = 0; i < trans_table_used; i++)
- if (trans_table[i].base[0] == guest_addr)
- break;
- if (i == trans_table_used) {
- if (0) printf("none\n");
- return 0; /* not found */
- }
-
- /* Move this translation one step towards the front, so finding it
- next time round is just that little bit cheaper. */
- if (i > 2) {
- VexGuestExtents tmpE = trans_table[i-1];
- ULong* tmpP = trans_tableP[i-1];
- trans_table[i-1] = trans_table[i];
- trans_tableP[i-1] = trans_tableP[i];
- trans_table[i] = tmpE;
- trans_tableP[i] = tmpP;
- i--;
- }
-
- __res = (HWord)trans_tableP[i];
- if (0) printf("%p\n", (void*)__res);
- return __res;
-}
-
-#define N_TRANSBUF 5000
-static UChar transbuf[N_TRANSBUF];
-void make_translation ( Addr guest_addr, Bool verbose )
-{
- VexTranslateArgs vta;
- VexTranslateResult tres;
- VexArchInfo vex_archinfo;
- Int trans_used, i, ws_needed;
-
- memset(&vta, 0, sizeof(vta));
- memset(&tres, 0, sizeof(tres));
- memset(&vex_archinfo, 0, sizeof(vex_archinfo));
-
- if (trans_table_used >= N_TRANS_TABLE
- || trans_cache_used >= N_TRANS_CACHE-1000) {
- /* If things are looking to full, just dump
- all the translations. */
- trans_cache_used = 0;
- trans_table_used = 0;
- }
-
- assert(trans_table_used < N_TRANS_TABLE);
- if (0)
- printf("make translation %p\n", (void *)guest_addr);
-
- LibVEX_default_VexArchInfo(&vex_archinfo);
- //vex_archinfo.subarch = VexSubArch;
- //vex_archinfo.ppc_icache_line_szB = CacheLineSize;
-
- /* */
- vta.arch_guest = VexArch;
- vta.archinfo_guest = vex_archinfo;
- vta.arch_host = VexArch;
- vta.archinfo_host = vex_archinfo;
- vta.guest_bytes = (UChar*)guest_addr;
- vta.guest_bytes_addr = guest_addr;
- vta.chase_into_ok = chase_into_ok;
-// vta.guest_extents = &vge;
- vta.guest_extents = &trans_table[trans_table_used];
- vta.host_bytes = transbuf;
- vta.host_bytes_size = N_TRANSBUF;
- vta.host_bytes_used = &trans_used;
- vta.instrument1 = NULL;
- vta.instrument2 = NULL;
- vta.needs_self_check = needs_self_check;
- vta.traceflags = verbose ? TEST_FLAGS : DEBUG_TRACE_FLAGS;
-
- vta.disp_cp_chain_me_to_slowEP = NULL; //disp_chain_fast;
- vta.disp_cp_chain_me_to_fastEP = NULL; //disp_chain_slow;
- vta.disp_cp_xindir = NULL; //disp_chain_indir;
- vta.disp_cp_xassisted = disp_chain_assisted;
-
- vta.addProfInc = False;
-
- tres = LibVEX_Translate ( &vta );
-
- assert(tres.status == VexTransOK);
- assert(tres.offs_profInc == -1);
-
- ws_needed = (trans_used+7) / 8;
- assert(ws_needed > 0);
- assert(trans_cache_used + ws_needed < N_TRANS_CACHE);
- n_translations_made++;
-
- for (i = 0; i < trans_used; i++) {
- HChar* dst = ((HChar*)(&trans_cache[trans_cache_used])) + i;
- HChar* src = (HChar*)(&transbuf[i]);
- *dst = *src;
- }
-
-#if defined(__aarch64__)
- invalidate_icache( &trans_cache[trans_cache_used], trans_used );
-#endif
-
- trans_tableP[trans_table_used] = &trans_cache[trans_cache_used];
- trans_table_used++;
- trans_cache_used += ws_needed;
-}
-
-
-__attribute__((unused))
-static Bool overlap ( Addr start, UInt len, VexGuestExtents* vge )
-{
- Int i;
- for (i = 0; i < vge->n_used; i++) {
- if (vge->base[i]+vge->len[i] <= start
- || vge->base[i] >= start+len) {
- /* ok */
- } else {
- return True;
- }
- }
- return False; /* no overlap */
-}
-
-static ULong stopAfter = 0;
-static UChar* entryP = NULL;
-
-
-__attribute__ ((noreturn))
-static
-void failure_exit ( void )
-{
- fprintf(stdout, "VEX did failure_exit. Bye.\n");
- fprintf(stdout, "bb counter = %llu\n\n", n_bbs_done);
- exit(1);
-}
-
-static
-void log_bytes ( HChar* bytes, Int nbytes )
-{
- fwrite ( bytes, 1, nbytes, stdout );
- fflush ( stdout );
-}
-
-
-/* run simulated code forever (it will exit by calling
- serviceFn(0)). */
-static void run_simulator ( void )
-{
- static Addr last_guest = 0;
- Addr next_guest;
- HWord next_host;
- while (1) {
- next_guest = gst.GuestPC;
-
- if (0)
- printf("\nnext_guest: 0x%x\n", (UInt)next_guest);
-
- if (next_guest == (Addr)&serviceFn) {
-
- /* "do" the function call to serviceFn */
-# if defined(__i386__)
- {
- HWord esp = gst.guest_ESP;
- gst.guest_EIP = *(UInt*)(esp+0);
- gst.guest_EAX = serviceFn( *(UInt*)(esp+4), *(UInt*)(esp+8) );
- gst.guest_ESP = esp+4;
- next_guest = gst.guest_EIP;
- }
-# elif defined(__aarch64__)
- {
- gst.guest_X0 = serviceFn( gst.guest_X0, gst.guest_X1 );
- gst.guest_PC = gst.guest_X30;
- next_guest = gst.guest_PC;
- }
-# else
-# error "Unknown arch"
-# endif
- }
-
- next_host = find_translation(next_guest);
- if (next_host == 0) {
- make_translation(next_guest,False);
- next_host = find_translation(next_guest);
- assert(next_host != 0);
- }
-
- // Switchback
- if (n_bbs_done == stopAfter) {
- printf("---begin SWITCHBACK at bb:%llu---\n", n_bbs_done);
-#if 1
- if (last_guest) {
- printf("\n*** Last run translation (bb:%llu):\n", n_bbs_done-1);
- make_translation(last_guest,True);
- }
-#endif
-#if 0
- if (next_guest) {
- printf("\n*** Current translation (bb:%llu):\n", n_bbs_done);
- make_translation(next_guest,True);
- }
-#endif
- printf("--- end SWITCHBACK at bb:%llu ---\n", n_bbs_done);
- switchback();
- assert(0); /*NOTREACHED*/
- }
-
- last_guest = next_guest;
- HWord trc = run_translation(next_host);
- if (0) printf("------- trc = %lu\n", trc);
- if (trc != VEX_TRC_JMP_BORING) {
- if (1) printf("------- trc = %lu\n", trc);
- }
- assert(trc == VEX_TRC_JMP_BORING);
- }
-}
-
-
-static void usage ( void )
-{
- printf("usage: switchback #bbs\n");
- printf(" - begins switchback for basic block #bbs\n");
- printf(" - use -1 for largest possible run without switchback\n\n");
- exit(1);
-}
-
-
-int main ( Int argc, HChar** argv )
-{
- if (argc != 2)
- usage();
-
- stopAfter = (ULong)atoll(argv[1]);
-
- extern void entry ( void*(*service)(int,int) );
- entryP = (UChar*)&entry;
-
- if (!entryP) {
- printf("switchback: can't find entry point\n");
- exit(1);
- }
-
- LibVEX_default_VexControl(&vcon);
- vcon.guest_max_insns=50 - 49;
- vcon.guest_chase_thresh=0;
- vcon.iropt_level=2;
-
- LibVEX_Init( failure_exit, log_bytes, 1, &vcon );
- LibVEX_Guest_initialise(&gst);
- gst.host_EvC_COUNTER = 999999999; // so we should never get an exit
- gst.host_EvC_FAILADDR = 0x5a5a5a5a5a5a5a5a;
-
- /* set up as if a call to the entry point passing serviceFn as
- the one and only parameter */
-# if defined(__i386__)
- gst.guest_EIP = (UInt)entryP;
- gst.guest_ESP = (UInt)&gstack[32000];
- *(UInt*)(gst.guest_ESP+4) = (UInt)serviceFn;
- *(UInt*)(gst.guest_ESP+0) = 0x12345678;
-
-# elif defined(__aarch64__)
- gst.guest_PC = (ULong)entryP;
- gst.guest_SP = (ULong)&gstack[32000];
- gst.guest_X0 = (ULong)serviceFn;
- HWord tpidr_el0 = 0;
- __asm__ __volatile__("mrs %0, tpidr_el0" : "=r"(tpidr_el0));
- gst.guest_TPIDR_EL0 = tpidr_el0;
-
-# else
-# error "Unknown arch"
-# endif
-
- printf("\n---START---\n");
-
-#if 1
- run_simulator();
-#else
- ( (void(*)(HWord(*)(HWord,HWord))) entryP ) (serviceFn);
-#endif
-
-
- return 0;
-}
+++ /dev/null
-
-#define BZ_NO_STDIO
-
-
-/*-------------------------------------------------------------*/
-/*--- Private header file for the library. ---*/
-/*--- bzlib_private.h ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2004 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-
-#ifndef _BZLIB_PRIVATE_H
-#define _BZLIB_PRIVATE_H
-
-#include <stdlib.h>
-
-#ifndef BZ_NO_STDIO
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#endif
-
-
-/*-------------------------------------------------------------*/
-/*--- Public header file for the library. ---*/
-/*--- bzlib.h ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2004 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-
-#ifndef _BZLIB_H
-#define _BZLIB_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define BZ_RUN 0
-#define BZ_FLUSH 1
-#define BZ_FINISH 2
-
-#define BZ_OK 0
-#define BZ_RUN_OK 1
-#define BZ_FLUSH_OK 2
-#define BZ_FINISH_OK 3
-#define BZ_STREAM_END 4
-#define BZ_SEQUENCE_ERROR (-1)
-#define BZ_PARAM_ERROR (-2)
-#define BZ_MEM_ERROR (-3)
-#define BZ_DATA_ERROR (-4)
-#define BZ_DATA_ERROR_MAGIC (-5)
-#define BZ_IO_ERROR (-6)
-#define BZ_UNEXPECTED_EOF (-7)
-#define BZ_OUTBUFF_FULL (-8)
-#define BZ_CONFIG_ERROR (-9)
-
-typedef
- struct {
- char *next_in;
- unsigned int avail_in;
- unsigned int total_in_lo32;
- unsigned int total_in_hi32;
-
- char *next_out;
- unsigned int avail_out;
- unsigned int total_out_lo32;
- unsigned int total_out_hi32;
-
- void *state;
-
- void *(*bzalloc)(void *,int,int);
- void (*bzfree)(void *,void *);
- void *opaque;
- }
- bz_stream;
-
-
-#ifndef BZ_IMPORT
-#define BZ_EXPORT
-#endif
-
-#ifndef BZ_NO_STDIO
-/* Need a definitition for FILE */
-#include <stdio.h>
-#endif
-
-#ifdef _WIN32
-# include <windows.h>
-# ifdef small
- /* windows.h define small to char */
-# undef small
-# endif
-# ifdef BZ_EXPORT
-# define BZ_API(func) WINAPI func
-# define BZ_EXTERN extern
-# else
- /* import windows dll dynamically */
-# define BZ_API(func) (WINAPI * func)
-# define BZ_EXTERN
-# endif
-#else
-# define BZ_API(func) func
-# define BZ_EXTERN extern
-#endif
-
-
-/*-- Core (low-level) library functions --*/
-
-BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
- bz_stream* strm,
- int blockSize100k,
- int verbosity,
- int workFactor
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzCompress) (
- bz_stream* strm,
- int action
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
- bz_stream* strm
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
- bz_stream *strm,
- int verbosity,
- int small
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
- bz_stream* strm
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
- bz_stream *strm
- );
-
-
-
-/*-- High(er) level library functions --*/
-
-#ifndef BZ_NO_STDIO
-#define BZ_MAX_UNUSED 5000
-
-typedef void BZFILE;
-
-BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
- int* bzerror,
- FILE* f,
- int verbosity,
- int small,
- void* unused,
- int nUnused
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
- int* bzerror,
- BZFILE* b
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
- int* bzerror,
- BZFILE* b,
- void** unused,
- int* nUnused
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzRead) (
- int* bzerror,
- BZFILE* b,
- void* buf,
- int len
- );
-
-BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
- int* bzerror,
- FILE* f,
- int blockSize100k,
- int verbosity,
- int workFactor
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzWrite) (
- int* bzerror,
- BZFILE* b,
- void* buf,
- int len
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
- int* bzerror,
- BZFILE* b,
- int abandon,
- unsigned int* nbytes_in,
- unsigned int* nbytes_out
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
- int* bzerror,
- BZFILE* b,
- int abandon,
- unsigned int* nbytes_in_lo32,
- unsigned int* nbytes_in_hi32,
- unsigned int* nbytes_out_lo32,
- unsigned int* nbytes_out_hi32
- );
-#endif
-
-
-/*-- Utility functions --*/
-
-BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
- char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int blockSize100k,
- int verbosity,
- int workFactor
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
- char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int small,
- int verbosity
- );
-
-
-/*--
- Code contributed by Yoshioka Tsuneo
- (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
- to support better zlib compatibility.
- This code is not _officially_ part of libbzip2 (yet);
- I haven't tested it, documented it, or considered the
- threading-safeness of it.
- If this code breaks, please contact both Yoshioka and me.
---*/
-
-BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
- void
- );
-
-#ifndef BZ_NO_STDIO
-BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
- const char *path,
- const char *mode
- );
-
-BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
- int fd,
- const char *mode
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzread) (
- BZFILE* b,
- void* buf,
- int len
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzwrite) (
- BZFILE* b,
- void* buf,
- int len
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzflush) (
- BZFILE* b
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzclose) (
- BZFILE* b
- );
-
-BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
- BZFILE *b,
- int *errnum
- );
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-/*-------------------------------------------------------------*/
-/*--- end bzlib.h ---*/
-/*-------------------------------------------------------------*/
-
-
-
-
-/*-- General stuff. --*/
-
-#define BZ_VERSION "1.0.3, 17-Oct-2004"
-
-typedef char Char;
-typedef unsigned char Bool;
-typedef unsigned char UChar;
-typedef int Int32;
-typedef unsigned int UInt32;
-typedef short Int16;
-typedef unsigned short UInt16;
-
-#define True ((Bool)1)
-#define False ((Bool)0)
-
-#ifndef __GNUC__
-#define __inline__ /* */
-#endif
-
-#ifndef BZ_NO_STDIO
-extern void BZ2_bz__AssertH__fail ( int errcode );
-#define AssertH(cond,errcode) \
- { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
-#if BZ_DEBUG
-#define AssertD(cond,msg) \
- { if (!(cond)) { \
- fprintf ( stderr, \
- "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
- exit(1); \
- }}
-#else
-#define AssertD(cond,msg) /* */
-#endif
-#define VPrintf0(zf) \
- fprintf(stderr,zf)
-#define VPrintf1(zf,za1) \
- fprintf(stderr,zf,za1)
-#define VPrintf2(zf,za1,za2) \
- fprintf(stderr,zf,za1,za2)
-#define VPrintf3(zf,za1,za2,za3) \
- fprintf(stderr,zf,za1,za2,za3)
-#define VPrintf4(zf,za1,za2,za3,za4) \
- fprintf(stderr,zf,za1,za2,za3,za4)
-#define VPrintf5(zf,za1,za2,za3,za4,za5) \
- fprintf(stderr,zf,za1,za2,za3,za4,za5)
-#else
-extern void bz_internal_error ( int errcode );
-#define AssertH(cond,errcode) \
- { if (!(cond)) bz_internal_error ( errcode ); }
-#define AssertD(cond,msg) /* */
-#define VPrintf0(zf) \
- vexxx_printf(zf)
-#define VPrintf1(zf,za1) \
- vexxx_printf(zf,za1)
-#define VPrintf2(zf,za1,za2) \
- vexxx_printf(zf,za1,za2)
-#define VPrintf3(zf,za1,za2,za3) \
- vexxx_printf(zf,za1,za2,za3)
-#define VPrintf4(zf,za1,za2,za3,za4) \
- vexxx_printf(zf,za1,za2,za3,za4)
-#define VPrintf5(zf,za1,za2,za3,za4,za5) \
- vexxx_printf(zf,za1,za2,za3,za4,za5)
-#endif
-
-
-#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
-#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp))
-
-
-/*-- Header bytes. --*/
-
-#define BZ_HDR_B 0x42 /* 'B' */
-#define BZ_HDR_Z 0x5a /* 'Z' */
-#define BZ_HDR_h 0x68 /* 'h' */
-#define BZ_HDR_0 0x30 /* '0' */
-
-/*-- Constants for the back end. --*/
-
-#define BZ_MAX_ALPHA_SIZE 258
-#define BZ_MAX_CODE_LEN 23
-
-#define BZ_RUNA 0
-#define BZ_RUNB 1
-
-#define BZ_N_GROUPS 6
-#define BZ_G_SIZE 50
-#define BZ_N_ITERS 4
-
-#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
-
-
-
-/*-- Stuff for randomising repetitive blocks. --*/
-
-extern Int32 BZ2_rNums[512];
-
-#define BZ_RAND_DECLS \
- Int32 rNToGo; \
- Int32 rTPos \
-
-#define BZ_RAND_INIT_MASK \
- s->rNToGo = 0; \
- s->rTPos = 0 \
-
-#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
-
-#define BZ_RAND_UPD_MASK \
- if (s->rNToGo == 0) { \
- s->rNToGo = BZ2_rNums[s->rTPos]; \
- s->rTPos++; \
- if (s->rTPos == 512) s->rTPos = 0; \
- } \
- s->rNToGo--;
-
-
-
-/*-- Stuff for doing CRCs. --*/
-
-extern UInt32 BZ2_crc32Table[256];
-
-#define BZ_INITIALISE_CRC(crcVar) \
-{ \
- crcVar = 0xffffffffL; \
-}
-
-#define BZ_FINALISE_CRC(crcVar) \
-{ \
- crcVar = ~(crcVar); \
-}
-
-#define BZ_UPDATE_CRC(crcVar,cha) \
-{ \
- crcVar = (crcVar << 8) ^ \
- BZ2_crc32Table[(crcVar >> 24) ^ \
- ((UChar)cha)]; \
-}
-
-
-
-/*-- States and modes for compression. --*/
-
-#define BZ_M_IDLE 1
-#define BZ_M_RUNNING 2
-#define BZ_M_FLUSHING 3
-#define BZ_M_FINISHING 4
-
-#define BZ_S_OUTPUT 1
-#define BZ_S_INPUT 2
-
-#define BZ_N_RADIX 2
-#define BZ_N_QSORT 12
-#define BZ_N_SHELL 18
-#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
-
-
-
-
-/*-- Structure holding all the compression-side stuff. --*/
-
-typedef
- struct {
- /* pointer back to the struct bz_stream */
- bz_stream* strm;
-
- /* mode this stream is in, and whether inputting */
- /* or outputting data */
- Int32 mode;
- Int32 state;
-
- /* remembers avail_in when flush/finish requested */
- UInt32 avail_in_expect;
-
- /* for doing the block sorting */
- UInt32* arr1;
- UInt32* arr2;
- UInt32* ftab;
- Int32 origPtr;
-
- /* aliases for arr1 and arr2 */
- UInt32* ptr;
- UChar* block;
- UInt16* mtfv;
- UChar* zbits;
-
- /* for deciding when to use the fallback sorting algorithm */
- Int32 workFactor;
-
- /* run-length-encoding of the input */
- UInt32 state_in_ch;
- Int32 state_in_len;
- BZ_RAND_DECLS;
-
- /* input and output limits and current posns */
- Int32 nblock;
- Int32 nblockMAX;
- Int32 numZ;
- Int32 state_out_pos;
-
- /* map of bytes used in block */
- Int32 nInUse;
- Bool inUse[256];
- UChar unseqToSeq[256];
-
- /* the buffer for bit stream creation */
- UInt32 bsBuff;
- Int32 bsLive;
-
- /* block and combined CRCs */
- UInt32 blockCRC;
- UInt32 combinedCRC;
-
- /* misc administratium */
- Int32 verbosity;
- Int32 blockNo;
- Int32 blockSize100k;
-
- /* stuff for coding the MTF values */
- Int32 nMTF;
- Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
- UChar selector [BZ_MAX_SELECTORS];
- UChar selectorMtf[BZ_MAX_SELECTORS];
-
- UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- /* second dimension: only 3 needed; 4 makes index calculations faster */
- UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
-
- }
- EState;
-
-
-
-/*-- externs for compression. --*/
-
-extern void
-BZ2_blockSort ( EState* );
-
-extern void
-BZ2_compressBlock ( EState*, Bool );
-
-extern void
-BZ2_bsInitWrite ( EState* );
-
-extern void
-BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
-
-extern void
-BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
-
-
-
-/*-- states for decompression. --*/
-
-#define BZ_X_IDLE 1
-#define BZ_X_OUTPUT 2
-
-#define BZ_X_MAGIC_1 10
-#define BZ_X_MAGIC_2 11
-#define BZ_X_MAGIC_3 12
-#define BZ_X_MAGIC_4 13
-#define BZ_X_BLKHDR_1 14
-#define BZ_X_BLKHDR_2 15
-#define BZ_X_BLKHDR_3 16
-#define BZ_X_BLKHDR_4 17
-#define BZ_X_BLKHDR_5 18
-#define BZ_X_BLKHDR_6 19
-#define BZ_X_BCRC_1 20
-#define BZ_X_BCRC_2 21
-#define BZ_X_BCRC_3 22
-#define BZ_X_BCRC_4 23
-#define BZ_X_RANDBIT 24
-#define BZ_X_ORIGPTR_1 25
-#define BZ_X_ORIGPTR_2 26
-#define BZ_X_ORIGPTR_3 27
-#define BZ_X_MAPPING_1 28
-#define BZ_X_MAPPING_2 29
-#define BZ_X_SELECTOR_1 30
-#define BZ_X_SELECTOR_2 31
-#define BZ_X_SELECTOR_3 32
-#define BZ_X_CODING_1 33
-#define BZ_X_CODING_2 34
-#define BZ_X_CODING_3 35
-#define BZ_X_MTF_1 36
-#define BZ_X_MTF_2 37
-#define BZ_X_MTF_3 38
-#define BZ_X_MTF_4 39
-#define BZ_X_MTF_5 40
-#define BZ_X_MTF_6 41
-#define BZ_X_ENDHDR_2 42
-#define BZ_X_ENDHDR_3 43
-#define BZ_X_ENDHDR_4 44
-#define BZ_X_ENDHDR_5 45
-#define BZ_X_ENDHDR_6 46
-#define BZ_X_CCRC_1 47
-#define BZ_X_CCRC_2 48
-#define BZ_X_CCRC_3 49
-#define BZ_X_CCRC_4 50
-
-
-
-/*-- Constants for the fast MTF decoder. --*/
-
-#define MTFA_SIZE 4096
-#define MTFL_SIZE 16
-
-
-
-/*-- Structure holding all the decompression-side stuff. --*/
-
-typedef
- struct {
- /* pointer back to the struct bz_stream */
- bz_stream* strm;
-
- /* state indicator for this stream */
- Int32 state;
-
- /* for doing the final run-length decoding */
- UChar state_out_ch;
- Int32 state_out_len;
- Bool blockRandomised;
- BZ_RAND_DECLS;
-
- /* the buffer for bit stream reading */
- UInt32 bsBuff;
- Int32 bsLive;
-
- /* misc administratium */
- Int32 blockSize100k;
- Bool smallDecompress;
- Int32 currBlockNo;
- Int32 verbosity;
-
- /* for undoing the Burrows-Wheeler transform */
- Int32 origPtr;
- UInt32 tPos;
- Int32 k0;
- Int32 unzftab[256];
- Int32 nblock_used;
- Int32 cftab[257];
- Int32 cftabCopy[257];
-
- /* for undoing the Burrows-Wheeler transform (FAST) */
- UInt32 *tt;
-
- /* for undoing the Burrows-Wheeler transform (SMALL) */
- UInt16 *ll16;
- UChar *ll4;
-
- /* stored and calculated CRCs */
- UInt32 storedBlockCRC;
- UInt32 storedCombinedCRC;
- UInt32 calculatedBlockCRC;
- UInt32 calculatedCombinedCRC;
-
- /* map of bytes used in block */
- Int32 nInUse;
- Bool inUse[256];
- Bool inUse16[16];
- UChar seqToUnseq[256];
-
- /* for decoding the MTF values */
- UChar mtfa [MTFA_SIZE];
- Int32 mtfbase[256 / MTFL_SIZE];
- UChar selector [BZ_MAX_SELECTORS];
- UChar selectorMtf[BZ_MAX_SELECTORS];
- UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-
- Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 minLens[BZ_N_GROUPS];
-
- /* save area for scalars in the main decompress code */
- Int32 save_i;
- Int32 save_j;
- Int32 save_t;
- Int32 save_alphaSize;
- Int32 save_nGroups;
- Int32 save_nSelectors;
- Int32 save_EOB;
- Int32 save_groupNo;
- Int32 save_groupPos;
- Int32 save_nextSym;
- Int32 save_nblockMAX;
- Int32 save_nblock;
- Int32 save_es;
- Int32 save_N;
- Int32 save_curr;
- Int32 save_zt;
- Int32 save_zn;
- Int32 save_zvec;
- Int32 save_zj;
- Int32 save_gSel;
- Int32 save_gMinlen;
- Int32* save_gLimit;
- Int32* save_gBase;
- Int32* save_gPerm;
-
- }
- DState;
-
-
-
-/*-- Macros for decompression. --*/
-
-#define BZ_GET_FAST(cccc) \
- s->tPos = s->tt[s->tPos]; \
- cccc = (UChar)(s->tPos & 0xff); \
- s->tPos >>= 8;
-
-#define BZ_GET_FAST_C(cccc) \
- c_tPos = c_tt[c_tPos]; \
- cccc = (UChar)(c_tPos & 0xff); \
- c_tPos >>= 8;
-
-#define SET_LL4(i,n) \
- { if (((i) & 0x1) == 0) \
- s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
- s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
- }
-
-#define GET_LL4(i) \
- ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
-
-#define SET_LL(i,n) \
- { s->ll16[i] = (UInt16)(n & 0x0000ffff); \
- SET_LL4(i, n >> 16); \
- }
-
-#define GET_LL(i) \
- (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
-
-#define BZ_GET_SMALL(cccc) \
- cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
- s->tPos = GET_LL(s->tPos);
-
-
-/*-- externs for decompression. --*/
-
-extern Int32
-BZ2_indexIntoF ( Int32, Int32* );
-
-extern Int32
-BZ2_decompress ( DState* );
-
-extern void
-BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
- Int32, Int32, Int32 );
-
-
-#endif
-
-
-/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
-
-#ifdef BZ_NO_STDIO
-#ifndef NULL
-#define NULL 0
-#endif
-#endif
-
-
-/*-------------------------------------------------------------*/
-/*--- end bzlib_private.h ---*/
-/*-------------------------------------------------------------*/
-
-
-/* Something which has the same size as void* on the host. That is,
- it is 32 bits on a 32-bit host and 64 bits on a 64-bit host, and so
- it can safely be coerced to and from a pointer type on the host
- machine. */
-typedef unsigned long HWord;
-typedef char HChar;
-typedef signed int Int;
-typedef unsigned int UInt;
-
-typedef signed long long int Long;
-typedef unsigned long long int ULong;
-
-
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-
-//#include "/home/sewardj/VEX/trunk/pub/libvex_basictypes.h"
-
-static HWord (*serviceFn)(HWord,HWord) = 0;
-
-
-static char* my_strcpy ( char* dest, const char* src )
-{
- char* dest_orig = dest;
- while (*src) *dest++ = *src++;
- *dest = 0;
- return dest_orig;
-}
-
-static void* my_memcpy ( void *dest, const void *src, int sz )
-{
- const char *s = (const char *)src;
- char *d = (char *)dest;
-
- while (sz--)
- *d++ = *s++;
-
- return dest;
-}
-
-static void* my_memmove( void *dst, const void *src, unsigned int len )
-{
- register char *d;
- register char *s;
- if ( dst > src ) {
- d = (char *)dst + len - 1;
- s = (char *)src + len - 1;
- while ( len >= 4 ) {
- *d-- = *s--;
- *d-- = *s--;
- *d-- = *s--;
- *d-- = *s--;
- len -= 4;
- }
- while ( len-- ) {
- *d-- = *s--;
- }
- } else if ( dst < src ) {
- d = (char *)dst;
- s = (char *)src;
- while ( len >= 4 ) {
- *d++ = *s++;
- *d++ = *s++;
- *d++ = *s++;
- *d++ = *s++;
- len -= 4;
- }
- while ( len-- ) {
- *d++ = *s++;
- }
- }
- return dst;
-}
-
-char* my_strcat ( char* dest, const char* src )
-{
- char* dest_orig = dest;
- while (*dest) dest++;
- while (*src) *dest++ = *src++;
- *dest = 0;
- return dest_orig;
-}
-
-
-/////////////////////////////////////////////////////////////////////
-
-static void vexxx_log_bytes ( char* p, int n )
-{
- int i;
- for (i = 0; i < n; i++)
- (*serviceFn)( 1, (int)p[i] );
-}
-
-/*---------------------------------------------------------*/
-/*--- vexxx_printf ---*/
-/*---------------------------------------------------------*/
-
-/* This should be the only <...> include in the entire VEX library.
- New code for vexxx_util.c should go above this point. */
-#include <stdarg.h>
-
-static HChar vexxx_toupper ( HChar c )
-{
- if (c >= 'a' && c <= 'z')
- return c + ('A' - 'a');
- else
- return c;
-}
-
-static Int vexxx_strlen ( const HChar* str )
-{
- Int i = 0;
- while (str[i] != 0) i++;
- return i;
-}
-
-Bool vexxx_streq ( const HChar* s1, const HChar* s2 )
-{
- while (True) {
- if (*s1 == 0 && *s2 == 0)
- return True;
- if (*s1 != *s2)
- return False;
- s1++;
- s2++;
- }
-}
-
-/* Some flags. */
-#define VG_MSG_SIGNED 1 /* The value is signed. */
-#define VG_MSG_ZJUSTIFY 2 /* Must justify with '0'. */
-#define VG_MSG_LJUSTIFY 4 /* Must justify on the left. */
-#define VG_MSG_PAREN 8 /* Parenthesize if present (for %y) */
-#define VG_MSG_COMMA 16 /* Add commas to numbers (for %d, %u) */
-
-/* Copy a string into the buffer. */
-static UInt
-myvprintf_str ( void(*send)(HChar), Int flags, Int width, HChar* str,
- Bool capitalise )
-{
-# define MAYBE_TOUPPER(ch) (capitalise ? vexxx_toupper(ch) : (ch))
- UInt ret = 0;
- Int i, extra;
- Int len = vexxx_strlen(str);
-
- if (width == 0) {
- ret += len;
- for (i = 0; i < len; i++)
- send(MAYBE_TOUPPER(str[i]));
- return ret;
- }
-
- if (len > width) {
- ret += width;
- for (i = 0; i < width; i++)
- send(MAYBE_TOUPPER(str[i]));
- return ret;
- }
-
- extra = width - len;
- if (flags & VG_MSG_LJUSTIFY) {
- ret += extra;
- for (i = 0; i < extra; i++)
- send(' ');
- }
- ret += len;
- for (i = 0; i < len; i++)
- send(MAYBE_TOUPPER(str[i]));
- if (!(flags & VG_MSG_LJUSTIFY)) {
- ret += extra;
- for (i = 0; i < extra; i++)
- send(' ');
- }
-
-# undef MAYBE_TOUPPER
-
- return ret;
-}
-
-/* Write P into the buffer according to these args:
- * If SIGN is true, p is a signed.
- * BASE is the base.
- * If WITH_ZERO is true, '0' must be added.
- * WIDTH is the width of the field.
- */
-static UInt
-myvprintf_int64 ( void(*send)(HChar), Int flags, Int base, Int width, ULong pL)
-{
- HChar buf[40];
- Int ind = 0;
- Int i, nc = 0;
- Bool neg = False;
- HChar *digits = "0123456789ABCDEF";
- UInt ret = 0;
- UInt p = (UInt)pL;
-
- if (base < 2 || base > 16)
- return ret;
-
- if ((flags & VG_MSG_SIGNED) && (Int)p < 0) {
- p = - (Int)p;
- neg = True;
- }
-
- if (p == 0)
- buf[ind++] = '0';
- else {
- while (p > 0) {
- if ((flags & VG_MSG_COMMA) && 10 == base &&
- 0 == (ind-nc) % 3 && 0 != ind)
- {
- buf[ind++] = ',';
- nc++;
- }
- buf[ind++] = digits[p % base];
- p /= base;
- }
- }
-
- if (neg)
- buf[ind++] = '-';
-
- if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) {
- for(; ind < width; ind++) {
- //vassert(ind < 39);
- buf[ind] = ((flags & VG_MSG_ZJUSTIFY) ? '0': ' ');
- }
- }
-
- /* Reverse copy to buffer. */
- ret += ind;
- for (i = ind -1; i >= 0; i--) {
- send(buf[i]);
- }
- if (width > 0 && (flags & VG_MSG_LJUSTIFY)) {
- for(; ind < width; ind++) {
- ret++;
- send(' '); // Never pad with zeroes on RHS -- changes the value!
- }
- }
- return ret;
-}
-
-
-/* A simple vprintf(). */
-static
-UInt vprintf_wrk ( void(*send)(HChar), const HChar *format, va_list vargs )
-{
- UInt ret = 0;
- int i;
- int flags;
- int width;
- Bool is_long;
-
- /* We assume that vargs has already been initialised by the
- caller, using va_start, and that the caller will similarly
- clean up with va_end.
- */
-
- for (i = 0; format[i] != 0; i++) {
- if (format[i] != '%') {
- send(format[i]);
- ret++;
- continue;
- }
- i++;
- /* A '%' has been found. Ignore a trailing %. */
- if (format[i] == 0)
- break;
- if (format[i] == '%') {
- /* `%%' is replaced by `%'. */
- send('%');
- ret++;
- continue;
- }
- flags = 0;
- is_long = False;
- width = 0; /* length of the field. */
- if (format[i] == '(') {
- flags |= VG_MSG_PAREN;
- i++;
- }
- /* If ',' follows '%', commas will be inserted. */
- if (format[i] == ',') {
- flags |= VG_MSG_COMMA;
- i++;
- }
- /* If '-' follows '%', justify on the left. */
- if (format[i] == '-') {
- flags |= VG_MSG_LJUSTIFY;
- i++;
- }
- /* If '0' follows '%', pads will be inserted. */
- if (format[i] == '0') {
- flags |= VG_MSG_ZJUSTIFY;
- i++;
- }
- /* Compute the field length. */
- while (format[i] >= '0' && format[i] <= '9') {
- width *= 10;
- width += format[i++] - '0';
- }
- while (format[i] == 'l') {
- i++;
- is_long = True;
- }
-
- switch (format[i]) {
- case 'd': /* %d */
- flags |= VG_MSG_SIGNED;
- if (is_long)
- ret += myvprintf_int64(send, flags, 10, width,
- (ULong)(va_arg (vargs, Long)));
- else
- ret += myvprintf_int64(send, flags, 10, width,
- (ULong)(va_arg (vargs, Int)));
- break;
- case 'u': /* %u */
- if (is_long)
- ret += myvprintf_int64(send, flags, 10, width,
- (ULong)(va_arg (vargs, ULong)));
- else
- ret += myvprintf_int64(send, flags, 10, width,
- (ULong)(va_arg (vargs, UInt)));
- break;
- case 'p': /* %p */
- ret += 2;
- send('0');
- send('x');
- ret += myvprintf_int64(send, flags, 16, width,
- (ULong)((HWord)va_arg (vargs, void *)));
- break;
- case 'x': /* %x */
- if (is_long)
- ret += myvprintf_int64(send, flags, 16, width,
- (ULong)(va_arg (vargs, ULong)));
- else
- ret += myvprintf_int64(send, flags, 16, width,
- (ULong)(va_arg (vargs, UInt)));
- break;
- case 'c': /* %c */
- ret++;
- send((va_arg (vargs, int)));
- break;
- case 's': case 'S': { /* %s */
- char *str = va_arg (vargs, char *);
- if (str == (char*) 0) str = "(null)";
- ret += myvprintf_str(send, flags, width, str,
- (format[i]=='S'));
- break;
- }
-# if 0
- case 'y': { /* %y - print symbol */
- Addr a = va_arg(vargs, Addr);
-
- HChar *name;
- if (VG_(get_fnname_w_offset)(a, &name)) {
- HChar buf[1 + VG_strlen(name) + 1 + 1];
- if (flags & VG_MSG_PAREN) {
- VG_(sprintf)(str, "(%s)", name):
- } else {
- VG_(sprintf)(str, "%s", name):
- }
- ret += myvprintf_str(send, flags, width, buf, 0);
- }
- break;
- }
-# endif
- default:
- break;
- }
- }
- return ret;
-}
-
-
-/* A general replacement for printf(). Note that only low-level
- debugging info should be sent via here. The official route is to
- to use vg_message(). This interface is deprecated.
-*/
-static HChar myprintf_buf[1000];
-static Int n_myprintf_buf;
-
-static void add_to_myprintf_buf ( HChar c )
-{
- if (c == '\n' || n_myprintf_buf >= 1000-10 /*paranoia*/ ) {
- (*vexxx_log_bytes)( myprintf_buf, vexxx_strlen(myprintf_buf) );
- n_myprintf_buf = 0;
- myprintf_buf[n_myprintf_buf] = 0;
- }
- myprintf_buf[n_myprintf_buf++] = c;
- myprintf_buf[n_myprintf_buf] = 0;
-}
-
-static UInt vexxx_printf ( const char *format, ... )
-{
- UInt ret;
- va_list vargs;
- va_start(vargs,format);
-
- n_myprintf_buf = 0;
- myprintf_buf[n_myprintf_buf] = 0;
- ret = vprintf_wrk ( add_to_myprintf_buf, format, vargs );
-
- if (n_myprintf_buf > 0) {
- (*vexxx_log_bytes)( myprintf_buf, n_myprintf_buf );
- }
-
- va_end(vargs);
-
- return ret;
-}
-
-/*---------------------------------------------------------------*/
-/*--- end vexxx_util.c ---*/
-/*---------------------------------------------------------------*/
-
-
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-
-
-/*-------------------------------------------------------------*/
-/*--- Decompression machinery ---*/
-/*--- decompress.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2004 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-
-
-
-/*---------------------------------------------------*/
-static
-void makeMaps_d ( DState* s )
-{
- Int32 i;
- s->nInUse = 0;
- for (i = 0; i < 256; i++)
- if (s->inUse[i]) {
- s->seqToUnseq[s->nInUse] = i;
- s->nInUse++;
- }
-}
-
-
-/*---------------------------------------------------*/
-#define RETURN(rrr) \
- { retVal = rrr; goto save_state_and_return; };
-
-#define GET_BITS(lll,vvv,nnn) \
- case lll: s->state = lll; \
- while (True) { \
- if (s->bsLive >= nnn) { \
- UInt32 v; \
- v = (s->bsBuff >> \
- (s->bsLive-nnn)) & ((1 << nnn)-1); \
- s->bsLive -= nnn; \
- vvv = v; \
- break; \
- } \
- if (s->strm->avail_in == 0) RETURN(BZ_OK); \
- s->bsBuff \
- = (s->bsBuff << 8) | \
- ((UInt32) \
- (*((UChar*)(s->strm->next_in)))); \
- s->bsLive += 8; \
- s->strm->next_in++; \
- s->strm->avail_in--; \
- s->strm->total_in_lo32++; \
- if (s->strm->total_in_lo32 == 0) \
- s->strm->total_in_hi32++; \
- }
-
-#define GET_UCHAR(lll,uuu) \
- GET_BITS(lll,uuu,8)
-
-#define GET_BIT(lll,uuu) \
- GET_BITS(lll,uuu,1)
-
-/*---------------------------------------------------*/
-#define GET_MTF_VAL(label1,label2,lval) \
-{ \
- if (groupPos == 0) { \
- groupNo++; \
- if (groupNo >= nSelectors) \
- RETURN(BZ_DATA_ERROR); \
- groupPos = BZ_G_SIZE; \
- gSel = s->selector[groupNo]; \
- gMinlen = s->minLens[gSel]; \
- gLimit = &(s->limit[gSel][0]); \
- gPerm = &(s->perm[gSel][0]); \
- gBase = &(s->base[gSel][0]); \
- } \
- groupPos--; \
- zn = gMinlen; \
- GET_BITS(label1, zvec, zn); \
- while (1) { \
- if (zn > 20 /* the longest code */) \
- RETURN(BZ_DATA_ERROR); \
- if (zvec <= gLimit[zn]) break; \
- zn++; \
- GET_BIT(label2, zj); \
- zvec = (zvec << 1) | zj; \
- }; \
- if (zvec - gBase[zn] < 0 \
- || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
- RETURN(BZ_DATA_ERROR); \
- lval = gPerm[zvec - gBase[zn]]; \
-}
-
-
-
-/*---------------------------------------------------*/
-__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
-{
- Int32 nb, na, mid;
- nb = 0;
- na = 256;
- do {
- mid = (nb + na) >> 1;
- if (indx >= cftab[mid]) nb = mid; else na = mid;
- }
- while (na - nb != 1);
- return nb;
-}
-
-/*---------------------------------------------------*/
-Int32 BZ2_decompress ( DState* s )
-{
- UChar uc;
- Int32 retVal;
- Int32 minLen, maxLen;
- bz_stream* strm = s->strm;
-
- /* stuff that needs to be saved/restored */
- Int32 i;
- Int32 j;
- Int32 t;
- Int32 alphaSize;
- Int32 nGroups;
- Int32 nSelectors;
- Int32 EOB;
- Int32 groupNo;
- Int32 groupPos;
- Int32 nextSym;
- Int32 nblockMAX;
- Int32 nblock;
- Int32 es;
- Int32 N;
- Int32 curr;
- Int32 zt;
- Int32 zn;
- Int32 zvec;
- Int32 zj;
- Int32 gSel;
- Int32 gMinlen;
- Int32* gLimit;
- Int32* gBase;
- Int32* gPerm;
-
- if (s->state == BZ_X_MAGIC_1) {
- /*initialise the save area*/
- s->save_i = 0;
- s->save_j = 0;
- s->save_t = 0;
- s->save_alphaSize = 0;
- s->save_nGroups = 0;
- s->save_nSelectors = 0;
- s->save_EOB = 0;
- s->save_groupNo = 0;
- s->save_groupPos = 0;
- s->save_nextSym = 0;
- s->save_nblockMAX = 0;
- s->save_nblock = 0;
- s->save_es = 0;
- s->save_N = 0;
- s->save_curr = 0;
- s->save_zt = 0;
- s->save_zn = 0;
- s->save_zvec = 0;
- s->save_zj = 0;
- s->save_gSel = 0;
- s->save_gMinlen = 0;
- s->save_gLimit = NULL;
- s->save_gBase = NULL;
- s->save_gPerm = NULL;
- }
-
- /*restore from the save area*/
- i = s->save_i;
- j = s->save_j;
- t = s->save_t;
- alphaSize = s->save_alphaSize;
- nGroups = s->save_nGroups;
- nSelectors = s->save_nSelectors;
- EOB = s->save_EOB;
- groupNo = s->save_groupNo;
- groupPos = s->save_groupPos;
- nextSym = s->save_nextSym;
- nblockMAX = s->save_nblockMAX;
- nblock = s->save_nblock;
- es = s->save_es;
- N = s->save_N;
- curr = s->save_curr;
- zt = s->save_zt;
- zn = s->save_zn;
- zvec = s->save_zvec;
- zj = s->save_zj;
- gSel = s->save_gSel;
- gMinlen = s->save_gMinlen;
- gLimit = s->save_gLimit;
- gBase = s->save_gBase;
- gPerm = s->save_gPerm;
-
- retVal = BZ_OK;
-
- switch (s->state) {
-
- GET_UCHAR(BZ_X_MAGIC_1, uc);
- if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
-
- GET_UCHAR(BZ_X_MAGIC_2, uc);
- if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
-
- GET_UCHAR(BZ_X_MAGIC_3, uc)
- if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
-
- GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
- if (s->blockSize100k < (BZ_HDR_0 + 1) ||
- s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
- s->blockSize100k -= BZ_HDR_0;
-
- if (s->smallDecompress) {
- s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
- s->ll4 = BZALLOC(
- ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
- );
- if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
- } else {
- s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
- if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
- }
-
- GET_UCHAR(BZ_X_BLKHDR_1, uc);
-
- if (uc == 0x17) goto endhdr_2;
- if (uc != 0x31) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_BLKHDR_2, uc);
- if (uc != 0x41) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_BLKHDR_3, uc);
- if (uc != 0x59) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_BLKHDR_4, uc);
- if (uc != 0x26) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_BLKHDR_5, uc);
- if (uc != 0x53) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_BLKHDR_6, uc);
- if (uc != 0x59) RETURN(BZ_DATA_ERROR);
-
- s->currBlockNo++;
- if (s->verbosity >= 2)
- VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
-
- s->storedBlockCRC = 0;
- GET_UCHAR(BZ_X_BCRC_1, uc);
- s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
- GET_UCHAR(BZ_X_BCRC_2, uc);
- s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
- GET_UCHAR(BZ_X_BCRC_3, uc);
- s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
- GET_UCHAR(BZ_X_BCRC_4, uc);
- s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
-
- GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
-
- s->origPtr = 0;
- GET_UCHAR(BZ_X_ORIGPTR_1, uc);
- s->origPtr = (s->origPtr << 8) | ((Int32)uc);
- GET_UCHAR(BZ_X_ORIGPTR_2, uc);
- s->origPtr = (s->origPtr << 8) | ((Int32)uc);
- GET_UCHAR(BZ_X_ORIGPTR_3, uc);
- s->origPtr = (s->origPtr << 8) | ((Int32)uc);
-
- if (s->origPtr < 0)
- RETURN(BZ_DATA_ERROR);
- if (s->origPtr > 10 + 100000*s->blockSize100k)
- RETURN(BZ_DATA_ERROR);
-
- /*--- Receive the mapping table ---*/
- for (i = 0; i < 16; i++) {
- GET_BIT(BZ_X_MAPPING_1, uc);
- if (uc == 1)
- s->inUse16[i] = True; else
- s->inUse16[i] = False;
- }
-
- for (i = 0; i < 256; i++) s->inUse[i] = False;
-
- for (i = 0; i < 16; i++)
- if (s->inUse16[i])
- for (j = 0; j < 16; j++) {
- GET_BIT(BZ_X_MAPPING_2, uc);
- if (uc == 1) s->inUse[i * 16 + j] = True;
- }
- makeMaps_d ( s );
- if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
- alphaSize = s->nInUse+2;
-
- /*--- Now the selectors ---*/
- GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
- if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
- GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
- if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
- for (i = 0; i < nSelectors; i++) {
- j = 0;
- while (True) {
- GET_BIT(BZ_X_SELECTOR_3, uc);
- if (uc == 0) break;
- j++;
- if (j >= nGroups) RETURN(BZ_DATA_ERROR);
- }
- s->selectorMtf[i] = j;
- }
-
- /*--- Undo the MTF values for the selectors. ---*/
- {
- UChar pos[BZ_N_GROUPS], tmp, v;
- for (v = 0; v < nGroups; v++) pos[v] = v;
-
- for (i = 0; i < nSelectors; i++) {
- v = s->selectorMtf[i];
- tmp = pos[v];
- while (v > 0) { pos[v] = pos[v-1]; v--; }
- pos[0] = tmp;
- s->selector[i] = tmp;
- }
- }
-
- /*--- Now the coding tables ---*/
- for (t = 0; t < nGroups; t++) {
- GET_BITS(BZ_X_CODING_1, curr, 5);
- for (i = 0; i < alphaSize; i++) {
- while (True) {
- if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
- GET_BIT(BZ_X_CODING_2, uc);
- if (uc == 0) break;
- GET_BIT(BZ_X_CODING_3, uc);
- if (uc == 0) curr++; else curr--;
- }
- s->len[t][i] = curr;
- }
- }
-
- /*--- Create the Huffman decoding tables ---*/
- for (t = 0; t < nGroups; t++) {
- minLen = 32;
- maxLen = 0;
- for (i = 0; i < alphaSize; i++) {
- if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
- if (s->len[t][i] < minLen) minLen = s->len[t][i];
- }
- BZ2_hbCreateDecodeTables (
- &(s->limit[t][0]),
- &(s->base[t][0]),
- &(s->perm[t][0]),
- &(s->len[t][0]),
- minLen, maxLen, alphaSize
- );
- s->minLens[t] = minLen;
- }
-
- /*--- Now the MTF values ---*/
-
- EOB = s->nInUse+1;
- nblockMAX = 100000 * s->blockSize100k;
- groupNo = -1;
- groupPos = 0;
-
- for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
-
- /*-- MTF init --*/
- {
- Int32 ii, jj, kk;
- kk = MTFA_SIZE-1;
- for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
- for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
- s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
- kk--;
- }
- s->mtfbase[ii] = kk + 1;
- }
- }
- /*-- end MTF init --*/
-
- nblock = 0;
- GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
-
- while (True) {
-
- if (nextSym == EOB) break;
-
- if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
-
- es = -1;
- N = 1;
- do {
- if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
- if (nextSym == BZ_RUNB) es = es + (1+1) * N;
- N = N * 2;
- GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
- }
- while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
-
- es++;
- uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
- s->unzftab[uc] += es;
-
- if (s->smallDecompress)
- while (es > 0) {
- if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
- s->ll16[nblock] = (UInt16)uc;
- nblock++;
- es--;
- }
- else
- while (es > 0) {
- if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
- s->tt[nblock] = (UInt32)uc;
- nblock++;
- es--;
- };
-
- continue;
-
- } else {
-
- if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
-
- /*-- uc = MTF ( nextSym-1 ) --*/
- {
- Int32 ii, jj, kk, pp, lno, off;
- UInt32 nn;
- nn = (UInt32)(nextSym - 1);
-
- if (nn < MTFL_SIZE) {
- /* avoid general-case expense */
- pp = s->mtfbase[0];
- uc = s->mtfa[pp+nn];
- while (nn > 3) {
- Int32 z = pp+nn;
- s->mtfa[(z) ] = s->mtfa[(z)-1];
- s->mtfa[(z)-1] = s->mtfa[(z)-2];
- s->mtfa[(z)-2] = s->mtfa[(z)-3];
- s->mtfa[(z)-3] = s->mtfa[(z)-4];
- nn -= 4;
- }
- while (nn > 0) {
- s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
- };
- s->mtfa[pp] = uc;
- } else {
- /* general case */
- lno = nn / MTFL_SIZE;
- off = nn % MTFL_SIZE;
- pp = s->mtfbase[lno] + off;
- uc = s->mtfa[pp];
- while (pp > s->mtfbase[lno]) {
- s->mtfa[pp] = s->mtfa[pp-1]; pp--;
- };
- s->mtfbase[lno]++;
- while (lno > 0) {
- s->mtfbase[lno]--;
- s->mtfa[s->mtfbase[lno]]
- = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
- lno--;
- }
- s->mtfbase[0]--;
- s->mtfa[s->mtfbase[0]] = uc;
- if (s->mtfbase[0] == 0) {
- kk = MTFA_SIZE-1;
- for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
- for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
- s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
- kk--;
- }
- s->mtfbase[ii] = kk + 1;
- }
- }
- }
- }
- /*-- end uc = MTF ( nextSym-1 ) --*/
-
- s->unzftab[s->seqToUnseq[uc]]++;
- if (s->smallDecompress)
- s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
- s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
- nblock++;
-
- GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
- continue;
- }
- }
-
- /* Now we know what nblock is, we can do a better sanity
- check on s->origPtr.
- */
- if (s->origPtr < 0 || s->origPtr >= nblock)
- RETURN(BZ_DATA_ERROR);
-
- /*-- Set up cftab to facilitate generation of T^(-1) --*/
- s->cftab[0] = 0;
- for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
- for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
- for (i = 0; i <= 256; i++) {
- if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
- /* s->cftab[i] can legitimately be == nblock */
- RETURN(BZ_DATA_ERROR);
- }
- }
-
- s->state_out_len = 0;
- s->state_out_ch = 0;
- BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
- s->state = BZ_X_OUTPUT;
- if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
-
- if (s->smallDecompress) {
-
- /*-- Make a copy of cftab, used in generation of T --*/
- for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
-
- /*-- compute the T vector --*/
- for (i = 0; i < nblock; i++) {
- uc = (UChar)(s->ll16[i]);
- SET_LL(i, s->cftabCopy[uc]);
- s->cftabCopy[uc]++;
- }
-
- /*-- Compute T^(-1) by pointer reversal on T --*/
- i = s->origPtr;
- j = GET_LL(i);
- do {
- Int32 tmp = GET_LL(j);
- SET_LL(j, i);
- i = j;
- j = tmp;
- }
- while (i != s->origPtr);
-
- s->tPos = s->origPtr;
- s->nblock_used = 0;
- if (s->blockRandomised) {
- BZ_RAND_INIT_MASK;
- BZ_GET_SMALL(s->k0); s->nblock_used++;
- BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
- } else {
- BZ_GET_SMALL(s->k0); s->nblock_used++;
- }
-
- } else {
-
- /*-- compute the T^(-1) vector --*/
- for (i = 0; i < nblock; i++) {
- uc = (UChar)(s->tt[i] & 0xff);
- s->tt[s->cftab[uc]] |= (i << 8);
- s->cftab[uc]++;
- }
-
- s->tPos = s->tt[s->origPtr] >> 8;
- s->nblock_used = 0;
- if (s->blockRandomised) {
- BZ_RAND_INIT_MASK;
- BZ_GET_FAST(s->k0); s->nblock_used++;
- BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
- } else {
- BZ_GET_FAST(s->k0); s->nblock_used++;
- }
-
- }
-
- RETURN(BZ_OK);
-
-
-
- endhdr_2:
-
- GET_UCHAR(BZ_X_ENDHDR_2, uc);
- if (uc != 0x72) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_ENDHDR_3, uc);
- if (uc != 0x45) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_ENDHDR_4, uc);
- if (uc != 0x38) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_ENDHDR_5, uc);
- if (uc != 0x50) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_ENDHDR_6, uc);
- if (uc != 0x90) RETURN(BZ_DATA_ERROR);
-
- s->storedCombinedCRC = 0;
- GET_UCHAR(BZ_X_CCRC_1, uc);
- s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
- GET_UCHAR(BZ_X_CCRC_2, uc);
- s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
- GET_UCHAR(BZ_X_CCRC_3, uc);
- s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
- GET_UCHAR(BZ_X_CCRC_4, uc);
- s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
-
- s->state = BZ_X_IDLE;
- RETURN(BZ_STREAM_END);
-
- default: AssertH ( False, 4001 );
- }
-
- AssertH ( False, 4002 );
-
- save_state_and_return:
-
- s->save_i = i;
- s->save_j = j;
- s->save_t = t;
- s->save_alphaSize = alphaSize;
- s->save_nGroups = nGroups;
- s->save_nSelectors = nSelectors;
- s->save_EOB = EOB;
- s->save_groupNo = groupNo;
- s->save_groupPos = groupPos;
- s->save_nextSym = nextSym;
- s->save_nblockMAX = nblockMAX;
- s->save_nblock = nblock;
- s->save_es = es;
- s->save_N = N;
- s->save_curr = curr;
- s->save_zt = zt;
- s->save_zn = zn;
- s->save_zvec = zvec;
- s->save_zj = zj;
- s->save_gSel = gSel;
- s->save_gMinlen = gMinlen;
- s->save_gLimit = gLimit;
- s->save_gBase = gBase;
- s->save_gPerm = gPerm;
-
- return retVal;
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end decompress.c ---*/
-/*-------------------------------------------------------------*/
-
-/*-------------------------------------------------------------*/
-/*--- Block sorting machinery ---*/
-/*--- blocksort.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2004 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
-
- To get some idea how the block sorting algorithms in this file
- work, read my paper
- On the Performance of BWT Sorting Algorithms
- in Proceedings of the IEEE Data Compression Conference 2000,
- Snowbird, Utah, USA, 27-30 March 2000. The main sort in this
- file implements the algorithm called cache in the paper.
---*/
-
-
-
-/*---------------------------------------------*/
-/*--- Fallback O(N log(N)^2) sorting ---*/
-/*--- algorithm, for repetitive blocks ---*/
-/*---------------------------------------------*/
-
-/*---------------------------------------------*/
-static
-__inline__
-void fallbackSimpleSort ( UInt32* fmap,
- UInt32* eclass,
- Int32 lo,
- Int32 hi )
-{
- Int32 i, j, tmp;
- UInt32 ec_tmp;
-
- if (lo == hi) return;
-
- if (hi - lo > 3) {
- for ( i = hi-4; i >= lo; i-- ) {
- tmp = fmap[i];
- ec_tmp = eclass[tmp];
- for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
- fmap[j-4] = fmap[j];
- fmap[j-4] = tmp;
- }
- }
-
- for ( i = hi-1; i >= lo; i-- ) {
- tmp = fmap[i];
- ec_tmp = eclass[tmp];
- for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
- fmap[j-1] = fmap[j];
- fmap[j-1] = tmp;
- }
-}
-
-
-/*---------------------------------------------*/
-#define fswap(zz1, zz2) \
- { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
-
-#define fvswap(zzp1, zzp2, zzn) \
-{ \
- Int32 yyp1 = (zzp1); \
- Int32 yyp2 = (zzp2); \
- Int32 yyn = (zzn); \
- while (yyn > 0) { \
- fswap(fmap[yyp1], fmap[yyp2]); \
- yyp1++; yyp2++; yyn--; \
- } \
-}
-
-
-#define fmin(a,b) ((a) < (b)) ? (a) : (b)
-
-#define fpush(lz,hz) { stackLo[sp] = lz; \
- stackHi[sp] = hz; \
- sp++; }
-
-#define fpop(lz,hz) { sp--; \
- lz = stackLo[sp]; \
- hz = stackHi[sp]; }
-
-#define FALLBACK_QSORT_SMALL_THRESH 10
-#define FALLBACK_QSORT_STACK_SIZE 100
-
-
-static
-void fallbackQSort3 ( UInt32* fmap,
- UInt32* eclass,
- Int32 loSt,
- Int32 hiSt )
-{
- Int32 unLo, unHi, ltLo, gtHi, n, m;
- Int32 sp, lo, hi;
- UInt32 med, r, r3;
- Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
- Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
-
- r = 0;
-
- sp = 0;
- fpush ( loSt, hiSt );
-
- while (sp > 0) {
-
- AssertH ( sp < FALLBACK_QSORT_STACK_SIZE, 1004 );
-
- fpop ( lo, hi );
- if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
- fallbackSimpleSort ( fmap, eclass, lo, hi );
- continue;
- }
-
- /* Random partitioning. Median of 3 sometimes fails to
- avoid bad cases. Median of 9 seems to help but
- looks rather expensive. This too seems to work but
- is cheaper. Guidance for the magic constants
- 7621 and 32768 is taken from Sedgewick's algorithms
- book, chapter 35.
- */
- r = ((r * 7621) + 1) % 32768;
- r3 = r % 3;
- if (r3 == 0) med = eclass[fmap[lo]]; else
- if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
- med = eclass[fmap[hi]];
-
- unLo = ltLo = lo;
- unHi = gtHi = hi;
-
- while (1) {
- while (1) {
- if (unLo > unHi) break;
- n = (Int32)eclass[fmap[unLo]] - (Int32)med;
- if (n == 0) {
- fswap(fmap[unLo], fmap[ltLo]);
- ltLo++; unLo++;
- continue;
- };
- if (n > 0) break;
- unLo++;
- }
- while (1) {
- if (unLo > unHi) break;
- n = (Int32)eclass[fmap[unHi]] - (Int32)med;
- if (n == 0) {
- fswap(fmap[unHi], fmap[gtHi]);
- gtHi--; unHi--;
- continue;
- };
- if (n < 0) break;
- unHi--;
- }
- if (unLo > unHi) break;
- fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
- }
-
- AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
-
- if (gtHi < ltLo) continue;
-
- n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
- m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
-
- n = lo + unLo - ltLo - 1;
- m = hi - (gtHi - unHi) + 1;
-
- if (n - lo > hi - m) {
- fpush ( lo, n );
- fpush ( m, hi );
- } else {
- fpush ( m, hi );
- fpush ( lo, n );
- }
- }
-}
-
-#undef fmin
-#undef fpush
-#undef fpop
-#undef fswap
-#undef fvswap
-#undef FALLBACK_QSORT_SMALL_THRESH
-#undef FALLBACK_QSORT_STACK_SIZE
-
-
-/*---------------------------------------------*/
-/* Pre:
- nblock > 0
- eclass exists for [0 .. nblock-1]
- ((UChar*)eclass) [0 .. nblock-1] holds block
- ptr exists for [0 .. nblock-1]
-
- Post:
- ((UChar*)eclass) [0 .. nblock-1] holds block
- All other areas of eclass destroyed
- fmap [0 .. nblock-1] holds sorted order
- bhtab [ 0 .. 2+(nblock/32) ] destroyed
-*/
-
-#define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
-#define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
-#define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
-#define WORD_BH(zz) bhtab[(zz) >> 5]
-#define UNALIGNED_BH(zz) ((zz) & 0x01f)
-
-static
-void fallbackSort ( UInt32* fmap,
- UInt32* eclass,
- UInt32* bhtab,
- Int32 nblock,
- Int32 verb )
-{
- Int32 ftab[257];
- Int32 ftabCopy[256];
- Int32 H, i, j, k, l, r, cc, cc1;
- Int32 nNotDone;
- Int32 nBhtab;
- UChar* eclass8 = (UChar*)eclass;
-
- /*--
- Initial 1-char radix sort to generate
- initial fmap and initial BH bits.
- --*/
- if (verb >= 4)
- VPrintf0 ( " bucket sorting ...\n" );
- for (i = 0; i < 257; i++) ftab[i] = 0;
- for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
- for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i];
- for (i = 1; i < 257; i++) ftab[i] += ftab[i-1];
-
- for (i = 0; i < nblock; i++) {
- j = eclass8[i];
- k = ftab[j] - 1;
- ftab[j] = k;
- fmap[k] = i;
- }
-
- nBhtab = 2 + (nblock / 32);
- for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
- for (i = 0; i < 256; i++) SET_BH(ftab[i]);
-
- /*--
- Inductively refine the buckets. Kind-of an
- "exponential radix sort" (!), inspired by the
- Manber-Myers suffix array construction algorithm.
- --*/
-
- /*-- set sentinel bits for block-end detection --*/
- for (i = 0; i < 32; i++) {
- SET_BH(nblock + 2*i);
- CLEAR_BH(nblock + 2*i + 1);
- }
-
- /*-- the log(N) loop --*/
- H = 1;
- while (1) {
-
- if (verb >= 4)
- VPrintf1 ( " depth %6d has ", H );
-
- j = 0;
- for (i = 0; i < nblock; i++) {
- if (ISSET_BH(i)) j = i;
- k = fmap[i] - H; if (k < 0) k += nblock;
- eclass[k] = j;
- }
-
- nNotDone = 0;
- r = -1;
- while (1) {
-
- /*-- find the next non-singleton bucket --*/
- k = r + 1;
- while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
- if (ISSET_BH(k)) {
- while (WORD_BH(k) == 0xffffffff) k += 32;
- while (ISSET_BH(k)) k++;
- }
- l = k - 1;
- if (l >= nblock) break;
- while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
- if (!ISSET_BH(k)) {
- while (WORD_BH(k) == 0x00000000) k += 32;
- while (!ISSET_BH(k)) k++;
- }
- r = k - 1;
- if (r >= nblock) break;
-
- /*-- now [l, r] bracket current bucket --*/
- if (r > l) {
- nNotDone += (r - l + 1);
- fallbackQSort3 ( fmap, eclass, l, r );
-
- /*-- scan bucket and generate header bits-- */
- cc = -1;
- for (i = l; i <= r; i++) {
- cc1 = eclass[fmap[i]];
- if (cc != cc1) { SET_BH(i); cc = cc1; };
- }
- }
- }
-
- if (verb >= 4)
- VPrintf1 ( "%6d unresolved strings\n", nNotDone );
-
- H *= 2;
- if (H > nblock || nNotDone == 0) break;
- }
-
- /*--
- Reconstruct the original block in
- eclass8 [0 .. nblock-1], since the
- previous phase destroyed it.
- --*/
- if (verb >= 4)
- VPrintf0 ( " reconstructing block ...\n" );
- j = 0;
- for (i = 0; i < nblock; i++) {
- while (ftabCopy[j] == 0) j++;
- ftabCopy[j]--;
- eclass8[fmap[i]] = (UChar)j;
- }
- AssertH ( j < 256, 1005 );
-}
-
-#undef SET_BH
-#undef CLEAR_BH
-#undef ISSET_BH
-#undef WORD_BH
-#undef UNALIGNED_BH
-
-
-/*---------------------------------------------*/
-/*--- The main, O(N^2 log(N)) sorting ---*/
-/*--- algorithm. Faster for "normal" ---*/
-/*--- non-repetitive blocks. ---*/
-/*---------------------------------------------*/
-
-/*---------------------------------------------*/
-static
-__inline__
-Bool mainGtU ( UInt32 i1,
- UInt32 i2,
- UChar* block,
- UInt16* quadrant,
- UInt32 nblock,
- Int32* budget )
-{
- Int32 k;
- UChar c1, c2;
- UInt16 s1, s2;
-
- AssertD ( i1 != i2, "mainGtU" );
- /* 1 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 2 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 3 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 4 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 5 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 6 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 7 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 8 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 9 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 10 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 11 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 12 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
-
- k = nblock + 8;
-
- do {
- /* 1 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 2 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 3 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 4 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 5 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 6 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 7 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 8 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
-
- if (i1 >= nblock) i1 -= nblock;
- if (i2 >= nblock) i2 -= nblock;
-
- k -= 8;
- (*budget)--;
- }
- while (k >= 0);
-
- return False;
-}
-
-
-/*---------------------------------------------*/
-/*--
- Knuth's increments seem to work better
- than Incerpi-Sedgewick here. Possibly
- because the number of elems to sort is
- usually small, typically <= 20.
---*/
-static
-Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
- 9841, 29524, 88573, 265720,
- 797161, 2391484 };
-
-static
-void mainSimpleSort ( UInt32* ptr,
- UChar* block,
- UInt16* quadrant,
- Int32 nblock,
- Int32 lo,
- Int32 hi,
- Int32 d,
- Int32* budget )
-{
- Int32 i, j, h, bigN, hp;
- UInt32 v;
-
- bigN = hi - lo + 1;
- if (bigN < 2) return;
-
- hp = 0;
- while (incs[hp] < bigN) hp++;
- hp--;
-
- for (; hp >= 0; hp--) {
- h = incs[hp];
-
- i = lo + h;
- while (True) {
-
- /*-- copy 1 --*/
- if (i > hi) break;
- v = ptr[i];
- j = i;
- while ( mainGtU (
- ptr[j-h]+d, v+d, block, quadrant, nblock, budget
- ) ) {
- ptr[j] = ptr[j-h];
- j = j - h;
- if (j <= (lo + h - 1)) break;
- }
- ptr[j] = v;
- i++;
-
- /*-- copy 2 --*/
- if (i > hi) break;
- v = ptr[i];
- j = i;
- while ( mainGtU (
- ptr[j-h]+d, v+d, block, quadrant, nblock, budget
- ) ) {
- ptr[j] = ptr[j-h];
- j = j - h;
- if (j <= (lo + h - 1)) break;
- }
- ptr[j] = v;
- i++;
-
- /*-- copy 3 --*/
- if (i > hi) break;
- v = ptr[i];
- j = i;
- while ( mainGtU (
- ptr[j-h]+d, v+d, block, quadrant, nblock, budget
- ) ) {
- ptr[j] = ptr[j-h];
- j = j - h;
- if (j <= (lo + h - 1)) break;
- }
- ptr[j] = v;
- i++;
-
- if (*budget < 0) return;
- }
- }
-}
-
-
-/*---------------------------------------------*/
-/*--
- The following is an implementation of
- an elegant 3-way quicksort for strings,
- described in a paper "Fast Algorithms for
- Sorting and Searching Strings", by Robert
- Sedgewick and Jon L. Bentley.
---*/
-
-#define mswap(zz1, zz2) \
- { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
-
-#define mvswap(zzp1, zzp2, zzn) \
-{ \
- Int32 yyp1 = (zzp1); \
- Int32 yyp2 = (zzp2); \
- Int32 yyn = (zzn); \
- while (yyn > 0) { \
- mswap(ptr[yyp1], ptr[yyp2]); \
- yyp1++; yyp2++; yyn--; \
- } \
-}
-
-static
-__inline__
-UChar mmed3 ( UChar a, UChar b, UChar c )
-{
- UChar t;
- if (a > b) { t = a; a = b; b = t; };
- if (b > c) {
- b = c;
- if (a > b) b = a;
- }
- return b;
-}
-
-#define mmin(a,b) ((a) < (b)) ? (a) : (b)
-
-#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
- stackHi[sp] = hz; \
- stackD [sp] = dz; \
- sp++; }
-
-#define mpop(lz,hz,dz) { sp--; \
- lz = stackLo[sp]; \
- hz = stackHi[sp]; \
- dz = stackD [sp]; }
-
-
-#define mnextsize(az) (nextHi[az]-nextLo[az])
-
-#define mnextswap(az,bz) \
- { Int32 tz; \
- tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
- tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
- tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
-
-
-#define MAIN_QSORT_SMALL_THRESH 20
-#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
-#define MAIN_QSORT_STACK_SIZE 100
-
-static
-void mainQSort3 ( UInt32* ptr,
- UChar* block,
- UInt16* quadrant,
- Int32 nblock,
- Int32 loSt,
- Int32 hiSt,
- Int32 dSt,
- Int32* budget )
-{
- Int32 unLo, unHi, ltLo, gtHi, n, m, med;
- Int32 sp, lo, hi, d;
-
- Int32 stackLo[MAIN_QSORT_STACK_SIZE];
- Int32 stackHi[MAIN_QSORT_STACK_SIZE];
- Int32 stackD [MAIN_QSORT_STACK_SIZE];
-
- Int32 nextLo[3];
- Int32 nextHi[3];
- Int32 nextD [3];
-
- sp = 0;
- mpush ( loSt, hiSt, dSt );
-
- while (sp > 0) {
-
- AssertH ( sp < MAIN_QSORT_STACK_SIZE, 1001 );
-
- mpop ( lo, hi, d );
- if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
- d > MAIN_QSORT_DEPTH_THRESH) {
- mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
- if (*budget < 0) return;
- continue;
- }
-
- med = (Int32)
- mmed3 ( block[ptr[ lo ]+d],
- block[ptr[ hi ]+d],
- block[ptr[ (lo+hi)>>1 ]+d] );
-
- unLo = ltLo = lo;
- unHi = gtHi = hi;
-
- while (True) {
- while (True) {
- if (unLo > unHi) break;
- n = ((Int32)block[ptr[unLo]+d]) - med;
- if (n == 0) {
- mswap(ptr[unLo], ptr[ltLo]);
- ltLo++; unLo++; continue;
- };
- if (n > 0) break;
- unLo++;
- }
- while (True) {
- if (unLo > unHi) break;
- n = ((Int32)block[ptr[unHi]+d]) - med;
- if (n == 0) {
- mswap(ptr[unHi], ptr[gtHi]);
- gtHi--; unHi--; continue;
- };
- if (n < 0) break;
- unHi--;
- }
- if (unLo > unHi) break;
- mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
- }
-
- AssertD ( unHi == unLo-1, "mainQSort3(2)" );
-
- if (gtHi < ltLo) {
- mpush(lo, hi, d+1 );
- continue;
- }
-
- n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
- m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
-
- n = lo + unLo - ltLo - 1;
- m = hi - (gtHi - unHi) + 1;
-
- nextLo[0] = lo; nextHi[0] = n; nextD[0] = d;
- nextLo[1] = m; nextHi[1] = hi; nextD[1] = d;
- nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
-
- if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
- if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
- if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
-
- AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
- AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
-
- mpush (nextLo[0], nextHi[0], nextD[0]);
- mpush (nextLo[1], nextHi[1], nextD[1]);
- mpush (nextLo[2], nextHi[2], nextD[2]);
- }
-}
-
-#undef mswap
-#undef mvswap
-#undef mpush
-#undef mpop
-#undef mmin
-#undef mnextsize
-#undef mnextswap
-#undef MAIN_QSORT_SMALL_THRESH
-#undef MAIN_QSORT_DEPTH_THRESH
-#undef MAIN_QSORT_STACK_SIZE
-
-
-/*---------------------------------------------*/
-/* Pre:
- nblock > N_OVERSHOOT
- block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
- ((UChar*)block32) [0 .. nblock-1] holds block
- ptr exists for [0 .. nblock-1]
-
- Post:
- ((UChar*)block32) [0 .. nblock-1] holds block
- All other areas of block32 destroyed
- ftab [0 .. 65536 ] destroyed
- ptr [0 .. nblock-1] holds sorted order
- if (*budget < 0), sorting was abandoned
-*/
-
-#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
-#define SETMASK (1 << 21)
-#define CLEARMASK (~(SETMASK))
-
-static
-void mainSort ( UInt32* ptr,
- UChar* block,
- UInt16* quadrant,
- UInt32* ftab,
- Int32 nblock,
- Int32 verb,
- Int32* budget )
-{
- Int32 i, j, k, ss, sb;
- Int32 runningOrder[256];
- Bool bigDone[256];
- Int32 copyStart[256];
- Int32 copyEnd [256];
- UChar c1;
- Int32 numQSorted;
- UInt16 s;
- if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" );
-
- /*-- set up the 2-byte frequency table --*/
- for (i = 65536; i >= 0; i--) ftab[i] = 0;
-
- j = block[0] << 8;
- i = nblock-1;
- for (; i >= 3; i -= 4) {
- quadrant[i] = 0;
- j = (j >> 8) | ( ((UInt16)block[i]) << 8);
- ftab[j]++;
- quadrant[i-1] = 0;
- j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
- ftab[j]++;
- quadrant[i-2] = 0;
- j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
- ftab[j]++;
- quadrant[i-3] = 0;
- j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
- ftab[j]++;
- }
- for (; i >= 0; i--) {
- quadrant[i] = 0;
- j = (j >> 8) | ( ((UInt16)block[i]) << 8);
- ftab[j]++;
- }
-
- /*-- (emphasises close relationship of block & quadrant) --*/
- for (i = 0; i < BZ_N_OVERSHOOT; i++) {
- block [nblock+i] = block[i];
- quadrant[nblock+i] = 0;
- }
-
- if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" );
-
- /*-- Complete the initial radix sort --*/
- for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
-
- s = block[0] << 8;
- i = nblock-1;
- for (; i >= 3; i -= 4) {
- s = (s >> 8) | (block[i] << 8);
- j = ftab[s] -1;
- ftab[s] = j;
- ptr[j] = i;
- s = (s >> 8) | (block[i-1] << 8);
- j = ftab[s] -1;
- ftab[s] = j;
- ptr[j] = i-1;
- s = (s >> 8) | (block[i-2] << 8);
- j = ftab[s] -1;
- ftab[s] = j;
- ptr[j] = i-2;
- s = (s >> 8) | (block[i-3] << 8);
- j = ftab[s] -1;
- ftab[s] = j;
- ptr[j] = i-3;
- }
- for (; i >= 0; i--) {
- s = (s >> 8) | (block[i] << 8);
- j = ftab[s] -1;
- ftab[s] = j;
- ptr[j] = i;
- }
-
- /*--
- Now ftab contains the first loc of every small bucket.
- Calculate the running order, from smallest to largest
- big bucket.
- --*/
- for (i = 0; i <= 255; i++) {
- bigDone [i] = False;
- runningOrder[i] = i;
- }
-
- {
- Int32 vv;
- Int32 h = 1;
- do h = 3 * h + 1; while (h <= 256);
- do {
- h = h / 3;
- for (i = h; i <= 255; i++) {
- vv = runningOrder[i];
- j = i;
- while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
- runningOrder[j] = runningOrder[j-h];
- j = j - h;
- if (j <= (h - 1)) goto zero;
- }
- zero:
- runningOrder[j] = vv;
- }
- } while (h != 1);
- }
-
- /*--
- The main sorting loop.
- --*/
-
- numQSorted = 0;
-
- for (i = 0; i <= 255; i++) {
-
- /*--
- Process big buckets, starting with the least full.
- Basically this is a 3-step process in which we call
- mainQSort3 to sort the small buckets [ss, j], but
- also make a big effort to avoid the calls if we can.
- --*/
- ss = runningOrder[i];
-
- /*--
- Step 1:
- Complete the big bucket [ss] by quicksorting
- any unsorted small buckets [ss, j], for j != ss.
- Hopefully previous pointer-scanning phases have already
- completed many of the small buckets [ss, j], so
- we don't have to sort them at all.
- --*/
- for (j = 0; j <= 255; j++) {
- if (j != ss) {
- sb = (ss << 8) + j;
- if ( ! (ftab[sb] & SETMASK) ) {
- Int32 lo = ftab[sb] & CLEARMASK;
- Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
- if (hi > lo) {
- if (verb >= 4)
- VPrintf4 ( " qsort [0x%x, 0x%x] "
- "done %d this %d\n",
- ss, j, numQSorted, hi - lo + 1 );
- mainQSort3 (
- ptr, block, quadrant, nblock,
- lo, hi, BZ_N_RADIX, budget
- );
- numQSorted += (hi - lo + 1);
- if (*budget < 0) return;
- }
- }
- ftab[sb] |= SETMASK;
- }
- }
-
- AssertH ( !bigDone[ss], 1006 );
-
- /*--
- Step 2:
- Now scan this big bucket [ss] so as to synthesise the
- sorted order for small buckets [t, ss] for all t,
- including, magically, the bucket [ss,ss] too.
- This will avoid doing Real Work in subsequent Step 1's.
- --*/
- {
- for (j = 0; j <= 255; j++) {
- copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK;
- copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
- }
- for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
- k = ptr[j]-1; if (k < 0) k += nblock;
- c1 = block[k];
- if (!bigDone[c1])
- ptr[ copyStart[c1]++ ] = k;
- }
- for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
- k = ptr[j]-1; if (k < 0) k += nblock;
- c1 = block[k];
- if (!bigDone[c1])
- ptr[ copyEnd[c1]-- ] = k;
- }
- }
-
- AssertH ( (copyStart[ss]-1 == copyEnd[ss])
- ||
- /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
- Necessity for this case is demonstrated by compressing
- a sequence of approximately 48.5 million of character
- 251; 1.0.0/1.0.1 will then die here. */
- (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
- 1007 )
-
- for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
-
- /*--
- Step 3:
- The [ss] big bucket is now done. Record this fact,
- and update the quadrant descriptors. Remember to
- update quadrants in the overshoot area too, if
- necessary. The "if (i < 255)" test merely skips
- this updating for the last bucket processed, since
- updating for the last bucket is pointless.
-
- The quadrant array provides a way to incrementally
- cache sort orderings, as they appear, so as to
- make subsequent comparisons in fullGtU() complete
- faster. For repetitive blocks this makes a big
- difference (but not big enough to be able to avoid
- the fallback sorting mechanism, exponential radix sort).
-
- The precise meaning is: at all times:
-
- for 0 <= i < nblock and 0 <= j <= nblock
-
- if block[i] != block[j],
-
- then the relative values of quadrant[i] and
- quadrant[j] are meaningless.
-
- else {
- if quadrant[i] < quadrant[j]
- then the string starting at i lexicographically
- precedes the string starting at j
-
- else if quadrant[i] > quadrant[j]
- then the string starting at j lexicographically
- precedes the string starting at i
-
- else
- the relative ordering of the strings starting
- at i and j has not yet been determined.
- }
- --*/
- bigDone[ss] = True;
-
- if (i < 255) {
- Int32 bbStart = ftab[ss << 8] & CLEARMASK;
- Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
- Int32 shifts = 0;
-
- while ((bbSize >> shifts) > 65534) shifts++;
-
- for (j = bbSize-1; j >= 0; j--) {
- Int32 a2update = ptr[bbStart + j];
- UInt16 qVal = (UInt16)(j >> shifts);
- quadrant[a2update] = qVal;
- if (a2update < BZ_N_OVERSHOOT)
- quadrant[a2update + nblock] = qVal;
- }
- AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
- }
-
- }
-
- if (verb >= 4)
- VPrintf3 ( " %d pointers, %d sorted, %d scanned\n",
- nblock, numQSorted, nblock - numQSorted );
-}
-
-#undef BIGFREQ
-#undef SETMASK
-#undef CLEARMASK
-
-
-/*---------------------------------------------*/
-/* Pre:
- nblock > 0
- arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
- ((UChar*)arr2) [0 .. nblock-1] holds block
- arr1 exists for [0 .. nblock-1]
-
- Post:
- ((UChar*)arr2) [0 .. nblock-1] holds block
- All other areas of block destroyed
- ftab [ 0 .. 65536 ] destroyed
- arr1 [0 .. nblock-1] holds sorted order
-*/
-void BZ2_blockSort ( EState* s )
-{
- UInt32* ptr = s->ptr;
- UChar* block = s->block;
- UInt32* ftab = s->ftab;
- Int32 nblock = s->nblock;
- Int32 verb = s->verbosity;
- Int32 wfact = s->workFactor;
- UInt16* quadrant;
- Int32 budget;
- Int32 budgetInit;
- Int32 i;
-
- if (nblock < /* 10000 */1000 ) {
- fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
- } else {
- /* Calculate the location for quadrant, remembering to get
- the alignment right. Assumes that &(block[0]) is at least
- 2-byte aligned -- this should be ok since block is really
- the first section of arr2.
- */
- i = nblock+BZ_N_OVERSHOOT;
- if (i & 1) i++;
- quadrant = (UInt16*)(&(block[i]));
-
- /* (wfact-1) / 3 puts the default-factor-30
- transition point at very roughly the same place as
- with v0.1 and v0.9.0.
- Not that it particularly matters any more, since the
- resulting compressed stream is now the same regardless
- of whether or not we use the main sort or fallback sort.
- */
- if (wfact < 1 ) wfact = 1;
- if (wfact > 100) wfact = 100;
- budgetInit = nblock * ((wfact-1) / 3);
- budget = budgetInit;
-
- mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
- if (0 && verb >= 3)
- VPrintf3 ( " %d work, %d block, ratio %5.2f\n",
- budgetInit - budget,
- nblock,
- (float)(budgetInit - budget) /
- (float)(nblock==0 ? 1 : nblock) );
- if (budget < 0) {
- if (verb >= 2)
- VPrintf0 ( " too repetitive; using fallback"
- " sorting algorithm\n" );
- fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
- }
- }
-
- s->origPtr = -1;
- for (i = 0; i < s->nblock; i++)
- if (ptr[i] == 0)
- { s->origPtr = i; break; };
-
- AssertH( s->origPtr != -1, 1003 );
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end blocksort.c ---*/
-/*-------------------------------------------------------------*/
-
-/*-------------------------------------------------------------*/
-/*--- Huffman coding low-level stuff ---*/
-/*--- huffman.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2004 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-
-
-/*---------------------------------------------------*/
-#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
-#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
-#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
-
-#define ADDWEIGHTS(zw1,zw2) \
- (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
- (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
-
-#define UPHEAP(z) \
-{ \
- Int32 zz, tmp; \
- zz = z; tmp = heap[zz]; \
- while (weight[tmp] < weight[heap[zz >> 1]]) { \
- heap[zz] = heap[zz >> 1]; \
- zz >>= 1; \
- } \
- heap[zz] = tmp; \
-}
-
-#define DOWNHEAP(z) \
-{ \
- Int32 zz, yy, tmp; \
- zz = z; tmp = heap[zz]; \
- while (True) { \
- yy = zz << 1; \
- if (yy > nHeap) break; \
- if (yy < nHeap && \
- weight[heap[yy+1]] < weight[heap[yy]]) \
- yy++; \
- if (weight[tmp] < weight[heap[yy]]) break; \
- heap[zz] = heap[yy]; \
- zz = yy; \
- } \
- heap[zz] = tmp; \
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_hbMakeCodeLengths ( UChar *len,
- Int32 *freq,
- Int32 alphaSize,
- Int32 maxLen )
-{
- /*--
- Nodes and heap entries run from 1. Entry 0
- for both the heap and nodes is a sentinel.
- --*/
- Int32 nNodes, nHeap, n1, n2, i, j, k;
- Bool tooLong;
-
- Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
- Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
- Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
-
- for (i = 0; i < alphaSize; i++)
- weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
-
- while (True) {
-
- nNodes = alphaSize;
- nHeap = 0;
-
- heap[0] = 0;
- weight[0] = 0;
- parent[0] = -2;
-
- for (i = 1; i <= alphaSize; i++) {
- parent[i] = -1;
- nHeap++;
- heap[nHeap] = i;
- UPHEAP(nHeap);
- }
-
- AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
-
- while (nHeap > 1) {
- n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
- n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
- nNodes++;
- parent[n1] = parent[n2] = nNodes;
- weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
- parent[nNodes] = -1;
- nHeap++;
- heap[nHeap] = nNodes;
- UPHEAP(nHeap);
- }
-
- AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
-
- tooLong = False;
- for (i = 1; i <= alphaSize; i++) {
- j = 0;
- k = i;
- while (parent[k] >= 0) { k = parent[k]; j++; }
- len[i-1] = j;
- if (j > maxLen) tooLong = True;
- }
-
- if (! tooLong) break;
-
- /* 17 Oct 04: keep-going condition for the following loop used
- to be 'i < alphaSize', which missed the last element,
- theoretically leading to the possibility of the compressor
- looping. However, this count-scaling step is only needed if
- one of the generated Huffman code words is longer than
- maxLen, which up to and including version 1.0.2 was 20 bits,
- which is extremely unlikely. In version 1.0.3 maxLen was
- changed to 17 bits, which has minimal effect on compression
- ratio, but does mean this scaling step is used from time to
- time, enough to verify that it works.
-
- This means that bzip2-1.0.3 and later will only produce
- Huffman codes with a maximum length of 17 bits. However, in
- order to preserve backwards compatibility with bitstreams
- produced by versions pre-1.0.3, the decompressor must still
- handle lengths of up to 20. */
-
- for (i = 1; i <= alphaSize; i++) {
- j = weight[i] >> 8;
- j = 1 + (j / 2);
- weight[i] = j << 8;
- }
- }
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_hbAssignCodes ( Int32 *code,
- UChar *length,
- Int32 minLen,
- Int32 maxLen,
- Int32 alphaSize )
-{
- Int32 n, vec, i;
-
- vec = 0;
- for (n = minLen; n <= maxLen; n++) {
- for (i = 0; i < alphaSize; i++)
- if (length[i] == n) { code[i] = vec; vec++; };
- vec <<= 1;
- }
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_hbCreateDecodeTables ( Int32 *limit,
- Int32 *base,
- Int32 *perm,
- UChar *length,
- Int32 minLen,
- Int32 maxLen,
- Int32 alphaSize )
-{
- Int32 pp, i, j, vec;
-
- pp = 0;
- for (i = minLen; i <= maxLen; i++)
- for (j = 0; j < alphaSize; j++)
- if (length[j] == i) { perm[pp] = j; pp++; };
-
- for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
- for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
-
- for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
-
- for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
- vec = 0;
-
- for (i = minLen; i <= maxLen; i++) {
- vec += (base[i+1] - base[i]);
- limit[i] = vec-1;
- vec <<= 1;
- }
- for (i = minLen + 1; i <= maxLen; i++)
- base[i] = ((limit[i-1] + 1) << 1) - base[i];
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end huffman.c ---*/
-/*-------------------------------------------------------------*/
-
-/*-------------------------------------------------------------*/
-/*--- Compression machinery (not incl block sorting) ---*/
-/*--- compress.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2004 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-/*--
- CHANGES
- ~~~~~~~
- 0.9.0 -- original version.
-
- 0.9.0a/b -- no changes in this file.
-
- 0.9.0c
- * changed setting of nGroups in sendMTFValues() so as to
- do a bit better on small files
---*/
-
-
-
-/*---------------------------------------------------*/
-/*--- Bit stream I/O ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-void BZ2_bsInitWrite ( EState* s )
-{
- s->bsLive = 0;
- s->bsBuff = 0;
-}
-
-
-/*---------------------------------------------------*/
-static
-void bsFinishWrite ( EState* s )
-{
- while (s->bsLive > 0) {
- s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
- s->numZ++;
- s->bsBuff <<= 8;
- s->bsLive -= 8;
- }
-}
-
-
-/*---------------------------------------------------*/
-#define bsNEEDW(nz) \
-{ \
- while (s->bsLive >= 8) { \
- s->zbits[s->numZ] \
- = (UChar)(s->bsBuff >> 24); \
- s->numZ++; \
- s->bsBuff <<= 8; \
- s->bsLive -= 8; \
- } \
-}
-
-
-/*---------------------------------------------------*/
-static
-__inline__
-void bsW ( EState* s, Int32 n, UInt32 v )
-{
- bsNEEDW ( n );
- s->bsBuff |= (v << (32 - s->bsLive - n));
- s->bsLive += n;
-}
-
-
-/*---------------------------------------------------*/
-static
-void bsPutUInt32 ( EState* s, UInt32 u )
-{
- bsW ( s, 8, (u >> 24) & 0xffL );
- bsW ( s, 8, (u >> 16) & 0xffL );
- bsW ( s, 8, (u >> 8) & 0xffL );
- bsW ( s, 8, u & 0xffL );
-}
-
-
-/*---------------------------------------------------*/
-static
-void bsPutUChar ( EState* s, UChar c )
-{
- bsW( s, 8, (UInt32)c );
-}
-
-
-/*---------------------------------------------------*/
-/*--- The back end proper ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-static
-void makeMaps_e ( EState* s )
-{
- Int32 i;
- s->nInUse = 0;
- for (i = 0; i < 256; i++)
- if (s->inUse[i]) {
- s->unseqToSeq[i] = s->nInUse;
- s->nInUse++;
- }
-}
-
-
-/*---------------------------------------------------*/
-static
-void generateMTFValues ( EState* s )
-{
- UChar yy[256];
- Int32 i, j;
- Int32 zPend;
- Int32 wr;
- Int32 EOB;
-
- /*
- After sorting (eg, here),
- s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
- and
- ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
- holds the original block data.
-
- The first thing to do is generate the MTF values,
- and put them in
- ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
- Because there are strictly fewer or equal MTF values
- than block values, ptr values in this area are overwritten
- with MTF values only when they are no longer needed.
-
- The final compressed bitstream is generated into the
- area starting at
- (UChar*) (&((UChar*)s->arr2)[s->nblock])
-
- These storage aliases are set up in bzCompressInit(),
- except for the last one, which is arranged in
- compressBlock().
- */
- UInt32* ptr = s->ptr;
- UChar* block = s->block;
- UInt16* mtfv = s->mtfv;
-
- makeMaps_e ( s );
- EOB = s->nInUse+1;
-
- for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
-
- wr = 0;
- zPend = 0;
- for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
-
- for (i = 0; i < s->nblock; i++) {
- UChar ll_i;
- AssertD ( wr <= i, "generateMTFValues(1)" );
- j = ptr[i]-1; if (j < 0) j += s->nblock;
- ll_i = s->unseqToSeq[block[j]];
- AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
-
- if (yy[0] == ll_i) {
- zPend++;
- } else {
-
- if (zPend > 0) {
- zPend--;
- while (True) {
- if (zPend & 1) {
- mtfv[wr] = BZ_RUNB; wr++;
- s->mtfFreq[BZ_RUNB]++;
- } else {
- mtfv[wr] = BZ_RUNA; wr++;
- s->mtfFreq[BZ_RUNA]++;
- }
- if (zPend < 2) break;
- zPend = (zPend - 2) / 2;
- };
- zPend = 0;
- }
- {
- register UChar rtmp;
- register UChar* ryy_j;
- register UChar rll_i;
- rtmp = yy[1];
- yy[1] = yy[0];
- ryy_j = &(yy[1]);
- rll_i = ll_i;
- while ( rll_i != rtmp ) {
- register UChar rtmp2;
- ryy_j++;
- rtmp2 = rtmp;
- rtmp = *ryy_j;
- *ryy_j = rtmp2;
- };
- yy[0] = rtmp;
- j = ryy_j - &(yy[0]);
- mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
- }
-
- }
- }
-
- if (zPend > 0) {
- zPend--;
- while (True) {
- if (zPend & 1) {
- mtfv[wr] = BZ_RUNB; wr++;
- s->mtfFreq[BZ_RUNB]++;
- } else {
- mtfv[wr] = BZ_RUNA; wr++;
- s->mtfFreq[BZ_RUNA]++;
- }
- if (zPend < 2) break;
- zPend = (zPend - 2) / 2;
- };
- zPend = 0;
- }
-
- mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
-
- s->nMTF = wr;
-}
-
-
-/*---------------------------------------------------*/
-#define BZ_LESSER_ICOST 0
-#define BZ_GREATER_ICOST 15
-
-static
-void sendMTFValues ( EState* s )
-{
- Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
- Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
- Int32 nGroups, nBytes;
-
- /*--
- UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- is a global since the decoder also needs it.
-
- Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- are also globals only used in this proc.
- Made global to keep stack frame size small.
- --*/
-
-
- UInt16 cost[BZ_N_GROUPS];
- Int32 fave[BZ_N_GROUPS];
-
- UInt16* mtfv = s->mtfv;
-
- if (s->verbosity >= 3)
- VPrintf3( " %d in block, %d after MTF & 1-2 coding, "
- "%d+2 syms in use\n",
- s->nblock, s->nMTF, s->nInUse );
-
- alphaSize = s->nInUse+2;
- for (t = 0; t < BZ_N_GROUPS; t++)
- for (v = 0; v < alphaSize; v++)
- s->len[t][v] = BZ_GREATER_ICOST;
-
- /*--- Decide how many coding tables to use ---*/
- AssertH ( s->nMTF > 0, 3001 );
- if (s->nMTF < 200) nGroups = 2; else
- if (s->nMTF < 600) nGroups = 3; else
- if (s->nMTF < 1200) nGroups = 4; else
- if (s->nMTF < 2400) nGroups = 5; else
- nGroups = 6;
-
- /*--- Generate an initial set of coding tables ---*/
- {
- Int32 nPart, remF, tFreq, aFreq;
-
- nPart = nGroups;
- remF = s->nMTF;
- gs = 0;
- while (nPart > 0) {
- tFreq = remF / nPart;
- ge = gs-1;
- aFreq = 0;
- while (aFreq < tFreq && ge < alphaSize-1) {
- ge++;
- aFreq += s->mtfFreq[ge];
- }
-
- if (ge > gs
- && nPart != nGroups && nPart != 1
- && ((nGroups-nPart) % 2 == 1)) {
- aFreq -= s->mtfFreq[ge];
- ge--;
- }
-
- if (0 && s->verbosity >= 3)
- VPrintf5( " initial group %d, [%d .. %d], "
- "has %d syms (%4.1f%%)\n",
- nPart, gs, ge, aFreq,
- (100.0 * (float)aFreq) / (float)(s->nMTF) );
-
- for (v = 0; v < alphaSize; v++)
- if (v >= gs && v <= ge)
- s->len[nPart-1][v] = BZ_LESSER_ICOST; else
- s->len[nPart-1][v] = BZ_GREATER_ICOST;
-
- nPart--;
- gs = ge+1;
- remF -= aFreq;
- }
- }
-
- /*---
- Iterate up to BZ_N_ITERS times to improve the tables.
- ---*/
- for (iter = 0; iter < BZ_N_ITERS; iter++) {
-
- for (t = 0; t < nGroups; t++) fave[t] = 0;
-
- for (t = 0; t < nGroups; t++)
- for (v = 0; v < alphaSize; v++)
- s->rfreq[t][v] = 0;
-
- /*---
- Set up an auxiliary length table which is used to fast-track
- the common case (nGroups == 6).
- ---*/
- if (nGroups == 6) {
- for (v = 0; v < alphaSize; v++) {
- s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
- s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
- s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
- }
- }
-
- nSelectors = 0;
- totc = 0;
- gs = 0;
- while (True) {
-
- /*--- Set group start & end marks. --*/
- if (gs >= s->nMTF) break;
- ge = gs + BZ_G_SIZE - 1;
- if (ge >= s->nMTF) ge = s->nMTF-1;
-
- /*--
- Calculate the cost of this group as coded
- by each of the coding tables.
- --*/
- for (t = 0; t < nGroups; t++) cost[t] = 0;
-
- if (nGroups == 6 && 50 == ge-gs+1) {
- /*--- fast track the common case ---*/
- register UInt32 cost01, cost23, cost45;
- register UInt16 icv;
- cost01 = cost23 = cost45 = 0;
-
-# define BZ_ITER(nn) \
- icv = mtfv[gs+(nn)]; \
- cost01 += s->len_pack[icv][0]; \
- cost23 += s->len_pack[icv][1]; \
- cost45 += s->len_pack[icv][2]; \
-
- BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
- BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
- BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
- BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
- BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
- BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
- BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
- BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
- BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
- BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
-
-# undef BZ_ITER
-
- cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
- cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
- cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
-
- } else {
- /*--- slow version which correctly handles all situations ---*/
- for (i = gs; i <= ge; i++) {
- UInt16 icv = mtfv[i];
- for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
- }
- }
-
- /*--
- Find the coding table which is best for this group,
- and record its identity in the selector table.
- --*/
- bc = 999999999; bt = -1;
- for (t = 0; t < nGroups; t++)
- if (cost[t] < bc) { bc = cost[t]; bt = t; };
- totc += bc;
- fave[bt]++;
- s->selector[nSelectors] = bt;
- nSelectors++;
-
- /*--
- Increment the symbol frequencies for the selected table.
- --*/
- if (nGroups == 6 && 50 == ge-gs+1) {
- /*--- fast track the common case ---*/
-
-# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
-
- BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
- BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
- BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
- BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
- BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
- BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
- BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
- BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
- BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
- BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
-
-# undef BZ_ITUR
-
- } else {
- /*--- slow version which correctly handles all situations ---*/
- for (i = gs; i <= ge; i++)
- s->rfreq[bt][ mtfv[i] ]++;
- }
-
- gs = ge+1;
- }
- if (s->verbosity >= 3) {
- VPrintf2 ( " pass %d: size is %d, grp uses are ",
- iter+1, totc/8 );
- for (t = 0; t < nGroups; t++)
- VPrintf1 ( "%d ", fave[t] );
- VPrintf0 ( "\n" );
- }
-
- /*--
- Recompute the tables based on the accumulated frequencies.
- --*/
- /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See
- comment in huffman.c for details. */
- for (t = 0; t < nGroups; t++)
- BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
- alphaSize, 17 /*20*/ );
- }
-
-
- AssertH( nGroups < 8, 3002 );
- AssertH( nSelectors < 32768 &&
- nSelectors <= (2 + (900000 / BZ_G_SIZE)),
- 3003 );
-
-
- /*--- Compute MTF values for the selectors. ---*/
- {
- UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
- for (i = 0; i < nGroups; i++) pos[i] = i;
- for (i = 0; i < nSelectors; i++) {
- ll_i = s->selector[i];
- j = 0;
- tmp = pos[j];
- while ( ll_i != tmp ) {
- j++;
- tmp2 = tmp;
- tmp = pos[j];
- pos[j] = tmp2;
- };
- pos[0] = tmp;
- s->selectorMtf[i] = j;
- }
- };
-
- /*--- Assign actual codes for the tables. --*/
- for (t = 0; t < nGroups; t++) {
- minLen = 32;
- maxLen = 0;
- for (i = 0; i < alphaSize; i++) {
- if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
- if (s->len[t][i] < minLen) minLen = s->len[t][i];
- }
- AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
- AssertH ( !(minLen < 1), 3005 );
- BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
- minLen, maxLen, alphaSize );
- }
-
- /*--- Transmit the mapping table. ---*/
- {
- Bool inUse16[16];
- for (i = 0; i < 16; i++) {
- inUse16[i] = False;
- for (j = 0; j < 16; j++)
- if (s->inUse[i * 16 + j]) inUse16[i] = True;
- }
-
- nBytes = s->numZ;
- for (i = 0; i < 16; i++)
- if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
-
- for (i = 0; i < 16; i++)
- if (inUse16[i])
- for (j = 0; j < 16; j++) {
- if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
- }
-
- if (s->verbosity >= 3)
- VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes );
- }
-
- /*--- Now the selectors. ---*/
- nBytes = s->numZ;
- bsW ( s, 3, nGroups );
- bsW ( s, 15, nSelectors );
- for (i = 0; i < nSelectors; i++) {
- for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
- bsW(s,1,0);
- }
- if (s->verbosity >= 3)
- VPrintf1( "selectors %d, ", s->numZ-nBytes );
-
- /*--- Now the coding tables. ---*/
- nBytes = s->numZ;
-
- for (t = 0; t < nGroups; t++) {
- Int32 curr = s->len[t][0];
- bsW ( s, 5, curr );
- for (i = 0; i < alphaSize; i++) {
- while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
- while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
- bsW ( s, 1, 0 );
- }
- }
-
- if (s->verbosity >= 3)
- VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
-
- /*--- And finally, the block data proper ---*/
- nBytes = s->numZ;
- selCtr = 0;
- gs = 0;
- while (True) {
- if (gs >= s->nMTF) break;
- ge = gs + BZ_G_SIZE - 1;
- if (ge >= s->nMTF) ge = s->nMTF-1;
- AssertH ( s->selector[selCtr] < nGroups, 3006 );
-
- if (nGroups == 6 && 50 == ge-gs+1) {
- /*--- fast track the common case ---*/
- UInt16 mtfv_i;
- UChar* s_len_sel_selCtr
- = &(s->len[s->selector[selCtr]][0]);
- Int32* s_code_sel_selCtr
- = &(s->code[s->selector[selCtr]][0]);
-
-# define BZ_ITAH(nn) \
- mtfv_i = mtfv[gs+(nn)]; \
- bsW ( s, \
- s_len_sel_selCtr[mtfv_i], \
- s_code_sel_selCtr[mtfv_i] )
-
- BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
- BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
- BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
- BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
- BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
- BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
- BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
- BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
- BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
- BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
-
-# undef BZ_ITAH
-
- } else {
- /*--- slow version which correctly handles all situations ---*/
- for (i = gs; i <= ge; i++) {
- bsW ( s,
- s->len [s->selector[selCtr]] [mtfv[i]],
- s->code [s->selector[selCtr]] [mtfv[i]] );
- }
- }
-
-
- gs = ge+1;
- selCtr++;
- }
- AssertH( selCtr == nSelectors, 3007 );
-
- if (s->verbosity >= 3)
- VPrintf1( "codes %d\n", s->numZ-nBytes );
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_compressBlock ( EState* s, Bool is_last_block )
-{
- if (s->nblock > 0) {
-
- BZ_FINALISE_CRC ( s->blockCRC );
- s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
- s->combinedCRC ^= s->blockCRC;
- if (s->blockNo > 1) s->numZ = 0;
-
- if (s->verbosity >= 2)
- VPrintf4( " block %d: crc = 0x%08x, "
- "combined CRC = 0x%08x, size = %d\n",
- s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
-
- BZ2_blockSort ( s );
- }
-
- s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
-
- /*-- If this is the first block, create the stream header. --*/
- if (s->blockNo == 1) {
- BZ2_bsInitWrite ( s );
- bsPutUChar ( s, BZ_HDR_B );
- bsPutUChar ( s, BZ_HDR_Z );
- bsPutUChar ( s, BZ_HDR_h );
- bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
- }
-
- if (s->nblock > 0) {
-
- bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
- bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
- bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
-
- /*-- Now the block's CRC, so it is in a known place. --*/
- bsPutUInt32 ( s, s->blockCRC );
-
- /*--
- Now a single bit indicating (non-)randomisation.
- As of version 0.9.5, we use a better sorting algorithm
- which makes randomisation unnecessary. So always set
- the randomised bit to 'no'. Of course, the decoder
- still needs to be able to handle randomised blocks
- so as to maintain backwards compatibility with
- older versions of bzip2.
- --*/
- bsW(s,1,0);
-
- bsW ( s, 24, s->origPtr );
- generateMTFValues ( s );
- sendMTFValues ( s );
- }
-
-
- /*-- If this is the last block, add the stream trailer. --*/
- if (is_last_block) {
-
- bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
- bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
- bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
- bsPutUInt32 ( s, s->combinedCRC );
- if (s->verbosity >= 2)
- VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC );
- bsFinishWrite ( s );
- }
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end compress.c ---*/
-/*-------------------------------------------------------------*/
-
-
-/*-------------------------------------------------------------*/
-/*--- Table for randomising repetitive blocks ---*/
-/*--- randtable.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2004 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-
-
-
-/*---------------------------------------------*/
-Int32 BZ2_rNums[512] = {
- 619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
- 985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
- 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
- 419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
- 878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
- 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
- 150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
- 170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
- 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
- 909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
- 641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
- 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
- 382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
- 98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
- 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
- 469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
- 184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
- 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
- 951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
- 652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
- 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
- 609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
- 653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
- 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
- 170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
- 857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
- 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
- 944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
- 344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
- 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
- 433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
- 686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
- 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
- 978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
- 680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
- 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
- 297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
- 134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
- 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
- 140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
- 170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
- 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
- 804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
- 896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
- 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
- 768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
- 61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
- 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
- 780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
- 920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
- 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
- 936, 638
-};
-
-
-/*-------------------------------------------------------------*/
-/*--- end randtable.c ---*/
-/*-------------------------------------------------------------*/
-
-/*-------------------------------------------------------------*/
-/*--- Table for doing CRCs ---*/
-/*--- crctable.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2004 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-
-
-
-
-/*--
- I think this is an implementation of the AUTODIN-II,
- Ethernet & FDDI 32-bit CRC standard. Vaguely derived
- from code by Rob Warnock, in Section 51 of the
- comp.compression FAQ.
---*/
-
-UInt32 BZ2_crc32Table[256] = {
-
- /*-- Ugly, innit? --*/
-
- 0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
- 0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
- 0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
- 0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
- 0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
- 0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
- 0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
- 0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
- 0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
- 0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
- 0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
- 0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
- 0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
- 0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
- 0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
- 0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
- 0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
- 0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
- 0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
- 0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
- 0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
- 0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
- 0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
- 0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
- 0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
- 0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
- 0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
- 0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
- 0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
- 0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
- 0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
- 0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
- 0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
- 0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
- 0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
- 0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
- 0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
- 0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
- 0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
- 0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
- 0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
- 0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
- 0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
- 0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
- 0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
- 0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
- 0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
- 0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
- 0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
- 0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
- 0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
- 0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
- 0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
- 0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
- 0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
- 0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
- 0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
- 0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
- 0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
- 0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
- 0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
- 0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
- 0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
- 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
-};
-
-
-/*-------------------------------------------------------------*/
-/*--- end crctable.c ---*/
-/*-------------------------------------------------------------*/
-
-/*-------------------------------------------------------------*/
-/*--- Library top-level functions. ---*/
-/*--- bzlib.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2004 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-/*--
- CHANGES
- ~~~~~~~
- 0.9.0 -- original version.
-
- 0.9.0a/b -- no changes in this file.
-
- 0.9.0c
- * made zero-length BZ_FLUSH work correctly in bzCompress().
- * fixed bzWrite/bzRead to ignore zero-length requests.
- * fixed bzread to correctly handle read requests after EOF.
- * wrong parameter order in call to bzDecompressInit in
- bzBuffToBuffDecompress. Fixed.
---*/
-
-
-
-/*---------------------------------------------------*/
-/*--- Compression stuff ---*/
-/*---------------------------------------------------*/
-
-
-/*---------------------------------------------------*/
-void BZ2_bz__AssertH__fail ( int errcode )
-{
- vexxx_printf("BZ2_bz__AssertH__fail(%d) called, exiting\n", errcode);
- (*serviceFn)(0,0);
-}
-
-void bz_internal_error ( int errcode )
-{
- vexxx_printf("bz_internal_error called, exiting\n", errcode);
- (*serviceFn)(0,0);
-}
-
-/*---------------------------------------------------*/
-static
-int bz_config_ok ( void )
-{
- if (sizeof(int) != 4) return 0;
- if (sizeof(short) != 2) return 0;
- if (sizeof(char) != 1) return 0;
- return 1;
-}
-
-
-/*---------------------------------------------------*/
-static
-void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
-{
- void* v = (void*) (*serviceFn)(2, items * size );
- return v;
-}
-
-static
-void default_bzfree ( void* opaque, void* addr )
-{
- if (addr != NULL) (*serviceFn)( 3, (HWord)addr );
-}
-
-
-/*---------------------------------------------------*/
-static
-void prepare_new_block ( EState* s )
-{
- Int32 i;
- s->nblock = 0;
- s->numZ = 0;
- s->state_out_pos = 0;
- BZ_INITIALISE_CRC ( s->blockCRC );
- for (i = 0; i < 256; i++) s->inUse[i] = False;
- s->blockNo++;
-}
-
-
-/*---------------------------------------------------*/
-static
-void init_RL ( EState* s )
-{
- s->state_in_ch = 256;
- s->state_in_len = 0;
-}
-
-
-static
-Bool isempty_RL ( EState* s )
-{
- if (s->state_in_ch < 256 && s->state_in_len > 0)
- return False; else
- return True;
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompressInit)
- ( bz_stream* strm,
- int blockSize100k,
- int verbosity,
- int workFactor )
-{
- Int32 n;
- EState* s;
-
- if (!bz_config_ok()) return BZ_CONFIG_ERROR;
-
- if (strm == NULL ||
- blockSize100k < 1 || blockSize100k > 9 ||
- workFactor < 0 || workFactor > 250)
- return BZ_PARAM_ERROR;
-
- if (workFactor == 0) workFactor = 30;
- if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
- if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
-
- s = BZALLOC( sizeof(EState) );
- if (s == NULL) return BZ_MEM_ERROR;
- s->strm = strm;
-
- s->arr1 = NULL;
- s->arr2 = NULL;
- s->ftab = NULL;
-
- n = 100000 * blockSize100k;
- s->arr1 = BZALLOC( n * sizeof(UInt32) );
- s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
- s->ftab = BZALLOC( 65537 * sizeof(UInt32) );
-
- if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
- if (s->arr1 != NULL) BZFREE(s->arr1);
- if (s->arr2 != NULL) BZFREE(s->arr2);
- if (s->ftab != NULL) BZFREE(s->ftab);
- if (s != NULL) BZFREE(s);
- return BZ_MEM_ERROR;
- }
-
- s->blockNo = 0;
- s->state = BZ_S_INPUT;
- s->mode = BZ_M_RUNNING;
- s->combinedCRC = 0;
- s->blockSize100k = blockSize100k;
- s->nblockMAX = 100000 * blockSize100k - 19;
- s->verbosity = verbosity;
- s->workFactor = workFactor;
-
- s->block = (UChar*)s->arr2;
- s->mtfv = (UInt16*)s->arr1;
- s->zbits = NULL;
- s->ptr = (UInt32*)s->arr1;
-
- strm->state = s;
- strm->total_in_lo32 = 0;
- strm->total_in_hi32 = 0;
- strm->total_out_lo32 = 0;
- strm->total_out_hi32 = 0;
- init_RL ( s );
- prepare_new_block ( s );
- return BZ_OK;
-}
-
-
-/*---------------------------------------------------*/
-static
-void add_pair_to_block ( EState* s )
-{
- Int32 i;
- UChar ch = (UChar)(s->state_in_ch);
- for (i = 0; i < s->state_in_len; i++) {
- BZ_UPDATE_CRC( s->blockCRC, ch );
- }
- s->inUse[s->state_in_ch] = True;
- switch (s->state_in_len) {
- case 1:
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- break;
- case 2:
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- break;
- case 3:
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- break;
- default:
- s->inUse[s->state_in_len-4] = True;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = ((UChar)(s->state_in_len-4));
- s->nblock++;
- break;
- }
-}
-
-
-/*---------------------------------------------------*/
-static
-void flush_RL ( EState* s )
-{
- if (s->state_in_ch < 256) add_pair_to_block ( s );
- init_RL ( s );
-}
-
-
-/*---------------------------------------------------*/
-#define ADD_CHAR_TO_BLOCK(zs,zchh0) \
-{ \
- UInt32 zchh = (UInt32)(zchh0); \
- /*-- fast track the common case --*/ \
- if (zchh != zs->state_in_ch && \
- zs->state_in_len == 1) { \
- UChar ch = (UChar)(zs->state_in_ch); \
- BZ_UPDATE_CRC( zs->blockCRC, ch ); \
- zs->inUse[zs->state_in_ch] = True; \
- zs->block[zs->nblock] = (UChar)ch; \
- zs->nblock++; \
- zs->state_in_ch = zchh; \
- } \
- else \
- /*-- general, uncommon cases --*/ \
- if (zchh != zs->state_in_ch || \
- zs->state_in_len == 255) { \
- if (zs->state_in_ch < 256) \
- add_pair_to_block ( zs ); \
- zs->state_in_ch = zchh; \
- zs->state_in_len = 1; \
- } else { \
- zs->state_in_len++; \
- } \
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool copy_input_until_stop ( EState* s )
-{
- Bool progress_in = False;
-
- if (s->mode == BZ_M_RUNNING) {
-
- /*-- fast track the common case --*/
- while (True) {
- /*-- block full? --*/
- if (s->nblock >= s->nblockMAX) break;
- /*-- no input? --*/
- if (s->strm->avail_in == 0) break;
- progress_in = True;
- ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
- s->strm->next_in++;
- s->strm->avail_in--;
- s->strm->total_in_lo32++;
- if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
- }
-
- } else {
-
- /*-- general, uncommon case --*/
- while (True) {
- /*-- block full? --*/
- if (s->nblock >= s->nblockMAX) break;
- /*-- no input? --*/
- if (s->strm->avail_in == 0) break;
- /*-- flush/finish end? --*/
- if (s->avail_in_expect == 0) break;
- progress_in = True;
- ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
- s->strm->next_in++;
- s->strm->avail_in--;
- s->strm->total_in_lo32++;
- if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
- s->avail_in_expect--;
- }
- }
- return progress_in;
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool copy_output_until_stop ( EState* s )
-{
- Bool progress_out = False;
-
- while (True) {
-
- /*-- no output space? --*/
- if (s->strm->avail_out == 0) break;
-
- /*-- block done? --*/
- if (s->state_out_pos >= s->numZ) break;
-
- progress_out = True;
- *(s->strm->next_out) = s->zbits[s->state_out_pos];
- s->state_out_pos++;
- s->strm->avail_out--;
- s->strm->next_out++;
- s->strm->total_out_lo32++;
- if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
- }
-
- return progress_out;
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool handle_compress ( bz_stream* strm )
-{
- Bool progress_in = False;
- Bool progress_out = False;
- EState* s = strm->state;
-
- while (True) {
-
- if (s->state == BZ_S_OUTPUT) {
- progress_out |= copy_output_until_stop ( s );
- if (s->state_out_pos < s->numZ) break;
- if (s->mode == BZ_M_FINISHING &&
- s->avail_in_expect == 0 &&
- isempty_RL(s)) break;
- prepare_new_block ( s );
- s->state = BZ_S_INPUT;
- if (s->mode == BZ_M_FLUSHING &&
- s->avail_in_expect == 0 &&
- isempty_RL(s)) break;
- }
-
- if (s->state == BZ_S_INPUT) {
- progress_in |= copy_input_until_stop ( s );
- if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
- flush_RL ( s );
- BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
- s->state = BZ_S_OUTPUT;
- }
- else
- if (s->nblock >= s->nblockMAX) {
- BZ2_compressBlock ( s, False );
- s->state = BZ_S_OUTPUT;
- }
- else
- if (s->strm->avail_in == 0) {
- break;
- }
- }
-
- }
-
- return progress_in || progress_out;
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
-{
- Bool progress;
- EState* s;
- if (strm == NULL) return BZ_PARAM_ERROR;
- s = strm->state;
- if (s == NULL) return BZ_PARAM_ERROR;
- if (s->strm != strm) return BZ_PARAM_ERROR;
-
- preswitch:
- switch (s->mode) {
-
- case BZ_M_IDLE:
- return BZ_SEQUENCE_ERROR;
-
- case BZ_M_RUNNING:
- if (action == BZ_RUN) {
- progress = handle_compress ( strm );
- return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
- }
- else
- if (action == BZ_FLUSH) {
- s->avail_in_expect = strm->avail_in;
- s->mode = BZ_M_FLUSHING;
- goto preswitch;
- }
- else
- if (action == BZ_FINISH) {
- s->avail_in_expect = strm->avail_in;
- s->mode = BZ_M_FINISHING;
- goto preswitch;
- }
- else
- return BZ_PARAM_ERROR;
-
- case BZ_M_FLUSHING:
- if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
- if (s->avail_in_expect != s->strm->avail_in)
- return BZ_SEQUENCE_ERROR;
- progress = handle_compress ( strm );
- if (s->avail_in_expect > 0 || !isempty_RL(s) ||
- s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
- s->mode = BZ_M_RUNNING;
- return BZ_RUN_OK;
-
- case BZ_M_FINISHING:
- if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
- if (s->avail_in_expect != s->strm->avail_in)
- return BZ_SEQUENCE_ERROR;
- progress = handle_compress ( strm );
- if (!progress) return BZ_SEQUENCE_ERROR;
- if (s->avail_in_expect > 0 || !isempty_RL(s) ||
- s->state_out_pos < s->numZ) return BZ_FINISH_OK;
- s->mode = BZ_M_IDLE;
- return BZ_STREAM_END;
- }
- return BZ_OK; /*--not reached--*/
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm )
-{
- EState* s;
- if (strm == NULL) return BZ_PARAM_ERROR;
- s = strm->state;
- if (s == NULL) return BZ_PARAM_ERROR;
- if (s->strm != strm) return BZ_PARAM_ERROR;
-
- if (s->arr1 != NULL) BZFREE(s->arr1);
- if (s->arr2 != NULL) BZFREE(s->arr2);
- if (s->ftab != NULL) BZFREE(s->ftab);
- BZFREE(strm->state);
-
- strm->state = NULL;
-
- return BZ_OK;
-}
-
-
-/*---------------------------------------------------*/
-/*--- Decompression stuff ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompressInit)
- ( bz_stream* strm,
- int verbosity,
- int small )
-{
- DState* s;
-
- if (!bz_config_ok()) return BZ_CONFIG_ERROR;
-
- if (strm == NULL) return BZ_PARAM_ERROR;
- if (small != 0 && small != 1) return BZ_PARAM_ERROR;
- if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
-
- if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
- if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
-
- s = BZALLOC( sizeof(DState) );
- if (s == NULL) return BZ_MEM_ERROR;
- s->strm = strm;
- strm->state = s;
- s->state = BZ_X_MAGIC_1;
- s->bsLive = 0;
- s->bsBuff = 0;
- s->calculatedCombinedCRC = 0;
- strm->total_in_lo32 = 0;
- strm->total_in_hi32 = 0;
- strm->total_out_lo32 = 0;
- strm->total_out_hi32 = 0;
- s->smallDecompress = (Bool)small;
- s->ll4 = NULL;
- s->ll16 = NULL;
- s->tt = NULL;
- s->currBlockNo = 0;
- s->verbosity = verbosity;
-
- return BZ_OK;
-}
-
-
-/*---------------------------------------------------*/
-/* Return True iff data corruption is discovered.
- Returns False if there is no problem.
-*/
-static
-Bool unRLE_obuf_to_output_FAST ( DState* s )
-{
- UChar k1;
-
- if (s->blockRandomised) {
-
- while (True) {
- /* try to finish existing run */
- while (True) {
- if (s->strm->avail_out == 0) return False;
- if (s->state_out_len == 0) break;
- *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
- BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
- s->state_out_len--;
- s->strm->next_out++;
- s->strm->avail_out--;
- s->strm->total_out_lo32++;
- if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
- }
-
- /* can a new run be started? */
- if (s->nblock_used == s->save_nblock+1) return False;
-
- /* Only caused by corrupt data stream? */
- if (s->nblock_used > s->save_nblock+1)
- return True;
-
- s->state_out_len = 1;
- s->state_out_ch = s->k0;
- BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 2;
- BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 3;
- BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- s->state_out_len = ((Int32)k1) + 4;
- BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
- s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
- }
-
- } else {
-
- /* restore */
- UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC;
- UChar c_state_out_ch = s->state_out_ch;
- Int32 c_state_out_len = s->state_out_len;
- Int32 c_nblock_used = s->nblock_used;
- Int32 c_k0 = s->k0;
- UInt32* c_tt = s->tt;
- UInt32 c_tPos = s->tPos;
- char* cs_next_out = s->strm->next_out;
- unsigned int cs_avail_out = s->strm->avail_out;
- /* end restore */
-
- UInt32 avail_out_INIT = cs_avail_out;
- Int32 s_save_nblockPP = s->save_nblock+1;
- unsigned int total_out_lo32_old;
-
- while (True) {
-
- /* try to finish existing run */
- if (c_state_out_len > 0) {
- while (True) {
- if (cs_avail_out == 0) goto return_notr;
- if (c_state_out_len == 1) break;
- *( (UChar*)(cs_next_out) ) = c_state_out_ch;
- BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
- c_state_out_len--;
- cs_next_out++;
- cs_avail_out--;
- }
- s_state_out_len_eq_one:
- {
- if (cs_avail_out == 0) {
- c_state_out_len = 1; goto return_notr;
- };
- *( (UChar*)(cs_next_out) ) = c_state_out_ch;
- BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
- cs_next_out++;
- cs_avail_out--;
- }
- }
- /* Only caused by corrupt data stream? */
- if (c_nblock_used > s_save_nblockPP)
- return True;
-
- /* can a new run be started? */
- if (c_nblock_used == s_save_nblockPP) {
- c_state_out_len = 0; goto return_notr;
- };
- c_state_out_ch = c_k0;
- BZ_GET_FAST_C(k1); c_nblock_used++;
- if (k1 != c_k0) {
- c_k0 = k1; goto s_state_out_len_eq_one;
- };
- if (c_nblock_used == s_save_nblockPP)
- goto s_state_out_len_eq_one;
-
- c_state_out_len = 2;
- BZ_GET_FAST_C(k1); c_nblock_used++;
- if (c_nblock_used == s_save_nblockPP) continue;
- if (k1 != c_k0) { c_k0 = k1; continue; };
-
- c_state_out_len = 3;
- BZ_GET_FAST_C(k1); c_nblock_used++;
- if (c_nblock_used == s_save_nblockPP) continue;
- if (k1 != c_k0) { c_k0 = k1; continue; };
-
- BZ_GET_FAST_C(k1); c_nblock_used++;
- c_state_out_len = ((Int32)k1) + 4;
- BZ_GET_FAST_C(c_k0); c_nblock_used++;
- }
-
- return_notr:
- total_out_lo32_old = s->strm->total_out_lo32;
- s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
- if (s->strm->total_out_lo32 < total_out_lo32_old)
- s->strm->total_out_hi32++;
-
- /* save */
- s->calculatedBlockCRC = c_calculatedBlockCRC;
- s->state_out_ch = c_state_out_ch;
- s->state_out_len = c_state_out_len;
- s->nblock_used = c_nblock_used;
- s->k0 = c_k0;
- s->tt = c_tt;
- s->tPos = c_tPos;
- s->strm->next_out = cs_next_out;
- s->strm->avail_out = cs_avail_out;
- /* end save */
- }
- return False;
-}
-
-
-
-/*---------------------------------------------------*/
-/* Return True iff data corruption is discovered.
- Returns False if there is no problem.
-*/
-static
-Bool unRLE_obuf_to_output_SMALL ( DState* s )
-{
- UChar k1;
-
- if (s->blockRandomised) {
-
- while (True) {
- /* try to finish existing run */
- while (True) {
- if (s->strm->avail_out == 0) return False;
- if (s->state_out_len == 0) break;
- *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
- BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
- s->state_out_len--;
- s->strm->next_out++;
- s->strm->avail_out--;
- s->strm->total_out_lo32++;
- if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
- }
-
- /* can a new run be started? */
- if (s->nblock_used == s->save_nblock+1) return False;
-
- /* Only caused by corrupt data stream? */
- if (s->nblock_used > s->save_nblock+1)
- return True;
-
- s->state_out_len = 1;
- s->state_out_ch = s->k0;
- BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 2;
- BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 3;
- BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- s->state_out_len = ((Int32)k1) + 4;
- BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
- s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
- }
-
- } else {
-
- while (True) {
- /* try to finish existing run */
- while (True) {
- if (s->strm->avail_out == 0) return False;
- if (s->state_out_len == 0) break;
- *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
- BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
- s->state_out_len--;
- s->strm->next_out++;
- s->strm->avail_out--;
- s->strm->total_out_lo32++;
- if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
- }
-
- /* can a new run be started? */
- if (s->nblock_used == s->save_nblock+1) return False;
-
- /* Only caused by corrupt data stream? */
- if (s->nblock_used > s->save_nblock+1)
- return True;
-
- s->state_out_len = 1;
- s->state_out_ch = s->k0;
- BZ_GET_SMALL(k1); s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 2;
- BZ_GET_SMALL(k1); s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 3;
- BZ_GET_SMALL(k1); s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- BZ_GET_SMALL(k1); s->nblock_used++;
- s->state_out_len = ((Int32)k1) + 4;
- BZ_GET_SMALL(s->k0); s->nblock_used++;
- }
-
- }
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
-{
- Bool corrupt;
- DState* s;
- if (strm == NULL) return BZ_PARAM_ERROR;
- s = strm->state;
- if (s == NULL) return BZ_PARAM_ERROR;
- if (s->strm != strm) return BZ_PARAM_ERROR;
-
- while (True) {
- if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
- if (s->state == BZ_X_OUTPUT) {
- if (s->smallDecompress)
- corrupt = unRLE_obuf_to_output_SMALL ( s ); else
- corrupt = unRLE_obuf_to_output_FAST ( s );
- if (corrupt) return BZ_DATA_ERROR;
- if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
- BZ_FINALISE_CRC ( s->calculatedBlockCRC );
- if (s->verbosity >= 3)
- VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
- s->calculatedBlockCRC );
- if (s->verbosity >= 2) VPrintf0 ( "]" );
- if (s->calculatedBlockCRC != s->storedBlockCRC)
- return BZ_DATA_ERROR;
- s->calculatedCombinedCRC
- = (s->calculatedCombinedCRC << 1) |
- (s->calculatedCombinedCRC >> 31);
- s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
- s->state = BZ_X_BLKHDR_1;
- } else {
- return BZ_OK;
- }
- }
- if (s->state >= BZ_X_MAGIC_1) {
- Int32 r = BZ2_decompress ( s );
- if (r == BZ_STREAM_END) {
- if (s->verbosity >= 3)
- VPrintf2 ( "\n combined CRCs: stored = 0x%08x, computed = 0x%08x",
- s->storedCombinedCRC, s->calculatedCombinedCRC );
- if (s->calculatedCombinedCRC != s->storedCombinedCRC)
- return BZ_DATA_ERROR;
- return r;
- }
- if (s->state != BZ_X_OUTPUT) return r;
- }
- }
-
- AssertH ( 0, 6001 );
-
- return 0; /*NOTREACHED*/
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm )
-{
- DState* s;
- if (strm == NULL) return BZ_PARAM_ERROR;
- s = strm->state;
- if (s == NULL) return BZ_PARAM_ERROR;
- if (s->strm != strm) return BZ_PARAM_ERROR;
-
- if (s->tt != NULL) BZFREE(s->tt);
- if (s->ll16 != NULL) BZFREE(s->ll16);
- if (s->ll4 != NULL) BZFREE(s->ll4);
-
- BZFREE(strm->state);
- strm->state = NULL;
-
- return BZ_OK;
-}
-
-
-#ifndef BZ_NO_STDIO
-/*---------------------------------------------------*/
-/*--- File I/O stuff ---*/
-/*---------------------------------------------------*/
-
-#define BZ_SETERR(eee) \
-{ \
- if (bzerror != NULL) *bzerror = eee; \
- if (bzf != NULL) bzf->lastErr = eee; \
-}
-
-typedef
- struct {
- FILE* handle;
- Char buf[BZ_MAX_UNUSED];
- Int32 bufN;
- Bool writing;
- bz_stream strm;
- Int32 lastErr;
- Bool initialisedOk;
- }
- bzFile;
-
-
-/*---------------------------------------------*/
-static Bool myfeof ( FILE* f )
-{
- Int32 c = fgetc ( f );
- if (c == EOF) return True;
- ungetc ( c, f );
- return False;
-}
-
-
-/*---------------------------------------------------*/
-BZFILE* BZ_API(BZ2_bzWriteOpen)
- ( int* bzerror,
- FILE* f,
- int blockSize100k,
- int verbosity,
- int workFactor )
-{
- Int32 ret;
- bzFile* bzf = NULL;
-
- BZ_SETERR(BZ_OK);
-
- if (f == NULL ||
- (blockSize100k < 1 || blockSize100k > 9) ||
- (workFactor < 0 || workFactor > 250) ||
- (verbosity < 0 || verbosity > 4))
- { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
-
- if (ferror(f))
- { BZ_SETERR(BZ_IO_ERROR); return NULL; };
-
- bzf = malloc ( sizeof(bzFile) );
- if (bzf == NULL)
- { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
-
- BZ_SETERR(BZ_OK);
- bzf->initialisedOk = False;
- bzf->bufN = 0;
- bzf->handle = f;
- bzf->writing = True;
- bzf->strm.bzalloc = NULL;
- bzf->strm.bzfree = NULL;
- bzf->strm.opaque = NULL;
-
- if (workFactor == 0) workFactor = 30;
- ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
- verbosity, workFactor );
- if (ret != BZ_OK)
- { BZ_SETERR(ret); free(bzf); return NULL; };
-
- bzf->strm.avail_in = 0;
- bzf->initialisedOk = True;
- return bzf;
-}
-
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzWrite)
- ( int* bzerror,
- BZFILE* b,
- void* buf,
- int len )
-{
- Int32 n, n2, ret;
- bzFile* bzf = (bzFile*)b;
-
- BZ_SETERR(BZ_OK);
- if (bzf == NULL || buf == NULL || len < 0)
- { BZ_SETERR(BZ_PARAM_ERROR); return; };
- if (!(bzf->writing))
- { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
- if (ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return; };
-
- if (len == 0)
- { BZ_SETERR(BZ_OK); return; };
-
- bzf->strm.avail_in = len;
- bzf->strm.next_in = buf;
-
- while (True) {
- bzf->strm.avail_out = BZ_MAX_UNUSED;
- bzf->strm.next_out = bzf->buf;
- ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
- if (ret != BZ_RUN_OK)
- { BZ_SETERR(ret); return; };
-
- if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
- n = BZ_MAX_UNUSED - bzf->strm.avail_out;
- n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
- n, bzf->handle );
- if (n != n2 || ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return; };
- }
-
- if (bzf->strm.avail_in == 0)
- { BZ_SETERR(BZ_OK); return; };
- }
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzWriteClose)
- ( int* bzerror,
- BZFILE* b,
- int abandon,
- unsigned int* nbytes_in,
- unsigned int* nbytes_out )
-{
- BZ2_bzWriteClose64 ( bzerror, b, abandon,
- nbytes_in, NULL, nbytes_out, NULL );
-}
-
-
-void BZ_API(BZ2_bzWriteClose64)
- ( int* bzerror,
- BZFILE* b,
- int abandon,
- unsigned int* nbytes_in_lo32,
- unsigned int* nbytes_in_hi32,
- unsigned int* nbytes_out_lo32,
- unsigned int* nbytes_out_hi32 )
-{
- Int32 n, n2, ret;
- bzFile* bzf = (bzFile*)b;
-
- if (bzf == NULL)
- { BZ_SETERR(BZ_OK); return; };
- if (!(bzf->writing))
- { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
- if (ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return; };
-
- if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
- if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
- if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
- if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
-
- if ((!abandon) && bzf->lastErr == BZ_OK) {
- while (True) {
- bzf->strm.avail_out = BZ_MAX_UNUSED;
- bzf->strm.next_out = bzf->buf;
- ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
- if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
- { BZ_SETERR(ret); return; };
-
- if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
- n = BZ_MAX_UNUSED - bzf->strm.avail_out;
- n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
- n, bzf->handle );
- if (n != n2 || ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return; };
- }
-
- if (ret == BZ_STREAM_END) break;
- }
- }
-
- if ( !abandon && !ferror ( bzf->handle ) ) {
- fflush ( bzf->handle );
- if (ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return; };
- }
-
- if (nbytes_in_lo32 != NULL)
- *nbytes_in_lo32 = bzf->strm.total_in_lo32;
- if (nbytes_in_hi32 != NULL)
- *nbytes_in_hi32 = bzf->strm.total_in_hi32;
- if (nbytes_out_lo32 != NULL)
- *nbytes_out_lo32 = bzf->strm.total_out_lo32;
- if (nbytes_out_hi32 != NULL)
- *nbytes_out_hi32 = bzf->strm.total_out_hi32;
-
- BZ_SETERR(BZ_OK);
- BZ2_bzCompressEnd ( &(bzf->strm) );
- free ( bzf );
-}
-
-
-/*---------------------------------------------------*/
-BZFILE* BZ_API(BZ2_bzReadOpen)
- ( int* bzerror,
- FILE* f,
- int verbosity,
- int small,
- void* unused,
- int nUnused )
-{
- bzFile* bzf = NULL;
- int ret;
-
- BZ_SETERR(BZ_OK);
-
- if (f == NULL ||
- (small != 0 && small != 1) ||
- (verbosity < 0 || verbosity > 4) ||
- (unused == NULL && nUnused != 0) ||
- (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
- { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
-
- if (ferror(f))
- { BZ_SETERR(BZ_IO_ERROR); return NULL; };
-
- bzf = malloc ( sizeof(bzFile) );
- if (bzf == NULL)
- { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
-
- BZ_SETERR(BZ_OK);
-
- bzf->initialisedOk = False;
- bzf->handle = f;
- bzf->bufN = 0;
- bzf->writing = False;
- bzf->strm.bzalloc = NULL;
- bzf->strm.bzfree = NULL;
- bzf->strm.opaque = NULL;
-
- while (nUnused > 0) {
- bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
- unused = ((void*)( 1 + ((UChar*)(unused)) ));
- nUnused--;
- }
-
- ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
- if (ret != BZ_OK)
- { BZ_SETERR(ret); free(bzf); return NULL; };
-
- bzf->strm.avail_in = bzf->bufN;
- bzf->strm.next_in = bzf->buf;
-
- bzf->initialisedOk = True;
- return bzf;
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
-{
- bzFile* bzf = (bzFile*)b;
-
- BZ_SETERR(BZ_OK);
- if (bzf == NULL)
- { BZ_SETERR(BZ_OK); return; };
-
- if (bzf->writing)
- { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
-
- if (bzf->initialisedOk)
- (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
- free ( bzf );
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzRead)
- ( int* bzerror,
- BZFILE* b,
- void* buf,
- int len )
-{
- Int32 n, ret;
- bzFile* bzf = (bzFile*)b;
-
- BZ_SETERR(BZ_OK);
-
- if (bzf == NULL || buf == NULL || len < 0)
- { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
-
- if (bzf->writing)
- { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
-
- if (len == 0)
- { BZ_SETERR(BZ_OK); return 0; };
-
- bzf->strm.avail_out = len;
- bzf->strm.next_out = buf;
-
- while (True) {
-
- if (ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return 0; };
-
- if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
- n = fread ( bzf->buf, sizeof(UChar),
- BZ_MAX_UNUSED, bzf->handle );
- if (ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return 0; };
- bzf->bufN = n;
- bzf->strm.avail_in = bzf->bufN;
- bzf->strm.next_in = bzf->buf;
- }
-
- ret = BZ2_bzDecompress ( &(bzf->strm) );
-
- if (ret != BZ_OK && ret != BZ_STREAM_END)
- { BZ_SETERR(ret); return 0; };
-
- if (ret == BZ_OK && myfeof(bzf->handle) &&
- bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
- { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
-
- if (ret == BZ_STREAM_END)
- { BZ_SETERR(BZ_STREAM_END);
- return len - bzf->strm.avail_out; };
- if (bzf->strm.avail_out == 0)
- { BZ_SETERR(BZ_OK); return len; };
-
- }
-
- return 0; /*not reached*/
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzReadGetUnused)
- ( int* bzerror,
- BZFILE* b,
- void** unused,
- int* nUnused )
-{
- bzFile* bzf = (bzFile*)b;
- if (bzf == NULL)
- { BZ_SETERR(BZ_PARAM_ERROR); return; };
- if (bzf->lastErr != BZ_STREAM_END)
- { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
- if (unused == NULL || nUnused == NULL)
- { BZ_SETERR(BZ_PARAM_ERROR); return; };
-
- BZ_SETERR(BZ_OK);
- *nUnused = bzf->strm.avail_in;
- *unused = bzf->strm.next_in;
-}
-#endif
-
-
-/*---------------------------------------------------*/
-/*--- Misc convenience stuff ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzBuffToBuffCompress)
- ( char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int blockSize100k,
- int verbosity,
- int workFactor )
-{
- bz_stream strm;
- int ret;
-
- if (dest == NULL || destLen == NULL ||
- source == NULL ||
- blockSize100k < 1 || blockSize100k > 9 ||
- verbosity < 0 || verbosity > 4 ||
- workFactor < 0 || workFactor > 250)
- return BZ_PARAM_ERROR;
-
- if (workFactor == 0) workFactor = 30;
- strm.bzalloc = NULL;
- strm.bzfree = NULL;
- strm.opaque = NULL;
- ret = BZ2_bzCompressInit ( &strm, blockSize100k,
- verbosity, workFactor );
- if (ret != BZ_OK) return ret;
-
- strm.next_in = source;
- strm.next_out = dest;
- strm.avail_in = sourceLen;
- strm.avail_out = *destLen;
-
- ret = BZ2_bzCompress ( &strm, BZ_FINISH );
- if (ret == BZ_FINISH_OK) goto output_overflow;
- if (ret != BZ_STREAM_END) goto errhandler;
-
- /* normal termination */
- *destLen -= strm.avail_out;
- BZ2_bzCompressEnd ( &strm );
- return BZ_OK;
-
- output_overflow:
- BZ2_bzCompressEnd ( &strm );
- return BZ_OUTBUFF_FULL;
-
- errhandler:
- BZ2_bzCompressEnd ( &strm );
- return ret;
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzBuffToBuffDecompress)
- ( char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int small,
- int verbosity )
-{
- bz_stream strm;
- int ret;
-
- if (dest == NULL || destLen == NULL ||
- source == NULL ||
- (small != 0 && small != 1) ||
- verbosity < 0 || verbosity > 4)
- return BZ_PARAM_ERROR;
-
- strm.bzalloc = NULL;
- strm.bzfree = NULL;
- strm.opaque = NULL;
- ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
- if (ret != BZ_OK) return ret;
-
- strm.next_in = source;
- strm.next_out = dest;
- strm.avail_in = sourceLen;
- strm.avail_out = *destLen;
-
- ret = BZ2_bzDecompress ( &strm );
- if (ret == BZ_OK) goto output_overflow_or_eof;
- if (ret != BZ_STREAM_END) goto errhandler;
-
- /* normal termination */
- *destLen -= strm.avail_out;
- BZ2_bzDecompressEnd ( &strm );
- return BZ_OK;
-
- output_overflow_or_eof:
- if (strm.avail_out > 0) {
- BZ2_bzDecompressEnd ( &strm );
- return BZ_UNEXPECTED_EOF;
- } else {
- BZ2_bzDecompressEnd ( &strm );
- return BZ_OUTBUFF_FULL;
- };
-
- errhandler:
- BZ2_bzDecompressEnd ( &strm );
- return ret;
-}
-
-
-/*---------------------------------------------------*/
-/*--
- Code contributed by Yoshioka Tsuneo
- (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
- to support better zlib compatibility.
- This code is not _officially_ part of libbzip2 (yet);
- I haven't tested it, documented it, or considered the
- threading-safeness of it.
- If this code breaks, please contact both Yoshioka and me.
---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-/*--
- return version like "0.9.0c".
---*/
-const char * BZ_API(BZ2_bzlibVersion)(void)
-{
- return BZ_VERSION;
-}
-
-
-#ifndef BZ_NO_STDIO
-/*---------------------------------------------------*/
-
-#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
-# include <fcntl.h>
-# include <io.h>
-# define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
-#else
-# define SET_BINARY_MODE(file)
-#endif
-static
-BZFILE * bzopen_or_bzdopen
- ( const char *path, /* no use when bzdopen */
- int fd, /* no use when bzdopen */
- const char *mode,
- int open_mode) /* bzopen: 0, bzdopen:1 */
-{
- int bzerr;
- char unused[BZ_MAX_UNUSED];
- int blockSize100k = 9;
- int writing = 0;
- char mode2[10] = "";
- FILE *fp = NULL;
- BZFILE *bzfp = NULL;
- int verbosity = 0;
- int workFactor = 30;
- int smallMode = 0;
- int nUnused = 0;
-
- if (mode == NULL) return NULL;
- while (*mode) {
- switch (*mode) {
- case 'r':
- writing = 0; break;
- case 'w':
- writing = 1; break;
- case 's':
- smallMode = 1; break;
- default:
- if (isdigit((int)(*mode))) {
- blockSize100k = *mode-BZ_HDR_0;
- }
- }
- mode++;
- }
- strcat(mode2, writing ? "w" : "r" );
- strcat(mode2,"b"); /* binary mode */
-
- if (open_mode==0) {
- if (path==NULL || strcmp(path,"")==0) {
- fp = (writing ? stdout : stdin);
- SET_BINARY_MODE(fp);
- } else {
- fp = fopen(path,mode2);
- }
- } else {
-#ifdef BZ_STRICT_ANSI
- fp = NULL;
-#else
- fp = fdopen(fd,mode2);
-#endif
- }
- if (fp == NULL) return NULL;
-
- if (writing) {
- /* Guard against total chaos and anarchy -- JRS */
- if (blockSize100k < 1) blockSize100k = 1;
- if (blockSize100k > 9) blockSize100k = 9;
- bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
- verbosity,workFactor);
- } else {
- bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
- unused,nUnused);
- }
- if (bzfp == NULL) {
- if (fp != stdin && fp != stdout) fclose(fp);
- return NULL;
- }
- return bzfp;
-}
-
-
-/*---------------------------------------------------*/
-/*--
- open file for read or write.
- ex) bzopen("file","w9")
- case path="" or NULL => use stdin or stdout.
---*/
-BZFILE * BZ_API(BZ2_bzopen)
- ( const char *path,
- const char *mode )
-{
- return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
-}
-
-
-/*---------------------------------------------------*/
-BZFILE * BZ_API(BZ2_bzdopen)
- ( int fd,
- const char *mode )
-{
- return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
-{
- int bzerr, nread;
- if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
- nread = BZ2_bzRead(&bzerr,b,buf,len);
- if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
- return nread;
- } else {
- return -1;
- }
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
-{
- int bzerr;
-
- BZ2_bzWrite(&bzerr,b,buf,len);
- if(bzerr == BZ_OK){
- return len;
- }else{
- return -1;
- }
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzflush) (BZFILE *b)
-{
- /* do nothing now... */
- return 0;
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzclose) (BZFILE* b)
-{
- int bzerr;
- FILE *fp = ((bzFile *)b)->handle;
-
- if (b==NULL) {return;}
- if(((bzFile*)b)->writing){
- BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
- if(bzerr != BZ_OK){
- BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
- }
- }else{
- BZ2_bzReadClose(&bzerr,b);
- }
- if(fp!=stdin && fp!=stdout){
- fclose(fp);
- }
-}
-
-
-/*---------------------------------------------------*/
-/*--
- return last error code
---*/
-static char *bzerrorstrings[] = {
- "OK"
- ,"SEQUENCE_ERROR"
- ,"PARAM_ERROR"
- ,"MEM_ERROR"
- ,"DATA_ERROR"
- ,"DATA_ERROR_MAGIC"
- ,"IO_ERROR"
- ,"UNEXPECTED_EOF"
- ,"OUTBUFF_FULL"
- ,"CONFIG_ERROR"
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
-};
-
-
-const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
-{
- int err = ((bzFile *)b)->lastErr;
-
- if(err>0) err = 0;
- *errnum = err;
- return bzerrorstrings[err*-1];
-}
-#endif
-
-
-/*-------------------------------------------------------------*/
-/*--- end bzlib.c ---*/
-/*-------------------------------------------------------------*/
-
-
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-
-
-/* A test program written to test robustness to decompression of
- corrupted data. Usage is
- unzcrash filename
- and the program will read the specified file, compress it (in memory),
- and then repeatedly decompress it, each time with a different bit of
- the compressed data inverted, so as to test all possible one-bit errors.
- This should not cause any invalid memory accesses. If it does,
- I want to know about it!
-
- p.s. As you can see from the above description, the process is
- incredibly slow. A file of size eg 5KB will cause it to run for
- many hours.
-*/
-
-//#include <stdio.h>
-//#include <assert.h>
-//#include "bzlib.h"
-
-#define M_BLOCK 1000000
-
-typedef unsigned char uchar;
-
-#define M_BLOCK_OUT (M_BLOCK + 1000000)
-uchar inbuf[M_BLOCK];
-uchar outbuf[M_BLOCK_OUT];
-uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];
-
-int nIn, nOut, nZ;
-
-static char *bzerrorstrings[] = {
- "OK"
- ,"SEQUENCE_ERROR"
- ,"PARAM_ERROR"
- ,"MEM_ERROR"
- ,"DATA_ERROR"
- ,"DATA_ERROR_MAGIC"
- ,"IO_ERROR"
- ,"UNEXPECTED_EOF"
- ,"OUTBUFF_FULL"
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
-};
-
-void flip_bit ( int bit )
-{
- int byteno = bit / 8;
- int bitno = bit % 8;
- uchar mask = 1 << bitno;
- //fprintf ( stderr, "(byte %d bit %d mask %d)",
- // byteno, bitno, (int)mask );
- zbuf[byteno] ^= mask;
-}
-
-void set_inbuf ( void )
-{
- inbuf[0] = 0;
- my_strcat(inbuf, "At her sixtieth birthday party, Margaret Thatcher ");
- my_strcat(inbuf, "blew on the cake to light the candles.\n");
- my_strcat(inbuf, "This program, bzip2, the associated library libbzip2, and all\n");
- my_strcat(inbuf, "documentation, are copyright (C) 1996-2004 Julian R Seward. All\n");
- my_strcat(inbuf, "rights reserved.\n");
- my_strcat(inbuf, "\n");
- my_strcat(inbuf, "Redistribution and use in source and binary forms, with or without\n");
- my_strcat(inbuf, "modification, are permitted provided that the following conditions\n");
- my_strcat(inbuf, "are met:\n");
- my_strcat(inbuf, "\n");
- my_strcat(inbuf, "1. Redistributions of source code must retain the above copyright\n");
- my_strcat(inbuf, " notice, this list of conditions and the following disclaimer.\n");
- my_strcat(inbuf, "\n");
- my_strcat(inbuf, "2. The origin of this software must not be misrepresented; you must\n");
- my_strcat(inbuf, " not claim that you wrote the original software. If you use this\n");
- my_strcat(inbuf, " software in a product, an acknowledgment in the product\n");
- my_strcat(inbuf, " documentation would be appreciated but is not required.\n");
- my_strcat(inbuf, "\n");
- my_strcat(inbuf, "3. Altered source versions must be plainly marked as such, and must\n");
- my_strcat(inbuf, " not be misrepresented as being the original software.\n");
- my_strcat(inbuf, "\n");
- my_strcat(inbuf, "4. The name of the author may not be used to endorse or promote\n");
- my_strcat(inbuf, " products derived from this software without specific prior written\n");
- my_strcat(inbuf, " permission.\n");
- my_strcat(inbuf, "\n");
- my_strcat(inbuf, "THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS\n");
- my_strcat(inbuf, "OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n");
- my_strcat(inbuf, "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n");
- my_strcat(inbuf, "ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n");
- my_strcat(inbuf, "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n");
- my_strcat(inbuf, "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n");
- my_strcat(inbuf, "GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n");
- my_strcat(inbuf, "INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n");
- my_strcat(inbuf, "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n");
- my_strcat(inbuf, "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n");
- my_strcat(inbuf, "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
- my_strcat(inbuf, "\n");
-}
-
-
-void entry ( HWord(*service)(HWord,HWord) )
-{
- int r;
- int bit;
- int i;
-
- serviceFn = service;
-
- set_inbuf();
- nIn = vexxx_strlen(inbuf)+1;
- vexxx_printf( "%d bytes read\n", nIn );
-
- nZ = M_BLOCK;
- r = BZ2_bzBuffToBuffCompress (
- zbuf, &nZ, inbuf, nIn, 9, 4/*verb*/, 30 );
-
- if (r != BZ_OK) {
- vexxx_printf("initial compress failed!\n");
- (*serviceFn)(0,0);
- }
- vexxx_printf( "%d after compression\n", nZ );
-
- for (bit = 0; bit < nZ*8; bit += (bit < 35 ? 1 : 377)) {
- vexxx_printf( "bit %d ", bit );
- flip_bit ( bit );
- nOut = M_BLOCK_OUT;
- r = BZ2_bzBuffToBuffDecompress (
- outbuf, &nOut, zbuf, nZ, 1/*small*/, 0 );
- vexxx_printf( " %d %s ", r, bzerrorstrings[-r] );
-
- if (r != BZ_OK) {
- vexxx_printf( "\n" );
- } else {
- if (nOut != nIn) {
- vexxx_printf( "nIn/nOut mismatch %d %d\n", nIn, nOut );
- (*serviceFn)(0,0);
- } else {
- for (i = 0; i < nOut; i++)
- if (inbuf[i] != outbuf[i]) {
- vexxx_printf( "mismatch at %d\n", i );
- (*serviceFn)(0,0);
- }
- if (i == nOut) vexxx_printf( "really ok!\n" );
- }
- }
-
- flip_bit ( bit );
- }
-
-#if 0
- assert (nOut == nIn);
- for (i = 0; i < nOut; i++) {
- if (inbuf[i] != outbuf[i]) {
- vexxx_printf( "difference at %d !\n", i );
- return 1;
- }
- }
-#endif
-
- vexxx_printf( "all ok\n" );
- (*serviceFn)(0,0);
-}
+++ /dev/null
-/*
-** emfloat.c
-** Source for emulated floating-point routines.
-** BYTEmark (tm)
-** BYTE's Native Mode Benchmarks
-** Rick Grehan, BYTE Magazine.
-**
-** Created:
-** Last update: 3/95
-**
-** DISCLAIMER
-** The source, executable, and documentation files that comprise
-** the BYTEmark benchmarks are made available on an "as is" basis.
-** This means that we at BYTE Magazine have made every reasonable
-** effort to verify that the there are no errors in the source and
-** executable code. We cannot, however, guarantee that the programs
-** are error-free. Consequently, McGraw-HIll and BYTE Magazine make
-** no claims in regard to the fitness of the source code, executable
-** code, and documentation of the BYTEmark.
-** Furthermore, BYTE Magazine, McGraw-Hill, and all employees
-** of McGraw-Hill cannot be held responsible for any damages resulting
-** from the use of this code or the results obtained from using
-** this code.
-*/
-
-#include "../pub/libvex_basictypes.h"
-
-static HWord (*serviceFn)(HWord,HWord) = 0;
-
-
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-
-static char* my_strcpy ( char* dest, const char* src )
-{
- char* dest_orig = dest;
- while (*src) *dest++ = *src++;
- *dest = 0;
- return dest_orig;
-}
-
-static void* my_memcpy ( void *dest, const void *src, int sz )
-{
- const char *s = (const char *)src;
- char *d = (char *)dest;
-
- while (sz--)
- *d++ = *s++;
-
- return dest;
-}
-
-static void* my_memmove( void *dst, const void *src, unsigned int len )
-{
- register char *d;
- register char *s;
- if ( dst > src ) {
- d = (char *)dst + len - 1;
- s = (char *)src + len - 1;
- while ( len >= 4 ) {
- *d-- = *s--;
- *d-- = *s--;
- *d-- = *s--;
- *d-- = *s--;
- len -= 4;
- }
- while ( len-- ) {
- *d-- = *s--;
- }
- } else if ( dst < src ) {
- d = (char *)dst;
- s = (char *)src;
- while ( len >= 4 ) {
- *d++ = *s++;
- *d++ = *s++;
- *d++ = *s++;
- *d++ = *s++;
- len -= 4;
- }
- while ( len-- ) {
- *d++ = *s++;
- }
- }
- return dst;
-}
-
-/////////////////////////////////////////////////////////////////////
-
-static void vexxx_log_bytes ( char* p, int n )
-{
- int i;
- for (i = 0; i < n; i++)
- (*serviceFn)( 1, (int)p[i] );
-}
-
-/*---------------------------------------------------------*/
-/*--- vexxx_printf ---*/
-/*---------------------------------------------------------*/
-
-/* This should be the only <...> include in the entire VEXXX library.
- New code for vexxx_util.c should go above this point. */
-#include <stdarg.h>
-
-static HChar vexxx_toupper ( HChar c )
-{
- if (c >= 'a' && c <= 'z')
- return toHChar(c + ('A' - 'a'));
- else
- return c;
-}
-
-static Int vexxx_strlen ( const HChar* str )
-{
- Int i = 0;
- while (str[i] != 0) i++;
- return i;
-}
-
-Bool vexxx_streq ( const HChar* s1, const HChar* s2 )
-{
- while (True) {
- if (*s1 == 0 && *s2 == 0)
- return True;
- if (*s1 != *s2)
- return False;
- s1++;
- s2++;
- }
-}
-
-/* Some flags. */
-#define VG_MSG_SIGNED 1 /* The value is signed. */
-#define VG_MSG_ZJUSTIFY 2 /* Must justify with '0'. */
-#define VG_MSG_LJUSTIFY 4 /* Must justify on the left. */
-#define VG_MSG_PAREN 8 /* Parenthesize if present (for %y) */
-#define VG_MSG_COMMA 16 /* Add commas to numbers (for %d, %u) */
-
-/* Copy a string into the buffer. */
-static UInt
-myvprintf_str ( void(*send)(HChar), Int flags, Int width, HChar* str,
- Bool capitalise )
-{
-# define MAYBE_TOUPPER(ch) toHChar(capitalise ? vexxx_toupper(ch) : (ch))
- UInt ret = 0;
- Int i, extra;
- Int len = vexxx_strlen(str);
-
- if (width == 0) {
- ret += len;
- for (i = 0; i < len; i++)
- send(MAYBE_TOUPPER(str[i]));
- return ret;
- }
-
- if (len > width) {
- ret += width;
- for (i = 0; i < width; i++)
- send(MAYBE_TOUPPER(str[i]));
- return ret;
- }
-
- extra = width - len;
- if (flags & VG_MSG_LJUSTIFY) {
- ret += extra;
- for (i = 0; i < extra; i++)
- send(' ');
- }
- ret += len;
- for (i = 0; i < len; i++)
- send(MAYBE_TOUPPER(str[i]));
- if (!(flags & VG_MSG_LJUSTIFY)) {
- ret += extra;
- for (i = 0; i < extra; i++)
- send(' ');
- }
-
-# undef MAYBE_TOUPPER
-
- return ret;
-}
-
-/* Write P into the buffer according to these args:
- * If SIGN is true, p is a signed.
- * BASE is the base.
- * If WITH_ZERO is true, '0' must be added.
- * WIDTH is the width of the field.
- */
-static UInt
-myvprintf_int64 ( void(*send)(HChar), Int flags, Int base, Int width, ULong pL)
-{
- HChar buf[40];
- Int ind = 0;
- Int i, nc = 0;
- Bool neg = False;
- HChar *digits = "0123456789ABCDEF";
- UInt ret = 0;
- UInt p = (UInt)pL;
-
- if (base < 2 || base > 16)
- return ret;
-
- if ((flags & VG_MSG_SIGNED) && (Int)p < 0) {
- p = - (Int)p;
- neg = True;
- }
-
- if (p == 0)
- buf[ind++] = '0';
- else {
- while (p > 0) {
- if ((flags & VG_MSG_COMMA) && 10 == base &&
- 0 == (ind-nc) % 3 && 0 != ind)
- {
- buf[ind++] = ',';
- nc++;
- }
- buf[ind++] = digits[p % base];
- p /= base;
- }
- }
-
- if (neg)
- buf[ind++] = '-';
-
- if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) {
- for(; ind < width; ind++) {
- //vassert(ind < 39);
- buf[ind] = toHChar((flags & VG_MSG_ZJUSTIFY) ? '0': ' ');
- }
- }
-
- /* Reverse copy to buffer. */
- ret += ind;
- for (i = ind -1; i >= 0; i--) {
- send(buf[i]);
- }
- if (width > 0 && (flags & VG_MSG_LJUSTIFY)) {
- for(; ind < width; ind++) {
- ret++;
- send(' '); // Never pad with zeroes on RHS -- changes the value!
- }
- }
- return ret;
-}
-
-
-/* A simple vprintf(). */
-static
-UInt vprintf_wrk ( void(*send)(HChar), const HChar *format, va_list vargs )
-{
- UInt ret = 0;
- int i;
- int flags;
- int width;
- Bool is_long;
-
- /* We assume that vargs has already been initialised by the
- caller, using va_start, and that the caller will similarly
- clean up with va_end.
- */
-
- for (i = 0; format[i] != 0; i++) {
- if (format[i] != '%') {
- send(format[i]);
- ret++;
- continue;
- }
- i++;
- /* A '%' has been found. Ignore a trailing %. */
- if (format[i] == 0)
- break;
- if (format[i] == '%') {
- /* `%%' is replaced by `%'. */
- send('%');
- ret++;
- continue;
- }
- flags = 0;
- is_long = False;
- width = 0; /* length of the field. */
- if (format[i] == '(') {
- flags |= VG_MSG_PAREN;
- i++;
- }
- /* If ',' follows '%', commas will be inserted. */
- if (format[i] == ',') {
- flags |= VG_MSG_COMMA;
- i++;
- }
- /* If '-' follows '%', justify on the left. */
- if (format[i] == '-') {
- flags |= VG_MSG_LJUSTIFY;
- i++;
- }
- /* If '0' follows '%', pads will be inserted. */
- if (format[i] == '0') {
- flags |= VG_MSG_ZJUSTIFY;
- i++;
- }
- /* Compute the field length. */
- while (format[i] >= '0' && format[i] <= '9') {
- width *= 10;
- width += format[i++] - '0';
- }
- while (format[i] == 'l') {
- i++;
- is_long = True;
- }
-
- switch (format[i]) {
- case 'd': /* %d */
- flags |= VG_MSG_SIGNED;
- if (is_long)
- ret += myvprintf_int64(send, flags, 10, width,
- (ULong)(va_arg (vargs, Long)));
- else
- ret += myvprintf_int64(send, flags, 10, width,
- (ULong)(va_arg (vargs, Int)));
- break;
- case 'u': /* %u */
- if (is_long)
- ret += myvprintf_int64(send, flags, 10, width,
- (ULong)(va_arg (vargs, ULong)));
- else
- ret += myvprintf_int64(send, flags, 10, width,
- (ULong)(va_arg (vargs, UInt)));
- break;
- case 'p': /* %p */
- ret += 2;
- send('0');
- send('x');
- ret += myvprintf_int64(send, flags, 16, width,
- (ULong)((HWord)va_arg (vargs, void *)));
- break;
- case 'x': /* %x */
- if (is_long)
- ret += myvprintf_int64(send, flags, 16, width,
- (ULong)(va_arg (vargs, ULong)));
- else
- ret += myvprintf_int64(send, flags, 16, width,
- (ULong)(va_arg (vargs, UInt)));
- break;
- case 'c': /* %c */
- ret++;
- send(toHChar(va_arg (vargs, int)));
- break;
- case 's': case 'S': { /* %s */
- char *str = va_arg (vargs, char *);
- if (str == (char*) 0) str = "(null)";
- ret += myvprintf_str(send, flags, width, str,
- toBool(format[i]=='S'));
- break;
- }
-# if 0
- case 'y': { /* %y - print symbol */
- Addr a = va_arg(vargs, Addr);
-
- HChar *name;
- if (VG_(get_fnname_w_offset)(a, &name)) {
- HChar buf[1 + VG_strlen(name) + 1 + 1];
- if (flags & VG_MSG_PAREN) {
- VG_(sprintf)(str, "(%s)", name):
- } else {
- VG_(sprintf)(str, "%s", name):
- }
- ret += myvprintf_str(send, flags, width, buf, 0);
- }
- break;
- }
-# endif
- default:
- break;
- }
- }
- return ret;
-}
-
-
-/* A general replacement for printf(). Note that only low-level
- debugging info should be sent via here. The official route is to
- to use vg_message(). This interface is deprecated.
-*/
-static HChar myprintf_buf[1000];
-static Int n_myprintf_buf;
-
-static void add_to_myprintf_buf ( HChar c )
-{
- if (c == '\n' || n_myprintf_buf >= 1000-10 /*paranoia*/ ) {
- (*vexxx_log_bytes)( myprintf_buf, vexxx_strlen(myprintf_buf) );
- n_myprintf_buf = 0;
- myprintf_buf[n_myprintf_buf] = 0;
- }
- myprintf_buf[n_myprintf_buf++] = c;
- myprintf_buf[n_myprintf_buf] = 0;
-}
-
-static UInt vexxx_printf ( const char *format, ... )
-{
- UInt ret;
- va_list vargs;
- va_start(vargs,format);
-
- n_myprintf_buf = 0;
- myprintf_buf[n_myprintf_buf] = 0;
- ret = vprintf_wrk ( add_to_myprintf_buf, format, vargs );
-
- if (n_myprintf_buf > 0) {
- (*vexxx_log_bytes)( myprintf_buf, n_myprintf_buf );
- }
-
- va_end(vargs);
-
- return ret;
-}
-
-/*---------------------------------------------------------------*/
-/*--- end vexxx_util.c ---*/
-/*---------------------------------------------------------------*/
-
-
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-
-//#include <stdio.h>
-//#include <string.h>
-//#include <malloc.h>
-
-typedef unsigned char uchar;
-typedef unsigned int uint;
-typedef unsigned short ushort;
-typedef unsigned long ulong;
-typedef int int32; /* Signed 32 bit integer */
-
-#define INTERNAL_FPF_PRECISION 4
-#define CPUEMFLOATLOOPMAX 500000L
-#define EMFARRAYSIZE 3000L
-
-typedef struct {
- int adjust; /* Set adjust code */
- ulong request_secs; /* # of seconds requested */
- ulong arraysize; /* Size of array */
- ulong loops; /* Loops per iterations */
- double emflops; /* Results */
-} EmFloatStruct;
-
-
-
-/* Is this a 64 bit architecture? If so, this will define LONG64 */
-/* Uwe F. Mayer 15 November 1997 */
-// #include "pointer.h"
-
-#define u8 unsigned char
-#define u16 unsigned short
-#ifdef LONG64
-#define u32 unsigned int
-#else
-#define u32 unsigned long
-#endif
-#define uchar unsigned char
-#define ulong unsigned long
-
-#define MAX_EXP 32767L
-#define MIN_EXP (-32767L)
-
-#define IFPF_IS_ZERO 0
-#define IFPF_IS_SUBNORMAL 1
-#define IFPF_IS_NORMAL 2
-#define IFPF_IS_INFINITY 3
-#define IFPF_IS_NAN 4
-#define IFPF_TYPE_COUNT 5
-
-#define ZERO_ZERO 0
-#define ZERO_SUBNORMAL 1
-#define ZERO_NORMAL 2
-#define ZERO_INFINITY 3
-#define ZERO_NAN 4
-
-#define SUBNORMAL_ZERO 5
-#define SUBNORMAL_SUBNORMAL 6
-#define SUBNORMAL_NORMAL 7
-#define SUBNORMAL_INFINITY 8
-#define SUBNORMAL_NAN 9
-
-#define NORMAL_ZERO 10
-#define NORMAL_SUBNORMAL 11
-#define NORMAL_NORMAL 12
-#define NORMAL_INFINITY 13
-#define NORMAL_NAN 14
-
-#define INFINITY_ZERO 15
-#define INFINITY_SUBNORMAL 16
-#define INFINITY_NORMAL 17
-#define INFINITY_INFINITY 18
-#define INFINITY_NAN 19
-
-#define NAN_ZERO 20
-#define NAN_SUBNORMAL 21
-#define NAN_NORMAL 22
-#define NAN_INFINITY 23
-#define NAN_NAN 24
-#define OPERAND_ZERO 0
-#define OPERAND_SUBNORMAL 1
-#define OPERAND_NORMAL 2
-#define OPERAND_INFINITY 3
-#define OPERAND_NAN 4
-
-typedef struct
-{
- u8 type; /* Indicates, NORMAL, SUBNORMAL, etc. */
- u8 sign; /* Mantissa sign */
- short exp; /* Signed exponent...no bias */
- u16 mantissa[INTERNAL_FPF_PRECISION];
-} InternalFPF;
-
-static
-void SetupCPUEmFloatArrays(InternalFPF *abase,
- InternalFPF *bbase, InternalFPF *cbase, ulong arraysize);
-static
-ulong DoEmFloatIteration(InternalFPF *abase,
- InternalFPF *bbase, InternalFPF *cbase,
- ulong arraysize, ulong loops);
-
-static void SetInternalFPFZero(InternalFPF *dest,
- uchar sign);
-static void SetInternalFPFInfinity(InternalFPF *dest,
- uchar sign);
-static void SetInternalFPFNaN(InternalFPF *dest);
-static int IsMantissaZero(u16 *mant);
-static void Add16Bits(u16 *carry,u16 *a,u16 b,u16 c);
-static void Sub16Bits(u16 *borrow,u16 *a,u16 b,u16 c);
-static void ShiftMantLeft1(u16 *carry,u16 *mantissa);
-static void ShiftMantRight1(u16 *carry,u16 *mantissa);
-static void StickyShiftRightMant(InternalFPF *ptr,int amount);
-static void normalize(InternalFPF *ptr);
-static void denormalize(InternalFPF *ptr,int minimum_exponent);
-static void RoundInternalFPF(InternalFPF *ptr);
-static void choose_nan(InternalFPF *x,InternalFPF *y,InternalFPF *z,
- int intel_flag);
-static void AddSubInternalFPF(uchar operation,InternalFPF *x,
- InternalFPF *y,InternalFPF *z);
-static void MultiplyInternalFPF(InternalFPF *x,InternalFPF *y,
- InternalFPF *z);
-static void DivideInternalFPF(InternalFPF *x,InternalFPF *y,
- InternalFPF *z);
-
-static void Int32ToInternalFPF(int32 mylong,
- InternalFPF *dest);
-static int InternalFPFToString(char *dest,
- InternalFPF *src);
-
-static int32 randnum(int32 lngval);
-
-static int32 randwc(int32 num)
-{
- return(randnum((int32)0)%num);
-}
-
-static int32 randw[2] = { (int32)13 , (int32)117 };
-static int32 randnum(int32 lngval)
-{
- register int32 interm;
-
- if (lngval!=(int32)0)
- { randw[0]=(int32)13; randw[1]=(int32)117; }
-
- interm=(randw[0]*(int32)254754+randw[1]*(int32)529562)%(int32)999563;
- randw[1]=randw[0];
- randw[0]=interm;
- return(interm);
-}
-
-
-static
-void SetupCPUEmFloatArrays(InternalFPF *abase,
- InternalFPF *bbase,
- InternalFPF *cbase,
- ulong arraysize)
-{
-ulong i;
-InternalFPF locFPF1,locFPF2;
-
-randnum((int32)13);
-
-for(i=0;i<arraysize;i++)
-{/* LongToInternalFPF(randwc(50000L),&locFPF1); */
- Int32ToInternalFPF(randwc((int32)50000),&locFPF1);
- /* LongToInternalFPF(randwc(50000L)+1L,&locFPF2); */
- Int32ToInternalFPF(randwc((int32)50000)+(int32)1,&locFPF2);
- DivideInternalFPF(&locFPF1,&locFPF2,abase+i);
- /* LongToInternalFPF(randwc(50000L)+1L,&locFPF2); */
- Int32ToInternalFPF(randwc((int32)50000)+(int32)1,&locFPF2);
- DivideInternalFPF(&locFPF1,&locFPF2,bbase+i);
-}
-return;
-}
-
-
-static char* str1 = "loops %d\n";
-static
-ulong DoEmFloatIteration(InternalFPF *abase,
- InternalFPF *bbase,
- InternalFPF *cbase,
- ulong arraysize, ulong loops)
-{
-static uchar jtable[16] = {0,0,0,0,1,1,1,1,2,2,2,2,2,3,3,3};
-ulong i;
-int number_of_loops;
- loops = 100;
-number_of_loops=loops-1; /* the index of the first loop we run */
-
-vexxx_printf(str1, (int)loops);
-
-/*
-** Each pass through the array performs operations in
-** the followingratios:
-** 4 adds, 4 subtracts, 5 multiplies, 3 divides
-** (adds and subtracts being nearly the same operation)
-*/
-
-{
- for(i=0;i<arraysize;i++)
- switch(jtable[i % 16])
- {
- case 0: /* Add */
- AddSubInternalFPF(0,abase+i,
- bbase+i,
- cbase+i);
- break;
- case 1: /* Subtract */
- AddSubInternalFPF(1,abase+i,
- bbase+i,
- cbase+i);
- break;
- case 2: /* Multiply */
- MultiplyInternalFPF(abase+i,
- bbase+i,
- cbase+i);
- break;
- case 3: /* Divide */
- DivideInternalFPF(abase+i,
- bbase+i,
- cbase+i);
- break;
- }
-{
- ulong j[8]; /* we test 8 entries */
- int k;
- ulong i;
- char buffer[1024];
- if (100==loops) /* the first loop */
- {
- j[0]=(ulong)2;
- j[1]=(ulong)6;
- j[2]=(ulong)10;
- j[3]=(ulong)14;
- j[4]=(ulong)(arraysize-14);
- j[5]=(ulong)(arraysize-10);
- j[6]=(ulong)(arraysize-6);
- j[7]=(ulong)(arraysize-2);
- for(k=0;k<8;k++){
- i=j[k];
- InternalFPFToString(buffer,abase+i);
- vexxx_printf("%6d: (%s) ",i,buffer);
- switch(jtable[i % 16])
- {
- case 0: my_strcpy(buffer,"+"); break;
- case 1: my_strcpy(buffer,"-"); break;
- case 2: my_strcpy(buffer,"*"); break;
- case 3: my_strcpy(buffer,"/"); break;
- }
- vexxx_printf("%s ",buffer);
- InternalFPFToString(buffer,bbase+i);
- vexxx_printf("(%s) = ",buffer);
- InternalFPFToString(buffer,cbase+i);
- vexxx_printf("%s\n",buffer);
- }
-return 0;
- }
-}
-}
-return 0;
-}
-
-/***********************
-** SetInternalFPFZero **
-************************
-** Set an internal floating-point-format number to zero.
-** sign determines the sign of the zero.
-*/
-static void SetInternalFPFZero(InternalFPF *dest,
- uchar sign)
-{
-int i; /* Index */
-
-dest->type=IFPF_IS_ZERO;
-dest->sign=sign;
-dest->exp=MIN_EXP;
-for(i=0;i<INTERNAL_FPF_PRECISION;i++)
- dest->mantissa[i]=0;
-return;
-}
-
-/***************************
-** SetInternalFPFInfinity **
-****************************
-** Set an internal floating-point-format number to infinity.
-** This can happen if the exponent exceeds MAX_EXP.
-** As above, sign picks the sign of infinity.
-*/
-static void SetInternalFPFInfinity(InternalFPF *dest,
- uchar sign)
-{
-int i; /* Index */
-
-dest->type=IFPF_IS_INFINITY;
-dest->sign=sign;
-dest->exp=MIN_EXP;
-for(i=0;i<INTERNAL_FPF_PRECISION;i++)
- dest->mantissa[i]=0;
-return;
-}
-
-/**********************
-** SetInternalFPFNaN **
-***********************
-** Set an internal floating-point-format number to Nan
-** (not a number). Note that we "emulate" an 80x87 as far
-** as the mantissa bits go.
-*/
-static void SetInternalFPFNaN(InternalFPF *dest)
-{
-int i; /* Index */
-
-dest->type=IFPF_IS_NAN;
-dest->exp=MAX_EXP;
-dest->sign=1;
-dest->mantissa[0]=0x4000;
-for(i=1;i<INTERNAL_FPF_PRECISION;i++)
- dest->mantissa[i]=0;
-
-return;
-}
-
-/*******************
-** IsMantissaZero **
-********************
-** Pass this routine a pointer to an internal floating point format
-** number's mantissa. It checks for an all-zero mantissa.
-** Returns 0 if it is NOT all zeros, !=0 otherwise.
-*/
-static int IsMantissaZero(u16 *mant)
-{
-int i; /* Index */
-int n; /* Return value */
-
-n=0;
-for(i=0;i<INTERNAL_FPF_PRECISION;i++)
- n|=mant[i];
-
-return(!n);
-}
-
-/**************
-** Add16Bits **
-***************
-** Add b, c, and carry. Retult in a. New carry in carry.
-*/
-static void Add16Bits(u16 *carry,
- u16 *a,
- u16 b,
- u16 c)
-{
-u32 accum; /* Accumulator */
-
-/*
-** Do the work in the 32-bit accumulator so we can return
-** the carry.
-*/
-accum=(u32)b;
-accum+=(u32)c;
-accum+=(u32)*carry;
-*carry=(u16)((accum & 0x00010000) ? 1 : 0); /* New carry */
-*a=(u16)(accum & 0xFFFF); /* Result is lo 16 bits */
-return;
-}
-
-/**************
-** Sub16Bits **
-***************
-** Additive inverse of above.
-*/
-static void Sub16Bits(u16 *borrow,
- u16 *a,
- u16 b,
- u16 c)
-{
-u32 accum; /* Accumulator */
-
-accum=(u32)b;
-accum-=(u32)c;
-accum-=(u32)*borrow;
-*borrow=(u32)((accum & 0x00010000) ? 1 : 0); /* New borrow */
-*a=(u16)(accum & 0xFFFF);
-return;
-}
-
-/*******************
-** ShiftMantLeft1 **
-********************
-** Shift a vector of 16-bit numbers left 1 bit. Also provides
-** a carry bit, which is shifted in at the beginning, and
-** shifted out at the end.
-*/
-static void ShiftMantLeft1(u16 *carry,
- u16 *mantissa)
-{
-int i; /* Index */
-int new_carry;
-u16 accum; /* Temporary holding placed */
-
-for(i=INTERNAL_FPF_PRECISION-1;i>=0;i--)
-{ accum=mantissa[i];
- new_carry=accum & 0x8000; /* Get new carry */
- accum=accum<<1; /* Do the shift */
- if(*carry)
- accum|=1; /* Insert previous carry */
- *carry=new_carry;
- mantissa[i]=accum; /* Return shifted value */
-}
-return;
-}
-
-/********************
-** ShiftMantRight1 **
-*********************
-** Shift a mantissa right by 1 bit. Provides carry, as
-** above
-*/
-static void ShiftMantRight1(u16 *carry,
- u16 *mantissa)
-{
-int i; /* Index */
-int new_carry;
-u16 accum;
-
-for(i=0;i<INTERNAL_FPF_PRECISION;i++)
-{ accum=mantissa[i];
- new_carry=accum & 1; /* Get new carry */
- accum=accum>>1;
- if(*carry)
- accum|=0x8000;
- *carry=new_carry;
- mantissa[i]=accum;
-}
-return;
-}
-
-
-/*****************************
-** StickyShiftMantRight **
-******************************
-** This is a shift right of the mantissa with a "sticky bit".
-** I.E., if a carry of 1 is shifted out of the least significant
-** bit, the least significant bit is set to 1.
-*/
-static void StickyShiftRightMant(InternalFPF *ptr,
- int amount)
-{
-int i; /* Index */
-u16 carry; /* Self-explanatory */
-u16 *mantissa;
-
-mantissa=ptr->mantissa;
-
-if(ptr->type!=IFPF_IS_ZERO) /* Don't bother shifting a zero */
-{
- /*
- ** If the amount of shifting will shift everyting
- ** out of existence, then just clear the whole mantissa
- ** and set the lowmost bit to 1.
- */
- if(amount>=INTERNAL_FPF_PRECISION * 16)
- {
- for(i=0;i<INTERNAL_FPF_PRECISION-1;i++)
- mantissa[i]=0;
- mantissa[INTERNAL_FPF_PRECISION-1]=1;
- }
- else
- for(i=0;i<amount;i++)
- {
- carry=0;
- ShiftMantRight1(&carry,mantissa);
- if(carry)
- mantissa[INTERNAL_FPF_PRECISION-1] |= 1;
- }
-}
-return;
-}
-
-
-/**************************************************
-** POST ARITHMETIC PROCESSING **
-** (NORMALIZE, ROUND, OVERFLOW, AND UNDERFLOW) **
-**************************************************/
-
-/**************
-** normalize **
-***************
-** Normalize an internal-representation number. Normalization
-** discards empty most-significant bits.
-*/
-static void normalize(InternalFPF *ptr)
-{
-u16 carry;
-
-/*
-** As long as there's a highmost 0 bit, shift the significand
-** left 1 bit. Each time you do this, though, you've
-** gotta decrement the exponent.
-*/
-while ((ptr->mantissa[0] & 0x8000) == 0)
-{
- carry = 0;
- ShiftMantLeft1(&carry, ptr->mantissa);
- ptr->exp--;
-}
-return;
-}
-
-/****************
-** denormalize **
-*****************
-** Denormalize an internal-representation number. This means
-** shifting it right until its exponent is equivalent to
-** minimum_exponent. (You have to do this often in order
-** to perform additions and subtractions).
-*/
-static void denormalize(InternalFPF *ptr,
- int minimum_exponent)
-{
-long exponent_difference;
-
-if (IsMantissaZero(ptr->mantissa))
-{
- vexxx_printf("Error: zero significand in denormalize\n");
-}
-
-exponent_difference = ptr->exp-minimum_exponent;
-if (exponent_difference < 0)
-{
- /*
- ** The number is subnormal
- */
- exponent_difference = -exponent_difference;
- if (exponent_difference >= (INTERNAL_FPF_PRECISION * 16))
- {
- /* Underflow */
- SetInternalFPFZero(ptr, ptr->sign);
- }
- else
- {
- ptr->exp+=exponent_difference;
- StickyShiftRightMant(ptr, exponent_difference);
- }
-}
-return;
-}
-
-
-/*********************
-** RoundInternalFPF **
-**********************
-** Round an internal-representation number.
-** The kind of rounding we do here is simplest...referred to as
-** "chop". "Extraneous" rightmost bits are simply hacked off.
-*/
-void RoundInternalFPF(InternalFPF *ptr)
-{
-/* int i; */
-
-if (ptr->type == IFPF_IS_NORMAL ||
- ptr->type == IFPF_IS_SUBNORMAL)
-{
- denormalize(ptr, MIN_EXP);
- if (ptr->type != IFPF_IS_ZERO)
- {
-
- /* clear the extraneous bits */
- ptr->mantissa[3] &= 0xfff8;
-/* for (i=4; i<INTERNAL_FPF_PRECISION; i++)
- {
- ptr->mantissa[i] = 0;
- }
-*/
- /*
- ** Check for overflow
- */
-/* Does not do anything as ptr->exp is a short and MAX_EXP=37268
- if (ptr->exp > MAX_EXP)
- {
- SetInternalFPFInfinity(ptr, ptr->sign);
- }
-*/
- }
-}
-return;
-}
-
-/*******************************************************
-** ARITHMETIC OPERATIONS ON INTERNAL REPRESENTATION **
-*******************************************************/
-
-/***************
-** choose_nan **
-****************
-** Called by routines that are forced to perform math on
-** a pair of NaN's. This routine "selects" which NaN is
-** to be returned.
-*/
-static void choose_nan(InternalFPF *x,
- InternalFPF *y,
- InternalFPF *z,
- int intel_flag)
-{
-int i;
-
-/*
-** Compare the two mantissas,
-** return the larger. Note that we will be emulating
-** an 80387 in this operation.
-*/
-for (i=0; i<INTERNAL_FPF_PRECISION; i++)
-{
- if (x->mantissa[i] > y->mantissa[i])
- {
- my_memmove((void *)x,(void *)z,sizeof(InternalFPF));
- return;
- }
- if (x->mantissa[i] < y->mantissa[i])
- {
- my_memmove((void *)y,(void *)z,sizeof(InternalFPF));
- return;
- }
-}
-
-/*
-** They are equal
-*/
-if (!intel_flag)
- /* if the operation is addition */
- my_memmove((void *)x,(void *)z,sizeof(InternalFPF));
-else
- /* if the operation is multiplication */
- my_memmove((void *)y,(void *)z,sizeof(InternalFPF));
-return;
-}
-
-
-/**********************
-** AddSubInternalFPF **
-***********************
-** Adding or subtracting internal-representation numbers.
-** Internal-representation numbers pointed to by x and y are
-** added/subtracted and the result returned in z.
-*/
-static void AddSubInternalFPF(uchar operation,
- InternalFPF *x,
- InternalFPF *y,
- InternalFPF *z)
-{
-int exponent_difference;
-u16 borrow;
-u16 carry;
-int i;
-InternalFPF locx,locy; /* Needed since we alter them */
-
-/*
-** Following big switch statement handles the
-** various combinations of operand types.
-*/
-switch ((x->type * IFPF_TYPE_COUNT) + y->type)
-{
-case ZERO_ZERO:
- my_memmove((void *)x,(void *)z,sizeof(InternalFPF));
- if (x->sign ^ y->sign ^ operation)
- {
- z->sign = 0; /* positive */
- }
- break;
-
-case NAN_ZERO:
-case NAN_SUBNORMAL:
-case NAN_NORMAL:
-case NAN_INFINITY:
-case SUBNORMAL_ZERO:
-case NORMAL_ZERO:
-case INFINITY_ZERO:
-case INFINITY_SUBNORMAL:
-case INFINITY_NORMAL:
- my_memmove((void *)x,(void *)z,sizeof(InternalFPF));
- break;
-
-
-case ZERO_NAN:
-case SUBNORMAL_NAN:
-case NORMAL_NAN:
-case INFINITY_NAN:
- my_memmove((void *)y,(void *)z,sizeof(InternalFPF));
- break;
-
-case ZERO_SUBNORMAL:
-case ZERO_NORMAL:
-case ZERO_INFINITY:
-case SUBNORMAL_INFINITY:
-case NORMAL_INFINITY:
- my_memmove((void *)y,(void *)z,sizeof(InternalFPF));
- z->sign ^= operation;
- break;
-
-case SUBNORMAL_SUBNORMAL:
-case SUBNORMAL_NORMAL:
-case NORMAL_SUBNORMAL:
-case NORMAL_NORMAL:
- /*
- ** Copy x and y to locals, since we may have
- ** to alter them.
- */
- my_memmove((void *)&locx,(void *)x,sizeof(InternalFPF));
- my_memmove((void *)&locy,(void *)y,sizeof(InternalFPF));
-
- /* compute sum/difference */
- exponent_difference = locx.exp-locy.exp;
- if (exponent_difference == 0)
- {
- /*
- ** locx.exp == locy.exp
- ** so, no shifting required
- */
- if (locx.type == IFPF_IS_SUBNORMAL ||
- locy.type == IFPF_IS_SUBNORMAL)
- z->type = IFPF_IS_SUBNORMAL;
- else
- z->type = IFPF_IS_NORMAL;
-
- /*
- ** Assume that locx.mantissa > locy.mantissa
- */
- z->sign = locx.sign;
- z->exp= locx.exp;
- }
- else
- if (exponent_difference > 0)
- {
- /*
- ** locx.exp > locy.exp
- */
- StickyShiftRightMant(&locy,
- exponent_difference);
- z->type = locx.type;
- z->sign = locx.sign;
- z->exp = locx.exp;
- }
- else /* if (exponent_difference < 0) */
- {
- /*
- ** locx.exp < locy.exp
- */
- StickyShiftRightMant(&locx,
- -exponent_difference);
- z->type = locy.type;
- z->sign = locy.sign ^ operation;
- z->exp = locy.exp;
- }
-
- if (locx.sign ^ locy.sign ^ operation)
- {
- /*
- ** Signs are different, subtract mantissas
- */
- borrow = 0;
- for (i=(INTERNAL_FPF_PRECISION-1); i>=0; i--)
- Sub16Bits(&borrow,
- &z->mantissa[i],
- locx.mantissa[i],
- locy.mantissa[i]);
-
- if (borrow)
- {
- /* The y->mantissa was larger than the
- ** x->mantissa leaving a negative
- ** result. Change the result back to
- ** an unsigned number and flip the
- ** sign flag.
- */
- z->sign = locy.sign ^ operation;
- borrow = 0;
- for (i=(INTERNAL_FPF_PRECISION-1); i>=0; i--)
- {
- Sub16Bits(&borrow,
- &z->mantissa[i],
- 0,
- z->mantissa[i]);
- }
- }
- else
- {
- /* The assumption made above
- ** (i.e. x->mantissa >= y->mantissa)
- ** was correct. Therefore, do nothing.
- ** z->sign = x->sign;
- */
- }
-
- if (IsMantissaZero(z->mantissa))
- {
- z->type = IFPF_IS_ZERO;
- z->sign = 0; /* positive */
- }
- else
- if (locx.type == IFPF_IS_NORMAL ||
- locy.type == IFPF_IS_NORMAL)
- {
- normalize(z);
- }
- }
- else
- {
- /* signs are the same, add mantissas */
- carry = 0;
- for (i=(INTERNAL_FPF_PRECISION-1); i>=0; i--)
- {
- Add16Bits(&carry,
- &z->mantissa[i],
- locx.mantissa[i],
- locy.mantissa[i]);
- }
-
- if (carry)
- {
- z->exp++;
- carry=0;
- ShiftMantRight1(&carry,z->mantissa);
- z->mantissa[0] |= 0x8000;
- z->type = IFPF_IS_NORMAL;
- }
- else
- if (z->mantissa[0] & 0x8000)
- z->type = IFPF_IS_NORMAL;
- }
- break;
-
-case INFINITY_INFINITY:
- SetInternalFPFNaN(z);
- break;
-
-case NAN_NAN:
- choose_nan(x, y, z, 1);
- break;
-}
-
-/*
-** All the math is done; time to round.
-*/
-RoundInternalFPF(z);
-return;
-}
-
-
-/************************
-** MultiplyInternalFPF **
-*************************
-** Two internal-representation numbers x and y are multiplied; the
-** result is returned in z.
-*/
-static void MultiplyInternalFPF(InternalFPF *x,
- InternalFPF *y,
- InternalFPF *z)
-{
-int i;
-int j;
-u16 carry;
-u16 extra_bits[INTERNAL_FPF_PRECISION];
-InternalFPF locy; /* Needed since this will be altered */
-/*
-** As in the preceding function, this large switch
-** statement selects among the many combinations
-** of operands.
-*/
-switch ((x->type * IFPF_TYPE_COUNT) + y->type)
-{
-case INFINITY_SUBNORMAL:
-case INFINITY_NORMAL:
-case INFINITY_INFINITY:
-case ZERO_ZERO:
-case ZERO_SUBNORMAL:
-case ZERO_NORMAL:
- my_memmove((void *)x,(void *)z,sizeof(InternalFPF));
- z->sign ^= y->sign;
- break;
-
-case SUBNORMAL_INFINITY:
-case NORMAL_INFINITY:
-case SUBNORMAL_ZERO:
-case NORMAL_ZERO:
- my_memmove((void *)y,(void *)z,sizeof(InternalFPF));
- z->sign ^= x->sign;
- break;
-
-case ZERO_INFINITY:
-case INFINITY_ZERO:
- SetInternalFPFNaN(z);
- break;
-
-case NAN_ZERO:
-case NAN_SUBNORMAL:
-case NAN_NORMAL:
-case NAN_INFINITY:
- my_memmove((void *)x,(void *)z,sizeof(InternalFPF));
- break;
-
-case ZERO_NAN:
-case SUBNORMAL_NAN:
-case NORMAL_NAN:
-case INFINITY_NAN:
- my_memmove((void *)y,(void *)z,sizeof(InternalFPF));
- break;
-
-
-case SUBNORMAL_SUBNORMAL:
-case SUBNORMAL_NORMAL:
-case NORMAL_SUBNORMAL:
-case NORMAL_NORMAL:
- /*
- ** Make a local copy of the y number, since we will be
- ** altering it in the process of multiplying.
- */
- my_memmove((void *)&locy,(void *)y,sizeof(InternalFPF));
-
- /*
- ** Check for unnormal zero arguments
- */
- if (IsMantissaZero(x->mantissa) || IsMantissaZero(y->mantissa))
- SetInternalFPFInfinity(z, 0);
-
- /*
- ** Initialize the result
- */
- if (x->type == IFPF_IS_SUBNORMAL ||
- y->type == IFPF_IS_SUBNORMAL)
- z->type = IFPF_IS_SUBNORMAL;
- else
- z->type = IFPF_IS_NORMAL;
-
- z->sign = x->sign ^ y->sign;
- z->exp = x->exp + y->exp ;
- for (i=0; i<INTERNAL_FPF_PRECISION; i++)
- {
- z->mantissa[i] = 0;
- extra_bits[i] = 0;
- }
-
- for (i=0; i<(INTERNAL_FPF_PRECISION*16); i++)
- {
- /*
- ** Get rightmost bit of the multiplier
- */
- carry = 0;
- ShiftMantRight1(&carry, locy.mantissa);
- if (carry)
- {
- /*
- ** Add the multiplicand to the product
- */
- carry = 0;
- for (j=(INTERNAL_FPF_PRECISION-1); j>=0; j--)
- Add16Bits(&carry,
- &z->mantissa[j],
- z->mantissa[j],
- x->mantissa[j]);
- }
- else
- {
- carry = 0;
- }
-
- /*
- ** Shift the product right. Overflow bits get
- ** shifted into extra_bits. We'll use it later
- ** to help with the "sticky" bit.
- */
- ShiftMantRight1(&carry, z->mantissa);
- ShiftMantRight1(&carry, extra_bits);
- }
-
- /*
- ** Normalize
- ** Note that we use a "special" normalization routine
- ** because we need to use the extra bits. (These are
- ** bits that may have been shifted off the bottom that
- ** we want to reclaim...if we can.
- */
- while ((z->mantissa[0] & 0x8000) == 0)
- {
- carry = 0;
- ShiftMantLeft1(&carry, extra_bits);
- ShiftMantLeft1(&carry, z->mantissa);
- z->exp--;
- }
-
- /*
- ** Set the sticky bit if any bits set in extra bits.
- */
- if (IsMantissaZero(extra_bits))
- {
- z->mantissa[INTERNAL_FPF_PRECISION-1] |= 1;
- }
- break;
-
-case NAN_NAN:
- choose_nan(x, y, z, 0);
- break;
-}
-
-/*
-** All math done...do rounding.
-*/
-RoundInternalFPF(z);
-return;
-}
-
-
-/**********************
-** DivideInternalFPF **
-***********************
-** Divide internal FPF number x by y. Return result in z.
-*/
-static void DivideInternalFPF(InternalFPF *x,
- InternalFPF *y,
- InternalFPF *z)
-{
-int i;
-int j;
-u16 carry;
-u16 extra_bits[INTERNAL_FPF_PRECISION];
-InternalFPF locx; /* Local for x number */
-
-/*
-** As with preceding function, the following switch
-** statement selects among the various possible
-** operands.
-*/
-switch ((x->type * IFPF_TYPE_COUNT) + y->type)
-{
-case ZERO_ZERO:
-case INFINITY_INFINITY:
- SetInternalFPFNaN(z);
- break;
-
-case ZERO_SUBNORMAL:
-case ZERO_NORMAL:
- if (IsMantissaZero(y->mantissa))
- {
- SetInternalFPFNaN(z);
- break;
- }
-
-case ZERO_INFINITY:
-case SUBNORMAL_INFINITY:
-case NORMAL_INFINITY:
- SetInternalFPFZero(z, x->sign ^ y->sign);
- break;
-
-case SUBNORMAL_ZERO:
-case NORMAL_ZERO:
- if (IsMantissaZero(x->mantissa))
- {
- SetInternalFPFNaN(z);
- break;
- }
-
-case INFINITY_ZERO:
-case INFINITY_SUBNORMAL:
-case INFINITY_NORMAL:
- SetInternalFPFInfinity(z, 0);
- z->sign = x->sign ^ y->sign;
- break;
-
-case NAN_ZERO:
-case NAN_SUBNORMAL:
-case NAN_NORMAL:
-case NAN_INFINITY:
- my_memmove((void *)x,(void *)z,sizeof(InternalFPF));
- break;
-
-case ZERO_NAN:
-case SUBNORMAL_NAN:
-case NORMAL_NAN:
-case INFINITY_NAN:
- my_memmove((void *)y,(void *)z,sizeof(InternalFPF));
- break;
-
-case SUBNORMAL_SUBNORMAL:
-case NORMAL_SUBNORMAL:
-case SUBNORMAL_NORMAL:
-case NORMAL_NORMAL:
- /*
- ** Make local copy of x number, since we'll be
- ** altering it in the process of dividing.
- */
- my_memmove((void *)&locx,(void *)x,sizeof(InternalFPF));
-
- /*
- ** Check for unnormal zero arguments
- */
- if (IsMantissaZero(locx.mantissa))
- {
- if (IsMantissaZero(y->mantissa))
- SetInternalFPFNaN(z);
- else
- SetInternalFPFZero(z, 0);
- break;
- }
- if (IsMantissaZero(y->mantissa))
- {
- SetInternalFPFInfinity(z, 0);
- break;
- }
-
- /*
- ** Initialize the result
- */
- z->type = x->type;
- z->sign = x->sign ^ y->sign;
- z->exp = x->exp - y->exp +
- ((INTERNAL_FPF_PRECISION * 16 * 2));
- for (i=0; i<INTERNAL_FPF_PRECISION; i++)
- {
- z->mantissa[i] = 0;
- extra_bits[i] = 0;
- }
-
- while ((z->mantissa[0] & 0x8000) == 0)
- {
- carry = 0;
- ShiftMantLeft1(&carry, locx.mantissa);
- ShiftMantLeft1(&carry, extra_bits);
-
- /*
- ** Time to subtract yet?
- */
- if (carry == 0)
- for (j=0; j<INTERNAL_FPF_PRECISION; j++)
- {
- if (y->mantissa[j] > extra_bits[j])
- {
- carry = 0;
- goto no_subtract;
- }
- if (y->mantissa[j] < extra_bits[j])
- break;
- }
- /*
- ** Divisor (y) <= dividend (x), subtract
- */
- carry = 0;
- for (j=(INTERNAL_FPF_PRECISION-1); j>=0; j--)
- Sub16Bits(&carry,
- &extra_bits[j],
- extra_bits[j],
- y->mantissa[j]);
- carry = 1; /* 1 shifted into quotient */
- no_subtract:
- ShiftMantLeft1(&carry, z->mantissa);
- z->exp--;
- }
- break;
-
-case NAN_NAN:
- choose_nan(x, y, z, 0);
- break;
-}
-
-/*
-** Math complete...do rounding
-*/
-RoundInternalFPF(z);
-}
-
-/**********************
-** LongToInternalFPF **
-** Int32ToInternalFPF **
-***********************
-** Convert a signed (long) 32-bit integer into an internal FPF number.
-*/
-/* static void LongToInternalFPF(long mylong, */
-static void Int32ToInternalFPF(int32 mylong,
- InternalFPF *dest)
-{
-int i; /* Index */
-u16 myword; /* Used to hold converted stuff */
-/*
-** Save the sign and get the absolute value. This will help us
-** with 64-bit machines, since we use only the lower 32
-** bits just in case. (No longer necessary after we use int32.)
-*/
-/* if(mylong<0L) */
-if(mylong<(int32)0)
-{ dest->sign=1;
- mylong=(int32)0-mylong;
-}
-else
- dest->sign=0;
-/*
-** Prepare the destination floating point number
-*/
-dest->type=IFPF_IS_NORMAL;
-for(i=0;i<INTERNAL_FPF_PRECISION;i++)
- dest->mantissa[i]=0;
-
-/*
-** See if we've got a zero. If so, make the resultant FP
-** number a true zero and go home.
-*/
-if(mylong==0)
-{ dest->type=IFPF_IS_ZERO;
- dest->exp=0;
- return;
-}
-
-/*
-** Not a true zero. Set the exponent to 32 (internal FPFs have
-** no bias) and load the low and high words into their proper
-** locations in the mantissa. Then normalize. The action of
-** normalizing slides the mantissa bits into place and sets
-** up the exponent properly.
-*/
-dest->exp=32;
-myword=(u16)((mylong >> 16) & 0xFFFFL);
-dest->mantissa[0]=myword;
-myword=(u16)(mylong & 0xFFFFL);
-dest->mantissa[1]=myword;
-normalize(dest);
-return;
-}
-
-#if 1
-/************************
-** InternalFPFToString **
-*************************
-** FOR DEBUG PURPOSES
-** This routine converts an internal floating point representation
-** number to a string. Used in debugging the package.
-** Returns length of converted number.
-** NOTE: dest must point to a buffer big enough to hold the
-** result. Also, this routine does append a null (an effect
-** of using the sprintf() function). It also returns
-** a length count.
-** NOTE: This routine returns 5 significant digits. Thats
-** about all I feel safe with, given the method of
-** conversion. It should be more than enough for programmers
-** to determine whether the package is properly ported.
-*/
-static int InternalFPFToString(char *dest,
- InternalFPF *src)
-{
-InternalFPF locFPFNum; /* Local for src (will be altered) */
-InternalFPF IFPF10; /* Floating-point 10 */
-InternalFPF IFPFComp; /* For doing comparisons */
-int msign; /* Holding for mantissa sign */
-int expcount; /* Exponent counter */
-int ccount; /* Character counter */
-int i,j,k; /* Index */
-u16 carryaccum; /* Carry accumulator */
-u16 mycarry; /* Local for carry */
-
-/*
-** Check first for the simple things...Nan, Infinity, Zero.
-** If found, copy the proper string in and go home.
-*/
-switch(src->type)
-{
- case IFPF_IS_NAN:
- my_memcpy(dest,"NaN",3);
- return(3);
-
- case IFPF_IS_INFINITY:
- if(src->sign==0)
- my_memcpy(dest,"+Inf",4);
- else
- my_memcpy(dest,"-Inf",4);
- return(4);
-
- case IFPF_IS_ZERO:
- if(src->sign==0)
- my_memcpy(dest,"+0",2);
- else
- my_memcpy(dest,"-0",2);
- return(2);
-}
-
-/*
-** Move the internal number into our local holding area, since
-** we'll be altering it to print it out.
-*/
-my_memcpy((void *)&locFPFNum,(void *)src,sizeof(InternalFPF));
-
-/*
-** Set up a floating-point 10...which we'll use a lot in a minute.
-*/
-/* LongToInternalFPF(10L,&IFPF10); */
-Int32ToInternalFPF((int32)10,&IFPF10);
-
-/*
-** Save the mantissa sign and make it positive.
-*/
-msign=src->sign;
-
-/* src->sign=0 */ /* bug, fixed Nov. 13, 1997 */
-(&locFPFNum)->sign=0;
-
-expcount=0; /* Init exponent counter */
-
-/*
-** See if the number is less than 10. If so, multiply
-** the number repeatedly by 10 until it's not. For each
-** multiplication, decrement a counter so we can keep track
-** of the exponent.
-*/
-
-while(1)
-{ AddSubInternalFPF(1,&locFPFNum,&IFPF10,&IFPFComp);
- if(IFPFComp.sign==0) break;
- MultiplyInternalFPF(&locFPFNum,&IFPF10,&IFPFComp);
- expcount--;
- my_memcpy((void *)&locFPFNum,(void *)&IFPFComp,sizeof(InternalFPF));
-}
-/*
-** Do the reverse of the above. As long as the number is
-** greater than or equal to 10, divide it by 10. Increment the
-** exponent counter for each multiplication.
-*/
-
-while(1)
-{
- AddSubInternalFPF(1,&locFPFNum,&IFPF10,&IFPFComp);
- if(IFPFComp.sign!=0) break;
- DivideInternalFPF(&locFPFNum,&IFPF10,&IFPFComp);
- expcount++;
- my_memcpy((void *)&locFPFNum,(void *)&IFPFComp,sizeof(InternalFPF));
-}
-
-/*
-** About time to start storing things. First, store the
-** mantissa sign.
-*/
-ccount=1; /* Init character counter */
-if(msign==0)
- *dest++='+';
-else
- *dest++='-';
-
-/*
-** At this point we know that the number is in the range
-** 10 > n >=1. We need to "strip digits" out of the
-** mantissa. We do this by treating the mantissa as
-** an integer and multiplying by 10. (Not a floating-point
-** 10, but an integer 10. Since this is debug code and we
-** could care less about speed, we'll do it the stupid
-** way and simply add the number to itself 10 times.
-** Anything that makes it to the left of the implied binary point
-** gets stripped off and emitted. We'll do this for
-** 5 significant digits (which should be enough to
-** verify things).
-*/
-/*
-** Re-position radix point
-*/
-carryaccum=0;
-while(locFPFNum.exp>0)
-{
- mycarry=0;
- ShiftMantLeft1(&mycarry,locFPFNum.mantissa);
- carryaccum=(carryaccum<<1);
- if(mycarry) carryaccum++;
- locFPFNum.exp--;
-}
-
-while(locFPFNum.exp<0)
-{
- mycarry=0;
- ShiftMantRight1(&mycarry,locFPFNum.mantissa);
- locFPFNum.exp++;
-}
-
-for(i=0;i<6;i++)
- if(i==1)
- { /* Emit decimal point */
- *dest++='.';
- ccount++;
- }
- else
- { /* Emit a digit */
- *dest++=('0'+carryaccum);
- ccount++;
-
- carryaccum=0;
- my_memcpy((void *)&IFPF10,
- (void *)&locFPFNum,
- sizeof(InternalFPF));
-
- /* Do multiply via repeated adds */
- for(j=0;j<9;j++)
- {
- mycarry=0;
- for(k=(INTERNAL_FPF_PRECISION-1);k>=0;k--)
- Add16Bits(&mycarry,&(IFPFComp.mantissa[k]),
- locFPFNum.mantissa[k],
- IFPF10.mantissa[k]);
- carryaccum+=mycarry ? 1 : 0;
- my_memcpy((void *)&locFPFNum,
- (void *)&IFPFComp,
- sizeof(InternalFPF));
- }
- }
-
-/*
-** Now move the 'E', the exponent sign, and the exponent
-** into the string.
-*/
-*dest++='E';
-
-/* sprint is supposed to return an integer, but it caused problems on SunOS
- * with the native cc. Hence we force it.
- * Uwe F. Mayer
- */
-if (expcount < 0) {
- *dest++ = '-';
- expcount =- expcount;
-}
-else *dest++ = ' ';
-
-*dest++ = (char)(expcount + '0');
-*dest++ = 0;
-
-ccount += 3;
-/*
-** All done, go home.
-*/
-return(ccount);
-
-}
-
-#endif
-
-
-
-////////////////////////////////////////////////////////////////////////
-static
-void* AllocateMemory ( unsigned long n, int* p )
-{
- *p = 0;
- void* r = (void*) (*serviceFn)(2,n);
- return r;
-}
-static
-void FreeMemory ( void* p, int* zz )
-{
- *zz = 0;
- // free(p);
-}
-
-
-
-/**************
-** DoEmFloat **
-***************
-** Perform the floating-point emulation routines portion of the
-** CPU benchmark. Returns the operations per second.
-*/
-static
-void DoEmFloat(void)
-{
-EmFloatStruct *locemfloatstruct; /* Local structure */
-InternalFPF *abase; /* Base of A array */
-InternalFPF *bbase; /* Base of B array */
-InternalFPF *cbase; /* Base of C array */
-ulong tickcount; /* # of ticks */
-char *errorcontext; /* Error context string pointer */
-int systemerror; /* For holding error code */
-ulong loops; /* # of loops */
-
-/*
-** Link to global structure
-*/
-EmFloatStruct global_emfloatstruct;
- global_emfloatstruct.adjust = 0;
- global_emfloatstruct.request_secs = 0;
- global_emfloatstruct.arraysize = 100;
- global_emfloatstruct.loops = 1;
- global_emfloatstruct.emflops = 0.0;
-locemfloatstruct=&global_emfloatstruct;
-
-/*
-** Set the error context
-*/
-errorcontext="CPU:Floating Emulation";
-
-
-abase=(InternalFPF *)AllocateMemory(locemfloatstruct->arraysize*sizeof(InternalFPF),
- &systemerror);
-
-bbase=(InternalFPF *)AllocateMemory(locemfloatstruct->arraysize*sizeof(InternalFPF),
- &systemerror);
-
-cbase=(InternalFPF *)AllocateMemory(locemfloatstruct->arraysize*sizeof(InternalFPF),
- &systemerror);
-
-/*
-** Set up the arrays
-*/
-SetupCPUEmFloatArrays(abase,bbase,cbase,locemfloatstruct->arraysize);
-
- loops=100;
- tickcount=DoEmFloatIteration(abase,bbase,cbase,
- locemfloatstruct->arraysize,
- loops);
-
-FreeMemory((void *)abase,&systemerror);
-FreeMemory((void *)bbase,&systemerror);
-FreeMemory((void *)cbase,&systemerror);
-
-return;
-}
-
-//////////////////
-void entry ( HWord(*f)(HWord,HWord) )
-{
- serviceFn = f;
- vexxx_printf("starting\n");
- DoEmFloat();
- (*serviceFn)(0,0);
-}
+++ /dev/null
-
-
-static void bar ( void*(*service)(int,int) )
-{
- int i;
- for (i = 0; i < 100000; i++) ;
- service(1, 'h');
- service(1, 'e');
- service(1, 'l');
- service(1, 'l');
- service(1, 'o');
- service(1, '\n');
-}
-
-void entry ( void*(*service)(int,int) )
-{
- bar(service);
- service(0,0);
-}
-
+++ /dev/null
-
-/* HOW TO COMPILE FOR SWITCHBACK:
-
- gcc -O -c test_ppc_jm1.c -mregnames -Wall
-
-*/
-
-#undef HAS_ALTIVEC
-#define NO_FLOAT
-#undef IS_PPC405
-
-
-/*
- * test-ppc.c:
- * PPC tests for qemu-PPC CPU emulation checks
- *
- * Copyright (c) 2005 Jocelyn Mayer
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License V2
- * as published by the Free Software Foundation.
- */
-
-/*
- * Theory of operations:
- * a few registers are reserved for the test program:
- * r14 => r18
- * f14 => f18
- * I do preload test values in r14 thru r17 (or less, depending on the number
- * of register operands needed), patch the test opcode if any immediate
- * operands are required, execute the tested opcode.
- * XER, CCR and FPSCR are cleared before every test.
- * I always get the result in r17 and also save XER and CCR for fixed-point
- * operations. I also check FPSCR for floating points operations.
- *
- * Improvments:
- * a more cleaver FPSCR management is needed: for now, I always test
- * the round-to-zero case. Other rounding modes also need to be tested.
- */
-
-#include <stdint.h>
-//#include <stdlib.h>
-//#include <stdio.h>
-//#include <string.h>
-//#include <unistd.h>
-//#include <fcntl.h>
-//#include <ctype.h>
-//#include <math.h>
-//#include <fenv.h>
-
-#define NULL ((void*)0)
-
-//#include "test-ppc.h"
-
-// BEGIN #include "test-ppc.h"
-/*
- * test-ppc.h:
- * PPC tests for qemu-PPC CPU emulation checks - definitions
- *
- * Copyright (c) 2005 Jocelyn Mayer
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License V2
- * as published by the Free Software Foundation.
- */
-
-#if !defined (__TEST_PPC_H__)
-#define __TEST_PPC_H__
-
-typedef void (*test_func_t) (void);
-typedef struct test_t test_t;
-typedef struct test_table_t test_table_t;
-struct test_t {
- test_func_t func;
- const unsigned char *name;
-};
-
-struct test_table_t {
- test_t *tests;
- const unsigned char *name;
- int flags;
-};
-
-typedef void (*test_loop_t) (const unsigned char *name, test_func_t func);
-
-enum test_flags {
- /* Nb arguments */
- PPC_ONE_ARG = 0x00000001,
- PPC_TWO_ARGS = 0x00000002,
- PPC_THREE_ARGS = 0x00000003,
- PPC_CMP_ARGS = 0x00000004,
- PPC_CMPI_ARGS = 0x00000005,
- PPC_TWO_I16 = 0x00000006,
- PPC_SPECIAL = 0x00000007,
- PPC_NB_ARGS = 0x0000000F,
- /* Type */
- PPC_ARITH = 0x00000100,
- PPC_LOGICAL = 0x00000200,
- PPC_COMPARE = 0x00000300,
- PPC_CROP = 0x00000400,
- PPC_TYPE = 0x00000F00,
- /* Family */
- PPC_INTEGER = 0x00010000,
- PPC_FLOAT = 0x00020000,
- PPC_405 = 0x00030000,
- PPC_ALTIVEC = 0x00040000,
- PPC_FALTIVEC = 0x00050000,
- PPC_FAMILY = 0x000F0000,
- /* Flags */
- PPC_CR = 0x01000000,
-};
-
-#endif /* !defined (__TEST_PPC_H__) */
-
-// END #include "test-ppc.h"
-
-
-
-
-//#define DEBUG_ARGS_BUILD
-#if defined (DEBUG_ARGS_BUILD)
-#define AB_DPRINTF(fmt, args...) do { vexxx_printf(fmt , ##args); } while (0)
-#else
-#define AB_DPRINTF(fmt, args...) do { } while (0)
-#endif
-
-//#define DEBUG_FILTER
-#if defined (DEBUG_FILTER)
-#define FDPRINTF(fmt, args...) do { vexxx_printf(fmt , ##args); } while (0)
-#else
-#define FDPRINTF(fmt, args...) do { } while (0)
-#endif
-
-#if !defined (NO_FLOAT)
-register double f14 __asm__ ("f14");
-register double f15 __asm__ ("f15");
-register double f16 __asm__ ("f16");
-register double f17 __asm__ ("f17");
-register double f18 __asm__ ("f18");
-#endif
-register uint32_t r14 __asm__ ("r14");
-register uint32_t r15 __asm__ ("r15");
-register uint32_t r16 __asm__ ("r16");
-register uint32_t r17 __asm__ ("r17");
-register uint32_t r18 __asm__ ("r18");
-
-
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-
-/* Something which has the same size as void* on the host. That is,
- it is 32 bits on a 32-bit host and 64 bits on a 64-bit host, and so
- it can safely be coerced to and from a pointer type on the host
- machine. */
-typedef unsigned long HWord;
-typedef char HChar;
-typedef signed int Int;
-typedef unsigned int UInt;
-typedef unsigned char UChar;
-
-typedef signed long long int Long;
-typedef unsigned long long int ULong;
-
-typedef unsigned char Bool;
-#define True ((Bool)1)
-#define False ((Bool)0)
-
-
-//#include "/home/sewardj/VEX/trunk/pub/libvex_basictypes.h"
-
-static HWord (*serviceFn)(HWord,HWord) = 0;
-
-static Bool my_isspace ( UChar c )
-{
- return c == ' '
- || c == '\f'
- || c == '\n'
- || c == '\r'
- || c == '\t'
- || c == '\v';
-}
-
-#if 0 // unused
-static char* my_strcpy ( char* dest, const char* src )
-{
- char* dest_orig = dest;
- while (*src) *dest++ = *src++;
- *dest = 0;
- return dest_orig;
-}
-
-static void* my_memcpy ( void *dest, const void *src, int sz )
-{
- const char *s = (const char *)src;
- char *d = (char *)dest;
-
- while (sz--)
- *d++ = *s++;
-
- return dest;
-}
-
-static void* my_memmove( void *dst, const void *src, unsigned int len )
-{
- register char *d;
- register char *s;
- if ( dst > src ) {
- d = (char *)dst + len - 1;
- s = (char *)src + len - 1;
- while ( len >= 4 ) {
- *d-- = *s--;
- *d-- = *s--;
- *d-- = *s--;
- *d-- = *s--;
- len -= 4;
- }
- while ( len-- ) {
- *d-- = *s--;
- }
- } else if ( dst < src ) {
- d = (char *)dst;
- s = (char *)src;
- while ( len >= 4 ) {
- *d++ = *s++;
- *d++ = *s++;
- *d++ = *s++;
- *d++ = *s++;
- len -= 4;
- }
- while ( len-- ) {
- *d++ = *s++;
- }
- }
- return dst;
-}
-#endif
-
-char* my_strcat ( char* dest, const char* src )
-{
- char* dest_orig = dest;
- while (*dest) dest++;
- while (*src) *dest++ = *src++;
- *dest = 0;
- return dest_orig;
-}
-
-int my_strcmp ( const char* s1, const char* s2 )
-{
- register unsigned char c1;
- register unsigned char c2;
- while (True) {
- c1 = *(unsigned char *)s1;
- c2 = *(unsigned char *)s2;
- if (c1 != c2) break;
- if (c1 == 0) break;
- s1++; s2++;
- }
- if ((unsigned char)c1 < (unsigned char)c2) return -1;
- if ((unsigned char)c1 > (unsigned char)c2) return 1;
- return 0;
-}
-
-
-int my_memcmp ( const void *s1V, const void *s2V, int n )
-{
- int res;
- unsigned char a0;
- unsigned char b0;
- unsigned char* s1 = (unsigned char*)s1V;
- unsigned char* s2 = (unsigned char*)s2V;
-
- while (n != 0) {
- a0 = s1[0];
- b0 = s2[0];
- s1 += 1;
- s2 += 1;
- res = ((int)a0) - ((int)b0);
- if (res != 0)
- return res;
- n -= 1;
- }
- return 0;
-}
-
-char* my_strchr ( const char* s, int c )
-{
- UChar ch = (UChar)((UInt)c);
- UChar* p = (UChar*)s;
- while (True) {
- if (*p == ch) return p;
- if (*p == 0) return NULL;
- p++;
- }
-}
-
-void* my_malloc ( int n )
-{
- void* r = (void*) (*serviceFn)(2,n);
- return r;
-}
-
-
-/////////////////////////////////////////////////////////////////////
-
-static void vexxx_log_bytes ( char* p, int n )
-{
- int i;
- for (i = 0; i < n; i++)
- (*serviceFn)( 1, (int)p[i] );
-}
-
-/*---------------------------------------------------------*/
-/*--- vexxx_printf ---*/
-/*---------------------------------------------------------*/
-
-/* This should be the only <...> include in the entire VEX library.
- New code for vex_util.c should go above this point. */
-#include <stdarg.h>
-
-static HChar vexxx_toupper ( HChar c )
-{
- if (c >= 'a' && c <= 'z')
- return c + ('A' - 'a');
- else
- return c;
-}
-
-static Int vexxx_strlen ( const HChar* str )
-{
- Int i = 0;
- while (str[i] != 0) i++;
- return i;
-}
-
-Bool vexxx_streq ( const HChar* s1, const HChar* s2 )
-{
- while (True) {
- if (*s1 == 0 && *s2 == 0)
- return True;
- if (*s1 != *s2)
- return False;
- s1++;
- s2++;
- }
-}
-
-/* Some flags. */
-#define VG_MSG_SIGNED 1 /* The value is signed. */
-#define VG_MSG_ZJUSTIFY 2 /* Must justify with '0'. */
-#define VG_MSG_LJUSTIFY 4 /* Must justify on the left. */
-#define VG_MSG_PAREN 8 /* Parenthesize if present (for %y) */
-#define VG_MSG_COMMA 16 /* Add commas to numbers (for %d, %u) */
-
-/* Copy a string into the buffer. */
-static UInt
-myvprintf_str ( void(*send)(HChar), Int flags, Int width, HChar* str,
- Bool capitalise )
-{
-# define MAYBE_TOUPPER(ch) (capitalise ? vexxx_toupper(ch) : (ch))
- UInt ret = 0;
- Int i, extra;
- Int len = vexxx_strlen(str);
-
- if (width == 0) {
- ret += len;
- for (i = 0; i < len; i++)
- send(MAYBE_TOUPPER(str[i]));
- return ret;
- }
-
- if (len > width) {
- ret += width;
- for (i = 0; i < width; i++)
- send(MAYBE_TOUPPER(str[i]));
- return ret;
- }
-
- extra = width - len;
- if (flags & VG_MSG_LJUSTIFY) {
- ret += extra;
- for (i = 0; i < extra; i++)
- send(' ');
- }
- ret += len;
- for (i = 0; i < len; i++)
- send(MAYBE_TOUPPER(str[i]));
- if (!(flags & VG_MSG_LJUSTIFY)) {
- ret += extra;
- for (i = 0; i < extra; i++)
- send(' ');
- }
-
-# undef MAYBE_TOUPPER
-
- return ret;
-}
-
-/* Write P into the buffer according to these args:
- * If SIGN is true, p is a signed.
- * BASE is the base.
- * If WITH_ZERO is true, '0' must be added.
- * WIDTH is the width of the field.
- */
-static UInt
-myvprintf_int64 ( void(*send)(HChar), Int flags, Int base, Int width, ULong pL)
-{
- HChar buf[40];
- Int ind = 0;
- Int i, nc = 0;
- Bool neg = False;
- HChar *digits = "0123456789ABCDEF";
- UInt ret = 0;
- UInt p = (UInt)pL;
-
- if (base < 2 || base > 16)
- return ret;
-
- if ((flags & VG_MSG_SIGNED) && (Int)p < 0) {
- p = - (Int)p;
- neg = True;
- }
-
- if (p == 0)
- buf[ind++] = '0';
- else {
- while (p > 0) {
- if ((flags & VG_MSG_COMMA) && 10 == base &&
- 0 == (ind-nc) % 3 && 0 != ind)
- {
- buf[ind++] = ',';
- nc++;
- }
- buf[ind++] = digits[p % base];
- p /= base;
- }
- }
-
- if (neg)
- buf[ind++] = '-';
-
- if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) {
- for(; ind < width; ind++) {
- //vassert(ind < 39);
- buf[ind] = ((flags & VG_MSG_ZJUSTIFY) ? '0': ' ');
- }
- }
-
- /* Reverse copy to buffer. */
- ret += ind;
- for (i = ind -1; i >= 0; i--) {
- send(buf[i]);
- }
- if (width > 0 && (flags & VG_MSG_LJUSTIFY)) {
- for(; ind < width; ind++) {
- ret++;
- send(' '); // Never pad with zeroes on RHS -- changes the value!
- }
- }
- return ret;
-}
-
-
-/* A simple vprintf(). */
-static
-UInt vprintf_wrk ( void(*send)(HChar), const HChar *format, va_list vargs )
-{
- UInt ret = 0;
- int i;
- int flags;
- int width;
- Bool is_long;
-
- /* We assume that vargs has already been initialised by the
- caller, using va_start, and that the caller will similarly
- clean up with va_end.
- */
-
- for (i = 0; format[i] != 0; i++) {
- if (format[i] != '%') {
- send(format[i]);
- ret++;
- continue;
- }
- i++;
- /* A '%' has been found. Ignore a trailing %. */
- if (format[i] == 0)
- break;
- if (format[i] == '%') {
- /* `%%' is replaced by `%'. */
- send('%');
- ret++;
- continue;
- }
- flags = 0;
- is_long = False;
- width = 0; /* length of the field. */
- if (format[i] == '(') {
- flags |= VG_MSG_PAREN;
- i++;
- }
- /* If ',' follows '%', commas will be inserted. */
- if (format[i] == ',') {
- flags |= VG_MSG_COMMA;
- i++;
- }
- /* If '-' follows '%', justify on the left. */
- if (format[i] == '-') {
- flags |= VG_MSG_LJUSTIFY;
- i++;
- }
- /* If '0' follows '%', pads will be inserted. */
- if (format[i] == '0') {
- flags |= VG_MSG_ZJUSTIFY;
- i++;
- }
- /* Compute the field length. */
- while (format[i] >= '0' && format[i] <= '9') {
- width *= 10;
- width += format[i++] - '0';
- }
- while (format[i] == 'l') {
- i++;
- is_long = True;
- }
-
- switch (format[i]) {
- case 'd': /* %d */
- flags |= VG_MSG_SIGNED;
- if (is_long)
- ret += myvprintf_int64(send, flags, 10, width,
- (ULong)(va_arg (vargs, Long)));
- else
- ret += myvprintf_int64(send, flags, 10, width,
- (ULong)(va_arg (vargs, Int)));
- break;
- case 'u': /* %u */
- if (is_long)
- ret += myvprintf_int64(send, flags, 10, width,
- (ULong)(va_arg (vargs, ULong)));
- else
- ret += myvprintf_int64(send, flags, 10, width,
- (ULong)(va_arg (vargs, UInt)));
- break;
- case 'p': /* %p */
- ret += 2;
- send('0');
- send('x');
- ret += myvprintf_int64(send, flags, 16, width,
- (ULong)((HWord)va_arg (vargs, void *)));
- break;
- case 'x': /* %x */
- if (is_long)
- ret += myvprintf_int64(send, flags, 16, width,
- (ULong)(va_arg (vargs, ULong)));
- else
- ret += myvprintf_int64(send, flags, 16, width,
- (ULong)(va_arg (vargs, UInt)));
- break;
- case 'c': /* %c */
- ret++;
- send((va_arg (vargs, int)));
- break;
- case 's': case 'S': { /* %s */
- char *str = va_arg (vargs, char *);
- if (str == (char*) 0) str = "(null)";
- ret += myvprintf_str(send, flags, width, str,
- (format[i]=='S'));
- break;
- }
-# if 0
- case 'y': { /* %y - print symbol */
- Addr a = va_arg(vargs, Addr);
-
- HChar *name;
- if (VG_(get_fnname_w_offset)(a, &name)) {
- HChar buf[1 + VG_strlen(name) + 1 + 1];
- if (flags & VG_MSG_PAREN) {
- VG_(sprintf)(str, "(%s)", name):
- } else {
- VG_(sprintf)(str, "%s", name):
- }
- ret += myvprintf_str(send, flags, width, buf, 0);
- }
- break;
- }
-# endif
- default:
- break;
- }
- }
- return ret;
-}
-
-
-/* A general replacement for printf(). Note that only low-level
- debugging info should be sent via here. The official route is to
- to use vg_message(). This interface is deprecated.
-*/
-static HChar myprintf_buf[1000];
-static Int n_myprintf_buf;
-
-static void add_to_myprintf_buf ( HChar c )
-{
- if (c == '\n' || n_myprintf_buf >= 1000-10 /*paranoia*/ ) {
- (*vexxx_log_bytes)( myprintf_buf, vexxx_strlen(myprintf_buf) );
- n_myprintf_buf = 0;
- myprintf_buf[n_myprintf_buf] = 0;
- }
- myprintf_buf[n_myprintf_buf++] = c;
- myprintf_buf[n_myprintf_buf] = 0;
-}
-
-static UInt vexxx_printf ( const char *format, ... )
-{
- UInt ret;
- va_list vargs;
- va_start(vargs,format);
-
- n_myprintf_buf = 0;
- myprintf_buf[n_myprintf_buf] = 0;
- ret = vprintf_wrk ( add_to_myprintf_buf, format, vargs );
-
- if (n_myprintf_buf > 0) {
- (*vexxx_log_bytes)( myprintf_buf, n_myprintf_buf );
- }
-
- va_end(vargs);
-
- return ret;
-}
-
-/*---------------------------------------------------------------*/
-/*--- end vex_util.c ---*/
-/*---------------------------------------------------------------*/
-
-
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-
-// BEGIN #include "ops-ppc.c"
-/*
- * WARNING:
- * This file has been auto-generated by './gen-ppc' program
- * Please don't edit by hand
- */
-
-
-//BEGIN #include "test-ppc.h"
-/*
- * test-ppc.h:
- * PPC tests for qemu-PPC CPU emulation checks - definitions
- *
- * Copyright (c) 2005 Jocelyn Mayer
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License V2
- * as published by the Free Software Foundation.
- */
-
-#if !defined (__TEST_PPC_H__)
-#define __TEST_PPC_H__
-
-typedef void (*test_func_t) (void);
-typedef struct test_t test_t;
-typedef struct test_table_t test_table_t;
-struct test_t {
- test_func_t func;
- const unsigned char *name;
-};
-
-struct test_table_t {
- test_t *tests;
- const unsigned char *name;
- int flags;
-};
-
-typedef void (*test_loop_t) (const unsigned char *name, test_func_t func);
-
-enum test_flags {
- /* Nb arguments */
- PPC_ONE_ARG = 0x00000001,
- PPC_TWO_ARGS = 0x00000002,
- PPC_THREE_ARGS = 0x00000003,
- PPC_CMP_ARGS = 0x00000004,
- PPC_CMPI_ARGS = 0x00000005,
- PPC_TWO_I16 = 0x00000006,
- PPC_SPECIAL = 0x00000007,
- PPC_NB_ARGS = 0x0000000F,
- /* Type */
- PPC_ARITH = 0x00000100,
- PPC_LOGICAL = 0x00000200,
- PPC_COMPARE = 0x00000300,
- PPC_CROP = 0x00000400,
- PPC_TYPE = 0x00000F00,
- /* Family */
- PPC_INTEGER = 0x00010000,
- PPC_FLOAT = 0x00020000,
- PPC_405 = 0x00030000,
- PPC_ALTIVEC = 0x00040000,
- PPC_FALTIVEC = 0x00050000,
- PPC_FAMILY = 0x000F0000,
- /* Flags */
- PPC_CR = 0x01000000,
-};
-
-#endif /* !defined (__TEST_PPC_H__) */
-
-//END #include "test-ppc.h"
-
-static void test_add (void)
-{
- __asm__ __volatile__ ("add 17, 14, 15");
-}
-
-static void test_addo (void)
-{
- __asm__ __volatile__ ("addo 17, 14, 15");
-}
-
-static void test_addc (void)
-{
- __asm__ __volatile__ ("addc 17, 14, 15");
-}
-
-static void test_addco (void)
-{
- __asm__ __volatile__ ("addco 17, 14, 15");
-}
-
-static void test_adde (void)
-{
- __asm__ __volatile__ ("adde 17, 14, 15");
-}
-
-static void test_addeo (void)
-{
- __asm__ __volatile__ ("addeo 17, 14, 15");
-}
-
-static void test_divw (void)
-{
- __asm__ __volatile__ ("divw 17, 14, 15");
-}
-
-static void test_divwo (void)
-{
- __asm__ __volatile__ ("divwo 17, 14, 15");
-}
-
-static void test_divwu (void)
-{
- __asm__ __volatile__ ("divwu 17, 14, 15");
-}
-
-static void test_divwuo (void)
-{
- __asm__ __volatile__ ("divwuo 17, 14, 15");
-}
-
-static void test_mulhw (void)
-{
- __asm__ __volatile__ ("mulhw 17, 14, 15");
-}
-
-static void test_mulhwu (void)
-{
- __asm__ __volatile__ ("mulhwu 17, 14, 15");
-}
-
-static void test_mullw (void)
-{
- __asm__ __volatile__ ("mullw 17, 14, 15");
-}
-
-static void test_mullwo (void)
-{
- __asm__ __volatile__ ("mullwo 17, 14, 15");
-}
-
-static void test_subf (void)
-{
- __asm__ __volatile__ ("subf 17, 14, 15");
-}
-
-static void test_subfo (void)
-{
- __asm__ __volatile__ ("subfo 17, 14, 15");
-}
-
-static void test_subfc (void)
-{
- __asm__ __volatile__ ("subfc 17, 14, 15");
-}
-
-static void test_subfco (void)
-{
- __asm__ __volatile__ ("subfco 17, 14, 15");
-}
-
-static void test_subfe (void)
-{
- __asm__ __volatile__ ("subfe 17, 14, 15");
-}
-
-static void test_subfeo (void)
-{
- __asm__ __volatile__ ("subfeo 17, 14, 15");
-}
-
-static test_t tests_ia_ops_two[] = {
- { &test_add , " add", },
- { &test_addo , " addo", },
- { &test_addc , " addc", },
- { &test_addco , " addco", },
- { &test_adde , " adde", },
- { &test_addeo , " addeo", },
- { &test_divw , " divw", },
- { &test_divwo , " divwo", },
- { &test_divwu , " divwu", },
- { &test_divwuo , " divwuo", },
- { &test_mulhw , " mulhw", },
- { &test_mulhwu , " mulhwu", },
- { &test_mullw , " mullw", },
- { &test_mullwo , " mullwo", },
- { &test_subf , " subf", },
- { &test_subfo , " subfo", },
- { &test_subfc , " subfc", },
- { &test_subfco , " subfco", },
- { &test_subfe , " subfe", },
- { &test_subfeo , " subfeo", },
- { NULL, NULL, },
-};
-
-static void test_add_ (void)
-{
- __asm__ __volatile__ ("add. 17, 14, 15");
-}
-
-static void test_addo_ (void)
-{
- __asm__ __volatile__ ("addo. 17, 14, 15");
-}
-
-static void test_addc_ (void)
-{
- __asm__ __volatile__ ("addc. 17, 14, 15");
-}
-
-static void test_addco_ (void)
-{
- __asm__ __volatile__ ("addco. 17, 14, 15");
-}
-
-static void test_adde_ (void)
-{
- __asm__ __volatile__ ("adde. 17, 14, 15");
-}
-
-static void test_addeo_ (void)
-{
- __asm__ __volatile__ ("addeo. 17, 14, 15");
-}
-
-static void test_divw_ (void)
-{
- __asm__ __volatile__ ("divw. 17, 14, 15");
-}
-
-static void test_divwo_ (void)
-{
- __asm__ __volatile__ ("divwo. 17, 14, 15");
-}
-
-static void test_divwu_ (void)
-{
- __asm__ __volatile__ ("divwu. 17, 14, 15");
-}
-
-static void test_divwuo_ (void)
-{
- __asm__ __volatile__ ("divwuo. 17, 14, 15");
-}
-
-static void test_subf_ (void)
-{
- __asm__ __volatile__ ("subf. 17, 14, 15");
-}
-
-static void test_subfo_ (void)
-{
- __asm__ __volatile__ ("subfo. 17, 14, 15");
-}
-
-static void test_subfc_ (void)
-{
- __asm__ __volatile__ ("subfc. 17, 14, 15");
-}
-
-static void test_subfco_ (void)
-{
- __asm__ __volatile__ ("subfco. 17, 14, 15");
-}
-
-static void test_subfe_ (void)
-{
- __asm__ __volatile__ ("subfe. 17, 14, 15");
-}
-
-static void test_subfeo_ (void)
-{
- __asm__ __volatile__ ("subfeo. 17, 14, 15");
-}
-
-static test_t tests_iar_ops_two[] = {
- { &test_add_ , " add.", },
- { &test_addo_ , " addo.", },
- { &test_addc_ , " addc.", },
- { &test_addco_ , " addco.", },
- { &test_adde_ , " adde.", },
- { &test_addeo_ , " addeo.", },
- { &test_divw_ , " divw.", },
- { &test_divwo_ , " divwo.", },
- { &test_divwu_ , " divwu.", },
- { &test_divwuo_ , " divwuo.", },
- { &test_subf_ , " subf.", },
- { &test_subfo_ , " subfo.", },
- { &test_subfc_ , " subfc.", },
- { &test_subfco_ , " subfco.", },
- { &test_subfe_ , " subfe.", },
- { &test_subfeo_ , " subfeo.", },
- { NULL, NULL, },
-};
-
-static void test_and (void)
-{
- __asm__ __volatile__ ("and 17, 14, 15");
-}
-
-static void test_andc (void)
-{
- __asm__ __volatile__ ("andc 17, 14, 15");
-}
-
-static void test_eqv (void)
-{
- __asm__ __volatile__ ("eqv 17, 14, 15");
-}
-
-static void test_nand (void)
-{
- __asm__ __volatile__ ("nand 17, 14, 15");
-}
-
-static void test_nor (void)
-{
- __asm__ __volatile__ ("nor 17, 14, 15");
-}
-
-static void test_or (void)
-{
- __asm__ __volatile__ ("or 17, 14, 15");
-}
-
-static void test_orc (void)
-{
- __asm__ __volatile__ ("orc 17, 14, 15");
-}
-
-static void test_xor (void)
-{
- __asm__ __volatile__ ("xor 17, 14, 15");
-}
-
-static void test_slw (void)
-{
- __asm__ __volatile__ ("slw 17, 14, 15");
-}
-
-static void test_sraw (void)
-{
- __asm__ __volatile__ ("sraw 17, 14, 15");
-}
-
-static void test_srw (void)
-{
- __asm__ __volatile__ ("srw 17, 14, 15");
-}
-
-static test_t tests_il_ops_two[] = {
- { &test_and , " and", },
- { &test_andc , " andc", },
- { &test_eqv , " eqv", },
- { &test_nand , " nand", },
- { &test_nor , " nor", },
- { &test_or , " or", },
- { &test_orc , " orc", },
- { &test_xor , " xor", },
- { &test_slw , " slw", },
- { &test_sraw , " sraw", },
- { &test_srw , " srw", },
- { NULL, NULL, },
-};
-
-static void test_and_ (void)
-{
- __asm__ __volatile__ ("and. 17, 14, 15");
-}
-
-static void test_andc_ (void)
-{
- __asm__ __volatile__ ("andc. 17, 14, 15");
-}
-
-static void test_eqv_ (void)
-{
- __asm__ __volatile__ ("eqv. 17, 14, 15");
-}
-
-static void test_mulhw_ (void)
-{
- __asm__ __volatile__ ("mulhw. 17, 14, 15");
-}
-
-static void test_mulhwu_ (void)
-{
- __asm__ __volatile__ ("mulhwu. 17, 14, 15");
-}
-
-static void test_mullw_ (void)
-{
- __asm__ __volatile__ ("mullw. 17, 14, 15");
-}
-
-static void test_mullwo_ (void)
-{
- __asm__ __volatile__ ("mullwo. 17, 14, 15");
-}
-
-static void test_nand_ (void)
-{
- __asm__ __volatile__ ("nand. 17, 14, 15");
-}
-
-static void test_nor_ (void)
-{
- __asm__ __volatile__ ("nor. 17, 14, 15");
-}
-
-static void test_or_ (void)
-{
- __asm__ __volatile__ ("or. 17, 14, 15");
-}
-
-static void test_orc_ (void)
-{
- __asm__ __volatile__ ("orc. 17, 14, 15");
-}
-
-static void test_xor_ (void)
-{
- __asm__ __volatile__ ("xor. 17, 14, 15");
-}
-
-static void test_slw_ (void)
-{
- __asm__ __volatile__ ("slw. 17, 14, 15");
-}
-
-static void test_sraw_ (void)
-{
- __asm__ __volatile__ ("sraw. 17, 14, 15");
-}
-
-static void test_srw_ (void)
-{
- __asm__ __volatile__ ("srw. 17, 14, 15");
-}
-
-static test_t tests_ilr_ops_two[] = {
- { &test_and_ , " and.", },
- { &test_andc_ , " andc.", },
- { &test_eqv_ , " eqv.", },
- { &test_mulhw_ , " mulhw.", },
- { &test_mulhwu_ , " mulhwu.", },
- { &test_mullw_ , " mullw.", },
- { &test_mullwo_ , " mullwo.", },
- { &test_nand_ , " nand.", },
- { &test_nor_ , " nor.", },
- { &test_or_ , " or.", },
- { &test_orc_ , " orc.", },
- { &test_xor_ , " xor.", },
- { &test_slw_ , " slw.", },
- { &test_sraw_ , " sraw.", },
- { &test_srw_ , " srw.", },
- { NULL, NULL, },
-};
-
-static void test_cmp (void)
-{
- __asm__ __volatile__ ("cmp 2, 14, 15");
-}
-
-static void test_cmpl (void)
-{
- __asm__ __volatile__ ("cmpl 2, 14, 15");
-}
-
-static test_t tests_icr_ops_two[] = {
- { &test_cmp , " cmp", },
- { &test_cmpl , " cmpl", },
- { NULL, NULL, },
-};
-
-static void test_cmpi (void)
-{
- __asm__ __volatile__ ("cmpi 2, 14, 15");
-}
-
-static void test_cmpli (void)
-{
- __asm__ __volatile__ ("cmpli 2, 14, 15");
-}
-
-static test_t tests_icr_ops_two_i16[] = {
- { &test_cmpi , " cmpi", },
- { &test_cmpli , " cmpli", },
- { NULL, NULL, },
-};
-
-static void test_addi (void)
-{
- __asm__ __volatile__ ("addi 17, 14, 0");
-}
-
-static void test_addic (void)
-{
- __asm__ __volatile__ ("addic 17, 14, 0");
-}
-
-static void test_addis (void)
-{
- __asm__ __volatile__ ("addis 17, 14, 0");
-}
-
-static void test_mulli (void)
-{
- __asm__ __volatile__ ("mulli 17, 14, 0");
-}
-
-static void test_subfic (void)
-{
- __asm__ __volatile__ ("subfic 17, 14, 0");
-}
-
-static test_t tests_ia_ops_two_i16[] = {
- { &test_addi , " addi", },
- { &test_addic , " addic", },
- { &test_addis , " addis", },
- { &test_mulli , " mulli", },
- { &test_subfic , " subfic", },
- { NULL, NULL, },
-};
-
-static void test_addic_ (void)
-{
- __asm__ __volatile__ ("addic. 17, 14, 0");
-}
-
-static test_t tests_iar_ops_two_i16[] = {
- { &test_addic_ , " addic.", },
- { NULL, NULL, },
-};
-
-static void test_ori (void)
-{
- __asm__ __volatile__ ("ori 17, 14, 0");
-}
-
-static void test_oris (void)
-{
- __asm__ __volatile__ ("oris 17, 14, 0");
-}
-
-static void test_xori (void)
-{
- __asm__ __volatile__ ("xori 17, 14, 0");
-}
-
-static void test_xoris (void)
-{
- __asm__ __volatile__ ("xoris 17, 14, 0");
-}
-
-static test_t tests_il_ops_two_i16[] = {
- { &test_ori , " ori", },
- { &test_oris , " oris", },
- { &test_xori , " xori", },
- { &test_xoris , " xoris", },
- { NULL, NULL, },
-};
-
-static void test_andi_ (void)
-{
- __asm__ __volatile__ ("andi. 17, 14, 0");
-}
-
-static void test_andis_ (void)
-{
- __asm__ __volatile__ ("andis. 17, 14, 0");
-}
-
-static test_t tests_ilr_ops_two_i16[] = {
- { &test_andi_ , " andi.", },
- { &test_andis_ , " andis.", },
- { NULL, NULL, },
-};
-
-static void test_crand (void)
-{
- __asm__ __volatile__ ("crand 17, 14, 15");
-}
-
-static void test_crandc (void)
-{
- __asm__ __volatile__ ("crandc 17, 14, 15");
-}
-
-static void test_creqv (void)
-{
- __asm__ __volatile__ ("creqv 17, 14, 15");
-}
-
-static void test_crnand (void)
-{
- __asm__ __volatile__ ("crnand 17, 14, 15");
-}
-
-static void test_crnor (void)
-{
- __asm__ __volatile__ ("crnor 17, 14, 15");
-}
-
-static void test_cror (void)
-{
- __asm__ __volatile__ ("cror 17, 14, 15");
-}
-
-static void test_crorc (void)
-{
- __asm__ __volatile__ ("crorc 17, 14, 15");
-}
-
-static void test_crxor (void)
-{
- __asm__ __volatile__ ("crxor 17, 14, 15");
-}
-
-static test_t tests_crl_ops_two[] = {
- { &test_crand , " crand", },
- { &test_crandc , " crandc", },
- { &test_creqv , " creqv", },
- { &test_crnand , " crnand", },
- { &test_crnor , " crnor", },
- { &test_cror , " cror", },
- { &test_crorc , " crorc", },
- { &test_crxor , " crxor", },
- { NULL, NULL, },
-};
-
-static void test_addme (void)
-{
- __asm__ __volatile__ ("addme 17, 14");
-}
-
-static void test_addmeo (void)
-{
- __asm__ __volatile__ ("addmeo 17, 14");
-}
-
-static void test_addze (void)
-{
- __asm__ __volatile__ ("addze 17, 14");
-}
-
-static void test_addzeo (void)
-{
- __asm__ __volatile__ ("addzeo 17, 14");
-}
-
-static void test_subfme (void)
-{
- __asm__ __volatile__ ("subfme 17, 14");
-}
-
-static void test_subfmeo (void)
-{
- __asm__ __volatile__ ("subfmeo 17, 14");
-}
-
-static void test_subfze (void)
-{
- __asm__ __volatile__ ("subfze 17, 14");
-}
-
-static void test_subfzeo (void)
-{
- __asm__ __volatile__ ("subfzeo 17, 14");
-}
-
-static test_t tests_ia_ops_one[] = {
- { &test_addme , " addme", },
- { &test_addmeo , " addmeo", },
- { &test_addze , " addze", },
- { &test_addzeo , " addzeo", },
- { &test_subfme , " subfme", },
- { &test_subfmeo , " subfmeo", },
- { &test_subfze , " subfze", },
- { &test_subfzeo , " subfzeo", },
- { NULL, NULL, },
-};
-
-static void test_addme_ (void)
-{
- __asm__ __volatile__ ("addme. 17, 14");
-}
-
-static void test_addmeo_ (void)
-{
- __asm__ __volatile__ ("addmeo. 17, 14");
-}
-
-static void test_addze_ (void)
-{
- __asm__ __volatile__ ("addze. 17, 14");
-}
-
-static void test_addzeo_ (void)
-{
- __asm__ __volatile__ ("addzeo. 17, 14");
-}
-
-static void test_subfme_ (void)
-{
- __asm__ __volatile__ ("subfme. 17, 14");
-}
-
-static void test_subfmeo_ (void)
-{
- __asm__ __volatile__ ("subfmeo. 17, 14");
-}
-
-static void test_subfze_ (void)
-{
- __asm__ __volatile__ ("subfze. 17, 14");
-}
-
-static void test_subfzeo_ (void)
-{
- __asm__ __volatile__ ("subfzeo. 17, 14");
-}
-
-static test_t tests_iar_ops_one[] = {
- { &test_addme_ , " addme.", },
- { &test_addmeo_ , " addmeo.", },
- { &test_addze_ , " addze.", },
- { &test_addzeo_ , " addzeo.", },
- { &test_subfme_ , " subfme.", },
- { &test_subfmeo_ , " subfmeo.", },
- { &test_subfze_ , " subfze.", },
- { &test_subfzeo_ , " subfzeo.", },
- { NULL, NULL, },
-};
-
-static void test_cntlzw (void)
-{
- __asm__ __volatile__ ("cntlzw 17, 14");
-}
-
-static void test_extsb (void)
-{
- __asm__ __volatile__ ("extsb 17, 14");
-}
-
-static void test_extsh (void)
-{
- __asm__ __volatile__ ("extsh 17, 14");
-}
-
-static void test_neg (void)
-{
- __asm__ __volatile__ ("neg 17, 14");
-}
-
-static void test_nego (void)
-{
- __asm__ __volatile__ ("nego 17, 14");
-}
-
-static test_t tests_il_ops_one[] = {
- { &test_cntlzw , " cntlzw", },
- { &test_extsb , " extsb", },
- { &test_extsh , " extsh", },
- { &test_neg , " neg", },
- { &test_nego , " nego", },
- { NULL, NULL, },
-};
-
-static void test_cntlzw_ (void)
-{
- __asm__ __volatile__ ("cntlzw. 17, 14");
-}
-
-static void test_extsb_ (void)
-{
- __asm__ __volatile__ ("extsb. 17, 14");
-}
-
-static void test_extsh_ (void)
-{
- __asm__ __volatile__ ("extsh. 17, 14");
-}
-
-static void test_neg_ (void)
-{
- __asm__ __volatile__ ("neg. 17, 14");
-}
-
-static void test_nego_ (void)
-{
- __asm__ __volatile__ ("nego. 17, 14");
-}
-
-static test_t tests_ilr_ops_one[] = {
- { &test_cntlzw_ , " cntlzw.", },
- { &test_extsb_ , " extsb.", },
- { &test_extsh_ , " extsh.", },
- { &test_neg_ , " neg.", },
- { &test_nego_ , " nego.", },
- { NULL, NULL, },
-};
-
-static void test_rlwimi (void)
-{
- __asm__ __volatile__ ("rlwimi 17, 14, 0, 0, 0");
-}
-
-static void test_rlwinm (void)
-{
- __asm__ __volatile__ ("rlwinm 17, 14, 0, 0, 0");
-}
-
-static void test_rlwnm (void)
-{
- __asm__ __volatile__ ("rlwnm 17, 14, 15, 0, 0");
-}
-
-static void test_srawi (void)
-{
- __asm__ __volatile__ ("srawi 17, 14, 0");
-}
-
-static test_t tests_il_ops_spe[] = {
- { &test_rlwimi , " rlwimi", },
- { &test_rlwinm , " rlwinm", },
- { &test_rlwnm , " rlwnm", },
- { &test_srawi , " srawi", },
- { NULL, NULL, },
-};
-
-static void test_rlwimi_ (void)
-{
- __asm__ __volatile__ ("rlwimi. 17, 14, 0, 0, 0");
-}
-
-static void test_rlwinm_ (void)
-{
- __asm__ __volatile__ ("rlwinm. 17, 14, 0, 0, 0");
-}
-
-static void test_rlwnm_ (void)
-{
- __asm__ __volatile__ ("rlwnm. 17, 14, 15, 0, 0");
-}
-
-static void test_srawi_ (void)
-{
- __asm__ __volatile__ ("srawi. 17, 14, 0");
-}
-
-static test_t tests_ilr_ops_spe[] = {
- { &test_rlwimi_ , " rlwimi.", },
- { &test_rlwinm_ , " rlwinm.", },
- { &test_rlwnm_ , " rlwnm.", },
- { &test_srawi_ , " srawi.", },
- { NULL, NULL, },
-};
-
-#if !defined (NO_FLOAT)
-static void test_fsel (void)
-{
- __asm__ __volatile__ ("fsel 17, 14, 15, 16");
-}
-
-static void test_fmadd (void)
-{
- __asm__ __volatile__ ("fmadd 17, 14, 15, 16");
-}
-
-static void test_fmadds (void)
-{
- __asm__ __volatile__ ("fmadds 17, 14, 15, 16");
-}
-
-static void test_fmsub (void)
-{
- __asm__ __volatile__ ("fmsub 17, 14, 15, 16");
-}
-
-static void test_fmsubs (void)
-{
- __asm__ __volatile__ ("fmsubs 17, 14, 15, 16");
-}
-
-static void test_fnmadd (void)
-{
- __asm__ __volatile__ ("fnmadd 17, 14, 15, 16");
-}
-
-static void test_fnmadds (void)
-{
- __asm__ __volatile__ ("fnmadds 17, 14, 15, 16");
-}
-
-static void test_fnmsub (void)
-{
- __asm__ __volatile__ ("fnmsub 17, 14, 15, 16");
-}
-
-static void test_fnmsubs (void)
-{
- __asm__ __volatile__ ("fnmsubs 17, 14, 15, 16");
-}
-
-static test_t tests_fa_ops_three[] = {
- { &test_fsel , " fsel", },
- { &test_fmadd , " fmadd", },
- { &test_fmadds , " fmadds", },
- { &test_fmsub , " fmsub", },
- { &test_fmsubs , " fmsubs", },
- { &test_fnmadd , " fnmadd", },
- { &test_fnmadds , " fnmadds", },
- { &test_fnmsub , " fnmsub", },
- { &test_fnmsubs , " fnmsubs", },
- { NULL, NULL, },
-};
-#endif /* !defined (NO_FLOAT) */
-
-#if !defined (NO_FLOAT)
-static void test_fsel_ (void)
-{
- __asm__ __volatile__ ("fsel. 17, 14, 15, 16");
-}
-
-static void test_fmadd_ (void)
-{
- __asm__ __volatile__ ("fmadd. 17, 14, 15, 16");
-}
-
-static void test_fmadds_ (void)
-{
- __asm__ __volatile__ ("fmadds. 17, 14, 15, 16");
-}
-
-static void test_fmsub_ (void)
-{
- __asm__ __volatile__ ("fmsub. 17, 14, 15, 16");
-}
-
-static void test_fmsubs_ (void)
-{
- __asm__ __volatile__ ("fmsubs. 17, 14, 15, 16");
-}
-
-static void test_fnmadd_ (void)
-{
- __asm__ __volatile__ ("fnmadd. 17, 14, 15, 16");
-}
-
-static void test_fnmadds_ (void)
-{
- __asm__ __volatile__ ("fnmadds. 17, 14, 15, 16");
-}
-
-static void test_fnmsub_ (void)
-{
- __asm__ __volatile__ ("fnmsub. 17, 14, 15, 16");
-}
-
-static void test_fnmsubs_ (void)
-{
- __asm__ __volatile__ ("fnmsubs. 17, 14, 15, 16");
-}
-
-static test_t tests_far_ops_three[] = {
- { &test_fsel_ , " fsel.", },
- { &test_fmadd_ , " fmadd.", },
- { &test_fmadds_ , " fmadds.", },
- { &test_fmsub_ , " fmsub.", },
- { &test_fmsubs_ , " fmsubs.", },
- { &test_fnmadd_ , " fnmadd.", },
- { &test_fnmadds_ , " fnmadds.", },
- { &test_fnmsub_ , " fnmsub.", },
- { &test_fnmsubs_ , " fnmsubs.", },
- { NULL, NULL, },
-};
-#endif /* !defined (NO_FLOAT) */
-
-#if !defined (NO_FLOAT)
-static void test_fadd (void)
-{
- __asm__ __volatile__ ("fadd 17, 14, 15");
-}
-
-static void test_fadds (void)
-{
- __asm__ __volatile__ ("fadds 17, 14, 15");
-}
-
-static void test_fsub (void)
-{
- __asm__ __volatile__ ("fsub 17, 14, 15");
-}
-
-static void test_fsubs (void)
-{
- __asm__ __volatile__ ("fsubs 17, 14, 15");
-}
-
-static void test_fmul (void)
-{
- __asm__ __volatile__ ("fmul 17, 14, 15");
-}
-
-static void test_fmuls (void)
-{
- __asm__ __volatile__ ("fmuls 17, 14, 15");
-}
-
-static void test_fdiv (void)
-{
- __asm__ __volatile__ ("fdiv 17, 14, 15");
-}
-
-static void test_fdivs (void)
-{
- __asm__ __volatile__ ("fdivs 17, 14, 15");
-}
-
-static test_t tests_fa_ops_two[] = {
- { &test_fadd , " fadd", },
- { &test_fadds , " fadds", },
- { &test_fsub , " fsub", },
- { &test_fsubs , " fsubs", },
- { &test_fmul , " fmul", },
- { &test_fmuls , " fmuls", },
- { &test_fdiv , " fdiv", },
- { &test_fdivs , " fdivs", },
- { NULL, NULL, },
-};
-#endif /* !defined (NO_FLOAT) */
-
-#if !defined (NO_FLOAT)
-static void test_fadd_ (void)
-{
- __asm__ __volatile__ ("fadd. 17, 14, 15");
-}
-
-static void test_fadds_ (void)
-{
- __asm__ __volatile__ ("fadds. 17, 14, 15");
-}
-
-static void test_fsub_ (void)
-{
- __asm__ __volatile__ ("fsub. 17, 14, 15");
-}
-
-static void test_fsubs_ (void)
-{
- __asm__ __volatile__ ("fsubs. 17, 14, 15");
-}
-
-static void test_fmul_ (void)
-{
- __asm__ __volatile__ ("fmul. 17, 14, 15");
-}
-
-static void test_fmuls_ (void)
-{
- __asm__ __volatile__ ("fmuls. 17, 14, 15");
-}
-
-static void test_fdiv_ (void)
-{
- __asm__ __volatile__ ("fdiv. 17, 14, 15");
-}
-
-static void test_fdivs_ (void)
-{
- __asm__ __volatile__ ("fdivs. 17, 14, 15");
-}
-
-static test_t tests_far_ops_two[] = {
- { &test_fadd_ , " fadd.", },
- { &test_fadds_ , " fadds.", },
- { &test_fsub_ , " fsub.", },
- { &test_fsubs_ , " fsubs.", },
- { &test_fmul_ , " fmul.", },
- { &test_fmuls_ , " fmuls.", },
- { &test_fdiv_ , " fdiv.", },
- { &test_fdivs_ , " fdivs.", },
- { NULL, NULL, },
-};
-#endif /* !defined (NO_FLOAT) */
-
-#if !defined (NO_FLOAT)
-static void test_fcmpo (void)
-{
- __asm__ __volatile__ ("fcmpo 2, 14, 15");
-}
-
-static void test_fcmpu (void)
-{
- __asm__ __volatile__ ("fcmpu 2, 14, 15");
-}
-
-static test_t tests_fcr_ops_two[] = {
- { &test_fcmpo , " fcmpo", },
- { &test_fcmpu , " fcmpu", },
- { NULL, NULL, },
-};
-#endif /* !defined (NO_FLOAT) */
-
-#if !defined (NO_FLOAT)
-static void test_fres (void)
-{
- __asm__ __volatile__ ("fres 17, 14");
-}
-
-static void test_frsqrte (void)
-{
- __asm__ __volatile__ ("frsqrte 17, 14");
-}
-
-static void test_frsp (void)
-{
- __asm__ __volatile__ ("frsp 17, 14");
-}
-
-static void test_fctiw (void)
-{
- __asm__ __volatile__ ("fctiw 17, 14");
-}
-
-static void test_fctiwz (void)
-{
- __asm__ __volatile__ ("fctiwz 17, 14");
-}
-
-static void test_fmr (void)
-{
- __asm__ __volatile__ ("fmr 17, 14");
-}
-
-static void test_fneg (void)
-{
- __asm__ __volatile__ ("fneg 17, 14");
-}
-
-static void test_fabs (void)
-{
- __asm__ __volatile__ ("fabs 17, 14");
-}
-
-static void test_fnabs (void)
-{
- __asm__ __volatile__ ("fnabs 17, 14");
-}
-
-static test_t tests_fa_ops_one[] = {
- { &test_fres , " fres", },
- { &test_frsqrte , " frsqrte", },
- { &test_frsp , " frsp", },
- { &test_fctiw , " fctiw", },
- { &test_fctiwz , " fctiwz", },
- { &test_fmr , " fmr", },
- { &test_fneg , " fneg", },
- { &test_fabs , " fabs", },
- { &test_fnabs , " fnabs", },
- { NULL, NULL, },
-};
-#endif /* !defined (NO_FLOAT) */
-
-#if !defined (NO_FLOAT)
-static void test_fres_ (void)
-{
- __asm__ __volatile__ ("fres. 17, 14");
-}
-
-static void test_frsqrte_ (void)
-{
- __asm__ __volatile__ ("frsqrte. 17, 14");
-}
-
-static void test_frsp_ (void)
-{
- __asm__ __volatile__ ("frsp. 17, 14");
-}
-
-static void test_fctiw_ (void)
-{
- __asm__ __volatile__ ("fctiw. 17, 14");
-}
-
-static void test_fctiwz_ (void)
-{
- __asm__ __volatile__ ("fctiwz. 17, 14");
-}
-
-static void test_fmr_ (void)
-{
- __asm__ __volatile__ ("fmr. 17, 14");
-}
-
-static void test_fneg_ (void)
-{
- __asm__ __volatile__ ("fneg. 17, 14");
-}
-
-static void test_fabs_ (void)
-{
- __asm__ __volatile__ ("fabs. 17, 14");
-}
-
-static void test_fnabs_ (void)
-{
- __asm__ __volatile__ ("fnabs. 17, 14");
-}
-
-static test_t tests_far_ops_one[] = {
- { &test_fres_ , " fres.", },
- { &test_frsqrte_ , " frsqrte.", },
- { &test_frsp_ , " frsp.", },
- { &test_fctiw_ , " fctiw.", },
- { &test_fctiwz_ , " fctiwz.", },
- { &test_fmr_ , " fmr.", },
- { &test_fneg_ , " fneg.", },
- { &test_fabs_ , " fabs.", },
- { &test_fnabs_ , " fnabs.", },
- { NULL, NULL, },
-};
-#endif /* !defined (NO_FLOAT) */
-
-#if !defined (NO_FLOAT)
-static test_t tests_fl_ops_spe[] = {
- { NULL, NULL, },
-};
-#endif /* !defined (NO_FLOAT) */
-
-#if !defined (NO_FLOAT)
-static test_t tests_flr_ops_spe[] = {
- { NULL, NULL, },
-};
-#endif /* !defined (NO_FLOAT) */
-
-#if defined (HAS_ALTIVEC)
-static void test_vmhaddshs (void)
-{
- __asm__ __volatile__ ("vmhaddshs 17, 14, 15, 16");
-}
-
-static void test_vmhraddshs (void)
-{
- __asm__ __volatile__ ("vmhraddshs 17, 14, 15, 16");
-}
-
-static void test_vmladduhm (void)
-{
- __asm__ __volatile__ ("vmladduhm 17, 14, 15, 16");
-}
-
-static void test_vmsumubm (void)
-{
- __asm__ __volatile__ ("vmsumubm 17, 14, 15, 16");
-}
-
-static void test_vmsumuhm (void)
-{
- __asm__ __volatile__ ("vmsumuhm 17, 14, 15, 16");
-}
-
-static void test_vmsumshs (void)
-{
- __asm__ __volatile__ ("vmsumshs 17, 14, 15, 16");
-}
-
-static void test_vmsumuhs (void)
-{
- __asm__ __volatile__ ("vmsumuhs 17, 14, 15, 16");
-}
-
-static void test_vmsummbm (void)
-{
- __asm__ __volatile__ ("vmsummbm 17, 14, 15, 16");
-}
-
-static void test_vmsumshm (void)
-{
- __asm__ __volatile__ ("vmsumshm 17, 14, 15, 16");
-}
-
-static test_t tests_aa_ops_three[] = {
- { &test_vmhaddshs , " vmhaddshs", },
- { &test_vmhraddshs , " vmhraddshs", },
- { &test_vmladduhm , " vmladduhm", },
- { &test_vmsumubm , " vmsumubm", },
- { &test_vmsumuhm , " vmsumuhm", },
- { &test_vmsumshs , " vmsumshs", },
- { &test_vmsumuhs , " vmsumuhs", },
- { &test_vmsummbm , " vmsummbm", },
- { &test_vmsumshm , " vmsumshm", },
- { NULL, NULL, },
-};
-#endif /* defined (HAS_ALTIVEC) */
-
-#if defined (HAS_ALTIVEC)
-static void test_vperm (void)
-{
- __asm__ __volatile__ ("vperm 17, 14, 15, 16");
-}
-
-static void test_vsel (void)
-{
- __asm__ __volatile__ ("vsel 17, 14, 15, 16");
-}
-
-static test_t tests_al_ops_three[] = {
- { &test_vperm , " vperm", },
- { &test_vsel , " vsel", },
- { NULL, NULL, },
-};
-#endif /* defined (HAS_ALTIVEC) */
-
-#if defined (HAS_ALTIVEC)
-static void test_vaddubm (void)
-{
- __asm__ __volatile__ ("vaddubm 17, 14, 15");
-}
-
-static void test_vadduhm (void)
-{
- __asm__ __volatile__ ("vadduhm 17, 14, 15");
-}
-
-static void test_vadduwm (void)
-{
- __asm__ __volatile__ ("vadduwm 17, 14, 15");
-}
-
-static void test_vaddubs (void)
-{
- __asm__ __volatile__ ("vaddubs 17, 14, 15");
-}
-
-static void test_vadduhs (void)
-{
- __asm__ __volatile__ ("vadduhs 17, 14, 15");
-}
-
-static void test_vadduws (void)
-{
- __asm__ __volatile__ ("vadduws 17, 14, 15");
-}
-
-static void test_vaddsbs (void)
-{
- __asm__ __volatile__ ("vaddsbs 17, 14, 15");
-}
-
-static void test_vaddshs (void)
-{
- __asm__ __volatile__ ("vaddshs 17, 14, 15");
-}
-
-static void test_vaddsws (void)
-{
- __asm__ __volatile__ ("vaddsws 17, 14, 15");
-}
-
-static void test_vaddcuw (void)
-{
- __asm__ __volatile__ ("vaddcuw 17, 14, 15");
-}
-
-static void test_vsububm (void)
-{
- __asm__ __volatile__ ("vsububm 17, 14, 15");
-}
-
-static void test_vsubuhm (void)
-{
- __asm__ __volatile__ ("vsubuhm 17, 14, 15");
-}
-
-static void test_vsubuwm (void)
-{
- __asm__ __volatile__ ("vsubuwm 17, 14, 15");
-}
-
-static void test_vsububs (void)
-{
- __asm__ __volatile__ ("vsububs 17, 14, 15");
-}
-
-static void test_vsubuhs (void)
-{
- __asm__ __volatile__ ("vsubuhs 17, 14, 15");
-}
-
-static void test_vsubuws (void)
-{
- __asm__ __volatile__ ("vsubuws 17, 14, 15");
-}
-
-static void test_vsubcuw (void)
-{
- __asm__ __volatile__ ("vsubcuw 17, 14, 15");
-}
-
-static void test_vmuloub (void)
-{
- __asm__ __volatile__ ("vmuloub 17, 14, 15");
-}
-
-static void test_vmulouh (void)
-{
- __asm__ __volatile__ ("vmulouh 17, 14, 15");
-}
-
-static void test_vmulosb (void)
-{
- __asm__ __volatile__ ("vmulosb 17, 14, 15");
-}
-
-static void test_vmulosh (void)
-{
- __asm__ __volatile__ ("vmulosh 17, 14, 15");
-}
-
-static void test_vmuleub (void)
-{
- __asm__ __volatile__ ("vmuleub 17, 14, 15");
-}
-
-static void test_vmuleuh (void)
-{
- __asm__ __volatile__ ("vmuleuh 17, 14, 15");
-}
-
-static void test_vmulesb (void)
-{
- __asm__ __volatile__ ("vmulesb 17, 14, 15");
-}
-
-static void test_vmulesh (void)
-{
- __asm__ __volatile__ ("vmulesh 17, 14, 15");
-}
-
-static void test_vsumsws (void)
-{
- __asm__ __volatile__ ("vsumsws 17, 14, 15");
-}
-
-static void test_vsum2sws (void)
-{
- __asm__ __volatile__ ("vsum2sws 17, 14, 15");
-}
-
-static void test_vsum4ubs (void)
-{
- __asm__ __volatile__ ("vsum4ubs 17, 14, 15");
-}
-
-static void test_vsum4sbs (void)
-{
- __asm__ __volatile__ ("vsum4sbs 17, 14, 15");
-}
-
-static void test_vsum4shs (void)
-{
- __asm__ __volatile__ ("vsum4shs 17, 14, 15");
-}
-
-static void test_vavgub (void)
-{
- __asm__ __volatile__ ("vavgub 17, 14, 15");
-}
-
-static void test_vavguh (void)
-{
- __asm__ __volatile__ ("vavguh 17, 14, 15");
-}
-
-static void test_vavguw (void)
-{
- __asm__ __volatile__ ("vavguw 17, 14, 15");
-}
-
-static void test_vavgsb (void)
-{
- __asm__ __volatile__ ("vavgsb 17, 14, 15");
-}
-
-static void test_vavgsh (void)
-{
- __asm__ __volatile__ ("vavgsh 17, 14, 15");
-}
-
-static void test_vavgsw (void)
-{
- __asm__ __volatile__ ("vavgsw 17, 14, 15");
-}
-
-static void test_vmaxub (void)
-{
- __asm__ __volatile__ ("vmaxub 17, 14, 15");
-}
-
-static void test_vmaxuh (void)
-{
- __asm__ __volatile__ ("vmaxuh 17, 14, 15");
-}
-
-static void test_vmaxuw (void)
-{
- __asm__ __volatile__ ("vmaxuw 17, 14, 15");
-}
-
-static void test_vmaxsb (void)
-{
- __asm__ __volatile__ ("vmaxsb 17, 14, 15");
-}
-
-static void test_vmaxsh (void)
-{
- __asm__ __volatile__ ("vmaxsh 17, 14, 15");
-}
-
-static void test_vmaxsw (void)
-{
- __asm__ __volatile__ ("vmaxsw 17, 14, 15");
-}
-
-static void test_vminub (void)
-{
- __asm__ __volatile__ ("vminub 17, 14, 15");
-}
-
-static void test_vminuh (void)
-{
- __asm__ __volatile__ ("vminuh 17, 14, 15");
-}
-
-static void test_vminuw (void)
-{
- __asm__ __volatile__ ("vminuw 17, 14, 15");
-}
-
-static void test_vminsb (void)
-{
- __asm__ __volatile__ ("vminsb 17, 14, 15");
-}
-
-static void test_vminsh (void)
-{
- __asm__ __volatile__ ("vminsh 17, 14, 15");
-}
-
-static void test_vminsw (void)
-{
- __asm__ __volatile__ ("vminsw 17, 14, 15");
-}
-
-static test_t tests_aa_ops_two[] = {
- { &test_vaddubm , " vaddubm", },
- { &test_vadduhm , " vadduhm", },
- { &test_vadduwm , " vadduwm", },
- { &test_vaddubs , " vaddubs", },
- { &test_vadduhs , " vadduhs", },
- { &test_vadduws , " vadduws", },
- { &test_vaddsbs , " vaddsbs", },
- { &test_vaddshs , " vaddshs", },
- { &test_vaddsws , " vaddsws", },
- { &test_vaddcuw , " vaddcuw", },
- { &test_vsububm , " vsububm", },
- { &test_vsubuhm , " vsubuhm", },
- { &test_vsubuwm , " vsubuwm", },
- { &test_vsububs , " vsububs", },
- { &test_vsubuhs , " vsubuhs", },
- { &test_vsubuws , " vsubuws", },
- { &test_vsubcuw , " vsubcuw", },
- { &test_vmuloub , " vmuloub", },
- { &test_vmulouh , " vmulouh", },
- { &test_vmulosb , " vmulosb", },
- { &test_vmulosh , " vmulosh", },
- { &test_vmuleub , " vmuleub", },
- { &test_vmuleuh , " vmuleuh", },
- { &test_vmulesb , " vmulesb", },
- { &test_vmulesh , " vmulesh", },
- { &test_vsumsws , " vsumsws", },
- { &test_vsum2sws , " vsum2sws", },
- { &test_vsum4ubs , " vsum4ubs", },
- { &test_vsum4sbs , " vsum4sbs", },
- { &test_vsum4shs , " vsum4shs", },
- { &test_vavgub , " vavgub", },
- { &test_vavguh , " vavguh", },
- { &test_vavguw , " vavguw", },
- { &test_vavgsb , " vavgsb", },
- { &test_vavgsh , " vavgsh", },
- { &test_vavgsw , " vavgsw", },
- { &test_vmaxub , " vmaxub", },
- { &test_vmaxuh , " vmaxuh", },
- { &test_vmaxuw , " vmaxuw", },
- { &test_vmaxsb , " vmaxsb", },
- { &test_vmaxsh , " vmaxsh", },
- { &test_vmaxsw , " vmaxsw", },
- { &test_vminub , " vminub", },
- { &test_vminuh , " vminuh", },
- { &test_vminuw , " vminuw", },
- { &test_vminsb , " vminsb", },
- { &test_vminsh , " vminsh", },
- { &test_vminsw , " vminsw", },
- { NULL, NULL, },
-};
-#endif /* defined (HAS_ALTIVEC) */
-
-#if defined (HAS_ALTIVEC)
-static void test_vand (void)
-{
- __asm__ __volatile__ ("vand 17, 14, 15");
-}
-
-static void test_vor (void)
-{
- __asm__ __volatile__ ("vor 17, 14, 15");
-}
-
-static void test_vxor (void)
-{
- __asm__ __volatile__ ("vxor 17, 14, 15");
-}
-
-static void test_vandc (void)
-{
- __asm__ __volatile__ ("vandc 17, 14, 15");
-}
-
-static void test_vnor (void)
-{
- __asm__ __volatile__ ("vnor 17, 14, 15");
-}
-
-static void test_vrlb (void)
-{
- __asm__ __volatile__ ("vrlb 17, 14, 15");
-}
-
-static void test_vrlh (void)
-{
- __asm__ __volatile__ ("vrlh 17, 14, 15");
-}
-
-static void test_vrlw (void)
-{
- __asm__ __volatile__ ("vrlw 17, 14, 15");
-}
-
-static void test_vslb (void)
-{
- __asm__ __volatile__ ("vslb 17, 14, 15");
-}
-
-static void test_vslh (void)
-{
- __asm__ __volatile__ ("vslh 17, 14, 15");
-}
-
-static void test_vslw (void)
-{
- __asm__ __volatile__ ("vslw 17, 14, 15");
-}
-
-static void test_vsrb (void)
-{
- __asm__ __volatile__ ("vsrb 17, 14, 15");
-}
-
-static void test_vsrh (void)
-{
- __asm__ __volatile__ ("vsrh 17, 14, 15");
-}
-
-static void test_vsrw (void)
-{
- __asm__ __volatile__ ("vsrw 17, 14, 15");
-}
-
-static void test_vsrab (void)
-{
- __asm__ __volatile__ ("vsrab 17, 14, 15");
-}
-
-static void test_vsrah (void)
-{
- __asm__ __volatile__ ("vsrah 17, 14, 15");
-}
-
-static void test_vsraw (void)
-{
- __asm__ __volatile__ ("vsraw 17, 14, 15");
-}
-
-static void test_vpkuhum (void)
-{
- __asm__ __volatile__ ("vpkuhum 17, 14, 15");
-}
-
-static void test_vpkuwum (void)
-{
- __asm__ __volatile__ ("vpkuwum 17, 14, 15");
-}
-
-static void test_vpkuhus (void)
-{
- __asm__ __volatile__ ("vpkuhus 17, 14, 15");
-}
-
-static void test_vpkuwus (void)
-{
- __asm__ __volatile__ ("vpkuwus 17, 14, 15");
-}
-
-static void test_vpkshus (void)
-{
- __asm__ __volatile__ ("vpkshus 17, 14, 15");
-}
-
-static void test_vpkswus (void)
-{
- __asm__ __volatile__ ("vpkswus 17, 14, 15");
-}
-
-static void test_vpkshss (void)
-{
- __asm__ __volatile__ ("vpkshss 17, 14, 15");
-}
-
-static void test_vpkswss (void)
-{
- __asm__ __volatile__ ("vpkswss 17, 14, 15");
-}
-
-static void test_vpkpx (void)
-{
- __asm__ __volatile__ ("vpkpx 17, 14, 15");
-}
-
-static void test_vmrghb (void)
-{
- __asm__ __volatile__ ("vmrghb 17, 14, 15");
-}
-
-static void test_vmrghh (void)
-{
- __asm__ __volatile__ ("vmrghh 17, 14, 15");
-}
-
-static void test_vmrghw (void)
-{
- __asm__ __volatile__ ("vmrghw 17, 14, 15");
-}
-
-static void test_vmrglb (void)
-{
- __asm__ __volatile__ ("vmrglb 17, 14, 15");
-}
-
-static void test_vmrglh (void)
-{
- __asm__ __volatile__ ("vmrglh 17, 14, 15");
-}
-
-static void test_vmrglw (void)
-{
- __asm__ __volatile__ ("vmrglw 17, 14, 15");
-}
-
-static void test_vsl (void)
-{
- __asm__ __volatile__ ("vsl 17, 14, 15");
-}
-
-static void test_vsr (void)
-{
- __asm__ __volatile__ ("vsr 17, 14, 15");
-}
-
-static void test_vslo (void)
-{
- __asm__ __volatile__ ("vslo 17, 14, 15");
-}
-
-static void test_vsro (void)
-{
- __asm__ __volatile__ ("vsro 17, 14, 15");
-}
-
-static test_t tests_al_ops_two[] = {
- { &test_vand , " vand", },
- { &test_vor , " vor", },
- { &test_vxor , " vxor", },
- { &test_vandc , " vandc", },
- { &test_vnor , " vnor", },
- { &test_vrlb , " vrlb", },
- { &test_vrlh , " vrlh", },
- { &test_vrlw , " vrlw", },
- { &test_vslb , " vslb", },
- { &test_vslh , " vslh", },
- { &test_vslw , " vslw", },
- { &test_vsrb , " vsrb", },
- { &test_vsrh , " vsrh", },
- { &test_vsrw , " vsrw", },
- { &test_vsrab , " vsrab", },
- { &test_vsrah , " vsrah", },
- { &test_vsraw , " vsraw", },
- { &test_vpkuhum , " vpkuhum", },
- { &test_vpkuwum , " vpkuwum", },
- { &test_vpkuhus , " vpkuhus", },
- { &test_vpkuwus , " vpkuwus", },
- { &test_vpkshus , " vpkshus", },
- { &test_vpkswus , " vpkswus", },
- { &test_vpkshss , " vpkshss", },
- { &test_vpkswss , " vpkswss", },
- { &test_vpkpx , " vpkpx", },
- { &test_vmrghb , " vmrghb", },
- { &test_vmrghh , " vmrghh", },
- { &test_vmrghw , " vmrghw", },
- { &test_vmrglb , " vmrglb", },
- { &test_vmrglh , " vmrglh", },
- { &test_vmrglw , " vmrglw", },
- { &test_vsl , " vsl", },
- { &test_vsr , " vsr", },
- { &test_vslo , " vslo", },
- { &test_vsro , " vsro", },
- { NULL, NULL, },
-};
-#endif /* defined (HAS_ALTIVEC) */
-
-#if defined (HAS_ALTIVEC)
-static void test_vupkhsb (void)
-{
- __asm__ __volatile__ ("vupkhsb 17, 14");
-}
-
-static void test_vupkhsh (void)
-{
- __asm__ __volatile__ ("vupkhsh 17, 14");
-}
-
-static void test_vupkhpx (void)
-{
- __asm__ __volatile__ ("vupkhpx 17, 14");
-}
-
-static void test_vupklsb (void)
-{
- __asm__ __volatile__ ("vupklsb 17, 14");
-}
-
-static void test_vupklsh (void)
-{
- __asm__ __volatile__ ("vupklsh 17, 14");
-}
-
-static void test_vupklpx (void)
-{
- __asm__ __volatile__ ("vupklpx 17, 14");
-}
-
-static test_t tests_al_ops_one[] = {
- { &test_vupkhsb , " vupkhsb", },
- { &test_vupkhsh , " vupkhsh", },
- { &test_vupkhpx , " vupkhpx", },
- { &test_vupklsb , " vupklsb", },
- { &test_vupklsh , " vupklsh", },
- { &test_vupklpx , " vupklpx", },
- { NULL, NULL, },
-};
-#endif /* defined (HAS_ALTIVEC) */
-
-#if defined (HAS_ALTIVEC)
-static void test_vcmpgtub (void)
-{
- __asm__ __volatile__ ("vcmpgtub 17, 14, 15");
-}
-
-static void test_vcmpgtuh (void)
-{
- __asm__ __volatile__ ("vcmpgtuh 17, 14, 15");
-}
-
-static void test_vcmpgtuw (void)
-{
- __asm__ __volatile__ ("vcmpgtuw 17, 14, 15");
-}
-
-static void test_vcmpgtsb (void)
-{
- __asm__ __volatile__ ("vcmpgtsb 17, 14, 15");
-}
-
-static void test_vcmpgtsh (void)
-{
- __asm__ __volatile__ ("vcmpgtsh 17, 14, 15");
-}
-
-static void test_vcmpgtsw (void)
-{
- __asm__ __volatile__ ("vcmpgtsw 17, 14, 15");
-}
-
-static void test_vcmpequb (void)
-{
- __asm__ __volatile__ ("vcmpequb 17, 14, 15");
-}
-
-static void test_vcmpequh (void)
-{
- __asm__ __volatile__ ("vcmpequh 17, 14, 15");
-}
-
-static void test_vcmpequw (void)
-{
- __asm__ __volatile__ ("vcmpequw 17, 14, 15");
-}
-
-static test_t tests_ac_ops_two[] = {
- { &test_vcmpgtub , " vcmpgtub", },
- { &test_vcmpgtuh , " vcmpgtuh", },
- { &test_vcmpgtuw , " vcmpgtuw", },
- { &test_vcmpgtsb , " vcmpgtsb", },
- { &test_vcmpgtsh , " vcmpgtsh", },
- { &test_vcmpgtsw , " vcmpgtsw", },
- { &test_vcmpequb , " vcmpequb", },
- { &test_vcmpequh , " vcmpequh", },
- { &test_vcmpequw , " vcmpequw", },
- { NULL, NULL, },
-};
-#endif /* defined (HAS_ALTIVEC) */
-
-#if defined (HAS_ALTIVEC)
-static void test_vcmpgtub_ (void)
-{
- __asm__ __volatile__ ("vcmpgtub. 17, 14, 15");
-}
-
-static void test_vcmpgtuh_ (void)
-{
- __asm__ __volatile__ ("vcmpgtuh. 17, 14, 15");
-}
-
-static void test_vcmpgtuw_ (void)
-{
- __asm__ __volatile__ ("vcmpgtuw. 17, 14, 15");
-}
-
-static void test_vcmpgtsb_ (void)
-{
- __asm__ __volatile__ ("vcmpgtsb. 17, 14, 15");
-}
-
-static void test_vcmpgtsh_ (void)
-{
- __asm__ __volatile__ ("vcmpgtsh. 17, 14, 15");
-}
-
-static void test_vcmpgtsw_ (void)
-{
- __asm__ __volatile__ ("vcmpgtsw. 17, 14, 15");
-}
-
-static void test_vcmpequb_ (void)
-{
- __asm__ __volatile__ ("vcmpequb. 17, 14, 15");
-}
-
-static void test_vcmpequh_ (void)
-{
- __asm__ __volatile__ ("vcmpequh. 17, 14, 15");
-}
-
-static void test_vcmpequw_ (void)
-{
- __asm__ __volatile__ ("vcmpequw. 17, 14, 15");
-}
-
-static test_t tests_acr_ops_two[] = {
- { &test_vcmpgtub_ , " vcmpgtub.", },
- { &test_vcmpgtuh_ , " vcmpgtuh.", },
- { &test_vcmpgtuw_ , " vcmpgtuw.", },
- { &test_vcmpgtsb_ , " vcmpgtsb.", },
- { &test_vcmpgtsh_ , " vcmpgtsh.", },
- { &test_vcmpgtsw_ , " vcmpgtsw.", },
- { &test_vcmpequb_ , " vcmpequb.", },
- { &test_vcmpequh_ , " vcmpequh.", },
- { &test_vcmpequw_ , " vcmpequw.", },
- { NULL, NULL, },
-};
-#endif /* defined (HAS_ALTIVEC) */
-
-#if defined (HAS_ALTIVEC)
-static void test_vmaddfp (void)
-{
- __asm__ __volatile__ ("vmaddfp 17, 14, 15, 16");
-}
-
-static void test_vnmsubfp (void)
-{
- __asm__ __volatile__ ("vnmsubfp 17, 14, 15, 16");
-}
-
-static test_t tests_afa_ops_three[] = {
- { &test_vmaddfp , " vmaddfp", },
- { &test_vnmsubfp , " vnmsubfp", },
- { NULL, NULL, },
-};
-#endif /* defined (HAS_ALTIVEC) */
-
-#if defined (HAS_ALTIVEC)
-static void test_vaddfp (void)
-{
- __asm__ __volatile__ ("vaddfp 17, 14, 15");
-}
-
-static void test_vsubfp (void)
-{
- __asm__ __volatile__ ("vsubfp 17, 14, 15");
-}
-
-static void test_vmaxfp (void)
-{
- __asm__ __volatile__ ("vmaxfp 17, 14, 15");
-}
-
-static void test_vminfp (void)
-{
- __asm__ __volatile__ ("vminfp 17, 14, 15");
-}
-
-static test_t tests_afa_ops_two[] = {
- { &test_vaddfp , " vaddfp", },
- { &test_vsubfp , " vsubfp", },
- { &test_vmaxfp , " vmaxfp", },
- { &test_vminfp , " vminfp", },
- { NULL, NULL, },
-};
-#endif /* defined (HAS_ALTIVEC) */
-
-#if defined (HAS_ALTIVEC)
-static void test_vrfin (void)
-{
- __asm__ __volatile__ ("vrfin 17, 14");
-}
-
-static void test_vrfiz (void)
-{
- __asm__ __volatile__ ("vrfiz 17, 14");
-}
-
-static void test_vrfip (void)
-{
- __asm__ __volatile__ ("vrfip 17, 14");
-}
-
-static void test_vrfim (void)
-{
- __asm__ __volatile__ ("vrfim 17, 14");
-}
-
-static void test_vrefp (void)
-{
- __asm__ __volatile__ ("vrefp 17, 14");
-}
-
-static void test_vrsqrtefp (void)
-{
- __asm__ __volatile__ ("vrsqrtefp 17, 14");
-}
-
-static void test_vlogefp (void)
-{
- __asm__ __volatile__ ("vlogefp 17, 14");
-}
-
-static void test_vexptefp (void)
-{
- __asm__ __volatile__ ("vexptefp 17, 14");
-}
-
-static test_t tests_afa_ops_one[] = {
- { &test_vrfin , " vrfin", },
- { &test_vrfiz , " vrfiz", },
- { &test_vrfip , " vrfip", },
- { &test_vrfim , " vrfim", },
- { &test_vrefp , " vrefp", },
- { &test_vrsqrtefp , " vrsqrtefp", },
- { &test_vlogefp , " vlogefp", },
- { &test_vexptefp , " vexptefp", },
- { NULL, NULL, },
-};
-#endif /* defined (HAS_ALTIVEC) */
-
-#if defined (HAS_ALTIVEC)
-static void test_vcmpgtfp (void)
-{
- __asm__ __volatile__ ("vcmpgtfp 17, 14, 15");
-}
-
-static void test_vcmpeqfp (void)
-{
- __asm__ __volatile__ ("vcmpeqfp 17, 14, 15");
-}
-
-static void test_vcmpgefp (void)
-{
- __asm__ __volatile__ ("vcmpgefp 17, 14, 15");
-}
-
-static void test_vcmpbfp (void)
-{
- __asm__ __volatile__ ("vcmpbfp 17, 14, 15");
-}
-
-static test_t tests_afc_ops_two[] = {
- { &test_vcmpgtfp , " vcmpgtfp", },
- { &test_vcmpeqfp , " vcmpeqfp", },
- { &test_vcmpgefp , " vcmpgefp", },
- { &test_vcmpbfp , " vcmpbfp", },
- { NULL, NULL, },
-};
-#endif /* defined (HAS_ALTIVEC) */
-
-#if defined (HAS_ALTIVEC)
-static void test_vcmpgtfp_ (void)
-{
- __asm__ __volatile__ ("vcmpgtfp. 17, 14, 15");
-}
-
-static void test_vcmpeqfp_ (void)
-{
- __asm__ __volatile__ ("vcmpeqfp. 17, 14, 15");
-}
-
-static void test_vcmpgefp_ (void)
-{
- __asm__ __volatile__ ("vcmpgefp. 17, 14, 15");
-}
-
-static void test_vcmpbfp_ (void)
-{
- __asm__ __volatile__ ("vcmpbfp. 17, 14, 15");
-}
-
-static test_t tests_afcr_ops_two[] = {
- { &test_vcmpgtfp_ , " vcmpgtfp.", },
- { &test_vcmpeqfp_ , " vcmpeqfp.", },
- { &test_vcmpgefp_ , " vcmpgefp.", },
- { &test_vcmpbfp_ , " vcmpbfp.", },
- { NULL, NULL, },
-};
-#endif /* defined (HAS_ALTIVEC) */
-
-#if defined (IS_PPC405)
-static void test_macchw (void)
-{
- __asm__ __volatile__ ("macchw 17, 14, 15");
-}
-
-static void test_macchwo (void)
-{
- __asm__ __volatile__ ("macchwo 17, 14, 15");
-}
-
-static void test_macchws (void)
-{
- __asm__ __volatile__ ("macchws 17, 14, 15");
-}
-
-static void test_macchwso (void)
-{
- __asm__ __volatile__ ("macchwso 17, 14, 15");
-}
-
-static void test_macchwsu (void)
-{
- __asm__ __volatile__ ("macchwsu 17, 14, 15");
-}
-
-static void test_macchwsuo (void)
-{
- __asm__ __volatile__ ("macchwsuo 17, 14, 15");
-}
-
-static void test_macchwu (void)
-{
- __asm__ __volatile__ ("macchwu 17, 14, 15");
-}
-
-static void test_macchwuo (void)
-{
- __asm__ __volatile__ ("macchwuo 17, 14, 15");
-}
-
-static void test_machhw (void)
-{
- __asm__ __volatile__ ("machhw 17, 14, 15");
-}
-
-static void test_machhwo (void)
-{
- __asm__ __volatile__ ("machhwo 17, 14, 15");
-}
-
-static void test_machhws (void)
-{
- __asm__ __volatile__ ("machhws 17, 14, 15");
-}
-
-static void test_machhwso (void)
-{
- __asm__ __volatile__ ("machhwso 17, 14, 15");
-}
-
-static void test_machhwsu (void)
-{
- __asm__ __volatile__ ("machhwsu 17, 14, 15");
-}
-
-static void test_machhwsuo (void)
-{
- __asm__ __volatile__ ("machhwsuo 17, 14, 15");
-}
-
-static void test_machhwu (void)
-{
- __asm__ __volatile__ ("machhwu 17, 14, 15");
-}
-
-static void test_machhwuo (void)
-{
- __asm__ __volatile__ ("machhwuo 17, 14, 15");
-}
-
-static void test_maclhw (void)
-{
- __asm__ __volatile__ ("maclhw 17, 14, 15");
-}
-
-static void test_maclhwo (void)
-{
- __asm__ __volatile__ ("maclhwo 17, 14, 15");
-}
-
-static void test_maclhws (void)
-{
- __asm__ __volatile__ ("maclhws 17, 14, 15");
-}
-
-static void test_maclhwso (void)
-{
- __asm__ __volatile__ ("maclhwso 17, 14, 15");
-}
-
-static void test_maclhwsu (void)
-{
- __asm__ __volatile__ ("maclhwsu 17, 14, 15");
-}
-
-static void test_maclhwsuo (void)
-{
- __asm__ __volatile__ ("maclhwsuo 17, 14, 15");
-}
-
-static void test_maclhwu (void)
-{
- __asm__ __volatile__ ("maclhwu 17, 14, 15");
-}
-
-static void test_maclhwuo (void)
-{
- __asm__ __volatile__ ("maclhwuo 17, 14, 15");
-}
-
-static void test_mulchw (void)
-{
- __asm__ __volatile__ ("mulchw 17, 14, 15");
-}
-
-static void test_mulchwu (void)
-{
- __asm__ __volatile__ ("mulchwu 17, 14, 15");
-}
-
-static void test_mulhhw (void)
-{
- __asm__ __volatile__ ("mulhhw 17, 14, 15");
-}
-
-static void test_mulhhwu (void)
-{
- __asm__ __volatile__ ("mulhhwu 17, 14, 15");
-}
-
-static void test_mullhw (void)
-{
- __asm__ __volatile__ ("mullhw 17, 14, 15");
-}
-
-static void test_mullhwu (void)
-{
- __asm__ __volatile__ ("mullhwu 17, 14, 15");
-}
-
-static void test_nmacchw (void)
-{
- __asm__ __volatile__ ("nmacchw 17, 14, 15");
-}
-
-static void test_nmacchwo (void)
-{
- __asm__ __volatile__ ("nmacchwo 17, 14, 15");
-}
-
-static void test_nmacchws (void)
-{
- __asm__ __volatile__ ("nmacchws 17, 14, 15");
-}
-
-static void test_nmacchwso (void)
-{
- __asm__ __volatile__ ("nmacchwso 17, 14, 15");
-}
-
-static void test_nmachhw (void)
-{
- __asm__ __volatile__ ("nmachhw 17, 14, 15");
-}
-
-static void test_nmachhwo (void)
-{
- __asm__ __volatile__ ("nmachhwo 17, 14, 15");
-}
-
-static void test_nmachhws (void)
-{
- __asm__ __volatile__ ("nmachhws 17, 14, 15");
-}
-
-static void test_nmachhwso (void)
-{
- __asm__ __volatile__ ("nmachhwso 17, 14, 15");
-}
-
-static void test_nmaclhw (void)
-{
- __asm__ __volatile__ ("nmaclhw 17, 14, 15");
-}
-
-static void test_nmaclhwo (void)
-{
- __asm__ __volatile__ ("nmaclhwo 17, 14, 15");
-}
-
-static void test_nmaclhws (void)
-{
- __asm__ __volatile__ ("nmaclhws 17, 14, 15");
-}
-
-static void test_nmaclhwso (void)
-{
- __asm__ __volatile__ ("nmaclhwso 17, 14, 15");
-}
-
-static test_t tests_p4m_ops_two[] = {
- { &test_macchw , " macchw", },
- { &test_macchwo , " macchwo", },
- { &test_macchws , " macchws", },
- { &test_macchwso , " macchwso", },
- { &test_macchwsu , " macchwsu", },
- { &test_macchwsuo , " macchwsuo", },
- { &test_macchwu , " macchwu", },
- { &test_macchwuo , " macchwuo", },
- { &test_machhw , " machhw", },
- { &test_machhwo , " machhwo", },
- { &test_machhws , " machhws", },
- { &test_machhwso , " machhwso", },
- { &test_machhwsu , " machhwsu", },
- { &test_machhwsuo , " machhwsuo", },
- { &test_machhwu , " machhwu", },
- { &test_machhwuo , " machhwuo", },
- { &test_maclhw , " maclhw", },
- { &test_maclhwo , " maclhwo", },
- { &test_maclhws , " maclhws", },
- { &test_maclhwso , " maclhwso", },
- { &test_maclhwsu , " maclhwsu", },
- { &test_maclhwsuo , " maclhwsuo", },
- { &test_maclhwu , " maclhwu", },
- { &test_maclhwuo , " maclhwuo", },
- { &test_mulchw , " mulchw", },
- { &test_mulchwu , " mulchwu", },
- { &test_mulhhw , " mulhhw", },
- { &test_mulhhwu , " mulhhwu", },
- { &test_mullhw , " mullhw", },
- { &test_mullhwu , " mullhwu", },
- { &test_nmacchw , " nmacchw", },
- { &test_nmacchwo , " nmacchwo", },
- { &test_nmacchws , " nmacchws", },
- { &test_nmacchwso , " nmacchwso", },
- { &test_nmachhw , " nmachhw", },
- { &test_nmachhwo , " nmachhwo", },
- { &test_nmachhws , " nmachhws", },
- { &test_nmachhwso , " nmachhwso", },
- { &test_nmaclhw , " nmaclhw", },
- { &test_nmaclhwo , " nmaclhwo", },
- { &test_nmaclhws , " nmaclhws", },
- { &test_nmaclhwso , " nmaclhwso", },
- { NULL, NULL, },
-};
-#endif /* defined (IS_PPC405) */
-
-#if defined (IS_PPC405)
-static void test_macchw_ (void)
-{
- __asm__ __volatile__ ("macchw. 17, 14, 15");
-}
-
-static void test_macchwo_ (void)
-{
- __asm__ __volatile__ ("macchwo. 17, 14, 15");
-}
-
-static void test_macchws_ (void)
-{
- __asm__ __volatile__ ("macchws. 17, 14, 15");
-}
-
-static void test_macchwso_ (void)
-{
- __asm__ __volatile__ ("macchwso. 17, 14, 15");
-}
-
-static void test_macchwsu_ (void)
-{
- __asm__ __volatile__ ("macchwsu. 17, 14, 15");
-}
-
-static void test_macchwsuo_ (void)
-{
- __asm__ __volatile__ ("macchwsuo. 17, 14, 15");
-}
-
-static void test_macchwu_ (void)
-{
- __asm__ __volatile__ ("macchwu. 17, 14, 15");
-}
-
-static void test_macchwuo_ (void)
-{
- __asm__ __volatile__ ("macchwuo. 17, 14, 15");
-}
-
-static void test_machhw_ (void)
-{
- __asm__ __volatile__ ("machhw. 17, 14, 15");
-}
-
-static void test_machhwo_ (void)
-{
- __asm__ __volatile__ ("machhwo. 17, 14, 15");
-}
-
-static void test_machhws_ (void)
-{
- __asm__ __volatile__ ("machhws. 17, 14, 15");
-}
-
-static void test_machhwso_ (void)
-{
- __asm__ __volatile__ ("machhwso. 17, 14, 15");
-}
-
-static void test_machhwsu_ (void)
-{
- __asm__ __volatile__ ("machhwsu. 17, 14, 15");
-}
-
-static void test_machhwsuo_ (void)
-{
- __asm__ __volatile__ ("machhwsuo. 17, 14, 15");
-}
-
-static void test_machhwu_ (void)
-{
- __asm__ __volatile__ ("machhwu. 17, 14, 15");
-}
-
-static void test_machhwuo_ (void)
-{
- __asm__ __volatile__ ("machhwuo. 17, 14, 15");
-}
-
-static void test_maclhw_ (void)
-{
- __asm__ __volatile__ ("maclhw. 17, 14, 15");
-}
-
-static void test_maclhwo_ (void)
-{
- __asm__ __volatile__ ("maclhwo. 17, 14, 15");
-}
-
-static void test_maclhws_ (void)
-{
- __asm__ __volatile__ ("maclhws. 17, 14, 15");
-}
-
-static void test_maclhwso_ (void)
-{
- __asm__ __volatile__ ("maclhwso. 17, 14, 15");
-}
-
-static void test_maclhwsu_ (void)
-{
- __asm__ __volatile__ ("maclhwsu. 17, 14, 15");
-}
-
-static void test_maclhwsuo_ (void)
-{
- __asm__ __volatile__ ("maclhwsuo. 17, 14, 15");
-}
-
-static void test_maclhwu_ (void)
-{
- __asm__ __volatile__ ("maclhwu. 17, 14, 15");
-}
-
-static void test_maclhwuo_ (void)
-{
- __asm__ __volatile__ ("maclhwuo. 17, 14, 15");
-}
-
-static void test_mulchw_ (void)
-{
- __asm__ __volatile__ ("mulchw. 17, 14, 15");
-}
-
-static void test_mulchwu_ (void)
-{
- __asm__ __volatile__ ("mulchwu. 17, 14, 15");
-}
-
-static void test_mulhhw_ (void)
-{
- __asm__ __volatile__ ("mulhhw. 17, 14, 15");
-}
-
-static void test_mulhhwu_ (void)
-{
- __asm__ __volatile__ ("mulhhwu. 17, 14, 15");
-}
-
-static void test_mullhw_ (void)
-{
- __asm__ __volatile__ ("mullhw. 17, 14, 15");
-}
-
-static void test_mullhwu_ (void)
-{
- __asm__ __volatile__ ("mullhwu. 17, 14, 15");
-}
-
-static void test_nmacchw_ (void)
-{
- __asm__ __volatile__ ("nmacchw. 17, 14, 15");
-}
-
-static void test_nmacchwo_ (void)
-{
- __asm__ __volatile__ ("nmacchwo. 17, 14, 15");
-}
-
-static void test_nmacchws_ (void)
-{
- __asm__ __volatile__ ("nmacchws. 17, 14, 15");
-}
-
-static void test_nmacchwso_ (void)
-{
- __asm__ __volatile__ ("nmacchwso. 17, 14, 15");
-}
-
-static void test_nmachhw_ (void)
-{
- __asm__ __volatile__ ("nmachhw. 17, 14, 15");
-}
-
-static void test_nmachhwo_ (void)
-{
- __asm__ __volatile__ ("nmachhwo. 17, 14, 15");
-}
-
-static void test_nmachhws_ (void)
-{
- __asm__ __volatile__ ("nmachhws. 17, 14, 15");
-}
-
-static void test_nmachhwso_ (void)
-{
- __asm__ __volatile__ ("nmachhwso. 17, 14, 15");
-}
-
-static void test_nmaclhw_ (void)
-{
- __asm__ __volatile__ ("nmaclhw. 17, 14, 15");
-}
-
-static void test_nmaclhwo_ (void)
-{
- __asm__ __volatile__ ("nmaclhwo. 17, 14, 15");
-}
-
-static void test_nmaclhws_ (void)
-{
- __asm__ __volatile__ ("nmaclhws. 17, 14, 15");
-}
-
-static void test_nmaclhwso_ (void)
-{
- __asm__ __volatile__ ("nmaclhwso. 17, 14, 15");
-}
-
-static test_t tests_p4mc_ops_two[] = {
- { &test_macchw_ , " macchw.", },
- { &test_macchwo_ , " macchwo.", },
- { &test_macchws_ , " macchws.", },
- { &test_macchwso_ , " macchwso.", },
- { &test_macchwsu_ , " macchwsu.", },
- { &test_macchwsuo_ , " macchwsuo.", },
- { &test_macchwu_ , " macchwu.", },
- { &test_macchwuo_ , " macchwuo.", },
- { &test_machhw_ , " machhw.", },
- { &test_machhwo_ , " machhwo.", },
- { &test_machhws_ , " machhws.", },
- { &test_machhwso_ , " machhwso.", },
- { &test_machhwsu_ , " machhwsu.", },
- { &test_machhwsuo_ , " machhwsuo.", },
- { &test_machhwu_ , " machhwu.", },
- { &test_machhwuo_ , " machhwuo.", },
- { &test_maclhw_ , " maclhw.", },
- { &test_maclhwo_ , " maclhwo.", },
- { &test_maclhws_ , " maclhws.", },
- { &test_maclhwso_ , " maclhwso.", },
- { &test_maclhwsu_ , " maclhwsu.", },
- { &test_maclhwsuo_ , " maclhwsuo.", },
- { &test_maclhwu_ , " maclhwu.", },
- { &test_maclhwuo_ , " maclhwuo.", },
- { &test_mulchw_ , " mulchw.", },
- { &test_mulchwu_ , " mulchwu.", },
- { &test_mulhhw_ , " mulhhw.", },
- { &test_mulhhwu_ , " mulhhwu.", },
- { &test_mullhw_ , " mullhw.", },
- { &test_mullhwu_ , " mullhwu.", },
- { &test_nmacchw_ , " nmacchw.", },
- { &test_nmacchwo_ , " nmacchwo.", },
- { &test_nmacchws_ , " nmacchws.", },
- { &test_nmacchwso_ , " nmacchwso.", },
- { &test_nmachhw_ , " nmachhw.", },
- { &test_nmachhwo_ , " nmachhwo.", },
- { &test_nmachhws_ , " nmachhws.", },
- { &test_nmachhwso_ , " nmachhwso.", },
- { &test_nmaclhw_ , " nmaclhw.", },
- { &test_nmaclhwo_ , " nmaclhwo.", },
- { &test_nmaclhws_ , " nmaclhws.", },
- { &test_nmaclhwso_ , " nmaclhwso.", },
- { NULL, NULL, },
-};
-#endif /* defined (IS_PPC405) */
-
-static test_table_t all_tests[] = {
- {
- tests_ia_ops_two ,
- "PPC integer arithmetic instructions with two arguments",
- 0x00010102,
- },
- {
- tests_iar_ops_two ,
- "PPC integer instructions with two arguments with flags update",
- 0x01010102,
- },
- {
- tests_il_ops_two ,
- "PPC integer logical instructions with two arguments",
- 0x00010202,
- },
- {
- tests_ilr_ops_two ,
- "PPC integer logical instructions with two arguments with flags update",
- 0x01010202,
- },
- {
- tests_icr_ops_two ,
- "PPC integer compare instructions (two arguents)",
- 0x01010304,
- },
- {
- tests_icr_ops_two_i16 ,
- "PPC integer compare with immediate instructions (two arguents)",
- 0x01010304,
- },
- {
- tests_ia_ops_two_i16 ,
- "PPC integer arithmetic instructions\n with one register + one 16 bits immediate arguments",
- 0x00010106,
- },
- {
- tests_iar_ops_two_i16 ,
- "PPC integer arithmetic instructions\n with one register + one 16 bits immediate arguments with flags update",
- 0x01010106,
- },
- {
- tests_il_ops_two_i16 ,
- "PPC integer logical instructions\n with one register + one 16 bits immediate arguments",
- 0x00010206,
- },
- {
- tests_ilr_ops_two_i16 ,
- "PPC integer logical instructions\n with one register + one 16 bits immediate arguments with flags update",
- 0x01010206,
- },
- {
- tests_crl_ops_two ,
- "PPC condition register logical instructions - two operands",
- 0x01000602,
- },
- {
- tests_ia_ops_one ,
- "PPC integer arithmetic instructions with one argument",
- 0x00010101,
- },
- {
- tests_iar_ops_one ,
- "PPC integer arithmetic instructions with one argument with flags update",
- 0x01010101,
- },
- {
- tests_il_ops_one ,
- "PPC integer logical instructions with one argument",
- 0x00010201,
- },
- {
- tests_ilr_ops_one ,
- "PPC integer logical instructions with one argument with flags update",
- 0x01010201,
- },
- {
- tests_il_ops_spe ,
- "PPC logical instructions with special forms",
- 0x00010207,
- },
- {
- tests_ilr_ops_spe ,
- "PPC logical instructions with special forms with flags update",
- 0x01010207,
- },
-#if !defined (NO_FLOAT)
- {
- tests_fa_ops_three ,
- "PPC floating point arithmetic instructions with three arguments",
- 0x00020103,
- },
-#endif /* !defined (NO_FLOAT) */
-#if !defined (NO_FLOAT)
- {
- tests_far_ops_three ,
- "PPC floating point arithmetic instructions\n with three arguments with flags update",
- 0x01020103,
- },
-#endif /* !defined (NO_FLOAT) */
-#if !defined (NO_FLOAT)
- {
- tests_fa_ops_two ,
- "PPC floating point arithmetic instructions with two arguments",
- 0x00020102,
- },
-#endif /* !defined (NO_FLOAT) */
-#if !defined (NO_FLOAT)
- {
- tests_far_ops_two ,
- "PPC floating point arithmetic instructions\n with two arguments with flags update",
- 0x01020102,
- },
-#endif /* !defined (NO_FLOAT) */
-#if !defined (NO_FLOAT)
- {
- tests_fcr_ops_two ,
- "PPC floating point compare instructions (two arguments)",
- 0x01020304,
- },
-#endif /* !defined (NO_FLOAT) */
-#if !defined (NO_FLOAT)
- {
- tests_fa_ops_one ,
- "PPC floating point arithmetic instructions with one argument",
- 0x00020101,
- },
-#endif /* !defined (NO_FLOAT) */
-#if !defined (NO_FLOAT)
- {
- tests_far_ops_one ,
- "PPC floating point arithmetic instructions\n with one argument with flags update",
- 0x01020101,
- },
-#endif /* !defined (NO_FLOAT) */
-#if !defined (NO_FLOAT)
- {
- tests_fl_ops_spe ,
- "PPC floating point status register manipulation instructions",
- 0x00020207,
- },
-#endif /* !defined (NO_FLOAT) */
-#if !defined (NO_FLOAT)
- {
- tests_flr_ops_spe ,
- "PPC floating point status register manipulation instructions\n with flags update",
- 0x01020207,
- },
-#endif /* !defined (NO_FLOAT) */
-#if defined (HAS_ALTIVEC)
- {
- tests_aa_ops_three ,
- "PPC altivec integer arithmetic instructions with three arguments",
- 0x00040103,
- },
-#endif /* defined (HAS_ALTIVEC) */
-#if defined (HAS_ALTIVEC)
- {
- tests_al_ops_three ,
- "PPC altivec integer logical instructions with three arguments",
- 0x00040203,
- },
-#endif /* defined (HAS_ALTIVEC) */
-#if defined (HAS_ALTIVEC)
- {
- tests_aa_ops_two ,
- "PPC altivec integer arithmetic instructions with two arguments",
- 0x00040102,
- },
-#endif /* defined (HAS_ALTIVEC) */
-#if defined (HAS_ALTIVEC)
- {
- tests_al_ops_two ,
- "PPC altivec integer logical instructions with two arguments",
- 0x00040202,
- },
-#endif /* defined (HAS_ALTIVEC) */
-#if defined (HAS_ALTIVEC)
- {
- tests_al_ops_one ,
- "PPC altivec integer logical instructions with one argument",
- 0x00040201,
- },
-#endif /* defined (HAS_ALTIVEC) */
-#if defined (HAS_ALTIVEC)
- {
- tests_ac_ops_two ,
- "Altivec integer compare instructions",
- 0x00040302,
- },
-#endif /* defined (HAS_ALTIVEC) */
-#if defined (HAS_ALTIVEC)
- {
- tests_acr_ops_two ,
- "Altivec integer compare instructions with flags update",
- 0x01040302,
- },
-#endif /* defined (HAS_ALTIVEC) */
-#if defined (HAS_ALTIVEC)
- {
- tests_afa_ops_three ,
- "Altivec floating point arithmetic instructions with three arguments",
- 0x00050103,
- },
-#endif /* defined (HAS_ALTIVEC) */
-#if defined (HAS_ALTIVEC)
- {
- tests_afa_ops_two ,
- "Altivec floating point arithmetic instructions with two arguments",
- 0x00050102,
- },
-#endif /* defined (HAS_ALTIVEC) */
-#if defined (HAS_ALTIVEC)
- {
- tests_afa_ops_one ,
- "Altivec floating point arithmetic instructions with one argument",
- 0x00050101,
- },
-#endif /* defined (HAS_ALTIVEC) */
-#if defined (HAS_ALTIVEC)
- {
- tests_afc_ops_two ,
- "Altivec floating point compare instructions",
- 0x00050302,
- },
-#endif /* defined (HAS_ALTIVEC) */
-#if defined (HAS_ALTIVEC)
- {
- tests_afcr_ops_two ,
- "Altivec floating point compare instructions with flags update",
- 0x01050302,
- },
-#endif /* defined (HAS_ALTIVEC) */
-#if defined (IS_PPC405)
- {
- tests_p4m_ops_two ,
- "PPC 405 mac instructions with three arguments",
- 0x00030102,
- },
-#endif /* defined (IS_PPC405) */
-#if defined (IS_PPC405)
- {
- tests_p4mc_ops_two ,
- "PPC 405 mac instructions with three arguments with flags update",
- 0x01030102,
- },
-#endif /* defined (IS_PPC405) */
- { NULL, NULL, 0x00000000, },
-};
-
-// END #include "ops-ppc.c"
-
-
-static int verbose = 0;
-
-static double *fargs;
-static int nb_fargs;
-static uint32_t *iargs;
-static int nb_iargs;
-static uint16_t *ii16;
-static int nb_ii16;
-
-static inline void register_farg (void *farg,
- int s, uint16_t _exp, uint64_t mant)
-{
- uint64_t tmp;
-
- tmp = ((uint64_t)s << 63) | ((uint64_t)_exp << 52) | mant;
- *(uint64_t *)farg = tmp;
- AB_DPRINTF("%d %03x %013llx => %016llx %0e\n",
- s, _exp, mant, *(uint64_t *)farg, *(double *)farg);
-}
-
-static void build_fargs_table (void)
-{
- /* Sign goes from zero to one
- * Exponent goes from 0 to ((1 << 12) - 1)
- * Mantissa goes from 1 to ((1 << 52) - 1)
- * + special values:
- * +0.0 : 0 0x000 0x0000000000000
- * -0.0 : 1 0x000 0x0000000000000
- * +infinity : 0 0x7FF 0x0000000000000
- * -infinity : 1 0x7FF 0x0000000000000
- * +SNaN : 0 0x7FF 0x7FFFFFFFFFFFF
- * -SNaN : 1 0x7FF 0x7FFFFFFFFFFFF
- * +QNaN : 0 0x7FF 0x8000000000000
- * -QNaN : 1 0x7FF 0x8000000000000
- * (8 values)
- */
- uint64_t mant;
- uint16_t _exp, e0, e1;
- int s;
- int i;
-
- fargs = my_malloc(200 * sizeof(double));
- i = 0;
- for (s = 0; s < 2; s++) {
- for (e0 = 0; e0 < 2; e0++) {
- for (e1 = 0x000; ; e1 = ((e1 + 1) << 2) + 6) {
- if (e1 >= 0x400)
- e1 = 0x3fe;
- _exp = (e0 << 10) | e1;
- for (mant = 0x0000000000001ULL; mant < (1ULL << 52);
- /* Add 'random' bits */
- mant = ((mant + 0x4A6) << 13) + 0x359) {
- register_farg(&fargs[i++], s, _exp, mant);
- }
- if (e1 == 0x3fe)
- break;
- }
- }
- }
- /* Special values */
- /* +0.0 : 0 0x000 0x0000000000000 */
- s = 0;
- _exp = 0x000;
- mant = 0x0000000000000ULL;
- register_farg(&fargs[i++], s, _exp, mant);
- /* -0.0 : 1 0x000 0x0000000000000 */
- s = 1;
- _exp = 0x000;
- mant = 0x0000000000000ULL;
- register_farg(&fargs[i++], s, _exp, mant);
- /* +infinity : 0 0x7FF 0x0000000000000 */
- s = 0;
- _exp = 0x7FF;
- mant = 0x0000000000000ULL;
- register_farg(&fargs[i++], s, _exp, mant);
- /* -infinity : 1 0x7FF 0x0000000000000 */
- s = 1;
- _exp = 0x7FF;
- mant = 0x0000000000000ULL;
- register_farg(&fargs[i++], s, _exp, mant);
- /* +SNaN : 0 0x7FF 0x7FFFFFFFFFFFF */
- s = 0;
- _exp = 0x7FF;
- mant = 0x7FFFFFFFFFFFFULL;
- register_farg(&fargs[i++], s, _exp, mant);
- /* -SNaN : 1 0x7FF 0x7FFFFFFFFFFFF */
- s = 1;
- _exp = 0x7FF;
- mant = 0x7FFFFFFFFFFFFULL;
- register_farg(&fargs[i++], s, _exp, mant);
- /* +QNaN : 0 0x7FF 0x8000000000000 */
- s = 0;
- _exp = 0x7FF;
- mant = 0x8000000000000ULL;
- register_farg(&fargs[i++], s, _exp, mant);
- /* -QNaN : 1 0x7FF 0x8000000000000 */
- s = 1;
- _exp = 0x7FF;
- mant = 0x8000000000000ULL;
- register_farg(&fargs[i++], s, _exp, mant);
- AB_DPRINTF("Registered %d floats values\n", i);
- nb_fargs = i;
-}
-
-static void build_iargs_table (void)
-{
- uint64_t tmp;
- int i;
-
- iargs = my_malloc(400 * sizeof(uint32_t));
- i = 0;
- for (tmp = 0; ; tmp = tmp + 1 + (tmp>>1)+(tmp>>2)+(tmp>>3)) {
- if (tmp >= 0x100000000ULL)
- tmp = 0xFFFFFFFF;
- iargs[i++] = tmp;
- AB_DPRINTF("val %08llx\n", tmp);
- if (tmp == 0xFFFFFFFF)
- break;
- }
- AB_DPRINTF("Registered %d ints values\n", i);
- nb_iargs = i;
-}
-
-static void build_ii16_table (void)
-{
- uint32_t tmp;
- int i;
-
- ii16 = my_malloc(200 * sizeof(uint32_t));
- i = 0;
- for (tmp = 0; ; tmp = tmp + 1 + (tmp>>1)+(tmp>>2)+(tmp>>3)) {
- if (tmp >= 0x10000)
- tmp = 0xFFFF;
- ii16[i++] = tmp;
- AB_DPRINTF("val %08llx\n", tmp);
- if (tmp == 0xFFFF)
- break;
- }
- AB_DPRINTF("Registered %d ints values\n", i);
- nb_ii16 = i;
-}
-
-static void test_int_three_args (const unsigned char *name, test_func_t func)
-{
- uint32_t res, flags, xer;
- int i, j, k;
-
- if (verbose > 1)
- vexxx_printf( "Test instruction %s\n", name);
- for (i = 0; i < nb_iargs; i++) {
- for (j = 0; j < nb_iargs; j++) {
- for (k = 0;k < nb_iargs; k++) {
- r14 = iargs[i];
- r15 = iargs[j];
- r16 = iargs[k];
- r18 = 0;
- __asm__ __volatile__ ("mtcr 18");
- __asm__ __volatile__ ("mtxer 18");
- (*func)();
- __asm__ __volatile__ ("mfcr 18");
- flags = r18;
- __asm__ __volatile__ ("mfxer 18");
- xer = r18;
- res = r17;
- vexxx_printf("%s %08x, %08x, %08x => %08x (%08x %08x)\n",
- name, iargs[i], iargs[j], iargs[k], res, flags, xer);
- }
- vexxx_printf("\n");
- }
- vexxx_printf("\n");
- }
- vexxx_printf("\n");
-}
-
-static void test_int_two_args (const unsigned char *name, test_func_t func)
-{
- uint32_t res, flags, xer;
- int i, j;
-
- if (verbose > 1)
- vexxx_printf( "Test instruction %s\n", name);
- for (i = 0; i < nb_iargs; i++) {
- for (j = 0; j < nb_iargs; j++) {
- r14 = iargs[i];
- r15 = iargs[j];
- r18 = 0;
- __asm__ __volatile__ ("mtcr 18");
- __asm__ __volatile__ ("mtxer 18");
- (*func)();
- __asm__ __volatile__ ("mfcr 18");
- flags = r18;
- __asm__ __volatile__ ("mfxer 18");
- xer = r18;
- res = r17;
- vexxx_printf("%s %08x, %08x => %08x (%08x %08x)\n",
- name, iargs[i], iargs[j], res, flags, xer);
- }
- vexxx_printf("\n");
- }
- vexxx_printf("\n");
-}
-
-static void test_int_one_arg (const unsigned char *name, test_func_t func)
-{
- uint32_t res, flags, xer;
- int i;
-
- if (verbose > 1)
- vexxx_printf( "Test instruction %s\n", name);
- for (i = 0; i < nb_iargs; i++) {
- r14 = iargs[i];
- r18 = 0;
- __asm__ __volatile__ ("mtcr 18");
-// r18 = 0x20000000; // set xer_ca
- __asm__ __volatile__ ("mtxer 18");
- (*func)();
- res = r17;
- __asm__ __volatile__ ("mfcr 18");
- flags = r18;
- __asm__ __volatile__ ("mfxer 18");
- xer = r18;
- vexxx_printf("%s %08x => %08x (%08x %08x)\n",
- name, iargs[i], res, flags, xer);
- }
- vexxx_printf("\n");
-}
-
-static inline void _patch_op_imm (void *out, void *in,
- uint16_t imm, int sh, int len)
-{
- volatile uint32_t *p, *q;
-
- p = out;
- q = in;
- *p = (*q & ~(((1 << len) - 1) << sh)) | ((imm & ((1 << len) - 1)) << sh);
-}
-
-static inline void patch_op_imm (void *out, void *in,
- uint16_t imm, int sh, int len)
-{
- volatile uint32_t *p;
-
- p = out;
- _patch_op_imm(out, in, imm, sh, len);
- __asm__ __volatile__ ("dcbf 0, %0 ; icbi 0, %0 ; isync" ::"r"(p));
-}
-
-static inline void patch_op_imm16 (void *out, void *in, uint16_t imm)
-{
- patch_op_imm(out, in, imm, 0, 16);
-}
-
-static void test_int_one_reg_imm16 (const unsigned char *name,
- test_func_t func)
-{
- uint32_t func_buf[2], *p;
- uint32_t res, flags, xer;
- int i, j;
-
- if (verbose > 1)
- vexxx_printf( "Test instruction %s\n", name);
- for (i = 0; i < nb_iargs; i++) {
- for (j = 0; j < nb_ii16; j++) {
- p = (void *)func;
-#if 0
- vexxx_printf("copy func %s from %p to %p (%08x %08x)\n",
- name, func, func_buf, p[0], p[1]);
-#endif
- func_buf[1] = p[1];
- patch_op_imm16(func_buf, p, ii16[j]);
- func = (void *)func_buf;
-#if 0
- vexxx_printf(" => func %s from %p to %p (%08x %08x)\n",
- name, func, func_buf, func_buf[0], func_buf[1]);
-#endif
- r14 = iargs[i];
- r18 = 0;
- __asm__ __volatile__ ("mtcr 18");
- __asm__ __volatile__ ("mtxer 18");
- (*func)();
- __asm__ __volatile__ ("mfcr 18");
- flags = r18;
- __asm__ __volatile__ ("mfxer 18");
- xer = r18;
- res = r17;
- vexxx_printf("%s %08x, %08x => %08x (%08x %08x)\n",
- name, iargs[i], ii16[j], res, flags, xer);
- }
- vexxx_printf("\n");
- }
- vexxx_printf("\n");
-}
-
-/* Special test cases for:
- * rlwimi
- * rlwinm
- * rlwnm
- * srawi
- * mcrf
- * mcrfs
- * mffs
- * mtfsb0
- * mtfsb1
- */
-
-static void rlwi_cb (const unsigned char *name, test_func_t func)
-{
- uint32_t func_buf[2], *p;
- uint32_t res, flags, xer;
- int i, j, k, l;
-
- if (verbose > 1)
- vexxx_printf( "Test instruction %s\n", name);
- for (i = 0;;) {
- if (i >= nb_iargs)
- i = nb_iargs - 1;
- for (j = 0; j < 32; j++) {
- for (k = 0; k < 32; k++) {
- for (l = 0; l < 32; l++) {
- p = (void *)func;
- func_buf[1] = p[1];
- _patch_op_imm(func_buf, p, j, 11, 5);
- _patch_op_imm(func_buf, p, k, 6, 5);
- patch_op_imm(func_buf, p, l, 1, 5);
- func = (void *)func_buf;
- r14 = iargs[i];
- r18 = 0;
- __asm__ __volatile__ ("mtcr 18");
- __asm__ __volatile__ ("mtxer 18");
- (*func)();
- __asm__ __volatile__ ("mfcr 18");
- flags = r18;
- __asm__ __volatile__ ("mfxer 18");
- xer = r18;
- res = r17;
- vexxx_printf("%s %08x, %d, %d, %d => %08x (%08x %08x)\n",
- name, iargs[i], j, k, l, res, flags, xer);
- }
- vexxx_printf("\n");
- }
- vexxx_printf("\n");
- }
- vexxx_printf("\n");
- if (i == 0)
- i = 1;
- else if (i == nb_iargs - 1)
- break;
- else
- i += 3;
- }
- vexxx_printf("\n");
-}
-
-static void rlwnm_cb (const unsigned char *name, test_func_t func)
-{
- uint32_t func_buf[2], *p;
- uint32_t res, flags, xer;
- int i, j, k, l;
-
- if (verbose > 1)
- vexxx_printf( "Test instruction %s\n", name);
- for (i = 0; i < nb_iargs; i++) {
- for (j = 0; j < 64; j++) {
- for (k = 0; k < 32; k++) {
- for (l = 0; l < 32; l++) {
- p = (void *)func;
- func_buf[1] = p[1];
- _patch_op_imm(func_buf, p, k, 6, 5);
- patch_op_imm(func_buf, p, l, 1, 5);
- func = (void *)func_buf;
- r14 = iargs[i];
- r15 = j;
- r18 = 0;
- __asm__ __volatile__ ("mtcr 18");
- __asm__ __volatile__ ("mtxer 18");
- (*func)();
- __asm__ __volatile__ ("mfcr 18");
- flags = r18;
- __asm__ __volatile__ ("mfxer 18");
- xer = r18;
- res = r17;
- vexxx_printf("%s %08x, %08x, %d, %d => %08x (%08x %08x)\n",
- name, iargs[i], j, k, l, res, flags, xer);
- }
- vexxx_printf("\n");
- }
- vexxx_printf("\n");
- }
- vexxx_printf("\n");
- }
- vexxx_printf("\n");
-}
-
-static void srawi_cb (const unsigned char *name, test_func_t func)
-{
- uint32_t func_buf[2], *p;
- uint32_t res, flags, xer;
- int i, j;
-
- if (verbose > 1)
- vexxx_printf( "Test instruction %s\n", name);
- for (i = 0; i < nb_iargs; i++) {
- for (j = 0; j < 32; j++) {
- p = (void *)func;
- func_buf[1] = p[1];
- patch_op_imm(func_buf, p, j, 11, 5);
- func = (void *)func_buf;
- r14 = iargs[i];
- r18 = 0;
- __asm__ __volatile__ ("mtcr 18");
- __asm__ __volatile__ ("mtxer 18");
- (*func)();
- __asm__ __volatile__ ("mfcr 18");
- flags = r18;
- __asm__ __volatile__ ("mfxer 18");
- xer = r18;
- res = r17;
- vexxx_printf("%s %08x, %d => %08x (%08x %08x)\n",
- name, iargs[i], j, res, flags, xer);
- }
- vexxx_printf("\n");
- }
- vexxx_printf("\n");
-}
-
-typedef struct special_t special_t;
-struct special_t {
- const unsigned char *name;
- void (*test_cb)(const unsigned char *name, test_func_t func);
-};
-
-static void test_special (special_t *table,
- const unsigned char *name, test_func_t func)
-{
- const unsigned char *tmp;
- int i;
-
- for (tmp = name; my_isspace(*tmp); tmp++)
- continue;
- for (i = 0; table[i].name != NULL; i++) {
-#if 0
- vexxx_printf( "look for handler for '%s' (%s)\n", name,
- table[i].name);
-#endif
- if (my_strcmp(table[i].name, tmp) == 0) {
- (*table[i].test_cb)(name, func);
- return;
- }
- }
- vexxx_printf( "ERROR: no test found for op '%s'\n", name);
-}
-
-static special_t special_int_ops[] = {
-#if 0
- {
- "rlwimi", /* One register + 3 5 bits immediate arguments */
- &rlwi_cb,
- },
- {
- "rlwimi.", /* One register + 3 5 bits immediate arguments */
- &rlwi_cb,
- },
- {
- "rlwinm", /* One register + 3 5 bits immediate arguments */
- &rlwi_cb,
- },
- {
- "rlwinm.", /* One register + 3 5 bits immediate arguments */
- &rlwi_cb,
- },
- {
- "rlwnm", /* Two registers + 3 5 bits immediate arguments */
- &rlwnm_cb,
- },
- {
- "rlwnm.", /* Two registers + 3 5 bits immediate arguments */
- &rlwnm_cb,
- },
- {
- "srawi", /* One register + 1 5 bits immediate arguments */
- &srawi_cb,
- },
- {
- "srawi.", /* One register + 1 5 bits immediate arguments */
- &srawi_cb,
- },
-#endif
-#if 0
- {
- "mcrf", /* 2 3 bits immediate arguments */
- &mcrf_cb,
- },
- {
- "mcrf", /* 2 3 bits immediate arguments */
- &mcrf_cb,
- },
-#endif
- {
- NULL,
- NULL,
- },
-};
-
-static void test_int_special (const unsigned char *name, test_func_t func)
-{
- test_special(special_int_ops, name, func);
-}
-
-static test_loop_t int_loops[] = {
- &test_int_one_arg,
- &test_int_two_args,
- &test_int_three_args,
- &test_int_two_args,
- &test_int_one_reg_imm16,
- &test_int_one_reg_imm16,
- &test_int_special,
-};
-
-#if !defined (NO_FLOAT)
-static void test_float_three_args (const unsigned char *name, test_func_t func)
-{
- double res;
- uint64_t u0, u1, u2, ur;
- uint32_t flags;
- int i, j, k;
-
- if (verbose > 1)
- vexxx_printf( "Test instruction %s\n", name);
- for (i = 0; i < nb_fargs; i++) {
- for (j = 0; j < nb_fargs; j++) {
- for (k = 0;k < nb_fargs; k++) {
- u0 = *(uint64_t *)(&fargs[i]);
- u1 = *(uint64_t *)(&fargs[j]);
- u2 = *(uint64_t *)(&fargs[k]);
- f14 = fargs[i];
- f15 = fargs[j];
- f16 = fargs[k];
- r18 = 0;
- __asm__ __volatile__ ("mtcr 18");
- __asm__ __volatile__ ("mtxer 18");
- f18 = +0.0;
- __asm__ __volatile__ ("mtfsf 0xFF, 18");
- (*func)();
- __asm__ __volatile__ ("mfcr 18");
- flags = r18;
- res = f17;
- ur = *(uint64_t *)(&res);
- vexxx_printf("%s %016llx, %016llx, %016llx => %016llx (%08x)\n",
- name, u0, u1, u2, ur, flags);
- }
- vexxx_printf("\n");
- }
- vexxx_printf("\n");
- }
- vexxx_printf("\n");
-}
-
-static void test_float_two_args (const unsigned char *name, test_func_t func)
-{
- double res;
- uint64_t u0, u1, ur;
- uint32_t flags;
- int i, j;
-
- if (verbose > 1)
- vexxx_printf( "Test instruction %s\n", name);
- for (i = 0; i < nb_fargs; i++) {
- for (j = 0; j < nb_fargs; j++) {
- u0 = *(uint64_t *)(&fargs[i]);
- u1 = *(uint64_t *)(&fargs[j]);
- f14 = fargs[i];
- f15 = fargs[j];
- r18 = 0;
- __asm__ __volatile__ ("mtcr 18");
- __asm__ __volatile__ ("mtxer 18");
- f18 = +0.0;
- __asm__ __volatile__ ("mtfsf 0xFF, 18");
- (*func)();
- __asm__ __volatile__ ("mfcr 18");
- flags = r18;
- res = f17;
- ur = *(uint64_t *)(&res);
- vexxx_printf("%s %016llx, %016llx => %016llx (%08x)\n",
- name, u0, u1, ur, flags);
- }
- vexxx_printf("\n");
- }
- vexxx_printf("\n");
-}
-
-static void test_float_one_arg (const unsigned char *name, test_func_t func)
-{
- double res;
- uint64_t u0, ur;
- uint32_t flags;
- int i;
-
- if (verbose > 1)
- vexxx_printf( "Test instruction %s\n", name);
- for (i = 0; i < nb_fargs; i++) {
- u0 = *(uint64_t *)(&fargs[i]);
- f14 = fargs[i];
- r18 = 0;
- __asm__ __volatile__ ("mtcr 18");
- __asm__ __volatile__ ("mtxer 18");
- f18 = +0.0;
- __asm__ __volatile__ ("mtfsf 0xFF, 18");
- (*func)();
- __asm__ __volatile__ ("mfcr 18");
- flags = r18;
- res = f17;
- ur = *(uint64_t *)(&res);
- vexxx_printf("%s %016llx => %016llx (%08x)\n", name, u0, ur, flags);
- }
- vexxx_printf("\n");
-}
-
-static special_t special_float_ops[] = {
-#if 0
- {
- "mffs", /* One 5 bits immediate argument */
- &mffs_cb,
- },
- {
- "mffs.", /* One 5 bits immediate argument */
- &mffs_cb,
- },
- {
- "mtfsb0", /* One 5 bits immediate argument */
- &mffs_cb,
- },
- {
- "mtfsb0.", /* One 5 bits immediate argument */
- &mffs_cb,
- },
- {
- "mtfsb1", /* One 5 bits immediate argument */
- &mffs_cb,
- },
- {
- "mtfsb1.", /* One 5 bits immediate argument */
- &mffs_cb,
- },
- {
- "mtfsf", /* One register + 1 8 bits immediate argument */
- &mtfsf_cb,
- },
- {
- "mtfsf.", /* One register + 1 8 bits immediate argument */
- &mtfsf_cb,
- },
- {
- "mtfsfi", /* One 5 bits argument + 1 5 bits argument */
- &mtfsfi_cb,
- },
- {
- "mtfsfi.", /* One 5 bits argument + 1 5 bits argument */
- &mtfsfi_cb,
- },
-#endif
- {
- NULL,
- NULL,
- },
-};
-
-static void test_float_special (const unsigned char *name, test_func_t func)
-{
- test_special(special_float_ops, name, func);
-}
-
-static test_loop_t float_loops[] = {
- &test_float_one_arg,
- &test_float_two_args,
- &test_float_three_args,
- &test_float_two_args,
- NULL,
- NULL,
- &test_float_special,
-};
-#endif /* !defined (NO_FLOAT) */
-
-
-#if defined (HAS_ALTIVEC) /* XXX: TODO */
-#endif /* defined (HAS_ALTIVEC) */
-
-#if defined (IS_PPC405)
-static void test_ppc405 (const unsigned char *name, test_func_t func)
-{
- uint32_t res, flags, xer;
- int i, j, k;
-
- if (verbose > 1)
- vexxx_printf( "Test instruction %s\n", name);
- for (i = 0; i < nb_iargs; i++) {
- for (j = 0; j < nb_iargs; j++) {
- for (k = 0;k < nb_iargs; k++) {
- r14 = iargs[i];
- r15 = iargs[j];
- /* Beware: the third argument and the result
- * are in the same register
- */
- r17 = iargs[k];
- r18 = 0;
- __asm__ __volatile__ ("mtcr 18");
- __asm__ __volatile__ ("mtxer 18");
- (*func)();
- __asm__ __volatile__ ("mfcr 18");
- flags = r18;
- __asm__ __volatile__ ("mfxer 18");
- xer = r18;
- res = r17;
- vexxx_printf("%s %08x, %08x, %08x => %08x (%08x %08x)\n",
- name, iargs[i], iargs[j], iargs[k], res, flags, xer);
- }
- vexxx_printf("\n");
- }
- vexxx_printf("\n");
- }
- vexxx_printf("\n");
-}
-#endif /* defined (IS_PPC405) */
-
-static int check_filter (unsigned char *filter)
-{
- unsigned char *c;
- int ret = 1;
-
- if (filter != NULL) {
- c = my_strchr(filter, '*');
- if (c != NULL) {
- *c = '\0';
- ret = 0;
- }
- }
-
- return ret;
-}
-
-static int check_name (const unsigned char *name, const unsigned char *filter,
- int exact)
-{
- int nlen, flen;
- int ret = 0;
-
- if (filter != NULL) {
- for (; my_isspace(*name); name++)
- continue;
- FDPRINTF("Check '%s' againt '%s' (%s match)\n",
- name, filter, exact ? "exact" : "starting");
- nlen = vexxx_strlen(name);
- flen = vexxx_strlen(filter);
- if (exact) {
- if (nlen == flen && my_memcmp(name, filter, flen) == 0)
- ret = 1;
- } else {
- if (flen <= nlen && my_memcmp(name, filter, flen) == 0)
- ret = 1;
- }
- } else {
- ret = 1;
- }
-
- return ret;
-}
-
-static void do_tests (int one_arg, int two_args, int three_args,
- int arith, int logical, int compare,
- int integer, int floats, int p405,
- int altivec, int faltivec,
- int cr, unsigned char *filter)
-{
-#if defined (IS_PPC405)
- test_loop_t tmpl;
-#endif
- test_loop_t *loop;
- test_t *tests;
- int nb_args, type, family;
- int i, j, n;
- int exact;
-
- exact = check_filter(filter);
- n = 0;
- for (i = 0; all_tests[i].name != NULL; i++) {
- nb_args = all_tests[i].flags & PPC_NB_ARGS;
- /* Check number of arguments */
- if ((nb_args == 1 && !one_arg) ||
- (nb_args == 2 && !two_args) ||
- (nb_args == 3 && !three_args))
- continue;
- /* Check instruction type */
- type = all_tests[i].flags & PPC_TYPE;
- if ((type == PPC_ARITH && !arith) ||
- (type == PPC_LOGICAL && !logical) ||
- (type == PPC_COMPARE && !compare))
- continue;
- /* Check instruction family */
- family = all_tests[i].flags & PPC_FAMILY;
- if ((family == PPC_INTEGER && !integer) ||
- (family == PPC_FLOAT && !floats) ||
- (family == PPC_405 && !p405) ||
- (family == PPC_ALTIVEC && !altivec) ||
- (family == PPC_FALTIVEC && !faltivec))
- continue;
- /* Check flags update */
- if (((all_tests[i].flags & PPC_CR) && cr == 0) ||
- (!(all_tests[i].flags & PPC_CR) && cr == 1))
- continue;
- /* All passed, do the tests */
- tests = all_tests[i].tests;
- /* Select the test loop */
- switch (family) {
- case PPC_INTEGER:
- loop = &int_loops[nb_args - 1];
- break;
- case PPC_FLOAT:
-#if !defined (NO_FLOAT)
- loop = &float_loops[nb_args - 1];
- break;
-#else
- vexxx_printf( "Sorry. "
- "PPC floating point instructions tests "
- "are disabled on your host\n");
-#endif /* !defined (NO_FLOAT) */
-
- case PPC_405:
-#if defined (IS_PPC405)
- tmpl = &test_ppc405;
- loop = &tmpl;
- break;
-#else
- vexxx_printf( "Sorry. "
- "PPC405 instructions tests are disabled on your host\n");
- continue;
-#endif /* defined (IS_PPC405) */
- case PPC_ALTIVEC:
-#if defined (HAS_ALTIVEC)
-#if 0
- loop = &altivec_int_loops[nb_args - 1];
- break;
-#else
- vexxx_printf( "Sorry. "
- "Altivec instructions tests are not yet implemented\n");
- continue;
-#endif
-#else
- vexxx_printf( "Sorry. "
- "Altivec instructions tests are disabled on your host\n");
- continue;
-#endif
- case PPC_FALTIVEC:
-#if defined (HAS_ALTIVEC)
-#if 0
- loop = &altivec_float_loops[nb_args - 1];
- break;
-#else
- vexxx_printf( "Sorry. "
- "Altivec instructions tests are not yet implemented\n");
- continue;
-#endif
-#else
- vexxx_printf( "Sorry. "
- "Altivec float instructions tests "
- "are disabled on your host\n");
-#endif
- continue;
- default:
- vexxx_printf("ERROR: unknown insn family %08x\n", family);
- continue;
- }
- if (verbose > 0)
- vexxx_printf( "%s:\n", all_tests[i].name);
- for (j = 0; tests[j].name != NULL; j++) {
- if (check_name(tests[j].name, filter, exact))
- (*loop)(tests[j].name, tests[j].func);
- n++;
- }
- vexxx_printf("\n");
- }
- vexxx_printf( "All done. Tested %d different instructions\n", n);
-}
-
-#if 0 // unused
-static void usage (void)
-{
- vexxx_printf(
- "test-ppc [-1] [-2] [-3] [-*] [-t <type>] [-f <family>] [-u] "
- "[-n <filter>] [-x] [-h]\n"
- "\t-1: test opcodes with one argument\n"
- "\t-2: test opcodes with two arguments\n"
- "\t-3: test opcodes with three arguments\n"
- "\t-*: launch test without checking the number of arguments\n"
- "\t-t: launch test for instructions of type <type>\n"
- "\t recognized types:\n"
- "\t\tarith (or a)\n"
- "\t\tlogical (or l)\n"
- "\t\tcompare (or c)\n"
- "\t-f: launch test for instructions of family <family>\n"
- "\t recognized families:\n"
- "\t\tinteger (or i)\n"
- "\t\tfloat (or f)\n"
- "\t\tppc405 (or mac)\n"
- "\t\taltivec (or a)\n"
- "\t-u: test instructions that update flags\n"
- "\t-n: filter instructions with <filter>\n"
- "\t <filter> can be in two forms:\n"
- "\t\tname : filter functions that exactly match <name>\n"
- "\t\tname* : filter functions that start with <name>\n"
- "\t-h: print this help\n"
- );
-}
-#endif
-
-int _main (int argc, char **argv)
-{
- unsigned char /* *tmp, */ *filter = NULL;
- int one_arg = 0, two_args = 0, three_args = 0;
- int arith = 0, logical = 0, compare = 0;
- int integer = 0, floats = 0, p405 = 0, altivec = 0, faltivec = 0;
- int cr = -1;
- //int c;
-
- // while ((c = getopt(argc, argv, "123t:f:n:uvh")) != -1) {
- // switch (c) {
- // case '1':
- // one_arg = 1;
- // break;
- // case '2':
- // two_args = 1;
- // break;
- // case '3':
- // three_args = 1;
- // break;
- // case 't':
- // tmp = optarg;
- // if (my_strcmp(tmp, "arith") == 0 || my_strcmp(tmp, "a") == 0) {
- // arith = 1;
- // } else if (my_strcmp(tmp, "logical") == 0 || my_strcmp(tmp, "l") == 0) {
- // logical = 1;
- // } else if (my_strcmp(tmp, "compare") == 0 || my_strcmp(tmp, "c") == 0) {
- // compare = 1;
- // } else {
- // goto bad_arg;
- // }
- // break;
- // case 'f':
- // tmp = optarg;
- // if (my_strcmp(tmp, "integer") == 0 || my_strcmp(tmp, "i") == 0) {
- // integer = 1;
- // } else if (my_strcmp(tmp, "float") == 0 || my_strcmp(tmp, "f") == 0) {
- // floats = 1;
- // } else if (my_strcmp(tmp, "ppc405") == 0 || my_strcmp(tmp, "mac") == 0) {
- // p405 = 1;
- // } else if (my_strcmp(tmp, "altivec") == 0 || my_strcmp(tmp, "a") == 0) {
- // altivec = 1;
- // faltivec = 1;
- // } else {
- // goto bad_arg;
- // }
- // break;
- // case 'n':
- // filter = optarg;
- // break;
- // case 'u':
- // cr = 1;
- // break;
- // case 'h':
- // usage();
- // return 0;
- // case 'v':
- // verbose++;
- // break;
- // default:
- // usage();
- // vexxx_printf( "Unknown argument: '%c'\n", c);
- // return 1;
- // bad_arg:
- // usage();
- // vexxx_printf( "Bad argument for '%c': '%s'\n", c, tmp);
- // return 1;
- // }
- // }
- // if (argc != optind) {
- // usage();
- // vexxx_printf( "Bad number of arguments\n");
- // return 1;
- // }
-
- if (one_arg == 0 && two_args == 0 && three_args == 0) {
- one_arg = 1;
- two_args = 1;
- three_args = 1;
- }
- if (arith == 0 && logical == 0 && compare == 0) {
- arith = 1;
- logical = 1;
- compare = 1;
- }
- if (integer == 0 && floats == 0 && altivec == 0 && faltivec == 0 &&
- p405 == 0) {
- integer = 1;
- floats = 1;
- altivec = 1;
- faltivec = 1;
- p405 = 1;
- }
- if (cr == -1)
- cr = 2;
- build_iargs_table();
- build_fargs_table();
- build_ii16_table();
-
-#if 1
- one_arg=1;
- two_args=1;
- three_args=1;
-
- arith=1;
- logical=1;
- compare=1;
-
- integer=1;
- floats=0;
-
- p405=0;
- altivec=0;
- faltivec=0;
-#endif
-
- do_tests(one_arg, two_args, three_args,
- arith, logical, compare,
- integer, floats, p405, altivec, faltivec,
- cr, filter);
-
- return 0;
-}
-
-
-void entry ( HWord(*service)(HWord,HWord) )
-{
- char* argv[2] = { NULL, NULL };
- serviceFn = service;
- _main(0, argv);
- (*service)(0,0);
-}
+++ /dev/null
-
-
-static void bar ( void*(*service)(int,int) )
-{
- __asm__ __volatile__ ("addi 17, 14, 5");
-}
-
-void entry ( void*(*service)(int,int) )
-{
- bar(service);
- service(0,0);
-}