1 (in-package "SB!ARM64-ASM")
3 (defun current-instruction (dstate &optional
(offset 0))
4 (sap-ref-int (dstate-segment-sap dstate
)
5 (+ (dstate-cur-offs dstate
) offset
)
7 (dstate-byte-order dstate
)))
9 (defun 32-bit-register-p (dstate)
10 (not (logbitp 31 (current-instruction dstate
))))
12 (defun print-lsl-alias-name (value stream dstate
)
13 (declare (ignore dstate
))
14 (destructuring-bind (immr imms
) value
15 (princ (if (and (/= imms
63)
21 (defun print-lsl-alias (value stream dstate
)
22 (declare (ignore dstate
))
23 (destructuring-bind (immr imms
) value
26 (format stream
"#~d" (- 63 imms
))
27 (format stream
"#~d, #~d" immr imms
))))
29 (defun print-mem-bar-kind (value stream dstate
)
30 (declare (ignore dstate
))
31 (let ((kind (car (rassoc value
**mem-bar-kinds
**))))
34 (format stream
"#~d" value
))))
36 (defun print-shift (value stream dstate
)
37 (declare (ignore dstate
))
38 (destructuring-bind (kind amount
) value
47 (format stream
" #~d" amount
))))
49 (defun print-wide-shift (value stream dstate
)
50 (declare (ignore dstate
))
52 (format stream
", LSL #~d" (* value
16))))
54 (defun print-2-bit-shift (value stream dstate
)
55 (declare (ignore dstate
))
57 (princ ", LSL #12" stream
)))
59 (defun print-extend (value stream dstate
)
60 (destructuring-bind (kind amount
) value
61 (let* ((inst (current-instruction dstate
))
62 (rd (ldb (byte 5 0) inst
))
63 (rn (ldb (byte 5 5) inst
)))
65 (princ (if (and (= kind
#b011
)
80 (format stream
" #~d" amount
))))
82 (defun print-ldr-str-extend (value stream dstate
)
83 (declare (ignore dstate
))
84 (destructuring-bind (kind amount
) value
85 (unless (and (= kind
#b011
)
95 (princ " #3" stream
))))
97 (defun print-immediate (value stream dstate
)
98 (declare (ignore dstate
))
99 (format stream
"#~D" value
))
101 (defun print-test-branch-immediate (value stream dstate
)
102 (declare (ignore dstate
))
104 (dpb (car value
) (byte 1 5) (car value
))))
106 (defun decode-scaled-immediate (value)
107 (destructuring-bind (size opc value simd
) value
109 (ash value
(logior (ash opc
2) size
))
112 (defun print-scaled-immediate (value stream dstate
)
113 (declare (ignore dstate
))
114 (format stream
"#~D" (if (consp value
)
115 (decode-scaled-immediate value
)
118 (defun print-logical-immediate (value stream dstate
)
119 (declare (ignore dstate
))
120 (format stream
"#~D" (apply #'decode-logical-immediate value
)))
122 (defun print-imm-writeback (value stream dstate
)
123 (declare (ignore dstate
))
124 (destructuring-bind (imm mode
) value
125 (let ((imm (sign-extend imm
9)))
130 (format stream
", #~D]" imm
))
132 (format stream
"], #~D" imm
))
134 (format stream
", #~D]!" imm
)))))))
136 (defun decode-pair-scaled-immediate (opc value simd
)
137 (ash (sign-extend value
7)
138 (+ 2 (ash opc
(- (logxor 1 simd
))))))
140 (defun print-pair-imm-writeback (value stream dstate
)
141 (declare (ignore dstate
))
142 (destructuring-bind (mode &rest imm
) value
143 (let ((imm (apply #'decode-pair-scaled-immediate imm
)))
148 (format stream
"], #~D" imm
))
150 (format stream
", #~D]" imm
))
152 (format stream
", #~D]!" imm
)))))))
154 (defun print-w-reg (value stream dstate
)
155 (declare (ignore dstate
))
157 (princ (aref *register-names
* value
) stream
))
159 (defun print-x-reg (value stream dstate
)
160 (declare (ignore dstate
))
161 (princ (aref *register-names
* value
) stream
))
163 (defun print-reg (value stream dstate
)
164 (when (32-bit-register-p dstate
)
166 (princ (aref *register-names
* value
) stream
))
168 (defun print-x-reg-sp (value stream dstate
)
169 (declare (ignore dstate
))
170 (if (= value nsp-offset
)
172 (princ (aref *register-names
* value
) stream
)))
174 (defun print-reg-sp (value stream dstate
)
175 (when (32-bit-register-p dstate
)
177 (if (= value nsp-offset
)
179 (princ (aref *register-names
* value
) stream
)))
181 (defun print-reg-float-reg (value stream dstate
)
182 (let* ((inst (current-instruction dstate
))
183 (v (ldb (byte 1 26) inst
)))
184 (if (= (length value
) 3)
185 (destructuring-bind (size opc reg
) value
189 (princ (svref *register-names
* reg
) stream
))
191 (format stream
"~a~d"
192 (cond ((and (= size
#b10
)
202 (destructuring-bind (size reg
) value
206 (princ (svref *register-names
* reg
) stream
))
208 (format stream
"~a~d"
215 (defun print-float-reg (value stream dstate
)
216 (multiple-value-bind (type value
)
218 (values (car value
) (cadr value
))
219 (values (ldb (byte 1 22) (current-instruction dstate
))
221 (format stream
"~a~d"
227 (defun print-simd-reg (value stream dstate
)
228 (declare (ignore dstate
))
229 (destructuring-bind (size offset
) value
230 (format stream
"V~d.~a" offset
235 (defun lowest-set-bit-index (integer-value)
236 (max 0 (1- (integer-length (logand integer-value
(- integer-value
))))))
238 (defun print-simd-copy-reg (value stream dstate
)
239 (declare (ignore dstate
))
240 (destructuring-bind (offset imm5
&optional imm4
) value
241 (let ((index (lowest-set-bit-index imm5
)))
242 (format stream
"V~d.~a[~a]" offset
246 (ash imm5
(- (1+ index
))))))))
248 (defun print-sys-reg (value stream dstate
)
249 (declare (ignore dstate
))
250 (princ (decode-sys-reg value
) stream
))
252 (defun print-cond (value stream dstate
)
253 (declare (ignore dstate
))
254 (princ (svref *condition-name-vec
* value
) stream
))
256 (defun use-label (value dstate
)
257 (let* ((value (if (consp value
)
258 (logior (ldb (byte 2 0) (car value
))
259 (ash (cadr value
) 2))
261 (address (+ value
(dstate-cur-addr dstate
))))
263 (if (= (logand address lowtag-mask
) other-pointer-lowtag
)
264 (- address
(- other-pointer-lowtag n-word-bytes
))
268 (defun annotate-ldr-str (register offset dstate
)
270 (#.sb
!vm
::code-offset
271 (note-code-constant offset dstate
))
272 (#.sb
!vm
::null-offset
273 (let ((offset (+ sb
!vm
::nil-value offset
)))
274 (maybe-note-assembler-routine offset nil dstate
)
275 (maybe-note-static-symbol (logior offset other-pointer-lowtag
)
278 (#.sb
!vm
::thread-offset
281 (primitive-object-slots
282 (find 'sb
!vm
::thread
*primitive-objects
*
283 :key
#'primitive-object-name
)) t
))
284 (slot (find (ash offset
(- word-shift
)) thread-slots
285 :key
#'slot-offset
)))
287 (note (lambda (stream)
288 (format stream
"thread.~(~A~)" (slot-name slot
)))
291 (defun find-value-from-previos-inst (register dstate
)
292 ;; Needs to be MOVZ REGISTER, imm, LSL #0
293 ;; Should cover most offsets in sane code
294 (let ((inst (current-instruction dstate -
4)))
295 (when (and (= (ldb (byte 9 23) inst
) #b110100101
) ;; MOVZ
296 (= (ldb (byte 5 0) inst
) register
)
297 (= (ldb (byte 2 21) inst
) 0)) ;; LSL #0
298 (ldb (byte 16 5) inst
))))
300 (defun annotate-ldr-str-reg (value stream dstate
)
301 (declare (ignore stream
))
302 (let* ((inst (current-instruction dstate
))
303 (float (ldb-test (byte 1 26) inst
)))
305 (let ((value (find-value-from-previos-inst value dstate
)))
307 (annotate-ldr-str (ldb (byte 5 5) inst
) value dstate
))))))
309 (defun annotate-ldr-str-imm (value stream dstate
)
310 (declare (ignore stream
))
311 (let* ((inst (current-instruction dstate
))
312 (float-reg (ldb-test (byte 1 26) inst
)))
314 (annotate-ldr-str (ldb (byte 5 5) inst
)
316 (decode-scaled-immediate value
)
320 ;;;; special magic to support decoding internal-error and related traps
321 (defun snarf-error-junk (sap offset
&optional length-only
)
322 (let* ((inst (sap-ref-32 sap
(- offset
4)))
323 (error-number (ldb (byte 8 13) inst
))
324 (length (sb!kernel
::error-length error-number
))
326 (declare (type sb
!sys
:system-area-pointer sap
)
327 (type (unsigned-byte 8) length
))
329 (loop repeat length do
(sb!c
::sap-read-var-integerf sap index
))
330 (values 0 (- index offset
) nil nil
))
332 (collect ((sc-offsets)
334 (loop repeat length do
335 (let ((old-index index
))
336 (sc-offsets (sb!c
::sap-read-var-integerf sap index
))
337 (lengths (- index old-index
))))
343 (defun brk-control (chunk inst stream dstate
)
344 (declare (ignore inst chunk
))
345 (let ((code (ldb (byte 8 5) (current-instruction dstate
))))
346 (flet ((nt (x) (if stream
(note x dstate
))))
350 (#.pending-interrupt-trap
351 (nt "Pending interrupt trap"))
354 (handle-break-args #'snarf-error-junk stream dstate
))
357 (handle-break-args #'snarf-error-junk stream dstate
))
359 (nt "Breakpoint trap"))
360 (#.fun-end-breakpoint-trap
361 (nt "Function end breakpoint trap"))
362 (#.single-step-around-trap
363 (nt "Single step around trap"))
364 (#.single-step-before-trap
365 (nt "Single step before trap"))
366 (#.invalid-arg-count-trap
367 (nt "Invalid argument count trap"))))))