* add p cc
[mascara-docs.git] / compilers / pcc / pcc-1.0.0 / arch / pdp10 / table.c
blob4e140c5bae571d5dfa2888ada5e87bf4227ad28b
1 /* $Id: table.c,v 1.97 2008/02/10 19:25:44 ragge Exp $ */
2 /*
3 * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 # include "pass2.h"
32 # define TLL TLONGLONG|TULONGLONG
33 # define ANYSIGNED TINT|TLONG|TSHORT|TCHAR
34 # define ANYUSIGNED TUNSIGNED|TULONG|TUSHORT|TUCHAR
35 # define ANYFIXED ANYSIGNED|ANYUSIGNED
36 # define TUWORD TUNSIGNED|TULONG
37 # define TSWORD TINT|TLONG
38 # define TWORD TUWORD|TSWORD
40 struct optab table[] = {
41 { -1, FORREW,SANY,TANY,SANY,TANY,REWRITE,-1,"", },
43 * A bunch of pointer conversions.
44 * First pointer to integer.
46 /* Convert char pointer to int */
47 { SCONV, INAREG,
48 SAREG|SAREG, TPTRTO|TCHAR|TUCHAR,
49 SANY, TWORD,
50 NAREG, RLEFT,
51 " lsh AL,2\n"
52 " move A1,AL\n"
53 " lsh A1,-040\n"
54 " trz A1,074\n"
55 " ior AL,A1\n"
56 " tlz AL,0740000\n", },
58 /* Convert short pointer to int */
59 { SCONV, INAREG,
60 SAREG|SAREG, TPTRTO|TSHORT|TUSHORT,
61 SANY, TWORD,
62 NAREG, RLEFT,
63 " lsh AL,2\n"
64 " move A1,AL\n"
65 " lsh A1,-041\n"
66 " trz A1,2\n"
67 " ior AL,A1\n"
68 " tlz AL,0740000\n", },
70 /* Convert int/unsigned/long/ulong/struct/union/func ptr to int */
71 { SCONV, INAREG,
72 SAREG|SAREG, TPTRTO|TWORD|TSTRUCT|TPOINT,
73 SANY, TWORD,
74 0, RLEFT,
75 " lsh AL,2\n", },
78 * Convert int/long to pointers.
80 /* Convert int to char pointer */
81 { PCONV, INAREG,
82 SAREG, TWORD,
83 SANY, TPTRTO|TCHAR|TUCHAR,
84 NAREG, RLEFT,
85 " move A1,AL\n"
86 " lsh A1,036\n"
87 " tlo A1,0700000\n"
88 " tlz A1,0040000\n"
89 " lsh AL,-2\n"
90 " ior AL,A1\n", },
92 /* Convert int/long to short pointer */
93 { PCONV, INAREG,
94 SAREG, TWORD,
95 SANY, TPTRTO|TSHORT|TUSHORT,
96 NAREG, RLEFT,
97 " move A1,AL\n"
98 " lsh AL,-2\n"
99 " tlo AL,0750000\n"
100 " lsh A1,035\n"
101 " tlz A1,0760000\n"
102 " add AL,A1\n", },
104 /* Convert int/long to int/struct/multiple ptr */
105 { PCONV, INAREG,
106 SAREG, TWORD,
107 SANY, TPOINT|TWORD|TSTRUCT,
108 0, RLEFT,
109 " lsh AL,-2\n", },
112 * Pointer to pointer conversions.
114 /* Convert char ptr to short ptr */
115 { PCONV, INAREG,
116 SAREG, TPTRTO|TCHAR|TUCHAR,
117 SANY, TPTRTO|TSHORT|TUSHORT,
118 0, RLEFT,
119 " tlo AL,050000\n"
120 " tlne AL,020000\n"
121 " tlz AL,010000\n", },
123 /* Convert char/short pointer to int/struct/multiple ptr */
124 { PCONV, INAREG,
125 SAREG, TPTRTO|TCHAR|TUCHAR|TSHORT|TUSHORT,
126 SANY, TPOINT|TWORD|TSTRUCT,
127 0, RLEFT,
128 " tlz AL,0770000\n", },
130 /* Convert short pointer to char ptr */
131 { PCONV, INAREG,
132 SAREG, TPTRTO|TSHORT|TUSHORT,
133 SANY, TPTRTO|TCHAR|TUCHAR,
134 0, RLEFT,
135 " tlz AL,050000\n", },
137 /* Convert int/struct/foo pointer to char ptr */
138 { PCONV, INAREG,
139 SAREG, TPOINT|TWORD|TSTRUCT,
140 SANY, TPTRTO|TCHAR|TUCHAR,
141 0, RLEFT,
142 " tlo AL,0700000\n", },
144 /* Convert int/struct/foo pointer to short ptr */
145 { PCONV, INAREG,
146 SAREG, TPTRTO|TWORD|TSTRUCT,
147 SANY, TPTRTO|TSHORT|TUSHORT,
148 0, RLEFT,
149 " tlo AL,0750000\n", },
152 * A bunch conversions of integral<->integral types
155 /* convert short/char to int. This is done when register is loaded */
156 { SCONV, INAREG,
157 SAREG, TSHORT|TUSHORT|TCHAR|TUCHAR|TWORD,
158 SANY, TWORD,
159 0, RLEFT,
160 "", },
162 /* convert int to short/char. This is done when register is loaded */
163 { SCONV, INAREG,
164 SAREG, TWORD,
165 SANY, TSHORT|TUSHORT|TCHAR|TUCHAR|TWORD,
166 0, RLEFT,
167 "", },
169 /* convert int/long to unsigned long long */
170 { SCONV, INAREG,
171 SAREG|SAREG|SNAME|SOREG, TWORD,
172 SANY, TULONGLONG,
173 NAREG|NASL, RESC1,
174 " move U1,AL\n"
175 " setz A1,\n"
176 " tlze U1,0400000\n"
177 " tro A1,01\n" , },
179 /* convert int/long to long long */
180 { SCONV, INAREG,
181 SAREG|SAREG|SNAME|SOREG, TWORD,
182 SANY, TLONGLONG,
183 NAREG|NASL, RESC1,
184 " move U1,AL\n"
185 " move A1,U1\n"
186 " ash A1,-043\n", },
188 /* convert uchar/ushort to (unsigned) long long */
189 { SCONV, INAREG,
190 SAREG|SAREG|SNAME|SOREG, TUCHAR|TUSHORT,
191 SANY, TLL,
192 NAREG|NASL, RESC1,
193 " move U1,AL\n"
194 " setz A1,\n", },
196 /* convert long long to int/long */
197 { SCONV, INAREG,
198 SAREG|SAREG|SNAME|SOREG, TLL,
199 SANY, TWORD,
200 NAREG|NASL, RESC1,
201 " move A1,UL\n", },
203 /* convert long long to unsigned char - XXX - signed char */
204 { SCONV, INAREG,
205 SAREG|SAREG|SNAME|SOREG, TLL,
206 SANY, TCHAR|TUCHAR,
207 NAREG|NASL, RESC1,
208 " move A1,UL\n"
209 " andi A1,0777\n", },
211 /* convert long long to short - XXX - signed short */
212 { SCONV, INAREG,
213 SAREG|SAREG|SNAME|SOREG, TLL,
214 SANY, TSHORT|TUSHORT,
215 NAREG|NASL, RESC1,
216 " move A1,UL\n"
217 " hrrz A1,A1\n", },
219 /* floating point conversions */
220 { SCONV, INAREG,
221 SAREG|SAREG|SNAME|SOREG, TDOUBLE|TFLOAT,
222 SANY, TWORD,
223 NAREG|NASL, RESC1,
224 " fix A1,AL\n", },
226 { SCONV, INAREG,
227 SAREG|SAREG|SNAME|SOREG, TWORD,
228 SANY, TFLOAT,
229 NAREG|NASL, RESC1,
230 " fltr A1,AL\n", },
232 { SCONV, INAREG,
233 SAREG|SAREG|SNAME|SOREG, TWORD,
234 SANY, TDOUBLE,
235 NAREG|NASL, RESC1,
236 " fltr A1,AL\n setz U1,\n", },
238 { SCONV, INAREG,
239 SAREG|SAREG|SNAME|SOREG, TDOUBLE,
240 SANY, TFLOAT,
241 NAREG|NASL, RESC1,
242 " move A1,AL\n", },
244 { SCONV, INAREG,
245 SAREG|SAREG|SNAME|SOREG, TFLOAT,
246 SANY, TDOUBLE,
247 NAREG|NASL, RESC1,
248 " move A1,AL\n setz U1,\n", },
251 * Subroutine calls.
254 { UCALL, FOREFF,
255 SCON, TANY,
256 SANY, TANY,
257 0, 0, /* should be 0 */
258 " pushj 017,AL\nZB", },
260 { CALL, FOREFF,
261 SCON, TANY,
262 SANY, TANY,
263 0, 0, /* should be 0 */
264 " pushj 017,AL\nZB", },
266 { UCALL, INAREG,
267 SCON, TANY,
268 SANY, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT|TFLOAT|TPOINT,
269 NAREG, RESC1, /* should be 0 */
270 " pushj 017,AL\nZB", },
272 { CALL, INAREG,
273 SCON, TANY,
274 SANY, TANY,
275 NAREG|NASL, RESC1, /* should be 0 */
276 " pushj 017,AL\nZB", },
278 { UCALL, INAREG,
279 SAREG|SAREG, TANY,
280 SANY, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT|TFLOAT|TDOUBLE|TLL|TPOINT,
281 NAREG|NASL, RESC1, /* should be 0 */
282 " pushj 017,(AL)\nZB", },
284 { UCALL, INAREG,
285 SNAME|SOREG, TANY,
286 SANY, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT|TFLOAT|TDOUBLE|TLL|TPOINT,
287 NAREG, RESC1, /* should be 0 */
288 " pushj 017,@AL\nZB", },
290 #ifdef notyet
292 * INCR can be slightly optimized.
294 { INCR, INAREG,
295 SAREG|SAREG|SNAME|SOREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TPTRTO,
296 SONE, TANY,
297 NAREG, RESC1,
298 " move A1,AL\n"
299 " ibp AL\n", },
301 /* Fix check of return value */
302 { INCR, FOREFF,
303 SAREG|SAREG|SNAME|SOREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TPTRTO,
304 SONE, TANY,
305 0, 0,
306 " ibp AL\n", },
307 #endif
310 * PLUS operators.
312 /* Add a value to a char/short pointer */
313 { PLUS, INAREG|INAREG|FOREFF,
314 SAREG|SAREG|SNAME|SOREG, TPTRTO|TCHAR|TUCHAR|TSHORT|TUSHORT,
315 SAREG|SAREG, TWORD,
316 0, RRIGHT,
317 " adjbp AR,AL\n", },
319 /* No more search for char/short pointer addition */
320 { PLUS, INAREG|INAREG|FOREFF,
321 SANY, TPTRTO|TCHAR|TUCHAR|TSHORT|TUSHORT,
322 SANY, TANY,
323 REWRITE, 0,
324 "DIEDIEDIE!\n", },
326 /* Add char/short/int to register */
327 { PLUS, FOREFF|INAREG|INAREG,
328 SAREG|SAREG, TWORD,
329 SAREG|SAREG|SNAME|SOREG, TWORD,
330 0, RLEFT,
331 " add AL,AR\n", },
333 /* Add char/short/int to memory */
334 { PLUS, FOREFF|INAREG|INAREG,
335 SAREG|SAREG|SNAME|SOREG, TWORD,
336 SAREG|SAREG, TWORD,
337 0, RLEFT,
338 " addm AR,AL\n", },
340 /* Add a small constant to a register */
341 { PLUS, FOREFF|INAREG|INAREG,
342 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD|TPOINT,
343 SUSHCON, TWORD,
344 0, RLEFT,
345 " addi AL,AR\n", },
347 /* Add a larger constant to a register */
348 { PLUS, FOREFF|INAREG|INAREG,
349 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD|TPOINT,
350 SCON, TWORD,
351 0, RLEFT,
352 " add AL,[ .long AR ]\n", },
354 /* Add long long to register */
355 { PLUS, INAREG|INAREG|FOREFF,
356 SAREG|SAREG, TLL,
357 SAREG|SAREG|SNAME|SOREG, TLL,
358 0, RLEFT,
359 " dadd AL,AR\n", },
361 /* Add int (or int pointer) to register */
362 { PLUS, FOREFF|INAREG|INAREG,
363 SAREG|SAREG, TWORD|TPOINT,
364 SAREG|SAREG|SNAME|SOREG, TWORD,
365 0, RLEFT,
366 " add AL,AR # foo \n", },
368 /* char/short are allowed to be added if they are in registers */
369 { PLUS, INAREG|INAREG|FOREFF,
370 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
371 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
372 0, RLEFT,
373 " add AL,AR\n", },
375 /* get address of an memory position into a register */
376 { PLUS, INAREG|INAREG,
377 SAREG|SAREG, TWORD|TPTRTO,
378 SCON, TANY,
379 NAREG, RESC1,
380 " xmovei A1,AR(AL)\n", },
382 /* Safety belt for plus */
383 { PLUS, FORREW|FOREFF|INAREG|INAREG,
384 SANY, TANY,
385 SANY, TANY,
386 REWRITE, 0,
387 "DIEDIEDIE", },
390 * MINUS operators.
392 /* Rewrite subtracts from char/short pointers (to negative adds) */
393 { MINUS, FORREW|FOREFF|INAREG|INAREG,
394 SANY, TCHAR|TUCHAR|TSHORT|TUSHORT|TPTRTO,
395 SANY, TANY,
396 REWRITE, 0,
397 "DIEDIEDIE", },
399 /* Subtract char/short/int word in memory from reg */
400 { MINUS, FOREFF|INAREG|INAREG,
401 SAREG|SAREG, TWORD|TPOINT,
402 SAREG|SAREG|SNAME|SOREG, TWORD|TPOINT,
403 0, RLEFT,
404 " sub AL,AR\n", },
406 /* Subtract a small constant from reg */
407 { MINUS, FOREFF|INAREG|INAREG,
408 SAREG|SAREG, TWORD|TPOINT,
409 SUSHCON, TWORD|TPOINT,
410 0, RLEFT,
411 " subi AL,AR\n", },
413 /* Subtract a large constant from reg */
414 { MINUS, FOREFF|INAREG|INAREG,
415 SAREG|SAREG, TWORD|TPOINT,
416 SCON, TWORD|TPOINT,
417 0, RLEFT,
418 " sub AL,[ .long AR ]\n", },
420 /* Subtract char/short/int word in memory from reg, save in memory */
421 { MINUS, FOREFF|INAREG|INAREG,
422 SAREG|SAREG, TWORD,
423 SAREG|SAREG|SNAME|SOREG, TWORD,
424 0, RRIGHT,
425 " subm AL,AR\n", },
427 /* Subtract long long from register */
428 { MINUS, INAREG|INAREG|FOREFF,
429 SAREG|SAREG, TLL,
430 SAREG|SAREG|SNAME|SOREG, TLL,
431 0, RLEFT,
432 " dsub AL,AR\n", },
434 /* char/short are allowed to be subtracted if they are in registers */
435 { MINUS, INAREG|INAREG|FOREFF,
436 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
437 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
438 0, RLEFT,
439 " sub AL,AR\n", },
441 /* Safety belt for plus */
442 { MINUS, FORREW|FOREFF|INAREG|INAREG,
443 SANY, TANY,
444 SANY, TANY,
445 REWRITE, 0,
446 "DIEDIEDIE", },
449 * AND/OR/ER operators.
450 * Simpler that the ops above in that they only work on integral types.
452 /* And char/short/int with integer memory */
453 { AND, FOREFF|INAREG|INAREG,
454 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
455 SAREG|SAREG|SNAME|SOREG, TWORD,
456 0, RLEFT,
457 " and AL,AR\n", },
459 /* And char/short/int with register */
460 { AND, FOREFF|INAREG|INAREG,
461 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
462 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
463 0, RLEFT,
464 " and AL,AR\n", },
466 /* And char/short/int with small constant */
467 { AND, FOREFF|INAREG|INAREG,
468 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
469 SUSHCON, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
470 0, RLEFT,
471 " andi AL,AR\n", },
473 /* And char/short/int with large constant */
474 { AND, FOREFF|INAREG|INAREG,
475 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
476 SCON, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
477 0, RLEFT,
478 " and AL,[ .long AR ]\n", },
480 /* long long AND */
481 { AND, INAREG|FOREFF,
482 SAREG|SAREG, TLL,
483 SAREG|SAREG|SNAME|SOREG, TLL,
484 0, RLEFT,
485 " and AL,AR\n"
486 " and UL,UR\n", },
488 /* Safety belt for AND */
489 { AND, FORREW|FOREFF|INAREG|INAREG,
490 SANY, TANY,
491 SANY, TANY,
492 REWRITE, 0,
493 "DIEDIEDIE", },
496 /* OR char/short/int with integer memory */
497 { OR, FOREFF|INAREG|INAREG,
498 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
499 SAREG|SAREG|SNAME|SOREG, TWORD,
500 0, RLEFT,
501 " ior AL,AR\n", },
503 /* OR char/short/int with register */
504 { OR, FOREFF|INAREG|INAREG,
505 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
506 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
507 0, RLEFT,
508 " ior AL,AR\n", },
510 /* OR char/short/int with small constant */
511 { OR, FOREFF|INAREG|INAREG,
512 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
513 SUSHCON, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
514 0, RLEFT,
515 " iori AL,AR\n", },
517 /* OR char/short/int with large constant */
518 { OR, FOREFF|INAREG|INAREG,
519 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
520 SCON, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
521 0, RLEFT,
522 " ior AL,[ .long AR ]\n", },
524 /* long long OR */
525 { OR, INAREG|FOREFF,
526 SAREG|SAREG, TLL,
527 SAREG|SAREG|SNAME|SOREG, TLL,
528 0, RLEFT,
529 " ior AL,AR\n"
530 " ior UL,UR\n", },
532 /* Safety belt for OR */
533 { OR, FORREW|FOREFF|INAREG|INAREG,
534 SANY, TANY,
535 SANY, TANY,
536 REWRITE, 0,
537 "DIEDIEDIE", },
540 /* ER char/short/int with integer memory */
541 { ER, FOREFF|INAREG|INAREG,
542 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
543 SAREG|SAREG|SNAME|SOREG, TWORD,
544 0, RLEFT,
545 " xor AL,AR\n", },
547 /* ER char/short/int with register */
548 { ER, FOREFF|INAREG|INAREG,
549 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
550 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
551 0, RLEFT,
552 " xor AL,AR\n", },
554 /* ER char/short/int with small constant */
555 { ER, FOREFF|INAREG|INAREG,
556 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
557 SUSHCON, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
558 0, RLEFT,
559 " xori AL,AR\n", },
561 /* ER char/short/int with large constant */
562 { ER, FOREFF|INAREG|INAREG,
563 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
564 SCON, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD,
565 0, RLEFT,
566 " xor AL,[ .long AR ]\n", },
568 /* long long ER */
569 { ER, INAREG|FOREFF,
570 SAREG|SAREG, TLL,
571 SAREG|SAREG|SNAME|SOREG, TLL,
572 0, RLEFT,
573 " xor AL,AR\n"
574 " xor UL,UR\n", },
576 /* Safety belt for ER */
577 { ER, FORREW|FOREFF|INAREG|INAREG,
578 SANY, TANY,
579 SANY, TANY,
580 REWRITE, 0,
581 "DIEDIEDIE", },
584 * The next rules handle all shift operators.
586 { LS, INAREG|INAREG|FOREFF,
587 SAREG|SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
588 SAREG|SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
589 0, RLEFT,
590 " lsh AL,(AR)\n", },
592 { LS, INAREG|INAREG|FOREFF,
593 SAREG|SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
594 SNAME|SOREG, TWORD,
595 0, RLEFT,
596 " lsh AL,@AR\n", },
598 { LS, INAREG|INAREG|FOREFF,
599 SAREG|SAREG, TLL,
600 SCON, TANY,
601 0, RLEFT,
602 " ashc AL,ZH\n", },
604 { LS, INAREG|INAREG|FOREFF,
605 SAREG|SAREG, TLL,
606 SAREG|SAREG /* |SNAME|SOREG */, TANY,
607 0, RLEFT,
608 " ashc AL,(AR)\n", },
610 { RS, INAREG|INAREG|FOREFF,
611 SAREG|SAREG, TSWORD,
612 SCON, TWORD,
613 0, RLEFT,
614 " ash AL,-ZH\n", },
616 { RS, INAREG|INAREG|FOREFF,
617 SAREG|SAREG, TUWORD,
618 SCON, TWORD,
619 0, RLEFT,
620 " lsh AL,-ZH\n", },
622 /* Safety belt for LS/RS */
623 { LS, FORREW|FOREFF|INAREG|INAREG,
624 SANY, TANY,
625 SANY, TANY,
626 REWRITE, 0,
627 "DIEDIEDIE", },
629 { RS, FORREW|FOREFF|INAREG|INAREG,
630 SANY, TANY,
631 SANY, TANY,
632 REWRITE, 0,
633 "DIEDIEDIE", },
636 * The next rules takes care of assignments. "=".
638 /* Match zeroed registers first */
639 { ASSIGN, INAREG|FOREFF,
640 SAREG, TUCHAR|TUSHORT|TCHAR|TSHORT|TWORD|TPOINT,
641 SZERO, TANY,
642 0, RDEST,
643 " setz AL,\n", },
645 { ASSIGN, FOREFF,
646 SAREG|SNAME|SOREG, TWORD|TPOINT,
647 SZERO, TANY,
648 0, 0,
649 " setzm AL\n", },
651 { ASSIGN, INAREG|FOREFF,
652 SAREG|SAREG, TUCHAR|TUSHORT|TCHAR|TSHORT|TWORD|TPOINT,
653 SMONE, TANY,
654 0, RDEST,
655 " setom AL\n", },
657 { ASSIGN, FOREFF,
658 SAREG|SNAME|SOREG, TWORD|TPOINT,
659 SMONE, TANY,
660 0, 0,
661 " setom AL\n", },
663 { ASSIGN, INAREG|INAREG|FOREFF,
664 SAREG|SAREG, TWORD|TPOINT,
665 SCON, TWORD|TPOINT,
666 0, RDEST,
667 " ZC\n", },
669 { ASSIGN, INAREG|INAREG|FOREFF,
670 SAREG|SNAME|SOREG, TWORD|TPOINT|TFLOAT,
671 SAREG|SAREG, TUCHAR|TUSHORT|TWORD|TPOINT|TFLOAT,
672 0, RDEST,
673 " movem AR,AL\n", },
675 { ASSIGN, INAREG|INAREG|FOREFF,
676 SAREG|SNAME|SOREG, TWORD|TPOINT|TFLOAT,
677 SAREG|SAREG, TSHORT,
678 0, RDEST,
679 " hrrem AR,AL\n", },
681 { ASSIGN, INAREG|INAREG|FOREFF,
682 SAREG|SAREG, TUCHAR|TUSHORT|TCHAR|TSHORT|TWORD|TPOINT,
683 SAREG|SAREG|SNAME|SOREG, TWORD|TPOINT,
684 0, RDEST,
685 " move AL,AR\n", },
687 { ASSIGN, INAREG|INAREG|FOREFF,
688 SAREG|SAREG, TUCHAR|TUSHORT|TCHAR|TSHORT,
689 SAREG|SAREG, TUCHAR|TUSHORT|TCHAR|TSHORT,
690 0, RDEST,
691 " move AL,AR\n", },
693 { ASSIGN, INBREG|FOREFF,
694 SBREG|SNAME|SOREG, TLL|TDOUBLE,
695 SBREG, TLL|TDOUBLE,
696 0, RDEST,
697 " dmovem AR,AL\n", },
699 { ASSIGN, INAREG|INAREG|FOREFF,
700 SOREG|SNAME, TSHORT|TUSHORT|TCHAR|TUCHAR,
701 SAREG|SAREG, TANY,
702 0, RDEST,
703 "ZV", },
705 { ASSIGN, INAREG|INAREG|FOREFF,
706 SAREG|SAREG, TUSHORT|TUCHAR,
707 SOREG, TANY,
708 0, RDEST,
709 " ldb AL,Zg\n", },
711 { ASSIGN, INAREG|INAREG|FOREFF,
712 SAREG|SAREG, TSHORT|TUSHORT|TCHAR|TUCHAR,
713 SSCON, TANY,
714 0, RDEST,
715 " movei AL,AR\n", },
717 { ASSIGN, INAREG|INAREG|FOREFF,
718 SAREG|SAREG, TSHORT|TUSHORT|TCHAR|TUCHAR,
719 SCON, TANY,
720 0, RDEST,
721 " move AL,[ .long AR]\n", },
724 * DIV/MOD/MUL
725 * These can be done way more efficient.
727 /* long long div. XXX - work only with unsigned */
728 { DIV, INBREG,
729 SBREG|SNAME|SOREG, TLL,
730 SBREG|SNAME|SOREG, TLL,
731 (2*NBREG)|NBSL, RESC1,
732 " dmove A2,AL ; dmove A1,[ .long 0,0 ]\n"
733 " ddiv A1,AR\n", },
735 /* long long div. with constant. XXX - work only with unsigned */
736 { DIV, INBREG,
737 SBREG|SNAME|SOREG, TLL,
738 SCON, TLL,
739 (2*NBREG)|NBSL, RESC1,
740 " dmove A2,AL ; dmove A1,[ .long 0,0 ]\n"
741 " ddiv A1,ZP\n", },
743 /* Simple divide. XXX - fix so next reg can be free */
744 { DIV, INAREG|INAREG|FOREFF,
745 SAREG|SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
746 SAREG|SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
747 0, RRIGHT,
748 " idivm AL,AR\n", },
750 /* Safety belt for DIV */
751 { DIV, FORREW|FOREFF|INAREG|INAREG,
752 SANY, TANY,
753 SANY, TANY,
754 REWRITE, 0,
755 "DIEDIEDIE", },
757 /* long long MOD */
758 { MOD, INBREG,
759 SBREG|SNAME|SOREG, TLL,
760 SBREG|SNAME|SOREG, TLL,
761 2*NBREG|NBSL, RESC2,
762 " dmove A2,AL ; dmove A1,[ .long 0,0 ]\n"
763 " ddiv A1,AR\n", },
765 /* integer MOD */
766 { MOD, INAREG,
767 SAREG|SNAME|SOREG, TWORD,
768 SAREG|SNAME|SOREG, TWORD,
769 2*NAREG|NASL, RESC2,
770 " move A2,AL\n"
771 " setz A1,\n"
772 " idiv A1,AR\n", },
774 /* integer MOD for char/short */
775 { MOD, INAREG,
776 SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
777 SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
778 2*NAREG|NASL, RESC2,
779 " move A2,AL\n"
780 " setz A1,\n"
781 " idiv A1,AR\n", },
783 /* Safety belt for MOD */
784 { MOD, FOREFF,
785 SANY, TANY,
786 SANY, TANY,
787 REWRITE, 0,
788 "DIEDIEDIE", },
790 /* long long MUL */
791 { MUL, INBREG,
792 SBREG|SNAME|SOREG, TLL,
793 SBREG|SNAME|SOREG, TLL,
794 2*NBREG|NBSL, RESC2,
795 " dmove A1,AL\n"
796 " dmul A1,AR\n", },
798 /* integer multiply to memory*/
799 { MUL, INAREG|INAREG|FOREFF,
800 SAREG|SAREG|SNAME|SOREG, TWORD,
801 SAREG|SAREG, TWORD,
802 0, RLEFT,
803 " imulm AR,AL\n", },
805 /* integer multiply */
806 { MUL, INAREG|INAREG|FOREFF,
807 SAREG|SAREG, TWORD,
808 SAREG|SAREG|SNAME|SOREG, TWORD,
809 0, RLEFT,
810 " imul AL,AR\n", },
812 /* integer multiply for char/short */
813 { MUL, INAREG|INAREG|FOREFF,
814 SAREG|SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
815 SAREG|SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
816 0, RLEFT,
817 " imul AL,AR\n", },
819 /* integer multiply with small constant */
820 { MUL, INAREG|INAREG|FOREFF,
821 SAREG|SAREG, TWORD,
822 SUSHCON, TWORD,
823 0, RLEFT,
824 " imuli AL,AR\n", },
826 /* integer multiply with large constant */
827 { MUL, INAREG|INAREG|FOREFF,
828 SAREG|SAREG, TWORD,
829 SCON, TWORD,
830 0, RLEFT,
831 " imul AL,[ .long AR ]\n", },
833 /* Safety belt for MUL */
834 { MUL, FORREW|FOREFF|INAREG|INAREG,
835 SANY, TANY,
836 SANY, TANY,
837 REWRITE, 0,
838 "DIEDIEDIE", },
840 /* read an indirect long long value into register */
841 { UMUL, INAREG,
842 SAREG|SAREG, TPTRTO|TLL|TWORD,
843 SANY, TLL,
844 NAREG|NASL, RESC1,
845 " dmove A1,(AL)\n", },
847 /* read an indirect integer value into register */
848 { UMUL, INAREG,
849 SAREG|SAREG, TWORD|TPOINT,
850 SANY, TWORD|TPOINT,
851 NAREG|NASL, RESC1,
852 " move A1,(AL)\n", },
854 /* read an indirect value into register */
855 { UMUL, INAREG,
856 SOREG, TWORD|TPOINT,
857 SANY, TWORD|TPOINT,
858 NAREG, RESC1,
859 " move A1,@AL\n", },
861 /* read an indirect value into register */
862 { UMUL, INAREG,
863 SAREG|SAREG|SOREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TPTRTO,
864 SANY, TCHAR|TUCHAR|TSHORT|TUSHORT,
865 NAREG|NASL, RESC1,
866 " ldb A1,AL\n", },
868 #ifdef notyet
869 /* Match tree shape for ildb */
870 { UMUL, INAREG,
871 SANY, TANY,
872 SILDB, TUCHAR|TCHAR|TPTRTO,
873 NAREG, RESC1,
874 " ildb A1,ZA\n", },
875 #endif
877 /* Match char/short pointers first, requires special handling */
878 { OPLOG, FORCC,
879 SAREG|SAREG, TPTRTO|TCHAR|TUCHAR|TSHORT|TUSHORT,
880 SAREG|SAREG, TPTRTO|TCHAR|TUCHAR|TSHORT|TUSHORT,
881 0, RESCC,
882 "ZZ", },
884 /* Can check anything by just comparing if EQ/NE */
885 { OPLOG, FORCC,
886 SAREG|SAREG, TWORD|TPOINT|TCHAR|TUCHAR|TSHORT|TUSHORT,
887 SZERO, TANY,
888 0, RESCC,
889 " jumpZe AL,LC # bu\n", },
891 { EQ, FORCC,
892 SAREG|SAREG, TWORD|TPOINT|TCHAR|TUCHAR|TSHORT|TUSHORT,
893 SAREG|SAREG|SOREG|SNAME|SCON, TWORD|TPOINT,
894 0, RESCC,
895 "ZR", },
897 { NE, FORCC,
898 SAREG|SAREG, TWORD|TPOINT|TCHAR|TUCHAR|TSHORT|TUSHORT,
899 SAREG|SAREG|SOREG|SNAME|SCON, TWORD|TPOINT,
900 0, RESCC,
901 "ZR", },
903 { OPLOG, FORCC,
904 SAREG|SAREG, TWORD,
905 SAREG|SAREG|SOREG|SNAME|SCON, TSWORD,
906 0, RESCC,
907 "ZR", },
909 { OPLOG, FORCC,
910 SAREG|SAREG, TCHAR|TUCHAR,
911 SCON, TANY,
912 0, RESCC,
913 "ZR", },
915 { OPLOG, FORCC,
916 SAREG|SAREG, TWORD|TPOINT|TFLOAT,
917 SAREG|SAREG|SOREG|SNAME|SCON, TWORD|TPOINT|TFLOAT,
918 0, RESCC,
919 "ZR", },
921 { OPLOG, FORCC,
922 SAREG|SAREG, TWORD|TPOINT|TCHAR|TUCHAR|TSHORT|TUSHORT,
923 SAREG|SAREG, TWORD|TPOINT|TCHAR|TUCHAR|TSHORT|TUSHORT,
924 0, RESCC,
925 "ZR", },
927 { OPLOG, FORCC,
928 SAREG|SAREG, TLL|TDOUBLE, /* XXX - does double work here? */
929 SAREG|SAREG|SOREG|SNAME, TLL|TDOUBLE,
930 0, RESCC,
931 "ZQ", },
934 * Jumps.
936 { GOTO, FOREFF,
937 SCON, TANY,
938 SANY, TANY,
939 0, RNOP,
940 " jrst LL\n", },
943 * Convert LTYPE to reg.
945 { OPLTYPE, INBREG,
946 SANY, TANY,
947 SMONE, TLL,
948 NBREG, RESC1,
949 " seto A1,\n seto U1,\n", },
951 { OPLTYPE, INAREG,
952 SANY, TANY,
953 SMONE, TANY,
954 NAREG, RESC1,
955 " seto A1,\n", },
957 { OPLTYPE, INBREG,
958 SANY, TANY,
959 SZERO, TLL,
960 NBREG, RESC1,
961 " setz A1,\n setz U1,\n", },
963 { OPLTYPE, INAREG,
964 SANY, TANY,
965 SZERO, TANY,
966 NAREG, RESC1,
967 " setz A1,\n", },
969 { OPLTYPE, INBREG,
970 SANY, TANY,
971 SUSHCON, TLL,
972 NBREG, RESC1,
973 " setz A1,\n movei U1,AR\n", },
975 { OPLTYPE, INAREG,
976 SANY, TANY,
977 SUSHCON, ANYFIXED,
978 NAREG, RESC1,
979 " movei A1,AR\n", },
981 { OPLTYPE, INAREG,
982 SANY, ANYFIXED,
983 SNSHCON, ANYFIXED,
984 NAREG, RESC1,
985 " hrroi A1,AR\n", },
987 { OPLTYPE, INAREG,
988 SANY, ANYFIXED,
989 SCON, ANYFIXED,
990 NAREG|NASR, RESC1,
991 " ZD A1,ZE # suspekt\n", },
993 { OPLTYPE, INAREG,
994 SANY, TWORD|TPOINT|TFLOAT,
995 SAREG|SAREG|SOREG|SNAME, TWORD|TPOINT|TFLOAT,
996 NAREG|NASR, RESC1,
997 " move A1,AR\n", },
999 { OPLTYPE, INBREG,
1000 SANY, TLL,
1001 SCON, TLL,
1002 NBREG, RESC1,
1003 " dmove A1,ZO\n", },
1005 { OPLTYPE, INBREG,
1006 SANY, TLL|TDOUBLE,
1007 SANY, TLL|TDOUBLE,
1008 NBREG|NBSR, RESC1,
1009 " dmove A1,AR\n", },
1011 { OPLTYPE, INAREG,
1012 SOREG, TSHORT|TUSHORT|TCHAR|TUCHAR,
1013 SOREG, TSHORT|TUSHORT|TCHAR|TUCHAR,
1014 NASR, RESC1,
1015 "ZU", },
1017 { OPLTYPE, INAREG,
1018 SNAME, TUCHAR,
1019 SNAME, TUCHAR,
1020 NAREG|NASR, RESC1,
1021 " ldb A1,[ .long AL ]\n" },
1023 { OPLTYPE, INAREG,
1024 SNAME, TCHAR,
1025 SNAME, TCHAR,
1026 NAREG|NASR, RESC1,
1027 " ldb A1,[ .long AL ]\n"
1028 " ash A1,033\n"
1029 " ash A1,-033\n", },
1031 { OPLTYPE, INAREG,
1032 SANY, TANY,
1033 SNAME, TSHORT|TUSHORT,
1034 NAREG|NASR, RESC1,
1035 "Zi", },
1037 { OPLTYPE, INAREG,
1038 SANY, TWORD|TPOINT,
1039 SCON, TWORD|TPOINT,
1040 NAREG|NASR, RESC1,
1041 "Zc", },
1043 { OPLTYPE, INAREG,
1044 SAREG|SAREG, TUSHORT|TUCHAR,
1045 SAREG|SAREG, TUSHORT|TUCHAR|TWORD,
1046 NAREG, RESC1,
1047 " move A1,AL\n", },
1050 * Negate a word.
1052 { UMINUS, INAREG,
1053 SAREG|SAREG|SNAME|SOREG, TWORD,
1054 SANY, TWORD,
1055 NAREG|NASL, RESC1,
1056 " movn A1,AL\n", },
1058 { UMINUS, INAREG,
1059 SAREG|SAREG, TWORD,
1060 SANY, TCHAR|TUCHAR|TSHORT|TUSHORT,
1061 0, RLEFT,
1062 " movn AL,AL\n", },
1064 { UMINUS, INAREG,
1065 SAREG|SNAME|SOREG, TLL,
1066 SANY, TLL,
1067 NAREG|NASR, RESC1,
1068 " dmovn A1,AL\n", },
1070 { COMPL, INAREG,
1071 SAREG|SAREG|SNAME|SOREG, TLL,
1072 SANY, TANY,
1073 NAREG|NASL, RESC1,
1074 " setcm A1,AL\n"
1075 " setcm U1,UL\n", },
1077 { COMPL, INAREG,
1078 SAREG|SAREG|SNAME|SOREG, TWORD,
1079 SANY, TANY,
1080 NAREG|NASL, RESC1,
1081 " setcm A1,AL\n", },
1083 { COMPL, INAREG,
1084 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT,
1085 SANY, TCHAR|TUCHAR|TSHORT|TUSHORT,
1086 NAREG|NASL, RESC1,
1087 " setcm A1,AL\n", },
1090 * Arguments to functions.
1092 { FUNARG, FOREFF,
1093 SAREG|SNAME|SOREG, TWORD|TPOINT|TFLOAT,
1094 SANY, TANY,
1095 0, RNULL,
1096 " push 017,AL\n", },
1098 { FUNARG, FOREFF,
1099 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT,
1100 SANY, TANY,
1101 0, RNULL,
1102 " push 017,AL\n", },
1104 { FUNARG, FOREFF,
1105 SCON, TCHAR|TUCHAR|TSHORT|TUSHORT|TPOINT|TWORD,
1106 SANY, TANY,
1107 0, RNULL,
1108 " push 017,[ .long AL]\n", },
1110 { FUNARG, FOREFF,
1111 SBREG, TLL|TDOUBLE,
1112 SANY, TANY,
1113 0, RNULL,
1114 " push 017,AL\n push 017,UL\n", },
1116 { STARG, FOREFF,
1117 SAREG|SOREG|SNAME|SCON, TANY,
1118 SANY, TSTRUCT,
1119 0, 0,
1120 "ZG", },
1123 # define DF(x) FORREW,SANY,TANY,SANY,TANY,REWRITE,x,""
1125 { UMUL, DF( UMUL ), },
1127 { ASSIGN, DF(ASSIGN), },
1129 { OPLEAF, DF(NAME), },
1131 { OPUNARY, DF(UMINUS), },
1133 { FREE, FREE, FREE, FREE, FREE, FREE, FREE, FREE, "help; I'm in trouble\n" },
1136 int tablesize = sizeof(table)/sizeof(table[0]);