1#| -*-Scheme-*-
2
3Copyright (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, 2011, 2012, 2013, 2014 Massachusetts
6    Institute of Technology
7
8This file is part of MIT/GNU Scheme.
9
10MIT/GNU Scheme is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2 of the License, or (at
13your option) any later version.
14
15MIT/GNU Scheme is distributed in the hope that it will be useful, but
16WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with MIT/GNU Scheme; if not, write to the Free Software
22Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
23USA.
24
25|#
26
27;;;; Intel 386 Instruction Set, utilities
28
29(declare (usual-integrations))
30
31;;;; Addressing modes
32
33;; r/m part of ModR/M byte and SIB byte.
34;; These are valid only for 32-bit addressing.
35
36(define-ea-database
37  ((R (? r))
38   (REGISTER)
39   #b11 r)
40
41  ((@R (? r indirect-reg))
42   (MEMORY)
43   #b00 r)
44
45  ((@R 5)				; EBP
46   (MEMORY)
47   #b01 5
48   (BYTE (8 0)))
49
50  ((@R 4)				; ESP
51   (MEMORY)
52   #b00 4
53   (BYTE (3 4)
54	 (3 4)
55	 (2 0)))
56
57  ((@RO B (? r index-reg) (? offset))
58   (MEMORY)
59   #b01 r
60   (BYTE (8 offset SIGNED)))
61
62  ((@RO UB (? r index-reg) (? offset))
63   (MEMORY)
64   #b01 r
65   (BYTE (8 offset UNSIGNED)))
66
67  ((@RO B 4 (? offset))
68   (MEMORY)
69   #b01 4
70   (BYTE (3 4)
71	 (3 4)
72	 (2 0)
73	 (8 offset SIGNED)))
74
75  ((@RO UB 4 (? offset))
76   (MEMORY)
77   #b01 4
78   (BYTE (3 4)
79	 (3 4)
80	 (2 0)
81	 (8 offset UNSIGNED)))
82
83  ((@RO W (? r index-reg) (? offset))
84   (MEMORY)
85   #b10 r
86   (IMMEDIATE offset ADDRESS SIGNED))
87
88  ((@RO UW (? r index-reg) (? offset))
89   (MEMORY)
90   #b10 r
91   (IMMEDIATE offset ADDRESS UNSIGNED))
92
93  ((@RO W 4 (? offset))			; ESP
94   (MEMORY)
95   #b10 #b100
96   (BYTE (3 4)
97	 (3 4)
98	 (2 0))
99   (IMMEDIATE offset ADDRESS SIGNED))
100
101  ((@RO UW 4 (? offset))		; ESP
102   (MEMORY)
103   #b10 #b100
104   (BYTE (3 4)
105	 (3 4)
106	 (2 0))
107   (IMMEDIATE offset ADDRESS UNSIGNED))
108
109  ((@RI (? b base-reg) (? i index-reg) (? s index-scale))
110   (MEMORY)
111   #b00 #b100
112   (BYTE (3 b)
113	 (3 i)
114	 (2 s)))
115
116  ((@RI 5 (? i index-reg) (? s index-scale)) ; EBP
117   (MEMORY)
118   #b01 #b100
119   (BYTE (3 5)
120	 (3 i)
121	 (2 s)
122	 (8 0)))
123
124  ((@ROI B (? b) (? offset) (? i index-reg) (? s index-scale))
125   (MEMORY)
126   #b01 #b100
127   (BYTE (3 b)
128	 (3 i)
129	 (2 s)
130	 (8 offset SIGNED)))
131
132  ((@ROI UB (? b) (? offset) (? i index-reg) (? s index-scale))
133   (MEMORY)
134   #b01 #b100
135   (BYTE (3 b)
136	 (3 i)
137	 (2 s)
138	 (8 offset UNSIGNED)))
139
140  ((@ROI W (? b) (? offset) (? i index-reg) (? s index-scale))
141   (MEMORY)
142   #b10 #b100
143   (BYTE (3 b)
144	 (3 i)
145	 (2 s))
146   (IMMEDIATE offset ADDRESS SIGNED))
147
148  ((@ROI UW (? b) (? offset) (? i index-reg) (? s index-scale))
149   (MEMORY)
150   #b10 #b100
151   (BYTE (3 b)
152	 (3 i)
153	 (2 s))
154   (IMMEDIATE offset ADDRESS UNSIGNED))
155
156  ((@ (? value))
157   (MEMORY)
158   #b00 #b101
159   (IMMEDIATE value ADDRESS)))
160
161(define-ea-transformer r/mW)
162(define-ea-transformer mW MEMORY)
163(define-ea-transformer r/mB)
164(define-ea-transformer mB MEMORY)
165
166(define-structure (effective-address
167		   (conc-name ea/)
168		   (constructor make-effective-address))
169  (keyword false read-only true)
170  (categories false read-only true)
171  (mode false read-only true)
172  (register false read-only true)
173  (extra '() read-only true))
174
175(define (sign-extended-byte value)
176  (and (fits-in-signed-byte? value)
177       value))
178
179(define (zero-extended-byte value)
180  (and (fits-in-unsigned-byte? value)
181       value))
182
183(define-integrable (indirect-reg r)
184  (and (not (= r esp))
185       (not (= r ebp))
186       r))
187
188(define-integrable (base-reg r)
189  (and (not (= r ebp))
190       r))
191
192(define-integrable (index-reg r)
193  (and (not (= r esp))
194       r))
195
196(define (index-scale scale-value)
197  (case scale-value
198    ((1) #b00)
199    ((2) #b01)
200    ((4) #b10)
201    ((8) #b11)
202    (else false)))