1 ;;; the instruction set definition for the Alpha
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
12 (in-package "SB!ALPHA-ASM")
14 (eval-when (:compile-toplevel
:load-toplevel
:execute
)
15 ;; Imports from this package into SB-VM
16 (import '(reg-tn-encoding) 'sb
!vm
)
17 ;; Imports from SB-VM into this package
18 (import '(sb!vm
::zero sb
!vm
::fp-single-zero sb
!vm
::fp-double-zero
19 sb
!vm
::registers sb
!vm
::float-registers
20 sb
!vm
::zero-tn sb
!vm
::fp-single-zero-tn sb
!vm
::fp-double-zero-tn
21 sb
!vm
::zero-offset sb
!vm
::null-offset sb
!vm
::code-offset
)))
23 (setf *disassem-inst-alignment-bytes
* 4)
26 ;;;; utility functions
28 (defun reg-tn-encoding (tn)
30 (values (unsigned-byte 5)))
35 (aver (eq (sb-name (sc-sb (tn-sc tn
))) 'registers
))
38 (defun fp-reg-tn-encoding (tn)
39 (declare (type tn tn
))
41 (fp-single-zero (tn-offset fp-single-zero-tn
))
42 (fp-double-zero (tn-offset fp-double-zero-tn
))
44 (unless (eq (sb-name (sc-sb (tn-sc tn
))) 'float-registers
)
45 (error "~S isn't a floating-point register." tn
))
48 ;;;; initial disassembler setup
50 (defvar *disassem-use-lisp-reg-names
* t
)
52 (defparameter reg-symbols
55 (cond ((null name
) nil
)
56 (t (make-symbol (concatenate 'string
"$" name
)))))
57 sb
!vm
::*register-names
*))
60 :printer
(lambda (value stream dstate
)
61 (declare (stream stream
) (fixnum value
))
62 (let ((regname (aref reg-symbols value
)))
63 (princ regname stream
)
64 (maybe-note-associated-storage-ref
70 (define-arg-type memory-address-annotation
71 :printer
(lambda (value stream dstate
)
72 (declare (ignore stream
))
73 (destructuring-bind (reg offset
) value
76 (note-code-constant offset dstate
))
78 (maybe-note-nil-indexed-object offset dstate
))))))
80 (defparameter float-reg-symbols
82 (loop for n from
0 to
31 collect
(make-symbol (format nil
"~D" n
)))
85 (define-arg-type fp-reg
86 :printer
(lambda (value stream dstate
)
87 (declare (stream stream
) (fixnum value
))
88 (let ((regname (aref float-reg-symbols value
)))
89 (princ regname stream
)
90 (maybe-note-associated-storage-ref
96 (define-arg-type relative-label
98 :use-label
(lambda (value dstate
)
99 (declare (type (signed-byte 21) value
)
100 (type disassem-state dstate
))
101 (+ 4 (ash value
2) (dstate-cur-addr dstate
))))
103 ;;;; DEFINE-INSTRUCTION-FORMATs for the disassembler
105 (define-instruction-format (memory 32
106 :default-printer
'(:name
:tab ra
"," disp
"(" rb
")"
107 memory-address-annotation
))
108 (op :field
(byte 6 26))
109 (ra :field
(byte 5 21) :type
'reg
)
110 (rb :field
(byte 5 16) :type
'reg
)
111 (disp :field
(byte 16 0) :sign-extend t
)
112 (memory-address-annotation :fields
(list (byte 5 16) (byte 16 0))
113 :type
'memory-address-annotation
))
115 (define-instruction-format (jump 32
116 :default-printer
'(:name
:tab ra
",(" rb
")," hint
))
117 (op :field
(byte 6 26))
118 (ra :field
(byte 5 21) :type
'reg
)
119 (rb :field
(byte 5 16) :type
'reg
)
120 (subop :field
(byte 2 14))
121 (hint :field
(byte 14 0)))
123 (define-instruction-format (branch 32
124 :default-printer
'(:name
:tab ra
"," disp
))
125 (op :field
(byte 6 26))
126 (ra :field
(byte 5 21) :type
'reg
)
127 (disp :field
(byte 21 0) :type
'relative-label
))
129 (define-instruction-format (reg-operate 32
130 :default-printer
'(:name
:tab ra
"," rb
"," rc
))
131 (op :field
(byte 6 26))
132 (ra :field
(byte 5 21) :type
'reg
)
133 (rb :field
(byte 5 16) :type
'reg
)
134 (sbz :field
(byte 3 13))
135 (f :field
(byte 1 12) :value
0)
136 (fn :field
(byte 7 5))
137 (rc :field
(byte 5 0) :type
'reg
))
139 (define-instruction-format (lit-operate 32
140 :default-printer
'(:name
:tab ra
"," lit
"," rc
))
141 (op :field
(byte 6 26))
142 (ra :field
(byte 5 21) :type
'reg
)
143 (lit :field
(byte 8 13))
144 (f :field
(byte 1 12) :value
1)
145 (fn :field
(byte 7 5))
146 (rc :field
(byte 5 0) :type
'reg
))
148 (define-instruction-format (fp-operate 32
149 :default-printer
'(:name
:tab fa
"," fb
"," fc
))
150 (op :field
(byte 6 26))
151 (fa :field
(byte 5 21) :type
'fp-reg
)
152 (fb :field
(byte 5 16) :type
'fp-reg
)
153 (fn :field
(byte 11 5))
154 (fc :field
(byte 5 0) :type
'fp-reg
))
156 (define-instruction-format (call-pal 32
157 :default-printer
'('call_pal
:tab
'pal_
:name
))
158 (op :field
(byte 6 26) :value
0)
159 (palcode :field
(byte 26 0)))
161 (define-instruction-format (bugchk 32
162 :default-printer
'('call_pal
:tab
'pal_bugchk
"," code
))
163 (op :field
(byte 6 26) :value
0)
164 (palcode :field
(byte 26 0) :value
#x81
)
165 ;; We use CALL-PAL BUGCHK as part of our trap logic. It is invariably
166 ;; followed by a trap-code word, which we pick out with the
167 ;; semi-traditional prefilter approach.
168 (code :prefilter
(lambda (dstate) (read-suffix 32 dstate
))
169 :reader bugchk-trap-code
))
173 (define-bitfield-emitter emit-word
16
176 (define-bitfield-emitter emit-lword
32
179 (define-bitfield-emitter emit-qword
64
182 (define-bitfield-emitter emit-memory
32
183 (byte 6 26) (byte 5 21) (byte 5 16) (byte 16 0))
185 (define-bitfield-emitter emit-branch
32
186 (byte 6 26) (byte 5 21) (byte 21 0))
188 (define-bitfield-emitter emit-reg-operate
32
189 (byte 6 26) (byte 5 21) (byte 5 16) (byte 3 13) (byte 1 12) (byte 7 5)
192 (define-bitfield-emitter emit-lit-operate
32
193 (byte 6 26) (byte 5 21) (byte 8 13) (byte 1 12) (byte 7 5) (byte 5 0))
195 (define-bitfield-emitter emit-fp-operate
32
196 (byte 6 26) (byte 5 21) (byte 5 16) (byte 11 5) (byte 5 0))
198 (define-bitfield-emitter emit-pal
32
199 (byte 6 26) (byte 26 0))
201 ;;;; macros for instructions
203 (macrolet ((define-memory (name op
&optional fixup float
)
204 `(define-instruction ,name
(segment ra disp rb
,@(if fixup
206 (:declare
(type tn ra rb
)
207 ,@(if fixup
; ### unsigned-byte 16 bad idea?
208 '((type (or (unsigned-byte 16) (signed-byte 16) fixup
)
210 '((type (or (unsigned-byte 16) (signed-byte 16)) disp
))))
211 (:printer memory
((op ,op
))
213 ;; Don't try to parse a constant
214 ;; reference if we're doing LDA or LDAH
216 '('(:name
:tab ra
"," disp
"(" rb
")"))))
219 `((when (fixup-p disp
)
220 (note-fixup segment
(or type
,fixup
) disp
)
222 (emit-memory segment
,op
,@(if float
223 '((fp-reg-tn-encoding ra
))
224 '((reg-tn-encoding ra
)))
227 (define-memory lda
#x08
:lda
)
228 (define-memory ldah
#x09
:ldah
)
229 (define-memory ldbu
#x0a
) ; BWX extension
230 (define-memory ldwu
#x0c
) ; BWX extension
231 (define-memory ldl
#x28
)
232 (define-memory ldq
#x29
)
233 (define-memory ldl_l
#x2a
)
234 (define-memory ldq_q
#x2b
)
235 (define-memory ldq_u
#x0b
)
236 (define-memory stw
#x0d
) ; BWX extension
237 (define-memory stb
#x0e
) ; BWX extension
238 (define-memory stl
#x2c
)
239 (define-memory stq
#x2d
)
240 (define-memory stl_c
#x2e
)
241 (define-memory stq_c
#x2f
)
242 (define-memory stq_u
#x0f
)
243 (define-memory ldf
#x20 nil t
)
244 (define-memory ldg
#x21 nil t
)
245 (define-memory lds
#x22 nil t
)
246 (define-memory ldt
#x23 nil t
)
247 (define-memory stf
#x24 nil t
)
248 (define-memory stg
#x25 nil t
)
249 (define-memory sts
#x26 nil t
)
250 (define-memory stt
#x27 nil t
))
252 (macrolet ((define-jump (name subop
)
253 `(define-instruction ,name
(segment ra rb
&optional
(hint 0))
254 (:declare
(type tn ra rb
)
255 (type (or (unsigned-byte 14) fixup
) hint
))
256 (:printer jump
((op #x1a
) (subop ,subop
)))
259 (note-fixup segment
:jmp-hint hint
)
261 (emit-memory segment
#x1a
(reg-tn-encoding ra
) (reg-tn-encoding rb
)
262 (logior (ash ,subop
14) hint
))))))
266 (define-jump jsr-coroutine
3))
269 (macrolet ((define-branch (name op
&optional
(float nil
))
270 `(define-instruction ,name
(segment ra target
)
271 (:declare
(type tn ra
)
273 (:printer branch
((op ,op
)
275 '((ra nil
:type
'fp-reg
)))))
277 (emit-back-patch segment
4
278 (lambda (segment posn
)
279 (emit-branch segment
,op
281 '((fp-reg-tn-encoding ra
))
282 '((reg-tn-encoding ra
)))
283 (ash (- (label-position target
)
286 (define-branch br
#x30
)
287 (define-branch bsr
#x34
)
288 (define-branch blbc
#x38
)
289 (define-branch blbs
#x3c
)
290 (define-branch fbeq
#x31 t
)
291 (define-branch fbne
#x35 t
)
292 (define-branch beq
#x39
)
293 (define-branch bne
#x3d
)
294 (define-branch fblt
#x32 t
)
295 (define-branch fbge
#x36 t
)
296 (define-branch blt
#x3a
)
297 (define-branch bge
#x3e
)
298 (define-branch fble
#x33 t
)
299 (define-branch fbgt
#x37 t
)
300 (define-branch ble
#x3b
)
301 (define-branch bgt
#x3f
))
303 (macrolet ((define-operate (name op fn
)
304 `(define-instruction ,name
(segment ra rb rc
)
305 (:declare
(type tn ra rc
)
306 (type (or tn
(unsigned-byte 8)) rb
))
307 (:printer reg-operate
((op ,op
) (fn ,fn
)))
308 (:printer lit-operate
((op ,op
) (fn ,fn
)))
309 ,@(when (and (= op
#x11
) (= fn
#x20
))
310 `((:printer reg-operate
((op ,op
) (fn ,fn
) (ra 31))
311 '('move
:tab rb
"," rc
))
312 (:printer reg-operate
((op ,op
) (fn ,fn
) (ra 31) (rb 31) (rc 31))
317 (emit-reg-operate segment
,op
(reg-tn-encoding ra
)
318 (reg-tn-encoding rb
) 0 0 ,fn
(reg-tn-encoding rc
)))
320 (emit-lit-operate segment
,op
(reg-tn-encoding ra
) rb
1 ,fn
321 (reg-tn-encoding rc
))))))))
322 (define-operate addl
#x10
#x00
)
323 (define-operate addl
/v
#x10
#x40
)
324 (define-operate addq
#x10
#x20
)
325 (define-operate addq
/v
#x10
#x60
)
326 (define-operate cmpule
#x10
#x3d
)
327 (define-operate cmpbge
#x10
#x0f
)
328 (define-operate subl
#x10
#x09
)
329 (define-operate subl
/v
#x10
#x49
)
330 (define-operate subq
#x10
#x29
)
331 (define-operate subq
/v
#x10
#x69
)
332 (define-operate cmpeq
#x10
#x2d
)
333 (define-operate cmplt
#x10
#x4d
)
334 (define-operate cmple
#x10
#x6d
)
335 (define-operate cmpult
#x10
#x1d
)
336 (define-operate s4addl
#x10
#x02
)
337 (define-operate s4addq
#x10
#x22
)
338 (define-operate s4subl
#x10
#x0b
)
339 (define-operate s4subq
#x10
#x2b
)
340 (define-operate s8addl
#x10
#x12
)
341 (define-operate s8addq
#x10
#x32
)
342 (define-operate s8subl
#x10
#x1b
)
343 (define-operate s8subq
#x10
#x3b
)
345 (define-operate and
#x11
#x00
)
346 (define-operate bic
#x11
#x08
)
347 (define-operate cmoveq
#x11
#x24
)
348 (define-operate cmovne
#x11
#x26
)
349 (define-operate cmovlbs
#x11
#x14
)
350 (define-operate bis
#x11
#x20
)
351 (define-operate ornot
#x11
#x28
)
352 (define-operate cmovlt
#x11
#x44
)
353 (define-operate cmovge
#x11
#x46
)
354 (define-operate cmovlbc
#x11
#x16
)
355 (define-operate xor
#x11
#x40
)
356 (define-operate eqv
#x11
#x48
)
357 (define-operate cmovle
#x11
#x64
)
358 (define-operate cmovgt
#x11
#x66
)
360 (define-operate sll
#x12
#x39
)
361 (define-operate extbl
#x12
#x06
)
362 (define-operate extwl
#x12
#x16
)
363 (define-operate extll
#x12
#x26
)
364 (define-operate extql
#x12
#x36
)
365 (define-operate extwh
#x12
#x5a
)
366 (define-operate extlh
#x12
#x6a
)
367 (define-operate extqh
#x12
#x7a
)
368 (define-operate sra
#x12
#x3c
)
369 (define-operate insbl
#x12
#x0b
)
370 (define-operate inswl
#x12
#x1b
)
371 (define-operate insll
#x12
#x2b
)
372 (define-operate insql
#x12
#x3b
)
373 (define-operate inswh
#x12
#x57
)
374 (define-operate inslh
#x12
#x67
)
375 (define-operate insqh
#x12
#x77
)
376 (define-operate srl
#x12
#x34
)
377 (define-operate mskbl
#x12
#x02
)
378 (define-operate mskwl
#x12
#x12
)
379 (define-operate mskll
#x12
#x22
)
380 (define-operate mskql
#x12
#x32
)
381 (define-operate mskwh
#x12
#x52
)
382 (define-operate msklh
#x12
#x62
)
383 (define-operate mskqh
#x12
#x72
)
384 (define-operate zap
#x12
#x30
)
385 (define-operate zapnot
#x12
#x31
)
387 (define-operate mull
#x13
#x00
)
388 (define-operate mulq
/v
#x13
#x60
)
389 (define-operate mull
/v
#x13
#x40
)
390 (define-operate umulh
#x13
#x30
)
391 (define-operate mulq
#x13
#x20
)
393 (define-operate ctpop
#x1c
#x30
) ; CIX extension
394 (define-operate ctlz
#x1c
#x32
) ; CIX extension
395 (define-operate cttz
#x1c
#x33
)) ; CIX extension
398 (macrolet ((define-fp-operate (name op fn
&optional
(args 3))
399 `(define-instruction ,name
(segment ,@(when (= args
3) '(fa)) fb fc
)
400 (:declare
(type tn
,@(when (= args
3) '(fa)) fb fc
))
401 (:printer fp-operate
((op ,op
) (fn ,fn
) ,@(when (= args
2) '((fa 31))))
403 '('(:name
:tab fb
"," fc
))))
404 ,@(when (and (= op
#x17
) (= fn
#x20
))
405 `((:printer fp-operate
((op ,op
) (fn ,fn
) (fa 31))
406 '('fabs
:tab fb
"," fc
))))
408 (emit-fp-operate segment
,op
,@(if (= args
3)
409 '((fp-reg-tn-encoding fa
))
411 (fp-reg-tn-encoding fb
) ,fn
(fp-reg-tn-encoding fc
))))))
412 (define-fp-operate cpys
#x17
#x020
)
413 (define-fp-operate mf_fpcr
#x17
#x025
)
414 (define-fp-operate cpysn
#x17
#x021
)
415 (define-fp-operate mt_fpcr
#x17
#x024
)
416 (define-fp-operate cpyse
#x17
#x022
)
417 (define-fp-operate cvtql
/sv
#x17
#x530
2)
418 (define-fp-operate cvtlq
#x17
#x010
2)
419 (define-fp-operate cvtql
#x17
#x030
2)
420 (define-fp-operate cvtql
/v
#x17
#x130
2)
421 (define-fp-operate fcmoveq
#x17
#x02a
)
422 (define-fp-operate fcmovne
#x17
#x02b
)
423 (define-fp-operate fcmovlt
#x17
#x02c
)
424 (define-fp-operate fcmovge
#x17
#x02d
)
425 (define-fp-operate fcmovle
#x17
#x02e
)
426 (define-fp-operate fcmovgt
#x17
#x02f
)
428 (define-fp-operate cvtqs
#x16
#x0bc
2)
429 (define-fp-operate cvtqt
#x16
#x0be
2)
430 (define-fp-operate cvtts
#x16
#x0ac
2)
431 (define-fp-operate cvttq
#x16
#x0af
2)
432 (define-fp-operate cvttq
/c
#x16
#x02f
2)
433 (define-fp-operate cmpteq
#x16
#x5a5
)
434 (define-fp-operate cmptlt
#x16
#x5a6
)
435 (define-fp-operate cmptle
#x16
#x5a7
)
436 (define-fp-operate cmptun
#x16
#x5a4
)
437 (define-fp-operate adds
#x16
#x080
)
438 (define-fp-operate addt
#x16
#x0a0
)
439 (define-fp-operate divs
#x16
#x083
)
440 (define-fp-operate divt
#x16
#x0a3
)
441 (define-fp-operate muls
#x16
#x082
)
442 (define-fp-operate mult
#x16
#x0a2
)
443 (define-fp-operate subs
#x16
#x081
)
444 (define-fp-operate subt
#x16
#x0a1
)
447 (defconstant +su
+ #x500
) ; software, underflow enabled
448 (defconstant +sui
+ #x700
) ; software, inexact & underflow enabled
449 (defconstant +sv
+ #x500
) ; software, interger overflow enabled
450 (defconstant +svi
+ #x700
)
451 (defconstant +rnd
+ #x0c0
) ; dynamic rounding mode
452 (defconstant +sud
+ #x5c0
)
453 (defconstant +svid
+ #x7c0
)
454 (defconstant +suid
+ #x7c0
)
456 (define-fp-operate cvtqs_su
#x16
(logior +su
+ #x0bc
) 2)
457 (define-fp-operate cvtqs_sui
#x16
(logior +sui
+ #x0bc
) 2)
458 (define-fp-operate cvtqt_su
#x16
(logior +su
+ #x0be
) 2)
459 (define-fp-operate cvtqt_sui
#x16
(logior +sui
+ #x0be
) 2)
460 (define-fp-operate cvtts_su
#x16
(logior +su
+ #x0ac
) 2)
462 (define-fp-operate cvttq_sv
#x16
(logior +su
+ #x0af
) 2)
463 (define-fp-operate cvttq
/c_sv
#x16
(logior +su
+ #x02f
) 2)
465 (define-fp-operate adds_su
#x16
(logior +su
+ #x080
))
466 (define-fp-operate addt_su
#x16
(logior +su
+ #x0a0
))
467 (define-fp-operate divs_su
#x16
(logior +su
+ #x083
))
468 (define-fp-operate divt_su
#x16
(logior +su
+ #x0a3
))
469 (define-fp-operate muls_su
#x16
(logior +su
+ #x082
))
470 (define-fp-operate mult_su
#x16
(logior +su
+ #x0a2
))
471 (define-fp-operate subs_su
#x16
(logior +su
+ #x081
))
472 (define-fp-operate subt_su
#x16
(logior +su
+ #x0a1
)))
474 (define-instruction excb
(segment)
475 (:emitter
(emit-lword segment
#x63ff0400
)))
477 (define-instruction trapb
(segment)
478 (:emitter
(emit-lword segment
#x63ff0000
)))
480 (define-instruction imb
(segment)
481 (:emitter
(emit-lword segment
#x00000086
)))
483 (defun bugchk-trap-control (chunk inst stream dstate
)
484 (declare (ignore inst
))
485 (flet ((nt (x) (if stream
(note x dstate
))))
486 (case (bugchk-trap-code chunk dstate
)
489 (#.pending-interrupt-trap
490 (nt "Pending interrupt trap"))
493 (handle-break-args #'snarf-error-junk stream dstate
))
496 (handle-break-args #'snarf-error-junk stream dstate
))
498 (nt "Breakpoint trap"))
499 (#.fun-end-breakpoint-trap
500 (nt "Function end breakpoint trap"))
501 (#.single-step-breakpoint-trap
502 (nt "Single step breakpoint trap"))
503 (#.single-step-around-trap
504 (nt "Single step around trap"))
505 (#.single-step-before-trap
506 (nt "Single step before trap")))))
508 (define-instruction gentrap
(segment code
)
509 (:printer bugchk
() :default
510 :control
#'bugchk-trap-control
)
512 (emit-lword segment
#x000081
) ;actually bugchk
513 (emit-lword segment code
)))
515 (define-instruction-macro move
(src dst
)
516 `(inst bis zero-tn
,src
,dst
))
518 (define-instruction-macro not
(src dst
)
519 `(inst ornot zero-tn
,src
,dst
))
521 (define-instruction-macro fmove
(src dst
)
522 `(inst cpys
,src
,src
,dst
))
524 (define-instruction-macro fabs
(src dst
)
525 `(inst cpys fp-single-zero-tn
,src
,dst
))
527 (define-instruction-macro fneg
(src dst
)
528 `(inst cpysn
,src
,src
,dst
))
530 (define-instruction-macro nop
()
531 `(inst bis zero-tn zero-tn zero-tn
))
533 (defun %li
(value reg
)
536 (inst lda reg value zero-tn
))
539 (let ((x (logand x
(lognot (ash -
1 n
)))))
540 (if (logbitp (1- n
) x
)
541 (logior (ash -
1 (1- n
)) x
)
543 (let* ((value (se value
32))
544 (low (ldb (byte 16 0) value
))
545 (tmp1 (- value
(se low
16)))
546 (high (ldb (byte 16 16) tmp1
))
547 (tmp2 (- tmp1
(se (ash high
16) 32)))
551 (setf tmp1
(- tmp1
#x40000000
))
552 (setf high
(ldb (byte 16 16) tmp1
)))
553 (inst lda reg low zero-tn
)
555 (inst ldah reg extra reg
))
557 (inst ldah reg high reg
)))))
558 ((or (unsigned-byte 32) (signed-byte 64) (unsigned-byte 64))
559 ;; Since it took NJF and CSR a good deal of puzzling to work out
560 ;; (a) what a previous version of this was doing and (b) why it
563 ;; write VALUE = a_63 * 2^63 + a_48-62 * 2^48
564 ;; + a_47 * 2^47 + a_32-46 * 2^32
565 ;; + a_31 * 2^31 + a_16-30 * 2^16
566 ;; + a_15 * 2^15 + a_0-14
568 ;; then, because of the wonders of sign-extension and
569 ;; twos-complement arithmetic modulo 2^64, if a_15 is set, LDA
570 ;; (which sign-extends its argument) will add
572 ;; (a_15 * 2^15 + a_0-14 - 65536).
574 ;; So we need to add that 65536 back on, which is what this
575 ;; LOGBITP business is doing. The same applies for bits 31 and
576 ;; 47 (bit 63 is taken care of by the fact that all of this
577 ;; arithmetic is mod 2^64 anyway), but we have to be careful that
578 ;; we consider the altered value, not the original value.
580 ;; I think, anyway. -- CSR, 2003-09-26
581 (let* ((value1 (if (logbitp 15 value
) (+ value
(ash 1 16)) value
))
582 (value2 (if (logbitp 31 value1
) (+ value1
(ash 1 32)) value1
))
583 (value3 (if (logbitp 47 value2
) (+ value2
(ash 1 48)) value2
)))
584 (inst lda reg
(ldb (byte 16 32) value2
) zero-tn
)
585 ;; FIXME: Don't yet understand these conditionals. If I'm
586 ;; right, surely we can just consider the zeroness of the
587 ;; particular bitfield, not the zeroness of the whole thing?
588 ;; -- CSR, 2003-09-26
590 (inst ldah reg
(ldb (byte 16 48) value3
) reg
))
591 (unless (and (= value2
0) (= value3
0))
592 (inst sll reg
32 reg
))
594 (inst lda reg
(ldb (byte 16 0) value
) reg
))
596 (inst ldah reg
(ldb (byte 16 16) value1
) reg
))))
598 (inst lda reg value zero-tn
:bits-47-32
)
599 (inst ldah reg value reg
:bits-63-48
)
600 (inst sll reg
32 reg
)
601 (inst lda reg value reg
)
602 (inst ldah reg value reg
))))
604 (define-instruction-macro li
(value reg
)
610 (define-instruction lword
(segment lword
)
611 (:declare
(type (or (unsigned-byte 32) (signed-byte 32) fixup
) lword
))
616 (note-fixup segment
:absolute32 lword
)
617 (emit-lword segment
0))
619 (emit-lword segment lword
)))))
621 (define-instruction short
(segment word
)
622 (:declare
(type (or (unsigned-byte 16) (signed-byte 16)) word
))
625 (emit-word segment word
)))
627 (define-instruction byte
(segment byte
)
628 (:declare
(type (or (unsigned-byte 8) (signed-byte 8)) byte
))
631 (emit-byte segment byte
)))
633 (defun emit-header-data (segment type
)
636 (lambda (segment posn
)
639 (ash (+ posn
(component-header-length))
640 (- n-widetag-bits word-shift
)))))))
642 (define-instruction simple-fun-header-word
(segment)
645 (emit-header-data segment simple-fun-widetag
)))
647 (define-instruction lra-header-word
(segment)
650 (emit-header-data segment return-pc-widetag
)))
652 (defun emit-compute-inst (segment vop dst src label temp calc
)
653 (declare (ignore temp
))
655 ;; We emit either 12 or 4 bytes, so we maintain 8 byte alignments.
657 (lambda (segment posn delta-if-after
)
658 (let ((delta (funcall calc label posn delta-if-after
)))
659 (when (<= (- (ash 1 15)) delta
(1- (ash 1 15)))
660 (emit-back-patch segment
4
661 (lambda (segment posn
)
662 (assemble (segment vop
)
664 (funcall calc label posn
0)
667 (lambda (segment posn
)
668 (assemble (segment vop
)
670 (let ((x (logand x
(lognot (ash -
1 n
)))))
671 (if (logbitp (1- n
) x
)
672 (logior (ash -
1 (1- n
)) x
)
674 (let* ((value (se (funcall calc label posn
0) 32))
675 (low (ldb (byte 16 0) value
))
676 (tmp1 (- value
(se low
16)))
677 (high (ldb (byte 16 16) tmp1
))
678 (tmp2 (- tmp1
(se (ash high
16) 32)))
682 (setf tmp1
(- tmp1
#x40000000
))
683 (setf high
(ldb (byte 16 16) tmp1
)))
684 (inst lda dst low src
)
685 (inst ldah dst extra dst
)
686 (inst ldah dst high dst
)))))))
688 ;; code = lip - header - label-offset + other-pointer-tag
689 (define-instruction compute-code-from-lip
(segment dst src label temp
)
690 (:declare
(type tn dst src temp
) (type label label
))
693 (emit-compute-inst segment vop dst src label temp
694 (lambda (label posn delta-if-after
)
695 (- other-pointer-lowtag
696 (label-position label posn delta-if-after
)
697 (component-header-length))))))
699 ;; code = lra - other-pointer-tag - header - label-offset + other-pointer-tag
700 ;; = lra - (header + label-offset)
701 (define-instruction compute-code-from-lra
(segment dst src label temp
)
702 (:declare
(type tn dst src temp
) (type label label
))
705 (emit-compute-inst segment vop dst src label temp
706 (lambda (label posn delta-if-after
)
707 (- (+ (label-position label posn delta-if-after
)
708 (component-header-length)))))))
710 ;; lra = code + other-pointer-tag + header + label-offset - other-pointer-tag
711 ;; = code + header + label-offset
712 (define-instruction compute-lra-from-code
(segment dst src label temp
)
713 (:declare
(type tn dst src temp
) (type label label
))
716 (emit-compute-inst segment vop dst src label temp
717 (lambda (label posn delta-if-after
)
718 (+ (label-position label posn delta-if-after
)
719 (component-header-length))))))