| ... |
... |
@@ -303,8 +303,12 @@ |
|
303
|
303
|
(imm :fields (list (byte 19 5) (byte 2 29))
|
|
304
|
304
|
:printer #'(lambda (vlist stream dstate)
|
|
305
|
305
|
(declare (ignore dstate))
|
|
306
|
|
- (let ((imm (logior (ash (first vlist) 2)
|
|
307
|
|
- (second vlist))))
|
|
|
306
|
+ (let* ((raw (logior (ash (first vlist) 2)
|
|
|
307
|
+ (second vlist)))
|
|
|
308
|
+ ;; sign-extend from bit 20 (21-bit signed value)
|
|
|
309
|
+ (imm (if (logbitp 20 raw)
|
|
|
310
|
+ (- raw (ash 1 21))
|
|
|
311
|
+ raw)))
|
|
308
|
312
|
(print-immed imm stream))))
|
|
309
|
313
|
(rd :field (byte 5 0) :type 'reg))
|
|
310
|
314
|
|
| ... |
... |
@@ -320,6 +324,8 @@ |
|
320
|
324
|
;;; [29] S (0=no flags, 1=set flags)
|
|
321
|
325
|
;;; [28:24] 10001
|
|
322
|
326
|
;;; [23:22] shift (00=LSL#0, 01=LSL#12)
|
|
|
327
|
+;;; [23] 0 (reserved)
|
|
|
328
|
+;;; [22] shift (0=LSL#0, 1=LSL#12)
|
|
323
|
329
|
;;; [21:10] imm12
|
|
324
|
330
|
;;; [9:5] Rn
|
|
325
|
331
|
;;; [4:0] Rd
|
| ... |
... |
@@ -333,14 +339,15 @@ |
|
333
|
339
|
(op :field (byte 1 30))
|
|
334
|
340
|
(s :field (byte 1 29))
|
|
335
|
341
|
(op1 :field (byte 5 24))
|
|
336
|
|
- (shift :field (byte 2 22))
|
|
|
342
|
+ (res0 :field (byte 1 23) :value 0)
|
|
|
343
|
+ (shift :field (byte 1 22))
|
|
337
|
344
|
(imm12 :field (byte 12 10))
|
|
338
|
345
|
(rn :field (byte 5 5) :type 'reg)
|
|
339
|
346
|
(rd :field (byte 5 0) :type 'reg))
|
|
340
|
347
|
|
|
341
|
348
|
(define-emitter emit-format-add-sub-imm 32
|
|
342
|
|
- (byte 1 31) (byte 1 30) (byte 1 29) (byte 5 24) (byte 2 22)
|
|
343
|
|
- (byte 12 10) (byte 5 5) (byte 5 0))
|
|
|
349
|
+ (byte 1 31) (byte 1 30) (byte 1 29) (byte 5 24) (byte 1 23)
|
|
|
350
|
+ (byte 1 22) (byte 12 10) (byte 5 5) (byte 5 0))
|
|
344
|
351
|
|
|
345
|
352
|
|
|
346
|
353
|
;;; Logical (immediate)
|
| ... |
... |
@@ -719,7 +726,7 @@ |
|
719
|
726
|
(op2 :field (byte 2 24) :value #b00)
|
|
720
|
727
|
(opc :field (byte 2 22))
|
|
721
|
728
|
(z :field (byte 1 21) :value 0)
|
|
722
|
|
- (imm9 :field (byte 9 12))
|
|
|
729
|
+ (imm9 :field (byte 9 12) :sign-extend t)
|
|
723
|
730
|
(type :field (byte 2 10))
|
|
724
|
731
|
(rn :field (byte 5 5) :type 'reg)
|
|
725
|
732
|
(rt :field (byte 5 0) :type 'reg))
|
| ... |
... |
@@ -759,7 +766,15 @@ |
|
759
|
766
|
(op2 :field (byte 2 24) :value #b00)
|
|
760
|
767
|
(opc :field (byte 2 22))
|
|
761
|
768
|
(one :field (byte 1 21) :value 1)
|
|
762
|
|
- (rm :field (byte 5 16) :type 'reg)
|
|
|
769
|
+ (rm :field (byte 5 16)
|
|
|
770
|
+ :printer #'(lambda (value stream dstate)
|
|
|
771
|
+ (let* ((word (disassem::sap-ref-int
|
|
|
772
|
+ (disassem:dstate-segment-sap dstate)
|
|
|
773
|
+ (disassem:dstate-cur-offs dstate)
|
|
|
774
|
+ 4 :little-endian))
|
|
|
775
|
+ (option (ldb (byte 3 13) word)))
|
|
|
776
|
+ (princ (get-reg-name value (if (< option 6) 0 1))
|
|
|
777
|
+ stream))))
|
|
763
|
778
|
(option :field (byte 3 13) :type 'extend-type)
|
|
764
|
779
|
(s :field (byte 1 12))
|
|
765
|
780
|
(op3 :field (byte 2 10) :value #b10)
|
| ... |
... |
@@ -801,7 +816,7 @@ |
|
801
|
816
|
(op2 :field (byte 1 25) :value 0)
|
|
802
|
817
|
(index :field (byte 2 23))
|
|
803
|
818
|
(l :field (byte 1 22))
|
|
804
|
|
- (imm7 :field (byte 7 15))
|
|
|
819
|
+ (imm7 :field (byte 7 15) :sign-extend t)
|
|
805
|
820
|
(rt2 :field (byte 5 10) :type 'reg)
|
|
806
|
821
|
(rn :field (byte 5 5) :type 'reg)
|
|
807
|
822
|
(rt :field (byte 5 0) :type 'reg))
|
| ... |
... |
@@ -986,14 +1001,17 @@ |
|
986
|
1001
|
|
|
987
|
1002
|
(defstruct memory-ref
|
|
988
|
1003
|
;; Base register.
|
|
989
|
|
- (base nil :type tn)
|
|
|
1004
|
+ (base (required-argument) :type tn)
|
|
990
|
1005
|
;; Byte offset -- semantics depend on mode:
|
|
991
|
|
- ;; :offset unsigned, scaled by access size at emit time
|
|
992
|
|
- ;; :pre signed 9-bit, stored unscaled in imm9
|
|
993
|
|
- ;; :post signed 9-bit, stored unscaled in imm9
|
|
|
1006
|
+ ;; :offset unsigned, scaled by access size at emit time
|
|
|
1007
|
+ ;; :pre signed 9-bit, stored unscaled in imm9
|
|
|
1008
|
+ ;; :post signed 9-bit, stored unscaled in imm9
|
|
|
1009
|
+ ;; :reg-offset register offset via extended-reg
|
|
994
|
1010
|
(offset 0 :type integer)
|
|
|
1011
|
+ ;; Register offset operand (only for :reg-offset mode).
|
|
|
1012
|
+ (rm nil :type (or null extended-reg))
|
|
995
|
1013
|
;; Addressing mode.
|
|
996
|
|
- (mode :offset :type (member :offset :pre :post)))
|
|
|
1014
|
+ (mode :offset :type (member :offset :pre :post :reg-offset)))
|
|
997
|
1015
|
|
|
998
|
1016
|
(defun mem (base &optional (offset 0))
|
|
999
|
1017
|
"Unsigned-offset memory reference: [base, #offset].
|
| ... |
... |
@@ -1014,6 +1032,18 @@ |
|
1014
|
1032
|
(declare (type tn base) (type (signed-byte 9) offset))
|
|
1015
|
1033
|
(make-memory-ref :base base :offset offset :mode :post))
|
|
1016
|
1034
|
|
|
|
1035
|
+(defun reg-offset (base rm &optional (extend-type :uxtx) (shift 0))
|
|
|
1036
|
+ "Register-offset memory reference: [base, rm, extend #shift]
|
|
|
1037
|
+ Rm is the offset register, extended and optionally shifted.
|
|
|
1038
|
+ Extend-type defaults to :uxtx (no extension, X register).
|
|
|
1039
|
+ Use :uxtw or :sxtw to treat rm as a W register.
|
|
|
1040
|
+ Shift is 0 or the log2 of the access size."
|
|
|
1041
|
+ (declare (type tn base rm)
|
|
|
1042
|
+ (type (member :uxtb :uxth :uxtw :uxtx :sxtb :sxth :sxtw :sxtx) extend-type)
|
|
|
1043
|
+ (type (integer 0 4) shift))
|
|
|
1044
|
+ (make-memory-ref :base base :mode :reg-offset
|
|
|
1045
|
+ :rm (extend rm extend-type shift)))
|
|
|
1046
|
+
|
|
1017
|
1047
|
(defun nzcv (&rest flags)
|
|
1018
|
1048
|
"Return a 4-bit integer encoding the NZCV flags, suitable for use as
|
|
1019
|
1049
|
the nzcv argument to CCMP/CCMN. Also usable with MSR NZCV after
|
| ... |
... |
@@ -1785,12 +1815,12 @@ |
|
1785
|
1815
|
(etypecase src
|
|
1786
|
1816
|
((unsigned-byte 12)
|
|
1787
|
1817
|
(emit-format-add-sub-imm segment ,sf ,op ,s #b10001
|
|
1788
|
|
- 0 src
|
|
|
1818
|
+ 0 0 src
|
|
1789
|
1819
|
(reg-tn-encoding rn)
|
|
1790
|
1820
|
(reg-tn-encoding rd)))
|
|
1791
|
1821
|
(shifted-imm
|
|
1792
|
1822
|
(emit-format-add-sub-imm segment ,sf ,op ,s #b10001
|
|
1793
|
|
- (shifted-imm-shift src)
|
|
|
1823
|
+ 0 (shifted-imm-shift src)
|
|
1794
|
1824
|
(shifted-imm-value src)
|
|
1795
|
1825
|
(reg-tn-encoding rn)
|
|
1796
|
1826
|
(reg-tn-encoding rd)))
|
| ... |
... |
@@ -1856,10 +1886,10 @@ |
|
1856
|
1886
|
(etypecase src
|
|
1857
|
1887
|
((unsigned-byte 12)
|
|
1858
|
1888
|
(emit-format-add-sub-imm segment ,sf ,op 1 #b10001
|
|
1859
|
|
- 0 src (reg-tn-encoding rn) 31))
|
|
|
1889
|
+ 0 0 src (reg-tn-encoding rn) 31))
|
|
1860
|
1890
|
(shifted-imm
|
|
1861
|
1891
|
(emit-format-add-sub-imm segment ,sf ,op 1 #b10001
|
|
1862
|
|
- (shifted-imm-shift src)
|
|
|
1892
|
+ 0 (shifted-imm-shift src)
|
|
1863
|
1893
|
(shifted-imm-value src)
|
|
1864
|
1894
|
(reg-tn-encoding rn) 31))
|
|
1865
|
1895
|
(tn
|
| ... |
... |
@@ -2022,7 +2052,7 @@ |
|
2022
|
2052
|
(define-instruction-macro mov (rd src)
|
|
2023
|
2053
|
`(inst orr ,rd null-tn ,src))
|
|
2024
|
2054
|
|
|
2025
|
|
-;; MVN Xd, src = ORN Xd, XZR, src
|
|
|
2055
|
+;; MVN Xd, src = ORN Xd, XZR, src -- bitwise NOT.
|
|
2026
|
2056
|
(define-instruction-macro mvn (rd src)
|
|
2027
|
2057
|
`(inst orn ,rd null-tn ,src))
|
|
2028
|
2058
|
|
| ... |
... |
@@ -2311,7 +2341,8 @@ |
|
2311
|
2341
|
`(define-instruction ,name (segment rt target)
|
|
2312
|
2342
|
(:declare (type tn rt) (type label target))
|
|
2313
|
2343
|
(:printer format-compare-branch
|
|
2314
|
|
- ((sf ,sf) (op1 #b011010) (op ,op)))
|
|
|
2344
|
+ ((sf ,sf) (op1 #b011010) (op ,op)
|
|
|
2345
|
+ ,@(when (zerop sf) '((rt nil :type 'wreg)))))
|
|
2315
|
2346
|
(:attributes branch)
|
|
2316
|
2347
|
(:emitter
|
|
2317
|
2348
|
(emit-back-patch segment 4
|
| ... |
... |
@@ -2337,7 +2368,8 @@ |
|
2337
|
2368
|
(type (unsigned-byte ,(if (zerop sf) 5 6)) bit-num)
|
|
2338
|
2369
|
(type label target))
|
|
2339
|
2370
|
(:printer format-test-branch
|
|
2340
|
|
- ((op1 #b011011) (op ,op) (b5 ,sf)))
|
|
|
2371
|
+ ((op1 #b011011) (op ,op) (b5 ,sf)
|
|
|
2372
|
+ ,@(when (zerop sf) '((rt nil :type 'wreg)))))
|
|
2341
|
2373
|
(:attributes branch)
|
|
2342
|
2374
|
(:emitter
|
|
2343
|
2375
|
(emit-back-patch segment 4
|
| ... |
... |
@@ -2499,6 +2531,10 @@ |
|
2499
|
2531
|
;; (inst ldr x0 (mem x1 16)) ; LDR X0, [X1, #16]
|
|
2500
|
2532
|
;; (inst ldr x0 (pre-index x1 16)) ; LDR X0, [X1, #16]!
|
|
2501
|
2533
|
;; (inst ldr x0 (post-index x1 -8)) ; LDR X0, [X1], #-8
|
|
|
2534
|
+;; (inst ldr x0 (reg-offset x1 x2)) ; LDR X0, [X1, X2]
|
|
|
2535
|
+;; (inst ldr x0 (reg-offset x1 x2 :uxtx 3)) ; LDR X0, [X1, X2, LSL #3]
|
|
|
2536
|
+;; (inst ldr x0 (reg-offset x1 x2 :uxtw)) ; LDR X0, [X1, W2, UXTW]
|
|
|
2537
|
+;; (inst ldr x0 (reg-offset x1 x2 :sxtw 2)) ; LDR X0, [X1, W2, SXTW #2]
|
|
2502
|
2538
|
;; (inst ldrh w0 (mem x1 6)) ; LDRH W0, [X1, #6]
|
|
2503
|
2539
|
;; (inst ldrb w0 (mem x1 3)) ; LDRB W0, [X1, #3]
|
|
2504
|
2540
|
;; (inst str x0 (mem x1 16)) ; STR X0, [X1, #16]
|
| ... |
... |
@@ -2516,6 +2552,9 @@ |
|
2516
|
2552
|
(:printer format-ldst-imm9
|
|
2517
|
2553
|
((size ,size) (op1 #b111) (v 0) (op2 #b00) (opc ,opc)
|
|
2518
|
2554
|
(type #b01)))
|
|
|
2555
|
+ (:printer format-ldst-reg
|
|
|
2556
|
+ ((size ,size) (op1 #b111) (v 0) (op2 #b00) (opc ,opc)
|
|
|
2557
|
+ (one 1) (op3 #b10)))
|
|
2519
|
2558
|
(:emitter
|
|
2520
|
2559
|
(let ((rn (memory-ref-base mem))
|
|
2521
|
2560
|
(offset (memory-ref-offset mem)))
|
| ... |
... |
@@ -2540,7 +2579,19 @@ |
|
2540
|
2579
|
(emit-format-ldst-imm9 segment ,size #b111 0 #b00 ,opc
|
|
2541
|
2580
|
0 (ldb (byte 9 0) offset) #b01
|
|
2542
|
2581
|
(reg-tn-encoding rn)
|
|
2543
|
|
- (reg-tn-encoding rt)))))))))
|
|
|
2582
|
+ (reg-tn-encoding rt)))
|
|
|
2583
|
+ (:reg-offset
|
|
|
2584
|
+ (let* ((ext (memory-ref-rm mem))
|
|
|
2585
|
+ (rm (extended-reg-reg ext))
|
|
|
2586
|
+ (s (if (zerop (extended-reg-shift ext)) 0 1)))
|
|
|
2587
|
+ (emit-format-ldst-reg segment ,size #b111 0 #b00 ,opc
|
|
|
2588
|
+ 1
|
|
|
2589
|
+ (reg-tn-encoding rm)
|
|
|
2590
|
+ (extend-type-encoding
|
|
|
2591
|
+ (extended-reg-extend-type ext))
|
|
|
2592
|
+ s #b10
|
|
|
2593
|
+ (reg-tn-encoding rn)
|
|
|
2594
|
+ (reg-tn-encoding rt))))))))))
|
|
2544
|
2595
|
;; name size opc access-size
|
|
2545
|
2596
|
(def strb #b00 #b00 1)
|
|
2546
|
2597
|
(def ldrb #b00 #b01 1)
|
| ... |
... |
@@ -3448,5 +3499,3 @@ |
|
3448
|
3499
|
|
|
3449
|
3500
|
(define-instruction-macro li (reg value)
|
|
3450
|
3501
|
`(%li ,reg ,value)) |
|
3451
|
|
-
|
|
3452
|
|
-;; NOT Xd, Xm = ORN Xd, XZR, Xm (already covered by MVN macro). |