0.8.0.78.vector-nil-string.1:
[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
639 (defconstant-eqx cond-move-printer
640   `(:name cond :tab
641           cc ", " (:choose immed rs2) ", " rd)
642   #'equalp)
643
644 ;; Conditional move integer register on integer or FP condition code
645 (sb!disassem:define-instruction-format
646     (format-4-cond-move 32 :default-printer cond-move-printer)
647   (op   :field (byte 2 30))
648   (rd    :field (byte 5 25) :type 'reg)
649   (op3  :field (byte 6 19))
650   (cc2   :field (byte 1 18) :value 1)
651   (cond  :field (byte 4 14) :type 'branch-condition)
652   (i     :field (byte 1 13) :value 0)
653   (cc    :field (byte 2 11) :type 'integer-condition-register)
654   (empty :field (byte 6 5) :value 0)
655   (rs2   :field (byte 5 0) :type 'reg))
656
657 (sb!disassem:define-instruction-format
658     (format-4-cond-move-immed 32 :default-printer cond-move-printer)
659   (op    :field (byte 2 30))
660   (rd    :field (byte 5 25) :type 'reg)
661   (op3   :field (byte 6 19))
662   (cc2   :field (byte 1 18) :value 1)
663   (cond  :field (byte 4 14) :type 'branch-condition)
664   (i     :field (byte 1 13) :value 1)
665   (cc    :field (byte 2 11) :type 'integer-condition-register)
666   (immed :field (byte 11 0) :sign-extend t))
667
668 ;; Floating-point versions of the above integer conditional moves
669 (defconstant-eqx cond-fp-move-printer
670   `(:name rs1 :tab opf1 ", " rs2 ", " rd)
671   #'equalp)
672
673 ;;; Conditional move on integer register condition (only on Sparc
674 ;;; V9). That is, move an integer register if some other integer
675 ;;; register satisfies some condition.
676
677 (defconstant-eqx cond-move-integer-conditions
678   '(:reserved :z :lez :lz :reserved :nz :gz :gez)
679   #'equalp)
680
681 (defconstant-eqx cond-move-integer-condition-vec
682   (coerce cond-move-integer-conditions 'vector)
683   #'equalp)
684
685 (deftype cond-move-integer-condition ()
686   `(member ,@(remove :reserved cond-move-integer-conditions)))
687
688 (sb!disassem:define-arg-type register-condition
689     :printer (lambda (value stream dstate)
690                  (declare (stream stream) (fixnum value) (ignore dstate))
691                  (let ((regname (aref cond-move-integer-condition-vec value)))
692                    (princ regname stream))))
693
694 (defconstant-eqx cond-move-integer-printer
695   `(:name rcond :tab rs1 ", " (:choose immed rs2) ", " rd)
696   #'equalp)
697
698 (defun register-condition (rcond)
699   (or (position rcond cond-move-integer-conditions)
700       (error "Unknown register condition:  ~S~%")))
701
702 (sb!disassem:define-instruction-format
703     (format-4-cond-move-integer 32 :default-printer cond-move-integer-printer)
704   (op    :field (byte 2 30))
705   (rd    :field (byte 5 25) :type 'reg)
706   (op3   :field (byte 6 19))
707   (rs1   :field (byte 5 14) :type 'reg)
708   (i     :field (byte 1 13) :value 0)
709   (rcond :field (byte 3 10) :type 'register-condition)
710   (opf   :field (byte 5 5))
711   (rs2   :field (byte 5 0) :type 'reg))
712
713 (sb!disassem:define-instruction-format
714     (format-4-cond-move-integer-immed 32 :default-printer cond-move-integer-printer)
715   (op    :field (byte 2 30))
716   (rd    :field (byte 5 25) :type 'reg)
717   (op3   :field (byte 6 19))
718   (rs1   :field (byte 5 14) :type 'reg)
719   (i     :field (byte 1 13) :value 1)
720   (rcond :field (byte 3 10) :type 'register-condition)
721   (immed :field (byte 10 0) :sign-extend t))
722
723 (defconstant-eqx trap-printer
724   `(:name rd :tab cc ", " immed)
725   #'equalp)
726
727 (sb!disassem:define-instruction-format
728     (format-4-trap 32 :default-printer trap-printer)
729   (op    :field (byte 2 30))
730   (rd    :field (byte 5 25) :type 'reg)
731   (op3   :field (byte 6 19))
732   (rs1   :field (byte 5 14) :type 'reg)
733   (i     :field (byte 1 13) :value 1)
734   (cc    :field (byte 2 11) :type 'integer-condition-register)
735   (immed :field (byte 11 0) :sign-extend t))    ; usually sign extended
736
737
738 (defconstant-eqx cond-fp-move-integer-printer
739   `(:name opf1 :tab rs1 ", " rs2 ", " rd)
740   #'equalp)
741
742 \f
743 ;;;; Primitive emitters.
744
745 (define-bitfield-emitter emit-word 32
746   (byte 32 0))
747
748 (define-bitfield-emitter emit-short 16
749   (byte 16 0))
750
751 (define-bitfield-emitter emit-format-1 32
752   (byte 2 30) (byte 30 0))
753
754 (define-bitfield-emitter emit-format-2-immed 32
755   (byte 2 30) (byte 5 25) (byte 3 22) (byte 22 0))
756
757 (define-bitfield-emitter emit-format-2-branch 32
758   (byte 2 30) (byte 1 29) (byte 4 25) (byte 3 22) (byte 22 0))
759
760 ;; Integer and FP branches with prediction for V9
761 (define-bitfield-emitter emit-format-2-branch-pred 32
762   (byte 2 30) (byte 1 29) (byte 4 25) (byte 3 22) (byte 2 20) (byte 1 19) (byte 19 0))
763 (define-bitfield-emitter emit-format-2-fp-branch-pred 32
764   (byte 2 30) (byte 1 29) (byte 4 25) (byte 3 22) (byte 2 20) (byte 1 19) (byte 19 0))
765   
766 (define-bitfield-emitter emit-format-2-unimp 32
767   (byte 2 30) (byte 5 25) (byte 3 22) (byte 22 0))
768
769 (define-bitfield-emitter emit-format-3-reg 32
770   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 1 13) (byte 8 5)
771   (byte 5 0))
772
773 (define-bitfield-emitter emit-format-3-immed 32
774   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 1 13) (byte 13 0))
775
776 (define-bitfield-emitter emit-format-3-fpop 32
777   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 9 5) (byte 5 0))
778
779 (define-bitfield-emitter emit-format-3-fpop2 32
780   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14)
781   (byte 1 13) (byte 3 10) (byte 1 9) (byte 4 5)
782   (byte 5 0))
783
784 ;;; Shift instructions
785
786 (define-bitfield-emitter emit-format-3-shift-reg 32
787   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 1 13) (byte 1 12) (byte 7 5)
788   (byte 5 0))
789
790 (define-bitfield-emitter emit-format-3-shift-immed 32
791   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 1 13) (byte 1 12) (byte 12 0))
792
793 ;;; Conditional moves
794
795 ;; Conditional move in condition code
796 (define-bitfield-emitter emit-format-4-cond-move 32
797   (byte 2 30) (byte 5 25) (byte 6 19) (byte 1 18) (byte 4 14) (byte 1 13) (byte 2 11)
798   (byte 11 0))
799
800 ;; Conditional move on integer condition
801 (define-bitfield-emitter emit-format-4-cond-move-integer 32
802   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 1 13) (byte 3 10) (byte 5 5)
803   (byte 5 0))
804
805 (define-bitfield-emitter emit-format-4-cond-move-integer-immed 32
806   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 1 13) (byte 3 10)
807   (byte 10 0))
808
809 (define-bitfield-emitter emit-format-4-trap 32
810   (byte 2 30) (byte 5 25) (byte 6 19) (byte 5 14) (byte 1 13) (byte 2 11)
811   (byte 11 0))
812   
813 \f
814 ;;;; Most of the format-3-instructions.
815
816 (defun emit-format-3-inst (segment op op3 dst src1 src2
817                                    &key load-store fixup dest-kind)
818   (unless src2
819     (cond ((and (typep src1 'tn) load-store)
820            (setf src2 0))
821           (t
822            (setf src2 src1)
823            (setf src1 dst))))
824   (etypecase src2
825     (tn
826      (emit-format-3-reg segment op
827                         (if dest-kind
828                             (fp-reg-tn-encoding dst)
829                             (reg-tn-encoding dst))
830                         op3 (reg-tn-encoding src1) 0 0 (reg-tn-encoding src2)))
831     (integer
832      (emit-format-3-immed segment op
833                           (if dest-kind
834                               (fp-reg-tn-encoding dst)
835                               (reg-tn-encoding dst))
836                           op3 (reg-tn-encoding src1) 1 src2))
837     (fixup
838      (unless (or load-store fixup)
839        (error "Fixups aren't allowed."))
840      (note-fixup segment :add src2)
841      (emit-format-3-immed segment op
842                           (if dest-kind
843                               (fp-reg-tn-encoding dst)
844                               (reg-tn-encoding dst))
845                           op3 (reg-tn-encoding src1) 1 0))))
846
847 ;;; Shift instructions because an extra bit is used in Sparc V9's to
848 ;;; indicate whether the shift is a 32-bit or 64-bit shift.
849 ;;;
850 (defun emit-format-3-shift-inst (segment op op3 dst src1 src2 &key extended)
851   (unless src2
852     (setf src2 src1)
853     (setf src1 dst))
854   (etypecase src2
855     (tn
856      (emit-format-3-shift-reg segment op (reg-tn-encoding dst)
857                               op3 (reg-tn-encoding src1) 0 (if extended 1 0)
858                               0 (reg-tn-encoding src2)))
859     (integer
860      (emit-format-3-shift-immed segment op (reg-tn-encoding dst)
861                                 op3 (reg-tn-encoding src1) 1
862                                 (if extended 1 0) src2))))
863
864
865 (eval-when (:compile-toplevel :execute)
866
867 ;;; have to do this because def!constant is evalutated in the null lex env.
868 (defmacro with-ref-format (printer)
869   `(let* ((addend
870            '(:choose (:plus-integer immed) ("+" rs2)))
871           (ref-format
872            `("[" rs1 (:unless (:constant 0) ,addend) "]"
873              (:choose (:unless (:constant 0) asi) nil))))
874      ,printer))
875
876 (defconstant-eqx load-printer
877   (with-ref-format `(:NAME :TAB ,ref-format ", " rd))
878   #'equalp)
879
880 (defconstant-eqx store-printer
881   (with-ref-format `(:NAME :TAB rd ", " ,ref-format))
882   #'equalp)
883
884 ) ; EVAL-WHEN
885
886 (macrolet ((define-f3-inst (name op op3 &key fixup load-store (dest-kind 'reg)
887                                  (printer :default) reads writes flushable print-name)
888   (let ((printer
889          (if (eq printer :default)
890              (case load-store
891                ((nil) :default)
892                ((:load t) 'load-printer)
893                (:store 'store-printer))
894              printer)))
895     (when (and (atom reads) (not (null reads)))
896       (setf reads (list reads)))
897     (when (and (atom writes) (not (null writes)))
898        (setf writes (list writes)))
899     `(define-instruction ,name (segment dst src1 &optional src2)
900        (:declare (type tn dst)
901                  ,(if (or fixup load-store)
902                       '(type (or tn (signed-byte 13) null fixup) src1 src2)
903                       '(type (or tn (signed-byte 13) null) src1 src2)))
904        (:printer format-3-reg
905                  ((op ,op) (op3 ,op3) (rd nil :type ',dest-kind))
906                  ,printer
907                  ,@(when print-name `(:print-name ,print-name)))
908        (:printer format-3-immed
909                  ((op ,op) (op3 ,op3) (rd nil :type ',dest-kind))
910                  ,printer
911                  ,@(when print-name `(:print-name ,print-name)))
912        ,@(when flushable
913            '((:attributes flushable)))
914        (:dependencies
915         (reads src1)
916         ,@(let ((reads-list nil))
917             (dolist (read reads)
918               (push (list 'reads read) reads-list))
919             reads-list)
920         ,@(cond ((eq load-store :store)
921                  '((reads dst)
922                    (if src2 (reads src2))))
923                  ((eq load-store t)
924                   '((reads :memory)
925                     (reads dst)
926                     (if src2 (reads src2))))
927                 ((eq load-store :load)
928                  '((reads :memory)
929                    (if src2 (reads src2) (reads dst))))
930                 (t
931                  '((if src2 (reads src2) (reads dst)))))
932         ,@(let ((writes-list nil))
933             (dolist (write writes)
934               (push (list 'writes write) writes-list))
935             writes-list)
936         ,@(cond ((eq load-store :store)
937                  '((writes :memory :partially t)))
938                 ((eq load-store t)
939                  '((writes :memory :partially t)
940                    (writes dst)))
941                 ((eq load-store :load)
942                  '((writes dst)))
943                 (t
944                  '((writes dst)))))
945        (:delay 0)
946        (:emitter (emit-format-3-inst segment ,op ,op3 dst src1 src2
947                                      :load-store ,load-store
948                                      :fixup ,fixup
949                                      :dest-kind (not (eq ',dest-kind 'reg)))))))
950
951            (define-f3-shift-inst (name op op3 &key extended)
952                `(define-instruction ,name (segment dst src1 &optional src2)
953                  (:declare (type tn dst)
954                   (type (or tn (unsigned-byte 6) null) src1 src2))
955                  (:printer format-3-shift-reg
956                   ((op ,op) (op3 ,op3) (x ,(if extended 1 0)) (i 0)))
957                  (:printer format-3-shift-immed
958                   ((op ,op) (op3 ,op3) (x ,(if extended 1 0)) (i 1)))
959                  (:dependencies
960                   (reads src1)
961                   (if src2 (reads src2) (reads dst))
962                   (writes dst))
963                  (:delay 0)
964                  (:emitter (emit-format-3-shift-inst segment ,op ,op3 dst src1 src2
965                             :extended ,extended)))))
966
967   (define-f3-inst ldsb #b11 #b001001 :load-store :load)
968   (define-f3-inst ldsh #b11 #b001010 :load-store :load)
969   (define-f3-inst ldub #b11 #b000001 :load-store :load)
970   (define-f3-inst lduh #b11 #b000010 :load-store :load)
971
972   ;; This instruction is called lduw for V9 , but looks exactly like ld
973   ;; on previous architectures.
974   (define-f3-inst ld #b11 #b000000 :load-store :load
975                   #!+sparc-v9 :print-name #!+sparc-v9 'lduw)
976
977   (define-f3-inst ldsw #b11 #b001000 :load-store :load) ; v9
978   
979   ;; ldd is deprecated on the Sparc V9.
980   (define-f3-inst ldd #b11 #b000011 :load-store :load)
981   
982   (define-f3-inst ldx #b11 #b001011 :load-store :load) ; v9
983   
984   (define-f3-inst ldf #b11 #b100000 :dest-kind fp-reg :load-store :load)
985   (define-f3-inst lddf #b11 #b100011 :dest-kind fp-reg :load-store :load)
986   (define-f3-inst ldqf #b11 #b100010 :dest-kind fp-reg :load-store :load)       ; v9
987   (define-f3-inst stb #b11 #b000101 :load-store :store)
988   (define-f3-inst sth #b11 #b000110 :load-store :store)
989   (define-f3-inst st #b11 #b000100 :load-store :store)
990   
991   ;; std is deprecated on the Sparc V9.
992   (define-f3-inst std #b11 #b000111 :load-store :store)
993   
994   (define-f3-inst stx #b11 #b001110 :load-store :store) ; v9
995   
996   (define-f3-inst stf #b11 #b100100 :dest-kind fp-reg :load-store :store)
997   (define-f3-inst stdf #b11 #b100111 :dest-kind fp-reg :load-store :store)
998   (define-f3-inst stqf #b11 #b100110 :dest-kind fp-reg :load-store :store) ; v9
999   (define-f3-inst ldstub #b11 #b001101 :load-store t)
1000   
1001   ;; swap is deprecated on the Sparc V9
1002   (define-f3-inst swap #b11 #b001111 :load-store t)
1003   
1004   (define-f3-inst add #b10 #b000000 :fixup t)
1005   (define-f3-inst addcc #b10 #b010000 :writes :psr)
1006   (define-f3-inst addx #b10 #b001000 :reads :psr)
1007   (define-f3-inst addxcc #b10 #b011000 :reads :psr :writes :psr)
1008   (define-f3-inst taddcc #b10 #b100000 :writes :psr)
1009   
1010   ;; taddcctv is deprecated on the Sparc V9.  Use taddcc and bpvs or
1011   ;; taddcc and trap to get a similar effect.  (Requires changing the C
1012   ;; code though!)
1013   ;;(define-f3-inst taddcctv #b10 #b100010 :writes :psr)
1014
1015   (define-f3-inst sub #b10 #b000100)
1016   (define-f3-inst subcc #b10 #b010100 :writes :psr)
1017   (define-f3-inst subx #b10 #b001100 :reads :psr)
1018   (define-f3-inst subxcc #b10 #b011100 :reads :psr :writes :psr)
1019   (define-f3-inst tsubcc #b10 #b100001 :writes :psr)
1020
1021   ;; tsubcctv is deprecated on the Sparc V9.  Use tsubcc and bpvs or
1022   ;; tsubcc and trap to get a similar effect.  (Requires changing the C
1023   ;; code though!)
1024   ;;(define-f3-inst tsubcctv #b10 #b100011 :writes :psr)
1025
1026   (define-f3-inst mulscc #b10 #b100100 :reads :y :writes (:psr :y))
1027   (define-f3-inst and #b10 #b000001)
1028   (define-f3-inst andcc #b10 #b010001 :writes :psr)
1029   (define-f3-inst andn #b10 #b000101)
1030   (define-f3-inst andncc #b10 #b010101 :writes :psr)
1031   (define-f3-inst or #b10 #b000010)
1032   (define-f3-inst orcc #b10 #b010010 :writes :psr)
1033   (define-f3-inst orn #b10 #b000110)
1034   (define-f3-inst orncc #b10 #b010110 :writes :psr)
1035   (define-f3-inst xor #b10 #b000011)
1036   (define-f3-inst xorcc #b10 #b010011 :writes :psr)
1037   (define-f3-inst xnor #b10 #b000111)
1038   (define-f3-inst xnorcc #b10 #b010111 :writes :psr)
1039   
1040   (define-f3-shift-inst sll #b10 #b100101)
1041   (define-f3-shift-inst srl #b10 #b100110)
1042   (define-f3-shift-inst sra #b10 #b100111)
1043   (define-f3-shift-inst sllx #b10 #b100101 :extended t) ; v9
1044   (define-f3-shift-inst srlx #b10 #b100110 :extended t) ; v9
1045   (define-f3-shift-inst srax #b10 #b100111 :extended t) ; v9
1046
1047   (define-f3-inst save #b10 #b111100 :reads :psr :writes :psr)
1048   (define-f3-inst restore #b10 #b111101 :reads :psr :writes :psr)
1049   
1050   ;; smul, smulcc, umul, umulcc, sdiv, sdivcc, udiv, and udivcc are
1051   ;; deprecated on the Sparc V9.  Use mulx, sdivx, and udivx instead.
1052   (define-f3-inst smul #b10 #b001011 :writes :y)                        ; v8
1053   (define-f3-inst smulcc #b10 #b011011 :writes (:psr :y))               ; v8
1054   (define-f3-inst umul #b10 #b001010 :writes :y)                        ; v8
1055   (define-f3-inst umulcc #b10 #b011010 :writes (:psr :y))               ; v8
1056   (define-f3-inst sdiv #b10 #b001111 :reads :y)                 ; v8
1057   (define-f3-inst sdivcc #b10 #b011111 :reads :y :writes :psr)  ; v8
1058   (define-f3-inst udiv #b10 #b001110 :reads :y)                 ; v8
1059   (define-f3-inst udivcc #b10 #b011110 :reads :y :writes :psr)  ; v8
1060   
1061   (define-f3-inst mulx #b10 #b001001)   ; v9 for both signed and unsigned
1062   (define-f3-inst sdivx #b10 #b101101)  ; v9
1063   (define-f3-inst udivx #b10 #b001101)  ; v9
1064
1065   (define-f3-inst popc #b10 #b101110)   ; v9: count one bits
1066
1067 ) ; MACROLET
1068
1069 \f
1070 ;;;; Random instructions.
1071
1072 ;; ldfsr is deprecated on the Sparc V9.  Use ldxfsr instead
1073 (define-instruction ldfsr (segment src1 src2)
1074   (:declare (type tn src1) (type (signed-byte 13) src2))
1075   (:printer format-3-immed ((op #b11) (op3 #b100001) (rd 0)))
1076   :pinned
1077   (:delay 0)
1078   (:emitter (emit-format-3-immed segment #b11 0 #b100001
1079                                  (reg-tn-encoding src1) 1 src2)))
1080
1081 #!+sparc-64
1082 (define-instruction ldxfsr (segment src1 src2)
1083   (:declare (type tn src1) (type (signed-byte 13) src2))
1084   (:printer format-3-immed ((op #b11) (op3 #b100001) (rd 1))
1085             '(:name :tab "[" rs1 (:unless (:constant 0) "+" immed) "], %FSR")
1086             :print-name 'ldx)
1087   :pinned
1088   (:delay 0)
1089   (:emitter (emit-format-3-immed segment #b11 1 #b100001
1090                                  (reg-tn-encoding src1) 1 src2)))
1091   
1092 ;; stfsr is deprecated on the Sparc V9.  Use stxfsr instead.
1093 (define-instruction stfsr (segment src1 src2)
1094   (:declare (type tn src1) (type (signed-byte 13) src2))
1095   (:printer format-3-immed ((op #b11) (op3 #b100101) (rd 0)))
1096   :pinned
1097   (:delay 0)
1098   (:emitter (emit-format-3-immed segment #b11 0 #b100101 
1099                                  (reg-tn-encoding src1) 1 src2)))
1100
1101 #!+sparc-64
1102 (define-instruction stxfsr (segment src1 src2)
1103   (:declare (type tn src1) (type (signed-byte 13) src2))
1104   (:printer format-3-immed ((op #b11) (op3 #b100101) (rd 1))
1105             '(:name :tab "%FSR, [" rs1 "+" (:unless (:constant 0) "+" immed) "]")
1106             :print-name 'stx)
1107   :pinned
1108   (:delay 0)
1109   (:emitter (emit-format-3-immed segment #b11 1 #b100101 
1110                                  (reg-tn-encoding src1) 1 src2)))
1111
1112 (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)
1113   (defun sethi-arg-printer (value stream dstate)
1114     (format stream "%hi(#x~8,'0x)" (ash value 10))
1115     ;; Save the immediate value and the destination register from this
1116     ;; sethi instruction.  This is used later to print some possible
1117     ;; notes about the value loaded by sethi.
1118     (let* ((word (sb!disassem::sap-ref-int (sb!disassem::dstate-segment-sap dstate)
1119                                            (sb!disassem::dstate-cur-offs dstate)
1120                                            n-word-bytes
1121                                            (sb!disassem::dstate-byte-order dstate)))
1122            (imm22 (ldb (byte 22 0) word))
1123            (rd (ldb (byte 5 25) word)))
1124       (push (cons rd imm22) *note-sethi-inst*)))
1125 ) ; EVAL-WHEN
1126
1127
1128 (define-instruction sethi (segment dst src1)
1129   (:declare (type tn dst)
1130             (type (or (signed-byte 22) (unsigned-byte 22) fixup) src1))
1131   (:printer format-2-immed
1132             ((op2 #b100) (immed nil :printer #'sethi-arg-printer)))
1133   (:dependencies (writes dst))
1134   (:delay 0)
1135   (:emitter
1136    (etypecase src1
1137      (integer
1138       (emit-format-2-immed segment #b00 (reg-tn-encoding dst) #b100
1139                                  src1))
1140      (fixup
1141       (note-fixup segment :sethi src1)
1142       (emit-format-2-immed segment #b00 (reg-tn-encoding dst) #b100 0)))))
1143                            
1144 ;; rdy is deprecated on the Sparc V9.  It's not needed with 64-bit
1145 ;; registers.
1146 (define-instruction rdy (segment dst)
1147   (:declare (type tn dst))
1148   (:printer format-3-reg ((op #b10) (op3 #b101000) (rs1 0) (immed 0))
1149             '('RD :tab '%Y ", " rd))
1150   (:dependencies (reads :y) (writes dst))
1151   (:delay 0)
1152   (:emitter (emit-format-3-reg segment #b10 (reg-tn-encoding dst) #b101000
1153                                0 0 0 0)))
1154
1155 (defconstant-eqx wry-printer
1156   '('WR :tab rs1 (:unless (:constant 0) ", " (:choose immed rs2)) ", " '%Y)
1157   #'equalp)
1158
1159 ;; wry is deprecated on the Sparc V9.  It's not needed with 64-bit
1160 ;; registers.
1161 (define-instruction wry (segment src1 &optional src2)
1162   (:declare (type tn src1) (type (or (signed-byte 13) tn null) src2))
1163   (:printer format-3-reg ((op #b10) (op3 #b110000) (rd 0)) wry-printer)
1164   (:printer format-3-immed ((op #b10) (op3 #b110000) (rd 0)) wry-printer)
1165   (:dependencies (reads src1) (if src2 (reads src2)) (writes :y))
1166   (:delay 3)
1167   (:emitter
1168    (etypecase src2
1169      (null 
1170       (emit-format-3-reg segment #b10 0 #b110000 (reg-tn-encoding src1) 0 0 0))
1171      (tn
1172       (emit-format-3-reg segment #b10 0 #b110000 (reg-tn-encoding src1) 0 0
1173                          (reg-tn-encoding src2)))
1174      (integer
1175       (emit-format-3-immed segment #b10 0 #b110000 (reg-tn-encoding src1) 1
1176                            src2)))))
1177
1178 (defun snarf-error-junk (sap offset &optional length-only)
1179   (let* ((length (sb!sys:sap-ref-8 sap offset))
1180          (vector (make-array length :element-type '(unsigned-byte 8))))
1181     (declare (type sb!sys:system-area-pointer sap)
1182              (type (unsigned-byte 8) length)
1183              (type (simple-array (unsigned-byte 8) (*)) vector))
1184     (cond (length-only
1185            (values 0 (1+ length) nil nil))
1186           (t
1187            (sb!kernel:copy-from-system-area sap (* n-byte-bits (1+ offset))
1188                                          vector (* n-word-bits
1189                                                    vector-data-offset)
1190                                          (* length n-byte-bits))
1191            (collect ((sc-offsets)
1192                      (lengths))
1193              (lengths 1)                ; the length byte
1194              (let* ((index 0)
1195                     (error-number (sb!c:read-var-integer vector index)))
1196                (lengths index)
1197                (loop
1198                  (when (>= index length)
1199                    (return))
1200                  (let ((old-index index))
1201                    (sc-offsets (sb!c:read-var-integer vector index))
1202                    (lengths (- index old-index))))
1203                (values error-number
1204                        (1+ length)
1205                        (sc-offsets)
1206                        (lengths))))))))
1207
1208 (defun unimp-control (chunk inst stream dstate)
1209   (declare (ignore inst))
1210   (flet ((nt (x) (if stream (sb!disassem:note x dstate))))
1211     (case (format-2-unimp-data chunk dstate)
1212       (#.error-trap
1213        (nt "Error trap")
1214        (sb!disassem:handle-break-args #'snarf-error-junk stream dstate))
1215       (#.cerror-trap
1216        (nt "Cerror trap")
1217        (sb!disassem:handle-break-args #'snarf-error-junk stream dstate))
1218       (#.object-not-list-trap
1219        (nt "Object not list trap"))
1220       (#.breakpoint-trap
1221        (nt "Breakpoint trap"))
1222       (#.pending-interrupt-trap
1223        (nt "Pending interrupt trap"))
1224       (#.halt-trap
1225        (nt "Halt trap"))
1226       (#.fun-end-breakpoint-trap
1227        (nt "Function end breakpoint trap"))
1228       (#.object-not-instance-trap
1229        (nt "Object not instance trap"))
1230     )))
1231
1232 (define-instruction unimp (segment data)
1233   (:declare (type (unsigned-byte 22) data))
1234   (:printer format-2-unimp () :default :control #'unimp-control
1235             :print-name #!-sparc-v9 'unimp #!+sparc-v9 'illtrap)
1236   (:delay 0)
1237   (:emitter (emit-format-2-unimp segment 0 0 0 data)))
1238
1239
1240 \f
1241 ;;;; Branch instructions.
1242
1243 ;; The branch instruction is deprecated on the Sparc V9.  Use the
1244 ;; branch with prediction instructions instead.
1245 (defun emit-relative-branch (segment a op2 cond-or-target target &optional fp)
1246   (emit-back-patch segment 4
1247     (lambda (segment posn)
1248         (unless target
1249           (setf target cond-or-target)
1250           (setf cond-or-target :t))
1251         (emit-format-2-branch
1252           segment #b00 a
1253           (if fp
1254               (fp-branch-condition cond-or-target)
1255               (branch-condition cond-or-target))
1256           op2
1257           (let ((offset (ash (- (label-position target) posn) -2)))
1258             (when (and (= a 1) (> 0 offset))
1259               (error "Offset of BA must be positive"))
1260             offset)))))
1261
1262 (defun emit-relative-branch-integer (segment a op2 cond-or-target target &optional (cc :icc) (pred :pt))
1263   (declare (type integer-condition-register cc))
1264   (assert (member :sparc-v9 *backend-subfeatures*))
1265   (emit-back-patch segment 4
1266     (lambda (segment posn)
1267         (unless target
1268           (setf target cond-or-target)
1269           (setf cond-or-target :t))
1270         (emit-format-2-branch-pred
1271           segment #b00 a
1272           (branch-condition cond-or-target)
1273           op2
1274           (integer-condition cc)
1275           (branch-prediction pred)
1276           (let ((offset (ash (- (label-position target) posn) -2)))
1277             (when (and (= a 1) (> 0 offset))
1278               (error "Offset of BA must be positive"))
1279             offset)))))
1280
1281 (defun emit-relative-branch-fp (segment a op2 cond-or-target target &optional (cc :fcc0) (pred :pt))
1282   (assert (member :sparc-v9 *backend-subfeatures*))
1283   (emit-back-patch segment 4
1284     (lambda (segment posn)
1285         (unless target
1286           (setf target cond-or-target)
1287           (setf cond-or-target :t))
1288         (emit-format-2-branch-pred
1289           segment #b00 a
1290           (fp-branch-condition cond-or-target)
1291           op2
1292           (fp-condition cc)
1293           (branch-prediction pred)
1294           (let ((offset (ash (- (label-position target) posn) -2)))
1295             (when (and (= a 1) (> 0 offset))
1296               (error "Offset of BA must be positive"))
1297             offset)))))
1298
1299 ;; So that I don't have to go change the syntax of every single use of
1300 ;; branches, I'm keeping the Lisp instruction names the same.  They
1301 ;; just get translated to the branch with prediction
1302 ;; instructions. However, the disassembler uses the correct V9
1303 ;; mnemonic.
1304 (define-instruction b (segment cond-or-target &rest args)
1305   (:declare (type (or label branch-condition) cond-or-target))
1306   (:printer format-2-branch ((op #b00) (op2 #b010)))
1307   (:attributes branch)
1308   (:dependencies (reads :psr))
1309   (:delay 1)
1310   (:emitter
1311    (cond
1312      ((member :sparc-v9 *backend-subfeatures*)
1313       (destructuring-bind (&optional target pred cc) args
1314         (declare (type (or label null) target))
1315         (emit-relative-branch-integer segment 0 #b001 cond-or-target target (or cc :icc) (or pred :pt))))
1316      (t
1317       (destructuring-bind (&optional target) args
1318         (declare (type (or label null) target))
1319         (emit-relative-branch segment 0 #b010 cond-or-target target))))))
1320
1321 (define-instruction bp (segment cond-or-target &optional target pred cc)
1322   (:declare (type (or label branch-condition) cond-or-target)
1323             (type (or label null) target))
1324   (:printer format-2-branch-pred ((op #b00) (op2 #b001))
1325             branch-pred-printer
1326             :print-name 'bp)
1327   (:attributes branch)
1328   (:dependencies (reads :psr))
1329   (:delay 1)
1330   (:emitter
1331    (emit-relative-branch-integer segment 0 #b001 cond-or-target target (or cc :icc) (or pred :pt))))
1332
1333 (define-instruction ba (segment cond-or-target &rest args)
1334   (:declare (type (or label branch-condition) cond-or-target))
1335   (:printer format-2-branch ((op #b00) (op2 #b010) (a 1))
1336             nil
1337             :print-name 'b)
1338   (:attributes branch)
1339   (:dependencies (reads :psr))
1340   (:delay 0)
1341   (:emitter
1342    (cond
1343      ((member :sparc-v9 *backend-subfeatures*)
1344       (destructuring-bind (&optional target pred cc) args
1345         (declare (type (or label null) target))
1346         (emit-relative-branch-integer segment 1 #b001 cond-or-target target (or cc :icc) (or pred :pt))))
1347      (t
1348       (destructuring-bind (&optional target) args
1349         (declare (type (or label null) target))
1350         (emit-relative-branch segment 1 #b010 cond-or-target target))))))
1351
1352 (define-instruction bpa (segment cond-or-target &optional target pred cc)
1353   (:declare (type (or label branch-condition) cond-or-target)
1354             (type (or label null) target))
1355   (:printer format-2-branch ((op #b00) (op2 #b001) (a 1))
1356             nil
1357             :print-name 'bp)
1358   (:attributes branch)
1359   (:dependencies (reads :psr))
1360   (:delay 0)
1361   (:emitter
1362    (emit-relative-branch-integer segment 1 #b001 cond-or-target target (or cc :icc) (or pred :pt))))
1363
1364 ;; This doesn't cover all of the possible formats for the trap
1365 ;; instruction.  We really only want a trap with a immediate trap
1366 ;; value and with RS1 = register 0.  Also, the Sparc Compliance
1367 ;; Definition 2.4.1 says only trap numbers 16-31 are allowed for user
1368 ;; code.  All other trap numbers have other uses.  The restriction on
1369 ;; target will prevent us from using bad trap numbers by mistake.
1370
1371 (define-instruction t (segment condition target &optional cc)
1372   (:declare (type branch-condition condition)
1373             ;; KLUDGE: see comments in vm.lisp regarding
1374             ;; pseudo-atomic-trap.
1375             #!-linux
1376             (type (integer 16 31) target))
1377   (:printer format-3-immed ((op #b10)
1378                             (rd nil :type 'branch-condition)
1379                             (op3 #b111010)
1380                             (rs1 0))
1381             '(:name rd :tab immed))
1382   (:attributes branch)
1383   (:dependencies (reads :psr))
1384   (:delay 0)
1385   (:emitter 
1386    (cond
1387      ((member :sparc-v9 *backend-subfeatures*)
1388       (unless cc
1389         (setf cc :icc))
1390       (emit-format-4-trap segment
1391                           #b10
1392                           (branch-condition condition)
1393                           #b111010 0 1
1394                           (integer-condition cc)
1395                           target))
1396      (t
1397       (assert (null cc))
1398       (emit-format-3-immed segment #b10 (branch-condition condition)
1399                            #b111010 0 1 target)))))
1400
1401 ;;; KLUDGE: we leave this commented out, as these two (T and TCC)
1402 ;;; operations are actually indistinguishable from their bitfields,
1403 ;;; breaking the disassembler if these are left in. The printer isn't
1404 ;;; terribly smart, but the emitted code is right. - CSR, 2002-08-04
1405 #+nil
1406 (define-instruction tcc (segment condition target &optional (cc #!-sparc-64 :icc #!+sparc-64 :xcc))
1407   (:declare (type branch-condition condition)
1408             ;; KLUDGE: see above.
1409             #!-linux
1410             (type (integer 16 31) target)
1411             (type integer-condition-register cc))
1412   (:printer format-4-trap ((op #b10)
1413                             (rd nil :type 'branch-condition)
1414                             (op3 #b111010)
1415                             (rs1 0))
1416             trap-printer)
1417   (:attributes branch)
1418   (:dependencies (reads :psr))
1419   (:delay 0)
1420   (:emitter (emit-format-4-trap segment
1421                                 #b10
1422                                 (branch-condition condition)
1423                                 #b111010 0 1
1424                                 (integer-condition cc)
1425                                 target)))
1426
1427 ;; Same as for the branch instructions.  On the Sparc V9, we will use
1428 ;; the FP branch with prediction instructions instead.
1429
1430 (define-instruction fb (segment condition target &rest args)
1431   (:declare (type fp-branch-condition condition) (type label target))
1432   (:printer format-2-branch ((op #B00)
1433                              (cond nil :type 'branch-fp-condition)
1434                              (op2 #b110)))
1435   (:attributes branch)
1436   (:dependencies (reads :fsr))
1437   (:delay 1)
1438   (:emitter
1439    (cond
1440      ((member :sparc-v9 *backend-subfeatures*)
1441       (destructuring-bind (&optional fcc pred) args
1442         (emit-relative-branch-fp segment 0 #b101 condition target (or fcc :fcc0) (or pred :pt))))
1443      (t 
1444       (assert (null args))
1445       (emit-relative-branch segment 0 #b110 condition target t)))))
1446
1447 (define-instruction fbp (segment condition target &optional fcc pred)
1448   (:declare (type fp-branch-condition condition) (type label target))
1449   (:printer format-2-fp-branch-pred ((op #b00) (op2 #b101))
1450             fp-branch-pred-printer
1451             :print-name 'fbp)
1452   (:attributes branch)
1453   (:dependencies (reads :fsr))
1454   (:delay 1)
1455   (:emitter
1456    (emit-relative-branch-fp segment 0 #b101 condition target (or fcc :fcc0) (or pred :pt))))
1457
1458 (defconstant-eqx jal-printer
1459   '(:name :tab
1460           (:choose (rs1 (:unless (:constant 0) (:plus-integer immed)))
1461                    (:cond ((rs2 :constant 0) rs1)
1462                           ((rs1 :constant 0) rs2)
1463                           (t rs1 "+" rs2)))
1464           (:unless (:constant 0) ", " rd))
1465   #'equalp)
1466
1467 (define-instruction jal (segment dst src1 &optional src2)
1468   (:declare (type tn dst)
1469             (type (or tn integer) src1)
1470             (type (or null fixup tn (signed-byte 13)) src2))
1471   (:printer format-3-reg ((op #b10) (op3 #b111000)) jal-printer)
1472   (:printer format-3-immed ((op #b10) (op3 #b111000)) jal-printer)
1473   (:attributes branch)
1474   (:dependencies (reads src1) (if src2 (reads src2) (reads dst)) (writes dst))
1475   (:delay 1)
1476   (:emitter
1477    (unless src2
1478      (setf src2 src1)
1479      (setf src1 0))
1480    (etypecase src2
1481      (tn
1482       (emit-format-3-reg segment #b10 (reg-tn-encoding dst) #b111000
1483                          (if (integerp src1)
1484                              src1
1485                              (reg-tn-encoding src1))
1486                          0 0 (reg-tn-encoding src2)))
1487      (integer
1488       (emit-format-3-immed segment #b10 (reg-tn-encoding dst) #b111000
1489                            (reg-tn-encoding src1) 1 src2))
1490      (fixup
1491       (note-fixup segment :add src2)
1492       (emit-format-3-immed segment #b10 (reg-tn-encoding dst)
1493                            #b111000 (reg-tn-encoding src1) 1 0)))))
1494
1495 (define-instruction j (segment src1 &optional src2)
1496   (:declare (type tn src1) (type (or tn (signed-byte 13) fixup null) src2))
1497   (:printer format-3-reg ((op #b10) (op3 #b111000) (rd 0)) jal-printer)
1498   (:printer format-3-immed ((op #b10) (op3 #b111000) (rd 0)) jal-printer)
1499   (:attributes branch)
1500   (:dependencies (reads src1) (if src2 (reads src2)))
1501   (:delay 1)
1502   (:emitter
1503    (etypecase src2
1504      (null
1505       (emit-format-3-reg segment #b10 0 #b111000 (reg-tn-encoding src1) 0 0 0))
1506      (tn
1507       (emit-format-3-reg segment #b10 0 #b111000 (reg-tn-encoding src1) 0 0
1508                          (reg-tn-encoding src2)))
1509      (integer
1510       (emit-format-3-immed segment #b10 0 #b111000 (reg-tn-encoding src1) 1
1511                            src2))
1512      (fixup
1513       (note-fixup segment :add src2)
1514       (emit-format-3-immed segment #b10 0 #b111000 (reg-tn-encoding src1) 1
1515                            0)))))
1516
1517
1518 \f
1519 ;;;; Unary and binary fp insts.
1520
1521 (macrolet ((define-unary-fp-inst (name opf &key reads extended)
1522   `(define-instruction ,name (segment dst src)
1523      (:declare (type tn dst src))
1524      (:printer format-unary-fpop
1525        ((op #b10) (op3 #b110100) (opf ,opf)
1526         (rs1 0)
1527         (rs2 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
1528         (rd nil :type ',(if extended 'fp-ext-reg 'fp-reg))))
1529      (:dependencies
1530       ,@(when reads
1531           `((reads ,reads)))
1532       (reads dst)
1533       (reads src)
1534       (writes dst))
1535      (:delay 0)
1536      (:emitter (emit-format-3-fpop segment #b10 (fp-reg-tn-encoding dst)
1537                 #b110100 0 ,opf (fp-reg-tn-encoding src)))))
1538
1539            (define-binary-fp-inst (name opf &key (op3 #b110100)
1540                                       reads writes delay extended)
1541   `(define-instruction ,name (segment dst src1 src2)
1542      (:declare (type tn dst src1 src2))
1543      (:printer format-binary-fpop
1544       ((op #b10) (op3 ,op3) (opf ,opf)
1545        (rs1 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
1546        (rs2 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
1547        (rd nil :type ',(if extended 'fp-ext-reg 'fp-reg))
1548        ))
1549      (:dependencies
1550       ,@(when reads
1551           `((reads ,reads)))
1552       (reads src1)
1553       (reads src2)
1554       ,@(when writes
1555           `((writes ,writes)))
1556       (writes dst))
1557      ,@(if delay
1558            `((:delay ,delay))
1559            '((:delay 0)))
1560      (:emitter (emit-format-3-fpop segment #b10 (fp-reg-tn-encoding dst)
1561                 ,op3 (fp-reg-tn-encoding src1) ,opf
1562                 (fp-reg-tn-encoding src2)))))
1563
1564            (define-cmp-fp-inst (name opf &key extended)
1565                (let ((opf0 #b0)
1566                      (opf1 #b010)
1567                      (opf2 #b1))
1568                  `(define-instruction ,name (segment src1 src2 &optional (fcc :fcc0))
1569                    (:declare (type tn src1 src2)
1570                     (type (member :fcc0 :fcc1 :fcc2 :fcc3) fcc))
1571        (:printer format-fpop2
1572                  ((op #b10)
1573                   (op3 #b110101)
1574                   (opf0 ,opf0)
1575                   (opf1 ,opf1)
1576                   (opf2 ,opf2)
1577                   (opf3 ,opf)
1578                   (rs1 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
1579                   (rs2 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
1580                   #!-sparc-v9
1581                   (rd 0)
1582                   #!+sparc-v9
1583                   (rd nil :type 'fp-condition-register))
1584         )
1585      (:dependencies
1586       (reads src1)
1587       (reads src2)
1588       (writes :fsr))
1589      ;; The Sparc V9 doesn't need a delay after a FP compare.
1590      ;;
1591      ;; KLUDGE FIXME YAARGH -- how to express that? I guess for now we
1592      ;; do the worst case, and hope to fix it.
1593      ;; (:delay #-sparc-v9 1 #+sparc-v9 0)
1594      (:delay 1)
1595        (:emitter
1596         (emit-format-3-fpop2 segment #b10
1597                              (or (position fcc '(:fcc0 :fcc1 :fcc2 :fcc3))
1598                                  0)
1599                              #b110101
1600                              (fp-reg-tn-encoding src1)
1601                              ,opf0 ,opf1 ,opf2 ,opf
1602                              (fp-reg-tn-encoding src2)))))))
1603
1604   (define-unary-fp-inst fitos #b011000100 :reads :fsr)
1605   (define-unary-fp-inst fitod #b011001000 :reads :fsr :extended t)
1606   (define-unary-fp-inst fitoq #b011001100 :reads :fsr :extended t)      ; v8
1607   
1608   (define-unary-fp-inst fxtos #b010000100 :reads :fsr)                    ; v9
1609   (define-unary-fp-inst fxtod #b010001000 :reads :fsr :extended t)        ; v9
1610   (define-unary-fp-inst fxtoq #b010001100 :reads :fsr :extended t)      ; v9
1611
1612
1613   ;; I (Raymond Toy) don't think these f{sd}toir instructions exist on
1614   ;; any Ultrasparc, but I only have a V9 manual. The code in
1615   ;; float.lisp seems to indicate that they only existed on non-sun4
1616   ;; machines (sun3 68K machines?).
1617   (define-unary-fp-inst fstoir #b011000001 :reads :fsr)
1618   (define-unary-fp-inst fdtoir #b011000010 :reads :fsr)
1619   
1620   (define-unary-fp-inst fstoi #b011010001)
1621   (define-unary-fp-inst fdtoi #b011010010 :extended t)
1622   (define-unary-fp-inst fqtoi #b011010011 :extended t)  ; v8
1623
1624   (define-unary-fp-inst fstox #b010000001)                ; v9
1625   (define-unary-fp-inst fdtox #b010000010 :extended t)    ; v9
1626   (define-unary-fp-inst fqtox #b010000011 :extended t)  ; v9
1627
1628   (define-unary-fp-inst fstod #b011001001 :reads :fsr)
1629   (define-unary-fp-inst fstoq #b011001101 :reads :fsr)  ; v8
1630   (define-unary-fp-inst fdtos #b011000110 :reads :fsr)
1631   (define-unary-fp-inst fdtoq #b011001110 :reads :fsr)  ; v8
1632   (define-unary-fp-inst fqtos #b011000111 :reads :fsr)  ; v8
1633   (define-unary-fp-inst fqtod #b011001011 :reads :fsr)  ; v8
1634   
1635   (define-unary-fp-inst fmovs #b000000001)
1636   (define-unary-fp-inst fmovd #b000000010 :extended t)  ; v9
1637   (define-unary-fp-inst fmovq #b000000011 :extended t)  ; v9
1638   
1639   (define-unary-fp-inst fnegs #b000000101)
1640   (define-unary-fp-inst fnegd #b000000110 :extended t)  ; v9
1641   (define-unary-fp-inst fnegq #b000000111 :extended t)  ; v9
1642
1643   (define-unary-fp-inst fabss #b000001001)
1644   (define-unary-fp-inst fabsd #b000001010 :extended t)  ; v9
1645   (define-unary-fp-inst fabsq #b000001011 :extended t)  ; v9
1646   
1647   (define-unary-fp-inst fsqrts #b000101001 :reads :fsr)         ; V7
1648   (define-unary-fp-inst fsqrtd #b000101010 :reads :fsr :extended t)     ; V7
1649   (define-unary-fp-inst fsqrtq #b000101011 :reads :fsr :extended t)     ; v8
1650   
1651   (define-binary-fp-inst fadds #b001000001)
1652   (define-binary-fp-inst faddd #b001000010 :extended t)
1653   (define-binary-fp-inst faddq #b001000011 :extended t) ; v8
1654   (define-binary-fp-inst fsubs #b001000101)
1655   (define-binary-fp-inst fsubd #b001000110 :extended t)
1656   (define-binary-fp-inst fsubq #b001000111 :extended t) ; v8
1657   
1658   (define-binary-fp-inst fmuls #b001001001)
1659   (define-binary-fp-inst fmuld #b001001010 :extended t)
1660   (define-binary-fp-inst fmulq #b001001011 :extended t) ; v8
1661   (define-binary-fp-inst fdivs #b001001101)
1662   (define-binary-fp-inst fdivd #b001001110 :extended t)
1663   (define-binary-fp-inst fdivq #b001001111 :extended t) ; v8
1664
1665 ;;; Float comparison instructions.
1666 ;;;
1667   (define-cmp-fp-inst fcmps #b0001)
1668   (define-cmp-fp-inst fcmpd #b0010 :extended t)
1669   (define-cmp-fp-inst fcmpq #b0011 :extended t) ;v8
1670   (define-cmp-fp-inst fcmpes #b0101)
1671   (define-cmp-fp-inst fcmped #b0110 :extended t)
1672   (define-cmp-fp-inst fcmpeq #b0111 :extended t)        ; v8
1673
1674 ) ; MACROLET
1675 \f
1676 ;;;; li, jali, ji, nop, cmp, not, neg, move, and more
1677
1678 (defun %li (reg value)
1679   (etypecase value
1680     ((signed-byte 13)
1681      (inst add reg zero-tn value))
1682     ((or (signed-byte 32) (unsigned-byte 32))
1683      (let ((hi (ldb (byte 22 10) value))
1684            (lo (ldb (byte 10 0) value)))
1685        (inst sethi reg hi)
1686        (unless (zerop lo)
1687          (inst add reg lo))))
1688     (fixup
1689      (inst sethi reg value)
1690      (inst add reg value))))
1691
1692 (define-instruction-macro li (reg value)
1693   `(%li ,reg ,value))
1694
1695 ;;; Jal to a full 32-bit address.  Tmpreg is trashed.
1696 (define-instruction jali (segment link tmpreg value)
1697   (:declare (type tn link tmpreg)
1698             (type (or (signed-byte 13) (signed-byte 32) (unsigned-byte 32)
1699                       fixup) value))
1700   (:attributes variable-length)
1701   (:vop-var vop)
1702   (:attributes branch)
1703   (:dependencies (writes link) (writes tmpreg))
1704   (:delay 1)
1705   (:emitter
1706    (assemble (segment vop)
1707      (etypecase value
1708        ((signed-byte 13)
1709         (inst jal link zero-tn value))
1710        ((or (signed-byte 32) (unsigned-byte 32))
1711         (let ((hi (ldb (byte 22 10) value))
1712               (lo (ldb (byte 10 0) value)))
1713           (inst sethi tmpreg hi)
1714           (inst jal link tmpreg lo)))
1715        (fixup
1716         (inst sethi tmpreg value)
1717         (inst jal link tmpreg value))))))
1718
1719 ;;; Jump to a full 32-bit address.  Tmpreg is trashed.
1720 (define-instruction ji (segment tmpreg value)
1721   (:declare (type tn tmpreg)
1722             (type (or (signed-byte 13) (signed-byte 32) (unsigned-byte 32)
1723                       fixup) value))
1724   (:attributes variable-length)
1725   (:vop-var vop)
1726   (:attributes branch)
1727   (:dependencies (writes tmpreg))
1728   (:delay 1)
1729   (:emitter
1730    (assemble (segment vop)
1731              (inst jali zero-tn tmpreg value))))
1732
1733 (define-instruction nop (segment)
1734   (:printer format-2-immed ((rd 0) (op2 #b100) (immed 0)) '(:name))
1735   (:attributes flushable)
1736   (:delay 0)
1737   (:emitter (emit-format-2-immed segment 0 0 #b100 0)))
1738
1739 (!def-vm-support-routine emit-nop (segment)
1740   (emit-format-2-immed segment 0 0 #b100 0))
1741
1742 (define-instruction cmp (segment src1 &optional src2)
1743   (:declare (type tn src1) (type (or null tn (signed-byte 13)) src2))
1744   (:printer format-3-reg ((op #b10) (op3 #b010100) (rd 0))
1745             '(:name :tab rs1 ", " rs2))
1746   (:printer format-3-immed ((op #b10) (op3 #b010100) (rd 0))
1747             '(:name :tab rs1 ", " immed))
1748   (:dependencies (reads src1) (if src2 (reads src2)) (writes :psr))
1749   (:delay 0)
1750   (:emitter
1751    (etypecase src2
1752      (null
1753       (emit-format-3-reg segment #b10 0 #b010100 (reg-tn-encoding src1) 0 0 0))
1754      (tn
1755       (emit-format-3-reg segment #b10 0 #b010100 (reg-tn-encoding src1) 0 0
1756                          (reg-tn-encoding src2)))
1757      (integer
1758       (emit-format-3-immed segment #b10 0 #b010100 (reg-tn-encoding src1) 1
1759                            src2)))))
1760
1761 (define-instruction not (segment dst &optional src1)
1762   (:declare (type tn dst) (type (or tn null) src1))
1763   (:printer format-3-reg ((op #b10) (op3 #b000111) (rs2 0))
1764             '(:name :tab (:unless (:same-as rd) rs1 ", " ) rd))
1765   (:dependencies (if src1 (reads src1) (reads dst)) (writes dst))
1766   (:delay 0)
1767   (:emitter
1768    (unless src1
1769      (setf src1 dst))
1770    (emit-format-3-reg segment #b10 (reg-tn-encoding dst) #b000111
1771                       (reg-tn-encoding src1) 0 0 0)))
1772
1773 (define-instruction neg (segment dst &optional src1)
1774   (:declare (type tn dst) (type (or tn null) src1))
1775   (:printer format-3-reg ((op #b10) (op3 #b000100) (rs1 0))
1776             '(:name :tab (:unless (:same-as rd) rs2 ", " ) rd))
1777   (:dependencies (if src1 (reads src1) (reads dst)) (writes dst))
1778   (:delay 0)
1779   (:emitter
1780    (unless src1
1781      (setf src1 dst))
1782    (emit-format-3-reg segment #b10 (reg-tn-encoding dst) #b000100
1783                       0 0 0 (reg-tn-encoding src1))))
1784
1785 (define-instruction move (segment dst src1)
1786   (:declare (type tn dst src1))
1787   (:printer format-3-reg ((op #b10) (op3 #b000010) (rs1 0))
1788             '(:name :tab rs2 ", " rd)
1789             :print-name 'mov)
1790   (:attributes flushable)
1791   (:dependencies (reads src1) (writes dst))
1792   (:delay 0)
1793   (:emitter (emit-format-3-reg segment #b10 (reg-tn-encoding dst) #b000010
1794                                0 0 0 (reg-tn-encoding src1))))
1795
1796
1797 \f
1798 ;;;; Instructions for dumping data and header objects.
1799
1800 (define-instruction word (segment word)
1801   (:declare (type (or (unsigned-byte 32) (signed-byte 32)) word))
1802   :pinned
1803   (:delay 0)
1804   (:emitter
1805    (emit-word segment word)))
1806
1807 (define-instruction short (segment short)
1808   (:declare (type (or (unsigned-byte 16) (signed-byte 16)) short))
1809   :pinned
1810   (:delay 0)
1811   (:emitter
1812    (emit-short segment short)))
1813
1814 (define-instruction byte (segment byte)
1815   (:declare (type (or (unsigned-byte 8) (signed-byte 8)) byte))
1816   :pinned
1817   (:delay 0)
1818   (:emitter
1819    (emit-byte segment byte)))
1820
1821 (define-bitfield-emitter emit-header-object 32
1822   (byte 24 8) (byte 8 0))
1823   
1824 (defun emit-header-data (segment type)
1825   (emit-back-patch
1826    segment 4
1827    (lambda (segment posn)
1828        (emit-word segment
1829                   (logior type
1830                           (ash (+ posn (component-header-length))
1831                                (- n-widetag-bits word-shift)))))))
1832
1833 (define-instruction simple-fun-header-word (segment)
1834   :pinned
1835   (:delay 0)
1836   (:emitter
1837    (emit-header-data segment simple-fun-header-widetag)))
1838
1839 (define-instruction lra-header-word (segment)
1840   :pinned
1841   (:delay 0)
1842   (:emitter
1843    (emit-header-data segment return-pc-header-widetag)))
1844
1845 \f
1846 ;;;; Instructions for converting between code objects, functions, and lras.
1847
1848 (defun emit-compute-inst (segment vop dst src label temp calc)
1849   (emit-chooser
1850    ;; We emit either 12 or 4 bytes, so we maintain 8 byte alignments.
1851    segment 12 3
1852    (lambda (segment posn delta-if-after)
1853        (let ((delta (funcall calc label posn delta-if-after)))
1854          (when (<= (- (ash 1 12)) delta (1- (ash 1 12)))
1855            (emit-back-patch segment 4
1856                             (lambda (segment posn)
1857                                 (assemble (segment vop)
1858                                           (inst add dst src
1859                                                 (funcall calc label posn 0)))))
1860            t)))
1861    (lambda (segment posn)
1862        (let ((delta (funcall calc label posn 0)))
1863          (assemble (segment vop)
1864                    (inst sethi temp (ldb (byte 22 10) delta))
1865                    (inst or temp (ldb (byte 10 0) delta))
1866                    (inst add dst src temp))))))
1867
1868 ;; code = fn - fn-ptr-type - header - label-offset + other-pointer-tag
1869 (define-instruction compute-code-from-fn (segment dst src label temp)
1870   (:declare (type tn dst src temp) (type label label))
1871   (:attributes variable-length)
1872   (:dependencies (reads src) (writes dst) (writes temp))
1873   (:delay 0)
1874   (:vop-var vop)
1875   (:emitter
1876    (emit-compute-inst segment vop dst src label temp
1877                       (lambda (label posn delta-if-after)
1878                           (- other-pointer-lowtag
1879                              fun-pointer-lowtag
1880                              (label-position label posn delta-if-after)
1881                              (component-header-length))))))
1882
1883 ;; code = lra - other-pointer-tag - header - label-offset + other-pointer-tag
1884 (define-instruction compute-code-from-lra (segment dst src label temp)
1885   (:declare (type tn dst src temp) (type label label))
1886   (:attributes variable-length)
1887   (:dependencies (reads src) (writes dst) (writes temp))
1888   (:delay 0)
1889   (:vop-var vop)
1890   (:emitter
1891    (emit-compute-inst segment vop dst src label temp
1892                       (lambda (label posn delta-if-after)
1893                           (- (+ (label-position label posn delta-if-after)
1894                                 (component-header-length)))))))
1895
1896 ;; lra = code + other-pointer-tag + header + label-offset - other-pointer-tag
1897 (define-instruction compute-lra-from-code (segment dst src label temp)
1898   (:declare (type tn dst src temp) (type label label))
1899   (:attributes variable-length)
1900   (:dependencies (reads src) (writes dst) (writes temp))
1901   (:delay 0)
1902   (:vop-var vop)
1903   (:emitter
1904    (emit-compute-inst segment vop dst src label temp
1905                       (lambda (label posn delta-if-after)
1906                           (+ (label-position label posn delta-if-after)
1907                              (component-header-length))))))
1908 \f
1909 ;;; Sparc V9 additions
1910
1911
1912
1913 ;; Conditional move integer on condition code
1914 (define-instruction cmove (segment condition dst src &optional (ccreg :icc))
1915   (:declare (type (or branch-condition fp-branch-condition) condition)
1916             (type cond-move-condition-register ccreg)
1917             (type tn dst)
1918             (type (or (signed-byte 13) tn) src))
1919   (:printer format-4-cond-move
1920             ((op #b10)
1921              (op3 #b101100)
1922              (cc2 #b1)
1923              (i 0)
1924              (cc nil :type 'integer-condition-register))
1925              cond-move-printer
1926              :print-name 'mov)
1927   (:printer format-4-cond-move-immed
1928             ((op #b10)
1929              (op3 #b101100)
1930              (cc2 #b1)
1931              (i 1)
1932              (cc nil :type 'integer-condition-register))
1933              cond-move-printer
1934              :print-name 'mov)
1935   (:printer format-4-cond-move
1936             ((op #b10)
1937              (op3 #b101100)
1938              (cc2 #b0)
1939              (cond nil :type 'branch-fp-condition)
1940              (i 0)
1941              (cc nil :type 'fp-condition-register))
1942              cond-move-printer
1943              :print-name 'mov)
1944   (:printer format-4-cond-move-immed
1945             ((op #b10)
1946              (op3 #b101100)
1947              (cc2 #b0)
1948              (cond nil :type 'branch-fp-condition)
1949              (i 1)
1950              (cc nil :type 'fp-condition-register))
1951              cond-move-printer
1952              :print-name 'mov)
1953   (:delay 0)
1954   (:dependencies
1955    (if (member ccreg '(:icc :xcc))
1956        (reads :psr)
1957        (reads :fsr))
1958    (reads src)
1959    (reads dst)
1960    (writes dst))
1961   (:emitter
1962    (let ((op #b10)
1963          (op3 #b101100))
1964      (multiple-value-bind (cc2 cc01)
1965          (cond-move-condition-parts ccreg)
1966        (etypecase src
1967          (tn
1968           (emit-format-4-cond-move segment
1969                                    op
1970                                    (reg-tn-encoding dst)
1971                                    op3
1972                                    cc2
1973                                    (if (member ccreg '(:icc :xcc))
1974                                        (branch-condition condition)
1975                                        (fp-branch-condition condition))
1976                                    0
1977                                    cc01
1978                                    (reg-tn-encoding src)))
1979          (integer
1980           (emit-format-4-cond-move segment
1981                                    op
1982                                    (reg-tn-encoding dst)
1983                                    op3
1984                                    cc2
1985                                    (if (member ccreg '(:icc :xcc))
1986                                        (branch-condition condition)
1987                                        (fp-branch-condition condition))
1988                                    1
1989                                    cc01
1990                                    src)))))))
1991
1992 ;; Conditional move floating-point on condition codes
1993 (macrolet ((define-cond-fp-move (name print-name op op3 opf_low &key extended)
1994   `(define-instruction ,name (segment condition dst src &optional (ccreg :fcc0))
1995      (:declare (type (or branch-condition fp-branch-condition) condition)
1996                (type cond-move-condition-register ccreg)
1997                (type tn dst src))
1998      (:printer format-fpop2
1999                ((op ,op)
2000                 (op3 ,op3)
2001                 (opf0 0)
2002                 (opf1 nil :type 'fp-condition-register-shifted)
2003                 (opf2 0)
2004                 (opf3 ,opf_low)
2005                 (rs1 nil :type 'branch-fp-condition)
2006                 (rs2 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
2007                 (rd nil :type ',(if extended 'fp-ext-reg 'fp-reg)))
2008                 cond-fp-move-printer
2009                 :print-name ',print-name)
2010      (:printer format-fpop2
2011                ((op ,op)
2012                 (op3 ,op3)
2013                 (opf0 1)
2014                 (opf1 nil :type 'integer-condition-register)
2015                 (opf2 0)
2016                 (rs1 nil :type 'branch-condition)
2017                 (opf3 ,opf_low)
2018                 (rs2 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
2019                 (rd nil :type ',(if extended 'fp-ext-reg 'fp-reg)))
2020                cond-fp-move-printer
2021                :print-name ',print-name)
2022      (:delay 0)
2023      (:dependencies
2024       (if (member ccreg '(:icc :xcc))
2025           (reads :psr)
2026           (reads :fsr))
2027       (reads src)
2028       (reads dst)
2029       (writes dst))
2030      (:emitter
2031       (multiple-value-bind (opf_cc2 opf_cc01)
2032           (cond-move-condition-parts ccreg)
2033         (emit-format-3-fpop2 segment
2034                              ,op
2035                              (fp-reg-tn-encoding dst)
2036                              ,op3
2037                              (if (member ccreg '(:icc :xcc))
2038                                  (branch-condition condition)
2039                                  (fp-branch-condition condition))
2040                              opf_cc2
2041                              (ash opf_cc01 1)
2042                              0
2043                              ,opf_low
2044                              (fp-reg-tn-encoding src)))))))
2045   (define-cond-fp-move cfmovs fmovs #b10 #b110101 #b0001)
2046   (define-cond-fp-move cfmovd fmovd #b10 #b110101 #b0010 :extended t)
2047   (define-cond-fp-move cfmovq fmovq #b10 #b110101 #b0011 :extended t))
2048
2049
2050 ;; Move on integer register condition
2051 ;;
2052 ;; movr dst src reg reg-cond
2053 ;;
2054 ;; This means if reg satisfies reg-cond, src is copied to dst.  If the
2055 ;; condition is not satisfied, nothing is done.
2056 ;;
2057 (define-instruction movr (segment dst src2 src1 reg-condition)
2058   (:declare (type cond-move-integer-condition reg-condition)
2059             (type tn dst src1)
2060             (type (or (signed-byte 10) tn) src2))
2061   (:printer format-4-cond-move-integer
2062             ((op #b10)
2063              (op3 #b101111)
2064              (i 0)))
2065   (:printer format-4-cond-move-integer-immed
2066             ((op #b10)
2067              (op3 #b101111)
2068              (i 1)))
2069   (:delay 0)
2070   (:dependencies
2071    (reads :psr)
2072    (reads src2)
2073    (reads src1)
2074    (reads dst)
2075    (writes dst))
2076   (:emitter
2077    (etypecase src2
2078      (tn
2079       (emit-format-4-cond-move-integer
2080        segment #b10 (reg-tn-encoding dst) #b101111 (reg-tn-encoding src1)
2081        0 (register-condition reg-condition)
2082        0 (reg-tn-encoding src2)))
2083      (integer
2084       (emit-format-4-cond-move-integer-immed
2085        segment #b10 (reg-tn-encoding dst) #b101111 (reg-tn-encoding src1)
2086        1 (register-condition reg-condition) src2)))))
2087
2088
2089 ;; Same as MOVR, except we move FP registers depending on the value of
2090 ;; an integer register.
2091 ;;
2092 ;; fmovr dst src reg cond
2093 ;;
2094 ;; This means if REG satifies COND, SRC is COPIED to DST.  Nothing
2095 ;; happens if the condition is not satisfied.
2096 (macrolet ((define-cond-fp-move-integer (name opf_low &key extended)
2097   `(define-instruction ,name (segment dst src2 src1 reg-condition)
2098      (:declare (type cond-move-integer-condition reg-condition)
2099                (type tn dst src1 src2))
2100      (:printer format-fpop2
2101                ((op #b10)
2102                 (rd nil :type ',(if extended 'fp-ext-reg 'fp-reg))
2103                 (op3 #b110101)
2104                 (rs1 nil :type 'reg)
2105                 (opf0 0)
2106                 (opf1 nil :type 'register-condition)
2107                 (opf2 0)
2108                 (opf3 ,opf_low)
2109                 (rs2 nil :type ',(if extended 'fp-ext-reg 'fp-reg))
2110                 )
2111                cond-fp-move-integer-printer)
2112      (:delay 0)
2113      (:dependencies
2114       (reads src2)
2115       (reads src1)
2116       (reads dst)
2117       (writes dst))
2118      (:emitter
2119       (emit-format-3-fpop2
2120        segment
2121        #b10
2122        (fp-reg-tn-encoding dst)
2123        #b110101
2124        (reg-tn-encoding src1)
2125        0
2126        (register-condition reg-condition)
2127        0
2128        ,opf_low
2129        (fp-reg-tn-encoding src2))))))
2130   (define-cond-fp-move-integer fmovrs #b0101)
2131   (define-cond-fp-move-integer fmovrd #b0110 :extended t)
2132   (define-cond-fp-move-integer fmovrq #b0111 :extended t))