cmd/5a, cmd/5l: add MULW{T,B} and MULAW{T,B} support for ARM

Supported in ARMv5TE and above.
        Also corrected MULA disassembly listing.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6265045
This commit is contained in:
Shenghou Ma 2012-06-08 02:42:28 +08:00
parent f51390b23c
commit a0084b3494
16 changed files with 153 additions and 84 deletions

View File

@ -286,18 +286,19 @@ inst:
outcode(AWORD, Always, &nullgen, NREG, &g); outcode(AWORD, Always, &nullgen, NREG, &g);
} }
/* /*
* MULL hi,lo,r1,r2 * MULL r1,r2,(hi,lo)
*/ */
| LTYPEM cond reg ',' reg ',' regreg | LTYPEM cond reg ',' reg ',' regreg
{ {
outcode($1, $2, &$3, $5.reg, &$7); outcode($1, $2, &$3, $5.reg, &$7);
} }
/* /*
* MULA hi,lo,r1,r2 * MULA r1,r2,r3,r4: (r1*r2+r3) & 0xffffffff -> r4
* MULAW{T,B} r1,r2,r3,r4
*/ */
| LTYPEN cond reg ',' reg ',' reg ',' spreg | LTYPEN cond reg ',' reg ',' reg ',' spreg
{ {
$7.type = D_REGREG; $7.type = D_REGREG2;
$7.offset = $9; $7.offset = $9;
outcode($1, $2, &$3, $5.reg, &$7); outcode($1, $2, &$3, $5.reg, &$7);
} }

View File

@ -408,6 +408,11 @@ struct
"UNDEF", LTYPEE, AUNDEF, "UNDEF", LTYPEE, AUNDEF,
"CLZ", LTYPE2, ACLZ, "CLZ", LTYPE2, ACLZ,
"MULWT", LTYPE1, AMULWT,
"MULWB", LTYPE1, AMULWB,
"MULAWT", LTYPEN, AMULAWT,
"MULAWB", LTYPEN, AMULAWB,
0 0
}; };
@ -511,6 +516,7 @@ zaddr(Gen *a, int s)
break; break;
case D_REGREG: case D_REGREG:
case D_REGREG2:
Bputc(&obuf, a->offset); Bputc(&obuf, a->offset);
break; break;

View File

@ -586,16 +586,16 @@ static const yytype_uint16 yyrline[] =
93, 99, 100, 101, 107, 111, 115, 122, 129, 136, 93, 99, 100, 101, 107, 111, 115, 122, 129, 136,
140, 147, 154, 161, 168, 175, 184, 196, 200, 204, 140, 147, 154, 161, 168, 175, 184, 196, 200, 204,
211, 218, 222, 229, 236, 243, 250, 254, 258, 262, 211, 218, 222, 229, 236, 243, 250, 254, 258, 262,
269, 291, 298, 307, 314, 320, 323, 327, 332, 333, 269, 291, 299, 308, 315, 321, 324, 328, 333, 334,
336, 342, 351, 359, 365, 370, 375, 381, 384, 390, 337, 343, 352, 360, 366, 371, 376, 382, 385, 391,
398, 402, 411, 417, 418, 419, 420, 425, 431, 437, 399, 403, 412, 418, 419, 420, 421, 426, 432, 438,
443, 444, 447, 448, 456, 465, 466, 475, 476, 482, 444, 445, 448, 449, 457, 466, 467, 476, 477, 483,
485, 486, 487, 489, 497, 505, 514, 520, 526, 532, 486, 487, 488, 490, 498, 506, 515, 521, 527, 533,
540, 546, 554, 555, 559, 567, 568, 574, 575, 583, 541, 547, 555, 556, 560, 568, 569, 575, 576, 584,
584, 587, 593, 601, 609, 617, 627, 630, 634, 640, 585, 588, 594, 602, 610, 618, 628, 631, 635, 641,
641, 642, 645, 646, 650, 654, 658, 662, 668, 671, 642, 643, 646, 647, 651, 655, 659, 663, 669, 672,
677, 678, 682, 686, 690, 694, 698, 702, 706, 710, 678, 679, 683, 687, 691, 695, 699, 703, 707, 711,
714 715
}; };
#endif #endif
@ -2084,9 +2084,9 @@ yyreduce:
case 42: case 42:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 299 "a.y" #line 300 "a.y"
{ {
(yyvsp[(7) - (9)].gen).type = D_REGREG; (yyvsp[(7) - (9)].gen).type = D_REGREG2;
(yyvsp[(7) - (9)].gen).offset = (yyvsp[(9) - (9)].lval); (yyvsp[(7) - (9)].gen).offset = (yyvsp[(9) - (9)].lval);
outcode((yyvsp[(1) - (9)].lval), (yyvsp[(2) - (9)].lval), &(yyvsp[(3) - (9)].gen), (yyvsp[(5) - (9)].gen).reg, &(yyvsp[(7) - (9)].gen)); outcode((yyvsp[(1) - (9)].lval), (yyvsp[(2) - (9)].lval), &(yyvsp[(3) - (9)].gen), (yyvsp[(5) - (9)].gen).reg, &(yyvsp[(7) - (9)].gen));
} }
@ -2095,7 +2095,7 @@ yyreduce:
case 43: case 43:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 308 "a.y" #line 309 "a.y"
{ {
outcode((yyvsp[(1) - (2)].lval), Always, &(yyvsp[(2) - (2)].gen), NREG, &nullgen); outcode((yyvsp[(1) - (2)].lval), Always, &(yyvsp[(2) - (2)].gen), NREG, &nullgen);
} }
@ -2104,7 +2104,7 @@ yyreduce:
case 44: case 44:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 315 "a.y" #line 316 "a.y"
{ {
outcode((yyvsp[(1) - (2)].lval), Always, &nullgen, NREG, &nullgen); outcode((yyvsp[(1) - (2)].lval), Always, &nullgen, NREG, &nullgen);
} }
@ -2113,7 +2113,7 @@ yyreduce:
case 45: case 45:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 320 "a.y" #line 321 "a.y"
{ {
(yyval.lval) = Always; (yyval.lval) = Always;
} }
@ -2122,7 +2122,7 @@ yyreduce:
case 46: case 46:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 324 "a.y" #line 325 "a.y"
{ {
(yyval.lval) = ((yyvsp[(1) - (2)].lval) & ~C_SCOND) | (yyvsp[(2) - (2)].lval); (yyval.lval) = ((yyvsp[(1) - (2)].lval) & ~C_SCOND) | (yyvsp[(2) - (2)].lval);
} }
@ -2131,7 +2131,7 @@ yyreduce:
case 47: case 47:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 328 "a.y" #line 329 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (2)].lval) | (yyvsp[(2) - (2)].lval); (yyval.lval) = (yyvsp[(1) - (2)].lval) | (yyvsp[(2) - (2)].lval);
} }
@ -2140,7 +2140,7 @@ yyreduce:
case 50: case 50:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 337 "a.y" #line 338 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_BRANCH; (yyval.gen).type = D_BRANCH;
@ -2151,7 +2151,7 @@ yyreduce:
case 51: case 51:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 343 "a.y" #line 344 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
if(pass == 2) if(pass == 2)
@ -2165,7 +2165,7 @@ yyreduce:
case 52: case 52:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 352 "a.y" #line 353 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_BRANCH; (yyval.gen).type = D_BRANCH;
@ -2177,7 +2177,7 @@ yyreduce:
case 53: case 53:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 360 "a.y" #line 361 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_CONST; (yyval.gen).type = D_CONST;
@ -2188,7 +2188,7 @@ yyreduce:
case 54: case 54:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 366 "a.y" #line 367 "a.y"
{ {
(yyval.gen) = (yyvsp[(2) - (2)].gen); (yyval.gen) = (yyvsp[(2) - (2)].gen);
(yyval.gen).type = D_CONST; (yyval.gen).type = D_CONST;
@ -2198,7 +2198,7 @@ yyreduce:
case 55: case 55:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 371 "a.y" #line 372 "a.y"
{ {
(yyval.gen) = (yyvsp[(4) - (4)].gen); (yyval.gen) = (yyvsp[(4) - (4)].gen);
(yyval.gen).type = D_OCONST; (yyval.gen).type = D_OCONST;
@ -2208,7 +2208,7 @@ yyreduce:
case 56: case 56:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 376 "a.y" #line 377 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_SCONST; (yyval.gen).type = D_SCONST;
@ -2219,7 +2219,7 @@ yyreduce:
case 58: case 58:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 385 "a.y" #line 386 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_FCONST; (yyval.gen).type = D_FCONST;
@ -2230,7 +2230,7 @@ yyreduce:
case 59: case 59:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 391 "a.y" #line 392 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_FCONST; (yyval.gen).type = D_FCONST;
@ -2241,7 +2241,7 @@ yyreduce:
case 60: case 60:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 399 "a.y" #line 400 "a.y"
{ {
(yyval.lval) = 1 << (yyvsp[(1) - (1)].lval); (yyval.lval) = 1 << (yyvsp[(1) - (1)].lval);
} }
@ -2250,7 +2250,7 @@ yyreduce:
case 61: case 61:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 403 "a.y" #line 404 "a.y"
{ {
int i; int i;
(yyval.lval)=0; (yyval.lval)=0;
@ -2264,7 +2264,7 @@ yyreduce:
case 62: case 62:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 412 "a.y" #line 413 "a.y"
{ {
(yyval.lval) = (1<<(yyvsp[(1) - (3)].lval)) | (yyvsp[(3) - (3)].lval); (yyval.lval) = (1<<(yyvsp[(1) - (3)].lval)) | (yyvsp[(3) - (3)].lval);
} }
@ -2273,7 +2273,7 @@ yyreduce:
case 66: case 66:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 421 "a.y" #line 422 "a.y"
{ {
(yyval.gen) = (yyvsp[(1) - (4)].gen); (yyval.gen) = (yyvsp[(1) - (4)].gen);
(yyval.gen).reg = (yyvsp[(3) - (4)].lval); (yyval.gen).reg = (yyvsp[(3) - (4)].lval);
@ -2283,7 +2283,7 @@ yyreduce:
case 67: case 67:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 426 "a.y" #line 427 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_PSR; (yyval.gen).type = D_PSR;
@ -2294,7 +2294,7 @@ yyreduce:
case 68: case 68:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 432 "a.y" #line 433 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_FPCR; (yyval.gen).type = D_FPCR;
@ -2305,7 +2305,7 @@ yyreduce:
case 69: case 69:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 438 "a.y" #line 439 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_OREG; (yyval.gen).type = D_OREG;
@ -2316,7 +2316,7 @@ yyreduce:
case 73: case 73:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 449 "a.y" #line 450 "a.y"
{ {
(yyval.gen) = (yyvsp[(1) - (1)].gen); (yyval.gen) = (yyvsp[(1) - (1)].gen);
if((yyvsp[(1) - (1)].gen).name != D_EXTERN && (yyvsp[(1) - (1)].gen).name != D_STATIC) { if((yyvsp[(1) - (1)].gen).name != D_EXTERN && (yyvsp[(1) - (1)].gen).name != D_STATIC) {
@ -2327,7 +2327,7 @@ yyreduce:
case 74: case 74:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 457 "a.y" #line 458 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_OREG; (yyval.gen).type = D_OREG;
@ -2339,7 +2339,7 @@ yyreduce:
case 76: case 76:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 467 "a.y" #line 468 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_OREG; (yyval.gen).type = D_OREG;
@ -2351,7 +2351,7 @@ yyreduce:
case 78: case 78:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 477 "a.y" #line 478 "a.y"
{ {
(yyval.gen) = (yyvsp[(1) - (4)].gen); (yyval.gen) = (yyvsp[(1) - (4)].gen);
(yyval.gen).type = D_OREG; (yyval.gen).type = D_OREG;
@ -2362,7 +2362,7 @@ yyreduce:
case 83: case 83:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 490 "a.y" #line 491 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_CONST; (yyval.gen).type = D_CONST;
@ -2373,7 +2373,7 @@ yyreduce:
case 84: case 84:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 498 "a.y" #line 499 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_REG; (yyval.gen).type = D_REG;
@ -2384,7 +2384,7 @@ yyreduce:
case 85: case 85:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 506 "a.y" #line 507 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_REGREG; (yyval.gen).type = D_REGREG;
@ -2396,7 +2396,7 @@ yyreduce:
case 86: case 86:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 515 "a.y" #line 516 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_SHIFT; (yyval.gen).type = D_SHIFT;
@ -2407,7 +2407,7 @@ yyreduce:
case 87: case 87:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 521 "a.y" #line 522 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_SHIFT; (yyval.gen).type = D_SHIFT;
@ -2418,7 +2418,7 @@ yyreduce:
case 88: case 88:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 527 "a.y" #line 528 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_SHIFT; (yyval.gen).type = D_SHIFT;
@ -2429,7 +2429,7 @@ yyreduce:
case 89: case 89:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 533 "a.y" #line 534 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_SHIFT; (yyval.gen).type = D_SHIFT;
@ -2440,7 +2440,7 @@ yyreduce:
case 90: case 90:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 541 "a.y" #line 542 "a.y"
{ {
if((yyval.lval) < 0 || (yyval.lval) >= 16) if((yyval.lval) < 0 || (yyval.lval) >= 16)
print("register value out of range\n"); print("register value out of range\n");
@ -2451,7 +2451,7 @@ yyreduce:
case 91: case 91:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 547 "a.y" #line 548 "a.y"
{ {
if((yyval.lval) < 0 || (yyval.lval) >= 32) if((yyval.lval) < 0 || (yyval.lval) >= 32)
print("shift value out of range\n"); print("shift value out of range\n");
@ -2462,7 +2462,7 @@ yyreduce:
case 93: case 93:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 556 "a.y" #line 557 "a.y"
{ {
(yyval.lval) = REGPC; (yyval.lval) = REGPC;
} }
@ -2471,7 +2471,7 @@ yyreduce:
case 94: case 94:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 560 "a.y" #line 561 "a.y"
{ {
if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG) if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG)
print("register value out of range\n"); print("register value out of range\n");
@ -2482,7 +2482,7 @@ yyreduce:
case 96: case 96:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 569 "a.y" #line 570 "a.y"
{ {
(yyval.lval) = REGSP; (yyval.lval) = REGSP;
} }
@ -2491,7 +2491,7 @@ yyreduce:
case 98: case 98:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 576 "a.y" #line 577 "a.y"
{ {
if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG) if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG)
print("register value out of range\n"); print("register value out of range\n");
@ -2502,7 +2502,7 @@ yyreduce:
case 101: case 101:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 588 "a.y" #line 589 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_FREG; (yyval.gen).type = D_FREG;
@ -2513,7 +2513,7 @@ yyreduce:
case 102: case 102:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 594 "a.y" #line 595 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_FREG; (yyval.gen).type = D_FREG;
@ -2524,7 +2524,7 @@ yyreduce:
case 103: case 103:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 602 "a.y" #line 603 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_OREG; (yyval.gen).type = D_OREG;
@ -2537,7 +2537,7 @@ yyreduce:
case 104: case 104:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 610 "a.y" #line 611 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_OREG; (yyval.gen).type = D_OREG;
@ -2550,7 +2550,7 @@ yyreduce:
case 105: case 105:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 618 "a.y" #line 619 "a.y"
{ {
(yyval.gen) = nullgen; (yyval.gen) = nullgen;
(yyval.gen).type = D_OREG; (yyval.gen).type = D_OREG;
@ -2563,7 +2563,7 @@ yyreduce:
case 106: case 106:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 627 "a.y" #line 628 "a.y"
{ {
(yyval.lval) = 0; (yyval.lval) = 0;
} }
@ -2572,7 +2572,7 @@ yyreduce:
case 107: case 107:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 631 "a.y" #line 632 "a.y"
{ {
(yyval.lval) = (yyvsp[(2) - (2)].lval); (yyval.lval) = (yyvsp[(2) - (2)].lval);
} }
@ -2581,7 +2581,7 @@ yyreduce:
case 108: case 108:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 635 "a.y" #line 636 "a.y"
{ {
(yyval.lval) = -(yyvsp[(2) - (2)].lval); (yyval.lval) = -(yyvsp[(2) - (2)].lval);
} }
@ -2590,7 +2590,7 @@ yyreduce:
case 113: case 113:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 647 "a.y" #line 648 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (1)].sym)->value; (yyval.lval) = (yyvsp[(1) - (1)].sym)->value;
} }
@ -2599,7 +2599,7 @@ yyreduce:
case 114: case 114:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 651 "a.y" #line 652 "a.y"
{ {
(yyval.lval) = -(yyvsp[(2) - (2)].lval); (yyval.lval) = -(yyvsp[(2) - (2)].lval);
} }
@ -2608,7 +2608,7 @@ yyreduce:
case 115: case 115:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 655 "a.y" #line 656 "a.y"
{ {
(yyval.lval) = (yyvsp[(2) - (2)].lval); (yyval.lval) = (yyvsp[(2) - (2)].lval);
} }
@ -2617,7 +2617,7 @@ yyreduce:
case 116: case 116:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 659 "a.y" #line 660 "a.y"
{ {
(yyval.lval) = ~(yyvsp[(2) - (2)].lval); (yyval.lval) = ~(yyvsp[(2) - (2)].lval);
} }
@ -2626,7 +2626,7 @@ yyreduce:
case 117: case 117:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 663 "a.y" #line 664 "a.y"
{ {
(yyval.lval) = (yyvsp[(2) - (3)].lval); (yyval.lval) = (yyvsp[(2) - (3)].lval);
} }
@ -2635,7 +2635,7 @@ yyreduce:
case 118: case 118:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 668 "a.y" #line 669 "a.y"
{ {
(yyval.lval) = 0; (yyval.lval) = 0;
} }
@ -2644,7 +2644,7 @@ yyreduce:
case 119: case 119:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 672 "a.y" #line 673 "a.y"
{ {
(yyval.lval) = (yyvsp[(2) - (2)].lval); (yyval.lval) = (yyvsp[(2) - (2)].lval);
} }
@ -2653,7 +2653,7 @@ yyreduce:
case 121: case 121:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 679 "a.y" #line 680 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval);
} }
@ -2662,7 +2662,7 @@ yyreduce:
case 122: case 122:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 683 "a.y" #line 684 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval);
} }
@ -2671,7 +2671,7 @@ yyreduce:
case 123: case 123:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 687 "a.y" #line 688 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval);
} }
@ -2680,7 +2680,7 @@ yyreduce:
case 124: case 124:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 691 "a.y" #line 692 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval);
} }
@ -2689,7 +2689,7 @@ yyreduce:
case 125: case 125:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 695 "a.y" #line 696 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval);
} }
@ -2698,7 +2698,7 @@ yyreduce:
case 126: case 126:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 699 "a.y" #line 700 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval); (yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval);
} }
@ -2707,7 +2707,7 @@ yyreduce:
case 127: case 127:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 703 "a.y" #line 704 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval); (yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval);
} }
@ -2716,7 +2716,7 @@ yyreduce:
case 128: case 128:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 707 "a.y" #line 708 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval);
} }
@ -2725,7 +2725,7 @@ yyreduce:
case 129: case 129:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 711 "a.y" #line 712 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval);
} }
@ -2734,7 +2734,7 @@ yyreduce:
case 130: case 130:
/* Line 1455 of yacc.c */ /* Line 1455 of yacc.c */
#line 715 "a.y" #line 716 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval);
} }

View File

@ -176,7 +176,7 @@ cgen64(Node *n, Node *res)
p1->from.type = D_REG; p1->from.type = D_REG;
p1->from.reg = bl.val.u.reg; p1->from.reg = bl.val.u.reg;
p1->reg = ch.val.u.reg; p1->reg = ch.val.u.reg;
p1->to.type = D_REGREG; p1->to.type = D_REGREG2;
p1->to.reg = ah.val.u.reg; p1->to.reg = ah.val.u.reg;
p1->to.offset = ah.val.u.reg; p1->to.offset = ah.val.u.reg;
//print("%P\n", p1); //print("%P\n", p1);
@ -186,7 +186,7 @@ cgen64(Node *n, Node *res)
p1->from.type = D_REG; p1->from.type = D_REG;
p1->from.reg = bh.val.u.reg; p1->from.reg = bh.val.u.reg;
p1->reg = cl.val.u.reg; p1->reg = cl.val.u.reg;
p1->to.type = D_REGREG; p1->to.type = D_REGREG2;
p1->to.reg = ah.val.u.reg; p1->to.reg = ah.val.u.reg;
p1->to.offset = ah.val.u.reg; p1->to.offset = ah.val.u.reg;
//print("%P\n", p1); //print("%P\n", p1);

View File

@ -147,6 +147,7 @@ zaddr(Biobuf *b, Addr *a, int s)
break; break;
case D_REGREG: case D_REGREG:
case D_REGREG2:
Bputc(b, a->offset); Bputc(b, a->offset);
break; break;

View File

@ -153,6 +153,12 @@ Dconv(Fmt *fp)
sprint(str, "%M(R%d)(REG)", a, a->reg); sprint(str, "%M(R%d)(REG)", a, a->reg);
break; break;
case D_REGREG2:
sprint(str, "R%d,R%d", a->reg, (int)a->offset);
if(a->name != D_NONE || a->sym != S)
sprint(str, "%M(R%d)(REG)", a, a->reg);
break;
case D_FREG: case D_FREG:
sprint(str, "F%d", a->reg); sprint(str, "F%d", a->reg);
if(a->name != D_NONE || a->sym != S) if(a->name != D_NONE || a->sym != S)

View File

@ -1213,7 +1213,7 @@ copyau(Adr *a, Adr *v)
if(a->reg == v->reg) if(a->reg == v->reg)
return 1; return 1;
} else } else
if(a->type == D_REGREG) { if(a->type == D_REGREG || a->type == D_REGREG2) {
if(a->reg == v->reg) if(a->reg == v->reg)
return 1; return 1;
if(a->offset == v->reg) if(a->offset == v->reg)
@ -1276,7 +1276,7 @@ copysub(Adr *a, Adr *v, Adr *s, int f)
if((a->offset&(1<<4)) && (a->offset>>8) == v->reg) if((a->offset&(1<<4)) && (a->offset>>8) == v->reg)
a->offset = (a->offset&~(0xf<<8))|(s->reg<<8); a->offset = (a->offset&~(0xf<<8))|(s->reg<<8);
} else } else
if(a->type == D_REGREG) { if(a->type == D_REGREG || a->type == D_REGREG2) {
if(a->offset == v->reg) if(a->offset == v->reg)
a->offset = s->reg; a->offset = s->reg;
if(a->reg == v->reg) if(a->reg == v->reg)

View File

@ -874,6 +874,7 @@ mkvar(Reg *r, Adr *a)
goto onereg; goto onereg;
case D_REGREG: case D_REGREG:
case D_REGREG2:
bit = zbits; bit = zbits;
if(a->offset != NREG) if(a->offset != NREG)
bit.b[0] |= RtoB(a->offset); bit.b[0] |= RtoB(a->offset);

View File

@ -189,6 +189,11 @@ enum as
ACLZ, ACLZ,
AMULWT,
AMULWB,
AMULAWT,
AMULAWB,
ALAST, ALAST,
}; };
@ -242,12 +247,14 @@ enum as
#define D_SHIFT (D_NONE+19) #define D_SHIFT (D_NONE+19)
#define D_FPCR (D_NONE+20) #define D_FPCR (D_NONE+20)
#define D_REGREG (D_NONE+21) #define D_REGREG (D_NONE+21) // (reg, reg)
#define D_ADDR (D_NONE+22) #define D_ADDR (D_NONE+22)
#define D_SBIG (D_NONE+23) #define D_SBIG (D_NONE+23)
#define D_CONST2 (D_NONE+24) #define D_CONST2 (D_NONE+24)
#define D_REGREG2 (D_NONE+25) // reg, reg
/* name */ /* name */
#define D_EXTERN (D_NONE+3) #define D_EXTERN (D_NONE+3)
#define D_STATIC (D_NONE+4) #define D_STATIC (D_NONE+4)

View File

@ -1806,6 +1806,19 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
o1 |= p->to.reg << 12; o1 |= p->to.reg << 12;
o1 |= p->from.reg; o1 |= p->from.reg;
break; break;
case 98: /* MULW{T,B} Rs, Rm, Rd */
o1 = oprrr(p->as, p->scond);
o1 |= p->to.reg << 16;
o1 |= p->from.reg << 8;
o1 |= p->reg;
break;
case 99: /* MULAW{T,B} Rs, Rm, Rn, Rd */
o1 = oprrr(p->as, p->scond);
o1 |= p->to.reg << 12;
o1 |= p->from.reg << 8;
o1 |= p->reg;
o1 |= p->to.offset << 16;
break;
} }
out[0] = o1; out[0] = o1;
@ -1967,6 +1980,15 @@ oprrr(int a, int sc)
case ACLZ: case ACLZ:
// CLZ doesn't support .S // CLZ doesn't support .S
return (o & (0xf<<28)) | (0x16f<<16) | (0xf1<<4); return (o & (0xf<<28)) | (0x16f<<16) | (0xf1<<4);
case AMULWT:
return (o & (0xf<<28)) | (0x12 << 20) | (0xe<<4);
case AMULWB:
return (o & (0xf<<28)) | (0x12 << 20) | (0xa<<4);
case AMULAWT:
return (o & (0xf<<28)) | (0x12 << 20) | (0xc<<4);
case AMULAWB:
return (o & (0xf<<28)) | (0x12 << 20) | (0x8<<4);
} }
diag("bad rrr %d", a); diag("bad rrr %d", a);
prasm(curp); prasm(curp);

View File

@ -212,6 +212,7 @@ enum
C_NONE = 0, C_NONE = 0,
C_REG, C_REG,
C_REGREG, C_REGREG,
C_REGREG2,
C_SHIFT, C_SHIFT,
C_FREG, C_FREG,
C_PSR, C_PSR,

View File

@ -225,6 +225,12 @@ Dconv(Fmt *fp)
snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg); snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
break; break;
case D_REGREG2:
snprint(str, sizeof str, "R%d,R%d", a->reg, (int)a->offset);
if(a->name != D_NONE || a->sym != S)
snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
break;
case D_FREG: case D_FREG:
snprint(str, sizeof str, "F%d", a->reg); snprint(str, sizeof str, "F%d", a->reg);
if(a->name != D_NONE || a->sym != S) if(a->name != D_NONE || a->sym != S)
@ -438,6 +444,7 @@ cnames[] =
[C_RCON] = "C_RCON", [C_RCON] = "C_RCON",
[C_REG] = "C_REG", [C_REG] = "C_REG",
[C_REGREG] = "C_REGREG", [C_REGREG] = "C_REGREG",
[C_REGREG2] = "C_REGREG2",
[C_ROREG] = "C_ROREG", [C_ROREG] = "C_ROREG",
[C_SAUTO] = "C_SAUTO", [C_SAUTO] = "C_SAUTO",
[C_SBRA] = "C_SBRA", [C_SBRA] = "C_SBRA",

View File

@ -338,6 +338,7 @@ zaddr(Biobuf *f, Adr *a, Sym *h[])
break; break;
case D_REGREG: case D_REGREG:
case D_REGREG2:
a->offset = BGETC(f); a->offset = BGETC(f);
break; break;

View File

@ -103,6 +103,7 @@ Optab optab[] =
{ ADIV, C_REG, C_NONE, C_REG, 16, 4, 0 }, { ADIV, C_REG, C_NONE, C_REG, 16, 4, 0 },
{ AMULL, C_REG, C_REG, C_REGREG, 17, 4, 0 }, { AMULL, C_REG, C_REG, C_REGREG, 17, 4, 0 },
{ AMULA, C_REG, C_REG, C_REGREG2, 17, 4, 0 },
{ AMOVW, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP }, { AMOVW, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP },
{ AMOVW, C_REG, C_NONE, C_SOREG, 20, 4, 0 }, { AMOVW, C_REG, C_NONE, C_SOREG, 20, 4, 0 },
@ -238,5 +239,8 @@ Optab optab[] =
{ ACLZ, C_REG, C_NONE, C_REG, 97, 4, 0 }, { ACLZ, C_REG, C_NONE, C_REG, 97, 4, 0 },
{ AMULWT, C_REG, C_REG, C_REG, 98, 4, 0 },
{ AMULAWT, C_REG, C_REG, C_REGREG2, 99, 4, 0 },
{ AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0 }, { AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0 },
}; };

View File

@ -447,6 +447,9 @@ aclass(Adr *a)
case D_REGREG: case D_REGREG:
return C_REGREG; return C_REGREG;
case D_REGREG2:
return C_REGREG2;
case D_SHIFT: case D_SHIFT:
return C_SHIFT; return C_SHIFT;
@ -835,12 +838,20 @@ buildop(void)
break; break;
case AMULL: case AMULL:
oprange[AMULA] = oprange[r];
oprange[AMULAL] = oprange[r]; oprange[AMULAL] = oprange[r];
oprange[AMULLU] = oprange[r]; oprange[AMULLU] = oprange[r];
oprange[AMULALU] = oprange[r]; oprange[AMULALU] = oprange[r];
break; break;
case AMULWT:
oprange[AMULWB] = oprange[r];
break;
case AMULAWT:
oprange[AMULAWB] = oprange[r];
break;
case AMULA:
case ALDREX: case ALDREX:
case ASTREX: case ASTREX:
case ALDREXD: case ALDREXD:

View File

@ -124,6 +124,7 @@ addr(Biobuf *bp)
case D_FPCR: case D_FPCR:
break; break;
case D_REGREG: case D_REGREG:
case D_REGREG2:
Bgetc(bp); Bgetc(bp);
break; break;
case D_CONST2: case D_CONST2: