1 /* Id: table.c,v 1.97 2008/02/10 19:25:44 ragge Exp */ 2 /* $NetBSD: table.c,v 1.1.1.2 2010/06/03 18:57:24 plunky Exp $ */ 3 /* 4 * Copyright (c) 2003 Anders Magnusson (ragge (at) 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 41 struct optab table[] = { 42 { -1, FORREW,SANY,TANY,SANY,TANY,REWRITE,-1,"", }, 43 /* 44 * A bunch of pointer conversions. 45 * First pointer to integer. 46 */ 47 /* Convert char pointer to int */ 48 { SCONV, INAREG, 49 SAREG|SAREG, TPTRTO|TCHAR|TUCHAR, 50 SANY, TWORD, 51 NAREG, RLEFT, 52 " lsh AL,2\n" 53 " move A1,AL\n" 54 " lsh A1,-040\n" 55 " trz A1,074\n" 56 " ior AL,A1\n" 57 " tlz AL,0740000\n", }, 58 59 /* Convert short pointer to int */ 60 { SCONV, INAREG, 61 SAREG|SAREG, TPTRTO|TSHORT|TUSHORT, 62 SANY, TWORD, 63 NAREG, RLEFT, 64 " lsh AL,2\n" 65 " move A1,AL\n" 66 " lsh A1,-041\n" 67 " trz A1,2\n" 68 " ior AL,A1\n" 69 " tlz AL,0740000\n", }, 70 71 /* Convert int/unsigned/long/ulong/struct/union/func ptr to int */ 72 { SCONV, INAREG, 73 SAREG|SAREG, TPTRTO|TWORD|TSTRUCT|TPOINT, 74 SANY, TWORD, 75 0, RLEFT, 76 " lsh AL,2\n", }, 77 78 /* 79 * Convert int/long to pointers. 80 */ 81 /* Convert int to char pointer */ 82 { PCONV, INAREG, 83 SAREG, TWORD, 84 SANY, TPTRTO|TCHAR|TUCHAR, 85 NAREG, RLEFT, 86 " move A1,AL\n" 87 " lsh A1,036\n" 88 " tlo A1,0700000\n" 89 " tlz A1,0040000\n" 90 " lsh AL,-2\n" 91 " ior AL,A1\n", }, 92 93 /* Convert int/long to short pointer */ 94 { PCONV, INAREG, 95 SAREG, TWORD, 96 SANY, TPTRTO|TSHORT|TUSHORT, 97 NAREG, RLEFT, 98 " move A1,AL\n" 99 " lsh AL,-2\n" 100 " tlo AL,0750000\n" 101 " lsh A1,035\n" 102 " tlz A1,0760000\n" 103 " add AL,A1\n", }, 104 105 /* Convert int/long to int/struct/multiple ptr */ 106 { PCONV, INAREG, 107 SAREG, TWORD, 108 SANY, TPOINT|TWORD|TSTRUCT, 109 0, RLEFT, 110 " lsh AL,-2\n", }, 111 112 /* 113 * Pointer to pointer conversions. 114 */ 115 /* Convert char ptr to short ptr */ 116 { PCONV, INAREG, 117 SAREG, TPTRTO|TCHAR|TUCHAR, 118 SANY, TPTRTO|TSHORT|TUSHORT, 119 0, RLEFT, 120 " tlo AL,050000\n" 121 " tlne AL,020000\n" 122 " tlz AL,010000\n", }, 123 124 /* Convert char/short pointer to int/struct/multiple ptr */ 125 { PCONV, INAREG, 126 SAREG, TPTRTO|TCHAR|TUCHAR|TSHORT|TUSHORT, 127 SANY, TPOINT|TWORD|TSTRUCT, 128 0, RLEFT, 129 " tlz AL,0770000\n", }, 130 131 /* Convert short pointer to char ptr */ 132 { PCONV, INAREG, 133 SAREG, TPTRTO|TSHORT|TUSHORT, 134 SANY, TPTRTO|TCHAR|TUCHAR, 135 0, RLEFT, 136 " tlz AL,050000\n", }, 137 138 /* Convert int/struct/foo pointer to char ptr */ 139 { PCONV, INAREG, 140 SAREG, TPOINT|TWORD|TSTRUCT, 141 SANY, TPTRTO|TCHAR|TUCHAR, 142 0, RLEFT, 143 " tlo AL,0700000\n", }, 144 145 /* Convert int/struct/foo pointer to short ptr */ 146 { PCONV, INAREG, 147 SAREG, TPTRTO|TWORD|TSTRUCT, 148 SANY, TPTRTO|TSHORT|TUSHORT, 149 0, RLEFT, 150 " tlo AL,0750000\n", }, 151 152 /* 153 * A bunch conversions of integral<->integral types 154 */ 155 156 /* convert short/char to int. This is done when register is loaded */ 157 { SCONV, INAREG, 158 SAREG, TSHORT|TUSHORT|TCHAR|TUCHAR|TWORD, 159 SANY, TWORD, 160 0, RLEFT, 161 "", }, 162 163 /* convert int to short/char. This is done when register is loaded */ 164 { SCONV, INAREG, 165 SAREG, TWORD, 166 SANY, TSHORT|TUSHORT|TCHAR|TUCHAR|TWORD, 167 0, RLEFT, 168 "", }, 169 170 /* convert int/long to unsigned long long */ 171 { SCONV, INAREG, 172 SAREG|SAREG|SNAME|SOREG, TWORD, 173 SANY, TULONGLONG, 174 NAREG|NASL, RESC1, 175 " move U1,AL\n" 176 " setz A1,\n" 177 " tlze U1,0400000\n" 178 " tro A1,01\n" , }, 179 180 /* convert int/long to long long */ 181 { SCONV, INAREG, 182 SAREG|SAREG|SNAME|SOREG, TWORD, 183 SANY, TLONGLONG, 184 NAREG|NASL, RESC1, 185 " move U1,AL\n" 186 " move A1,U1\n" 187 " ash A1,-043\n", }, 188 189 /* convert uchar/ushort to (unsigned) long long */ 190 { SCONV, INAREG, 191 SAREG|SAREG|SNAME|SOREG, TUCHAR|TUSHORT, 192 SANY, TLL, 193 NAREG|NASL, RESC1, 194 " move U1,AL\n" 195 " setz A1,\n", }, 196 197 /* convert long long to int/long */ 198 { SCONV, INAREG, 199 SAREG|SAREG|SNAME|SOREG, TLL, 200 SANY, TWORD, 201 NAREG|NASL, RESC1, 202 " move A1,UL\n", }, 203 204 /* convert long long to unsigned char - XXX - signed char */ 205 { SCONV, INAREG, 206 SAREG|SAREG|SNAME|SOREG, TLL, 207 SANY, TCHAR|TUCHAR, 208 NAREG|NASL, RESC1, 209 " move A1,UL\n" 210 " andi A1,0777\n", }, 211 212 /* convert long long to short - XXX - signed short */ 213 { SCONV, INAREG, 214 SAREG|SAREG|SNAME|SOREG, TLL, 215 SANY, TSHORT|TUSHORT, 216 NAREG|NASL, RESC1, 217 " move A1,UL\n" 218 " hrrz A1,A1\n", }, 219 220 /* floating point conversions */ 221 { SCONV, INAREG, 222 SAREG|SAREG|SNAME|SOREG, TDOUBLE|TFLOAT, 223 SANY, TWORD, 224 NAREG|NASL, RESC1, 225 " fix A1,AL\n", }, 226 227 { SCONV, INAREG, 228 SAREG|SAREG|SNAME|SOREG, TWORD, 229 SANY, TFLOAT, 230 NAREG|NASL, RESC1, 231 " fltr A1,AL\n", }, 232 233 { SCONV, INAREG, 234 SAREG|SAREG|SNAME|SOREG, TWORD, 235 SANY, TDOUBLE, 236 NAREG|NASL, RESC1, 237 " fltr A1,AL\n setz U1,\n", }, 238 239 { SCONV, INAREG, 240 SAREG|SAREG|SNAME|SOREG, TDOUBLE, 241 SANY, TFLOAT, 242 NAREG|NASL, RESC1, 243 " move A1,AL\n", }, 244 245 { SCONV, INAREG, 246 SAREG|SAREG|SNAME|SOREG, TFLOAT, 247 SANY, TDOUBLE, 248 NAREG|NASL, RESC1, 249 " move A1,AL\n setz U1,\n", }, 250 251 /* 252 * Subroutine calls. 253 */ 254 255 { UCALL, FOREFF, 256 SCON, TANY, 257 SANY, TANY, 258 0, 0, /* should be 0 */ 259 " pushj 017,AL\nZB", }, 260 261 { CALL, FOREFF, 262 SCON, TANY, 263 SANY, TANY, 264 0, 0, /* should be 0 */ 265 " pushj 017,AL\nZB", }, 266 267 { UCALL, INAREG, 268 SCON, TANY, 269 SANY, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT|TFLOAT|TPOINT, 270 NAREG, RESC1, /* should be 0 */ 271 " pushj 017,AL\nZB", }, 272 273 { CALL, INAREG, 274 SCON, TANY, 275 SANY, TANY, 276 NAREG|NASL, RESC1, /* should be 0 */ 277 " pushj 017,AL\nZB", }, 278 279 { UCALL, INAREG, 280 SAREG|SAREG, TANY, 281 SANY, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT|TFLOAT|TDOUBLE|TLL|TPOINT, 282 NAREG|NASL, RESC1, /* should be 0 */ 283 " pushj 017,(AL)\nZB", }, 284 285 { UCALL, INAREG, 286 SNAME|SOREG, TANY, 287 SANY, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT|TFLOAT|TDOUBLE|TLL|TPOINT, 288 NAREG, RESC1, /* should be 0 */ 289 " pushj 017,@AL\nZB", }, 290 291 #ifdef notyet 292 /* 293 * INCR can be slightly optimized. 294 */ 295 { INCR, INAREG, 296 SAREG|SAREG|SNAME|SOREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TPTRTO, 297 SONE, TANY, 298 NAREG, RESC1, 299 " move A1,AL\n" 300 " ibp AL\n", }, 301 302 /* Fix check of return value */ 303 { INCR, FOREFF, 304 SAREG|SAREG|SNAME|SOREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TPTRTO, 305 SONE, TANY, 306 0, 0, 307 " ibp AL\n", }, 308 #endif 309 310 /* 311 * PLUS operators. 312 */ 313 /* Add a value to a char/short pointer */ 314 { PLUS, INAREG|INAREG|FOREFF, 315 SAREG|SAREG|SNAME|SOREG, TPTRTO|TCHAR|TUCHAR|TSHORT|TUSHORT, 316 SAREG|SAREG, TWORD, 317 0, RRIGHT, 318 " adjbp AR,AL\n", }, 319 320 /* No more search for char/short pointer addition */ 321 { PLUS, INAREG|INAREG|FOREFF, 322 SANY, TPTRTO|TCHAR|TUCHAR|TSHORT|TUSHORT, 323 SANY, TANY, 324 REWRITE, 0, 325 "DIEDIEDIE!\n", }, 326 327 /* Add char/short/int to register */ 328 { PLUS, FOREFF|INAREG|INAREG, 329 SAREG|SAREG, TWORD, 330 SAREG|SAREG|SNAME|SOREG, TWORD, 331 0, RLEFT, 332 " add AL,AR\n", }, 333 334 /* Add char/short/int to memory */ 335 { PLUS, FOREFF|INAREG|INAREG, 336 SAREG|SAREG|SNAME|SOREG, TWORD, 337 SAREG|SAREG, TWORD, 338 0, RLEFT, 339 " addm AR,AL\n", }, 340 341 /* Add a small constant to a register */ 342 { PLUS, FOREFF|INAREG|INAREG, 343 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD|TPOINT, 344 SUSHCON, TWORD, 345 0, RLEFT, 346 " addi AL,AR\n", }, 347 348 /* Add a larger constant to a register */ 349 { PLUS, FOREFF|INAREG|INAREG, 350 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD|TPOINT, 351 SCON, TWORD, 352 0, RLEFT, 353 " add AL,[ .long AR ]\n", }, 354 355 /* Add long long to register */ 356 { PLUS, INAREG|INAREG|FOREFF, 357 SAREG|SAREG, TLL, 358 SAREG|SAREG|SNAME|SOREG, TLL, 359 0, RLEFT, 360 " dadd AL,AR\n", }, 361 362 /* Add int (or int pointer) to register */ 363 { PLUS, FOREFF|INAREG|INAREG, 364 SAREG|SAREG, TWORD|TPOINT, 365 SAREG|SAREG|SNAME|SOREG, TWORD, 366 0, RLEFT, 367 " add AL,AR # foo \n", }, 368 369 /* char/short are allowed to be added if they are in registers */ 370 { PLUS, INAREG|INAREG|FOREFF, 371 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 372 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 373 0, RLEFT, 374 " add AL,AR\n", }, 375 376 /* get address of an memory position into a register */ 377 { PLUS, INAREG|INAREG, 378 SAREG|SAREG, TWORD|TPTRTO, 379 SCON, TANY, 380 NAREG, RESC1, 381 " xmovei A1,AR(AL)\n", }, 382 383 /* Safety belt for plus */ 384 { PLUS, FORREW|FOREFF|INAREG|INAREG, 385 SANY, TANY, 386 SANY, TANY, 387 REWRITE, 0, 388 "DIEDIEDIE", }, 389 390 /* 391 * MINUS operators. 392 */ 393 /* Rewrite subtracts from char/short pointers (to negative adds) */ 394 { MINUS, FORREW|FOREFF|INAREG|INAREG, 395 SANY, TCHAR|TUCHAR|TSHORT|TUSHORT|TPTRTO, 396 SANY, TANY, 397 REWRITE, 0, 398 "DIEDIEDIE", }, 399 400 /* Subtract char/short/int word in memory from reg */ 401 { MINUS, FOREFF|INAREG|INAREG, 402 SAREG|SAREG, TWORD|TPOINT, 403 SAREG|SAREG|SNAME|SOREG, TWORD|TPOINT, 404 0, RLEFT, 405 " sub AL,AR\n", }, 406 407 /* Subtract a small constant from reg */ 408 { MINUS, FOREFF|INAREG|INAREG, 409 SAREG|SAREG, TWORD|TPOINT, 410 SUSHCON, TWORD|TPOINT, 411 0, RLEFT, 412 " subi AL,AR\n", }, 413 414 /* Subtract a large constant from reg */ 415 { MINUS, FOREFF|INAREG|INAREG, 416 SAREG|SAREG, TWORD|TPOINT, 417 SCON, TWORD|TPOINT, 418 0, RLEFT, 419 " sub AL,[ .long AR ]\n", }, 420 421 /* Subtract char/short/int word in memory from reg, save in memory */ 422 { MINUS, FOREFF|INAREG|INAREG, 423 SAREG|SAREG, TWORD, 424 SAREG|SAREG|SNAME|SOREG, TWORD, 425 0, RRIGHT, 426 " subm AL,AR\n", }, 427 428 /* Subtract long long from register */ 429 { MINUS, INAREG|INAREG|FOREFF, 430 SAREG|SAREG, TLL, 431 SAREG|SAREG|SNAME|SOREG, TLL, 432 0, RLEFT, 433 " dsub AL,AR\n", }, 434 435 /* char/short are allowed to be subtracted if they are in registers */ 436 { MINUS, INAREG|INAREG|FOREFF, 437 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 438 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 439 0, RLEFT, 440 " sub AL,AR\n", }, 441 442 /* Safety belt for plus */ 443 { MINUS, FORREW|FOREFF|INAREG|INAREG, 444 SANY, TANY, 445 SANY, TANY, 446 REWRITE, 0, 447 "DIEDIEDIE", }, 448 449 /* 450 * AND/OR/ER operators. 451 * Simpler that the ops above in that they only work on integral types. 452 */ 453 /* And char/short/int with integer memory */ 454 { AND, FOREFF|INAREG|INAREG, 455 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 456 SAREG|SAREG|SNAME|SOREG, TWORD, 457 0, RLEFT, 458 " and AL,AR\n", }, 459 460 /* And char/short/int with register */ 461 { AND, FOREFF|INAREG|INAREG, 462 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 463 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 464 0, RLEFT, 465 " and AL,AR\n", }, 466 467 /* And char/short/int with small constant */ 468 { AND, FOREFF|INAREG|INAREG, 469 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 470 SUSHCON, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 471 0, RLEFT, 472 " andi AL,AR\n", }, 473 474 /* And char/short/int with large constant */ 475 { AND, FOREFF|INAREG|INAREG, 476 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 477 SCON, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 478 0, RLEFT, 479 " and AL,[ .long AR ]\n", }, 480 481 /* long long AND */ 482 { AND, INAREG|FOREFF, 483 SAREG|SAREG, TLL, 484 SAREG|SAREG|SNAME|SOREG, TLL, 485 0, RLEFT, 486 " and AL,AR\n" 487 " and UL,UR\n", }, 488 489 /* Safety belt for AND */ 490 { AND, FORREW|FOREFF|INAREG|INAREG, 491 SANY, TANY, 492 SANY, TANY, 493 REWRITE, 0, 494 "DIEDIEDIE", }, 495 496 497 /* OR char/short/int with integer memory */ 498 { OR, FOREFF|INAREG|INAREG, 499 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 500 SAREG|SAREG|SNAME|SOREG, TWORD, 501 0, RLEFT, 502 " ior AL,AR\n", }, 503 504 /* OR char/short/int with register */ 505 { OR, FOREFF|INAREG|INAREG, 506 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 507 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 508 0, RLEFT, 509 " ior AL,AR\n", }, 510 511 /* OR char/short/int with small constant */ 512 { OR, FOREFF|INAREG|INAREG, 513 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 514 SUSHCON, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 515 0, RLEFT, 516 " iori AL,AR\n", }, 517 518 /* OR char/short/int with large constant */ 519 { OR, FOREFF|INAREG|INAREG, 520 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 521 SCON, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 522 0, RLEFT, 523 " ior AL,[ .long AR ]\n", }, 524 525 /* long long OR */ 526 { OR, INAREG|FOREFF, 527 SAREG|SAREG, TLL, 528 SAREG|SAREG|SNAME|SOREG, TLL, 529 0, RLEFT, 530 " ior AL,AR\n" 531 " ior UL,UR\n", }, 532 533 /* Safety belt for OR */ 534 { OR, FORREW|FOREFF|INAREG|INAREG, 535 SANY, TANY, 536 SANY, TANY, 537 REWRITE, 0, 538 "DIEDIEDIE", }, 539 540 541 /* ER char/short/int with integer memory */ 542 { ER, FOREFF|INAREG|INAREG, 543 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 544 SAREG|SAREG|SNAME|SOREG, TWORD, 545 0, RLEFT, 546 " xor AL,AR\n", }, 547 548 /* ER char/short/int with register */ 549 { ER, FOREFF|INAREG|INAREG, 550 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 551 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 552 0, RLEFT, 553 " xor AL,AR\n", }, 554 555 /* ER char/short/int with small constant */ 556 { ER, FOREFF|INAREG|INAREG, 557 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 558 SUSHCON, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 559 0, RLEFT, 560 " xori AL,AR\n", }, 561 562 /* ER char/short/int with large constant */ 563 { ER, FOREFF|INAREG|INAREG, 564 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 565 SCON, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, 566 0, RLEFT, 567 " xor AL,[ .long AR ]\n", }, 568 569 /* long long ER */ 570 { ER, INAREG|FOREFF, 571 SAREG|SAREG, TLL, 572 SAREG|SAREG|SNAME|SOREG, TLL, 573 0, RLEFT, 574 " xor AL,AR\n" 575 " xor UL,UR\n", }, 576 577 /* Safety belt for ER */ 578 { ER, FORREW|FOREFF|INAREG|INAREG, 579 SANY, TANY, 580 SANY, TANY, 581 REWRITE, 0, 582 "DIEDIEDIE", }, 583 584 /* 585 * The next rules handle all shift operators. 586 */ 587 { LS, INAREG|INAREG|FOREFF, 588 SAREG|SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT, 589 SAREG|SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT, 590 0, RLEFT, 591 " lsh AL,(AR)\n", }, 592 593 { LS, INAREG|INAREG|FOREFF, 594 SAREG|SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT, 595 SNAME|SOREG, TWORD, 596 0, RLEFT, 597 " lsh AL,@AR\n", }, 598 599 { LS, INAREG|INAREG|FOREFF, 600 SAREG|SAREG, TLL, 601 SCON, TANY, 602 0, RLEFT, 603 " ashc AL,ZH\n", }, 604 605 { LS, INAREG|INAREG|FOREFF, 606 SAREG|SAREG, TLL, 607 SAREG|SAREG /* |SNAME|SOREG */, TANY, 608 0, RLEFT, 609 " ashc AL,(AR)\n", }, 610 611 { RS, INAREG|INAREG|FOREFF, 612 SAREG|SAREG, TSWORD, 613 SCON, TWORD, 614 0, RLEFT, 615 " ash AL,-ZH\n", }, 616 617 { RS, INAREG|INAREG|FOREFF, 618 SAREG|SAREG, TUWORD, 619 SCON, TWORD, 620 0, RLEFT, 621 " lsh AL,-ZH\n", }, 622 623 /* Safety belt for LS/RS */ 624 { LS, FORREW|FOREFF|INAREG|INAREG, 625 SANY, TANY, 626 SANY, TANY, 627 REWRITE, 0, 628 "DIEDIEDIE", }, 629 630 { RS, FORREW|FOREFF|INAREG|INAREG, 631 SANY, TANY, 632 SANY, TANY, 633 REWRITE, 0, 634 "DIEDIEDIE", }, 635 636 /* 637 * The next rules takes care of assignments. "=". 638 */ 639 /* Match zeroed registers first */ 640 { ASSIGN, INAREG|FOREFF, 641 SAREG, TUCHAR|TUSHORT|TCHAR|TSHORT|TWORD|TPOINT, 642 SZERO, TANY, 643 0, RDEST, 644 " setz AL,\n", }, 645 646 { ASSIGN, FOREFF, 647 SAREG|SNAME|SOREG, TWORD|TPOINT, 648 SZERO, TANY, 649 0, 0, 650 " setzm AL\n", }, 651 652 { ASSIGN, INAREG|FOREFF, 653 SAREG|SAREG, TUCHAR|TUSHORT|TCHAR|TSHORT|TWORD|TPOINT, 654 SMONE, TANY, 655 0, RDEST, 656 " setom AL\n", }, 657 658 { ASSIGN, FOREFF, 659 SAREG|SNAME|SOREG, TWORD|TPOINT, 660 SMONE, TANY, 661 0, 0, 662 " setom AL\n", }, 663 664 { ASSIGN, INAREG|INAREG|FOREFF, 665 SAREG|SAREG, TWORD|TPOINT, 666 SCON, TWORD|TPOINT, 667 0, RDEST, 668 " ZC\n", }, 669 670 { ASSIGN, INAREG|INAREG|FOREFF, 671 SAREG|SNAME|SOREG, TWORD|TPOINT|TFLOAT, 672 SAREG|SAREG, TUCHAR|TUSHORT|TWORD|TPOINT|TFLOAT, 673 0, RDEST, 674 " movem AR,AL\n", }, 675 676 { ASSIGN, INAREG|INAREG|FOREFF, 677 SAREG|SNAME|SOREG, TWORD|TPOINT|TFLOAT, 678 SAREG|SAREG, TSHORT, 679 0, RDEST, 680 " hrrem AR,AL\n", }, 681 682 { ASSIGN, INAREG|INAREG|FOREFF, 683 SAREG|SAREG, TUCHAR|TUSHORT|TCHAR|TSHORT|TWORD|TPOINT, 684 SAREG|SAREG|SNAME|SOREG, TWORD|TPOINT, 685 0, RDEST, 686 " move AL,AR\n", }, 687 688 { ASSIGN, INAREG|INAREG|FOREFF, 689 SAREG|SAREG, TUCHAR|TUSHORT|TCHAR|TSHORT, 690 SAREG|SAREG, TUCHAR|TUSHORT|TCHAR|TSHORT, 691 0, RDEST, 692 " move AL,AR\n", }, 693 694 { ASSIGN, INBREG|FOREFF, 695 SBREG|SNAME|SOREG, TLL|TDOUBLE, 696 SBREG, TLL|TDOUBLE, 697 0, RDEST, 698 " dmovem AR,AL\n", }, 699 700 { ASSIGN, INAREG|INAREG|FOREFF, 701 SOREG|SNAME, TSHORT|TUSHORT|TCHAR|TUCHAR, 702 SAREG|SAREG, TANY, 703 0, RDEST, 704 "ZV", }, 705 706 { ASSIGN, INAREG|INAREG|FOREFF, 707 SAREG|SAREG, TUSHORT|TUCHAR, 708 SOREG, TANY, 709 0, RDEST, 710 " ldb AL,Zg\n", }, 711 712 { ASSIGN, INAREG|INAREG|FOREFF, 713 SAREG|SAREG, TSHORT|TUSHORT|TCHAR|TUCHAR, 714 SSCON, TANY, 715 0, RDEST, 716 " movei AL,AR\n", }, 717 718 { ASSIGN, INAREG|INAREG|FOREFF, 719 SAREG|SAREG, TSHORT|TUSHORT|TCHAR|TUCHAR, 720 SCON, TANY, 721 0, RDEST, 722 " move AL,[ .long AR]\n", }, 723 724 /* 725 * DIV/MOD/MUL 726 * These can be done way more efficient. 727 */ 728 /* long long div. XXX - work only with unsigned */ 729 { DIV, INBREG, 730 SBREG|SNAME|SOREG, TLL, 731 SBREG|SNAME|SOREG, TLL, 732 (2*NBREG)|NBSL, RESC1, 733 " dmove A2,AL ; dmove A1,[ .long 0,0 ]\n" 734 " ddiv A1,AR\n", }, 735 736 /* long long div. with constant. XXX - work only with unsigned */ 737 { DIV, INBREG, 738 SBREG|SNAME|SOREG, TLL, 739 SCON, TLL, 740 (2*NBREG)|NBSL, RESC1, 741 " dmove A2,AL ; dmove A1,[ .long 0,0 ]\n" 742 " ddiv A1,ZP\n", }, 743 744 /* Simple divide. XXX - fix so next reg can be free */ 745 { DIV, INAREG|INAREG|FOREFF, 746 SAREG|SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT, 747 SAREG|SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT, 748 0, RRIGHT, 749 " idivm AL,AR\n", }, 750 751 /* Safety belt for DIV */ 752 { DIV, FORREW|FOREFF|INAREG|INAREG, 753 SANY, TANY, 754 SANY, TANY, 755 REWRITE, 0, 756 "DIEDIEDIE", }, 757 758 /* long long MOD */ 759 { MOD, INBREG, 760 SBREG|SNAME|SOREG, TLL, 761 SBREG|SNAME|SOREG, TLL, 762 2*NBREG|NBSL, RESC2, 763 " dmove A2,AL ; dmove A1,[ .long 0,0 ]\n" 764 " ddiv A1,AR\n", }, 765 766 /* integer MOD */ 767 { MOD, INAREG, 768 SAREG|SNAME|SOREG, TWORD, 769 SAREG|SNAME|SOREG, TWORD, 770 2*NAREG|NASL, RESC2, 771 " move A2,AL\n" 772 " setz A1,\n" 773 " idiv A1,AR\n", }, 774 775 /* integer MOD for char/short */ 776 { MOD, INAREG, 777 SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT, 778 SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT, 779 2*NAREG|NASL, RESC2, 780 " move A2,AL\n" 781 " setz A1,\n" 782 " idiv A1,AR\n", }, 783 784 /* Safety belt for MOD */ 785 { MOD, FOREFF, 786 SANY, TANY, 787 SANY, TANY, 788 REWRITE, 0, 789 "DIEDIEDIE", }, 790 791 /* long long MUL */ 792 { MUL, INBREG, 793 SBREG|SNAME|SOREG, TLL, 794 SBREG|SNAME|SOREG, TLL, 795 2*NBREG|NBSL, RESC2, 796 " dmove A1,AL\n" 797 " dmul A1,AR\n", }, 798 799 /* integer multiply to memory*/ 800 { MUL, INAREG|INAREG|FOREFF, 801 SAREG|SAREG|SNAME|SOREG, TWORD, 802 SAREG|SAREG, TWORD, 803 0, RLEFT, 804 " imulm AR,AL\n", }, 805 806 /* integer multiply */ 807 { MUL, INAREG|INAREG|FOREFF, 808 SAREG|SAREG, TWORD, 809 SAREG|SAREG|SNAME|SOREG, TWORD, 810 0, RLEFT, 811 " imul AL,AR\n", }, 812 813 /* integer multiply for char/short */ 814 { MUL, INAREG|INAREG|FOREFF, 815 SAREG|SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT, 816 SAREG|SAREG, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT, 817 0, RLEFT, 818 " imul AL,AR\n", }, 819 820 /* integer multiply with small constant */ 821 { MUL, INAREG|INAREG|FOREFF, 822 SAREG|SAREG, TWORD, 823 SUSHCON, TWORD, 824 0, RLEFT, 825 " imuli AL,AR\n", }, 826 827 /* integer multiply with large constant */ 828 { MUL, INAREG|INAREG|FOREFF, 829 SAREG|SAREG, TWORD, 830 SCON, TWORD, 831 0, RLEFT, 832 " imul AL,[ .long AR ]\n", }, 833 834 /* Safety belt for MUL */ 835 { MUL, FORREW|FOREFF|INAREG|INAREG, 836 SANY, TANY, 837 SANY, TANY, 838 REWRITE, 0, 839 "DIEDIEDIE", }, 840 841 /* read an indirect long long value into register */ 842 { UMUL, INAREG, 843 SAREG|SAREG, TPTRTO|TLL|TWORD, 844 SANY, TLL, 845 NAREG|NASL, RESC1, 846 " dmove A1,(AL)\n", }, 847 848 /* read an indirect integer value into register */ 849 { UMUL, INAREG, 850 SAREG|SAREG, TWORD|TPOINT, 851 SANY, TWORD|TPOINT, 852 NAREG|NASL, RESC1, 853 " move A1,(AL)\n", }, 854 855 /* read an indirect value into register */ 856 { UMUL, INAREG, 857 SOREG, TWORD|TPOINT, 858 SANY, TWORD|TPOINT, 859 NAREG, RESC1, 860 " move A1,@AL\n", }, 861 862 /* read an indirect value into register */ 863 { UMUL, INAREG, 864 SAREG|SAREG|SOREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TPTRTO, 865 SANY, TCHAR|TUCHAR|TSHORT|TUSHORT, 866 NAREG|NASL, RESC1, 867 " ldb A1,AL\n", }, 868 869 #ifdef notyet 870 /* Match tree shape for ildb */ 871 { UMUL, INAREG, 872 SANY, TANY, 873 SILDB, TUCHAR|TCHAR|TPTRTO, 874 NAREG, RESC1, 875 " ildb A1,ZA\n", }, 876 #endif 877 878 /* Match char/short pointers first, requires special handling */ 879 { OPLOG, FORCC, 880 SAREG|SAREG, TPTRTO|TCHAR|TUCHAR|TSHORT|TUSHORT, 881 SAREG|SAREG, TPTRTO|TCHAR|TUCHAR|TSHORT|TUSHORT, 882 0, RESCC, 883 "ZZ", }, 884 885 /* Can check anything by just comparing if EQ/NE */ 886 { OPLOG, FORCC, 887 SAREG|SAREG, TWORD|TPOINT|TCHAR|TUCHAR|TSHORT|TUSHORT, 888 SZERO, TANY, 889 0, RESCC, 890 " jumpZe AL,LC # bu\n", }, 891 892 { EQ, FORCC, 893 SAREG|SAREG, TWORD|TPOINT|TCHAR|TUCHAR|TSHORT|TUSHORT, 894 SAREG|SAREG|SOREG|SNAME|SCON, TWORD|TPOINT, 895 0, RESCC, 896 "ZR", }, 897 898 { NE, FORCC, 899 SAREG|SAREG, TWORD|TPOINT|TCHAR|TUCHAR|TSHORT|TUSHORT, 900 SAREG|SAREG|SOREG|SNAME|SCON, TWORD|TPOINT, 901 0, RESCC, 902 "ZR", }, 903 904 { OPLOG, FORCC, 905 SAREG|SAREG, TWORD, 906 SAREG|SAREG|SOREG|SNAME|SCON, TSWORD, 907 0, RESCC, 908 "ZR", }, 909 910 { OPLOG, FORCC, 911 SAREG|SAREG, TCHAR|TUCHAR, 912 SCON, TANY, 913 0, RESCC, 914 "ZR", }, 915 916 { OPLOG, FORCC, 917 SAREG|SAREG, TWORD|TPOINT|TFLOAT, 918 SAREG|SAREG|SOREG|SNAME|SCON, TWORD|TPOINT|TFLOAT, 919 0, RESCC, 920 "ZR", }, 921 922 { OPLOG, FORCC, 923 SAREG|SAREG, TWORD|TPOINT|TCHAR|TUCHAR|TSHORT|TUSHORT, 924 SAREG|SAREG, TWORD|TPOINT|TCHAR|TUCHAR|TSHORT|TUSHORT, 925 0, RESCC, 926 "ZR", }, 927 928 { OPLOG, FORCC, 929 SAREG|SAREG, TLL|TDOUBLE, /* XXX - does double work here? */ 930 SAREG|SAREG|SOREG|SNAME, TLL|TDOUBLE, 931 0, RESCC, 932 "ZQ", }, 933 934 /* 935 * Jumps. 936 */ 937 { GOTO, FOREFF, 938 SCON, TANY, 939 SANY, TANY, 940 0, RNOP, 941 " jrst LL\n", }, 942 943 /* 944 * Convert LTYPE to reg. 945 */ 946 { OPLTYPE, INBREG, 947 SANY, TANY, 948 SMONE, TLL, 949 NBREG, RESC1, 950 " seto A1,\n seto U1,\n", }, 951 952 { OPLTYPE, INAREG, 953 SANY, TANY, 954 SMONE, TANY, 955 NAREG, RESC1, 956 " seto A1,\n", }, 957 958 { OPLTYPE, INBREG, 959 SANY, TANY, 960 SZERO, TLL, 961 NBREG, RESC1, 962 " setz A1,\n setz U1,\n", }, 963 964 { OPLTYPE, INAREG, 965 SANY, TANY, 966 SZERO, TANY, 967 NAREG, RESC1, 968 " setz A1,\n", }, 969 970 { OPLTYPE, INBREG, 971 SANY, TANY, 972 SUSHCON, TLL, 973 NBREG, RESC1, 974 " setz A1,\n movei U1,AR\n", }, 975 976 { OPLTYPE, INAREG, 977 SANY, TANY, 978 SUSHCON, ANYFIXED, 979 NAREG, RESC1, 980 " movei A1,AR\n", }, 981 982 { OPLTYPE, INAREG, 983 SANY, ANYFIXED, 984 SNSHCON, ANYFIXED, 985 NAREG, RESC1, 986 " hrroi A1,AR\n", }, 987 988 { OPLTYPE, INAREG, 989 SANY, ANYFIXED, 990 SCON, ANYFIXED, 991 NAREG|NASR, RESC1, 992 " ZD A1,ZE # suspekt\n", }, 993 994 { OPLTYPE, INAREG, 995 SANY, TWORD|TPOINT|TFLOAT, 996 SAREG|SAREG|SOREG|SNAME, TWORD|TPOINT|TFLOAT, 997 NAREG|NASR, RESC1, 998 " move A1,AR\n", }, 999 1000 { OPLTYPE, INBREG, 1001 SANY, TLL, 1002 SCON, TLL, 1003 NBREG, RESC1, 1004 " dmove A1,ZO\n", }, 1005 1006 { OPLTYPE, INBREG, 1007 SANY, TLL|TDOUBLE, 1008 SANY, TLL|TDOUBLE, 1009 NBREG|NBSR, RESC1, 1010 " dmove A1,AR\n", }, 1011 1012 { OPLTYPE, INAREG, 1013 SOREG, TSHORT|TUSHORT|TCHAR|TUCHAR, 1014 SOREG, TSHORT|TUSHORT|TCHAR|TUCHAR, 1015 NASR, RESC1, 1016 "ZU", }, 1017 1018 { OPLTYPE, INAREG, 1019 SNAME, TUCHAR, 1020 SNAME, TUCHAR, 1021 NAREG|NASR, RESC1, 1022 " ldb A1,[ .long AL ]\n" }, 1023 1024 { OPLTYPE, INAREG, 1025 SNAME, TCHAR, 1026 SNAME, TCHAR, 1027 NAREG|NASR, RESC1, 1028 " ldb A1,[ .long AL ]\n" 1029 " ash A1,033\n" 1030 " ash A1,-033\n", }, 1031 1032 { OPLTYPE, INAREG, 1033 SANY, TANY, 1034 SNAME, TSHORT|TUSHORT, 1035 NAREG|NASR, RESC1, 1036 "Zi", }, 1037 1038 { OPLTYPE, INAREG, 1039 SANY, TWORD|TPOINT, 1040 SCON, TWORD|TPOINT, 1041 NAREG|NASR, RESC1, 1042 "Zc", }, 1043 1044 { OPLTYPE, INAREG, 1045 SAREG|SAREG, TUSHORT|TUCHAR, 1046 SAREG|SAREG, TUSHORT|TUCHAR|TWORD, 1047 NAREG, RESC1, 1048 " move A1,AL\n", }, 1049 1050 /* 1051 * Negate a word. 1052 */ 1053 { UMINUS, INAREG, 1054 SAREG|SAREG|SNAME|SOREG, TWORD, 1055 SANY, TWORD, 1056 NAREG|NASL, RESC1, 1057 " movn A1,AL\n", }, 1058 1059 { UMINUS, INAREG, 1060 SAREG|SAREG, TWORD, 1061 SANY, TCHAR|TUCHAR|TSHORT|TUSHORT, 1062 0, RLEFT, 1063 " movn AL,AL\n", }, 1064 1065 { UMINUS, INAREG, 1066 SAREG|SNAME|SOREG, TLL, 1067 SANY, TLL, 1068 NAREG|NASR, RESC1, 1069 " dmovn A1,AL\n", }, 1070 1071 { COMPL, INAREG, 1072 SAREG|SAREG|SNAME|SOREG, TLL, 1073 SANY, TANY, 1074 NAREG|NASL, RESC1, 1075 " setcm A1,AL\n" 1076 " setcm U1,UL\n", }, 1077 1078 { COMPL, INAREG, 1079 SAREG|SAREG|SNAME|SOREG, TWORD, 1080 SANY, TANY, 1081 NAREG|NASL, RESC1, 1082 " setcm A1,AL\n", }, 1083 1084 { COMPL, INAREG, 1085 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT, 1086 SANY, TCHAR|TUCHAR|TSHORT|TUSHORT, 1087 NAREG|NASL, RESC1, 1088 " setcm A1,AL\n", }, 1089 1090 /* 1091 * Arguments to functions. 1092 */ 1093 { FUNARG, FOREFF, 1094 SAREG|SNAME|SOREG, TWORD|TPOINT|TFLOAT, 1095 SANY, TANY, 1096 0, RNULL, 1097 " push 017,AL\n", }, 1098 1099 { FUNARG, FOREFF, 1100 SAREG|SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT, 1101 SANY, TANY, 1102 0, RNULL, 1103 " push 017,AL\n", }, 1104 1105 { FUNARG, FOREFF, 1106 SCON, TCHAR|TUCHAR|TSHORT|TUSHORT|TPOINT|TWORD, 1107 SANY, TANY, 1108 0, RNULL, 1109 " push 017,[ .long AL]\n", }, 1110 1111 { FUNARG, FOREFF, 1112 SBREG, TLL|TDOUBLE, 1113 SANY, TANY, 1114 0, RNULL, 1115 " push 017,AL\n push 017,UL\n", }, 1116 1117 { STARG, FOREFF, 1118 SAREG|SOREG|SNAME|SCON, TANY, 1119 SANY, TSTRUCT, 1120 0, 0, 1121 "ZG", }, 1122 1123 1124 # define DF(x) FORREW,SANY,TANY,SANY,TANY,REWRITE,x,"" 1125 1126 { UMUL, DF( UMUL ), }, 1127 1128 { ASSIGN, DF(ASSIGN), }, 1129 1130 { OPLEAF, DF(NAME), }, 1131 1132 { OPUNARY, DF(UMINUS), }, 1133 1134 { FREE, FREE, FREE, FREE, FREE, FREE, FREE, FREE, "help; I'm in trouble\n" }, 1135 }; 1136 1137 int tablesize = sizeof(table)/sizeof(table[0]); 1138