Add sb-mpfr contrib.
[sbcl/nyef.git] / src / compiler / arm / insts.lisp
blob07ce8527d5cdb8017a65abfacc18292e675f5f8c
1 ;;;; that part of the description of the ARM instruction set (for
2 ;;;; ARMv5) which can live on the cross-compilation host
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.
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.
18 ;;; Note: In CMU CL, this used to be a call to SET-DISASSEM-PARAMS.
19 (setf sb!disassem:*disassem-inst-alignment-bytes* 4)
22 (defparameter *conditions*
23 '((:eq . 0)
24 (:ne . 1)
25 (:cs . 2) (:hs . 2)
26 (:cc . 3) (:lo . 3)
27 (:mi . 4)
28 (:pl . 5)
29 (:vs . 6)
30 (:vc . 7)
31 (:hi . 8)
32 (:ls . 9)
33 (:ge . 10)
34 (:lt . 11)
35 (:gt . 12)
36 (:le . 13)
37 (:al . 14)))
38 (defparameter *condition-name-vec*
39 (let ((vec (make-array 16 :initial-element nil)))
40 (dolist (cond *conditions*)
41 (when (null (aref vec (cdr cond)))
42 (setf (aref vec (cdr cond)) (car cond))))
43 vec))
45 ;;; Set assembler parameters. (In CMU CL, this was done with
46 ;;; a call to a macro DEF-ASSEMBLER-PARAMS.)
47 (eval-when (:compile-toplevel :load-toplevel :execute)
48 (setf sb!assem:*assem-scheduler-p* nil))
50 (defun conditional-opcode (condition)
51 (cdr (assoc condition *conditions* :test #'eq)))
53 ;;;; disassembler field definitions
55 (defun maybe-add-notes (register dstate)
56 (when (eql register code-offset)
57 (let* ((inst (sb!disassem::sap-ref-int
58 (sb!disassem::dstate-segment-sap dstate)
59 (sb!disassem::dstate-cur-offs dstate)
60 n-word-bytes
61 (sb!disassem::dstate-byte-order dstate)))
62 (op (ldb (byte 8 20) inst)))
63 (case op
64 (89 ;; LDR
65 (sb!disassem:note-code-constant (ldb (byte 12 0) inst) dstate))))))
67 (eval-when (:compile-toplevel :load-toplevel :execute)
68 ;; DEFINE-ARG-TYPE requires that any :PRINTER be defined at
69 ;; compile-time... Why?
71 (defun print-condition (value stream dstate)
72 (declare (type stream stream)
73 (fixnum value)
74 (ignore dstate))
75 (unless (= value 14) ;; Don't print :al
76 (princ (aref *condition-name-vec* value) stream)))
78 (defun print-reg (value stream dstate)
79 (declare (type stream stream)
80 (fixnum value))
81 (maybe-add-notes value dstate)
82 (princ (aref *register-names* value) stream))
84 (defun print-shift-type (value stream dstate)
85 (declare (type stream stream)
86 (fixnum value)
87 (ignore dstate))
88 (princ (aref #(lsl lsr asr ror) value) stream))
90 (defun print-immediate-shift (value stream dstate)
91 (declare (type stream stream)
92 (type (cons fixnum (cons fixnum null)))
93 (ignore dstate))
94 (destructuring-bind (amount shift) value
95 (cond
96 ((and (zerop amount)
97 (zerop shift))
98 ;; No shift
100 ((and (zerop amount)
101 (= shift 3))
102 (princ ", RRX" stream))
104 (princ ", " stream)
105 (princ (aref #(lsl lsr asr ror) shift) stream)
106 (princ " #" stream)
107 (princ amount stream)))))
109 (defun print-shifter-immediate (value stream dstate)
110 (declare (type stream stream)
111 (fixnum value)
112 (ignore dstate))
113 (let* ((rotate (ldb (byte 4 8) value))
114 (immediate (mask-field (byte 8 0) value))
115 (left (mask-field (byte 32 0)
116 (ash immediate (- 32 rotate rotate))))
117 (right (ash immediate (- 0 rotate rotate))))
118 (princ (logior left right) stream)))
120 (defun use-label-relative-label (value dstate)
121 (declare (type (signed-byte 24) value)
122 (type sb!disassem:disassem-state dstate))
123 (+ 8 (ash value 2) (sb!disassem:dstate-cur-addr dstate)))
125 (defun print-load/store-immediate (value stream dstate)
126 (declare (type stream stream)
127 (type (cons bit (cons bit (cons bit (cons fixnum null)))) value)
128 (ignore dstate))
129 (destructuring-bind (p u w offset) value
130 (if (zerop offset)
131 (princ "]" stream)
132 (progn
133 (princ (if (zerop p) "], #" ", #") stream)
134 (princ (if (zerop u) "-" "+") stream)
135 (princ offset stream)
136 (unless (zerop p)
137 (princ (if (zerop w) "]" "]!") stream))))))
139 (defun print-load/store-register (value stream dstate)
140 (destructuring-bind (p u w offset) value
141 (when (zerop p)
142 (princ "]" stream))
143 (princ (if (zerop u) "-" "+") stream)
144 (print-immediate-shift offset stream dstate)
145 (unless (zerop p)
146 (princ (if (zerop w) "]" "]!") stream))))
148 (defun print-msr-field-mask (value stream dstate)
149 (declare (type stream stream)
150 (type (cons bit (cons (unsigned-byte 4) null)) value)
151 (ignore dstate))
152 (destructuring-bind (spsr-p field-mask) value
153 (if (zerop spsr-p)
154 (princ "CPSR_" stream)
155 (princ "SPSR_" stream))
156 (when (logbitp 0 field-mask) (princ "c" stream))
157 (when (logbitp 1 field-mask) (princ "x" stream))
158 (when (logbitp 2 field-mask) (princ "s" stream))
159 (when (logbitp 3 field-mask) (princ "f" stream))))
160 ) ; EVAL-WHEN
162 (sb!disassem:define-arg-type condition-code
163 :printer #'print-condition)
165 (sb!disassem:define-arg-type reg
166 :printer #'print-reg)
168 (sb!disassem:define-arg-type shift-type
169 :printer #'print-shift-type)
171 (sb!disassem:define-arg-type immediate-shift
172 :printer #'print-immediate-shift)
174 (sb!disassem:define-arg-type shifter-immediate
175 :printer #'print-shifter-immediate)
177 (sb!disassem:define-arg-type relative-label
178 :sign-extend t
179 :use-label #'use-label-relative-label)
181 (sb!disassem:define-arg-type load/store-immediate
182 :printer #'print-load/store-immediate)
184 (sb!disassem:define-arg-type load/store-register
185 :printer #'print-load/store-register)
187 ;; We use a prefilter in order to read trap codes in order to avoid
188 ;; encoding the code within the instruction body (requiring the use of
189 ;; a different trap instruction and a SIGILL handler) and in order to
190 ;; avoid attempting to include the code in the decoded instruction
191 ;; proper (requiring moving to a 40-bit instruction for disassembling
192 ;; trap codes, and being affected by endianness issues).
193 (sb!disassem:define-arg-type debug-trap-code
194 :prefilter (lambda (value dstate)
195 (declare (ignore value))
196 (sb!disassem:read-suffix 8 dstate)))
198 (sb!disassem:define-arg-type msr-field-mask
199 :printer #'print-msr-field-mask)
201 ;;;; disassembler instruction format definitions
203 (sb!disassem:define-instruction-format
204 (dp-shift-immediate 32
205 :default-printer '(:name cond :tab rd ", " rn ", " rm shift))
206 (cond :field (byte 4 28) :type 'condition-code)
207 (opcode-8 :field (byte 8 20))
208 (rn :field (byte 4 16) :type 'reg)
209 (rd :field (byte 4 12) :type 'reg)
210 (shift :fields (list (byte 5 7) (byte 2 5)) :type 'immediate-shift)
211 (register-shift-p :field (byte 1 4) :value 0)
212 (rm :field (byte 4 0) :type 'reg))
214 (sb!disassem:define-instruction-format
215 (dp-shift-register 32
216 :default-printer '(:name cond :tab rd ", " rn ", " rm ", " shift-type " " rs))
217 (cond :field (byte 4 28) :type 'condition-code)
218 (opcode-8 :field (byte 8 20))
219 (rn :field (byte 4 16) :type 'reg)
220 (rd :field (byte 4 12) :type 'reg)
221 (rs :field (byte 4 8) :type 'reg)
222 (multiply-p :field (byte 1 7) :value 0)
223 (shift-type :field (byte 2 5) :type 'shift-type)
224 (register-shift-p :field (byte 1 4) :value 1)
225 (rm :field (byte 4 0) :type 'reg))
227 (sb!disassem:define-instruction-format
228 (dp-immediate 32
229 :default-printer '(:name cond :tab rd ", " rn ", #" immediate))
230 (cond :field (byte 4 28) :type 'condition-code)
231 (opcode-8 :field (byte 8 20))
232 (rn :field (byte 4 16) :type 'reg)
233 (rd :field (byte 4 12) :type 'reg)
234 (immediate :field (byte 12 0) :type 'shifter-immediate))
236 (sb!disassem:define-instruction-format
237 (branch 32 :default-printer '(:name cond :tab target))
238 (cond :field (byte 4 28) :type 'condition-code)
239 (opcode-4 :field (byte 4 24))
240 (target :field (byte 24 0) :type 'relative-label))
242 (sb!disassem:define-instruction-format
243 (load/store-immediate 32
244 ;; FIXME: cond should come between LDR/STR and B.
245 :default-printer '(:name cond :tab rd ", [" rn load/store-offset))
246 (cond :field (byte 4 28) :type 'condition-code)
247 (opcode-3 :field (byte 3 25))
248 (load/store-offset :fields (list (byte 1 24)
249 (byte 1 23)
250 (byte 1 21)
251 (byte 12 0))
252 :type 'load/store-immediate)
253 (opcode-b :field (byte 1 22))
254 (opcode-l :field (byte 1 20))
255 (rn :field (byte 4 16) :type 'reg)
256 (rd :field (byte 4 12) :type 'reg))
258 (sb!disassem:define-instruction-format
259 (load/store-register 32
260 ;; FIXME: cond should come between LDR/STR and B.
261 :default-printer '(:name cond :tab rd ", [" rn rm load/store-offset))
262 (cond :field (byte 4 28) :type 'condition-code)
263 (opcode-3 :field (byte 3 25))
264 (load/store-offset :fields (list (byte 1 24)
265 (byte 1 23)
266 (byte 1 21)
267 (byte 7 5))
268 :type 'load/store-register)
269 (opcode-b :field (byte 1 22))
270 (opcode-l :field (byte 1 20))
271 (opcode-0 :field (byte 1 4))
272 (rn :field (byte 4 16) :type 'reg)
273 (rd :field (byte 4 12) :type 'reg)
274 (rm :field (byte 4 0) :type 'reg))
276 (sb!disassem:define-instruction-format
277 (swi 32 :default-printer '(:name cond :tab "#" swi-number))
278 (cond :field (byte 4 28) :type 'condition-code)
279 (opcode-4 :field (byte 4 24))
280 (swi-number :field (byte 24 0)))
282 (sb!disassem:define-instruction-format
283 (debug-trap 32 :default-printer '(:name :tab code))
284 (opcode-32 :field (byte 32 0))
285 (code :type 'debug-trap-code :reader debug-trap-code))
287 (sb!disassem:define-instruction-format
288 (msr-immediate 32
289 :default-printer '(:name cond :tab field-mask ", #" immediate))
290 (cond :field (byte 4 28) :type 'condition-code)
291 (opcode-5 :field (byte 5 23) :value #b00110)
292 (field-mask :fields (list (byte 1 22) (byte 4 16)) :type 'msr-field-mask)
293 (opcode-2 :field (byte 2 20) :value #b10)
294 (sbo :field (byte 4 12) :value #b1111)
295 (immediate :field (byte 12 0) :type 'shifter-immediate))
297 (sb!disassem:define-instruction-format
298 (msr-register 32
299 :default-printer '(:name cond :tab field-mask ", " rm))
300 (cond :field (byte 4 28) :type 'condition-code)
301 (opcode-5 :field (byte 5 23) :value #b00010)
302 (field-mask :fields (list (byte 1 22) (byte 4 16)) :type 'msr-field-mask)
303 (opcode-2 :field (byte 2 20) :value #b10)
304 (sbo :field (byte 4 12) :value #b1111)
305 (sbz :field (byte 8 4) :value #b00000000)
306 (rm :field (byte 4 0) :type 'reg))
308 (sb!disassem:define-instruction-format
309 (multiply-dzsm 32
310 :default-printer '(:name cond :tab rd ", " rs ", " rm))
311 (cond :field (byte 4 28) :type 'condition-code)
312 (opcode-8 :field (byte 8 20))
313 (rd :field (byte 4 16) :type 'reg)
314 (sbz :field (byte 4 12) :value 0)
315 (rs :field (byte 4 8) :type 'reg)
316 (opcode-4 :field (byte 4 4))
317 (rm :field (byte 4 0) :type 'reg))
319 (sb!disassem:define-instruction-format
320 (multiply-dnsm 32
321 :default-printer '(:name cond :tab rd ", " rs ", " rm ", " num))
322 (cond :field (byte 4 28) :type 'condition-code)
323 (opcode-8 :field (byte 8 20))
324 (rd :field (byte 4 16) :type 'reg)
325 (num :field (byte 4 12) :type 'reg)
326 (rs :field (byte 4 8) :type 'reg)
327 (opcode-4 :field (byte 4 4))
328 (rm :field (byte 4 0) :type 'reg))
330 (sb!disassem:define-instruction-format
331 (multiply-ddsm 32
332 :default-printer '(:name cond :tab rdlo ", " rdhi ", " rs ", " rm))
333 (cond :field (byte 4 28) :type 'condition-code)
334 (opcode-8 :field (byte 8 20))
335 (rdhi :field (byte 4 16) :type 'reg)
336 (rdlo :field (byte 4 12) :type 'reg)
337 (rs :field (byte 4 8) :type 'reg)
338 (opcode-4 :field (byte 4 4))
339 (rm :field (byte 4 0) :type 'reg))
341 ;;;; special magic to support decoding internal-error and related traps
343 ;; snarf-error-junk is basically identical on all platforms that
344 ;; define it (meaning, not Alpha). Shouldn't it be common somewhere?
345 (defun snarf-error-junk (sap offset &optional length-only)
346 (let* ((length (sb!sys:sap-ref-8 sap offset))
347 (vector (make-array length :element-type '(unsigned-byte 8))))
348 (declare (type sb!sys:system-area-pointer sap)
349 (type (unsigned-byte 8) length)
350 (type (simple-array (unsigned-byte 8) (*)) vector))
351 (cond (length-only
352 (values 0 (1+ length) nil nil))
354 (sb!kernel:copy-ub8-from-system-area sap (1+ offset)
355 vector 0 length)
356 (collect ((sc-offsets)
357 (lengths))
358 (lengths 1) ; the length byte
359 (let* ((index 0)
360 (error-number (sb!c:read-var-integer vector index)))
361 (lengths index)
362 (loop
363 (when (>= index length)
364 (return))
365 (let ((old-index index))
366 (sc-offsets (sb!c:read-var-integer vector index))
367 (lengths (- index old-index))))
368 (values error-number
369 (1+ length)
370 (sc-offsets)
371 (lengths))))))))
373 (defun debug-trap-control (chunk inst stream dstate)
374 (declare (ignore inst))
375 (flet ((nt (x) (if stream (sb!disassem:note x dstate))))
376 (case (debug-trap-code chunk dstate)
377 (#.halt-trap
378 (nt "Halt trap"))
379 (#.pending-interrupt-trap
380 (nt "Pending interrupt trap"))
381 (#.error-trap
382 (nt "Error trap")
383 (sb!disassem:handle-break-args #'snarf-error-junk stream dstate))
384 (#.cerror-trap
385 (nt "Cerror trap")
386 (sb!disassem:handle-break-args #'snarf-error-junk stream dstate))
387 (#.breakpoint-trap
388 (nt "Breakpoint trap"))
389 (#.fun-end-breakpoint-trap
390 (nt "Function end breakpoint trap"))
391 (#.single-step-around-trap
392 (nt "Single step around trap"))
393 (#.single-step-before-trap
394 (nt "Single step before trap")))))
396 ;;;; primitive emitters
398 ;(define-bitfield-emitter emit-word 16
399 ; (byte 16 0))
401 (define-bitfield-emitter emit-word 32
402 (byte 32 0))
404 ;;;; fixup emitters
406 (defun emit-absolute-fixup (segment fixup)
407 (note-fixup segment :absolute fixup)
408 (let ((offset (fixup-offset fixup)))
409 (if (label-p offset)
410 (emit-back-patch segment
411 4 ; FIXME: n-word-bytes
412 (lambda (segment posn)
413 (declare (ignore posn))
414 (emit-dword segment
415 (- (+ (component-header-length)
416 (or (label-position offset)
418 other-pointer-lowtag))))
419 (emit-dword segment (or offset 0)))))
421 (defun emit-relative-fixup (segment fixup)
422 (note-fixup segment :relative fixup)
423 (emit-dword segment (or (fixup-offset fixup) 0)))
426 ;;;; miscellaneous hackery
428 (defun register-p (thing)
429 (and (tn-p thing)
430 (eq (sb-name (sc-sb (tn-sc thing))) 'registers)))
432 (defmacro with-condition-defaulted ((argvar arglist) &body body)
433 (let ((internal-emitter (gensym)))
434 `(flet ((,internal-emitter ,arglist
435 ,@body))
436 (if (assoc (car ,argvar) *conditions*)
437 (apply #',internal-emitter ,argvar)
438 (apply #',internal-emitter :al ,argvar)))))
440 (define-instruction byte (segment byte)
441 (:emitter
442 (emit-byte segment byte)))
444 ;(define-instruction word (segment word)
445 ; (:emitter
446 ; (emit-word segment word)))
448 (define-instruction word (segment word)
449 (:emitter
450 (etypecase word
451 (fixup
452 (note-fixup segment :absolute word)
453 (emit-word segment 0))
454 (integer
455 (emit-word segment word)))))
457 (defun emit-header-data (segment type)
458 (emit-back-patch segment
460 (lambda (segment posn)
461 (emit-word segment
462 (logior type
463 (ash (+ posn
464 (component-header-length))
465 (- n-widetag-bits
466 word-shift)))))))
468 (define-instruction simple-fun-header-word (segment)
469 (:emitter
470 (emit-header-data segment simple-fun-header-widetag)))
472 (define-instruction lra-header-word (segment)
473 (:emitter
474 (emit-header-data segment return-pc-header-widetag)))
476 ;;;; Addressing mode 1 support
478 ;;; Addressing mode 1 has some 11 formats. These are immediate,
479 ;;; register, and nine shift/rotate functions based on one or more
480 ;;; registers. As the mnemonics used for these functions are not
481 ;;; currently used, we simply define them as constructors for a
482 ;;; shifter-operand structure, similar to the make-ea function in the
483 ;;; x86 backend.
485 (defstruct shifter-operand
486 register
487 function-code
488 operand)
490 (defun lsl (register operand)
491 (aver (register-p register))
492 (aver (or (register-p operand)
493 (typep operand '(integer 0 31))))
495 (make-shifter-operand :register register :function-code 0 :operand operand))
497 (defun lsr (register operand)
498 (aver (register-p register))
499 (aver (or (register-p operand)
500 (typep operand '(integer 1 32))))
502 (make-shifter-operand :register register :function-code 1 :operand operand))
504 (defun asr (register operand)
505 (aver (register-p register))
506 (aver (or (register-p operand)
507 (typep operand '(integer 1 32))))
509 (make-shifter-operand :register register :function-code 2 :operand operand))
511 (defun ror (register operand)
512 ;; ROR is a special case: the encoding for ROR with an immediate
513 ;; shift of 32 (0) is actually RRX.
514 (aver (register-p register))
515 (aver (or (register-p operand)
516 (typep operand '(integer 1 31))))
518 (make-shifter-operand :register register :function-code 3 :operand operand))
520 (defun rrx (register)
521 ;; RRX is a special case: it is encoded as ROR with an immediate
522 ;; shift of 32 (0), and has no operand.
523 (aver (register-p register))
525 (make-shifter-operand :register register :function-code 3 :operand 0))
527 (define-condition cannot-encode-immediate-operand (error)
528 ((value :initarg value)))
530 (defun encode-shifter-immediate (operand)
531 ;; 32-bit immediate data is encoded as an 8-bit immediate data value
532 ;; and a 4-bit immediate shift count. The actual value is the
533 ;; immediate data rotated right by a number of bits equal to twice
534 ;; the shift count. Note that this means that there are a limited
535 ;; number of valid immediate integers and that some integers have
536 ;; multiple possible encodings. In the case of multiple encodings,
537 ;; the correct one to use is the one with the lowest shift count.
539 ;; XXX: Is it possible to determine the correct encoding in constant
540 ;; time, rather than time proportional to the final shift count? Is
541 ;; it possible to determine if a given integer is valid without
542 ;; attempting to encode it? Are such solutions cheaper (either time
543 ;; or spacewise) than simply attempting to encode it?
544 (labels ((try-immediate-encoding (value shift)
545 (unless (<= 0 shift 15)
546 (error 'cannot-encode-immediate-operand :value operand))
547 (if (typep value '(unsigned-byte 8))
548 (dpb shift (byte 4 8) value)
549 (try-immediate-encoding (dpb value (byte 30 2)
550 (ldb (byte 2 30) value))
551 (1+ shift)))))
552 (try-immediate-encoding operand 0)))
554 (defun encode-shifter-operand (operand)
555 (etypecase operand
556 (integer
557 (dpb 1 (byte 1 25) (encode-shifter-immediate operand)))
560 (cond
561 ((eq 'registers (sb-name (sc-sb (tn-sc operand))))
562 ;; For those wondering, this is LSL immediate for 0 bits.
563 (tn-offset operand))
565 ((eq 'null (sc-name (tn-sc operand)))
566 null-offset)
568 (t (error "Don't know how to encode TN ~A as a SHIFTER-OPERAND" operand))))
570 (shifter-operand
571 (let ((Rm (tn-offset (shifter-operand-register operand)))
572 (shift-code (shifter-operand-function-code operand))
573 (shift-amount (shifter-operand-operand operand)))
574 (etypecase shift-amount
575 (integer
576 (dpb shift-amount (byte 5 7)
577 (dpb shift-code (byte 2 5)
578 Rm)))
580 (dpb (tn-offset shift-amount) (byte 4 8)
581 (dpb shift-code (byte 2 5)
582 (dpb 1 (byte 1 4)
583 Rm)))))))))
585 (defmacro composite-immediate-instruction (op r x y &key fixnumize neg-op invert-y invert-r single-op-op first-op first-no-source)
586 ;; Successively applies 8-bit wide chunks of Y to X using OP storing the result in R.
588 ;; If FIXNUMIZE is true, Y is fixnumized before being used.
589 ;; If NEG-OP is given and Y is negative, NEG-OP is used instead of OP.
590 ;; If INVERT-Y is given LOGNOT is applied to Y before it being used (but after possibly
591 ;; being fixnumized.
592 ;; If INVERT-R is given R is bit wise inverted at the end.
593 ;; If SINGLE-OP-OP is given and (possibly fixnumized) Y fits into a single ARM immediate
594 ;; it is used for a single operation instead of OP.
595 ;; If FIRST-OP is given, it is used in the first iteration instead of OP.
596 ;; If FIRST-NO-SOURCE is given, there will be ne source register (X) in the first iteration.
597 (let ((bytespec (gensym "bytespec"))
598 (value (gensym "value"))
599 (transformed (gensym "transformed")))
600 (labels ((instruction (source-reg op neg-op &optional no-source)
601 `(,@(if neg-op
602 `((if (< ,y 0)
603 (inst ,neg-op ,r ,@(when (not no-source)`(,source-reg))
604 (mask-field ,bytespec ,value))
605 (inst ,op ,r ,@(when (not no-source) `(,source-reg))
606 (mask-field ,bytespec ,value))))
607 `((inst ,op ,r ,@(when (not no-source) `(,source-reg))
608 (mask-field ,bytespec ,value))))
609 (setf (ldb ,bytespec ,value) 0)))
610 (composite ()
611 `((let ((,bytespec (byte 8 (logandc1 1 (lowest-set-bit-index ,value)))))
612 ,@(instruction x (or first-op op) neg-op first-no-source))
613 (do ((,bytespec (byte 8 (logandc1 1 (lowest-set-bit-index ,value)))
614 (byte 8 (logandc1 1 (lowest-set-bit-index ,value)))))
615 ((zerop ,value))
616 ,@(instruction r op neg-op)
617 ,@(when invert-r
618 `((inst mvn ,r ,r)))))))
619 `(let* ((,transformed ,(if fixnumize
620 `(fixnumize ,y)
621 `,y))
622 (,value (ldb (byte 32 0)
623 ,@(if neg-op
624 `((if (< ,transformed 0) (- ,transformed) ,transformed))
625 (if invert-y
626 `((lognot ,transformed))
627 `(,transformed))))))
628 ,@(if single-op-op
629 `((handler-case
630 (progn
631 (inst ,single-op-op ,r ,x ,transformed))
632 (cannot-encode-immediate-operand ()
633 ,@(composite))))
634 (composite))))))
637 ;;;; Addressing mode 2 support
639 ;;; Addressing mode 2 ostensibly has 9 formats. These are formed from
640 ;;; a cross product of three address calculations and three base
641 ;;; register writeback modes. As one of the address calculations is a
642 ;;; scaled register calculation identical to the mode 1 register shift
643 ;;; by constant, we reuse the shifter-operand structure and its public
644 ;;; constructors.
646 (defstruct memory-operand
647 base
648 offset
649 direction
650 mode)
652 ;;; The @ macro is used to encode a memory addressing mode. The
653 ;;; parameters for the base form are a base register, an optional
654 ;;; offset (either an integer, a register tn or a shifter-operand
655 ;;; structure with a constant shift amount, optionally within a unary
656 ;;; - form), and a base register writeback mode (either :offset,
657 ;;; :pre-index, or :post-index). The alternative form uses a label as
658 ;;; the base register, and accepts only (optionally negated) integers
659 ;;; as offsets, and requires a mode of :offset.
660 (defun %@ (base offset direction mode)
661 (when (label-p base)
662 (aver (eq mode :offset))
663 (aver (integerp offset)))
665 (when (shifter-operand-p offset)
666 (aver (integerp (shifter-operand-operand offset))))
668 ;; Fix up direction with negative offsets.
669 (when (and (not (label-p base))
670 (integerp offset)
671 (< offset 0))
672 (setf offset (- offset))
673 (setf direction (if (eq direction :up) :down :up)))
675 (make-memory-operand :base base :offset offset
676 :direction direction :mode mode))
678 (defmacro @ (base &optional (offset 0) (mode :offset))
679 (let* ((direction (if (and (consp offset)
680 (eq (car offset) '-)
681 (null (cddr offset)))
682 :down
683 :up))
684 (offset (if (eq direction :down) (cadr offset) offset)))
685 `(%@ ,base ,offset ,direction ,mode)))
687 ;;;; Data-processing instructions
689 ;;; Data processing instructions have a 4-bit opcode field and a 1-bit
690 ;;; "S" field for updating condition bits. They are adjacent, so we
691 ;;; roll them into one 5-bit field for convenience.
693 (define-bitfield-emitter emit-dp-instruction 32
694 (byte 4 28) (byte 2 26) (byte 1 25) (byte 5 20)
695 (byte 4 16) (byte 4 12) (byte 12 0))
697 ;;; There are 16 data processing instructions, with a breakdown as
698 ;;; follows:
700 ;;; 1.) Two "move" instructions, with no "source" operand (they have
701 ;;; destination and shifter operands only).
703 ;;; 2.) Four "test" instructions, with no "destination" operand.
704 ;;; These instructions always have their "S" bit set, though it
705 ;;; is not specified in their mnemonics.
707 ;;; 3.) Ten "normal" instructions, with all three operands.
709 ;;; Aside from this, the instructions all have a regular encoding, so
710 ;;; we can use a single macro to define them.
712 (defmacro define-data-processing-instruction (instruction opcode dest-p src-p)
713 `(define-instruction ,instruction (segment &rest args)
714 (:printer dp-shift-immediate ((opcode-8 ,opcode)
715 ,@(unless dest-p '((rd 0)))
716 ,@(unless src-p '((rn 0))))
717 ,@(cond
718 ((not dest-p)
719 '('(:name cond :tab rn ", " rm shift)))
720 ((not src-p)
721 '('(:name cond :tab rd ", " rm shift)))))
722 (:printer dp-shift-register ((opcode-8 ,opcode)
723 ,@(unless dest-p '((rd 0)))
724 ,@(unless src-p '((rn 0))))
725 ,@(cond
726 ((not dest-p)
727 '('(:name cond :tab rn ", " rm ", " shift-type " " rs)))
728 ((not src-p)
729 '('(:name cond :tab rd ", " rm ", " shift-type " " rs)))))
730 (:printer dp-immediate ((opcode-8 ,(logior opcode #x20))
731 ,@(unless dest-p '((rd 0)))
732 ,@(unless src-p '((rn 0))))
733 ,@(cond
734 ((not dest-p)
735 '('(:name cond :tab rn ", " immediate)))
736 ((not src-p)
737 '('(:name cond :tab rd ", " immediate)))))
738 (:emitter
739 (with-condition-defaulted (args (condition ,@(if dest-p '(dest))
740 ,@(if src-p '(src))
741 shifter-operand))
742 ,(if dest-p '(aver (register-p dest)))
743 ,(if src-p '(aver (register-p src)))
744 (let ((shifter-operand (encode-shifter-operand shifter-operand)))
745 (emit-dp-instruction segment
746 (conditional-opcode condition)
748 (ldb (byte 1 25) shifter-operand)
749 ,opcode
750 ,(if src-p '(tn-offset src) 0)
751 ,(if dest-p '(tn-offset dest) 0)
752 (ldb (byte 12 0) shifter-operand)))))))
754 (define-data-processing-instruction and #x00 t t)
755 (define-data-processing-instruction ands #x01 t t)
756 (define-data-processing-instruction eor #x02 t t)
757 (define-data-processing-instruction eors #x03 t t)
758 (define-data-processing-instruction sub #x04 t t)
759 (define-data-processing-instruction subs #x05 t t)
760 (define-data-processing-instruction rsb #x06 t t)
761 (define-data-processing-instruction rsbs #x07 t t)
762 (define-data-processing-instruction add #x08 t t)
763 (define-data-processing-instruction adds #x09 t t)
764 (define-data-processing-instruction adc #x0a t t)
765 (define-data-processing-instruction adcs #x0b t t)
766 (define-data-processing-instruction sbc #x0c t t)
767 (define-data-processing-instruction sbcs #x0d t t)
768 (define-data-processing-instruction rsc #x0e t t)
769 (define-data-processing-instruction rscs #x0f t t)
770 (define-data-processing-instruction orr #x18 t t)
771 (define-data-processing-instruction orrs #x19 t t)
772 (define-data-processing-instruction bic #x1c t t)
773 (define-data-processing-instruction bics #x1d t t)
775 (define-data-processing-instruction tst #x11 nil t)
776 (define-data-processing-instruction teq #x13 nil t)
777 (define-data-processing-instruction cmp #x15 nil t)
778 (define-data-processing-instruction cmn #x17 nil t)
780 (define-data-processing-instruction mov #x1a t nil)
781 (define-data-processing-instruction movs #x1b t nil)
782 (define-data-processing-instruction mvn #x1e t nil)
783 (define-data-processing-instruction mvns #x1f t nil)
785 ;;;; Exception-generating instructions
787 ;;; There are two exception-generating instructions. One, BKPT, is
788 ;;; ostensibly used as a breakpoint instruction, and to communicate
789 ;;; with debugging hardware. The other, SWI, is intended for use as a
790 ;;; system call interface. We need both because, at least on some
791 ;;; platforms, the only breakpoint trap that works properly is a
792 ;;; syscall.
794 (define-bitfield-emitter emit-swi-instruction 32
795 (byte 4 28) (byte 4 24) (byte 24 0))
797 (define-instruction swi (segment &rest args)
798 (:printer swi ((opcode-4 #b1111)))
799 (:emitter
800 (with-condition-defaulted (args (condition code))
801 (emit-swi-instruction segment
802 (conditional-opcode condition)
803 #b1111 code))))
805 (define-bitfield-emitter emit-bkpt-instruction 32
806 (byte 4 28) (byte 8 20) (byte 12 8) (byte 4 4) (byte 4 0))
808 (define-instruction bkpt (segment code)
809 (:emitter
810 (emit-bkpt-instruction segment #b1110 #b00010010
811 (ldb (byte 12 4) code)
812 #b0111
813 (ldb (byte 4 0) code))))
815 ;;; It turns out that the Linux kernel decodes this particular
816 ;;; officially undefined instruction as a single-instruction SIGTRAP
817 ;;; generation instruction, or breakpoint.
818 (define-instruction debug-trap (segment)
819 (:printer debug-trap ((opcode-32 #xe7f001f0))
820 :default :control #'debug-trap-control)
821 (:emitter
822 (emit-word segment #xe7f001f0)))
824 ;;;; Miscellaneous arithmetic instructions
826 (define-bitfield-emitter emit-clz-instruction 32
827 (byte 4 28) (byte 12 16) (byte 4 12) (byte 8 4) (byte 4 0))
829 (define-instruction clz (segment &rest args)
830 (:printer dp-shift-register ((opcode-8 #b00010110)
831 (rn #b1111)
832 (rs #b1111)
833 (shift-type #b00))
834 '(:name cond :tab rd ", " rm))
835 (:emitter
836 (with-condition-defaulted (args (condition dest src))
837 (aver (register-p dest))
838 (aver (register-p src))
839 (emit-clz-instruction segment (conditional-opcode condition)
840 #b000101101111
841 (tn-offset dest)
842 #b11110001
843 (tn-offset src)))))
845 ;;;; Branch instructions
847 (define-bitfield-emitter emit-branch-instruction 32
848 (byte 4 28) (byte 4 24) (byte 24 0))
850 (defun emit-branch-back-patch (segment condition opcode dest)
851 (emit-back-patch segment 4
852 (lambda (segment posn)
853 (emit-branch-instruction segment
854 (conditional-opcode condition)
855 opcode
856 (ldb (byte 24 2)
857 (- (label-position dest)
858 (+ posn 8)))))))
860 (define-instruction b (segment &rest args)
861 (:printer branch ((opcode-4 #b1010)))
862 (:emitter
863 (with-condition-defaulted (args (condition dest))
864 (aver (label-p dest))
865 (emit-branch-back-patch segment condition #b1010 dest))))
867 (define-instruction bl (segment &rest args)
868 (:printer branch ((opcode-4 #b1011)))
869 (:emitter
870 (with-condition-defaulted (args (condition dest))
871 (aver (label-p dest))
872 (emit-branch-back-patch segment condition #b1011 dest))))
874 (define-bitfield-emitter emit-branch-exchange-instruction 32
875 (byte 4 28) (byte 8 20) (byte 4 16) (byte 4 12)
876 (byte 4 8) (byte 4 4) (byte 4 0))
878 (define-instruction bx (segment &rest args)
879 (:emitter
880 (with-condition-defaulted (args (condition dest))
881 (aver (register-p dest))
882 (emit-branch-exchange-instruction segment
883 (conditional-opcode condition)
884 #b00010010 #b1111 #b1111
885 #b1111 #b0001 (tn-offset dest)))))
887 (define-instruction blx (segment &rest args)
888 (:emitter
889 (with-condition-defaulted (args (condition dest))
890 (aver (register-p dest))
891 (emit-branch-exchange-instruction segment
892 (conditional-opcode condition)
893 #b00010010 #b1111 #b1111
894 #b1111 #b0011 (tn-offset dest)))))
896 ;;;; Semaphore instructions
898 (defun emit-semaphore-instruction (segment opcode condition dest value address)
899 (aver (register-p dest))
900 (aver (register-p value))
901 (aver (memory-operand-p address))
902 (aver (zerop (memory-operand-offset address)))
903 (aver (eq :offset (memory-operand-mode address)))
904 (emit-dp-instruction segment (conditional-opcode condition)
905 #b00 0 opcode (tn-offset (memory-operand-base address))
906 (tn-offset dest)
907 (dpb #b1001 (byte 4 4) (tn-offset value))))
909 (define-instruction swp (segment &rest args)
910 (:emitter
911 (with-condition-defaulted (args (condition dest value address))
912 (emit-semaphore-instruction segment #b10000
913 condition dest value address))))
915 (define-instruction swpb (segment &rest args)
916 (:emitter
917 (with-condition-defaulted (args (condition dest value address))
918 (emit-semaphore-instruction segment #b10100
919 condition dest value address))))
921 ;;;; Status-register instructions
923 (define-instruction mrs (segment &rest args)
924 (:printer dp-shift-immediate ((opcode-8 #b0010000)
925 (rn #b1111)
926 (shift '(0 0))
927 (rm 0))
928 '(:name cond :tab rd ", CPSR"))
929 (:printer dp-shift-immediate ((opcode-8 #b0010100)
930 (rn #b1111)
931 (shift '(0 0))
932 (rm 0))
933 '(:name cond :tab rd ", SPSR"))
934 (:emitter
935 (with-condition-defaulted (args (condition dest reg))
936 (aver (register-p dest))
937 (aver (member reg '(:cpsr :spsr)))
938 (emit-dp-instruction segment (conditional-opcode condition)
939 #b00 0 (if (eq reg :cpsr) #b10000 #b10100)
940 #b1111 (tn-offset dest) 0))))
942 (defun encode-status-register-fields (fields)
943 (let ((fields (string fields)))
944 (labels ((frob (mask index)
945 (let* ((field (aref fields index))
946 (field-mask (cdr (assoc field
947 '((#\C . #b0001) (#\X . #b0010)
948 (#\S . #b0100) (#\F . #b1000))
949 :test #'char=))))
950 (unless field-mask
951 (error "bad status register field desginator ~S" fields))
952 (if (< (1+ index) (length fields))
953 (frob (logior mask field-mask) (1+ index))
954 (logior mask field-mask)))))
955 (frob 0 0))))
957 (defmacro cpsr (fields)
958 (encode-status-register-fields fields))
960 (defmacro spsr (fields)
961 (logior #b10000 (encode-status-register-fields fields)))
963 (define-instruction msr (segment &rest args)
964 (:printer msr-immediate ())
965 (:printer msr-register ())
966 (:emitter
967 (with-condition-defaulted (args (condition field-mask src))
968 (aver (or (register-p src)
969 (integerp src)))
970 (let ((encoded-src (encode-shifter-operand src)))
971 (emit-dp-instruction segment (conditional-opcode condition)
972 #b00 (ldb (byte 1 25) encoded-src)
973 (if (logbitp 4 field-mask) #b10110 #b10010)
974 field-mask #b1111
975 (ldb (byte 12 0) encoded-src))))))
977 ;;;; Multiply instructions
979 (define-bitfield-emitter emit-multiply-instruction 32
980 (byte 4 28) (byte 8 20) (byte 4 16) (byte 4 12)
981 (byte 4 8) (byte 4 4) (byte 4 0))
983 (macrolet
984 ((define-multiply-instruction (name field-mapping opcode1 opcode2)
985 (let ((arglist (ecase field-mapping
986 (:dzsm '(dest src multiplicand))
987 (:dnsm '(dest src multiplicand num))
988 (:ddsm '(dest-lo dest src multiplicand)))))
989 `(define-instruction ,name (segment &rest args)
990 (:printer ,(symbolicate 'multiply- field-mapping)
991 ((opcode-8 ,opcode1)
992 (opcode-4 ,opcode2)))
993 (:emitter
994 (with-condition-defaulted (args (condition ,@arglist))
995 ,@(loop
996 for arg in arglist
997 collect `(aver (register-p ,arg)))
998 (emit-multiply-instruction segment (conditional-opcode condition)
999 ,opcode1
1000 (tn-offset dest)
1001 ,(ecase field-mapping
1002 (:dzsm 0)
1003 (:dnsm '(tn-offset num))
1004 (:ddsm '(tn-offset dest-lo)))
1005 (tn-offset src)
1006 ,opcode2
1007 (tn-offset multiplicand))))))))
1009 (define-multiply-instruction mul :dzsm #b00000000 #b1001)
1010 (define-multiply-instruction muls :dzsm #b00000001 #b1001)
1011 (define-multiply-instruction mla :dnsm #b00000010 #b1001)
1012 (define-multiply-instruction mlas :dnsm #b00000011 #b1001)
1014 (define-multiply-instruction umull :ddsm #b00001000 #b1001)
1015 (define-multiply-instruction umulls :ddsm #b00001001 #b1001)
1016 (define-multiply-instruction umlal :ddsm #b00001010 #b1001)
1017 (define-multiply-instruction umlals :ddsm #b00001011 #b1001)
1019 (define-multiply-instruction smull :ddsm #b00001100 #b1001)
1020 (define-multiply-instruction smulls :ddsm #b00001101 #b1001)
1021 (define-multiply-instruction smlal :ddsm #b00001110 #b1001)
1022 (define-multiply-instruction smlals :ddsm #b00001111 #b1001)
1024 (define-multiply-instruction smlabb :dnsm #b00010000 #b1000)
1025 (define-multiply-instruction smlatb :dnsm #b00010000 #b1010)
1026 (define-multiply-instruction smlabt :dnsm #b00010000 #b1100)
1027 (define-multiply-instruction smlatt :dnsm #b00010000 #b1110)
1029 (define-multiply-instruction smlalbb :ddsm #b00010100 #b1000)
1030 (define-multiply-instruction smlaltb :ddsm #b00010100 #b1010)
1031 (define-multiply-instruction smlalbt :ddsm #b00010100 #b1100)
1032 (define-multiply-instruction smlaltt :ddsm #b00010100 #b1110)
1034 (define-multiply-instruction smulbb :dzsm #b00010110 #b1000)
1035 (define-multiply-instruction smultb :dzsm #b00010110 #b1010)
1036 (define-multiply-instruction smulbt :dzsm #b00010110 #b1100)
1037 (define-multiply-instruction smultt :dzsm #b00010110 #b1110)
1039 (define-multiply-instruction smlawb :dnsm #b00010010 #b1000)
1040 (define-multiply-instruction smlawt :dnsm #b00010010 #b1100)
1042 (define-multiply-instruction smulwb :dzsm #b00010010 #b1010)
1043 (define-multiply-instruction smulwt :dzsm #b00010010 #b1110))
1045 ;;;; Load/store instructions
1047 ;;; Emit a load/store instruction. CONDITION is a condition code
1048 ;;; name, KIND is :load or :store, WIDTH is :word or :byte, DATA is a
1049 ;;; register TN and ADDRESS is either a memory-operand structure or a
1050 ;;; stack TN.
1051 (defun emit-load/store-instruction (segment condition kind width data address)
1052 (flet ((compute-opcode (direction mode)
1053 (let ((opcode-bits '(:load #b00001 :store #b00000
1054 :word #b00000 :byte #b00100
1055 :up #b01000 :down #b00000
1056 :offset #b10000
1057 :pre-index #b10010
1058 :post-index #b00000)))
1059 (reduce #'logior (list kind width direction mode)
1060 :key (lambda (value) (getf opcode-bits value))))))
1061 (etypecase address
1062 (memory-operand
1063 (let* ((base (memory-operand-base address))
1064 (offset (memory-operand-offset address))
1065 (direction (memory-operand-direction address))
1066 (mode (memory-operand-mode address))
1067 (cond-bits (conditional-opcode condition)))
1068 (cond
1069 ((label-p base)
1070 (emit-back-patch
1071 segment 4
1072 (lambda (segment posn)
1073 (let* ((label-delta (- (label-position base)
1074 (+ posn 8)))
1075 (offset-delta (if (eq direction :up)
1076 offset
1077 (- offset)))
1078 (overall-delta (+ label-delta
1079 offset-delta))
1080 (absolute-delta (abs overall-delta)))
1081 (aver (typep absolute-delta '(unsigned-byte 12)))
1082 (emit-dp-instruction segment cond-bits #b01 0
1083 (compute-opcode (if (< overall-delta 0)
1084 :down
1085 :up)
1086 mode)
1087 pc-offset (tn-offset data)
1088 absolute-delta)))))
1089 ((integerp offset)
1090 (aver (typep offset '(unsigned-byte 12)))
1091 (emit-dp-instruction segment cond-bits #b01 0
1092 (compute-opcode direction mode)
1093 (tn-offset base) (tn-offset data)
1094 offset))
1096 (emit-dp-instruction segment cond-bits #b01 1
1097 (compute-opcode direction mode)
1098 (tn-offset base) (tn-offset data)
1099 (encode-shifter-operand offset))))))
1101 #+(or)
1103 ;; FIXME: This is for stack TN references, and needs must be
1104 ;; implemented.
1105 ))))
1107 (macrolet
1108 ((define-load/store-instruction (name kind width)
1109 `(define-instruction ,name (segment &rest args)
1110 (:printer load/store-immediate ((opcode-3 #b010)
1111 (opcode-b ,(ecase width
1112 (:word 0)
1113 (:byte 1)))
1114 (opcode-l ,(ecase kind
1115 (:load 1)
1116 (:store 0)))))
1117 (:printer load/store-register ((opcode-3 #b011)
1118 (opcode-0 0)
1119 (opcode-b ,(ecase width
1120 (:word 0)
1121 (:byte 1)))
1122 (opcode-l ,(ecase kind
1123 (:load 1)
1124 (:store 0)))))
1125 (:emitter
1126 (with-condition-defaulted (args (condition reg address))
1127 (aver (or (register-p reg)
1128 ,@(when (eq :store kind)
1129 '((and (tn-p reg)
1130 (eq 'null (sc-name (tn-sc reg))))))))
1131 (emit-load/store-instruction segment condition
1132 ,kind ,width
1133 (if (register-p reg) reg null-tn)
1134 address))))))
1135 (define-load/store-instruction ldr :load :word)
1136 (define-load/store-instruction ldrb :load :byte)
1137 (define-load/store-instruction str :store :word)
1138 (define-load/store-instruction strb :store :byte))
1140 ;;; Emit a miscellaneous load/store instruction. CONDITION is a
1141 ;;; condition code name, OPCODE1 is the low bit of the first opcode
1142 ;;; field, OPCODE2 is the second opcode field, DATA is a register TN
1143 ;;; and ADDRESS is either a memory-operand structure or a stack TN.
1144 (defun emit-misc-load/store-instruction (segment condition opcode1
1145 opcode2 data address)
1146 (flet ((compute-opcode (kind direction mode)
1147 (let ((opcode-bits '(:register #b00000 :immediate #b00100
1148 :up #b01000 :down #b00000
1149 :offset #b10000
1150 :pre-index #b10010
1151 :post-index #b00000)))
1152 (reduce #'logior (list kind direction mode)
1153 :key (lambda (value) (getf opcode-bits value))))))
1154 (etypecase address
1155 (memory-operand
1156 (let* ((base (memory-operand-base address))
1157 (offset (memory-operand-offset address))
1158 (direction (memory-operand-direction address))
1159 (mode (memory-operand-mode address))
1160 (cond-bits (conditional-opcode condition)))
1161 (cond
1162 ((label-p base)
1163 (emit-back-patch
1164 segment 4
1165 (lambda (segment posn)
1166 (let* ((label-delta (- (label-position base)
1167 (+ posn 8)))
1168 (offset-delta (if (eq direction :up)
1169 offset
1170 (- offset)))
1171 (overall-delta (+ label-delta
1172 offset-delta))
1173 (absolute-delta (abs overall-delta)))
1174 (aver (typep absolute-delta '(unsigned-byte 8)))
1175 (emit-multiply-instruction segment cond-bits
1176 (logior opcode1
1177 (compute-opcode :immedaite
1178 (if (< overall-delta 0)
1179 :down
1180 :up)
1181 mode))
1182 (tn-offset base) (tn-offset data)
1183 (ldb (byte 4 4) absolute-delta)
1184 opcode2 absolute-delta)))))
1185 ((integerp offset)
1186 (aver (typep offset '(unsigned-byte 8)))
1187 (emit-multiply-instruction segment cond-bits
1188 (logior opcode1
1189 (compute-opcode :immediate direction mode))
1190 (tn-offset base) (tn-offset data)
1191 (ldb (byte 4 4) offset)
1192 opcode2 offset))
1193 ((register-p offset)
1194 (emit-multiply-instruction segment cond-bits
1195 (logior opcode1
1196 (compute-opcode :register direction mode))
1197 (tn-offset base) (tn-offset data)
1198 0 opcode2 (tn-offset offset)))
1200 (error "bad thing for a miscellaneous load/store address ~S"
1201 address)))))
1203 #+(or)
1205 ;; FIXME: This is for stack TN references, and needs must be
1206 ;; implemented.
1207 ))))
1209 (macrolet
1210 ((define-misc-load/store-instruction (name opcode1 opcode2 double-width)
1211 `(define-instruction ,name (segment &rest args)
1212 (:emitter
1213 (with-condition-defaulted (args (condition reg address))
1214 (aver (register-p reg))
1215 ,(when double-width '(aver (evenp (tn-offset reg))))
1216 (emit-misc-load/store-instruction segment condition
1217 ,opcode1 ,opcode2
1218 reg address))))))
1219 (define-misc-load/store-instruction strh 0 #b1011 nil)
1220 (define-misc-load/store-instruction ldrd 0 #b1101 t)
1221 (define-misc-load/store-instruction strd 0 #b1111 t)
1223 (define-misc-load/store-instruction ldrh 1 #b1011 nil)
1224 (define-misc-load/store-instruction ldrsb 1 #b1101 nil)
1225 (define-misc-load/store-instruction ldrsh 1 #b1111 nil))
1227 ;;;; Boxed-object computation instructions (for LRA and CODE)
1229 ;;; Compute the address of a CODE object by parsing the header of a
1230 ;;; nearby LRA or SIMPLE-FUN.
1231 (define-instruction compute-code (segment code lip object-label temp)
1232 (:vop-var vop)
1233 (:emitter
1234 (emit-back-patch
1235 segment 12
1236 (lambda (segment position)
1237 (assemble (segment vop)
1238 ;; Calculate the address of the code component. This is an
1239 ;; exercise in excess cleverness. First, we calculate (from
1240 ;; our program counter only) the address of OBJECT-LABEL plus
1241 ;; OTHER-POINTER-LOWTAG. The extra two words are to
1242 ;; compensate for the offset applied by ARM CPUs when reading
1243 ;; the program counter.
1244 (inst sub lip pc-tn (- ;; The 8 below is the displacement
1245 ;; from reading the program counter.
1246 (+ position 8)
1247 (+ (label-position object-label)
1248 other-pointer-lowtag)))
1249 ;; Next, we read the function header.
1250 (inst ldr temp (@ lip (- other-pointer-lowtag)))
1251 ;; And finally we use the header value (a count in words),
1252 ;; plus the fact that the top two bits of the widetag are
1253 ;; clear (SIMPLE-FUN-HEADER-WIDETAG is #x2A and
1254 ;; RETURN-PC-HEADER-WIDETAG is #x36) to compute the boxed
1255 ;; address of the code component.
1256 (inst sub code lip (lsr temp (- 8 word-shift))))))))
1258 ;;; Compute the address of a nearby LRA object by dead reckoning from
1259 ;;; the location of the current instruction.
1260 (define-instruction compute-lra (segment dest lip lra-label)
1261 (:vop-var vop)
1262 (:emitter
1263 ;; We can compute the LRA in a single instruction if the overall
1264 ;; offset puts it to within an 8-bit displacement. Otherwise, we
1265 ;; need to load it by parts into LIP until we're down to an 8-bit
1266 ;; displacement, and load the final 8 bits into DEST. We may
1267 ;; safely presume that an overall displacement may be up to 24 bits
1268 ;; wide (the PPC backend has special provision for branches over 15
1269 ;; bits, which implies that segments can become large, but a 16
1270 ;; megabyte segment (24 bits of displacement) is ridiculous), so we
1271 ;; need to cover a range of up to three octets of displacement.
1272 (labels ((compute-delta (position &optional magic-value)
1273 (- (+ (label-position lra-label
1274 (when magic-value position)
1275 magic-value)
1276 other-pointer-lowtag)
1277 ;; The 8 below is the displacement
1278 ;; from reading the program counter.
1279 (+ position 8)))
1281 (load-chunk (segment delta dst src chunk)
1282 (assemble (segment vop)
1283 (if (< delta 0)
1284 (inst sub dst src chunk)
1285 (inst add dst src chunk))))
1287 (three-instruction-emitter (segment position)
1288 (let* ((delta (compute-delta position))
1289 (absolute-delta (abs delta)))
1290 (load-chunk segment delta
1291 lip pc-tn (mask-field (byte 8 16) absolute-delta))
1292 (load-chunk segment delta
1293 lip lip (mask-field (byte 8 8) absolute-delta))
1294 (load-chunk segment delta
1295 dest lip (mask-field (byte 8 0) absolute-delta))))
1297 (two-instruction-emitter (segment position)
1298 (let* ((delta (compute-delta position))
1299 (absolute-delta (abs delta)))
1300 (assemble (segment vop)
1301 (load-chunk segment delta
1302 lip pc-tn (mask-field (byte 8 8) absolute-delta))
1303 (load-chunk segment delta
1304 dest lip (mask-field (byte 8 0) absolute-delta)))))
1306 (one-instruction-emitter (segment position)
1307 (let* ((delta (compute-delta position))
1308 (absolute-delta (abs delta)))
1309 (assemble (segment vop)
1310 (load-chunk segment delta
1311 dest pc-tn absolute-delta))))
1313 (two-instruction-maybe-shrink (segment posn magic-value)
1314 (let ((delta (compute-delta posn magic-value)))
1315 (when (<= (integer-length delta) 8)
1316 (emit-back-patch segment 4
1317 #'one-instruction-emitter)
1318 t)))
1320 (three-instruction-maybe-shrink (segment posn magic-value)
1321 (let ((delta (compute-delta posn magic-value)))
1322 (when (<= (integer-length delta) 16)
1323 (emit-chooser segment 8 2
1324 #'two-instruction-maybe-shrink
1325 #'two-instruction-emitter)
1326 t))))
1327 (emit-chooser
1328 ;; We need to emit up to three instructions, which is 12 octets.
1329 ;; This preserves a mere two bits of alignment.
1330 segment 12 2
1331 #'three-instruction-maybe-shrink
1332 #'three-instruction-emitter))))
1334 ;;; Load a register from a "nearby" LABEL by dead reckoning from the
1335 ;;; location of the current instruction.
1336 (define-instruction load-from-label (segment &rest args)
1337 (:vop-var vop)
1338 (:emitter
1339 (with-condition-defaulted (args (condition dest lip label))
1340 ;; We can load the word addressed by a label in a single
1341 ;; instruction if the overall offset puts it to within a 12-bit
1342 ;; displacement. Otherwise, we need to build an address by parts
1343 ;; into LIP until we're down to a 12-bit displacement, and then
1344 ;; apply the final 12 bits with LDR. For now, we'll allow up to 20
1345 ;; bits of displacement, as that should be easy to implement, and a
1346 ;; megabyte large code object is already a bit unwieldly. If
1347 ;; neccessary, we can expand to a 28 bit displacement.
1348 (labels ((compute-delta (position &optional magic-value)
1349 (- (label-position label
1350 (when magic-value position)
1351 magic-value)
1352 ;; The 8 below is the displacement
1353 ;; from reading the program counter.
1354 (+ position 8)))
1356 (load-chunk (segment delta dst src chunk)
1357 (assemble (segment vop)
1358 (if (< delta 0)
1359 (inst sub condition dst src chunk)
1360 (inst add condition dst src chunk))))
1362 (two-instruction-emitter (segment position)
1363 (let* ((delta (compute-delta position))
1364 (absolute-delta (abs delta)))
1365 (assemble (segment vop)
1366 (load-chunk segment delta
1367 lip pc-tn (mask-field (byte 8 12) absolute-delta))
1368 (inst ldr condition dest (@ lip (mask-field (byte 12 0) delta))))))
1370 (one-instruction-emitter (segment position)
1371 (let* ((delta (compute-delta position)))
1372 (assemble (segment vop)
1373 (inst ldr condition dest (@ pc-tn delta)))))
1375 (two-instruction-maybe-shrink (segment posn magic-value)
1376 (let ((delta (compute-delta posn magic-value)))
1377 (when (<= (integer-length delta) 12)
1378 (emit-back-patch segment 4
1379 #'one-instruction-emitter)
1380 t))))
1381 (emit-chooser
1382 ;; We need to emit up to two instructions, which is 8 octets,
1383 ;; but might wish to emit only one. This preserves a mere two
1384 ;; bits of alignment.
1385 segment 8 2
1386 #'two-instruction-maybe-shrink
1387 #'two-instruction-emitter)))))
1389 ;; data processing floating point instructions
1390 (define-bitfield-emitter emit-fp-dp-instruction 32
1391 (byte 4 28) ; cond
1392 (byte 4 24) ; #b1110
1393 (byte 1 23) ; p
1394 (byte 1 22) ; D
1395 (byte 1 21) ; q
1396 (byte 1 20) ; r
1397 (byte 4 16) ; Fn || extension op
1398 (byte 4 12) ; Fd
1399 (byte 3 9) ; #b101
1400 (byte 1 8) ; double/single precission
1401 (byte 1 7) ; N || extension op
1402 (byte 1 6) ; s
1403 (byte 1 5) ; M
1404 (byte 1 4) ; #b0
1405 (byte 4 0)) ; Fm
1407 (defun low-bit-float-reg (reg-tn)
1408 (logand 1 (tn-offset reg-tn)))
1410 (defun high-bits-float-reg (reg-tn)
1411 (ash (tn-offset reg-tn) -1))
1413 (defmacro define-binary-fp-data-processing-instruction (name precision p q r s)
1414 (let ((precision-flag (ecase precision
1415 (:single 0)
1416 (:double 1))))
1417 `(define-instruction ,name (segment &rest args)
1418 (:emitter
1419 (with-condition-defaulted (args (condition dest op-n op-m))
1420 (emit-fp-dp-instruction segment
1421 (conditional-opcode condition)
1422 #b1110
1424 (low-bit-float-reg dest)
1427 (high-bits-float-reg op-n)
1428 (high-bits-float-reg dest)
1429 #b101
1430 ,precision-flag
1431 (low-bit-float-reg op-n)
1433 (low-bit-float-reg op-m)
1435 (high-bits-float-reg op-m)))))))
1437 (defmacro define-binary-fp-data-processing-instructions (root p q r s)
1438 `(progn
1439 (define-binary-fp-data-processing-instruction ,(symbolicate root 's) :single ,p ,q ,r ,s)
1440 (define-binary-fp-data-processing-instruction ,(symbolicate root 'd) :double ,p ,q ,r ,s)))
1442 (define-binary-fp-data-processing-instructions fmac 0 0 0 0)
1443 (define-binary-fp-data-processing-instructions fnmac 0 0 0 1)
1444 (define-binary-fp-data-processing-instructions fmsc 0 0 1 0)
1445 (define-binary-fp-data-processing-instructions fnmsc 0 0 1 1)
1446 (define-binary-fp-data-processing-instructions fmul 0 1 0 0)
1447 (define-binary-fp-data-processing-instructions fnmul 0 1 0 1)
1448 (define-binary-fp-data-processing-instructions fadd 0 1 1 0)
1449 (define-binary-fp-data-processing-instructions fsub 0 1 1 1)
1450 (define-binary-fp-data-processing-instructions fdiv 1 0 0 0)
1452 ;;; op-m-sbz means that it should-be-zero, and only one register is supplied.
1453 (defmacro define-unary-fp-data-processing-instruction (name precision fn n
1454 &key op-m-sbz)
1455 (let ((precision-flag (ecase precision
1456 (:single 0)
1457 (:double 1))))
1458 `(define-instruction ,name (segment &rest args)
1459 (:emitter
1460 (with-condition-defaulted (args (condition dest
1461 ,@(unless op-m-sbz
1462 '(op-m))))
1463 (emit-fp-dp-instruction segment
1464 (conditional-opcode condition)
1465 #b1110
1467 (low-bit-float-reg dest)
1471 (high-bits-float-reg dest)
1472 #b101
1473 ,precision-flag
1476 ,(if op-m-sbz
1478 '(low-bit-float-reg op-m))
1480 ,(if op-m-sbz
1482 '(high-bits-float-reg op-m))))))))
1484 (defmacro define-unary-fp-data-processing-instructions (root fn n &key op-m-sbz)
1485 `(progn
1486 (define-unary-fp-data-processing-instruction ,(symbolicate root 's) :single ,fn ,n
1487 :op-m-sbz ,op-m-sbz)
1488 (define-unary-fp-data-processing-instruction ,(symbolicate root 'd) :double ,fn ,n
1489 :op-m-sbz ,op-m-sbz)))
1491 (define-unary-fp-data-processing-instructions fcpy #b0000 0)
1492 (define-unary-fp-data-processing-instructions fabs #b0000 1)
1493 (define-unary-fp-data-processing-instructions fneg #b0001 0)
1494 (define-unary-fp-data-processing-instructions fsqrt #b0001 1)
1495 (define-unary-fp-data-processing-instructions fcmp #b0100 0)
1496 (define-unary-fp-data-processing-instructions fcmpe #b0100 1)
1497 (define-unary-fp-data-processing-instructions fcmpz #b0101 0 :op-m-sbz t)
1498 (define-unary-fp-data-processing-instructions fcmpez #b0101 1 :op-m-sbz t)
1499 (define-unary-fp-data-processing-instructions fuito #b1000 0)
1500 (define-unary-fp-data-processing-instructions fsito #b1000 1)
1501 (define-unary-fp-data-processing-instructions ftoui #b1100 0)
1502 (define-unary-fp-data-processing-instructions ftouiz #b1100 1)
1503 (define-unary-fp-data-processing-instructions ftosi #b1101 0)
1504 (define-unary-fp-data-processing-instructions ftosiz #b1101 1)
1506 (define-unary-fp-data-processing-instruction fcvtds :single #b0111 1)
1507 (define-unary-fp-data-processing-instruction fcvtsd :double #b0111 1)
1509 ;;; Load/Store Float Instructions
1511 (define-bitfield-emitter emit-fp-ls-instruction 32
1512 (byte 4 28) ; cond
1513 (byte 3 25) ; #b110
1514 (byte 1 24) ; P
1515 (byte 1 23) ; U
1516 (byte 1 22) ; D
1517 (byte 1 21) ; W
1518 (byte 1 20) ; L
1519 (byte 4 16) ; Rn
1520 (byte 4 12) ; Fd
1521 (byte 3 9) ; #b101
1522 (byte 1 8) ; double/single precission
1523 (byte 8 0)) ; offset
1525 ;; Define a load/store multiple floating point instruction. PRECISION is
1526 ;; :SINGLE for single precision values and :DOUBLE for double precision values.
1527 ;; DIRECTION has to be either :LOAD or :STORE.
1528 ;; If INC-OFFSET is true, the offset part of the instruction will be incremented by 1
1529 ;; indicating in the double case a load/store unknown instruction.
1530 (defmacro define-load-store-multiple-fp-instruction (name precision direction &optional inc-offset)
1531 (let ((precision-flag (ecase precision
1532 (:single 0)
1533 (:double 1)))
1534 (direction-flag (ecase direction
1535 (:load 1)
1536 (:store 0))))
1537 `(define-instruction ,name (segment &rest args)
1538 (:emitter
1539 (with-condition-defaulted (args (condition address base-reg reg-count))
1540 (let* ((mode (cond
1541 ((consp address)
1542 (cdr address))
1543 (t :unindexed)))
1544 (p (ecase mode
1545 ((:unindexed :increment) 0)
1546 ((:decrement) 1)))
1547 (u (ecase mode
1548 ((:unindexed :increment) 1)
1549 ((:decrement) 0)))
1550 (w (ecase mode
1551 ((:unindexed) 0)
1552 ((:increment :decrement) 1))))
1553 (emit-fp-ls-instruction segment
1554 (conditional-opcode condition)
1555 #b110
1558 (low-bit-float-reg base-reg)
1560 ,direction-flag
1561 (tn-offset address)
1562 (high-bits-float-reg base-reg)
1563 #b101
1564 ,precision-flag
1565 ,(ecase precision
1566 (:single 'reg-count)
1567 (:double `(+ (* 2 reg-count)
1568 ,(if inc-offset 1 0)))))))))))
1570 ;; multiple single precision
1571 (define-load-store-multiple-fp-instruction fstms :single :store)
1572 (define-load-store-multiple-fp-instruction fldms :single :load)
1573 ;; multiple double precision
1574 (define-load-store-multiple-fp-instruction fstmd :double :store)
1575 (define-load-store-multiple-fp-instruction fldmd :double :load)
1576 ;; multiple double precision registers of unknown content (needs up to 2 * reg-count + 1 words of space)
1577 (define-load-store-multiple-fp-instruction fstmx :double :store t)
1578 (define-load-store-multiple-fp-instruction fldmx :double :load t)
1580 ;; KLUDGE: this group of pseudo-instructions are fragile (no error
1581 ;; handling for the various ways to mis-use them), have no support for
1582 ;; predication, and use the somewhat-broken interface for the
1583 ;; load-store-multiple-fp instructions above.
1584 (define-instruction-macro load-complex-single (dest memory-operand)
1585 `(inst fldms (memory-operand-base ,memory-operand) ,dest 2))
1586 (define-instruction-macro load-complex-double (dest memory-operand)
1587 `(inst fldmd (memory-operand-base ,memory-operand) ,dest 2))
1588 (define-instruction-macro store-complex-single (src memory-operand)
1589 `(inst fstms (memory-operand-base ,memory-operand) ,src 2))
1590 (define-instruction-macro store-complex-double (src memory-operand)
1591 `(inst fstmd (memory-operand-base ,memory-operand) ,src 2))
1593 ;; Define a load/store one floating point instruction. PRECISION is
1594 ;; :SINGLE for single precision values and :DOUBLE for double precision values.
1595 ;; DIRECTION has to be either :LOAD or :STORE.
1596 (defmacro define-load-store-one-fp-instruction (name precision direction)
1597 (let ((precision-flag (ecase precision
1598 (:single 0)
1599 (:double 1)))
1600 (direction-flag (ecase direction
1601 (:load 1)
1602 (:store 0))))
1603 `(define-instruction ,name (segment &rest args)
1604 (:emitter
1605 (with-condition-defaulted (args (condition float-reg memory-operand))
1606 (let ((base (memory-operand-base memory-operand))
1607 (offset (memory-operand-offset memory-operand))
1608 (direction (memory-operand-direction memory-operand)))
1609 (aver (eq (memory-operand-mode memory-operand) :offset))
1610 (aver (and (integerp offset)
1611 (zerop (logand offset 3))))
1612 ;; FIXME: Should support LABEL bases.
1613 (aver (tn-p base))
1614 (emit-fp-ls-instruction segment
1615 (conditional-opcode condition)
1616 #b110
1618 (if (eq direction :up) 1 0)
1619 (low-bit-float-reg float-reg)
1621 ,direction-flag
1622 (tn-offset base)
1623 (high-bits-float-reg float-reg)
1624 #b101
1625 ,precision-flag
1626 (ash offset -2))))))))
1628 (define-load-store-one-fp-instruction fsts :single :store)
1629 (define-load-store-one-fp-instruction flds :single :load)
1630 (define-load-store-one-fp-instruction fstd :double :store)
1631 (define-load-store-one-fp-instruction fldd :double :load)
1634 ;; single register transfer instructions
1636 (define-bitfield-emitter emit-fp-srt-instruction 32
1637 (byte 4 28) ; cond
1638 (byte 4 24) ; #b1110
1639 (byte 3 21) ; opc
1640 (byte 1 20) ; L
1642 (byte 4 16) ; Fn
1643 (byte 4 12) ; Rd
1644 (byte 3 9) ; #b101
1645 (byte 1 8) ; precision
1647 (byte 1 7) ; N
1648 (byte 7 0)) ; #b0010000
1650 (defun system-reg-encoding (float-reg)
1651 (ecase float-reg
1652 (:fpsid #b0000)
1653 (:fpscr #b0001)
1654 (:fpexc #b1000)))
1656 (defmacro define-single-reg-transfer-fp-instruction (name precision direction opcode &optional system-reg)
1657 (let ((precision-flag (ecase precision
1658 (:single 0)
1659 (:double 1)))
1660 (direction-flag (ecase direction
1661 (:to-arm 1)
1662 (:from-arm 0))))
1663 `(define-instruction ,name (segment &rest args)
1664 (:emitter
1665 (with-condition-defaulted (args (condition ,@(if (eq direction :to-arm)
1666 '(arm-reg float-reg)
1667 '(float-reg arm-reg))))
1668 (emit-fp-srt-instruction segment
1669 (conditional-opcode condition)
1670 #b1110
1671 ,opcode
1672 ,direction-flag
1673 ,(if system-reg
1674 '(system-reg-encoding float-reg)
1675 '(high-bits-float-reg float-reg))
1676 (tn-offset arm-reg)
1677 #b101
1678 ,precision-flag
1679 ,(if system-reg
1681 '(low-bit-float-reg float-reg))
1682 #b0010000))))))
1684 (define-single-reg-transfer-fp-instruction fmsr :single :from-arm #b000)
1685 (define-single-reg-transfer-fp-instruction fmrs :single :to-arm #b000)
1686 (define-single-reg-transfer-fp-instruction fmdlr :double :from-arm #b000)
1687 (define-single-reg-transfer-fp-instruction fmrdl :double :to-arm #b000)
1688 (define-single-reg-transfer-fp-instruction fmdhr :double :from-arm #b001)
1689 (define-single-reg-transfer-fp-instruction fmrdh :double :to-arm #b001)
1690 (define-single-reg-transfer-fp-instruction fmxr :single :from-arm #b111 t)
1691 (define-single-reg-transfer-fp-instruction fmrx :single :to-arm #b111 t)
1693 (define-bitfield-emitter emit-fp-trt-instruction 32
1694 (byte 4 28) ; cond
1695 (byte 7 21) ; #b1100010
1696 (byte 1 20) ; L
1697 (byte 4 16) ; Rn
1698 (byte 4 12) ; Rd
1699 (byte 3 9) ; #b101
1700 (byte 1 8) ; precision
1701 (byte 2 6) ; #b00
1702 (byte 1 5) ; M
1703 (byte 1 4) ; #b1
1704 (byte 4 0)) ; Fm
1706 (defmacro define-two-reg-transfer-fp-instruction (name precision direction)
1707 (let ((precision-flag (ecase precision
1708 (:single 0)
1709 (:double 1)))
1710 (direction-flag (ecase direction
1711 (:to-arm 1)
1712 (:from-arm 0))))
1713 `(define-instruction ,name (segment &rest args)
1714 (:emitter
1715 (with-condition-defaulted (args (condition float-reg arm-reg-1 arm-reg-2))
1716 (emit-fp-trt-instruction segment
1717 (conditional-opcode condition)
1718 #b1100010
1719 ,direction-flag
1720 (tn-offset arm-reg-2)
1721 (tn-offset arm-reg-1)
1722 #b101
1723 ,precision-flag
1724 #b00
1725 (low-bit-float-reg float-reg)
1727 (high-bits-float-reg float-reg)))))))
1729 (define-two-reg-transfer-fp-instruction fmsrr :single :from-arm)
1730 (define-two-reg-transfer-fp-instruction fmrrs :single :to-arm)
1731 (define-two-reg-transfer-fp-instruction fmdrr :double :from-arm)
1732 (define-two-reg-transfer-fp-instruction fmrrd :double :to-arm)