github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/cmd/5g/cgen64.c (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include <u.h> 6 #include <libc.h> 7 #include "gg.h" 8 9 /* 10 * attempt to generate 64-bit 11 * res = n 12 * return 1 on success, 0 if op not handled. 13 */ 14 void 15 cgen64(Node *n, Node *res) 16 { 17 Node t1, t2, *l, *r; 18 Node lo1, lo2, hi1, hi2; 19 Node al, ah, bl, bh, cl, ch, s, n1, creg; 20 Prog *p1, *p2, *p3, *p4, *p5, *p6; 21 22 uint64 v; 23 24 if(res->op != OINDREG && res->op != ONAME) { 25 dump("n", n); 26 dump("res", res); 27 fatal("cgen64 %O of %O", n->op, res->op); 28 } 29 30 l = n->left; 31 if(!l->addable) { 32 tempname(&t1, l->type); 33 cgen(l, &t1); 34 l = &t1; 35 } 36 37 split64(l, &lo1, &hi1); 38 switch(n->op) { 39 default: 40 fatal("cgen64 %O", n->op); 41 42 case OMINUS: 43 split64(res, &lo2, &hi2); 44 45 regalloc(&t1, lo1.type, N); 46 regalloc(&al, lo1.type, N); 47 regalloc(&ah, hi1.type, N); 48 49 gins(AMOVW, &lo1, &al); 50 gins(AMOVW, &hi1, &ah); 51 52 gmove(ncon(0), &t1); 53 p1 = gins(ASUB, &al, &t1); 54 p1->scond |= C_SBIT; 55 gins(AMOVW, &t1, &lo2); 56 57 gmove(ncon(0), &t1); 58 gins(ASBC, &ah, &t1); 59 gins(AMOVW, &t1, &hi2); 60 61 regfree(&t1); 62 regfree(&al); 63 regfree(&ah); 64 splitclean(); 65 splitclean(); 66 return; 67 68 case OCOM: 69 regalloc(&t1, lo1.type, N); 70 gmove(ncon(-1), &t1); 71 72 split64(res, &lo2, &hi2); 73 regalloc(&n1, lo1.type, N); 74 75 gins(AMOVW, &lo1, &n1); 76 gins(AEOR, &t1, &n1); 77 gins(AMOVW, &n1, &lo2); 78 79 gins(AMOVW, &hi1, &n1); 80 gins(AEOR, &t1, &n1); 81 gins(AMOVW, &n1, &hi2); 82 83 regfree(&t1); 84 regfree(&n1); 85 splitclean(); 86 splitclean(); 87 return; 88 89 case OADD: 90 case OSUB: 91 case OMUL: 92 case OLSH: 93 case ORSH: 94 case OAND: 95 case OOR: 96 case OXOR: 97 case OLROT: 98 // binary operators. 99 // common setup below. 100 break; 101 } 102 103 // setup for binary operators 104 r = n->right; 105 if(r != N && !r->addable) { 106 tempname(&t2, r->type); 107 cgen(r, &t2); 108 r = &t2; 109 } 110 if(is64(r->type)) 111 split64(r, &lo2, &hi2); 112 113 regalloc(&al, lo1.type, N); 114 regalloc(&ah, hi1.type, N); 115 116 // Do op. Leave result in ah:al. 117 switch(n->op) { 118 default: 119 fatal("cgen64: not implemented: %N\n", n); 120 121 case OADD: 122 // TODO: Constants 123 regalloc(&bl, types[TPTR32], N); 124 regalloc(&bh, types[TPTR32], N); 125 gins(AMOVW, &hi1, &ah); 126 gins(AMOVW, &lo1, &al); 127 gins(AMOVW, &hi2, &bh); 128 gins(AMOVW, &lo2, &bl); 129 p1 = gins(AADD, &bl, &al); 130 p1->scond |= C_SBIT; 131 gins(AADC, &bh, &ah); 132 regfree(&bl); 133 regfree(&bh); 134 break; 135 136 case OSUB: 137 // TODO: Constants. 138 regalloc(&bl, types[TPTR32], N); 139 regalloc(&bh, types[TPTR32], N); 140 gins(AMOVW, &lo1, &al); 141 gins(AMOVW, &hi1, &ah); 142 gins(AMOVW, &lo2, &bl); 143 gins(AMOVW, &hi2, &bh); 144 p1 = gins(ASUB, &bl, &al); 145 p1->scond |= C_SBIT; 146 gins(ASBC, &bh, &ah); 147 regfree(&bl); 148 regfree(&bh); 149 break; 150 151 case OMUL: 152 // TODO(kaib): this can be done with 4 regs and does not need 6 153 regalloc(&bl, types[TPTR32], N); 154 regalloc(&bh, types[TPTR32], N); 155 regalloc(&cl, types[TPTR32], N); 156 regalloc(&ch, types[TPTR32], N); 157 158 // load args into bh:bl and bh:bl. 159 gins(AMOVW, &hi1, &bh); 160 gins(AMOVW, &lo1, &bl); 161 gins(AMOVW, &hi2, &ch); 162 gins(AMOVW, &lo2, &cl); 163 164 // bl * cl -> ah al 165 p1 = gins(AMULLU, N, N); 166 p1->from.type = D_REG; 167 p1->from.reg = bl.val.u.reg; 168 p1->reg = cl.val.u.reg; 169 p1->to.type = D_REGREG; 170 p1->to.reg = ah.val.u.reg; 171 p1->to.offset = al.val.u.reg; 172 //print("%P\n", p1); 173 174 // bl * ch + ah -> ah 175 p1 = gins(AMULA, N, N); 176 p1->from.type = D_REG; 177 p1->from.reg = bl.val.u.reg; 178 p1->reg = ch.val.u.reg; 179 p1->to.type = D_REGREG2; 180 p1->to.reg = ah.val.u.reg; 181 p1->to.offset = ah.val.u.reg; 182 //print("%P\n", p1); 183 184 // bh * cl + ah -> ah 185 p1 = gins(AMULA, N, N); 186 p1->from.type = D_REG; 187 p1->from.reg = bh.val.u.reg; 188 p1->reg = cl.val.u.reg; 189 p1->to.type = D_REGREG2; 190 p1->to.reg = ah.val.u.reg; 191 p1->to.offset = ah.val.u.reg; 192 //print("%P\n", p1); 193 194 regfree(&bh); 195 regfree(&bl); 196 regfree(&ch); 197 regfree(&cl); 198 199 break; 200 201 case OLROT: 202 // We only rotate by a constant c in [0,64). 203 // if c >= 32: 204 // lo, hi = hi, lo 205 // c -= 32 206 // if c == 0: 207 // no-op 208 // else: 209 // t = hi 210 // shld hi:lo, c 211 // shld lo:t, c 212 v = mpgetfix(r->val.u.xval); 213 regalloc(&bl, lo1.type, N); 214 regalloc(&bh, hi1.type, N); 215 if(v >= 32) { 216 // reverse during load to do the first 32 bits of rotate 217 v -= 32; 218 gins(AMOVW, &hi1, &bl); 219 gins(AMOVW, &lo1, &bh); 220 } else { 221 gins(AMOVW, &hi1, &bh); 222 gins(AMOVW, &lo1, &bl); 223 } 224 if(v == 0) { 225 gins(AMOVW, &bh, &ah); 226 gins(AMOVW, &bl, &al); 227 } else { 228 // rotate by 1 <= v <= 31 229 // MOVW bl<<v, al 230 // MOVW bh<<v, ah 231 // OR bl>>(32-v), ah 232 // OR bh>>(32-v), al 233 gshift(AMOVW, &bl, SHIFT_LL, v, &al); 234 gshift(AMOVW, &bh, SHIFT_LL, v, &ah); 235 gshift(AORR, &bl, SHIFT_LR, 32-v, &ah); 236 gshift(AORR, &bh, SHIFT_LR, 32-v, &al); 237 } 238 regfree(&bl); 239 regfree(&bh); 240 break; 241 242 case OLSH: 243 regalloc(&bl, lo1.type, N); 244 regalloc(&bh, hi1.type, N); 245 gins(AMOVW, &hi1, &bh); 246 gins(AMOVW, &lo1, &bl); 247 248 if(r->op == OLITERAL) { 249 v = mpgetfix(r->val.u.xval); 250 if(v >= 64) { 251 // TODO(kaib): replace with gins(AMOVW, nodintconst(0), &al) 252 // here and below (verify it optimizes to EOR) 253 gins(AEOR, &al, &al); 254 gins(AEOR, &ah, &ah); 255 } else 256 if(v > 32) { 257 gins(AEOR, &al, &al); 258 // MOVW bl<<(v-32), ah 259 gshift(AMOVW, &bl, SHIFT_LL, (v-32), &ah); 260 } else 261 if(v == 32) { 262 gins(AEOR, &al, &al); 263 gins(AMOVW, &bl, &ah); 264 } else 265 if(v > 0) { 266 // MOVW bl<<v, al 267 gshift(AMOVW, &bl, SHIFT_LL, v, &al); 268 269 // MOVW bh<<v, ah 270 gshift(AMOVW, &bh, SHIFT_LL, v, &ah); 271 272 // OR bl>>(32-v), ah 273 gshift(AORR, &bl, SHIFT_LR, 32-v, &ah); 274 } else { 275 gins(AMOVW, &bl, &al); 276 gins(AMOVW, &bh, &ah); 277 } 278 goto olsh_break; 279 } 280 281 regalloc(&s, types[TUINT32], N); 282 regalloc(&creg, types[TUINT32], N); 283 if (is64(r->type)) { 284 // shift is >= 1<<32 285 split64(r, &cl, &ch); 286 gmove(&ch, &s); 287 gins(ATST, &s, N); 288 p6 = gbranch(ABNE, T, 0); 289 gmove(&cl, &s); 290 splitclean(); 291 } else { 292 gmove(r, &s); 293 p6 = P; 294 } 295 gins(ATST, &s, N); 296 297 // shift == 0 298 p1 = gins(AMOVW, &bl, &al); 299 p1->scond = C_SCOND_EQ; 300 p1 = gins(AMOVW, &bh, &ah); 301 p1->scond = C_SCOND_EQ; 302 p2 = gbranch(ABEQ, T, 0); 303 304 // shift is < 32 305 nodconst(&n1, types[TUINT32], 32); 306 gmove(&n1, &creg); 307 gcmp(ACMP, &s, &creg); 308 309 // MOVW.LO bl<<s, al 310 p1 = gregshift(AMOVW, &bl, SHIFT_LL, &s, &al); 311 p1->scond = C_SCOND_LO; 312 313 // MOVW.LO bh<<s, ah 314 p1 = gregshift(AMOVW, &bh, SHIFT_LL, &s, &ah); 315 p1->scond = C_SCOND_LO; 316 317 // SUB.LO s, creg 318 p1 = gins(ASUB, &s, &creg); 319 p1->scond = C_SCOND_LO; 320 321 // OR.LO bl>>creg, ah 322 p1 = gregshift(AORR, &bl, SHIFT_LR, &creg, &ah); 323 p1->scond = C_SCOND_LO; 324 325 // BLO end 326 p3 = gbranch(ABLO, T, 0); 327 328 // shift == 32 329 p1 = gins(AEOR, &al, &al); 330 p1->scond = C_SCOND_EQ; 331 p1 = gins(AMOVW, &bl, &ah); 332 p1->scond = C_SCOND_EQ; 333 p4 = gbranch(ABEQ, T, 0); 334 335 // shift is < 64 336 nodconst(&n1, types[TUINT32], 64); 337 gmove(&n1, &creg); 338 gcmp(ACMP, &s, &creg); 339 340 // EOR.LO al, al 341 p1 = gins(AEOR, &al, &al); 342 p1->scond = C_SCOND_LO; 343 344 // MOVW.LO creg>>1, creg 345 p1 = gshift(AMOVW, &creg, SHIFT_LR, 1, &creg); 346 p1->scond = C_SCOND_LO; 347 348 // SUB.LO creg, s 349 p1 = gins(ASUB, &creg, &s); 350 p1->scond = C_SCOND_LO; 351 352 // MOVW bl<<s, ah 353 p1 = gregshift(AMOVW, &bl, SHIFT_LL, &s, &ah); 354 p1->scond = C_SCOND_LO; 355 356 p5 = gbranch(ABLO, T, 0); 357 358 // shift >= 64 359 if (p6 != P) patch(p6, pc); 360 gins(AEOR, &al, &al); 361 gins(AEOR, &ah, &ah); 362 363 patch(p2, pc); 364 patch(p3, pc); 365 patch(p4, pc); 366 patch(p5, pc); 367 regfree(&s); 368 regfree(&creg); 369 370 olsh_break: 371 regfree(&bl); 372 regfree(&bh); 373 break; 374 375 376 case ORSH: 377 regalloc(&bl, lo1.type, N); 378 regalloc(&bh, hi1.type, N); 379 gins(AMOVW, &hi1, &bh); 380 gins(AMOVW, &lo1, &bl); 381 382 if(r->op == OLITERAL) { 383 v = mpgetfix(r->val.u.xval); 384 if(v >= 64) { 385 if(bh.type->etype == TINT32) { 386 // MOVW bh->31, al 387 gshift(AMOVW, &bh, SHIFT_AR, 31, &al); 388 389 // MOVW bh->31, ah 390 gshift(AMOVW, &bh, SHIFT_AR, 31, &ah); 391 } else { 392 gins(AEOR, &al, &al); 393 gins(AEOR, &ah, &ah); 394 } 395 } else 396 if(v > 32) { 397 if(bh.type->etype == TINT32) { 398 // MOVW bh->(v-32), al 399 gshift(AMOVW, &bh, SHIFT_AR, v-32, &al); 400 401 // MOVW bh->31, ah 402 gshift(AMOVW, &bh, SHIFT_AR, 31, &ah); 403 } else { 404 // MOVW bh>>(v-32), al 405 gshift(AMOVW, &bh, SHIFT_LR, v-32, &al); 406 gins(AEOR, &ah, &ah); 407 } 408 } else 409 if(v == 32) { 410 gins(AMOVW, &bh, &al); 411 if(bh.type->etype == TINT32) { 412 // MOVW bh->31, ah 413 gshift(AMOVW, &bh, SHIFT_AR, 31, &ah); 414 } else { 415 gins(AEOR, &ah, &ah); 416 } 417 } else 418 if( v > 0) { 419 // MOVW bl>>v, al 420 gshift(AMOVW, &bl, SHIFT_LR, v, &al); 421 422 // OR bh<<(32-v), al 423 gshift(AORR, &bh, SHIFT_LL, 32-v, &al); 424 425 if(bh.type->etype == TINT32) { 426 // MOVW bh->v, ah 427 gshift(AMOVW, &bh, SHIFT_AR, v, &ah); 428 } else { 429 // MOVW bh>>v, ah 430 gshift(AMOVW, &bh, SHIFT_LR, v, &ah); 431 } 432 } else { 433 gins(AMOVW, &bl, &al); 434 gins(AMOVW, &bh, &ah); 435 } 436 goto orsh_break; 437 } 438 439 regalloc(&s, types[TUINT32], N); 440 regalloc(&creg, types[TUINT32], N); 441 if(is64(r->type)) { 442 // shift is >= 1<<32 443 split64(r, &cl, &ch); 444 gmove(&ch, &s); 445 gins(ATST, &s, N); 446 if(bh.type->etype == TINT32) 447 p1 = gshift(AMOVW, &bh, SHIFT_AR, 31, &ah); 448 else 449 p1 = gins(AEOR, &ah, &ah); 450 p1->scond = C_SCOND_NE; 451 p6 = gbranch(ABNE, T, 0); 452 gmove(&cl, &s); 453 splitclean(); 454 } else { 455 gmove(r, &s); 456 p6 = P; 457 } 458 gins(ATST, &s, N); 459 460 // shift == 0 461 p1 = gins(AMOVW, &bl, &al); 462 p1->scond = C_SCOND_EQ; 463 p1 = gins(AMOVW, &bh, &ah); 464 p1->scond = C_SCOND_EQ; 465 p2 = gbranch(ABEQ, T, 0); 466 467 // check if shift is < 32 468 nodconst(&n1, types[TUINT32], 32); 469 gmove(&n1, &creg); 470 gcmp(ACMP, &s, &creg); 471 472 // MOVW.LO bl>>s, al 473 p1 = gregshift(AMOVW, &bl, SHIFT_LR, &s, &al); 474 p1->scond = C_SCOND_LO; 475 476 // SUB.LO s,creg 477 p1 = gins(ASUB, &s, &creg); 478 p1->scond = C_SCOND_LO; 479 480 // OR.LO bh<<(32-s), al 481 p1 = gregshift(AORR, &bh, SHIFT_LL, &creg, &al); 482 p1->scond = C_SCOND_LO; 483 484 if(bh.type->etype == TINT32) { 485 // MOVW bh->s, ah 486 p1 = gregshift(AMOVW, &bh, SHIFT_AR, &s, &ah); 487 } else { 488 // MOVW bh>>s, ah 489 p1 = gregshift(AMOVW, &bh, SHIFT_LR, &s, &ah); 490 } 491 p1->scond = C_SCOND_LO; 492 493 // BLO end 494 p3 = gbranch(ABLO, T, 0); 495 496 // shift == 32 497 p1 = gins(AMOVW, &bh, &al); 498 p1->scond = C_SCOND_EQ; 499 if(bh.type->etype == TINT32) 500 gshift(AMOVW, &bh, SHIFT_AR, 31, &ah); 501 else 502 gins(AEOR, &ah, &ah); 503 p4 = gbranch(ABEQ, T, 0); 504 505 // check if shift is < 64 506 nodconst(&n1, types[TUINT32], 64); 507 gmove(&n1, &creg); 508 gcmp(ACMP, &s, &creg); 509 510 // MOVW.LO creg>>1, creg 511 p1 = gshift(AMOVW, &creg, SHIFT_LR, 1, &creg); 512 p1->scond = C_SCOND_LO; 513 514 // SUB.LO creg, s 515 p1 = gins(ASUB, &creg, &s); 516 p1->scond = C_SCOND_LO; 517 518 if(bh.type->etype == TINT32) { 519 // MOVW bh->(s-32), al 520 p1 = gregshift(AMOVW, &bh, SHIFT_AR, &s, &al); 521 p1->scond = C_SCOND_LO; 522 } else { 523 // MOVW bh>>(v-32), al 524 p1 = gregshift(AMOVW, &bh, SHIFT_LR, &s, &al); 525 p1->scond = C_SCOND_LO; 526 } 527 528 // BLO end 529 p5 = gbranch(ABLO, T, 0); 530 531 // s >= 64 532 if(p6 != P) 533 patch(p6, pc); 534 if(bh.type->etype == TINT32) { 535 // MOVW bh->31, al 536 gshift(AMOVW, &bh, SHIFT_AR, 31, &al); 537 } else { 538 gins(AEOR, &al, &al); 539 } 540 541 patch(p2, pc); 542 patch(p3, pc); 543 patch(p4, pc); 544 patch(p5, pc); 545 regfree(&s); 546 regfree(&creg); 547 548 549 orsh_break: 550 regfree(&bl); 551 regfree(&bh); 552 break; 553 554 case OXOR: 555 case OAND: 556 case OOR: 557 // TODO(kaib): literal optimizations 558 // make constant the right side (it usually is anyway). 559 // if(lo1.op == OLITERAL) { 560 // nswap(&lo1, &lo2); 561 // nswap(&hi1, &hi2); 562 // } 563 // if(lo2.op == OLITERAL) { 564 // // special cases for constants. 565 // lv = mpgetfix(lo2.val.u.xval); 566 // hv = mpgetfix(hi2.val.u.xval); 567 // splitclean(); // right side 568 // split64(res, &lo2, &hi2); 569 // switch(n->op) { 570 // case OXOR: 571 // gmove(&lo1, &lo2); 572 // gmove(&hi1, &hi2); 573 // switch(lv) { 574 // case 0: 575 // break; 576 // case 0xffffffffu: 577 // gins(ANOTL, N, &lo2); 578 // break; 579 // default: 580 // gins(AXORL, ncon(lv), &lo2); 581 // break; 582 // } 583 // switch(hv) { 584 // case 0: 585 // break; 586 // case 0xffffffffu: 587 // gins(ANOTL, N, &hi2); 588 // break; 589 // default: 590 // gins(AXORL, ncon(hv), &hi2); 591 // break; 592 // } 593 // break; 594 595 // case OAND: 596 // switch(lv) { 597 // case 0: 598 // gins(AMOVL, ncon(0), &lo2); 599 // break; 600 // default: 601 // gmove(&lo1, &lo2); 602 // if(lv != 0xffffffffu) 603 // gins(AANDL, ncon(lv), &lo2); 604 // break; 605 // } 606 // switch(hv) { 607 // case 0: 608 // gins(AMOVL, ncon(0), &hi2); 609 // break; 610 // default: 611 // gmove(&hi1, &hi2); 612 // if(hv != 0xffffffffu) 613 // gins(AANDL, ncon(hv), &hi2); 614 // break; 615 // } 616 // break; 617 618 // case OOR: 619 // switch(lv) { 620 // case 0: 621 // gmove(&lo1, &lo2); 622 // break; 623 // case 0xffffffffu: 624 // gins(AMOVL, ncon(0xffffffffu), &lo2); 625 // break; 626 // default: 627 // gmove(&lo1, &lo2); 628 // gins(AORL, ncon(lv), &lo2); 629 // break; 630 // } 631 // switch(hv) { 632 // case 0: 633 // gmove(&hi1, &hi2); 634 // break; 635 // case 0xffffffffu: 636 // gins(AMOVL, ncon(0xffffffffu), &hi2); 637 // break; 638 // default: 639 // gmove(&hi1, &hi2); 640 // gins(AORL, ncon(hv), &hi2); 641 // break; 642 // } 643 // break; 644 // } 645 // splitclean(); 646 // splitclean(); 647 // goto out; 648 // } 649 regalloc(&n1, lo1.type, N); 650 gins(AMOVW, &lo1, &al); 651 gins(AMOVW, &hi1, &ah); 652 gins(AMOVW, &lo2, &n1); 653 gins(optoas(n->op, lo1.type), &n1, &al); 654 gins(AMOVW, &hi2, &n1); 655 gins(optoas(n->op, lo1.type), &n1, &ah); 656 regfree(&n1); 657 break; 658 } 659 if(is64(r->type)) 660 splitclean(); 661 splitclean(); 662 663 split64(res, &lo1, &hi1); 664 gins(AMOVW, &al, &lo1); 665 gins(AMOVW, &ah, &hi1); 666 splitclean(); 667 668 //out: 669 regfree(&al); 670 regfree(&ah); 671 } 672 673 /* 674 * generate comparison of nl, nr, both 64-bit. 675 * nl is memory; nr is constant or memory. 676 */ 677 void 678 cmp64(Node *nl, Node *nr, int op, int likely, Prog *to) 679 { 680 Node lo1, hi1, lo2, hi2, r1, r2; 681 Prog *br; 682 Type *t; 683 684 split64(nl, &lo1, &hi1); 685 split64(nr, &lo2, &hi2); 686 687 // compare most significant word; 688 // if they differ, we're done. 689 t = hi1.type; 690 regalloc(&r1, types[TINT32], N); 691 regalloc(&r2, types[TINT32], N); 692 gins(AMOVW, &hi1, &r1); 693 gins(AMOVW, &hi2, &r2); 694 gcmp(ACMP, &r1, &r2); 695 regfree(&r1); 696 regfree(&r2); 697 698 br = P; 699 switch(op) { 700 default: 701 fatal("cmp64 %O %T", op, t); 702 case OEQ: 703 // cmp hi 704 // bne L 705 // cmp lo 706 // beq to 707 // L: 708 br = gbranch(ABNE, T, -likely); 709 break; 710 case ONE: 711 // cmp hi 712 // bne to 713 // cmp lo 714 // bne to 715 patch(gbranch(ABNE, T, likely), to); 716 break; 717 case OGE: 718 case OGT: 719 // cmp hi 720 // bgt to 721 // blt L 722 // cmp lo 723 // bge to (or bgt to) 724 // L: 725 patch(gbranch(optoas(OGT, t), T, likely), to); 726 br = gbranch(optoas(OLT, t), T, -likely); 727 break; 728 case OLE: 729 case OLT: 730 // cmp hi 731 // blt to 732 // bgt L 733 // cmp lo 734 // ble to (or jlt to) 735 // L: 736 patch(gbranch(optoas(OLT, t), T, likely), to); 737 br = gbranch(optoas(OGT, t), T, -likely); 738 break; 739 } 740 741 // compare least significant word 742 t = lo1.type; 743 regalloc(&r1, types[TINT32], N); 744 regalloc(&r2, types[TINT32], N); 745 gins(AMOVW, &lo1, &r1); 746 gins(AMOVW, &lo2, &r2); 747 gcmp(ACMP, &r1, &r2); 748 regfree(&r1); 749 regfree(&r2); 750 751 // jump again 752 patch(gbranch(optoas(op, t), T, likely), to); 753 754 // point first branch down here if appropriate 755 if(br != P) 756 patch(br, pc); 757 758 splitclean(); 759 splitclean(); 760 }