... |
... |
@@ -11,6 +11,7 @@ |
11
|
11
|
#include <stdlib.h>
|
12
|
12
|
#include <string.h>
|
13
|
13
|
#include <limits.h>
|
|
14
|
+#include <math.h>
|
14
|
15
|
|
15
|
16
|
#include "lisp.h"
|
16
|
17
|
#include "os.h"
|
... |
... |
@@ -29,6 +30,8 @@ |
29
|
30
|
/* Like (ceiling x y), but y is constrained to be a power of two */
|
30
|
31
|
#define CEILING(x,y) (((x) + ((y) - 1)) & (~((y) - 1)))
|
31
|
32
|
|
|
33
|
+#define NWORDS(x,y) (CEILING((x),(y)) / (y))
|
|
34
|
+
|
32
|
35
|
#ifdef FEATURE_EXECUTABLE
|
33
|
36
|
#include "elf.h"
|
34
|
37
|
#if !(defined(DARWIN) && defined(__ppc__))
|
... |
... |
@@ -309,8 +312,10 @@ save_executable(char *filename, lispobj init_function) |
309
|
312
|
(os_vm_address_t)SymbolValue(STATIC_SPACE_FREE_POINTER));
|
310
|
313
|
|
311
|
314
|
|
|
315
|
+ write_asm_object(dir_name, READ_ONLY_SPACE_ID, (os_vm_address_t)read_only_space,
|
|
316
|
+ (os_vm_address_t)SymbolValue(READ_ONLY_SPACE_FREE_POINTER));
|
312
|
317
|
write_asm_object(dir_name, STATIC_SPACE_ID, (os_vm_address_t)static_space,
|
313
|
|
- (os_vm_address_t)SymbolValue(STATIC_SPACE_FREE_POINTER));
|
|
318
|
+ (os_vm_address_t)SymbolValue(STATIC_SPACE_FREE_POINTER));
|
314
|
319
|
|
315
|
320
|
#ifdef GENCGC
|
316
|
321
|
/* Flush the current_region updating the tables. */
|
... |
... |
@@ -432,12 +437,12 @@ asm_align(FILE* f) |
432
|
437
|
}
|
433
|
438
|
|
434
|
439
|
void
|
435
|
|
-asm_header_word(lispobj* ptr, lispobj object, FILE* f)
|
|
440
|
+asm_header_word(lispobj* ptr, lispobj object, FILE* f, const char* note)
|
436
|
441
|
{
|
437
|
442
|
unsigned long len = HeaderValue(object);
|
438
|
443
|
unsigned long type = TypeOf(object);
|
439
|
444
|
|
440
|
|
- fprintf(f, "\t.4byte\t0x%lx << 8 + %ld\n", len, type);
|
|
445
|
+ fprintf(f, "\t.4byte\t0x%lx << 8 + %ld\t# %s\n", len, type, note);
|
441
|
446
|
}
|
442
|
447
|
|
443
|
448
|
|
... |
... |
@@ -462,7 +467,7 @@ asm_boxed(lispobj* ptr, lispobj object, FILE* f) |
462
|
467
|
|
463
|
468
|
asm_label(ptr, object, f);
|
464
|
469
|
|
465
|
|
- asm_header_word(ptr, object, f);
|
|
470
|
+ asm_header_word(ptr, object, f, "");
|
466
|
471
|
|
467
|
472
|
for (k = 1; k < len; ++k) {
|
468
|
473
|
asm_lispobj(ptr + k, ptr[k], f);
|
... |
... |
@@ -494,8 +499,10 @@ asm_list_pointer(lispobj* ptr, lispobj object, FILE* f) |
494
|
499
|
int
|
495
|
500
|
asm_function_pointer(lispobj* ptr, lispobj object, FILE* f)
|
496
|
501
|
{
|
|
502
|
+#if 0
|
497
|
503
|
printf("function pointer 0x%lx\n", object);
|
498
|
|
-
|
|
504
|
+#endif
|
|
505
|
+
|
499
|
506
|
asm_label(ptr, object, f);
|
500
|
507
|
asm_lispobj(ptr, object, f);
|
501
|
508
|
return 1;
|
... |
... |
@@ -515,7 +522,7 @@ asm_fdefn(lispobj* ptr, lispobj object, FILE* f) |
515
|
522
|
{
|
516
|
523
|
asm_label(ptr, object, f);
|
517
|
524
|
|
518
|
|
- asm_header_word(ptr, object, f);
|
|
525
|
+ asm_header_word(ptr, object, f, "fdefn");
|
519
|
526
|
asm_lispobj(ptr + 1, ptr[1], f);
|
520
|
527
|
asm_lispobj(ptr + 2, ptr[2], f);
|
521
|
528
|
|
... |
... |
@@ -541,7 +548,7 @@ asm_simple_vector(lispobj* ptr, lispobj object, FILE* f) |
541
|
548
|
lispobj* data = ptr + 2;
|
542
|
549
|
|
543
|
550
|
asm_label(ptr, object, f);
|
544
|
|
- asm_header_word(ptr, object, f);
|
|
551
|
+ asm_header_word(ptr, object, f, "simple vector");
|
545
|
552
|
asm_lispobj(ptr + 1, ptr[1], f);
|
546
|
553
|
|
547
|
554
|
for (k = 0; k < len; ++k) {
|
... |
... |
@@ -563,24 +570,277 @@ asm_complex_vector(lispobj* ptr, lispobj object, FILE* f) |
563
|
570
|
return asm_ni(ptr, object, f);
|
564
|
571
|
}
|
565
|
572
|
|
|
573
|
+int
|
|
574
|
+asm_code_header(lispobj* ptr, lispobj object, FILE* f)
|
|
575
|
+{
|
|
576
|
+ struct code *code;
|
|
577
|
+ int nheader_words;
|
|
578
|
+ int ncode_words;
|
|
579
|
+ int nwords;
|
|
580
|
+ int k;
|
|
581
|
+
|
|
582
|
+ code = (struct code *) ptr;
|
|
583
|
+ ncode_words = fixnum_value(code->code_size);
|
|
584
|
+ nheader_words = HeaderValue(object);
|
|
585
|
+ nwords = ncode_words + nheader_words;
|
|
586
|
+ nwords = CEILING(nwords, 2);
|
|
587
|
+
|
566
|
588
|
#if 0
|
|
589
|
+ fprintf(stderr, "nwords = %d nheader_words %d\n",
|
|
590
|
+ nwords, nheader_words);
|
|
591
|
+#endif
|
|
592
|
+
|
|
593
|
+ asm_label(ptr, object, f);
|
|
594
|
+ asm_header_word(ptr, object, f, "code header");
|
|
595
|
+
|
|
596
|
+ for (k = 0; k < nheader_words - 1; ++k) {
|
|
597
|
+ asm_lispobj(ptr + k + 1, ptr[k + 1], f);
|
|
598
|
+ }
|
|
599
|
+
|
|
600
|
+ fprintf(f, "# Code bytes?\n");
|
|
601
|
+
|
|
602
|
+ for (; k < nwords; ++k) {
|
|
603
|
+ fprintf(f, "\t.4byte\t0x%lx\n", ptr[k + 1]);
|
|
604
|
+ }
|
|
605
|
+
|
|
606
|
+ return nwords;
|
|
607
|
+}
|
|
608
|
+
|
567
|
609
|
int
|
568
|
|
-asm_bignum(lispobj* ptr, lispobj object, FILE* f)
|
|
610
|
+asm_simple_string(lispobj* where, lispobj object, FILE* f)
|
569
|
611
|
{
|
570
|
|
- int len = HeaderValue(object);
|
|
612
|
+ struct vector* vector;
|
|
613
|
+ int length;
|
|
614
|
+ int nwords;
|
|
615
|
+ int k;
|
|
616
|
+ int nchars;
|
|
617
|
+ uint16_t* s;
|
|
618
|
+
|
|
619
|
+ /*
|
|
620
|
+ * NOTE: Strings contain one more byte of data than the length
|
|
621
|
+ * slot indicates.
|
|
622
|
+ */
|
|
623
|
+
|
|
624
|
+ vector = (struct vector *) where;
|
|
625
|
+ length = fixnum_value(vector->length) + 1;
|
|
626
|
+#ifndef UNICODE
|
|
627
|
+#ifdef __x86_64
|
|
628
|
+ nwords = CEILING(NWORDS(length, 8) + 2, 2);
|
|
629
|
+#else
|
|
630
|
+ nwords = CEILING(NWORDS(length, 4) + 2, 2);
|
|
631
|
+#endif
|
|
632
|
+#else
|
|
633
|
+ /*
|
|
634
|
+ * Strings are just like arrays with 16-bit elements, and contain
|
|
635
|
+ * one more element than the slot length indicates.
|
|
636
|
+ */
|
|
637
|
+ nchars = CEILING(length + 1, 2);
|
|
638
|
+ nwords = CEILING(NWORDS(length, 2) + 2, 2);
|
|
639
|
+#endif
|
|
640
|
+
|
|
641
|
+ asm_label(where, object, f);
|
|
642
|
+ asm_header_word(where, object, f, "simple string");
|
|
643
|
+ asm_lispobj(where + 1, where[1], f);
|
|
644
|
+
|
|
645
|
+ s = (uint16_t*) vector->data;
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+ for (k = 0; k < nchars; ++k) {
|
|
649
|
+ int c = s[k];
|
|
650
|
+
|
|
651
|
+ fprintf(f, "\t.2byte\t0x%x\t# ", c);
|
|
652
|
+ if (c >= ' ' && c <= 127) {
|
|
653
|
+ fprintf(f, "%c\n", c);
|
|
654
|
+ } else {
|
|
655
|
+ fprintf(f, "#\\u+%04x\n", c);
|
|
656
|
+ }
|
|
657
|
+ }
|
|
658
|
+
|
|
659
|
+ return nwords;
|
|
660
|
+}
|
|
661
|
+
|
|
662
|
+void
|
|
663
|
+print_float(FILE* f, float value)
|
|
664
|
+{
|
|
665
|
+ if (isfinite(value)) {
|
|
666
|
+ fprintf(f, "\t.float\t%.15g\n", value);
|
|
667
|
+ } else {
|
|
668
|
+ union
|
|
669
|
+ {
|
|
670
|
+ uint32_t a;
|
|
671
|
+ float f;
|
|
672
|
+ } val;
|
|
673
|
+
|
|
674
|
+ val.f = value;
|
|
675
|
+ fprintf(f, "\t.4byte\t0x%x\n", val.a);
|
|
676
|
+ }
|
|
677
|
+}
|
|
678
|
+
|
|
679
|
+int
|
|
680
|
+asm_single_float(lispobj* ptr, lispobj object, FILE* f)
|
|
681
|
+{
|
|
682
|
+ struct single_float* obj = (struct single_float*) ptr;
|
571
|
683
|
|
572
|
684
|
asm_label(ptr, object, f);
|
|
685
|
+ asm_header_word(ptr, object, f, "single float");
|
|
686
|
+ print_float(f, obj->value);
|
573
|
687
|
|
574
|
|
- asm_lispobj(ptr, object, f);
|
575
|
|
- ++ptr;
|
|
688
|
+
|
|
689
|
+ return 2;
|
|
690
|
+}
|
|
691
|
+
|
|
692
|
+void
|
|
693
|
+print_double(FILE* f, double value)
|
|
694
|
+{
|
|
695
|
+ if (isfinite(value)) {
|
|
696
|
+ fprintf(f, "\t.double\t%.15g\n", value);
|
|
697
|
+ } else {
|
|
698
|
+ union
|
|
699
|
+ {
|
|
700
|
+ uint32_t a[2];
|
|
701
|
+ double d;
|
|
702
|
+ } val;
|
|
703
|
+
|
|
704
|
+ val.d = value;
|
|
705
|
+
|
|
706
|
+ fprintf(f, "\t.4byte\t0x%x\n", val.a[0]);
|
|
707
|
+ fprintf(f, "\t.4byte\t0x%x\n", val.a[1]);
|
|
708
|
+ }
|
|
709
|
+}
|
|
710
|
+
|
|
711
|
+int
|
|
712
|
+asm_double_float(lispobj* ptr, lispobj object, FILE* f)
|
|
713
|
+{
|
|
714
|
+ struct double_float* obj = (struct double_float*) ptr;
|
576
|
715
|
|
577
|
|
- for (k = 0; k < len; ++k) {
|
578
|
|
- fprintf(f, "\t.4byte\t%d\n", ptr[k]);
|
|
716
|
+ asm_label(ptr, object, f);
|
|
717
|
+ asm_header_word(ptr, object, f, "double float");
|
|
718
|
+ asm_lispobj(&obj->filler, obj->filler, f);
|
|
719
|
+ print_double(f, obj->value);
|
|
720
|
+
|
|
721
|
+ return 4;
|
|
722
|
+}
|
|
723
|
+
|
|
724
|
+int
|
|
725
|
+asm_double_double_float(lispobj* ptr, lispobj object, FILE* f)
|
|
726
|
+{
|
|
727
|
+ struct double_double_float* obj = (struct double_double_float*) ptr;
|
|
728
|
+
|
|
729
|
+ asm_label(ptr, object, f);
|
|
730
|
+ asm_header_word(ptr, object, f, "double double float");
|
|
731
|
+ asm_lispobj(&obj->filler, obj->filler, f);
|
|
732
|
+
|
|
733
|
+ print_double(f, obj->hi);
|
|
734
|
+ print_double(f, obj->lo);
|
|
735
|
+
|
|
736
|
+ return 1 + HeaderValue(object);
|
|
737
|
+}
|
|
738
|
+
|
|
739
|
+int
|
|
740
|
+asm_complex_single_float(lispobj* ptr, lispobj object, FILE* f)
|
|
741
|
+{
|
|
742
|
+ struct complex_single_float* obj = (struct complex_single_float*) ptr;
|
|
743
|
+
|
|
744
|
+ asm_label(ptr, object, f);
|
|
745
|
+ asm_header_word(ptr, object, f, "complex single-float");
|
|
746
|
+ print_float(f, obj->real);
|
|
747
|
+ print_float(f, obj->imag);
|
|
748
|
+ /* Force double word boundary */
|
|
749
|
+ asm_lispobj(ptr + 3, ptr[3], f);
|
|
750
|
+
|
|
751
|
+ return CEILING(1 + HeaderValue(object), 2);
|
|
752
|
+}
|
|
753
|
+
|
|
754
|
+
|
|
755
|
+int
|
|
756
|
+asm_vector_unsigned_byte_8(lispobj* ptr, lispobj object, FILE* f)
|
|
757
|
+{
|
|
758
|
+ struct vector *vector;
|
|
759
|
+ int length, nwords;
|
|
760
|
+ unsigned long* data;
|
|
761
|
+ int k;
|
|
762
|
+
|
|
763
|
+ vector = (struct vector *) ptr;
|
|
764
|
+ length = fixnum_value(vector->length);
|
|
765
|
+#ifdef __x86_64
|
|
766
|
+ nwords = CEILING(NWORDS(length, 8) + 2, 2);
|
|
767
|
+#else
|
|
768
|
+ nwords = CEILING(NWORDS(length, 4) + 2, 2);
|
|
769
|
+#endif
|
|
770
|
+ asm_label(ptr, object, f);
|
|
771
|
+ asm_header_word(ptr, object, f, "vector unsigned_byte 8");
|
|
772
|
+ asm_lispobj(ptr + 1, ptr[1], f);
|
|
773
|
+
|
|
774
|
+ data = vector->data;
|
|
775
|
+
|
|
776
|
+ /* Minus 2 for the header and length words */
|
|
777
|
+ for (k = 0; k < nwords - 2; ++k) {
|
|
778
|
+ fprintf(f, "\t.4byte\t0x%lx\n", data[k]);
|
|
779
|
+ }
|
|
780
|
+
|
|
781
|
+ return nwords;
|
|
782
|
+}
|
|
783
|
+
|
|
784
|
+int
|
|
785
|
+asm_vector_unsigned_byte_32(lispobj* ptr, lispobj object, FILE* f)
|
|
786
|
+{
|
|
787
|
+ struct vector *vector;
|
|
788
|
+ int length, nwords;
|
|
789
|
+ unsigned long* data;
|
|
790
|
+ int k;
|
|
791
|
+
|
|
792
|
+ vector = (struct vector *) ptr;
|
|
793
|
+ length = fixnum_value(vector->length);
|
|
794
|
+#ifdef __x86_64
|
|
795
|
+ nwords = CEILING(NWORDS(length, 2) + 2, 2);
|
|
796
|
+#else
|
|
797
|
+ nwords = CEILING(length + 2, 2);
|
|
798
|
+#endif
|
|
799
|
+
|
|
800
|
+ asm_label(ptr, object, f);
|
|
801
|
+ asm_header_word(ptr, object, f, "vector unsigned_byte 32");
|
|
802
|
+ asm_lispobj(ptr + 1, ptr[1], f);
|
|
803
|
+
|
|
804
|
+ data = vector->data;
|
|
805
|
+
|
|
806
|
+ /* Minus 2 for the header and length words */
|
|
807
|
+ for (k = 0; k < nwords - 2; ++k) {
|
|
808
|
+ fprintf(f, "\t.4byte\t0x%lx\n", data[k]);
|
|
809
|
+ }
|
|
810
|
+
|
|
811
|
+ return nwords;
|
|
812
|
+}
|
|
813
|
+
|
|
814
|
+int
|
|
815
|
+asm_bignum(lispobj* ptr, lispobj object, FILE* f)
|
|
816
|
+{
|
|
817
|
+ int len = 1 + HeaderValue(object);
|
|
818
|
+ int k;
|
|
819
|
+
|
|
820
|
+ len = CEILING(len, 2);
|
|
821
|
+
|
|
822
|
+ asm_label(ptr, object, f);
|
|
823
|
+ asm_header_word(ptr, object, f, "bignum");
|
|
824
|
+
|
|
825
|
+ for (k = 1; k < len; ++k) {
|
|
826
|
+ fprintf(f, "\t.4byte\t0x%lx\t# %lu\n", ptr[k], ptr[k]);
|
579
|
827
|
}
|
580
|
828
|
|
581
|
829
|
return len;
|
582
|
830
|
}
|
583
|
831
|
|
|
832
|
+int
|
|
833
|
+asm_sap(lispobj* ptr, lispobj object, FILE* f)
|
|
834
|
+{
|
|
835
|
+ asm_label(ptr, object, f);
|
|
836
|
+ asm_header_word(ptr, object, f, "sap");
|
|
837
|
+ /* Just print out the raw value of the address */
|
|
838
|
+ fprintf(f, "\t.4byte\t0x%lx\n", ptr[1]);
|
|
839
|
+
|
|
840
|
+ return 2;
|
|
841
|
+}
|
|
842
|
+
|
|
843
|
+#if 0
|
584
|
844
|
int
|
585
|
845
|
asm_catch_block(lispobj* ptr, lispobj object, FILE* f)
|
586
|
846
|
{
|
... |
... |
@@ -674,19 +934,30 @@ init_asmtab(void) |
674
|
934
|
asmtab[type_OtherPointer | (k << 3)] = asm_other_pointer;
|
675
|
935
|
}
|
676
|
936
|
|
|
937
|
+ asmtab[type_Bignum] = asm_bignum;
|
677
|
938
|
asmtab[type_Ratio] = asm_boxed;
|
|
939
|
+ asmtab[type_SingleFloat] = asm_single_float;
|
|
940
|
+ asmtab[type_DoubleFloat] = asm_double_float;
|
|
941
|
+ asmtab[type_DoubleDoubleFloat] = asm_double_double_float;
|
678
|
942
|
asmtab[type_Complex] = asm_boxed;
|
|
943
|
+ asmtab[type_ComplexSingleFloat] = asm_complex_single_float;
|
679
|
944
|
asmtab[type_SimpleArray] = asm_boxed;
|
680
|
|
- asmtab[type_SymbolHeader] = asm_boxed;
|
681
|
|
- asmtab[type_Fdefn] = asm_fdefn;
|
682
|
|
- asmtab[type_InstanceHeader] = asm_boxed;
|
|
945
|
+ asmtab[type_SimpleString] = asm_simple_string;
|
683
|
946
|
asmtab[type_SimpleVector] = asm_simple_vector;
|
684
|
|
- asmtab[type_FuncallableInstanceHeader] = asm_closure_header;
|
|
947
|
+ asmtab[type_SimpleArrayUnsignedByte8] = asm_vector_unsigned_byte_8;
|
|
948
|
+ asmtab[type_SimpleArrayUnsignedByte32] = asm_vector_unsigned_byte_32;
|
|
949
|
+ asmtab[type_ComplexString] = asm_boxed;
|
685
|
950
|
asmtab[type_ComplexVector] = asm_boxed;
|
686
|
|
- asmtab[type_BaseChar] = asm_immediate;
|
|
951
|
+ asmtab[type_CodeHeader] = asm_code_header;
|
|
952
|
+ asmtab[type_ClosureHeader] = asm_closure_header;
|
|
953
|
+ asmtab[type_FuncallableInstanceHeader] = asm_closure_header;
|
687
|
954
|
/* Just use asm_boxed or have a special version for a value cell? */
|
688
|
955
|
asmtab[type_ValueCellHeader] = asm_boxed;
|
689
|
|
-
|
|
956
|
+ asmtab[type_SymbolHeader] = asm_boxed;
|
|
957
|
+ asmtab[type_BaseChar] = asm_immediate;
|
|
958
|
+ asmtab[type_Sap] = asm_sap;
|
|
959
|
+ asmtab[type_InstanceHeader] = asm_boxed;
|
|
960
|
+ asmtab[type_Fdefn] = asm_fdefn;
|
690
|
961
|
}
|
691
|
962
|
|
692
|
963
|
void
|
... |
... |
@@ -710,9 +981,9 @@ write_asm_object(const char *dir, int id, os_vm_address_t start, os_vm_address_t |
710
|
981
|
int k;
|
711
|
982
|
|
712
|
983
|
/* Output the first word */
|
713
|
|
- asm_header_word(ptr, *ptr, f);
|
|
984
|
+ asm_header_word(ptr, *ptr, f, "");
|
714
|
985
|
/* Header word for NIL */
|
715
|
|
- asm_header_word(ptr + 1, ptr[1], f);
|
|
986
|
+ asm_header_word(ptr + 1, ptr[1], f, "NIL header");
|
716
|
987
|
/* Label for NIL */
|
717
|
988
|
asm_label(ptr + 2, ptr[2], f);
|
718
|
989
|
ptr += 2;
|