Put MIPS instruction set in its own package.
[sbcl.git] / src / compiler / mips / insts.lisp
bloba8defffd38663f7488c1c9c56f201574fe0c61a4
1 ;;; the instruction set definition for MIPS
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5 ;;;;
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
12 (in-package "SB!MIPS-ASM")
14 (eval-when (:compile-toplevel :load-toplevel :execute)
15 ;; Imports from this package into SB-VM
16 (import '(reg-tn-encoding) 'sb!vm)
17 ;; Imports from SB-VM into this package
18 (import '(;; SBs, SCs, and TNs
19 sb!vm::immediate-constant
20 sb!vm::registers sb!vm::float-registers
21 sb!vm::zero
22 sb!vm::lip-tn sb!vm::zero-tn)))
24 (setf *assem-scheduler-p* t)
25 (setf *assem-max-locations* 68)
27 ;;;; Constants, types, conversion functions, some disassembler stuff.
29 (defun reg-tn-encoding (tn)
30 (declare (type tn tn))
31 (sc-case tn
32 (zero sb!vm::zero-offset)
33 (null sb!vm::null-offset)
35 (if (eq (sb-name (sc-sb (tn-sc tn))) 'registers)
36 (tn-offset tn)
37 (error "~S isn't a register." tn)))))
39 (defun fp-reg-tn-encoding (tn)
40 (declare (type tn tn))
41 (unless (eq (sb-name (sc-sb (tn-sc tn))) 'float-registers)
42 (error "~S isn't a floating-point register." tn))
43 (tn-offset tn))
45 ;;;(sb!disassem:set-disassem-params :instruction-alignment 32)
47 (defvar *disassem-use-lisp-reg-names* t)
49 (defun location-number (loc)
50 (etypecase loc
51 (null)
52 (number)
53 (label)
54 (fixup)
55 (tn
56 (ecase (sb-name (sc-sb (tn-sc loc)))
57 (immediate-constant
58 ;; Can happen if $ZERO or $NULL are passed in.
59 nil)
60 (registers
61 (unless (zerop (tn-offset loc))
62 (tn-offset loc)))
63 (float-registers
64 (+ (tn-offset loc) 32))))
65 (symbol
66 (ecase loc
67 (:memory 0)
68 (:hi-reg 64)
69 (:low-reg 65)
70 (:float-status 66)
71 (:ctrl-stat-reg 67)))))
73 (defparameter *reg-symbols*
74 (map 'vector
75 (lambda (name)
76 (and name
77 (make-symbol (concatenate 'string "$" name))))
78 sb!vm::*register-names*))
80 (define-arg-type reg
81 :printer #'(lambda (value stream dstate)
82 (declare (stream stream) (fixnum value))
83 (let ((regname (aref *reg-symbols* value)))
84 (princ regname stream)
85 (maybe-note-associated-storage-ref
86 value 'registers regname dstate))))
88 (define-arg-type load-store-annotation
89 :printer (lambda (value stream dstate)
90 (declare (ignore stream))
91 (destructuring-bind (reg offset) value
92 (when (= reg sb!vm::code-offset)
93 (note-code-constant offset dstate)))))
95 (defparameter *float-reg-symbols*
96 (coerce
97 (loop for n from 0 to 31 collect (make-symbol (format nil "$F~d" n)))
98 'vector))
100 (define-arg-type fp-reg
101 :printer #'(lambda (value stream dstate)
102 (declare (stream stream) (fixnum value))
103 (let ((regname (aref *float-reg-symbols* value)))
104 (princ regname stream)
105 (maybe-note-associated-storage-ref
106 value 'float-registers regname dstate))))
108 (define-arg-type control-reg :printer "(CR:#x~X)")
110 (define-arg-type relative-label
111 :sign-extend t
112 :use-label #'(lambda (value dstate)
113 (declare (type (signed-byte 16) value)
114 (type disassem-state dstate))
115 (+ (ash (1+ value) 2) (dstate-cur-addr dstate))))
117 (deftype float-format ()
118 '(member :s :single :d :double :w :word))
120 (defun float-format-value (format)
121 (ecase format
122 ((:s :single) 0)
123 ((:d :double) 1)
124 ((:w :word) 4)))
126 (define-arg-type float-format
127 :printer #'(lambda (value stream dstate)
128 (declare (ignore dstate)
129 (stream stream)
130 (fixnum value))
131 (princ (case value
132 (0 's)
133 (1 'd)
134 (4 'w)
135 (t '?))
136 stream)))
138 (defconstant-eqx compare-kinds
139 '(:f :un :eq :ueq :olt :ult :ole :ule :sf :ngle :seq :ngl :lt :nge :le :ngt)
140 #'equalp)
142 (defconstant-eqx compare-kinds-vec
143 (apply #'vector compare-kinds)
144 #'equalp)
146 (deftype compare-kind ()
147 `(member ,@compare-kinds))
149 (defun compare-kind (kind)
150 (or (position kind compare-kinds)
151 (error "Unknown floating point compare kind: ~S~%Must be one of: ~S"
152 kind
153 compare-kinds)))
155 (define-arg-type compare-kind :printer compare-kinds-vec)
157 (defconstant-eqx float-operations '(+ - * /) #'equalp)
159 (deftype float-operation ()
160 `(member ,@float-operations))
162 (defconstant-eqx float-operation-names
163 ;; this gets used for output only
164 #(add sub mul div)
165 #'equalp)
167 (defun float-operation (op)
168 (or (position op float-operations)
169 (error "Unknown floating point operation: ~S~%Must be one of: ~S"
171 float-operations)))
173 (define-arg-type float-operation :printer float-operation-names)
177 ;;;; Constants used by instruction emitters.
179 (def!constant special-op #b000000)
180 (def!constant bcond-op #b000001)
181 (def!constant cop0-op #b010000)
182 (def!constant cop1-op #b010001)
183 (def!constant cop2-op #b010010)
184 (def!constant cop3-op #b010011)
188 ;;;; dissassem:define-instruction-formats
190 (defconstant-eqx immed-printer
191 '(:name :tab rt (:unless (:same-as rt) ", " rs) ", " immediate)
192 #'equalp)
194 ;;; for things that use rt=0 as a nop
195 (defconstant-eqx immed-zero-printer
196 '(:name :tab rt (:unless (:constant 0) ", " rs) ", " immediate)
197 #'equalp)
199 (define-instruction-format (immediate 32 :default-printer immed-printer)
200 (op :field (byte 6 26))
201 (rs :field (byte 5 21) :type 'reg)
202 (rt :field (byte 5 16) :type 'reg)
203 (immediate :field (byte 16 0) :sign-extend t))
205 (defconstant-eqx load-store-printer
206 '(:name :tab
207 rt ", "
209 (:unless (:constant 0) "[" immediate "]"))
210 #'equalp)
212 (define-instruction-format
213 (load-store 32 :default-printer '(:name :tab
214 rt ", "
216 (:unless (:constant 0) "[" immediate "]")
217 load-store-annotation)
218 :include immediate)
219 (load-store-annotation :fields (list (byte 5 21) (byte 16 0))
220 :type 'load-store-annotation))
222 (eval-when (:compile-toplevel :load-toplevel :execute)
223 (defparameter jump-printer
224 #'(lambda (value stream dstate)
225 (let ((addr (ash value 2)))
226 (maybe-note-assembler-routine addr t dstate)
227 (write addr :base 16 :radix t :stream stream)))))
229 (define-instruction-format (jump 32 :default-printer '(:name :tab target))
230 (op :field (byte 6 26))
231 (target :field (byte 26 0) :printer jump-printer))
233 (defconstant-eqx reg-printer
234 '(:name :tab rd (:unless (:same-as rd) ", " rs) ", " rt)
235 #'equalp)
237 (define-instruction-format(register 32 :default-printer reg-printer)
238 (op :field (byte 6 26))
239 (rs :field (byte 5 21) :type 'reg)
240 (rt :field (byte 5 16) :type 'reg)
241 (rd :field (byte 5 11) :type 'reg)
242 (shamt :field (byte 5 6) :value 0)
243 (funct :field (byte 6 0)))
245 (define-instruction-format
246 (break 32 :default-printer
247 '(:name :tab code (:unless (:constant 0) ", " subcode)))
248 (op :field (byte 6 26) :value special-op)
249 (code :field (byte 10 16) :reader break-code)
250 (subcode :field (byte 10 6) :reader break-subcode)
251 (funct :field (byte 6 0) :value #b001101))
253 (define-instruction-format
254 (coproc-branch 32 :default-printer '(:name :tab offset))
255 (op :field (byte 6 26))
256 (funct :field (byte 10 16))
257 (offset :field (byte 16 0)))
259 (defconstant-eqx float-fmt-printer
260 '((:unless :constant funct)
261 (:choose (:unless :constant sub-funct) nil)
262 "." format)
263 #'equalp)
265 (defconstant-eqx float-printer
266 `(:name ,@float-fmt-printer
267 :tab
269 (:unless (:same-as fd) ", " fs)
270 ", " ft)
271 #'equalp)
273 (define-instruction-format (float 32 :default-printer float-printer)
274 (op :field (byte 6 26) :value cop1-op)
275 (filler :field (byte 1 25) :value 1)
276 (format :field (byte 4 21) :type 'float-format)
277 (ft :field (byte 5 16) :value 0)
278 (fs :field (byte 5 11) :type 'fp-reg)
279 (fd :field (byte 5 6) :type 'fp-reg)
280 (funct :field (byte 6 0)))
282 (define-instruction-format (float-aux 32 :default-printer float-printer)
283 (op :field (byte 6 26) :value cop1-op)
284 (filler-1 :field (byte 1 25) :value 1)
285 (format :field (byte 4 21) :type 'float-format)
286 (ft :field (byte 5 16) :type 'fp-reg)
287 (fs :field (byte 5 11) :type 'fp-reg)
288 (fd :field (byte 5 6) :type 'fp-reg)
289 (funct :field (byte 2 4))
290 (sub-funct :field (byte 4 0)))
292 (define-instruction-format
293 (float-op 32
294 :include float
295 :default-printer
296 '('f funct "." format
297 :tab
299 (:unless (:same-as fd) ", " fs)
300 ", " ft))
301 (funct :field (byte 2 0) :type 'float-operation)
302 (funct-filler :field (byte 4 2) :value 0)
303 (ft :value nil :type 'fp-reg))
306 ;;;; Primitive emitters.
308 (define-bitfield-emitter emit-word 32
309 (byte 32 0))
311 (define-bitfield-emitter emit-short 16
312 (byte 16 0))
314 (define-bitfield-emitter emit-immediate-inst 32
315 (byte 6 26) (byte 5 21) (byte 5 16) (byte 16 0))
317 (define-bitfield-emitter emit-jump-inst 32
318 (byte 6 26) (byte 26 0))
320 (define-bitfield-emitter emit-register-inst 32
321 (byte 6 26) (byte 5 21) (byte 5 16) (byte 5 11) (byte 5 6) (byte 6 0))
323 (define-bitfield-emitter emit-break-inst 32
324 (byte 6 26) (byte 10 16) (byte 10 6) (byte 6 0))
326 (define-bitfield-emitter emit-float-inst 32
327 (byte 6 26) (byte 1 25) (byte 4 21) (byte 5 16)
328 (byte 5 11) (byte 5 6) (byte 6 0))
332 ;;;; Math instructions.
334 (defun emit-math-inst (segment dst src1 src2 reg-opcode immed-opcode
335 &optional allow-fixups)
336 (unless src2
337 (setf src2 src1)
338 (setf src1 dst))
339 (etypecase src2
341 (emit-register-inst segment special-op (reg-tn-encoding src1)
342 (reg-tn-encoding src2) (reg-tn-encoding dst)
343 0 reg-opcode))
344 (integer
345 (emit-immediate-inst segment immed-opcode (reg-tn-encoding src1)
346 (reg-tn-encoding dst) src2))
347 (fixup
348 (unless allow-fixups
349 (error "Fixups aren't allowed."))
350 (note-fixup segment :addi src2)
351 (emit-immediate-inst segment immed-opcode (reg-tn-encoding src1)
352 (reg-tn-encoding dst) 0))))
354 (define-instruction add (segment dst src1 &optional src2)
355 (:declare (type tn dst)
356 (type (or tn (signed-byte 16) null) src1 src2))
357 (:printer register ((op special-op) (funct #b100000)))
358 (:printer immediate ((op #b001000)))
359 (:dependencies (reads src1) (if src2 (reads src2) (reads dst)) (writes dst))
360 (:delay 0)
361 (:emitter
362 (emit-math-inst segment dst src1 src2 #b100000 #b001000)))
364 (define-instruction addu (segment dst src1 &optional src2)
365 (:declare (type tn dst)
366 (type (or tn (signed-byte 16) fixup null) src1 src2))
367 (:printer register ((op special-op) (funct #b100001)))
368 (:printer immediate ((op #b001001)))
369 (:dependencies (reads src1) (if src2 (reads src2) (reads dst)) (writes dst))
370 (:delay 0)
371 (:emitter
372 (emit-math-inst segment dst src1 src2 #b100001 #b001001 t)))
374 (define-instruction sub (segment dst src1 &optional src2)
375 (:declare
376 (type tn dst)
377 (type (or tn (integer #.(- 1 (ash 1 15)) #.(ash 1 15)) null) src1 src2))
378 (:printer register ((op special-op) (funct #b100010)))
379 (:dependencies (reads src1) (if src2 (reads src2) (reads dst)) (writes dst))
380 (:delay 0)
381 (:emitter
382 (unless src2
383 (setf src2 src1)
384 (setf src1 dst))
385 (emit-math-inst segment dst src1
386 (if (integerp src2) (- src2) src2)
387 #b100010 #b001000)))
389 (define-instruction subu (segment dst src1 &optional src2)
390 (:declare
391 (type tn dst)
392 (type
393 (or tn (integer #.(- 1 (ash 1 15)) #.(ash 1 15)) fixup null) src1 src2))
394 (:printer register ((op special-op) (funct #b100011)))
395 (:dependencies (reads src1) (if src2 (reads src2) (reads dst)) (writes dst))
396 (:delay 0)
397 (:emitter
398 (unless src2
399 (setf src2 src1)
400 (setf src1 dst))
401 (emit-math-inst segment dst src1
402 (if (integerp src2) (- src2) src2)
403 #b100011 #b001001 t)))
405 (define-instruction and (segment dst src1 &optional src2)
406 (:declare (type tn dst)
407 (type (or tn (unsigned-byte 16) null) src1 src2))
408 (:printer register ((op special-op) (funct #b100100)))
409 (:printer immediate ((op #b001100) (immediate nil :sign-extend nil)))
410 (:dependencies (reads src1) (if src2 (reads src2) (reads dst)) (writes dst))
411 (:delay 0)
412 (:emitter
413 (emit-math-inst segment dst src1 src2 #b100100 #b001100)))
415 (define-instruction or (segment dst src1 &optional src2)
416 (:declare (type tn dst)
417 (type (or tn (unsigned-byte 16) null) src1 src2))
418 (:printer register ((op special-op) (funct #b100101)))
419 (:printer immediate ((op #b001101)))
420 (:dependencies (reads src1) (if src2 (reads src2) (reads dst)) (writes dst))
421 (:delay 0)
422 (:emitter
423 (emit-math-inst segment dst src1 src2 #b100101 #b001101)))
425 (define-instruction xor (segment dst src1 &optional src2)
426 (:declare (type tn dst)
427 (type (or tn (unsigned-byte 16) null) src1 src2))
428 (:printer register ((op special-op) (funct #b100110)))
429 (:printer immediate ((op #b001110)))
430 (:dependencies (reads src1) (if src2 (reads src2) (reads dst)) (writes dst))
431 (:delay 0)
432 (:emitter
433 (emit-math-inst segment dst src1 src2 #b100110 #b001110)))
435 (define-instruction nor (segment dst src1 &optional src2)
436 (:declare (type tn dst src1) (type (or tn null) src2))
437 (:printer register ((op special-op) (funct #b100111)))
438 (:dependencies (reads src1) (if src2 (reads src2) (reads dst)) (writes dst))
439 (:delay 0)
440 (:emitter
441 (emit-math-inst segment dst src1 src2 #b100111 #b000000)))
443 (define-instruction slt (segment dst src1 &optional src2)
444 (:declare (type tn dst)
445 (type (or tn (signed-byte 16) null) src1 src2))
446 (:printer register ((op special-op) (funct #b101010)))
447 (:printer immediate ((op #b001010)))
448 (:dependencies (reads src1) (if src2 (reads src2) (reads dst)) (writes dst))
449 (:delay 0)
450 (:emitter
451 (emit-math-inst segment dst src1 src2 #b101010 #b001010)))
453 (define-instruction sltu (segment dst src1 &optional src2)
454 (:declare (type tn dst)
455 (type (or tn (signed-byte 16) null) src1 src2))
456 (:printer register ((op special-op) (funct #b101011)))
457 (:printer immediate ((op #b001011)))
458 (:dependencies (reads src1) (if src2 (reads src2) (reads dst)) (writes dst))
459 (:delay 0)
460 (:emitter
461 (emit-math-inst segment dst src1 src2 #b101011 #b001011)))
463 (defconstant-eqx divmul-printer '(:name :tab rs ", " rt) #'equalp)
465 (define-instruction div (segment src1 src2)
466 (:declare (type tn src1 src2))
467 (:printer register ((op special-op) (rd 0) (funct #b011010)) divmul-printer)
468 (:dependencies (reads src1) (reads src2) (writes :hi-reg) (writes :low-reg))
469 (:delay 1)
470 (:emitter
471 (emit-register-inst segment special-op (reg-tn-encoding src1)
472 (reg-tn-encoding src2) 0 0 #b011010)))
474 (define-instruction divu (segment src1 src2)
475 (:declare (type tn src1 src2))
476 (:printer register ((op special-op) (rd 0) (funct #b011011))
477 divmul-printer)
478 (:dependencies (reads src1) (reads src2) (writes :hi-reg) (writes :low-reg))
479 (:delay 1)
480 (:emitter
481 (emit-register-inst segment special-op (reg-tn-encoding src1)
482 (reg-tn-encoding src2) 0 0 #b011011)))
484 (define-instruction mult (segment src1 src2)
485 (:declare (type tn src1 src2))
486 (:printer register ((op special-op) (rd 0) (funct #b011000)) divmul-printer)
487 (:dependencies (reads src1) (reads src2) (writes :hi-reg) (writes :low-reg))
488 (:delay 1)
489 (:emitter
490 (emit-register-inst segment special-op (reg-tn-encoding src1)
491 (reg-tn-encoding src2) 0 0 #b011000)))
493 (define-instruction multu (segment src1 src2)
494 (:declare (type tn src1 src2))
495 (:printer register ((op special-op) (rd 0) (funct #b011001)))
496 (:dependencies (reads src1) (reads src2) (writes :hi-reg) (writes :low-reg))
497 (:delay 1)
498 (:emitter
499 (emit-register-inst segment special-op (reg-tn-encoding src1)
500 (reg-tn-encoding src2) 0 0 #b011001)))
502 (defun emit-shift-inst (segment opcode dst src1 src2)
503 (unless src2
504 (setf src2 src1)
505 (setf src1 dst))
506 (etypecase src2
508 (emit-register-inst segment special-op (reg-tn-encoding src2)
509 (reg-tn-encoding src1) (reg-tn-encoding dst)
510 0 (logior #b000100 opcode)))
511 ((unsigned-byte 5)
512 (emit-register-inst segment special-op 0 (reg-tn-encoding src1)
513 (reg-tn-encoding dst) src2 opcode))))
515 (defconstant-eqx shift-printer
516 '(:name :tab
518 (:unless (:same-as rd) ", " rt)
519 ", " (:cond ((rs :constant 0) shamt)
520 (t rs)))
521 #'equalp)
523 (define-instruction sll (segment dst src1 &optional src2)
524 (:declare (type tn dst)
525 (type (or tn (unsigned-byte 5) null) src1 src2))
526 (:printer register ((op special-op) (rs 0) (shamt nil) (funct #b000000))
527 shift-printer)
528 (:printer register ((op special-op) (funct #b000100)) shift-printer)
529 (:dependencies (reads src1) (if src2 (reads src2) (reads dst)) (writes dst))
530 (:delay 0)
531 (:emitter
532 (emit-shift-inst segment #b00 dst src1 src2)))
534 (define-instruction sra (segment dst src1 &optional src2)
535 (:declare (type tn dst)
536 (type (or tn (unsigned-byte 5) null) src1 src2))
537 (:printer register ((op special-op) (rs 0) (shamt nil) (funct #b000011))
538 shift-printer)
539 (:printer register ((op special-op) (funct #b000111)) shift-printer)
540 (:dependencies (reads src1) (if src2 (reads src2) (reads dst)) (writes dst))
541 (:delay 0)
542 (:emitter
543 (emit-shift-inst segment #b11 dst src1 src2)))
545 (define-instruction srl (segment dst src1 &optional src2)
546 (:declare (type tn dst)
547 (type (or tn (unsigned-byte 5) null) src1 src2))
548 (:printer register ((op special-op) (rs 0) (shamt nil) (funct #b000010))
549 shift-printer)
550 (:printer register ((op special-op) (funct #b000110)) shift-printer)
551 (:dependencies (reads src1) (if src2 (reads src2) (reads dst)) (writes dst))
552 (:delay 0)
553 (:emitter
554 (emit-shift-inst segment #b10 dst src1 src2)))
557 ;;;; Floating point math.
559 (define-instruction float-op (segment operation format dst src1 src2)
560 (:declare (type float-operation operation)
561 (type float-format format)
562 (type tn dst src1 src2))
563 (:printer float-op ())
564 (:dependencies (reads src1) (reads src2) (writes dst))
565 (:delay 0)
566 (:emitter
567 (emit-float-inst segment cop1-op 1 (float-format-value format)
568 (fp-reg-tn-encoding src2) (fp-reg-tn-encoding src1)
569 (fp-reg-tn-encoding dst) (float-operation operation))))
571 (defconstant-eqx float-unop-printer
572 `(:name ,@float-fmt-printer :tab fd (:unless (:same-as fd) ", " fs))
573 #'equalp)
575 (define-instruction fabs (segment format dst &optional (src dst))
576 (:declare (type float-format format) (type tn dst src))
577 (:printer float ((funct #b000101)) float-unop-printer)
578 (:dependencies (reads src) (writes dst))
579 (:delay 0)
580 (:emitter
581 (emit-float-inst segment cop1-op 1 (float-format-value format)
582 0 (fp-reg-tn-encoding src) (fp-reg-tn-encoding dst)
583 #b000101)))
585 (define-instruction fneg (segment format dst &optional (src dst))
586 (:declare (type float-format format) (type tn dst src))
587 (:printer float ((funct #b000111)) float-unop-printer)
588 (:dependencies (reads src) (writes dst))
589 (:delay 0)
590 (:emitter
591 (emit-float-inst segment cop1-op 1 (float-format-value format)
592 0 (fp-reg-tn-encoding src) (fp-reg-tn-encoding dst)
593 #b000111)))
595 (define-instruction fcvt (segment format1 format2 dst src)
596 (:declare (type float-format format1 format2) (type tn dst src))
597 (:printer float-aux ((funct #b10) (sub-funct nil :type 'float-format))
598 `(:name "." sub-funct "." format :tab fd ", " fs))
599 (:dependencies (reads src) (writes dst))
600 (:delay 0)
601 (:emitter
602 (emit-float-inst segment cop1-op 1 (float-format-value format2) 0
603 (fp-reg-tn-encoding src) (fp-reg-tn-encoding dst)
604 (logior #b100000 (float-format-value format1)))))
606 (define-instruction fcmp (segment operation format fs ft)
607 (:declare (type compare-kind operation)
608 (type float-format format)
609 (type tn fs ft))
610 (:printer float-aux ((fd 0) (funct #b11) (sub-funct nil :type 'compare-kind))
611 `(:name "-" sub-funct "." format :tab fs ", " ft))
612 (:dependencies (reads fs) (reads ft) (writes :float-status))
613 (:delay 1)
614 (:emitter
615 (emit-float-inst segment cop1-op 1 (float-format-value format)
616 (fp-reg-tn-encoding ft) (fp-reg-tn-encoding fs) 0
617 (logior #b110000 (compare-kind operation)))))
620 ;;;; Branch/Jump instructions.
622 (defun emit-relative-branch (segment opcode r1 r2 target)
623 (emit-chooser
624 segment 20 2
625 #'(lambda (segment posn magic-value)
626 (declare (ignore magic-value))
627 (let ((delta (ash (- (label-position target) (+ posn 4)) -2)))
628 (when (typep delta '(signed-byte 16))
629 (emit-back-patch segment 4
630 #'(lambda (segment posn)
631 (emit-immediate-inst segment
632 opcode
633 (if (fixnump r1)
635 (reg-tn-encoding r1))
636 (if (fixnump r2)
638 (reg-tn-encoding r2))
639 (ash (- (label-position target)
640 (+ posn 4))
641 -2))))
642 t)))
643 #'(lambda (segment posn)
644 (declare (ignore posn))
645 (let ((linked))
646 ;; invert branch condition
647 (if (or (= opcode bcond-op) (= opcode cop1-op))
648 (setf r2 (logxor r2 #b00001))
649 (setf opcode (logxor opcode #b00001)))
650 ;; check link flag
651 (if (= opcode bcond-op)
652 (if (logand r2 #b10000)
653 (progn (setf r2 (logand r2 #b01111))
654 (setf linked t))))
655 (emit-immediate-inst segment
656 opcode
657 (if (fixnump r1) r1 (reg-tn-encoding r1))
658 (if (fixnump r2) r2 (reg-tn-encoding r2))
660 (emit-nop segment)
661 (emit-back-patch segment 8
662 #'(lambda (segment posn)
663 (declare (ignore posn))
664 (emit-immediate-inst segment #b001111 0
665 (reg-tn-encoding lip-tn)
666 (ldb (byte 16 16)
667 (label-position target)))
668 (emit-immediate-inst segment #b001101 0
669 (reg-tn-encoding lip-tn)
670 (ldb (byte 16 0)
671 (label-position target)))))
672 (emit-register-inst segment special-op (reg-tn-encoding lip-tn)
673 0 (if linked 31 0) 0
674 (if linked #b001001 #b001000))))))
676 (define-instruction b (segment target)
677 (:declare (type label target))
678 (:printer immediate ((op #b000100) (rs 0) (rt 0)
679 (immediate nil :type 'relative-label))
680 '(:name :tab immediate))
681 (:attributes branch)
682 (:delay 1)
683 (:emitter
684 (emit-relative-branch segment #b000100 0 0 target)))
686 (define-instruction bal (segment target)
687 (:declare (type label target))
688 (:printer immediate ((op bcond-op) (rs 0) (rt #b01001)
689 (immediate nil :type 'relative-label))
690 '(:name :tab immediate))
691 (:attributes branch)
692 (:dependencies (writes lip-tn))
693 (:delay 1)
694 (:emitter
695 (emit-relative-branch segment bcond-op 0 #b10001 target)))
697 (define-instruction beq (segment r1 r2-or-target &optional target)
698 (:declare (type tn r1)
699 (type (or tn fixnum label) r2-or-target)
700 (type (or label null) target))
701 (:printer immediate ((op #b000100) (immediate nil :type 'relative-label)))
702 (:attributes branch)
703 (:dependencies (reads r1) (if target (reads r2-or-target)))
704 (:delay 1)
705 (:emitter
706 (unless target
707 (setf target r2-or-target)
708 (setf r2-or-target 0))
709 (emit-relative-branch segment #b000100 r1 r2-or-target target)))
711 (define-instruction bne (segment r1 r2-or-target &optional target)
712 (:declare (type tn r1)
713 (type (or tn fixnum label) r2-or-target)
714 (type (or label null) target))
715 (:printer immediate ((op #b000101) (immediate nil :type 'relative-label)))
716 (:attributes branch)
717 (:dependencies (reads r1) (if target (reads r2-or-target)))
718 (:delay 1)
719 (:emitter
720 (unless target
721 (setf target r2-or-target)
722 (setf r2-or-target 0))
723 (emit-relative-branch segment #b000101 r1 r2-or-target target)))
725 (defconstant-eqx cond-branch-printer
726 '(:name :tab rs ", " immediate)
727 #'equalp)
729 (define-instruction blez (segment reg target)
730 (:declare (type label target) (type tn reg))
731 (:printer
732 immediate ((op #b000110) (rt 0) (immediate nil :type 'relative-label))
733 cond-branch-printer)
734 (:attributes branch)
735 (:dependencies (reads reg))
736 (:delay 1)
737 (:emitter
738 (emit-relative-branch segment #b000110 reg 0 target)))
740 (define-instruction bgtz (segment reg target)
741 (:declare (type label target) (type tn reg))
742 (:printer
743 immediate ((op #b000111) (rt 0) (immediate nil :type 'relative-label))
744 cond-branch-printer)
745 (:attributes branch)
746 (:dependencies (reads reg))
747 (:delay 1)
748 (:emitter
749 (emit-relative-branch segment #b000111 reg 0 target)))
751 (define-instruction bltz (segment reg target)
752 (:declare (type label target) (type tn reg))
753 (:printer
754 immediate ((op bcond-op) (rt 0) (immediate nil :type 'relative-label))
755 cond-branch-printer)
756 (:attributes branch)
757 (:dependencies (reads reg))
758 (:delay 1)
759 (:emitter
760 (emit-relative-branch segment bcond-op reg #b00000 target)))
762 (define-instruction bgez (segment reg target)
763 (:declare (type label target) (type tn reg))
764 (:printer
765 immediate ((op bcond-op) (rt 1) (immediate nil :type 'relative-label))
766 cond-branch-printer)
767 (:attributes branch)
768 (:dependencies (reads reg))
769 (:delay 1)
770 (:emitter
771 (emit-relative-branch segment bcond-op reg #b00001 target)))
773 (define-instruction bltzal (segment reg target)
774 (:declare (type label target) (type tn reg))
775 (:printer
776 immediate ((op bcond-op) (rt #b01000) (immediate nil :type 'relative-label))
777 cond-branch-printer)
778 (:attributes branch)
779 (:dependencies (reads reg) (writes lip-tn))
780 (:delay 1)
781 (:emitter
782 (emit-relative-branch segment bcond-op reg #b10000 target)))
784 (define-instruction bgezal (segment reg target)
785 (:declare (type label target) (type tn reg))
786 (:printer
787 immediate ((op bcond-op) (rt #b01001) (immediate nil :type 'relative-label))
788 cond-branch-printer)
789 (:attributes branch)
790 (:delay 1)
791 (:dependencies (reads reg) (writes lip-tn))
792 (:emitter
793 (emit-relative-branch segment bcond-op reg #b10001 target)))
795 (defconstant-eqx j-printer
796 '(:name :tab (:choose rs target))
797 #'equalp)
799 (define-instruction j (segment target)
800 (:declare (type (or tn fixup) target))
801 (:printer register ((op special-op) (rt 0) (rd 0) (funct #b001000))
802 j-printer)
803 (:printer jump ((op #b000010)) j-printer)
804 (:attributes branch)
805 (:dependencies (reads target))
806 (:delay 1)
807 (:emitter
808 (etypecase target
810 (emit-register-inst segment special-op (reg-tn-encoding target)
811 0 0 0 #b001000))
812 (fixup
813 (note-fixup segment :lui target)
814 (emit-immediate-inst segment #b001111 0 28 0)
815 (note-fixup segment :addi target)
816 (emit-immediate-inst segment #b001001 28 28 0)
817 (emit-register-inst segment special-op 28 0 0 0 #b001000)))))
819 (define-instruction jal (segment reg-or-target &optional target)
820 (:declare (type (or null tn fixup) target)
821 (type (or tn fixup) reg-or-target))
822 (:printer register ((op special-op) (rt 0) (funct #b001001)) j-printer)
823 (:printer jump ((op #b000011)) j-printer)
824 (:attributes branch)
825 (:dependencies (cond
826 (target
827 (writes reg-or-target) (reads target))
829 (writes lip-tn)
830 (when (tn-p reg-or-target)
831 (reads reg-or-target)))))
832 (:delay 1)
833 (:emitter
834 (unless target
835 (setf target reg-or-target
836 reg-or-target lip-tn))
837 (etypecase target
839 (emit-register-inst segment special-op (reg-tn-encoding target) 0
840 (reg-tn-encoding reg-or-target) 0 #b001001))
841 (fixup
842 (note-fixup segment :lui target)
843 (emit-immediate-inst segment #b001111 0 28 0)
844 (note-fixup segment :addi target)
845 (emit-immediate-inst segment #b001001 28 28 0)
846 (emit-register-inst segment special-op 28 0
847 (reg-tn-encoding reg-or-target) 0 #b001001)))))
849 (define-instruction bc1f (segment target)
850 (:declare (type label target))
851 (:printer coproc-branch ((op cop1-op) (funct #x100)
852 (offset nil :type 'relative-label)))
853 (:attributes branch)
854 (:dependencies (reads :float-status))
855 (:delay 1)
856 (:emitter
857 (emit-relative-branch segment cop1-op #b01000 #b00000 target)))
859 (define-instruction bc1t (segment target)
860 (:declare (type label target))
861 (:printer coproc-branch ((op cop1-op) (funct #x101)
862 (offset nil :type 'relative-label)))
863 (:attributes branch)
864 (:dependencies (reads :float-status))
865 (:delay 1)
866 (:emitter
867 (emit-relative-branch segment cop1-op #b01000 #b00001 target)))
871 ;;;; Random movement instructions.
873 (define-instruction lui (segment reg value)
874 (:declare (type tn reg)
875 (type (or fixup (signed-byte 16) (unsigned-byte 16)) value))
876 (:printer immediate ((op #b001111)
877 (immediate nil :sign-extend nil :printer "#x~4,'0X")))
878 (:dependencies (writes reg))
879 (:delay 0)
880 (:emitter
881 (when (fixup-p value)
882 (note-fixup segment :lui value)
883 (setf value 0))
884 (emit-immediate-inst segment #b001111 0 (reg-tn-encoding reg) value)))
886 (defconstant-eqx mvsreg-printer '(:name :tab rd)
887 #'equalp)
889 (define-instruction mfhi (segment reg)
890 (:declare (type tn reg))
891 (:printer register ((op special-op) (rs 0) (rt 0) (funct #b010000))
892 mvsreg-printer)
893 (:dependencies (reads :hi-reg) (writes reg))
894 (:delay 2)
895 (:emitter
896 (emit-register-inst segment special-op 0 0 (reg-tn-encoding reg) 0
897 #b010000)))
899 (define-instruction mthi (segment reg)
900 (:declare (type tn reg))
901 (:printer register ((op special-op) (rs 0) (rt 0) (funct #b010001))
902 mvsreg-printer)
903 (:dependencies (reads reg) (writes :hi-reg))
904 (:delay 0)
905 (:emitter
906 (emit-register-inst segment special-op 0 0 (reg-tn-encoding reg) 0
907 #b010001)))
909 (define-instruction mflo (segment reg)
910 (:declare (type tn reg))
911 (:printer register ((op special-op) (rs 0) (rt 0) (funct #b010010))
912 mvsreg-printer)
913 (:dependencies (reads :low-reg) (writes reg))
914 (:delay 2)
915 (:emitter
916 (emit-register-inst segment special-op 0 0 (reg-tn-encoding reg) 0
917 #b010010)))
919 (define-instruction mtlo (segment reg)
920 (:declare (type tn reg))
921 (:printer register ((op special-op) (rs 0) (rt 0) (funct #b010011))
922 mvsreg-printer)
923 (:dependencies (reads reg) (writes :low-reg))
924 (:delay 0)
925 (:emitter
926 (emit-register-inst segment special-op 0 0 (reg-tn-encoding reg) 0
927 #b010011)))
929 (define-instruction move (segment dst src)
930 (:declare (type tn dst src))
931 (:printer register ((op special-op) (rt 0) (funct #b100001))
932 '(:name :tab rd ", " rs))
933 (:attributes flushable)
934 (:dependencies (reads src) (writes dst))
935 (:delay 0)
936 (:emitter
937 (emit-register-inst segment special-op (reg-tn-encoding src) 0
938 (reg-tn-encoding dst) 0 #b100001)))
940 (define-instruction fmove (segment format dst src)
941 (:declare (type float-format format) (type tn dst src))
942 (:printer float ((funct #b000110)) '(:name "." format :tab fd ", " fs))
943 (:attributes flushable)
944 (:dependencies (reads src) (writes dst))
945 (:delay 0)
946 (:emitter
947 (emit-float-inst segment cop1-op 1 (float-format-value format) 0
948 (fp-reg-tn-encoding src) (fp-reg-tn-encoding dst)
949 #b000110)))
951 (defun %li (reg value)
952 (etypecase value
953 ((unsigned-byte 16)
954 (inst or reg zero-tn value))
955 ((signed-byte 16)
956 (inst addu reg zero-tn value))
957 ((or (signed-byte 32) (unsigned-byte 32))
958 (inst lui reg (ldb (byte 16 16) value))
959 (inst or reg (ldb (byte 16 0) value)))
960 (fixup
961 (inst lui reg value)
962 (inst addu reg value))))
964 (define-instruction-macro li (reg value)
965 `(%li ,reg ,value))
967 (defconstant-eqx sub-op-printer '(:name :tab rd ", " rt) #'equalp)
969 (define-instruction mtc1 (segment to from)
970 (:declare (type tn to from))
971 (:printer register ((op cop1-op) (rs #b00100) (funct 0)) sub-op-printer)
972 (:dependencies (reads from) (writes to))
973 (:delay 1)
974 (:emitter
975 (emit-register-inst segment cop1-op #b00100 (reg-tn-encoding from)
976 (fp-reg-tn-encoding to) 0 0)))
978 (define-instruction mtc1-odd (segment to from)
979 (:declare (type tn to from))
980 (:dependencies (reads from) (writes to))
981 (:delay 1)
982 (:emitter
983 (emit-register-inst segment cop1-op #b00100 (reg-tn-encoding from)
984 (1+ (fp-reg-tn-encoding to)) 0 0)))
986 (define-instruction mfc1 (segment to from)
987 (:declare (type tn to from))
988 (:printer register ((op cop1-op) (rs 0) (rd nil :type 'fp-reg) (funct 0))
989 sub-op-printer)
990 (:dependencies (reads from) (writes to))
991 (:delay 1)
992 (:emitter
993 (emit-register-inst segment cop1-op #b00000 (reg-tn-encoding to)
994 (fp-reg-tn-encoding from) 0 0)))
996 (define-instruction mfc1-odd (segment to from)
997 (:declare (type tn to from))
998 (:dependencies (reads from) (writes to))
999 (:delay 1)
1000 (:emitter
1001 (emit-register-inst segment cop1-op #b00000 (reg-tn-encoding to)
1002 (1+ (fp-reg-tn-encoding from)) 0 0)))
1004 (define-instruction mfc1-odd2 (segment to from)
1005 (:declare (type tn to from))
1006 (:dependencies (reads from) (writes to))
1007 (:delay 1)
1008 (:emitter
1009 (emit-register-inst segment cop1-op #b00000 (1+ (reg-tn-encoding to))
1010 (fp-reg-tn-encoding from) 0 0)))
1012 (define-instruction mfc1-odd3 (segment to from)
1013 (:declare (type tn to from))
1014 (:dependencies (reads from) (writes to))
1015 (:delay 1)
1016 (:emitter
1017 (emit-register-inst segment cop1-op #b00000 (1+ (reg-tn-encoding to))
1018 (1+ (fp-reg-tn-encoding from)) 0 0)))
1020 (define-instruction cfc1 (segment reg cr)
1021 (:declare (type tn reg) (type (unsigned-byte 5) cr))
1022 (:printer register ((op cop1-op) (rs #b00010) (rd nil :type 'control-reg)
1023 (funct 0)) sub-op-printer)
1024 (:dependencies (reads :ctrl-stat-reg) (writes reg))
1025 (:delay 1)
1026 (:emitter
1027 (emit-register-inst segment cop1-op #b00010 (reg-tn-encoding reg)
1028 cr 0 0)))
1030 (define-instruction ctc1 (segment reg cr)
1031 (:declare (type tn reg) (type (unsigned-byte 5) cr))
1032 (:printer register ((op cop1-op) (rs #b00110) (rd nil :type 'control-reg)
1033 (funct 0)) sub-op-printer)
1034 (:dependencies (reads reg) (writes :ctrl-stat-reg))
1035 (:delay 1)
1036 (:emitter
1037 (emit-register-inst segment cop1-op #b00110 (reg-tn-encoding reg)
1038 cr 0 0)))
1042 ;;;; Random system hackery and other noise
1044 (define-instruction-macro entry-point ()
1045 nil)
1047 (defun snarf-error-junk (sap offset &optional length-only)
1048 (let* ((length (sap-ref-8 sap offset))
1049 (vector (make-array length :element-type '(unsigned-byte 8))))
1050 (declare (type system-area-pointer sap)
1051 (type (unsigned-byte 8) length)
1052 (type (simple-array (unsigned-byte 8) (*)) vector))
1053 (cond (length-only
1054 (values 0 (1+ length) nil nil))
1056 (copy-ub8-from-system-area sap (1+ offset) vector 0 length)
1057 (collect ((sc-offsets)
1058 (lengths))
1059 (lengths 1) ; the length byte
1060 (let* ((index 0)
1061 (error-number (read-var-integer vector index)))
1062 (lengths index)
1063 (loop
1064 (when (>= index length)
1065 (return))
1066 (let ((old-index index))
1067 (sc-offsets (read-var-integer vector index))
1068 (lengths (- index old-index))))
1069 (values error-number
1070 (1+ length)
1071 (sc-offsets)
1072 (lengths))))))))
1074 (defmacro break-cases (breaknum &body cases)
1075 (let ((bn-temp (gensym)))
1076 (collect ((clauses))
1077 (dolist (case cases)
1078 (clauses `((= ,bn-temp ,(car case)) ,@(cdr case))))
1079 `(let ((,bn-temp ,breaknum))
1080 (cond ,@(clauses))))))
1082 (defun break-control (chunk inst stream dstate)
1083 (declare (ignore inst))
1084 (flet ((nt (x) (if stream (note x dstate))))
1085 (when (= (break-code chunk dstate) 0)
1086 (case (break-subcode chunk dstate)
1087 (#.halt-trap
1088 (nt "Halt trap"))
1089 (#.pending-interrupt-trap
1090 (nt "Pending interrupt trap"))
1091 (#.error-trap
1092 (nt "Error trap")
1093 (handle-break-args #'snarf-error-junk stream dstate))
1094 (#.cerror-trap
1095 (nt "Cerror trap")
1096 (handle-break-args #'snarf-error-junk stream dstate))
1097 (#.breakpoint-trap
1098 (nt "Breakpoint trap"))
1099 (#.fun-end-breakpoint-trap
1100 (nt "Function end breakpoint trap"))
1101 (#.after-breakpoint-trap
1102 (nt "After breakpoint trap"))
1103 ;; KLUDGE: see comment in compiler/generic/genesis regarding
1104 ;; the non-exportation of PSEUDO-ATOMIC-TRAP.
1105 (#.sb!vm::pseudo-atomic-trap
1106 (nt "Pseudo atomic trap"))
1107 (#.object-not-list-trap
1108 (nt "Object not list trap"))
1109 (#.object-not-instance-trap
1110 (nt "Object not instance trap"))
1111 (#.single-step-around-trap
1112 (nt "Single step around trap"))
1113 (#.single-step-before-trap
1114 (nt "Single step before trap"))))))
1116 (define-instruction break (segment code &optional (subcode 0))
1117 (:declare (type (unsigned-byte 10) code subcode))
1118 (:printer break ((op special-op) (funct #b001101))
1119 '(:name :tab code (:unless (:constant 0) ", " subcode))
1120 :control #'break-control)
1121 :pinned
1122 (:cost 0)
1123 (:delay 0)
1124 (:emitter
1125 (emit-break-inst segment special-op code subcode #b001101)))
1127 (define-instruction syscall (segment)
1128 (:printer register ((op special-op) (rd 0) (rt 0) (rs 0) (funct #b001110))
1129 '(:name))
1130 :pinned
1131 (:delay 0)
1132 (:emitter
1133 (emit-register-inst segment special-op 0 0 0 0 #b001110)))
1135 (define-instruction nop (segment)
1136 (:printer register ((op 0) (rd 0) (rd 0) (rs 0) (funct 0)) '(:name))
1137 (:attributes flushable)
1138 (:delay 0)
1139 (:emitter
1140 (emit-word segment 0)))
1142 (defun emit-nop (segment)
1143 (emit-word segment 0))
1145 (define-instruction word (segment word)
1146 (:declare (type (or (unsigned-byte 32) (signed-byte 32)) word))
1147 :pinned
1148 (:cost 0)
1149 (:delay 0)
1150 (:emitter
1151 (emit-word segment word)))
1153 (define-instruction short (segment short)
1154 (:declare (type (or (unsigned-byte 16) (signed-byte 16)) short))
1155 :pinned
1156 (:cost 0)
1157 (:delay 0)
1158 (:emitter
1159 (emit-short segment short)))
1161 (define-instruction byte (segment byte)
1162 (:declare (type (or (unsigned-byte 8) (signed-byte 8)) byte))
1163 :pinned
1164 (:cost 0)
1165 (:delay 0)
1166 (:emitter
1167 (emit-byte segment byte)))
1170 (defun emit-header-data (segment type)
1171 (emit-back-patch
1172 segment 4
1173 #'(lambda (segment posn)
1174 (emit-word segment
1175 (logior type
1176 (ash (+ posn (component-header-length))
1177 (- n-widetag-bits word-shift)))))))
1179 (define-instruction simple-fun-header-word (segment)
1180 :pinned
1181 (:cost 0)
1182 (:delay 0)
1183 (:emitter
1184 (emit-header-data segment simple-fun-header-widetag)))
1186 (define-instruction lra-header-word (segment)
1187 :pinned
1188 (:cost 0)
1189 (:delay 0)
1190 (:emitter
1191 (emit-header-data segment return-pc-header-widetag)))
1194 (defun emit-compute-inst (segment vop dst src label temp calc)
1195 (emit-chooser
1196 ;; We emit either 12 or 4 bytes, so we maintain 8 byte alignments.
1197 segment 12 3
1198 #'(lambda (segment posn delta-if-after)
1199 (let ((delta (funcall calc label posn delta-if-after)))
1200 (when (typep delta '(signed-byte 16))
1201 (emit-back-patch segment 4
1202 #'(lambda (segment posn)
1203 (assemble (segment vop)
1204 (inst addu dst src
1205 (funcall calc label posn 0)))))
1206 t)))
1207 #'(lambda (segment posn)
1208 (let ((delta (funcall calc label posn 0)))
1209 (assemble (segment vop)
1210 (inst lui temp (ldb (byte 16 16) delta))
1211 (inst or temp (ldb (byte 16 0) delta))
1212 (inst addu dst src temp))))))
1214 ;; code = lip - header - label-offset + other-pointer-lowtag
1215 (define-instruction compute-code-from-lip (segment dst src label temp)
1216 (:declare (type tn dst src temp) (type label label))
1217 (:attributes variable-length)
1218 (:dependencies (reads src) (writes dst) (writes temp))
1219 (:delay 0)
1220 (:vop-var vop)
1221 (:emitter
1222 (emit-compute-inst segment vop dst src label temp
1223 #'(lambda (label posn delta-if-after)
1224 (- other-pointer-lowtag
1225 (label-position label posn delta-if-after)
1226 (component-header-length))))))
1228 ;; code = lra - other-pointer-tag - header - label-offset + other-pointer-tag
1229 ;; = lra - (header + label-offset)
1230 (define-instruction compute-code-from-lra (segment dst src label temp)
1231 (:declare (type tn dst src temp) (type label label))
1232 (:attributes variable-length)
1233 (:dependencies (reads src) (writes dst) (writes temp))
1234 (:delay 0)
1235 (:vop-var vop)
1236 (:emitter
1237 (emit-compute-inst segment vop dst src label temp
1238 #'(lambda (label posn delta-if-after)
1239 (- (+ (label-position label posn delta-if-after)
1240 (component-header-length)))))))
1242 ;; lra = code + other-pointer-tag + header + label-offset - other-pointer-tag
1243 ;; = code + header + label-offset
1244 (define-instruction compute-lra-from-code (segment dst src label temp)
1245 (:declare (type tn dst src temp) (type label label))
1246 (:attributes variable-length)
1247 (:dependencies (reads src) (writes dst) (writes temp))
1248 (:delay 0)
1249 (:vop-var vop)
1250 (:emitter
1251 (emit-compute-inst segment vop dst src label temp
1252 #'(lambda (label posn delta-if-after)
1253 (+ (label-position label posn delta-if-after)
1254 (component-header-length))))))
1257 ;;;; Loads and Stores
1259 (defun emit-load/store-inst (segment opcode reg base index
1260 &optional (oddhack 0))
1261 (when (fixup-p index)
1262 (note-fixup segment :addi index)
1263 (setf index 0))
1264 (emit-immediate-inst segment opcode (reg-tn-encoding reg)
1265 (+ (reg-tn-encoding base) oddhack) index))
1267 (define-instruction lb (segment reg base &optional (index 0))
1268 (:declare (type tn reg base)
1269 (type (or (signed-byte 16) fixup) index))
1270 (:printer immediate ((op #b100000)) load-store-printer)
1271 (:dependencies (reads base) (reads :memory) (writes reg))
1272 (:delay 1)
1273 (:emitter
1274 (emit-load/store-inst segment #b100000 base reg index)))
1276 (define-instruction lh (segment reg base &optional (index 0))
1277 (:declare (type tn reg base)
1278 (type (or (signed-byte 16) fixup) index))
1279 (:printer immediate ((op #b100001)) load-store-printer)
1280 (:dependencies (reads base) (reads :memory) (writes reg))
1281 (:delay 1)
1282 (:emitter
1283 (emit-load/store-inst segment #b100001 base reg index)))
1285 (define-instruction lwl (segment reg base &optional (index 0))
1286 (:declare (type tn reg base)
1287 (type (or (signed-byte 16) fixup) index))
1288 (:printer immediate ((op #b100010)) load-store-printer)
1289 (:dependencies (reads base) (reads :memory) (writes reg))
1290 (:delay 1)
1291 (:emitter
1292 (emit-load/store-inst segment #b100010 base reg index)))
1294 (define-instruction lw (segment reg base &optional (index 0))
1295 (:declare (type tn reg base)
1296 (type (or (signed-byte 16) fixup) index))
1297 (:printer load-store ((op #b100011)))
1298 (:dependencies (reads base) (reads :memory) (writes reg))
1299 (:delay 1)
1300 (:emitter
1301 (emit-load/store-inst segment #b100011 base reg index)))
1303 ;; next is just for ease of coding double-in-int c-call convention
1304 (define-instruction lw-odd (segment reg base &optional (index 0))
1305 (:declare (type tn reg base)
1306 (type (or (signed-byte 16) fixup) index))
1307 (:dependencies (reads base) (reads :memory) (writes reg))
1308 (:delay 1)
1309 (:emitter
1310 (emit-load/store-inst segment #b100011 base reg index 1)))
1312 (define-instruction lbu (segment reg base &optional (index 0))
1313 (:declare (type tn reg base)
1314 (type (or (signed-byte 16) fixup) index))
1315 (:printer immediate ((op #b100100)) load-store-printer)
1316 (:dependencies (reads base) (reads :memory) (writes reg))
1317 (:delay 1)
1318 (:emitter
1319 (emit-load/store-inst segment #b100100 base reg index)))
1321 (define-instruction lhu (segment reg base &optional (index 0))
1322 (:declare (type tn reg base)
1323 (type (or (signed-byte 16) fixup) index))
1324 (:printer immediate ((op #b100101)) load-store-printer)
1325 (:dependencies (reads base) (reads :memory) (writes reg))
1326 (:delay 1)
1327 (:emitter
1328 (emit-load/store-inst segment #b100101 base reg index)))
1330 (define-instruction lwr (segment reg base &optional (index 0))
1331 (:declare (type tn reg base)
1332 (type (or (signed-byte 16) fixup) index))
1333 (:printer immediate ((op #b100110)) load-store-printer)
1334 (:dependencies (reads base) (reads :memory) (writes reg))
1335 (:delay 1)
1336 (:emitter
1337 (emit-load/store-inst segment #b100110 base reg index)))
1339 (define-instruction sb (segment reg base &optional (index 0))
1340 (:declare (type tn reg base)
1341 (type (or (signed-byte 16) fixup) index))
1342 (:printer immediate ((op #b101000)) load-store-printer)
1343 (:dependencies (reads base) (reads reg) (writes :memory))
1344 (:delay 0)
1345 (:emitter
1346 (emit-load/store-inst segment #b101000 base reg index)))
1348 (define-instruction sh (segment reg base &optional (index 0))
1349 (:declare (type tn reg base)
1350 (type (or (signed-byte 16) fixup) index))
1351 (:printer immediate ((op #b101001)) load-store-printer)
1352 (:dependencies (reads base) (reads reg) (writes :memory))
1353 (:delay 0)
1354 (:emitter
1355 (emit-load/store-inst segment #b101001 base reg index)))
1357 (define-instruction swl (segment reg base &optional (index 0))
1358 (:declare (type tn reg base)
1359 (type (or (signed-byte 16) fixup) index))
1360 (:printer immediate ((op #b101010)) load-store-printer)
1361 (:dependencies (reads base) (reads reg) (writes :memory))
1362 (:delay 0)
1363 (:emitter
1364 (emit-load/store-inst segment #b101010 base reg index)))
1366 (define-instruction sw (segment reg base &optional (index 0))
1367 (:declare (type tn reg base)
1368 (type (or (signed-byte 16) fixup) index))
1369 (:printer immediate ((op #b101011)) load-store-printer)
1370 (:dependencies (reads base) (reads reg) (writes :memory))
1371 (:delay 0)
1372 (:emitter
1373 (emit-load/store-inst segment #b101011 base reg index)))
1375 (define-instruction swr (segment reg base &optional (index 0))
1376 (:declare (type tn reg base)
1377 (type (or (signed-byte 16) fixup) index))
1378 (:printer immediate ((op #b101110)) load-store-printer)
1379 (:dependencies (reads base) (reads reg) (writes :memory))
1380 (:delay 0)
1381 (:emitter
1382 (emit-load/store-inst segment #b101110 base reg index)))
1385 (defun emit-fp-load/store-inst (segment opcode reg odd base index)
1386 (when (fixup-p index)
1387 (note-fixup segment :addi index)
1388 (setf index 0))
1389 (emit-immediate-inst segment opcode (reg-tn-encoding base)
1390 (+ (fp-reg-tn-encoding reg) odd) index))
1392 (define-instruction lwc1 (segment reg base &optional (index 0))
1393 (:declare (type tn reg base)
1394 (type (or (signed-byte 16) fixup) index))
1395 (:printer immediate ((op #b110001) (rt nil :type 'fp-reg)) load-store-printer)
1396 (:dependencies (reads base) (reads :memory) (writes reg))
1397 (:delay 1)
1398 (:emitter
1399 (emit-fp-load/store-inst segment #b110001 reg 0 base index)))
1401 (define-instruction lwc1-odd (segment reg base &optional (index 0))
1402 (:declare (type tn reg base)
1403 (type (or (signed-byte 16) fixup) index))
1404 (:dependencies (reads base) (reads :memory) (writes reg))
1405 (:delay 1)
1406 (:emitter
1407 (emit-fp-load/store-inst segment #b110001 reg 1 base index)))
1409 (define-instruction swc1 (segment reg base &optional (index 0))
1410 (:declare (type tn reg base)
1411 (type (or (signed-byte 16) fixup) index))
1412 (:printer immediate ((op #b111001) (rt nil :type 'fp-reg)) load-store-printer)
1413 (:dependencies (reads base) (reads reg) (writes :memory))
1414 (:delay 0)
1415 (:emitter
1416 (emit-fp-load/store-inst segment #b111001 reg 0 base index)))
1418 (define-instruction swc1-odd (segment reg base &optional (index 0))
1419 (:declare (type tn reg base)
1420 (type (or (signed-byte 16) fixup) index))
1421 (:dependencies (reads base) (reads reg) (writes :memory))
1422 (:delay 0)
1423 (:emitter
1424 (emit-fp-load/store-inst segment #b111001 reg 1 base index)))