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
#.
(apply #'vector compare-kinds
)
145 (deftype compare-kind
()
146 `(member ,@compare-kinds
))
148 (defun compare-kind (kind)
149 (or (position kind compare-kinds
)
150 (error "Unknown floating point compare kind: ~S~%Must be one of: ~S"
154 (define-arg-type compare-kind
:printer compare-kinds-vec
)
156 (defconstant-eqx float-operations
'(+ -
* /) #'equalp
)
158 (deftype float-operation
()
159 `(member ,@float-operations
))
161 (defconstant-eqx float-operation-names
162 ;; this gets used for output only
166 (defun float-operation (op)
167 (or (position op float-operations
)
168 (error "Unknown floating point operation: ~S~%Must be one of: ~S"
172 (define-arg-type float-operation
:printer float-operation-names
)
176 ;;;; Constants used by instruction emitters.
178 (defconstant special-op
#b000000
)
179 (defconstant bcond-op
#b000001
)
180 (defconstant cop0-op
#b010000
)
181 (defconstant cop1-op
#b010001
)
182 (defconstant cop2-op
#b010010
)
183 (defconstant cop3-op
#b010011
)
187 ;;;; dissassem:define-instruction-formats
189 (defconstant-eqx immed-printer
190 '(:name
:tab rt
(:unless
(:same-as rt
) ", " rs
) ", " immediate
)
193 ;;; for things that use rt=0 as a nop
194 (defconstant-eqx immed-zero-printer
195 '(:name
:tab rt
(:unless
(:constant
0) ", " rs
) ", " immediate
)
198 (define-instruction-format (immediate 32 :default-printer immed-printer
)
199 (op :field
(byte 6 26))
200 (rs :field
(byte 5 21) :type
'reg
)
201 (rt :field
(byte 5 16) :type
'reg
)
202 (immediate :field
(byte 16 0) :sign-extend t
))
204 (defconstant-eqx load-store-printer
208 (:unless
(:constant
0) "[" immediate
"]"))
211 (define-instruction-format
212 (load-store 32 :default-printer
'(:name
:tab
215 (:unless
(:constant
0) "[" immediate
"]")
216 load-store-annotation
)
218 (load-store-annotation :fields
(list (byte 5 21) (byte 16 0))
219 :type
'load-store-annotation
))
221 (eval-when (:compile-toplevel
:load-toplevel
:execute
)
222 (defparameter jump-printer
223 #'(lambda (value stream dstate
)
224 (let ((addr (ash value
2)))
225 (maybe-note-assembler-routine addr t dstate
)
226 (write addr
:base
16 :radix t
:stream stream
)))))
228 (define-instruction-format (jump 32 :default-printer
'(:name
:tab target
))
229 (op :field
(byte 6 26))
230 (target :field
(byte 26 0) :printer jump-printer
))
232 (defconstant-eqx reg-printer
233 '(:name
:tab rd
(:unless
(:same-as rd
) ", " rs
) ", " rt
)
236 (define-instruction-format (register 32 :default-printer reg-printer
)
237 (op :field
(byte 6 26))
238 (rs :field
(byte 5 21) :type
'reg
)
239 (rt :field
(byte 5 16) :type
'reg
)
240 (rd :field
(byte 5 11) :type
'reg
)
241 (shamt :field
(byte 5 6) :value
0)
242 (funct :field
(byte 6 0)))
244 (define-instruction-format
245 (break 32 :default-printer
246 '(:name
:tab code
(:unless
(:constant
0) ", " subcode
)))
247 (op :field
(byte 6 26) :value special-op
)
248 (code :field
(byte 10 16) :reader break-code
)
249 (subcode :field
(byte 10 6) :reader break-subcode
)
250 (funct :field
(byte 6 0) :value
#b001101
))
252 (define-instruction-format (coproc-branch 32
253 :default-printer
'(:name
:tab offset
))
254 (op :field
(byte 6 26))
255 (funct :field
(byte 10 16))
256 (offset :field
(byte 16 0)))
258 (defconstant-eqx float-fmt-printer
259 '((:unless
:constant funct
)
260 (:choose
(:unless
:constant sub-funct
) nil
)
264 (defconstant-eqx float-printer
265 `(:name
,@float-fmt-printer
268 (:unless
(:same-as fd
) ", " fs
)
272 (define-instruction-format (float 32 :default-printer float-printer
)
273 (op :field
(byte 6 26) :value cop1-op
)
274 (filler :field
(byte 1 25) :value
1)
275 (format :field
(byte 4 21) :type
'float-format
)
276 (ft :field
(byte 5 16) :value
0)
277 (fs :field
(byte 5 11) :type
'fp-reg
)
278 (fd :field
(byte 5 6) :type
'fp-reg
)
279 (funct :field
(byte 6 0)))
281 (define-instruction-format (float-aux 32 :default-printer float-printer
)
282 (op :field
(byte 6 26) :value cop1-op
)
283 (filler-1 :field
(byte 1 25) :value
1)
284 (format :field
(byte 4 21) :type
'float-format
)
285 (ft :field
(byte 5 16) :type
'fp-reg
)
286 (fs :field
(byte 5 11) :type
'fp-reg
)
287 (fd :field
(byte 5 6) :type
'fp-reg
)
288 (funct :field
(byte 2 4))
289 (sub-funct :field
(byte 4 0)))
291 (define-instruction-format
295 '('f funct
"." format
298 (:unless
(:same-as fd
) ", " fs
)
300 (funct :field
(byte 2 0) :type
'float-operation
)
301 (funct-filler :field
(byte 4 2) :value
0)
302 (ft :value nil
:type
'fp-reg
))
305 ;;;; Primitive emitters.
307 (define-bitfield-emitter emit-word
32
310 (define-bitfield-emitter emit-short
16
313 (define-bitfield-emitter emit-immediate-inst
32
314 (byte 6 26) (byte 5 21) (byte 5 16) (byte 16 0))
316 (define-bitfield-emitter emit-jump-inst
32
317 (byte 6 26) (byte 26 0))
319 (define-bitfield-emitter emit-register-inst
32
320 (byte 6 26) (byte 5 21) (byte 5 16) (byte 5 11) (byte 5 6) (byte 6 0))
322 (define-bitfield-emitter emit-break-inst
32
323 (byte 6 26) (byte 10 16) (byte 10 6) (byte 6 0))
325 (define-bitfield-emitter emit-float-inst
32
326 (byte 6 26) (byte 1 25) (byte 4 21) (byte 5 16)
327 (byte 5 11) (byte 5 6) (byte 6 0))
331 ;;;; Math instructions.
333 (defun emit-math-inst (segment dst src1 src2 reg-opcode immed-opcode
334 &optional allow-fixups
)
340 (emit-register-inst segment special-op
(reg-tn-encoding src1
)
341 (reg-tn-encoding src2
) (reg-tn-encoding dst
)
344 (emit-immediate-inst segment immed-opcode
(reg-tn-encoding src1
)
345 (reg-tn-encoding dst
) src2
))
348 (error "Fixups aren't allowed."))
349 (note-fixup segment
:addi src2
)
350 (emit-immediate-inst segment immed-opcode
(reg-tn-encoding src1
)
351 (reg-tn-encoding dst
) 0))))
353 (define-instruction add
(segment dst src1
&optional src2
)
354 (:declare
(type tn dst
)
355 (type (or tn
(signed-byte 16) null
) src1 src2
))
356 (:printer register
((op special-op
) (funct #b100000
)))
357 (:printer immediate
((op #b001000
)))
358 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
361 (emit-math-inst segment dst src1 src2
#b100000
#b001000
)))
363 (define-instruction addu
(segment dst src1
&optional src2
)
364 (:declare
(type tn dst
)
365 (type (or tn
(signed-byte 16) fixup null
) src1 src2
))
366 (:printer register
((op special-op
) (funct #b100001
)))
367 (:printer immediate
((op #b001001
)))
368 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
371 (emit-math-inst segment dst src1 src2
#b100001
#b001001 t
)))
373 (define-instruction sub
(segment dst src1
&optional src2
)
376 (type (or tn
(integer #.
(- 1 (ash 1 15)) #.
(ash 1 15)) null
) src1 src2
))
377 (:printer register
((op special-op
) (funct #b100010
)))
378 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
384 (emit-math-inst segment dst src1
385 (if (integerp src2
) (- src2
) src2
)
388 (define-instruction subu
(segment dst src1
&optional src2
)
392 (or tn
(integer #.
(- 1 (ash 1 15)) #.
(ash 1 15)) fixup null
) src1 src2
))
393 (:printer register
((op special-op
) (funct #b100011
)))
394 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
400 (emit-math-inst segment dst src1
401 (if (integerp src2
) (- src2
) src2
)
402 #b100011
#b001001 t
)))
404 (define-instruction and
(segment dst src1
&optional src2
)
405 (:declare
(type tn dst
)
406 (type (or tn
(unsigned-byte 16) null
) src1 src2
))
407 (:printer register
((op special-op
) (funct #b100100
)))
408 (:printer immediate
((op #b001100
) (immediate nil
:sign-extend nil
)))
409 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
412 (emit-math-inst segment dst src1 src2
#b100100
#b001100
)))
414 (define-instruction or
(segment dst src1
&optional src2
)
415 (:declare
(type tn dst
)
416 (type (or tn
(unsigned-byte 16) null
) src1 src2
))
417 (:printer register
((op special-op
) (funct #b100101
)))
418 (:printer immediate
((op #b001101
)))
419 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
422 (emit-math-inst segment dst src1 src2
#b100101
#b001101
)))
424 (define-instruction xor
(segment dst src1
&optional src2
)
425 (:declare
(type tn dst
)
426 (type (or tn
(unsigned-byte 16) null
) src1 src2
))
427 (:printer register
((op special-op
) (funct #b100110
)))
428 (:printer immediate
((op #b001110
)))
429 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
432 (emit-math-inst segment dst src1 src2
#b100110
#b001110
)))
434 (define-instruction nor
(segment dst src1
&optional src2
)
435 (:declare
(type tn dst src1
) (type (or tn null
) src2
))
436 (:printer register
((op special-op
) (funct #b100111
)))
437 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
440 (emit-math-inst segment dst src1 src2
#b100111
#b000000
)))
442 (define-instruction slt
(segment dst src1
&optional src2
)
443 (:declare
(type tn dst
)
444 (type (or tn
(signed-byte 16) null
) src1 src2
))
445 (:printer register
((op special-op
) (funct #b101010
)))
446 (:printer immediate
((op #b001010
)))
447 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
450 (emit-math-inst segment dst src1 src2
#b101010
#b001010
)))
452 (define-instruction sltu
(segment dst src1
&optional src2
)
453 (:declare
(type tn dst
)
454 (type (or tn
(signed-byte 16) null
) src1 src2
))
455 (:printer register
((op special-op
) (funct #b101011
)))
456 (:printer immediate
((op #b001011
)))
457 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
460 (emit-math-inst segment dst src1 src2
#b101011
#b001011
)))
462 (defconstant-eqx divmul-printer
'(:name
:tab rs
", " rt
) #'equalp
)
464 (define-instruction div
(segment src1 src2
)
465 (:declare
(type tn src1 src2
))
466 (:printer register
((op special-op
) (rd 0) (funct #b011010
)) divmul-printer
)
467 (:dependencies
(reads src1
) (reads src2
) (writes :hi-reg
) (writes :low-reg
))
470 (emit-register-inst segment special-op
(reg-tn-encoding src1
)
471 (reg-tn-encoding src2
) 0 0 #b011010
)))
473 (define-instruction divu
(segment src1 src2
)
474 (:declare
(type tn src1 src2
))
475 (:printer register
((op special-op
) (rd 0) (funct #b011011
))
477 (:dependencies
(reads src1
) (reads src2
) (writes :hi-reg
) (writes :low-reg
))
480 (emit-register-inst segment special-op
(reg-tn-encoding src1
)
481 (reg-tn-encoding src2
) 0 0 #b011011
)))
483 (define-instruction mult
(segment src1 src2
)
484 (:declare
(type tn src1 src2
))
485 (:printer register
((op special-op
) (rd 0) (funct #b011000
)) divmul-printer
)
486 (:dependencies
(reads src1
) (reads src2
) (writes :hi-reg
) (writes :low-reg
))
489 (emit-register-inst segment special-op
(reg-tn-encoding src1
)
490 (reg-tn-encoding src2
) 0 0 #b011000
)))
492 (define-instruction multu
(segment src1 src2
)
493 (:declare
(type tn src1 src2
))
494 (:printer register
((op special-op
) (rd 0) (funct #b011001
)))
495 (:dependencies
(reads src1
) (reads src2
) (writes :hi-reg
) (writes :low-reg
))
498 (emit-register-inst segment special-op
(reg-tn-encoding src1
)
499 (reg-tn-encoding src2
) 0 0 #b011001
)))
501 (defun emit-shift-inst (segment opcode dst src1 src2
)
507 (emit-register-inst segment special-op
(reg-tn-encoding src2
)
508 (reg-tn-encoding src1
) (reg-tn-encoding dst
)
509 0 (logior #b000100 opcode
)))
511 (emit-register-inst segment special-op
0 (reg-tn-encoding src1
)
512 (reg-tn-encoding dst
) src2 opcode
))))
514 (defconstant-eqx shift-printer
517 (:unless
(:same-as rd
) ", " rt
)
518 ", " (:cond
((rs :constant
0) shamt
)
522 (define-instruction sll
(segment dst src1
&optional src2
)
523 (:declare
(type tn dst
)
524 (type (or tn
(unsigned-byte 5) null
) src1 src2
))
525 (:printer register
((op special-op
) (rs 0) (shamt nil
) (funct #b000000
))
527 (:printer register
((op special-op
) (funct #b000100
)) shift-printer
)
528 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
531 (emit-shift-inst segment
#b00 dst src1 src2
)))
533 (define-instruction sra
(segment dst src1
&optional src2
)
534 (:declare
(type tn dst
)
535 (type (or tn
(unsigned-byte 5) null
) src1 src2
))
536 (:printer register
((op special-op
) (rs 0) (shamt nil
) (funct #b000011
))
538 (:printer register
((op special-op
) (funct #b000111
)) shift-printer
)
539 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
542 (emit-shift-inst segment
#b11 dst src1 src2
)))
544 (define-instruction srl
(segment dst src1
&optional src2
)
545 (:declare
(type tn dst
)
546 (type (or tn
(unsigned-byte 5) null
) src1 src2
))
547 (:printer register
((op special-op
) (rs 0) (shamt nil
) (funct #b000010
))
549 (:printer register
((op special-op
) (funct #b000110
)) shift-printer
)
550 (:dependencies
(reads src1
) (if src2
(reads src2
) (reads dst
)) (writes dst
))
553 (emit-shift-inst segment
#b10 dst src1 src2
)))
556 ;;;; Floating point math.
558 (define-instruction float-op
(segment operation format dst src1 src2
)
559 (:declare
(type float-operation operation
)
560 (type float-format format
)
561 (type tn dst src1 src2
))
562 (:printer float-op
())
563 (:dependencies
(reads src1
) (reads src2
) (writes dst
))
566 (emit-float-inst segment cop1-op
1 (float-format-value format
)
567 (fp-reg-tn-encoding src2
) (fp-reg-tn-encoding src1
)
568 (fp-reg-tn-encoding dst
) (float-operation operation
))))
570 (defconstant-eqx float-unop-printer
571 `(:name
,@float-fmt-printer
:tab fd
(:unless
(:same-as fd
) ", " fs
))
574 (define-instruction fabs
(segment format dst
&optional
(src dst
))
575 (:declare
(type float-format format
) (type tn dst src
))
576 (:printer float
((funct #b000101
)) float-unop-printer
)
577 (:dependencies
(reads src
) (writes dst
))
580 (emit-float-inst segment cop1-op
1 (float-format-value format
)
581 0 (fp-reg-tn-encoding src
) (fp-reg-tn-encoding dst
)
584 (define-instruction fneg
(segment format dst
&optional
(src dst
))
585 (:declare
(type float-format format
) (type tn dst src
))
586 (:printer float
((funct #b000111
)) float-unop-printer
)
587 (:dependencies
(reads src
) (writes dst
))
590 (emit-float-inst segment cop1-op
1 (float-format-value format
)
591 0 (fp-reg-tn-encoding src
) (fp-reg-tn-encoding dst
)
594 (define-instruction fcvt
(segment format1 format2 dst src
)
595 (:declare
(type float-format format1 format2
) (type tn dst src
))
596 (:printer float-aux
((funct #b10
) (sub-funct nil
:type
'float-format
))
597 `(:name
"." sub-funct
"." format
:tab fd
", " fs
))
598 (:dependencies
(reads src
) (writes dst
))
601 (emit-float-inst segment cop1-op
1 (float-format-value format2
) 0
602 (fp-reg-tn-encoding src
) (fp-reg-tn-encoding dst
)
603 (logior #b100000
(float-format-value format1
)))))
605 (define-instruction fcmp
(segment operation format fs ft
)
606 (:declare
(type compare-kind operation
)
607 (type float-format format
)
609 (:printer float-aux
((fd 0) (funct #b11
) (sub-funct nil
:type
'compare-kind
))
610 `(:name
"-" sub-funct
"." format
:tab fs
", " ft
))
611 (:dependencies
(reads fs
) (reads ft
) (writes :float-status
))
614 (emit-float-inst segment cop1-op
1 (float-format-value format
)
615 (fp-reg-tn-encoding ft
) (fp-reg-tn-encoding fs
) 0
616 (logior #b110000
(compare-kind operation
)))))
619 ;;;; Branch/Jump instructions.
621 (defun emit-relative-branch (segment opcode r1 r2 target
)
624 #'(lambda (segment posn magic-value
)
625 (declare (ignore magic-value
))
626 (let ((delta (ash (- (label-position target
) (+ posn
4)) -
2)))
627 (when (typep delta
'(signed-byte 16))
628 (emit-back-patch segment
4
629 #'(lambda (segment posn
)
630 (emit-immediate-inst segment
634 (reg-tn-encoding r1
))
637 (reg-tn-encoding r2
))
638 (ash (- (label-position target
)
642 #'(lambda (segment posn
)
643 (declare (ignore posn
))
645 ;; invert branch condition
646 (if (or (= opcode bcond-op
) (= opcode cop1-op
))
647 (setf r2
(logxor r2
#b00001
))
648 (setf opcode
(logxor opcode
#b00001
)))
650 (if (= opcode bcond-op
)
651 (if (logand r2
#b10000
)
652 (progn (setf r2
(logand r2
#b01111
))
654 (emit-immediate-inst segment
656 (if (fixnump r1
) r1
(reg-tn-encoding r1
))
657 (if (fixnump r2
) r2
(reg-tn-encoding r2
))
660 (emit-back-patch segment
8
661 #'(lambda (segment posn
)
662 (declare (ignore posn
))
663 (emit-immediate-inst segment
#b001111
0
664 (reg-tn-encoding lip-tn
)
666 (label-position target
)))
667 (emit-immediate-inst segment
#b001101
0
668 (reg-tn-encoding lip-tn
)
670 (label-position target
)))))
671 (emit-register-inst segment special-op
(reg-tn-encoding lip-tn
)
673 (if linked
#b001001
#b001000
))))))
675 (define-instruction b
(segment target
)
676 (:declare
(type label target
))
677 (:printer immediate
((op #b000100
) (rs 0) (rt 0)
678 (immediate nil
:type
'relative-label
))
679 '(:name
:tab immediate
))
683 (emit-relative-branch segment
#b000100
0 0 target
)))
685 (define-instruction bal
(segment target
)
686 (:declare
(type label target
))
687 (:printer immediate
((op bcond-op
) (rs 0) (rt #b01001
)
688 (immediate nil
:type
'relative-label
))
689 '(:name
:tab immediate
))
691 (:dependencies
(writes lip-tn
))
694 (emit-relative-branch segment bcond-op
0 #b10001 target
)))
696 (define-instruction beq
(segment r1 r2-or-target
&optional target
)
697 (:declare
(type tn r1
)
698 (type (or tn fixnum label
) r2-or-target
)
699 (type (or label null
) target
))
700 (:printer immediate
((op #b000100
) (immediate nil
:type
'relative-label
)))
702 (:dependencies
(reads r1
) (if target
(reads r2-or-target
)))
706 (setf target r2-or-target
)
707 (setf r2-or-target
0))
708 (emit-relative-branch segment
#b000100 r1 r2-or-target target
)))
710 (define-instruction bne
(segment r1 r2-or-target
&optional target
)
711 (:declare
(type tn r1
)
712 (type (or tn fixnum label
) r2-or-target
)
713 (type (or label null
) target
))
714 (:printer immediate
((op #b000101
) (immediate nil
:type
'relative-label
)))
716 (:dependencies
(reads r1
) (if target
(reads r2-or-target
)))
720 (setf target r2-or-target
)
721 (setf r2-or-target
0))
722 (emit-relative-branch segment
#b000101 r1 r2-or-target target
)))
724 (defconstant-eqx cond-branch-printer
725 '(:name
:tab rs
", " immediate
)
728 (define-instruction blez
(segment reg target
)
729 (:declare
(type label target
) (type tn reg
))
731 immediate
((op #b000110
) (rt 0) (immediate nil
:type
'relative-label
))
734 (:dependencies
(reads reg
))
737 (emit-relative-branch segment
#b000110 reg
0 target
)))
739 (define-instruction bgtz
(segment reg target
)
740 (:declare
(type label target
) (type tn reg
))
742 immediate
((op #b000111
) (rt 0) (immediate nil
:type
'relative-label
))
745 (:dependencies
(reads reg
))
748 (emit-relative-branch segment
#b000111 reg
0 target
)))
750 (define-instruction bltz
(segment reg target
)
751 (:declare
(type label target
) (type tn reg
))
753 immediate
((op bcond-op
) (rt 0) (immediate nil
:type
'relative-label
))
756 (:dependencies
(reads reg
))
759 (emit-relative-branch segment bcond-op reg
#b00000 target
)))
761 (define-instruction bgez
(segment reg target
)
762 (:declare
(type label target
) (type tn reg
))
764 immediate
((op bcond-op
) (rt 1) (immediate nil
:type
'relative-label
))
767 (:dependencies
(reads reg
))
770 (emit-relative-branch segment bcond-op reg
#b00001 target
)))
772 (define-instruction bltzal
(segment reg target
)
773 (:declare
(type label target
) (type tn reg
))
775 immediate
((op bcond-op
) (rt #b01000
) (immediate nil
:type
'relative-label
))
778 (:dependencies
(reads reg
) (writes lip-tn
))
781 (emit-relative-branch segment bcond-op reg
#b10000 target
)))
783 (define-instruction bgezal
(segment reg target
)
784 (:declare
(type label target
) (type tn reg
))
786 immediate
((op bcond-op
) (rt #b01001
) (immediate nil
:type
'relative-label
))
790 (:dependencies
(reads reg
) (writes lip-tn
))
792 (emit-relative-branch segment bcond-op reg
#b10001 target
)))
794 (defconstant-eqx j-printer
795 '(:name
:tab
(:choose rs target
))
798 (define-instruction j
(segment target
)
799 (:declare
(type (or tn fixup
) target
))
800 (:printer register
((op special-op
) (rt 0) (rd 0) (funct #b001000
))
802 (:printer jump
((op #b000010
)) j-printer
)
804 (:dependencies
(reads target
))
809 (emit-register-inst segment special-op
(reg-tn-encoding target
)
812 (note-fixup segment
:lui target
)
813 (emit-immediate-inst segment
#b001111
0 28 0)
814 (note-fixup segment
:addi target
)
815 (emit-immediate-inst segment
#b001001
28 28 0)
816 (emit-register-inst segment special-op
28 0 0 0 #b001000
)))))
818 (define-instruction jal
(segment reg-or-target
&optional target
)
819 (:declare
(type (or null tn fixup
) target
)
820 (type (or tn fixup
) reg-or-target
))
821 (:printer register
((op special-op
) (rt 0) (funct #b001001
)) j-printer
)
822 (:printer jump
((op #b000011
)) j-printer
)
826 (writes reg-or-target
) (reads target
))
829 (when (tn-p reg-or-target
)
830 (reads reg-or-target
)))))
834 (setf target reg-or-target
835 reg-or-target lip-tn
))
838 (emit-register-inst segment special-op
(reg-tn-encoding target
) 0
839 (reg-tn-encoding reg-or-target
) 0 #b001001
))
841 (note-fixup segment
:lui target
)
842 (emit-immediate-inst segment
#b001111
0 28 0)
843 (note-fixup segment
:addi target
)
844 (emit-immediate-inst segment
#b001001
28 28 0)
845 (emit-register-inst segment special-op
28 0
846 (reg-tn-encoding reg-or-target
) 0 #b001001
)))))
848 (define-instruction bc1f
(segment target
)
849 (:declare
(type label target
))
850 (:printer coproc-branch
((op cop1-op
) (funct #x100
)
851 (offset nil
:type
'relative-label
)))
853 (:dependencies
(reads :float-status
))
856 (emit-relative-branch segment cop1-op
#b01000
#b00000 target
)))
858 (define-instruction bc1t
(segment target
)
859 (:declare
(type label target
))
860 (:printer coproc-branch
((op cop1-op
) (funct #x101
)
861 (offset nil
:type
'relative-label
)))
863 (:dependencies
(reads :float-status
))
866 (emit-relative-branch segment cop1-op
#b01000
#b00001 target
)))
870 ;;;; Random movement instructions.
872 (define-instruction lui
(segment reg value
)
873 (:declare
(type tn reg
)
874 (type (or fixup
(signed-byte 16) (unsigned-byte 16)) value
))
875 (:printer immediate
((op #b001111
)
876 (immediate nil
:sign-extend nil
:printer
"#x~4,'0X")))
877 (:dependencies
(writes reg
))
880 (when (fixup-p value
)
881 (note-fixup segment
:lui value
)
883 (emit-immediate-inst segment
#b001111
0 (reg-tn-encoding reg
) value
)))
885 (defconstant-eqx mvsreg-printer
'(:name
:tab rd
)
888 (define-instruction mfhi
(segment reg
)
889 (:declare
(type tn reg
))
890 (:printer register
((op special-op
) (rs 0) (rt 0) (funct #b010000
))
892 (:dependencies
(reads :hi-reg
) (writes reg
))
895 (emit-register-inst segment special-op
0 0 (reg-tn-encoding reg
) 0
898 (define-instruction mthi
(segment reg
)
899 (:declare
(type tn reg
))
900 (:printer register
((op special-op
) (rs 0) (rt 0) (funct #b010001
))
902 (:dependencies
(reads reg
) (writes :hi-reg
))
905 (emit-register-inst segment special-op
0 0 (reg-tn-encoding reg
) 0
908 (define-instruction mflo
(segment reg
)
909 (:declare
(type tn reg
))
910 (:printer register
((op special-op
) (rs 0) (rt 0) (funct #b010010
))
912 (:dependencies
(reads :low-reg
) (writes reg
))
915 (emit-register-inst segment special-op
0 0 (reg-tn-encoding reg
) 0
918 (define-instruction mtlo
(segment reg
)
919 (:declare
(type tn reg
))
920 (:printer register
((op special-op
) (rs 0) (rt 0) (funct #b010011
))
922 (:dependencies
(reads reg
) (writes :low-reg
))
925 (emit-register-inst segment special-op
0 0 (reg-tn-encoding reg
) 0
928 (define-instruction move
(segment dst src
)
929 (:declare
(type tn dst src
))
930 (:printer register
((op special-op
) (rt 0) (funct #b100001
))
931 '(:name
:tab rd
", " rs
))
932 (:attributes flushable
)
933 (:dependencies
(reads src
) (writes dst
))
936 (emit-register-inst segment special-op
(reg-tn-encoding src
) 0
937 (reg-tn-encoding dst
) 0 #b100001
)))
939 (define-instruction fmove
(segment format dst src
)
940 (:declare
(type float-format format
) (type tn dst src
))
941 (:printer float
((funct #b000110
)) '(:name
"." format
:tab fd
", " fs
))
942 (:attributes flushable
)
943 (:dependencies
(reads src
) (writes dst
))
946 (emit-float-inst segment cop1-op
1 (float-format-value format
) 0
947 (fp-reg-tn-encoding src
) (fp-reg-tn-encoding dst
)
950 (defun %li
(reg value
)
953 (inst or reg zero-tn value
))
955 (inst addu reg zero-tn value
))
956 ((or (signed-byte 32) (unsigned-byte 32))
957 (inst lui reg
(ldb (byte 16 16) value
))
958 (inst or reg
(ldb (byte 16 0) value
)))
961 (inst addu reg value
))))
963 (define-instruction-macro li
(reg value
)
966 (defconstant-eqx sub-op-printer
'(:name
:tab rd
", " rt
) #'equalp
)
968 (define-instruction mtc1
(segment to from
)
969 (:declare
(type tn to from
))
970 (:printer register
((op cop1-op
) (rs #b00100
) (funct 0)) sub-op-printer
)
971 (:dependencies
(reads from
) (writes to
))
974 (emit-register-inst segment cop1-op
#b00100
(reg-tn-encoding from
)
975 (fp-reg-tn-encoding to
) 0 0)))
977 (define-instruction mtc1-odd
(segment to from
)
978 (:declare
(type tn to from
))
979 (:dependencies
(reads from
) (writes to
))
982 (emit-register-inst segment cop1-op
#b00100
(reg-tn-encoding from
)
983 (1+ (fp-reg-tn-encoding to
)) 0 0)))
985 (define-instruction mfc1
(segment to from
)
986 (:declare
(type tn to from
))
987 (:printer register
((op cop1-op
) (rs 0) (rd nil
:type
'fp-reg
) (funct 0))
989 (:dependencies
(reads from
) (writes to
))
992 (emit-register-inst segment cop1-op
#b00000
(reg-tn-encoding to
)
993 (fp-reg-tn-encoding from
) 0 0)))
995 (define-instruction mfc1-odd
(segment to from
)
996 (:declare
(type tn to from
))
997 (:dependencies
(reads from
) (writes to
))
1000 (emit-register-inst segment cop1-op
#b00000
(reg-tn-encoding to
)
1001 (1+ (fp-reg-tn-encoding from
)) 0 0)))
1003 (define-instruction mfc1-odd2
(segment to from
)
1004 (:declare
(type tn to from
))
1005 (:dependencies
(reads from
) (writes to
))
1008 (emit-register-inst segment cop1-op
#b00000
(1+ (reg-tn-encoding to
))
1009 (fp-reg-tn-encoding from
) 0 0)))
1011 (define-instruction mfc1-odd3
(segment to from
)
1012 (:declare
(type tn to from
))
1013 (:dependencies
(reads from
) (writes to
))
1016 (emit-register-inst segment cop1-op
#b00000
(1+ (reg-tn-encoding to
))
1017 (1+ (fp-reg-tn-encoding from
)) 0 0)))
1019 (define-instruction cfc1
(segment reg cr
)
1020 (:declare
(type tn reg
) (type (unsigned-byte 5) cr
))
1021 (:printer register
((op cop1-op
) (rs #b00010
) (rd nil
:type
'control-reg
)
1022 (funct 0)) sub-op-printer
)
1023 (:dependencies
(reads :ctrl-stat-reg
) (writes reg
))
1026 (emit-register-inst segment cop1-op
#b00010
(reg-tn-encoding reg
)
1029 (define-instruction ctc1
(segment reg cr
)
1030 (:declare
(type tn reg
) (type (unsigned-byte 5) cr
))
1031 (:printer register
((op cop1-op
) (rs #b00110
) (rd nil
:type
'control-reg
)
1032 (funct 0)) sub-op-printer
)
1033 (:dependencies
(reads reg
) (writes :ctrl-stat-reg
))
1036 (emit-register-inst segment cop1-op
#b00110
(reg-tn-encoding reg
)
1041 ;;;; Random system hackery and other noise
1043 (define-instruction-macro entry-point
()
1046 (defmacro break-cases
(breaknum &body cases
)
1047 (let ((bn-temp (gensym)))
1048 (collect ((clauses))
1049 (dolist (case cases
)
1050 (clauses `((= ,bn-temp
,(car case
)) ,@(cdr case
))))
1051 `(let ((,bn-temp
,breaknum
))
1052 (cond ,@(clauses))))))
1054 (defun break-control (chunk inst stream dstate
)
1055 (declare (ignore inst
))
1056 (flet ((nt (x) (if stream
(note x dstate
))))
1057 (when (= (break-code chunk dstate
) 0)
1058 (case (break-subcode chunk dstate
)
1061 (#.pending-interrupt-trap
1062 (nt "Pending interrupt trap"))
1065 (handle-break-args #'snarf-error-junk stream dstate
))
1068 (handle-break-args #'snarf-error-junk stream dstate
))
1070 (nt "Breakpoint trap"))
1071 (#.fun-end-breakpoint-trap
1072 (nt "Function end breakpoint trap"))
1073 (#.after-breakpoint-trap
1074 (nt "After breakpoint trap"))
1075 (#.single-step-around-trap
1076 (nt "Single step around trap"))
1077 (#.single-step-before-trap
1078 (nt "Single step before trap"))))))
1080 (define-instruction break
(segment code
&optional
(subcode 0))
1081 (:declare
(type (unsigned-byte 10) code subcode
))
1082 (:printer break
((op special-op
) (funct #b001101
))
1083 '(:name
:tab code
(:unless
(:constant
0) ", " subcode
))
1084 :control
#'break-control
)
1089 (emit-break-inst segment special-op code subcode
#b001101
)))
1091 (define-instruction syscall
(segment)
1092 (:printer register
((op special-op
) (rd 0) (rt 0) (rs 0) (funct #b001110
))
1097 (emit-register-inst segment special-op
0 0 0 0 #b001110
)))
1099 (define-instruction nop
(segment)
1100 (:printer register
((op 0) (rd 0) (rs 0) (funct 0)) '(:name
))
1101 (:attributes flushable
)
1104 (emit-word segment
0)))
1106 (defun emit-nop (segment)
1107 (emit-word segment
0))
1109 (define-instruction word
(segment word
)
1116 (note-fixup segment
:absolute word
)
1117 (emit-word segment
0))
1119 (emit-word segment word
)))))
1121 (define-instruction short
(segment short
)
1122 (:declare
(type (or (unsigned-byte 16) (signed-byte 16)) short
))
1127 (emit-short segment short
)))
1129 (define-instruction byte
(segment byte
)
1130 (:declare
(type (or (unsigned-byte 8) (signed-byte 8)) byte
))
1135 (emit-byte segment byte
)))
1138 (defun emit-header-data (segment type
)
1141 #'(lambda (segment posn
)
1144 (ash (+ posn
(component-header-length))
1145 (- n-widetag-bits word-shift
)))))))
1147 (define-instruction simple-fun-header-word
(segment)
1152 (emit-header-data segment simple-fun-header-widetag
)))
1154 (define-instruction lra-header-word
(segment)
1159 (emit-header-data segment return-pc-header-widetag
)))
1162 (defun emit-compute-inst (segment vop dst src label temp calc
)
1164 ;; We emit either 12 or 4 bytes, so we maintain 8 byte alignments.
1166 #'(lambda (segment posn delta-if-after
)
1167 (let ((delta (funcall calc label posn delta-if-after
)))
1168 (when (typep delta
'(signed-byte 16))
1169 (emit-back-patch segment
4
1170 #'(lambda (segment posn
)
1171 (assemble (segment vop
)
1173 (funcall calc label posn
0)))))
1175 #'(lambda (segment posn
)
1176 (let ((delta (funcall calc label posn
0)))
1177 (assemble (segment vop
)
1178 (inst lui temp
(ldb (byte 16 16) delta
))
1179 (inst or temp
(ldb (byte 16 0) delta
))
1180 (inst addu dst src temp
))))))
1182 ;; code = lip - header - label-offset + other-pointer-lowtag
1183 (define-instruction compute-code-from-lip
(segment dst src label temp
)
1184 (:declare
(type tn dst src temp
) (type label label
))
1185 (:attributes variable-length
)
1186 (:dependencies
(reads src
) (writes dst
) (writes temp
))
1190 (emit-compute-inst segment vop dst src label temp
1191 #'(lambda (label posn delta-if-after
)
1192 (- other-pointer-lowtag
1193 (label-position label posn delta-if-after
)
1194 (component-header-length))))))
1196 ;; code = lra - other-pointer-tag - header - label-offset + other-pointer-tag
1197 ;; = lra - (header + label-offset)
1198 (define-instruction compute-code-from-lra
(segment dst src label temp
)
1199 (:declare
(type tn dst src temp
) (type label label
))
1200 (:attributes variable-length
)
1201 (:dependencies
(reads src
) (writes dst
) (writes temp
))
1205 (emit-compute-inst segment vop dst src label temp
1206 #'(lambda (label posn delta-if-after
)
1207 (- (+ (label-position label posn delta-if-after
)
1208 (component-header-length)))))))
1210 ;; lra = code + other-pointer-tag + header + label-offset - other-pointer-tag
1211 ;; = code + header + label-offset
1212 (define-instruction compute-lra-from-code
(segment dst src label temp
)
1213 (:declare
(type tn dst src temp
) (type label label
))
1214 (:attributes variable-length
)
1215 (:dependencies
(reads src
) (writes dst
) (writes temp
))
1219 (emit-compute-inst segment vop dst src label temp
1220 #'(lambda (label posn delta-if-after
)
1221 (+ (label-position label posn delta-if-after
)
1222 (component-header-length))))))
1225 ;;;; Loads and Stores
1227 (defun emit-load/store-inst
(segment opcode reg base index
1228 &optional
(oddhack 0))
1229 (when (fixup-p index
)
1230 (note-fixup segment
:addi index
)
1232 (emit-immediate-inst segment opcode
(reg-tn-encoding reg
)
1233 (+ (reg-tn-encoding base
) oddhack
) index
))
1235 (define-instruction lb
(segment reg base
&optional
(index 0))
1236 (:declare
(type tn reg base
)
1237 (type (or (signed-byte 16) fixup
) index
))
1238 (:printer immediate
((op #b100000
)) load-store-printer
)
1239 (:dependencies
(reads base
) (reads :memory
) (writes reg
))
1242 (emit-load/store-inst segment
#b100000 base reg index
)))
1244 (define-instruction lh
(segment reg base
&optional
(index 0))
1245 (:declare
(type tn reg base
)
1246 (type (or (signed-byte 16) fixup
) index
))
1247 (:printer immediate
((op #b100001
)) load-store-printer
)
1248 (:dependencies
(reads base
) (reads :memory
) (writes reg
))
1251 (emit-load/store-inst segment
#b100001 base reg index
)))
1253 (define-instruction lwl
(segment reg base
&optional
(index 0))
1254 (:declare
(type tn reg base
)
1255 (type (or (signed-byte 16) fixup
) index
))
1256 (:printer immediate
((op #b100010
)) load-store-printer
)
1257 (:dependencies
(reads base
) (reads :memory
) (writes reg
))
1260 (emit-load/store-inst segment
#b100010 base reg index
)))
1262 (define-instruction lw
(segment reg base
&optional
(index 0))
1263 (:declare
(type tn reg base
)
1264 (type (or (signed-byte 16) fixup
) index
))
1265 (:printer load-store
((op #b100011
)))
1266 (:dependencies
(reads base
) (reads :memory
) (writes reg
))
1269 (emit-load/store-inst segment
#b100011 base reg index
)))
1271 ;; next is just for ease of coding double-in-int c-call convention
1272 (define-instruction lw-odd
(segment reg base
&optional
(index 0))
1273 (:declare
(type tn reg base
)
1274 (type (or (signed-byte 16) fixup
) index
))
1275 (:dependencies
(reads base
) (reads :memory
) (writes reg
))
1278 (emit-load/store-inst segment
#b100011 base reg index
1)))
1280 (define-instruction lbu
(segment reg base
&optional
(index 0))
1281 (:declare
(type tn reg base
)
1282 (type (or (signed-byte 16) fixup
) index
))
1283 (:printer immediate
((op #b100100
)) load-store-printer
)
1284 (:dependencies
(reads base
) (reads :memory
) (writes reg
))
1287 (emit-load/store-inst segment
#b100100 base reg index
)))
1289 (define-instruction lhu
(segment reg base
&optional
(index 0))
1290 (:declare
(type tn reg base
)
1291 (type (or (signed-byte 16) fixup
) index
))
1292 (:printer immediate
((op #b100101
)) load-store-printer
)
1293 (:dependencies
(reads base
) (reads :memory
) (writes reg
))
1296 (emit-load/store-inst segment
#b100101 base reg index
)))
1298 (define-instruction lwr
(segment reg base
&optional
(index 0))
1299 (:declare
(type tn reg base
)
1300 (type (or (signed-byte 16) fixup
) index
))
1301 (:printer immediate
((op #b100110
)) load-store-printer
)
1302 (:dependencies
(reads base
) (reads :memory
) (writes reg
))
1305 (emit-load/store-inst segment
#b100110 base reg index
)))
1307 (define-instruction sb
(segment reg base
&optional
(index 0))
1308 (:declare
(type tn reg base
)
1309 (type (or (signed-byte 16) fixup
) index
))
1310 (:printer immediate
((op #b101000
)) load-store-printer
)
1311 (:dependencies
(reads base
) (reads reg
) (writes :memory
))
1314 (emit-load/store-inst segment
#b101000 base reg index
)))
1316 (define-instruction sh
(segment reg base
&optional
(index 0))
1317 (:declare
(type tn reg base
)
1318 (type (or (signed-byte 16) fixup
) index
))
1319 (:printer immediate
((op #b101001
)) load-store-printer
)
1320 (:dependencies
(reads base
) (reads reg
) (writes :memory
))
1323 (emit-load/store-inst segment
#b101001 base reg index
)))
1325 (define-instruction swl
(segment reg base
&optional
(index 0))
1326 (:declare
(type tn reg base
)
1327 (type (or (signed-byte 16) fixup
) index
))
1328 (:printer immediate
((op #b101010
)) load-store-printer
)
1329 (:dependencies
(reads base
) (reads reg
) (writes :memory
))
1332 (emit-load/store-inst segment
#b101010 base reg index
)))
1334 (define-instruction sw
(segment reg base
&optional
(index 0))
1335 (:declare
(type tn reg base
)
1336 (type (or (signed-byte 16) fixup
) index
))
1337 (:printer immediate
((op #b101011
)) load-store-printer
)
1338 (:dependencies
(reads base
) (reads reg
) (writes :memory
))
1341 (emit-load/store-inst segment
#b101011 base reg index
)))
1343 (define-instruction swr
(segment reg base
&optional
(index 0))
1344 (:declare
(type tn reg base
)
1345 (type (or (signed-byte 16) fixup
) index
))
1346 (:printer immediate
((op #b101110
)) load-store-printer
)
1347 (:dependencies
(reads base
) (reads reg
) (writes :memory
))
1350 (emit-load/store-inst segment
#b101110 base reg index
)))
1353 (defun emit-fp-load/store-inst
(segment opcode reg odd base index
)
1354 (when (fixup-p index
)
1355 (note-fixup segment
:addi index
)
1357 (emit-immediate-inst segment opcode
(reg-tn-encoding base
)
1358 (+ (fp-reg-tn-encoding reg
) odd
) index
))
1360 (define-instruction lwc1
(segment reg base
&optional
(index 0))
1361 (:declare
(type tn reg base
)
1362 (type (or (signed-byte 16) fixup
) index
))
1363 (:printer immediate
((op #b110001
) (rt nil
:type
'fp-reg
)) load-store-printer
)
1364 (:dependencies
(reads base
) (reads :memory
) (writes reg
))
1367 (emit-fp-load/store-inst segment
#b110001 reg
0 base index
)))
1369 (define-instruction lwc1-odd
(segment reg base
&optional
(index 0))
1370 (:declare
(type tn reg base
)
1371 (type (or (signed-byte 16) fixup
) index
))
1372 (:dependencies
(reads base
) (reads :memory
) (writes reg
))
1375 (emit-fp-load/store-inst segment
#b110001 reg
1 base index
)))
1377 (define-instruction swc1
(segment reg base
&optional
(index 0))
1378 (:declare
(type tn reg base
)
1379 (type (or (signed-byte 16) fixup
) index
))
1380 (:printer immediate
((op #b111001
) (rt nil
:type
'fp-reg
)) load-store-printer
)
1381 (:dependencies
(reads base
) (reads reg
) (writes :memory
))
1384 (emit-fp-load/store-inst segment
#b111001 reg
0 base index
)))
1386 (define-instruction swc1-odd
(segment reg base
&optional
(index 0))
1387 (:declare
(type tn reg base
)
1388 (type (or (signed-byte 16) fixup
) index
))
1389 (:dependencies
(reads base
) (reads reg
) (writes :memory
))
1392 (emit-fp-load/store-inst segment
#b111001 reg
1 base index
)))