3
Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
4
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
5
2006, 2007, 2008, 2009, 2010 Massachusetts Institute of Technology
7
This file is part of MIT/GNU Scheme.
9
MIT/GNU Scheme is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or (at
12
your option) any later version.
14
MIT/GNU Scheme is distributed in the hope that it will be useful, but
15
WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
General Public License for more details.
19
You should have received a copy of the GNU General Public License
20
along with MIT/GNU Scheme; if not, write to the Free Software
21
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
26
;;;; Intel 386 Instruction Set, utilities
28
(declare (usual-integrations))
32
;; r/m part of ModR/M byte and SIB byte.
33
;; These are valid only for 64-bit addressing.
43
(R/M (register-bits r)))
49
(R/M (register-bits r)))
51
;;;; Register-indirect
53
((@R (? r indirect-reg))
57
(R/M (register-bits r)))
59
;; Mode #b00, r/m 4 means SIB, so put the register in a SIB base and
60
;; use no index (i.e. index of 4).
62
((@R (? r indirect-reg=4mod8))
71
;; Mode #b00, r/m 5 means RIP-relative 32-bit offset, so use mode
72
;; #b01, r/m 5, which means the register plus 8-bit offset, and
73
;; specify a zero offset.
75
((@R (? r indirect-reg=5mod8))
82
;;;; Register-indirect with 8-bit offset
84
((@RO (? r offset-indirect-reg) (? offset sign-extended-byte))
88
(R/M (register-bits r))
89
(BITS (8 offset SIGNED)))
91
;; Mode #b01, r/m 4 means SIB plus 8-bit offset, so use the SIB base
92
;; for the register with no index (i.e. index of 4).
94
((@RO (? r offset-indirect-reg=4mod8) (? offset sign-extended-byte))
104
;;;; Register-indirect with 32-bit offset
106
((@RO (? r offset-indirect-reg) (? offset sign-extended-long))
110
(R/M (register-bits r))
111
(BITS (32 offset SIGNED)))
113
;; Same special case as above, but with 32-bit offsets.
115
((@RO (? r offset-indirect-reg=4mod8) (? offset sign-extended-long))
125
;;;; Register-indirect with index
127
((@RI (? b base-reg) (? i index-reg) (? s index-scale))
132
(BITS (3 (register-bits b))
133
(3 (register-bits i))
136
;; Mode 0, r/m 4, SIB base 5 mean the register plus 32-bit offset,
137
;; so specify a zero offset.
139
((@RI (? b base-reg=5mod8) (? i index-reg) (? s index-scale))
145
(3 (register-bits i))
149
;;;; Register-indirect with offset and scaled index
151
;; No more special cases -- except that rsp can't be the index
152
;; register at all here.
154
((@ROI (? b) (? offset sign-extended-byte) (? i index-reg) (? s index-scale))
159
(BITS (3 (register-bits b))
160
(3 (register-bits i))
164
((@ROI (? b) (? offset sign-extended-long) (? i index-reg) (? s index-scale))
169
(BITS (3 (register-bits b))
170
(3 (register-bits i))
174
;;;; RIP-relative (PC-relative)
181
(BITS (32 `(- ,label (+ *PC* 4)) SIGNED)))
183
((@PCO (? offset signed-long))
188
(BITS (32 offset SIGNED))))
190
(define-ea-transformer r-ea REGISTER)
191
(define-ea-transformer xmm-ea XMM)
192
(define-ea-transformer m-ea MEMORY)
193
(define-ea-transformer r/m-ea REGISTER MEMORY)
194
(define-ea-transformer xmm/m-ea XMM MEMORY)
196
(define-structure (effective-address
198
(constructor make-effective-address))
199
(keyword #f read-only #t)
200
(categories #f read-only #t)
201
(rex-prefix #f read-only #t)
202
(mode #f read-only #t)
203
(register #f read-only #t)
204
(extra '() read-only #t))
206
(declare (integrate-operator register-rex))
207
(define-integrable (register-rex register rex)
208
(declare (integrate register))
213
(define (cons-ModR/M digit ea tail)
214
(cons-syntax (ea/register ea)
216
(cons-syntax (ea/mode ea)
217
(append-syntax! (ea/extra ea) tail)))))
219
(declare (integrate-operator opcode-register))
220
(define (opcode-register opcode register)
221
(declare (integrate opcode))
222
(+ opcode (if (>= register 8) (- register 8) register)))
224
(declare (integrate-operator float-comparator))
225
(define (float-comparator comparator)
235
(else (error "Bad float comparator:" comparator))))
237
(declare (integrate-operator operand-size))
238
(define (operand-size s)
239
;; B must be handled separately in general.
244
(declare (integrate-operator float-packed/scalar))
245
(define (float-packed/scalar s)
250
(declare (integrate-operator float-precision))
251
(define (float-precision s)
256
;;; The REX prefix must come last, just before the `actual' opcode.
258
(define (cons-prefix operand-size register ea tail)
260
(if (eq? operand-size 'W)
261
(cons-syntax (syntax-evaluation #x66 coerce-8-bit-unsigned)
264
((lambda (rex-prefix)
265
(if (zero? rex-prefix)
267
(cons-syntax (syntax-evaluation rex-prefix coerce-8-bit-unsigned)
271
;; B must be handled separately; there is no prefix for it.
272
;; W is handled with a #x66 prefix.
276
(else (error "Invalid operand size:" operand-size)))
277
(let ((extended-register?
278
(or (eqv? register #t)
279
(and register (>= register 8)))))
281
(fix:or (if extended-register? #x44 0) (ea/rex-prefix ea))
282
(if extended-register? #x41 0)))))))
284
(define (cons-float-prefix register ea packed/scalar precision tail)
286
(let ((float (list packed/scalar precision)))
287
(if (equal? float '(P S))
289
(cons-syntax (syntax-evaluation
290
(cond ((equal? float '(P D)) #x66)
291
((equal? float '(S D)) #xF2)
292
((equal? float '(S S)) #xF3)
293
(else (error "Bad float type:" float)))
294
coerce-8-bit-unsigned)
297
(let ((extended-register?
298
(or (eqv? register #t)
299
(and register (>= register 8)))))
301
(fix:or (if extended-register? #x44 0) (ea/rex-prefix ea))
302
(if extended-register? #x41 0)))))
303
(if (zero? rex-prefix)
305
(cons-syntax (syntax-evaluation rex-prefix coerce-8-bit-unsigned)
308
(define-integrable (register-bits r)
311
(declare (integrate-operator indirect-reg))
312
(define (indirect-reg r)
313
(and (not (let ((bits (register-bits r)))
318
(declare (integrate-operator indirect-reg=4mod8))
319
(define (indirect-reg=4mod8 r)
320
(and (= (register-bits r) 4)
323
(declare (integrate-operator indirect-reg=5mod8))
324
(define (indirect-reg=5mod8 r)
325
(and (= (register-bits r) 5)
328
(declare (integrate-operator offset-indirect-reg))
329
(define (offset-indirect-reg r)
330
(and (not (= (register-bits r) 4))
333
(declare (integrate-operator offset-indirect-reg=4mod8))
334
(define (offset-indirect-reg=4mod8 r)
335
(and (= (register-bits r) 4)
338
(declare (integrate-operator base-reg))
340
(and (not (= (register-bits r) 5))
343
(declare (integrate-operator base-reg=5mod8))
344
(define (base-reg=5mod8 r)
345
(and (= (register-bits r) 5)
348
(declare (integrate-operator index-reg))
349
(define (index-reg r)
353
(define-integrable (index-scale scale-value)
361
(declare (integrate-operator unsigned-2bit))
362
(define (unsigned-2bit value)
363
(and (<= 0 value #b11) value))
365
(declare (integrate-operator unsigned-3bit))
366
(define (unsigned-3bit value)
367
(and (<= 0 value #b111) value))
369
(declare (integrate-operator unsigned-5bit))
370
(define (unsigned-5bit value)
371
(and (<= 0 value #b11111) value))
373
(define (signed-byte value)
374
(and (fits-in-signed-byte? value)
377
(define (unsigned-byte value)
378
(and (fits-in-unsigned-byte? value)
381
(define (signed-word value)
382
(and (fits-in-signed-word? value)
385
(define (unsigned-word value)
386
(and (fits-in-unsigned-word? value)
389
(define (signed-long value)
390
(and (fits-in-signed-long? value)
393
(define (unsigned-long value)
394
(and (fits-in-unsigned-long? value)
397
(define (signed-quad value)
398
(and (fits-in-signed-quad? value)
401
(define (unsigned-quad value)
402
(and (fits-in-unsigned-quad? value)
405
(define (sign-extended-byte value)
406
(and (fits-in-signed-byte? value)
409
(define (zero-extended-byte value)
410
(and (not (negative? value))
411
(fits-in-signed-byte? value)
414
(define (sign-extended-word value)
415
(and (fits-in-signed-word? value)
418
(define (zero-extended-word value)
419
(and (not (negative? value))
420
(fits-in-signed-word? value)
423
(define (sign-extended-long value)
424
(and (fits-in-signed-long? value)
427
(define (zero-extended-long value)
428
(and (not (negative? value))
429
(fits-in-signed-long? value)
432
(define (sign-extended-quad value)
433
(and (fits-in-signed-quad? value)
436
(define (zero-extended-quad value)
437
(and (not (negative? value))
438
(fits-in-signed-quad? value)
b'\\ No newline at end of file'