xref: /netbsd/external/bsd/pcc/dist/pcc/arch/mips/table.c (revision 6550d01e)
1 /*	Id: table.c,v 1.13 2008/04/15 10:24:23 gmcgarry Exp 	*/
2 /*	$NetBSD: table.c,v 1.1.1.2 2010/06/03 18:57:20 plunky Exp $	*/
3 /*
4  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /*
31  * MIPS port by Jan Enoksson (janeno-1@student.ltu.se) and
32  * Simon Olsson (simols-1@student.ltu.se) 2005.
33  *
34  * It appears that the target machine was big endian.  The original
35  * code contained many endian aspects which are now handled in
36  * machine-independent code.
37  *
38  * On MIPS, the assembler does an amazing amount of work for us.
39  * We don't have to worry about PIC, nor about finding the address
40  * of SNAMES.  Whenever possible, we defer the work to the assembler.
41  */
42 
43 #include "pass2.h"
44 
45 #define TUWORD TUNSIGNED|TULONG
46 #define TSWORD TINT|TLONG
47 #define TWORD TUWORD|TSWORD
48 
49 struct optab table[] = {
50 /* First entry must be an empty entry */
51 { -1, FOREFF, SANY, TANY, SANY, TANY, 0, 0, "", },
52 
53 /* PCONVs are usually not necessary */
54 { PCONV,	INAREG,
55 	SAREG,	TWORD|TPOINT,
56 	SAREG,	TWORD|TPOINT,
57 		0,	RLEFT,
58 		"	# convert between word and pointer", },
59 
60 /*
61  * Conversions of integral<->integral types
62  */
63 
64 { SCONV,	INAREG,
65 	SOREG,  TCHAR,
66 	SAREG,	TSWORD|TSHORT,
67 		NAREG,	RESC1,
68 		"	lb A1,AL	# convert oreg char to short/int\n"
69 		"	nop\n", },
70 
71 { SCONV, 	INAREG,
72 	SOREG,	TCHAR,
73 	SAREG,	TUWORD|TUSHORT|TUCHAR,
74 		NAREG,	RESC1,
75 		"	lbu A1,AL	# convert oreg char to uchar/ushort/uint\n"
76 		"	nop\n", },
77 
78 { SCONV,	INAREG,
79 	SOREG,  TUCHAR,
80 	SAREG,	TWORD|TSHORT|TUSHORT,
81 		NAREG,	RESC1,
82 		"	lbu A1,AL	# convert oreg uchar to (u)short/(u)int\n"
83 		"	nop\n", },
84 
85 { SCONV,	INBREG,
86 	SOREG,	TCHAR,
87 	SBREG,	TLONGLONG,
88 		NBREG,	RESC1,
89       		"	lb A1,AL	# convert oreg char to longlong\n"
90       		"	nop\n"
91       		"	sra U1,A1,31\n", },
92 
93 /* chor -> ulonglong handled later */
94 
95 { SCONV,	INBREG,
96 	SOREG,	TUCHAR,
97 	SBREG,	TLONGLONG|TULONGLONG,
98 		NBREG,	RESC1,
99 		"	lbu A1,AL	# convert oreg uchar to (u)longlong\n"
100       		"	move U1,$zero\n", },
101 
102 { SCONV,	INAREG,
103 	SOREG,	TSHORT|TUSHORT,
104 	SAREG,	TCHAR,
105 		NAREG,	RESC1,
106 		"	lb A1,AL	# convert oreg (u)short to char (endianness problem?)\n"
107 		"	nop\n", },
108 
109 { SCONV,	INAREG,
110 	SOREG,	TSHORT|TUSHORT,
111 	SAREG,  TUCHAR,
112 		NAREG,	RESC1,
113 		"	lbu A1,AL	# convert oreg (u)short to uchar (endianness problem?)\n"
114 		"	nop\n", },
115 
116 { SCONV,	INAREG,
117 	SOREG,	TSHORT,
118 	SAREG,	TSWORD,
119 		NAREG,	RESC1,
120 		"	lh A1,AL	# convert oreg short to int\n"
121 		"	nop\n", },
122 
123 { SCONV,	INAREG,
124 	SOREG,	TSHORT,
125 	SAREG,	TUWORD,
126 		NAREG,	RESC1,
127 		"	lhu A1,AL	# convert oreg short to uint\n"
128 		"	nop\n", },
129 
130 { SCONV,	INAREG,
131 	SOREG,	TUSHORT,
132 	SAREG,	TWORD,
133 		NAREG,	RESC1,
134 		"	lhu A1,AL	# convert oreg ushort to (u)int\n"
135 		"	nop\n", },
136 
137 { SCONV,	INBREG,
138 	SOREG,	TSHORT,
139 	SBREG,	TLONGLONG,
140 		NBREG,	RESC1,
141       		"	lh A1,AL	# convert oreg short to longlong\n"
142       		"	nop\n"
143       		"	sra U1,A1,31\n", },
144 
145 { SCONV,	INBREG,
146 	SOREG,	TSHORT,
147 	SBREG,	TULONGLONG,
148 		NBREG,	RESC1,
149       		"	lhu A1,AL	# convert oreg short to ulonglong\n"
150       		"	nop\n"
151 		"	move U1,$zero\n", },
152 
153 { SCONV,	INBREG,
154 	SOREG,	TUSHORT,
155 	SBREG,	TLONGLONG|TULONGLONG,
156 		NBREG,	RESC1,
157 		"	lhu A1,AL	# convert oreg ushort to (u)longlong\n"
158       		"	move U1,$zero\n", },
159 
160 { SCONV,	INAREG,
161 	SOREG,	TWORD,
162 	SAREG,	TCHAR,
163 		NAREG,	RESC1,
164 		"	lb A1,AL	# convert oreg word to char (endianness problem here?)\n"
165 		"	nop\n", },
166 
167 { SCONV,	INAREG,
168 	SOREG,	TWORD,
169 	SAREG,	TUCHAR,
170 		NAREG,	RESC1,
171 		"	lbu A1,AL	# convert oreg word to uchar (endianness problem here?)\n"
172 		"	nop\n", },
173 
174 { SCONV,	INAREG,
175 	SOREG,	TWORD,
176 	SAREG,	TSHORT,
177 		NAREG,	RESC1,
178 		"	lh A1,AL	# convert oreg word to short (endianness problem here?)\n"
179 		"	nop\n", },
180 
181 /* convert (u)long to ushort */
182 { SCONV,	INAREG,
183 	SOREG,	TWORD,
184 	SAREG,	TUSHORT,
185 		NAREG,	RESC1,
186 		"	lhu A1,AL	# convert oreg word to ushort (endianness problem here?)\n"
187 		"	nop\n", },
188 
189 { SCONV,	INBREG,
190 	SOREG,	TSWORD,
191 	SBREG,	TLONGLONG|TULONGLONG,
192 		NBREG,	RESC1,
193       		"	lw A1,AL	# convert oreg int/long to (u)llong (endianness problem here?)\n"
194       		"	nop\n"
195       		"	sra U1,A1,31\n" },
196 
197 { SCONV,	INBREG,
198 	SOREG,	TUWORD,
199 	SBREG,	TLONGLONG|TULONGLONG,
200 		NBREG,	RESC1,
201 		"	lw A1,AL	# convert oreg (u)int to (u)llong (endianness problem here?)\n"
202       		"	move U1,$zero\n", },
203 
204 { SCONV,	INAREG,
205 	SOREG,	TLONGLONG|TULONGLONG,
206 	SAREG,	TCHAR,
207 		NAREG,	RESC1,
208 		"	lb A1,AL	# convert oreg (u)llong to char	(endianness problem here?)\n"
209 		"	nop\n", },
210 
211 { SCONV,	INAREG,
212 	SOREG,	TLONGLONG|TULONGLONG,
213 	SAREG,	TUCHAR,
214 		NAREG,	RESC1,
215 		"	lbu A1,AL	# convert oreg (u)llong to uchar (endianness problem?)\n"
216 		"	nop\n", },
217 
218 { SCONV,	INAREG,
219 	SOREG,	TLONGLONG|TULONGLONG,
220 	SAREG,	TSHORT,
221 		NAREG,	RESC1,
222 		"	lh A1,AL	# convert oreg (u)llong to short (endianness problem?)\n"
223 		"	nop\n", },
224 
225 { SCONV,	INAREG,
226 	SOREG,	TLONGLONG|TULONGLONG,
227 	SAREG,	TUSHORT,
228 		NAREG,	RESC1,
229 		"	lhu A1,AL	# convert oreg (u)llong to ushort (endianness problem here?)\n"
230 		"	nop\n", },
231 
232 { SCONV,	INAREG,
233 	SOREG,	TLONGLONG|TULONGLONG,
234 	SAREG,	TWORD,
235 		NAREG,	RESC1,
236       		"	lw A1,AL	# convert oreg (u)llong to (u)int (endianness problem here?)\n"
237 		"	nop\n", },
238 
239 /*
240  * Conversions of integral types (register-register)
241  *
242  * For each deunsigned type, they look something like this:
243  *
244  * signed -> bigger signed      - nothing to do
245  * signed -> bigger unsigned    - clear the top bits (of source type)
246  *
247  * signed -> smaller signed     - sign-extend the bits (to dest type)
248  * signed -> smaller unsigned   - clear the top bits (of dest type)
249  * unsigned -> smaller signed   - sign-extend top bits (to dest type)
250  * unsigned -> smaller unsigned - clear the top bits (of dest type)
251  *
252  * unsigned -> bigger           - nothing to do
253  */
254 
255 { SCONV,	INAREG,
256 	SAREG,	TPOINT|TWORD,
257 	SAREG,	TPOINT|TWORD,
258 		0,	RLEFT,
259 		"	# convert int to int\n", },
260 
261 { SCONV,	INBREG,
262 	SBREG,	TLONGLONG|TULONGLONG,
263 	SBREG,	TLONGLONG|TULONGLONG,
264 		0,	RLEFT,
265 		"	# convert (u)longlong to (u)longlong", },
266 
267 { SCONV,	INAREG,
268 	SAREG,	TCHAR,
269 	SAREG,	TSWORD|TSHORT,
270 		0,	RLEFT,
271 		"	# convert char to short/int\n", },
272 
273 { SCONV,	INAREG,
274 	SAREG,	TCHAR,
275 	SAREG,	TUWORD|TUSHORT|TUCHAR,
276 		NAREG|NASL,	RESC1,
277 		"	andi A1,AL,255	# convert char to uchar/ushort/uint\n", },
278 
279 { SCONV,	INAREG,
280 	SAREG,	TUCHAR,
281 	SAREG,	TCHAR,
282 		NAREG|NASL,	RESC1,
283 		"	sll A1,AL,24	# convert uchar to char\n"
284 		"	sra A1,A1,24\n", },
285 
286 { SCONV,	INAREG,
287 	SAREG,	TUCHAR,
288 	SAREG,	TWORD|TSHORT|TUSHORT,
289 		0,	RLEFT,
290 		"	# convert uchar to (u)short/(u)int\n", },
291 
292 { SCONV,	INAREG,
293 	SAREG,	TSHORT,
294 	SAREG,	TCHAR,
295 		NAREG|NASL,	RESC1,
296 		"	sll A1,AL,24	# convert short to char\n"
297 		"	sra A1,A1,24\n", },
298 
299 { SCONV,	INAREG,
300 	SAREG,	TSHORT,
301 	SAREG,	TUCHAR,
302 		NAREG|NASL,	RESC1,
303 		"	andi A1,AL,255	# convert short to uchar\n", },
304 
305 { SCONV,	INAREG,
306 	SAREG,	TSHORT,
307 	SAREG,	TUWORD|TUSHORT,
308 		NAREG|NASL,	RESC1,
309 		"	andi A1,AL,65535	# convert short to ushort\n", },
310 
311 { SCONV,	INAREG,
312 	SAREG,	TSHORT,
313 	SAREG,	TSWORD,
314 		NAREG|NASL,	RESC1,
315 		"	sll A1,AL,16	# convert short to ushort\n"
316 		"	sra A1,A1,16\n", },
317 
318 { SCONV,	INAREG,
319 	SAREG,	TUSHORT,
320 	SAREG,	TCHAR,
321 		NAREG|NASL,	RESC1,
322 		"	sll A1,AL,24	# convert short to char\n"
323 		"	sra A1,A1,24\n", },
324 
325 { SCONV,	INAREG,
326 	SAREG,	TUSHORT,
327 	SAREG,	TUCHAR,
328 		NAREG|NASL,	RESC1,
329 		"	andi A1,AL,255	# convert ushort to char\n", },
330 
331 { SCONV,	INAREG,
332 	SAREG,	TUSHORT,
333 	SAREG,	TSHORT,
334 		NAREG|NASL,	RESC1,
335 		"	sll A1,AL,16	# convert short to ushort\n"
336 		"	sra A1,A1,16\n", },
337 
338 { SCONV,	INAREG,
339 	SAREG,	TUSHORT,
340 	SAREG,	TWORD,
341 		0,	RDEST,
342 		"	# convert ushort to (u)int\n", },
343 
344 { SCONV,	INAREG,
345 	SAREG,	TSWORD,
346 	SAREG,	TCHAR,
347 		NAREG|NASL,	RESC1,
348 		"	sll A1,AL,8	# convert int to char\n"
349 		"	sra A1,A1,8\n", },
350 
351 { SCONV,	INAREG,
352 	SAREG,	TSWORD,
353 	SAREG,	TUCHAR,
354 		NAREG|NASL,	RESC1,
355 		"	andi A1,AL,255	# convert int to uchar\n", },
356 
357 { SCONV,	INAREG,
358 	SAREG,	TSWORD,
359 	SAREG,	TSHORT,
360 		NAREG|NASL,	RESC1,
361 		"	sll A1,AL,16	# convert int to short\n"
362 		"	sra A1,A1,16\n", },
363 
364 { SCONV,	INAREG,
365 	SAREG,	TSWORD,
366 	SAREG,	TUSHORT,
367 		NAREG|NASL,	RESC1,
368 		"	andi A1,AL,65535	# convert int to ushort\n", },
369 
370 { SCONV,	INAREG,
371 	SAREG,	TUWORD,
372 	SAREG,	TCHAR,
373 		NAREG|NASL,	RESC1,
374 		"	sll A1,AL,24	# convert int to char\n"
375 		"	sra A1,A1,24\n", },
376 
377 { SCONV,	INAREG,
378 	SAREG,	TUWORD,
379 	SAREG,	TUCHAR,
380 		NAREG|NASL,	RESC1,
381 		"	andi A1,AL,255	# convert int to uchar\n", },
382 
383 { SCONV,	INAREG,
384 	SAREG,	TUWORD,
385 	SAREG,	TSHORT,
386 		NAREG|NASL,	RESC1,
387 		"	sll A1,AL,16	# convert int to short\n"
388 		"	sra A1,A1,16\n", },
389 
390 { SCONV,	INAREG,
391 	SAREG,	TUWORD,
392 	SAREG,	TUSHORT,
393 		NAREG|NASL,	RESC1,
394 		"	andi A1,AL,65535	# convert int to ushort\n", },
395 
396 { SCONV,	INBREG,
397 	SAREG,	TSWORD|TSHORT|TCHAR,
398 	SBREG,	TLONGLONG,
399 		NBREG,	RESC1,
400 		"	move A1,AL	# convert int/short/char to longlong\n"
401 		"	sra U1,AL,31\n", },
402 
403 { SCONV,	INBREG,
404 	SAREG,	TSWORD|TSHORT|TCHAR,
405 	SBREG,	TULONGLONG,
406 		NBREG,	RESC1,
407 		"	move A1,AL	# convert int/short/char to ulonglong\n"
408 		"	move U1,$zero\n", },
409 
410 { SCONV,	INBREG,
411 	SAREG,	TWORD|TUSHORT|TSHORT|TUCHAR|TCHAR,
412 	SBREG,	TLONGLONG|TULONGLONG,
413 		NBREG,	RESC1,
414 		"	move A1,AL	# convert (u)int/(u)short/(u)char to ulonglong\n"
415 		"	move U1,$zero\n", },
416 
417 { SCONV,	INAREG,
418 	SBREG,	TLONGLONG|TULONGLONG,
419 	SAREG,	TWORD,
420 		NAREG,	RESC1,
421 		"	move A1,AL	# convert (u)longlong to int\n", },
422 
423 { SCONV,	INAREG,
424 	SBREG,	TLONGLONG|TULONGLONG,
425 	SAREG,	TSHORT,
426 		NAREG,	RESC1,
427 		"	sll A1,AL,16	# convert (u)longlong to short\n"
428 		"	sra A1,A1,16\n", },
429 
430 { SCONV,	INAREG,
431 	SBREG,	TLONGLONG|TULONGLONG,
432 	SAREG,	TCHAR,
433 		NAREG,	RESC1,
434 		"	sll A1,AL,24	# convert (u)longlong to char\n"
435 		"	sra A1,A1,24\n", },
436 
437 { SCONV,	INAREG,
438 	SBREG,	TLONGLONG|TULONGLONG,
439 	SAREG,	TUSHORT,
440 		NAREG,	RESC1,
441 		"	andi A1,AL,65535	# convert (u)longlong to ushort\n", },
442 
443 { SCONV,	INAREG,
444 	SBREG,	TLONGLONG|TULONGLONG,
445 	SAREG,	TUCHAR,
446 		NAREG,	RESC1,
447 		"	andi A1,AL,255	# convert (u)longlong to uchar\n", },
448 
449 { SCONV,	INCREG,
450 	SCREG,	TFLOAT,
451 	SCREG,	TDOUBLE|TLDOUBLE,
452 		NCREG,	RESC1,
453 		"	cvt.d.s A1,AL	# convert float to (l)double\n", },
454 
455 { SCONV,	INCREG,
456 	SCREG,	TDOUBLE|TLDOUBLE,
457 	SCREG,	TFLOAT,
458 		NCREG,	RESC1,
459 		"	cvt.s.d A1,AL	# convert (l)double to float\n", },
460 
461 { SCONV,	INCREG,
462 	SAREG,	TWORD,
463 	SCREG,	TFLOAT,
464 		NCREG,	RESC1,
465 		"	mtc1 AL,A1	# convert (u)int to float\n"
466 		"	nop\n"
467 		"	cvt.s.w A1,A1\n", },
468 
469 { SCONV,	INCREG,
470 	SOREG,	TWORD,
471 	SCREG,	TFLOAT,
472 		NCREG,	RESC1,
473 		"	l.s A1,AL	# convert (u)int to float\n"
474 		"	nop\n"
475 		"	cvt.s.w A1,A1\n", },
476 
477 { SCONV,	INCREG,
478 	SAREG,	TWORD,
479 	SCREG,	TDOUBLE|TLDOUBLE,
480 		NCREG,	RESC1,
481 		"	mtc1 AL,A1	# convert (u)int to (l)double\n"
482 		"	nop\n"
483 		"	cvt.d.w A1,A1\n", },
484 
485 { SCONV,	INCREG,
486 	SOREG,	TWORD,
487 	SCREG,	TDOUBLE|TLDOUBLE,
488 		NCREG,	RESC1,
489 		"	l.d A1,AL	# convert (u)int to (l)double\n"
490 		"	nop\n"
491 		"	cvt.d.w A1,A1\n", },
492 
493 { SCONV,	INAREG,
494 	SCREG,	TFLOAT,
495 	SAREG,	TWORD,
496 		NCREG|NAREG,	RESC1,
497 		"	cvt.w.s A2,AL	# convert float to (u)int\n"
498 		"	mfc1 A1,A2\n"
499 		"	nop\n", },
500 
501 { SCONV,	FOREFF,
502 	SCREG,	TFLOAT,
503 	SOREG,	TWORD,
504 		NCREG,	RDEST,
505 		"	cvt.w.s A1,AL	# convert float to (u)int\n"
506 		"	s.s A1,AR\n"
507 		"	nop\n", },
508 
509 { SCONV,	INAREG,
510 	SCREG,	TDOUBLE|TLDOUBLE,
511 	SAREG,	TWORD,
512 		NCREG|NAREG,	RESC1,
513 		"	cvt.w.d A2,AL	# convert (l)double to (u)int\n"
514 		"	mfc1 A1,A2\n"
515 		"	nop\n", },
516 
517 { SCONV,	INCREG,
518 	SCREG,	TDOUBLE|TLDOUBLE,
519 	SCREG,	TDOUBLE|TLDOUBLE,
520 		0,	RLEFT,
521 		"	# convert between double and ldouble\n", },
522 
523 { SCONV,	INCREG,
524 	SBREG,	TLONGLONG|TULONGLONG,
525 	SCREG,	TFLOAT,
526 		NSPECIAL|NCREG,	RESC1,
527 		"ZF", },
528 
529 { SCONV,	INCREG,
530 	SBREG,	TLONGLONG|TULONGLONG,
531 	SCREG,	TDOUBLE|TLDOUBLE,
532 		NSPECIAL|NCREG,	RESC1,
533 		"ZF", },
534 
535 { SCONV,	INBREG,
536 	SCREG,	TDOUBLE|TLDOUBLE,
537 	SBREG,	TLONGLONG|TULONGLONG,
538 		NSPECIAL|NBREG,		RESC1,
539 		"ZF", },
540 
541 { SCONV,	INBREG,
542 	SCREG,	TFLOAT,
543 	SBREG,	TLONGLONG|TULONGLONG,
544 		NSPECIAL|NBREG,		RESC1,
545 		"ZF", },
546 
547 /*
548  * Multiplication and division
549  */
550 
551 { MUL,	INAREG,
552 	SAREG,	TUWORD|TUSHORT|TUCHAR,
553 	SAREG,	TUWORD|TUSHORT|TUCHAR,
554 		NAREG|NASR|NASL,	RESC1,
555 		"	multu AL,AR	# unsigned multiply\n"
556 		"	mflo A1\n"
557 		"	nop\n"
558 		"	nop\n", },
559 
560 /* this previous will match on unsigned/unsigned multiplication first */
561 { MUL,	INAREG,
562 	SAREG,	TWORD|TUSHORT|TSHORT|TUCHAR|TCHAR,
563 	SAREG,	TWORD|TUSHORT|TSHORT|TUCHAR|TCHAR,
564 		NAREG|NASR|NASL,	RESC1,
565 		"	mult AL,AR	# signed multiply\n"
566 		"	mflo A1\n"
567 		"	nop\n"
568 		"	nop\n", },
569 
570 { MUL,	INBREG,
571 	SBREG,	TLONGLONG|TULONGLONG,
572 	SBREG,	TLONGLONG|TULONGLONG,
573 		2*NBREG,	RESC1,
574 		"	multu AL,AR\n"
575 		"	mfhi U1\n"
576 		"	mflo A1\n"
577 		"	mult AL,UR\n"
578 		"	mflo A2\n"
579 		"	nop\n"
580 		"	nop\n"
581 		"	addu A2,U1,A2\n"
582 		"	mult UL,AR\n"
583 		"	mflo U2\n"
584 		"	nop\n"
585 		"	nop\n"
586 		"	addu U1,A2,U2\n", },
587 
588 { MUL,	INCREG,
589 	SCREG,	TFLOAT,
590 	SCREG,	TFLOAT,
591 		NCREG,	RESC1,
592 		"	mul.s A1,AL,AR		# floating-point multiply\n", },
593 
594 { MUL,	INCREG,
595 	SCREG,	TDOUBLE|TLDOUBLE,
596 	SCREG,	TDOUBLE|TLDOUBLE,
597 		NCREG,	RESC1,
598 		"	mul.d	A1,AL,AR	# double-floating-point multiply\n", },
599 
600 { DIV,	INAREG,
601 	SAREG,	TUWORD|TUSHORT|TUCHAR,
602 	SAREG,	TUWORD|TUSHORT|TUCHAR,
603 		NAREG|NASR|NASL,	RESC1,
604 		"	divu AL,AR	# unsigned division\n"
605 		"	mflo A1\n"
606 		"	nop\n"
607 		"	nop\n", },
608 
609 /* the previous rule will match unsigned/unsigned first */
610 { DIV,	INAREG,
611 	SAREG,	TWORD|TUSHORT|TSHORT|TUCHAR|TCHAR,
612 	SAREG,	TWORD|TUSHORT|TSHORT|TUCHAR|TCHAR,
613 		NAREG|NASR|NASL,	RESC1,
614 		"	div AL,AR	# signed division\n"
615 		"	mflo A1\n"
616 		"	nop\n"
617 		"	nop\n", },
618 
619 { DIV, INBREG,
620 	SBREG,	TLONGLONG|TULONGLONG,
621 	SBREG,	TLONGLONG|TULONGLONG,
622 		NSPECIAL|NBREG,	RESC1,
623 		"ZE", },
624 
625 { DIV,	INCREG,
626 	SCREG,	TFLOAT,
627 	SCREG,	TFLOAT,
628 		NCREG,	RESC1,
629 		"	div.s A1,AL,AR		# floating-point division\n", },
630 
631 { DIV,	INCREG,
632 	SCREG,	TDOUBLE|TLDOUBLE,
633 	SCREG,	TDOUBLE|TLDOUBLE,
634 		NCREG,	RESC1,
635 		"	div.d	A1,AL,AR	# double-floating-point division\n", },
636 
637 { MOD,  INAREG,
638         SAREG,  TUWORD|TUSHORT|TUCHAR,
639         SAREG,  TUWORD|TUSHORT|TUCHAR,
640                 NAREG,  RESC1,
641                 "       divu AL,AR	# signed modulo\n"
642 		"	mfhi A1\n"
643 		"	nop\n"
644 		"	nop\n", },
645 
646 /* the previous rule will match unsigned%unsigned first */
647 { MOD,  INAREG,
648         SAREG,  TWORD|TUSHORT|TSHORT|TUCHAR|TCHAR,
649         SAREG,  TWORD|TUSHORT|TSHORT|TUCHAR|TCHAR,
650                 NAREG,  RESC1,
651                 "	div AL,AR	# signed modulo\n"
652 		"	mfhi A1\n"
653 		"	nop\n"
654 		"	nop\n", },
655 
656 { MOD,  INBREG,
657 	SBREG,	TLONGLONG|TULONGLONG,
658 	SBREG,	TLONGLONG|TULONGLONG,
659                 NSPECIAL|NBREG,  RESC1,
660                 "ZE", },
661 
662 /*
663  * Templates for unsigned values needs to come before OPSIMP
664  */
665 
666 { PLUS,	INBREG,
667 	SBREG,	TULONGLONG|TLONGLONG,
668 	SBREG,	TULONGLONG|TLONGLONG,
669 		2*NBREG,	RESC1,
670       		"	addu A1,AL,AR	# 64-bit addition\n"
671       		"	sltu A2,A1,AR\n"
672       		"	addu U1,UL,UR\n"
673       		"	addu U1,U1,A2\n", },
674 
675 { PLUS,	INAREG,
676 	SAREG,	TSWORD|TSHORT|TCHAR,
677 	SSCON,	TANY,
678 		NAREG|NASL,	RESC1,
679 		"	addi A1,AL,AR\n", },
680 
681 { PLUS,	INAREG,
682 	SAREG,	TUWORD|TPOINT|TUSHORT|TUCHAR,
683 	SSCON,	TANY,
684 		NAREG|NASL,	RESC1,
685 		"	addiu A1,AL,AR\n", },
686 
687 { PLUS,	INAREG,
688 	SAREG,	TUWORD|TPOINT|TUSHORT|TUCHAR,
689 	SAREG,	TUWORD|TUSHORT|TUCHAR,
690 		NAREG|NASL,	RESC1,
691       		"	addu A1,AL,AR\n", },
692 
693 { PLUS,	INAREG,
694 	SAREG,	TSWORD|TSHORT|TCHAR,
695 	SAREG,	TSWORD|TSHORT|TCHAR,
696 		NAREG|NASL,	RESC1,
697       		"	add A1,AL,AR\n", },
698 
699 { PLUS,	INCREG,
700 	SCREG,	TFLOAT,
701 	SCREG,	TFLOAT,
702 		NCREG|NCSL,	RESC1,
703 		"	add.s A1,AL,AR\n", },
704 
705 { PLUS,	INCREG,
706 	SCREG,	TDOUBLE|TLDOUBLE,
707 	SCREG,	TDOUBLE|TLDOUBLE,
708 		NCREG|NCSL,	RESC1,
709 		"	add.d A1,AL,AR\n", },
710 
711 { MINUS,	INBREG,
712 	SBREG,	TLONGLONG|TULONGLONG,
713 	SBREG,	TLONGLONG|TULONGLONG,
714 		2*NBREG,	RESC1,
715       		"	sltu A2,AL,AR	# 64-bit subtraction\n"
716       		"	subu A1,AL,AR\n"
717       		"	subu U1,UL,UR\n"
718       		"	subu U1,U1,A2\n", },
719 
720 { MINUS,	INAREG,
721 	SAREG,	TUWORD|TPOINT|TUSHORT|TUCHAR,
722 	SSCON,	TANY,
723 		NAREG|NASL,	RESC1,
724 		"	subu A1,AL,AR\n", },
725 
726 { MINUS,	INAREG,
727 	SAREG,	TSWORD|TSHORT|TCHAR,
728 	SSCON,	TANY,
729 		NAREG|NASL,	RESC1,
730 		"	sub A1,AL,AR\n", },
731 
732 { MINUS,	INAREG,
733 	SAREG,	TSWORD|TSHORT|TCHAR,
734 	SAREG,	TSWORD|TSHORT|TCHAR,
735 		NAREG|NASL,	RESC1,
736       		"	sub A1,AL,AR\n", },
737 
738 { MINUS,	INCREG,
739 	SCREG,	TFLOAT,
740 	SCREG,	TFLOAT,
741 		NCREG|NCSL,	RESC1,
742 		"	sub.s A1,AL,AR\n", },
743 
744 { MINUS,	INCREG,
745 	SCREG,	TDOUBLE|TLDOUBLE,
746 	SCREG,	TDOUBLE|TLDOUBLE,
747 		NCREG|NCSL,	RESC1,
748 		"	sub.d A1,AL,AR\n", },
749 
750 { UMINUS,	INAREG,
751 	SAREG,	TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
752 	SANY,	TANY,
753 		NAREG|NASL,	RESC1,
754 		"	neg A1,AL\n", },
755 
756 { UMINUS,	INBREG,
757 	SBREG,	TLONGLONG|TULONGLONG,
758 	SANY,	TANY,
759 		NBREG|NAREG|NBSL,	RESC2,
760 		"	subu A1,$zero,AL\n"
761 		"	subu U1,$zero,UL\n"
762 		"	sltu A2,$zero,A1\n"
763 		"	subu U1,U1,A2\n", },
764 
765 { UMINUS,	INCREG,
766 	SCREG,	TFLOAT,
767 	SCREG,	TFLOAT,
768 		NCREG|NCSL,	RESC1,
769 		"	neg.s A1,AL\n", },
770 
771 { UMINUS,	INCREG,
772 	SCREG,	TDOUBLE|TLDOUBLE,
773 	SCREG,	TDOUBLE|TLDOUBLE,
774 		NCREG|NCSL,	RESC1,
775 		"	neg.d A1,AL\n", },
776 
777 /* Simple 'op rd, rs, rt' or 'op rt, rs, imm' operations */
778 
779 { OPSIMP,	INBREG,
780 	SBREG,	TLONGLONG|TULONGLONG,
781 	SBREG,	TLONGLONG|TULONGLONG,
782 		NBREG|NBSR|NBSL,	RESC1,
783       		"	O A1,AL,AR\n"
784       		"	O U1,UL,UR\n", },
785 
786 { OPSIMP,	INAREG,
787 	SAREG,	TWORD|TPOINT|TSHORT|TUSHORT|TUCHAR|TCHAR,
788 	SAREG,	TWORD|TPOINT|TSHORT|TUSHORT|TUCHAR|TCHAR,
789 		NAREG|NASR|NASL,	RESC1,
790 		"	O A1,AL,AR\n", },
791 
792 { OPSIMP,	INAREG,
793 	SAREG,	TWORD|TPOINT|TSHORT|TUSHORT|TUCHAR|TCHAR,
794 	SPCON,	TANY,
795 		NAREG|NASL,	RESC1,
796 		"	Oi A1,AL,AR\n", },
797 
798 /*
799  * Shift instructions
800  */
801 
802 { RS,	INAREG,
803 	SAREG,	TSWORD|TSHORT|TCHAR,
804 	SCON,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
805 		NAREG|NASL,	RESC1,
806 		"	sra A1,AL,AR	# shift right by constant\n", },
807 
808 { RS,	INAREG,
809 	SAREG,	TUWORD|TUSHORT|TUCHAR,
810 	SCON,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
811 		NAREG|NASL,	RESC1,
812 		"	srl A1,AL,AR	# shift right by constant\n", },
813 
814 { LS,	INAREG,
815 	SAREG,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
816 	SCON,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
817 		NAREG|NASL,	RESC1,
818 		"	sll A1,AL,AR	# shift left by constant\n", },
819 
820 { RS,	INAREG,
821 	SAREG,	TSWORD|TSHORT|TCHAR,
822 	SAREG,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
823 		NAREG|NASL,	RESC1,
824 		"	srav A1,AL,AR	# shift right by register\n", },
825 
826 { RS,	INAREG,
827 	SAREG,	TUWORD|TUSHORT|TUCHAR,
828 	SAREG,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
829 		NAREG|NASL,	RESC1,
830 		"	srlv A1,AL,AR	# shift right by register\n", },
831 
832 { LS,	INAREG,
833 	SAREG,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
834 	SAREG,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
835 		NAREG|NASL,	RESC1,
836 		"	sllv A1,AL,AR	# shift left by register\n", },
837 
838 { RS,	INBREG,
839 	SBREG,	TLONGLONG|TULONGLONG,
840 	SCON,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
841 		NBREG,	RESC1,
842 		"ZO", },
843 
844 { LS,	INBREG,
845 	SBREG,	TLONGLONG|TULONGLONG,
846 	SCON,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
847 		NBREG,	RESC1,
848 		"ZO", },
849 
850 { RS,	INBREG,
851 	SBREG,	TLONGLONG|TULONGLONG,
852 	SAREG,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
853 		NSPECIAL|NBREG,	RESC1,
854 		"ZE", },
855 
856 { LS,	INBREG,
857 	SBREG,	TLONGLONG|TULONGLONG,
858 	SAREG,	TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
859 		NSPECIAL|NBREG,	RESC1,
860 		"ZE", },
861 
862 /*
863  * Rule for unary one's complement
864  */
865 
866 { COMPL,        INAREG,
867         SAREG,  TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
868         SANY,   TANY,
869                 NAREG|NASL,   RESC1,
870                 "	nor A1,$zero,AL	# complement\n", },
871 
872 { COMPL,        INBREG,
873 	SBREG,	TLONGLONG|TULONGLONG,
874         SANY,   TANY,
875                 NBREG|NBSL,   RESC1,
876                 "	nor A1,$zero,AL	# complement\n"
877                 "	nor U1,$zero,UL\n", },
878 
879 /*
880  * The next rules takes care of assignments. "=".
881  */
882 
883 { ASSIGN,	FOREFF|INAREG,
884 	SOREG|SNAME,	TWORD|TPOINT,
885 	SAREG,		TWORD|TPOINT,
886 		0,	RDEST,
887 		"	sw AR,AL		# store (u)int/(u)long\n"
888 		"	nop\n", },
889 
890 { ASSIGN,	FOREFF|INAREG,
891 	SOREG|SNAME,	TSHORT|TUSHORT,
892 	SAREG,		TSHORT|TUSHORT,
893 		0,	RDEST,
894         	"	sh AR,AL		# store (u)short\n"
895 		"	nop\n", },
896 
897 { ASSIGN,	FOREFF|INAREG,
898 	SOREG|SNAME,	TCHAR|TUCHAR,
899 	SAREG,		TCHAR|TUCHAR,
900 		0,	RDEST,
901         	"	sb AR,AL		# store (u)char\n"
902 		"	nop\n", },
903 
904 { ASSIGN,	FOREFF|INBREG,
905 	SOREG|SNAME,	TLONGLONG|TULONGLONG,
906 	SBREG,		TLONGLONG|TULONGLONG,
907 		0,	RDEST,
908       		"	sw UR,UL		# store (u)longlong\n"
909 		"	nop\n"
910       		"	sw AR,AL\n"
911 		"	nop\n", },
912 
913 { ASSIGN,	FOREFF|INBREG,
914 	SBREG,		TLONGLONG|TULONGLONG,
915 	SBREG,		TLONGLONG|TULONGLONG,
916 		0,	RDEST,
917       		"	move UL,UR		# register move\n"
918       		"	move AL,AR\n", },
919 
920 { ASSIGN,	FOREFF|INAREG,
921 	SAREG,	TANY,
922 	SAREG,	TANY,
923 		0,	RDEST,
924         	"	move AL,AR		# register move\n", },
925 
926 { ASSIGN,	FOREFF|INCREG,
927 	SCREG,	TFLOAT,
928 	SCREG,	TFLOAT,
929 		0,	RDEST,
930         	"	mov.s AL,AR		# register move\n", },
931 
932 { ASSIGN,	FOREFF|INCREG,
933 	SCREG,	TDOUBLE|TLDOUBLE,
934 	SCREG,	TDOUBLE|TLDOUBLE,
935 		0,	RDEST,
936         	"	mov.d AL,AR		# register move\n", },
937 
938 { ASSIGN,	FOREFF|INCREG,
939 	SNAME|SOREG,	TFLOAT,
940 	SCREG,		TFLOAT,
941 		0,	RDEST,
942 		"	s.s AR,AL		# store floating-point reg to oreg/sname\n"
943 		"	nop\n", },
944 
945 { ASSIGN,	FOREFF|INCREG,
946 	SNAME|SOREG,	TDOUBLE|TLDOUBLE,
947 	SCREG,		TDOUBLE|TLDOUBLE,
948 		0,	RDEST,
949 		"	s.d AR,AL		# store double floating-point reg to oreg/sname\n"
950 		"	nop\n", },
951 
952 { ASSIGN,	FOREFF|INAREG,
953 	SFLD,		TANY,
954 	SOREG|SNAME,	TANY,
955 		3*NAREG,	RDEST,
956 		"	lw A1,AR		# bit-field assignment\n"
957 		"	li A3,M\n"
958 		"	lw A2,AL\n"
959 		"	sll A1,A1,H\n"
960 		"	and A1,A1,A3\n"
961 		"	nor A3,$zero,A3\n"
962 		"	and A2,A2,A3\n"
963 		"	or A2,A2,A1\n"
964 		"	sw A2,AL\n"
965 		"F	lw AD,AR\n"
966 		"F	nop\n"
967 		"F	sll AD,AD,32-S\n"
968 		"F	sra AD,AD,32-S\n", },
969 
970 /* XXX we can optimise this away */
971 { ASSIGN,	FOREFF|INAREG,
972 	SFLD,		TANY,
973 	SCON,		TANY,
974 		3*NAREG,	RDEST,
975 		"	li A1,AR		# bit-field assignment\n"
976 		"	lw A2,AL\n"
977 		"	li A3,M\n"
978 		"	sll A1,A1,H\n"
979 		"	and A1,A1,A3\n"
980 		"	nor A3,$zero,A3\n"
981 		"	and A2,A2,A3\n"
982 		"	or A2,A2,A1\n"
983 		"	sw A2,AL\n"
984 		"F	li AD,AR\n"
985 		"F	sll AD,AD,32-S\n"
986 		"F	sra AD,AD,32-S\n", },
987 
988 { ASSIGN,	FOREFF|INAREG,
989 	SFLD,		TANY,
990 	SAREG,		TANY,
991 		3*NAREG,	RDEST,
992 		"	move A1,AR		# bit-field assignment\n"
993 		"	lw A2,AL\n"
994 		"	li A3,M\n"
995 		"	sll A1,A1,H\n"
996 		"	and A1,A1,A3\n"
997 		"	nor A3,$zero,A3\n"
998 		"	and A2,A2,A3\n"
999 		"	or A2,A2,A1\n"
1000 		"	sw A2,AL\n"
1001 		"F	move AR,AD\n"
1002 		"F	sll AD,AD,32-S\n"
1003 		"F	sra AD,AD,32-S\n", },
1004 
1005 { STASG,        INAREG|FOREFF,
1006         SOREG|SNAME,	TANY,
1007         SAREG,  	TPTRTO|TANY,
1008                 NSPECIAL,       RRIGHT,
1009                 "ZQ", },
1010 
1011 /*
1012  * Compare instructions
1013  */
1014 
1015 { EQ,	FORCC,
1016         SAREG,		TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
1017         SAREG,		TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
1018                 0,      RESCC,
1019                 "	beq AL,AR,LC\n"
1020 		"	nop\n", },
1021 
1022 { NE,	FORCC,
1023         SAREG,		TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
1024         SAREG,		TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
1025                 0,      RESCC,
1026                 "	bne AL,AR,LC\n"
1027 		"	nop\n", },
1028 
1029 { OPLOG,	FORCC,
1030         SAREG,		TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
1031         SZERO,		TANY,
1032                 0,      RESCC,
1033                 "	O AL,LC\n"
1034 		"	nop\n", },
1035 
1036 { OPLOG,	FORCC,
1037         SAREG,		TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
1038         SAREG,		TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
1039                 NAREG|NASL,     RESCC,
1040 		"	sub A1,AL,AR\n"
1041                 "	O A1,LC\n"
1042 		"	nop\n", },
1043 
1044 { OPLOG,	FORCC,
1045         SAREG,		TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
1046         SSCON,		TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
1047                 NAREG|NASL,     RESCC,
1048 		"	sub A1,AL,AR\n"
1049                 "	O A1,LC\n"
1050 		"	nop\n", },
1051 
1052 { OPLOG,	FORCC,
1053 	SBREG,		TLONGLONG|TULONGLONG,
1054 	SBREG,		TLONGLONG|TULONGLONG,
1055 		NAREG,	RESCC,
1056 		"ZD", },
1057 
1058 { OPLOG,	FORCC,
1059 	SCREG,	TFLOAT|TDOUBLE|TLDOUBLE,
1060 	SCREG,	TFLOAT|TDOUBLE|TLDOUBLE,
1061 		0,	RESCC,
1062 		"ZG", },
1063 
1064 /*
1065  * Convert LTYPE to reg.
1066  */
1067 
1068 { OPLTYPE,	INAREG,
1069 	SANY,		TANY,
1070 	SOREG|SNAME,	TCHAR,
1071 		NAREG,	RESC1,
1072 		"	lb A1,AL	# load char to reg\n"
1073 		"	nop\n", },
1074 
1075 { OPLTYPE,	INAREG,
1076 	SANY,		TANY,
1077 	SOREG|SNAME,	TUCHAR,
1078 		NAREG,	RESC1,
1079 		"	lbu A1,AL	# load uchar to reg\n"
1080 		"	nop\n", },
1081 
1082 { OPLTYPE,	INAREG,
1083 	SANY,		TANY,
1084 	SOREG|SNAME,	TSHORT,
1085 		NAREG,	RESC1,
1086 		"	lh A1,AL	# load short to reg\n"
1087 		"	nop\n", },
1088 
1089 { OPLTYPE,	INAREG,
1090 	SANY,		TANY,
1091 	SOREG|SNAME,	TUSHORT,
1092 		NAREG,	RESC1,
1093 		"	lhu A1,AL	# load ushort to reg\n"
1094 		"	nop\n", },
1095 
1096 { OPLTYPE,	INAREG,
1097 	SANY,		TANY,
1098 	SOREG|SNAME,	TWORD|TPOINT,
1099 		NAREG,	RESC1,
1100 		"	lw A1,AL	# load (u)int/(u)long to reg\n"
1101 		"	nop\n", },
1102 
1103 { OPLTYPE,	INBREG,
1104 	SANY,		TANY,
1105 	SOREG|SNAME,	TLONGLONG|TULONGLONG,
1106 		NBREG,	RESC1,
1107 		"	lw U1,UL	# load (u)longlong to reg\n"
1108 		"	nop\n"
1109 		"	lw A1,AL\n"
1110       		"	nop\n", },
1111 
1112 { OPLTYPE,	INAREG,
1113 	SANY,	TANY,
1114 	SCON,	TPOINT,
1115 		NAREG,	RESC1,
1116 		"	la A1,AL	# load constant address to reg\n", },
1117 
1118 { OPLTYPE,	INAREG,
1119 	SANY,	TANY,
1120 	SZERO,	TANY,
1121 		NAREG,	RESC1,
1122 		"	move A1,$zero	# load 0 to reg\n", },
1123 
1124 { OPLTYPE,	INAREG,
1125 	SANY,	TANY,
1126 	SCON,	TANY,
1127 		NAREG,	RESC1,
1128 		"	li A1,AL	# load constant to reg\n", },
1129 
1130 { OPLTYPE,	INBREG,
1131 	SANY,	TANY,
1132 	SZERO,	TANY,
1133 		NBREG,	RESC1,
1134 		"	move A1,$zero	# load 0 to reg\n"
1135 		"	move U1,$zero\n", },
1136 
1137 { OPLTYPE,	INBREG,
1138 	SANY,	TANY,
1139 	SCON,	TANY,
1140 		NBREG,	RESC1,
1141 		"	li A1,AL	# load constant to reg\n"
1142 		"	li U1,UL\n", },
1143 
1144 { OPLTYPE,	INAREG,
1145 	SANY,	TANY,
1146 	SANY,	TANY,
1147 		NAREG,	RESC1,
1148 		"	move A1,AL\n", },
1149 
1150 { OPLTYPE,	INCREG,
1151 	SANY,	TANY,
1152 	SZERO,	TFLOAT,
1153 		NCREG,	RESC1,
1154 		"	mtc1 $zero,A1	# load 0 to float reg\n"
1155 		"	nop\n", },
1156 
1157 { OPLTYPE,	INCREG,
1158 	SANY,	TANY,
1159 	SZERO,	TDOUBLE|TLDOUBLE,
1160 		NCREG,	RESC1,
1161 		"	mtc1 $zero,A1	# load 0 to (l)double reg\n"
1162 		"	mtc1 $zero,U1\n"
1163 		"	nop\n", },
1164 
1165 { OPLTYPE,	INCREG,
1166 	SANY,	TANY,
1167 	SOREG|SNAME,	TFLOAT,
1168 		NCREG,	RESC1,
1169 		"	l.s A1,AL	# load into floating-point reg\n"
1170 		"	nop\n", },
1171 
1172 { OPLTYPE,	INCREG,
1173 	SANY,	TANY,
1174 	OREG|SNAME,	TDOUBLE|TLDOUBLE,
1175 		NCREG,	RESC1,
1176 		"	l.d A1,AL	# load into double floating-point reg\n"
1177 		"	nop\n", },
1178 
1179 /*
1180  * Jumps.
1181  */
1182 { GOTO, 	FOREFF,
1183 	SCON,	TANY,
1184 	SANY,	TANY,
1185 		0,	RNOP,
1186 		"	j LL		# goto label\n"
1187 		"	nop\n"
1188 		"	nop\n", },
1189 
1190 /*
1191  * Subroutine calls.
1192  */
1193 
1194 { CALL,         FOREFF,
1195         SCON,		TANY,
1196         SANY,           TANY,
1197                 0,      0,
1198                 "	subu $sp,$sp,16	# call (args, no result) to scon/sname\n"
1199                 "	jal CL\n"
1200 		"	nop\n"
1201 		"ZC", },
1202 
1203 { UCALL,        FOREFF,
1204         SCON,		TANY,
1205         SANY,           TANY,
1206                 0,      0,
1207                 "	jal CL			# call (no args, no result) to scon/sname\n"
1208 		"	nop\n", },
1209 
1210 { CALL,         INAREG,
1211         SCON,		TANY,
1212         SAREG,          TANY,
1213                 NAREG,     RESC1,  /* should be 0 */
1214                 "	subu $sp,$sp,16	# call (args, result in v0) to scon/sname\n"
1215 		"	jal CL\n"
1216 		"	nop\n"
1217 		"ZC", },
1218 
1219 { UCALL,        INAREG,
1220         SCON,		TANY,
1221         SAREG,          TANY,
1222                 NAREG,     RESC1,  /* should be 0 */
1223                 "	jal CL   # call (no args, result in v0) to scon/sname\n"
1224 		"	nop\n",
1225  },
1226 
1227 { CALL,         INBREG,
1228         SCON,		TANY,
1229         SBREG,          TANY,
1230                 NBREG,     RESC1,  /* should be 0 */
1231                 "	subu $sp,$sp,16	# call (args, result in v0:v1) to scon/sname\n"
1232 		"	jal CL\n"
1233 		"	nop\n"
1234 		"ZC", },
1235 
1236 { UCALL,        INBREG,
1237         SCON,		TANY,
1238         SBREG,          TANY,
1239                 NBREG,     RESC1,  /* should be 0 */
1240                 "	jal CL   # call (no args, result in v0:v1) to scon/sname\n"
1241 		"	nop\n",
1242  },
1243 
1244 { CALL,         INCREG,
1245         SCON,		TANY,
1246         SCREG,          TANY,
1247                 NCREG,     RESC1,  /* should be 0 */
1248                 "	subu $sp,$sp,16	# call (args, result in f0:f1) to scon/sname\n"
1249 		"	jal CL\n"
1250 		"	nop\n"
1251 		"ZC", },
1252 
1253 { UCALL,        INCREG,
1254         SCON,		TANY,
1255         SCREG,          TANY,
1256                 NCREG,     RESC1,  /* should be 0 */
1257                 "	jal CL   # call (no args, result in v0:v1) to scon/sname\n"
1258 		"	nop\n",
1259  },
1260 
1261 { CALL,         FOREFF,
1262         SAREG,		TANY,
1263         SANY,		TANY,
1264                 0,      0,
1265                 "	subu $sp,$sp,16	# call (args, no result) to reg\n"
1266 		"	move $25,AL\n"
1267                 "	jal $25\n"
1268 		"	nop\n"
1269 		"ZC", },
1270 
1271 { UCALL,        FOREFF,
1272         SAREG,		TANY,
1273         SANY,		TANY,
1274                 0,      0,
1275 		"	move $25,AL\n"
1276                 "	jal $25			# call (no args, no result) to reg\n"
1277 		"	nop\n", },
1278 
1279 { CALL,         INAREG,
1280         SAREG,		TANY,
1281         SAREG,		TANY,
1282                 NAREG,     RESC1,  /* should be 0 */
1283                 "	subu $sp,$sp,16	# call (args, result) to reg\n"
1284 		"	move $25,AL\n"
1285                 "	jal $25\n"
1286 		"	nop\n"
1287 		"ZC", },
1288 
1289 { UCALL,        INAREG,
1290         SAREG,		TANY,
1291         SAREG,		TANY,
1292                 NAREG,     RESC1,  /* should be 0 */
1293 		"	move $25,AL\n"
1294                 "	jal $25		# call (no args, result) to reg\n"
1295 		"	nop\n", },
1296 
1297 { CALL,         INBREG,
1298         SAREG,		TANY,
1299         SBREG,		TANY,
1300                 NBREG,     RESC1,  /* should be 0 */
1301                 "	subu $sp,$sp,16	# call (args, result) to reg\n"
1302 		"	move $25,AL\n"
1303                 "	jal $25\n"
1304 		"	nop\n"
1305 		"ZC", },
1306 
1307 { UCALL,        INBREG,
1308         SAREG,		TANY,
1309         SBREG,		TANY,
1310                 NBREG,     RESC1,  /* should be 0 */
1311 		"	move $25,AL\n"
1312                 "	jal $25			# call (no args, result) to reg\n"
1313 		"	nop\n", },
1314 
1315 { CALL,         INCREG,
1316         SAREG,		TANY,
1317         SCREG,		TANY,
1318                 NCREG,     RESC1,  /* should be 0 */
1319                 "	subu $sp,$sp,16	# call (args, result) to reg\n"
1320 		"	move $25,AL\n"
1321                 "	jal $25\n"
1322 		"	nop\n"
1323 		"ZC", },
1324 
1325 { UCALL,        INCREG,
1326         SCREG,		TANY,
1327         SCREG,		TANY,
1328                 NCREG,     RESC1,  /* should be 0 */
1329 		"	move $25,AL\n"
1330                 "	jal $25			# call (no args, result) to reg\n"
1331 		"	nop\n", },
1332 
1333 
1334 /* struct return */
1335 { USTCALL,      FOREFF,
1336 	SCON|SNAME,	TANY,
1337 	SANY,   	TANY,
1338 		0,	0,
1339 		"	jal CL\n"
1340 		"	nop\n", },
1341 
1342 { USTCALL,      FOREFF,
1343 	SAREG,		TANY,
1344 	SANY,   	TANY,
1345 		0,	0,
1346 		"	move $25,AL\n"
1347                 "	jal $25\n"
1348 		"	nop\n", },
1349 
1350 { USTCALL,      INAREG,
1351 	SCON|SNAME,	TANY,
1352 	SANY,   	TANY,
1353 		NAREG|NASL,	RESC1,
1354 		"	jal CL\n"
1355 		"	nop\n", },
1356 
1357 { USTCALL,      INAREG,
1358 	SAREG,		TANY,
1359 	SANY,   	TANY,
1360 		NAREG|NASL,	RESC1,
1361 		"	move $25,AL\n"
1362                 "	jal $25\n"
1363 		"	nop\n", },
1364 
1365 { STCALL,      FOREFF,
1366 	SCON|SNAME,	TANY,
1367 	SANY,   	TANY,
1368 		0,	0,
1369                 "	subu $sp,$sp,16\n"
1370 		"	jal CL\n"
1371 		"	nop\n"
1372 		"ZC", },
1373 
1374 { STCALL,      FOREFF,
1375 	SAREG,	TANY,
1376 	SANY,   	TANY,
1377 		0,	0,
1378                 "	subu $sp,$sp,16\n"
1379 		"	move $25,AL\n"
1380                 "	jal $25\n"
1381 		"	nop\n"
1382 		"ZC", },
1383 
1384 { STCALL,      INAREG,
1385 	SCON|SNAME,	TANY,
1386 	SANY,   	TANY,
1387 		NAREG|NASL,	RESC1,
1388                 "	subu $sp,$sp,16\n"
1389 		"	jal CL\n"
1390 		"	nop\n"
1391 		"ZC", },
1392 
1393 { STCALL,      INAREG,
1394 	SAREG,	TANY,
1395 	SANY,   	TANY,
1396 		0,	0,
1397                 "	subu $sp,$sp,16\n"
1398 		"	move $25,AL\n"
1399                 "	jal $25\n"
1400 		"	nop\n"
1401 		"ZC", },
1402 
1403 
1404 /*
1405  *  Function arguments
1406  */
1407 
1408 #if 0
1409 
1410 /* intentionally write out the register for (u)short/(u)char */
1411 { FUNARG,       FOREFF,
1412         SAREG,  TWORD|TPOINT|TUSHORT|TSHORT|TUCHAR|TCHAR,
1413         SANY,   TWORD|TPOINT|TUSHORT|TSHORT|TUCHAR|TCHAR,
1414                 0,      0,
1415                 "	subu $sp,$sp,4		# save function arg to stack\n"
1416 		"	sw AL,($sp)\n"
1417 		"	#nop\n", },
1418 
1419 { FUNARG,	FOREFF,
1420 	SBREG,	TLONGLONG|TULONGLONG,
1421 	SANY,	TLONGLONG|TULONGLONG,
1422 		0,	0,
1423 		"	addi $sp,$sp,-8		# save function arg to stack (endian problem here?\n"
1424 		"	sw UL,4($sp)\n"
1425 		"	sw AL,($sp)\n"
1426 		"	#nop\n", },
1427 
1428 { FUNARG,	FOREFF,
1429 	SCREG,	TFLOAT,
1430 	SANY,	TFLOAT,
1431 		0,	0,
1432 		"	addi $sp,$sp,-4		# save function arg to stack\n"
1433 		"	s.s AL,($sp)\n"
1434 		"	#nop\n", },
1435 
1436 { FUNARG,	FOREFF,
1437 	SCREG,	TDOUBLE|TLDOUBLE,
1438 	SANY,	TDOUBLE|TLDOUBLE,
1439 		0,	0,
1440 		"	addi $sp,$sp,-8		# save function arg to stack\n"
1441 		"	s.d AL,($sp)\n"
1442 		"	#nop\n", },
1443 
1444 #endif
1445 
1446 { STARG,	FOREFF,
1447 	SAREG,		TANY,
1448 	SANY,		TSTRUCT,
1449 		NSPECIAL,	0,
1450 		"ZH", },
1451 
1452 /*
1453  * Indirection operators.
1454  */
1455 { UMUL, INAREG,
1456 	SANY,	TPOINT|TWORD,
1457 	SOREG,	TPOINT|TWORD,
1458     		NAREG,     RESC1,
1459         	"	lw A1,AL		# word load\n"
1460 		"	nop\n", },
1461 
1462 { UMUL, INAREG,
1463 	SANY,	TSHORT|TUSHORT,
1464 	SOREG,	TSHORT|TUSHORT,
1465     		NAREG,     RESC1,
1466         	"	lh A1,AL		# (u)short load\n"
1467 		"	nop\n", },
1468 
1469 { UMUL, INAREG,
1470 	SANY,	TCHAR|TUCHAR,
1471 	SOREG,	TCHAR|TUCHAR,
1472     		NAREG,     RESC1,
1473         	"	lb A1,AL		# (u)char load\n"
1474 		"	nop\n", },
1475 
1476 { UMUL,	INBREG,
1477 	SANY,	TLONGLONG|TULONGLONG,
1478 	SOREG,	TLONGLONG|TULONGLONG,
1479 		NBREG,	RESC1,
1480 		"	lw A1,AL		# (u)longlong load - endian problem here?\n"
1481 		"	nop\n"
1482 		"	lw U1,UL\n"
1483 		"	nop\n", },
1484 
1485 { UMUL,	INCREG,
1486 	SANY,	TFLOAT,
1487 	SOREG,	TFLOAT,
1488 		NCREG,	RESC1,
1489 		"	l.s A1,AL		# float load\n"
1490 		"	nop\n", },
1491 
1492 { UMUL,	INCREG,
1493 	SANY,	TDOUBLE|TLDOUBLE,
1494 	SOREG,	TDOUBLE|TLDOUBLE,
1495 		NCREG,	RESC1,
1496 		"	l.d A1,AL		# float load\n"
1497 		"	nop\n", },
1498 
1499 #if 0
1500 { UMUL,	INCREG,
1501 	SANY,	TDOUBLE|TLDOUBLE,
1502 	SAREG,	TPOINT,
1503 		NCREG,	RESC1,
1504 		"	l.d A1,(AL)\n"
1505 		"	nop\n", },
1506 
1507 { UMUL, INAREG,
1508 	SANY,	TPOINT|TWORD,
1509 	SNAME,	TPOINT|TWORD,
1510     		NAREG,     RESC1,
1511         	"	la A1,AL		# sname word load\n"
1512 		"	lw A1,(A1)\n"
1513 		"	nop\n", },
1514 
1515 { UMUL, INAREG,
1516 	SANY,	TSHORT|TUSHORT,
1517 	SNAME,	TSHORT|TUSHORT,
1518     		NAREG,     RESC1,
1519         	"	la A1,AL		# sname (u)short load\n"
1520 		"	lh A1,(A1)\n"
1521 		"	nop\n", },
1522 
1523 { UMUL, INAREG,
1524 	SANY,	TCHAR|TUCHAR,
1525 	SNAME,	TCHAR|TUCHAR,
1526     		NAREG,     RESC1,
1527         	"	la A1,AL		# sname (u)char load\n"
1528 		"	lb A1,(A1)\n"
1529 		"	nop\n", },
1530 
1531 { UMUL, INBREG,
1532 	SANY,	TLONGLONG|TULONGLONG,
1533 	SNAME,	TLONGLONG|TULONGLONG,
1534 		NBREG|NAREG,	RESC1,
1535 		"	la A2,AL		# sname (u)long long load - endian problems here?\n"
1536 		"	lw A1,(A1)\n"
1537 		"	nop\n"
1538 		"	lw U1,4(A1)\n"
1539 		"	nop\n", },
1540 #endif
1541 
1542 { UMUL, INAREG,
1543 	SANY,	TPOINT|TWORD,
1544 	SAREG,	TPOINT|TWORD,
1545     		NAREG,     RESC1,
1546         	"	lw A1,(AL)		# word load\n"
1547 		"	nop\n", },
1548 
1549 #if 0
1550 { UMUL, INAREG,
1551 	SANY,	TSHORT|TUSHORT,
1552 	SAREG,	TPTRTO|TSHORT|TUSHORT,
1553     		NAREG,     RESC1,
1554         	"	lh A1,(AL)		# (u)short load\n"
1555 		"	nop\n", },
1556 
1557 { UMUL, INAREG,
1558 	SANY,	TCHAR|TUCHAR,
1559 	SAREG,	TPTRTO|TCHAR|TUCHAR,
1560     		NAREG|NASL,     RESC1,
1561         	"	lb A1,(AL)		# (u)char load\n"
1562 		"	nop\n", },
1563 
1564 { UMUL, INBREG,
1565 	SANY,	TLONGLONG|TULONGLONG,
1566 	SAREG,	TPTRTO|TLONGLONG|TULONGLONG,
1567 		NBREG,	RESC1,
1568 		"	lw A1,(AL)		# (u)long long load - endianness problems?\n"
1569 		"	nop\n"
1570 		"	lw U1,4(AL)"
1571 		"	nop\n", },
1572 #endif
1573 
1574 #define DF(x) FORREW,SANY,TANY,SANY,TANY,REWRITE,x,""
1575 
1576 { FLD, DF(FLD), },
1577 
1578 { FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	FREE,	"help; I'm in trouble\n" },
1579 };
1580 
1581 int tablesize = sizeof(table)/sizeof(table[0]);
1582