great work by cinap! thankfully, many of the 64-bit woes of gs weren't that deep (just very difficult to find.) the usual structure padding, &c issues caused by not carefully marshalling. the usual cavets about #pragma pack and non-amd64 arches apply. Reference: /n/atom/patch/applied/gs64bit Date: Mon May 5 18:13:27 CES 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/gs/src/ttfsfnt.h Mon May 5 18:10:20 2014 +++ /sys/src/cmd/gs/src/ttfsfnt.h Mon May 5 18:10:20 2014 @@ -47,6 +47,8 @@ typedef int32_t F26Dot6; /* 26.6 32-bit signed fixed-point number */ #endif +#pragma pack on + typedef struct { uint32 bc; uint32 ad; @@ -348,5 +350,7 @@ } FontTableInfo; #define RAW_TRUE_TYPE_SIZE 512 + +#pragma pack off #endif --- /sys/src/cmd/gs/src/ttinterp.c Mon May 5 18:10:20 2014 +++ /sys/src/cmd/gs/src/ttinterp.c Mon May 5 18:10:20 2014 @@ -166,7 +166,7 @@ #endif -#define INS_ARG EXEC_OPS PStorage args /* see ttexec.h */ +#define INS_ARG EXEC_OPS PLong args /* see ttexec.h */ #define SKIP_Code() SkipCode( EXEC_ARG ) --- /sys/src/cmd/gs/src/ttobjs.h Mon May 5 18:10:20 2014 +++ /sys/src/cmd/gs/src/ttobjs.h Mon May 5 18:10:20 2014 @@ -589,7 +589,7 @@ PLong cvt; Int storeSize; /* The storage area is now part of the */ - PStorage storage; /* instance */ + PLong storage; /* instance */ }; @@ -638,11 +638,11 @@ /* useful for the debugger */ Int storeSize; /* size of current storage */ - PStorage storage; /* storage area */ + PLong storage; /* storage area */ Int stackSize; /* size of exec. stack */ Int top; /* top of exec. stack */ - PStorage stack; /* current exec. stack */ + PLong stack; /* current exec. stack */ Int args, new_top; /* new top after exec. */ --- /sys/src/cmd/gs/src/tttables.h Mon May 5 18:10:20 2014 +++ /sys/src/cmd/gs/src/tttables.h Mon May 5 18:10:20 2014 @@ -191,7 +191,7 @@ struct _TLoca { UShort Size; - PStorage Table; + PLong Table; }; typedef struct _TLoca TLoca; --- /sys/src/cmd/gs/src/tttypes.h Mon May 5 18:10:20 2014 +++ /sys/src/cmd/gs/src/tttypes.h Mon May 5 18:10:20 2014 @@ -117,21 +117,6 @@ #define NULL (void*)0 #endif -#ifdef Plan9 -#ifdef Tamd64 - typedef unsigned long long* PStorage; -#else - typedef unsigned int* PStorage; -#endif -#elif ARCH_SIZEOF_PTR == SIZEOF_LONG - typedef long* PStorage; -#elif ARCH_SIZEOF_PTR == SIZEOF_INT - typedef int* PStorage; -#else -#error "Size of pointer type is not equal to either long or int" -#endif - - /* Rounding mode constants */ #define TT_Round_Off 5 --- /sys/src/cmd/gs/src/gdevpsft.c Mon May 5 18:10:20 2014 +++ /sys/src/cmd/gs/src/gdevpsft.c Mon May 5 18:10:20 2014 @@ -393,34 +393,6 @@ /* ------ hmtx/vmtx ------ */ -/* - * avoid fp exceptions storing large doubles into integers by limiting - * the range of the results. these are band-aids that don't fix the - * root cause of the out-of-range results, but they keep gs on the rails. - */ - -ushort -limdbl2ushort(double d) -{ - if (d < 0) - return 0; - else if (d > 64000) - return 64000; - else - return d; -} - -long -limdbl2long(double d) -{ - if (d > 2e9) - return 2e9; - else if (d < -2e9) - return -2e9; - else - return d; -} - private void write_mtx(stream *s, gs_font_type42 *pfont, const gs_type42_mtx_t *pmtx, int wmode) @@ -434,12 +406,12 @@ sbw[0] = sbw[1] = sbw[2] = sbw[3] = 0; /* in case of failures */ for (i = 0; i < pmtx->numMetrics; ++i) { DISCARD(pfont->data.get_metrics(pfont, i, wmode, sbw)); - put_ushort(s, limdbl2ushort(sbw[wmode + 2] * factor)); /* width */ - put_ushort(s, limdbl2ushort(sbw[wmode] * factor)); /* lsb, may be <0 */ + put_ushort(s, (ushort)(sbw[wmode + 2] * factor)); /* width */ + put_ushort(s, (ushort)(sbw[wmode] * factor)); /* lsb, may be <0 */ } for (; len < pmtx->length; ++i, len += 2) { DISCARD(pfont->data.get_metrics(pfont, i, wmode, sbw)); - put_ushort(s, limdbl2ushort(sbw[wmode] * factor)); /* lsb, may be <0 */ + put_ushort(s, (ushort)(sbw[wmode] * factor)); /* lsb, may be <0 */ } } @@ -448,24 +420,19 @@ size_mtx(gs_font_type42 *pfont, gs_type42_mtx_t *pmtx, uint max_glyph, int wmode) { - int prev_width = min_int, wmode2; + int prev_width = min_int; uint last_width = 0; /* pacify compilers */ double factor = pfont->data.unitsPerEm * (wmode ? -1 : 1); - uint i, j; + uint i; for (i = 0; i <= max_glyph; ++i) { float sbw[4]; - int code, width; + int code = pfont->data.get_metrics(pfont, i, wmode, sbw); + int width; - for (j = 0; j < 4; j++) - sbw[j] = 0; - code = pfont->data.get_metrics(pfont, i, wmode, sbw); if (code < 0) continue; - wmode2 = wmode + 2; - if (wmode2 < 0 || wmode2 >= 4) - abort(); /* "wmode2 out of range" */ - width = limdbl2long(sbw[wmode2] * factor + 0.5); + width = (int)(sbw[wmode + 2] * factor + 0.5); if (width != prev_width) prev_width = width, last_width = i; } --- /sys/src/cmd/gs/src/zcrd.c Mon May 5 18:10:20 2014 +++ /sys/src/cmd/gs/src/zcrd.c Mon May 5 18:10:20 2014 @@ -361,8 +361,6 @@ space = r_space(&pqr_procs); for (i = 0; i < 3; i++) { ref *p = pqr_procs.value.refs + 3 + (4 + 4 * 6) * i; - const float *ppt = (float *)&pjc->points_sd; - int j; make_array(pqr_procs.value.refs + i, a_readonly | a_executable | space, 4, p); @@ -370,9 +368,37 @@ p[1] = pcrprocs->TransformPQR.value.refs[i]; make_oper(p + 2, 0, cie_exec_tpqr); make_oper(p + 3, 0, cie_post_exec_tpqr); - for (j = 0, p += 4; j < 4 * 6; j++, p++, ppt++) - make_real(p, *ppt); - } + p += 4; + + /* cant use array due to structure alignment */ + make_real(p, pjc->points_sd.ws.xyz.u); p++; + make_real(p, pjc->points_sd.ws.xyz.v); p++; + make_real(p, pjc->points_sd.ws.xyz.w); p++; + make_real(p, pjc->points_sd.ws.pqr.u); p++; + make_real(p, pjc->points_sd.ws.pqr.v); p++; + make_real(p, pjc->points_sd.ws.pqr.w); p++; + + make_real(p, pjc->points_sd.bs.xyz.u); p++; + make_real(p, pjc->points_sd.bs.xyz.v); p++; + make_real(p, pjc->points_sd.bs.xyz.w); p++; + make_real(p, pjc->points_sd.bs.pqr.u); p++; + make_real(p, pjc->points_sd.bs.pqr.v); p++; + make_real(p, pjc->points_sd.bs.pqr.w); p++; + + make_real(p, pjc->points_sd.wd.xyz.u); p++; + make_real(p, pjc->points_sd.wd.xyz.v); p++; + make_real(p, pjc->points_sd.wd.xyz.w); p++; + make_real(p, pjc->points_sd.wd.pqr.u); p++; + make_real(p, pjc->points_sd.wd.pqr.v); p++; + make_real(p, pjc->points_sd.wd.pqr.w); p++; + + make_real(p, pjc->points_sd.bd.xyz.u); p++; + make_real(p, pjc->points_sd.bd.xyz.v); p++; + make_real(p, pjc->points_sd.bd.xyz.w); p++; + make_real(p, pjc->points_sd.bd.pqr.u); p++; + make_real(p, pjc->points_sd.bd.pqr.v); p++; + make_real(p, pjc->points_sd.bd.pqr.w); p++; + } return cie_prepare_cache3(i_ctx_p, &pcrd->RangePQR, pqr_procs.value.const_refs, pjc->TransformPQR.caches,