Compare commits

..

5 commits

Author SHA1 Message Date
f54e064fda Make ASM-FUNCTION hold an address to be called 2025-07-03 16:53:00 +02:00
3b8c906d75 Store ASM-FUNCTIONs in a hash table keyed on name
TODO: Populate the table based on the asm source code declaration
comments and signal an error when a named function is missing.
2025-07-03 16:51:47 +02:00
094f01d258 Ensure IBLOCK names are unique 2025-07-03 15:59:41 +02:00
7171398c07 Fix broken IR graph flow with merge iblocks 2025-07-03 15:58:56 +02:00
235ca8c07e Rename EMIT-STORE-RESULT's parameter to match similar functions 2025-07-03 10:54:21 +02:00
5 changed files with 58 additions and 21 deletions

View file

@ -1,10 +1,16 @@
(in-package #:user-side-compiler)
;;; STUB, TODO
(defvar *asm-functions* (make-hash-table :test #'equalp))
(defclass asm-function ()
((%name :accessor name :initarg :name)))
((%name :accessor name :initarg :name)
(%address :accessor address :initarg :address
:initform #xFEC0)))
(define-transformation (token (token-name asm-function))
;; TODO: Choose from a list, don't just create like this
(make-instance 'asm-function :name (name token)))
(multiple-value-bind (asm-function existsp)
(gethash (name token) *asm-functions*)
(if existsp
asm-function
(setf (gethash (name token) *asm-functions*)
(make-instance 'asm-function :name (name token))))))

View file

@ -93,14 +93,14 @@
(define-normal-emitter emit-sta (error "STA has no immediate mode.") #x85 #x8d)
(define-normal-emitter emit-adc #x69 #x65 #x6d)
(defun emit-store-result (result)
(if (or (null (allocation-details result))
(member (strategy (allocation-details result))
(defun emit-store-data (data)
(if (or (null (allocation-details data))
(member (strategy (allocation-details data))
'(:constant :accumulator)))
(setf *last-instruction* '(:useless))
(progn
(emit-sta :address (data-reference result))
(setf *last-instruction* (list :store result)))))
(emit-sta :address (data-reference data))
(setf *last-instruction* (list :store data)))))
(defun emit-load-data (data)
(if (or (member (strategy (allocation-details data))

View file

@ -74,7 +74,7 @@
(then-iblock (make-instance 'iblock :name "then"))
(else-iblock (make-instance 'iblock :name "else"))
(continuation (if else-exists-p
(make-instance 'iblock :name "merge")
(make-instance 'iblock-merge :name "merge")
else-iblock)))
(build-insert-end (make-instance
'ir-if

View file

@ -40,19 +40,46 @@
;;; Compilation setup
(defun fix-iblock-flow (iblock)
(let ((reached '()))
(defun make-iblock-names-unique (start-iblock)
(let ((encountered '()))
(do-iblocks (iblock start-iblock)
(let ((existing (assoc (name iblock) encountered :test #'equalp)))
(if existing
(progn
(setf (name iblock)
(format nil "~A_~A" (name iblock) (incf (cdr existing)))))
(progn
(push (cons (copy-seq (name iblock)) 1) encountered)
(setf (name iblock)
(format nil "~A_1" (name iblock)))))))))
(defun fix-iblock-flow (start-iblock)
(let ((reached '())
(last nil)
(deferred '()))
(labels
((fix (iblock prev)
((fix-deferred ()
(unless (null deferred)
(loop :for after :in (nreverse (pop deferred))
:do (fix after last))))
(fix (iblock prev)
(unless (member iblock reached)
(push iblock reached)
(setf (next iblock)
(first (successors iblock))
(prev iblock) prev)
(loop :for prev := iblock :then s
:for s :in (successors iblock)
:do (fix s prev)))))
(fix iblock nil))))
(unless (null prev)
(setf (next prev) iblock))
(setf (prev iblock) prev
last iblock)
(fix-deferred)
(push '() deferred)
(loop :for s :in (successors iblock)
:if (typep s 'iblock-merge)
:do (pushnew s (car deferred))
:else
:do (fix s last))
(when (null prev)
(loop :until (null deferred)
:do (fix-deferred))))))
(fix start-iblock nil))))
(defmacro with-compilation-setup ((iblock builder &key add-return-p) &body body)
`(let ((,iblock (make-instance 'iblock :name "toplevel" :program (make-instance 'ir-program)))
@ -63,7 +90,9 @@
,@body)
(when ,add-return-p
(build-insert-end (make-instance 'ir-return) ,builder))
(fix-iblock-flow ,iblock))))
(fix-iblock-flow ,iblock)
(unless (null (next ,iblock))
(make-iblock-names-unique (next ,iblock))))))
;;; Some quick example code

View file

@ -12,6 +12,8 @@
(%prev :accessor prev :type (or null iblock) :initform nil)
(%name :accessor name :initarg :name :initform nil)))
(defclass iblock-merge (iblock) ())
(defmethod find-variable (reference (search-from ir-program))
(multiple-value-bind (var existsp)
(gethash reference (variables search-from))