Raymond Toy pushed to branch issue-355-solaris-x86-fp-trap-handler at cmucl / cmucl
Commits: 83899880 by Carl Shapiro at 2024-08-29T23:32:31-07:00 Remove the call to malloc and strdup from obj_run_linker
- - - - - 5f6bce01 by Carl Shapiro at 2024-08-30T17:07:11+00:00 Merge branch 'obj-run-linker-no-malloc-or-strdup' into 'master'
Remove the call to malloc and strdup from obj_run_linker
Closes #309
See merge request cmucl/cmucl!251 - - - - - 706eb21f by Raymond Toy at 2024-09-01T08:30:51-07:00 Fix #356: Put x87 status word in low 16 bits of mode
`x87-floating-point-modes` combines the FPU status word and control word into a single 32-bit value. Currently the control word is in the low 16-bits and the status word is in the high 16 bits. The status word contains the flags to show if an exception has occurred.
However, the SSE2 mscsr register has the exception flags in the low part of the register.
For consistency, put the status word in the low 16-bits of the result to match more closely what SSE2 does. This simplifies debugging when looking at the the x87 and sse2 modes independently.
- - - - - ab7cfc59 by Raymond Toy at 2024-09-03T06:21:12-07:00 Clean up indentation; add a few comments.
- - - - - c0f457a2 by Raymond Toy at 2024-09-03T07:22:59-07:00 Oops. Fix the comments for the x87 mode vops
The comments for the x87 mode getter and setter vops had incorrect comments. The low 16-bits have the status word.
- - - - - f0bd9f3e by Raymond Toy at 2024-09-04T07:54:26-07:00 Merge branch 'issue-356-x87-status-word-in-low-part' into issue-355-solaris-x86-fp-trap-handler
- - - - -
3 changed files:
- src/code/float-trap.lisp - src/compiler/x86/float-sse2.lisp - src/lisp/elf.c
Changes:
===================================== src/code/float-trap.lisp ===================================== @@ -102,9 +102,11 @@ ;; FPU and only use the SSE2 rounding control bits. (let* ((x87-modes (vm::x87-floating-point-modes)) (sse-modes (vm::sse2-floating-point-modes)) + (x87-exceptions (logand #x3f x87-modes)) + (x87-enables (logand #x3f (ash x87-modes -16))) (final-mode (logior sse-modes - (ash (logand #x3f x87-modes) 7) ; control - (logand #x3f (ash x87-modes -16))))) + x87-exceptions + (ash x87-enables 7))))
final-mode)) (defun (setf floating-point-modes) (new-mode) @@ -112,15 +114,17 @@ ;; Set the floating point modes for both X87 and SSE2. This ;; include the rounding control bits. (let* ((rc (ldb float-rounding-mode new-mode)) + (new-exceptions (logand #x3f new-mode)) + (new-enables (logand #x3f (ash new-mode -7))) (x87-modes - (logior (ash (logand #x3f new-mode) 16) + (logior new-exceptions (ash rc 10) - (logand #x3f (ash new-mode -7)) + (ash new-enables 16) ;; Set precision control to be 64-bit, always. We ;; don't use the x87 registers with sse2, so this ;; is ok and would be the correct setting if we ;; ever support long-floats. - (ash 3 8)))) + (ash 3 (+ 8 16))))) (setf (vm::sse2-floating-point-modes) (ldb (byte 24 0) new-mode)) (setf (vm::x87-floating-point-modes) (ldb (byte 24 0) x87-modes))) new-mode)
===================================== src/compiler/x86/float-sse2.lisp ===================================== @@ -1380,7 +1380,7 @@ float-modes)
;; Extract the control and status words from the FPU. The low 16 bits -;; contain the control word, and the high 16 bits contain the status. +;; contain the status word, and the high 16 bits contain the control. (define-vop (x87-floating-point-modes) (:results (res :scs (unsigned-reg))) (:result-types unsigned-num) @@ -1396,12 +1396,15 @@ (inst byte #x66) ; operand size prefix (inst or sw-reg cw-stack) (inst xor sw-reg #x3f) ; invert exception mask - (move res sw-reg))) + (move res sw-reg) + ;; Put status word in the low 16 bits and the control word in the + ;; high 16 bits. + (inst rol res 16)))
;; Set the control and status words from the FPU. The low 16 bits -;; contain the control word, and the high 16 bits contain the status. +;; contain the status word, and the high 16 bits contain the control. (define-vop (x87-set-floating-point-modes) - (:args (new :scs (unsigned-reg) :to :result :target res)) + (:args (new-modes :scs (unsigned-reg) :to :result :target res)) (:results (res :scs (unsigned-reg))) (:arg-types unsigned-num) (:result-types unsigned-num) @@ -1410,7 +1413,12 @@ (:temporary (:sc unsigned-stack) cw-stack) (:temporary (:sc byte-reg :offset al-offset) sw-reg) (:temporary (:sc unsigned-reg :offset ecx-offset) old) + (:temporary (:sc unsigned-reg) new) (:generator 6 + (move new new-modes) + ;; Put the status word in the high 16 bits and the control word in + ;; the low 16 bits. + (inst rol new 16) (inst mov cw-stack new) (inst xor cw-stack #x3f) ; invert exception mask (inst fnstsw) @@ -1425,7 +1433,7 @@ (inst fldenv (make-ea :dword :base esp-tn)) (inst add esp-tn 28) DONE - (move res new))) + (move res new-modes)))
(defun sse2-floating-point-modes ()
===================================== src/lisp/elf.c ===================================== @@ -11,11 +11,11 @@ $Id: elf.c,v 1.32 2010/12/23 03:20:27 rtoy Exp $ */
+#include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> -#include <sys/stat.h> #include <sys/types.h> #include <unistd.h>
@@ -319,59 +319,65 @@ write_space_object(const char *dir, int id, os_vm_address_t start, os_vm_address return ret; }
+#ifdef UNICODE +#define LISPCHAR unsigned short +#else +#define LISPCHAR char +#endif + +static LISPCHAR * +tokenize(LISPCHAR *str, LISPCHAR **end) +{ + LISPCHAR *ptr; + + ptr = str; +again: + while (*ptr != '\0' && *ptr != ':') + ptr++; + if (str == ptr && *ptr == ':') { + str = ++ptr; + goto again; + } + *end = ptr; + return str; +} + int obj_run_linker(long init_func_address, char *file) { lispobj libstring = SymbolValue(CMUCL_LIB); /* Get library: */ struct vector *vec = (struct vector *)PTR(libstring); - char *paths; - char command[FILENAME_MAX + 1]; - char command_line[FILENAME_MAX + FILENAME_MAX + 10]; - char *strptr; - struct stat st; + char command[PATH_MAX]; + char command_line[PATH_MAX * 2 + 10]; + LISPCHAR *strptr, *end = (LISPCHAR *)vec->data; int ret; extern int debug_lisp_search; -#ifndef UNICODE - paths = strdup((char *)vec->data); - if (paths == NULL) { - perror("strdup"); - return -1; - } -#else - /* - * What should we do here with 16-bit characters? For now we just - * take the low 8-bits. - */ - paths = malloc(vec->length); - if (paths == NULL) { - perror("malloc"); - return -1; - } else { - int k; - unsigned short *data; - data = (unsigned short*) vec->data; - - for (k = 0; k < vec->length; ++k) { - paths[k] = data[k] & 0xff; - } - } -#endif - strptr = strtok(paths, ":");
if (debug_lisp_search) { printf("Searching for linker.sh script\n"); }
- while(strptr != NULL) { - - sprintf(command, "%s/%s", strptr, LINKER_SCRIPT); + while ((strptr = tokenize(end, &end)) != end) { + ptrdiff_t len = end - strptr; + ptrdiff_t i; + + if (len + strlen("/" LINKER_SCRIPT) > PATH_MAX) + continue; + + /* + * What should we do here with 16-bit characters? For now we just + * take the low 8-bits. + */ + for (i = 0; i < len; i++) + command[i] = strptr[i] & 0xFF; + command[i] = '\0'; + strcat(command, "/" LINKER_SCRIPT);
if (debug_lisp_search) { printf(" %s\n", command); }
- if (stat(command, &st) == 0) { - free(paths); + if (access(command, F_OK) == 0) { printf("\t[%s: linking %s... \n", command, file); fflush(stdout); #if defined(__linux__) || defined(__FreeBSD__) || defined(SOLARIS) || defined(__NetBSD__) @@ -394,15 +400,14 @@ obj_run_linker(long init_func_address, char *file) } return ret; } - strptr = strtok(NULL, ":"); }
fprintf(stderr, "Can't find %s script in CMUCL library directory list.\n", LINKER_SCRIPT); - free(paths); return -1; }
+#undef LISPCHAR
/* Read the ELF header from a file descriptor and stuff it into a structure. Make sure it is really an elf header etc. */
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/959faae166c9f9df7bf448f...