0.8.18.14:
[sbcl.git] / src / compiler / x86-64 / insts.lisp
1 ;;;; that part of the description of the x86 instruction set (for
2 ;;;; 80386 and above) which can live on the cross-compilation host
3
4 ;;;; This software is part of the SBCL system. See the README file for
5 ;;;; more information.
6 ;;;;
7 ;;;; This software is derived from the CMU CL system, which was
8 ;;;; written at Carnegie Mellon University and released into the
9 ;;;; public domain. The software is in the public domain and is
10 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
11 ;;;; files for more information.
12
13 (in-package "SB!VM")
14 ;;; FIXME: SB!DISASSEM: prefixes are used so widely in this file that
15 ;;; I wonder whether the separation of the disassembler from the
16 ;;; virtual machine is valid or adds value.
17
18 ;;; Note: In CMU CL, this used to be a call to SET-DISASSEM-PARAMS.
19 (setf sb!disassem:*disassem-inst-alignment-bytes* 1)
20
21 ;;; this type is used mostly in disassembly and represents legacy
22 ;;; registers only.  r8-15 are handled separately
23 (deftype reg () '(unsigned-byte 3))
24
25 ;; This includes legacy records and r8-16
26 (deftype full-reg () '(unsigned-byte 4))
27
28 ;;; default word size for the chip: if the operand size !=:dword
29 ;;; we need to output #x66 (or REX) prefix
30 (def!constant +default-operand-size+ :dword)
31 \f
32 (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)
33
34 (defun offset-next (value dstate)
35   (declare (type integer value)
36            (type sb!disassem:disassem-state dstate))
37   (+ (sb!disassem:dstate-next-addr dstate) value))
38
39 (defparameter *default-address-size*
40   ;; Again, this is the chip default, not the SBCL backend preference
41   ;; which must be set with prefixes if it's different.  It's :dword;
42   ;; this is not negotiable
43   :dword)
44
45 (defparameter *byte-reg-names*
46   #(al cl dl bl sil dil r8b r9b r10b r11b r14b r15b))
47 (defparameter *word-reg-names*
48   #(ax cx dx bx sp bp si di))
49 (defparameter *dword-reg-names*
50   #(eax ecx edx ebx esp ebp esi edi))
51 (defparameter *qword-reg-names*
52   #(rax rcx rdx rbx rsp rbp rsi rdi r8 r9 r10 r11 r12 r13 r14 r15))
53
54 (defun print-reg-with-width (value width stream dstate)
55   (declare (ignore dstate)
56            (type full-reg value))
57   (princ (aref (ecase width
58                  (:byte *byte-reg-names*)
59                  (:word *word-reg-names*)
60                  (:dword *dword-reg-names*)
61                  (:qword *qword-reg-names*))
62                value)
63          stream)
64   ;; XXX plus should do some source-var notes
65   )
66
67 (defun print-reg (value stream dstate)
68   (declare (type full-reg value)
69            (type stream stream)
70            (type sb!disassem:disassem-state dstate))
71   (print-reg-with-width value
72                         (or (sb!disassem:dstate-get-prop dstate 'reg-width)
73                             *default-address-size*)
74                         stream
75                         dstate))
76
77 (defun print-word-reg (value stream dstate)
78   (declare (type (or full-reg list) value)
79            (type stream stream)
80            (type sb!disassem:disassem-state dstate))
81   (print-reg-with-width
82    (if (consp value) (car value) value)
83    (or (sb!disassem:dstate-get-prop dstate 'reg-width)
84        +default-operand-size+)
85    stream
86    dstate))
87
88 (defun print-byte-reg (value stream dstate)
89   (declare (type full-reg value)
90            (type stream stream)
91            (type sb!disassem:disassem-state dstate))
92   (print-reg-with-width value :byte stream dstate))
93
94 (defun print-addr-reg (value stream dstate)
95   (declare (type full-reg value)
96            (type stream stream)
97            (type sb!disassem:disassem-state dstate))
98   (print-reg-with-width value 
99                         (or (sb!disassem:dstate-get-prop dstate 'reg-width)
100                             *default-address-size*)
101                         stream dstate))
102
103 (defun print-rex-reg/mem (value stream dstate)
104   (declare (type (or list full-reg) value)
105            (type stream stream)
106            (type sb!disassem:disassem-state dstate))
107   (if (typep value 'full-reg)
108       (print-reg value stream dstate)
109     (print-mem-access value stream nil dstate)))
110
111 (defun print-reg/mem (value stream dstate)
112   (declare (type (or list full-reg) value)
113            (type stream stream)
114            (type sb!disassem:disassem-state dstate))
115   (if (typep value 'full-reg)
116       (print-reg value stream dstate)
117       (print-mem-access value stream nil dstate)))
118
119 ;; Same as print-reg/mem, but prints an explicit size indicator for
120 ;; memory references.
121 (defun print-sized-reg/mem (value stream dstate)
122   (declare (type (or list full-reg) value)
123            (type stream stream)
124            (type sb!disassem:disassem-state dstate))
125   (if (typep value 'full-reg)
126       (print-reg value stream dstate)
127     (print-mem-access value stream t dstate)))
128
129 (defun print-byte-reg/mem (value stream dstate)
130   (declare (type (or list full-reg) value)
131            (type stream stream)
132            (type sb!disassem:disassem-state dstate))
133   (if (typep value 'full-reg)
134       (print-byte-reg value stream dstate)
135       (print-mem-access value stream t dstate)))
136
137 (defun print-word-reg/mem (value stream dstate)
138   (declare (type (or list full-reg) value)
139            (type stream stream)
140            (type sb!disassem:disassem-state dstate))
141   (if (typep value 'full-reg)
142       (print-word-reg value stream dstate)
143       (print-mem-access value stream nil dstate)))
144
145 (defun print-label (value stream dstate)
146   (declare (ignore dstate))
147   (sb!disassem:princ16 value stream))
148
149 (defun prefilter-word-reg (value dstate)
150   (declare (type (or full-reg list) value))
151   (if (atom value)
152       value
153     (let ((reg (first value))
154           (rex.wrxb (second value)))
155       (declare (type (or null (unsigned-byte 4)) rex.wrxb)
156                (type (unsigned-byte 3) reg))
157         (setf (sb!disassem:dstate-get-prop dstate 'reg-width)
158               (if (and rex.wrxb (plusp (logand rex.wrxb #b1000)))
159                   :qword
160                 +default-operand-size+))
161         (if (plusp (logand rex.wrxb #b0100))
162             (+ 8 reg)
163           reg))))
164   
165 ;;; Returns either an integer, meaning a register, or a list of
166 ;;; (BASE-REG OFFSET INDEX-REG INDEX-SCALE), where any component
167 ;;; may be missing or nil to indicate that it's not used or has the
168 ;;; obvious default value (e.g., 1 for the index-scale).
169 (defun prefilter-reg/mem (value dstate)
170   (declare (type list value)
171            (type sb!disassem:disassem-state dstate))
172   (let ((mod (first value))
173         (r/m (second value))
174         (rex.wrxb (third value)))
175     (declare (type (unsigned-byte 2) mod)
176              (type (unsigned-byte 3) r/m)
177              (type (or null (unsigned-byte 4)) rex.wrxb))
178     
179     (setf (sb!disassem:dstate-get-prop dstate 'reg-width)
180           (if (and rex.wrxb (plusp (logand rex.wrxb #b1000)))
181               :qword
182             +default-operand-size+))
183
184     (let ((full-reg (if (and rex.wrxb (plusp (logand rex.wrxb #b0001)))
185                         (progn
186                           (setf (sb!disassem:dstate-get-prop dstate 'reg-width)
187                                 :qword)
188                           (+ 8 r/m) )
189                       r/m)))
190       (declare (type full-reg full-reg))
191       (cond ((= mod #b11)
192              ;; registers
193              full-reg)
194             ((= r/m #b100)
195              ;; sib byte
196              (let ((sib (sb!disassem:read-suffix 8 dstate)))
197                (declare (type (unsigned-byte 8) sib))
198                (let ((base-reg (ldb (byte 3 0) sib))
199                      (index-reg (ldb (byte 3 3) sib))
200                      (index-scale (ldb (byte 2 6) sib)))
201                  (declare (type (unsigned-byte 3) base-reg index-reg)
202                           (type (unsigned-byte 2) index-scale))
203                  (let* ((offset
204                          (case mod
205                                (#b00
206                                 (if (= base-reg #b101)
207                                     (sb!disassem:read-signed-suffix 32 dstate)
208                                   nil))
209                                (#b01
210                                 (sb!disassem:read-signed-suffix 8 dstate))
211                                (#b10
212                                 (sb!disassem:read-signed-suffix 32 dstate)))))
213                    (list (if (and (= mod #b00) (= base-reg #b101)) nil base-reg)
214                          offset
215                          (if (= index-reg #b100) nil index-reg)
216                          (ash 1 index-scale))))))
217             ((and (= mod #b00) (= r/m #b101))
218              (list nil (sb!disassem:read-signed-suffix 32 dstate)) )
219             ((= mod #b00)
220              (list full-reg))
221             ((= mod #b01)
222            (list full-reg (sb!disassem:read-signed-suffix 8 dstate)))
223           (t                            ; (= mod #b10)
224            (list full-reg (sb!disassem:read-signed-suffix 32 dstate)))))))
225
226
227 ;;; This is a sort of bogus prefilter that just stores the info globally for
228 ;;; other people to use; it probably never gets printed.
229 (defun prefilter-width (value dstate)
230   (setf (sb!disassem:dstate-get-prop dstate 'width)
231         (if (zerop value)
232             (setf (sb!disassem:dstate-get-prop dstate 'reg-width)
233                   :byte)
234             (let ((reg-width
235                    ;; set by a prefix instruction
236                    (or (sb!disassem:dstate-get-prop dstate 'reg-width)
237                        +default-operand-size+)))
238               (when (not (eql reg-width +default-operand-size+))
239                 ;; Reset it.
240                 (setf (sb!disassem:dstate-get-prop dstate 'reg-width)
241                       +default-operand-size+))
242               reg-width))))
243
244 (defun read-address (value dstate)
245   (declare (ignore value))              ; always nil anyway
246   (sb!disassem:read-suffix (width-bits *default-address-size*) dstate))
247
248 (defun width-bits (width)
249   (ecase width
250     (:byte 8)
251     (:word 16)
252     (:dword 32)
253     (:qword 64)
254     (:float 32)
255     (:double 64)))
256
257 ) ; EVAL-WHEN
258 \f
259 ;;;; disassembler argument types
260
261 (sb!disassem:define-arg-type displacement
262   :sign-extend t
263   :use-label #'offset-next
264   :printer (lambda (value stream dstate)
265              (sb!disassem:maybe-note-assembler-routine value nil dstate)
266              (print-label value stream dstate)))
267
268 (sb!disassem:define-arg-type accum
269   :printer (lambda (value stream dstate)
270              (declare (ignore value)
271                       (type stream stream)
272                       (type sb!disassem:disassem-state dstate))
273              (print-reg 0 stream dstate)))
274
275 (sb!disassem:define-arg-type word-accum
276   :printer (lambda (value stream dstate)
277              (declare (ignore value)
278                       (type stream stream)
279                       (type sb!disassem:disassem-state dstate))
280              (print-word-reg 0 stream dstate)))
281
282 (sb!disassem:define-arg-type reg
283   :printer #'print-reg)
284
285 (sb!disassem:define-arg-type addr-reg
286   :printer #'print-addr-reg)
287
288 (sb!disassem:define-arg-type word-reg
289   :prefilter #'prefilter-word-reg
290   :printer (lambda (value stream dstate)
291              (print-word-reg value stream dstate)))
292
293
294 (sb!disassem:define-arg-type imm-addr
295   :prefilter #'read-address
296   :printer #'print-label)
297
298 (sb!disassem:define-arg-type imm-data
299   :prefilter (lambda (value dstate)
300                (declare (ignore value)) ; always nil anyway
301                (sb!disassem:read-suffix
302                 (width-bits
303                  (or (sb!disassem:dstate-get-prop dstate 'width)
304                      *default-address-size*))
305                 dstate)))
306
307 (sb!disassem:define-arg-type signed-imm-data
308   :prefilter (lambda (value dstate)
309                (declare (ignore value)) ; always nil anyway
310                (let ((width (or (sb!disassem:dstate-get-prop dstate 'width)
311                                 *default-address-size*)))
312                  (sb!disassem:read-signed-suffix (width-bits width) dstate))))
313
314 (sb!disassem:define-arg-type signed-imm-byte
315   :prefilter (lambda (value dstate)
316                (declare (ignore value)) ; always nil anyway
317                (sb!disassem:read-signed-suffix 8 dstate)))
318
319 (sb!disassem:define-arg-type signed-imm-dword
320   :prefilter (lambda (value dstate)
321                (declare (ignore value)) ; always nil anyway
322                (sb!disassem:read-signed-suffix 32 dstate)))
323
324 (sb!disassem:define-arg-type imm-word
325   :prefilter (lambda (value dstate)
326                (declare (ignore value)) ; always nil anyway
327                (let ((width
328                       (or (sb!disassem:dstate-get-prop dstate 'reg-width)
329                           +default-operand-size+)))
330                  (sb!disassem:read-suffix (width-bits width) dstate))))
331
332 ;;; needed for the ret imm16 instruction
333 (sb!disassem:define-arg-type imm-word-16
334   :prefilter (lambda (value dstate)
335                (declare (ignore value)) ; always nil anyway
336                (sb!disassem:read-suffix 16 dstate)))
337
338 (sb!disassem:define-arg-type reg/mem
339   :prefilter #'prefilter-reg/mem
340   :printer #'print-reg/mem)
341 (sb!disassem:define-arg-type sized-reg/mem
342   ;; Same as reg/mem, but prints an explicit size indicator for
343   ;; memory references.
344   :prefilter #'prefilter-reg/mem
345   :printer #'print-sized-reg/mem)
346 (sb!disassem:define-arg-type byte-reg/mem
347   :prefilter #'prefilter-reg/mem
348   :printer #'print-byte-reg/mem)
349 (sb!disassem:define-arg-type word-reg/mem
350   :prefilter #'prefilter-reg/mem
351   :printer #'print-word-reg/mem)
352
353 (sb!disassem:define-arg-type rex-reg/mem
354   :prefilter #'prefilter-reg/mem
355   :printer #'print-rex-reg/mem)
356 (sb!disassem:define-arg-type sized-rex-reg/mem
357   ;; Same as reg/mem, but prints an explicit size indicator for
358   ;; memory references.
359   :prefilter #'prefilter-reg/mem
360   :printer #'print-sized-reg/mem)
361
362 ;;; added by jrd
363 (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)
364 (defun print-fp-reg (value stream dstate)
365   (declare (ignore dstate))
366   (format stream "FR~D" value))
367 (defun prefilter-fp-reg (value dstate)
368   ;; just return it
369   (declare (ignore dstate))
370   value)
371 ) ; EVAL-WHEN
372 (sb!disassem:define-arg-type fp-reg
373                              :prefilter #'prefilter-fp-reg
374                              :printer #'print-fp-reg)
375
376 (sb!disassem:define-arg-type width
377   :prefilter #'prefilter-width
378   :printer (lambda (value stream dstate)
379              (if;; (zerop value)
380                  (or (null value)
381                      (and (numberp value) (zerop value))) ; zzz jrd
382                  (princ 'b stream)
383                  (let ((reg-width
384                         ;; set by a prefix instruction
385                         (or (sb!disassem:dstate-get-prop dstate 'reg-width)
386                             +default-operand-size+)))
387                    (princ (schar (symbol-name reg-width) 0) stream)))))
388
389 (eval-when (:compile-toplevel :load-toplevel :execute)
390 (defparameter *conditions*
391   '((:o . 0)
392     (:no . 1)
393     (:b . 2) (:nae . 2) (:c . 2)
394     (:nb . 3) (:ae . 3) (:nc . 3)
395     (:eq . 4) (:e . 4) (:z . 4)
396     (:ne . 5) (:nz . 5)
397     (:be . 6) (:na . 6)
398     (:nbe . 7) (:a . 7)
399     (:s . 8)
400     (:ns . 9)
401     (:p . 10) (:pe . 10)
402     (:np . 11) (:po . 11)
403     (:l . 12) (:nge . 12)
404     (:nl . 13) (:ge . 13)
405     (:le . 14) (:ng . 14)
406     (:nle . 15) (:g . 15)))
407 (defparameter *condition-name-vec*
408   (let ((vec (make-array 16 :initial-element nil)))
409     (dolist (cond *conditions*)
410       (when (null (aref vec (cdr cond)))
411         (setf (aref vec (cdr cond)) (car cond))))
412     vec))
413 ) ; EVAL-WHEN
414
415 ;;; Set assembler parameters. (In CMU CL, this was done with
416 ;;; a call to a macro DEF-ASSEMBLER-PARAMS.)
417 (eval-when (:compile-toplevel :load-toplevel :execute)
418   (setf sb!assem:*assem-scheduler-p* nil))
419
420 (sb!disassem:define-arg-type condition-code
421   :printer *condition-name-vec*)
422
423 (defun conditional-opcode (condition)
424   (cdr (assoc condition *conditions* :test #'eq)))
425 \f
426 ;;;; disassembler instruction formats
427
428 (eval-when (:compile-toplevel :execute)
429   (defun swap-if (direction field1 separator field2)
430     `(:if (,direction :constant 0)
431           (,field1 ,separator ,field2)
432           (,field2 ,separator ,field1))))
433
434 (sb!disassem:define-instruction-format (byte 8 :default-printer '(:name))
435   (op    :field (byte 8 0))
436   ;; optional fields
437   (accum :type 'accum)
438   (imm))
439
440 (sb!disassem:define-instruction-format (simple 8)
441   (op    :field (byte 7 1))
442   (width :field (byte 1 0) :type 'width)
443   ;; optional fields
444   (accum :type 'accum)
445   (imm))
446
447 (sb!disassem:define-instruction-format (rex-simple 16)
448   (rex  :field (byte 4 4) :value #b0100)
449   (wrxb  :field (byte 4 0))
450   (op    :field (byte 7 9))
451   (width :field (byte 1 8) :type 'width)
452   ;; optional fields
453   (accum :type 'accum)
454   (imm))
455
456 ;;; Same as simple, but with direction bit
457 (sb!disassem:define-instruction-format (simple-dir 8 :include 'simple)
458   (op :field (byte 6 2))
459   (dir :field (byte 1 1)))
460
461 ;;; Same as simple, but with the immediate value occurring by default,
462 ;;; and with an appropiate printer.
463 (sb!disassem:define-instruction-format (accum-imm 8
464                                      :include 'simple
465                                      :default-printer '(:name
466                                                         :tab accum ", " imm))
467   (imm :type 'imm-data))
468
469 (sb!disassem:define-instruction-format (rex-accum-imm 16
470                                      :include 'rex-simple
471                                      :default-printer '(:name
472                                                         :tab accum ", " imm))
473   (imm :type 'imm-data))
474
475 (sb!disassem:define-instruction-format (reg-no-width 8
476                                      :default-printer '(:name :tab reg))
477   (op    :field (byte 5 3))
478   (reg   :field (byte 3 0) :type 'word-reg)
479   ;; optional fields
480   (accum :type 'word-accum)
481   (imm))
482
483 (sb!disassem:define-instruction-format (rex-reg-no-width 16
484                                      :default-printer '(:name :tab reg))
485   (rex   :field (byte 4 4)  :value #b0100)
486   (op    :field (byte 5 11))
487   (reg   :fields (list (byte 3 8) (byte 4 0)) :type 'word-reg)
488   ;; optional fields
489   (accum :type 'word-accum)
490   (imm))
491
492 (sb!disassem:define-instruction-format (modrm-reg-no-width 24
493                                      :default-printer '(:name :tab reg))
494   (rex   :field (byte 4 4)  :value #b0100)
495   (ff   :field (byte 8 8)  :value #b11111111)
496   (mod   :field (byte 2 22))
497   (modrm-reg :field (byte 3 19))
498   (reg   :fields (list (byte 3 16) (byte 4 0)) :type 'word-reg)
499   ;; optional fields
500   (accum :type 'word-accum)
501   (imm))
502
503 ;;; adds a width field to reg-no-width
504 (sb!disassem:define-instruction-format (reg 8
505                                         :default-printer '(:name :tab reg))
506   (op    :field (byte 4 4))
507   (width :field (byte 1 3) :type 'width)
508   (reg   :field (byte 3 0) :type 'reg)
509   ;; optional fields
510   (accum :type 'accum)
511   (imm)
512   )
513
514 (sb!disassem:define-instruction-format (rex-reg 16
515                                         :default-printer '(:name :tab reg))
516   (rex   :field (byte 4 4)  :value #b0100)
517   (op    :field (byte 5 11))
518   (reg   :field (byte 3 8) :type 'reg)
519   ;; optional fields
520   (accum :type 'accum)
521   (imm)
522   )
523
524 ;;; Same as reg, but with direction bit
525 (sb!disassem:define-instruction-format (reg-dir 8 :include 'reg)
526   (op  :field (byte 3 5))
527   (dir :field (byte 1 4)))
528
529 (sb!disassem:define-instruction-format (two-bytes 16
530                                         :default-printer '(:name))
531   (op :fields (list (byte 8 0) (byte 8 8))))
532
533 (sb!disassem:define-instruction-format (reg-reg/mem 16
534                                         :default-printer
535                                         `(:name :tab reg ", " reg/mem))
536   (op      :field (byte 7 1))
537   (width   :field (byte 1 0)    :type 'width)
538   (reg/mem :fields (list (byte 2 14) (byte 3 8))
539                                 :type 'reg/mem)
540   (reg     :field (byte 3 11)   :type 'reg)
541   ;; optional fields
542   (imm))
543
544 (sb!disassem:define-instruction-format (rex-reg-reg/mem 24
545                                         :default-printer
546                                         `(:name :tab reg ", " reg/mem))
547   (rex    :field (byte 4 4)  :value #b0100)
548   (op      :field (byte 8 8))
549   (reg/mem :fields (list (byte 2 22) (byte 3 16) (byte 4 0))
550            :type 'rex-reg/mem)
551   (reg     :field (byte 3 19)   :type 'reg)
552   ;; optional fields
553   (imm))
554
555 ;;; same as reg-reg/mem, but with direction bit
556 (sb!disassem:define-instruction-format (reg-reg/mem-dir 16
557                                         :include 'reg-reg/mem
558                                         :default-printer
559                                         `(:name
560                                           :tab
561                                           ,(swap-if 'dir 'reg/mem ", " 'reg)))
562   (op  :field (byte 6 2))
563   (dir :field (byte 1 1)))
564
565 (sb!disassem:define-instruction-format (rex-reg-reg/mem-dir 24
566                                         :include 'rex-reg-reg/mem
567                                         :default-printer
568                                         `(:name
569                                           :tab
570                                           ,(swap-if 'dir 'reg/mem ", " 'reg)))
571   (rex    :field (byte 4 4)  :value #b0100)
572   (op  :field (byte 6 10))
573   (dir :field (byte 1 9)))
574
575 ;;; Same as reg-rem/mem, but uses the reg field as a second op code.
576 (sb!disassem:define-instruction-format (reg/mem 16
577                                         :default-printer '(:name :tab reg/mem))
578   (op      :fields (list (byte 7 1) (byte 3 11)))
579   (width   :field (byte 1 0)    :type 'width)
580   (reg/mem :fields (list (byte 2 14) (byte 3 8))
581                                 :type 'sized-reg/mem)
582   ;; optional fields
583   (imm))
584
585 (sb!disassem:define-instruction-format (rex-reg/mem 24
586                                         :default-printer '(:name :tab reg/mem))
587   (rex    :field (byte 4 4)  :value #b0100)
588   (op     :fields (list (byte 8 8) (byte 3 19)))
589   (reg/mem :fields (list (byte 2 22) (byte 3 16) (byte 4 0)) :type 'sized-rex-reg/mem)
590   ;; optional fields
591   (imm))
592
593 ;;; Same as reg/mem, but with the immediate value occurring by default,
594 ;;; and with an appropiate printer.
595 (sb!disassem:define-instruction-format (reg/mem-imm 16
596                                         :include 'reg/mem
597                                         :default-printer
598                                         '(:name :tab reg/mem ", " imm))
599   (reg/mem :type 'sized-reg/mem)
600   (imm     :type 'imm-data))
601
602 (sb!disassem:define-instruction-format (rex-reg/mem-imm 24
603                                         :include 'rex-reg/mem
604                                         :default-printer
605                                         '(:name :tab reg/mem ", " imm))
606   (reg/mem :type 'sized-rex-reg/mem)
607   (imm     :type 'imm-data))
608
609 ;;; Same as reg/mem, but with using the accumulator in the default printer
610 (sb!disassem:define-instruction-format
611     (accum-reg/mem 16
612      :include 'reg/mem :default-printer '(:name :tab accum ", " reg/mem))
613   (reg/mem :type 'reg/mem)              ; don't need a size
614   (accum :type 'accum))
615
616 ;;; Same as reg-reg/mem, but with a prefix of #b00001111
617 (sb!disassem:define-instruction-format (ext-reg-reg/mem 24
618                                         :default-printer
619                                         `(:name :tab reg ", " reg/mem))
620   (prefix  :field (byte 8 0)    :value #b00001111)
621   (op      :field (byte 7 9))
622   (width   :field (byte 1 8)    :type 'width)
623   (reg/mem :fields (list (byte 2 22) (byte 3 16))
624                                 :type 'reg/mem)
625   (reg     :field (byte 3 19)   :type 'reg)
626   ;; optional fields
627   (imm))
628
629 ;;; Same as reg-reg/mem, but with a prefix of #xf2 0f
630 (sb!disassem:define-instruction-format (xmm-ext-reg-reg/mem 32
631                                         :default-printer
632                                         `(:name :tab reg ", " reg/mem))
633   (prefix  :field (byte 8 0)    :value #xf2)
634   (prefix2  :field (byte 8 8)   :value #x0f)
635   (op      :field (byte 7 17))
636   (width   :field (byte 1 16)   :type 'width)
637   (reg/mem :fields (list (byte 2 30) (byte 3 24))
638                                 :type 'reg/mem)
639   (reg     :field (byte 3 27)   :type 'reg)
640   ;; optional fields
641   (imm))
642
643 ;;; reg-no-width with #x0f prefix
644 (sb!disassem:define-instruction-format (ext-reg-no-width 16
645                                         :default-printer '(:name :tab reg))
646   (prefix  :field (byte 8 0)    :value #b00001111)
647   (op    :field (byte 5 11))
648   (reg   :field (byte 3 8) :type 'word-reg))
649
650 ;;; Same as reg/mem, but with a prefix of #b00001111
651 (sb!disassem:define-instruction-format (ext-reg/mem 24
652                                         :default-printer '(:name :tab reg/mem))
653   (prefix  :field (byte 8 0)    :value #b00001111)
654   (op      :fields (list (byte 7 9) (byte 3 19)))
655   (width   :field (byte 1 8)    :type 'width)
656   (reg/mem :fields (list (byte 2 22) (byte 3 16))
657                                 :type 'sized-reg/mem)
658   ;; optional fields
659   (imm))
660
661 (sb!disassem:define-instruction-format (ext-reg/mem-imm 24
662                                         :include 'ext-reg/mem
663                                         :default-printer
664                                         '(:name :tab reg/mem ", " imm))
665   (imm :type 'imm-data))
666 \f
667 ;;;; This section was added by jrd, for fp instructions.
668
669 ;;; regular fp inst to/from registers/memory
670 (sb!disassem:define-instruction-format (floating-point 16
671                                         :default-printer
672                                         `(:name :tab reg/mem))
673   (prefix :field (byte 5 3) :value #b11011)
674   (op     :fields (list (byte 3 0) (byte 3 11)))
675   (reg/mem :fields (list (byte 2 14) (byte 3 8)) :type 'reg/mem))
676
677 ;;; fp insn to/from fp reg
678 (sb!disassem:define-instruction-format (floating-point-fp 16
679                                         :default-printer `(:name :tab fp-reg))
680   (prefix :field (byte 5 3) :value #b11011)
681   (suffix :field (byte 2 14) :value #b11)
682   (op     :fields (list (byte 3 0) (byte 3 11)))
683   (fp-reg :field (byte 3 8) :type 'fp-reg))
684
685 ;;; fp insn to/from fp reg, with the reversed source/destination flag.
686 (sb!disassem:define-instruction-format
687  (floating-point-fp-d 16
688    :default-printer `(:name :tab ,(swap-if 'd "ST0" ", " 'fp-reg)))
689   (prefix :field (byte 5 3) :value #b11011)
690   (suffix :field (byte 2 14) :value #b11)
691   (op     :fields (list (byte 2 0) (byte 3 11)))
692   (d      :field (byte 1 2))
693   (fp-reg :field (byte 3 8) :type 'fp-reg))
694
695
696 ;;; (added by (?) pfw)
697 ;;; fp no operand isns
698 (sb!disassem:define-instruction-format (floating-point-no 16
699                                       :default-printer '(:name))
700   (prefix :field (byte 8  0) :value #b11011001)
701   (suffix :field (byte 3 13) :value #b111)
702   (op     :field (byte 5  8)))
703
704 (sb!disassem:define-instruction-format (floating-point-3 16
705                                       :default-printer '(:name))
706   (prefix :field (byte 5 3) :value #b11011)
707   (suffix :field (byte 2 14) :value #b11)
708   (op     :fields (list (byte 3 0) (byte 6 8))))
709
710 (sb!disassem:define-instruction-format (floating-point-5 16
711                                       :default-printer '(:name))
712   (prefix :field (byte 8  0) :value #b11011011)
713   (suffix :field (byte 3 13) :value #b111)
714   (op     :field (byte 5  8)))
715
716 (sb!disassem:define-instruction-format (floating-point-st 16
717                                       :default-printer '(:name))
718   (prefix :field (byte 8  0) :value #b11011111)
719   (suffix :field (byte 3 13) :value #b111)
720   (op     :field (byte 5  8)))
721
722 (sb!disassem:define-instruction-format (string-op 8
723                                      :include 'simple
724                                      :default-printer '(:name width)))
725
726 (sb!disassem:define-instruction-format (rex-string-op 16
727                                      :include 'rex-simple
728                                      :default-printer '(:name width)))
729
730 (sb!disassem:define-instruction-format (short-cond-jump 16)
731   (op    :field (byte 4 4))
732   (cc    :field (byte 4 0) :type 'condition-code)
733   (label :field (byte 8 8) :type 'displacement))
734
735 (sb!disassem:define-instruction-format (short-jump 16
736                                      :default-printer '(:name :tab label))
737   (const :field (byte 4 4) :value #b1110)
738   (op    :field (byte 4 0))
739   (label :field (byte 8 8) :type 'displacement))
740
741 (sb!disassem:define-instruction-format (near-cond-jump 16)
742   (op    :fields (list (byte 8 0) (byte 4 12)) :value '(#b00001111 #b1000))
743   (cc    :field (byte 4 8) :type 'condition-code)
744   ;; The disassembler currently doesn't let you have an instruction > 32 bits
745   ;; long, so we fake it by using a prefilter to read the offset.
746   (label :type 'displacement
747          :prefilter (lambda (value dstate)
748                       (declare (ignore value)) ; always nil anyway
749                       (sb!disassem:read-signed-suffix 32 dstate))))
750
751 (sb!disassem:define-instruction-format (near-jump 8
752                                      :default-printer '(:name :tab label))
753   (op    :field (byte 8 0))
754   ;; The disassembler currently doesn't let you have an instruction > 32 bits
755   ;; long, so we fake it by using a prefilter to read the address.
756   (label :type 'displacement
757          :prefilter (lambda (value dstate)
758                       (declare (ignore value)) ; always nil anyway
759                       (sb!disassem:read-signed-suffix 32 dstate))))
760
761
762 (sb!disassem:define-instruction-format (cond-set 24
763                                      :default-printer '('set cc :tab reg/mem))
764   (prefix :field (byte 8 0) :value #b00001111)
765   (op    :field (byte 4 12) :value #b1001)
766   (cc    :field (byte 4 8) :type 'condition-code)
767   (reg/mem :fields (list (byte 2 22) (byte 3 16))
768            :type 'byte-reg/mem)
769   (reg     :field (byte 3 19)   :value #b000))
770
771 (sb!disassem:define-instruction-format (cond-move 24
772                                      :default-printer
773                                         '('cmov cc :tab reg ", " reg/mem))
774   (prefix  :field (byte 8 0)    :value #b00001111)
775   (op      :field (byte 4 12)   :value #b0100)
776   (cc      :field (byte 4 8)    :type 'condition-code)
777   (reg/mem :fields (list (byte 2 22) (byte 3 16))
778                                 :type 'reg/mem)
779   (reg     :field (byte 3 19)   :type 'reg))
780
781 (sb!disassem:define-instruction-format (enter-format 32
782                                      :default-printer '(:name
783                                                         :tab disp
784                                                         (:unless (:constant 0)
785                                                           ", " level)))
786   (op :field (byte 8 0))
787   (disp :field (byte 16 8))
788   (level :field (byte 8 24)))
789
790 ;;; Single byte instruction with an immediate byte argument.
791 (sb!disassem:define-instruction-format (byte-imm 16
792                                      :default-printer '(:name :tab code))
793  (op :field (byte 8 0))
794  (code :field (byte 8 8)))
795 \f
796 ;;;; primitive emitters
797
798 (define-bitfield-emitter emit-word 16
799   (byte 16 0))
800
801 (define-bitfield-emitter emit-dword 32
802   (byte 32 0))
803
804 (define-bitfield-emitter emit-qword 64
805   (byte 64 0))
806
807 (define-bitfield-emitter emit-byte-with-reg 8
808   (byte 5 3) (byte 3 0))
809
810 (define-bitfield-emitter emit-mod-reg-r/m-byte 8
811   (byte 2 6) (byte 3 3) (byte 3 0))
812
813 (define-bitfield-emitter emit-sib-byte 8
814   (byte 2 6) (byte 3 3) (byte 3 0))
815
816 (define-bitfield-emitter emit-rex-byte 8
817   (byte 4 4) (byte 1 3) (byte 1 2) (byte 1 1) (byte 1 0))
818
819
820 \f
821 ;;;; fixup emitters
822
823 (defun emit-absolute-fixup (segment fixup &optional quad-p)
824   (note-fixup segment (if quad-p :absolute64 :absolute) fixup)
825   (let ((offset (fixup-offset fixup)))
826     (if (label-p offset)
827         (emit-back-patch segment
828                          (if quad-p 8 4)
829                          (lambda (segment posn)
830                            (declare (ignore posn))
831                            (let ((val  (- (+ (component-header-length)
832                                              (or (label-position offset)
833                                                  0))
834                                           other-pointer-lowtag)))
835                              (if quad-p
836                                  (emit-qword segment val )
837                                  (emit-dword segment val )))))
838         (if quad-p
839             (emit-qword segment (or offset 0))
840             (emit-dword segment (or offset 0))))))
841
842 (defun emit-relative-fixup (segment fixup)
843   (note-fixup segment :relative fixup)
844   (emit-dword segment (or (fixup-offset fixup) 0)))
845
846 \f
847 ;;;; the effective-address (ea) structure
848
849 (defun reg-tn-encoding (tn)
850   (declare (type tn tn))
851   (aver (member  (sb-name (sc-sb (tn-sc tn))) '(registers float-registers)))
852   ;; ea only has space for three bits of register number: regs r8
853   ;; and up are selected by a REX prefix byte which caller is responsible
854   ;; for having emitted where necessary already
855   (cond ((fp-reg-tn-p tn)
856          (mod (tn-offset tn) 8))
857         (t
858          (let ((offset (mod (tn-offset tn) 16)))
859            (logior (ash (logand offset 1) 2)
860                    (ash offset -1))))))
861   
862 (defstruct (ea (:constructor make-ea (size &key base index scale disp))
863                (:copier nil))
864   ;; note that we can represent an EA qith a QWORD size, but EMIT-EA
865   ;; can't actually emit it on its own: caller also needs to emit REX
866   ;; prefix
867   (size nil :type (member :byte :word :dword :qword))
868   (base nil :type (or tn null))
869   (index nil :type (or tn null))
870   (scale 1 :type (member 1 2 4 8))
871   (disp 0 :type (or (unsigned-byte 32) (signed-byte 32) fixup)))
872 (def!method print-object ((ea ea) stream)
873   (cond ((or *print-escape* *print-readably*)
874          (print-unreadable-object (ea stream :type t)
875            (format stream
876                    "~S~@[ base=~S~]~@[ index=~S~]~@[ scale=~S~]~@[ disp=~S~]"
877                    (ea-size ea)
878                    (ea-base ea)
879                    (ea-index ea)
880                    (let ((scale (ea-scale ea)))
881                      (if (= scale 1) nil scale))
882                    (ea-disp ea))))
883         (t
884          (format stream "~A PTR [" (symbol-name (ea-size ea)))
885          (when (ea-base ea)
886            (write-string (sb!c::location-print-name (ea-base ea)) stream)
887            (when (ea-index ea)
888              (write-string "+" stream)))
889          (when (ea-index ea)
890            (write-string (sb!c::location-print-name (ea-index ea)) stream))
891          (unless (= (ea-scale ea) 1)
892            (format stream "*~A" (ea-scale ea)))
893          (typecase (ea-disp ea)
894            (null)
895            (integer
896             (format stream "~@D" (ea-disp ea)))
897            (t
898             (format stream "+~A" (ea-disp ea))))
899          (write-char #\] stream))))
900
901 (defun emit-constant-tn-rip (segment constant-tn reg)
902   ;; AMD64 doesn't currently have a code object register to use as a
903   ;; base register for constant access. Instead we use RIP-relative
904   ;; addressing. The offset from the SIMPLE-FUN-HEADER to the instruction
905   ;; is passed to the backpatch callback. In addition we need the offset
906   ;; from the start of the function header to the slot in the CODE-HEADER
907   ;; that stores the constant. Since we don't know where the code header
908   ;; starts, instead count backwards from the function header.
909   (let* ((2comp (component-info *component-being-compiled*))
910          (constants (ir2-component-constants 2comp))
911          (len (length constants))
912          ;; Both CODE-HEADER and SIMPLE-FUN-HEADER are 16-byte aligned.
913          ;; If there are an even amount of constants, there will be
914          ;; an extra qword of padding before the function header, which
915          ;; needs to be adjusted for. XXX: This will break if new slots
916          ;; are added to the code header.
917          (offset (* (- (+ len (if (evenp len)
918                                   1
919                                   2))
920                        (tn-offset constant-tn))
921                     n-word-bytes)))
922     ;; RIP-relative addressing
923     (emit-mod-reg-r/m-byte segment #b00 reg #b101)
924     (emit-back-patch segment
925                      4
926                      (lambda (segment posn)
927                        ;; The addressing is relative to end of instruction,
928                        ;; i.e. the end of this dword. Hence the + 4.
929                        (emit-dword segment (+ 4 (- (+ offset posn)))))))
930   (values))
931
932 (defun emit-label-rip (segment fixup reg)
933   (let ((label (fixup-offset fixup)))
934     ;; RIP-relative addressing
935     (emit-mod-reg-r/m-byte segment #b00 reg #b101)
936     (emit-back-patch segment
937                      4
938                      (lambda (segment posn)
939                        (emit-dword segment (- (label-position label)
940                                               (+ posn 4))))))
941   (values))
942
943 (defun emit-ea (segment thing reg &optional allow-constants)
944   (etypecase thing
945     (tn
946      ;; this would be eleganter if we had a function that would create
947      ;; an ea given a tn
948      (ecase (sb-name (sc-sb (tn-sc thing)))
949        ((registers float-registers)
950         (emit-mod-reg-r/m-byte segment #b11 reg (reg-tn-encoding thing)))
951        (stack
952         ;; Convert stack tns into an index off RBP.
953         (let ((disp (- (* (1+ (tn-offset thing)) n-word-bytes))))
954           (cond ((< -128 disp 127)
955                  (emit-mod-reg-r/m-byte segment #b01 reg #b101)
956                  (emit-byte segment disp))
957                 (t
958                  (emit-mod-reg-r/m-byte segment #b10 reg #b101)
959                  (emit-dword segment disp)))))
960        (constant
961         (unless allow-constants
962           ;; Why?
963           (error
964            "Constant TNs can only be directly used in MOV, PUSH, and CMP."))
965         (emit-constant-tn-rip segment thing reg))))
966     (ea
967      (let* ((base (ea-base thing))
968             (index (ea-index thing))
969             (scale (ea-scale thing))
970             (disp (ea-disp thing))
971             (mod (cond ((or (null base)
972                             (and (eql disp 0)
973                                  (not (= (reg-tn-encoding base) #b101))))
974                         #b00)
975                        ((and (fixnump disp) (<= -128 disp 127))
976                         #b01)
977                        (t
978                         #b10)))
979             (r/m (cond (index #b100)
980                        ((null base) #b101)
981                        (t (reg-tn-encoding base)))))
982        (when (and (= mod 0) (= r/m #b101))
983          ;; this is rip-relative in amd64, so we'll use a sib instead
984          (setf r/m #b100 scale 1))
985        (emit-mod-reg-r/m-byte segment mod reg r/m)
986        (when (= r/m #b100)
987          (let ((ss (1- (integer-length scale)))
988                (index (if (null index)
989                           #b100
990                           (let ((index (reg-tn-encoding index)))
991                             (if (= index #b100)
992                                 (error "can't index off of ESP")
993                                 index))))
994                (base (if (null base)
995                          #b101
996                          (reg-tn-encoding base))))
997            (emit-sib-byte segment ss index base)))
998        (cond ((= mod #b01)
999               (emit-byte segment disp))
1000              ((or (= mod #b10) (null base))
1001               (if (fixup-p disp)
1002                   (emit-absolute-fixup segment disp)
1003                   (emit-dword segment disp))))))
1004     (fixup
1005      (typecase (fixup-offset thing)
1006        (label
1007         (emit-label-rip segment thing reg))
1008        (t
1009         (emit-mod-reg-r/m-byte segment #b00 reg #b100)
1010         (emit-sib-byte segment 0 #b100 #b101)
1011         (emit-absolute-fixup segment thing))))))
1012
1013 (defun fp-reg-tn-p (thing)
1014   (and (tn-p thing)
1015        (eq (sb-name (sc-sb (tn-sc thing))) 'float-registers)))
1016
1017 ;;; like the above, but for fp-instructions--jrd
1018 (defun emit-fp-op (segment thing op)
1019   (if (fp-reg-tn-p thing)
1020       (emit-byte segment (dpb op (byte 3 3) (dpb (tn-offset thing)
1021                                                  (byte 3 0)
1022                                                  #b11000000)))
1023     (emit-ea segment thing op)))
1024
1025 (defun byte-reg-p (thing)
1026   (and (tn-p thing)
1027        (eq (sb-name (sc-sb (tn-sc thing))) 'registers)
1028        (member (sc-name (tn-sc thing)) *byte-sc-names*)
1029        t))
1030
1031 (defun byte-ea-p (thing)
1032   (typecase thing
1033     (ea (eq (ea-size thing) :byte))
1034     (tn
1035      (and (member (sc-name (tn-sc thing)) *byte-sc-names*) t))
1036     (t nil)))
1037
1038 (defun word-reg-p (thing)
1039   (and (tn-p thing)
1040        (eq (sb-name (sc-sb (tn-sc thing))) 'registers)
1041        (member (sc-name (tn-sc thing)) *word-sc-names*)
1042        t))
1043
1044 (defun word-ea-p (thing)
1045   (typecase thing
1046     (ea (eq (ea-size thing) :word))
1047     (tn (and (member (sc-name (tn-sc thing)) *word-sc-names*) t))
1048     (t nil)))
1049
1050 (defun dword-reg-p (thing)
1051   (and (tn-p thing)
1052        (eq (sb-name (sc-sb (tn-sc thing))) 'registers)
1053        (member (sc-name (tn-sc thing)) *dword-sc-names*)
1054        t))
1055
1056 (defun dword-ea-p (thing)
1057   (typecase thing
1058     (ea (eq (ea-size thing) :dword))
1059     (tn
1060      (and (member (sc-name (tn-sc thing)) *dword-sc-names*) t))
1061     (t nil)))
1062
1063 (defun qword-reg-p (thing)
1064   (and (tn-p thing)
1065        (eq (sb-name (sc-sb (tn-sc thing))) 'registers)
1066        (member (sc-name (tn-sc thing)) *qword-sc-names*)
1067        t))
1068
1069 (defun qword-ea-p (thing)
1070   (typecase thing
1071     (ea (eq (ea-size thing) :qword))
1072     (tn
1073      (and (member (sc-name (tn-sc thing)) *qword-sc-names*) t))
1074     (t nil)))
1075
1076 (defun register-p (thing)
1077   (and (tn-p thing)
1078        (eq (sb-name (sc-sb (tn-sc thing))) 'registers)))
1079
1080 (defun accumulator-p (thing)
1081   (and (register-p thing)
1082        (= (tn-offset thing) 0)))
1083
1084 \f
1085 ;;;; utilities
1086
1087 (def!constant +operand-size-prefix-byte+ #b01100110)
1088
1089 (defun maybe-emit-operand-size-prefix (segment size)
1090   (unless (or (eq size :byte) 
1091               (eq size :qword)          ; REX prefix handles this
1092               (eq size +default-operand-size+))
1093     (emit-byte segment +operand-size-prefix-byte+)))
1094
1095 (defun maybe-emit-rex-prefix (segment operand-size r x b)
1096   (labels ((if-hi (r)
1097              (if (and r (> (tn-offset r)
1098                            ;; offset of r8 is 16, offset of xmm8 is 8
1099                            (if (fp-reg-tn-p r)
1100                                7
1101                                15)))
1102                  1
1103                  0)))
1104     (let ((rex-w (if (eq operand-size :qword) 1 0))
1105           (rex-r (if-hi r))
1106           (rex-x (if-hi x))
1107           (rex-b (if-hi b)))
1108       (when (or (eq operand-size :byte) ;; REX needed to access SIL/DIL
1109                 (not (zerop (logior rex-w rex-r rex-x rex-b))))
1110         (emit-rex-byte segment #b0100 rex-w rex-r rex-x rex-b)))))
1111
1112 (defun maybe-emit-rex-for-ea (segment ea reg &key operand-size)
1113   (let ((ea-p (ea-p ea)))               ;emit-ea can also be called with a tn
1114     (maybe-emit-rex-prefix segment
1115                            (or operand-size (operand-size ea))
1116                            reg
1117                            (and ea-p (ea-index ea))
1118                            (cond (ea-p (ea-base ea))
1119                                  ((and (tn-p ea)
1120                                        (member (sb-name (sc-sb (tn-sc ea))) 
1121                                                '(float-registers registers)))
1122                                   ea)
1123                                  (t nil)))))
1124
1125 (defun operand-size (thing)
1126   (typecase thing
1127     (tn
1128      ;; FIXME: might as well be COND instead of having to use #. readmacro
1129      ;; to hack up the code
1130      (case (sc-name (tn-sc thing))
1131        (#.*qword-sc-names*
1132         :qword)
1133        (#.*dword-sc-names*
1134         :dword)
1135        (#.*word-sc-names*
1136         :word)
1137        (#.*byte-sc-names*
1138         :byte)
1139        ;; added by jrd: float-registers is a separate size (?)
1140        (#.*float-sc-names*
1141         :float)
1142        (#.*double-sc-names*
1143         :double)
1144        (t
1145         (error "can't tell the size of ~S ~S" thing (sc-name (tn-sc thing))))))
1146     (ea
1147      (ea-size thing))
1148     (fixup
1149      ;; GNA.  Guess who spelt "flavor" correctly first time round?
1150      ;; There's a strong argument in my mind to change all uses of
1151      ;; "flavor" to "kind": and similarly with some misguided uses of
1152      ;; "type" here and there.  -- CSR, 2005-01-06.
1153      (case (fixup-flavor thing)
1154        ((:foreign-dataref) :qword)))
1155     (t
1156      nil)))
1157
1158 (defun matching-operand-size (dst src)
1159   (let ((dst-size (operand-size dst))
1160         (src-size (operand-size src)))
1161     (if dst-size
1162         (if src-size
1163             (if (eq dst-size src-size)
1164                 dst-size
1165                 (error "size mismatch: ~S is a ~S and ~S is a ~S."
1166                        dst dst-size src src-size))
1167             dst-size)
1168         (if src-size
1169             src-size
1170             (error "can't tell the size of either ~S or ~S" dst src)))))
1171
1172 (defun emit-sized-immediate (segment size value &optional quad-p)
1173   (ecase size
1174     (:byte
1175      (emit-byte segment value))
1176     (:word
1177      (emit-word segment value))
1178     ((:dword :qword)
1179      ;; except in a very few cases (MOV instructions A1,A3,B8) we expect
1180      ;; dword data bytes even when 64 bit work is being done.  So, mostly
1181      ;; we treat quad constants as dwords.
1182      (if (and quad-p (eq size :qword))
1183          (emit-qword segment value)
1184          (emit-dword segment value)))))
1185 \f
1186 ;;;; general data transfer
1187
1188 (define-instruction mov (segment dst src)
1189   ;; immediate to register
1190   (:printer reg ((op #b1011) (imm nil :type 'imm-data))
1191             '(:name :tab reg ", " imm))
1192   (:printer rex-reg ((op #b10111) (imm nil :type 'imm-data))
1193             '(:name :tab reg ", " imm))
1194   ;; absolute mem to/from accumulator
1195   (:printer simple-dir ((op #b101000) (imm nil :type 'imm-addr))
1196             `(:name :tab ,(swap-if 'dir 'accum ", " '("[" imm "]"))))
1197   ;; register to/from register/memory
1198   (:printer reg-reg/mem-dir ((op #b100010)))
1199   (:printer rex-reg-reg/mem-dir ((op #b100010)))
1200   ;; immediate to register/memory
1201   (:printer reg/mem-imm ((op '(#b1100011 #b000))))
1202   (:printer rex-reg/mem-imm ((op '(#b1100011 #b000))))
1203
1204   (:emitter
1205    (let ((size (matching-operand-size dst src)))
1206      (maybe-emit-operand-size-prefix segment size)
1207      (cond ((register-p dst)
1208             (cond ((integerp src)
1209                    (maybe-emit-rex-prefix segment size nil nil dst)
1210                    (emit-byte-with-reg segment
1211                                        (if (eq size :byte)
1212                                            #b10110
1213                                            #b10111)
1214                                        (reg-tn-encoding dst))
1215                    (emit-sized-immediate segment size src (eq size :qword)))
1216                   (t
1217                    (maybe-emit-rex-for-ea segment src dst)
1218                    (emit-byte segment
1219                               (if (eq size :byte)
1220                                   #b10001010
1221                                   #b10001011))
1222                    (emit-ea segment src (reg-tn-encoding dst) t))))
1223            ((integerp src)
1224             ;; C7 only deals with 32 bit immediates even if register is 
1225             ;; 64 bit: only b8-bf use 64 bit immediates
1226             (maybe-emit-rex-for-ea segment dst nil)
1227             (cond ((typep src '(or (signed-byte 32) (unsigned-byte 32)))
1228                    (emit-byte segment
1229                               (if (eq size :byte) #b11000110 #b11000111))
1230                    (emit-ea segment dst #b000)
1231                    (emit-sized-immediate segment 
1232                                          (case size (:qword :dword) (t size))
1233                                          src))
1234                   (t
1235                    (aver nil))))
1236            ((register-p src)
1237             (maybe-emit-rex-for-ea segment dst src)
1238             (emit-byte segment (if (eq size :byte) #b10001000 #b10001001))
1239             (emit-ea segment dst (reg-tn-encoding src)))
1240            ((fixup-p src)
1241             ;; Generally we can't MOV a fixupped value into an EA, since
1242             ;; MOV on non-registers can only take a 32-bit immediate arg.
1243             ;; Make an exception for :FOREIGN fixups (pretty much just
1244             ;; the runtime asm, since other foreign calls go through the
1245             ;; the linkage table) and for linkage table references, since
1246             ;; these should always end up in low memory.
1247             (aver (or (eq (fixup-flavor src) :foreign)
1248                       (eq (fixup-flavor src) :foreign-dataref)
1249                       (eq (ea-size dst) :dword)))
1250             (maybe-emit-rex-for-ea segment dst nil)
1251             (emit-byte segment #b11000111)
1252             (emit-ea segment dst #b000)
1253             (emit-absolute-fixup segment src))
1254            (t
1255             (error "bogus arguments to MOV: ~S ~S" dst src))))))
1256
1257 (defun emit-move-with-extension (segment dst src signed-p)
1258   (aver (register-p dst))
1259   (let ((dst-size (operand-size dst))
1260         (src-size (operand-size src))
1261         (opcode (if signed-p  #b10111110 #b10110110)))
1262     (ecase dst-size
1263       (:word
1264        (aver (eq src-size :byte))
1265        (maybe-emit-operand-size-prefix segment :word)
1266        (emit-byte segment #b00001111)
1267        (emit-byte segment opcode)
1268        (emit-ea segment src (reg-tn-encoding dst)))
1269       ((:dword :qword)
1270        (ecase src-size
1271          (:byte
1272           (maybe-emit-operand-size-prefix segment :dword)
1273           (maybe-emit-rex-for-ea segment src dst
1274                                  :operand-size (operand-size dst))
1275           (emit-byte segment #b00001111)
1276           (emit-byte segment opcode)
1277           (emit-ea segment src (reg-tn-encoding dst)))
1278          (:word
1279           (maybe-emit-rex-for-ea segment src dst
1280                                  :operand-size (operand-size dst))
1281           (emit-byte segment #b00001111)
1282           (emit-byte segment (logior opcode 1))
1283           (emit-ea segment src (reg-tn-encoding dst)))
1284          (:dword
1285           (aver (eq dst-size :qword))
1286           ;; dst is in reg, src is in modrm
1287           (let ((ea-p (ea-p src)))
1288             (maybe-emit-rex-prefix segment (if signed-p :qword :dword) dst 
1289                                    (and ea-p (ea-index src))
1290                                    (cond (ea-p (ea-base src))
1291                                          ((tn-p src) src)
1292                                          (t nil)))
1293             (emit-byte segment #x63)    ;movsxd 
1294             ;;(emit-byte segment opcode)
1295             (emit-ea segment src (reg-tn-encoding dst)))))))))
1296
1297 (define-instruction movsx (segment dst src)
1298   (:printer ext-reg-reg/mem ((op #b1011111) (reg nil :type 'word-reg)))
1299   (:emitter (emit-move-with-extension segment dst src :signed)))
1300
1301 (define-instruction movzx (segment dst src)
1302   (:printer ext-reg-reg/mem ((op #b1011011) (reg nil :type 'word-reg)))
1303   (:emitter (emit-move-with-extension segment dst src nil)))
1304
1305 (define-instruction movsxd (segment dst src)
1306   (:printer reg-reg/mem ((op #x63) (reg nil :type 'word-reg)))
1307   (:emitter (emit-move-with-extension segment dst src :signed)))
1308
1309 ;;; this is not a real amd64 instruction, of course
1310 (define-instruction movzxd (segment dst src)
1311   ; (:printer reg-reg/mem ((op #x63) (reg nil :type 'word-reg)))
1312   (:emitter (emit-move-with-extension segment dst src nil)))
1313
1314 (define-instruction push (segment src)
1315   ;; register
1316   (:printer reg-no-width ((op #b01010)))
1317   (:printer rex-reg-no-width ((op #b01010)))
1318   ;; register/memory
1319   (:printer reg/mem ((op '(#b1111111 #b110)) (width 1)))
1320   (:printer rex-reg/mem ((op '(#b11111111 #b110))))
1321   ;; immediate
1322   (:printer byte ((op #b01101010) (imm nil :type 'signed-imm-byte))
1323             '(:name :tab imm))
1324   (:printer byte ((op #b01101000) (imm nil :type 'imm-word))
1325             '(:name :tab imm))
1326   ;; ### segment registers?
1327
1328   (:emitter
1329    (cond ((integerp src)
1330           (cond ((<= -128 src 127)
1331                  (emit-byte segment #b01101010)
1332                  (emit-byte segment src))
1333                 (t
1334                  ;; AMD64 manual says no REX needed but is unclear
1335                  ;; whether it expects 32 or 64 bit immediate here
1336                  (emit-byte segment #b01101000)
1337                  (emit-dword segment src))))
1338          (t
1339           (let ((size (operand-size src)))
1340             (aver (not (eq size :byte)))
1341             (maybe-emit-operand-size-prefix segment size)
1342             (maybe-emit-rex-for-ea segment src nil)
1343             (cond ((register-p src)
1344                    (emit-byte-with-reg segment #b01010 (reg-tn-encoding src)))
1345                   (t
1346                    (emit-byte segment #b11111111)
1347                    (emit-ea segment src #b110 t))))))))
1348
1349 (define-instruction pusha (segment)
1350   (:printer byte ((op #b01100000)))
1351   (:emitter
1352    (emit-byte segment #b01100000)))
1353
1354 (define-instruction pop (segment dst)
1355   (:printer reg-no-width ((op #b01011)))
1356   (:printer rex-reg-no-width ((op #b01011)))
1357   (:printer reg/mem ((op '(#b1000111 #b000)) (width 1)))
1358   (:printer rex-reg/mem ((op '(#b10001111 #b000))))
1359   (:emitter
1360    (let ((size (operand-size dst)))
1361      (aver (not (eq size :byte)))
1362      (maybe-emit-operand-size-prefix segment size)
1363      (maybe-emit-rex-for-ea segment dst nil)     
1364      (cond ((register-p dst)
1365             (emit-byte-with-reg segment #b01011 (reg-tn-encoding dst)))
1366            (t
1367             (emit-byte segment #b10001111)
1368             (emit-ea segment dst #b000))))))
1369
1370 (define-instruction popa (segment)
1371   (:printer byte ((op #b01100001)))
1372   (:emitter
1373    (emit-byte segment #b01100001)))
1374
1375 (define-instruction xchg (segment operand1 operand2)
1376   ;; Register with accumulator.
1377   (:printer reg-no-width ((op #b10010)) '(:name :tab accum ", " reg))
1378   ;; Register/Memory with Register.
1379   (:printer reg-reg/mem ((op #b1000011)))
1380   (:emitter
1381    (let ((size (matching-operand-size operand1 operand2)))
1382      (maybe-emit-operand-size-prefix segment size)
1383      (labels ((xchg-acc-with-something (acc something)
1384                 (if (and (not (eq size :byte)) (register-p something))
1385                     (progn
1386                       (maybe-emit-rex-for-ea segment acc something)
1387                       (emit-byte-with-reg segment
1388                                           #b10010
1389                                           (reg-tn-encoding something)))
1390                     (xchg-reg-with-something acc something)))
1391               (xchg-reg-with-something (reg something)
1392                 (maybe-emit-rex-for-ea segment something reg)
1393                 (emit-byte segment (if (eq size :byte) #b10000110 #b10000111))
1394                 (emit-ea segment something (reg-tn-encoding reg))))
1395        (cond ((accumulator-p operand1)
1396               (xchg-acc-with-something operand1 operand2))
1397              ((accumulator-p operand2)
1398               (xchg-acc-with-something operand2 operand1))
1399              ((register-p operand1)
1400               (xchg-reg-with-something operand1 operand2))
1401              ((register-p operand2)
1402               (xchg-reg-with-something operand2 operand1))
1403              (t
1404               (error "bogus args to XCHG: ~S ~S" operand1 operand2)))))))
1405
1406 (define-instruction lea (segment dst src)
1407   (:printer rex-reg-reg/mem ((op #b10001101)))
1408   (:printer reg-reg/mem ((op #b1000110) (width 1)))
1409   (:emitter
1410    (aver (or (dword-reg-p dst) (qword-reg-p dst)))
1411    (maybe-emit-rex-for-ea segment src dst
1412                           :operand-size :qword)
1413    (emit-byte segment #b10001101)
1414    (emit-ea segment src (reg-tn-encoding dst))))
1415
1416 (define-instruction cmpxchg (segment dst src)
1417   ;; Register/Memory with Register.
1418   (:printer ext-reg-reg/mem ((op #b1011000)) '(:name :tab reg/mem ", " reg))
1419   (:emitter
1420    (aver (register-p src))
1421    (let ((size (matching-operand-size src dst)))
1422      (maybe-emit-operand-size-prefix segment size)
1423      (maybe-emit-rex-for-ea segment dst src)
1424      (emit-byte segment #b00001111)
1425      (emit-byte segment (if (eq size :byte) #b10110000 #b10110001))
1426      (emit-ea segment dst (reg-tn-encoding src)))))
1427
1428 \f
1429
1430 (define-instruction fs-segment-prefix (segment)
1431   (:emitter
1432    (emit-byte segment #x64)))
1433
1434 ;;;; flag control instructions
1435
1436 ;;; CLC -- Clear Carry Flag.
1437 (define-instruction clc (segment)
1438   (:printer byte ((op #b11111000)))
1439   (:emitter
1440    (emit-byte segment #b11111000)))
1441
1442 ;;; CLD -- Clear Direction Flag.
1443 (define-instruction cld (segment)
1444   (:printer byte ((op #b11111100)))
1445   (:emitter
1446    (emit-byte segment #b11111100)))
1447
1448 ;;; CLI -- Clear Iterrupt Enable Flag.
1449 (define-instruction cli (segment)
1450   (:printer byte ((op #b11111010)))
1451   (:emitter
1452    (emit-byte segment #b11111010)))
1453
1454 ;;; CMC -- Complement Carry Flag.
1455 (define-instruction cmc (segment)
1456   (:printer byte ((op #b11110101)))
1457   (:emitter
1458    (emit-byte segment #b11110101)))
1459
1460 ;;; LAHF -- Load AH into flags.
1461 (define-instruction lahf (segment)
1462   (:printer byte ((op #b10011111)))
1463   (:emitter
1464    (emit-byte segment #b10011111)))
1465
1466 ;;; POPF -- Pop flags.
1467 (define-instruction popf (segment)
1468   (:printer byte ((op #b10011101)))
1469   (:emitter
1470    (emit-byte segment #b10011101)))
1471
1472 ;;; PUSHF -- push flags.
1473 (define-instruction pushf (segment)
1474   (:printer byte ((op #b10011100)))
1475   (:emitter
1476    (emit-byte segment #b10011100)))
1477
1478 ;;; SAHF -- Store AH into flags.
1479 (define-instruction sahf (segment)
1480   (:printer byte ((op #b10011110)))
1481   (:emitter
1482    (emit-byte segment #b10011110)))
1483
1484 ;;; STC -- Set Carry Flag.
1485 (define-instruction stc (segment)
1486   (:printer byte ((op #b11111001)))
1487   (:emitter
1488    (emit-byte segment #b11111001)))
1489
1490 ;;; STD -- Set Direction Flag.
1491 (define-instruction std (segment)
1492   (:printer byte ((op #b11111101)))
1493   (:emitter
1494    (emit-byte segment #b11111101)))
1495
1496 ;;; STI -- Set Interrupt Enable Flag.
1497 (define-instruction sti (segment)
1498   (:printer byte ((op #b11111011)))
1499   (:emitter
1500    (emit-byte segment #b11111011)))
1501 \f
1502 ;;;; arithmetic
1503
1504 (defun emit-random-arith-inst (name segment dst src opcode
1505                                     &optional allow-constants)
1506   (let ((size (matching-operand-size dst src)))
1507     (maybe-emit-operand-size-prefix segment size)
1508     (cond
1509      ((integerp src)
1510       (cond ((and (not (eq size :byte)) (<= -128 src 127))
1511              (maybe-emit-rex-for-ea segment dst nil)
1512              (emit-byte segment #b10000011)
1513              (emit-ea segment dst opcode allow-constants)
1514              (emit-byte segment src))
1515             ((accumulator-p dst)  
1516              (maybe-emit-rex-for-ea segment dst nil)
1517              (emit-byte segment
1518                         (dpb opcode
1519                              (byte 3 3)
1520                              (if (eq size :byte)
1521                                  #b00000100
1522                                  #b00000101)))
1523              (emit-sized-immediate segment size src))
1524             (t
1525              (maybe-emit-rex-for-ea segment dst nil)
1526              (emit-byte segment (if (eq size :byte) #b10000000 #b10000001))
1527              (emit-ea segment dst opcode allow-constants)
1528              (emit-sized-immediate segment size src))))
1529      ((register-p src)
1530       (maybe-emit-rex-for-ea segment dst src)
1531       (emit-byte segment
1532                  (dpb opcode
1533                       (byte 3 3)
1534                       (if (eq size :byte) #b00000000 #b00000001)))
1535       (emit-ea segment dst (reg-tn-encoding src) allow-constants))
1536      ((register-p dst)
1537       (maybe-emit-rex-for-ea segment src dst)
1538       (emit-byte segment
1539                  (dpb opcode
1540                       (byte 3 3)
1541                       (if (eq size :byte) #b00000010 #b00000011)))
1542       (emit-ea segment src (reg-tn-encoding dst) allow-constants))
1543      (t
1544       (error "bogus operands to ~A" name)))))
1545
1546 (eval-when (:compile-toplevel :execute)
1547   (defun arith-inst-printer-list (subop)
1548     `((accum-imm ((op ,(dpb subop (byte 3 2) #b0000010))))
1549       (rex-accum-imm ((op ,(dpb subop (byte 3 2) #b0000010))))
1550       (reg/mem-imm ((op (#b1000000 ,subop))))
1551       (rex-reg/mem-imm ((op (#b10000001 ,subop))))
1552       (reg/mem-imm ((op (#b1000001 ,subop))
1553                     (imm nil :type signed-imm-byte)))
1554       (rex-reg/mem-imm ((op (#b10000011 ,subop))
1555                     (imm nil :type signed-imm-byte)))
1556       (reg-reg/mem-dir ((op ,(dpb subop (byte 3 1) #b000000))))
1557       (rex-reg-reg/mem-dir ((op ,(dpb subop (byte 3 1) #b000000))))))
1558   )
1559
1560 (define-instruction add (segment dst src)
1561   (:printer-list (arith-inst-printer-list #b000))
1562   (:emitter (emit-random-arith-inst "ADD" segment dst src #b000)))
1563
1564 (define-instruction adc (segment dst src)
1565   (:printer-list (arith-inst-printer-list #b010))
1566   (:emitter (emit-random-arith-inst "ADC" segment dst src #b010)))
1567
1568 (define-instruction sub (segment dst src)
1569   (:printer-list (arith-inst-printer-list #b101))
1570   (:emitter (emit-random-arith-inst "SUB" segment dst src #b101)))
1571
1572 (define-instruction sbb (segment dst src)
1573   (:printer-list (arith-inst-printer-list #b011))
1574   (:emitter (emit-random-arith-inst "SBB" segment dst src #b011)))
1575
1576 (define-instruction cmp (segment dst src)
1577   (:printer-list (arith-inst-printer-list #b111))
1578   (:emitter (emit-random-arith-inst "CMP" segment dst src #b111 t)))
1579
1580 (define-instruction inc (segment dst)
1581   ;; Register
1582   (:printer modrm-reg-no-width ((modrm-reg #b000)))
1583   ;; Register/Memory
1584   ;; (:printer rex-reg/mem ((op '(#b11111111 #b001))))
1585   (:printer reg/mem ((op '(#b1111111 #b000))))
1586   (:emitter
1587    (let ((size (operand-size dst)))
1588      (maybe-emit-operand-size-prefix segment size)
1589      (cond #+nil ; these opcodes become REX prefixes in x86-64
1590            ((and (not (eq size :byte)) (register-p dst))
1591             (emit-byte-with-reg segment #b01000 (reg-tn-encoding dst)))
1592            (t
1593             (maybe-emit-rex-for-ea segment dst nil)
1594             (emit-byte segment (if (eq size :byte) #b11111110 #b11111111))
1595             (emit-ea segment dst #b000))))))
1596
1597 (define-instruction dec (segment dst)
1598   ;; Register.
1599   (:printer modrm-reg-no-width ((modrm-reg #b001)))
1600   ;; Register/Memory
1601   (:printer reg/mem ((op '(#b1111111 #b001))))
1602   (:emitter
1603    (let ((size (operand-size dst)))
1604      (maybe-emit-operand-size-prefix segment size)
1605      (cond #+nil
1606            ((and (not (eq size :byte)) (register-p dst))
1607             (emit-byte-with-reg segment #b01001 (reg-tn-encoding dst)))
1608            (t
1609             (maybe-emit-rex-for-ea segment dst nil)
1610             (emit-byte segment (if (eq size :byte) #b11111110 #b11111111))
1611             (emit-ea segment dst #b001))))))
1612
1613 (define-instruction neg (segment dst)
1614   (:printer reg/mem ((op '(#b1111011 #b011))))
1615   (:emitter
1616    (let ((size (operand-size dst)))
1617      (maybe-emit-operand-size-prefix segment size)
1618      (maybe-emit-rex-for-ea segment dst nil)
1619      (emit-byte segment (if (eq size :byte) #b11110110 #b11110111))
1620      (emit-ea segment dst #b011))))
1621
1622 (define-instruction mul (segment dst src)
1623   (:printer accum-reg/mem ((op '(#b1111011 #b100))))
1624   (:emitter
1625    (let ((size (matching-operand-size dst src)))
1626      (aver (accumulator-p dst))
1627      (maybe-emit-operand-size-prefix segment size)
1628      (maybe-emit-rex-for-ea segment src nil)
1629      (emit-byte segment (if (eq size :byte) #b11110110 #b11110111))
1630      (emit-ea segment src #b100))))
1631
1632 (define-instruction imul (segment dst &optional src1 src2)
1633   (:printer accum-reg/mem ((op '(#b1111011 #b101))))
1634   (:printer ext-reg-reg/mem ((op #b1010111)))
1635   (:printer reg-reg/mem ((op #b0110100) (width 1) (imm nil :type 'imm-word))
1636             '(:name :tab reg ", " reg/mem ", " imm))
1637   (:printer reg-reg/mem ((op #b0110101) (width 1)
1638                          (imm nil :type 'signed-imm-byte))
1639             '(:name :tab reg ", " reg/mem ", " imm))
1640   (:emitter
1641    (flet ((r/m-with-immed-to-reg (reg r/m immed)
1642             (let* ((size (matching-operand-size reg r/m))
1643                    (sx (and (not (eq size :byte)) (<= -128 immed 127))))
1644               (maybe-emit-operand-size-prefix segment size)
1645               (maybe-emit-rex-for-ea segment r/m reg)
1646               (emit-byte segment (if sx #b01101011 #b01101001))
1647               (emit-ea segment r/m (reg-tn-encoding reg))
1648               (if sx
1649                   (emit-byte segment immed)
1650                   (emit-sized-immediate segment size immed)))))
1651      (cond (src2
1652             (r/m-with-immed-to-reg dst src1 src2))
1653            (src1
1654             (if (integerp src1)
1655                 (r/m-with-immed-to-reg dst dst src1)
1656                 (let ((size (matching-operand-size dst src1)))
1657                   (maybe-emit-operand-size-prefix segment size)
1658                   (maybe-emit-rex-for-ea segment src1 dst)
1659                   (emit-byte segment #b00001111)
1660                   (emit-byte segment #b10101111)
1661                   (emit-ea segment src1 (reg-tn-encoding dst)))))
1662            (t
1663             (let ((size (operand-size dst)))
1664               (maybe-emit-operand-size-prefix segment size)
1665               (maybe-emit-rex-for-ea segment dst nil)
1666               (emit-byte segment (if (eq size :byte) #b11110110 #b11110111))
1667               (emit-ea segment dst #b101)))))))
1668
1669 (define-instruction div (segment dst src)
1670   (:printer accum-reg/mem ((op '(#b1111011 #b110))))
1671   (:emitter
1672    (let ((size (matching-operand-size dst src)))
1673      (aver (accumulator-p dst))
1674      (maybe-emit-operand-size-prefix segment size)
1675      (maybe-emit-rex-for-ea segment src nil)
1676      (emit-byte segment (if (eq size :byte) #b11110110 #b11110111))
1677      (emit-ea segment src #b110))))
1678
1679 (define-instruction idiv (segment dst src)
1680   (:printer accum-reg/mem ((op '(#b1111011 #b111))))
1681   (:emitter
1682    (let ((size (matching-operand-size dst src)))
1683      (aver (accumulator-p dst))
1684      (maybe-emit-operand-size-prefix segment size)
1685      (maybe-emit-rex-for-ea segment src nil)
1686      (emit-byte segment (if (eq size :byte) #b11110110 #b11110111))
1687      (emit-ea segment src #b111))))
1688
1689 (define-instruction bswap (segment dst)
1690   (:printer ext-reg-no-width ((op #b11001)))
1691   (:emitter
1692    (let ((size (operand-size dst)))
1693      (maybe-emit-rex-prefix segment size nil nil dst)
1694      (emit-byte segment #x0f)
1695      (emit-byte-with-reg segment #b11001 (reg-tn-encoding dst)))))
1696
1697 ;;; CBW -- Convert Byte to Word. AX <- sign_xtnd(AL)
1698 (define-instruction cbw (segment)
1699   (:emitter
1700    (maybe-emit-operand-size-prefix segment :word)
1701    (emit-byte segment #b10011000)))
1702
1703 ;;; CWDE -- Convert Word To Double Word Extened. EAX <- sign_xtnd(AX)
1704 (define-instruction cwde (segment)
1705   (:emitter
1706    (maybe-emit-operand-size-prefix segment :dword)
1707    (emit-byte segment #b10011000)))
1708
1709 ;;; CWD -- Convert Word to Double Word. DX:AX <- sign_xtnd(AX)
1710 (define-instruction cwd (segment)
1711   (:emitter
1712    (maybe-emit-operand-size-prefix segment :word)
1713    (emit-byte segment #b10011001)))
1714
1715 ;;; CDQ -- Convert Double Word to Quad Word. EDX:EAX <- sign_xtnd(EAX)
1716 (define-instruction cdq (segment)
1717   (:printer byte ((op #b10011001)))
1718   (:emitter
1719    (maybe-emit-operand-size-prefix segment :dword)
1720    (emit-byte segment #b10011001)))
1721
1722 ;;; CQO -- Convert Quad or Octaword. RDX:RAX <- sign_xtnd(RAX)
1723 (define-instruction cqo (segment)
1724   (:emitter
1725    (maybe-emit-rex-prefix segment :qword nil nil nil)
1726    (emit-byte segment #b10011001)))
1727
1728 (define-instruction xadd (segment dst src)
1729   ;; Register/Memory with Register.
1730   (:printer ext-reg-reg/mem ((op #b1100000)) '(:name :tab reg/mem ", " reg))
1731   (:emitter
1732    (aver (register-p src))
1733    (let ((size (matching-operand-size src dst)))
1734      (maybe-emit-operand-size-prefix segment size)
1735      (maybe-emit-rex-for-ea segment dst src)
1736      (emit-byte segment #b00001111)
1737      (emit-byte segment (if (eq size :byte) #b11000000 #b11000001))
1738      (emit-ea segment dst (reg-tn-encoding src)))))
1739
1740 \f
1741 ;;;; logic
1742
1743 (defun emit-shift-inst (segment dst amount opcode)
1744   (let ((size (operand-size dst)))
1745     (maybe-emit-operand-size-prefix segment size)
1746     (multiple-value-bind (major-opcode immed)
1747         (case amount
1748           (:cl (values #b11010010 nil))
1749           (1 (values #b11010000 nil))
1750           (t (values #b11000000 t)))
1751       (maybe-emit-rex-for-ea segment dst nil)
1752       (emit-byte segment
1753                  (if (eq size :byte) major-opcode (logior major-opcode 1)))
1754       (emit-ea segment dst opcode)
1755       (when immed
1756         (emit-byte segment amount)))))
1757
1758 (eval-when (:compile-toplevel :execute)
1759   (defun shift-inst-printer-list (subop)
1760     `((reg/mem ((op (#b1101000 ,subop)))
1761                (:name :tab reg/mem ", 1"))
1762       (rex-reg/mem ((op (#b1101000 ,subop)))
1763                    (:name :tab reg/mem ", 1"))
1764       (reg/mem ((op (#b1101001 ,subop)))
1765                (:name :tab reg/mem ", " 'cl))
1766       (rex-reg/mem ((op (#b1101001 ,subop)))
1767                (:name :tab reg/mem ", " 'cl))
1768       (reg/mem-imm ((op (#b1100000 ,subop))
1769                     (imm nil :type signed-imm-byte)))
1770       (rex-reg/mem-imm ((op (#b11000001 ,subop))
1771                     (imm nil :type signed-imm-byte))))))
1772
1773 (define-instruction rol (segment dst amount)
1774   (:printer-list
1775    (shift-inst-printer-list #b000))
1776   (:emitter
1777    (emit-shift-inst segment dst amount #b000)))
1778
1779 (define-instruction ror (segment dst amount)
1780   (:printer-list
1781    (shift-inst-printer-list #b001))
1782   (:emitter
1783    (emit-shift-inst segment dst amount #b001)))
1784
1785 (define-instruction rcl (segment dst amount)
1786   (:printer-list
1787    (shift-inst-printer-list #b010))
1788   (:emitter
1789    (emit-shift-inst segment dst amount #b010)))
1790
1791 (define-instruction rcr (segment dst amount)
1792   (:printer-list
1793    (shift-inst-printer-list #b011))
1794   (:emitter
1795    (emit-shift-inst segment dst amount #b011)))
1796
1797 (define-instruction shl (segment dst amount)
1798   (:printer-list
1799    (shift-inst-printer-list #b100))
1800   (:emitter
1801    (emit-shift-inst segment dst amount #b100)))
1802
1803 (define-instruction shr (segment dst amount)
1804   (:printer-list
1805    (shift-inst-printer-list #b101))
1806   (:emitter
1807    (emit-shift-inst segment dst amount #b101)))
1808
1809 (define-instruction sar (segment dst amount)
1810   (:printer-list
1811    (shift-inst-printer-list #b111))
1812   (:emitter
1813    (emit-shift-inst segment dst amount #b111)))
1814
1815 (defun emit-double-shift (segment opcode dst src amt)
1816   (let ((size (matching-operand-size dst src)))
1817     (when (eq size :byte)
1818       (error "Double shifts can only be used with words."))
1819     (maybe-emit-operand-size-prefix segment size)
1820     (maybe-emit-rex-for-ea segment dst src)
1821     (emit-byte segment #b00001111)
1822     (emit-byte segment (dpb opcode (byte 1 3)
1823                             (if (eq amt :cl) #b10100101 #b10100100)))
1824     (emit-ea segment dst (reg-tn-encoding src)) 
1825     (unless (eq amt :cl)
1826       (emit-byte segment amt))))
1827
1828 (eval-when (:compile-toplevel :execute)
1829   (defun double-shift-inst-printer-list (op)
1830     `(#+nil
1831       (ext-reg-reg/mem-imm ((op ,(logior op #b100))
1832                             (imm nil :type signed-imm-byte)))
1833       (ext-reg-reg/mem ((op ,(logior op #b101)))
1834          (:name :tab reg/mem ", " 'cl)))))
1835
1836 (define-instruction shld (segment dst src amt)
1837   (:declare (type (or (member :cl) (mod 32)) amt))
1838   (:printer-list (double-shift-inst-printer-list #b10100000))
1839   (:emitter
1840    (emit-double-shift segment #b0 dst src amt)))
1841
1842 (define-instruction shrd (segment dst src amt)
1843   (:declare (type (or (member :cl) (mod 32)) amt))
1844   (:printer-list (double-shift-inst-printer-list #b10101000))
1845   (:emitter
1846    (emit-double-shift segment #b1 dst src amt)))
1847
1848 (define-instruction and (segment dst src)
1849   (:printer-list
1850    (arith-inst-printer-list #b100))
1851   (:emitter
1852    (emit-random-arith-inst "AND" segment dst src #b100)))
1853
1854 (define-instruction test (segment this that)
1855   (:printer accum-imm ((op #b1010100)))
1856   (:printer rex-accum-imm ((op #b1010100)))
1857   (:printer reg/mem-imm ((op '(#b1111011 #b000))))
1858   (:printer rex-reg/mem-imm ((op '(#b11110111 #b000))))
1859   (:printer reg-reg/mem ((op #b1000010)))
1860   (:printer rex-reg-reg/mem ((op #b10000101)))
1861   (:emitter
1862    (let ((size (matching-operand-size this that)))
1863      (maybe-emit-operand-size-prefix segment size)
1864      (flet ((test-immed-and-something (immed something)
1865               (cond ((accumulator-p something)
1866                      (maybe-emit-rex-for-ea segment something nil)
1867                      (emit-byte segment
1868                                 (if (eq size :byte) #b10101000 #b10101001))
1869                      (emit-sized-immediate segment size immed))
1870                     (t
1871                      (maybe-emit-rex-for-ea segment something nil)
1872                      (emit-byte segment
1873                                 (if (eq size :byte) #b11110110 #b11110111))
1874                      (emit-ea segment something #b000)
1875                      (emit-sized-immediate segment size immed))))
1876             (test-reg-and-something (reg something)
1877               (maybe-emit-rex-for-ea segment something reg)
1878               (emit-byte segment (if (eq size :byte) #b10000100 #b10000101))
1879               (emit-ea segment something (reg-tn-encoding reg))))
1880        (cond ((integerp that)
1881               (test-immed-and-something that this))
1882              ((integerp this)
1883               (test-immed-and-something this that))
1884              ((register-p this)
1885               (test-reg-and-something this that))
1886              ((register-p that)
1887               (test-reg-and-something that this))
1888              (t
1889               (error "bogus operands for TEST: ~S and ~S" this that)))))))
1890
1891 (define-instruction or (segment dst src)
1892   (:printer-list
1893    (arith-inst-printer-list #b001))
1894   (:emitter
1895    (emit-random-arith-inst "OR" segment dst src #b001)))
1896
1897 (define-instruction xor (segment dst src)
1898   (:printer-list
1899    (arith-inst-printer-list #b110))
1900   (:emitter
1901    (emit-random-arith-inst "XOR" segment dst src #b110)))
1902
1903 (define-instruction not (segment dst)
1904   (:printer reg/mem ((op '(#b1111011 #b010))))
1905   (:emitter
1906    (let ((size (operand-size dst)))
1907      (maybe-emit-operand-size-prefix segment size)
1908      (maybe-emit-rex-for-ea segment dst nil)
1909      (emit-byte segment (if (eq size :byte) #b11110110 #b11110111))
1910      (emit-ea segment dst #b010))))
1911 \f
1912 ;;;; string manipulation
1913
1914 (define-instruction cmps (segment size)
1915   (:printer string-op ((op #b1010011)))
1916   (:printer rex-string-op ((op #b1010011)))
1917   (:emitter
1918    (maybe-emit-operand-size-prefix segment size)
1919    (maybe-emit-rex-prefix segment size nil nil nil)
1920    (emit-byte segment (if (eq size :byte) #b10100110 #b10100111))))
1921
1922 (define-instruction ins (segment acc)
1923   (:printer string-op ((op #b0110110)))
1924   (:printer rex-string-op ((op #b0110110)))
1925   (:emitter
1926    (let ((size (operand-size acc)))
1927      (aver (accumulator-p acc))
1928      (maybe-emit-operand-size-prefix segment size)
1929      (maybe-emit-rex-prefix segment size nil nil nil)
1930      (emit-byte segment (if (eq size :byte) #b01101100 #b01101101)))))
1931
1932 (define-instruction lods (segment acc)
1933   (:printer string-op ((op #b1010110)))
1934   (:printer rex-string-op ((op #b1010110)))
1935   (:emitter
1936    (let ((size (operand-size acc)))
1937      (aver (accumulator-p acc))
1938      (maybe-emit-operand-size-prefix segment size)
1939      (maybe-emit-rex-prefix segment size nil nil nil)
1940      (emit-byte segment (if (eq size :byte) #b10101100 #b10101101)))))
1941
1942 (define-instruction movs (segment size)
1943   (:printer string-op ((op #b1010010)))
1944   (:printer rex-string-op ((op #b1010010)))
1945   (:emitter
1946    (maybe-emit-operand-size-prefix segment size)
1947    (maybe-emit-rex-prefix segment size nil nil nil)
1948    (emit-byte segment (if (eq size :byte) #b10100100 #b10100101))))
1949
1950 (define-instruction outs (segment acc)
1951   (:printer string-op ((op #b0110111)))
1952   (:printer rex-string-op ((op #b0110111)))
1953   (:emitter
1954    (let ((size (operand-size acc)))
1955      (aver (accumulator-p acc))
1956      (maybe-emit-operand-size-prefix segment size)
1957      (maybe-emit-rex-prefix segment size nil nil nil)
1958      (emit-byte segment (if (eq size :byte) #b01101110 #b01101111)))))
1959
1960 (define-instruction scas (segment acc)
1961   (:printer string-op ((op #b1010111)))
1962   (:printer rex-string-op ((op #b1010111)))
1963   (:emitter
1964    (let ((size (operand-size acc)))
1965      (aver (accumulator-p acc))
1966      (maybe-emit-operand-size-prefix segment size)
1967      (maybe-emit-rex-prefix segment size nil nil nil)
1968      (emit-byte segment (if (eq size :byte) #b10101110 #b10101111)))))
1969
1970 (define-instruction stos (segment acc)
1971   (:printer string-op ((op #b1010101)))
1972   (:printer rex-string-op ((op #b1010101)))
1973   (:emitter
1974    (let ((size (operand-size acc)))
1975      (aver (accumulator-p acc))
1976      (maybe-emit-operand-size-prefix segment size)
1977      (maybe-emit-rex-prefix segment size nil nil nil)
1978      (emit-byte segment (if (eq size :byte) #b10101010 #b10101011)))))
1979
1980 (define-instruction xlat (segment)
1981   (:printer byte ((op #b11010111)))
1982   (:emitter
1983    (emit-byte segment #b11010111)))
1984
1985 (define-instruction rep (segment)
1986   (:emitter
1987    (emit-byte segment #b11110010)))
1988
1989 (define-instruction repe (segment)
1990   (:printer byte ((op #b11110011)))
1991   (:emitter
1992    (emit-byte segment #b11110011)))
1993
1994 (define-instruction repne (segment)
1995   (:printer byte ((op #b11110010)))
1996   (:emitter
1997    (emit-byte segment #b11110010)))
1998
1999 \f
2000 ;;;; bit manipulation
2001
2002 (define-instruction bsf (segment dst src)
2003   (:printer ext-reg-reg/mem ((op #b1011110) (width 0)))
2004   (:emitter
2005    (let ((size (matching-operand-size dst src)))
2006      (when (eq size :byte)
2007        (error "can't scan bytes: ~S" src))
2008      (maybe-emit-operand-size-prefix segment size)
2009      (maybe-emit-rex-for-ea segment src dst)
2010      (emit-byte segment #b00001111)
2011      (emit-byte segment #b10111100)
2012      (emit-ea segment src (reg-tn-encoding dst)))))
2013
2014 (define-instruction bsr (segment dst src)
2015   (:printer ext-reg-reg/mem ((op #b1011110) (width 1)))
2016   (:emitter
2017    (let ((size (matching-operand-size dst src)))
2018      (when (eq size :byte)
2019        (error "can't scan bytes: ~S" src))
2020      (maybe-emit-operand-size-prefix segment size)
2021      (maybe-emit-rex-for-ea segment src dst)
2022      (emit-byte segment #b00001111)
2023      (emit-byte segment #b10111101)
2024      (emit-ea segment src (reg-tn-encoding dst)))))
2025
2026 (defun emit-bit-test-and-mumble (segment src index opcode)
2027   (let ((size (operand-size src)))
2028     (when (eq size :byte)
2029       (error "can't scan bytes: ~S" src))
2030     (maybe-emit-operand-size-prefix segment size)
2031     (cond ((integerp index)
2032            (maybe-emit-rex-for-ea segment src nil)
2033            (emit-byte segment #b00001111)
2034            (emit-byte segment #b10111010)
2035            (emit-ea segment src opcode)
2036            (emit-byte segment index))
2037           (t
2038            (maybe-emit-rex-for-ea segment src index)
2039            (emit-byte segment #b00001111)
2040            (emit-byte segment (dpb opcode (byte 3 3) #b10000011))
2041            (emit-ea segment src (reg-tn-encoding index))))))
2042
2043 (eval-when (:compile-toplevel :execute)
2044   (defun bit-test-inst-printer-list (subop)
2045     `((ext-reg/mem-imm ((op (#b1011101 ,subop))
2046                         (reg/mem nil :type word-reg/mem)
2047                         (imm nil :type imm-data)
2048                         (width 0)))
2049       (ext-reg-reg/mem ((op ,(dpb subop (byte 3 2) #b1000001))
2050                         (width 1))
2051                        (:name :tab reg/mem ", " reg)))))
2052
2053 (define-instruction bt (segment src index)
2054   (:printer-list (bit-test-inst-printer-list #b100))
2055   (:emitter
2056    (emit-bit-test-and-mumble segment src index #b100)))
2057
2058 (define-instruction btc (segment src index)
2059   (:printer-list (bit-test-inst-printer-list #b111))
2060   (:emitter
2061    (emit-bit-test-and-mumble segment src index #b111)))
2062
2063 (define-instruction btr (segment src index)
2064   (:printer-list (bit-test-inst-printer-list #b110))
2065   (:emitter
2066    (emit-bit-test-and-mumble segment src index #b110)))
2067
2068 (define-instruction bts (segment src index)
2069   (:printer-list (bit-test-inst-printer-list #b101))
2070   (:emitter
2071    (emit-bit-test-and-mumble segment src index #b101)))
2072
2073 \f
2074 ;;;; control transfer
2075
2076 (define-instruction call (segment where)
2077   (:printer near-jump ((op #b11101000)))
2078   (:printer reg/mem ((op '(#b1111111 #b010)) (width 1)))
2079   (:emitter
2080    (typecase where
2081      (label
2082       (maybe-emit-rex-for-ea segment where nil)
2083       (emit-byte segment #b11101000) ; 32 bit relative
2084       (emit-back-patch segment
2085                        4
2086                        (lambda (segment posn)
2087                          (emit-dword segment
2088                                      (- (label-position where)
2089                                         (+ posn 4))))))
2090      (fixup
2091       (maybe-emit-rex-for-ea segment where nil)
2092       (emit-byte segment #b11101000)
2093       (emit-relative-fixup segment where))
2094      (t
2095       (maybe-emit-rex-for-ea segment where nil)
2096       (emit-byte segment #b11111111)
2097       (emit-ea segment where #b010)))))
2098
2099 (defun emit-byte-displacement-backpatch (segment target)
2100   (emit-back-patch segment
2101                    1
2102                    (lambda (segment posn)
2103                      (let ((disp (- (label-position target) (1+ posn))))
2104                        (aver (<= -128 disp 127))
2105                        (emit-byte segment disp)))))
2106
2107 (define-instruction jmp (segment cond &optional where)
2108   ;; conditional jumps
2109   (:printer short-cond-jump ((op #b0111)) '('j cc :tab label))
2110   (:printer near-cond-jump () '('j cc :tab label))
2111   ;; unconditional jumps
2112   (:printer short-jump ((op #b1011)))
2113   (:printer near-jump ((op #b11101001)) )
2114   (:printer reg/mem ((op '(#b1111111 #b100)) (width 1)))
2115   (:emitter
2116    (cond (where
2117           (emit-chooser
2118            segment 6 2
2119            (lambda (segment posn delta-if-after)
2120              (let ((disp (- (label-position where posn delta-if-after)
2121                             (+ posn 2))))
2122                (when (<= -128 disp 127)
2123                  (emit-byte segment
2124                             (dpb (conditional-opcode cond)
2125                                  (byte 4 0)
2126                                  #b01110000))
2127                  (emit-byte-displacement-backpatch segment where)
2128                  t)))
2129            (lambda (segment posn)
2130              (let ((disp (- (label-position where) (+ posn 6))))
2131                (emit-byte segment #b00001111)
2132                (emit-byte segment
2133                           (dpb (conditional-opcode cond)
2134                                (byte 4 0)
2135                                #b10000000))
2136                (emit-dword segment disp)))))
2137          ((label-p (setq where cond))
2138           (emit-chooser
2139            segment 5 0
2140            (lambda (segment posn delta-if-after)
2141              (let ((disp (- (label-position where posn delta-if-after)
2142                             (+ posn 2))))
2143                (when (<= -128 disp 127)
2144                  (emit-byte segment #b11101011)
2145                  (emit-byte-displacement-backpatch segment where)
2146                  t)))
2147            (lambda (segment posn)
2148              (let ((disp (- (label-position where) (+ posn 5))))
2149                (emit-byte segment #b11101001)
2150                (emit-dword segment disp)))))
2151          ((fixup-p where)
2152           (emit-byte segment #b11101001)
2153           (emit-relative-fixup segment where))
2154          (t
2155           (unless (or (ea-p where) (tn-p where))
2156                   (error "don't know what to do with ~A" where))
2157           (maybe-emit-rex-for-ea segment where nil)
2158           (emit-byte segment #b11111111)
2159           (emit-ea segment where #b100)))))
2160
2161 (define-instruction jmp-short (segment label)
2162   (:emitter
2163    (emit-byte segment #b11101011)
2164    (emit-byte-displacement-backpatch segment label)))
2165
2166 (define-instruction ret (segment &optional stack-delta)
2167   (:printer byte ((op #b11000011)))
2168   (:printer byte ((op #b11000010) (imm nil :type 'imm-word-16))
2169             '(:name :tab imm))
2170   (:emitter
2171    (cond (stack-delta
2172           (emit-byte segment #b11000010)
2173           (emit-word segment stack-delta))
2174          (t
2175           (emit-byte segment #b11000011)))))
2176
2177 (define-instruction jecxz (segment target)
2178   (:printer short-jump ((op #b0011)))
2179   (:emitter
2180    (emit-byte segment #b11100011)
2181    (emit-byte-displacement-backpatch segment target)))
2182
2183 (define-instruction loop (segment target)
2184   (:printer short-jump ((op #b0010)))
2185   (:emitter
2186    (emit-byte segment #b11100010)       ; pfw this was 11100011, or jecxz!!!!
2187    (emit-byte-displacement-backpatch segment target)))
2188
2189 (define-instruction loopz (segment target)
2190   (:printer short-jump ((op #b0001)))
2191   (:emitter
2192    (emit-byte segment #b11100001)
2193    (emit-byte-displacement-backpatch segment target)))
2194
2195 (define-instruction loopnz (segment target)
2196   (:printer short-jump ((op #b0000)))
2197   (:emitter
2198    (emit-byte segment #b11100000)
2199    (emit-byte-displacement-backpatch segment target)))
2200 \f
2201 ;;;; conditional move
2202 (define-instruction cmov (segment cond dst src)
2203   (:printer cond-move ())
2204   (:emitter
2205    (aver (register-p dst))
2206    (let ((size (matching-operand-size dst src)))
2207      (aver (or (eq size :word) (eq size :dword) (eq size :qword) ))
2208      (maybe-emit-operand-size-prefix segment size))
2209    (maybe-emit-rex-for-ea segment src dst)
2210    (emit-byte segment #b00001111)
2211    (emit-byte segment (dpb (conditional-opcode cond) (byte 4 0) #b01000000))
2212    (emit-ea segment src (reg-tn-encoding dst))))
2213
2214 ;;;; conditional byte set
2215
2216 (define-instruction set (segment dst cond)
2217   (:printer cond-set ())
2218   (:emitter
2219    (maybe-emit-rex-for-ea segment dst nil)
2220    (emit-byte segment #b00001111)
2221    (emit-byte segment (dpb (conditional-opcode cond) (byte 4 0) #b10010000))
2222    (emit-ea segment dst #b000)))
2223 \f
2224 ;;;; enter/leave
2225
2226 (define-instruction enter (segment disp &optional (level 0))
2227   (:declare (type (unsigned-byte 16) disp)
2228             (type (unsigned-byte 8) level))
2229   (:printer enter-format ((op #b11001000)))
2230   (:emitter
2231    (emit-byte segment #b11001000)
2232    (emit-word segment disp)
2233    (emit-byte segment level)))
2234
2235 (define-instruction leave (segment)
2236   (:printer byte ((op #b11001001)))
2237   (:emitter
2238    (emit-byte segment #b11001001)))
2239 \f
2240 ;;;; interrupt instructions
2241
2242 (defun snarf-error-junk (sap offset &optional length-only)
2243   (let* ((length (sb!sys:sap-ref-8 sap offset))
2244          (vector (make-array length :element-type '(unsigned-byte 8))))
2245     (declare (type sb!sys:system-area-pointer sap)
2246              (type (unsigned-byte 8) length)
2247              (type (simple-array (unsigned-byte 8) (*)) vector))
2248     (cond (length-only
2249            (values 0 (1+ length) nil nil))
2250           (t
2251            (sb!kernel:copy-from-system-area sap (* n-byte-bits (1+ offset))
2252                                             vector (* n-word-bits
2253                                                       vector-data-offset)
2254                                             (* length n-byte-bits))
2255            (collect ((sc-offsets)
2256                      (lengths))
2257              (lengths 1)                ; the length byte
2258              (let* ((index 0)
2259                     (error-number (sb!c:read-var-integer vector index)))
2260                (lengths index)
2261                (loop
2262                  (when (>= index length)
2263                    (return))
2264                  (let ((old-index index))
2265                    (sc-offsets (sb!c:read-var-integer vector index))
2266                    (lengths (- index old-index))))
2267                (values error-number
2268                        (1+ length)
2269                        (sc-offsets)
2270                        (lengths))))))))
2271
2272 #|
2273 (defmacro break-cases (breaknum &body cases)
2274   (let ((bn-temp (gensym)))
2275     (collect ((clauses))
2276       (dolist (case cases)
2277         (clauses `((= ,bn-temp ,(car case)) ,@(cdr case))))
2278       `(let ((,bn-temp ,breaknum))
2279          (cond ,@(clauses))))))
2280 |#
2281
2282 (defun break-control (chunk inst stream dstate)
2283   (declare (ignore inst))
2284   (flet ((nt (x) (if stream (sb!disassem:note x dstate))))
2285     ;; FIXME: Make sure that BYTE-IMM-CODE is defined. The genesis
2286     ;; map has it undefined; and it should be easier to look in the target
2287     ;; Lisp (with (DESCRIBE 'BYTE-IMM-CODE)) than to definitively deduce
2288     ;; from first principles whether it's defined in some way that genesis
2289     ;; can't grok.
2290     (case (byte-imm-code chunk dstate)
2291       (#.error-trap
2292        (nt "error trap")
2293        (sb!disassem:handle-break-args #'snarf-error-junk stream dstate))
2294       (#.cerror-trap
2295        (nt "cerror trap")
2296        (sb!disassem:handle-break-args #'snarf-error-junk stream dstate))
2297       (#.breakpoint-trap
2298        (nt "breakpoint trap"))
2299       (#.pending-interrupt-trap
2300        (nt "pending interrupt trap"))
2301       (#.halt-trap
2302        (nt "halt trap"))
2303       (#.fun-end-breakpoint-trap
2304        (nt "function end breakpoint trap")))))
2305
2306 (define-instruction break (segment code)
2307   (:declare (type (unsigned-byte 8) code))
2308   (:printer byte-imm ((op #b11001100)) '(:name :tab code)
2309             :control #'break-control)
2310   (:emitter
2311    (emit-byte segment #b11001100)
2312    (emit-byte segment code)))
2313
2314 (define-instruction int (segment number)
2315   (:declare (type (unsigned-byte 8) number))
2316   (:printer byte-imm ((op #b11001101)))
2317   (:emitter
2318    (etypecase number
2319      ((member 3)
2320       (emit-byte segment #b11001100))
2321      ((unsigned-byte 8)
2322       (emit-byte segment #b11001101)
2323       (emit-byte segment number)))))
2324
2325 (define-instruction into (segment)
2326   (:printer byte ((op #b11001110)))
2327   (:emitter
2328    (emit-byte segment #b11001110)))
2329
2330 (define-instruction bound (segment reg bounds)
2331   (:emitter
2332    (let ((size (matching-operand-size reg bounds)))
2333      (when (eq size :byte)
2334        (error "can't bounds-test bytes: ~S" reg))
2335      (maybe-emit-operand-size-prefix segment size)
2336      (maybe-emit-rex-for-ea segment bounds reg)
2337      (emit-byte segment #b01100010)
2338      (emit-ea segment bounds (reg-tn-encoding reg)))))
2339
2340 (define-instruction iret (segment)
2341   (:printer byte ((op #b11001111)))
2342   (:emitter
2343    (emit-byte segment #b11001111)))
2344 \f
2345 ;;;; processor control
2346
2347 (define-instruction hlt (segment)
2348   (:printer byte ((op #b11110100)))
2349   (:emitter
2350    (emit-byte segment #b11110100)))
2351
2352 (define-instruction nop (segment)
2353   (:printer byte ((op #b10010000)))
2354   (:emitter
2355    (emit-byte segment #b10010000)))
2356
2357 (define-instruction wait (segment)
2358   (:printer byte ((op #b10011011)))
2359   (:emitter
2360    (emit-byte segment #b10011011)))
2361
2362 (define-instruction lock (segment)
2363   (:printer byte ((op #b11110000)))
2364   (:emitter
2365    (emit-byte segment #b11110000)))
2366 \f
2367 ;;;; miscellaneous hackery
2368
2369 (define-instruction byte (segment byte)
2370   (:emitter
2371    (emit-byte segment byte)))
2372
2373 (define-instruction word (segment word)
2374   (:emitter
2375    (emit-word segment word)))
2376
2377 (define-instruction dword (segment dword)
2378   (:emitter
2379    (emit-dword segment dword)))
2380
2381 (defun emit-header-data (segment type)
2382   (emit-back-patch segment
2383                    n-word-bytes
2384                    (lambda (segment posn)
2385                      (emit-qword segment
2386                                  (logior type
2387                                          (ash (+ posn
2388                                                  (component-header-length))
2389                                               (- n-widetag-bits
2390                                                  word-shift)))))))
2391
2392 (define-instruction simple-fun-header-word (segment)
2393   (:emitter
2394    (emit-header-data segment simple-fun-header-widetag)))
2395
2396 (define-instruction lra-header-word (segment)
2397   (:emitter
2398    (emit-header-data segment return-pc-header-widetag)))
2399 \f
2400 ;;;; fp instructions
2401 ;;;;
2402 ;;;; Note: We treat the single-precision and double-precision variants
2403 ;;;; as separate instructions.
2404
2405 ;;; Load single to st(0).
2406 (define-instruction fld (segment source)
2407   (:printer floating-point ((op '(#b001 #b000))))
2408   (:emitter
2409     (and (not (fp-reg-tn-p source))
2410          (maybe-emit-rex-for-ea segment source nil))
2411     (emit-byte segment #b11011001)
2412     (emit-fp-op segment source #b000)))
2413
2414 ;;; Load double to st(0).
2415 (define-instruction fldd (segment source)
2416   (:printer floating-point ((op '(#b101 #b000))))
2417   (:printer floating-point-fp ((op '(#b001 #b000))))
2418   (:emitter
2419    (if (fp-reg-tn-p source)
2420        (emit-byte segment #b11011001)
2421        (progn
2422          (maybe-emit-rex-for-ea segment source nil)
2423          (emit-byte segment #b11011101)))
2424    (emit-fp-op segment source #b000)))
2425
2426 ;;; Load long to st(0).
2427 (define-instruction fldl (segment source)
2428   (:printer floating-point ((op '(#b011 #b101))))
2429   (:emitter
2430     (and (not (fp-reg-tn-p source))
2431          (maybe-emit-rex-for-ea segment source nil))
2432     (emit-byte segment #b11011011)
2433     (emit-fp-op segment source #b101)))
2434
2435 ;;; Store single from st(0).
2436 (define-instruction fst (segment dest)
2437   (:printer floating-point ((op '(#b001 #b010))))
2438   (:emitter
2439     (cond ((fp-reg-tn-p dest)
2440            (emit-byte segment #b11011101)
2441            (emit-fp-op segment dest #b010))
2442           (t
2443            (maybe-emit-rex-for-ea segment dest nil)
2444            (emit-byte segment #b11011001)
2445            (emit-fp-op segment dest #b010)))))
2446
2447 ;;; Store double from st(0).
2448 (define-instruction fstd (segment dest)
2449   (:printer floating-point ((op '(#b101 #b010))))
2450   (:printer floating-point-fp ((op '(#b101 #b010))))
2451   (:emitter
2452    (cond ((fp-reg-tn-p dest)
2453           (emit-byte segment #b11011101)
2454           (emit-fp-op segment dest #b010))
2455          (t
2456           (maybe-emit-rex-for-ea segment dest nil)
2457           (emit-byte segment #b11011101)
2458           (emit-fp-op segment dest #b010)))))
2459
2460 ;;; Arithmetic ops are all done with at least one operand at top of
2461 ;;; stack. The other operand is is another register or a 32/64 bit
2462 ;;; memory loc.
2463
2464 ;;; dtc: I've tried to follow the Intel ASM386 conventions, but note
2465 ;;; that these conflict with the Gdb conventions for binops. To reduce
2466 ;;; the confusion I've added comments showing the mathamatical
2467 ;;; operation and the two syntaxes. By the ASM386 convention the
2468 ;;; instruction syntax is:
2469 ;;;
2470 ;;;      Fop Source
2471 ;;; or   Fop Destination, Source
2472 ;;;
2473 ;;; If only one operand is given then it is the source and the
2474 ;;; destination is ST(0). There are reversed forms of the fsub and
2475 ;;; fdiv instructions inducated by an 'R' suffix.
2476 ;;;
2477 ;;; The mathematical operation for the non-reverse form is always:
2478 ;;;     destination = destination op source
2479 ;;;
2480 ;;; For the reversed form it is:
2481 ;;;     destination = source op destination
2482 ;;;
2483 ;;; The instructions below only accept one operand at present which is
2484 ;;; usually the source. I've hack in extra instructions to implement
2485 ;;; the fops with a ST(i) destination, these have a -sti suffix and
2486 ;;; the operand is the destination with the source being ST(0).
2487
2488 ;;; Add single:
2489 ;;;   st(0) = st(0) + memory or st(i).
2490 (define-instruction fadd (segment source)
2491   (:printer floating-point ((op '(#b000 #b000))))
2492   (:emitter
2493     (and (not (fp-reg-tn-p source))
2494          (maybe-emit-rex-for-ea segment source nil))
2495     (emit-byte segment #b11011000)
2496     (emit-fp-op segment source #b000)))
2497
2498 ;;; Add double:
2499 ;;;   st(0) = st(0) + memory or st(i).
2500 (define-instruction faddd (segment source)
2501   (:printer floating-point ((op '(#b100 #b000))))
2502   (:printer floating-point-fp ((op '(#b000 #b000))))
2503   (:emitter
2504    (and (not (fp-reg-tn-p source))
2505         (maybe-emit-rex-for-ea segment source nil))
2506    (if (fp-reg-tn-p source)
2507        (emit-byte segment #b11011000)
2508      (emit-byte segment #b11011100))
2509    (emit-fp-op segment source #b000)))
2510
2511 ;;; Add double destination st(i):
2512 ;;;   st(i) = st(0) + st(i).
2513 (define-instruction fadd-sti (segment destination)
2514   (:printer floating-point-fp ((op '(#b100 #b000))))
2515   (:emitter
2516    (aver (fp-reg-tn-p destination))
2517    (emit-byte segment #b11011100)
2518    (emit-fp-op segment destination #b000)))
2519 ;;; with pop
2520 (define-instruction faddp-sti (segment destination)
2521   (:printer floating-point-fp ((op '(#b110 #b000))))
2522   (:emitter
2523    (aver (fp-reg-tn-p destination))
2524    (emit-byte segment #b11011110)
2525    (emit-fp-op segment destination #b000)))
2526
2527 ;;; Subtract single:
2528 ;;;   st(0) = st(0) - memory or st(i).
2529 (define-instruction fsub (segment source)
2530   (:printer floating-point ((op '(#b000 #b100))))
2531   (:emitter
2532     (and (not (fp-reg-tn-p source))
2533          (maybe-emit-rex-for-ea segment source nil))
2534     (emit-byte segment #b11011000)
2535     (emit-fp-op segment source #b100)))
2536
2537 ;;; Subtract single, reverse:
2538 ;;;   st(0) = memory or st(i) - st(0).
2539 (define-instruction fsubr (segment source)
2540   (:printer floating-point ((op '(#b000 #b101))))
2541   (:emitter
2542     (and (not (fp-reg-tn-p source))
2543          (maybe-emit-rex-for-ea segment source nil))
2544     (emit-byte segment #b11011000)
2545     (emit-fp-op segment source #b101)))
2546
2547 ;;; Subtract double:
2548 ;;;   st(0) = st(0) - memory or st(i).
2549 (define-instruction fsubd (segment source)
2550   (:printer floating-point ((op '(#b100 #b100))))
2551   (:printer floating-point-fp ((op '(#b000 #b100))))
2552   (:emitter
2553    (if (fp-reg-tn-p source)
2554        (emit-byte segment #b11011000)
2555        (progn
2556          (and (not (fp-reg-tn-p source))
2557               (maybe-emit-rex-for-ea segment source nil))
2558          (emit-byte segment #b11011100)))
2559    (emit-fp-op segment source #b100)))
2560
2561 ;;; Subtract double, reverse:
2562 ;;;   st(0) = memory or st(i) - st(0).
2563 (define-instruction fsubrd (segment source)
2564   (:printer floating-point ((op '(#b100 #b101))))
2565   (:printer floating-point-fp ((op '(#b000 #b101))))
2566   (:emitter
2567    (if (fp-reg-tn-p source)
2568        (emit-byte segment #b11011000)
2569        (progn
2570          (and (not (fp-reg-tn-p source))
2571               (maybe-emit-rex-for-ea segment source nil))
2572          (emit-byte segment #b11011100)))
2573    (emit-fp-op segment source #b101)))
2574
2575 ;;; Subtract double, destination st(i):
2576 ;;;   st(i) = st(i) - st(0).
2577 ;;;
2578 ;;; ASM386 syntax: FSUB ST(i), ST
2579 ;;; Gdb    syntax: fsubr %st,%st(i)
2580 (define-instruction fsub-sti (segment destination)
2581   (:printer floating-point-fp ((op '(#b100 #b101))))
2582   (:emitter
2583    (aver (fp-reg-tn-p destination))
2584    (emit-byte segment #b11011100)
2585    (emit-fp-op segment destination #b101)))
2586 ;;; with a pop
2587 (define-instruction fsubp-sti (segment destination)
2588   (:printer floating-point-fp ((op '(#b110 #b101))))
2589   (:emitter
2590    (aver (fp-reg-tn-p destination))
2591    (emit-byte segment #b11011110)
2592    (emit-fp-op segment destination #b101)))
2593
2594 ;;; Subtract double, reverse, destination st(i):
2595 ;;;   st(i) = st(0) - st(i).
2596 ;;;
2597 ;;; ASM386 syntax: FSUBR ST(i), ST
2598 ;;; Gdb    syntax: fsub %st,%st(i)
2599 (define-instruction fsubr-sti (segment destination)
2600   (:printer floating-point-fp ((op '(#b100 #b100))))
2601   (:emitter
2602    (aver (fp-reg-tn-p destination))
2603    (emit-byte segment #b11011100)
2604    (emit-fp-op segment destination #b100)))
2605 ;;; with a pop
2606 (define-instruction fsubrp-sti (segment destination)
2607   (:printer floating-point-fp ((op '(#b110 #b100))))
2608   (:emitter
2609    (aver (fp-reg-tn-p destination))
2610    (emit-byte segment #b11011110)
2611    (emit-fp-op segment destination #b100)))
2612
2613 ;;; Multiply single:
2614 ;;;   st(0) = st(0) * memory or st(i).
2615 (define-instruction fmul (segment source)
2616   (:printer floating-point ((op '(#b000 #b001))))
2617   (:emitter
2618    (and (not (fp-reg-tn-p source))
2619         (maybe-emit-rex-for-ea segment source nil))
2620    (emit-byte segment #b11011000)
2621    (emit-fp-op segment source #b001)))
2622
2623 ;;; Multiply double:
2624 ;;;   st(0) = st(0) * memory or st(i).
2625 (define-instruction fmuld (segment source)
2626   (:printer floating-point ((op '(#b100 #b001))))
2627   (:printer floating-point-fp ((op '(#b000 #b001))))
2628   (:emitter
2629    (if (fp-reg-tn-p source)
2630        (emit-byte segment #b11011000)
2631        (progn
2632          (and (not (fp-reg-tn-p source))
2633               (maybe-emit-rex-for-ea segment source nil))
2634          (emit-byte segment #b11011100)))
2635    (emit-fp-op segment source #b001)))
2636
2637 ;;; Multiply double, destination st(i):
2638 ;;;   st(i) = st(i) * st(0).
2639 (define-instruction fmul-sti (segment destination)
2640   (:printer floating-point-fp ((op '(#b100 #b001))))
2641   (:emitter
2642    (aver (fp-reg-tn-p destination))
2643    (emit-byte segment #b11011100)
2644    (emit-fp-op segment destination #b001)))
2645
2646 ;;; Divide single:
2647 ;;;   st(0) = st(0) / memory or st(i).
2648 (define-instruction fdiv (segment source)
2649   (:printer floating-point ((op '(#b000 #b110))))
2650   (:emitter
2651    (and (not (fp-reg-tn-p source))
2652         (maybe-emit-rex-for-ea segment source nil))
2653    (emit-byte segment #b11011000)
2654    (emit-fp-op segment source #b110)))
2655
2656 ;;; Divide single, reverse:
2657 ;;;   st(0) = memory or st(i) / st(0).
2658 (define-instruction fdivr (segment source)
2659   (:printer floating-point ((op '(#b000 #b111))))
2660   (:emitter
2661    (and (not (fp-reg-tn-p source))
2662         (maybe-emit-rex-for-ea segment source nil))
2663    (emit-byte segment #b11011000)
2664    (emit-fp-op segment source #b111)))
2665
2666 ;;; Divide double:
2667 ;;;   st(0) = st(0) / memory or st(i).
2668 (define-instruction fdivd (segment source)
2669   (:printer floating-point ((op '(#b100 #b110))))
2670   (:printer floating-point-fp ((op '(#b000 #b110))))
2671   (:emitter
2672    (if (fp-reg-tn-p source)
2673        (emit-byte segment #b11011000)
2674        (progn
2675          (and (not (fp-reg-tn-p source))
2676               (maybe-emit-rex-for-ea segment source nil))
2677          (emit-byte segment #b11011100)))
2678    (emit-fp-op segment source #b110)))
2679
2680 ;;; Divide double, reverse:
2681 ;;;   st(0) = memory or st(i) / st(0).
2682 (define-instruction fdivrd (segment source)
2683   (:printer floating-point ((op '(#b100 #b111))))
2684   (:printer floating-point-fp ((op '(#b000 #b111))))
2685   (:emitter
2686    (if (fp-reg-tn-p source)
2687        (emit-byte segment #b11011000)
2688        (progn 
2689          (and (not (fp-reg-tn-p source))
2690               (maybe-emit-rex-for-ea segment source nil))
2691          (emit-byte segment #b11011100)))
2692    (emit-fp-op segment source #b111)))
2693
2694 ;;; Divide double, destination st(i):
2695 ;;;   st(i) = st(i) / st(0).
2696 ;;;
2697 ;;; ASM386 syntax: FDIV ST(i), ST
2698 ;;; Gdb    syntax: fdivr %st,%st(i)
2699 (define-instruction fdiv-sti (segment destination)
2700   (:printer floating-point-fp ((op '(#b100 #b111))))
2701   (:emitter
2702    (aver (fp-reg-tn-p destination))
2703    (emit-byte segment #b11011100)
2704    (emit-fp-op segment destination #b111)))
2705
2706 ;;; Divide double, reverse, destination st(i):
2707 ;;;   st(i) = st(0) / st(i).
2708 ;;;
2709 ;;; ASM386 syntax: FDIVR ST(i), ST
2710 ;;; Gdb    syntax: fdiv %st,%st(i)
2711 (define-instruction fdivr-sti (segment destination)
2712   (:printer floating-point-fp ((op '(#b100 #b110))))
2713   (:emitter
2714    (aver (fp-reg-tn-p destination))
2715    (emit-byte segment #b11011100)
2716    (emit-fp-op segment destination #b110)))
2717
2718 ;;; Exchange fr0 with fr(n). (There is no double precision variant.)
2719 (define-instruction fxch (segment source)
2720   (:printer floating-point-fp ((op '(#b001 #b001))))
2721   (:emitter
2722     (unless (and (tn-p source)
2723                  (eq (sb-name (sc-sb (tn-sc source))) 'float-registers))
2724       (cl:break))
2725     (emit-byte segment #b11011001)
2726     (emit-fp-op segment source #b001)))
2727
2728 ;;; Push 32-bit integer to st0.
2729 (define-instruction fild (segment source)
2730   (:printer floating-point ((op '(#b011 #b000))))
2731   (:emitter
2732     (and (not (fp-reg-tn-p source))
2733          (maybe-emit-rex-for-ea segment source nil))
2734     (emit-byte segment #b11011011)
2735     (emit-fp-op segment source #b000)))
2736
2737 ;;; Push 64-bit integer to st0.
2738 (define-instruction fildl (segment source)
2739   (:printer floating-point ((op '(#b111 #b101))))
2740   (:emitter
2741     (and (not (fp-reg-tn-p source))
2742          (maybe-emit-rex-for-ea segment source nil))
2743     (emit-byte segment #b11011111)
2744     (emit-fp-op segment source #b101)))
2745
2746 ;;; Store 32-bit integer.
2747 (define-instruction fist (segment dest)
2748   (:printer floating-point ((op '(#b011 #b010))))
2749   (:emitter
2750    (and (not (fp-reg-tn-p dest))
2751         (maybe-emit-rex-for-ea segment dest nil))
2752    (emit-byte segment #b11011011)
2753    (emit-fp-op segment dest #b010)))
2754
2755 ;;; Store and pop 32-bit integer.
2756 (define-instruction fistp (segment dest)
2757   (:printer floating-point ((op '(#b011 #b011))))
2758   (:emitter
2759    (and (not (fp-reg-tn-p dest))
2760         (maybe-emit-rex-for-ea segment dest nil))
2761    (emit-byte segment #b11011011)
2762    (emit-fp-op segment dest #b011)))
2763
2764 ;;; Store and pop 64-bit integer.
2765 (define-instruction fistpl (segment dest)
2766   (:printer floating-point ((op '(#b111 #b111))))
2767   (:emitter
2768    (and (not (fp-reg-tn-p dest))
2769         (maybe-emit-rex-for-ea segment dest nil))
2770    (emit-byte segment #b11011111)
2771    (emit-fp-op segment dest #b111)))
2772
2773 ;;; Store single from st(0) and pop.
2774 (define-instruction fstp (segment dest)
2775   (:printer floating-point ((op '(#b001 #b011))))
2776   (:emitter
2777    (cond ((fp-reg-tn-p dest)
2778           (emit-byte segment #b11011101)
2779           (emit-fp-op segment dest #b011))
2780          (t
2781           (maybe-emit-rex-for-ea segment dest nil)
2782           (emit-byte segment #b11011001)
2783           (emit-fp-op segment dest #b011)))))
2784
2785 ;;; Store double from st(0) and pop.
2786 (define-instruction fstpd (segment dest)
2787   (:printer floating-point ((op '(#b101 #b011))))
2788   (:printer floating-point-fp ((op '(#b101 #b011))))
2789   (:emitter
2790    (cond ((fp-reg-tn-p dest)
2791           (emit-byte segment #b11011101)
2792           (emit-fp-op segment dest #b011))
2793          (t
2794           (maybe-emit-rex-for-ea segment dest nil)
2795           (emit-byte segment #b11011101)
2796           (emit-fp-op segment dest #b011)))))
2797
2798 ;;; Store long from st(0) and pop.
2799 (define-instruction fstpl (segment dest)
2800   (:printer floating-point ((op '(#b011 #b111))))
2801   (:emitter
2802    (and (not (fp-reg-tn-p dest))
2803         (maybe-emit-rex-for-ea segment dest nil))
2804    (emit-byte segment #b11011011)
2805    (emit-fp-op segment dest #b111)))
2806
2807 ;;; Decrement stack-top pointer.
2808 (define-instruction fdecstp (segment)
2809   (:printer floating-point-no ((op #b10110)))
2810   (:emitter
2811    (emit-byte segment #b11011001)
2812    (emit-byte segment #b11110110)))
2813
2814 ;;; Increment stack-top pointer.
2815 (define-instruction fincstp (segment)
2816   (:printer floating-point-no ((op #b10111)))
2817   (:emitter
2818    (emit-byte segment #b11011001)
2819    (emit-byte segment #b11110111)))
2820
2821 ;;; Free fp register.
2822 (define-instruction ffree (segment dest)
2823   (:printer floating-point-fp ((op '(#b101 #b000))))
2824   (:emitter
2825    (and (not (fp-reg-tn-p dest))
2826         (maybe-emit-rex-for-ea segment dest nil))
2827    (emit-byte segment #b11011101)
2828    (emit-fp-op segment dest #b000)))
2829
2830 (define-instruction fabs (segment)
2831   (:printer floating-point-no ((op #b00001)))
2832   (:emitter
2833    (emit-byte segment #b11011001)
2834    (emit-byte segment #b11100001)))
2835
2836 (define-instruction fchs (segment)
2837   (:printer floating-point-no ((op #b00000)))
2838   (:emitter
2839    (emit-byte segment #b11011001)
2840    (emit-byte segment #b11100000)))
2841
2842 (define-instruction frndint(segment)
2843   (:printer floating-point-no ((op #b11100)))
2844   (:emitter
2845    (emit-byte segment #b11011001)
2846    (emit-byte segment #b11111100)))
2847
2848 ;;; Initialize NPX.
2849 (define-instruction fninit(segment)
2850   (:printer floating-point-5 ((op #b00011)))
2851   (:emitter
2852    (emit-byte segment #b11011011)
2853    (emit-byte segment #b11100011)))
2854
2855 ;;; Store Status Word to AX.
2856 (define-instruction fnstsw(segment)
2857   (:printer floating-point-st ((op #b00000)))
2858   (:emitter
2859    (emit-byte segment #b11011111)
2860    (emit-byte segment #b11100000)))
2861
2862 ;;; Load Control Word.
2863 ;;;
2864 ;;; src must be a memory location
2865 (define-instruction fldcw(segment src)
2866   (:printer floating-point ((op '(#b001 #b101))))
2867   (:emitter
2868    (and (not (fp-reg-tn-p src))
2869         (maybe-emit-rex-for-ea segment src nil))
2870    (emit-byte segment #b11011001)
2871    (emit-fp-op segment src #b101)))
2872
2873 ;;; Store Control Word.
2874 (define-instruction fnstcw(segment dst)
2875   (:printer floating-point ((op '(#b001 #b111))))
2876   (:emitter
2877    (and (not (fp-reg-tn-p dst))
2878         (maybe-emit-rex-for-ea segment dst nil))
2879    (emit-byte segment #b11011001)
2880    (emit-fp-op segment dst #b111)))
2881
2882 ;;; Store FP Environment.
2883 (define-instruction fstenv(segment dst)
2884   (:printer floating-point ((op '(#b001 #b110))))
2885   (:emitter
2886    (and (not (fp-reg-tn-p dst))
2887         (maybe-emit-rex-for-ea segment dst nil))
2888    (emit-byte segment #b11011001)
2889    (emit-fp-op segment dst #b110)))
2890
2891 ;;; Restore FP Environment.
2892 (define-instruction fldenv(segment src)
2893   (:printer floating-point ((op '(#b001 #b100))))
2894   (:emitter
2895    (and (not (fp-reg-tn-p src))
2896         (maybe-emit-rex-for-ea segment src nil))
2897    (emit-byte segment #b11011001)
2898    (emit-fp-op segment src #b100)))
2899
2900 ;;; Save FP State.
2901 (define-instruction fsave(segment dst)
2902   (:printer floating-point ((op '(#b101 #b110))))
2903   (:emitter
2904    (and (not (fp-reg-tn-p dst))
2905         (maybe-emit-rex-for-ea segment dst nil))
2906    (emit-byte segment #b11011101)
2907    (emit-fp-op segment dst #b110)))
2908
2909 ;;; Restore FP State.
2910 (define-instruction frstor(segment src)
2911   (:printer floating-point ((op '(#b101 #b100))))
2912   (:emitter
2913    (and (not (fp-reg-tn-p src))
2914         (maybe-emit-rex-for-ea segment src nil))
2915    (emit-byte segment #b11011101)
2916    (emit-fp-op segment src #b100)))
2917
2918 ;;; Clear exceptions.
2919 (define-instruction fnclex(segment)
2920   (:printer floating-point-5 ((op #b00010)))
2921   (:emitter
2922    (emit-byte segment #b11011011)
2923    (emit-byte segment #b11100010)))
2924
2925 ;;; comparison
2926 (define-instruction fcom (segment src)
2927   (:printer floating-point ((op '(#b000 #b010))))
2928   (:emitter
2929    (and (not (fp-reg-tn-p src))
2930         (maybe-emit-rex-for-ea segment src nil))
2931    (emit-byte segment #b11011000)
2932    (emit-fp-op segment src #b010)))
2933
2934 (define-instruction fcomd (segment src)
2935   (:printer floating-point ((op '(#b100 #b010))))
2936   (:printer floating-point-fp ((op '(#b000 #b010))))
2937   (:emitter
2938    (if (fp-reg-tn-p src)
2939        (emit-byte segment #b11011000)
2940        (progn
2941          (maybe-emit-rex-for-ea segment src nil)
2942          (emit-byte segment #b11011100)))
2943    (emit-fp-op segment src #b010)))
2944
2945 ;;; Compare ST1 to ST0, popping the stack twice.
2946 (define-instruction fcompp (segment)
2947   (:printer floating-point-3 ((op '(#b110 #b011001))))
2948   (:emitter
2949    (emit-byte segment #b11011110)
2950    (emit-byte segment #b11011001)))
2951
2952 ;;; unordered comparison
2953 (define-instruction fucom (segment src)
2954   (:printer floating-point-fp ((op '(#b101 #b100))))
2955   (:emitter
2956    (aver (fp-reg-tn-p src))
2957    (emit-byte segment #b11011101)
2958    (emit-fp-op segment src #b100)))
2959
2960 (define-instruction ftst (segment)
2961   (:printer floating-point-no ((op #b00100)))
2962   (:emitter
2963    (emit-byte segment #b11011001)
2964    (emit-byte segment #b11100100)))
2965
2966 ;;;; 80387 specials
2967
2968 (define-instruction fsqrt(segment)
2969   (:printer floating-point-no ((op #b11010)))
2970   (:emitter
2971    (emit-byte segment #b11011001)
2972    (emit-byte segment #b11111010)))
2973
2974 (define-instruction fscale(segment)
2975   (:printer floating-point-no ((op #b11101)))
2976   (:emitter
2977    (emit-byte segment #b11011001)
2978    (emit-byte segment #b11111101)))
2979
2980 (define-instruction fxtract(segment)
2981   (:printer floating-point-no ((op #b10100)))
2982   (:emitter
2983    (emit-byte segment #b11011001)
2984    (emit-byte segment #b11110100)))
2985
2986 (define-instruction fsin(segment)
2987   (:printer floating-point-no ((op #b11110)))
2988   (:emitter
2989    (emit-byte segment #b11011001)
2990    (emit-byte segment #b11111110)))
2991
2992 (define-instruction fcos(segment)
2993   (:printer floating-point-no ((op #b11111)))
2994   (:emitter
2995    (emit-byte segment #b11011001)
2996    (emit-byte segment #b11111111)))
2997
2998 (define-instruction fprem1(segment)
2999   (:printer floating-point-no ((op #b10101)))
3000   (:emitter
3001    (emit-byte segment #b11011001)
3002    (emit-byte segment #b11110101)))
3003
3004 (define-instruction fprem(segment)
3005   (:printer floating-point-no ((op #b11000)))
3006   (:emitter
3007    (emit-byte segment #b11011001)
3008    (emit-byte segment #b11111000)))
3009
3010 (define-instruction fxam (segment)
3011   (:printer floating-point-no ((op #b00101)))
3012   (:emitter
3013    (emit-byte segment #b11011001)
3014    (emit-byte segment #b11100101)))
3015
3016 ;;; These do push/pop to stack and need special handling
3017 ;;; in any VOPs that use them. See the book.
3018
3019 ;;; st0 <- st1*log2(st0)
3020 (define-instruction fyl2x(segment)      ; pops stack
3021   (:printer floating-point-no ((op #b10001)))
3022   (:emitter
3023    (emit-byte segment #b11011001)
3024    (emit-byte segment #b11110001)))
3025
3026 (define-instruction fyl2xp1(segment)
3027   (:printer floating-point-no ((op #b11001)))
3028   (:emitter
3029    (emit-byte segment #b11011001)
3030    (emit-byte segment #b11111001)))
3031
3032 (define-instruction f2xm1(segment)
3033   (:printer floating-point-no ((op #b10000)))
3034   (:emitter
3035    (emit-byte segment #b11011001)
3036    (emit-byte segment #b11110000)))
3037
3038 (define-instruction fptan(segment)      ; st(0) <- 1; st(1) <- tan
3039   (:printer floating-point-no ((op #b10010)))
3040   (:emitter
3041    (emit-byte segment #b11011001)
3042    (emit-byte segment #b11110010)))
3043
3044 (define-instruction fpatan(segment)     ; POPS STACK
3045   (:printer floating-point-no ((op #b10011)))
3046   (:emitter
3047    (emit-byte segment #b11011001)
3048    (emit-byte segment #b11110011)))
3049
3050 ;;;; loading constants
3051
3052 (define-instruction fldz(segment)
3053   (:printer floating-point-no ((op #b01110)))
3054   (:emitter
3055    (emit-byte segment #b11011001)
3056    (emit-byte segment #b11101110)))
3057
3058 (define-instruction fld1(segment)
3059   (:printer floating-point-no ((op #b01000)))
3060   (:emitter
3061    (emit-byte segment #b11011001)
3062    (emit-byte segment #b11101000)))
3063
3064 (define-instruction fldpi(segment)
3065   (:printer floating-point-no ((op #b01011)))
3066   (:emitter
3067    (emit-byte segment #b11011001)
3068    (emit-byte segment #b11101011)))
3069
3070 (define-instruction fldl2t(segment)
3071   (:printer floating-point-no ((op #b01001)))
3072   (:emitter
3073    (emit-byte segment #b11011001)
3074    (emit-byte segment #b11101001)))
3075
3076 (define-instruction fldl2e(segment)
3077   (:printer floating-point-no ((op #b01010)))
3078   (:emitter
3079    (emit-byte segment #b11011001)
3080    (emit-byte segment #b11101010)))
3081
3082 (define-instruction fldlg2(segment)
3083   (:printer floating-point-no ((op #b01100)))
3084   (:emitter
3085    (emit-byte segment #b11011001)
3086    (emit-byte segment #b11101100)))
3087
3088 (define-instruction fldln2(segment)
3089   (:printer floating-point-no ((op #b01101)))
3090   (:emitter
3091    (emit-byte segment #b11011001)
3092    (emit-byte segment #b11101101)))
3093
3094 ;; new xmm insns required by sse float 
3095 ;; movsd andpd comisd comiss
3096
3097 (define-instruction movsd (segment dst src)
3098 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3099   (:emitter
3100    (cond ((typep src 'tn) 
3101           (emit-byte segment #xf2)
3102           (maybe-emit-rex-for-ea segment dst src)
3103           (emit-byte segment #x0f)
3104           (emit-byte segment #x11)
3105           (emit-ea segment dst (reg-tn-encoding src)))
3106          (t
3107           (emit-byte segment #xf2)
3108           (maybe-emit-rex-for-ea segment src dst)
3109           (emit-byte segment #x0f)
3110           (emit-byte segment #x10)
3111           (emit-ea segment src (reg-tn-encoding dst))))))
3112
3113 (define-instruction movss (segment dst src)
3114 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3115   (:emitter
3116    (cond ((tn-p src)
3117           (emit-byte segment #xf3)
3118           (maybe-emit-rex-for-ea segment dst src)
3119           (emit-byte segment #x0f)
3120           (emit-byte segment #x11)
3121           (emit-ea segment dst (reg-tn-encoding src)))
3122          (t
3123           (emit-byte segment #xf3)
3124           (maybe-emit-rex-for-ea segment src dst)
3125           (emit-byte segment #x0f)
3126           (emit-byte segment #x10)
3127           (emit-ea segment src (reg-tn-encoding dst))))))
3128
3129 (define-instruction andpd (segment dst src)
3130 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3131   (:emitter
3132    (emit-byte segment #x66)
3133    (maybe-emit-rex-for-ea segment src dst)
3134    (emit-byte segment #x0f)
3135    (emit-byte segment #x54)
3136    (emit-ea segment src (reg-tn-encoding dst))))
3137
3138 (define-instruction andps (segment dst src)
3139   (:emitter
3140    (maybe-emit-rex-for-ea segment src dst)
3141    (emit-byte segment #x0f)
3142    (emit-byte segment #x54)
3143    (emit-ea segment src (reg-tn-encoding dst))))
3144
3145 (define-instruction comisd (segment dst src)
3146 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3147   (:emitter
3148    (emit-byte segment #x66)
3149    (maybe-emit-rex-for-ea segment src dst)
3150    (emit-byte segment #x0f)
3151    (emit-byte segment #x2f)
3152    (emit-ea segment src (reg-tn-encoding dst))))
3153
3154 (define-instruction comiss (segment dst src)
3155 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3156   (:emitter
3157    (maybe-emit-rex-for-ea segment src dst)
3158    (emit-byte segment #x0f)
3159    (emit-byte segment #x2f)
3160    (emit-ea segment src (reg-tn-encoding dst))))
3161
3162 ;;  movd movq xorp xord
3163
3164 ;; we only do the xmm version of movd
3165 (define-instruction movd (segment dst src)
3166 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3167   (:emitter
3168    (cond ((typep dst 'tn)
3169           (emit-byte segment #x66)
3170           (maybe-emit-rex-for-ea segment src dst)
3171           (emit-byte segment #x0f)
3172           (emit-byte segment #x6e)
3173           (emit-ea segment src (reg-tn-encoding dst)))
3174          (t
3175           (emit-byte segment #x66)
3176           (maybe-emit-rex-for-ea segment dst src)
3177           (emit-byte segment #x0f)
3178           (emit-byte segment #x7e)
3179           (emit-ea segment dst (reg-tn-encoding src))))))
3180
3181 (define-instruction movq (segment dst src)
3182 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3183   (:emitter
3184    (cond ((typep dst 'tn)
3185           (emit-byte segment #xf3)
3186           (maybe-emit-rex-for-ea segment src dst)
3187           (emit-byte segment #x0f)
3188           (emit-byte segment #x7e)
3189           (emit-ea segment src (reg-tn-encoding dst)))
3190          (t
3191           (emit-byte segment #x66)
3192           (maybe-emit-rex-for-ea segment dst src)
3193           (emit-byte segment #x0f)
3194           (emit-byte segment #xd6)
3195           (emit-ea segment dst (reg-tn-encoding src))))))
3196
3197 (define-instruction xorpd (segment dst src)
3198 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3199   (:emitter
3200    (emit-byte segment #x66)
3201    (maybe-emit-rex-for-ea segment src dst)
3202    (emit-byte segment #x0f)
3203    (emit-byte segment #x57)
3204    (emit-ea segment src (reg-tn-encoding dst))))
3205
3206 (define-instruction xorps (segment dst src)
3207 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3208   (:emitter
3209    (maybe-emit-rex-for-ea segment src dst)
3210    (emit-byte segment #x0f)
3211    (emit-byte segment #x57)
3212    (emit-ea segment src (reg-tn-encoding dst))))
3213
3214 (define-instruction cvtsd2si (segment dst src)
3215 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3216   (:emitter
3217    (emit-byte segment #xf2)
3218    (maybe-emit-rex-for-ea segment src dst :operand-size :qword)
3219    (emit-byte segment #x0f)
3220    (emit-byte segment #x2d)
3221    (emit-ea segment src (reg-tn-encoding dst))))
3222
3223 (define-instruction cvtsd2ss (segment dst src)
3224 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3225   (:emitter
3226    (emit-byte segment #xf2)
3227    (maybe-emit-rex-for-ea segment src dst)
3228    (emit-byte segment #x0f)
3229    (emit-byte segment #x5a)
3230    (emit-ea segment src (reg-tn-encoding dst))))
3231
3232 (define-instruction cvtss2si (segment dst src)
3233 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3234   (:emitter
3235    (emit-byte segment #xf3)
3236    (maybe-emit-rex-for-ea segment src dst :operand-size :qword)
3237    (emit-byte segment #x0f)
3238    (emit-byte segment #x2d)
3239    (emit-ea segment src (reg-tn-encoding dst))))
3240
3241 (define-instruction cvtss2sd (segment dst src)
3242 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3243   (:emitter
3244    (emit-byte segment #xf3)
3245    (maybe-emit-rex-for-ea segment src dst)
3246    (emit-byte segment #x0f)
3247    (emit-byte segment #x5a)
3248    (emit-ea segment src (reg-tn-encoding dst))))
3249
3250 (define-instruction cvtsi2ss (segment dst src)
3251 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3252   (:emitter
3253    (emit-byte segment #xf3)
3254    (maybe-emit-rex-for-ea segment src dst)
3255    (emit-byte segment #x0f)
3256    (emit-byte segment #x2a)
3257    (emit-ea segment src (reg-tn-encoding dst))))
3258
3259 (define-instruction cvtsi2sd (segment dst src)
3260 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3261   (:emitter
3262    (emit-byte segment #xf2)
3263    (maybe-emit-rex-for-ea segment src dst)
3264    (emit-byte segment #x0f)
3265    (emit-byte segment #x2a)
3266    (emit-ea segment src (reg-tn-encoding dst))))
3267
3268 (define-instruction cvtdq2pd (segment dst src)
3269 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3270   (:emitter
3271    (emit-byte segment #xf3)
3272    (maybe-emit-rex-for-ea segment src dst)
3273    (emit-byte segment #x0f)
3274    (emit-byte segment #xe6)
3275    (emit-ea segment src (reg-tn-encoding dst))))
3276
3277 (define-instruction cvtdq2ps (segment dst src)
3278 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3279   (:emitter
3280    (maybe-emit-rex-for-ea segment src dst)
3281    (emit-byte segment #x0f)
3282    (emit-byte segment #x5b)
3283    (emit-ea segment src (reg-tn-encoding dst))))
3284
3285 ;; CVTTSD2SI CVTTSS2SI
3286
3287 (define-instruction cvttsd2si (segment dst src)
3288 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3289   (:emitter
3290    (emit-byte segment #xf2)
3291    (maybe-emit-rex-for-ea segment src dst :operand-size :qword)
3292    (emit-byte segment #x0f)
3293    (emit-byte segment #x2c)
3294    (emit-ea segment src (reg-tn-encoding dst))))
3295
3296 (define-instruction cvttss2si (segment dst src)
3297 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3298   (:emitter
3299    (emit-byte segment #xf3)
3300    (maybe-emit-rex-for-ea segment src dst :operand-size :qword)
3301    (emit-byte segment #x0f)
3302    (emit-byte segment #x2c)
3303    (emit-ea segment src (reg-tn-encoding dst))))
3304
3305 (define-instruction addsd (segment dst src)
3306 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3307   (:emitter
3308    (emit-byte segment #xf2)
3309    (maybe-emit-rex-for-ea segment src dst)
3310    (emit-byte segment #x0f)
3311    (emit-byte segment #x58)
3312    (emit-ea segment src (reg-tn-encoding dst))))
3313
3314 (define-instruction addss (segment dst src)
3315 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3316   (:emitter
3317    (emit-byte segment #xf3)
3318    (maybe-emit-rex-for-ea segment src dst)
3319    (emit-byte segment #x0f)
3320    (emit-byte segment #x58)
3321    (emit-ea segment src (reg-tn-encoding dst))))
3322
3323 (define-instruction divsd (segment dst src)
3324 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3325   (:emitter
3326    (emit-byte segment #xf2)
3327    (maybe-emit-rex-for-ea segment src dst)
3328    (emit-byte segment #x0f)
3329    (emit-byte segment #x5e)
3330    (emit-ea segment src (reg-tn-encoding dst))))
3331
3332 (define-instruction divss (segment dst src)
3333 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3334   (:emitter
3335    (emit-byte segment #xf3)
3336    (maybe-emit-rex-for-ea segment src dst)
3337    (emit-byte segment #x0f)
3338    (emit-byte segment #x5e)
3339    (emit-ea segment src (reg-tn-encoding dst))))
3340
3341 (define-instruction mulsd (segment dst src)
3342 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3343   (:emitter
3344    (emit-byte segment #xf2)
3345    (maybe-emit-rex-for-ea segment src dst)
3346    (emit-byte segment #x0f)
3347    (emit-byte segment #x59)
3348    (emit-ea segment src (reg-tn-encoding dst))))
3349
3350 (define-instruction mulss (segment dst src)
3351 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3352   (:emitter
3353    (emit-byte segment #xf3)
3354    (maybe-emit-rex-for-ea segment src dst)
3355    (emit-byte segment #x0f)
3356    (emit-byte segment #x59)
3357    (emit-ea segment src (reg-tn-encoding dst))))
3358
3359 (define-instruction subsd (segment dst src)
3360 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3361   (:emitter
3362    (emit-byte segment #xf2)
3363    (maybe-emit-rex-for-ea segment src dst)
3364    (emit-byte segment #x0f)
3365    (emit-byte segment #x5c)
3366    (emit-ea segment src (reg-tn-encoding dst))))
3367
3368 (define-instruction subss (segment dst src)
3369 ;  (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
3370   (:emitter
3371    (emit-byte segment #xf3)
3372    (maybe-emit-rex-for-ea segment src dst)
3373    (emit-byte segment #x0f)
3374    (emit-byte segment #x5c)
3375    (emit-ea segment src (reg-tn-encoding dst))))