* rtl-c.scm (s-do-count): New function.
(do-count): New rtl handler.
* rtl-traverse.scm (-rtx-traverse-iteration): New function.
(-rtx-make-traverser-table): Add ITERATION.
* rtl.scm (rtx-env-make-iteration-locals): New function.
* rtx-funcs.scm (do-count): New rtl function.
* cpu/play.cpu: Add do-count-test insn.
* doc/rtl.texi: Add docs on do-count.
+2009-08-27 Doug Evans <dje@sebabeach.org>
+
+ Add do-count rtl function.
+ * rtl-c.scm (s-do-count): New function.
+ (do-count): New rtl handler.
+ * rtl-traverse.scm (-rtx-traverse-iteration): New function.
+ (-rtx-make-traverser-table): Add ITERATION.
+ * rtl.scm (rtx-env-make-iteration-locals): New function.
+ * rtx-funcs.scm (do-count): New rtl function.
+ * cpu/play.cpu: Add do-count-test insn.
+ * doc/rtl.texi: Add docs on do-count.
+
2009-08-26 Doug Evans <dje@sebabeach.org>
* read.scm (parse-error): Change error message output format
(+ OP1_4 OP2_1 dr sr)
(sequence ((WI tmp1))
(parallel ()
- (set tmp1 (add dr sr))
+ (set (local DFLT tmp1) (add dr sr))
(set vbit (add-oflag dr sr (const 0)))
(set cbit (add-cflag dr sr (const 0))))
(set zbit (zflag tmp1))
(load-op h OP2_10 HI ext-expr)
(load-op ub OP2_9 QI zext-expr)
(load-op uh OP2_11 HI zext-expr)
+
+(dni do-count-test "do-count-test"
+ ()
+ "do-count-test $dr,$sr"
+ (+ OP1_7 OP2_0 dr sr)
+ (do-count VOID 4 iter (set dr (add sr iter)))
+ ()
+)
@code{index} is the name of the index as it appears in @code{expression}.
-At present, @code{sequence}, @code{parallel}, and @code{case} expressions
-are not allowed here.
+At present, @code{sequence}, @code{parallel}, @code{do-count}
+and @code{case} expressions are not allowed here.
@subsection set
@item (parallel mode empty expr1 ...)
Execute @samp{expr1}, @samp{expr2}, etc. in parallel. All inputs are
read before any output is written. @samp{empty} must be @samp{()} and
-is present for consistency with @samp{sequence}. @samp{mode} must be
-@samp{VOID} (void mode).
+is present for consistency with @samp{sequence}.
+@samp{mode} must be @samp{VOID} (void mode), or it can be elided.
+
+@item (do-count mode number-of-iterations iteration-variable expr1 ...)
+Execute @samp{expr1}, @samp{expr2}, etc. the specified number of times.
+@samp{iteration-variable} will contain the iteration number and is
+available for use in expressions. It has mode @samp{INT}.
+It's value will be 0 ... @samp{number-of-iterations} - 1.
+@samp{number-of-iterations} must (currently) be a constant non-negative
+integer.
+@samp{mode} must be @samp{VOID} (void mode), or it can be elided.
@item (unop mode operand)
Perform a unary arithmetic operation. @samp{unop} is one of @code{neg},
@item a memory reference, created with (mem mode address)
@item a constant, created with (const mode value)
@item a `sequence' local variable
+@item a `do-count' iteration variable
@item another expression
@end itemize
exprs))
(if (rtx-env-empty? env) ")" "; })")))))
)
+
+; Return a <c-expr> node for a `do-count'.
+
+(define (s-do-count estate nr-times iter-var . exprs)
+ (let* ((env (rtx-env-make-iteration-locals iter-var))
+ (estate (estate-push-env estate env))
+ (c-iter-var (rtx-temp-value (rtx-temp-lookup (estate-env estate) iter-var))))
+ (cx:make VOID
+ (string-append
+ "{\n"
+ (gen-temp-defs estate env)
+ " for (" c-iter-var " = 0;\n"
+ " " c-iter-var " < " (number->string nr-times) ";\n"
+ " ++" c-iter-var ")\n"
+ " {\n"
+ (string-map (lambda (e)
+ (rtl-c-with-estate estate DFLT e))
+ exprs)
+ " }\n"
+ "}\n"))
+ )
+)
\f
; *****************************************************************************
;
(cons estate (cons mode (cons locals (cons expr exprs)))))
)
+(define-fn do-count (estate options mode nr-times iter-var expr . exprs)
+ (apply s-do-count
+ (cons estate (cons nr-times (cons iter-var (cons expr exprs)))))
+)
+
(define-fn closure (estate options mode expr env)
; ??? estate-push-env?
(rtl-c-with-estate (estate-new-env estate env) DFLT expr)
(cons val (tstate-push-env tstate env)))
)
+(define (-rtx-traverse-iteration val mode expr op-num tstate appstuff)
+ (if (not (symbol? val))
+ (-rtx-traverse-error tstate "bad iteration variable name"
+ expr op-num))
+ (let ((env (rtx-env-make-iteration-locals val)))
+ (cons val (tstate-push-env tstate env)))
+)
+
(define (-rtx-traverse-env val mode expr op-num tstate appstuff)
; VAL is an environment stack.
(if (not (list? val))
(cons 'CONDRTX (/fastcall-make -rtx-traverse-condrtx))
(cons 'CASERTX (/fastcall-make -rtx-traverse-casertx))
(cons 'LOCALS (/fastcall-make -rtx-traverse-locals))
+ (cons 'ITERATION (/fastcall-make -rtx-traverse-iteration))
(cons 'ENV (/fastcall-make -rtx-traverse-env))
(cons 'ATTRS (/fastcall-make -rtx-traverse-attrs))
(cons 'SYMBOL (/fastcall-make -rtx-traverse-symbol))
var-list)
)
+; Create an environment with the iteration local variable of `do-count'.
+
+(define (rtx-env-make-iteration-locals iter-var)
+ (rtx-env-make-locals (list (list 'INT iter-var)))
+)
+
; Push environment ENV onto the front of environment stack ENV-STACK,
; returning a new object. ENV-STACK is not modified.
#f
)
\f
-; Parallels and Sequences
+; parallel, sequence, do-count
; This has to be a syntax node as we don't want EXPRS to be pre-evaluated.
; All semantic ops must have a mode, though here it must be VOID.
SEQUENCE
#f
)
+
+; This has to be a syntax node to handle iter-var properly: it's not defined
+; yet and thus pre-evaluating the expressions doesn't work.
+
+(drsn (do-count &options &mode nr-times iter-var expr . exprs)
+ (OPTIONS VOIDMODE NUMBER ITERATION RTX . RTX) (NA NA NA NA VOID . VOID)
+ SEQUENCE
+ #f
+)
\f
; Internal rtx to create a closure.
; Internal, so it does not appear in rtl.texi.