primop.scm 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. ;;; Ported from Scheme 48 1.9. See file COPYING for notices and license.
  2. ;;;
  3. ;;; Port Author: Andrew Whatson
  4. ;;;
  5. ;;; Original Authors: Richard Kelsey
  6. ;;;
  7. ;;; scheme48-1.9.2/ps-compiler/node/primop.scm
  8. ;;;
  9. ;;; The information about a primitive operation.
  10. (define-module (ps-compiler node primop)
  11. #:use-module (prescheme s48-defrecord)
  12. #:use-module (prescheme record-discloser)
  13. #:use-module (prescheme syntax-utils)
  14. #:use-module (ps-compiler node arch)
  15. #:use-module (ps-compiler node node)
  16. #:use-module (ps-compiler util syntax)
  17. #:use-module (ps-compiler util util)
  18. #:export (primop? make-primop make-proc-primop make-conditional-primop
  19. all-primops get-primop
  20. primop-id primop-trivial? primop-side-effects
  21. primop-cost
  22. simplify-call
  23. primop-procedure? primop-call-index
  24. primop-conditional?
  25. expand-to-conditional
  26. simplify-conditional?
  27. primop-code-data set-primop-code-data!
  28. trivial-call-return-type
  29. loc/owner loc/type loc/rep
  30. set/owner set/type set/rep set/value))
  31. (define-record-type primop
  32. (id ;; Symbol identifying this primop
  33. trivial? ;; #t if this primop has does not require a continuation
  34. side-effects ;; side-effects of this primop
  35. simplify-call-proc ;; Simplify method
  36. primop-cost-proc ;; Cost of executing this operation
  37. ;; (in some undisclosed metric)
  38. return-type-proc ;; Give the return type (for trivial primops only)
  39. proc-data ;; Record containing more data for the procedure primops
  40. cond-data ;; Record containing more data for conditional primops
  41. )
  42. (code-data ;; Code generation data
  43. ))
  44. (define-record-discloser type/primop
  45. (lambda (primop)
  46. (list 'primop (object-hash primop) (primop-id primop))))
  47. (define all-primops (make-vector primop-enum-count))
  48. (define (make-primop id trivial? side-effects simplify cost type)
  49. (let ((enum (name->enumerand id primop-enum))
  50. (primop (primop-maker id trivial? side-effects simplify cost type #f #f)))
  51. (if enum
  52. (vector-set! all-primops enum primop))
  53. primop))
  54. (define (get-primop enum)
  55. (vector-ref all-primops enum))
  56. (define-syntax define-primop-method
  57. (lambda (x)
  58. (syntax-case x ()
  59. ((_ method (call args ...))
  60. (with-syntax ((getter (syntax-conc 'primop- #'method '-proc)))
  61. #'(define (method call args ...)
  62. ((getter (call-primop call)) call args ...)))))))
  63. (define-primop-method primop-cost (call))
  64. (define-primop-method simplify-call (call))
  65. (define (trivial-call-return-type call)
  66. ((primop-return-type-proc (call-primop call)) call))
  67. ;;-------------------------------------------------------------------------------
  68. ;; procedure primops
  69. (define-subrecord primop primop-proc-data primop-proc-data
  70. (call-index ;; index of argument being called
  71. )
  72. ())
  73. (define (primop-procedure? primop)
  74. (if (primop-proc-data primop) #t #f))
  75. ;; (call <cont> <proc-var> . <args>)
  76. ;; (tail-call <cont-var> <proc-var> . <args>)
  77. ;; (return <proc-var> . <args>)
  78. ;; (jump <proc-var> . <args>)
  79. ;; (throw <proc-var> . <args>)
  80. ;;
  81. ;; (unknown-call <cont> <proc-var> . <args>)
  82. ;; (unknown-tail-call <cont-var> <proc-var> . <args>)
  83. ;; (unknown-return <proc-var> . <args>)
  84. (define (make-proc-primop id side-effects simplify cost index)
  85. (let* ((enum (name->enumerand id primop-enum))
  86. (data (primop-proc-data-maker index))
  87. (primop (primop-maker id #f side-effects simplify cost #f data #f)))
  88. (vector-set! all-primops enum primop)
  89. primop))
  90. ;;-------------------------------------------------------------------------------
  91. ;; conditional primops
  92. (define-subrecord primop primop-cond-data primop-cond-data
  93. (expand-to-conditional-proc ;; Expand this call to a conditional
  94. simplify-conditional?-proc ;; Can this conditional be simplified
  95. )
  96. ())
  97. (define-primop-method expand-to-conditional (call))
  98. (define-primop-method simplify-conditional? (call index value))
  99. (define (primop-conditional? primop)
  100. (if (primop-cond-data primop) #t #f))
  101. (define (make-conditional-primop id side-effects simplify cost expand simplify?)
  102. (let* ((enum (name->enumerand id primop-enum))
  103. (data (primop-cond-data-maker expand simplify?))
  104. (primop (primop-maker id #f side-effects simplify cost #f #f data)))
  105. (if enum (vector-set! all-primops enum primop))
  106. primop))
  107. ;;-------------------------------------------------------------------------------
  108. ;; Random constants for location calls:
  109. ;;
  110. ;; ($CONTENTS <thing> <type> <offset> <rep>)
  111. ;; ($SET-CONTENTS <cont> <thing> <type> <offset> <rep> <value>)
  112. ;; 0 1 2 3 4
  113. (define loc/owner 0)
  114. (define loc/type 1)
  115. (define loc/rep 2)
  116. (define set/owner 1)
  117. (define set/type 2)
  118. (define set/rep 3)
  119. (define set/value 4)
  120. ;; For slots that do not contain code pointers:
  121. ;; ($CLOSURE <cont> <env> <slot>)
  122. ;; ($SET-CLOSURE <cont> <env> <slot> <value>)
  123. ;; For slots that do contain code pointers:
  124. ;; ($MAKE-PROCEDURE <cont> <env> <slot>)
  125. ;; ($SET-CODE <cont> <env> <slot> <value>)
  126. ;; For known calls to slots that contain code pointers:
  127. ;; ($ENV-ADJUST <cont> <env> <slot>)
  128. ;; 0 1 2
  129. (define env/owner 0)
  130. (define env/offset 1)
  131. (define env/value 2)