From 079951a1573b33b652eaf55975df8dc73dea1ade Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 25 Jul 2008 17:21:54 -0400 Subject: [PATCH] We can now have up to 128 globals. The number is arbitrary, but could go up to 256, since we have a byte to encode them. For now, their number is statically determined, which can cause wasted space if not all are used. We'll change this to be dynamic, the number of globals will be encoded in the beginning of the bytecode, as is the case with constants and globals will simply occupy the beginning of ordinary ram. --- picobit-vm.c | 9 +++++---- picobit.scm | 66 ++++++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 51 insertions(+), 24 deletions(-) diff --git a/picobit-vm.c b/picobit-vm.c index 717add0..29eb328 100644 --- a/picobit-vm.c +++ b/picobit-vm.c @@ -78,7 +78,8 @@ static volatile near bit ACTIVITY_LED2 @ ((unsigned)&ACTIVITY_LED2_LAT*8)+ACTIVI #define CODE_START 0x5000 -#define GLOVARS 16 +#define GLOVARS 128 +// TODO was 16, and might change // TODO should this be read from the file like constants or statically allocated ? if read, it might cause problems because of dynamic allocation #ifdef DEBUG @@ -2209,7 +2210,7 @@ void interpreter (void) CASE(PUSH_STACK2); IF_TRACE(printf(" (push-stack %d)\n", bytecode_lo4+16)); - + // TODO does this ever happens ? bytecode_lo4 += 16; arg1 = env; @@ -2390,7 +2391,7 @@ void interpreter (void) case 5: // call-toplevel-short FETCH_NEXT_BYTECODE(); // TODO the sort version have a lot in common with the long ones, abstract ? - + // TODO short instructions don't work at the moment IF_TRACE(printf(" (call-toplevel-short 0x%04x)\n", pc + bytecode + CODE_START)); @@ -2480,7 +2481,7 @@ void interpreter (void) break; #endif case 14: // push_global [long] - FETCH_NEXT_BYTECODE(); + FETCH_NEXT_BYTECODE(); // TODO doesn't work yet IF_TRACE(printf(" (push-global [long] %d)\n", bytecode)); diff --git a/picobit.scm b/picobit.scm index 3261630..7bae796 100644 --- a/picobit.scm +++ b/picobit.scm @@ -2485,6 +2485,7 @@ (define max-ram-encoding 4095) (define min-vec-encoding 4096) (define max-vec-encoding 8191) +(define max-globals 128) ;; TODO might change (define code-start #x5000) @@ -2584,10 +2585,13 @@ (define (add-global var globals cont) (let ((x (assq var globals))) - (if x - (cont globals) + (if x + (begin + ;; increment reference counter + (vector-set! (cdr x) 1 (+ (vector-ref (cdr x) 1) 1)) + (cont globals)) (let ((new-globals - (cons (cons var (length globals)) + (cons (cons var (vector (length globals) 1)) ;; TODO added reference counter globals))) (cont new-globals))))) @@ -2600,7 +2604,9 @@ (let loop ((i min-rom-encoding) (lst csts)) (if (null? lst) - (if (> i min-ram-encoding) + ;; constants can use all the rom addresses up to 256 constants since + ;; their number is encoded in a byte at the beginning of the bytecode + (if (or (> i min-ram-encoding) (> (- i min-rom-encoding) 256)) (compiler-error "too many constants") csts) (begin @@ -2608,6 +2614,23 @@ (loop (+ i 1) (cdr lst))))))) +(define (sort-globals globals) ;; TODO a lot in common with sort-constants, ABSTRACT + (let ((glbs + (sort-list globals + (lambda (x y) + (> (vector-ref (cdr x) 1) + (vector-ref (cdr y) 1)))))) + (let loop ((i 0) + (lst glbs)) + (if (null? lst) + (if (> i max-globals) ;; TODO get rid of this check, and check for 256, since we want dynamically allocated globals, and the number will be encoded in a byte + (compiler-error "too many global variables") + glbs) + (begin + (vector-set! (cdr (car lst)) 0 i) + (loop (+ i 1) + (cdr lst))))))) + (define assemble (lambda (code hex-filename) (let loop1 ((lst code) @@ -2646,7 +2669,8 @@ globals labels)))) - (let ((constants (sort-constants constants))) + (let ((constants (sort-constants constants)) + (globals (sort-globals globals))) (define (label-instr label opcode) (define (short? self label) ;; TODO have this between -128 and 127 ? would be more flexible, I guess @@ -2663,7 +2687,7 @@ ;;; (lambda (self) ;;; (asm-8 (+ opcode 5)) ;;; (asm-8 (- (asm-label-pos label) self))) - ;; TODO don't work at the moment + ;; TODO doesn't work at the moment (lambda (self) 3) @@ -2685,19 +2709,17 @@ (compiler-error "stack is too deep") (asm-8 (+ #x20 n)))) - (define (push-global n) - (asm-8 (+ #x40 n)) ;; TODO maybe do the same as for csts, have a push-long-global to have more ? - ;; (if (> n 15) - ;; (compiler-error "too many global variables") - ;; (asm-8 (+ #x40 n))) - ) ;; TODO actually inline most, or put as csts + (define (push-global n) ;; TODO check if the numbers are good, we sorted them + (if (<= n 15) + (asm-8 (+ #x40 n)) + (begin (asm-8 #x8e) + (asm-8 n)))) (define (set-global n) - (asm-8 (+ #x50 n)) - ;; (if (> n 15) ;; ADDED prevented the stack from compiling - ;; (compiler-error "too many global variables") - ;; (asm-8 (+ #x50 n))) - ) + (if (<= n 15) + (asm-8 (+ #x50 n)) + (begin (asm-8 #x8f) + (asm-8 n)))) (define (call n) (if (> n 15) @@ -2785,7 +2807,7 @@ (asm-8 #xfb) (asm-8 #xd7) (asm-8 (length constants)) - (asm-8 0) + (asm-8 0) ;; TODO use for length globals ? (pp (list constants: constants globals: globals)) ;; TODO debug @@ -2861,10 +2883,14 @@ (push-stack (cadr instr))) ((eq? (car instr) 'push-global) - (push-global (cdr (assq (cadr instr) globals)))) + (push-global (vector-ref + (cdr (assq (cadr instr) globals)) + 0))) ((eq? (car instr) 'set-global) - (set-global (cdr (assq (cadr instr) globals)))) + (set-global (vector-ref + (cdr (assq (cadr instr) globals)) + 0))) ((eq? (car instr) 'call) (call (cadr instr))) -- 2.11.4.GIT