3
$Id: insmac.scm,v 1.17 2002/02/14 22:03:32 cph Exp $
5
Copyright (c) 1992, 1999, 2001, 2002 Massachusetts Institute of Technology
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or (at
10
your option) any later version.
12
This program is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23
;;;; Intel 386 Instruction Set Macros
25
(declare (usual-integrations))
27
(define-syntax define-trivial-instruction
29
(lambda (form environment)
30
(if (syntax-match? '(IDENTIFIER DATUM * DATUM) (cdr form))
31
`(DEFINE-INSTRUCTION ,(cadr form)
33
(BYTE (8 ,(close-syntax (caddr form) environment)))
34
,@(map (lambda (extra)
35
`(BYTE (8 ,(close-syntax extra environment))))
37
(ill-formed-syntax form)))))
39
;;;; Effective addressing
41
(define ea-database-name
44
(define-syntax define-ea-database
45
(rsc-macro-transformer
46
(lambda (form environment)
47
`(,(close-syntax 'DEFINE environment)
49
,(compile-database (cdr form) environment
50
(lambda (pattern actions)
51
(let ((keyword (car pattern))
52
(categories (car actions))
54
(register (caddr actions))
55
(tail (cdddr actions)))
56
`(,(close-syntax 'MAKE-EFFECTIVE-ADDRESS environment)
59
,(integer-syntaxer mode environment 'UNSIGNED 2)
60
,(integer-syntaxer register environment 'UNSIGNED 3)
63
(process-fields tail #f environment))))))))))
65
;; This one is necessary to distinguish between r/mW mW, etc.
67
(define-syntax define-ea-transformer
69
(lambda (form environment)
71
(if (syntax-match? '(IDENTIFIER ? SYMBOL) (cdr form))
72
`(DEFINE (,(cadr form) EXPRESSION)
73
(LET ((MATCH-RESULT (PATTERN-LOOKUP ,ea-database-name EXPRESSION)))
75
,(if (pair? (cddr form))
76
`(LET ((EA (MATCH-RESULT)))
77
(AND (MEMQ ',(caddr form) (EA/CATEGORIES EA))
80
(ill-formed-syntax form)))))
82
;; *** We can't really handle switching these right now. ***
84
(define-integrable *ADDRESS-SIZE* 32)
85
(define-integrable *OPERAND-SIZE* 32)
87
(define (parse-instruction opcode tail early? environment)
88
(process-fields (cons opcode tail) early? environment))
90
(define (process-fields fields early? environment)
91
(if (and (null? (cdr fields))
92
(eq? (caar fields) 'VARIABLE-WIDTH))
93
(expand-variable-width (car fields) early? environment)
94
(call-with-values (lambda () (expand-fields fields early? environment))
96
(if (not (zero? (remainder size 8)))
97
(error "Bad syllable size:" size))
100
(define (expand-variable-width field early? environment)
101
(let ((binding (cadr field))
102
(clauses (cddr field)))
103
`(,(close-syntax 'LIST environment)
104
,(variable-width-expression-syntaxer
108
(map (lambda (clause)
110
(lambda () (expand-fields (cdr clause) early? environment))
112
(if (not (zero? (remainder size 8)))
113
(error "Bad clause size:" size))
114
`(,code ,size ,@(car clause)))))
117
(define (expand-fields fields early? environment)
120
(lambda () (expand-fields (cdr fields) early? environment))
121
(lambda (tail tail-size)
123
;; For opcodes and fixed fields of the instruction
126
;; (BYTE (16 (+ foo #x23) SIGNED))
129
(collect-byte (cdar fields) tail environment))
131
(values code (+ size tail-size)))))
133
;; (ModR/M 2 source) = /2 r/m(source)
134
;; (ModR/M r target) = /r r/m(target)
136
(error "No early support for ModR/M -- Fix i386/insmac.scm"))
137
(let ((field (car fields)))
138
(let ((digit-or-reg (cadr field))
140
(values `(,(close-syntax 'CONS-SYNTAX environment)
141
(,(close-syntax 'EA/REGISTER environment) ,r/m)
142
(,(close-syntax 'CONS-SYNTAX environment)
143
,(integer-syntaxer digit-or-reg environment
145
(,(close-syntax 'CONS-SYNTAX environment)
146
(,(close-syntax 'EA/MODE environment) ,r/m)
147
(,(close-syntax 'APPEND-SYNTAX! environment)
148
(,(close-syntax 'EA/EXTRA environment) ,r/m)
151
;; For immediate operands whose size depends on the operand
152
;; size for the instruction (halfword vs. longword)
155
(let ((field (car fields)))
156
(let ((value (cadr field))
157
(mode (if (pair? (cddr field)) (caddr field) 'OPERAND))
159
(if (and (pair? (cddr field)) (pair? (cdddr field)))
162
`(,(close-syntax 'CONS-SYNTAX environment)
168
((OPERAND) *operand-size*)
169
((ADDRESS) *address-size*)
170
(else (error "Unknown IMMEDIATE mode:" mode))))
174
(error "Unknown field kind:" (caar fields))))))
177
(define (collect-byte components tail environment)
178
(let loop ((components components))
179
(if (pair? components)
180
(call-with-values (lambda () (loop (cdr components)))
181
(lambda (byte-tail byte-size)
182
(let ((size (caar components))
183
(expression (cadar components))
184
(type (if (pair? (cddar components))
187
(values `(,(close-syntax 'CONS-SYNTAX environment)
188
,(integer-syntaxer expression environment type size)
190
(+ size byte-size)))))
b'\\ No newline at end of file'