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