target.scm 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. ;;; Compilation targets
  2. ;; Copyright (C) 2011-2014,2017-2018 Free Software Foundation, Inc.
  3. ;; This library is free software; you can redistribute it and/or
  4. ;; modify it under the terms of the GNU Lesser General Public
  5. ;; License as published by the Free Software Foundation; either
  6. ;; version 3 of the License, or (at your option) any later version.
  7. ;;
  8. ;; This library is distributed in the hope that it will be useful,
  9. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. ;; Lesser General Public License for more details.
  12. ;;
  13. ;; You should have received a copy of the GNU Lesser General Public
  14. ;; License along with this library; if not, write to the Free Software
  15. ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  16. ;; 02110-1301 USA
  17. ;;; Code:
  18. (define-module (system base target)
  19. #:use-module (rnrs bytevectors)
  20. #:use-module (ice-9 regex)
  21. #:export (target-type with-target with-native-target
  22. target-cpu target-vendor target-os
  23. target-endianness target-word-size
  24. target-max-size-t
  25. target-max-size-t/scm
  26. target-max-vector-length
  27. target-most-negative-fixnum
  28. target-most-positive-fixnum
  29. target-fixnum?))
  30. ;;;
  31. ;;; Target types
  32. ;;;
  33. (define %native-word-size
  34. ((@ (system foreign) sizeof) '*))
  35. (define %target-type (make-fluid %host-type))
  36. (define %target-endianness (make-fluid (native-endianness)))
  37. (define %target-word-size (make-fluid %native-word-size))
  38. (define (validate-target target)
  39. (if (or (not (string? target))
  40. (let ((parts (string-split target #\-)))
  41. (or (< (length parts) 3)
  42. (let ((cpu (list-ref parts 0))
  43. (os (list-ref parts 2)))
  44. (or (string-null? cpu)
  45. ;; vendor (parts[1]) may be empty
  46. (string-null? os)
  47. ;; optional components (ABI) should be nonempty if
  48. ;; specified
  49. (or-map string-null? (list-tail parts 3)))))))
  50. (error "invalid target" target)))
  51. (define (with-target target thunk)
  52. (validate-target target)
  53. (let ((cpu (triplet-cpu target)))
  54. (with-fluids ((%target-type target)
  55. (%target-endianness (cpu-endianness cpu))
  56. (%target-word-size (triplet-pointer-size target)))
  57. (thunk))))
  58. (define (with-native-target thunk)
  59. (with-fluids ((%target-type %host-type)
  60. (%target-endianness (native-endianness))
  61. (%target-word-size %native-word-size))
  62. (thunk)))
  63. (define (cpu-endianness cpu)
  64. "Return the endianness for CPU."
  65. (if (string=? cpu (triplet-cpu %host-type))
  66. (native-endianness)
  67. (cond ((string-match "^i[0-9]86$" cpu)
  68. (endianness little))
  69. ((member cpu '("x86_64" "ia64"
  70. "powerpcle" "powerpc64le" "mipsel" "mips64el" "nios2" "sh3" "sh4" "alpha" "arc"))
  71. (endianness little))
  72. ((member cpu '("sparc" "sparc64" "powerpc" "powerpc64" "spu"
  73. "mips" "mips64" "m68k" "s390x"))
  74. (endianness big))
  75. ((string-match "^arm.*el" cpu)
  76. (endianness little))
  77. ((string-match "^arm.*eb" cpu)
  78. (endianness big))
  79. ((string-prefix? "arm" cpu) ;ARMs are LE by default
  80. (endianness little))
  81. ((string-match "^aarch64.*be" cpu)
  82. (endianness big))
  83. ((string=? "aarch64" cpu)
  84. (endianness little))
  85. ((string-match "riscv[1-9][0-9]*" cpu)
  86. (endianness little))
  87. ((string-match "loongarch[1-9][0-9]*" cpu)
  88. (endianness little))
  89. (else
  90. (error "unknown CPU endianness" cpu)))))
  91. (define (triplet-pointer-size triplet)
  92. "Return the size of pointers in bytes for TRIPLET."
  93. (let ((cpu (triplet-cpu triplet)))
  94. (cond ((and (string=? cpu (triplet-cpu %host-type))
  95. (string=? (triplet-os triplet) (triplet-os %host-type)))
  96. %native-word-size)
  97. ((string-match "^i[0-9]86$" cpu) 4)
  98. ;; Although GNU config.guess doesn't yet recognize them,
  99. ;; Debian (ab)uses the OS part to denote the specific ABI
  100. ;; being used: <http://wiki.debian.org/Multiarch/Tuples>.
  101. ;; See <http://www.linux-mips.org/wiki/WhatsWrongWithO32N32N64>
  102. ;; for details on the MIPS ABIs.
  103. ((string-match "^mips64.*-gnuabi64" triplet) 8) ; n64 ABI
  104. ((string-match "^mips64" cpu) 4) ; n32 or o32
  105. ((string-match "^x86_64-.*-gnux32" triplet) 4) ; x32
  106. ((string-match "32$" cpu) 4)
  107. ((string-match "64$" cpu) 8)
  108. ((string-match "64_?[lbe][lbe]$" cpu) 8)
  109. ((member cpu '("sparc" "powerpc" "mips" "mipsel" "nios2" "m68k" "sh3" "sh4" "arc")) 4)
  110. ((member cpu '("s390x" "alpha")) 8)
  111. ((string-match "^arm.*" cpu) 4)
  112. (else (error "unknown CPU word size" cpu)))))
  113. (define (triplet-cpu t)
  114. (substring t 0 (string-index t #\-)))
  115. (define (triplet-vendor t)
  116. (let ((start (1+ (string-index t #\-))))
  117. (substring t start (string-index t #\- start))))
  118. (define (triplet-os t)
  119. (let ((start (1+ (string-index t #\- (1+ (string-index t #\-))))))
  120. (substring t start)))
  121. (define (target-type)
  122. "Return the GNU configuration triplet of the target platform."
  123. (fluid-ref %target-type))
  124. (define (target-cpu)
  125. "Return the CPU name of the target platform."
  126. (triplet-cpu (target-type)))
  127. (define (target-vendor)
  128. "Return the vendor name of the target platform."
  129. (triplet-vendor (target-type)))
  130. (define (target-os)
  131. "Return the operating system name of the target platform."
  132. (triplet-os (target-type)))
  133. (define (target-endianness)
  134. "Return the endianness object of the target platform."
  135. (fluid-ref %target-endianness))
  136. (define (target-word-size)
  137. "Return the word size, in bytes, of the target platform."
  138. (fluid-ref %target-word-size))
  139. (define (target-max-size-t)
  140. "Return the maximum size_t value of the target platform, in bytes."
  141. ;; Apply the currently-universal restriction of a maximum 48-bit
  142. ;; address space.
  143. (1- (ash 1 (min (* (target-word-size) 8) 48))))
  144. (define (target-max-size-t/scm)
  145. "Return the maximum size_t value of the target platform, in units of
  146. SCM words."
  147. ;; Apply the currently-universal restriction of a maximum 48-bit
  148. ;; address space.
  149. (/ (target-max-size-t) (target-word-size)))
  150. (define (target-max-vector-length)
  151. "Return the maximum vector length of the target platform, in units of
  152. SCM words."
  153. ;; Vector size fits in first word; the low 8 bits are taken by the
  154. ;; type tag. Additionally, restrict to 48-bit address space.
  155. (1- (ash 1 (min (- (* (target-word-size) 8) 8) 48))))
  156. (define (target-most-negative-fixnum)
  157. "Return the most negative integer representable as a fixnum on the
  158. target platform."
  159. (- (ash 1 (- (* (target-word-size) 8) 3))))
  160. (define (target-most-positive-fixnum)
  161. "Return the most positive integer representable as a fixnum on the
  162. target platform."
  163. (1- (ash 1 (- (* (target-word-size) 8) 3))))
  164. (define (target-fixnum? n)
  165. (and (exact-integer? n)
  166. (<= (target-most-negative-fixnum)
  167. n
  168. (target-most-positive-fixnum))))