mirror of https://github.com/golang/go.git
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:
parent
604138e87b
commit
a5b1baeed7
|
|
@ -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
|
||||
|
||||
|
|
|
|||
149
src/cmd/8a/lex.c
149
src/cmd/8a/lex.c
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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(®, types[TINT], D_AX);
|
||||
nodreg(®, types[TINT], REG_AX);
|
||||
gins(AXCHGL, ®, ®);
|
||||
}
|
||||
p = gins(ACALL, N, f);
|
||||
|
|
@ -274,8 +274,8 @@ ginscall(Node *f, int proc)
|
|||
gins(AUNDEF, N, N);
|
||||
break;
|
||||
}
|
||||
nodreg(®, types[tptr], D_DX);
|
||||
nodreg(&r1, types[tptr], D_BX);
|
||||
nodreg(®, types[tptr], REG_DX);
|
||||
nodreg(&r1, types[tptr], REG_BX);
|
||||
gmove(f, ®);
|
||||
reg.op = OINDREG;
|
||||
gmove(®, &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(®, types[TINT32], D_AX);
|
||||
nodreg(®, types[TINT32], REG_AX);
|
||||
gins(ATESTL, ®, ®);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue