-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbinaries.lisp
96 lines (78 loc) · 2.64 KB
/
binaries.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
; binaries.lisp
; Support for generating binary object files
(in-package "AMD64-ASM")
(defparameter *scopes* '(:int :ext :und))
(defstruct asmdef
name
scope
bin)
(defstruct asmobj
cdefs
ddefs)
(defun new-asmdef (name sc bin)
(make-asmdef :name name :scope sc :bin bin))
(defun new-asmobj ()
(make-asmobj :cdefs (make-array 0 :fill-pointer t)
:ddefs (make-array 0 :fill-pointer t)))
(defun emit-code-def (obj name sc bin)
(vector-push-extend (new-asmdef name sc bin)
(asmobj-cdefs obj)))
(defun emit-data-def (obj name sc bin)
(vector-push-extend (new-asmdef name sc bin)
(asmobj-ddefs obj)))
(defstruct strtab
vec
table)
(defun new-strtab ()
(make-strtab :vec (make-array 1 :fill-pointer t :initial-element 0)
:table (make-hash-table)))
(defun strtab-intern (tab sym)
(if (gethash sym (strtab-table tab))
(gethash sym (strtab-table tab))
(let ((ndx (fill-pointer (strtab-vec tab))))
(iter (for char in-vector (symbol-name sym))
(vector-push-extend (char-code char) (strtab-vec tab)))
(vector-push-extend 0 (strtab-vec tab))
(setf (gethash sym (strtab-table tab)) ndx)
ndx)))
(defun strtab-member? (tab sym)
(gethash sym (strtab-table tab)))
(defun strtab-size (tab)
(length (strtab-vec tab)))
(defun emit-strtab (frag strtab)
(emit-byte-vector frag (strtab-vec strtab)))
(defgeneric emit-c-struct (struct frag))
(defgeneric sizeof-c-struct (struct))
(defmacro define-c-struct (name &body slots)
(labels ((slot-accessor (name slot-name)
(catsym- name slot-name))
(emitter-for-spec (spec)
(ecase spec
(:byte 'emit-byte)
(:half 'emit-half)
(:word 'emit-word)
(:wide 'emit-wide)))
(emitter-for-slot (struct frag slot)
(ecase (length slot)
(2 `(,(emitter-for-spec (second slot))
,frag
(,(slot-accessor name (first slot)) ,struct)))
(3 `(let ((vec (,(slot-accessor name (first slot)) ,struct)))
(assert (<= (length vec) ,(third slot)))
(iter (for e in-vector vec)
(,(emitter-for-spec (second slot)) ,frag e))
(iter (for i from (length vec) below ,(third slot))
(,(emitter-for-spec (second slot)) ,frag 0)))))))
`(progn
(defstruct ,name
,@(iter (for slot in slots)
(collect (car slot))))
(defmethod emit-c-struct ((xstruct ,name) xfrag)
,@(iter (for slot in slots)
(collect (emitter-for-slot 'xstruct 'xfrag slot))))
(defmethod sizeof-c-struct ((xstruct ,name))
,(iter (for slot in slots)
(ecase (length slot)
(2 (sum (specifier-width (second slot))))
(3 (sum (* (third slot)
(specifier-width (second slot)))))))))))