cdb9d3db5fe0fabb9772219d3ab12a85688ff36e
[sbcl.git] / src / compiler / sparc / insts.lisp
1 ;;;; the instruction set definition for the Sparc
2
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.
11
12 (in-package "SB!VM")
13
14 ;;;FIXME: the analogue is commented out in alpha/insts.lisp
15 ;;;(def-assembler-params
16 ;;;    :scheduler-p t
17 ;;;  :max-locations 100)
18 (eval-when (:compile-toplevel :load-toplevel :execute)
19   (setf sb!assem:*assem-scheduler-p* t)
20   (setf sb!assem:*assem-max-locations* 100))
21 \f
22 ;;; Constants, types, conversion functions, some disassembler stuff.
23 (defun reg-tn-encoding (tn)
24   (declare (type tn tn))
25   (sc-case tn
26     (zero zero-offset)
27     (null null-offset)
28     (t
29      (if (eq (sb-name (sc-sb (tn-sc tn))) 'registers)
30          (tn-offset tn)
31          (error "~S isn't a register." tn)))))
32
33 (defun fp-reg-tn-encoding (tn)
34   (declare (type tn tn))
35   (unless (eq (sb-name (sc-sb (tn-sc tn))) 'float-registers)
36     (error "~S isn't a floating-point register." tn))
37   (let ((offset (tn-offset tn)))
38     (cond ((> offset 31)
39            (assert (member :sparc-v9 *backend-subfeatures*))
40            ;; No single register encoding greater than reg 31.
41            (assert (zerop (mod offset 2)))
42            ;; Upper bit of the register number is encoded in the low bit.
43            (1+ (- offset 32)))
44           (t
45            (tn-offset tn)))))
46
47 ;;;(sb!disassem:set-disassem-params :instruction-alignment 32
48 ;;;                              :opcode-column-width 11)
49
50 (defvar *disassem-use-lisp-reg-names* t
51   #!+sb-doc
52   "If non-NIL, print registers using the Lisp register names.
53 Otherwise, use the Sparc register names")
54
55 (!def-vm-support-routine location-number (loc)
56   (etypecase loc
57     (null)
58     (number)
59     (fixup)
60     (tn
61      (ecase (sb-name (sc-sb (tn-sc loc)))
62        (registers
63         (unless (zerop (tn-offset loc))
64           (tn-offset loc)))
65        (float-registers
66         (sc-case loc
67           (single-reg
68            (+ (tn-offset loc) 32))
69           (double-reg
70            (let ((offset (tn-offset loc)))
71              (assert (zerop (mod offset 2)))
72              (values (+ offset 32) 2)))
73           #!+long-float
74           (long-reg
75            (let ((offset (tn-offset loc)))
76              (assert (zerop (mod offset 4)))
77              (values (+ offset 32) 4)))))
78        (control-registers
79         96)
80        (immediate-constant
81         nil)))
82     (symbol
83      (ecase loc
84        (:memory 0)
85        (:psr 97)
86        (:fsr 98)
87        (:y 99)))))
88
89 ;;; symbols used for disassembly printing
90 (defparameter reg-symbols
91   (map 'vector
92        (lambda (name)
93            (cond ((null name) nil)
94                  (t (make-symbol (concatenate 'string "%" name)))))
95        *register-names*)
96   #!+sb-doc "The Lisp names for the Sparc integer registers")
97
98 (defparameter sparc-reg-symbols
99   #("%G0" "%G1" "%G2" "%G3" "%G4" "%G5" NIL NIL
100     "%O0" "%O1" "%O2" "%O3" "%O4" "%O5" "%O6" "%O7"
101     "%L0" "%L1" "%L2" "%L3" "%L4" "%L5" "%L6" "%L7"
102     "%I0" "%I1" "%I2" "%I3" "%I4" "%I5" NIL "%I7")
103   #!+sb-doc "The standard names for the Sparc integer registers")
104     
105 (defun get-reg-name (index)
106   (if *disassem-use-lisp-reg-names*
107       (aref reg-symbols index)
108       (aref sparc-reg-symbols index)))
109
110 (defvar *note-sethi-inst* nil
111   "An alist for the disassembler indicating the target register and
112 value used in a SETHI instruction.  This is used to make annotations
113 about function addresses and register values.")
114
115 (defvar *pseudo-atomic-set* nil)
116
117 (defun sign-extend-immed-value (val)
118   ;; val is a 13-bit signed number.  Extend the sign appropriately.
119   (if (logbitp 12 val)
120       (- val (ash 1 13))
121       val))
122
123 ;; Look at the current instruction and see if we can't add some notes
124 ;; about what's happening.
125
126 (defun maybe-add-notes (reg dstate)
127   (let* ((word (sb!disassem::sap-ref-int (sb!disassem::dstate-segment-sap dstate)
128                                       (sb!disassem::dstate-cur-offs dstate)
129                                       n-word-bytes
130                                       (sb!disassem::dstate-byte-order dstate)))
131          (format (ldb (byte 2 30) word))
132          (op3 (ldb (byte 6 19) word))
133          (rs1 (ldb (byte 5 14) word))
134          (rd (ldb (byte 5 25) word))
135          (immed-p (not (zerop (ldb (byte 1 13) word))))
136          (immed-val (sign-extend-immed-value (ldb (byte 13 0) word))))
137     ;; Only the value of format and rd are guaranteed to be correct
138     ;; because the disassembler is trying to print out the value of a
139     ;; register.  The other values may not be right.
140     (case format
141       (2
142        (case op3
143          (#b000000
144           (when (= reg rs1)
145             (handle-add-inst rs1 immed-val rd dstate)))
146          (#b111000
147           (when (= reg rs1)
148             (handle-jmpl-inst rs1 immed-val rd dstate)))
149          (#b010001
150           (when (= reg rs1)
151             (handle-andcc-inst rs1 immed-val rd dstate)))))
152       (3
153        (case op3
154          ((#b000000 #b000100)
155           (when (= reg rs1)
156             (handle-ld/st-inst rs1 immed-val rd dstate))))))
157     ;; If this is not a SETHI instruction, and RD is the same as some
158     ;; register used by SETHI, we delete the entry.  (In case we have
159     ;; a SETHI without any additional instruction because the low bits
160     ;; were zero.)
161     (unless (and (zerop format) (= #b100 (ldb (byte 3 22) word)))
162       (let ((sethi (assoc rd *note-sethi-inst*)))
163         (when sethi
164           (setf *note-sethi-inst* (delete sethi *note-sethi-inst*)))))))
165
166 (defun handle-add-inst (rs1 immed-val rd dstate)
167   (let* ((sethi (assoc rs1 *note-sethi-inst*)))
168     (cond
169       (sethi
170        ;; RS1 was used in a SETHI instruction.  Assume that
171        ;; this is the offset part of the SETHI instruction for
172        ;; a full 32-bit address of something.  Make a note
173        ;; about this usage as a Lisp assembly routine or
174        ;; foreign routine, if possible.  If not, just note the
175        ;; final value.
176        (let ((addr (+ immed-val (ash (cdr sethi) 10))))
177          (or (sb!disassem::note-code-constant-absolute addr dstate)
178              (sb!disassem:maybe-note-assembler-routine addr t dstate)
179              (sb!disassem:note (format nil "~A = #x~8,'0X"
180                                      (get-reg-name rd) addr)
181                              dstate)))
182        (setf *note-sethi-inst* (delete sethi *note-sethi-inst*)))
183       ((= rs1 null-offset)
184        ;; We have an ADD %NULL, <n>, RD instruction.  This is a
185        ;; reference to a static symbol.
186        (sb!disassem:maybe-note-nil-indexed-object immed-val
187                                                dstate))
188       ((= rs1 alloc-offset)
189        ;; ADD %ALLOC, n.  This must be some allocation or
190        ;; pseudo-atomic stuff
191        (cond ((and (= immed-val 4) (= rd alloc-offset)
192                    (not *pseudo-atomic-set*))
193               ;; "ADD 4, %ALLOC" sets the flag
194               (sb!disassem::note "Set pseudo-atomic flag" dstate)
195               (setf *pseudo-atomic-set* t))
196              ((= rd alloc-offset)
197               ;; "ADD n, %ALLOC" is reseting the flag, with extra
198               ;; allocation.
199               (sb!disassem:note
200                (format nil "Reset pseudo-atomic, allocated ~D bytes"
201                        (+ immed-val 4)) dstate)
202               (setf *pseudo-atomic-set* nil))))
203       #+nil ((and (= rs1 zero-offset) *pseudo-atomic-set*)
204        ;; "ADD %ZERO, num, RD" inside a pseudo-atomic is very
205        ;; likely loading up a header word.  Make a note to that
206        ;; effect.
207        (let ((type (second (assoc (logand immed-val #xff) header-word-type-alist)))
208              (size (ldb (byte 24 8) immed-val)))
209          (when type
210            (sb!disassem:note (format nil "Header word ~A, size ~D?" type size)
211                           dstate)))))))
212
213 (defun handle-jmpl-inst (rs1 immed-val rd dstate)
214   (let* ((sethi (assoc rs1 *note-sethi-inst*)))
215     (when sethi
216       ;; RS1 was used in a SETHI instruction.  Assume that
217       ;; this is the offset part of the SETHI instruction for
218       ;; a full 32-bit address of something.  Make a note
219       ;; about this usage as a Lisp assembly routine or
220       ;; foreign routine, if possible.  If not, just note the
221       ;; final value.
222       (let ((addr (+ immed-val (ash (cdr sethi) 10))))
223         (sb!disassem:maybe-note-assembler-routine addr t dstate)
224         (setf *note-sethi-inst* (delete sethi *note-sethi-inst*))))))
225
226 (defun handle-ld/st-inst (rs1 immed-val rd dstate)
227   (declare (ignore rd))
228   ;; Got an LDUW/LD or STW instruction, with immediate offset.
229   (case rs1
230     (29
231      ;; A reference to a code constant (reg = %CODE)
232      (sb!disassem:note-code-constant immed-val dstate))
233     (2
234      ;; A reference to a static symbol or static function (reg =
235      ;; %NULL)
236      (or (sb!disassem:maybe-note-nil-indexed-symbol-slot-ref immed-val
237                                                       dstate)
238          #+nil (sb!disassem::maybe-note-static-function immed-val dstate)))
239     (t
240      (let ((sethi (assoc rs1 *note-sethi-inst*)))
241        (when sethi
242          (let ((addr (+ immed-val (ash (cdr sethi) 10))))
243            (sb!disassem:maybe-note-assembler-routine addr nil dstate)
244            (setf *note-sethi-inst* (delete sethi *note-sethi-inst*))))))))
245
246 (defun handle-andcc-inst (rs1 immed-val rd dstate)
247   ;; ANDCC %ALLOC, 3, %ZERO instruction
248   (when (and (= rs1 alloc-offset) (= rd zero-offset) (= immed-val 3))
249     (sb!disassem:note "pseudo-atomic interrupted?" dstate)))
250          
251 (sb!disassem:define-arg-type reg
252   :printer (lambda (value stream dstate)
253                (declare (stream stream) (fixnum value))
254                (let ((regname (get-reg-name value)))
255                  (princ regname stream)
256                  (sb!disassem:maybe-note-associated-storage-ref value
257                                                                 'registers
258                                                                 regname
259                                                                 dstate)
260                  (maybe-add-notes value dstate))))
261
262 (defparameter float-reg-symbols
263   #.(coerce 
264      (loop for n from 0 to 63 collect (make-symbol (format nil "%F~d" n)))
265      'vector))
266
267 (sb!disassem:define-arg-type fp-reg
268   :printer (lambda (value stream dstate)
269                (declare (stream stream) (fixnum value))
270                (let ((regname (aref float-reg-symbols value)))
271                  (princ regname stream)
272                  (sb!disassem:maybe-note-associated-storage-ref
273                   value
274                   'float-registers
275                   regname
276                   dstate))))
277
278 ;;; The extended 6 bit floating point register encoding for the double
279 ;;; and long instructions of the sparc v9.
280 (sb!disassem:define-arg-type fp-ext-reg
281   :printer (lambda (value stream dstate)
282                (declare (stream stream) (fixnum value))
283                (let* (;; Decode the register number.
284                       (value (if (oddp value) (+ value 31) value))
285                       (regname (aref float-reg-symbols value)))
286                  (princ regname stream)
287                  (sb!disassem:maybe-note-associated-storage-ref
288                   value
289                   'float-registers
290                   regname
291                   dstate))))
292
293 (sb!disassem:define-arg-type relative-label
294   :sign-extend t
295   :use-label (lambda (value dstate)
296                (declare (type (signed-byte 22) value)
297                         (type sb!disassem:disassem-state dstate))
298                (+ (ash value 2) (sb!disassem:dstate-cur-addr dstate))))
299
300 (defconstant-eqx branch-conditions
301   '(:f :eq :le :lt :leu :ltu :n :vs :t :ne :gt :ge :gtu :geu :p :vc)
302   #'equalp)
303
304 ;;; Note that these aren't the standard names for branch-conditions, I
305 ;;; think they're a bit more readable (e.g., "eq" instead of "e").
306 ;;; You could just put a vector of the normal ones here too.
307
308 (sb!disassem:define-arg-type branch-condition
309   :printer (coerce branch-conditions 'vector))
310
311 (deftype branch-condition ()
312   `(member ,@branch-conditions))
313
314 (defun branch-condition (condition)
315   (or (position condition branch-conditions)
316       (error "Unknown branch condition: ~S~%Must be one of: ~S"
317              condition branch-conditions)))
318
319 (def!constant branch-cond-true
320   #b1000)
321
322 (defconstant-eqx branch-fp-conditions
323   '(:f :ne :lg :ul :l :ug :g :u :t :eq :ue :ge :uge :le :ule :o)
324   #'equalp)
325
326 (sb!disassem:define-arg-type branch-fp-condition
327   :printer (coerce branch-fp-conditions 'vector))
328
329 (sb!disassem:define-arg-type call-fixup :use-label t)
330
331 (deftype fp-branch-condition ()
332   `(member ,@branch-fp-conditions))
333
334 (defun fp-branch-condition (condition)
335   (or (position condition branch-fp-conditions)
336       (error "Unknown fp-branch condition: ~S~%Must be one of: ~S"
337              condition branch-fp-conditions)))
338
339 \f
340 ;;;; dissassem:define-instruction-formats
341
342 (sb!disassem:define-instruction-format
343     (format-1 32 :default-printer '(:name :tab disp))
344   (op   :field (byte 2 30) :value 1)
345   (disp :field (byte 30 0)))
346
347 (sb!disassem:define-instruction-format
348     (format-2-immed 32 :default-printer '(:name :tab immed ", " rd))
349   (op    :field (byte 2 30) :value 0)
350   (rd    :field (byte 5 25) :type 'reg)
351   (op2   :field (byte 3 22))
352   (immed :field (byte 22 0)))
353
354   
355
356 (sb!disassem:define-instruction-format
357     (format-2-branch 32 :default-printer `(:name (:unless (:constant ,branch-cond-true) cond)
358                                            (:unless (a :constant 0) "," 'A)
359                                            :tab
360                                            disp))
361   (op   :field (byte 2 30) :value 0)
362   (a    :field (byte 1 29) :value 0)
363   (cond :field (byte 4 25) :type 'branch-condition)
364   (op2  :field (byte 3 22))
365   (disp :field (byte 22 0) :type 'relative-label))
366
367 ;; Branch with prediction instruction for V9
368
369 ;; Currently only %icc and %xcc are used of the four possible values
370
371 (defconstant-eqx integer-condition-registers
372   '(:icc :reserved :xcc :reserved)
373   #'equalp)
374
375 (defconstant-eqx integer-cond-reg-name-vec
376   (coerce integer-condition-registers 'vector)
377   #'equalp)
378
379 (deftype integer-condition-register ()
380   `(member ,@(remove :reserved integer-condition-registers)))
381
382 (defparameter integer-condition-reg-symbols
383   (map 'vector
384        (lambda (name)
385            (make-symbol (concatenate 'string "%" (string name))))
386        integer-condition-registers))
387
388 (sb!disassem:define-arg-type integer-condition-register
389     :printer (lambda (value stream dstate)
390                  (declare (stream stream) (fixnum value) (ignore dstate))
391                  (let ((regname (aref integer-condition-reg-symbols value)))
392                    (princ regname stream))))
393
394 (defconstant-eqx branch-predictions
395   '(:pn :pt)
396   #'equalp)
397
398 (sb!disassem:define-arg-type branch-prediction
399     :printer (coerce branch-predictions 'vector))
400
401 (defun integer-condition (condition-reg)
402   (declare (type (member :icc :xcc) condition-reg))
403   (or (position condition-reg integer-condition-registers)
404       (error "Unknown integer condition register:  ~S~%"
405              condition-reg)))
406
407 (defun branch-prediction (pred)
408   (or (position pred branch-predictions)
409       (error "Unknown branch prediction:  ~S~%Must be one of: ~S~%"
410              pred branch-predictions)))
411
412 (defconstant-eqx branch-pred-printer
413   `(:name (:unless (:constant ,branch-cond-true) cond)
414           (:unless (a :constant 0) "," 'A)
415           (:unless (p :constant 1) "," 'pn)
416           :tab
417           cc
418           ", "
419           disp)
420   #'equalp)
421
422 (sb!disassem:define-instruction-format
423     (format-2-branch-pred 32 :default-printer branch-pred-printer)
424   (op   :field (byte 2 30) :value 0)
425   (a    :field (byte 1 29) :value 0)
426   (cond :field (byte 4 25) :type 'branch-condition)
427   (op2  :field (byte 3 22))
428   (cc   :field (byte 2 20) :type 'integer-condition-register)
429   (p    :field (byte 1 19))
430   (disp :field (byte 19 0) :type 'relative-label))
431
432 (defconstant-eqx fp-condition-registers
433   '(:fcc0 :fcc1 :fcc2 :fcc3)
434   #'equalp)
435
436 (defconstant-eqx fp-cond-reg-name-vec
437   (coerce fp-condition-registers 'vector)
438   #'equalp)
439
440 (defparameter fp-condition-reg-symbols
441   (map 'vector
442        (lambda (name)
443            (make-symbol (concatenate 'string "%" (string name))))
444        fp-condition-registers))
445
446 (sb!disassem:define-arg-type fp-condition-register
447     :printer (lambda (value stream dstate)
448                  (declare (stream stream) (fixnum value) (ignore dstate))
449                  (let ((regname (aref fp-condition-reg-symbols value)))
450                    (princ regname stream))))
451
452 (sb!disassem:define-arg-type fp-condition-register-shifted
453     :printer (lambda (value stream dstate)
454                  (declare (stream stream) (fixnum value) (ignore dstate))
455                  (let ((regname (aref fp-condition-reg-symbols (ash value -1))))
456                    (princ regname stream))))
457
458 (defun fp-condition (condition-reg)
459   (or (position condition-reg fp-condition-registers)
460       (error "Unknown integer condition register:  ~S~%"
461              condition-reg)))
462
463 (defconstant-eqx fp-branch-pred-printer
464   `(:name (:unless (:constant ,branch-cond-true) cond)
465           (:unless (a :constant 0) "," 'A)
466           (:unless (p :constant 1) "," 'pn)
467           :tab
468           fcc
469           ", "
470           disp)
471   #'equalp)
472
473 (sb!disassem:define-instruction-format
474     (format-2-fp-branch-pred 32 :default-printer fp-branch-pred-printer)
475   (op   :field (byte 2 30) :value 0)
476   (a    :field (byte 1 29) :value 0)
477   (cond :field (byte 4 25) :type 'branch-fp-condition)
478   (op2  :field (byte 3 22))
479   (fcc  :field (byte 2 20) :type 'fp-condition-register)
480   (p    :field (byte 1 19))
481   (disp :field (byte 19 0) :type 'relative-label))
482   
483
484
485 (sb!disassem:define-instruction-format
486     (format-2-unimp 32 :default-printer '(:name :tab data))
487   (op     :field (byte 2 30) :value 0)
488   (ignore :field (byte 5 25) :value 0)
489   (op2    :field (byte 3 22) :value 0)
490   (data   :field (byte 22 0)))
491
492 (defconstant-eqx f3-printer
493   '(:name :tab
494           (:unless (:same-as rd) rs1 ", ")
495           (:choose rs2 immed) ", "
496           rd)
497   #'equalp)
498
499 (sb!disassem:define-instruction-format
500     (format-3-reg 32 :default-printer f3-printer)
501   (op  :field (byte 2 30))
502   (rd  :field (byte 5 25) :type 'reg)
503   (op3 :field (byte 6 19))
504   (rs1 :field (byte 5 14) :type 'reg)
505   (i   :field (byte 1 13) :value 0)
506   (asi :field (byte 8 5)  :value 0)
507   (rs2 :field (byte 5 0)  :type 'reg))
508
509 (sb!disassem:define-instruction-format
510     (format-3-immed 32 :default-printer f3-printer)
511   (op    :field (byte 2 30))
512   (rd    :field (byte 5 25) :type 'reg)
513   (op3   :field (byte 6 19))
514   (rs1   :field (byte 5 14) :type 'reg)
515   (i     :field (byte 1 13) :value 1)
516   (immed :field (byte 13 0) :sign-extend t))    ; usually sign extended
517
518 (sb!disassem:define-instruction-format
519     (format-binary-fpop 32
520      :default-printer '(:name :tab rs1 ", " rs2 ", " rd))
521   (op   :field (byte 2 30))
522   (rd   :field (byte 5 25) :type 'fp-reg)
523   (op3  :field (byte 6 19))
524   (rs1  :field (byte 5 14) :type 'fp-reg)
525   (opf  :field (byte 9 5))
526   (rs2  :field (byte 5 0) :type 'fp-reg))
527
528 ;;; Floating point load/save instructions encoding.
529 (sb!disassem:define-instruction-format
530     (format-unary-fpop 32 :default-printer '(:name :tab rs2 ", " rd))
531   (op   :field (byte 2 30))
532   (rd   :field (byte 5 25) :type 'fp-reg)
533   (op3  :field (byte 6 19))
534   (rs1  :field (byte 5 14) :value 0)
535   (opf  :field (byte 9 5))
536   (rs2  :field (byte 5 0) :type 'fp-reg))
537
538 ;;; Floating point comparison instructions encoding.
539
540 ;; This is a merge of the instructions for FP comparison and FP
541 ;; conditional moves available in the Sparc V9.  The main problem is
542 ;; that the new instructions use part of the opcode space used by the
543 ;; comparison instructions.  In particular, the OPF field is arranged
544 ;; as so:
545 ;;
546 ;; Bit          1       0
547 ;;              3       5
548 ;; FMOVcc       0nn0000xx       %fccn
549 ;;              1000000xx       %icc
550 ;;              1100000xx       %xcc
551 ;; FMOVR        0ccc001yy
552 ;; FCMP         001010zzz
553 ;;
554 ;; So we see that if we break up the OPF field into 4 pieces, opf0,
555 ;; opf1, opf2, and opf3, we can distinguish between these
556 ;; instructions. So bit 9 (opf2) can be used to distinguish between
557 ;; FCMP and the rest.  Also note that the nn field overlaps with the
558 ;; ccc.  We need to take this into account as well.
559 ;;
560 (sb!disassem:define-instruction-format
561     (format-fpop2 32
562                   :default-printer #!-sparc-v9 '(:name :tab rs1 ", " rs2)
563                                    #!+sparc-v9 '(:name :tab rd ", " rs1 ", " rs2))
564   (op   :field (byte 2 30))
565   (rd   :field (byte 5 25) :value 0)
566   (op3  :field (byte 6 19))
567   (rs1  :field (byte 5 14))
568   (opf0 :field (byte 1 13))
569   (opf1 :field (byte 3 10))
570   (opf2 :field (byte 1 9))
571   (opf3 :field (byte 4 5))
572   (rs2  :field (byte 5 0) :type 'fp-reg))
573
574 ;;; Shift instructions
575 (sb!disassem:define-instruction-format
576     (format-3-shift-reg 32 :default-printer f3-printer)
577   (op   :field (byte 2 30))
578   (rd    :field (byte 5 25) :type 'reg)
579   (op3  :field (byte 6 19))
580   (rs1   :field (byte 5 14) :type 'reg)
581   (i     :field (byte 1 13) :value 0)
582   (x     :field (byte 1 12))
583   (asi   :field (byte 7 5) :value 0)
584   (rs2   :field (byte 5 0) :type 'reg))
585
586 (sb!disassem:define-instruction-format
587     (format-3-shift-immed 32 :default-printer f3-printer)
588   (op   :field (byte 2 30))
589   (rd    :field (byte 5 25) :type 'reg)
590   (op3  :field (byte 6 19))
591   (rs1   :field (byte 5 14) :type 'reg)
592   (i     :field (byte 1 13) :value 1)
593   (x     :field (byte 1 12))
594   (immed :field (byte 12 0) :sign-extend nil))
595
596 \f
597 ;;; Conditional moves (only available for Sparc V9 architectures)
598
599 ;; The names of all of the condition registers on the V9: 4 FP
600 ;; conditions, the original integer condition register and the new
601 ;; extended register.  The :reserved register is reserved on the V9.
602
603 (defconstant-eqx cond-move-condition-registers
604   '(:fcc0 :fcc1 :fcc2 :fcc3 :icc :reserved :xcc :reserved)
605   #'equalp)
606
607 (defconstant-eqx cond-move-cond-reg-name-vec
608   (coerce cond-move-condition-registers 'vector)
609   #'equalp)
610
611 (deftype cond-move-condition-register ()
612     `(member ,@(remove :reserved cond-move-condition-registers)))
613
614 (defparameter cond-move-condition-reg-symbols
615   (map 'vector
616        (lambda (name)
617            (make-symbol (concatenate 'string "%" (string name))))
618        cond-move-condition-registers))
619
620 (sb!disassem:define-arg-type cond-move-condition-register
621     :printer (lambda (value stream dstate)
622                  (declare (stream stream) (fixnum value) (ignore dstate))
623                  (let ((regname (aref cond-move-condition-reg-symbols value)))
624                    (princ regname stream))))
625
626 ;; From the given condition register, figure out what the cc2, cc1,
627 ;; and cc0 bits should be.  Return cc2 and cc1/cc0 concatenated.
628 (defun cond-move-condition-parts (condition-reg)
629   (let ((posn (position condition-reg cond-move-condition-registers)))
630     (if posn
631         (truncate posn 4)
632         (error "Unknown conditional move condition register:  ~S~%"
633                condition-reg))))
634
635 (defun cond-move-condition (condition-reg)
636   (or (position condition-reg cond-move-condition-registers)
637       (error "Unknown conditional move condition register:  ~S~%"
638              condition-reg)))
639
640 (defconstant-eqx cond-move-printer
641   `(:name cond :tab
642           cc ", " (:choose immed rs2) ", " rd)
643   #'equalp)
644
645 ;; Conditional move integer register on integer or FP condition code
646 (sb!disassem:define-instruction-format
647     (format-4-cond-move 32 :default-printer cond-move-printer)
648   (op   :field (byte 2 30))
649   (rd    :field (byte 5 25) :type 'reg)
650   (op3  :field (byte 6 19))
651   (cc2   :field (byte 1 18) :value 1)
652   (cond  :field (byte 4 14) :type 'branch-condition)
653   (i     :field (byte 1 13) :value 0)
654   (cc    :field (byte 2 11) :type 'integer-condition-register)
655   (empty :field (byte 6 5) :value 0)
656   (rs2   :field (byte 5 0) :type 'reg))
657
658 (sb!disassem:define-instruction-format
659     (format-4-cond-move-immed 32 :default-printer cond-move-printer)
660   (op    :field (byte 2 30))
661   (rd    :field (byte 5 25) :type 'reg)
662   (op3   :field (byte 6 19))
663   (cc2   :field (byte 1 18) :value 1)
664   (cond  :field (byte 4 14) :type 'branch-condition)
665   (i     :field (byte 1 13) :value 1)
666   (cc    :field (byte 2 11) :type 'integer-condition-register)
667   (immed :field (byte 11 0) :sign-extend t))
668
669 ;; Floating-point versions of the above integer conditional moves
670 (defconstant-eqx cond-fp-move-printer
671   `(:name rs1 :tab opf1 ", " rs2 ", " rd)
672   #'equalp)
673
674 ;;; Conditional move on integer register condition (only on Sparc
675 ;;; V9). That is, move an integer register if some other integer
676 ;;; register satisfies some condition.
677
678 (defconstant-eqx cond-move-integer-conditions
679   '(:reserved :z :lez :lz :reserved :nz :gz :gez)
680   #'equalp)
681
682 (defconstant-eqx cond-move-integer-condition-vec
683   (coerce cond-move-integer-conditions 'vector)
684   #'equalp)
685
686 (deftype cond-move-integer-condition ()
687   `(member ,@(remove :reserved cond-move-integer-conditions)))
688
689 (sb!disassem:define-arg-type register-condition
690     :printer (lambda (value stream dstate)
691                  (declare (stream stream) (fixnum value) (ignore dstate))
692                  (let ((regname (aref cond-move-integer-condition-vec value)))
693                    (princ regname stream))))
694
695 (defconstant-eqx cond-move-integer-printer
696   `(:name rcond :tab rs1 ", " (:choose immed rs2) ", " rd)
697   #'equalp)
698
699 (defun register-condition (rcond)
700   (or (position rcond cond-move-integer-conditions)
701       (error "Unknown register condition:  ~S~%" rcond)))
702
703 (sb!disassem:define-instruction-format
704     (format-4-cond-move-integer 32 :default-printer cond-move-integer-printer)
705   (op    :field (byte 2 30))
706   (rd    :field (byte 5 25) :type 'reg)
707   (op3   :field (byte 6 19))
708   (rs1   :field (byte 5 14) :type 'reg)
709   (i     :field (byte 1 13) :value 0)
710   (rcond :field (byte 3 10) :type 'register-condition)
711   (opf   :field (byte 5 5))
712   (rs2   :field (byte 5 0) :type 'reg))
713
714 (sb!disassem:define-instruction-format
715     (format-4-cond-move-integer-immed 32 :default-printer cond-move-integer-printer)
716   (op    :field (byte 2 30))
717   (rd    :field (byte 5 25) :type 'reg)
718   (op3   :field (byte 6 19))
719   (rs1   :field (byte 5 14) :type 'reg)
720   (i     :field (byte 1 13) :value 1)
721   (rcond :field (byte 3 10) :type 'register-condition)
722   (immed :field (byte 10 0) :sign-extend t))
723
724 (defconstant-eqx trap-printer
725   `(:name rd :tab cc ", " immed)
726   #'equalp)
727
728 (sb!disassem:define-instruction-format
729     (format-4-trap 32 :default-printer trap-printer)
730   (op    :field (byte 2 30))
731   (rd    :field (byte 5 25) :type 'reg)
732   (op3   :field (byte 6 19))
733   (rs1   :field (byte 5 14) :type 'reg)
734   (i     :field (byte 1 13) :value 1)
735   (cc    :field (byte 2 11) :type 'integer-condition-register)
736   (immed :field (byte 11 0) :sign-extend t))    ; usually sign extended
737
738
739 (defconstant-eqx cond-fp-move-integer-printer
740   `(:name opf1 :tab rs1 ", " rs2 ", " rd)
741   #'equalp)
742
743 \f
744 ;;;; Primitive emitters.
745
746 (define-bitfield-emitter emit-word 32
747   (byte 32 0))
748
749 (define-bitfield-emitter emit-short 16
750   (byte 16 0))
751
752 (define-bitfield-emitter emit-format-1 32
753   (byte 2 30) (byte 30 0))
754
755 (define-bitfield-emitter emit-format-2-immed 32
756   (byte 2 30) (byte 5 25) (byte 3 22) (byte 22 0))
757
758 (define-bitfield-emitter emit-format-2-branch 32
759   (byte 2 30) (byte 1 29) (byte 4 25) (byte 3 22) (byte 22 0))
760
761 ;; Integer and FP branches with prediction for V9
762 (define-bitfield-emitter emit-format-2-branch-pred 32
763   (byte 2 30) (byte 1 29) (byte 4 25) (byte 3 22) (byte 2 20) (byte 1 19) (byte 19 0))
764 (define-bitfield-emitter emit-format-2-fp-branch-pred 32
765   (byte 2 30) (byte 1 29) (byte 4 25) (byte 3 22) (byte 2 20) (byte 1 19) (byte 19 0))
766   
767 (define-bitfield-emitter emit-format-2-unimp 32
768   (byte 2 30) (byte 5 25) (byte 3 22) (byte 22 0))
769
770 (define-bitfield-emitter emit-format-3-reg 32
771   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 1 13) (byte 8 5)
772   (byte 5 0))
773
774 (define-bitfield-emitter emit-format-3-immed 32
775   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 1 13) (byte 13 0))
776
777 (define-bitfield-emitter emit-format-3-fpop 32
778   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 9 5) (byte 5 0))
779
780 (define-bitfield-emitter emit-format-3-fpop2 32
781   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14)
782   (byte 1 13) (byte 3 10) (byte 1 9) (byte 4 5)
783   (byte 5 0))
784
785 ;;; Shift instructions
786
787 (define-bitfield-emitter emit-format-3-shift-reg 32
788   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 1 13) (byte 1 12) (byte 7 5)
789   (byte 5 0))
790
791 (define-bitfield-emitter emit-format-3-shift-immed 32
792   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 1 13) (byte 1 12) (byte 12 0))
793
794 ;;; Conditional moves
795
796 ;; Conditional move in condition code
797 (define-bitfield-emitter emit-format-4-cond-move 32
798   (byte 2 30) (byte 5 25) (byte 6 19) (byte 1 18) (byte 4 14) (byte 1 13) (byte 2 11)
799   (byte 11 0))
800
801 ;; Conditional move on integer condition
802 (define-bitfield-emitter emit-format-4-cond-move-integer 32
803   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 1 13) (byte 3 10) (byte 5 5)
804   (byte 5 0))
805
806 (define-bitfield-emitter emit-format-4-cond-move-integer-immed 32
807   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 1 13) (byte 3 10)
808   (byte 10 0))
809
810 (define-bitfield-emitter emit-format-4-trap 32
811   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 1 13) (byte 2 11)
812   (byte 11 0))
813   
814 \f
815 ;;;; Most of the format-3-instructions.
816
817 (defun emit-format-3-inst (segment op op3 dst src1 src2
818                                    &key load-store fixup dest-kind)
819   (unless src2
820     (cond ((and (typep src1 'tn) load-store)
821            (setf src2 0))
822           (t
823            (setf src2 src1)
824            (setf src1 dst))))
825   (etypecase src2
826     (tn
827      (emit-format-3-reg segment op
828                         (if dest-kind
829                             (fp-reg-tn-encoding dst)
830                             (reg-tn-encoding dst))
831                         op3 (reg-tn-encoding src1) 0 0 (reg-tn-encoding src2)))
832     (integer
833      (emit-format-3-immed segment op
834                           (if dest-kind
835                               (fp-reg-tn-encoding dst)
836                               (reg-tn-encoding dst))
837                           op3 (reg-tn-encoding src1) 1 src2))
838     (fixup
839      (unless (or load-store fixup)
840        (error "Fixups aren't allowed."))
841      (note-fixup segment :add src2)
842      (emit-format-3-immed segment op
843                           (if dest-kind
844                               (fp-reg-tn-encoding dst)
845                               (reg-tn-encoding dst))
846                           op3 (reg-tn-encoding src1) 1 0))))
847
848 ;;; Shift instructions because an extra bit is used in Sparc V9's to
849 ;;; indicate whether the shift is a 32-bit or 64-bit shift.
850 ;;;
851 (defun emit-format-3-shift-inst (segment op op3 dst src1 src2 &key extended)
852   (unless src2
853     (setf src2 src1)
854     (setf src1 dst))
855   (etypecase src2
856     (tn
857      (emit-format-3-shift-reg segment op (reg-tn-encoding dst)
858                               op3 (reg-tn-encoding src1) 0 (if extended 1 0)
859                               0 (reg-tn-encoding src2)))
860     (integer
861      (emit-format-3-shift-immed segment op (reg-tn-encoding dst)
862                                 op3 (reg-tn-encoding src1) 1
863                                 (if extended 1 0) src2))))
864
865
866 (eval-when (:compile-toplevel :execute)
867
868 ;;; have to do this because def!constant is evalutated in the null lex env.
869 (defmacro with-ref-format (printer)
870   `(let* ((addend
871            '(:choose (:plus-integer immed) ("+" rs2)))
872           (ref-format
873            `("[" rs1 (:unless (:constant 0) ,addend) "]"
874              (:choose (:unless (:constant 0) asi) nil))))
875      ,printer))
876
877 (defconstant-eqx load-printer
878   (with-ref-format `(:NAME :TAB ,ref-format ", " rd))
879   #'equalp)
880
881 (defconstant-eqx store-printer
882   (with-ref-format `(:NAME :TAB rd ", " ,ref-format))
883   #'equalp)
884
885 ) ; EVAL-WHEN
886
887 (macrolet ((define-f3-inst (name op op3 &key fixup load-store (dest-kind 'reg)
888                                  (printer :default) reads writes flushable print-name)
889   (let ((printer
890          (if (eq printer :default)
891              (case load-store
892                ((nil) :default)
893                ((:load t) 'load-printer)
894                (:store 'store-printer))
895              printer)))
896     (when (and (atom reads) (not (null reads)))
897       (setf reads (list reads)))
898     (when (and (atom writes) (not (null writes)))
899        (setf writes (list writes)))
900     `(define-instruction ,name (segment dst src1 &optional src2)
901        (:declare (type tn dst)
902                  ,(if (or fixup load-store)
903                       '(type (or tn (signed-byte 13) null fixup) src1 src2)
904                       '(type (or tn (signed-byte 13) null) src1 src2)))
905        (:printer format-3-reg
906                  ((op ,op) (op3 ,op3) (rd nil :type ',dest-kind))
907                  ,printer
908                  ,@(when print-name `(:print-name ,print-name)))
909        (:printer format-3-immed
910                  ((op ,op) (op3 ,op3) (rd nil :type ',dest-kind))
911                  ,printer
912                  ,@(when print-name `(:print-name ,print-name)))
913        ,@(when flushable
914            '((:attributes flushable)))
915        (:dependencies
916         (reads src1)
917         ,@(let ((reads-list nil))
918             (dolist (read reads)
919               (push (list 'reads read) reads-list))
920             reads-list)
921         ,@(cond ((eq load-store :store)
922                  '((reads dst)
923                    (if src2 (reads src2))))
924                  ((eq load-store t)
925                   '((reads :memory)
926                     (reads dst)
927                     (if src2 (reads src2))))
928                 ((eq load-store :load)
929                  '((reads :memory)
930                    (if src2 (reads src2) (reads dst))))
931                 (t
932                  '((if src2 (reads src2) (reads dst)))))
933         ,@(let ((writes-list nil))
934             (dolist (write writes)
935               (push (list 'writes write) writes-list))
936             writes-list)
937         ,@(cond ((eq load-store :store)
938                  '((writes :memory :partially t)))
939                 ((eq load-store t)
940                  '((writes :memory :partially t)
941                    (writes dst)))
942                 ((eq load-store :load)
943                  '((writes dst)))
944                 (t
945                  '((writes dst)))))
946        (:delay 0)
947        (:emitter (emit-format-3-inst segment ,op ,op3 dst src1 src2
948                                      :load-store ,load-store
949                                      :fixup ,fixup
950                                      :dest-kind (not (eq ',dest-kind 'reg)))))))
951
952            (define-f3-shift-inst (name op op3 &key extended)
953                `(define-instruction ,name (segment dst src1 &optional src2)
954                  (:declare (type tn dst)
955                   (type (or tn (unsigned-byte 6) null) src1 src2))
956                  (:printer format-3-shift-reg
957                   ((op ,op) (op3 ,op3) (x ,(if extended 1 0)) (i 0)))
958                  (:printer format-3-shift-immed
959                   ((op ,op) (op3 ,op3) (x ,(if extended 1 0)) (i 1)))
960                  (:dependencies
961                   (reads src1)
962                   (if src2 (reads src2) (reads dst))
963                   (writes dst))
964                  (:delay 0)
965                  (:emitter (emit-format-3-shift-inst segment ,op ,op3 dst src1 src2
966                             :extended ,extended)))))
967
968   (define-f3-inst ldsb #b11 #b001001 :load-store :load)
969   (define-f3-inst ldsh #b11 #b001010 :load-store :load)
970   (define-f3-inst ldub #b11 #b000001 :load-store :load)
971   (define-f3-inst lduh #b11 #b000010 :load-store :load)
972
973   ;; This instruction is called lduw for V9 , but looks exactly like ld
974   ;; on previous architectures.
975   (define-f3-inst ld #b11 #b000000 :load-store :load
976                   #!+sparc-v9 :print-name #!+sparc-v9 'lduw)
977
978   (define-f3-inst ldsw #b11 #b001000 :load-store :load) ; v9
979   
980   ;; ldd is deprecated on the Sparc V9.
981   (define-f3-inst ldd #b11 #b000011 :load-store :load)
982   
983   (define-f3-inst ldx #b11 #b001011 :load-store :load) ; v9
984   
985   (define-f3-inst ldf #b11 #b100000 :dest-kind fp-reg :load-store :load)
986   (define-f3-inst lddf #b11 #b100011 :dest-kind fp-reg :load-store :load)
987   (define-f3-inst ldqf #b11 #b100010 :dest-kind fp-reg :load-store :load)       ; v9
988   (define-f3-inst stb #b11 #b000101 :load-store :store)
989   (define-f3-inst sth #b11 #b000110 :load-store :store)
990   (define-f3-inst st #b11 #b000100 :load-store :store)
991   
992   ;; std is deprecated on the Sparc V9.
993   (define-f3-inst std #b11 #b000111 :load-store :store)
994   
995   (define-f3-inst stx #b11 #b001110 :load-store :store) ; v9
996   
997   (define-f3-inst stf #b11 #b100100 :dest-kind fp-reg :load-store :store)
998   (define-f3-inst stdf #b11 #b100111 :dest-kind fp-reg :load-store :store)
999   (define-f3-inst stqf #b11 #b100110 :dest-kind fp-reg :load-store :store) ; v9
1000   (define-f3-inst ldstub #b11 #b001101 :load-store t)
1001   
1002   ;; swap is deprecated on the Sparc V9
1003   (define-f3-inst swap #b11 #b001111 :load-store t)
1004   
1005   (define-f3-inst add #b10 #b000000 :fixup t)
1006   (define-f3-inst addcc #b10 #b010000 :writes :psr)
1007   (define-f3-inst addx #b10 #b001000 :reads :psr)
1008   (define-f3-inst addxcc #b10 #b011000 :reads :psr :writes :psr)
1009   (define-f3-inst taddcc #b10 #b100000 :writes :psr)
1010   
1011   ;; taddcctv is deprecated on the Sparc V9.  Use taddcc and bpvs or
1012   ;; taddcc and trap to get a similar effect.  (Requires changing the C
1013   ;; code though!)
1014   ;;(define-f3-inst taddcctv #b10 #b100010 :writes :psr)
1015
1016   (define-f3-inst sub #b10 #b000100)
1017   (define-f3-inst subcc #b10 #b010100 :writes :psr)
1018   (define-f3-inst subx #b10 #b001100 :reads :psr)
1019   (define-f3-inst subxcc #b10 #b011100 :reads :psr :writes :psr)
1020   (define-f3-inst tsubcc #b10 #b100001 :writes :psr)
1021
1022   ;; tsubcctv is deprecated on the Sparc V9.  Use tsubcc and bpvs or
1023   ;; tsubcc and trap to get a similar effect.  (Requires changing the C
1024   ;; code though!)
1025   ;;(define-f3-inst tsubcctv #b10 #b100011 :writes :psr)
1026
1027   (define-f3-inst mulscc #b10 #b100100 :reads :y :writes (:psr :y))
1028   (define-f3-inst and #b10 #b000001)
1029   (define-f3-inst andcc #b10 #b010001 :writes :psr)
1030   (define-f3-inst andn #b10 #b000101)
1031   (define-f3-inst andncc #b10 #b010101 :writes :psr)
1032   (define-f3-inst or #b10 #b000010)
1033   (define-f3-inst orcc #b10 #b010010 :writes :psr)
1034   (define-f3-inst orn #b10 #b000110)
1035   (define-f3-inst orncc #b10 #b010110 :writes :psr)
1036   (define-f3-inst xor #b10 #b000011)
1037   (define-f3-inst xorcc #b10 #b010011 :writes :psr)
1038   (define-f3-inst xnor #b10 #b000111)
1039   (define-f3-inst xnorcc #b10 #b010111 :writes :psr)
1040   
1041   (define-f3-shift-inst sll #b10 #b100101)
1042   (define-f3-shift-inst srl #b10 #b100110)
1043   (define-f3-shift-inst sra #b10 #b100111)
1044   (define-f3-shift-inst sllx #b10 #b100101 :extended t) ; v9
1045   (define-f3-shift-inst srlx #b10 #b100110 :extended t) ; v9
1046   (define-f3-shift-inst srax #b10 #b100111 :extended t) ; v9
1047
1048   (define-f3-inst save #b10 #b111100 :reads :psr :writes :psr)
1049   (define-f3-inst restore #b10 #b111101 :reads :psr :writes :psr)
1050   
1051   ;; smul, smulcc, umul, umulcc, sdiv, sdivcc, udiv, and udivcc are
1052   ;; deprecated on the Sparc V9.  Use mulx, sdivx, and udivx instead.
1053   (define-f3-inst smul #b10 #b001011 :writes :y)                        ; v8
1054   (define-f3-inst smulcc #b10 #b011011 :writes (:psr :y))               ; v8
1055   (define-f3-inst umul #b10 #b001010 :writes :y)                        ; v8
1056   (define-f3-inst umulcc #b10 #b011010 :writes (:psr :y))               ; v8
1057   (define-f3-inst sdiv #b10 #b001111 :reads :y)                 ; v8
1058   (define-f3-inst sdivcc #b10 #b011111 :reads :y :writes :psr)  ; v8
1059   (define-f3-inst udiv #b10 #b001110 :reads :y)                 ; v8
1060   (define-f3-inst udivcc #b10 #b011110 :reads :y :writes :psr)  ; v8
1061   
1062   (define-f3-inst mulx #b10 #b001001)   ; v9 for both signed and unsigned
1063   (define-f3-inst sdivx #b10 #b101101)  ; v9
1064   (define-f3-inst udivx #b10 #b001101)  ; v9
1065
1066   (define-f3-inst popc #b10 #b101110)   ; v9: count one bits
1067
1068 ) ; MACROLET
1069
1070 \f
1071 ;;;; Random instructions.
1072
1073 ;; ldfsr is deprecated on the Sparc V9.  Use ldxfsr instead
1074 (define-instruction ldfsr (segment src1 src2)
1075   (:declare (type tn src1) (type (signed-byte 13) src2))
1076   (:printer format-3-immed ((op #b11) (op3 #b100001) (rd 0)))
1077   :pinned
1078   (:delay 0)
1079   (:emitter (emit-format-3-immed segment #b11 0 #b100001
1080                                  (reg-tn-encoding src1) 1 src2)))
1081
1082 #!+sparc-64
1083 (define-instruction ldxfsr (segment src1 src2)
1084   (:declare (type tn src1) (type (signed-byte 13) src2))
1085   (:printer format-3-immed ((op #b11) (op3 #b100001) (rd 1))
1086             '(:name :tab "[" rs1 (:unless (:constant 0) "+" immed) "], %FSR")
1087             :print-name 'ldx)
1088   :pinned
1089   (:delay 0)
1090   (:emitter (emit-format-3-immed segment #b11 1 #b100001
1091                                  (reg-tn-encoding src1) 1 src2)))
1092   
1093 ;; stfsr is deprecated on the Sparc V9.  Use stxfsr instead.
1094 (define-instruction stfsr (segment src1 src2)
1095   (:declare (type tn src1) (type (signed-byte 13) src2))
1096   (:printer format-3-immed ((op #b11) (op3 #b100101) (rd 0)))
1097   :pinned
1098   (:delay 0)
1099   (:emitter (emit-format-3-immed segment #b11 0 #b100101 
1100                                  (reg-tn-encoding src1) 1 src2)))
1101
1102 #!+sparc-64
1103 (define-instruction stxfsr (segment src1 src2)
1104   (:declare (type tn src1) (type (signed-byte 13) src2))
1105   (:printer format-3-immed ((op #b11) (op3 #b100101) (rd 1))
1106             '(:name :tab "%FSR, [" rs1 "+" (:unless (:constant 0) "+" immed) "]")
1107             :print-name 'stx)
1108   :pinned
1109   (:delay 0)
1110   (:emitter (emit-format-3-immed segment #b11 1 #b100101 
1111                                  (reg-tn-encoding src1) 1 src2)))
1112
1113 (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)
1114   (defun sethi-arg-printer (value stream dstate)
1115     (format stream "%hi(#x~8,'0x)" (ash value 10))
1116     ;; Save the immediate value and the destination register from this
1117     ;; sethi instruction.  This is used later to print some possible
1118     ;; notes about the value loaded by sethi.
1119     (let* ((word (sb!disassem::sap-ref-int (sb!disassem::dstate-segment-sap dstate)
1120                                            (sb!disassem::dstate-cur-offs dstate)
1121                                            n-word-bytes
1122                                            (sb!disassem::dstate-byte-order dstate)))
1123            (imm22 (ldb (byte 22 0) word))
1124            (rd (ldb (byte 5 25) word)))
1125       (push (cons rd imm22) *note-sethi-inst*)))
1126 ) ; EVAL-WHEN
1127
1128
1129 (define-instruction sethi (segment dst src1)
1130   (:declare (type tn dst)
1131             (type (or (signed-byte 22) (unsigned-byte 22) fixup) src1))
1132   (:printer format-2-immed
1133             ((op2 #b100) (immed nil :printer #'sethi-arg-printer)))
1134   (:dependencies (writes dst))
1135   (:delay 0)
1136   (:emitter
1137    (etypecase src1
1138      (integer
1139       (emit-format-2-immed segment #b00 (reg-tn-encoding dst) #b100
1140                                  src1))
1141      (fixup
1142       (note-fixup segment :sethi src1)
1143       (emit-format-2-immed segment #b00 (reg-tn-encoding dst) #b100 0)))))
1144                            
1145 ;; rdy is deprecated on the Sparc V9.  It's not needed with 64-bit
1146 ;; registers.
1147 (define-instruction rdy (segment dst)
1148   (:declare (type tn dst))
1149   (:printer format-3-reg ((op #b10) (op3 #b101000) (rs1 0) (immed 0))
1150             '('RD :tab '%Y ", " rd))
1151   (:dependencies (reads :y) (writes dst))
1152   (:delay 0)
1153   (:emitter (emit-format-3-reg segment #b10 (reg-tn-encoding dst) #b101000
1154                                0 0 0 0)))
1155
1156 (defconstant-eqx wry-printer
1157   '('WR :tab rs1 (:unless (:constant 0) ", " (:choose immed rs2)) ", " '%Y)
1158   #'equalp)
1159
1160 ;; wry is deprecated on the Sparc V9.  It's not needed with 64-bit
1161 ;; registers.
1162 (define-instruction wry (segment src1 &optional src2)
1163   (:declare (type tn src1) (type (or (signed-byte 13) tn null) src2))
1164   (:printer format-3-reg ((op #b10) (op3 #b110000) (rd 0)) wry-printer)
1165   (:printer format-3-immed ((op #b10) (op3 #b110000) (rd 0)) wry-printer)
1166   (:dependencies (reads src1) (if src2 (reads src2)) (writes :y))
1167   (:delay 3)
1168   (:emitter
1169    (etypecase src2
1170      (null 
1171       (emit-format-3-reg segment #b10 0 #b110000 (reg-tn-encoding src1) 0 0 0))
1172      (tn
1173       (emit-format-3-reg segment #b10 0 #b110000 (reg-tn-encoding src1) 0 0
1174                          (reg-tn-encoding src2)))
1175      (integer
1176       (emit-format-3-immed segment #b10 0 #b110000 (reg-tn-encoding src1) 1
1177                            src2)))))
1178
1179 (defun snarf-error-junk (sap offset &optional length-only)
1180   (let* ((length (sb!sys:sap-ref-8 sap offset))
1181          (vector (make-array length :element-type '(unsigned-byte 8))))
1182     (declare (type sb!sys:system-area-pointer sap)
1183              (type (unsigned-byte 8) length)
1184              (type (simple-array (unsigned-byte 8) (*)) vector))
1185     (cond (length-only
1186            (values 0 (1+ length) nil nil))
1187           (t
1188            (sb!kernel:copy-from-system-area sap (* n-byte-bits (1+ offset))
1189                                          vector (* n-word-bits
1190                                                    vector-data-offset)
1191                                          (* length n-byte-bits))
1192            (collect ((sc-offsets)
1193                      (lengths))
1194              (lengths 1)                ; the length byte
1195              (let* ((index 0)
1196                     (error-number (sb!c:read-var-integer vector index)))
1197                (lengths index)
1198                (loop
1199                  (when (>= index length)
1200                    (return))
1201                  (let ((old-index index))
1202                    (sc-offsets (sb!c:read-var-integer vector index))
1203                    (lengths (- index old-index))))
1204                (values error-number
1205                        (1+ length)
1206                        (sc-offsets)
1207                        (lengths))))))))
1208
1209 (defun unimp-control (chunk inst stream dstate)
1210   (declare (ignore inst))
1211   (flet ((nt (x) (if stream (sb!disassem:note x dstate))))
1212     (case (format-2-unimp-data chunk dstate)
1213       (#.error-trap
1214        (nt "Error trap")
1215        (sb!disassem:handle-break-args #'snarf-error-junk stream dstate))
1216       (#.cerror-trap
1217        (nt "Cerror trap")
1218        (sb!disassem:handle-break-args #'snarf-error-junk stream dstate))
1219       (#.object-not-list-trap
1220        (nt "Object not list trap"))
1221       (#.breakpoint-trap
1222        (nt "Breakpoint trap"))
1223       (#.pending-interrupt-trap
1224        (nt "Pending interrupt trap"))
1225       (#.halt-trap
1226        (nt "Halt trap"))
1227       (#.fun-end-breakpoint-trap
1228        (nt "Function end breakpoint trap"))
1229       (#.object-not-instance-trap
1230        (nt "Object not instance trap"))
1231     )))
1232
1233 (define-instruction unimp (segment data)
1234   (:declare (type (unsigned-byte 22) data))
1235   (:printer format-2-unimp () :default :control #'unimp-control
1236             :print-name #!-sparc-v9 'unimp #!+sparc-v9 'illtrap)
1237   (:delay 0)
1238   (:emitter (emit-format-2-unimp segment 0 0 0 data)))
1239
1240
1241 \f
1242 ;;;; Branch instructions.
1243
1244 ;; The branch instruction is deprecated on the Sparc V9.  Use the
1245 ;; branch with prediction instructions instead.
1246 (defun emit-relative-branch (segment a op2 cond-or-target target &optional fp)
1247   (emit-back-patch segment 4
1248     (lambda (segment posn)
1249         (unless target
1250           (setf target cond-or-target)
1251           (setf cond-or-target :t))
1252         (emit-format-2-branch
1253           segment #b00 a
1254           (if fp
1255               (fp-branch-condition cond-or-target)
1256               (branch-condition cond-or-target))
1257           op2
1258           (let ((offset (ash (- (label-position target) posn) -2)))
1259             (when (and (= a 1) (> 0 offset))
1260               (error "Offset of BA must be positive"))
1261             offset)))))
1262
1263 (defun emit-relative-branch-integer (segment a op2 cond-or-target target &optional (cc :icc) (pred :pt))
1264   (declare (type integer-condition-register cc))
1265   (assert (member :sparc-v9 *backend-subfeatures*))
1266   (emit-back-patch segment 4
1267     (lambda (segment posn)
1268         (unless target
1269           (setf target cond-or-target)
1270           (setf cond-or-target :t))
1271         (emit-format-2-branch-pred
1272           segment #b00 a
1273           (branch-condition cond-or-target)
1274           op2
1275           (integer-condition cc)
1276           (branch-prediction pred)
1277           (let ((offset (ash (- (label-position target) posn) -2)))
1278             (when (and (= a 1) (> 0 offset))
1279               (error "Offset of BA must be positive"))
1280             offset)))))
1281
1282 (defun emit-relative-branch-fp (segment a op2 cond-or-target target &optional (cc :fcc0) (pred :pt))
1283   (assert (member :sparc-v9 *backend-subfeatures*))
1284   (emit-back-patch segment 4
1285     (lambda (segment posn)
1286         (unless target
1287           (setf target cond-or-target)
1288           (setf cond-or-target :t))
1289         (emit-format-2-branch-pred
1290           segment #b00 a
1291           (fp-branch-condition cond-or-target)
1292           op2
1293           (fp-condition cc)
1294           (branch-prediction pred)
1295           (let ((offset (ash (- (label-position target) posn) -2)))
1296             (when (and (= a 1) (> 0 offset))
1297               (error "Offset of BA must be positive"))
1298             offset)))))
1299
1300 ;; So that I don't have to go change the syntax of every single use of
1301 ;; branches, I'm keeping the Lisp instruction names the same.  They
1302 ;; just get translated to the branch with prediction
1303 ;; instructions. However, the disassembler uses the correct V9
1304 ;; mnemonic.
1305 (define-instruction b (segment cond-or-target &rest args)
1306   (:declare (type (or label branch-condition) cond-or-target))
1307   (:printer format-2-branch ((op #b00) (op2 #b010)))
1308   (:attributes branch)
1309   (:dependencies (reads :psr))
1310   (:delay 1)
1311   (:emitter
1312    (cond
1313      ((member :sparc-v9 *backend-subfeatures*)
1314       (destructuring-bind (&optional target pred cc) args
1315         (declare (type (or label null) target))
1316         (emit-relative-branch-integer segment 0 #b001 cond-or-target target (or cc :icc) (or pred :pt))))
1317      (t
1318       (destructuring-bind (&optional target) args
1319         (declare (type (or label null) target))
1320         (emit-relative-branch segment 0 #b010 cond-or-target target))))))
1321
1322 (define-instruction bp (segment cond-or-target &optional target pred cc)
1323   (:declare (type (or label branch-condition) cond-or-target)
1324             (type (or label null) target))
1325   (:printer format-2-branch-pred ((op #b00) (op2 #b001))
1326             branch-pred-printer
1327             :print-name 'bp)
1328   (:attributes branch)
1329   (:dependencies (reads :psr))
1330   (:delay 1)
1331   (:emitter
1332    (emit-relative-branch-integer segment 0 #b001 cond-or-target target (or cc :icc) (or pred :pt))))
1333
1334 (define-instruction ba (segment cond-or-target &rest args)
1335   (:declare (type (or label branch-condition) cond-or-target))
1336   (:printer format-2-branch ((op #b00) (op2 #b010) (a 1))
1337             nil
1338             :print-name 'b)
1339   (:attributes branch)
1340   (:dependencies (reads :psr))
1341   (:delay 0)
1342   (:emitter
1343    (cond
1344      ((member :sparc-v9 *backend-subfeatures*)
1345       (destructuring-bind (&optional target pred cc) args
1346         (declare (type (or label null) target))
1347         (emit-relative-branch-integer segment 1 #b001 cond-or-target target (or cc :icc) (or pred :pt))))
1348      (t
1349       (destructuring-bind (&optional target) args
1350         (declare (type (or label null) target))
1351         (emit-relative-branch segment 1 #b010 cond-or-target target))))))
1352
1353 (define-instruction bpa (segment cond-or-target &optional target pred cc)
1354   (:declare (type (or label branch-condition) cond-or-target)
1355             (type (or label null) target))
1356   (:printer format-2-branch ((op #b00) (op2 #b001) (a 1))
1357             nil
1358             :print-name 'bp)
1359   (:attributes branch)
1360   (:dependencies (reads :psr))
1361   (:delay 0)
1362   (:emitter
1363    (emit-relative-branch-integer segment 1 #b001 cond-or-target target (or cc :icc) (or pred :pt))))
1364
1365 ;; This doesn't cover all of the possible formats for the trap
1366 ;; instruction.  We really only want a trap with a immediate trap
1367 ;; value and with RS1 = register 0.  Also, the Sparc Compliance
1368 ;; Definition 2.4.1 says only trap numbers 16-31 are allowed for user
1369 ;; code.  All other trap numbers have other uses.  The restriction on
1370 ;; target will prevent us from using bad trap numbers by mistake.
1371
1372 (define-instruction t (segment condition target &optional cc)
1373   (:declare (type branch-condition condition)
1374             ;; KLUDGE: see comments in vm.lisp regarding
1375             ;; pseudo-atomic-trap.
1376             #!-linux
1377             (type (integer 16 31) target))
1378   (:printer format-3-immed ((op #b10)
1379                             (rd nil :type 'branch-condition)
1380                             (op3 #b111010)
1381                             (rs1 0))
1382             '(:name rd :tab immed))
1383   (:attributes branch)
1384   (:dependencies (reads :psr))
1385   (:delay 0)
1386   (:emitter 
1387    (cond
1388      ((member :sparc-v9 *backend-subfeatures*)
1389       (unless cc
1390         (setf cc :icc))
1391       (emit-format-4-trap segment
1392                           #b10
1393                           (branch-condition condition)
1394                           #b111010 0 1
1395                           (integer-condition cc)
1396                           target))
1397      (t
1398       (assert (null cc))
1399       (emit-format-3-immed segment #b10 (branch-condition condition)
1400                            #b111010 0 1 target)))))
1401
1402 ;;; KLUDGE: we leave this commented out, as these two (T and TCC)
1403 ;;; operations are actually indistinguishable from their bitfields,
1404 ;;; breaking the disassembler if these are left in. The printer isn't
1405 ;;; terribly smart, but the emitted code is right. - CSR, 2002-08-04
1406 #+nil
1407 (define-instruction tcc (segment condition target &optional (cc #!-sparc-64 :icc #!+sparc-64 :xcc))
1408   (:declare (type branch-condition condition)
1409             ;; KLUDGE: see above.
1410             #!-linux
1411             (type (integer 16 31) target)
1412             (type integer-condition-register cc))
1413   (:printer format-4-trap ((op #b10)
1414                             (rd nil :type 'branch-condition)
1415                             (op3 #b111010)
1416                             (rs1 0))
1417             trap-printer)
1418   (:attributes branch)
1419   (:dependencies (reads :psr))
1420   (:delay 0)
1421   (:emitter (emit-format-4-trap segment
1422                                 #b10
1423                                 (branch-condition condition)
1424                                 #b111010 0 1
1425                                 (integer-condition cc)
1426                                 target)))
1427
1428 ;; Same as for the branch instructions.  On the Sparc V9, we will use
1429 ;; the FP branch with prediction instructions instead.
1430
1431 (define-instruction fb (segment condition target &rest args)
1432   (:declare (type fp-branch-condition condition) (type label target))
1433   (:printer format-2-branch ((op #B00)
1434                              (cond nil :type 'branch-fp-condition)
1435                              (op2 #b110)))
1436   (:attributes branch)
1437   (:dependencies (reads :fsr))
1438   (:delay 1)
1439   (:emitter
1440    (cond
1441      ((member :sparc-v9 *backend-subfeatures*)
1442       (destructuring-bind (&optional fcc pred) args
1443         (emit-relative-branch-fp segment 0 #b101 condition target (or fcc :fcc0) (or pred :pt))))
1444      (t 
1445       (assert (null args))
1446       (emit-relative-branch segment 0 #b110 condition target t)))))
1447
1448 (define-instruction fbp (segment condition target &optional fcc pred)
1449   (:declare (type fp-branch-condition condition) (type label target))
1450   (:printer format-2-fp-branch-pred ((op #b00) (op2 #b101))
1451             fp-branch-pred-printer
1452             :print-name 'fbp)
1453   (:attributes branch)
1454   (:dependencies (reads :fsr))
1455   (:delay 1)
1456   (:emitter
1457    (emit-relative-branch-fp segment 0 #b101 condition target (or fcc :fcc0) (or pred :pt))))
1458
1459 (defconstant-eqx jal-printer
1460   '(:name :tab
1461           (:choose (rs1 (:unless (:constant 0) (:plus-integer immed)))
1462                    (:cond ((rs2 :constant 0) rs1)
1463                           ((rs1 :constant 0) rs2)
1464                           (t rs1 "+" rs2)))
1465           (:unless (:constant 0) ", " rd))
1466   #'equalp)
1467
1468 (define-instruction jal (segment dst src1 &optional src2)
1469   (:declare (type tn dst)
1470             (type (or tn integer) src1)
1471             (type (or null fixup tn (signed-byte 13)) src2))
1472   (:printer format-3-reg ((op #b10) (op3 #b111000)) jal-printer)
1473   (:printer format-3-immed ((op #b10) (op3 #b111000)) jal-printer)
1474   (:attributes branch)
1475   (:dependencies (reads src1) (if src2 (reads src2) (reads dst)) (writes dst))
1476   (:delay 1)
1477   (:emitter
1478    (unless src2
1479      (setf src2 src1)
1480      (setf src1 0))
1481    (etypecase src2
1482      (tn
1483       (emit-format-3-reg segment #b10 (reg-tn-encoding dst) #b111000
1484                          (if (integerp src1)
1485                              src1
1486                              (reg-tn-encoding src1))
1487                          0 0 (reg-tn-encoding src2)))
1488      (integer
1489       (emit-format-3-immed segment #b10 (reg-tn-encoding dst) #b111000
1490                            (reg-tn-encoding src1) 1 src2))
1491      (fixup
1492       (note-fixup segment :add src2)
1493       (emit-format-3-immed segment #b10 (reg-tn-encoding dst)
1494                            #b111000 (reg-tn-encoding src1) 1 0)))))
1495
1496 (define-instruction j (segment src1 &optional src2)
1497   (:declare (type tn src1) (type (or tn (signed-byte 13) fixup null) src2))
1498   (:printer format-3-reg ((op #b10) (op3 #b111000) (rd 0)) jal-printer)
1499   (:printer format-3-immed ((op #b10) (op3 #b111000) (rd 0)) jal-printer)
1500   (:attributes branch)
1501   (:dependencies (reads src1) (if src2 (reads src2)))
1502   (:delay 1)
1503   (:emitter
1504    (etypecase src2
1505      (null
1506       (emit-format-3-reg segment #b10 0 #b111000 (reg-tn-encoding src1) 0 0 0))
1507      (tn
1508       (emit-format-3-reg segment #b10 0 #b111000 (reg-tn-encoding src1) 0 0
1509                          (reg-tn-encoding src2)))
1510      (integer
1511       (emit-format-3-immed segment #b10 0 #b111000 (reg-tn-encoding src1) 1
1512                            src2))
1513      (fixup
1514       (note-fixup segment :add src2)
1515       (emit-format-3-immed segment #b10 0 #b111000 (reg-tn-encoding src1) 1
1516                            0)))))
1517
1518
1519 \f
1520 ;;;; Unary and binary fp insts.
1521
1522 (macrolet ((define-unary-fp-inst (name opf &key reads extended)
1523   `(define-instruction ,name (segment dst src)
1524      (:declare (type tn dst src))
1525      (:printer format-unary-fpop
1526        ((op #b10) (op3 #b110100) (opf ,opf)
1527         (rs1 0)
1528         (rs2 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
1529         (rd nil :type ',(if extended 'fp-ext-reg 'fp-reg))))
1530      (:dependencies
1531       ,@(when reads
1532           `((reads ,reads)))
1533       (reads dst)
1534       (reads src)
1535       (writes dst))
1536      (:delay 0)
1537      (:emitter (emit-format-3-fpop segment #b10 (fp-reg-tn-encoding dst)
1538                 #b110100 0 ,opf (fp-reg-tn-encoding src)))))
1539
1540            (define-binary-fp-inst (name opf &key (op3 #b110100)
1541                                       reads writes delay extended)
1542   `(define-instruction ,name (segment dst src1 src2)
1543      (:declare (type tn dst src1 src2))
1544      (:printer format-binary-fpop
1545       ((op #b10) (op3 ,op3) (opf ,opf)
1546        (rs1 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
1547        (rs2 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
1548        (rd nil :type ',(if extended 'fp-ext-reg 'fp-reg))
1549        ))
1550      (:dependencies
1551       ,@(when reads
1552           `((reads ,reads)))
1553       (reads src1)
1554       (reads src2)
1555       ,@(when writes
1556           `((writes ,writes)))
1557       (writes dst))
1558      ,@(if delay
1559            `((:delay ,delay))
1560            '((:delay 0)))
1561      (:emitter (emit-format-3-fpop segment #b10 (fp-reg-tn-encoding dst)
1562                 ,op3 (fp-reg-tn-encoding src1) ,opf
1563                 (fp-reg-tn-encoding src2)))))
1564
1565            (define-cmp-fp-inst (name opf &key extended)
1566                (let ((opf0 #b0)
1567                      (opf1 #b010)
1568                      (opf2 #b1))
1569                  `(define-instruction ,name (segment src1 src2 &optional (fcc :fcc0))
1570                    (:declare (type tn src1 src2)
1571                     (type (member :fcc0 :fcc1 :fcc2 :fcc3) fcc))
1572        (:printer format-fpop2
1573                  ((op #b10)
1574                   (op3 #b110101)
1575                   (opf0 ,opf0)
1576                   (opf1 ,opf1)
1577                   (opf2 ,opf2)
1578                   (opf3 ,opf)
1579                   (rs1 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
1580                   (rs2 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
1581                   #!-sparc-v9
1582                   (rd 0)
1583                   #!+sparc-v9
1584                   (rd nil :type 'fp-condition-register))
1585         )
1586      (:dependencies
1587       (reads src1)
1588       (reads src2)
1589       (writes :fsr))
1590      ;; The Sparc V9 doesn't need a delay after a FP compare.
1591      ;;
1592      ;; KLUDGE FIXME YAARGH -- how to express that? I guess for now we
1593      ;; do the worst case, and hope to fix it.
1594      ;; (:delay #-sparc-v9 1 #+sparc-v9 0)
1595      (:delay 1)
1596        (:emitter
1597         (emit-format-3-fpop2 segment #b10
1598                              (or (position fcc '(:fcc0 :fcc1 :fcc2 :fcc3))
1599                                  0)
1600                              #b110101
1601                              (fp-reg-tn-encoding src1)
1602                              ,opf0 ,opf1 ,opf2 ,opf
1603                              (fp-reg-tn-encoding src2)))))))
1604
1605   (define-unary-fp-inst fitos #b011000100 :reads :fsr)
1606   (define-unary-fp-inst fitod #b011001000 :reads :fsr :extended t)
1607   (define-unary-fp-inst fitoq #b011001100 :reads :fsr :extended t)      ; v8
1608   
1609   (define-unary-fp-inst fxtos #b010000100 :reads :fsr)                    ; v9
1610   (define-unary-fp-inst fxtod #b010001000 :reads :fsr :extended t)        ; v9
1611   (define-unary-fp-inst fxtoq #b010001100 :reads :fsr :extended t)      ; v9
1612
1613
1614   ;; I (Raymond Toy) don't think these f{sd}toir instructions exist on
1615   ;; any Ultrasparc, but I only have a V9 manual. The code in
1616   ;; float.lisp seems to indicate that they only existed on non-sun4
1617   ;; machines (sun3 68K machines?).
1618   (define-unary-fp-inst fstoir #b011000001 :reads :fsr)
1619   (define-unary-fp-inst fdtoir #b011000010 :reads :fsr)
1620   
1621   (define-unary-fp-inst fstoi #b011010001)
1622   (define-unary-fp-inst fdtoi #b011010010 :extended t)
1623   (define-unary-fp-inst fqtoi #b011010011 :extended t)  ; v8
1624
1625   (define-unary-fp-inst fstox #b010000001)                ; v9
1626   (define-unary-fp-inst fdtox #b010000010 :extended t)    ; v9
1627   (define-unary-fp-inst fqtox #b010000011 :extended t)  ; v9
1628
1629   (define-unary-fp-inst fstod #b011001001 :reads :fsr)
1630   (define-unary-fp-inst fstoq #b011001101 :reads :fsr)  ; v8
1631   (define-unary-fp-inst fdtos #b011000110 :reads :fsr)
1632   (define-unary-fp-inst fdtoq #b011001110 :reads :fsr)  ; v8
1633   (define-unary-fp-inst fqtos #b011000111 :reads :fsr)  ; v8
1634   (define-unary-fp-inst fqtod #b011001011 :reads :fsr)  ; v8
1635   
1636   (define-unary-fp-inst fmovs #b000000001)
1637   (define-unary-fp-inst fmovd #b000000010 :extended t)  ; v9
1638   (define-unary-fp-inst fmovq #b000000011 :extended t)  ; v9
1639   
1640   (define-unary-fp-inst fnegs #b000000101)
1641   (define-unary-fp-inst fnegd #b000000110 :extended t)  ; v9
1642   (define-unary-fp-inst fnegq #b000000111 :extended t)  ; v9
1643
1644   (define-unary-fp-inst fabss #b000001001)
1645   (define-unary-fp-inst fabsd #b000001010 :extended t)  ; v9
1646   (define-unary-fp-inst fabsq #b000001011 :extended t)  ; v9
1647   
1648   (define-unary-fp-inst fsqrts #b000101001 :reads :fsr)         ; V7
1649   (define-unary-fp-inst fsqrtd #b000101010 :reads :fsr :extended t)     ; V7
1650   (define-unary-fp-inst fsqrtq #b000101011 :reads :fsr :extended t)     ; v8
1651   
1652   (define-binary-fp-inst fadds #b001000001)
1653   (define-binary-fp-inst faddd #b001000010 :extended t)
1654   (define-binary-fp-inst faddq #b001000011 :extended t) ; v8
1655   (define-binary-fp-inst fsubs #b001000101)
1656   (define-binary-fp-inst fsubd #b001000110 :extended t)
1657   (define-binary-fp-inst fsubq #b001000111 :extended t) ; v8
1658   
1659   (define-binary-fp-inst fmuls #b001001001)
1660   (define-binary-fp-inst fmuld #b001001010 :extended t)
1661   (define-binary-fp-inst fmulq #b001001011 :extended t) ; v8
1662   (define-binary-fp-inst fdivs #b001001101)
1663   (define-binary-fp-inst fdivd #b001001110 :extended t)
1664   (define-binary-fp-inst fdivq #b001001111 :extended t) ; v8
1665
1666 ;;; Float comparison instructions.
1667 ;;;
1668   (define-cmp-fp-inst fcmps #b0001)
1669   (define-cmp-fp-inst fcmpd #b0010 :extended t)
1670   (define-cmp-fp-inst fcmpq #b0011 :extended t) ;v8
1671   (define-cmp-fp-inst fcmpes #b0101)
1672   (define-cmp-fp-inst fcmped #b0110 :extended t)
1673   (define-cmp-fp-inst fcmpeq #b0111 :extended t)        ; v8
1674
1675 ) ; MACROLET
1676 \f
1677 ;;;; li, jali, ji, nop, cmp, not, neg, move, and more
1678
1679 (defun %li (reg value)
1680   (etypecase value
1681     ((signed-byte 13)
1682      (inst add reg zero-tn value))
1683     ((or (signed-byte 32) (unsigned-byte 32))
1684      (let ((hi (ldb (byte 22 10) value))
1685            (lo (ldb (byte 10 0) value)))
1686        (inst sethi reg hi)
1687        (unless (zerop lo)
1688          (inst add reg lo))))
1689     (fixup
1690      (inst sethi reg value)
1691      (inst add reg value))))
1692
1693 (define-instruction-macro li (reg value)
1694   `(%li ,reg ,value))
1695
1696 ;;; Jal to a full 32-bit address.  Tmpreg is trashed.
1697 (define-instruction jali (segment link tmpreg value)
1698   (:declare (type tn link tmpreg)
1699             (type (or (signed-byte 13) (signed-byte 32) (unsigned-byte 32)
1700                       fixup) value))
1701   (:attributes variable-length)
1702   (:vop-var vop)
1703   (:attributes branch)
1704   (:dependencies (writes link) (writes tmpreg))
1705   (:delay 1)
1706   (:emitter
1707    (assemble (segment vop)
1708      (etypecase value
1709        ((signed-byte 13)
1710         (inst jal link zero-tn value))
1711        ((or (signed-byte 32) (unsigned-byte 32))
1712         (let ((hi (ldb (byte 22 10) value))
1713               (lo (ldb (byte 10 0) value)))
1714           (inst sethi tmpreg hi)
1715           (inst jal link tmpreg lo)))
1716        (fixup
1717         (inst sethi tmpreg value)
1718         (inst jal link tmpreg value))))))
1719
1720 ;;; Jump to a full 32-bit address.  Tmpreg is trashed.
1721 (define-instruction ji (segment tmpreg value)
1722   (:declare (type tn tmpreg)
1723             (type (or (signed-byte 13) (signed-byte 32) (unsigned-byte 32)
1724                       fixup) value))
1725   (:attributes variable-length)
1726   (:vop-var vop)
1727   (:attributes branch)
1728   (:dependencies (writes tmpreg))
1729   (:delay 1)
1730   (:emitter
1731    (assemble (segment vop)
1732              (inst jali zero-tn tmpreg value))))
1733
1734 (define-instruction nop (segment)
1735   (:printer format-2-immed ((rd 0) (op2 #b100) (immed 0)) '(:name))
1736   (:attributes flushable)
1737   (:delay 0)
1738   (:emitter (emit-format-2-immed segment 0 0 #b100 0)))
1739
1740 (!def-vm-support-routine emit-nop (segment)
1741   (emit-format-2-immed segment 0 0 #b100 0))
1742
1743 (define-instruction cmp (segment src1 &optional src2)
1744   (:declare (type tn src1) (type (or null tn (signed-byte 13)) src2))
1745   (:printer format-3-reg ((op #b10) (op3 #b010100) (rd 0))
1746             '(:name :tab rs1 ", " rs2))
1747   (:printer format-3-immed ((op #b10) (op3 #b010100) (rd 0))
1748             '(:name :tab rs1 ", " immed))
1749   (:dependencies (reads src1) (if src2 (reads src2)) (writes :psr))
1750   (:delay 0)
1751   (:emitter
1752    (etypecase src2
1753      (null
1754       (emit-format-3-reg segment #b10 0 #b010100 (reg-tn-encoding src1) 0 0 0))
1755      (tn
1756       (emit-format-3-reg segment #b10 0 #b010100 (reg-tn-encoding src1) 0 0
1757                          (reg-tn-encoding src2)))
1758      (integer
1759       (emit-format-3-immed segment #b10 0 #b010100 (reg-tn-encoding src1) 1
1760                            src2)))))
1761
1762 (define-instruction not (segment dst &optional src1)
1763   (:declare (type tn dst) (type (or tn null) src1))
1764   (:printer format-3-reg ((op #b10) (op3 #b000111) (rs2 0))
1765             '(:name :tab (:unless (:same-as rd) rs1 ", " ) rd))
1766   (:dependencies (if src1 (reads src1) (reads dst)) (writes dst))
1767   (:delay 0)
1768   (:emitter
1769    (unless src1
1770      (setf src1 dst))
1771    (emit-format-3-reg segment #b10 (reg-tn-encoding dst) #b000111
1772                       (reg-tn-encoding src1) 0 0 0)))
1773
1774 (define-instruction neg (segment dst &optional src1)
1775   (:declare (type tn dst) (type (or tn null) src1))
1776   (:printer format-3-reg ((op #b10) (op3 #b000100) (rs1 0))
1777             '(:name :tab (:unless (:same-as rd) rs2 ", " ) rd))
1778   (:dependencies (if src1 (reads src1) (reads dst)) (writes dst))
1779   (:delay 0)
1780   (:emitter
1781    (unless src1
1782      (setf src1 dst))
1783    (emit-format-3-reg segment #b10 (reg-tn-encoding dst) #b000100
1784                       0 0 0 (reg-tn-encoding src1))))
1785
1786 (define-instruction move (segment dst src1)
1787   (:declare (type tn dst src1))
1788   (:printer format-3-reg ((op #b10) (op3 #b000010) (rs1 0))
1789             '(:name :tab rs2 ", " rd)
1790             :print-name 'mov)
1791   (:attributes flushable)
1792   (:dependencies (reads src1) (writes dst))
1793   (:delay 0)
1794   (:emitter (emit-format-3-reg segment #b10 (reg-tn-encoding dst) #b000010
1795                                0 0 0 (reg-tn-encoding src1))))
1796
1797
1798 \f
1799 ;;;; Instructions for dumping data and header objects.
1800
1801 (define-instruction word (segment word)
1802   (:declare (type (or (unsigned-byte 32) (signed-byte 32)) word))
1803   :pinned
1804   (:delay 0)
1805   (:emitter
1806    (emit-word segment word)))
1807
1808 (define-instruction short (segment short)
1809   (:declare (type (or (unsigned-byte 16) (signed-byte 16)) short))
1810   :pinned
1811   (:delay 0)
1812   (:emitter
1813    (emit-short segment short)))
1814
1815 (define-instruction byte (segment byte)
1816   (:declare (type (or (unsigned-byte 8) (signed-byte 8)) byte))
1817   :pinned
1818   (:delay 0)
1819   (:emitter
1820    (emit-byte segment byte)))
1821
1822 (define-bitfield-emitter emit-header-object 32
1823   (byte 24 8) (byte 8 0))
1824   
1825 (defun emit-header-data (segment type)
1826   (emit-back-patch
1827    segment 4
1828    (lambda (segment posn)
1829        (emit-word segment
1830                   (logior type
1831                           (ash (+ posn (component-header-length))
1832                                (- n-widetag-bits word-shift)))))))
1833
1834 (define-instruction simple-fun-header-word (segment)
1835   :pinned
1836   (:delay 0)
1837   (:emitter
1838    (emit-header-data segment simple-fun-header-widetag)))
1839
1840 (define-instruction lra-header-word (segment)
1841   :pinned
1842   (:delay 0)
1843   (:emitter
1844    (emit-header-data segment return-pc-header-widetag)))
1845
1846 \f
1847 ;;;; Instructions for converting between code objects, functions, and lras.
1848
1849 (defun emit-compute-inst (segment vop dst src label temp calc)
1850   (emit-chooser
1851    ;; We emit either 12 or 4 bytes, so we maintain 8 byte alignments.
1852    segment 12 3
1853    (lambda (segment posn delta-if-after)
1854        (let ((delta (funcall calc label posn delta-if-after)))
1855          (when (<= (- (ash 1 12)) delta (1- (ash 1 12)))
1856            (emit-back-patch segment 4
1857                             (lambda (segment posn)
1858                                 (assemble (segment vop)
1859                                           (inst add dst src
1860                                                 (funcall calc label posn 0)))))
1861            t)))
1862    (lambda (segment posn)
1863        (let ((delta (funcall calc label posn 0)))
1864          (assemble (segment vop)
1865                    (inst sethi temp (ldb (byte 22 10) delta))
1866                    (inst or temp (ldb (byte 10 0) delta))
1867                    (inst add dst src temp))))))
1868
1869 ;; code = fn - fn-ptr-type - header - label-offset + other-pointer-tag
1870 (define-instruction compute-code-from-fn (segment dst src label temp)
1871   (:declare (type tn dst src temp) (type label label))
1872   (:attributes variable-length)
1873   (:dependencies (reads src) (writes dst) (writes temp))
1874   (:delay 0)
1875   (:vop-var vop)
1876   (:emitter
1877    (emit-compute-inst segment vop dst src label temp
1878                       (lambda (label posn delta-if-after)
1879                           (- other-pointer-lowtag
1880                              fun-pointer-lowtag
1881                              (label-position label posn delta-if-after)
1882                              (component-header-length))))))
1883
1884 ;; code = lra - other-pointer-tag - header - label-offset + other-pointer-tag
1885 (define-instruction compute-code-from-lra (segment dst src label temp)
1886   (:declare (type tn dst src temp) (type label label))
1887   (:attributes variable-length)
1888   (:dependencies (reads src) (writes dst) (writes temp))
1889   (:delay 0)
1890   (:vop-var vop)
1891   (:emitter
1892    (emit-compute-inst segment vop dst src label temp
1893                       (lambda (label posn delta-if-after)
1894                           (- (+ (label-position label posn delta-if-after)
1895                                 (component-header-length)))))))
1896
1897 ;; lra = code + other-pointer-tag + header + label-offset - other-pointer-tag
1898 (define-instruction compute-lra-from-code (segment dst src label temp)
1899   (:declare (type tn dst src temp) (type label label))
1900   (:attributes variable-length)
1901   (:dependencies (reads src) (writes dst) (writes temp))
1902   (:delay 0)
1903   (:vop-var vop)
1904   (:emitter
1905    (emit-compute-inst segment vop dst src label temp
1906                       (lambda (label posn delta-if-after)
1907                           (+ (label-position label posn delta-if-after)
1908                              (component-header-length))))))
1909 \f
1910 ;;; Sparc V9 additions
1911
1912
1913
1914 ;; Conditional move integer on condition code
1915 (define-instruction cmove (segment condition dst src &optional (ccreg :icc))
1916   (:declare (type (or branch-condition fp-branch-condition) condition)
1917             (type cond-move-condition-register ccreg)
1918             (type tn dst)
1919             (type (or (signed-byte 13) tn) src))
1920   (:printer format-4-cond-move
1921             ((op #b10)
1922              (op3 #b101100)
1923              (cc2 #b1)
1924              (i 0)
1925              (cc nil :type 'integer-condition-register))
1926              cond-move-printer
1927              :print-name 'mov)
1928   (:printer format-4-cond-move-immed
1929             ((op #b10)
1930              (op3 #b101100)
1931              (cc2 #b1)
1932              (i 1)
1933              (cc nil :type 'integer-condition-register))
1934              cond-move-printer
1935              :print-name 'mov)
1936   (:printer format-4-cond-move
1937             ((op #b10)
1938              (op3 #b101100)
1939              (cc2 #b0)
1940              (cond nil :type 'branch-fp-condition)
1941              (i 0)
1942              (cc nil :type 'fp-condition-register))
1943              cond-move-printer
1944              :print-name 'mov)
1945   (:printer format-4-cond-move-immed
1946             ((op #b10)
1947              (op3 #b101100)
1948              (cc2 #b0)
1949              (cond nil :type 'branch-fp-condition)
1950              (i 1)
1951              (cc nil :type 'fp-condition-register))
1952              cond-move-printer
1953              :print-name 'mov)
1954   (:delay 0)
1955   (:dependencies
1956    (if (member ccreg '(:icc :xcc))
1957        (reads :psr)
1958        (reads :fsr))
1959    (reads src)
1960    (reads dst)
1961    (writes dst))
1962   (:emitter
1963    (let ((op #b10)
1964          (op3 #b101100))
1965      (multiple-value-bind (cc2 cc01)
1966          (cond-move-condition-parts ccreg)
1967        (etypecase src
1968          (tn
1969           (emit-format-4-cond-move segment
1970                                    op
1971                                    (reg-tn-encoding dst)
1972                                    op3
1973                                    cc2
1974                                    (if (member ccreg '(:icc :xcc))
1975                                        (branch-condition condition)
1976                                        (fp-branch-condition condition))
1977                                    0
1978                                    cc01
1979                                    (reg-tn-encoding src)))
1980          (integer
1981           (emit-format-4-cond-move segment
1982                                    op
1983                                    (reg-tn-encoding dst)
1984                                    op3
1985                                    cc2
1986                                    (if (member ccreg '(:icc :xcc))
1987                                        (branch-condition condition)
1988                                        (fp-branch-condition condition))
1989                                    1
1990                                    cc01
1991                                    src)))))))
1992
1993 ;; Conditional move floating-point on condition codes
1994 (macrolet ((define-cond-fp-move (name print-name op op3 opf_low &key extended)
1995   `(define-instruction ,name (segment condition dst src &optional (ccreg :fcc0))
1996      (:declare (type (or branch-condition fp-branch-condition) condition)
1997                (type cond-move-condition-register ccreg)
1998                (type tn dst src))
1999      (:printer format-fpop2
2000                ((op ,op)
2001                 (op3 ,op3)
2002                 (opf0 0)
2003                 (opf1 nil :type 'fp-condition-register-shifted)
2004                 (opf2 0)
2005                 (opf3 ,opf_low)
2006                 (rs1 nil :type 'branch-fp-condition)
2007                 (rs2 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
2008                 (rd nil :type ',(if extended 'fp-ext-reg 'fp-reg)))
2009                 cond-fp-move-printer
2010                 :print-name ',print-name)
2011      (:printer format-fpop2
2012                ((op ,op)
2013                 (op3 ,op3)
2014                 (opf0 1)
2015                 (opf1 nil :type 'integer-condition-register)
2016                 (opf2 0)
2017                 (rs1 nil :type 'branch-condition)
2018                 (opf3 ,opf_low)
2019                 (rs2 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
2020                 (rd nil :type ',(if extended 'fp-ext-reg 'fp-reg)))
2021                cond-fp-move-printer
2022                :print-name ',print-name)
2023      (:delay 0)
2024      (:dependencies
2025       (if (member ccreg '(:icc :xcc))
2026           (reads :psr)
2027           (reads :fsr))
2028       (reads src)
2029       (reads dst)
2030       (writes dst))
2031      (:emitter
2032       (multiple-value-bind (opf_cc2 opf_cc01)
2033           (cond-move-condition-parts ccreg)
2034         (emit-format-3-fpop2 segment
2035                              ,op
2036                              (fp-reg-tn-encoding dst)
2037                              ,op3
2038                              (if (member ccreg '(:icc :xcc))
2039                                  (branch-condition condition)
2040                                  (fp-branch-condition condition))
2041                              opf_cc2
2042                              (ash opf_cc01 1)
2043                              0
2044                              ,opf_low
2045                              (fp-reg-tn-encoding src)))))))
2046   (define-cond-fp-move cfmovs fmovs #b10 #b110101 #b0001)
2047   (define-cond-fp-move cfmovd fmovd #b10 #b110101 #b0010 :extended t)
2048   (define-cond-fp-move cfmovq fmovq #b10 #b110101 #b0011 :extended t))
2049
2050
2051 ;; Move on integer register condition
2052 ;;
2053 ;; movr dst src reg reg-cond
2054 ;;
2055 ;; This means if reg satisfies reg-cond, src is copied to dst.  If the
2056 ;; condition is not satisfied, nothing is done.
2057 ;;
2058 (define-instruction movr (segment dst src2 src1 reg-condition)
2059   (:declare (type cond-move-integer-condition reg-condition)
2060             (type tn dst src1)
2061             (type (or (signed-byte 10) tn) src2))
2062   (:printer format-4-cond-move-integer
2063             ((op #b10)
2064              (op3 #b101111)
2065              (i 0)))
2066   (:printer format-4-cond-move-integer-immed
2067             ((op #b10)
2068              (op3 #b101111)
2069              (i 1)))
2070   (:delay 0)
2071   (:dependencies
2072    (reads :psr)
2073    (reads src2)
2074    (reads src1)
2075    (reads dst)
2076    (writes dst))
2077   (:emitter
2078    (etypecase src2
2079      (tn
2080       (emit-format-4-cond-move-integer
2081        segment #b10 (reg-tn-encoding dst) #b101111 (reg-tn-encoding src1)
2082        0 (register-condition reg-condition)
2083        0 (reg-tn-encoding src2)))
2084      (integer
2085       (emit-format-4-cond-move-integer-immed
2086        segment #b10 (reg-tn-encoding dst) #b101111 (reg-tn-encoding src1)
2087        1 (register-condition reg-condition) src2)))))
2088
2089
2090 ;; Same as MOVR, except we move FP registers depending on the value of
2091 ;; an integer register.
2092 ;;
2093 ;; fmovr dst src reg cond
2094 ;;
2095 ;; This means if REG satifies COND, SRC is COPIED to DST.  Nothing
2096 ;; happens if the condition is not satisfied.
2097 (macrolet ((define-cond-fp-move-integer (name opf_low &key extended)
2098   `(define-instruction ,name (segment dst src2 src1 reg-condition)
2099      (:declare (type cond-move-integer-condition reg-condition)
2100                (type tn dst src1 src2))
2101      (:printer format-fpop2
2102                ((op #b10)
2103                 (rd nil :type ',(if extended 'fp-ext-reg 'fp-reg))
2104                 (op3 #b110101)
2105                 (rs1 nil :type 'reg)
2106                 (opf0 0)
2107                 (opf1 nil :type 'register-condition)
2108                 (opf2 0)
2109                 (opf3 ,opf_low)
2110                 (rs2 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
2111                 )
2112                cond-fp-move-integer-printer)
2113      (:delay 0)
2114      (:dependencies
2115       (reads src2)
2116       (reads src1)
2117       (reads dst)
2118       (writes dst))
2119      (:emitter
2120       (emit-format-3-fpop2
2121        segment
2122        #b10
2123        (fp-reg-tn-encoding dst)
2124        #b110101
2125        (reg-tn-encoding src1)
2126        0
2127        (register-condition reg-condition)
2128        0
2129        ,opf_low
2130        (fp-reg-tn-encoding src2))))))
2131   (define-cond-fp-move-integer fmovrs #b0101)
2132   (define-cond-fp-move-integer fmovrd #b0110 :extended t)
2133   (define-cond-fp-move-integer fmovrq #b0111 :extended t))