* bug in collector causing dirty bits for code objects with younger reloc
vectors to be unset incorrectly. The bug was in using || instead of | when computing the dirty pattern.
This commit is contained in:
parent
0bd88991cb
commit
819a3ca1c1
|
@ -493,4 +493,5 @@
|
|||
)
|
||||
)
|
||||
|
||||
;(assembler-output #t)
|
||||
;------------------------------------------------------------------------------
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,12 +7,13 @@ all: ikarus
|
|||
|
||||
ikarus: ikarus-collect.o ikarus-runtime.o ikarus-main.o ikarus-fasl.o \
|
||||
ikarus-exec.o ikarus-print.o ikarus-enter.o ikarus-symbol-table.o \
|
||||
ikarus-weak-pairs.o ikarus-numerics.o ikarus-flonums.o
|
||||
ikarus-weak-pairs.o ikarus-numerics.o ikarus-flonums.o \
|
||||
verify-integrity.o
|
||||
$(CC) $(LDFLAGS) -o ikarus \
|
||||
ikarus-main.o ikarus-runtime.o \
|
||||
ikarus-fasl.o ikarus-exec.o ikarus-print.o ikarus-enter.o \
|
||||
ikarus-symbol-table.o ikarus-collect.o ikarus-weak-pairs.o \
|
||||
ikarus-numerics.o ikarus-flonums.o
|
||||
ikarus-numerics.o ikarus-flonums.o verify-integrity.o
|
||||
|
||||
ikarus-main.o: ikarus-main.c ikarus.h
|
||||
$(CC) $(CFLAGS) -c ikarus-main.c
|
||||
|
@ -27,6 +28,9 @@ ikarus-runtime.o: ikarus-runtime.c ikarus.h
|
|||
ikarus-fasl.o: ikarus-fasl.c ikarus.h
|
||||
$(CC) $(CFLAGS) -c ikarus-fasl.c
|
||||
|
||||
verify-integrity.o: verify-integrity.c ikarus.h
|
||||
$(CC) $(CFLAGS) -c verify-integrity.c
|
||||
|
||||
ikarus-exec.o: ikarus-exec.c ikarus.h
|
||||
$(CC) $(CFLAGS) -c ikarus-exec.c
|
||||
|
||||
|
|
BIN
bin/ikarus
BIN
bin/ikarus
Binary file not shown.
|
@ -51,9 +51,9 @@ typedef struct{
|
|||
#define meta_count 5
|
||||
|
||||
static int extension_amount[meta_count] = {
|
||||
4 * pagesize,
|
||||
1 * pagesize,
|
||||
4 * pagesize,
|
||||
1 * pagesize,
|
||||
1 * pagesize,
|
||||
1 * pagesize,
|
||||
1 * pagesize
|
||||
};
|
||||
|
@ -187,6 +187,7 @@ gc_alloc_new_data(int size, int old_gen, gc_t* gc){
|
|||
|
||||
static inline ikp
|
||||
gc_alloc_new_code(int size, int old_gen, gc_t* gc){
|
||||
assert(size == align(size));
|
||||
if(size < pagesize){
|
||||
return meta_alloc(size, old_gen, gc, meta_code);
|
||||
} else {
|
||||
|
@ -196,6 +197,7 @@ gc_alloc_new_code(int size, int old_gen, gc_t* gc){
|
|||
qupages_t* p = ik_malloc(sizeof(qupages_t));
|
||||
p->p = mem;
|
||||
p->q = mem+size;
|
||||
bzero(mem+size, memreq-size);
|
||||
p->next = gc->queues[meta_code];
|
||||
gc->queues[meta_code] = p;
|
||||
return mem;
|
||||
|
@ -285,10 +287,13 @@ static void deallocate_unused_pages(gc_t*);
|
|||
|
||||
static void fix_new_pages(gc_t* gc);
|
||||
|
||||
extern void verify_integrity(ikpcb* pcb, char*);
|
||||
|
||||
ikpcb*
|
||||
ik_collect(int mem_req, ikpcb* pcb){
|
||||
|
||||
#ifndef NDEBUG
|
||||
verify_integrity(pcb, "entry");
|
||||
#endif
|
||||
{ /* ACCOUNTING */
|
||||
int bytes = ((int)pcb->allocation_pointer) -
|
||||
((int)pcb->heap_base);
|
||||
|
@ -440,6 +445,9 @@ ik_collect(int mem_req, ikpcb* pcb){
|
|||
ref(x, 0) = (ikp)(0x1234FFFF);
|
||||
x+=wordsize;
|
||||
}
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
verify_integrity(pcb, "exit");
|
||||
#endif
|
||||
return pcb;
|
||||
}
|
||||
|
@ -893,12 +901,7 @@ add_object_proc(gc_t* gc, ikp x)
|
|||
if(is_fixnum(x)){
|
||||
return x;
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
if(x == forward_ptr){
|
||||
fprintf(stderr, "GOTCHA\n");
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
assert(x != forward_ptr);
|
||||
int tag = tagof(x);
|
||||
if(tag == immediate_tag){
|
||||
return x;
|
||||
|
@ -908,6 +911,9 @@ add_object_proc(gc_t* gc, ikp x)
|
|||
/* already moved */
|
||||
return ref(x, wordsize-tag);
|
||||
}
|
||||
if(x == (ikp)0x07a3f035){
|
||||
fprintf(stderr, "FST=0x%08x\n", (int)fst);
|
||||
}
|
||||
unsigned int t = gc->segment_vector[page_index(x)];
|
||||
int gen = t & gen_mask;
|
||||
if(gen > gc->collect_gen){
|
||||
|
@ -954,6 +960,7 @@ add_object_proc(gc_t* gc, ikp x)
|
|||
else if(tag == vector_tag){
|
||||
if(is_fixnum(fst)){
|
||||
/* real vector */
|
||||
//fprintf(stderr, "X=0x%08x, FST=0x%08x\n", (int)x, (int)fst);
|
||||
int size = (int)fst;
|
||||
assert(size >= 0);
|
||||
int memreq = align(size + disp_vector_data);
|
||||
|
@ -1063,6 +1070,7 @@ add_object_proc(gc_t* gc, ikp x)
|
|||
}
|
||||
else {
|
||||
fprintf(stderr, "unhandled vector with fst=0x%08x\n", (int)fst);
|
||||
assert(0);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
@ -1095,7 +1103,7 @@ add_object_proc(gc_t* gc, ikp x)
|
|||
static void
|
||||
relocate_new_code(ikp x, gc_t* gc){
|
||||
ikp relocvector = ref(x, disp_code_reloc_vector);
|
||||
relocvector = add_object(gc, relocvector, "reloc");
|
||||
relocvector = add_object(gc, relocvector, "relocvec");
|
||||
ref(x, disp_code_reloc_vector) = relocvector;
|
||||
int relocsize = (int)ref(relocvector, off_vector_length);
|
||||
ikp p = relocvector + off_vector_data;
|
||||
|
@ -1107,8 +1115,12 @@ relocate_new_code(ikp x, gc_t* gc){
|
|||
int code_off = r >> 2;
|
||||
if(tag == 0){
|
||||
/* undisplaced pointer */
|
||||
#ifndef NDEBUG
|
||||
// fprintf(stderr, "r=0x%08x code_off=%d reloc_size=0x%08x\n",
|
||||
// r, code_off, relocsize);
|
||||
#endif
|
||||
ikp old_object = ref(p, wordsize);
|
||||
ikp new_object = add_object(gc, old_object, "reloc");
|
||||
ikp new_object = add_object(gc, old_object, "reloc1");
|
||||
ref(code, code_off) = new_object;
|
||||
p += (2*wordsize);
|
||||
}
|
||||
|
@ -1116,14 +1128,19 @@ relocate_new_code(ikp x, gc_t* gc){
|
|||
/* displaced pointer */
|
||||
int obj_off = unfix(ref(p, wordsize));
|
||||
ikp old_object = ref(p, 2*wordsize);
|
||||
ikp new_object = add_object(gc, old_object, "reloc");
|
||||
ikp new_object = add_object(gc, old_object, "reloc2");
|
||||
ref(code, code_off) = new_object + obj_off;
|
||||
p += (3 * wordsize);
|
||||
}
|
||||
else if(tag == 3){
|
||||
/* displaced relative pointer */
|
||||
int obj_off = unfix(ref(p, wordsize));
|
||||
ikp obj = add_object(gc, ref(p, 2*wordsize), "reloc");
|
||||
ikp obj = ref(p, 2*wordsize);
|
||||
#ifndef NDEBUG
|
||||
//fprintf(stderr, "obj=0x%08x, obj_off=0x%08x\n", (int)obj,
|
||||
// obj_off);
|
||||
#endif
|
||||
obj = add_object(gc, obj, "reloc3");
|
||||
ikp displaced_object = obj + obj_off;
|
||||
ikp next_word = code + code_off + wordsize;
|
||||
ikp relative_distance = displaced_object - (int)next_word;
|
||||
|
@ -1610,16 +1627,22 @@ fix_new_pages(gc_t* gc){
|
|||
if(is_fixnum(x) || (tagof(x) == immediate_tag)){
|
||||
/* do nothing */
|
||||
} else {
|
||||
code_d = code_d || segment_vec[page_index(x)];
|
||||
code_d = code_d | segment_vec[page_index(x)];
|
||||
}
|
||||
vp += wordsize;
|
||||
}
|
||||
code_d = (code_d & meta_dirty_mask) >> meta_dirty_shift;
|
||||
int j = ((int)p - (int)page_base)/cardsize;
|
||||
assert(j < cards_per_page);
|
||||
d = d | (code_d<<(j*meta_dirty_shift));
|
||||
p += align(disp_code_data + unfix(ref(p, disp_code_code_size)));
|
||||
}
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
fprintf(stderr, " %p = 0x%08x & 0x%08x = 0x%08x\n",
|
||||
page_base, d, cleanup_mask[page_gen], d &
|
||||
cleanup_mask[page_gen]);
|
||||
#endif
|
||||
dirty_vec[i] = d & cleanup_mask[page_gen];
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -725,9 +725,11 @@ ik_dump_dirty_vector(ikpcb* pcb){
|
|||
|
||||
ikp
|
||||
ikrt_make_code(ikp codesizeptr, ikp freevars, ikp rvec, ikpcb* pcb){
|
||||
assert((fx_mask & (int)codesizeptr) == 0);
|
||||
int code_size = unfix(codesizeptr);
|
||||
int memreq = align_to_next_page(code_size + disp_code_data);
|
||||
ikp mem = ik_mmap_code(memreq, 0, pcb);
|
||||
bzero(mem, memreq);
|
||||
ref(mem, 0) = code_tag;
|
||||
ref(mem, disp_code_code_size) = codesizeptr;
|
||||
ref(mem, disp_code_freevars) = freevars;
|
||||
|
@ -918,7 +920,7 @@ ikrt_fork(){
|
|||
ikp
|
||||
ikrt_waitpid(ikp pid){
|
||||
int status;
|
||||
pid_t t = waitpid(unfix(pid), &status, 0);
|
||||
/*pid_t t = */ waitpid(unfix(pid), &status, 0);
|
||||
return fix(status);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
|
||||
#include "ikarus.h"
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
static int
|
||||
page_idx(unsigned char* x){
|
||||
unsigned int xi = (unsigned int) x;
|
||||
return xi >> pageshift;
|
||||
}
|
||||
|
||||
#define fixnum_mask 3
|
||||
#define pmask 7
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
static int isa_fixnum(ikp x){
|
||||
return ((fixnum_mask & (int)x) == 0);
|
||||
}
|
||||
|
||||
static int isa_vector(ikp x){
|
||||
return ( (tagof(x) == vector_tag) &&
|
||||
isa_fixnum(ref(x, -vector_tag)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
verify_code(unsigned char* x, unsigned char* base, unsigned int* svec, unsigned int* dvec){
|
||||
assert(ref(x, 0) == code_tag);
|
||||
ikp rvec = ref(x, disp_code_reloc_vector);
|
||||
assert(isa_vector(rvec));
|
||||
ikp codesize = ref(x, disp_code_code_size);
|
||||
codesize += 0;
|
||||
assert(unfix(codesize) >= 0);
|
||||
assert(isa_fixnum(codesize));
|
||||
ikp freevars = ref(x, disp_code_freevars);
|
||||
freevars += 0;
|
||||
assert(isa_fixnum(freevars));
|
||||
assert(unfix(freevars) >= 0);
|
||||
|
||||
unsigned int rs = svec[page_idx(rvec) - page_idx(base)];
|
||||
unsigned int cs = svec[page_idx(x) - page_idx(base)];
|
||||
int cgen = cs&gen_mask;
|
||||
int rgen = rs&gen_mask;
|
||||
if(rgen < cgen){
|
||||
unsigned int d = dvec[page_idx(x) - page_idx(base)];
|
||||
d = d & d;
|
||||
//int off = (((int)x) - align_to_prev_page(x)) / card_size;
|
||||
//int card_mark = (d >> off) & 0xF;
|
||||
assert(d != 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
verify_object(ikp x, unsigned char* base, unsigned int* svec, unsigned int* dvec){
|
||||
|
||||
}
|
||||
|
||||
|
||||
static unsigned char*
|
||||
verify_code_small(unsigned char* p, unsigned int s, unsigned int d,
|
||||
unsigned char* base, unsigned int* svec, unsigned int* dvec){
|
||||
ikp q = p + pagesize;
|
||||
while(p < q){
|
||||
ikp fst = ref(p, 0);
|
||||
if(fst == code_tag){
|
||||
assert(is_fixnum(ref(p, disp_code_code_size)));
|
||||
int code_size = unfix(ref(p, disp_code_code_size));
|
||||
assert(code_size >= 0);
|
||||
verify_code(p, base, svec, dvec);
|
||||
p+=align(code_size + disp_code_data);
|
||||
} else {
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
if(p != q){
|
||||
fprintf(stderr, "code extended beyond a page in %p, %p\n", p, q);
|
||||
assert(0);
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
static unsigned char*
|
||||
verify_code_large(unsigned char* p, unsigned int s, unsigned int d,
|
||||
unsigned char* base, unsigned int* svec, unsigned int* dvec){
|
||||
ikp fst = ref(p, 0);
|
||||
fst += 0;
|
||||
assert(fst == code_tag);
|
||||
int code_size = unfix(ref(p, disp_code_code_size));
|
||||
assert(code_size >= 0);
|
||||
verify_code(p, base, svec, dvec);
|
||||
assert(align(code_size+disp_code_data) >= pagesize);
|
||||
ikp end = p + code_size + disp_code_data;
|
||||
return((unsigned char*)align_to_next_page(end));
|
||||
}
|
||||
|
||||
static unsigned char*
|
||||
verify_code_page(unsigned char* p, unsigned int s, unsigned int d,
|
||||
unsigned char* base, unsigned int* svec, unsigned int* dvec){
|
||||
ikp fst = ref(p, 0);
|
||||
fst += 0;
|
||||
assert (fst == code_tag);
|
||||
int code_size = unfix(ref(p, disp_code_code_size));
|
||||
assert(code_size >= 0);
|
||||
int obj_size = align(code_size + disp_code_data);
|
||||
unsigned char* result;
|
||||
if(obj_size <= pagesize){
|
||||
result = verify_code_small(p,s,d,base,svec,dvec);
|
||||
} else {
|
||||
result = verify_code_large(p,s,d,base,svec,dvec);
|
||||
}
|
||||
// fprintf(stderr, "code verify incomplete\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static unsigned char*
|
||||
verify_pointers_page(unsigned char* p, unsigned int s, unsigned int d,
|
||||
unsigned char* base, unsigned int* svec, unsigned int* dvec){
|
||||
{
|
||||
int i = 0;
|
||||
while(i < pagesize){
|
||||
verify_object(ref(p, i), base, svec, dvec);
|
||||
i += wordsize;
|
||||
}
|
||||
}
|
||||
//fprintf(stderr, "pointers verif incomplete\n");
|
||||
return p+pagesize;
|
||||
}
|
||||
|
||||
static unsigned char*
|
||||
verify_page(unsigned char* p, unsigned char* base, unsigned int* svec, unsigned int* dvec){
|
||||
int idx = page_idx(p) - page_idx(base);
|
||||
unsigned int s = svec[idx];
|
||||
unsigned int d = dvec[idx];
|
||||
// if(s & dealloc_mask){
|
||||
// return p+pagesize;
|
||||
// }
|
||||
int type = s & type_mask;
|
||||
if(type == hole_type){
|
||||
return p+pagesize;
|
||||
}
|
||||
assert((s & new_gen_mask) == 0);
|
||||
if(type == code_type){
|
||||
return verify_code_page(p,s,d,base,svec,dvec);
|
||||
}
|
||||
else if(type == pointers_type){
|
||||
return verify_pointers_page(p,s,d,base,svec,dvec);
|
||||
}
|
||||
else if(type == data_type){
|
||||
/* nothing to do for data */
|
||||
return p+pagesize;
|
||||
}
|
||||
else if(type == mainheap_type){
|
||||
/* nothing to do for main heap */
|
||||
return p+pagesize;
|
||||
}
|
||||
else if(type == mainstack_type){
|
||||
/* nothing to do for main stack */
|
||||
return p+pagesize;
|
||||
}
|
||||
fprintf(stderr, "type=0x%08x\n", type);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
void
|
||||
verify_integrity(ikpcb* pcb, char* where){
|
||||
fprintf(stderr, "verifying in %s...\n", where);
|
||||
unsigned char* mem_base = pcb->memory_base;
|
||||
unsigned char* mem_end = pcb->memory_end;
|
||||
unsigned int* seg_vec = pcb->segment_vector_base;
|
||||
unsigned int* dir_vec = pcb->dirty_vector_base;
|
||||
unsigned char* mem = mem_base;
|
||||
while(mem < mem_end){
|
||||
mem = verify_page(mem, mem_base, seg_vec, dir_vec);
|
||||
}
|
||||
fprintf(stderr, "verify_ok in %s\n", where);
|
||||
}
|
BIN
src/ikarus.boot
BIN
src/ikarus.boot
Binary file not shown.
|
@ -154,6 +154,14 @@
|
|||
[$fx< p]
|
||||
[$fx<= p]
|
||||
[$fx= p]
|
||||
[- v]
|
||||
[+ v]
|
||||
[= p]
|
||||
[< p]
|
||||
[<= p]
|
||||
[> p]
|
||||
[>= p]
|
||||
[zero? p]
|
||||
|
||||
|
||||
[$char= p]
|
||||
|
@ -171,6 +179,8 @@
|
|||
[cdr v]
|
||||
[$car v]
|
||||
[$cdr v]
|
||||
[set-car! e]
|
||||
[set-cdr! e]
|
||||
[$set-car! e]
|
||||
[$set-cdr! e]
|
||||
|
||||
|
@ -831,6 +841,24 @@
|
|||
;;; case with vectors and records.
|
||||
(prm 'mset x (K off) v)
|
||||
(dirty-vector-set x))))]
|
||||
[(set-car! set-cdr!)
|
||||
(let ([off (if (eq? op 'set-car!)
|
||||
(- disp-car pair-tag)
|
||||
(- disp-cdr pair-tag))])
|
||||
(tbind ([x (Value (car arg*))]
|
||||
[v (Value (cadr arg*))])
|
||||
(seq* ;;; car/cdr addresses are in the same
|
||||
;;; card as the pair address, so no
|
||||
;;; adjustment is necessary as was the
|
||||
;;; case with vectors and records.
|
||||
(make-conditional
|
||||
(tag-test x pair-mask pair-tag)
|
||||
(make-seq
|
||||
(prm 'mset x (K off) v)
|
||||
(dirty-vector-set x))
|
||||
(Effect
|
||||
(make-funcall (make-primref 'error)
|
||||
(list (K op) (K "~s is not a pair") x)))))))]
|
||||
[($string-set!)
|
||||
(tbind ([x (Value (car arg*))])
|
||||
(let ([i (cadr arg*)]
|
||||
|
@ -957,6 +985,14 @@
|
|||
[(bwp-object?) (prm '= (Value (car arg*)) (K bwp-object))]
|
||||
[(neq?) (make-primcall '!= (map Value arg*))]
|
||||
[($fxzero?) (prm '= (Value (car arg*)) (K 0))]
|
||||
[(zero?)
|
||||
(tbind ([x (Value (car arg*))])
|
||||
(make-conditional
|
||||
(tag-test x fixnum-mask fixnum-tag)
|
||||
(prm '= x (K 0))
|
||||
(prm '!=
|
||||
(make-funcall (Value (make-primref 'zero?)) (list x))
|
||||
(Value (K #f)))))]
|
||||
[($unbound-object?) (prm '= (Value (car arg*)) (K unbound))]
|
||||
[(pair?)
|
||||
(tag-test (Value (car arg*)) pair-mask pair-tag)]
|
||||
|
@ -1023,6 +1059,56 @@
|
|||
(prm '<= (Value (car arg*)) (Value (cadr arg*)))]
|
||||
[($fx>= $char>=)
|
||||
(prm '>= (Value (car arg*)) (Value (cadr arg*)))]
|
||||
[(= < <= > >=)
|
||||
(unless (= (length arg*) 2)
|
||||
(error who "only binary ~s for now" op))
|
||||
(let ([cmp?
|
||||
(case op
|
||||
[(=) =]
|
||||
[(<) <]
|
||||
[(<=) <=]
|
||||
[(>) >]
|
||||
[(>=) >=]
|
||||
[else (error who "unhandled op ~s" op)])])
|
||||
(let ([a (car arg*)] [b (cadr arg*)])
|
||||
(define (call a b)
|
||||
(prm '!= (Value (K #f))
|
||||
(make-funcall
|
||||
(Value (make-primref op))
|
||||
(list a b))))
|
||||
(record-case a
|
||||
[(constant i)
|
||||
(cond
|
||||
[(fixnum? i)
|
||||
(record-case b
|
||||
[(constant j)
|
||||
(if (fixnum? j)
|
||||
(make-constant (cmp? i j))
|
||||
(call (Value a) (Value b)))]
|
||||
[else
|
||||
(tbind ([b (Value b)])
|
||||
(make-conditional
|
||||
(tag-test b fixnum-mask fixnum-tag)
|
||||
(prm op (Value a) b)
|
||||
(call (Value a) b)))])]
|
||||
[else
|
||||
(call (Value a) (Value b))])]
|
||||
[else
|
||||
(record-case b
|
||||
[(constant j)
|
||||
(if (fixnum? j)
|
||||
(tbind ([a (Value a)])
|
||||
(make-conditional
|
||||
(tag-test a fixnum-mask fixnum-tag)
|
||||
(prm op a (Value b))
|
||||
(call a (Value b))))
|
||||
(call (Value a) (Value b)))]
|
||||
[else
|
||||
(tbind ([a (Value a)] [b (Value b)])
|
||||
(make-conditional
|
||||
(tag-test (prm 'logor a b) fixnum-mask fixnum-tag)
|
||||
(prm op a b)
|
||||
(call a b)))])])))]
|
||||
[else (error who "pred prim ~a not supported" op)])]
|
||||
[(mvcall rator x)
|
||||
(make-mvcall (Value rator) (Clambda x Pred))]
|
||||
|
@ -1038,6 +1124,30 @@
|
|||
(K (+ known-amt (sub1 object-alignment))))
|
||||
(K align-shift))
|
||||
(K align-shift)))
|
||||
(define (remove-complex* ls k)
|
||||
(let-values ([(lhs* rhs* arg*)
|
||||
(let f ([ls ls])
|
||||
(cond
|
||||
[(null? ls) (values '() '() '())]
|
||||
[else
|
||||
(let-values ([(lhs* rhs* arg*)
|
||||
(f (cdr ls))])
|
||||
(let ([a (car ls)])
|
||||
(cond
|
||||
[(or (var? a) (complex? a))
|
||||
(values lhs* rhs* (cons a arg*))]
|
||||
[else
|
||||
(let ([t (unique-var 'tmp)])
|
||||
(values
|
||||
(cons t lhs*)
|
||||
(cons (Value a) rhs*)
|
||||
(cons t arg*)))])))]))])
|
||||
(cond
|
||||
[(null? lhs*)
|
||||
(k arg*)]
|
||||
[else
|
||||
(make-bind lhs* rhs*
|
||||
(k arg*))])))
|
||||
;;; value
|
||||
(define (Value x)
|
||||
(record-case x
|
||||
|
@ -1269,12 +1379,15 @@
|
|||
(tbind ([i (Value i)])
|
||||
(prm 'logor
|
||||
(prm 'sll
|
||||
(prm 'logand ;;; FIXME: bref
|
||||
(prm 'srl ;;; FIXME: bref
|
||||
(prm 'mref s
|
||||
(prm 'int+
|
||||
(prm 'sra i (K fixnum-shift))
|
||||
(K (- disp-string-data string-tag))))
|
||||
(K 255))
|
||||
(prm 'sra i (K fixnum-shift));
|
||||
;;; ENDIANNESS DEPENDENCY
|
||||
(K (- disp-string-data
|
||||
(- wordsize 1)
|
||||
string-tag))))
|
||||
(K (* (- wordsize 1) 8)))
|
||||
(K char-shift))
|
||||
(K char-tag)))])))]
|
||||
[($make-string)
|
||||
|
@ -1418,6 +1531,113 @@
|
|||
(prm 'logor (Value (car arg*)) (Value (cadr arg*)))]
|
||||
[($fxlognot)
|
||||
(Value (prm '$fxlogxor (car arg*) (K -1)))]
|
||||
[(+)
|
||||
(let ()
|
||||
(define (handle-binary a b)
|
||||
(record-case a
|
||||
[(constant i)
|
||||
(if (fixnum? i)
|
||||
(tbind ([b (Value b)])
|
||||
(make-shortcut^
|
||||
(tag-test b fixnum-mask fixnum-tag)
|
||||
(prm 'int+/overflow (Value a) b)
|
||||
(make-funcall (Value (make-primref '+))
|
||||
(list (Value a) b))))
|
||||
(make-funcall (Value (make-primref '+))
|
||||
(list (Value a) b)))]
|
||||
[else
|
||||
(record-case b
|
||||
[(constant i)
|
||||
(if (fixnum? i)
|
||||
(tbind ([a (Value a)])
|
||||
(make-shortcut^
|
||||
(tag-test a fixnum-mask fixnum-tag)
|
||||
(prm 'int+/overflow a (Value b))
|
||||
(make-funcall (Value (make-primref '+))
|
||||
(list a (Value b)))))
|
||||
(make-funcall (Value (make-primref '+))
|
||||
(list a (Value b))))]
|
||||
[else
|
||||
(tbind ([a (Value a)]
|
||||
[b (Value b)])
|
||||
(make-shortcut^
|
||||
(tag-test (prm 'logor a b) fixnum-mask fixnum-tag)
|
||||
(prm 'int+/overflow a b)
|
||||
(make-funcall (Value (make-primref '+))
|
||||
(list a b))))])]))
|
||||
(cond
|
||||
[(null? arg*) (K 0)]
|
||||
[(ormap (lambda (x)
|
||||
(record-case x
|
||||
[(constant i) (not (number? i))]
|
||||
[else #f])) arg*)
|
||||
(make-funcall (Value (make-primref '+)) (map Value arg*))]
|
||||
[(= (length arg*) 1) ;;; FIXME: do something better
|
||||
(handle-binary (K 0) (car arg*))]
|
||||
[(= (length arg*) 2)
|
||||
(handle-binary (car arg*) (cadr arg*))]
|
||||
[else
|
||||
(remove-complex* arg*
|
||||
(lambda (arg*)
|
||||
(Value
|
||||
(let f ([a (car arg*)] [d (cdr arg*)])
|
||||
(cond
|
||||
[(null? d) a]
|
||||
[else (f (prm '+ a (car d)) (cdr d))])))))]))]
|
||||
[(-)
|
||||
(let ()
|
||||
(define (handle-binary a b)
|
||||
(record-case a
|
||||
[(constant i)
|
||||
(if (fixnum? i)
|
||||
(tbind ([b (Value b)])
|
||||
(make-shortcut^
|
||||
(tag-test b fixnum-mask fixnum-tag)
|
||||
(prm 'int-/overflow (Value a) b)
|
||||
(make-funcall (Value (make-primref '-))
|
||||
(list (Value a) b))))
|
||||
(make-funcall (Value (make-primref '-))
|
||||
(list (Value a) b)))]
|
||||
[else
|
||||
(record-case b
|
||||
[(constant i)
|
||||
(if (fixnum? i)
|
||||
(tbind ([a (Value a)])
|
||||
(make-shortcut^
|
||||
(tag-test a fixnum-mask fixnum-tag)
|
||||
(prm 'int-/overflow a (Value b))
|
||||
(make-funcall (Value (make-primref '-))
|
||||
(list a (Value b)))))
|
||||
(make-funcall (Value (make-primref '-))
|
||||
(list a (Value b))))]
|
||||
[else
|
||||
(tbind ([a (Value a)]
|
||||
[b (Value b)])
|
||||
(make-shortcut^
|
||||
(tag-test (prm 'logor a b) fixnum-mask fixnum-tag)
|
||||
(prm 'int-/overflow a b)
|
||||
(make-funcall (Value (make-primref '-))
|
||||
(list a b))))])]))
|
||||
(cond
|
||||
[(or (null? arg*)
|
||||
(ormap
|
||||
(lambda (x)
|
||||
(record-case x
|
||||
[(constant i) (not (number? i))]
|
||||
[else #f])) arg*))
|
||||
(make-funcall (Value (make-primref '-)) (map Value arg*))]
|
||||
[(= (length arg*) 1)
|
||||
(handle-binary (K 0) (car arg*))]
|
||||
[(= (length arg*) 2)
|
||||
(handle-binary (car arg*) (cadr arg*))]
|
||||
[else
|
||||
(remove-complex* arg*
|
||||
(lambda (arg*)
|
||||
(Value
|
||||
(let f ([a (car arg*)] [d (cdr arg*)])
|
||||
(cond
|
||||
[(null? d) a]
|
||||
[else (f (prm '- a (car d)) (cdr d))])))))]))]
|
||||
[($char->fixnum)
|
||||
(tbind ([x (Value (car arg*))])
|
||||
(prm 'sra x
|
||||
|
@ -1878,7 +2098,8 @@
|
|||
(S* rands
|
||||
(lambda (rands)
|
||||
(make-set d (make-disp (car rands) (cadr rands)))))]
|
||||
[(logand logxor logor int+ int- int*)
|
||||
[(logand logxor logor int+ int- int*
|
||||
int-/overflow int+/overflow)
|
||||
(make-seq
|
||||
(V d (car rands))
|
||||
(S (cadr rands)
|
||||
|
@ -1900,7 +2121,7 @@
|
|||
(make-asm-instr 'cltd edx eax)
|
||||
(make-asm-instr 'idiv edx (cadr rands))
|
||||
(make-set d edx))))]
|
||||
[(sll sra)
|
||||
[(sll sra srl)
|
||||
(let ([a (car rands)] [b (cadr rands)])
|
||||
(cond
|
||||
[(constant? b)
|
||||
|
@ -1923,10 +2144,14 @@
|
|||
(handle-nontail-call
|
||||
(make-constant (make-foreign-label op))
|
||||
rands d op)]
|
||||
[(shortcut^ test body handler)
|
||||
(make-shortcut^ (P test)
|
||||
(V d body)
|
||||
(V d handler))]
|
||||
[else
|
||||
(if (symbol? x)
|
||||
(make-set d x)
|
||||
(error who "invalid value ~s" x))]))
|
||||
(error who "invalid value ~s" (unparse x)))]))
|
||||
;;;
|
||||
(define (assign* lhs* rhs* ac)
|
||||
(cond
|
||||
|
@ -1991,31 +2216,6 @@
|
|||
[else (error who "invalid pred ~s" x)]))
|
||||
;;;
|
||||
(define (Tail env)
|
||||
#;(define (handle-tail-call target rator rands)
|
||||
(let ([cpt (unique-var 'rator)]
|
||||
[rt* (map (lambda (x) (unique-var 't)) rands)])
|
||||
(do-bind rt* rands
|
||||
(do-bind (list cpt) (list rator)
|
||||
(let ([args (cons cpt rt*)]
|
||||
[locs (formals-locations (cons cpt rt*))])
|
||||
(assign* (reverse locs)
|
||||
(reverse args)
|
||||
(make-seq
|
||||
(make-set argc-register
|
||||
(make-constant
|
||||
(argc-convention (length rands))))
|
||||
(cond
|
||||
[target
|
||||
(make-primcall 'direct-jump
|
||||
(cons target
|
||||
(list* argc-register
|
||||
pcr esp apr
|
||||
locs)))]
|
||||
[else
|
||||
(make-primcall 'indirect-jump
|
||||
(list* argc-register
|
||||
pcr esp apr
|
||||
locs))]))))))))
|
||||
(define (handle-tail-call target rator rands)
|
||||
(let* ([args (cons rator rands)]
|
||||
[locs (formals-locations args)]
|
||||
|
@ -2036,7 +2236,10 @@
|
|||
(list* argc-register
|
||||
pcr esp apr
|
||||
locs))]))])
|
||||
(let f ([args args] [locs locs] [targs '()] [tlocs '()])
|
||||
(let f ([args (reverse args)]
|
||||
[locs (reverse locs)]
|
||||
[targs '()]
|
||||
[tlocs '()])
|
||||
(cond
|
||||
[(null? args) (assign* tlocs targs rest)]
|
||||
[(constant? (car args))
|
||||
|
@ -2087,6 +2290,8 @@
|
|||
[(jmpcall label rator rands)
|
||||
(handle-tail-call (make-code-loc label) rator rands)]
|
||||
[(forcall) (VT x)]
|
||||
[(shortcut^ test body handler)
|
||||
(make-shortcut^ (P test) (Tail body) (Tail handler))]
|
||||
[else (error who "invalid tail ~s" x)]))
|
||||
Tail)
|
||||
;;;
|
||||
|
@ -2255,6 +2460,8 @@
|
|||
(case op
|
||||
[(nop) #f]
|
||||
[else (error who "invalid effect ~s" (unparse x))])]
|
||||
[(shortcut^ test body handler)
|
||||
(or (P test) (E body) (E handler))]
|
||||
[else (error who "invalid effect ~s" x)]))
|
||||
(define (P x)
|
||||
(record-case x
|
||||
|
@ -2271,6 +2478,8 @@
|
|||
[(conditional e0 e1 e2)
|
||||
(or (P e0) (T e1) (T e2))]
|
||||
[(primcall) #f]
|
||||
[(shortcut^ test body handler)
|
||||
(or (P test) (T body) (T handler))]
|
||||
[else (error who "invalid tail ~s" x)]))
|
||||
(T x))
|
||||
;;;
|
||||
|
@ -2518,7 +2727,45 @@
|
|||
(values (add-var s vs) rs fs ns))]
|
||||
[else (error who "invalid ns ~s" s)])]
|
||||
[else (error who "invalid d ~s" d)])]
|
||||
[(logand logor logxor sll sra int+ int- int*)
|
||||
[(int-/overflow int+/overflow)
|
||||
(let ([v (exception-live-set)])
|
||||
(unless (vector? v)
|
||||
(error who "unbound exception"))
|
||||
(let ([vs (union-vars vs (vector-ref v 0))]
|
||||
[rs (union-regs rs (vector-ref v 1))]
|
||||
[fs (union-frms fs (vector-ref v 2))]
|
||||
[ns (union-nfvs ns (vector-ref v 3))])
|
||||
(cond
|
||||
[(var? d)
|
||||
(cond
|
||||
[(not (mem-var? d vs))
|
||||
(set-asm-instr-op! x 'nop)
|
||||
(values vs rs fs ns)]
|
||||
[else
|
||||
(let ([vs (rem-var d vs)])
|
||||
(mark-var/vars-conf! d vs)
|
||||
(mark-var/frms-conf! d fs)
|
||||
(mark-var/nfvs-conf! d ns)
|
||||
(mark-var/regs-conf! d rs)
|
||||
(R s (set-add d vs) rs fs ns))])]
|
||||
[(reg? d)
|
||||
(cond
|
||||
[(not (mem-reg? d rs))
|
||||
(values vs rs fs ns)]
|
||||
[else
|
||||
(let ([rs (rem-reg d rs)])
|
||||
(mark-reg/vars-conf! d vs)
|
||||
(R s vs (set-add d rs) fs ns))])]
|
||||
[(nfv? d)
|
||||
(cond
|
||||
[(not (mem-nfv? d ns)) (error who "dead nfv")]
|
||||
[else
|
||||
(let ([ns (rem-nfv d ns)])
|
||||
(mark-nfv/vars-conf! d vs)
|
||||
(mark-nfv/frms-conf! d fs)
|
||||
(R s vs rs fs (add-nfv d ns)))])]
|
||||
[else (error who "invalid op d ~s" (unparse x))])))]
|
||||
[(logand logor logxor sll sra srl int+ int- int*)
|
||||
(cond
|
||||
[(var? d)
|
||||
(cond
|
||||
|
@ -2570,6 +2817,19 @@
|
|||
(case op
|
||||
[(nop) (values vs rs fs ns)]
|
||||
[else (error who "invalid effect op ~s" op)])]
|
||||
[(shortcut^ pred body handler)
|
||||
(let-values ([(vsh rsh fsh nsh) (E handler vs rs fs ns)])
|
||||
(let-values ([(vsb rsb fsb nsb)
|
||||
(parameterize ([exception-live-set
|
||||
(vector vsh rsh fsh nsh)])
|
||||
(E body vs rs fs ns))])
|
||||
(P pred
|
||||
vsb rsb fsb nsb
|
||||
vsh rsh fsh nsh
|
||||
(union-vars vsb vsh)
|
||||
(union-regs rsb rsh)
|
||||
(union-frms fsb fsh)
|
||||
(union-nfvs nsb nsh))))]
|
||||
[else (error who "invalid effect ~s" (unparse x))]))
|
||||
(define (P x vst rst fst nst
|
||||
vsf rsf fsf nsf
|
||||
|
@ -2627,7 +2887,22 @@
|
|||
(empty-frm-set)
|
||||
(empty-nfv-set))]
|
||||
[else (error who "invalid tail op ~s" x)])]
|
||||
[(shortcut^ pred body handler)
|
||||
(let-values ([(vsh rsh fsh nsh) (T handler)])
|
||||
(let-values ([(vsb rsb fsb nsb)
|
||||
(parameterize ([exception-live-set
|
||||
(vector vsh rsh fsh nsh)])
|
||||
(T body))])
|
||||
(P pred
|
||||
vsb rsb fsb nsb
|
||||
vsh rsh fsh nsh
|
||||
(union-vars vsb vsh)
|
||||
(union-regs rsb rsh)
|
||||
(union-frms fsb fsh)
|
||||
(union-nfvs nsb nsh))))]
|
||||
[else (error who "invalid tail ~s" x)]))
|
||||
(define exception-live-set
|
||||
(make-parameter #f))
|
||||
(T x)
|
||||
spill-set)
|
||||
(define-syntax frm-loc
|
||||
|
@ -2651,26 +2926,6 @@
|
|||
;;;
|
||||
(define (assign-locations! ls)
|
||||
(for-each (lambda (x) (set-var-loc! x #t)) ls))
|
||||
;(define (assign-locations! ls)
|
||||
; (define (assign x)
|
||||
; (unless (var? x) (error 'assign "not a var"))
|
||||
; (when (var-loc x) (error 'assign "already assigned"))
|
||||
; (let ([frms (var-frm-conf x)]
|
||||
; [vars (var-var-conf x)])
|
||||
; (let f ([i 1])
|
||||
; (cond
|
||||
; [(frame-conflict? i vars frms) (f (fxadd1 i))]
|
||||
; [else
|
||||
; (let ([fv (mkfvar i)])
|
||||
; (set-var-loc! x fv)
|
||||
; (for-each
|
||||
; (lambda (var)
|
||||
; (set-var-var-conf! var
|
||||
; (rem-var x (var-var-conf var)))
|
||||
; (set-var-frm-conf! var
|
||||
; (add-frm fv (var-frm-conf var))))
|
||||
; vars))]))))
|
||||
; (for-each assign ls))
|
||||
(define (rewrite x)
|
||||
(define who 'rewrite)
|
||||
(define (assign x)
|
||||
|
@ -2720,7 +2975,6 @@
|
|||
fv)])))
|
||||
(or (assign-move x)
|
||||
(assign-any)))
|
||||
|
||||
(define (NFE idx mask x)
|
||||
(record-case x
|
||||
[(seq e0 e1)
|
||||
|
@ -2767,14 +3021,12 @@
|
|||
(let ([d (R d)] [s (R s)])
|
||||
(cond
|
||||
[(eq? d s)
|
||||
(printf "N")
|
||||
(make-primcall 'nop '())]
|
||||
[else
|
||||
(when (and (fvar? d) (fvar? s))
|
||||
(printf "Y"))
|
||||
(make-asm-instr 'move d s)]))]
|
||||
[(logand logor logxor int+ int- int* mset bset/c bset/h sll sra
|
||||
cltd idiv)
|
||||
[(logand logor logxor int+ int- int* mset bset/c bset/h
|
||||
sll sra srl
|
||||
cltd idiv int-/overflow int+/overflow)
|
||||
(make-asm-instr op (R d) (R s))]
|
||||
[(nop) (make-primcall 'nop '())]
|
||||
[else (error who "invalid op ~s" op)])]
|
||||
|
@ -2865,6 +3117,8 @@
|
|||
(case op
|
||||
[(nop) x]
|
||||
[else (error who "invalid effect prim ~s" op)])]
|
||||
[(shortcut^ test body handler)
|
||||
(make-shortcut^ (P test) (E body) (E handler))]
|
||||
[else (error who "invalid effect ~s" (unparse x))]))
|
||||
(define (P x)
|
||||
(record-case x
|
||||
|
@ -2884,6 +3138,8 @@
|
|||
[(conditional e0 e1 e2)
|
||||
(make-conditional (P e0) (T e1) (T e2))]
|
||||
[(primcall op args) x]
|
||||
[(shortcut^ test body handler)
|
||||
(make-shortcut^ (P test) (T body) (T handler))]
|
||||
[else (error who "invalid tail ~s" (unparse x))]))
|
||||
(T x))
|
||||
;;;
|
||||
|
@ -2960,7 +3216,20 @@
|
|||
[else
|
||||
(for-each (lambda (y) (add-edge! g d y)) s)
|
||||
(union (R v) s)]))]
|
||||
[(logand logxor int+ int- int* logor sll sra)
|
||||
[(int-/overflow int+/overflow)
|
||||
(unless (exception-live-set)
|
||||
(error who "uninitialized live set"))
|
||||
(let ([s (set-rem d (set-union s (exception-live-set)))])
|
||||
(record-case d
|
||||
[(nfv c i)
|
||||
(if (list? c)
|
||||
(set-nfv-conf! d (set-union c s))
|
||||
(set-nfv-conf! d s))
|
||||
(union (union (R v) (R d)) s)]
|
||||
[else
|
||||
(for-each (lambda (y) (add-edge! g d y)) s)
|
||||
(union (union (R v) (R d)) s)]))]
|
||||
[(logand logxor int+ int- int* logor sll sra srl)
|
||||
(let ([s (set-rem d s)])
|
||||
(record-case d
|
||||
[(nfv c i)
|
||||
|
@ -3008,7 +3277,12 @@
|
|||
(case op
|
||||
[(nop) s]
|
||||
[else (error who "invalid effect primcall ~s" op)])]
|
||||
[else (error who "invalid effect ~s" x)]))
|
||||
[(shortcut^ test body handler)
|
||||
(let ([s2 (E handler s)])
|
||||
(let ([s1 (parameterize ([exception-live-set s2])
|
||||
(E body s))])
|
||||
(P test s1 s2 (set-union s1 s2))))]
|
||||
[else (error who "invalid effect ~s" (unparse x))]))
|
||||
(define (P x st sf su)
|
||||
(record-case x
|
||||
[(constant c) (if c st sf)]
|
||||
|
@ -3019,7 +3293,7 @@
|
|||
(P e0 s1 s2 (set-union s1 s2)))]
|
||||
[(asm-instr op s0 s1)
|
||||
(union (union (R s0) (R s1)) su)]
|
||||
[else (error who "invalid pred ~s" x)]))
|
||||
[else (error who "invalid pred ~s" (unparse x))]))
|
||||
(define (T x)
|
||||
(record-case x
|
||||
[(conditional e0 e1 e2)
|
||||
|
@ -3028,7 +3302,13 @@
|
|||
[(primcall op rands)
|
||||
(R* rands)]
|
||||
[(seq e0 e1) (E e0 (T e1))]
|
||||
[else (error who "invalid tail ~s" x)]))
|
||||
[(shortcut^ test body handler)
|
||||
(let ([s2 (T handler)])
|
||||
(let ([s1 (parameterize ([exception-live-set s2])
|
||||
(T body))])
|
||||
(P test s1 s2 (set-union s1 s2))))]
|
||||
[else (error who "invalid tail ~s" (unparse x))]))
|
||||
(define exception-live-set (make-parameter #f))
|
||||
(let ([s (T x)])
|
||||
;(print-graph g)
|
||||
g))
|
||||
|
@ -3138,7 +3418,9 @@
|
|||
[(primcall op rands)
|
||||
(make-primcall op (map R rands))]
|
||||
[(ntcall) x]
|
||||
[else (error who "invalid effect ~s" x)]))
|
||||
[(shortcut^ test body handler)
|
||||
(make-shortcut^ (P test) (E body) (E handler))]
|
||||
[else (error who "invalid effect ~s" (unparse x))]))
|
||||
(define (P x)
|
||||
(record-case x
|
||||
[(constant) x]
|
||||
|
@ -3147,14 +3429,16 @@
|
|||
[(conditional e0 e1 e2)
|
||||
(make-conditional (P e0) (P e1) (P e2))]
|
||||
[(seq e0 e1) (make-seq (E e0) (P e1))]
|
||||
[else (error who "invalid pred ~s" x)]))
|
||||
[else (error who "invalid pred ~s" (unparse x))]))
|
||||
(define (T x)
|
||||
(record-case x
|
||||
[(primcall op rands) x]
|
||||
[(conditional e0 e1 e2)
|
||||
(make-conditional (P e0) (T e1) (T e2))]
|
||||
[(seq e0 e1) (make-seq (E e0) (T e1))]
|
||||
[else (error who "invalid tail ~s" x)]))
|
||||
[(shortcut^ test body handler)
|
||||
(make-shortcut^ (P test) (T body) (T handler))]
|
||||
[else (error who "invalid tail ~s" (unparse x))]))
|
||||
;(print-code x)
|
||||
(T x))
|
||||
;;;
|
||||
|
@ -3210,8 +3494,11 @@
|
|||
(make-conditional (P e0) (E e1) (E e2))]
|
||||
[(asm-instr op a b)
|
||||
(case op
|
||||
[(logor logxor logand int+ int- int* move)
|
||||
[(logor logxor logand int+ int- int* move
|
||||
int-/overflow int+/overflow)
|
||||
(cond
|
||||
[(and (eq? op 'move) (eq? a b))
|
||||
(make-primcall 'nop '())]
|
||||
[(and (mem? a) (mem? b))
|
||||
(let ([u (mku)])
|
||||
(make-seq
|
||||
|
@ -3257,7 +3544,7 @@
|
|||
[(disp? b)
|
||||
(error who "invalid arg to idiv ~s" b)]
|
||||
[else x])]
|
||||
[(sll sra)
|
||||
[(sll sra srl)
|
||||
(unless (or (constant? b)
|
||||
(eq? b ecx))
|
||||
(error who "invalid shift ~s" b))
|
||||
|
@ -3300,9 +3587,12 @@
|
|||
(S* rands
|
||||
(lambda (s*)
|
||||
(make-primcall op s*)))]
|
||||
[else (error who "invalid op in ~s" x)])]
|
||||
[else (error who "invalid op in ~s" (unparse x))])]
|
||||
[(ntcall) x]
|
||||
[else (error who "invalid effect ~s" x)]))
|
||||
[(shortcut^ test body handler)
|
||||
(let ([body (E body)])
|
||||
(make-shortcut^ (P test) body (E handler)))]
|
||||
[else (error who "invalid effect ~s" (unparse x))]))
|
||||
(define (P x)
|
||||
(record-case x
|
||||
[(constant) x]
|
||||
|
@ -3326,14 +3616,16 @@
|
|||
(E (make-asm-instr 'move u b))
|
||||
(make-asm-instr op a u)))]
|
||||
[else x])]
|
||||
[else (error who "invalid pred ~s" x)]))
|
||||
[else (error who "invalid pred ~s" (unparse x))]))
|
||||
(define (T x)
|
||||
(record-case x
|
||||
[(primcall op rands) x]
|
||||
[(conditional e0 e1 e2)
|
||||
(make-conditional (P e0) (T e1) (T e2))]
|
||||
[(seq e0 e1) (make-seq (E e0) (T e1))]
|
||||
[else (error who "invalid tail ~s" x)]))
|
||||
[(shortcut^ test body handler)
|
||||
(make-shortcut^ (P test) (T body) (T handler))]
|
||||
[else (error who "invalid tail ~s" (unparse x))]))
|
||||
(let ([x (T x)])
|
||||
(values un* x)))
|
||||
;;;
|
||||
|
@ -3498,13 +3790,29 @@
|
|||
[(logor) (cons `(orl ,(R s) ,(R d)) ac)]
|
||||
[(logxor) (cons `(xorl ,(R s) ,(R d)) ac)]
|
||||
[(mset) (cons `(movl ,(R s) ,(R d)) ac)]
|
||||
[(move) (cons `(movl ,(R s) ,(R d)) ac)]
|
||||
[(move)
|
||||
(if (eq? d s)
|
||||
ac
|
||||
(cons `(movl ,(R s) ,(R d)) ac))]
|
||||
[(bset/c) (cons `(movb ,(BYTE s) ,(R d)) ac)]
|
||||
[(bset/h) (cons `(movb ,(reg/h s) ,(R d)) ac)]
|
||||
[(sll) (cons `(sall ,(R/cl s) ,(R d)) ac)]
|
||||
[(sra) (cons `(sarl ,(R/cl s) ,(R d)) ac)]
|
||||
[(srl) (cons `(shrl ,(R/cl s) ,(R d)) ac)]
|
||||
[(idiv) (cons `(idivl ,(R s)) ac)]
|
||||
[(cltd) (cons `(cltd) ac)]
|
||||
[(int-/overflow)
|
||||
(let ([L (or (exception-label)
|
||||
(error who "no exception label"))])
|
||||
(list* `(subl ,(R s) ,(R d))
|
||||
`(jo ,L)
|
||||
ac))]
|
||||
[(int+/overflow)
|
||||
(let ([L (or (exception-label)
|
||||
(error who "no exception label"))])
|
||||
(list* `(addl ,(R s) ,(R d))
|
||||
`(jo ,L)
|
||||
ac))]
|
||||
[else (error who "invalid instr ~s" x)])]
|
||||
[(primcall op rands)
|
||||
(case op
|
||||
|
@ -3518,8 +3826,14 @@
|
|||
`(addl ,(pcb-ref 'dirty-vector) ,a)
|
||||
`(movl ,dirty-word (disp 0 ,a))
|
||||
ac))]
|
||||
[else (error who "invalid effect ~s" x)])]
|
||||
[else (error who "invalid effect ~s" x)]))
|
||||
[else (error who "invalid effect ~s" (unparse x))])]
|
||||
[(shortcut^ test body handler)
|
||||
(let ([L (unique-label)] [L2 (unique-label)])
|
||||
(let ([ac (cons L (E handler (cons L2 ac)))])
|
||||
(let ([ac (parameterize ([exception-label L])
|
||||
(E body (cons `(jmp ,L2) ac)))])
|
||||
(P test #f L ac))))]
|
||||
[else (error who "invalid effect ~s" (unparse x))]))
|
||||
;;;
|
||||
(define (unique-label)
|
||||
(label (gensym)))
|
||||
|
@ -3612,7 +3926,14 @@
|
|||
[(direct-jump)
|
||||
(cons `(jmp (label ,(code-loc-label (car rands)))) ac)]
|
||||
[else (error who "invalid tail ~s" x)])]
|
||||
[(shortcut^ test body handler)
|
||||
(let ([L (unique-label)])
|
||||
(let ([ac (cons L (T handler ac))])
|
||||
(let ([ac (parameterize ([exception-label L])
|
||||
(T body ac))])
|
||||
(P test #f L ac))))]
|
||||
[else (error who "invalid tail ~s" x)]))
|
||||
(define exception-label (make-parameter #f))
|
||||
;;;
|
||||
(define (handle-vararg fml-count ac)
|
||||
(define CONTINUE_LABEL (unique-label))
|
||||
|
|
|
@ -256,6 +256,9 @@
|
|||
|
||||
|
||||
|
||||
(define-record shortcut^ (test body handler))
|
||||
(define-record shortcut (body handler))
|
||||
|
||||
(define-record fvar (idx))
|
||||
(define-record object (val))
|
||||
(define-record locals (vars body))
|
||||
|
@ -480,6 +483,10 @@
|
|||
[(nframe vars live body) `(nframe ;[vars: ,(map E vars)]
|
||||
;[live: ,(map E live)]
|
||||
,(E body))]
|
||||
[(shortcut^ pred body handler)
|
||||
`(shortcut ,(E pred) ,(E body) ,(E handler))]
|
||||
[(shortcut body handler)
|
||||
`(exceptional ,(E body) ,(E handler))]
|
||||
[else
|
||||
(if (symbol? x)
|
||||
x
|
||||
|
|
|
@ -564,6 +564,8 @@
|
|||
(CODE #xC1 (ModRM 3 '/5 dst (IMM8 src ac)))]
|
||||
[(and (eq? src '%cl) (reg? dst))
|
||||
(CODE #xD3 (ModRM 3 '/5 dst ac))]
|
||||
[(and (imm8? src) (mem? dst))
|
||||
((CODE/digit #xC1 '/5) dst (IMM8 src ac))]
|
||||
[else (error who "invalid ~s" instr)])]
|
||||
[(sarl src dst)
|
||||
(cond
|
||||
|
@ -873,7 +875,7 @@
|
|||
(case (car x)
|
||||
[(reloc-word foreign-label) (fx+ ac 2)]
|
||||
[(relative reloc-word+ label-addr) (fx+ ac 3)]
|
||||
[(word byte label current-frame-offset local-relative) ac]
|
||||
[(word byte label current-frame-offset local-relative) ac]
|
||||
[else (error 'compute-reloc-size "unknown instr ~s" x)])))
|
||||
0
|
||||
ls)))
|
||||
|
@ -937,6 +939,9 @@
|
|||
[(relative)
|
||||
(let ([loc (label-loc v)])
|
||||
(let ([obj (car loc)] [disp (cadr loc)])
|
||||
(unless (and (code? obj) (fixnum? disp))
|
||||
(error 'whack-reloc "invalid relative jump obj=~s disp=~s\n"
|
||||
obj disp))
|
||||
(vector-set! vec reloc-idx (fxlogor 3 (fxsll idx 2)))
|
||||
(vector-set! vec (fx+ reloc-idx 1) (fx+ disp 11))
|
||||
(vector-set! vec (fx+ reloc-idx 2) obj)))
|
||||
|
@ -971,6 +976,9 @@
|
|||
(lambda (foo reloc*)
|
||||
(for-each (whack-reloc thunk?-label (car foo) (cdr foo)) reloc*))
|
||||
(map cons code* relv*) reloc**)
|
||||
;(for-each (lambda (x)
|
||||
; (printf "RV=~s\n" x))
|
||||
; relv*)
|
||||
(for-each set-code-reloc-vector! code* relv*)
|
||||
code*)))))))
|
||||
|
||||
|
|
|
@ -232,7 +232,6 @@
|
|||
["libcontrol1.ss" "libcontrol1.fasl" p0 onepass]
|
||||
["libcollect.ss" "libcollect.fasl" p0 onepass]
|
||||
["librecord.ss" "librecord.fasl" p0 onepass]
|
||||
;["libcxr.ss" "libcxr.fasl" p0 chaitin]
|
||||
["libcxr.ss" "libcxr.fasl" p0 onepass]
|
||||
["libnumerics.ss" "libnumerics.fasl" p0 onepass]
|
||||
["libguardians.ss" "libguardians.fasl" p0 onepass]
|
||||
|
@ -282,7 +281,7 @@
|
|||
|
||||
|
||||
|
||||
(let ()
|
||||
#;(let ()
|
||||
(define (compile-all who)
|
||||
(for-each
|
||||
(lambda (x)
|
||||
|
@ -299,10 +298,9 @@
|
|||
(time (compile-all 'p0))
|
||||
(exit))))
|
||||
|
||||
#;(for-each
|
||||
(for-each
|
||||
(lambda (x)
|
||||
(when (cadr x)
|
||||
(compile-library (car x) (cadr x))))
|
||||
(compile-library (car x) (cadr x) (cadddr x)))
|
||||
scheme-library-files)
|
||||
|
||||
(define (join s ls)
|
||||
|
|
Loading…
Reference in New Issue