-
Notifications
You must be signed in to change notification settings - Fork 6
/
print.lisp
78 lines (64 loc) · 2.44 KB
/
print.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
(cl:in-package #:cluster)
(defparameter *regs-16*
#("AX" "CX" "DX" "BX" "SP" "BP" "SI" "DI"
"R8W" "R9W" "R10W" "R11W" "R12W" "R13W" "R14W" "R15W"))
(defparameter *regs-32*
#("EAX" "ECX" "EDX" "EBX" "ESP" "EBP" "ESI" "EDI"
"R8D" "R9D" "R10D" "R11D" "R12D" "R13D" "R14D" "R15D"))
(defparameter *regs-64*
#("RAX" "RCX" "RDX" "RBX" "RSP" "RBP" "RSI" "RDI"
"R8" "R9" "R10" "R11" "R12" "R13" "R14" "R15"))
(defun print-register (code size stream)
(format stream "~a"
(aref (ecase size
(16 *regs-16*)
(32 *regs-32*)
(64 *regs-64*))
code)))
(defgeneric print-item (item stream))
(defgeneric print-operand (operand stream))
(defmethod print-item ((item code-command) stream)
(format stream " ~a " (mnemonic item))
(loop for operand in (butlast (operands item))
do (print-operand operand stream)
(format stream ", "))
(print-operand (car (last (operands item))) stream)
(format stream "~%"))
(defmethod print-operand ((operand immediate-operand) stream)
(format stream "~d" (value operand)))
(defmethod print-operand ((operand gpr-operand) stream)
(print-register (code-number operand) (size operand) stream))
(defmethod print-operand ((operand memory-operand) stream)
(format stream "[")
(with-accessors ((base-register base-register)
(index-register index-register)
(scale scale)
(size size)
(displacement displacement))
operand
(cond ((and (null base-register) (null index-register))
(format stream "~d" displacement))
((and (null index-register) (null displacement))
(print-register (base-register operand) size stream))
((and (null base-register) (null displacement))
(format stream "~d*" scale)
(print-register (index-register operand) size stream))
((null displacement)
(print-register (base-register operand) size stream)
(format stream "+")
(format stream "~d*" scale)
(print-register (index-register operand) size stream))
((null index-register)
(print-register (base-register operand) size stream)
(format stream "~2d" displacement))
((null base-register)
(format stream "~d*" scale)
(print-register (index-register operand) size stream)
(format stream "~@d" displacement))
(t
(print-register (base-register operand) size stream)
(format stream "+")
(format stream "~d*" scale)
(print-register (index-register operand) size stream)
(format stream "~@d" displacement))))
(format stream "]"))