* gas-test.scm (<hw-asm>,test-data): Choose pseudo-random data.
(<keyword>,test-data): Likewise.
(<hw-address>,test-data): Likewise.
(<hw-iaddress>,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.
2001-03-24 Ben Elliston <bje@redhat.com>
+ * gas-test.scm (<hw-asm>,test-data): Choose pseudo-random data.
+ (<keyword>,test-data): Likewise.
+ (<hw-address>,test-data): Likewise.
+ (<hw-iaddress>,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".
-; 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.
<hw-asm> '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!
<keyword> '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!
<hw-address> '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!
<hw-iaddress> '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! <hw-register> 'indices '(test-data))
(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.
(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.
)
; 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")
(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))
(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\"
; 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.
; 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.
\f
; Variables representing misc. global constants.
; 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)
--- /dev/null
+;;; 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.)