Raymond Toy pushed to branch native-image at cmucl / cmucl
Commits: e35e9f7a by Raymond Toy at 2021-02-06T13:33:21-08:00 Add complex double-double-float
Remove some old #if'd out code.
- - - - - 96e7aa5e by Raymond Toy at 2021-02-06T13:55:09-08:00 Add bit vector and double-float vector
- - - - - 57ceca08 by Raymond Toy at 2021-02-06T14:05:39-08:00 Add vectyor unsigned-byte 16
- - - - - 9e4049c6 by Raymond Toy at 2021-02-06T14:14:55-08:00 Add vector unsigned-byte 2
- - - - - 44913576 by Raymond Toy at 2021-02-06T14:20:12-08:00 Add vector unsigned-byte 4
- - - - - e2cecd5f by Raymond Toy at 2021-02-06T14:38:03-08:00 Print hex values for floats
The gcc assembler can't handle most-positive-double-float (when printed by C), so let's just print out the 32-bit words of the double with a comment on the actual value.
- - - - - 55c9c196 by Raymond Toy at 2021-02-06T14:42:16-08:00 Add comment on where we need to apply code fixups.
- - - - - 0a553364 by Raymond Toy at 2021-02-07T09:47:06-08:00 Fix handling of code header and symbol headers
Printing of the symbol header was broken because we printed out the unbound marker as Lba, indicating an address. But we just want the raw value of the unbound marker
The code header consists of multiple function header objects so we dump each of the objects now.
Finally a few changes on printing: * asm_word uses %08lx to the value * asm_lispobj prints out the address with %08lx to be consistent with asm_label.
- - - - - a31b485f by Raymond Toy at 2021-02-07T10:03:17-08:00 asm_lispobj handles immediates
If the object is an even or odd immediate, just print out the value since it's, duh, an immediate, not some kind of address or fixnum.
asm_symbol_header doesn't need the special case for the value slot anymore. (We can probably replace this with just asm_boxed as we did before.)
- - - - -
1 changed file:
- src/lisp/save.c
Changes:
===================================== src/lisp/save.c ===================================== @@ -407,7 +407,7 @@ asm_word(lispobj* ptr, lispobj object, FILE* f) { unsigned long val = (unsigned long) object;
- fprintf(f, "\t.4byte\t0x%lx\t# %ld\n", val, val); + fprintf(f, "\t.4byte\t0x%08lx\t# %ld\n", val, val); }
void @@ -419,8 +419,12 @@ asm_lispobj(lispobj* ptr, lispobj object, FILE* f) fprintf(f, "0x%lx\t# fixnum %ld\n", (long) object, ((long) object) >> 2); + } else if ((object & 7) == 2 || + (object & 7) == 6) { + /* Other immediates */ + fprintf(f, "0x%08lx\n", object); } else { - fprintf(f, "L%lx + %lu\n", PTR(object), LowtagOf(object)); + fprintf(f, "L%08lx + %lu\n", PTR(object), LowtagOf(object)); } }
@@ -564,6 +568,22 @@ asm_closure_header(lispobj* ptr, lispobj object, FILE* f) return asm_boxed(ptr, object, f); }
+int +asm_symbol_header(lispobj* ptr, lispobj object, FILE* f) +{ + struct symbol* sym = (struct symbol*) ptr; + + asm_label(ptr, object, f); + asm_header_word(ptr, object, f, "symbol header"); + asm_lispobj(&sym->value, sym->value, f); + asm_lispobj(&sym->hash, sym->hash, f); + asm_lispobj(&sym->plist, sym->plist, f); + asm_lispobj(&sym->name, sym->name, f); + asm_lispobj(&sym->package, sym->package, f); + + return 1 + HeaderValue(object); +} + int asm_complex_vector(lispobj* ptr, lispobj object, FILE* f) { @@ -578,6 +598,8 @@ asm_code_header(lispobj* ptr, lispobj object, FILE* f) int ncode_words; int nwords; int k; + lispobj fheaderl; + struct function *fheaderp;
code = (struct code *) ptr; ncode_words = fixnum_value(code->code_size); @@ -597,12 +619,66 @@ asm_code_header(lispobj* ptr, lispobj object, FILE* f) asm_lispobj(ptr + k + 1, ptr[k + 1], f); }
- fprintf(f, "# Code bytes?\n"); - - for (; k < nwords; ++k) { - fprintf(f, "\t.4byte\t0x%lx\n", ptr[k + 1]); + fheaderl = code->entry_points; + while (fheaderl != NIL) { + int code_words; + int fheader_len; + + fheaderp = (struct function *) PTR(fheaderl); + fheader_len = HeaderValue(fheaderp->header); +#if 0 + fprintf(f, "# fheaderp %p\n", (void*) fheaderp); + fprintf(f, "# ->header 0x%lx\n", fheaderp->header); + fprintf(f, "# ->self 0x%lx\n", fheaderp->self); + fprintf(f, "# ->next 0x%lx\n", fheaderp->next); + fprintf(f, "# ->name 0x%lx\n", fheaderp->name); + fprintf(f, "# ->arglist 0x%lx\n", fheaderp->arglist); + fprintf(f, "# ->type 0x%lx\n", fheaderp->type); + fprintf(f, "# ->code %p\n", &fheaderp->code); +#endif + asm_label((lispobj*)fheaderp, *((lispobj*)fheaderp), f); + asm_header_word(&fheaderp->header, fheaderp->header, f, "function header"); + fprintf(f, "\t.4byte\tL%lx\n", fheaderp->self); + asm_lispobj(&fheaderp->next, fheaderp->next, f); + asm_lispobj(&fheaderp->name, fheaderp->name, f); + asm_lispobj(&fheaderp->arglist, fheaderp->arglist, f); + asm_lispobj(&fheaderp->type, fheaderp->type, f); + asm_label((lispobj*)fheaderp->code, 0, f); + + /* We've sent out 6 of the total code words */ + ncode_words -= fheader_len; + + /* + * TODO: Adopt trans_code or apply_code_fixups to process the code + * here so we can relocate everthing. + */ + fprintf(f, "# Code bytes\n"); + + /* Dump out code between here and the next function header */ + if (fheaderp->next != NIL) { + code_words = (fheaderp->next - fheaderl) / 4 - fheader_len; + } else { + code_words = ncode_words; + } + + fprintf(f, "# fheaderp->next %p code words %d ncode_words %d\n", + (void*)fheaderp->next, code_words, ncode_words); + + { + uint32_t* code_data = (uint32_t*) fheaderp->code; + + for (k = 0; k < code_words; ++k) { + fprintf(f, "\t.4byte\t0x%08x\t# %p\n", code_data[k], + fheaderp->code + 4*k); + } + } + + ncode_words -= code_words; + + fheaderl = fheaderp->next; } - + + asm_align(f); return nwords; }
@@ -659,9 +735,42 @@ asm_simple_string(lispobj* where, lispobj object, FILE* f) return nwords; }
+int +asm_vector_bit(lispobj* ptr, lispobj object, FILE* f) +{ + struct vector *vector; + int length, nwords; + unsigned long* data; + int k; + + + vector = (struct vector *) ptr; + length = fixnum_value(vector->length); +#ifdef __x86_64 + nwords = CEILING(NWORDS(length, 64) + 2, 2); +#else + nwords = CEILING(NWORDS(length, 32) + 2, 2); +#endif + + asm_label(ptr, object, f); + asm_header_word(ptr, object, f, "simple bit-vector"); + asm_lispobj(ptr + 1, ptr[1], f); + + data = vector->data; + + for (k = 0; k < nwords - 2; ++k) { + fprintf(f, "\t.4byte\t0x%lx\n", data[k]); + } + + return nwords; + +} + + void print_float(FILE* f, float value) { +#if 0 if (isfinite(value)) { fprintf(f, "\t.float\t%.15g\n", value); } else { @@ -674,6 +783,17 @@ print_float(FILE* f, float value) val.f = value; fprintf(f, "\t.4byte\t0x%x\n", val.a); } +#else + union + { + uint32_t a; + float f; + } val; + + val.f = value; + fprintf(f, "\t.4byte\t0x%x\t# %lg\n", val.a, value); +#endif + }
int @@ -684,7 +804,6 @@ asm_single_float(lispobj* ptr, lispobj object, FILE* f) asm_label(ptr, object, f); asm_header_word(ptr, object, f, "single float"); print_float(f, obj->value); -
return 2; } @@ -692,8 +811,9 @@ asm_single_float(lispobj* ptr, lispobj object, FILE* f) void print_double(FILE* f, double value) { +#if 0 if (isfinite(value)) { - fprintf(f, "\t.double\t%.15g\n", value); + fprintf(f, "\t.double\t%.16lg\n", value); } else { union { @@ -706,6 +826,18 @@ print_double(FILE* f, double value) fprintf(f, "\t.4byte\t0x%x\n", val.a[0]); fprintf(f, "\t.4byte\t0x%x\n", val.a[1]); } +#else + union + { + uint32_t a[2]; + double d; + } val; + + val.d = value; + fprintf(f, "\t.4byte\t0x%x\t# %.18lg\n", val.a[0], value); + fprintf(f, "\t.4byte\t0x%x\n", val.a[1]); + +#endif }
int @@ -751,9 +883,41 @@ asm_complex_single_float(lispobj* ptr, lispobj object, FILE* f) return CEILING(1 + HeaderValue(object), 2); }
+int +asm_complex_double_float(lispobj* ptr, lispobj object, FILE* f) +{ + struct complex_double_float* obj = (struct complex_double_float*) ptr; + + asm_label(ptr, object, f); + asm_header_word(ptr, object, f, "complex double-float"); + asm_lispobj(&obj->filler, obj->filler, f); + + print_double(f, obj->real); + print_double(f, obj->imag);
+ return CEILING(1 + HeaderValue(object), 2); +} + int -asm_vector_unsigned_byte_8(lispobj* ptr, lispobj object, FILE* f) +asm_complex_double_double_float(lispobj* ptr, lispobj object, FILE* f) +{ + struct complex_double_double_float* obj = (struct complex_double_double_float*) ptr; + + asm_label(ptr, object, f); + asm_header_word(ptr, object, f, "complex double-float"); + asm_lispobj(&obj->filler, obj->filler, f); + + print_double(f, obj->real_hi); + print_double(f, obj->real_lo); + print_double(f, obj->imag_hi); + print_double(f, obj->imag_lo); + + return CEILING(1 + HeaderValue(object), 2); +} + + +int +asm_vector_unsigned_byte_2(lispobj* ptr, lispobj object, FILE* f) { struct vector *vector; int length, nwords; @@ -763,12 +927,12 @@ asm_vector_unsigned_byte_8(lispobj* ptr, lispobj object, FILE* f) vector = (struct vector *) ptr; length = fixnum_value(vector->length); #ifdef __x86_64 - nwords = CEILING(NWORDS(length, 8) + 2, 2); + nwords = CEILING(NWORDS(length, 32) + 2, 2); #else - nwords = CEILING(NWORDS(length, 4) + 2, 2); + nwords = CEILING(NWORDS(length, 16) + 2, 2); #endif asm_label(ptr, object, f); - asm_header_word(ptr, object, f, "vector unsigned_byte 8"); + asm_header_word(ptr, object, f, "vector unsigned_byte 2"); asm_lispobj(ptr + 1, ptr[1], f);
data = vector->data; @@ -777,12 +941,14 @@ asm_vector_unsigned_byte_8(lispobj* ptr, lispobj object, FILE* f) for (k = 0; k < nwords - 2; ++k) { fprintf(f, "\t.4byte\t0x%lx\n", data[k]); } + + asm_align(f);
return nwords; }
int -asm_vector_unsigned_byte_32(lispobj* ptr, lispobj object, FILE* f) +asm_vector_unsigned_byte_4(lispobj* ptr, lispobj object, FILE* f) { struct vector *vector; int length, nwords; @@ -792,13 +958,12 @@ asm_vector_unsigned_byte_32(lispobj* ptr, lispobj object, FILE* f) vector = (struct vector *) ptr; length = fixnum_value(vector->length); #ifdef __x86_64 - nwords = CEILING(NWORDS(length, 2) + 2, 2); + nwords = CEILING(NWORDS(length, 16) + 2, 2); #else - nwords = CEILING(length + 2, 2); + nwords = CEILING(NWORDS(length, 8) + 2, 2); #endif - asm_label(ptr, object, f); - asm_header_word(ptr, object, f, "vector unsigned_byte 32"); + asm_header_word(ptr, object, f, "vector unsigned_byte 4"); asm_lispobj(ptr + 1, ptr[1], f);
data = vector->data; @@ -807,113 +972,186 @@ asm_vector_unsigned_byte_32(lispobj* ptr, lispobj object, FILE* f) for (k = 0; k < nwords - 2; ++k) { fprintf(f, "\t.4byte\t0x%lx\n", data[k]); } + + asm_align(f);
return nwords; }
int -asm_bignum(lispobj* ptr, lispobj object, FILE* f) +asm_vector_unsigned_byte_8(lispobj* ptr, lispobj object, FILE* f) { - int len = 1 + HeaderValue(object); + struct vector *vector; + int length, nwords; + unsigned long* data; int k; - - len = CEILING(len, 2);
+ vector = (struct vector *) ptr; + length = fixnum_value(vector->length); +#ifdef __x86_64 + nwords = CEILING(NWORDS(length, 8) + 2, 2); +#else + nwords = CEILING(NWORDS(length, 4) + 2, 2); +#endif asm_label(ptr, object, f); - asm_header_word(ptr, object, f, "bignum"); + asm_header_word(ptr, object, f, "vector unsigned_byte 8"); + asm_lispobj(ptr + 1, ptr[1], f);
- for (k = 1; k < len; ++k) { - fprintf(f, "\t.4byte\t0x%lx\t# %lu\n", ptr[k], ptr[k]); - } + data = vector->data;
- return len; + /* Minus 2 for the header and length words */ + for (k = 0; k < nwords - 2; ++k) { + fprintf(f, "\t.4byte\t0x%lx\n", data[k]); + } + + return nwords; }
int -asm_sap(lispobj* ptr, lispobj object, FILE* f) +asm_vector_unsigned_byte_16(lispobj* ptr, lispobj object, FILE* f) { + struct vector *vector; + int length, nwords; + uint16_t* data; + int k; + + vector = (struct vector *) ptr; + length = fixnum_value(vector->length); +#ifdef __x86_64 + nwords = CEILING(NWORDS(length, 4) + 2, 2); +#else + nwords = CEILING(NWORDS(length, 2) + 2, 2); +#endif asm_label(ptr, object, f); - asm_header_word(ptr, object, f, "sap"); - /* Just print out the raw value of the address */ - fprintf(f, "\t.4byte\t0x%lx\n", ptr[1]); + asm_header_word(ptr, object, f, "vector unsigned_byte 16"); + asm_lispobj(ptr + 1, ptr[1], f); + + data = (uint16_t*) vector->data;
- return 2; -} + /* Minus 2 for the header and length words */ + for (k = 0; k < length; ++k) { + fprintf(f, "\t.4byte\t0x%x\n", data[k]); + } + + asm_align(f);
-#if 0 -int -asm_catch_block(lispobj* ptr, lispobj object, FILE* f) -{ - return asm_boxed(ptr, object, f); + return nwords; }
int -asm_catch_block(lispobj* ptr, lispobj object, FILE* f) +asm_vector_unsigned_byte_32(lispobj* ptr, lispobj object, FILE* f) { - return asm_boxed(ptr, object, f); -} + struct vector *vector; + int length, nwords; + unsigned long* data; + int k; + + vector = (struct vector *) ptr; + length = fixnum_value(vector->length); +#ifdef __x86_64 + nwords = CEILING(NWORDS(length, 2) + 2, 2); +#else + nwords = CEILING(length + 2, 2); +#endif
-int -asm_closure(lispobj* ptr, lispobj object, FILE* f) -{ - return asm_boxed(ptr, object, f); -} + asm_label(ptr, object, f); + asm_header_word(ptr, object, f, "vector unsigned_byte 32"); + asm_lispobj(ptr + 1, ptr[1], f); + + data = vector->data;
-int -asm_code(lispobj* ptr, lispobj object, FILE* f) -{ - return asm_boxed(ptr, object, f); + /* Minus 2 for the header and length words */ + for (k = 0; k < nwords - 2; ++k) { + fprintf(f, "\t.4byte\t0x%lx\n", data[k]); + } + + return nwords; }
int -asm_complex(lispobj* ptr, lispobj object, FILE* f) +asm_vector_double_float(lispobj* ptr, lispobj object, FILE* f) { - return asm_boxed(ptr, object, f); -} + struct vector *vector; + int length, nwords; + const double* data; + int k; + + vector = (struct vector *) ptr; + length = fixnum_value(vector->length); +#ifdef __x86_64 + nwords = CEILING(length + 2, 2); +#else + nwords = length * 2 + 2; /* alignment guaranteed */ +#endif
-int -asm_complex_double_double_float(lispobj* ptr, lispobj object, FILE* f) -{ asm_label(ptr, object, f); - asm_lispobj(ptr, object, f); + asm_header_word(ptr, object, f, "vector double-float"); asm_lispobj(ptr + 1, ptr[1], f); - - double* d = (double*) (ptr + 2);
- for (k = 0; k < 4; ++k) { - fprintf(f, "\t.double\t%.15lg\n", d[k]); + data = (const double*) vector->data; + + + for (k = 0; k < length; ++k) { + print_double(f, data[k]); }
- return HeaderValue(object); + return nwords; }
int -asm_complex_double_float(lispobj* ptr, lispobj object, FILE* f) +asm_vector_double_double_float(lispobj* ptr, lispobj object, FILE* f) { + struct vector *vector; + int length, nwords; + const double* data; + int k; + + vector = (struct vector *) ptr; + length = fixnum_value(vector->length); + nwords = CEILING(length * 4 + 2, 2); + asm_label(ptr, object, f); - asm_lispobj(ptr, object, f); + asm_header_word(ptr, object, f, "vector double-float"); asm_lispobj(ptr + 1, ptr[1], f); + + data = (const double*) vector->data;
- double* d = ptr + 2; - fprintf(f, "\t.double\t%.15lg, %.15lg\n", d[0], d[1]); + for (k = 0; k < 2*length; ++k) { + print_double(f, data[k]); + }
- return HeaderValue(object); + return nwords; }
int -asm_complex_double_float(lispobj* ptr, lispobj object, FILE* f) +asm_bignum(lispobj* ptr, lispobj object, FILE* f) { - asm_label(ptr, object, f); - asm_lispobj(ptr, object, f); + int len = 1 + HeaderValue(object); + int k;
- double* d = ptr + 2; - fprintf(f, "\t.double\t%.15lg, %.15lg\n", d[0], d[1]); + len = CEILING(len, 2); + + asm_label(ptr, object, f); + asm_header_word(ptr, object, f, "bignum"); + + for (k = 1; k < len; ++k) { + fprintf(f, "\t.4byte\t0x%lx\t# %lu\n", ptr[k], ptr[k]); + }
- return HeaderValue(object); + return len; }
-#endif +int +asm_sap(lispobj* ptr, lispobj object, FILE* f) +{ + asm_label(ptr, object, f); + asm_header_word(ptr, object, f, "sap"); + /* Just print out the raw value of the address */ + fprintf(f, "\t.4byte\t0x%lx\n", ptr[1]);
+ return 2; +} + void init_asmtab(void) { @@ -941,11 +1179,19 @@ init_asmtab(void) asmtab[type_DoubleDoubleFloat] = asm_double_double_float; asmtab[type_Complex] = asm_boxed; asmtab[type_ComplexSingleFloat] = asm_complex_single_float; + asmtab[type_ComplexDoubleFloat] = asm_complex_double_float; + asmtab[type_ComplexDoubleDoubleFloat] = asm_complex_double_double_float; asmtab[type_SimpleArray] = asm_boxed; asmtab[type_SimpleString] = asm_simple_string; + asmtab[type_SimpleBitVector] = asm_vector_bit; asmtab[type_SimpleVector] = asm_simple_vector; + asmtab[type_SimpleArrayUnsignedByte2] = asm_vector_unsigned_byte_2; + asmtab[type_SimpleArrayUnsignedByte4] = asm_vector_unsigned_byte_4; asmtab[type_SimpleArrayUnsignedByte8] = asm_vector_unsigned_byte_8; + asmtab[type_SimpleArrayUnsignedByte16] = asm_vector_unsigned_byte_16; asmtab[type_SimpleArrayUnsignedByte32] = asm_vector_unsigned_byte_32; + asmtab[type_SimpleArrayDoubleFloat] = asm_vector_double_float; + asmtab[type_SimpleArrayDoubleDoubleFloat] = asm_vector_double_double_float; asmtab[type_ComplexString] = asm_boxed; asmtab[type_ComplexVector] = asm_boxed; asmtab[type_CodeHeader] = asm_code_header; @@ -953,7 +1199,7 @@ init_asmtab(void) asmtab[type_FuncallableInstanceHeader] = asm_closure_header; /* Just use asm_boxed or have a special version for a value cell? */ asmtab[type_ValueCellHeader] = asm_boxed; - asmtab[type_SymbolHeader] = asm_boxed; + asmtab[type_SymbolHeader] = asm_symbol_header; asmtab[type_BaseChar] = asm_immediate; asmtab[type_Sap] = asm_sap; asmtab[type_InstanceHeader] = asm_boxed; @@ -966,6 +1212,9 @@ write_asm_object(const char *dir, int id, os_vm_address_t start, os_vm_address_t char asm_file[PATH_MAX]; FILE* f;
+ printf("write_asm_object space %d start %p end %p\n", + id, start, end); + snprintf(asm_file, PATH_MAX, "%s/space-%d.s", dir, id); f = fopen(asm_file, "w");
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/07991ccceb9f092900f7b55...