From d826f00c91fa5cb72adf232e3798aaf5bfadb026 Mon Sep 17 00:00:00 2001 From: Ben Elliston Date: Sat, 24 Mar 2001 12:22:35 +0000 Subject: [PATCH] 2001-03-24 Ben Elliston * gas-test.scm (,test-data): Choose pseudo-random data. (,test-data): Likewise. (,test-data): Likewise. (,test-data): Likewise. (-collate-test-set): New function. (build-test-set): Use it. (gen-gas-test): Generate five test cases per instruction. (cgen-allinsn.exp): Include "-*- Tcl -*-" in DejaGNU test file. * read.scm: Load "slib/random" if random is not defined. * slib/random.scm: New file. --- ChangeLog | 12 +++++ gas-test.scm | 58 ++++++++++++++---------- read.scm | 6 +-- slib/random.scm | 117 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 166 insertions(+), 27 deletions(-) create mode 100644 slib/random.scm diff --git a/ChangeLog b/ChangeLog index 534a320..89cfee4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 2001-03-24 Ben Elliston + * gas-test.scm (,test-data): Choose pseudo-random data. + (,test-data): Likewise. + (,test-data): Likewise. + (,test-data): Likewise. + (-collate-test-set): New function. + (build-test-set): Use it. + (gen-gas-test): Generate five test cases per instruction. + (cgen-allinsn.exp): Include "-*- Tcl -*-" in DejaGNU test file. + + * read.scm: Load "slib/random" if random is not defined. + * slib/random.scm: New file. + * utils.scm: Remove comments about the Hobbit compiler. (copyright-cygnus): Add 2001. (package-cygnus-simulators): Replace "Cygnus" with "Red Hat". diff --git a/gas-test.scm b/gas-test.scm index e848c46..0c0a347 100644 --- a/gas-test.scm +++ b/gas-test.scm @@ -1,5 +1,5 @@ -; CPU description file generator for the GAS testsuite. -; Copyright (C) 2000 Red Hat, Inc. +; CPU description file generator for the GNU assembler testsuite. +; Copyright (C) 2000, 2001 Red Hat, Inc. ; This file is part of CGEN. ; See file COPYING.CGEN for details. @@ -33,37 +33,38 @@ 'test-data (lambda (self n) ; FIXME: floating point support - (let ((signed (list 0 1 -1 2 -2)) - (unsigned (list 0 1 2 3 4)) - (mode (elm-get self 'mode))) + (let* ((signed (list 0 1 -1 2 -2)) + (unsigned (list 0 1 2 3 4)) + (mode (elm-get self 'mode)) + (test-cases (if (eq? (mode:class mode) 'UINT) unsigned signed)) + (selection (map (lambda (z) (random (length test-cases))) (iota n)))) + ; FIXME: wider ranges. (map number->string - (list-take n - (if (eq? (mode:class mode) 'UINT) - unsigned - signed))))) + (map (lambda (n) (list-ref test-cases n)) selection)))) ) (method-make! 'test-data (lambda (self n) - (let* ((values (elm-get self 'values)) - (n (min n (length values)))) - ; FIXME: Need to handle mach variants. - (map car (list-take n values)))) + (let* ((test-cases (elm-get self 'values)) + (selection (map (lambda (z) (random (length test-cases))) (iota n)))) + (map (lambda (n) (car (list-ref test-cases n))) selection))) ) (method-make! 'test-data (lambda (self n) - (let ((test-data '("foodata" "4" "footext" "-4"))) - (list-take n test-data))) + (let* ((test-cases '("foodata" "4" "footext" "-4")) + (selection (map (lambda (z) (random (length test-cases))) (iota n)))) + (map (lambda (n) (list-ref test-cases n)) selection))) ) (method-make! 'test-data (lambda (self n) - (let ((test-data '("footext" "4" "foodata" "-4"))) - (list-take n test-data))) + (let* ((test-cases '("footext" "4" "foodata" "-4")) + (selection (map (lambda (z) (random (length test-cases))) (iota n)))) + (map (lambda (n) (list-ref test-cases n)) selection))) ) (method-make-forward! 'indices '(test-data)) @@ -96,6 +97,18 @@ (else (loop result (cdr l))))) ) +; Collate a list of operands into a test test. +; Input is a list of operand lists. Returns a collated set of test +; inputs. For example: +; ((r0 r1 r2) (r3 r4 r5) (2 3 8)) => ((r0 r3 2) (r1 r4 3) (r2 r5 8)) + +(define (-collate-test-set L) + (if (=? (length (car L)) 0) + '() + (cons (map car L) + (-collate-test-set (map cdr L)))) +) + ; Given a list of operands for an instruction, return the test set ; (all possible combinations). ; N is the number of testcases for each operand. @@ -104,10 +117,8 @@ (define (build-test-set op-list n) (let ((test-data (map (lambda (op) (operand-test-data op n)) op-list)) (len (length op-list))) - ; FIXME: Make slicker later. (cond ((=? len 0) (list (list))) - ((=? len 1) test-data) - (else (list (map car test-data))))) + (else (-collate-test-set test-data)))) ) ; Given an assembler expression and a set of operands build a testcase. @@ -126,7 +137,7 @@ ) ; Generate the testsuite for INSN. -; FIXME: This needs to be expanded upon. +; FIXME: make the number of cases an argument to this application. (define (gen-gas-test insn) (logit 2 "Generating gas test data for " (obj:name insn) " ...\n") @@ -136,8 +147,7 @@ (gen-sym insn) ":\n" (let* ((syntax-list (insn-tmp insn)) (op-list (extract-operands syntax-list)) - (test-set (build-test-set op-list 2))) - ;(display test-set) (newline) + (test-set (build-test-set op-list 5))) (string-map (lambda (test-data) (build-asm-testcase syntax-list test-data)) test-set)) @@ -231,7 +241,7 @@ footext:\n" (logit 1 "Generating allinsn.exp ...\n") (string-append "\ -# " (string-upcase (current-arch-name)) " assembler testsuite. +# " (string-upcase (current-arch-name)) " assembler testsuite. -*- Tcl -*- if [istarget " (current-arch-name) "*-*-*] { run_dump_test \"allinsn\" diff --git a/read.scm b/read.scm index 0d8c6b3..efabe95 100644 --- a/read.scm +++ b/read.scm @@ -1,5 +1,5 @@ ; Top level file for reading and recording .cpu file contents. -; Copyright (C) 2000 Red Hat, Inc. +; Copyright (C) 2000, 2001 Red Hat, Inc. ; This file is part of CGEN. ; See file COPYING.CGEN for details. @@ -58,8 +58,7 @@ ; usually these procs return "*UNSPECIFIED*" ; - all -foo-parse,parse-foo procs shall have `context' as the first arg ; [FIXME: not all such procs have been converted] -; - stay away from non-portable C symbols, it makes using hobbit more difficult -; e.g. don't have anything named `index', sigh. +; - stay away from non-portable C symbols. ; Variables representing misc. global constants. @@ -167,6 +166,7 @@ ; Used to pretty-print debugging messages. (maybe-load "slib/pp" #f 'pretty-print) ; Used by pretty-print. +(maybe-load "slib/random" #f 'random) (maybe-load "slib/genwrite" #f 'generic-write) (maybe-load "utils" #f 'logit) (maybe-load "utils-cgen" "utils_cgen" 'obj:name) diff --git a/slib/random.scm b/slib/random.scm new file mode 100644 index 0000000..3603c33 --- /dev/null +++ b/slib/random.scm @@ -0,0 +1,117 @@ +;;; random-maker: constructs a random-number generator +;;; Copyright (c) 2001 John David Stone + +;;; This program is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by the +;;; Free Software Foundation; either version 2 of the License, or (at your +;;; option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License along +;;; with this program; if not, write to the Free Software Foundation, Inc., +;;; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +;;; John David Stone +;;; Department of Mathematics and Computer Science +;;; Grinnell College +;;; Grinnell, Iowa 50112 +;;; stone@cs.grinnell.edu + +;;; created July 10, 1995 +;;; last revised March 23, 2001 + +;;; A call to the RANDOM-MAKER procedure presented here yields a +;;; dynamically constructed procedure that acts as a random-number +;;; generator. When the dynamically constructed procedure is invoked with +;;; no arguments, it returns a pseudo-random real value evenly distributed +;;; in the range [0.0, 1.0); when it is invoked with one argument (which +;;; should be a positive integer N), it returns a pseudo-random integer +;;; value evenly distributed in the range [0, N); when it is invoked with +;;; two arguments, the first of which should be a positive integer and the +;;; second the symbol RESET, it changes the seed of the random-number +;;; generator to the value of the first argument. + +;;; The generator employs the linear-congruential method, and specifically +;;; uses a choice of multiplier that was proposed as a standard by Stephen +;;; K. Park _et al._ in ``Technical correspondence,'' _Communications of +;;; the ACM_ 36 (1993), number 7, 108--110. + +(define random-maker + (let* ((multiplier 48271) + (modulus 2147483647) + (apply-congruence + (lambda (current-seed) + (let ((candidate (modulo (* current-seed multiplier) + modulus))) + (if (zero? candidate) + modulus + candidate)))) + (coerce + (lambda (proposed-seed) + (if (integer? proposed-seed) + (- modulus (modulo proposed-seed modulus)) + 19860617)))) ;; an arbitrarily chosen birthday + (lambda (initial-seed) + (let ((seed (coerce initial-seed))) + (lambda args + (cond ((null? args) + (set! seed (apply-congruence seed)) + (/ (- modulus seed) modulus)) + ((null? (cdr args)) + (let* ((proposed-top + (ceiling (abs (car args)))) + (exact-top + (if (inexact? proposed-top) + (inexact->exact proposed-top) + proposed-top)) + (top + (if (zero? exact-top) + 1 + exact-top))) + (set! seed (apply-congruence seed)) + (inexact->exact (floor (* top (/ seed modulus)))))) + ((eq? (cadr args) 'reset) + (set! seed (coerce (car args)))) + (else + (display "random: unrecognized message") + (newline)))))))) + +(define random + (random-maker 19781116)) ;; another arbitrarily chosen birthday + +;;; The RANDOM procedure added at the end shows how to call +;;; RANDOM-MAKER to get a random-number generator with a specific seed. +;;; The random-number generator itself is invoked as described above, by +;;; such calls as (RANDOM), to get a real number between 0 and 1, and +;;; (RANDOM N), to get an integer in the range from 0 to N - 1. + +;;; The location of the binding of SEED -- inside the body of RANDOM-MAKER, +;;; but outside the LAMBDA-expression that denotes the dynamically +;;; allocated procedure -- ensures that the storage location containing the +;;; seed will be different for each invocation of RANDOM-MAKER (so that +;;; every generator that is constructed will have an independently settable +;;; seed), yet inaccessible except through invocations to the dynamically +;;; allocated procedure itself. In effect, random-number generators in +;;; this implementation constitute an abstract data type with the +;;; constructor RANDOM-MAKER and exactly three operations, corresponding to +;;; the three possible arities of a call to the generator. + +;;; When calling this procedure, the programmer must supply an initial +;;; value for the seed. This should be an integer (if it is not, an +;;; arbitrary default seed is silently substituted). The value supplied is +;;; forced into the range (0, MODULUS], since it is an invariant of the +;;; procedure that the seed must always be in this range. + +;;; To obtain an initial seed that is likely to be different each time a +;;; new generator is constructed, use some combination of the program's +;;; running time and the wall-clock time. (Most Scheme implementations +;;; provide procedures that return one or both of these quantities. For +;;; instance, in SCM, the call +;;; +;;; (RANDOM-MAKER (+ (* 100000 (GET-INTERNAL-RUN-TIME)) (CURRENT-TIME))) +;;; +;;; yields a generator with an effectively random seed.) -- 2.43.5