mescc: Tinycc support: Support bit-fields.
[mes.git] / module / mes / as-i386.mes
1 ;;; -*-scheme-*-
2
3 ;;; Mes --- Maxwell Equations of Software
4 ;;; Copyright © 2016,2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
5 ;;;
6 ;;; This file is part of Mes.
7 ;;;
8 ;;; Mes is free software; you can redistribute it and/or modify it
9 ;;; under the terms of the GNU General Public License as published by
10 ;;; the Free Software Foundation; either version 3 of the License, or (at
11 ;;; your option) any later version.
12 ;;;
13 ;;; Mes is distributed in the hope that it will be useful, but
14 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;;; GNU General Public License for more details.
17 ;;;
18 ;;; You should have received a copy of the GNU General Public License
19 ;;; along with Mes.  If not, see <http://www.gnu.org/licenses/>.
20
21 ;;; Commentary:
22
23 ;;; as-i386.mes defines i386 assembly
24
25 ;;; Code:
26
27 (cond-expand
28  (guile-2)
29  (guile)
30  (mes
31   (mes-use-module (mes as))))
32
33 (define (i386:nop)
34   '(("nop")))
35
36 (define (i386:function-preamble)
37   '(("push___%ebp")
38     ("mov____%esp,%ebp")))
39
40 (define (i386:function-locals)
41   `(("sub____%esp,$i32" (#:immediate ,(+ (* 4 1025) (* 20 4)))))) ; sub %esp,xxx 4*1024 buf, 20 local vars
42
43 (define (i386:push-label label)
44   `(("push___$i32" (#:address ,label)))) ; push  $0x<label>
45
46 (define (i386:push-label-mem label)
47   `(("mov____0x32,%eax" (#:address ,label)) ; mov    0x804a000,%eax
48     ("push___%eax")))                       ; push  %eax
49
50
51 ;;; \f locals
52
53 (define (i386:push-local n)
54   (or n (error "invalid value: push-local: " n))
55   (let ((n (- 0 (* 4 n))))
56     `(,(if (< (abs n) #x80) `("push___0x8(%ebp)" (#:immediate1 ,n))
57            `("push___0x32(%ebp)" (#:immediate ,n))))))
58
59 (define (i386:push-local-address n)
60   (or n (error "invalid value: push-local-address: " n))
61   (let ((n (- 0 (* 4 n))))
62     `(,(if (< (abs n) #x80) `("lea____0x8(%ebp),%eax" (#:immediate1 ,n))
63            `("lea____0x32(%ebp),%eax" (#:immediate ,n)))
64       ("push___%eax"))))
65
66 (define (i386:push-byte-local-de-ref n)
67   (or n (error "invalid value: push-byte-local-de-ref: " n))
68   (let ((n (- 0 (* 4 n))))
69     `(,(if (< (abs n) #x80) `("mov____0x8(%ebp),%eax" (#:immediate1 ,n))
70            `("mov____0x32(%ebp),%eax" (#:immediate ,n)))
71       ("movzbl_(%eax),%eax")
72       ("push___%eax"))))
73
74 (define (i386:push-word-local-de-ref n)
75   (or n (error "invalid value: push-word-local-de-ref: " n))
76   (let ((n (- 0 (* 4 n))))
77     `(,(if (< (abs n) #x80) `("mov____0x8(%ebp),%eax" (#:immediate1 ,n))
78            `("mov____0x32(%ebp),%eax" (#:immediate ,n)))
79       ("movzwl_(%eax),%eax")
80       ("push___%eax"))))
81
82 (define (i386:push-byte-local-de-de-ref n)
83   (or n (error "invalid value: push-byte-local-de-de-ref: " n))
84   (let ((n (- 0 (* 4 n))))
85     `(,(if (< (abs n) #x80) `("mov____0x8(%ebp),%eax" (#:immediate1 ,n))
86            `("mov____0x32(%ebp),%eax" (#:immediate ,n)))
87       ("mov____(%eax),%eax")
88       ("movzbl_(%eax),%eax")
89       ("push___%eax"))))
90
91 (define (i386:push-local-de-ref n)
92   (or n (error "invalid value: push-byte-local-de-ref: " n))
93   (let ((n (- 0 (* 4 n))))
94     `(,(if (< (abs n) #x80) `("mov____0x8(%ebp),%eax" (#:immediate1 ,n))
95            `("mov____0x32(%ebp),%eax" (#:immediate ,n)))
96       ("mov____(%eax),%eax")
97       ("push___%eax"))))
98
99 (define (i386:local-add n v)
100   (or n (error "invalid value: i386:local-add: " n))
101   (let ((n (- 0 (* 4 n))))
102     `(,(if (and (< (abs n) #x80)
103                 (< (abs v) #x80)) `("add____$i8,0x8(%ebp)" (#:immediate1 ,n) (#:immediate1 ,v))
104                 `("add____$i32,0x32(%ebp)" (#:immediate ,n) (#:immediate ,v))))))
105
106 (define (i386:accu->local n)
107   (or n (error "invalid value: accu->local: " n))
108   (let ((n (- 0 (* 4 n))))
109     `(,(if (< (abs n) #x80) `("mov____%eax,0x8(%ebp)" (#:immediate1 ,n))
110            `("mov____%eax,0x32(%ebp)" (#:immediate ,n))))))
111
112 (define (i386:accu->local+n id n)
113   (let ((n (+ (- 0 (* 4 id)) n)))
114     `(,(if (< (abs n) #x80) `("mov____%eax,0x8(%ebp)" (#:immediate1 ,n))
115            `("mov____%eax,0x32(%ebp)" (#:immediate ,n))))))
116
117 (define (i386:byte-accu->local+n id n)
118   (let ((n (+ (- 0 (* 4 id)) n)))
119     `(,(if (< (abs n) #x80) `("mov____%al,0x8(%ebp)" (#:immediate1 ,n))
120            `("mov____%al,0x32(%ebp)" (#:immediate ,n))))))
121
122 (define (i386:word-accu->local+n id n)
123   (let ((n (+ (- 0 (* 4 id)) n)))
124     `(,(if (< (abs n) #x80) `("mov____%ax,0x8(%ebp)" (#:immediate1 ,n))
125            `("mov____%ax,0x32(%ebp)" (#:immediate ,n))))))
126
127 (define (i386:accu*n->local i n)
128   (or n (error "invalid value: accu->local: " n))
129   (let ((o (- 0 (* 4 i))))
130     (let loop ((i 0))
131       (if (>= i n) '()  ;; FIXME: byte, word-sized
132           (let ((o (+ o i)))
133             (append
134              (if (< (abs o) #x80) `(("mov____0x8(%eax),%ebx" (#:immediate1 ,i))
135                                     ("mov____%ebx,0x8(%ebp)" (#:immediate1 ,o)))
136                  `(("mov____0x8(%eax),%ebx" (#:immediate1 ,i))
137                    ("mov____%ebx,0x32(%ebp)" (#:immediate ,o))))
138              (loop (+ i 4))))))))
139
140 (define (i386:local->accu n)
141   (or n (error "invalid value: local->accu: " n))
142   (let ((n (- 0 (* 4 n))))
143     `(,(if (< (abs n) #x80) `("mov____0x8(%ebp),%eax" (#:immediate1 ,n))
144            `("mov____0x32(%ebp),%eax" (#:immediate ,n))))))
145
146 (define (i386:local-address->accu n)
147   (or n (error "invalid value: ladd: " n))
148   (let ((n (- 0 (* 4 n))))
149     `(,(if (< (abs n) #x80) `("lea____0x8(%ebp),%eax" (#:immediate1 ,n))
150            `("lea____0x32(%ebp),%eax" (#:immediate ,n))))))
151
152 (define (i386:local-ptr->accu n)
153   (or n (error "invalid value: local-ptr->accu: " n))
154   (let ((n (- 0 (* 4 n))))
155   `(("mov____%ebp,%eax")                ; mov    %ebp,%eax
156     ,(if (< (abs n) #x80) `("add____$i8,%eax" (#:immediate1 ,n))
157          `("add____$i32,%eax" (#:immediate ,n))))))
158
159 (define (i386:byte-local->accu n)
160   (or n (error "invalid value: byte-local->accu: " n))
161   (let ((n (- 0 (* 4 n))))
162     `(,(if (< (abs n) #x80) `("movzbl_0x8(%ebp),%eax" (#:immediate1 ,n))
163            `("movzbl_0x32(%ebp),%eax" (#:immediate ,n))))))
164
165 (define (i386:word-local->accu n)
166   (or n (error "invalid value: word-local->accu: " n))
167   (let ((n (- 0 (* 4 n))))
168     `(,(if (< (abs n) #x80) `("movzwl_0x8(%ebp),%eax" (#:immediate1 ,n))
169            `("movzwl_0x32(%ebp),%eax" (#:immediate ,n))))))
170
171 (define (i386:byte-local->base n)
172   (or n (error "invalid value: byte-local->base: " n))
173   (let ((n (- 0 (* 4 n))))
174     `(,(if (< (abs n) #x80) `("movzbl_0x8(%ebp),%edx" (#:immediate1 ,n))
175            `,@(("mov_0x32(%ebp),%edx" (#:immediate ,n))
176                ("movzbl_%dl,%edx"))))))
177
178 (define (i386:local->base n)
179   (or n (error "invalid value: local->base: " n))
180   (let ((n (- 0 (* 4 n))))
181     `(,(if (< (abs n) #x80) `("mov____0x8(%ebp),%edx" (#:immediate1 ,n))
182            `("mov____0x32(%ebp),%edx" (#:immediate ,n))))))
183
184 (define (i386:local-address->base n) ;; DE-REF
185   (or n (error "invalid value: local-address->base: " n))
186   (let ((n (- 0 (* 4 n))))
187     `(,(if (< (abs n) #x80) `("lea____0x8(%ebp),%edx" (#:immediate1 ,n))
188            `("lea____0x32(%ebp),%edx" (#:immediate ,n))))))
189
190 (define (i386:local-ptr->base n)
191   (or n (error "invalid value: local-ptr->base: " n))
192   (let ((n (- 0 (* 4 n))))
193     `(("mov____%ebp,%edx")                ; mov    %ebp,%edx
194       ,(if (< (abs n) #x80) `("add____$i8,%edx" (#:immediate1 ,n))
195            `("add____$i32,%edx" (#:immediate ,n))))))
196
197 (define (i386:value->local n v)
198   (or n (error "invalid value: value->local: " n))
199   (let ((n (- 0 (* 4 n))))
200     `(,(if (< (abs n) #x80) `("mov____$i32,0x8(%ebp)" (#:immediate1 ,n) (#:immediate ,v))
201            `("mov____$i32,0x32(%ebp)" (#:immediate ,n) (#:immediate ,v))))))
202
203 (define (i386:local-test n v)
204   (or n (error "invalid value: local-test: " n))
205   (let ((n (- 0 (* 4 n))))
206     `(,(cond ((and (< (abs n) #x80)
207                    (< (abs v) #x80)) `("cmp____$i8,0x8(%ebp)" (#:immediate1 ,n) (#:immediate1 ,v)))
208              ((< (abs n) #x80) `("cmp____$i32,0x8(%ebp)" (#:immediate1 ,n) (#:immediate ,v)))
209              ((< (abs v) #x80) `("cmp____$i8,0x32(%ebp)" (#:immediate ,n) (#:immediate1 ,v)))
210              (else `("cmp____$i32,0x32(%ebp)" (#:immediate ,n) (#:immediate ,v)))))))
211
212 (define (i386:pop-accu)
213   '(("pop____%eax")))                   ; pop %eax
214
215 (define (i386:push-accu)
216   '(("push___%eax")))                   ; push %eax
217
218 (define (i386:pop-base)
219   '(("pop____%edx")))                   ; pop %edx
220
221 (define (i386:push-base)
222   '(("push___%edx")))                   ; push %edx
223
224 (define (i386:ret)
225   '(("leave")                           ; leave
226     ("ret")))                           ; ret
227
228 (define (i386:accu->base)
229   '(("mov____%eax,%edx")))              ; mov    %eax,%edx
230
231 (define (i386:accu->base-mem)
232   '(("mov____%eax,(%edx)")))            ; mov    %eax,(%edx)
233
234 (define (i386:byte-accu->base-mem)
235   '(("mov____%al,(%edx)")))             ; mov    %al,(%edx)
236
237 (define (i386:word-accu->base-mem)
238   '(("mov____%ax,(%edx)")))             ; mov    %ax,(%edx)
239
240 (define (i386:accu->base-mem+n n)
241   (or n (error "invalid value: accu->base-mem+n: " n))
242   `(,(if (< (abs n) #x80) `("mov____%eax,0x8(%edx)" (#:immediate1 ,n))
243          `("mov____%eax,0x32(%edx)" (#:immediate ,n)))))
244
245 (define (i386:byte-accu->base-mem+n n)
246   (or n (error "invalid value: accu->base-mem+n: " n))
247   `(,(if (< (abs n) #x80) `("mov____%al,0x8(%edx)" (#:immediate1 ,n))
248          `("mov____%al,0x32(%edx)" (#:immediate ,n)))))
249
250 (define (i386:word-accu->base-mem+n n)
251   (or n (error "invalid value: accu->base-mem+n: " n))
252   `(,(if (< (abs n) #x80) `("mov____%ax,0x8(%edx)" (#:immediate1 ,n))
253          `("mov____%ax,0x32(%edx)" (#:immediate ,n)))))
254
255 (define (i386:accu->label label)
256   `(("mov____%eax,0x32" (#:address ,label)))) ; mov    %eax,0x<label>
257
258 (define (i386:accu*n->label label n)
259   (append
260    '(("push___%edx"))
261    (let loop ((i 0))
262      (if (>= i n) '() ;; FIXME: byte, word-sized
263          (append
264           `(("mov____$i32,%edx" (#:address ,label))
265             ("mov____0x8(%eax),%ebx" (#:immediate1 ,i))
266             ("mov____%ebx,0x8(%edx)" (#:immediate1 ,i)))
267           (loop (+ i 4)))))
268    '(("pop____%edx"))))
269
270 (define (i386:accu-shl n)
271   (or n (error "invalid value: accu:shl n: " n))
272   `(("shl____$i8,%eax" (#:immediate1 ,n)))) ; shl    $0x8,%eax
273
274 (define (i386:accu<<base)
275   '(("xor____%ecx,%ecx")                ; xor    %ecx,%ecx
276     ("mov____%edx,%ecx")                ; mov    %edx,%ecx
277     ("shl____%cl,%eax")))               ; shl    %cl,%eax
278
279 (define (i386:accu>>base)
280   '(("xor____%ecx,%ecx")                ; xor    %ecx,%ecx
281     ("mov____%edx,%ecx")                ; mov    %edx,%ecx
282     ("shr____%cl,%eax")))               ; shr    %cl,%eax
283
284 (define (i386:accu-and-base)
285   '(("and____%edx,%eax")))
286
287 (define (i386:accu-and v)
288   `(("and____$i32,%eax" (#:immediate ,v))))
289
290 (define (i386:accu-and-base-mem)
291   '(("and____(%edx),%eax")))
292
293 (define (i386:accu-or-base-mem)
294   '(("or_____(%edx),%eax")))
295
296 (define (i386:accu-not)
297   '(("not____%eax")))                   ; not %eax
298
299 (define (i386:accu-or-base)
300   '(("or_____%edx,%eax")))              ; or    %edx,%eax
301
302 (define (i386:accu-xor-base)
303   '(("xor____%edx,%eax")))              ; xor    %edx,%eax
304
305 (define (i386:accu+accu)
306   '(("add____%eax,%eax")))              ; add    %eax,%eax
307
308 (define (i386:accu+base)
309   `(("add____%edx,%eax")))              ; add    %edx,%eax
310
311 (define (i386:accu+value v)
312   `(,(if (< (abs v) #x80) `("add____$i8,%eax" (#:immediate1 ,v))
313          `("add____$i32,%eax" (#:immediate ,v)))))
314
315 (define (i386:base+value v)
316   `(,(if (< (abs v) #x80) `("add____$i8,%edx" (#:immediate1 ,v))
317          `("add____$i32,%edx" (#:immediate ,v)))))
318
319 (define (i386:accu-base)
320   `(("sub____%edx,%eax")))              ; sub    %edx,%eax
321
322 (define (i386:accu*base)
323   `(("mul____%edx")))                   ; mul    %edx
324
325 (define (i386:accu/base)
326   '(("mov____%edx,%ebx")                ; mov    %edx,%ebx
327     ("xor____%edx,%edx")                ; xor    %edx,%edx
328     ("idiv___%ebx")))                   ; div    %ebx
329
330 (define (i386:accu%base)
331   '(("mov____%edx,%ebx")                ; mov    %edx,%ebx
332     ("xor____%edx,%edx")                ; xor    %edx,%edx
333     ("idiv___%ebx")                     ; div    %ebx
334     ("mov____%edx,%eax")))              ; mov    %edx,%eax
335
336 (define (i386:base->accu)
337   '(("mov____%edx,%eax")))              ; mov    %edx,%eax
338
339 (define (i386:label->accu label)
340   `(("mov____$i32,%eax" (#:address ,label)))) ; mov    $<n>,%eax
341
342 (define (i386:label->base label)
343   `(("mov____$i32,%edx" (#:address ,label)))) ; mov   $<n>,%edx
344
345 (define (i386:label-mem->accu label)
346   `(("mov____0x32,%eax" (#:address ,label)))) ; mov    0x<n>,%eax
347
348 (define (i386:label-mem->base label)
349   `(("mov____0x32,%edx" (#:address ,label)))) ; mov    0x<n>,%edx
350
351 (define (i386:label-mem-add label v)
352   `(,(if (< (abs v) #x80) `("add____$i8,0x32" (#:address ,label) (#:immediate1 ,v))
353          `("add____$i32,0x32" (#:address ,label) (#:immediate ,v)))))
354
355 (define (i386:byte-base-mem->accu)
356   '(("add____%edx,%eax")                ; add    %edx,%eax
357     ("movzbl_(%eax),%eax")))            ; movzbl (%eax),%eax
358
359 (define (i386:byte-mem->accu)
360   '(("movzbl_(%eax),%eax")))            ; movzbl (%eax),%eax
361
362 (define (i386:word-mem->accu)
363   '(("movzwl_(%eax),%eax")))
364
365 (define (i386:byte-mem->base)
366   '(("movzbl_(%edx),%edx")))            ; movzbl (%edx),%edx
367
368 (define (i386:base-mem->accu)
369   '(("mov____(%edx),%eax")))
370
371 (define (i386:mem->accu)
372   '(("mov____(%eax),%eax")))
373
374 (define (i386:mem->base)
375   '(("mov____(%edx),%edx")))
376
377 (define (i386:mem+n->accu n)
378   `(,(if (< (abs n) #x80) `("mov____0x8(%eax),%eax" (#:immediate1 ,n))
379          `("mov____0x32(%eax),%eax" (#:immediate ,n)))))
380
381 (define (i386:byte-mem+n->accu n)
382   `(,(if (< (abs n) #x80) `("movzbl_0x8(%eax),%eax" (#:immediate1 ,n))
383          `("movzbl_0x32(%eax),%eax" (#:immediate ,n)))))
384
385 (define (i386:word-mem+n->accu n)
386   `(,(if (< (abs n) #x80) `("movzwl_0x8(%eax),%eax" (#:immediate1 ,n))
387          `("movzwl_xb0x32(%eax),%eax" (#:immediate ,n)))))
388
389 (define (i386:base-mem+n->accu v)
390   (or v (error "invalid value: base-mem+n->accu: " v))
391   `(("add___%edx,%eax")
392     ,(if (< (abs v) #x80) `("mov____0x8(%eax),%eax" (#:immediate1 ,v))
393          `("mov____0x32(%eax),%eax" (#:immediate ,v)))))
394
395 (define (i386:value->accu v)
396   (or v (error "invalid value: i386:value->accu: " v))
397   `(("mov____$i32,%eax" (#:immediate ,v)))) ; mov    $<v>,%eax
398
399 (define (i386:value->accu-mem v)
400   `(("mov____$i32,(%eax)" (#:immediate ,v)))) ; movl   $0x<v>,(%eax)
401
402 (define (i386:value->accu-mem+n n v)
403   (or v (error "invalid value: i386:value->accu-mem+n: " v))
404   `(,(if (< (abs v) #x80) `("mov____$i32,0x8(%eax)" (#:immediate1 ,n) (#:immediate ,v))
405          `("mov____$i32,0x32(%eax)" (#:immediate ,n) (#:immediate ,v)))))
406
407 (define (i386:base->accu-mem)
408   '(("mov____%edx,(%eax)")))            ; mov    %edx,(%eax)
409
410 (define (i386:accu-mem->base-mem)
411   '(("mov____(%eax),%ecx")
412     ("mov____%ecx,(%edx)")))
413
414 (define (i386:base-mem->accu-mem)
415   '(("mov____(%edx),%ecx")              ; mov    (%edx),%ecx
416     ("mov____%ecx,(%eax)")))            ; mov    %ecx,(%eax)
417
418 (define (i386:byte-base->accu-mem)
419   '(("mov____%dl,(%eax)")))             ; mov    %dl,(%eax)
420
421 (define (i386:byte-base->accu-mem+n n)
422   (or n (error "invalid value: byte-base->accu-mem+n: " n))
423   `(,(if (< (abs n) #x80) `("mov____%dl,0x8(%eax)" (#:immediate1 ,n))
424          `("mov____%dl,0x32(%eax)" (#:immediate ,n)))))
425
426 (define (i386:value->base v)
427   (or v (error "invalid value: i386:value->base: " v))
428   `(("mov____$i32,%edx" (#:immediate ,v)))) ; mov    $<v>,%edx
429
430 (define (i386:accu-mem-add v)
431   `(,(if (< (abs v) #x80) `("add____$i8,(%eax)" (#:immediate1 ,v))
432          `("add____$i32,(%eax)" (#:immediate ,v)))))
433
434 (define (i386:value->label label v)
435   (or v (error "invalid value: value->label: " v))
436   `(("mov____$i32,0x32" (#:address ,label)
437      (#:immediate ,v))))
438
439 (define (i386:call-label label n)
440   `((call32 (#:offset ,label))
441     ("add____$i8,%esp" (#:immediate1 ,(* n 4)))))
442
443 (define (i386:call-accu n)
444   `(,@(i386:push-accu)
445     ,@(i386:pop-accu)
446     ("call___*%eax")                    ; call   *%eax
447     ("add____$i8,%esp" (#:immediate1  ,(* n 4))))) ; add    $00,%esp
448
449 (define (i386:accu-zero?)
450   '(("test___%eax,%eax")))
451
452 (define (i386:accu-negate)
453   '(("sete___%al")                      ; sete %al
454     ("movzbl_%al,%eax")))               ; movzbl %al,%eax
455
456 (define (i386:xor-accu v)
457   (or v (error "invalid value: i386:xor-accu: n: " v))
458   `(("xor___$i32,%eax" (#:immediate ,v)))) ;xor    $0xff,%eax
459
460 (define (i386:xor-zf)
461   '(("lahf")                               ; lahf
462     ("xor____$i8,%ah" (#:immediate1 #x40)) ; xor    $0x40,%ah
463     ("sahf")))                             ; sahf
464
465 (define (i386:accu-cmp-value v)
466   `(,(if (< (abs v) #x80) `("cmp____$i8,%eax" (#:immediate1 ,v))
467          `("cmp____$i32,%eax" (#:immediate ,v)))))
468
469 (define (i386:accu-test)
470   '(("test___%eax,%eax")))              ; test   %eax,%eax
471
472 (define (i386:jump label)
473   `(("jmp32 " (#:offset ,label))))
474
475 (define (i386:jump-z label)
476   `(("je32  " (#:offset ,label))))        ; jz . + <n>
477
478 (define (i386:jump-byte-z label)
479   `(("test___%al,%al")                  ; test   %al,%al
480     ("je32  " (#:offset ,label))))      ; je <n>
481
482 ;; signed
483 (define (i386:jump-g label)
484   `(("jg32  " (#:offset ,label))))        ; jg/jnle <n>
485
486 ;; signed
487 (define (i386:jump-ge label)
488   `(("jge32 " (#:offset ,label))))       ; jge/jnl <n>
489
490 ;; signed
491 (define (i386:jump-l label)
492   `(("jl32  " (#:offset ,label))))
493
494 ;; signed
495 (define (i386:jump-le label)
496   `(("jle32 " (#:offset ,label))))
497
498 (define (i386:jump-nz label)
499   `(("jne32 " (#:offset ,label))))       ; jnz . + <n>
500
501 (define (i386:byte-test-base)
502   '(("cmp____%al,%dl")))                ; cmp    %al,%dl
503
504 (define (i386:test-base)
505   (("cmp____%edx,%eax")))               ; cmp    %edx,%eax
506
507 (define (i386:byte-sub-base)
508   '(("sub____%dl,%al")))                ; sub    %dl,%al
509
510 (define (i386:byte-base-sub)
511   `(("sub____%al,%dl")))                ; sub    %al,%dl
512
513 (define (i386:sub-base)
514   `(("sub____%edx,%eax")))              ; sub    %edx,%eax
515
516 (define (i386:base-sub)
517   `(("sub____%eax,%edx")))              ; sub    %eax,%edx
518
519 (define (i386:g?->accu)
520   '(("setg___%al")
521     ("movzbl_%al,%eax")))
522
523 (define (i386:ge?->accu)
524   '(("setge__%al")
525     ("movzbl_%al,%eax")))
526
527 (define (i386:l?->accu)
528   '(("setl___%al")
529     ("movzbl_%al,%eax")))
530
531 (define (i386:le?->accu)
532   '(("setle__%al")
533     ("movzbl_%al,%eax")))
534
535 (define (i386:nz->accu)
536   '(("setne__%al")                      ; setne   %al
537     ("movzbl_%al,%eax")))               ; movzbl %al,%eax
538
539 (define (i386:z->accu)
540   '(("sete___%al")                      ; sete   %al
541     ("movzbl_%al,%eax")))               ; movzbl %al,%eax
542
543 (define (i386:accu<->stack)
544   '(("xchg___%eax,(%esp)")))            ; xchg   %eax,(%esp)