cmd/8a, cmd/8g, cmd/8l, liblink: update for portable Prog, Addr

Change-Id: I19ed283962aa0221cf806307bde9ea0773a1bfd4
Reviewed-on: https://go-review.googlesource.com/3518
Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
Russ Cox 2015-01-26 15:15:43 -05:00
parent 604138e87b
commit a5b1baeed7
18 changed files with 1277 additions and 1216 deletions

View File

@ -222,8 +222,7 @@ spec3: /* JMP/CALL */
{
$$.from = nullgen;
$$.to = $2;
$$.to.index = $2.type;
$$.to.type = D_INDIR+D_ADDR;
$$.to.type = TYPE_INDIR;
}
spec4: /* NOP */
@ -240,7 +239,7 @@ spec5: /* SHL/SHR */
{
$$.from = $1;
$$.to = $3;
if($$.from.index != D_NONE)
if($$.from.index != TYPE_NONE)
yyerror("dp shift with lhs index");
$$.from.index = $5;
}
@ -255,7 +254,7 @@ spec6: /* MOVW/MOVL */
{
$$.from = $1;
$$.to = $3;
if($$.to.index != D_NONE)
if($$.to.index != TYPE_NONE)
yyerror("dp move with lhs index");
$$.to.index = $5;
}
@ -303,7 +302,7 @@ spec10: /* PINSRD */
{
$$.from = $3;
$$.to = $5;
if($1.type != D_CONST)
if($1.type != TYPE_CONST)
yyerror("illegal constant");
$$.to.offset = $1.offset;
}
@ -311,7 +310,7 @@ spec10: /* PINSRD */
spec11: /* PCDATA */
rim ',' rim
{
if($1.type != D_CONST || $3.type != D_CONST)
if($1.type != TYPE_CONST || $3.type != TYPE_CONST)
yyerror("arguments to PCDATA must be integer constants");
$$.from = $1;
$$.to = $3;
@ -320,9 +319,9 @@ spec11: /* PCDATA */
spec12: /* FUNCDATA */
rim ',' rim
{
if($1.type != D_CONST)
if($1.type != TYPE_CONST)
yyerror("index for FUNCDATA must be integer constant");
if($3.type != D_EXTERN && $3.type != D_STATIC)
if($3.type != TYPE_MEM || ($3.name != NAME_EXTERN && $3.name != NAME_STATIC))
yyerror("value for FUNCDATA must be symbol reference");
$$.from = $1;
$$.to = $3;
@ -355,7 +354,7 @@ rel:
con '(' LPC ')'
{
$$ = nullgen;
$$.type = D_BRANCH;
$$.type = TYPE_BRANCH;
$$.offset = $1 + pc;
}
| LNAME offset
@ -364,7 +363,7 @@ rel:
$$ = nullgen;
if(pass == 2 && $1->type != LLAB)
yyerror("undefined label: %s", $1->labelname);
$$.type = D_BRANCH;
$$.type = TYPE_BRANCH;
$$.offset = $1->value + $2;
}
@ -372,48 +371,53 @@ reg:
LBREG
{
$$ = nullgen;
$$.type = $1;
$$.type = TYPE_REG;
$$.reg = $1;
}
| LFREG
{
$$ = nullgen;
$$.type = $1;
$$.type = TYPE_REG;
$$.reg = $1;
}
| LLREG
{
$$ = nullgen;
$$.type = $1;
$$.type = TYPE_REG;
$$.reg = $1;
}
| LXREG
{
$$ = nullgen;
$$.type = $1;
$$.type = TYPE_REG;
$$.reg = $1;
}
| LSP
{
$$ = nullgen;
$$.type = D_SP;
$$.type = TYPE_REG;
$$.reg = REG_SP;
}
| LSREG
{
$$ = nullgen;
$$.type = $1;
$$.type = TYPE_REG;
$$.reg = $1;
}
imm:
'$' con
{
$$ = nullgen;
$$.type = D_CONST;
$$.type = TYPE_CONST;
$$.offset = $2;
}
| '$' nam
{
$$ = $2;
$$.index = $2.type;
$$.type = D_ADDR;
$$.type = TYPE_ADDR;
/*
if($2.type == D_AUTO || $2.type == D_PARAM)
if($2.name == NAME_AUTO || $2.name == NAME_PARAM)
yyerror("constant cannot be automatic: %s",
$2.sym->name);
*/
@ -421,31 +425,31 @@ imm:
| '$' LSCONST
{
$$ = nullgen;
$$.type = D_SCONST;
$$.type = TYPE_SCONST;
memcpy($$.u.sval, $2, sizeof($$.u.sval));
}
| '$' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
$$.type = TYPE_FCONST;
$$.u.dval = $2;
}
| '$' '(' LFCONST ')'
{
$$ = nullgen;
$$.type = D_FCONST;
$$.type = TYPE_FCONST;
$$.u.dval = $3;
}
| '$' '(' '-' LFCONST ')'
{
$$ = nullgen;
$$.type = D_FCONST;
$$.type = TYPE_FCONST;
$$.u.dval = -$4;
}
| '$' '-' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
$$.type = TYPE_FCONST;
$$.u.dval = -$3;
}
@ -453,9 +457,9 @@ imm2:
'$' con2
{
$$ = nullgen;
$$.type = D_CONST2;
$$.type = TYPE_TEXTSIZE;
$$.offset = $2.v1;
$$.offset2 = $2.v2;
$$.u.argsize = $2.v2;
}
con2:
@ -488,25 +492,29 @@ omem:
con
{
$$ = nullgen;
$$.type = D_INDIR+D_NONE;
$$.type = TYPE_MEM;
$$.reg = REG_NONE;
$$.offset = $1;
}
| con '(' LLREG ')'
{
$$ = nullgen;
$$.type = D_INDIR+$3;
$$.type = TYPE_MEM;
$$.reg = $3;
$$.offset = $1;
}
| con '(' LSP ')'
{
$$ = nullgen;
$$.type = D_INDIR+D_SP;
$$.type = TYPE_MEM;
$$.reg = REG_SP;
$$.offset = $1;
}
| con '(' LLREG '*' con ')'
{
$$ = nullgen;
$$.type = D_INDIR+D_NONE;
$$.type = TYPE_MEM;
$$.reg = REG_NONE;
$$.offset = $1;
$$.index = $3;
$$.scale = $5;
@ -515,7 +523,8 @@ omem:
| con '(' LLREG ')' '(' LLREG '*' con ')'
{
$$ = nullgen;
$$.type = D_INDIR+$3;
$$.type = TYPE_MEM;
$$.reg = $3;
$$.offset = $1;
$$.index = $6;
$$.scale = $8;
@ -524,7 +533,8 @@ omem:
| con '(' LLREG ')' '(' LSREG '*' con ')'
{
$$ = nullgen;
$$.type = D_INDIR+$3;
$$.type = TYPE_MEM;
$$.reg = $3;
$$.offset = $1;
$$.index = $6;
$$.scale = $8;
@ -533,23 +543,27 @@ omem:
| '(' LLREG ')'
{
$$ = nullgen;
$$.type = D_INDIR+$2;
$$.type = TYPE_MEM;
$$.reg = $2;
}
| '(' LSP ')'
{
$$ = nullgen;
$$.type = D_INDIR+D_SP;
$$.type = TYPE_MEM;
$$.reg = REG_SP;
}
| con '(' LSREG ')'
{
$$ = nullgen;
$$.type = D_INDIR+$3;
$$.type = TYPE_MEM;
$$.reg = $3;
$$.offset = $1;
}
| '(' LLREG '*' con ')'
{
$$ = nullgen;
$$.type = D_INDIR+D_NONE;
$$.type = TYPE_MEM;
$$.reg = REG_NONE;
$$.index = $2;
$$.scale = $4;
checkscale($$.scale);
@ -557,7 +571,8 @@ omem:
| '(' LLREG ')' '(' LLREG '*' con ')'
{
$$ = nullgen;
$$.type = D_INDIR+$2;
$$.type = TYPE_MEM;
$$.reg = $2;
$$.index = $5;
$$.scale = $7;
checkscale($$.scale);
@ -580,14 +595,16 @@ nam:
LNAME offset '(' pointer ')'
{
$$ = nullgen;
$$.type = $4;
$$.type = TYPE_MEM;
$$.name = $4;
$$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2;
}
| LNAME '<' '>' offset '(' LSB ')'
{
$$ = nullgen;
$$.type = D_STATIC;
$$.type = TYPE_MEM;
$$.name = NAME_STATIC;
$$.sym = linklookup(ctxt, $1->name, 1);
$$.offset = $4;
}
@ -609,7 +626,7 @@ pointer:
LSB
| LSP
{
$$ = D_AUTO;
$$ = NAME_AUTO;
}
| LFP

View File

@ -192,87 +192,88 @@ struct
ushort value;
} itab[] =
{
"SP", LSP, D_AUTO,
"SB", LSB, D_EXTERN,
"FP", LFP, D_PARAM,
"PC", LPC, D_BRANCH,
"SP", LSP, NAME_AUTO,
"SB", LSB, NAME_EXTERN,
"FP", LFP, NAME_PARAM,
"AL", LBREG, D_AL,
"CL", LBREG, D_CL,
"DL", LBREG, D_DL,
"BL", LBREG, D_BL,
"AH", LBREG, D_AH,
"CH", LBREG, D_CH,
"DH", LBREG, D_DH,
"BH", LBREG, D_BH,
"PC", LPC, TYPE_BRANCH,
"AX", LLREG, D_AX,
"CX", LLREG, D_CX,
"DX", LLREG, D_DX,
"BX", LLREG, D_BX,
/* "SP", LLREG, D_SP, */
"BP", LLREG, D_BP,
"SI", LLREG, D_SI,
"DI", LLREG, D_DI,
"AL", LBREG, REG_AL,
"CL", LBREG, REG_CL,
"DL", LBREG, REG_DL,
"BL", LBREG, REG_BL,
"AH", LBREG, REG_AH,
"CH", LBREG, REG_CH,
"DH", LBREG, REG_DH,
"BH", LBREG, REG_BH,
"F0", LFREG, D_F0+0,
"F1", LFREG, D_F0+1,
"F2", LFREG, D_F0+2,
"F3", LFREG, D_F0+3,
"F4", LFREG, D_F0+4,
"F5", LFREG, D_F0+5,
"F6", LFREG, D_F0+6,
"F7", LFREG, D_F0+7,
"AX", LLREG, REG_AX,
"CX", LLREG, REG_CX,
"DX", LLREG, REG_DX,
"BX", LLREG, REG_BX,
/* "SP", LLREG, REG_SP, */
"BP", LLREG, REG_BP,
"SI", LLREG, REG_SI,
"DI", LLREG, REG_DI,
"X0", LXREG, D_X0+0,
"X1", LXREG, D_X0+1,
"X2", LXREG, D_X0+2,
"X3", LXREG, D_X0+3,
"X4", LXREG, D_X0+4,
"X5", LXREG, D_X0+5,
"X6", LXREG, D_X0+6,
"X7", LXREG, D_X0+7,
"F0", LFREG, REG_F0+0,
"F1", LFREG, REG_F0+1,
"F2", LFREG, REG_F0+2,
"F3", LFREG, REG_F0+3,
"F4", LFREG, REG_F0+4,
"F5", LFREG, REG_F0+5,
"F6", LFREG, REG_F0+6,
"F7", LFREG, REG_F0+7,
"CS", LSREG, D_CS,
"SS", LSREG, D_SS,
"DS", LSREG, D_DS,
"ES", LSREG, D_ES,
"FS", LSREG, D_FS,
"GS", LSREG, D_GS,
"TLS", LSREG, D_TLS,
"X0", LXREG, REG_X0+0,
"X1", LXREG, REG_X0+1,
"X2", LXREG, REG_X0+2,
"X3", LXREG, REG_X0+3,
"X4", LXREG, REG_X0+4,
"X5", LXREG, REG_X0+5,
"X6", LXREG, REG_X0+6,
"X7", LXREG, REG_X0+7,
"GDTR", LBREG, D_GDTR,
"IDTR", LBREG, D_IDTR,
"LDTR", LBREG, D_LDTR,
"MSW", LBREG, D_MSW,
"TASK", LBREG, D_TASK,
"CS", LSREG, REG_CS,
"SS", LSREG, REG_SS,
"DS", LSREG, REG_DS,
"ES", LSREG, REG_ES,
"FS", LSREG, REG_FS,
"GS", LSREG, REG_GS,
"TLS", LSREG, REG_TLS,
"CR0", LBREG, D_CR+0,
"CR1", LBREG, D_CR+1,
"CR2", LBREG, D_CR+2,
"CR3", LBREG, D_CR+3,
"CR4", LBREG, D_CR+4,
"CR5", LBREG, D_CR+5,
"CR6", LBREG, D_CR+6,
"CR7", LBREG, D_CR+7,
"GDTR", LBREG, REG_GDTR,
"IDTR", LBREG, REG_IDTR,
"LDTR", LBREG, REG_LDTR,
"MSW", LBREG, REG_MSW,
"TASK", LBREG, REG_TASK,
"DR0", LBREG, D_DR+0,
"DR1", LBREG, D_DR+1,
"DR2", LBREG, D_DR+2,
"DR3", LBREG, D_DR+3,
"DR4", LBREG, D_DR+4,
"DR5", LBREG, D_DR+5,
"DR6", LBREG, D_DR+6,
"DR7", LBREG, D_DR+7,
"CR0", LBREG, REG_CR+0,
"CR1", LBREG, REG_CR+1,
"CR2", LBREG, REG_CR+2,
"CR3", LBREG, REG_CR+3,
"CR4", LBREG, REG_CR+4,
"CR5", LBREG, REG_CR+5,
"CR6", LBREG, REG_CR+6,
"CR7", LBREG, REG_CR+7,
"TR0", LBREG, D_TR+0,
"TR1", LBREG, D_TR+1,
"TR2", LBREG, D_TR+2,
"TR3", LBREG, D_TR+3,
"TR4", LBREG, D_TR+4,
"TR5", LBREG, D_TR+5,
"TR6", LBREG, D_TR+6,
"TR7", LBREG, D_TR+7,
"DR0", LBREG, REG_DR+0,
"DR1", LBREG, REG_DR+1,
"DR2", LBREG, REG_DR+2,
"DR3", LBREG, REG_DR+3,
"DR4", LBREG, REG_DR+4,
"DR5", LBREG, REG_DR+5,
"DR6", LBREG, REG_DR+6,
"DR7", LBREG, REG_DR+7,
"TR0", LBREG, REG_TR+0,
"TR1", LBREG, REG_TR+1,
"TR2", LBREG, REG_TR+2,
"TR3", LBREG, REG_TR+3,
"TR4", LBREG, REG_TR+4,
"TR5", LBREG, REG_TR+5,
"TR6", LBREG, REG_TR+6,
"TR7", LBREG, REG_TR+7,
"AAA", LTYPE0, AAAA,
"AAD", LTYPE0, AAAD,
@ -829,8 +830,8 @@ cinit(void)
Sym *s;
int i;
nullgen.type = D_NONE;
nullgen.index = D_NONE;
nullgen.type = TYPE_NONE;
nullgen.index = TYPE_NONE;
nerrors = 0;
iostack = I;

View File

@ -543,16 +543,16 @@ static const yytype_uint16 yyrline[] =
91, 96, 102, 103, 104, 105, 106, 107, 108, 109,
110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
122, 126, 133, 140, 147, 152, 159, 164, 171, 176,
181, 188, 196, 202, 211, 216, 221, 230, 231, 234,
239, 249, 254, 264, 269, 274, 281, 286, 294, 302,
312, 321, 332, 333, 336, 337, 338, 342, 346, 347,
348, 351, 352, 355, 361, 372, 377, 382, 387, 392,
397, 404, 410, 421, 427, 433, 439, 445, 453, 462,
467, 472, 477, 484, 485, 488, 494, 500, 506, 515,
524, 533, 538, 543, 549, 557, 567, 571, 580, 587,
596, 599, 603, 609, 610, 614, 617, 618, 622, 626,
630, 634, 640, 641, 645, 649, 653, 657, 661, 665,
669, 673, 677
181, 188, 196, 202, 211, 216, 221, 229, 230, 233,
238, 248, 253, 263, 268, 273, 280, 285, 293, 301,
311, 320, 331, 332, 335, 336, 337, 341, 345, 346,
347, 350, 351, 354, 360, 371, 377, 383, 389, 395,
401, 409, 415, 425, 431, 437, 443, 449, 457, 466,
471, 476, 481, 488, 489, 492, 499, 506, 513, 523,
533, 543, 549, 555, 562, 571, 582, 586, 595, 603,
613, 616, 620, 626, 627, 631, 634, 635, 639, 643,
647, 651, 657, 658, 662, 666, 670, 674, 678, 682,
686, 690, 694
};
#endif
@ -1947,13 +1947,12 @@ yyreduce:
{
(yyval.addr2).from = nullgen;
(yyval.addr2).to = (yyvsp[(2) - (2)].addr);
(yyval.addr2).to.index = (yyvsp[(2) - (2)].addr).type;
(yyval.addr2).to.type = D_INDIR+D_ADDR;
(yyval.addr2).to.type = TYPE_INDIR;
}
break;
case 49:
#line 235 "a.y"
#line 234 "a.y"
{
(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
@ -1961,18 +1960,18 @@ yyreduce:
break;
case 50:
#line 240 "a.y"
#line 239 "a.y"
{
(yyval.addr2).from = (yyvsp[(1) - (5)].addr);
(yyval.addr2).to = (yyvsp[(3) - (5)].addr);
if((yyval.addr2).from.index != D_NONE)
if((yyval.addr2).from.index != TYPE_NONE)
yyerror("dp shift with lhs index");
(yyval.addr2).from.index = (yyvsp[(5) - (5)].lval);
}
break;
case 51:
#line 250 "a.y"
#line 249 "a.y"
{
(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
@ -1980,18 +1979,18 @@ yyreduce:
break;
case 52:
#line 255 "a.y"
#line 254 "a.y"
{
(yyval.addr2).from = (yyvsp[(1) - (5)].addr);
(yyval.addr2).to = (yyvsp[(3) - (5)].addr);
if((yyval.addr2).to.index != D_NONE)
if((yyval.addr2).to.index != TYPE_NONE)
yyerror("dp move with lhs index");
(yyval.addr2).to.index = (yyvsp[(5) - (5)].lval);
}
break;
case 53:
#line 265 "a.y"
#line 264 "a.y"
{
(yyval.addr2).from = (yyvsp[(1) - (2)].addr);
(yyval.addr2).to = nullgen;
@ -1999,7 +1998,7 @@ yyreduce:
break;
case 54:
#line 270 "a.y"
#line 269 "a.y"
{
(yyval.addr2).from = (yyvsp[(1) - (1)].addr);
(yyval.addr2).to = nullgen;
@ -2007,7 +2006,7 @@ yyreduce:
break;
case 55:
#line 275 "a.y"
#line 274 "a.y"
{
(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
@ -2015,7 +2014,7 @@ yyreduce:
break;
case 56:
#line 282 "a.y"
#line 281 "a.y"
{
(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
@ -2023,7 +2022,7 @@ yyreduce:
break;
case 57:
#line 287 "a.y"
#line 286 "a.y"
{
(yyval.addr2).from = (yyvsp[(1) - (5)].addr);
(yyval.addr2).from.scale = (yyvsp[(3) - (5)].lval);
@ -2032,7 +2031,7 @@ yyreduce:
break;
case 58:
#line 295 "a.y"
#line 294 "a.y"
{
(yyval.addr2).from = (yyvsp[(1) - (5)].addr);
(yyval.addr2).to = (yyvsp[(3) - (5)].addr);
@ -2041,20 +2040,20 @@ yyreduce:
break;
case 59:
#line 303 "a.y"
#line 302 "a.y"
{
(yyval.addr2).from = (yyvsp[(3) - (5)].addr);
(yyval.addr2).to = (yyvsp[(5) - (5)].addr);
if((yyvsp[(1) - (5)].addr).type != D_CONST)
if((yyvsp[(1) - (5)].addr).type != TYPE_CONST)
yyerror("illegal constant");
(yyval.addr2).to.offset = (yyvsp[(1) - (5)].addr).offset;
}
break;
case 60:
#line 313 "a.y"
#line 312 "a.y"
{
if((yyvsp[(1) - (3)].addr).type != D_CONST || (yyvsp[(3) - (3)].addr).type != D_CONST)
if((yyvsp[(1) - (3)].addr).type != TYPE_CONST || (yyvsp[(3) - (3)].addr).type != TYPE_CONST)
yyerror("arguments to PCDATA must be integer constants");
(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
@ -2062,11 +2061,11 @@ yyreduce:
break;
case 61:
#line 322 "a.y"
#line 321 "a.y"
{
if((yyvsp[(1) - (3)].addr).type != D_CONST)
if((yyvsp[(1) - (3)].addr).type != TYPE_CONST)
yyerror("index for FUNCDATA must be integer constant");
if((yyvsp[(3) - (3)].addr).type != D_EXTERN && (yyvsp[(3) - (3)].addr).type != D_STATIC)
if((yyvsp[(3) - (3)].addr).type != TYPE_MEM || ((yyvsp[(3) - (3)].addr).name != NAME_EXTERN && (yyvsp[(3) - (3)].addr).name != NAME_STATIC))
yyerror("value for FUNCDATA must be symbol reference");
(yyval.addr2).from = (yyvsp[(1) - (3)].addr);
(yyval.addr2).to = (yyvsp[(3) - (3)].addr);
@ -2074,45 +2073,46 @@ yyreduce:
break;
case 66:
#line 339 "a.y"
#line 338 "a.y"
{
(yyval.addr) = (yyvsp[(2) - (2)].addr);
}
break;
case 67:
#line 343 "a.y"
#line 342 "a.y"
{
(yyval.addr) = (yyvsp[(2) - (2)].addr);
}
break;
case 73:
#line 356 "a.y"
#line 355 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_BRANCH;
(yyval.addr).type = TYPE_BRANCH;
(yyval.addr).offset = (yyvsp[(1) - (4)].lval) + pc;
}
break;
case 74:
#line 362 "a.y"
#line 361 "a.y"
{
(yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
(yyval.addr) = nullgen;
if(pass == 2 && (yyvsp[(1) - (2)].sym)->type != LLAB)
yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->labelname);
(yyval.addr).type = D_BRANCH;
(yyval.addr).type = TYPE_BRANCH;
(yyval.addr).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
}
break;
case 75:
#line 373 "a.y"
#line 372 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = (yyvsp[(1) - (1)].lval);
(yyval.addr).type = TYPE_REG;
(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
}
break;
@ -2120,59 +2120,63 @@ yyreduce:
#line 378 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = (yyvsp[(1) - (1)].lval);
(yyval.addr).type = TYPE_REG;
(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
}
break;
case 77:
#line 383 "a.y"
#line 384 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = (yyvsp[(1) - (1)].lval);
(yyval.addr).type = TYPE_REG;
(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
}
break;
case 78:
#line 388 "a.y"
#line 390 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = (yyvsp[(1) - (1)].lval);
(yyval.addr).type = TYPE_REG;
(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
}
break;
case 79:
#line 393 "a.y"
#line 396 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_SP;
(yyval.addr).type = TYPE_REG;
(yyval.addr).reg = REG_SP;
}
break;
case 80:
#line 398 "a.y"
#line 402 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = (yyvsp[(1) - (1)].lval);
(yyval.addr).type = TYPE_REG;
(yyval.addr).reg = (yyvsp[(1) - (1)].lval);
}
break;
case 81:
#line 405 "a.y"
#line 410 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_CONST;
(yyval.addr).type = TYPE_CONST;
(yyval.addr).offset = (yyvsp[(2) - (2)].lval);
}
break;
case 82:
#line 411 "a.y"
#line 416 "a.y"
{
(yyval.addr) = (yyvsp[(2) - (2)].addr);
(yyval.addr).index = (yyvsp[(2) - (2)].addr).type;
(yyval.addr).type = D_ADDR;
(yyval.addr).type = TYPE_ADDR;
/*
if($2.type == D_AUTO || $2.type == D_PARAM)
if($2.name == D_AUTO || $2.name == D_PARAM)
yyerror("constant cannot be automatic: %s",
$2.sym->name);
*/
@ -2180,62 +2184,62 @@ yyreduce:
break;
case 83:
#line 422 "a.y"
#line 426 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_SCONST;
(yyval.addr).type = TYPE_SCONST;
memcpy((yyval.addr).u.sval, (yyvsp[(2) - (2)].sval), sizeof((yyval.addr).u.sval));
}
break;
case 84:
#line 428 "a.y"
#line 432 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_FCONST;
(yyval.addr).type = TYPE_FCONST;
(yyval.addr).u.dval = (yyvsp[(2) - (2)].dval);
}
break;
case 85:
#line 434 "a.y"
#line 438 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_FCONST;
(yyval.addr).type = TYPE_FCONST;
(yyval.addr).u.dval = (yyvsp[(3) - (4)].dval);
}
break;
case 86:
#line 440 "a.y"
#line 444 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_FCONST;
(yyval.addr).type = TYPE_FCONST;
(yyval.addr).u.dval = -(yyvsp[(4) - (5)].dval);
}
break;
case 87:
#line 446 "a.y"
#line 450 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_FCONST;
(yyval.addr).type = TYPE_FCONST;
(yyval.addr).u.dval = -(yyvsp[(3) - (3)].dval);
}
break;
case 88:
#line 454 "a.y"
#line 458 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_CONST2;
(yyval.addr).type = TYPE_TEXTSIZE;
(yyval.addr).offset = (yyvsp[(2) - (2)].con2).v1;
(yyval.addr).offset2 = (yyvsp[(2) - (2)].con2).v2;
(yyval.addr).u.argsize = (yyvsp[(2) - (2)].con2).v2;
}
break;
case 89:
#line 463 "a.y"
#line 467 "a.y"
{
(yyval.con2).v1 = (yyvsp[(1) - (1)].lval);
(yyval.con2).v2 = ArgsSizeUnknown;
@ -2243,7 +2247,7 @@ yyreduce:
break;
case 90:
#line 468 "a.y"
#line 472 "a.y"
{
(yyval.con2).v1 = -(yyvsp[(2) - (2)].lval);
(yyval.con2).v2 = ArgsSizeUnknown;
@ -2251,7 +2255,7 @@ yyreduce:
break;
case 91:
#line 473 "a.y"
#line 477 "a.y"
{
(yyval.con2).v1 = (yyvsp[(1) - (3)].lval);
(yyval.con2).v2 = (yyvsp[(3) - (3)].lval);
@ -2259,7 +2263,7 @@ yyreduce:
break;
case 92:
#line 478 "a.y"
#line 482 "a.y"
{
(yyval.con2).v1 = -(yyvsp[(2) - (4)].lval);
(yyval.con2).v2 = (yyvsp[(4) - (4)].lval);
@ -2267,37 +2271,41 @@ yyreduce:
break;
case 95:
#line 489 "a.y"
#line 493 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_INDIR+D_NONE;
(yyval.addr).type = TYPE_MEM;
(yyval.addr).reg = REG_NONE;
(yyval.addr).offset = (yyvsp[(1) - (1)].lval);
}
break;
case 96:
#line 495 "a.y"
#line 500 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_INDIR+(yyvsp[(3) - (4)].lval);
(yyval.addr).type = TYPE_MEM;
(yyval.addr).reg = (yyvsp[(3) - (4)].lval);
(yyval.addr).offset = (yyvsp[(1) - (4)].lval);
}
break;
case 97:
#line 501 "a.y"
#line 507 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_INDIR+D_SP;
(yyval.addr).type = TYPE_MEM;
(yyval.addr).reg = REG_SP;
(yyval.addr).offset = (yyvsp[(1) - (4)].lval);
}
break;
case 98:
#line 507 "a.y"
#line 514 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_INDIR+D_NONE;
(yyval.addr).type = TYPE_MEM;
(yyval.addr).reg = REG_NONE;
(yyval.addr).offset = (yyvsp[(1) - (6)].lval);
(yyval.addr).index = (yyvsp[(3) - (6)].lval);
(yyval.addr).scale = (yyvsp[(5) - (6)].lval);
@ -2306,10 +2314,11 @@ yyreduce:
break;
case 99:
#line 516 "a.y"
#line 524 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_INDIR+(yyvsp[(3) - (9)].lval);
(yyval.addr).type = TYPE_MEM;
(yyval.addr).reg = (yyvsp[(3) - (9)].lval);
(yyval.addr).offset = (yyvsp[(1) - (9)].lval);
(yyval.addr).index = (yyvsp[(6) - (9)].lval);
(yyval.addr).scale = (yyvsp[(8) - (9)].lval);
@ -2318,10 +2327,11 @@ yyreduce:
break;
case 100:
#line 525 "a.y"
#line 534 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_INDIR+(yyvsp[(3) - (9)].lval);
(yyval.addr).type = TYPE_MEM;
(yyval.addr).reg = (yyvsp[(3) - (9)].lval);
(yyval.addr).offset = (yyvsp[(1) - (9)].lval);
(yyval.addr).index = (yyvsp[(6) - (9)].lval);
(yyval.addr).scale = (yyvsp[(8) - (9)].lval);
@ -2330,35 +2340,39 @@ yyreduce:
break;
case 101:
#line 534 "a.y"
#line 544 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_INDIR+(yyvsp[(2) - (3)].lval);
(yyval.addr).type = TYPE_MEM;
(yyval.addr).reg = (yyvsp[(2) - (3)].lval);
}
break;
case 102:
#line 539 "a.y"
#line 550 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_INDIR+D_SP;
(yyval.addr).type = TYPE_MEM;
(yyval.addr).reg = REG_SP;
}
break;
case 103:
#line 544 "a.y"
#line 556 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_INDIR+(yyvsp[(3) - (4)].lval);
(yyval.addr).type = TYPE_MEM;
(yyval.addr).reg = (yyvsp[(3) - (4)].lval);
(yyval.addr).offset = (yyvsp[(1) - (4)].lval);
}
break;
case 104:
#line 550 "a.y"
#line 563 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_INDIR+D_NONE;
(yyval.addr).type = TYPE_MEM;
(yyval.addr).reg = REG_NONE;
(yyval.addr).index = (yyvsp[(2) - (5)].lval);
(yyval.addr).scale = (yyvsp[(4) - (5)].lval);
checkscale((yyval.addr).scale);
@ -2366,10 +2380,11 @@ yyreduce:
break;
case 105:
#line 558 "a.y"
#line 572 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_INDIR+(yyvsp[(2) - (8)].lval);
(yyval.addr).type = TYPE_MEM;
(yyval.addr).reg = (yyvsp[(2) - (8)].lval);
(yyval.addr).index = (yyvsp[(5) - (8)].lval);
(yyval.addr).scale = (yyvsp[(7) - (8)].lval);
checkscale((yyval.addr).scale);
@ -2377,14 +2392,14 @@ yyreduce:
break;
case 106:
#line 568 "a.y"
#line 583 "a.y"
{
(yyval.addr) = (yyvsp[(1) - (1)].addr);
}
break;
case 107:
#line 572 "a.y"
#line 587 "a.y"
{
(yyval.addr) = (yyvsp[(1) - (6)].addr);
(yyval.addr).index = (yyvsp[(3) - (6)].lval);
@ -2394,153 +2409,155 @@ yyreduce:
break;
case 108:
#line 581 "a.y"
#line 596 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = (yyvsp[(4) - (5)].lval);
(yyval.addr).type = TYPE_MEM;
(yyval.addr).name = (yyvsp[(4) - (5)].lval);
(yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (5)].sym)->name, 0);
(yyval.addr).offset = (yyvsp[(2) - (5)].lval);
}
break;
case 109:
#line 588 "a.y"
#line 604 "a.y"
{
(yyval.addr) = nullgen;
(yyval.addr).type = D_STATIC;
(yyval.addr).type = TYPE_MEM;
(yyval.addr).name = NAME_STATIC;
(yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (7)].sym)->name, 1);
(yyval.addr).offset = (yyvsp[(4) - (7)].lval);
}
break;
case 110:
#line 596 "a.y"
#line 613 "a.y"
{
(yyval.lval) = 0;
}
break;
case 111:
#line 600 "a.y"
#line 617 "a.y"
{
(yyval.lval) = (yyvsp[(2) - (2)].lval);
}
break;
case 112:
#line 604 "a.y"
#line 621 "a.y"
{
(yyval.lval) = -(yyvsp[(2) - (2)].lval);
}
break;
case 114:
#line 611 "a.y"
#line 628 "a.y"
{
(yyval.lval) = D_AUTO;
(yyval.lval) = NAME_AUTO;
}
break;
case 117:
#line 619 "a.y"
#line 636 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (1)].sym)->value;
}
break;
case 118:
#line 623 "a.y"
#line 640 "a.y"
{
(yyval.lval) = -(yyvsp[(2) - (2)].lval);
}
break;
case 119:
#line 627 "a.y"
#line 644 "a.y"
{
(yyval.lval) = (yyvsp[(2) - (2)].lval);
}
break;
case 120:
#line 631 "a.y"
#line 648 "a.y"
{
(yyval.lval) = ~(yyvsp[(2) - (2)].lval);
}
break;
case 121:
#line 635 "a.y"
#line 652 "a.y"
{
(yyval.lval) = (yyvsp[(2) - (3)].lval);
}
break;
case 123:
#line 642 "a.y"
#line 659 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval);
}
break;
case 124:
#line 646 "a.y"
#line 663 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval);
}
break;
case 125:
#line 650 "a.y"
#line 667 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval);
}
break;
case 126:
#line 654 "a.y"
#line 671 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval);
}
break;
case 127:
#line 658 "a.y"
#line 675 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval);
}
break;
case 128:
#line 662 "a.y"
#line 679 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval);
}
break;
case 129:
#line 666 "a.y"
#line 683 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval);
}
break;
case 130:
#line 670 "a.y"
#line 687 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval);
}
break;
case 131:
#line 674 "a.y"
#line 691 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval);
}
break;
case 132:
#line 678 "a.y"
#line 695 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval);
}
@ -2548,7 +2565,7 @@ yyreduce:
/* Line 1267 of yacc.c. */
#line 2552 "y.tab.c"
#line 2569 "y.tab.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);

View File

@ -715,8 +715,9 @@ agen(Node *n, Node *res)
// LEAL (n3)(n2*w), n3
p1 = gins(ALEAL, &n2, &n3);
p1->from.scale = w;
p1->from.index = p1->from.type;
p1->from.type = p1->to.type + D_INDIR;
p1->from.type = TYPE_MEM;
p1->from.index = p1->from.reg;
p1->from.reg = p1->to.reg;
} else {
nodconst(&tmp, types[TUINT32], w);
gins(optoas(OMUL, types[TUINT32]), &tmp, &n2);
@ -805,7 +806,7 @@ igen(Node *n, Node *a, Node *res)
case OINDREG:
// Increase the refcount of the register so that igen's caller
// has to call regfree.
if(n->val.u.reg != D_SP)
if(n->val.u.reg != REG_SP)
reg[n->val.u.reg]++;
*a = *n;
return;
@ -856,7 +857,7 @@ igen(Node *n, Node *a, Node *res)
fp = structfirst(&flist, getoutarg(n->left->type));
memset(a, 0, sizeof *a);
a->op = OINDREG;
a->val.u.reg = D_SP;
a->val.u.reg = REG_SP;
a->addable = 1;
a->xoffset = fp->width;
a->type = n->type;
@ -1262,8 +1263,8 @@ sgen(Node *n, Node *res, int64 w)
return;
}
nodreg(&dst, types[tptr], D_DI);
nodreg(&src, types[tptr], D_SI);
nodreg(&dst, types[tptr], REG_DI);
nodreg(&src, types[tptr], REG_SI);
tempname(&tsrc, types[tptr]);
tempname(&tdst, types[tptr]);
@ -1293,23 +1294,23 @@ sgen(Node *n, Node *res, int64 w)
// reverse direction
gins(ASTD, N, N); // set direction flag
if(c > 0) {
gconreg(AADDL, w-1, D_SI);
gconreg(AADDL, w-1, D_DI);
gconreg(AADDL, w-1, REG_SI);
gconreg(AADDL, w-1, REG_DI);
gconreg(AMOVL, c, D_CX);
gconreg(AMOVL, c, REG_CX);
gins(AREP, N, N); // repeat
gins(AMOVSB, N, N); // MOVB *(SI)-,*(DI)-
}
if(q > 0) {
if(c > 0) {
gconreg(AADDL, -3, D_SI);
gconreg(AADDL, -3, D_DI);
gconreg(AADDL, -3, REG_SI);
gconreg(AADDL, -3, REG_DI);
} else {
gconreg(AADDL, w-4, D_SI);
gconreg(AADDL, w-4, D_DI);
gconreg(AADDL, w-4, REG_SI);
gconreg(AADDL, w-4, REG_DI);
}
gconreg(AMOVL, q, D_CX);
gconreg(AMOVL, q, REG_CX);
gins(AREP, N, N); // repeat
gins(AMOVSL, N, N); // MOVL *(SI)-,*(DI)-
}
@ -1319,12 +1320,12 @@ sgen(Node *n, Node *res, int64 w)
gins(ACLD, N, N); // paranoia. TODO(rsc): remove?
// normal direction
if(q > 128 || (q >= 4 && nacl)) {
gconreg(AMOVL, q, D_CX);
gconreg(AMOVL, q, REG_CX);
gins(AREP, N, N); // repeat
gins(AMOVSL, N, N); // MOVL *(SI)+,*(DI)+
} else if(q >= 4) {
p = gins(ADUFFCOPY, N, N);
p->to.type = D_ADDR;
p->to.type = TYPE_ADDR;
p->to.sym = linksym(pkglookup("duffcopy", runtimepkg));
// 10 and 128 = magic constants: see ../../runtime/asm_386.s
p->to.offset = 10*(128-q);

View File

@ -73,9 +73,9 @@ cgen64(Node *n, Node *res)
r = &t2;
}
nodreg(&ax, types[TINT32], D_AX);
nodreg(&cx, types[TINT32], D_CX);
nodreg(&dx, types[TINT32], D_DX);
nodreg(&ax, types[TINT32], REG_AX);
nodreg(&cx, types[TINT32], REG_CX);
nodreg(&dx, types[TINT32], REG_DX);
// Setup for binary operation.
split64(l, &lo1, &hi1);
@ -159,10 +159,10 @@ cgen64(Node *n, Node *res)
} else {
gins(AMOVL, &dx, &cx);
p1 = gins(ASHLL, ncon(v), &dx);
p1->from.index = D_AX; // double-width shift
p1->from.index = REG_AX; // double-width shift
p1->from.scale = 0;
p1 = gins(ASHLL, ncon(v), &ax);
p1->from.index = D_CX; // double-width shift
p1->from.index = REG_CX; // double-width shift
p1->from.scale = 0;
}
break;
@ -198,7 +198,7 @@ cgen64(Node *n, Node *res)
gins(AMOVL, &lo1, &ax);
gins(AMOVL, &hi1, &dx);
p1 = gins(ASHLL, ncon(v), &dx);
p1->from.index = D_AX; // double-width shift
p1->from.index = REG_AX; // double-width shift
p1->from.scale = 0;
gins(ASHLL, ncon(v), &ax);
break;
@ -240,7 +240,7 @@ cgen64(Node *n, Node *res)
// general shift
p1 = gins(ASHLL, &cx, &dx);
p1->from.index = D_AX; // double-width shift
p1->from.index = REG_AX; // double-width shift
p1->from.scale = 0;
gins(ASHLL, &cx, &ax);
patch(p2, pc);
@ -287,7 +287,7 @@ cgen64(Node *n, Node *res)
gins(AMOVL, &lo1, &ax);
gins(AMOVL, &hi1, &dx);
p1 = gins(ASHRL, ncon(v), &ax);
p1->from.index = D_DX; // double-width shift
p1->from.index = REG_DX; // double-width shift
p1->from.scale = 0;
gins(optoas(ORSH, hi1.type), ncon(v), &dx);
break;
@ -339,7 +339,7 @@ cgen64(Node *n, Node *res)
// general shift
p1 = gins(ASHRL, &cx, &ax);
p1->from.index = D_DX; // double-width shift
p1->from.index = REG_DX; // double-width shift
p1->from.scale = 0;
gins(optoas(ORSH, hi1.type), &cx, &dx);
patch(p2, pc);

View File

@ -38,8 +38,8 @@ betypeinit(void)
zprog.link = P;
zprog.as = AGOK;
zprog.from.type = D_NONE;
zprog.from.index = D_NONE;
zprog.from.type = TYPE_NONE;
zprog.from.index = TYPE_NONE;
zprog.from.scale = 0;
zprog.to = zprog.from;
arch.zprog = zprog;
@ -71,10 +71,6 @@ main(int argc, char **argv)
arch.AUNDEF = AUNDEF;
arch.AVARDEF = AVARDEF;
arch.AVARKILL = AVARKILL;
arch.D_AUTO = D_AUTO;
arch.D_BRANCH = D_BRANCH;
arch.D_NONE = D_NONE;
arch.D_PARAM = D_PARAM;
arch.MAXWIDTH = MAXWIDTH;
arch.afunclit = afunclit;
arch.anyregalloc = anyregalloc;

View File

@ -20,7 +20,7 @@ enum
};
EXTERN int32 dynloc;
EXTERN uchar reg[D_NONE];
EXTERN uchar reg[MAXREG];
EXTERN int32 pcloc; // instruction counter
EXTERN Strlit emptystring;
EXTERN Prog zprog;

View File

@ -9,7 +9,7 @@
#include "gg.h"
#include "opt.h"
static Prog *appendpp(Prog*, int, int, vlong, int, vlong);
static Prog *appendpp(Prog*, int, int, int, vlong, int, int, vlong);
static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax);
void
@ -22,7 +22,7 @@ defframe(Prog *ptxt)
Node *n;
// fill in argument size
ptxt->to.offset2 = rnd(curfn->type->argwid, widthptr);
ptxt->to.u.argsize = rnd(curfn->type->argwid, widthptr);
// fill in final stack size
frame = rnd(stksize+maxarg, widthptr);
@ -68,28 +68,28 @@ zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax)
if(cnt == 0)
return p;
if(*ax == 0) {
p = appendpp(p, AMOVL, D_CONST, 0, D_AX, 0);
p = appendpp(p, AMOVL, TYPE_CONST, 0, 0, TYPE_REG, REG_AX, 0);
*ax = 1;
}
if(cnt <= 4*widthreg) {
for(i = 0; i < cnt; i += widthreg) {
p = appendpp(p, AMOVL, D_AX, 0, D_SP+D_INDIR, frame+lo+i);
p = appendpp(p, AMOVL, TYPE_REG, REG_AX, 0, TYPE_MEM, REG_SP, frame+lo+i);
}
} else if(!nacl && cnt <= 128*widthreg) {
p = appendpp(p, ALEAL, D_SP+D_INDIR, frame+lo, D_DI, 0);
p = appendpp(p, ADUFFZERO, D_NONE, 0, D_ADDR, 1*(128-cnt/widthreg));
p = appendpp(p, ALEAL, TYPE_MEM, REG_SP, frame+lo, TYPE_REG, REG_DI, 0);
p = appendpp(p, ADUFFZERO, TYPE_NONE, 0, 0, TYPE_ADDR, 0, 1*(128-cnt/widthreg));
p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
} else {
p = appendpp(p, AMOVL, D_CONST, cnt/widthreg, D_CX, 0);
p = appendpp(p, ALEAL, D_SP+D_INDIR, frame+lo, D_DI, 0);
p = appendpp(p, AREP, D_NONE, 0, D_NONE, 0);
p = appendpp(p, ASTOSL, D_NONE, 0, D_NONE, 0);
p = appendpp(p, AMOVL, TYPE_CONST, 0, cnt/widthreg, TYPE_REG, REG_CX, 0);
p = appendpp(p, ALEAL, TYPE_MEM, REG_SP, frame+lo, TYPE_REG, REG_DI, 0);
p = appendpp(p, AREP, TYPE_NONE, 0, 0, TYPE_NONE, 0, 0);
p = appendpp(p, ASTOSL, TYPE_NONE, 0, 0, TYPE_NONE, 0, 0);
}
return p;
}
static Prog*
appendpp(Prog *p, int as, int ftype, vlong foffset, int ttype, vlong toffset)
appendpp(Prog *p, int as, int ftype, int freg, vlong foffset, int ttype, int treg, vlong toffset)
{
Prog *q;
q = mal(sizeof(*q));
@ -97,8 +97,10 @@ appendpp(Prog *p, int as, int ftype, vlong foffset, int ttype, vlong toffset)
q->as = as;
q->lineno = p->lineno;
q->from.type = ftype;
q->from.reg = freg;
q->from.offset = foffset;
q->to.type = ttype;
q->to.reg = treg;
q->to.offset = toffset;
q->link = p->link;
p->link = q;
@ -128,7 +130,7 @@ fixautoused(Prog* p)
Prog **lp;
for (lp=&p; (p=*lp) != P; ) {
if (p->as == ATYPE && p->from.node && p->from.type == D_AUTO && !((Node*)(p->from.node))->used) {
if (p->as == ATYPE && p->from.node && p->from.name == NAME_AUTO && !((Node*)(p->from.node))->used) {
*lp = p->link;
continue;
}
@ -137,16 +139,14 @@ fixautoused(Prog* p)
// VARDEFs are interspersed with other code, and a jump might be using the
// VARDEF as a target. Replace with a no-op instead. A later pass will remove
// the no-ops.
p->to.type = D_NONE;
p->to.node = N;
p->as = ANOP;
nopout(p);
continue;
}
if (p->from.type == D_AUTO && p->from.node)
if (p->from.type == TYPE_MEM && p->from.name == NAME_AUTO && p->from.node)
p->from.offset += ((Node*)(p->from.node))->stkdelta;
if (p->to.type == D_AUTO && p->to.node)
if (p->to.type == TYPE_MEM && p->to.name == NAME_AUTO && p->to.node)
p->to.offset += ((Node*)(p->to.node))->stkdelta;
lp = &p->link;
@ -198,17 +198,17 @@ clearfat(Node *nl)
return;
}
nodreg(&n1, types[tptr], D_DI);
nodreg(&n1, types[tptr], REG_DI);
agen(nl, &n1);
gconreg(AMOVL, 0, D_AX);
gconreg(AMOVL, 0, REG_AX);
if(q > 128 || (q >= 4 && nacl)) {
gconreg(AMOVL, q, D_CX);
gconreg(AMOVL, q, REG_CX);
gins(AREP, N, N); // repeat
gins(ASTOSL, N, N); // STOL AL,*(DI)+
} else if(q >= 4) {
p = gins(ADUFFZERO, N, N);
p->to.type = D_ADDR;
p->to.type = TYPE_ADDR;
p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
// 1 and 128 = magic constants: see ../../runtime/asm_386.s
p->to.offset = 1*(128-q);
@ -265,7 +265,7 @@ ginscall(Node *f, int proc)
// x86 NOP 0x90 is really XCHG AX, AX; use that description
// because the NOP pseudo-instruction will be removed by
// the linker.
nodreg(&reg, types[TINT], D_AX);
nodreg(&reg, types[TINT], REG_AX);
gins(AXCHGL, &reg, &reg);
}
p = gins(ACALL, N, f);
@ -274,8 +274,8 @@ ginscall(Node *f, int proc)
gins(AUNDEF, N, N);
break;
}
nodreg(&reg, types[tptr], D_DX);
nodreg(&r1, types[tptr], D_BX);
nodreg(&reg, types[tptr], REG_DX);
nodreg(&r1, types[tptr], REG_BX);
gmove(f, &reg);
reg.op = OINDREG;
gmove(&reg, &r1);
@ -291,7 +291,7 @@ ginscall(Node *f, int proc)
case 2: // deferred call (defer)
memset(&stk, 0, sizeof(stk));
stk.op = OINDREG;
stk.val.u.reg = D_SP;
stk.val.u.reg = REG_SP;
stk.xoffset = 0;
// size of arguments at 0(SP)
@ -307,7 +307,7 @@ ginscall(Node *f, int proc)
else
ginscall(deferproc, 0);
if(proc == 2) {
nodreg(&reg, types[TINT32], D_AX);
nodreg(&reg, types[TINT32], REG_AX);
gins(ATESTL, &reg, &reg);
p = gbranch(AJEQ, T, +1);
cgen_ret(N);
@ -349,7 +349,7 @@ cgen_callinter(Node *n, Node *res, int proc)
// register to hold its address.
igen(i, &nodi, res); // REG = &inter
nodindreg(&nodsp, types[tptr], D_SP);
nodindreg(&nodsp, types[tptr], REG_SP);
nodsp.xoffset = 0;
if(proc != 0)
nodsp.xoffset += 2 * widthptr; // leave room for size & fn
@ -458,7 +458,7 @@ cgen_callret(Node *n, Node *res)
memset(&nod, 0, sizeof(nod));
nod.op = OINDREG;
nod.val.u.reg = D_SP;
nod.val.u.reg = REG_SP;
nod.addable = 1;
nod.xoffset = fp->width;
@ -488,7 +488,7 @@ cgen_aret(Node *n, Node *res)
memset(&nod1, 0, sizeof(nod1));
nod1.op = OINDREG;
nod1.val.u.reg = D_SP;
nod1.val.u.reg = REG_SP;
nod1.addable = 1;
nod1.xoffset = fp->width;
@ -519,7 +519,8 @@ cgen_ret(Node *n)
genlist(curfn->exit);
p = gins(ARET, N, N);
if(n != N && n->op == ORETJMP) {
p->to.type = D_EXTERN;
p->to.type = TYPE_MEM;
p->to.name = NAME_EXTERN;
p->to.sym = linksym(n->left->sym);
}
}
@ -830,8 +831,8 @@ cgen_div(int op, Node *nl, Node *nr, Node *res)
t = types[TINT32];
else
t = types[TUINT32];
savex(D_AX, &ax, &oldax, res, t);
savex(D_DX, &dx, &olddx, res, t);
savex(REG_AX, &ax, &oldax, res, t);
savex(REG_DX, &dx, &olddx, res, t);
dodiv(op, nl, nr, res, &ax, &dx);
restx(&dx, &olddx);
restx(&ax, &oldax);
@ -875,8 +876,8 @@ cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
}
memset(&oldcx, 0, sizeof oldcx);
nodreg(&cx, types[TUINT32], D_CX);
if(reg[D_CX] > 1 && !samereg(&cx, res)) {
nodreg(&cx, types[TUINT32], REG_CX);
if(reg[REG_CX] > 1 && !samereg(&cx, res)) {
tempname(&oldcx, types[TUINT32]);
gmove(&cx, &oldcx);
}
@ -885,7 +886,7 @@ cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
tempname(&nt, nr->type);
n1 = nt;
} else {
nodreg(&n1, types[TUINT32], D_CX);
nodreg(&n1, types[TUINT32], REG_CX);
regalloc(&n1, nr->type, &n1); // to hold the shift type in CX
}
@ -905,7 +906,7 @@ cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
if(bounded) {
if(nr->type->width > 4) {
// delayed reg alloc
nodreg(&n1, types[TUINT32], D_CX);
nodreg(&n1, types[TUINT32], REG_CX);
regalloc(&n1, types[TUINT32], &n1); // to hold the shift type in CX
split64(&nt, &lo, &hi);
gmove(&lo, &n1);
@ -914,7 +915,7 @@ cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
} else {
if(nr->type->width > 4) {
// delayed reg alloc
nodreg(&n1, types[TUINT32], D_CX);
nodreg(&n1, types[TUINT32], REG_CX);
regalloc(&n1, types[TUINT32], &n1); // to hold the shift type in CX
split64(&nt, &lo, &hi);
gmove(&lo, &n1);
@ -1005,18 +1006,18 @@ cgen_hmul(Node *nl, Node *nr, Node *res)
cgen(nr, &n2);
// multiply.
nodreg(&ax, t, D_AX);
nodreg(&ax, t, REG_AX);
gmove(&n2, &ax);
gins(a, &n1, N);
regfree(&n2);
if(t->width == 1) {
// byte multiply behaves differently.
nodreg(&ax, t, D_AH);
nodreg(&dx, t, D_DX);
nodreg(&ax, t, REG_AH);
nodreg(&dx, t, REG_DX);
gmove(&ax, &dx);
}
nodreg(&dx, t, D_DX);
nodreg(&dx, t, REG_DX);
gmove(&dx, res);
}
@ -1083,8 +1084,8 @@ cgen_float387(Node *n, Node *res)
nl = n->left;
nr = n->right;
nodreg(&f0, nl->type, D_F0);
nodreg(&f1, n->type, D_F0+1);
nodreg(&f0, nl->type, REG_F0);
nodreg(&f1, n->type, REG_F0+1);
if(nr != N)
goto flt2;
@ -1223,9 +1224,9 @@ x87:
a = brrev(a);
}
nodreg(&tmp, nr->type, D_F0);
nodreg(&n2, nr->type, D_F0 + 1);
nodreg(&ax, types[TUINT16], D_AX);
nodreg(&tmp, nr->type, REG_F0);
nodreg(&n2, nr->type, REG_F0 + 1);
nodreg(&ax, types[TUINT16], REG_AX);
et = simsimtype(nr->type);
if(et == TFLOAT64) {
if(nl->ullman > nr->ullman) {
@ -1336,22 +1337,24 @@ expandchecks(Prog *firstp)
p1->pc = 9999;
p2->pc = 9999;
p->as = ACMPL;
p->to.type = D_CONST;
p->to.type = TYPE_CONST;
p->to.offset = 0;
p1->as = AJNE;
p1->from.type = D_CONST;
p1->from.type = TYPE_CONST;
p1->from.offset = 1; // likely
p1->to.type = D_BRANCH;
p1->to.type = TYPE_BRANCH;
p1->to.u.branch = p2->link;
// crash by write to memory address 0.
// if possible, since we know arg is 0, use 0(arg),
// which will be shorter to encode than plain 0.
p2->as = AMOVL;
p2->from.type = D_AX;
if(regtyp(&p->from))
p2->to.type = p->from.type + D_INDIR;
else
p2->to.type = D_INDIR+D_NONE;
p2->from.type = TYPE_REG;
p2->from.reg = REG_AX;
if(regtyp(&p->from)) {
p2->to.type = TYPE_MEM;
p2->to.reg = p->from.reg;
} else
p2->to.type = TYPE_MEM;
p2->to.offset = 0;
}
}

View File

@ -38,14 +38,13 @@ dsname(Sym *s, int off, char *t, int n)
Prog *p;
p = gins(ADATA, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.offset = off;
p->from.scale = n;
p->from.sym = linksym(s);
p->to.type = D_SCONST;
p->to.index = D_NONE;
p->to.type = TYPE_SCONST;
memmove(p->to.u.sval, t, n);
return off + n;
}
@ -60,7 +59,8 @@ datastring(char *s, int len, Addr *a)
Sym *sym;
sym = stringsym(s, len);
a->type = D_EXTERN;
a->type = TYPE_MEM;
a->name = NAME_EXTERN;
a->sym = linksym(sym);
a->node = sym->def;
a->offset = widthptr+4; // skip header
@ -77,7 +77,8 @@ datagostring(Strlit *sval, Addr *a)
Sym *sym;
sym = stringsym(sval->s, sval->len);
a->type = D_EXTERN;
a->type = TYPE_MEM;
a->name = NAME_EXTERN;
a->sym = linksym(sym);
a->node = sym->def;
a->offset = 0; // header
@ -125,13 +126,13 @@ gdatacomplex(Node *nam, Mpcplx *cval)
p = gins(ADATA, nam, N);
p->from.scale = w;
p->to.type = D_FCONST;
p->to.type = TYPE_FCONST;
p->to.u.dval = mpgetflt(&cval->real);
p = gins(ADATA, nam, N);
p->from.scale = w;
p->from.offset += w;
p->to.type = D_FCONST;
p->to.type = TYPE_FCONST;
p->to.u.dval = mpgetflt(&cval->imag);
}
@ -144,8 +145,7 @@ gdatastring(Node *nam, Strlit *sval)
p = gins(ADATA, nam, N);
datastring(sval->s, sval->len, &p->to);
p->from.scale = types[tptr]->width;
p->to.index = p->to.type;
p->to.type = D_ADDR;
p->to.type = TYPE_ADDR;
//print("%P\n", p);
nodconst(&nod1, types[TINT32], sval->len);
@ -161,15 +161,14 @@ dstringptr(Sym *s, int off, char *str)
off = rnd(off, widthptr);
p = gins(ADATA, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.sym = linksym(s);
p->from.offset = off;
p->from.scale = widthptr;
datastring(str, strlen(str)+1, &p->to);
p->to.index = p->to.type;
p->to.type = D_ADDR;
p->to.type = TYPE_ADDR;
p->to.etype = TINT32;
off += widthptr;
@ -186,14 +185,13 @@ dgostrlitptr(Sym *s, int off, Strlit *lit)
off = rnd(off, widthptr);
p = gins(ADATA, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.sym = linksym(s);
p->from.offset = off;
p->from.scale = widthptr;
datagostring(lit, &p->to);
p->to.index = p->to.type;
p->to.type = D_ADDR;
p->to.type = TYPE_ADDR;
p->to.etype = TINT32;
off += widthptr;
@ -224,13 +222,13 @@ dsymptr(Sym *s, int off, Sym *x, int xoff)
off = rnd(off, widthptr);
p = gins(ADATA, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.sym = linksym(s);
p->from.offset = off;
p->from.scale = widthptr;
p->to.type = D_ADDR;
p->to.index = D_EXTERN;
p->to.type = TYPE_ADDR;
p->to.name = NAME_EXTERN;
p->to.sym = linksym(x);
p->to.offset = xoff;
off += widthptr;
@ -242,5 +240,7 @@ void
nopout(Prog *p)
{
p->as = ANOP;
p->from = zprog.from;
p->to = zprog.to;
}

View File

@ -45,10 +45,10 @@ void
clearp(Prog *p)
{
p->as = AEND;
p->from.type = D_NONE;
p->from.index = D_NONE;
p->to.type = D_NONE;
p->to.index = D_NONE;
p->from.type = TYPE_NONE;
p->from.index = TYPE_NONE;
p->to.type = TYPE_NONE;
p->to.index = TYPE_NONE;
p->pc = pcloc;
pcloc++;
}
@ -120,10 +120,10 @@ gbranch(int as, Type *t, int likely)
USED(t);
p = prog(as);
p->to.type = D_BRANCH;
p->to.type = TYPE_BRANCH;
p->to.u.branch = P;
if(likely != 0) {
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = likely > 0;
}
return p;
@ -135,7 +135,7 @@ gbranch(int as, Type *t, int likely)
void
patch(Prog *p, Prog *to)
{
if(p->to.type != D_BRANCH)
if(p->to.type != TYPE_BRANCH)
fatal("patch: not a branch");
p->to.u.branch = to;
p->to.offset = to->pc;
@ -146,7 +146,7 @@ unpatch(Prog *p)
{
Prog *q;
if(p->to.type != D_BRANCH)
if(p->to.type != TYPE_BRANCH)
fatal("unpatch: not a branch");
q = p->to.u.branch;
p->to.u.branch = P;
@ -197,7 +197,7 @@ ggloblnod(Node *nam)
p->lineno = nam->lineno;
p->from.sym->gotype = linksym(ngotype(nam));
p->to.sym = nil;
p->to.type = D_CONST;
p->to.type = TYPE_CONST;
p->to.offset = nam->type->width;
if(nam->readonly)
p->from.scale = RODATA;
@ -211,11 +211,12 @@ ggloblsym(Sym *s, int32 width, int8 flags)
Prog *p;
p = gins(AGLOBL, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.index = REG_NONE;
p->from.sym = linksym(s);
p->to.type = D_CONST;
p->to.index = D_NONE;
p->to.type = TYPE_CONST;
p->to.index = REG_NONE;
p->to.offset = width;
p->from.scale = flags;
}
@ -226,8 +227,8 @@ gtrack(Sym *s)
Prog *p;
p = gins(AUSEFIELD, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.sym = linksym(s);
}
@ -253,9 +254,8 @@ isfat(Type *t)
void
afunclit(Addr *a, Node *n)
{
if(a->type == D_ADDR && a->index == D_EXTERN) {
a->type = D_EXTERN;
a->index = D_NONE;
if(a->type == TYPE_ADDR && a->name == NAME_EXTERN) {
a->type = TYPE_MEM;
a->sym = linksym(n->sym);
}
}
@ -833,16 +833,16 @@ sse:
static int resvd[] =
{
// D_DI, // for movstring
// D_SI, // for movstring
// REG_DI, // for movstring
// REG_SI, // for movstring
D_AX, // for divide
D_CX, // for shift
D_DX, // for divide
D_SP, // for stack
REG_AX, // for divide
REG_CX, // for shift
REG_DX, // for divide
REG_SP, // for stack
D_BL, // because D_BX can be allocated
D_BH,
REG_BL, // because REG_BX can be allocated
REG_BH,
};
void
@ -852,15 +852,15 @@ ginit(void)
for(i=0; i<nelem(reg); i++)
reg[i] = 1;
for(i=D_AX; i<=D_DI; i++)
for(i=REG_AX; i<=REG_DI; i++)
reg[i] = 0;
for(i=D_X0; i<=D_X7; i++)
for(i=REG_X0; i<=REG_X7; i++)
reg[i] = 0;
for(i=0; i<nelem(resvd); i++)
reg[resvd[i]]++;
}
uintptr regpc[D_NONE];
uintptr regpc[MAXREG];
void
gclean(void)
@ -870,10 +870,10 @@ gclean(void)
for(i=0; i<nelem(resvd); i++)
reg[resvd[i]]--;
for(i=D_AX; i<=D_DI; i++)
for(i=REG_AX; i<=REG_DI; i++)
if(reg[i])
yyerror("reg %R left allocated at %ux", i, regpc[i]);
for(i=D_X0; i<=D_X7; i++)
for(i=REG_X0; i<=REG_X7; i++)
if(reg[i])
yyerror("reg %R left allocated\n", i);
}
@ -883,7 +883,7 @@ anyregalloc(void)
{
int i, j;
for(i=D_AX; i<=D_DI; i++) {
for(i=REG_AX; i<=REG_DI; i++) {
if(reg[i] == 0)
goto ok;
for(j=0; j<nelem(resvd); j++)
@ -892,7 +892,7 @@ anyregalloc(void)
return 1;
ok:;
}
for(i=D_X0; i<=D_X7; i++)
for(i=REG_X0; i<=REG_X7; i++)
if(reg[i])
return 1;
return 0;
@ -928,15 +928,15 @@ regalloc(Node *n, Type *t, Node *o)
case TBOOL:
if(o != N && o->op == OREGISTER) {
i = o->val.u.reg;
if(i >= D_AX && i <= D_DI)
if(i >= REG_AX && i <= REG_DI)
goto out;
}
for(i=D_AX; i<=D_DI; i++)
for(i=REG_AX; i<=REG_DI; i++)
if(reg[i] == 0)
goto out;
fprint(2, "registers allocated at\n");
for(i=D_AX; i<=D_DI; i++)
for(i=REG_AX; i<=REG_DI; i++)
fprint(2, "\t%R\t%#lux\n", i, regpc[i]);
fatal("out of fixed registers");
goto err;
@ -944,19 +944,19 @@ regalloc(Node *n, Type *t, Node *o)
case TFLOAT32:
case TFLOAT64:
if(!use_sse) {
i = D_F0;
i = REG_F0;
goto out;
}
if(o != N && o->op == OREGISTER) {
i = o->val.u.reg;
if(i >= D_X0 && i <= D_X7)
if(i >= REG_X0 && i <= REG_X7)
goto out;
}
for(i=D_X0; i<=D_X7; i++)
for(i=REG_X0; i<=REG_X7; i++)
if(reg[i] == 0)
goto out;
fprint(2, "registers allocated at\n");
for(i=D_X0; i<=D_X7; i++)
for(i=REG_X0; i<=REG_X7; i++)
fprint(2, "\t%R\t%#lux\n", i, regpc[i]);
fatal("out of floating registers");
}
@ -967,11 +967,11 @@ err:
return;
out:
if (i == D_SP)
if(i == REG_SP)
print("alloc SP\n");
if(reg[i] == 0) {
regpc[i] = (uintptr)getcallerpc(&n);
if(i == D_AX || i == D_CX || i == D_DX || i == D_SP) {
if(i == REG_AX || i == REG_CX || i == REG_DX || i == REG_SP) {
dump("regalloc-o", o);
fatal("regalloc %R", i);
}
@ -990,14 +990,14 @@ regfree(Node *n)
if(n->op != OREGISTER && n->op != OINDREG)
fatal("regfree: not a register");
i = n->val.u.reg;
if(i == D_SP)
if(i == REG_SP)
return;
if(i < 0 || i >= nelem(reg))
fatal("regfree: reg out of range");
if(reg[i] <= 0)
fatal("regfree: reg not allocated");
reg[i]--;
if(reg[i] == 0 && (i == D_AX || i == D_CX || i == D_DX || i == D_SP))
if(reg[i] == 0 && (i == REG_AX || i == REG_CX || i == REG_DX || i == REG_SP))
fatal("regfree %R", i);
}
@ -1088,7 +1088,7 @@ nodarg(Type *t, int fp)
case 0: // output arg
n->op = OINDREG;
n->val.u.reg = D_SP;
n->val.u.reg = REG_SP;
break;
case 1: // input arg
@ -1349,7 +1349,7 @@ gmove(Node *f, Node *t)
case CASE(TINT64, TUINT8):
case CASE(TUINT64, TUINT8):
split64(f, &flo, &fhi);
nodreg(&r1, t->type, D_AX);
nodreg(&r1, t->type, REG_AX);
gmove(&flo, &r1);
gins(AMOVB, &r1, t);
splitclean();
@ -1374,7 +1374,7 @@ gmove(Node *f, Node *t)
case CASE(TINT64, TUINT16):
case CASE(TUINT64, TUINT16):
split64(f, &flo, &fhi);
nodreg(&r1, t->type, D_AX);
nodreg(&r1, t->type, REG_AX);
gmove(&flo, &r1);
gins(AMOVW, &r1, t);
splitclean();
@ -1392,7 +1392,7 @@ gmove(Node *f, Node *t)
case CASE(TINT64, TUINT32):
case CASE(TUINT64, TUINT32):
split64(f, &flo, &fhi);
nodreg(&r1, t->type, D_AX);
nodreg(&r1, t->type, REG_AX);
gmove(&flo, &r1);
gins(AMOVL, &r1, t);
splitclean();
@ -1408,8 +1408,8 @@ gmove(Node *f, Node *t)
gins(AMOVL, &flo, &tlo);
gins(AMOVL, &fhi, &thi);
} else {
nodreg(&r1, t->type, D_AX);
nodreg(&r2, t->type, D_DX);
nodreg(&r1, t->type, REG_AX);
nodreg(&r2, t->type, REG_DX);
gins(AMOVL, &flo, &r1);
gins(AMOVL, &fhi, &r2);
gins(AMOVL, &r1, &tlo);
@ -1469,8 +1469,8 @@ gmove(Node *f, Node *t)
case CASE(TINT32, TINT64): // sign extend int32
case CASE(TINT32, TUINT64):
split64(t, &tlo, &thi);
nodreg(&flo, tlo.type, D_AX);
nodreg(&fhi, thi.type, D_DX);
nodreg(&flo, tlo.type, REG_AX);
nodreg(&fhi, thi.type, REG_DX);
gmove(f, &flo);
gins(ACDQ, N, N);
gins(AMOVL, &flo, &tlo);
@ -1571,7 +1571,7 @@ floatmove(Node *f, Node *t)
cvt = f->type;
goto hardmem;
}
nodreg(&r1, types[ft], D_F0);
nodreg(&r1, types[ft], REG_F0);
if(ft == TFLOAT32)
gins(AFMOVF, f, &r1);
else
@ -1599,9 +1599,9 @@ floatmove(Node *f, Node *t)
goto hardmem;
}
bignodes();
nodreg(&f0, types[ft], D_F0);
nodreg(&f1, types[ft], D_F0 + 1);
nodreg(&ax, types[TUINT16], D_AX);
nodreg(&f0, types[ft], REG_F0);
nodreg(&f1, types[ft], REG_F0 + 1);
nodreg(&ax, types[TUINT16], REG_AX);
if(ft == TFLOAT32)
gins(AFMOVF, f, &f0);
@ -1663,7 +1663,7 @@ floatmove(Node *f, Node *t)
case CASE(TINT64, TFLOAT64):
if(t->op == OREGISTER)
goto hardmem;
nodreg(&f0, t->type, D_F0);
nodreg(&f0, t->type, REG_F0);
gins(AFMOVV, f, &f0);
if(tt == TFLOAT32)
gins(AFMOVFP, &f0, t);
@ -1676,16 +1676,16 @@ floatmove(Node *f, Node *t)
// algorithm is:
// if small enough, use native int64 -> float64 conversion.
// otherwise, halve (rounding to odd?), convert, and double.
nodreg(&ax, types[TUINT32], D_AX);
nodreg(&dx, types[TUINT32], D_DX);
nodreg(&cx, types[TUINT32], D_CX);
nodreg(&ax, types[TUINT32], REG_AX);
nodreg(&dx, types[TUINT32], REG_DX);
nodreg(&cx, types[TUINT32], REG_CX);
tempname(&t1, f->type);
split64(&t1, &tlo, &thi);
gmove(f, &t1);
gins(ACMPL, &thi, ncon(0));
p1 = gbranch(AJLT, T, 0);
// native
nodreg(&r1, types[tt], D_F0);
nodreg(&r1, types[tt], REG_F0);
gins(AFMOVV, &t1, &r1);
if(tt == TFLOAT32)
gins(AFMOVFP, &r1, t);
@ -1697,7 +1697,7 @@ floatmove(Node *f, Node *t)
gmove(&tlo, &ax);
gmove(&thi, &dx);
p1 = gins(ASHRL, ncon(1), &ax);
p1->from.index = D_DX; // double-width shift DX -> AX
p1->from.index = REG_DX; // double-width shift DX -> AX
p1->from.scale = 0;
gins(AMOVL, ncon(0), &cx);
gins(ASETCC, N, &cx);
@ -1705,8 +1705,8 @@ floatmove(Node *f, Node *t)
gins(ASHRL, ncon(1), &dx);
gmove(&dx, &thi);
gmove(&ax, &tlo);
nodreg(&r1, types[tt], D_F0);
nodreg(&r2, types[tt], D_F0 + 1);
nodreg(&r1, types[tt], REG_F0);
nodreg(&r2, types[tt], REG_F0 + 1);
gins(AFMOVV, &t1, &r1);
gins(AFMOVD, &r1, &r1);
gins(AFADDDP, &r1, &r2);
@ -1762,7 +1762,7 @@ floatmove_387(Node *f, Node *t)
case CASE(TFLOAT64, TINT64):
if(t->op == OREGISTER)
goto hardmem;
nodreg(&r1, types[ft], D_F0);
nodreg(&r1, types[ft], REG_F0);
if(f->op != OREGISTER) {
if(ft == TFLOAT32)
gins(AFMOVF, f, &r1);
@ -1890,7 +1890,7 @@ floatmove_387(Node *f, Node *t)
if(ismem(f) && ismem(t))
goto hard;
if(f->op == OREGISTER && t->op == OREGISTER) {
if(f->val.u.reg != D_F0 || t->val.u.reg != D_F0)
if(f->val.u.reg != REG_F0 || t->val.u.reg != REG_F0)
goto fatal;
return;
}
@ -1898,7 +1898,7 @@ floatmove_387(Node *f, Node *t)
if(ft == TFLOAT64)
a = AFMOVD;
if(ismem(t)) {
if(f->op != OREGISTER || f->val.u.reg != D_F0)
if(f->op != OREGISTER || f->val.u.reg != REG_F0)
fatal("gmove %N", f);
a = AFMOVFP;
if(ft == TFLOAT64)
@ -1910,7 +1910,7 @@ floatmove_387(Node *f, Node *t)
if(ismem(f) && ismem(t))
goto hard;
if(f->op == OREGISTER && t->op == OREGISTER) {
if(f->val.u.reg != D_F0 || t->val.u.reg != D_F0)
if(f->val.u.reg != REG_F0 || t->val.u.reg != REG_F0)
goto fatal;
return;
}
@ -2110,7 +2110,7 @@ gins(int as, Node *f, Node *t)
fatal("gins MOVF reg, reg");
if(as == ACVTSD2SS && f && f->op == OLITERAL)
fatal("gins CVTSD2SS const");
if(as == AMOVSD && t && t->op == OREGISTER && t->val.u.reg == D_F0)
if(as == AMOVSD && t && t->op == OREGISTER && t->val.u.reg == REG_F0)
fatal("gins MOVSD into F0");
switch(as) {
@ -2159,6 +2159,8 @@ gins(int as, Node *f, Node *t)
dump("bad width to:", t);
fatal("bad width: %P (%d, %d)\n", p, af.width, at.width);
}
if(p->to.type == TYPE_ADDR && w > 0)
fatal("bad use of addr: %P", p);
return p;
}
@ -2173,8 +2175,10 @@ naddr(Node *n, Addr *a, int canemitcode)
Sym *s;
a->scale = 0;
a->index = D_NONE;
a->type = D_NONE;
a->reg = REG_NONE;
a->index = REG_NONE;
a->type = TYPE_NONE;
a->name = NAME_NONE;
a->gotype = nil;
a->node = N;
if(n == N)
@ -2186,12 +2190,14 @@ naddr(Node *n, Addr *a, int canemitcode)
break;
case OREGISTER:
a->type = n->val.u.reg;
a->type = TYPE_REG;
a->reg = n->val.u.reg;
a->sym = nil;
break;
case OINDREG:
a->type = n->val.u.reg+D_INDIR;
a->type = TYPE_MEM;
a->reg = n->val.u.reg;
a->sym = linksym(n->sym);
a->offset = n->xoffset;
break;
@ -2203,14 +2209,16 @@ naddr(Node *n, Addr *a, int canemitcode)
a->width = n->left->type->width;
a->offset = n->xoffset;
a->sym = linksym(n->left->sym);
a->type = D_PARAM;
a->type = TYPE_MEM;
a->name = NAME_PARAM;
a->node = n->left->orig;
break;
case OCLOSUREVAR:
if(!curfn->needctxt)
fatal("closurevar without needctxt");
a->type = D_DX+D_INDIR;
a->type = TYPE_MEM;
a->reg = REG_DX;
a->offset = n->xoffset;
a->sym = nil;
break;
@ -2246,18 +2254,21 @@ naddr(Node *n, Addr *a, int canemitcode)
default:
fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
case PEXTERN:
a->type = D_EXTERN;
a->type = TYPE_MEM;
a->name = NAME_EXTERN;
break;
case PAUTO:
a->type = D_AUTO;
a->type = TYPE_MEM;
a->name = NAME_AUTO;
break;
case PPARAM:
case PPARAMOUT:
a->type = D_PARAM;
a->type = TYPE_MEM;
a->name = NAME_PARAM;
break;
case PFUNC:
a->index = D_EXTERN;
a->type = D_ADDR;
a->type = TYPE_ADDR;
a->name = NAME_EXTERN;
s = funcsym(s);
break;
}
@ -2270,13 +2281,13 @@ naddr(Node *n, Addr *a, int canemitcode)
fatal("naddr: const %lT", n->type);
break;
case CTFLT:
a->type = D_FCONST;
a->type = TYPE_FCONST;
a->u.dval = mpgetflt(n->val.u.fval);
break;
case CTINT:
case CTRUNE:
a->sym = nil;
a->type = D_CONST;
a->type = TYPE_CONST;
a->offset = mpgetfix(n->val.u.xval);
break;
case CTSTR:
@ -2284,12 +2295,12 @@ naddr(Node *n, Addr *a, int canemitcode)
break;
case CTBOOL:
a->sym = nil;
a->type = D_CONST;
a->type = TYPE_CONST;
a->offset = n->val.u.bval;
break;
case CTNIL:
a->sym = nil;
a->type = D_CONST;
a->type = TYPE_CONST;
a->offset = 0;
break;
}
@ -2297,23 +2308,15 @@ naddr(Node *n, Addr *a, int canemitcode)
case OADDR:
naddr(n->left, a, canemitcode);
if(a->type >= D_INDIR) {
a->type -= D_INDIR;
break;
}
if(a->type == D_EXTERN || a->type == D_STATIC ||
a->type == D_AUTO || a->type == D_PARAM)
if(a->index == D_NONE) {
a->index = a->type;
a->type = D_ADDR;
break;
}
fatal("naddr: OADDR\n");
if(a->type != TYPE_MEM)
fatal("naddr: OADDR %D", a);
a->type = TYPE_ADDR;
break;
case OITAB:
// itable of interface value
naddr(n->left, a, canemitcode);
if(a->type == D_CONST && a->offset == 0)
if(a->type == TYPE_CONST && a->offset == 0)
break; // len(nil)
a->etype = tptr;
a->width = widthptr;
@ -2322,7 +2325,7 @@ naddr(Node *n, Addr *a, int canemitcode)
case OSPTR:
// pointer in a string or slice
naddr(n->left, a, canemitcode);
if(a->type == D_CONST && a->offset == 0)
if(a->type == TYPE_CONST && a->offset == 0)
break; // ptr(nil)
a->etype = simtype[tptr];
a->offset += Array_array;
@ -2332,7 +2335,7 @@ naddr(Node *n, Addr *a, int canemitcode)
case OLEN:
// len of string or slice
naddr(n->left, a, canemitcode);
if(a->type == D_CONST && a->offset == 0)
if(a->type == TYPE_CONST && a->offset == 0)
break; // len(nil)
a->etype = TUINT32;
a->offset += Array_nel;
@ -2342,7 +2345,7 @@ naddr(Node *n, Addr *a, int canemitcode)
case OCAP:
// cap of string or slice
naddr(n->left, a, canemitcode);
if(a->type == D_CONST && a->offset == 0)
if(a->type == TYPE_CONST && a->offset == 0)
break; // cap(nil)
a->etype = TUINT32;
a->offset += Array_cap;

View File

@ -32,9 +32,6 @@
#define Z N
#define Adr Addr
#define D_HI D_NONE
#define D_LO D_NONE
#define BLOAD(r) band(bnot(r->refbehind), r->refahead)
#define BSTORE(r) band(bnot(r->calbehind), r->calahead)
#define LOAD(r) (~r->refbehind.b[z] & r->refahead.b[z])
@ -52,8 +49,6 @@ typedef struct Rgn Rgn;
extern Node *Z;
enum
{
D_HI = D_NONE,
D_LO = D_NONE,
CLOAD = 5,
CREF = 5,
CINF = 1000,

View File

@ -74,7 +74,7 @@ rnops(Flow *r)
if(r != nil)
for(;;) {
p = r->prog;
if(p->as != ANOP || p->from.type != D_NONE || p->to.type != D_NONE)
if(p->as != ANOP || p->from.type != TYPE_NONE || p->to.type != TYPE_NONE)
break;
r1 = uniqs(r);
if(r1 == nil)
@ -110,7 +110,7 @@ peep(Prog *firstp)
case ALEAL:
if(regtyp(&p->to))
if(p->from.sym != nil)
if(p->from.index == D_NONE || p->from.index == D_CONST)
if(p->from.index == REG_NONE)
conprop(r);
break;
@ -120,7 +120,7 @@ peep(Prog *firstp)
case AMOVSS:
case AMOVSD:
if(regtyp(&p->to))
if(p->from.type == D_CONST || p->from.type == D_FCONST)
if(p->from.type == TYPE_CONST || p->from.type == TYPE_FCONST)
conprop(r);
break;
}
@ -158,7 +158,7 @@ loop1:
r1 = rnops(uniqs(r));
if(r1 != nil) {
p1 = r1->prog;
if(p->as == p1->as && p->to.type == p1->from.type){
if(p->as == p1->as && p->to.type == p1->from.type && p->to.reg == p1->from.reg){
p1->as = AMOVL;
t++;
}
@ -168,7 +168,7 @@ loop1:
case AADDL:
case AADDW:
if(p->from.type != D_CONST || needc(p->link))
if(p->from.type != TYPE_CONST || needc(p->link))
break;
if(p->from.offset == -1){
if(p->as == AADDL)
@ -190,7 +190,7 @@ loop1:
case ASUBL:
case ASUBW:
if(p->from.type != D_CONST || needc(p->link))
if(p->from.type != TYPE_CONST || needc(p->link))
break;
if(p->from.offset == -1) {
if(p->as == ASUBL)
@ -239,9 +239,7 @@ excise(Flow *r)
if(debug['P'] && debug['v'])
print("%P ===delete===\n", p);
p->as = ANOP;
p->from = zprog.from;
p->to = zprog.to;
nopout(p);
ostats.ndelmov++;
}
@ -249,14 +247,7 @@ excise(Flow *r)
int
regtyp(Adr *a)
{
int t;
t = a->type;
if(t >= D_AX && t <= D_DI)
return 1;
if(t >= D_X0 && t <= D_X7)
return 1;
return 0;
return a->type == TYPE_REG && (REG_AX <= a->reg && a->reg <= REG_DI || REG_X0 <= a->reg && a->reg <= REG_X7);
}
// movb elimination.
@ -293,7 +284,7 @@ elimshortmov(Graph *g)
p->as = ANOTL;
break;
}
if(regtyp(&p->from) || p->from.type == D_CONST) {
if(regtyp(&p->from) || p->from.type == TYPE_CONST) {
// move or artihmetic into partial register.
// from another register or constant can be movl.
// we don't switch to 32-bit arithmetic if it can
@ -398,7 +389,7 @@ subprop(Flow *r0)
if(info.reguse | info.regset)
return 0;
if((info.flags & Move) && (info.flags & (SizeL|SizeQ|SizeF|SizeD)) && p->to.type == v1->type)
if((info.flags & Move) && (info.flags & (SizeL|SizeQ|SizeF|SizeD)) && p->to.type == v1->type && p->to.reg == v1->reg)
goto gotit;
if(copyau(&p->from, v2) || copyau(&p->to, v2))
@ -412,7 +403,7 @@ gotit:
copysub(&p->to, v1, v2, 1);
if(debug['P']) {
print("gotit: %D->%D\n%P", v1, v2, r->prog);
if(p->from.type == v2->type)
if(p->from.type == v2->type && p->from.reg == v2->reg)
print(" excise");
print("\n");
}
@ -423,9 +414,9 @@ gotit:
if(debug['P'])
print("%P\n", r->prog);
}
t = v1->type;
v1->type = v2->type;
v2->type = t;
t = v1->reg;
v1->reg = v2->reg;
v2->reg = t;
if(debug['P'])
print("%P last\n", r->prog);
return 1;
@ -566,11 +557,11 @@ copyu(Prog *p, Adr *v, Adr *s)
return 3;
case ACALL:
if(REGEXT && v->type <= REGEXT && v->type > exregoffset)
if(REGEXT && v->type == TYPE_REG && v->reg <= REGEXT && v->reg > exregoffset)
return 2;
if(REGARG >= 0 && v->type == (uchar)REGARG)
if(REGARG >= 0 && v->type == TYPE_REG && v->reg == (uchar)REGARG)
return 2;
if(v->type == p->from.type)
if(v->type == p->from.type && v->reg == p->from.reg)
return 2;
if(s != nil) {
@ -583,7 +574,7 @@ copyu(Prog *p, Adr *v, Adr *s)
return 3;
case ATEXT:
if(REGARG >= 0 && v->type == (uchar)REGARG)
if(REGARG >= 0 && v->type == TYPE_REG && v->reg == (uchar)REGARG)
return 3;
return 0;
}
@ -592,7 +583,7 @@ copyu(Prog *p, Adr *v, Adr *s)
return 0;
proginfo(&info, p);
if((info.reguse|info.regset) & RtoB(v->type))
if((info.reguse|info.regset) & RtoB(v->reg))
return 2;
if(info.flags & LeftAddr)
@ -636,16 +627,16 @@ copyu(Prog *p, Adr *v, Adr *s)
static int
copyas(Adr *a, Adr *v)
{
if(D_AL <= a->type && a->type <= D_BL)
if(REG_AL <= a->reg && a->reg <= REG_BL)
fatal("use of byte register");
if(D_AL <= v->type && v->type <= D_BL)
if(REG_AL <= v->reg && v->reg <= REG_BL)
fatal("use of byte register");
if(a->type != v->type)
if(a->type != v->type || a->name != v->name || a->reg != v->reg)
return 0;
if(regtyp(v))
return 1;
if(v->type == D_AUTO || v->type == D_PARAM)
if(v->type == TYPE_MEM && (v->name == NAME_AUTO || v->name == NAME_PARAM))
if(v->offset == a->offset)
return 1;
return 0;
@ -654,11 +645,11 @@ copyas(Adr *a, Adr *v)
int
sameaddr(Addr *a, Addr *v)
{
if(a->type != v->type)
if(a->type != v->type || a->name != v->name || a->reg != v->reg)
return 0;
if(regtyp(v))
return 1;
if(v->type == D_AUTO || v->type == D_PARAM)
if(v->type == TYPE_MEM && (v->name == NAME_AUTO || v->name == NAME_PARAM))
if(v->offset == a->offset)
return 1;
return 0;
@ -674,9 +665,9 @@ copyau(Adr *a, Adr *v)
if(copyas(a, v))
return 1;
if(regtyp(v)) {
if(a->type-D_INDIR == v->type)
if(a->type == TYPE_MEM && a->reg == v->reg)
return 1;
if(a->index == v->type)
if(a->index == v->reg)
return 1;
}
return 0;
@ -689,28 +680,28 @@ copyau(Adr *a, Adr *v)
static int
copysub(Adr *a, Adr *v, Adr *s, int f)
{
int t;
int reg;
if(copyas(a, v)) {
t = s->type;
if(t >= D_AX && t <= D_DI || t >= D_X0 && t <= D_X7) {
reg = s->reg;
if(reg >= REG_AX && reg <= REG_DI || reg >= REG_X0 && reg <= REG_X7) {
if(f)
a->type = t;
a->reg = reg;
}
return 0;
}
if(regtyp(v)) {
t = v->type;
if(a->type == t+D_INDIR) {
if((s->type == D_BP) && a->index != D_NONE)
reg = v->reg;
if(a->type == TYPE_MEM && a->reg == reg) {
if((s->reg == REG_BP) && a->index != TYPE_NONE)
return 1; /* can't use BP-base with index */
if(f)
a->type = s->type+D_INDIR;
a->reg = s->reg;
// return 0;
}
if(a->index == t) {
if(a->index == reg) {
if(f)
a->index = s->type;
a->index = s->reg;
return 0;
}
return 0;
@ -751,10 +742,11 @@ loop:
case 3: // set
if(p->as == p0->as)
if(p->from.type == p0->from.type)
if(p->from.reg == p0->from.reg)
if(p->from.node == p0->from.node)
if(p->from.offset == p0->from.offset)
if(p->from.scale == p0->from.scale)
if(p->from.type == D_FCONST && p->from.u.dval == p0->from.u.dval)
if(p->from.type == TYPE_FCONST && p->from.u.dval == p0->from.u.dval)
if(p->from.index == p0->from.index) {
excise(r);
goto loop;
@ -767,13 +759,13 @@ int
smallindir(Addr *a, Addr *reg)
{
return regtyp(reg) &&
a->type == D_INDIR + reg->type &&
a->index == D_NONE &&
a->type == TYPE_MEM && a->reg == reg->reg &&
a->index == REG_NONE &&
0 <= a->offset && a->offset < 4096;
}
int
stackaddr(Addr *a)
{
return regtyp(a) && a->type == D_SP;
return a->type == TYPE_REG && a->reg == REG_SP;
}

View File

@ -8,15 +8,15 @@
#include "opt.h"
// Matches real RtoB but can be used in global initializer.
#define RtoB(r) (1<<((r)-D_AX))
#define RtoB(r) (1<<((r)-REG_AX))
enum {
AX = RtoB(D_AX),
BX = RtoB(D_BX),
CX = RtoB(D_CX),
DX = RtoB(D_DX),
DI = RtoB(D_DI),
SI = RtoB(D_SI),
AX = RtoB(REG_AX),
BX = RtoB(REG_BX),
CX = RtoB(REG_CX),
DX = RtoB(REG_DX),
DI = RtoB(REG_DI),
SI = RtoB(REG_SI),
LeftRdwr = LeftRead | LeftWrite,
RightRdwr = RightRead | RightWrite,
@ -325,11 +325,11 @@ proginfo(ProgInfo *info, Prog *p)
if(info->flags == 0)
fatal("unknown instruction %P", p);
if((info->flags & ShiftCX) && p->from.type != D_CONST)
if((info->flags & ShiftCX) && p->from.type != TYPE_CONST)
info->reguse |= CX;
if(info->flags & ImulAXDX) {
if(p->to.type == D_NONE) {
if(p->to.type == TYPE_NONE) {
info->reguse |= AX;
info->regset |= AX | DX;
} else {
@ -338,12 +338,12 @@ proginfo(ProgInfo *info, Prog *p)
}
// Addressing makes some registers used.
if(p->from.type >= D_INDIR)
info->regindex |= RtoB(p->from.type-D_INDIR);
if(p->from.index != D_NONE)
if(p->from.type == TYPE_MEM && p->from.name == NAME_NONE)
info->regindex |= RtoB(p->from.reg);
if(p->from.index != REG_NONE)
info->regindex |= RtoB(p->from.index);
if(p->to.type >= D_INDIR)
info->regindex |= RtoB(p->to.type-D_INDIR);
if(p->to.index != D_NONE)
if(p->to.type == TYPE_MEM && p->to.name == NAME_NONE)
info->regindex |= RtoB(p->to.reg);
if(p->to.index != REG_NONE)
info->regindex |= RtoB(p->to.index);
}

View File

@ -104,7 +104,7 @@ regopt(Prog *firstp)
if(first) {
fmtinstall('Q', Qconv);
exregoffset = D_DI; // no externals
exregoffset = REG_DI; // no externals
first = 0;
}
@ -123,7 +123,7 @@ regopt(Prog *firstp)
var[i].node = regnodes[i];
}
regbits = RtoB(D_SP);
regbits = RtoB(REG_SP);
for(z=0; z<BITS; z++) {
externs.b[z] = 0;
params.b[z] = 0;
@ -155,7 +155,7 @@ regopt(Prog *firstp)
proginfo(&info, p);
// Avoid making variables for direct-called functions.
if(p->as == ACALL && p->to.type == D_EXTERN)
if(p->as == ACALL && p->to.type == TYPE_MEM && p->to.name == NAME_EXTERN)
continue;
r->use1.b[0] |= info.reguse | info.regindex;
@ -401,17 +401,17 @@ brk:
for(p=firstp; p!=P; p=p->link) {
while(p->link != P && p->link->as == ANOP)
p->link = p->link->link;
if(p->to.type == D_BRANCH)
if(p->to.type == TYPE_BRANCH)
while(p->to.u.branch != P && p->to.u.branch->as == ANOP)
p->to.u.branch = p->to.u.branch->link;
}
if(!use_sse)
for(p=firstp; p!=P; p=p->link) {
if(p->from.type >= D_X0 && p->from.type <= D_X7)
fatal("invalid use of %R with GO386=387: %P", p->from.type, p);
if(p->to.type >= D_X0 && p->to.type <= D_X7)
fatal("invalid use of %R with GO386=387: %P", p->to.type, p);
if(p->from.reg >= REG_X0 && p->from.reg <= REG_X7)
fatal("invalid use of %R with GO386=387: %P", p->from.reg, p);
if(p->to.reg >= REG_X0 && p->to.reg <= REG_X7)
fatal("invalid use of %R with GO386=387: %P", p->to.reg, p);
}
if(debug['R']) {
@ -492,7 +492,8 @@ addmove(Reg *r, int bn, int rn, int f)
a = &p1->to;
a->offset = v->offset;
a->etype = v->etype;
a->type = v->name;
a->type = TYPE_MEM;
a->name = v->name;
a->node = v->node;
a->sym = linksym(v->node->sym);
@ -525,11 +526,14 @@ addmove(Reg *r, int bn, int rn, int f)
break;
}
p1->from.type = rn;
p1->from.type = TYPE_REG;
p1->from.reg = rn;
p1->from.name = 0;
if(!f) {
p1->from = *a;
*a = zprog.from;
a->type = rn;
a->type = TYPE_REG;
a->reg = rn;
if(v->etype == TUINT8)
p1->as = AMOVB;
if(v->etype == TUINT16)
@ -546,18 +550,16 @@ doregbits(int r)
uint32 b;
b = 0;
if(r >= D_INDIR)
r -= D_INDIR;
if(r >= D_AX && r <= D_DI)
if(r >= REG_AX && r <= REG_DI)
b |= RtoB(r);
else
if(r >= D_AL && r <= D_BL)
b |= RtoB(r-D_AL+D_AX);
if(r >= REG_AL && r <= REG_BL)
b |= RtoB(r-REG_AL+REG_AX);
else
if(r >= D_AH && r <= D_BH)
b |= RtoB(r-D_AH+D_AX);
if(r >= REG_AH && r <= REG_BH)
b |= RtoB(r-REG_AH+REG_AX);
else
if(r >= D_X0 && r <= D_X0+7)
if(r >= REG_X0 && r <= REG_X0+7)
b |= FtoB(r);
return b;
}
@ -580,7 +582,7 @@ Bits
mkvar(Reg *r, Adr *a)
{
Var *v;
int i, t, n, et, z, w, flag, regu;
int i, n, et, z, w, flag, regu;
int32 o;
Bits bit;
Node *node;
@ -588,36 +590,38 @@ mkvar(Reg *r, Adr *a)
/*
* mark registers used
*/
t = a->type;
if(t == D_NONE)
if(a->type == TYPE_NONE)
goto none;
if(r != R)
r->use1.b[0] |= doregbits(a->index);
switch(t) {
switch(a->type) {
default:
regu = doregbits(t);
regu = doregbits(a->reg);
if(regu == 0)
goto none;
bit = zbits;
bit.b[0] = regu;
return bit;
case D_ADDR:
a->type = a->index;
case TYPE_ADDR:
a->type = TYPE_MEM;
bit = mkvar(r, a);
setaddrs(bit);
a->type = t;
a->type = TYPE_ADDR;
ostats.naddr++;
goto none;
case D_EXTERN:
case D_STATIC:
case D_PARAM:
case D_AUTO:
n = t;
break;
case TYPE_MEM:
switch(a->name) {
case NAME_EXTERN:
case NAME_STATIC:
case NAME_PARAM:
case NAME_AUTO:
n = a->name;
break;
}
}
node = a->node;
@ -693,10 +697,10 @@ mkvar(Reg *r, Adr *a)
node->opt = v;
bit = blsh(i);
if(n == D_EXTERN || n == D_STATIC)
if(n == NAME_EXTERN || n == NAME_STATIC)
for(z=0; z<BITS; z++)
externs.b[z] |= bit.b[z];
if(n == D_PARAM)
if(n == NAME_PARAM)
for(z=0; z<BITS; z++)
params.b[z] |= bit.b[z];
@ -967,13 +971,13 @@ paint1(Reg *r, int bn)
if(r->use1.b[z] & bb) {
change += CREF * r->f.loop;
if(p->as == AFMOVL || p->as == AFMOVW)
if(BtoR(bb) != D_F0)
if(BtoR(bb) != REG_F0)
change = -CINF;
}
if((r->use2.b[z]|r->set.b[z]) & bb) {
change += CREF * r->f.loop;
if(p->as == AFMOVL || p->as == AFMOVW)
if(BtoR(bb) != D_F0)
if(BtoR(bb) != REG_F0)
change = -CINF;
}
}
@ -981,7 +985,7 @@ paint1(Reg *r, int bn)
if(STORE(r) & r->regdiff.b[z] & bb) {
change -= CLOAD * r->f.loop;
if(p->as == AFMOVL || p->as == AFMOVW)
if(BtoR(bb) != D_F0)
if(BtoR(bb) != REG_F0)
change = -CINF;
}
@ -1139,7 +1143,9 @@ addreg(Adr *a, int rn)
a->sym = nil;
a->node = nil;
a->offset = 0;
a->type = rn;
a->type = TYPE_REG;
a->reg = rn;
a->name = 0;
ostats.ncvtreg++;
}
@ -1148,9 +1154,9 @@ uint32
RtoB(int r)
{
if(r < D_AX || r > D_DI)
if(r < REG_AX || r > REG_DI)
return 0;
return 1L << (r-D_AX);
return 1L << (r-REG_AX);
}
int
@ -1160,15 +1166,15 @@ BtoR(uint32 b)
b &= 0xffL;
if(b == 0)
return 0;
return bitno(b) + D_AX;
return bitno(b) + REG_AX;
}
uint32
FtoB(int f)
{
if(f < D_X0 || f > D_X7)
if(f < REG_X0 || f > REG_X7)
return 0;
return 1L << (f - D_X0 + 8);
return 1L << (f - REG_X0 + 8);
}
int
@ -1177,7 +1183,7 @@ BtoF(uint32 b)
b &= 0xFF00L;
if(b == 0)
return 0;
return bitno(b) - 8 + D_X0;
return bitno(b) - 8 + REG_X0;
}
void

View File

@ -592,72 +592,58 @@ enum
enum
{
D_AL = 0,
D_CL,
D_DL,
D_BL,
REG_NONE = 0,
D_AH = 4,
D_CH,
D_DH,
D_BH,
REG_AL = 0+16,
REG_CL,
REG_DL,
REG_BL,
D_AX = 8,
D_CX,
D_DX,
D_BX,
D_SP,
D_BP,
D_SI,
D_DI,
REG_AH = 4+16,
REG_CH,
REG_DH,
REG_BH,
D_F0 = 16,
D_F7 = D_F0 + 7,
REG_AX = 8+16,
REG_CX,
REG_DX,
REG_BX,
REG_SP,
REG_BP,
REG_SI,
REG_DI,
D_CS = 24,
D_SS,
D_DS,
D_ES,
D_FS,
D_GS,
REG_F0 = 16+16,
REG_F7 = REG_F0 + 7+16,
D_GDTR, /* global descriptor table register */
D_IDTR, /* interrupt descriptor table register */
D_LDTR, /* local descriptor table register */
D_MSW, /* machine status word */
D_TASK, /* task register */
REG_CS = 24+16,
REG_SS,
REG_DS,
REG_ES,
REG_FS,
REG_GS,
D_CR = 35,
D_DR = 43,
D_TR = 51,
REG_GDTR, /* global descriptor table register */
REG_IDTR, /* interrupt descriptor table register */
REG_LDTR, /* local descriptor table register */
REG_MSW, /* machine status word */
REG_TASK, /* task register */
D_X0 = 59,
D_X1,
D_X2,
D_X3,
D_X4,
D_X5,
D_X6,
D_X7,
REG_CR = 35+16,
REG_DR = 43+16,
REG_TR = 51+16,
REG_X0 = 59+16,
REG_X1,
REG_X2,
REG_X3,
REG_X4,
REG_X5,
REG_X6,
REG_X7,
D_TLS = 67,
D_NONE = 68,
D_BRANCH = 69,
D_EXTERN = 70,
D_STATIC = 71,
D_AUTO = 72,
D_PARAM = 73,
D_CONST = 74,
D_FCONST = 75,
D_SCONST = 76,
D_ADDR = 77,
D_INDIR, /* additive */
D_CONST2 = D_INDIR+D_INDIR,
D_LAST,
REG_TLS = 67+16,
MAXREG = 68+16,
T_TYPE = 1<<0,
T_INDEX = 1<<1,
@ -669,10 +655,10 @@ enum
T_GOTYPE = 1<<7,
REGARG = -1,
REGRET = D_AX,
FREGRET = D_F0,
REGSP = D_SP,
REGTMP = D_DI,
REGRET = REG_AX,
FREGRET = REG_F0,
REGSP = REG_SP,
REGTMP = REG_DI,
};
/*

File diff suppressed because it is too large Load Diff

View File

@ -108,41 +108,38 @@ Dconv(Fmt *fp)
{
char str[STRINGSZ], s[STRINGSZ];
Addr *a;
int i;
a = va_arg(fp->args, Addr*);
i = a->type;
if(fp->flags & FmtLong) {
if(i == D_CONST2)
sprint(str, "$%lld-%d", a->offset, a->offset2);
else {
// ATEXT dst is not constant
sprint(str, "!!%D", a);
}
goto brk;
}
if(i >= D_INDIR) {
if(a->offset)
sprint(str, "%lld(%R)", a->offset, i-D_INDIR);
else
sprint(str, "(%R)", i-D_INDIR);
goto brk;
}
switch(i) {
switch(a->type) {
default:
if(a->offset)
sprint(str, "$%lld,%R", a->offset, i);
else
sprint(str, "%R", i);
sprint(str, "type=%d", a->type);
break;
case D_NONE:
case TYPE_NONE:
str[0] = 0;
break;
case TYPE_REG:
// TODO(rsc): This special case is for instructions like
// PINSRQ CX,$1,X6
// where the $1 is included in the p->to Addr.
// Move into a new field.
if(a->offset != 0) {
sprint(str, "$%lld,%R", a->offset, a->reg);
break;
}
sprint(str, "%R", a->reg);
// TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
// SHRQ $32(DX*0), AX
// Remove.
if(a->index != REG_NONE) {
sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
strcat(str, s);
}
break;
case D_BRANCH:
case TYPE_BRANCH:
if(a->sym != nil)
sprint(str, "%s(SB)", a->sym->name);
else if(bigP != nil && bigP->pcond != nil)
@ -153,67 +150,78 @@ Dconv(Fmt *fp)
sprint(str, "%lld(PC)", a->offset);
break;
case D_EXTERN:
sprint(str, "%s+%lld(SB)", a->sym->name, a->offset);
break;
case D_STATIC:
sprint(str, "%s<>+%lld(SB)", a->sym->name, a->offset);
break;
case D_AUTO:
if(a->sym)
sprint(str, "%s+%lld(SP)", a->sym->name, a->offset);
else
sprint(str, "%lld(SP)", a->offset);
break;
case D_PARAM:
if(a->sym)
sprint(str, "%s+%lld(FP)", a->sym->name, a->offset);
else
sprint(str, "%lld(FP)", a->offset);
break;
case D_CONST:
sprint(str, "$%lld", a->offset);
break;
case D_CONST2:
if(!(fp->flags & FmtLong)) {
// D_CONST2 outside of ATEXT should not happen
sprint(str, "!!$%lld-%d", a->offset, a->offset2);
case TYPE_MEM:
switch(a->name) {
default:
sprint(str, "name=%d", a->name);
break;
case NAME_NONE:
if(a->offset)
sprint(str, "%lld(%R)", a->offset, a->reg);
else
sprint(str, "(%R)", a->reg);
break;
case NAME_EXTERN:
sprint(str, "%s+%lld(SB)", a->sym->name, a->offset);
break;
case NAME_STATIC:
sprint(str, "%s<>+%lld(SB)", a->sym->name, a->offset);
break;
case NAME_AUTO:
if(a->sym)
sprint(str, "%s+%lld(SP)", a->sym->name, a->offset);
else
sprint(str, "%lld(SP)", a->offset);
break;
case NAME_PARAM:
if(a->sym)
sprint(str, "%s+%lld(FP)", a->sym->name, a->offset);
else
sprint(str, "%lld(FP)", a->offset);
break;
}
if(a->index != REG_NONE) {
sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
strcat(str, s);
}
break;
case D_FCONST:
case TYPE_CONST:
sprint(str, "$%lld", a->offset);
// TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
// SHRQ $32(DX*0), AX
// Remove.
if(a->index != REG_NONE) {
sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
strcat(str, s);
}
break;
case TYPE_TEXTSIZE:
sprint(str, "$%lld-%d", a->offset, a->u.argsize);
break;
case TYPE_FCONST:
sprint(str, "$(%.17g)", a->u.dval);
break;
case D_SCONST:
case TYPE_SCONST:
sprint(str, "$\"%$\"", a->u.sval);
break;
case D_ADDR:
a->type = a->index;
a->index = D_NONE;
case TYPE_ADDR:
a->type = TYPE_MEM;
sprint(str, "$%D", a);
a->index = a->type;
a->type = D_ADDR;
goto conv;
a->type = TYPE_ADDR;
break;
}
brk:
if(a->index != D_NONE) {
sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
strcat(str, s);
}
conv:
return fmtstrcpy(fp, str);
}
static char* regstr[] =
{
"AL", /* [D_AL] */
"AL", /* [REG_AL] */
"CL",
"DL",
"BL",
@ -222,7 +230,7 @@ static char* regstr[] =
"DH",
"BH",
"AX", /* [D_AX] */
"AX", /* [REG_AX] */
"CX",
"DX",
"BX",
@ -231,7 +239,7 @@ static char* regstr[] =
"SI",
"DI",
"F0", /* [D_F0] */
"F0", /* [REG_F0] */
"F1",
"F2",
"F3",
@ -240,20 +248,20 @@ static char* regstr[] =
"F6",
"F7",
"CS", /* [D_CS] */
"CS", /* [REG_CS] */
"SS",
"DS",
"ES",
"FS",
"GS",
"GDTR", /* [D_GDTR] */
"IDTR", /* [D_IDTR] */
"LDTR", /* [D_LDTR] */
"MSW", /* [D_MSW] */
"TASK", /* [D_TASK] */
"GDTR", /* [REG_GDTR] */
"IDTR", /* [REG_IDTR] */
"LDTR", /* [REG_LDTR] */
"MSW", /* [REG_MSW] */
"TASK", /* [REG_TASK] */
"CR0", /* [D_CR] */
"CR0", /* [REG_CR] */
"CR1",
"CR2",
"CR3",
@ -262,7 +270,7 @@ static char* regstr[] =
"CR6",
"CR7",
"DR0", /* [D_DR] */
"DR0", /* [REG_DR] */
"DR1",
"DR2",
"DR3",
@ -271,7 +279,7 @@ static char* regstr[] =
"DR6",
"DR7",
"TR0", /* [D_TR] */
"TR0", /* [REG_TR] */
"TR1",
"TR2",
"TR3",
@ -280,7 +288,7 @@ static char* regstr[] =
"TR6",
"TR7",
"X0", /* [D_X0] */
"X0", /* [REG_X0] */
"X1",
"X2",
"X3",
@ -289,8 +297,8 @@ static char* regstr[] =
"X6",
"X7",
"TLS", /* [D_TLS] */
"NONE", /* [D_NONE] */
"TLS", /* [REG_TLS] */
"MAXREG", /* [MAXREG] */
};
static int
@ -300,8 +308,10 @@ Rconv(Fmt *fp)
int r;
r = va_arg(fp->args, int);
if(r >= D_AL && r <= D_NONE)
sprint(str, "%s", regstr[r-D_AL]);
if(r == REG_NONE)
return fmtstrcpy(fp, "NONE");
if(r >= REG_AL && r-REG_AL < nelem(regstr))
sprint(str, "%s", regstr[r-REG_AL]);
else
sprint(str, "gok(%d)", r);

View File

@ -39,28 +39,17 @@ static Prog zprg = {
.back = 2,
.as = AGOK,
.from = {
.type = D_NONE,
.index = D_NONE,
.type = TYPE_NONE,
.index = REG_NONE,
.scale = 1,
},
.to = {
.type = D_NONE,
.index = D_NONE,
.type = TYPE_NONE,
.index = REG_NONE,
.scale = 1,
},
};
static int
symtype(Addr *a)
{
int t;
t = a->type;
if(t == D_ADDR)
t = a->index;
return t;
}
static int
isdata(Prog *p)
{
@ -120,20 +109,22 @@ progedit(Link *ctxt, Prog *p)
// become
// NOP
// ... off(TLS) ...
if(p->as == AMOVL && p->from.type == D_TLS && D_AX <= p->to.type && p->to.type <= D_DI) {
if(p->as == AMOVL && p->from.type == TYPE_REG && p->from.reg == REG_TLS && p->to.type == TYPE_REG && REG_AX <= p->to.reg && p->to.reg <= REG_DI) {
p->as = ANOP;
p->from.type = D_NONE;
p->to.type = D_NONE;
p->from.type = TYPE_NONE;
p->to.type = TYPE_NONE;
}
if(p->from.index == D_TLS && D_INDIR+D_AX <= p->from.type && p->from.type <= D_INDIR+D_DI) {
p->from.type = D_INDIR+D_TLS;
if(p->from.type == TYPE_MEM && p->from.index == REG_TLS && REG_AX <= p->from.reg && p->from.reg <= REG_DI) {
p->from.type = TYPE_MEM;
p->from.reg = REG_TLS;
p->from.scale = 0;
p->from.index = D_NONE;
p->from.index = REG_NONE;
}
if(p->to.index == D_TLS && D_INDIR+D_AX <= p->to.type && p->to.type <= D_INDIR+D_DI) {
p->to.type = D_INDIR+D_TLS;
if(p->to.type == TYPE_MEM && p->to.index == REG_TLS && REG_AX <= p->to.reg && p->to.reg <= REG_DI) {
p->to.type = TYPE_MEM;
p->to.reg = REG_TLS;
p->to.scale = 0;
p->to.index = D_NONE;
p->to.index = REG_NONE;
}
} else {
// As a courtesy to the C compilers, rewrite TLS local exec load as TLS initial exec load.
@ -143,35 +134,36 @@ progedit(Link *ctxt, Prog *p)
// MOVL TLS, BX
// MOVL off(BX)(TLS*1), BX
// This allows the C compilers to emit references to m and g using the direct off(TLS) form.
if(p->as == AMOVL && p->from.type == D_INDIR+D_TLS && D_AX <= p->to.type && p->to.type <= D_DI) {
if(p->as == AMOVL && p->from.type == TYPE_MEM && p->from.reg == REG_TLS && p->to.type == TYPE_REG && REG_AX <= p->to.reg && p->to.reg <= REG_DI) {
q = appendp(ctxt, p);
q->as = p->as;
q->from = p->from;
q->from.type = D_INDIR + p->to.type;
q->from.index = D_TLS;
q->from.type = TYPE_MEM;
q->from.reg = p->to.reg;
q->from.index = REG_TLS;
q->from.scale = 2; // TODO: use 1
q->to = p->to;
p->from.type = D_TLS;
p->from.index = D_NONE;
p->from.type = TYPE_REG;
p->from.reg = REG_TLS;
p->from.index = REG_NONE;
p->from.offset = 0;
}
}
// TODO: Remove.
if(ctxt->headtype == Hplan9) {
if(p->from.scale == 1 && p->from.index == D_TLS)
if(p->from.scale == 1 && p->from.index == REG_TLS)
p->from.scale = 2;
if(p->to.scale == 1 && p->to.index == D_TLS)
if(p->to.scale == 1 && p->to.index == REG_TLS)
p->to.scale = 2;
}
// Rewrite CALL/JMP/RET to symbol as D_BRANCH.
// Rewrite CALL/JMP/RET to symbol as TYPE_BRANCH.
switch(p->as) {
case ACALL:
case AJMP:
case ARET:
if((p->to.type == D_EXTERN || p->to.type == D_STATIC) && p->to.sym != nil)
p->to.type = D_BRANCH;
if(p->to.type == TYPE_MEM && (p->to.name == NAME_EXTERN || p->to.name == NAME_STATIC) && p->to.sym != nil)
p->to.type = TYPE_BRANCH;
break;
}
@ -179,13 +171,11 @@ progedit(Link *ctxt, Prog *p)
switch(p->as) {
case AMOVSS:
// Convert AMOVSS $(0), Xx to AXORPS Xx, Xx
if(p->from.type == D_FCONST)
if(p->from.type == TYPE_FCONST)
if(p->from.u.dval == 0)
if(p->to.type >= D_X0)
if(p->to.type <= D_X7) {
if(p->to.type == TYPE_REG && REG_X0 <= p->to.reg && p->to.reg <= REG_X7) {
p->as = AXORPS;
p->from.type = p->to.type;
p->from.index = p->to.index;
p->from = p->to;
break;
}
// fallthrough
@ -205,7 +195,7 @@ progedit(Link *ctxt, Prog *p)
case ADIVSS:
case ACOMISS:
case AUCOMISS:
if(p->from.type == D_FCONST) {
if(p->from.type == TYPE_FCONST) {
uint32 i32;
float32 f32;
f32 = p->from.u.dval;
@ -217,7 +207,8 @@ progedit(Link *ctxt, Prog *p)
adduint32(ctxt, s, i32);
s->reachable = 0;
}
p->from.type = D_EXTERN;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.sym = s;
p->from.offset = 0;
}
@ -225,13 +216,11 @@ progedit(Link *ctxt, Prog *p)
case AMOVSD:
// Convert AMOVSD $(0), Xx to AXORPS Xx, Xx
if(p->from.type == D_FCONST)
if(p->from.type == TYPE_FCONST)
if(p->from.u.dval == 0)
if(p->to.type >= D_X0)
if(p->to.type <= D_X7) {
if(p->to.type == TYPE_REG && REG_X0 <= p->to.reg && p->to.reg <= REG_X7) {
p->as = AXORPS;
p->from.type = p->to.type;
p->from.index = p->to.index;
p->from = p->to;
break;
}
// fallthrough
@ -251,7 +240,7 @@ progedit(Link *ctxt, Prog *p)
case ADIVSD:
case ACOMISD:
case AUCOMISD:
if(p->from.type == D_FCONST) {
if(p->from.type == TYPE_FCONST) {
uint64 i64;
memmove(&i64, &p->from.u.dval, 8);
sprint(literal, "$f64.%016llux", i64);
@ -261,7 +250,8 @@ progedit(Link *ctxt, Prog *p)
adduint64(ctxt, s, i64);
s->reachable = 0;
}
p->from.type = D_EXTERN;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.sym = s;
p->from.offset = 0;
}
@ -283,7 +273,7 @@ static Prog* load_g_cx(Link*, Prog*);
static Prog* stacksplit(Link*, Prog*, int32, int, Prog**);
static void
addstacksplit(Link *ctxt, LSym *cursym)
preprocess(Link *ctxt, LSym *cursym)
{
Prog *p, *q, *p1, *p2;
int32 autoffset, deltasp;
@ -308,7 +298,7 @@ addstacksplit(Link *ctxt, LSym *cursym)
autoffset = 0;
cursym->locals = autoffset;
cursym->args = p->to.offset2;
cursym->args = p->to.u.argsize;
q = nil;
@ -322,7 +312,7 @@ addstacksplit(Link *ctxt, LSym *cursym)
if(autoffset) {
p = appendp(ctxt, p);
p->as = AADJSP;
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = autoffset;
p->spadj = autoffset;
} else {
@ -358,41 +348,51 @@ addstacksplit(Link *ctxt, LSym *cursym)
p = appendp(ctxt, p);
p->as = AMOVL;
p->from.type = D_INDIR+D_CX;
p->from.type = TYPE_MEM;
p->from.reg = REG_CX;
p->from.offset = 4*ctxt->arch->ptrsize; // G.panic
p->to.type = D_BX;
p->to.type = TYPE_REG;
p->to.reg = REG_BX;
p = appendp(ctxt, p);
p->as = ATESTL;
p->from.type = D_BX;
p->to.type = D_BX;
p->from.type = TYPE_REG;
p->from.reg = REG_BX;
p->to.type = TYPE_REG;
p->to.reg = REG_BX;
p = appendp(ctxt, p);
p->as = AJEQ;
p->to.type = D_BRANCH;
p->to.type = TYPE_BRANCH;
p1 = p;
p = appendp(ctxt, p);
p->as = ALEAL;
p->from.type = D_INDIR+D_SP;
p->from.type = TYPE_MEM;
p->from.reg = REG_SP;
p->from.offset = autoffset+4;
p->to.type = D_DI;
p->to.type = TYPE_REG;
p->to.reg = REG_DI;
p = appendp(ctxt, p);
p->as = ACMPL;
p->from.type = D_INDIR+D_BX;
p->from.type = TYPE_MEM;
p->from.reg = REG_BX;
p->from.offset = 0; // Panic.argp
p->to.type = D_DI;
p->to.type = TYPE_REG;
p->to.reg = REG_DI;
p = appendp(ctxt, p);
p->as = AJNE;
p->to.type = D_BRANCH;
p->to.type = TYPE_BRANCH;
p2 = p;
p = appendp(ctxt, p);
p->as = AMOVL;
p->from.type = D_SP;
p->to.type = D_INDIR+D_BX;
p->from.type = TYPE_REG;
p->from.reg = REG_SP;
p->to.type = TYPE_MEM;
p->to.reg = REG_BX;
p->to.offset = 0; // Panic.argp
p = appendp(ctxt, p);
@ -407,20 +407,24 @@ addstacksplit(Link *ctxt, LSym *cursym)
// false positives in garbage collection.
p = appendp(ctxt, p);
p->as = AMOVL;
p->from.type = D_SP;
p->to.type = D_DI;
p->from.type = TYPE_REG;
p->from.reg = REG_SP;
p->to.type = TYPE_REG;
p->to.reg = REG_DI;
p = appendp(ctxt, p);
p->as = AMOVL;
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = autoffset/4;
p->to.type = D_CX;
p->to.type = TYPE_REG;
p->to.reg = REG_CX;
p = appendp(ctxt, p);
p->as = AMOVL;
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = 0;
p->to.type = D_AX;
p->to.type = TYPE_REG;
p->to.reg = REG_AX;
p = appendp(ctxt, p);
p->as = AREP;
@ -430,15 +434,15 @@ addstacksplit(Link *ctxt, LSym *cursym)
}
for(; p != nil; p = p->link) {
a = p->from.type;
if(a == D_AUTO)
a = p->from.name;
if(a == NAME_AUTO)
p->from.offset += deltasp;
if(a == D_PARAM)
if(a == NAME_PARAM)
p->from.offset += deltasp + 4;
a = p->to.type;
if(a == D_AUTO)
a = p->to.name;
if(a == NAME_AUTO)
p->to.offset += deltasp;
if(a == D_PARAM)
if(a == NAME_PARAM)
p->to.offset += deltasp + 4;
switch(p->as) {
@ -473,7 +477,7 @@ addstacksplit(Link *ctxt, LSym *cursym)
if(autoffset) {
p->as = AADJSP;
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = -autoffset;
p->spadj = -autoffset;
p = appendp(ctxt, p);
@ -500,16 +504,18 @@ load_g_cx(Link *ctxt, Prog *p)
Prog *next;
p->as = AMOVL;
p->from.type = D_INDIR+D_TLS;
p->from.type = TYPE_MEM;
p->from.reg = REG_TLS;
p->from.offset = 0;
p->to.type = D_CX;
p->to.type = TYPE_REG;
p->to.reg = REG_CX;
next = p->link;
progedit(ctxt, p);
while(p->link != next)
p = p->link;
if(p->from.index == D_TLS)
if(p->from.index == REG_TLS)
p->from.scale = 2;
return p;
@ -534,19 +540,21 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok)
// catches out-of-sync stack guard info.
p = appendp(ctxt, p);
p->as = ACMPL;
p->from.type = D_INDIR+D_CX;
p->from.type = TYPE_MEM;
p->from.reg = REG_CX;
p->from.offset = 4;
p->to.type = D_SP;
p->to.type = TYPE_REG;
p->to.reg = REG_SP;
p = appendp(ctxt, p);
p->as = AJCC;
p->to.type = D_BRANCH;
p->to.type = TYPE_BRANCH;
p->to.offset = 4;
q1 = p;
p = appendp(ctxt, p);
p->as = AINT;
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = 3;
p = appendp(ctxt, p);
@ -560,8 +568,10 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok)
// CMPL SP, stackguard
p = appendp(ctxt, p);
p->as = ACMPL;
p->from.type = D_SP;
p->to.type = D_INDIR+D_CX;
p->from.type = TYPE_REG;
p->from.reg = REG_SP;
p->to.type = TYPE_MEM;
p->to.reg = REG_CX;
p->to.offset = 2*ctxt->arch->ptrsize; // G.stackguard0
if(ctxt->cursym->cfunc)
p->to.offset = 3*ctxt->arch->ptrsize; // G.stackguard1
@ -571,14 +581,18 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok)
// CMPL AX, stackguard
p = appendp(ctxt, p);
p->as = ALEAL;
p->from.type = D_INDIR+D_SP;
p->from.type = TYPE_MEM;
p->from.reg = REG_SP;
p->from.offset = -(framesize-StackSmall);
p->to.type = D_AX;
p->to.type = TYPE_REG;
p->to.reg = REG_AX;
p = appendp(ctxt, p);
p->as = ACMPL;
p->from.type = D_AX;
p->to.type = D_INDIR+D_CX;
p->from.type = TYPE_REG;
p->from.reg = REG_AX;
p->to.type = TYPE_MEM;
p->to.reg = REG_CX;
p->to.offset = 2*ctxt->arch->ptrsize; // G.stackguard0
if(ctxt->cursym->cfunc)
p->to.offset = 3*ctxt->arch->ptrsize; // G.stackguard1
@ -599,53 +613,61 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok)
// CMPL AX, $(framesize+(StackGuard-StackSmall))
p = appendp(ctxt, p);
p->as = AMOVL;
p->from.type = D_INDIR+D_CX;
p->from.type = TYPE_MEM;
p->from.reg = REG_CX;
p->from.offset = 0;
p->from.offset = 2*ctxt->arch->ptrsize; // G.stackguard0
if(ctxt->cursym->cfunc)
p->from.offset = 3*ctxt->arch->ptrsize; // G.stackguard1
p->to.type = D_SI;
p->to.type = TYPE_REG;
p->to.reg = REG_SI;
p = appendp(ctxt, p);
p->as = ACMPL;
p->from.type = D_SI;
p->to.type = D_CONST;
p->from.type = TYPE_REG;
p->from.reg = REG_SI;
p->to.type = TYPE_CONST;
p->to.offset = (uint32)StackPreempt;
p = appendp(ctxt, p);
p->as = AJEQ;
p->to.type = D_BRANCH;
p->to.type = TYPE_BRANCH;
q1 = p;
p = appendp(ctxt, p);
p->as = ALEAL;
p->from.type = D_INDIR+D_SP;
p->from.type = TYPE_MEM;
p->from.reg = REG_SP;
p->from.offset = StackGuard;
p->to.type = D_AX;
p->to.type = TYPE_REG;
p->to.reg = REG_AX;
p = appendp(ctxt, p);
p->as = ASUBL;
p->from.type = D_SI;
p->from.type = TYPE_REG;
p->from.reg = REG_SI;
p->from.offset = 0;
p->to.type = D_AX;
p->to.type = TYPE_REG;
p->to.reg = REG_AX;
p = appendp(ctxt, p);
p->as = ACMPL;
p->from.type = D_AX;
p->to.type = D_CONST;
p->from.type = TYPE_REG;
p->from.reg = REG_AX;
p->to.type = TYPE_CONST;
p->to.offset = framesize+(StackGuard-StackSmall);
}
// common
p = appendp(ctxt, p);
p->as = AJHI;
p->to.type = D_BRANCH;
p->to.type = TYPE_BRANCH;
p->to.offset = 4;
q = p;
p = appendp(ctxt, p);
p->as = ACALL;
p->to.type = D_BRANCH;
p->to.type = TYPE_BRANCH;
if(ctxt->cursym->cfunc)
p->to.sym = linklookup(ctxt, "runtime.morestackc", 0);
else
@ -653,7 +675,7 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok)
p = appendp(ctxt, p);
p->as = AJMP;
p->to.type = D_BRANCH;
p->to.type = TYPE_BRANCH;
p->pcond = ctxt->cursym->text->link;
if(q != nil)
@ -804,7 +826,7 @@ loop:
q = ctxt->arch->prg();
q->as = AJMP;
q->lineno = p->lineno;
q->to.type = D_BRANCH;
q->to.type = TYPE_BRANCH;
q->to.offset = p->pc;
q->pcond = p;
p = q;
@ -829,7 +851,7 @@ loop:
p->pcond = q;
if((q = brchain(ctxt, p->link)) != nil)
p->link = q;
if(p->from.type == D_CONST) {
if(p->from.type == TYPE_CONST) {
if(p->from.offset == 1) {
/*
* expect conditional jump to be taken.
@ -864,7 +886,7 @@ LinkArch link386 = {
.thechar = '8',
.endian = LittleEndian,
.addstacksplit = addstacksplit,
.preprocess = preprocess,
.assemble = span8,
.datasize = datasize,
.follow = follow,
@ -873,24 +895,12 @@ LinkArch link386 = {
.prg = prg,
.progedit = progedit,
.settextflag = settextflag,
.symtype = symtype,
.textflag = textflag,
.minlc = 1,
.ptrsize = 4,
.regsize = 4,
.D_ADDR = D_ADDR,
.D_AUTO = D_AUTO,
.D_BRANCH = D_BRANCH,
.D_CONST = D_CONST,
.D_EXTERN = D_EXTERN,
.D_FCONST = D_FCONST,
.D_NONE = D_NONE,
.D_PARAM = D_PARAM,
.D_SCONST = D_SCONST,
.D_STATIC = D_STATIC,
.ACALL = ACALL,
.ADATA = ADATA,
.AEND = AEND,