1 ;;; the instruction set definition for MIPS
3 ;;;; This software is part of the SBCL system. See the README file for
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
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
))
32 (zero sb
!vm
::zero-offset
)
33 (null sb
!vm
::null-offset
)
35 (if (eq (sb-name (sc-sb (tn-sc tn
))) 'registers
)
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
))
45 ;;;(sb!disassem:set-disassem-params :instruction-alignment 32)
47 (defvar *disassem-use-lisp-reg-names
* t
)
49 (defun location-number (loc)
56 (ecase (sb-name (sc-sb (tn-sc loc
)))
58 ;; Can happen if $ZERO or $NULL are passed in.
61 (unless (zerop (tn-offset loc
))
64 (+ (tn-offset loc
) 32))))
71 (:ctrl-stat-reg
67)))))
73 (defparameter *reg-symbols
*
77 (make-symbol (concatenate 'string
"$" name
))))
78 sb
!vm
::*register-names
*))
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
*
97 (loop for n from
0 to
31 collect
(make-symbol (format nil
"$F~d" n
)))
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
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)
126 (define-arg-type float-format
127 :printer
#'(lambda (value stream dstate
)
128 (declare (ignore dstate
)
138 (defconstant-eqx compare-kinds
139 '(:f
:un
:eq
:ueq
:olt
:ult
:ole
:ule
:sf
:ngle
:seq
:ngl
:lt
:nge
:le
:ngt
)
142 (defconstant-eqx compare-kinds-vec
143 (apply #'vector compare-kinds
)
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"
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
167 (defun float-operation (op)
168 (or (position op float-operations
)
169 (error "Unknown floating point operation: ~S~%Must be one of: ~S"
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
)
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
)
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
209 (:unless
(:constant
0) "[" immediate
"]"))
212 (define-instruction-format
213 (load-store 32 :default-printer
'(:name
:tab
216 (:unless
(:constant
0) "[" immediate
"]")
217 load-store-annotation
)
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
)
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
)
265 (defconstant-eqx float-printer
266 `(:name
,@float-fmt-printer
269 (:unless
(:same-as fd
) ", " fs
)
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
296 '('f funct
"." format
299 (:unless
(:same-as fd
) ", " fs
)
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
311 (define-bitfield-emitter emit-short
16
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
)
341 (emit-register-inst segment special-op
(reg-tn-encoding src1
)
342 (reg-tn-encoding src2
) (reg-tn-encoding dst
)
345 (emit-immediate-inst segment immed-opcode
(reg-tn-encoding src1
)
346 (reg-tn-encoding dst
) src2
))
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
))
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
))
372 (emit-math-inst segment dst src1 src2
#b100001
#b001001 t
)))
374 (define-instruction sub
(segment dst src1
&optional src2
)
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
))
385 (emit-math-inst segment dst src1
386 (if (integerp src2
) (- src2
) src2
)
389 (define-instruction subu
(segment dst src1
&optional src2
)
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
))
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
))
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
))
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
))
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
))
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
))
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
))
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
))
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
))
478 (:dependencies
(reads src1
) (reads src2
) (writes :hi-reg
) (writes :low-reg
))
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
))
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
))
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
)
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
)))
512 (emit-register-inst segment special-op
0 (reg-tn-encoding src1
)
513 (reg-tn-encoding dst
) src2 opcode
))))
515 (defconstant-eqx shift-printer
518 (:unless
(:same-as rd
) ", " rt
)
519 ", " (:cond
((rs :constant
0) shamt
)
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
))
528 (:printer register
((op special-op
) (funct #b000100
)) shift-printer
)
529 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
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
))
539 (:printer register
((op special-op
) (funct #b000111
)) shift-printer
)
540 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
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
))
550 (:printer register
((op special-op
) (funct #b000110
)) shift-printer
)
551 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
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
))
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
))
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
))
581 (emit-float-inst segment cop1-op
1 (float-format-value format
)
582 0 (fp-reg-tn-encoding src
) (fp-reg-tn-encoding dst
)
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
))
591 (emit-float-inst segment cop1-op
1 (float-format-value format
)
592 0 (fp-reg-tn-encoding src
) (fp-reg-tn-encoding dst
)
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
))
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
)
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
))
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
)
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
635 (reg-tn-encoding r1
))
638 (reg-tn-encoding r2
))
639 (ash (- (label-position target
)
643 #'(lambda (segment posn
)
644 (declare (ignore posn
))
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
)))
651 (if (= opcode bcond-op
)
652 (if (logand r2
#b10000
)
653 (progn (setf r2
(logand r2
#b01111
))
655 (emit-immediate-inst segment
657 (if (fixnump r1
) r1
(reg-tn-encoding r1
))
658 (if (fixnump r2
) r2
(reg-tn-encoding r2
))
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
)
667 (label-position target
)))
668 (emit-immediate-inst segment
#b001101
0
669 (reg-tn-encoding lip-tn
)
671 (label-position target
)))))
672 (emit-register-inst segment special-op
(reg-tn-encoding lip-tn
)
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
))
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
))
692 (:dependencies
(writes lip-tn
))
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
)))
703 (:dependencies
(reads r1
) (if target
(reads r2-or-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
)))
717 (:dependencies
(reads r1
) (if target
(reads r2-or-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
)
729 (define-instruction blez
(segment reg target
)
730 (:declare
(type label target
) (type tn reg
))
732 immediate
((op #b000110
) (rt 0) (immediate nil
:type
'relative-label
))
735 (:dependencies
(reads reg
))
738 (emit-relative-branch segment
#b000110 reg
0 target
)))
740 (define-instruction bgtz
(segment reg target
)
741 (:declare
(type label target
) (type tn reg
))
743 immediate
((op #b000111
) (rt 0) (immediate nil
:type
'relative-label
))
746 (:dependencies
(reads reg
))
749 (emit-relative-branch segment
#b000111 reg
0 target
)))
751 (define-instruction bltz
(segment reg target
)
752 (:declare
(type label target
) (type tn reg
))
754 immediate
((op bcond-op
) (rt 0) (immediate nil
:type
'relative-label
))
757 (:dependencies
(reads reg
))
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
))
765 immediate
((op bcond-op
) (rt 1) (immediate nil
:type
'relative-label
))
768 (:dependencies
(reads reg
))
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
))
776 immediate
((op bcond-op
) (rt #b01000
) (immediate nil
:type
'relative-label
))
779 (:dependencies
(reads reg
) (writes lip-tn
))
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
))
787 immediate
((op bcond-op
) (rt #b01001
) (immediate nil
:type
'relative-label
))
791 (:dependencies
(reads reg
) (writes lip-tn
))
793 (emit-relative-branch segment bcond-op reg
#b10001 target
)))
795 (defconstant-eqx j-printer
796 '(:name
:tab
(:choose rs target
))
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
))
803 (:printer jump
((op #b000010
)) j-printer
)
805 (:dependencies
(reads target
))
810 (emit-register-inst segment special-op
(reg-tn-encoding target
)
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
)
827 (writes reg-or-target
) (reads target
))
830 (when (tn-p reg-or-target
)
831 (reads reg-or-target
)))))
835 (setf target reg-or-target
836 reg-or-target lip-tn
))
839 (emit-register-inst segment special-op
(reg-tn-encoding target
) 0
840 (reg-tn-encoding reg-or-target
) 0 #b001001
))
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
)))
854 (:dependencies
(reads :float-status
))
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
)))
864 (:dependencies
(reads :float-status
))
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
))
881 (when (fixup-p value
)
882 (note-fixup segment
:lui value
)
884 (emit-immediate-inst segment
#b001111
0 (reg-tn-encoding reg
) value
)))
886 (defconstant-eqx mvsreg-printer
'(:name
:tab rd
)
889 (define-instruction mfhi
(segment reg
)
890 (:declare
(type tn reg
))
891 (:printer register
((op special-op
) (rs 0) (rt 0) (funct #b010000
))
893 (:dependencies
(reads :hi-reg
) (writes reg
))
896 (emit-register-inst segment special-op
0 0 (reg-tn-encoding reg
) 0
899 (define-instruction mthi
(segment reg
)
900 (:declare
(type tn reg
))
901 (:printer register
((op special-op
) (rs 0) (rt 0) (funct #b010001
))
903 (:dependencies
(reads reg
) (writes :hi-reg
))
906 (emit-register-inst segment special-op
0 0 (reg-tn-encoding reg
) 0
909 (define-instruction mflo
(segment reg
)
910 (:declare
(type tn reg
))
911 (:printer register
((op special-op
) (rs 0) (rt 0) (funct #b010010
))
913 (:dependencies
(reads :low-reg
) (writes reg
))
916 (emit-register-inst segment special-op
0 0 (reg-tn-encoding reg
) 0
919 (define-instruction mtlo
(segment reg
)
920 (:declare
(type tn reg
))
921 (:printer register
((op special-op
) (rs 0) (rt 0) (funct #b010011
))
923 (:dependencies
(reads reg
) (writes :low-reg
))
926 (emit-register-inst segment special-op
0 0 (reg-tn-encoding reg
) 0
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
))
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
))
947 (emit-float-inst segment cop1-op
1 (float-format-value format
) 0
948 (fp-reg-tn-encoding src
) (fp-reg-tn-encoding dst
)
951 (defun %li
(reg value
)
954 (inst or reg zero-tn value
))
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
)))
962 (inst addu reg value
))))
964 (define-instruction-macro 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
))
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
))
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))
990 (:dependencies
(reads from
) (writes to
))
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
))
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
))
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
))
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
))
1027 (emit-register-inst segment cop1-op
#b00010
(reg-tn-encoding reg
)
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
))
1037 (emit-register-inst segment cop1-op
#b00110
(reg-tn-encoding reg
)
1042 ;;;; Random system hackery and other noise
1044 (define-instruction-macro entry-point
()
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
))
1054 (values 0 (1+ length
) nil nil
))
1056 (copy-ub8-from-system-area sap
(1+ offset
) vector
0 length
)
1057 (collect ((sc-offsets)
1059 (lengths 1) ; the length byte
1061 (error-number (read-var-integer vector index
)))
1064 (when (>= index length
)
1066 (let ((old-index index
))
1067 (sc-offsets (read-var-integer vector index
))
1068 (lengths (- index old-index
))))
1069 (values error-number
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
)
1089 (#.pending-interrupt-trap
1090 (nt "Pending interrupt trap"))
1093 (handle-break-args #'snarf-error-junk stream dstate
))
1096 (handle-break-args #'snarf-error-junk stream dstate
))
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
)
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
))
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
)
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
))
1151 (emit-word segment word
)))
1153 (define-instruction short
(segment short
)
1154 (:declare
(type (or (unsigned-byte 16) (signed-byte 16)) short
))
1159 (emit-short segment short
)))
1161 (define-instruction byte
(segment byte
)
1162 (:declare
(type (or (unsigned-byte 8) (signed-byte 8)) byte
))
1167 (emit-byte segment byte
)))
1170 (defun emit-header-data (segment type
)
1173 #'(lambda (segment posn
)
1176 (ash (+ posn
(component-header-length))
1177 (- n-widetag-bits word-shift
)))))))
1179 (define-instruction simple-fun-header-word
(segment)
1184 (emit-header-data segment simple-fun-header-widetag
)))
1186 (define-instruction lra-header-word
(segment)
1191 (emit-header-data segment return-pc-header-widetag
)))
1194 (defun emit-compute-inst (segment vop dst src label temp calc
)
1196 ;; We emit either 12 or 4 bytes, so we maintain 8 byte alignments.
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
)
1205 (funcall calc label posn
0)))))
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
))
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
))
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
))
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
)
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
))
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
))
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
))
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
))
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
))
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
))
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
))
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
))
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
))
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
))
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
))
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
))
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
))
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
)
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
))
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
))
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
))
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
))
1424 (emit-fp-load/store-inst segment
#b111001 reg
1 base index
)))