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