1 /* $Id: table.c,v 1.19 2008/05/16 02:20:36 gmcgarry Exp $ */
3 * Copyright (c) 2007 Gregory McGarry <g.mcgarry@ieee.org>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 * A template has five logical sections:
21 * 1) subtree (operator); goal to achieve (cookie)
22 * 2) left node descendent of operator (node class; type)
23 * 3) right node descendent of operator (node class; type)
24 * 4) resource requirements (number of scratch registers);
25 * subtree rewriting rule
26 * 5) emitted instructions
31 #define TUWORD TUNSIGNED|TULONG
32 #define TSWORD TINT|TLONG
33 #define TWORD TUWORD|TSWORD
35 struct optab table
[] = {
36 /* First entry must be an empty entry */
37 { -1, FOREFF
, SANY
, TANY
, SANY
, TANY
, 0, 0, "", },
39 /* PCONVs are not necessary */
44 COM
"pointer conversion\n", },
48 * Conversions of integral types
50 * For each deunsigned type, they look something like this:
52 * signed -> bigger signed - nothing to do
53 * signed -> bigger unsigned - clear the top bits (of source type)
55 * signed -> smaller signed - sign-extend the bits (to dest type)
56 * signed -> smaller unsigned - clear the top bits (of dest type)
57 * unsigned -> smaller signed - sign-extend top bits (to dest type)
58 * unsigned -> smaller unsigned - clear the top bits (of dest type)
60 * unsigned -> bigger - nothing to do
67 COM
"convert char to short/int\n", },
71 SAREG
, TUWORD
|TUSHORT
|TUCHAR
,
73 " and A1,AL,#255" COM
"convert char to uchar/ushort/uint\n", },
75 { SCONV
, INAREG
| FEATURE_EXTEND
,
79 " sxtb A1,AL" COM
"convert uchar to char\n", },
85 " mov A1,AL,asl #24" COM
"convert uchar to char\n"
86 " mov A1,A1,asr #24\n", },
90 SAREG
, TWORD
|TSHORT
|TUSHORT
,
92 COM
"convert uchar to (u)short/(u)int\n", },
98 COM
"convert short to int\n", },
100 { SCONV
, INAREG
| FEATURE_EXTEND
,
102 SAREG
, TUWORD
|TUSHORT
,
104 " uxth A1,AL" COM
"convert short to uint\n", },
108 SAREG
, TUWORD
|TUSHORT
,
110 " mov A1,AL,asl #16" COM
"convert short to uint\n"
111 " mov A1,AL,lsr #16\n", },
113 { SCONV
, INAREG
| FEATURE_EXTEND
,
117 " sxth A1,AL" COM
"convert ushort to short\n", },
123 " mov A1,AL,asl #16" COM
"convert ushort to short\n"
124 " mov A1,A1,asr #16\n", },
126 { SCONV
, INAREG
| FEATURE_EXTEND
,
127 SAREG
, TSHORT
|TUSHORT
,
130 " sxtb A1,AL" COM
"convert (u)short to char\n", },
133 SAREG
, TSHORT
|TUSHORT
,
136 " mov A1,AL,asl #24" COM
"convert (u)short to char\n"
137 " mov A1,A1,asr #24\n", },
140 SAREG
, TSHORT
|TUSHORT
,
143 " sxtb A1,AL" COM
"convert (u)short to char\n", },
146 SAREG
, TSHORT
|TUSHORT
,
149 " and A1,AL,#255" COM
"convert (u)short to uchar\n", },
155 COM
"convert ushort to (u)int\n", },
157 { SCONV
, INAREG
| FEATURE_EXTEND
,
161 " sxtb A1,AL" COM
"convert (u)int to char\n", },
167 " mov A1,AL,asl #24" COM
"convert (u)int to char\n"
168 " mov A1,A1,asr #24\n", },
170 { SCONV
, INAREG
| FEATURE_EXTEND
,
174 " sxth A1,AL" COM
"convert (u)int to short\n", },
180 " mov A1,AL,asl #16" COM
"convert (u)int to short\n"
181 " mov A1,A1,asr #16\n", },
187 " and A1,AL,#255" COM
"convert uchar to char\n", },
189 { SCONV
, INAREG
| FEATURE_EXTEND
,
193 " uxth A1,AL" COM
"convert int to ushort\n", },
199 " mov A1,AL,asl #16" COM
"convert int to ushort\n"
200 " mov A1,AL,lsr #16\n", },
206 COM
"convert between pointers and words\n", },
209 SBREG
, TLONGLONG
|TULONGLONG
,
210 SBREG
, TLONGLONG
|TULONGLONG
,
212 COM
"convert (u)longlong to (u)longlong\n", },
214 /* convert (u)char/(u)short/(u)int to longlong */
216 SAREG
, TCHAR
|TUCHAR
|TSHORT
|TUSHORT
|TWORD
,
217 SBREG
, TLONGLONG
|TULONGLONG
,
219 " mov A1,AL" COM
"convert (u)char/(u)short/(u)int to (u)longlong\n"
220 " mov U1,AL,asr #31\n", },
222 { SCONV
, INAREG
| FEATURE_EXTEND
,
223 SBREG
, TLONGLONG
|TULONGLONG
,
226 " sxtb A1,AL" COM
"convert (u)longlong to char\n", },
229 SBREG
, TLONGLONG
|TULONGLONG
,
232 " mov A1,AL,asl #24" COM
"convert (u)longlong to char\n"
233 " mov A1,A1,asr #24\n", },
235 { SCONV
, INAREG
| FEATURE_EXTEND
,
236 SBREG
, TLONGLONG
|TULONGLONG
,
239 " sxth A1,AL" COM
"convert (u)longlong to short\n", },
242 SBREG
, TLONGLONG
|TULONGLONG
,
245 " mov A1,AL,asl #16" COM
"convert (u)longlong to short\n"
246 " mov A1,A1,asr #16\n", },
249 SBREG
, TLONGLONG
|TULONGLONG
,
252 " mov A1,AL" COM
"convert (u)longlong to (u)int\n", },
255 SBREG
, TLONGLONG
|TULONGLONG
,
258 " and A1,AL,#255" COM
"convert (u)longlong to uchar\n", },
260 { SCONV
, INAREG
| FEATURE_EXTEND
,
261 SBREG
, TLONGLONG
|TULONGLONG
,
264 " uxth A1,AL" COM
"convert (u)longlong to ushort\n", },
267 SBREG
, TLONGLONG
|TULONGLONG
,
270 " mov A1,AL,asl #16" COM
"convert (u)longlong to ushort\n"
271 " mov A1,A1,lsr #16\n", },
273 /* conversions on load from memory */
280 " ldrsb A1,AL" COM
"convert char to int/long\n", },
287 " ldrb A1,AL" COM
"convert uchar to int/long\n", },
290 { SCONV
, INAREG
| FEATURE_HALFWORDS
,
294 " ldrsh A1,AL" COM
"convert short to int/long\n", },
297 { SCONV
, INAREG
| FEATURE_HALFWORDS
,
301 " ldrh A1,AL" COM
"convert ushort to int/long\n", },
305 SOREG
, TSHORT
|TUSHORT
,
310 { SCONV
, INAREG
| FEATURE_FPA
,
314 " fix AL,AR" COM
"convert float to int\n", },
316 { SCONV
, INAREG
| FEATURE_VFP
,
320 " ftosis AL,AR" COM
"convert float to int\n", },
322 { SCONV
, INAREG
| FEATURE_VFP
,
326 " ftouis AL,AR" COM
"convert float to int\n", },
331 NSPECIAL
|NAREG
, RESC1
,
334 { SCONV
, INBREG
| FEATURE_FPA
,
336 SBREG
, TULONGLONG
|TLONGLONG
,
338 COM
"unimplemented\n", },
340 { SCONV
, INBREG
| FEATURE_VFP
,
342 SBREG
, TULONGLONG
|TLONGLONG
,
344 COM
"unimplemented\n", },
348 SBREG
, TULONGLONG
|TLONGLONG
,
349 NSPECIAL
|NBREG
, RESC1
,
352 { SCONV
, INAREG
| FEATURE_FPA
,
353 SCREG
, TDOUBLE
|TLDOUBLE
,
356 " fix AL,AR" COM
"convert double/ldouble to int\n", },
358 { SCONV
, INAREG
| FEATURE_VFP
,
359 SCREG
, TDOUBLE
|TLDOUBLE
,
362 " ftosid AL,AR" COM
"convert double/ldouble to int\n", },
364 { SCONV
, INAREG
| FEATURE_VFP
,
365 SCREG
, TDOUBLE
|TLDOUBLE
,
368 " ftouid AL,AR" COM
"convert double/ldouble to int\n", },
371 SBREG
, TDOUBLE
|TLDOUBLE
,
373 NSPECIAL
|NAREG
, RESC1
,
376 { SCONV
, INBREG
| FEATURE_FPA
,
377 SCREG
, TDOUBLE
|TLDOUBLE
,
378 SBREG
, TLONGLONG
|TULONGLONG
,
380 COM
"unimplemented\n", },
382 { SCONV
, INBREG
| FEATURE_VFP
,
383 SCREG
, TDOUBLE
|TLDOUBLE
,
384 SBREG
, TULONGLONG
|TLONGLONG
,
386 COM
"unimplemented\n", },
389 SBREG
, TDOUBLE
|TLDOUBLE
,
390 SBREG
, TULONGLONG
|TLONGLONG
,
391 NSPECIAL
|NBREG
, RESC1
,
394 { SCONV
, INCREG
| FEATURE_FPA
,
398 " flts AL,AR" COM
"convert int to float\n" },
400 { SCONV
, INCREG
| FEATURE_VFP
,
404 " fsitos AL,AR" COM
"convert int to float\n" },
406 { SCONV
, INCREG
| FEATURE_VFP
,
410 " fuitos AL,AR" COM
"convert int to float\n" },
415 NSPECIAL
|NAREG
, RESC1
,
418 { SCONV
, INCREG
| FEATURE_FPA
,
419 SBREG
, TULONGLONG
|TLONGLONG
,
422 COM
"unimplemented\n", },
424 { SCONV
, INCREG
| FEATURE_VFP
,
425 SBREG
, TULONGLONG
|TLONGLONG
,
428 COM
"unimplemented\n", },
431 SBREG
, TULONGLONG
|TLONGLONG
,
434 COM
"unimplemented\n", },
436 { SCONV
, INCREG
| FEATURE_FPA
,
440 " fltd AL,AR" COM
"convert int to double\n" },
442 { SCONV
, INCREG
| FEATURE_VFP
,
446 " fsitod AL,AR" COM
"convert int to double\n" },
448 { SCONV
, INCREG
| FEATURE_VFP
,
452 " fuitod AL,AR" COM
"convert int to double\n" },
457 NSPECIAL
|NBREG
, RESC1
,
460 { SCONV
, INCREG
| FEATURE_FPA
,
461 SBREG
, TLONGLONG
|TULONGLONG
,
464 COM
"unimplemented\n", },
466 { SCONV
, INCREG
| FEATURE_VFP
,
467 SBREG
, TLONGLONG
|TULONGLONG
,
470 COM
"unimplemented\n", },
473 SBREG
, TLONGLONG
|TULONGLONG
,
475 NSPECIAL
|NBREG
, RESC1
,
478 { SCONV
, INCREG
| FEATURE_FPA
,
482 " flte AL,AR" COM
"convert int to ldouble\n" },
484 { SCONV
, INCREG
| FEATURE_VFP
,
488 " fsitod AL,AR" COM
"convert int to ldouble\n" },
490 { SCONV
, INCREG
| FEATURE_VFP
,
494 " fuitod AL,AR" COM
"convert uint to ldouble\n" },
499 NSPECIAL
|NBREG
, RESC1
,
502 { SCONV
, INCREG
| FEATURE_FPA
,
503 SBREG
, TLONGLONG
|TULONGLONG
,
506 COM
"unimplemented\n", },
508 { SCONV
, INCREG
| FEATURE_VFP
,
509 SBREG
, TLONGLONG
|TULONGLONG
,
512 COM
"unimplemented\n", },
515 SBREG
, TLONGLONG
|TULONGLONG
,
517 NSPECIAL
|NBREG
, RESC1
,
520 { SCONV
, INCREG
| FEATURE_FPA
,
521 SCREG
, TDOUBLE
|TLDOUBLE
,
524 COM
"unimplemented\n", },
526 { SCONV
, INCREG
| FEATURE_VFP
,
527 SCREG
, TDOUBLE
|TLDOUBLE
,
530 " fcvtds AL,AR" COM
"convert float to double\n" },
533 SBREG
, TDOUBLE
|TLDOUBLE
,
535 NSPECIAL
|NAREG
, RESC1
,
538 { SCONV
, INCREG
| FEATURE_FPA
,
540 SCREG
, TDOUBLE
|TLDOUBLE
,
542 COM
"unimplemented\n", },
544 { SCONV
, INCREG
| FEATURE_VFP
,
546 SCREG
, TDOUBLE
|TLDOUBLE
,
548 " fcvtsd AL,AR" COM
"convert float to double\n" },
552 SBREG
, TDOUBLE
|TLDOUBLE
,
553 NSPECIAL
|NBREG
, RESC1
,
556 { SCONV
, INCREG
| FEATURE_FPA
,
557 SCREG
, TDOUBLE
|TLDOUBLE
,
558 SCREG
, TDOUBLE
|TLDOUBLE
,
560 COM
"convert (l)double to (l)double", },
562 { SCONV
, INCREG
| FEATURE_VFP
,
563 SCREG
, TDOUBLE
|TLDOUBLE
,
564 SCREG
, TDOUBLE
|TLDOUBLE
,
566 COM
"convert (l)double to (l)double", },
569 SBREG
, TDOUBLE
|TLDOUBLE
,
570 SBREG
, TDOUBLE
|TLDOUBLE
,
572 COM
"convert (l)double to (l)double", },
582 " bl CL" COM
"call (args, no result) to scon/sname (CL)\n"
589 " bl CL" COM
"call (no args, no result) to scon/sname (CL)\n", },
593 SAREG
, TWORD
|TPOINT
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
594 NAREG
|NASL
, RESC1
, /* should be 0 */
595 " bl CL" COM
"call (args, result in r0) to scon/sname (CL)\n"
600 SBREG
, TLONGLONG
|TULONGLONG
,
601 NBREG
|NBSL
, RESC1
, /* should be 0 */
602 " bl CL" COM
"call (args, result in r0:r1) to scon/sname (CL)\n"
605 { CALL
, INCREG
| FEATURE_FPA
,
608 NCREG
|NCSL
, RESC1
, /* should be 0 */
609 " bl CL" COM
"call (args, result r0) to scon/sname (CL)\n"
612 { CALL
, INCREG
| FEATURE_FPA
,
614 SCREG
, TDOUBLE
|TLDOUBLE
,
615 NCREG
|NCSL
, RESC1
, /* should be 0 */
616 " bl CL" COM
"call (args, result in r0:r1) to scon/sname (CL)\n"
622 NAREG
|NASL
, RESC1
, /* should be 0 */
623 " bl CL" COM
"call (args, result r0) to scon/sname (CL)\n"
628 SBREG
, TDOUBLE
|TLDOUBLE
,
629 NBREG
|NBSL
, RESC1
, /* should be 0 */
630 " bl CL" COM
"call (args, result in r0:r1) to scon/sname (CL)\n"
635 SAREG
, TWORD
|TPOINT
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
636 NAREG
|NASL
, RESC1
, /* should be 0 */
637 " bl CL" COM
"call (no args, result in r0) to scon/sname (CL)\n", },
641 SBREG
, TLONGLONG
|TULONGLONG
,
642 NBREG
|NBSL
, RESC1
, /* should be 0 */
643 " bl CL" COM
"call (no args, result in r0:r1) to scon/sname (CL)\n", },
645 { UCALL
, INCREG
| FEATURE_FPA
,
648 NCREG
|NCSL
, RESC1
, /* should be 0 */
649 " bl CL" COM
"call (no args, result in r0) to scon/sname (CL)\n", },
651 { UCALL
, INCREG
| FEATURE_FPA
,
653 SCREG
, TDOUBLE
|TLDOUBLE
,
654 NCREG
|NCSL
, RESC1
, /* should be 0 */
655 " bl CL" COM
"call (no args, result in r0:r1) to scon/sname (CL)\n", },
712 NAREG
|NASL
, RESC1
, /* should be 0 */
718 NAREG
|NASL
, RESC1
, /* should be 0 */
732 NAREG
|NASL
, RESC1
, /* should be 0 */
739 NAREG
|NASL
, RESC1
, /* should be 0 */
745 * The next rules handle all binop-style operators.
752 " add A1,AL,AR" COM
"addition of constant\n", },
755 SBREG
, TLONGLONG
|TULONGLONG
,
758 " adds A1,AL,AR" COM
"64-bit addition of constant\n"
759 " adc U1,UL,UR\n", },
765 " add A1,AL,AR" COM
"addition\n", },
768 SBREG
, TLONGLONG
|TULONGLONG
,
769 SBREG
, TLONGLONG
|TULONGLONG
,
771 " adds A1,AL,AR" COM
"64-bit addition\n"
772 " adc U1,UL,UR\n", },
774 { PLUS
, INCREG
| FEATURE_FPA
,
778 " adfs A1,AL,AR" COM
"float add\n", },
780 { PLUS
, INCREG
| FEATURE_VFP
,
784 " fadds A1,AL,AR" COM
"float add\n", },
789 NSPECIAL
|NAREG
, RESC1
,
792 { PLUS
, INCREG
| FEATURE_FPA
,
796 " adfd A1,AL,AR" COM
"double add\n", },
798 { PLUS
, INCREG
| FEATURE_VFP
,
802 " faddd A1,AL,AR" COM
"double add\n", },
807 NSPECIAL
|NBREG
, RESC1
,
810 { PLUS
, INCREG
| FEATURE_FPA
,
814 " adfe A1,AL,AR" COM
"ldouble add\n", },
816 { PLUS
, INCREG
| FEATURE_VFP
,
820 " faddd A1,AL,AR" COM
"ldouble add\n", },
825 NSPECIAL
|NBREG
, RESC1
,
832 " sub A1,AL,AR" COM
"subtraction of constant\n", },
838 " sub A1,AL,AR" COM
"subtraction\n", },
841 SBREG
, TLONGLONG
|TULONGLONG
,
844 " subs A1,AL,AR" COM
"64-bit subtraction of constant\n"
845 " rsc U1,UL,AR\n", },
848 SBREG
, TLONGLONG
|TULONGLONG
,
849 SBREG
, TLONGLONG
|TULONGLONG
,
851 " subs A1,AL,AR" COM
"64-bit subtraction\n"
852 " sbc U1,UL,AR\n", },
854 { MINUS
, INCREG
| FEATURE_FPA
,
858 " sufs A1,AL,AR" COM
"float subtraction\n", },
860 { MINUS
, INCREG
| FEATURE_VFP
,
864 " fsubs A1,AL,AR" COM
"float subtraction\n", },
869 NSPECIAL
|NAREG
, RESC1
,
872 { MINUS
, INCREG
| FEATURE_FPA
,
876 " sufd A1,AL,AR" COM
"double subtraction\n", },
878 { MINUS
, INCREG
| FEATURE_VFP
,
882 " fsubd A1,AL,AR" COM
"double subtraction\n", },
887 NSPECIAL
|NBREG
, RESC1
,
890 { MINUS
, INCREG
| FEATURE_FPA
,
894 " sufe A1,AL,AR" COM
"ldouble subtraction\n", },
896 { MINUS
, INCREG
| FEATURE_VFP
,
900 " fsubd A1,AL,AR" COM
"double subtraction\n", },
905 NSPECIAL
|NBREG
, RESC1
,
909 * The next rules handle all shift operators.
913 SAREG
, TWORD
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
916 " mov A1,AL,asl AR" COM
"left shift\n", },
919 SAREG
, TWORD
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
922 " mov A1,AL,asl AR" COM
"left shift by constant\n", },
925 SBREG
, TLONGLONG
|TULONGLONG
,
931 SBREG
, TLONGLONG
|TULONGLONG
,
933 NSPECIAL
|NBREG
, RESC1
,
937 SAREG
, TSWORD
|TSHORT
|TCHAR
,
940 " mov A1,AL,asr AR" COM
"right shift\n", },
943 SAREG
, TUWORD
|TUSHORT
|TUCHAR
,
946 " mov A1,AL,lsr AR" COM
"right shift\n", },
949 SAREG
, TSWORD
|TSHORT
|TCHAR
,
952 " mov A1,AL,asr AR" COM
"right shift by constant\n", },
955 SAREG
, TUWORD
|TUSHORT
|TUCHAR
,
958 " mov A1,AL,lsr AR" COM
"right shift by constant\n", },
961 SBREG
, TLONGLONG
|TULONGLONG
,
967 SBREG
, TLONGLONG
|TULONGLONG
,
969 NSPECIAL
|NBREG
, RESC1
,
974 * The next rules takes care of assignments. "=".
977 { ASSIGN
, FOREFF
|INAREG
,
978 SOREG
|SNAME
, TWORD
|TPOINT
,
981 " str AR,AL" COM
"assign word\n", },
983 { ASSIGN
, FOREFF
|INBREG
,
984 SOREG
|SNAME
, TLONGLONG
|TULONGLONG
,
985 SBREG
, TLONGLONG
|TULONGLONG
,
987 " str AR,AL" COM
"assign 64-bit value\n"
990 /* XXX don't know if this works */
991 { ASSIGN
, FOREFF
|INBREG
,
992 SAREG
, TPTRTO
|TLONGLONG
|TULONGLONG
,
993 SBREG
, TLONGLONG
|TULONGLONG
,
995 " stmdb AL,{AR-UR}" COM
"assign 64-bit value\n", },
997 { ASSIGN
, FOREFF
|INAREG
,
998 SOREG
|SNAME
, TCHAR
|TUCHAR
,
1001 " strb AR,AL" COM
"assign (u)char\n", },
1003 { ASSIGN
, FOREFF
|INAREG
| FEATURE_HALFWORDS
,
1004 SOREG
|SNAME
, TSHORT
|TUSHORT
,
1005 SAREG
, TSHORT
|TUSHORT
,
1007 " strh AR,AL" COM
"assign (u)short\n", },
1009 { ASSIGN
, FOREFF
|INAREG
,
1010 SOREG
|SNAME
, TSHORT
|TUSHORT
,
1011 SAREG
, TSHORT
|TUSHORT
,
1015 { ASSIGN
, FOREFF
|INCREG
| FEATURE_FPA
,
1016 SOREG
|SNAME
, TFLOAT
,
1019 " stfs AR,AL" COM
"assign float\n", },
1021 { ASSIGN
, FOREFF
|INCREG
| FEATURE_VFP
,
1022 SOREG
|SNAME
, TFLOAT
,
1025 COM
"unimplemented\n", },
1027 { ASSIGN
, FOREFF
|INAREG
,
1028 SOREG
|SNAME
, TFLOAT
,
1031 " str AR,AL" COM
"assign float (soft-float)\n", },
1033 { ASSIGN
, FOREFF
|INCREG
| FEATURE_FPA
,
1034 SOREG
|SNAME
, TDOUBLE
,
1037 " stfd AR,AL" COM
"assign double\n", },
1039 { ASSIGN
, FOREFF
|INCREG
| FEATURE_VFP
,
1040 SOREG
|SNAME
, TDOUBLE
,
1043 COM
"unimplemented\n", },
1045 { ASSIGN
, FOREFF
|INBREG
,
1046 SOREG
|SNAME
, TDOUBLE
,
1049 " str AR,AL" COM
"assign double (soft-float)\n"
1052 { ASSIGN
, FOREFF
|INCREG
| FEATURE_FPA
,
1053 SOREG
|SNAME
, TLDOUBLE
,
1056 " stfe AR,AL" COM
"assign ldouble\n", },
1058 { ASSIGN
, FOREFF
|INCREG
| FEATURE_VFP
,
1059 SOREG
|SNAME
, TLDOUBLE
,
1062 COM
"not implemented", },
1064 { ASSIGN
, FOREFF
|INBREG
,
1065 SOREG
|SNAME
, TLDOUBLE
,
1068 " str AR,AL" COM
"assign ldouble (soft-float)\n"
1071 /* assign register to register */
1072 { ASSIGN
, FOREFF
|INAREG
,
1073 SAREG
, TWORD
|TPOINT
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
1074 SAREG
, TWORD
|TPOINT
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
1076 " mov AL,AR" COM
"assign AR to AL\n", },
1078 { ASSIGN
, FOREFF
|INBREG
,
1079 SBREG
, TLONGLONG
|TULONGLONG
,
1080 SBREG
, TLONGLONG
|TULONGLONG
,
1082 " mov AL,AR" COM
"assign UR:AR to UL:AL\n"
1085 { ASSIGN
, FOREFF
|INCREG
| FEATURE_FPA
,
1089 " mvf AL,AR" COM
"assign float reg to float reg\n", },
1091 { ASSIGN
, FOREFF
|INCREG
| FEATURE_VFP
,
1095 " fcpys AL,AR" COM
"assign float reg to float reg\n", },
1097 { ASSIGN
, FOREFF
|INAREG
,
1101 " mov AL,AR" COM
"assign float reg to float reg\n", },
1103 { ASSIGN
, FOREFF
|INCREG
| FEATURE_FPA
,
1104 SCREG
, TDOUBLE
|TLDOUBLE
,
1105 SCREG
, TDOUBLE
|TLDOUBLE
,
1107 " mvf AL,AR" COM
"assign float reg to float reg\n", },
1109 { ASSIGN
, FOREFF
|INCREG
| FEATURE_VFP
,
1110 SCREG
, TDOUBLE
|TLDOUBLE
,
1111 SCREG
, TDOUBLE
|TLDOUBLE
,
1113 " fcpyd AL,AR" COM
"assign float reg to float reg\n", },
1115 { ASSIGN
, FOREFF
|INBREG
,
1116 SBREG
, TDOUBLE
|TLDOUBLE
,
1117 SBREG
, TDOUBLE
|TLDOUBLE
,
1119 " mov AL,AR" COM
"assign (l)double reg to (l)double reg\n"
1122 { ASSIGN
, FOREFF
|INAREG
,
1126 " ldr A1,AR" COM
"bit-field assignment\n"
1129 " mov A1,A1,asl H\n"
1137 { ASSIGN
, FOREFF
|INAREG
,
1141 " ldr A2,AL" COM
"bit-field assignment\n"
1143 " mov A1,AR,asl H\n"
1151 { STASG
, INAREG
|FOREFF
,
1164 NSPECIAL
|NAREG
|NASL
, RESC1
,
1168 SBREG
, TLONGLONG
|TULONGLONG
,
1169 SBREG
, TLONGLONG
|TULONGLONG
,
1170 NSPECIAL
|NBREG
|NBSL
, RESC1
,
1173 { DIV
, INCREG
| FEATURE_FPA
,
1177 " dvfs A1,AL,AL" COM
"fast (float) divide\n", },
1179 { DIV
, INCREG
| FEATURE_VFP
,
1183 " fdivs A1,AL,AL" COM
"fast (float) divide\n", },
1188 NSPECIAL
|NAREG
, RESC1
,
1191 { DIV
, INCREG
| FEATURE_FPA
,
1195 " dvfd A1,AL,AL" COM
"double divide\n", },
1197 { DIV
, INCREG
| FEATURE_VFP
,
1201 " fdivd A1,AL,AL" COM
"double divide\n", },
1206 NSPECIAL
|NBREG
, RESC1
,
1209 { DIV
, INCREG
| FEATURE_FPA
,
1213 " dvfe A1,AL,AR" COM
"long double load\n", },
1215 { DIV
, INCREG
| FEATURE_VFP
,
1219 " fdivd A1,AL,AL" COM
"double divide\n", },
1224 NSPECIAL
|NBREG
, RESC1
,
1230 NSPECIAL
|NAREG
, RESC1
,
1234 SBREG
, TLONGLONG
|TULONGLONG
,
1235 SBREG
, TLONGLONG
|TULONGLONG
,
1236 NSPECIAL
|NBREG
, RESC1
,
1239 { MUL
, INAREG
| FEATURE_MUL
,
1240 SAREG
, TWORD
|TPOINT
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
1241 SAREG
, TWORD
|TPOINT
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
1243 " mul A1,AL,AR\n", },
1246 SAREG
, TWORD
|TPOINT
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
1247 SAREG
, TWORD
|TPOINT
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
1248 NSPECIAL
|NAREG
, RESC1
,
1251 { MUL
, INBREG
| FEATURE_MULL
,
1252 SAREG
, TUWORD
|TPOINT
|TUSHORT
|TUCHAR
,
1253 SAREG
, TUWORD
|TPOINT
|TUSHORT
|TUCHAR
,
1255 " smull U1,A1,AL,AR\n", },
1257 { MUL
, INBREG
| FEATURE_MUL
,
1258 SAREG
, TUWORD
|TPOINT
|TUSHORT
|TUCHAR
,
1259 SAREG
, TUWORD
|TPOINT
|TUSHORT
|TUCHAR
,
1262 " mov U1,A1,asr #31\n", },
1265 SAREG
, TUWORD
|TPOINT
|TUSHORT
|TUCHAR
,
1266 SAREG
, TUWORD
|TPOINT
|TUSHORT
|TUCHAR
,
1267 NSPECIAL
|NBREG
, RESC1
,
1270 { MUL
, INBREG
| FEATURE_MULL
,
1271 SAREG
, TSWORD
|TSHORT
|TCHAR
,
1272 SAREG
, TSWORD
|TSHORT
|TCHAR
,
1274 " umull U1,A1,AL,AR\n", },
1276 { MUL
, INBREG
| FEATURE_MUL
,
1277 SAREG
, TSWORD
|TSHORT
|TCHAR
,
1278 SAREG
, TSWORD
|TSHORT
|TCHAR
,
1284 SAREG
, TSWORD
|TSHORT
|TCHAR
,
1285 SAREG
, TSWORD
|TSHORT
|TCHAR
,
1286 NSPECIAL
|NBREG
, RESC1
,
1289 { MUL
, INBREG
| FEATURE_MULL
,
1290 SBREG
, TLONGLONG
|TULONGLONG
,
1291 SBREG
, TLONGLONG
|TULONGLONG
,
1293 " umull U1,A1,AL,AR\n", },
1295 { MUL
, INBREG
| FEATURE_MUL
,
1296 SBREG
, TLONGLONG
|TULONGLONG
,
1297 SBREG
, TLONGLONG
|TULONGLONG
,
1300 " mov U1,A1,asr #31\n", },
1303 SBREG
, TLONGLONG
|TULONGLONG
,
1304 SBREG
, TLONGLONG
|TULONGLONG
,
1305 NSPECIAL
|NBREG
, RESC1
,
1308 { MUL
, INCREG
| FEATURE_FPA
,
1312 " fmls A1,AL,AL" COM
"fast (float) multiply\n", },
1314 { MUL
, INCREG
| FEATURE_VFP
,
1318 " fmuls A1,AL,AL" COM
"float multiply\n", },
1323 NSPECIAL
|NAREG
, RESC1
,
1326 { MUL
, INCREG
| FEATURE_FPA
,
1327 SCREG
, TDOUBLE
|TLDOUBLE
,
1328 SCREG
, TDOUBLE
|TLDOUBLE
,
1330 " mufd A1,AL,AL" COM
"fast (l)double multiply\n", },
1332 { MUL
, INCREG
| FEATURE_VFP
,
1333 SCREG
, TDOUBLE
|TLDOUBLE
,
1334 SCREG
, TDOUBLE
|TLDOUBLE
,
1336 " muld A1,AL,AL" COM
"(l)double multiply\n", },
1339 SBREG
, TDOUBLE
|TLDOUBLE
,
1340 SBREG
, TDOUBLE
|TLDOUBLE
,
1341 NSPECIAL
|NBREG
, RESC1
,
1345 * Indirection operators.
1350 SOREG
|SNAME
, TWORD
|TPOINT
,
1352 " ldr A1,AL" COM
"word load\n", },
1358 " ldrsb A1,AL" COM
"char load\n", },
1362 SOREG
|SNAME
, TUCHAR
,
1364 " ldrb A1,AL" COM
"uchar load\n", },
1366 { UMUL
, INAREG
| FEATURE_HALFWORDS
,
1368 SOREG
|SNAME
, TUSHORT
,
1370 " ldrh A1,AL" COM
"short load\n", },
1372 { UMUL
, INAREG
| FEATURE_HALFWORDS
,
1374 SOREG
|SNAME
, TSHORT
,
1376 " ldrsh A1,AL" COM
"short load\n", },
1380 SOREG
|SNAME
, TSHORT
|TUSHORT
,
1381 2*NAREG
|NASL
, RESC1
,
1386 SOREG
|SNAME
, TLONGLONG
|TULONGLONG
,
1388 " ldr A1,AL" COM
"64-bit load\n"
1391 { UMUL
, INCREG
| FEATURE_FPA
,
1393 SOREG
|SNAME
, TFLOAT
,
1395 " ldfs A1,AL" COM
"float load\n", },
1397 { UMUL
, INCREG
| FEATURE_VFP
,
1399 SOREG
|SNAME
, TFLOAT
,
1401 COM
"not implemented\n", },
1405 SOREG
|SNAME
, TFLOAT
,
1407 " ldr A1,AL" COM
"float load\n", },
1409 { UMUL
, INCREG
| FEATURE_FPA
,
1411 SOREG
|SNAME
, TDOUBLE
,
1413 " ldfd A1,AL" COM
"double load\n", },
1415 { UMUL
, INCREG
| FEATURE_VFP
,
1417 SOREG
|SNAME
, TDOUBLE
,
1419 COM
"not implemented\n", },
1423 SOREG
|SNAME
, TDOUBLE
,
1425 " ldr A1,AL" COM
"double load\n"
1428 { UMUL
, INCREG
| FEATURE_FPA
,
1430 SOREG
|SNAME
, TLDOUBLE
,
1432 " ldfe A1,AL" COM
"long double load\n", },
1434 { UMUL
, INCREG
| FEATURE_VFP
,
1436 SOREG
|SNAME
, TLDOUBLE
,
1438 COM
"not implemented\n", },
1442 SOREG
|SNAME
, TLDOUBLE
,
1444 " ldr A1,AL" COM
"long double load (soft-float)\n"
1448 * Logical/branching operators
1451 /* compare with register */
1453 SAREG
, TSWORD
|TSHORT
|TCHAR
,
1454 SAREG
, TSWORD
|TSHORT
|TCHAR
,
1456 " cmp AL,AR" COM
"AR-AL (sets flags)\n", },
1458 /* compare with register */
1460 SAREG
, TUWORD
|TPOINT
|TUSHORT
|TUCHAR
,
1461 SAREG
, TUWORD
|TPOINT
|TUSHORT
|TUCHAR
,
1463 " cmp AL,AR" COM
"AR-AL (sets flags)\n", },
1465 /* compare with register */
1467 SBREG
, TLONGLONG
|TULONGLONG
,
1468 SBREG
, TLONGLONG
|TULONGLONG
,
1472 { OPLOG
, FORCC
| FEATURE_FPA
,
1476 " cmfs AL,AR" COM
"float compare\n", },
1478 { OPLOG
, FORCC
| FEATURE_VFP
,
1482 " fcmps AL,AR" COM
"float compare\n", },
1490 { OPLOG
, FORCC
| FEATURE_FPA
,
1494 " cmfd AL,AR" COM
"double compare\n", },
1496 { OPLOG
, FORCC
| FEATURE_VFP
,
1500 " fcmpd AL,AR" COM
"double compare\n", },
1508 { OPLOG
, FORCC
| FEATURE_FPA
,
1512 " cmfe AL,AR" COM
"ldouble compare\n", },
1514 { OPLOG
, FORCC
| FEATURE_VFP
,
1518 " fcmpd AL,AR" COM
"double compare\n", },
1528 SBREG
, TLONGLONG
|TULONGLONG
,
1529 SBREG
, TLONGLONG
|TULONGLONG
,
1530 NBREG
|NBSL
, RESC1
|RESCC
,
1531 " and A1,AL,AR" COM
"64-bit and\n"
1532 " and U1,UL,UR\n", },
1535 SBREG
, TLONGLONG
|TULONGLONG
,
1536 SBREG
, TLONGLONG
|TULONGLONG
,
1538 " orr A1,AL,AR" COM
"64-bit or\n"
1539 " orr U1,UL,UR\n" },
1542 SBREG
, TLONGLONG
|TULONGLONG
,
1543 SBREG
, TLONGLONG
|TULONGLONG
,
1545 " eor A1,AL,AR" COM
"64-bit xor\n"
1546 " eor U1,UL,UR\n" },
1549 SAREG
, TWORD
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
1550 SAREG
, TWORD
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
1551 NAREG
|NASL
, RESC1
|RESCC
,
1554 { OPSIMP
, INAREG
|FORCC
,
1555 SAREG
, TWORD
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
1556 SAREG
, TWORD
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
1558 " Os A1,AL,AR\n", },
1579 * Convert LTYPE to reg.
1584 SOREG
|SNAME
, TWORD
|TPOINT
,
1586 " ldr A1,AL" COM
"load word from memory\n", },
1590 SOREG
|SNAME
, TLONGLONG
|TULONGLONG
,
1592 " ldr A1,AL" COM
"load long long from memory\n"
1599 " ldrsb A1,AL" COM
"load char from memory\n" },
1603 SOREG
|SNAME
, TUCHAR
,
1605 " ldrb A1,AL" COM
"load uchar from memory\n", },
1607 { OPLTYPE
, INAREG
| FEATURE_HALFWORDS
,
1609 SOREG
|SNAME
, TSHORT
,
1611 " ldrsh A1,AL" COM
"load short from memory\n", },
1613 { OPLTYPE
, INAREG
| FEATURE_HALFWORDS
,
1615 SOREG
|SNAME
, TUSHORT
,
1617 " ldrh A1,AL" COM
"load ushort from memory\n", },
1621 SOREG
|SNAME
, TSHORT
|TUSHORT
,
1630 " ldr A1,AL" COM
"load integer constant\n", },
1649 " mov A1,AL" COM
"load AL into A1\n" },
1653 SBREG
, TLONGLONG
|TULONGLONG
,
1655 " mov A1,AL" COM
"load UL:AL into U1:A1\n"
1658 { OPLTYPE
, INCREG
| FEATURE_FPA
,
1660 SOREG
|SNAME
, TFLOAT
,
1662 " ldfs A1,AL" COM
"load float\n", },
1664 { OPLTYPE
, INCREG
| FEATURE_VFP
,
1666 SOREG
|SNAME
, TFLOAT
,
1668 COM
"not implemented\n", },
1672 SOREG
|SNAME
, TFLOAT
,
1674 " ldr A1,AL" COM
"load float (soft-float)\n", },
1676 { OPLTYPE
, INCREG
| FEATURE_FPA
,
1678 SOREG
|SNAME
, TDOUBLE
,
1680 " ldfd A1,AL" COM
"load double\n", },
1682 { OPLTYPE
, INCREG
| FEATURE_VFP
,
1684 SOREG
|SNAME
, TDOUBLE
,
1686 COM
"not implemented\n" },
1690 SOREG
|SNAME
, TDOUBLE
,
1692 " ldr A1,AL" COM
"load double (soft-float)\n"
1695 { OPLTYPE
, INCREG
| FEATURE_FPA
,
1697 SOREG
|SNAME
, TLDOUBLE
,
1699 " ldfe A1,AL" COM
"load ldouble\n", },
1701 { OPLTYPE
, INCREG
| FEATURE_VFP
,
1703 SOREG
|SNAME
, TLDOUBLE
,
1705 COM
"not implemented\n", },
1709 SOREG
|SNAME
, TLDOUBLE
,
1711 " ldr A1,AL" COM
"load ldouble (soft-float)\n"
1719 SAREG
, TWORD
|TPOINT
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
1720 SAREG
, TWORD
|TPOINT
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
1722 " rsb A1,AL,#0" COM
"negation\n", },
1725 SBREG
, TLONGLONG
|TULONGLONG
,
1726 SBREG
, TLONGLONG
|TULONGLONG
,
1728 " rsbs A1,AL,#0" COM
"64-bit negation\n"
1729 " rsc U1,UL,#0\n", },
1731 { UMINUS
, INCREG
| FEATURE_FPA
,
1735 " mvfs A1,AL" COM
"float negation\n", },
1737 { UMINUS
, INCREG
| FEATURE_VFP
,
1741 " negs A1,AL" COM
"float negation\n", },
1746 NSPECIAL
|NAREG
, RESC1
,
1749 { UMINUS
, INCREG
| FEATURE_FPA
,
1753 " mvfd A1,AL" COM
"double negation\n", },
1755 { UMINUS
, INCREG
| FEATURE_VFP
,
1759 " negd A1,AL" COM
"double negation\n", },
1764 NSPECIAL
|NBREG
, RESC1
,
1767 { UMINUS
, INCREG
| FEATURE_FPA
,
1771 " mvfe A1,AL" COM
"ldouble negation\n", },
1773 { UMINUS
, INCREG
| FEATURE_VFP
,
1777 " negd A1,AL" COM
"ldouble negation\n", },
1782 NSPECIAL
|NBREG
, RESC1
,
1786 SAREG
, TWORD
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
1789 " mvn A1,AL" COM
"complement\n", },
1792 SBREG
, TLONGLONG
|TULONGLONG
,
1795 " mvn A1,AL" COM
"64-bit complement\n"
1799 * Arguments to functions.
1803 SAREG
, TWORD
|TPOINT
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
1804 SANY
, TWORD
|TPOINT
|TSHORT
|TUSHORT
|TCHAR
|TUCHAR
,
1806 " stmfd sp!,{AL}" COM
"save function arg to stack\n", },
1809 SBREG
, TLONGLONG
|TULONGLONG
,
1810 SANY
, TLONGLONG
|TULONGLONG
,
1812 " stmfd sp!,{AL,UL}" COM
"save function arg to stack (endianness problem here?)\n", },
1818 " stmfd sp!,{AL}" COM
"save function arg to stack\n", },
1821 SCREG
, TDOUBLE
|TLDOUBLE
,
1822 SANY
, TDOUBLE
|TLDOUBLE
,
1824 " stmfd sp!,{AL,UL}" COM
"save function arg to stack (endianness problem here?)\n", },
1826 # define DF(x) FORREW,SANY,TANY,SANY,TANY,REWRITE,x,""
1828 { UMUL
, DF( UMUL
), },
1830 { ASSIGN
, DF(ASSIGN
), },
1832 { STASG
, DF(STASG
), },
1836 { OPLEAF
, DF(NAME
), },
1838 /* { INIT, DF(INIT), }, */
1840 { OPUNARY
, DF(UMINUS
), },
1842 { OPANY
, DF(BITYPE
), },
1844 { FREE
, FREE
, FREE
, FREE
, FREE
, FREE
, FREE
, FREE
, "help; I'm in trouble\n" },
1847 int tablesize
= sizeof(table
)/sizeof(table
[0]);