summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-04-11 16:39:21 -0400
committerbd <bdunahu@operationnull.com>2025-04-11 16:39:21 -0400
commit639098b1ea82be82bd18a4af415458fcbaf5e20b (patch)
treecaecdd1499d2e391cd5bd2dcde3aebfade002a09
parent5c9ac514d0556d875a12b2c7d3c4aedf23b9575b (diff)
Add RET and NOP j-type instructions
-rw-r--r--input/dominative-functions.asm5
-rw-r--r--src/parse.lisp11
-rw-r--r--src/util.lisp2
-rw-r--r--t/parse.lisp11
4 files changed, 18 insertions, 11 deletions
diff --git a/input/dominative-functions.asm b/input/dominative-functions.asm
index cb8564e..530717d 100644
--- a/input/dominative-functions.asm
+++ b/input/dominative-functions.asm
@@ -14,6 +14,7 @@ MAIN:
push $6
;; jal SUB23
+ pop $6
store $6 answer($0)
SUB23:
push $5 ; push old frame pointer
@@ -34,7 +35,7 @@ SUB23:
addi $2 $5 0x0 ; restore stack pointer
pop $5 ; restore frame pointer
- ;; ret
+ ret
ADD76:
push $5
addi $5 $2 0x0
@@ -51,4 +52,4 @@ ADD76:
addi $2 $5 0x0
pop $5
- ;; ret
+ ret
diff --git a/src/parse.lisp b/src/parse.lisp
index e58dea0..0ea6c0d 100644
--- a/src/parse.lisp
+++ b/src/parse.lisp
@@ -84,11 +84,12 @@
(generate-mnemonic 'i-type-2-m '("STOREV" "STORE"))
(generate-mnemonic 'j-type-1-m '("JMP" "JAL"))
(generate-mnemonic 'j-type-2-m '("PUSH" "POP"))
+(generate-mnemonic 'j-type-3-m '("RET" "NOP"))
;; we need to reverse to ensure rules like "ADDV" are matched before "ADD"
(generate-mnemonic 'r-type-3-m (reverse util:r-type))
(generate-mnemonic 'i-type-3-m (reverse util:i-type))
-(generate-mnemonic 'j-type-3-m (reverse util:j-type))
+(generate-mnemonic 'j-type-4-m (reverse util:j-type))
;; TODO this is pretty gross
(defmacro defrule-instr (name type-id order &rest destructure-pattern)
@@ -110,7 +111,7 @@ DESTRUCTURE-PATTERN is the list of non-terminals on the right side of the gramma
(defrule-instr r-type-2 'emit::r (0 1 2) register register)
(defrule-instr r-type-3 'emit::r (1 2 0) register register register)
(defrule-instr i-type-3 'emit::i (1 0 2) register register immediate)
-(defrule-instr j-type-3 'emit::j (1 0) label)
+(defrule-instr j-type-4 'emit::j (1 0) label)
(esrap:defrule i-type-1 (and i-type-1-m space register space dereference)
(:destructure (m w1 s w2 di)
@@ -132,8 +133,12 @@ DESTRUCTURE-PATTERN is the list of non-terminals on the right side of the gramma
(declare (ignore w))
`(emit::j ,m ,r 0)))
+(esrap:defrule j-type-3 j-type-3-m
+ (:lambda (m)
+ `(emit::j ,m (emit::rr 0) 0)))
+
(esrap:defrule instr (or r-type-1 r-type-2 r-type-3 i-type-1 i-type-2
- i-type-3 j-type-1 j-type-2 j-type-3))
+ i-type-3 j-type-1 j-type-2 j-type-3 j-type-4))
;;; defines rules to parse the .text segment
diff --git a/src/util.lisp b/src/util.lisp
index 8d98680..e52d7aa 100644
--- a/src/util.lisp
+++ b/src/util.lisp
@@ -76,5 +76,5 @@ of the elements from both lists. Returns nil if the lists are not equal size."
"I-type instructions.")
(defvar j-type
- '("JMP" "JRL" "JAL" "BEQ" "BGT" "BUF" "BOF" "PUSH" "POP")
+ '("JMP" "JRL" "JAL" "BEQ" "BGT" "BUF" "BOF" "PUSH" "POP" "RET" "NOP")
"J-type instructions.")
diff --git a/t/parse.lisp b/t/parse.lisp
index 7c084aa..2612f45 100644
--- a/t/parse.lisp
+++ b/t/parse.lisp
@@ -45,9 +45,10 @@
(emit::x
(emit::j "JMP" (emit::rr 3) 3)
(emit::j "JRL" (emit::rr 0) (emit::l "FOO" 8))
+ (emit::j "RET" (emit::rr 0) 0)
(emit::j "PUSH" (emit::rr 5) 0)))
(esrap:parse 'parse:str->ast (format nil ".DATA~%.TEXT~%~tJMP 3($3)
-~tJRL FOO~%~tPUSH $5~%")))))
+~tJRL FOO~%~tRET~%~tPUSH $5~%")))))
(test esrap-instr-type-i-negative
(is (equal
@@ -73,7 +74,7 @@
(emit::d)
(emit::x
(emit::j "JMP" (emit::rr 3) 3)
- (emit::j "JRL" (emit::rr 0) (emit::l "FOO" 14))
+ (emit::j "JRL" (emit::rr 0) (emit::l "FOO" 15))
(emit::j "PUSH" (emit::rr 5) 0)))
(esrap:parse 'parse:str->ast (format nil ".DATA~%~%.TEXT~t~%JMP 3($3)~t
JRL FOO~t~%PUSH $5~%")))))
@@ -84,7 +85,7 @@ JRL FOO~t~%PUSH $5~%")))))
(emit::d)
(emit::x
(emit::j "JMP" (emit::rr 3) 3)
- (emit::j "JRL" (emit::rr 0) (emit::l "FOO" 17))
+ (emit::j "JRL" (emit::rr 0) (emit::l "FOO" 18))
(emit::j "PUSH" (emit::rr 5) 0)))
(esrap:parse 'parse:str->ast (format nil ".DATA~%.TEXT;; dot dot dot
~tJMP 3($3) ;; this does things
@@ -143,11 +144,11 @@ H 3 5~%.TEXT~%")))))
(emit::i "ADDI" (emit::rr 0) (emit::rr 5) (emit::var "S"))
(emit::i "ADDI" (emit::rr 0) (emit::rr 10) (emit::var "ARR"))
(emit::i "ADDI" (emit::rr 0) (emit::rr 6) (emit::var "I"))
- (emit::j "JRL" (emit::rr 0) (emit::l "CMP" 23))
+ (emit::j "JRL" (emit::rr 0) (emit::l "CMP" 24))
(emit::r "ADD" (emit::rr 10) (emit::rr 6) (emit::rr 9))
(emit::i "ADDI" (emit::rr 6) (emit::rr 6) 1)
(emit::r "CMP" (emit::rr 6) (emit::rr 5) (emit::rr 0))
- (emit::j "BGT" (emit::rr 0) (emit::l "L" 27))))
+ (emit::j "BGT" (emit::rr 0) (emit::l "L" 28))))
(esrap:parse 'parse:str->ast (format nil "
.DATA
ARR 1 2 3 4