1 /* Id: table.c,v 1.137 2011/08/06 15:11:48 ragge Exp */ 2 /* $NetBSD: table.c,v 1.1.1.4 2011/09/01 12:46:36 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 # include "pass2.h" 32 33 # define TLL TLONGLONG|TULONGLONG 34 # define ANYSIGNED TINT|TLONG|TSHORT|TCHAR 35 # define ANYUSIGNED TUNSIGNED|TULONG|TUSHORT|TUCHAR 36 # define ANYFIXED ANYSIGNED|ANYUSIGNED 37 # define TUWORD TUNSIGNED|TULONG 38 # define TSWORD TINT|TLONG 39 # define TWORD TUWORD|TSWORD 40 #define SHINT SAREG /* short and int */ 41 #define ININT INAREG 42 #define SHCH SBREG /* shape for char */ 43 #define INCH INBREG 44 #define SHLL SCREG /* shape for long long */ 45 #define INLL INCREG 46 #define SHFL SDREG /* shape for float/double */ 47 #define INFL INDREG /* shape for float/double */ 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 "", }, 59 60 /* 61 * A bunch conversions of integral<->integral types 62 * There are lots of them, first in table conversions to itself 63 * and then conversions from each type to the others. 64 */ 65 66 /* itself to itself, including pointers */ 67 68 /* convert (u)char to (u)char. */ 69 { SCONV, INCH, 70 SHCH, TCHAR|TUCHAR, 71 SHCH, TCHAR|TUCHAR, 72 0, RLEFT, 73 "", }, 74 75 /* convert pointers to int. */ 76 { SCONV, ININT, 77 SHINT, TPOINT|TWORD, 78 SANY, TWORD, 79 0, RLEFT, 80 "", }, 81 82 /* convert (u)longlong to (u)longlong. */ 83 { SCONV, INLL, 84 SHLL, TLL, 85 SHLL, TLL, 86 0, RLEFT, 87 "", }, 88 89 /* convert between float/double/long double. */ 90 { SCONV, INFL, 91 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 92 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 93 0, RLEFT, 94 "ZI", }, 95 96 /* convert pointers to pointers. */ 97 { SCONV, ININT, 98 SHINT, TPOINT, 99 SANY, TPOINT, 100 0, RLEFT, 101 "", }, 102 103 /* char to something */ 104 105 /* convert char to (unsigned) short. */ 106 { SCONV, ININT, 107 SBREG|SOREG|SNAME, TCHAR, 108 SAREG, TSHORT|TUSHORT, 109 NASL|NAREG, RESC1, 110 " movsbw AL,A1\n", }, 111 112 /* convert unsigned char to (u)short. */ 113 { SCONV, ININT, 114 SHCH|SOREG|SNAME, TUCHAR, 115 SAREG, TSHORT|TUSHORT, 116 NASL|NAREG, RESC1, 117 " movzbw AL,A1\n", }, 118 119 /* convert signed char to int (or pointer). */ 120 { SCONV, ININT, 121 SHCH|SOREG|SNAME, TCHAR, 122 SAREG, TWORD|TPOINT, 123 NASL|NAREG, RESC1, 124 " movsbl AL,A1\n", }, 125 126 /* convert unsigned char to (u)int. */ 127 { SCONV, ININT, 128 SHCH|SOREG|SNAME, TUCHAR, 129 SAREG, TWORD, 130 NASL|NAREG, RESC1, 131 " movzbl AL,A1\n", }, 132 133 /* convert char to (u)long long */ 134 { SCONV, INLL, 135 SHCH|SOREG|SNAME, TCHAR, 136 SANY, TLL, 137 NSPECIAL|NCREG|NCSL, RESC1, 138 " movsbl AL,%eax\n cltd\n", }, 139 140 /* convert unsigned char to (u)long long */ 141 { SCONV, INLL, 142 SHCH|SOREG|SNAME, TUCHAR, 143 SANY, TLL, 144 NCREG|NCSL, RESC1, 145 " movzbl AL,A1\n xorl U1,U1\n", }, 146 147 /* convert char (in register) to double XXX - use NTEMP */ 148 { SCONV, INFL, 149 SHCH|SOREG|SNAME, TCHAR, 150 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 151 NAREG|NASL|NDREG, RESC2, 152 " movsbl AL,A1\n pushl A1\n" 153 " fildl (%esp)\n addl $4,%esp\n", }, 154 155 /* convert (u)char (in register) to double XXX - use NTEMP */ 156 { SCONV, INFL, 157 SHCH|SOREG|SNAME, TUCHAR, 158 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 159 NAREG|NASL|NDREG, RESC2, 160 " movzbl AL,A1\n pushl A1\n" 161 " fildl (%esp)\n addl $4,%esp\n", }, 162 163 /* short to something */ 164 165 /* convert (u)short to (u)short. */ 166 { SCONV, INAREG, 167 SAREG, TSHORT|TUSHORT, 168 SAREG, TSHORT|TUSHORT, 169 0, RLEFT, 170 "", }, 171 172 /* convert short (in memory) to char */ 173 { SCONV, INCH, 174 SNAME|SOREG, TSHORT|TUSHORT, 175 SHCH, TCHAR|TUCHAR, 176 NBREG|NBSL, RESC1, 177 " movb AL,A1\n", }, 178 179 /* convert short (in reg) to char. */ 180 { SCONV, INCH, 181 SAREG|SNAME|SOREG, TSHORT|TUSHORT, 182 SHCH, TCHAR|TUCHAR, 183 NSPECIAL|NBREG|NBSL, RESC1, 184 "ZM", }, 185 186 /* convert short to (u)int. */ 187 { SCONV, ININT, 188 SAREG|SOREG|SNAME, TSHORT, 189 SAREG, TWORD, 190 NASL|NAREG, RESC1, 191 " movswl AL,A1\n", }, 192 193 /* convert unsigned short to (u)int. */ 194 { SCONV, ININT, 195 SAREG|SOREG|SNAME, TUSHORT, 196 SAREG, TWORD, 197 NASL|NAREG, RESC1, 198 " movzwl AL,A1\n", }, 199 200 /* convert short to (u)long long */ 201 { SCONV, INLL, 202 SAREG|SOREG|SNAME, TSHORT, 203 SHLL, TLL, 204 NSPECIAL|NCREG|NCSL, RESC1, 205 " movswl AL,%eax\n cltd\n", }, 206 207 /* convert unsigned short to (u)long long */ 208 { SCONV, INLL, 209 SAREG|SOREG|SNAME, TUSHORT, 210 SHLL, TLL, 211 NCREG|NCSL, RESC1, 212 " movzwl AL,A1\n xorl U1,U1\n", }, 213 214 /* convert short (in memory) to float/double */ 215 { SCONV, INFL, 216 SOREG|SNAME, TSHORT, 217 SDREG, TLDOUBLE|TDOUBLE|TFLOAT, 218 NDREG, RESC1, 219 " fild AL\n", }, 220 221 /* convert short (in register) to float/double */ 222 { SCONV, INFL, 223 SAREG, TSHORT, 224 SDREG, TLDOUBLE|TDOUBLE|TFLOAT, 225 NTEMP|NDREG, RESC1, 226 " pushw AL\n fild (%esp)\n addl $2,%esp\n", }, 227 228 /* convert unsigned short to double XXX - use NTEMP */ 229 { SCONV, INFL, 230 SAREG|SOREG|SNAME, TUSHORT, 231 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 232 NAREG|NASL|NDREG|NTEMP, RESC2, 233 " movzwl AL,A1\n pushl A1\n" 234 " fildl (%esp)\n addl $4,%esp\n", }, 235 236 /* int to something */ 237 238 /* convert int to char. This is done when register is loaded */ 239 { SCONV, INCH, 240 SAREG, TWORD|TPOINT, 241 SANY, TCHAR|TUCHAR, 242 NSPECIAL|NBREG|NBSL, RESC1, 243 "ZM", }, 244 245 /* convert int to short. Nothing to do */ 246 { SCONV, INAREG, 247 SAREG, TWORD, 248 SANY, TSHORT|TUSHORT, 249 0, RLEFT, 250 "", }, 251 252 /* convert signed int to (u)long long */ 253 { SCONV, INLL, 254 SHINT, TSWORD, 255 SHLL, TLL, 256 NSPECIAL|NCREG|NCSL, RESC1, 257 " cltd\n", }, 258 259 /* convert unsigned int to (u)long long */ 260 { SCONV, INLL, 261 SHINT|SOREG|SNAME, TUWORD|TPOINT, 262 SHLL, TLL, 263 NCSL|NCREG, RESC1, 264 " movl AL,A1\n xorl U1,U1\n", }, 265 266 /* convert signed int (in memory) to double */ 267 { SCONV, INFL, 268 SOREG|SNAME, TSWORD, 269 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 270 NDREG, RESC1, 271 " fildl AL\n", }, 272 273 /* convert signed int (in register) to double */ 274 { SCONV, INFL, 275 SAREG, TSWORD, 276 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 277 NDREG, RESC1, 278 " pushl AL\n fildl (%esp)\n addl $4,%esp\n", }, 279 280 /* convert unsigned int (reg&mem) to double */ 281 { SCONV, INFL, 282 SOREG|SNAME|SAREG, TUWORD, 283 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 284 NDREG, RESC1, 285 " pushl $0\n" 286 " pushl AL\n" 287 " fildq (%esp)\n" 288 " addl $8,%esp\n", }, 289 290 /* long long to something */ 291 292 /* convert (u)long long to (u)char (mem->reg) */ 293 { SCONV, INCH, 294 SOREG|SNAME, TLL, 295 SANY, TCHAR|TUCHAR, 296 NBREG|NBSL, RESC1, 297 " movb AL,A1\n", }, 298 299 /* convert (u)long long to (u)char (reg->reg, hopefully nothing) */ 300 { SCONV, INCH, 301 SHLL, TLL, 302 SANY, TCHAR|TUCHAR, 303 NBREG|NBSL|NTEMP, RESC1, 304 "ZS", }, 305 306 /* convert (u)long long to (u)short (mem->reg) */ 307 { SCONV, INAREG, 308 SOREG|SNAME, TLL, 309 SAREG, TSHORT|TUSHORT, 310 NAREG|NASL, RESC1, 311 " movw AL,A1\n", }, 312 313 /* convert (u)long long to (u)short (reg->reg, hopefully nothing) */ 314 { SCONV, INAREG, 315 SHLL|SOREG|SNAME, TLL, 316 SAREG, TSHORT|TUSHORT, 317 NAREG|NASL|NTEMP, RESC1, 318 "ZS", }, 319 320 /* convert long long to int (mem->reg) */ 321 { SCONV, INAREG, 322 SOREG|SNAME, TLL, 323 SAREG, TWORD|TPOINT, 324 NAREG|NASL, RESC1, 325 " movl AL,A1\n", }, 326 327 /* convert long long to int (reg->reg, hopefully nothing) */ 328 { SCONV, INAREG, 329 SHLL|SOREG|SNAME, TLL, 330 SAREG, TWORD|TPOINT, 331 NAREG|NASL|NTEMP, RESC1, 332 "ZS", }, 333 334 /* convert long long (in memory) to floating */ 335 { SCONV, INFL, 336 SOREG|SNAME, TLONGLONG, 337 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 338 NDREG, RESC1, 339 " fildq AL\n", }, 340 341 /* convert long long (in register) to floating */ 342 { SCONV, INFL, 343 SHLL, TLONGLONG, 344 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 345 NTEMP|NDREG, RESC1, 346 " pushl UL\n pushl AL\n" 347 " fildq (%esp)\n addl $8,%esp\n", }, 348 349 /* convert unsigned long long to floating */ 350 { SCONV, INFL, 351 SCREG, TULONGLONG, 352 SDREG, TLDOUBLE|TDOUBLE|TFLOAT, 353 NDREG, RESC1, 354 "ZJ", }, 355 356 /* float to something */ 357 358 #if 0 /* go via int by adding an extra sconv in clocal() */ 359 /* convert float/double to (u) char. XXX should use NTEMP here */ 360 { SCONV, INCH, 361 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 362 SHCH, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR, 363 NBREG, RESC1, 364 " subl $4,%esp\n fistpl (%esp)\n popl A1\n", }, 365 366 /* convert float/double to (u) int/short/char. XXX should use NTEMP here */ 367 { SCONV, INCH, 368 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 369 SHCH, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR, 370 NCREG, RESC1, 371 " subl $4,%esp\n fistpl (%esp)\n popl A1\n", }, 372 #endif 373 374 /* convert float/double to int. XXX should use NTEMP here */ 375 { SCONV, INAREG, 376 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 377 SAREG, TSWORD, 378 NAREG, RESC1, 379 " subl $12,%esp\n" 380 " fnstcw (%esp)\n" 381 " fnstcw 4(%esp)\n" 382 " movb $12,1(%esp)\n" 383 " fldcw (%esp)\n" 384 " fistpl 8(%esp)\n" 385 " movl 8(%esp),A1\n" 386 " fldcw 4(%esp)\n" 387 " addl $12,%esp\n", }, 388 389 /* convert float/double to unsigned int. XXX should use NTEMP here */ 390 { SCONV, INAREG, 391 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 392 SAREG, TUWORD, 393 NAREG, RESC1, 394 " subl $16,%esp\n" 395 " fnstcw (%esp)\n" 396 " fnstcw 4(%esp)\n" 397 " movb $12,1(%esp)\n" 398 " fldcw (%esp)\n" 399 " fistpq 8(%esp)\n" 400 " movl 8(%esp),A1\n" 401 " fldcw 4(%esp)\n" 402 " addl $16,%esp\n", }, 403 404 /* convert float/double (in register) to long long */ 405 { SCONV, INLL, 406 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 407 SHLL, TLONGLONG, 408 NCREG, RESC1, 409 " subl $16,%esp\n" 410 " fnstcw (%esp)\n" 411 " fnstcw 4(%esp)\n" 412 " movb $12,1(%esp)\n" 413 " fldcw (%esp)\n" 414 " fistpq 8(%esp)\n" 415 " movl 8(%esp),A1\n" 416 " movl 12(%esp),U1\n" 417 " fldcw 4(%esp)\n" 418 " addl $16,%esp\n", }, 419 420 /* convert float/double (in register) to unsigned long long */ 421 { SCONV, INLL, 422 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 423 SHLL, TULONGLONG, 424 NCREG, RESC1, 425 " subl $16,%esp\n" 426 " fnstcw (%esp)\n" 427 " fnstcw 4(%esp)\n" 428 " movb $15,1(%esp)\n" /* 64-bit prec */ 429 " fldcw (%esp)\n" 430 " movl $0x5f000000, 8(%esp)\n" /* (float)(1<<63) */ 431 " fsubs 8(%esp)\n" /* keep in range of fistpq */ 432 " fistpq 8(%esp)\n" 433 " xorb $0x80,15(%esp)\n" /* addq $1>>63 to 8(%esp) */ 434 " movl 8(%esp),A1\n" 435 " movl 12(%esp),U1\n" 436 " fldcw 4(%esp)\n" 437 " addl $16,%esp\n", }, 438 439 440 441 /* slut sconv */ 442 443 /* 444 * Subroutine calls. 445 */ 446 447 { UCALL, FOREFF, 448 SCON, TANY, 449 SANY, TANY, 450 0, 0, 451 " call CL\nZC", }, 452 453 { CALL, FOREFF, 454 SCON, TANY, 455 SANY, TANY, 456 0, 0, 457 " call CL\nZC", }, 458 459 { UCALL, FOREFF, 460 SCON, TANY, 461 SAREG, TWORD|TPOINT, 462 0, 0, 463 " call CL\nZC", }, 464 465 { CALL, INAREG, 466 SCON, TANY, 467 SAREG, TSHORT|TUSHORT|TWORD|TPOINT, 468 NAREG|NASL, RESC1, /* should be 0 */ 469 " call CL\nZC", }, 470 471 { UCALL, INAREG, 472 SCON, TANY, 473 SAREG, TSHORT|TUSHORT|TWORD|TPOINT, 474 NAREG|NASL, RESC1, /* should be 0 */ 475 " call CL\nZC", }, 476 477 { CALL, INBREG, 478 SCON, TANY, 479 SBREG, TCHAR|TUCHAR, 480 NBREG, RESC1, /* should be 0 */ 481 " call CL\nZC", }, 482 483 { UCALL, INBREG, 484 SCON, TANY, 485 SBREG, TCHAR|TUCHAR, 486 NBREG, RESC1, /* should be 0 */ 487 " call CL\nZC", }, 488 489 { CALL, INCREG, 490 SCON, TANY, 491 SCREG, TANY, 492 NCREG|NCSL, RESC1, /* should be 0 */ 493 " call CL\nZC", }, 494 495 { UCALL, INCREG, 496 SCON, TANY, 497 SCREG, TANY, 498 NCREG|NCSL, RESC1, /* should be 0 */ 499 " call CL\nZC", }, 500 501 { CALL, INDREG, 502 SCON, TANY, 503 SDREG, TANY, 504 NDREG|NDSL, RESC1, /* should be 0 */ 505 " call CL\nZC", }, 506 507 { UCALL, INDREG, 508 SCON, TANY, 509 SDREG, TANY, 510 NDREG|NDSL, RESC1, /* should be 0 */ 511 " call CL\nZC", }, 512 513 { CALL, FOREFF, 514 SAREG, TANY, 515 SANY, TANY, 516 0, 0, 517 " call *AL\nZC", }, 518 519 { UCALL, FOREFF, 520 SAREG, TANY, 521 SANY, TANY, 522 0, 0, 523 " call *AL\nZC", }, 524 525 { CALL, INAREG, 526 SAREG, TANY, 527 SANY, TANY, 528 NAREG|NASL, RESC1, /* should be 0 */ 529 " call *AL\nZC", }, 530 531 { UCALL, INAREG, 532 SAREG, TANY, 533 SANY, TANY, 534 NAREG|NASL, RESC1, /* should be 0 */ 535 " call *AL\nZC", }, 536 537 { CALL, INBREG, 538 SAREG, TANY, 539 SANY, TANY, 540 NBREG|NBSL, RESC1, /* should be 0 */ 541 " call *AL\nZC", }, 542 543 { UCALL, INBREG, 544 SAREG, TANY, 545 SANY, TANY, 546 NBREG|NBSL, RESC1, /* should be 0 */ 547 " call *AL\nZC", }, 548 549 { CALL, INCREG, 550 SAREG, TANY, 551 SANY, TANY, 552 NCREG|NCSL, RESC1, /* should be 0 */ 553 " call *AL\nZC", }, 554 555 { UCALL, INCREG, 556 SAREG, TANY, 557 SANY, TANY, 558 NCREG|NCSL, RESC1, /* should be 0 */ 559 " call *AL\nZC", }, 560 561 { CALL, INDREG, 562 SAREG, TANY, 563 SANY, TANY, 564 NDREG|NDSL, RESC1, /* should be 0 */ 565 " call *AL\nZC", }, 566 567 { UCALL, INDREG, 568 SAREG, TANY, 569 SANY, TANY, 570 NDREG|NDSL, RESC1, /* should be 0 */ 571 " call *AL\nZC", }, 572 573 /* struct return */ 574 { USTCALL, FOREFF, 575 SCON, TANY, 576 SANY, TANY, 577 NAREG|NASL, 0, 578 "ZP call CL\nZC", }, 579 580 { USTCALL, INAREG, 581 SCON, TANY, 582 SANY, TANY, 583 NAREG|NASL, RESC1, /* should be 0 */ 584 "ZP call CL\nZC", }, 585 586 { USTCALL, INAREG, 587 SNAME|SAREG, TANY, 588 SANY, TANY, 589 NAREG|NASL, RESC1, /* should be 0 */ 590 "ZP call *AL\nZC", }, 591 592 { STCALL, FOREFF, 593 SCON, TANY, 594 SANY, TANY, 595 NAREG|NASL, 0, 596 "ZP call CL\nZC", }, 597 598 { STCALL, INAREG, 599 SCON, TANY, 600 SANY, TANY, 601 NAREG|NASL, RESC1, /* should be 0 */ 602 "ZP call CL\nZC", }, 603 604 { STCALL, INAREG, 605 SNAME|SAREG, TANY, 606 SANY, TANY, 607 NAREG|NASL, RESC1, /* should be 0 */ 608 "ZP call *AL\nZC", }, 609 610 /* 611 * The next rules handle all binop-style operators. 612 */ 613 /* Special treatment for long long */ 614 { PLUS, INLL|FOREFF, 615 SHLL, TLL, 616 SHLL|SNAME|SOREG, TLL, 617 0, RLEFT, 618 " addl AR,AL\n adcl UR,UL\n", }, 619 620 { PLUS, INLL|FOREFF, 621 SHLL|SNAME|SOREG, TLL, 622 SHLL|SCON, TLL, 623 0, RLEFT, 624 " addl AR,AL\n adcl UR,UL\n", }, 625 626 /* Special treatment for long long XXX - fix commutative check */ 627 { PLUS, INLL|FOREFF, 628 SHLL|SNAME|SOREG, TLL, 629 SHLL, TLL, 630 0, RRIGHT, 631 " addl AL,AR\n adcl UL,UR\n", }, 632 633 { PLUS, INFL, 634 SHFL, TDOUBLE, 635 SNAME|SOREG, TDOUBLE, 636 0, RLEFT, 637 " faddl AR\n", }, 638 639 { PLUS, INFL|FOREFF, 640 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 641 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 642 0, RLEFT, 643 " faddp\n", }, 644 645 { PLUS, INAREG|FOREFF, 646 SAREG|SNAME|SOREG, TWORD|TPOINT, 647 SONE, TANY, 648 0, RLEFT, 649 " incl AL\n", }, 650 651 { PLUS, INAREG|FOREFF, 652 SAREG|SNAME|SOREG, TSHORT|TUSHORT, 653 SONE, TANY, 654 0, RLEFT, 655 " incw AL\n", }, 656 657 { PLUS, INCH|FOREFF, 658 SHCH|SNAME|SOREG, TCHAR|TUCHAR, 659 SONE, TANY, 660 0, RLEFT, 661 " incb AL\n", }, 662 663 { PLUS, INAREG, 664 SAREG, TWORD, 665 SAREG, TWORD, 666 NAREG|NASL|NASR, RESC1, 667 " leal (AL,AR),A1\n", }, 668 669 { MINUS, INAREG|FOREFF, 670 SAREG|SNAME|SOREG, TWORD|TPOINT, 671 SONE, TANY, 672 0, RLEFT, 673 " decl AL\n", }, 674 675 { MINUS, INAREG|FOREFF, 676 SAREG|SNAME|SOREG, TSHORT|TUSHORT, 677 SONE, TANY, 678 0, RLEFT, 679 " decw AL\n", }, 680 681 { MINUS, INCH|FOREFF, 682 SHCH|SNAME|SOREG, TCHAR|TUCHAR, 683 SONE, TANY, 684 0, RLEFT, 685 " decb AL\n", }, 686 687 /* address as register offset, negative */ 688 { MINUS, INLL|FOREFF, 689 SHLL, TLL, 690 SHLL|SNAME|SOREG, TLL, 691 0, RLEFT, 692 " subl AR,AL\n sbbl UR,UL\n", }, 693 694 { MINUS, INLL|FOREFF, 695 SHLL|SNAME|SOREG, TLL, 696 SHLL|SCON, TLL, 697 0, RLEFT, 698 " subl AR,AL\n sbbl UR,UL\n", }, 699 700 { MINUS, INFL, 701 SHFL, TDOUBLE, 702 SNAME|SOREG, TDOUBLE, 703 0, RLEFT, 704 " fsubl AR\n", }, 705 706 { MINUS, INFL|FOREFF, 707 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 708 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 709 0, RLEFT, 710 " fsubZAp\n", }, 711 712 /* Simple r/m->reg ops */ 713 /* m/r |= r */ 714 { OPSIMP, INAREG|FOREFF|FORCC, 715 SAREG|SNAME|SOREG, TWORD|TPOINT, 716 SAREG, TWORD|TPOINT, 717 0, RLEFT|RESCC, 718 " Ol AR,AL\n", }, 719 720 /* r |= r/m */ 721 { OPSIMP, INAREG|FOREFF|FORCC, 722 SAREG, TWORD|TPOINT, 723 SAREG|SNAME|SOREG, TWORD|TPOINT, 724 0, RLEFT|RESCC, 725 " Ol AR,AL\n", }, 726 727 /* m/r |= r */ 728 { OPSIMP, INAREG|FOREFF|FORCC, 729 SHINT|SNAME|SOREG, TSHORT|TUSHORT, 730 SHINT, TSHORT|TUSHORT, 731 0, RLEFT|RESCC, 732 " Ow AR,AL\n", }, 733 734 /* r |= r/m */ 735 { OPSIMP, INAREG|FOREFF|FORCC, 736 SHINT, TSHORT|TUSHORT, 737 SHINT|SNAME|SOREG, TSHORT|TUSHORT, 738 0, RLEFT|RESCC, 739 " Ow AR,AL\n", }, 740 741 /* m/r |= r */ 742 { OPSIMP, INCH|FOREFF|FORCC, 743 SHCH, TCHAR|TUCHAR, 744 SHCH|SNAME|SOREG, TCHAR|TUCHAR, 745 0, RLEFT|RESCC, 746 " Ob AR,AL\n", }, 747 748 /* r |= r/m */ 749 { OPSIMP, INCH|FOREFF|FORCC, 750 SHCH, TCHAR|TUCHAR, 751 SHCH|SNAME|SOREG, TCHAR|TUCHAR, 752 0, RLEFT|RESCC, 753 " Ob AR,AL\n", }, 754 755 /* m/r |= const */ 756 { OPSIMP, INAREG|FOREFF|FORCC, 757 SAREG|SNAME|SOREG, TWORD|TPOINT, 758 SCON, TWORD|TPOINT, 759 0, RLEFT|RESCC, 760 " Ol AR,AL\n", }, 761 762 { OPSIMP, INAREG|FOREFF|FORCC, 763 SHINT|SNAME|SOREG, TSHORT|TUSHORT, 764 SCON, TANY, 765 0, RLEFT|RESCC, 766 " Ow AR,AL\n", }, 767 768 { OPSIMP, INCH|FOREFF|FORCC, 769 SHCH|SNAME|SOREG, TCHAR|TUCHAR, 770 SCON, TANY, 771 0, RLEFT|RESCC, 772 " Ob AR,AL\n", }, 773 774 /* r |= r/m */ 775 { OPSIMP, INLL|FOREFF, 776 SHLL, TLL, 777 SHLL|SNAME|SOREG, TLL, 778 0, RLEFT, 779 " Ol AR,AL\n Ol UR,UL\n", }, 780 781 /* m/r |= r/const */ 782 { OPSIMP, INLL|FOREFF, 783 SHLL|SNAME|SOREG, TLL, 784 SHLL|SCON, TLL, 785 0, RLEFT, 786 " Ol AR,AL\n Ol UR,UL\n", }, 787 788 /* Try use-reg instructions first */ 789 { PLUS, INAREG, 790 SAREG, TWORD|TPOINT, 791 SCON, TANY, 792 NAREG|NASL, RESC1, 793 " leal CR(AL),A1\n", }, 794 795 { MINUS, INAREG, 796 SAREG, TWORD|TPOINT, 797 SPCON, TANY, 798 NAREG|NASL, RESC1, 799 " leal -CR(AL),A1\n", }, 800 801 802 /* 803 * The next rules handle all shift operators. 804 */ 805 /* (u)longlong left shift is emulated */ 806 { LS, INCREG, 807 SCREG, TLL, 808 SHCH, TCHAR|TUCHAR, 809 NSPECIAL, RLEFT, 810 "ZO", }, 811 812 /* r/m <<= r */ 813 { LS, INAREG|FOREFF, 814 SAREG|SNAME|SOREG, TWORD, 815 SHCH, TCHAR|TUCHAR, 816 NSPECIAL, RLEFT, 817 " sall AR,AL\n", }, 818 819 /* r/m <<= const */ 820 { LS, INAREG|FOREFF, 821 SAREG|SNAME|SOREG, TWORD, 822 SCON, TANY, 823 0, RLEFT, 824 " sall AR,AL\n", }, 825 826 /* r/m <<= r */ 827 { LS, INAREG|FOREFF, 828 SAREG|SNAME|SOREG, TSHORT|TUSHORT, 829 SHCH, TCHAR|TUCHAR, 830 NSPECIAL, RLEFT, 831 " shlw AR,AL\n", }, 832 833 /* r/m <<= const */ 834 { LS, INAREG|FOREFF, 835 SAREG|SNAME|SOREG, TSHORT|TUSHORT, 836 SCON, TANY, 837 0, RLEFT, 838 " shlw AR,AL\n", }, 839 840 { LS, INCH|FOREFF, 841 SHCH|SNAME|SOREG, TCHAR|TUCHAR, 842 SHCH, TCHAR|TUCHAR, 843 NSPECIAL, RLEFT, 844 " salb AR,AL\n", }, 845 846 { LS, INCH|FOREFF, 847 SHCH|SNAME|SOREG, TCHAR|TUCHAR, 848 SCON, TANY, 849 0, RLEFT, 850 " salb AR,AL\n", }, 851 852 /* (u)longlong right shift is emulated */ 853 { RS, INCREG, 854 SCREG, TLL, 855 SHCH, TCHAR|TUCHAR, 856 NSPECIAL, RLEFT, 857 "ZO", }, 858 859 { RS, INAREG|FOREFF, 860 SAREG|SNAME|SOREG, TSWORD, 861 SHCH, TCHAR|TUCHAR, 862 NSPECIAL, RLEFT, 863 " sarl AR,AL\n", }, 864 865 { RS, INAREG|FOREFF, 866 SAREG|SNAME|SOREG, TSWORD, 867 SCON, TANY, 868 0, RLEFT, 869 " sarl AR,AL\n", }, 870 871 { RS, INAREG|FOREFF, 872 SAREG|SNAME|SOREG, TUWORD, 873 SHCH, TCHAR|TUCHAR, 874 NSPECIAL, RLEFT, 875 " shrl AR,AL\n", }, 876 877 { RS, INAREG|FOREFF, 878 SAREG|SNAME|SOREG, TUWORD, 879 SCON, TANY, 880 0, RLEFT, 881 " shrl AR,AL\n", }, 882 883 { RS, INAREG|FOREFF, 884 SAREG|SNAME|SOREG, TSHORT, 885 SHCH, TCHAR|TUCHAR, 886 NSPECIAL, RLEFT, 887 " sarw AR,AL\n", }, 888 889 { RS, INAREG|FOREFF, 890 SAREG|SNAME|SOREG, TSHORT, 891 SCON, TANY, 892 0, RLEFT, 893 " sarw AR,AL\n", }, 894 895 { RS, INAREG|FOREFF, 896 SAREG|SNAME|SOREG, TUSHORT, 897 SHCH, TCHAR|TUCHAR, 898 NSPECIAL, RLEFT, 899 " shrw AR,AL\n", }, 900 901 { RS, INAREG|FOREFF, 902 SAREG|SNAME|SOREG, TUSHORT, 903 SCON, TANY, 904 0, RLEFT, 905 " shrw AR,AL\n", }, 906 907 { RS, INCH|FOREFF, 908 SHCH|SNAME|SOREG, TCHAR, 909 SHCH, TCHAR|TUCHAR, 910 NSPECIAL, RLEFT, 911 " sarb AR,AL\n", }, 912 913 { RS, INCH|FOREFF, 914 SHCH|SNAME|SOREG, TCHAR, 915 SCON, TANY, 916 0, RLEFT, 917 " sarb AR,AL\n", }, 918 919 { RS, INCH|FOREFF, 920 SHCH|SNAME|SOREG, TUCHAR, 921 SHCH, TCHAR|TUCHAR, 922 NSPECIAL, RLEFT, 923 " shrb AR,AL\n", }, 924 925 { RS, INCH|FOREFF, 926 SHCH|SNAME|SOREG, TUCHAR, 927 SCON, TANY, 928 0, RLEFT, 929 " shrb AR,AL\n", }, 930 931 /* 932 * The next rules takes care of assignments. "=". 933 */ 934 { ASSIGN, FORCC|FOREFF|INLL, 935 SHLL, TLL, 936 SMIXOR, TANY, 937 0, RDEST, 938 " xorl AL,AL\n xorl UL,UL\n", }, 939 940 { ASSIGN, FORCC|FOREFF|INLL, 941 SHLL, TLL, 942 SMILWXOR, TANY, 943 0, RDEST, 944 " xorl AL,AL\n movl UR,UL\n", }, 945 946 { ASSIGN, FORCC|FOREFF|INLL, 947 SHLL, TLL, 948 SMIHWXOR, TANY, 949 0, RDEST, 950 " movl AR,AL\n xorl UL,UL\n", }, 951 952 { ASSIGN, FOREFF|INLL, 953 SHLL, TLL, 954 SCON, TANY, 955 0, RDEST, 956 " movl AR,AL\n movl UR,UL\n", }, 957 958 { ASSIGN, FOREFF, 959 SHLL|SNAME|SOREG, TLL, 960 SCON, TANY, 961 0, 0, 962 " movl AR,AL\n movl UR,UL\n", }, 963 964 { ASSIGN, FORCC|FOREFF|INAREG, 965 SAREG, TWORD|TPOINT, 966 SMIXOR, TANY, 967 0, RDEST, 968 " xorl AL,AL\n", }, 969 970 { ASSIGN, FOREFF, 971 SAREG|SNAME|SOREG, TWORD|TPOINT, 972 SCON, TANY, 973 0, 0, 974 " movl AR,AL\n", }, 975 976 { ASSIGN, FOREFF|INAREG, 977 SAREG, TWORD|TPOINT, 978 SCON, TANY, 979 0, RDEST, 980 " movl AR,AL\n", }, 981 982 { ASSIGN, FORCC|FOREFF|INAREG, 983 SAREG, TSHORT|TUSHORT, 984 SMIXOR, TANY, 985 0, RDEST, 986 " xorw AL,AL\n", }, 987 988 { ASSIGN, FOREFF, 989 SAREG|SNAME|SOREG, TSHORT|TUSHORT, 990 SCON, TANY, 991 0, 0, 992 " movw AR,AL\n", }, 993 994 { ASSIGN, FOREFF|INAREG, 995 SAREG, TSHORT|TUSHORT, 996 SCON, TANY, 997 0, RDEST, 998 " movw AR,AL\n", }, 999 1000 { ASSIGN, FOREFF, 1001 SHCH|SNAME|SOREG, TCHAR|TUCHAR, 1002 SCON, TANY, 1003 0, 0, 1004 " movb AR,AL\n", }, 1005 1006 { ASSIGN, FOREFF|INCH, 1007 SHCH, TCHAR|TUCHAR, 1008 SCON, TANY, 1009 0, RDEST, 1010 " movb AR,AL\n", }, 1011 1012 { ASSIGN, FOREFF|INLL, 1013 SNAME|SOREG, TLL, 1014 SHLL, TLL, 1015 0, RDEST, 1016 " movl AR,AL\n movl UR,UL\n", }, 1017 1018 { ASSIGN, FOREFF|INLL, 1019 SHLL, TLL, 1020 SHLL, TLL, 1021 0, RDEST, 1022 "ZH", }, 1023 1024 { ASSIGN, FOREFF|INAREG, 1025 SAREG|SNAME|SOREG, TWORD|TPOINT, 1026 SAREG, TWORD|TPOINT, 1027 0, RDEST, 1028 " movl AR,AL\n", }, 1029 1030 { ASSIGN, FOREFF|INAREG, 1031 SAREG, TWORD|TPOINT, 1032 SAREG|SNAME|SOREG, TWORD|TPOINT, 1033 0, RDEST, 1034 " movl AR,AL\n", }, 1035 1036 { ASSIGN, FOREFF|INAREG, 1037 SAREG|SNAME|SOREG, TSHORT|TUSHORT, 1038 SAREG, TSHORT|TUSHORT, 1039 0, RDEST, 1040 " movw AR,AL\n", }, 1041 1042 { ASSIGN, FOREFF|INCH, 1043 SHCH|SNAME|SOREG, TCHAR|TUCHAR, 1044 SHCH, TCHAR|TUCHAR|TWORD, 1045 0, RDEST, 1046 " movb AR,AL\n", }, 1047 1048 { ASSIGN, INDREG|FOREFF, 1049 SHFL, TFLOAT|TDOUBLE|TLDOUBLE, 1050 SHFL, TFLOAT|TDOUBLE|TLDOUBLE, 1051 0, RDEST, 1052 "", }, /* This will always be in the correct register */ 1053 1054 /* order of table entries is very important here! */ 1055 { ASSIGN, INFL, 1056 SNAME|SOREG, TLDOUBLE, 1057 SHFL, TFLOAT|TDOUBLE|TLDOUBLE, 1058 0, RDEST, 1059 " fstpt AL\n fldt AL\n", }, /* XXX */ 1060 1061 { ASSIGN, FOREFF, 1062 SNAME|SOREG, TLDOUBLE, 1063 SHFL, TFLOAT|TDOUBLE|TLDOUBLE, 1064 0, 0, 1065 " fstpt AL\n", }, 1066 1067 { ASSIGN, INFL, 1068 SNAME|SOREG, TDOUBLE, 1069 SHFL, TFLOAT|TDOUBLE|TLDOUBLE, 1070 0, RDEST, 1071 " fstl AL\n", }, 1072 1073 { ASSIGN, FOREFF, 1074 SNAME|SOREG, TDOUBLE, 1075 SHFL, TFLOAT|TDOUBLE|TLDOUBLE, 1076 0, 0, 1077 " fstpl AL\n", }, 1078 1079 { ASSIGN, INFL, 1080 SNAME|SOREG, TFLOAT, 1081 SHFL, TFLOAT|TDOUBLE|TLDOUBLE, 1082 0, RDEST, 1083 " fsts AL\n", }, 1084 1085 { ASSIGN, FOREFF, 1086 SNAME|SOREG, TFLOAT, 1087 SHFL, TFLOAT|TDOUBLE|TLDOUBLE, 1088 0, 0, 1089 " fstps AL\n", }, 1090 /* end very important order */ 1091 1092 { ASSIGN, INFL|FOREFF, 1093 SHFL, TLDOUBLE, 1094 SHFL|SOREG|SNAME, TLDOUBLE, 1095 0, RDEST, 1096 " fldt AR\n", }, 1097 1098 { ASSIGN, INFL|FOREFF, 1099 SHFL, TDOUBLE, 1100 SHFL|SOREG|SNAME, TDOUBLE, 1101 0, RDEST, 1102 " fldl AR\n", }, 1103 1104 { ASSIGN, INFL|FOREFF, 1105 SHFL, TFLOAT, 1106 SHFL|SOREG|SNAME, TFLOAT, 1107 0, RDEST, 1108 " flds AR\n", }, 1109 1110 /* Do not generate memcpy if return from funcall */ 1111 #if 0 1112 { STASG, INAREG|FOREFF, 1113 SOREG|SNAME|SAREG, TPTRTO|TSTRUCT, 1114 SFUNCALL, TPTRTO|TSTRUCT, 1115 0, RRIGHT, 1116 "", }, 1117 #endif 1118 1119 { STASG, INAREG|FOREFF, 1120 SOREG|SNAME, TANY, 1121 SAREG, TPTRTO|TANY, 1122 NSPECIAL, RDEST, 1123 "ZQ", }, 1124 1125 /* 1126 * DIV/MOD/MUL 1127 */ 1128 /* long long div is emulated */ 1129 { DIV, INCREG, 1130 SCREG|SNAME|SOREG|SCON, TLL, 1131 SCREG|SNAME|SOREG|SCON, TLL, 1132 NSPECIAL|NCREG|NCSL|NCSR, RESC1, 1133 "ZO", }, 1134 1135 { DIV, INAREG, 1136 SAREG, TSWORD, 1137 SAREG|SNAME|SOREG, TWORD, 1138 NSPECIAL, RDEST, 1139 " cltd\n idivl AR\n", }, 1140 1141 { DIV, INAREG, 1142 SAREG, TUWORD|TPOINT, 1143 SAREG|SNAME|SOREG, TUWORD|TPOINT, 1144 NSPECIAL, RDEST, 1145 " xorl %edx,%edx\n divl AR\n", }, 1146 1147 { DIV, INAREG, 1148 SAREG, TUSHORT, 1149 SAREG|SNAME|SOREG, TUSHORT, 1150 NSPECIAL, RDEST, 1151 " xorl %edx,%edx\n divw AR\n", }, 1152 1153 { DIV, INCH, 1154 SHCH, TUCHAR, 1155 SHCH|SNAME|SOREG, TUCHAR, 1156 NSPECIAL, RDEST, 1157 " xorb %ah,%ah\n divb AR\n", }, 1158 1159 { DIV, INFL, 1160 SHFL, TDOUBLE, 1161 SNAME|SOREG, TDOUBLE, 1162 0, RLEFT, 1163 " fdivl AR\n", }, 1164 1165 { DIV, INFL, 1166 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 1167 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 1168 0, RLEFT, 1169 " fdivZAp\n", }, 1170 1171 /* (u)longlong mod is emulated */ 1172 { MOD, INCREG, 1173 SCREG|SNAME|SOREG|SCON, TLL, 1174 SCREG|SNAME|SOREG|SCON, TLL, 1175 NSPECIAL|NCREG|NCSL|NCSR, RESC1, 1176 "ZO", }, 1177 1178 { MOD, INAREG, 1179 SAREG, TSWORD, 1180 SAREG|SNAME|SOREG, TSWORD, 1181 NAREG|NSPECIAL, RESC1, 1182 " cltd\n idivl AR\n", }, 1183 1184 { MOD, INAREG, 1185 SAREG, TWORD|TPOINT, 1186 SAREG|SNAME|SOREG, TUWORD|TPOINT, 1187 NAREG|NSPECIAL, RESC1, 1188 " xorl %edx,%edx\n divl AR\n", }, 1189 1190 { MOD, INAREG, 1191 SAREG, TUSHORT, 1192 SAREG|SNAME|SOREG, TUSHORT, 1193 NAREG|NSPECIAL, RESC1, 1194 " xorl %edx,%edx\n divw AR\n", }, 1195 1196 { MOD, INCH, 1197 SHCH, TUCHAR, 1198 SHCH|SNAME|SOREG, TUCHAR, 1199 NBREG|NSPECIAL, RESC1, 1200 " xorb %ah,%ah\n divb AR\n", }, 1201 1202 /* (u)longlong mul is emulated */ 1203 { MUL, INCREG, 1204 SCREG, TLL, 1205 SCREG, TLL, 1206 NSPECIAL, RDEST, 1207 "ZO", }, 1208 1209 { MUL, INAREG, 1210 SAREG, TWORD|TPOINT, 1211 SAREG|SNAME|SOREG|SCON, TWORD|TPOINT, 1212 0, RLEFT, 1213 " imull AR,AL\n", }, 1214 1215 { MUL, INAREG, 1216 SAREG, TSHORT|TUSHORT, 1217 SAREG|SNAME|SOREG, TSHORT|TUSHORT, 1218 0, RLEFT, 1219 " imulw AR,AL\n", }, 1220 1221 { MUL, INCH, 1222 SHCH, TCHAR|TUCHAR, 1223 SHCH|SNAME|SOREG, TCHAR|TUCHAR, 1224 NSPECIAL, RDEST, 1225 " imulb AR\n", }, 1226 1227 { MUL, INFL, 1228 SHFL, TDOUBLE, 1229 SNAME|SOREG, TDOUBLE, 1230 0, RLEFT, 1231 " fmull AR\n", }, 1232 1233 { MUL, INFL, 1234 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 1235 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 1236 0, RLEFT, 1237 " fmulp\n", }, 1238 1239 /* 1240 * Indirection operators. 1241 */ 1242 { UMUL, INLL, 1243 SANY, TANY, 1244 SOREG, TLL, 1245 NCREG, RESC1, 1246 " movl UL,U1\n movl AL,A1\n", }, 1247 1248 { UMUL, INAREG, 1249 SANY, TPOINT|TWORD, 1250 SOREG, TPOINT|TWORD, 1251 NAREG|NASL, RESC1, 1252 " movl AL,A1\n", }, 1253 1254 { UMUL, INCH, 1255 SANY, TANY, 1256 SOREG, TCHAR|TUCHAR, 1257 NBREG|NBSL, RESC1, 1258 " movb AL,A1\n", }, 1259 1260 { UMUL, INAREG, 1261 SANY, TANY, 1262 SOREG, TSHORT|TUSHORT, 1263 NAREG|NASL, RESC1, 1264 " movw AL,A1\n", }, 1265 1266 { UMUL, INFL, 1267 SANY, TANY, 1268 SOREG, TLDOUBLE, 1269 NDREG|NDSL, RESC1, 1270 " fldt AL\n", }, 1271 1272 { UMUL, INFL, 1273 SANY, TANY, 1274 SOREG, TDOUBLE, 1275 NDREG|NDSL, RESC1, 1276 " fldl AL\n", }, 1277 1278 { UMUL, INFL, 1279 SANY, TANY, 1280 SOREG, TFLOAT, 1281 NDREG|NDSL, RESC1, 1282 " flds AL\n", }, 1283 1284 /* 1285 * Logical/branching operators 1286 */ 1287 1288 /* Comparisions, take care of everything */ 1289 { OPLOG, FORCC, 1290 SHLL|SOREG|SNAME, TLL, 1291 SHLL, TLL, 1292 0, 0, 1293 "ZD", }, 1294 1295 { OPLOG, FORCC, 1296 SAREG|SOREG|SNAME, TWORD|TPOINT, 1297 SCON|SAREG, TWORD|TPOINT, 1298 0, RESCC, 1299 " cmpl AR,AL\n", }, 1300 1301 { OPLOG, FORCC, 1302 SCON|SAREG, TWORD|TPOINT, 1303 SAREG|SOREG|SNAME, TWORD|TPOINT, 1304 0, RESCC, 1305 " cmpl AR,AL\n", }, 1306 1307 { OPLOG, FORCC, 1308 SAREG|SOREG|SNAME, TSHORT|TUSHORT, 1309 SCON|SAREG, TANY, 1310 0, RESCC, 1311 " cmpw AR,AL\n", }, 1312 1313 { OPLOG, FORCC, 1314 SBREG|SOREG|SNAME, TCHAR|TUCHAR, 1315 SCON|SBREG, TANY, 1316 0, RESCC, 1317 " cmpb AR,AL\n", }, 1318 1319 { OPLOG, FORCC, 1320 SDREG, TLDOUBLE|TDOUBLE|TFLOAT, 1321 SDREG, TLDOUBLE|TDOUBLE|TFLOAT, 1322 0, RNOP, 1323 "ZG", }, 1324 1325 { OPLOG, FORCC, 1326 SANY, TANY, 1327 SANY, TANY, 1328 REWRITE, 0, 1329 "diediedie!", }, 1330 1331 /* AND/OR/ER/NOT */ 1332 { AND, INAREG|FOREFF, 1333 SAREG|SOREG|SNAME, TWORD, 1334 SCON|SAREG, TWORD, 1335 0, RLEFT, 1336 " andl AR,AL\n", }, 1337 1338 { AND, INCREG|FOREFF, 1339 SCREG, TLL, 1340 SCREG|SOREG|SNAME, TLL, 1341 0, RLEFT, 1342 " andl AR,AL\n andl UR,UL\n", }, 1343 1344 { AND, INAREG|FOREFF, 1345 SAREG, TWORD, 1346 SAREG|SOREG|SNAME, TWORD, 1347 0, RLEFT, 1348 " andl AR,AL\n", }, 1349 1350 { AND, INAREG|FOREFF, 1351 SAREG|SOREG|SNAME, TSHORT|TUSHORT, 1352 SCON|SAREG, TSHORT|TUSHORT, 1353 0, RLEFT, 1354 " andw AR,AL\n", }, 1355 1356 { AND, INAREG|FOREFF, 1357 SAREG, TSHORT|TUSHORT, 1358 SAREG|SOREG|SNAME, TSHORT|TUSHORT, 1359 0, RLEFT, 1360 " andw AR,AL\n", }, 1361 1362 { AND, INBREG|FOREFF, 1363 SBREG|SOREG|SNAME, TCHAR|TUCHAR, 1364 SCON|SBREG, TCHAR|TUCHAR, 1365 0, RLEFT, 1366 " andb AR,AL\n", }, 1367 1368 { AND, INBREG|FOREFF, 1369 SBREG, TCHAR|TUCHAR, 1370 SBREG|SOREG|SNAME, TCHAR|TUCHAR, 1371 0, RLEFT, 1372 " andb AR,AL\n", }, 1373 /* AND/OR/ER/NOT */ 1374 1375 /* 1376 * Jumps. 1377 */ 1378 { GOTO, FOREFF, 1379 SCON, TANY, 1380 SANY, TANY, 1381 0, RNOP, 1382 " jmp LL\n", }, 1383 1384 #if defined(GCC_COMPAT) || defined(LANG_F77) 1385 { GOTO, FOREFF, 1386 SAREG, TANY, 1387 SANY, TANY, 1388 0, RNOP, 1389 " jmp *AL\n", }, 1390 #endif 1391 1392 /* 1393 * Convert LTYPE to reg. 1394 */ 1395 { OPLTYPE, FORCC|INLL, 1396 SCREG, TLL, 1397 SMIXOR, TANY, 1398 NCREG, RESC1, 1399 " xorl U1,U1\n xorl A1,A1\n", }, 1400 1401 { OPLTYPE, FORCC|INLL, 1402 SCREG, TLL, 1403 SMILWXOR, TANY, 1404 NCREG, RESC1, 1405 " movl UL,U1\n xorl A1,A1\n", }, 1406 1407 { OPLTYPE, FORCC|INLL, 1408 SCREG, TLL, 1409 SMIHWXOR, TANY, 1410 NCREG, RESC1, 1411 " xorl U1,U1\n movl AL,A1\n", }, 1412 1413 { OPLTYPE, INLL, 1414 SANY, TANY, 1415 SCREG, TLL, 1416 NCREG, RESC1, 1417 "ZK", }, 1418 1419 { OPLTYPE, INLL, 1420 SANY, TANY, 1421 SCON|SOREG|SNAME, TLL, 1422 NCREG, RESC1, 1423 " movl UL,U1\n movl AL,A1\n", }, 1424 1425 { OPLTYPE, FORCC|INAREG, 1426 SAREG, TWORD|TPOINT, 1427 SMIXOR, TANY, 1428 NAREG|NASL, RESC1, 1429 " xorl A1,A1\n", }, 1430 1431 { OPLTYPE, INAREG, 1432 SANY, TANY, 1433 SAREG|SCON|SOREG|SNAME, TWORD|TPOINT, 1434 NAREG|NASL, RESC1, 1435 " movl AL,A1\n", }, 1436 1437 { OPLTYPE, INBREG, 1438 SANY, TANY, 1439 SBREG|SOREG|SNAME|SCON, TCHAR|TUCHAR, 1440 NBREG, RESC1, 1441 " movb AL,A1\n", }, 1442 1443 { OPLTYPE, FORCC|INAREG, 1444 SAREG, TSHORT|TUSHORT, 1445 SMIXOR, TANY, 1446 NAREG, RESC1, 1447 " xorw A1,A1\n", }, 1448 1449 { OPLTYPE, INAREG, 1450 SANY, TANY, 1451 SAREG|SOREG|SNAME|SCON, TSHORT|TUSHORT, 1452 NAREG, RESC1, 1453 " movw AL,A1\n", }, 1454 1455 { OPLTYPE, INDREG, 1456 SANY, TLDOUBLE, 1457 SOREG|SNAME, TLDOUBLE, 1458 NDREG, RESC1, 1459 " fldt AL\n", }, 1460 1461 { OPLTYPE, INDREG, 1462 SANY, TDOUBLE, 1463 SOREG|SNAME, TDOUBLE, 1464 NDREG, RESC1, 1465 " fldl AL\n", }, 1466 1467 { OPLTYPE, INDREG, 1468 SANY, TFLOAT, 1469 SOREG|SNAME, TFLOAT, 1470 NDREG, RESC1, 1471 " flds AL\n", }, 1472 1473 /* Only used in ?: constructs. The stack already contains correct value */ 1474 { OPLTYPE, INDREG, 1475 SANY, TFLOAT|TDOUBLE|TLDOUBLE, 1476 SDREG, TFLOAT|TDOUBLE|TLDOUBLE, 1477 NDREG, RESC1, 1478 "", }, 1479 1480 /* 1481 * Negate a word. 1482 */ 1483 1484 { UMINUS, INCREG|FOREFF, 1485 SCREG, TLL, 1486 SCREG, TLL, 1487 0, RLEFT, 1488 " negl AL\n adcl $0,UL\n negl UL\n", }, 1489 1490 { UMINUS, INAREG|FOREFF, 1491 SAREG, TWORD|TPOINT, 1492 SAREG, TWORD|TPOINT, 1493 0, RLEFT, 1494 " negl AL\n", }, 1495 1496 { UMINUS, INAREG|FOREFF, 1497 SAREG, TSHORT|TUSHORT, 1498 SAREG, TSHORT|TUSHORT, 1499 0, RLEFT, 1500 " negw AL\n", }, 1501 1502 { UMINUS, INBREG|FOREFF, 1503 SBREG, TCHAR|TUCHAR, 1504 SBREG, TCHAR|TUCHAR, 1505 0, RLEFT, 1506 " negb AL\n", }, 1507 1508 { UMINUS, INFL|FOREFF, 1509 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 1510 SHFL, TLDOUBLE|TDOUBLE|TFLOAT, 1511 0, RLEFT, 1512 " fchs\n", }, 1513 1514 { COMPL, INCREG, 1515 SCREG, TLL, 1516 SANY, TANY, 1517 0, RLEFT, 1518 " notl AL\n notl UL\n", }, 1519 1520 { COMPL, INAREG, 1521 SAREG, TWORD, 1522 SANY, TANY, 1523 0, RLEFT, 1524 " notl AL\n", }, 1525 1526 { COMPL, INAREG, 1527 SAREG, TSHORT|TUSHORT, 1528 SANY, TANY, 1529 0, RLEFT, 1530 " notw AL\n", }, 1531 1532 { COMPL, INBREG, 1533 SBREG, TCHAR|TUCHAR, 1534 SANY, TANY, 1535 0, RLEFT, 1536 " notb AL\n", }, 1537 1538 /* 1539 * Arguments to functions. 1540 */ 1541 { FUNARG, FOREFF, 1542 SCON|SCREG|SNAME|SOREG, TLL, 1543 SANY, TLL, 1544 0, RNULL, 1545 " pushl UL\n pushl AL\n", }, 1546 1547 { FUNARG, FOREFF, 1548 SCON|SAREG|SNAME|SOREG, TWORD|TPOINT, 1549 SANY, TWORD|TPOINT, 1550 0, RNULL, 1551 " pushl AL\n", }, 1552 1553 { FUNARG, FOREFF, 1554 SCON, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR, 1555 SANY, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR, 1556 0, RNULL, 1557 " pushl AL\n", }, 1558 1559 { FUNARG, FOREFF, 1560 SAREG|SNAME|SOREG, TSHORT, 1561 SANY, TSHORT, 1562 NAREG, 0, 1563 " movswl AL,ZN\n pushl ZN\n", }, 1564 1565 { FUNARG, FOREFF, 1566 SAREG|SNAME|SOREG, TUSHORT, 1567 SANY, TUSHORT, 1568 NAREG, 0, 1569 " movzwl AL,ZN\n pushl ZN\n", }, 1570 1571 { FUNARG, FOREFF, 1572 SHCH|SNAME|SOREG, TCHAR, 1573 SANY, TCHAR, 1574 NAREG, 0, 1575 " movsbl AL,A1\n pushl A1\n", }, 1576 1577 { FUNARG, FOREFF, 1578 SHCH|SNAME|SOREG, TUCHAR, 1579 SANY, TUCHAR, 1580 NAREG, 0, 1581 " movzbl AL,A1\n pushl A1\n", }, 1582 1583 { FUNARG, FOREFF, 1584 SNAME|SOREG, TDOUBLE, 1585 SANY, TDOUBLE, 1586 0, 0, 1587 " pushl UL\n pushl AL\n", }, 1588 1589 { FUNARG, FOREFF, 1590 SDREG, TDOUBLE, 1591 SANY, TDOUBLE, 1592 0, 0, 1593 " subl $8,%esp\n fstpl (%esp)\n", }, 1594 1595 { FUNARG, FOREFF, 1596 SNAME|SOREG, TFLOAT, 1597 SANY, TFLOAT, 1598 0, 0, 1599 " pushl AL\n", }, 1600 1601 { FUNARG, FOREFF, 1602 SDREG, TFLOAT, 1603 SANY, TFLOAT, 1604 0, 0, 1605 " subl $4,%esp\n fstps (%esp)\n", }, 1606 1607 { FUNARG, FOREFF, 1608 SDREG, TLDOUBLE, 1609 SANY, TLDOUBLE, 1610 0, 0, 1611 " subl $12,%esp\n fstpt (%esp)\n", }, 1612 1613 #if defined(MACHOABI) 1614 { STARG, FOREFF, 1615 SAREG|SOREG|SNAME|SCON, TANY, 1616 SANY, TSTRUCT, 1617 NSPECIAL|NAREG, 0, 1618 "ZF", }, 1619 #else 1620 { STARG, FOREFF, 1621 SAREG, TPTRTO|TSTRUCT, 1622 SANY, TSTRUCT, 1623 NSPECIAL, 0, 1624 "ZF", }, 1625 #endif 1626 1627 # define DF(x) FORREW,SANY,TANY,SANY,TANY,REWRITE,x,"" 1628 1629 { UMUL, DF( UMUL ), }, 1630 1631 { ASSIGN, DF(ASSIGN), }, 1632 1633 { STASG, DF(STASG), }, 1634 1635 { FLD, DF(FLD), }, 1636 1637 { OPLEAF, DF(NAME), }, 1638 1639 /* { INIT, DF(INIT), }, */ 1640 1641 { OPUNARY, DF(UMINUS), }, 1642 1643 { OPANY, DF(BITYPE), }, 1644 1645 { FREE, FREE, FREE, FREE, FREE, FREE, FREE, FREE, "help; I'm in trouble\n" }, 1646 }; 1647 1648 int tablesize = sizeof(table)/sizeof(table[0]); 1649