Commit 604138e8 authored by Russ Cox's avatar Russ Cox

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

Change-Id: I5535582660da3504663c6cba2637da132c65a400
Reviewed-on: https://go-review.googlesource.com/3517Reviewed-by: default avatarAustin Clements <austin@google.com>
parent 0d599909
...@@ -231,7 +231,7 @@ spec5: /* SHL/SHR */ ...@@ -231,7 +231,7 @@ spec5: /* SHL/SHR */
{ {
$$.from = $1; $$.from = $1;
$$.to = $3; $$.to = $3;
if($$.from.index != D_NONE) if($$.from.index != TYPE_NONE)
yyerror("dp shift with lhs index"); yyerror("dp shift with lhs index");
$$.from.index = $5; $$.from.index = $5;
} }
...@@ -246,7 +246,7 @@ spec6: /* MOVW/MOVL */ ...@@ -246,7 +246,7 @@ spec6: /* MOVW/MOVL */
{ {
$$.from = $1; $$.from = $1;
$$.to = $3; $$.to = $3;
if($$.to.index != D_NONE) if($$.to.index != TYPE_NONE)
yyerror("dp move with lhs index"); yyerror("dp move with lhs index");
$$.to.index = $5; $$.to.index = $5;
} }
...@@ -281,7 +281,7 @@ spec9: /* shufl */ ...@@ -281,7 +281,7 @@ spec9: /* shufl */
{ {
$$.from = $3; $$.from = $3;
$$.to = $5; $$.to = $5;
if($1.type != D_CONST) if($1.type != TYPE_CONST)
yyerror("illegal constant"); yyerror("illegal constant");
$$.to.offset = $1.offset; $$.to.offset = $1.offset;
} }
...@@ -313,7 +313,7 @@ spec11: /* GLOBL */ ...@@ -313,7 +313,7 @@ spec11: /* GLOBL */
spec12: /* PCDATA */ spec12: /* PCDATA */
rim ',' rim 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"); yyerror("arguments to PCDATA must be integer constants");
$$.from = $1; $$.from = $1;
$$.to = $3; $$.to = $3;
...@@ -322,9 +322,9 @@ spec12: /* PCDATA */ ...@@ -322,9 +322,9 @@ spec12: /* PCDATA */
spec13: /* FUNCDATA */ spec13: /* FUNCDATA */
rim ',' rim rim ',' rim
{ {
if($1.type != D_CONST) if($1.type != TYPE_CONST)
yyerror("index for FUNCDATA must be integer constant"); 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"); yyerror("value for FUNCDATA must be symbol reference");
$$.from = $1; $$.from = $1;
$$.to = $3; $$.to = $3;
...@@ -356,7 +356,7 @@ rel: ...@@ -356,7 +356,7 @@ rel:
con '(' LPC ')' con '(' LPC ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_BRANCH; $$.type = TYPE_BRANCH;
$$.offset = $1 + pc; $$.offset = $1 + pc;
} }
| LNAME offset | LNAME offset
...@@ -365,7 +365,7 @@ rel: ...@@ -365,7 +365,7 @@ rel:
$$ = nullgen; $$ = nullgen;
if(pass == 2 && $1->type != LLAB) if(pass == 2 && $1->type != LLAB)
yyerror("undefined label: %s", $1->labelname); yyerror("undefined label: %s", $1->labelname);
$$.type = D_BRANCH; $$.type = TYPE_BRANCH;
$$.offset = $1->value + $2; $$.offset = $1->value + $2;
} }
...@@ -373,43 +373,50 @@ reg: ...@@ -373,43 +373,50 @@ reg:
LBREG LBREG
{ {
$$ = nullgen; $$ = nullgen;
$$.type = $1; $$.type = TYPE_REG;
$$.reg = $1;
} }
| LFREG | LFREG
{ {
$$ = nullgen; $$ = nullgen;
$$.type = $1; $$.type = TYPE_REG;
$$.reg = $1;
} }
| LLREG | LLREG
{ {
$$ = nullgen; $$ = nullgen;
$$.type = $1; $$.type = TYPE_REG;
$$.reg = $1;
} }
| LMREG | LMREG
{ {
$$ = nullgen; $$ = nullgen;
$$.type = $1; $$.type = TYPE_REG;
$$.reg = $1;
} }
| LSP | LSP
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_SP; $$.type = TYPE_REG;
$$.reg = REG_SP;
} }
| LSREG | LSREG
{ {
$$ = nullgen; $$ = nullgen;
$$.type = $1; $$.type = TYPE_REG;
$$.reg = $1;
} }
| LXREG | LXREG
{ {
$$ = nullgen; $$ = nullgen;
$$.type = $1; $$.type = TYPE_REG;
$$.reg = $1;
} }
imm2: imm2:
'$' con2 '$' con2
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_CONST; $$.type = TYPE_CONST;
$$.offset = $2; $$.offset = $2;
} }
...@@ -417,14 +424,13 @@ imm: ...@@ -417,14 +424,13 @@ imm:
'$' con '$' con
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_CONST; $$.type = TYPE_CONST;
$$.offset = $2; $$.offset = $2;
} }
| '$' nam | '$' nam
{ {
$$ = $2; $$ = $2;
$$.index = $2.type; $$.type = TYPE_ADDR;
$$.type = D_ADDR;
/* /*
if($2.type == D_AUTO || $2.type == D_PARAM) if($2.type == D_AUTO || $2.type == D_PARAM)
yyerror("constant cannot be automatic: %s", yyerror("constant cannot be automatic: %s",
...@@ -434,31 +440,31 @@ imm: ...@@ -434,31 +440,31 @@ imm:
| '$' LSCONST | '$' LSCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_SCONST; $$.type = TYPE_SCONST;
memcpy($$.u.sval, $2, sizeof($$.u.sval)); memcpy($$.u.sval, $2, sizeof($$.u.sval));
} }
| '$' LFCONST | '$' LFCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FCONST; $$.type = TYPE_FCONST;
$$.u.dval = $2; $$.u.dval = $2;
} }
| '$' '(' LFCONST ')' | '$' '(' LFCONST ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FCONST; $$.type = TYPE_FCONST;
$$.u.dval = $3; $$.u.dval = $3;
} }
| '$' '(' '-' LFCONST ')' | '$' '(' '-' LFCONST ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FCONST; $$.type = TYPE_FCONST;
$$.u.dval = -$4; $$.u.dval = -$4;
} }
| '$' '-' LFCONST | '$' '-' LFCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FCONST; $$.type = TYPE_FCONST;
$$.u.dval = -$3; $$.u.dval = -$3;
} }
...@@ -470,31 +476,34 @@ omem: ...@@ -470,31 +476,34 @@ omem:
con con
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_INDIR+D_NONE; $$.type = TYPE_MEM;
$$.offset = $1; $$.offset = $1;
} }
| con '(' LLREG ')' | con '(' LLREG ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_INDIR+$3; $$.type = TYPE_MEM;
$$.reg = $3;
$$.offset = $1; $$.offset = $1;
} }
| con '(' LSP ')' | con '(' LSP ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_INDIR+D_SP; $$.type = TYPE_MEM;
$$.reg = REG_SP;
$$.offset = $1; $$.offset = $1;
} }
| con '(' LSREG ')' | con '(' LSREG ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_INDIR+$3; $$.type = TYPE_MEM;
$$.reg = $3;
$$.offset = $1; $$.offset = $1;
} }
| con '(' LLREG '*' con ')' | con '(' LLREG '*' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_INDIR+D_NONE; $$.type = TYPE_MEM;
$$.offset = $1; $$.offset = $1;
$$.index = $3; $$.index = $3;
$$.scale = $5; $$.scale = $5;
...@@ -503,7 +512,8 @@ omem: ...@@ -503,7 +512,8 @@ omem:
| con '(' LLREG ')' '(' LLREG '*' con ')' | con '(' LLREG ')' '(' LLREG '*' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_INDIR+$3; $$.type = TYPE_MEM;
$$.reg = $3;
$$.offset = $1; $$.offset = $1;
$$.index = $6; $$.index = $6;
$$.scale = $8; $$.scale = $8;
...@@ -512,7 +522,8 @@ omem: ...@@ -512,7 +522,8 @@ omem:
| con '(' LLREG ')' '(' LSREG '*' con ')' | con '(' LLREG ')' '(' LSREG '*' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_INDIR+$3; $$.type = TYPE_MEM;
$$.reg = $3;
$$.offset = $1; $$.offset = $1;
$$.index = $6; $$.index = $6;
$$.scale = $8; $$.scale = $8;
...@@ -521,17 +532,19 @@ omem: ...@@ -521,17 +532,19 @@ omem:
| '(' LLREG ')' | '(' LLREG ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_INDIR+$2; $$.type = TYPE_MEM;
$$.reg = $2;
} }
| '(' LSP ')' | '(' LSP ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_INDIR+D_SP; $$.type = TYPE_MEM;
$$.reg = REG_SP;
} }
| '(' LLREG '*' con ')' | '(' LLREG '*' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_INDIR+D_NONE; $$.type = TYPE_MEM;
$$.index = $2; $$.index = $2;
$$.scale = $4; $$.scale = $4;
checkscale($$.scale); checkscale($$.scale);
...@@ -539,7 +552,8 @@ omem: ...@@ -539,7 +552,8 @@ omem:
| '(' LLREG ')' '(' LLREG '*' con ')' | '(' LLREG ')' '(' LLREG '*' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_INDIR+$2; $$.type = TYPE_MEM;
$$.reg = $2;
$$.index = $5; $$.index = $5;
$$.scale = $7; $$.scale = $7;
checkscale($$.scale); checkscale($$.scale);
...@@ -562,14 +576,16 @@ nam: ...@@ -562,14 +576,16 @@ nam:
LNAME offset '(' pointer ')' LNAME offset '(' pointer ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = $4; $$.type = TYPE_MEM;
$$.name = $4;
$$.sym = linklookup(ctxt, $1->name, 0); $$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2; $$.offset = $2;
} }
| LNAME '<' '>' offset '(' LSB ')' | LNAME '<' '>' offset '(' LSB ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_STATIC; $$.type = TYPE_MEM;
$$.name = NAME_STATIC;
$$.sym = linklookup(ctxt, $1->name, 1); $$.sym = linklookup(ctxt, $1->name, 1);
$$.offset = $4; $$.offset = $4;
} }
...@@ -591,7 +607,7 @@ pointer: ...@@ -591,7 +607,7 @@ pointer:
LSB LSB
| LSP | LSP
{ {
$$ = D_AUTO; $$ = NAME_AUTO;
} }
| LFP | LFP
......
...@@ -204,135 +204,136 @@ struct ...@@ -204,135 +204,136 @@ struct
ushort value; ushort value;
} itab[] = } itab[] =
{ {
"SP", LSP, D_AUTO, "SP", LSP, NAME_AUTO,
"SB", LSB, D_EXTERN, "SB", LSB, NAME_EXTERN,
"FP", LFP, D_PARAM, "FP", LFP, NAME_PARAM,
"PC", LPC, D_BRANCH,
"AL", LBREG, D_AL, "PC", LPC, TYPE_BRANCH,
"CL", LBREG, D_CL,
"DL", LBREG, D_DL,
"BL", LBREG, D_BL,
/* "SPB", LBREG, D_SPB, */
"SIB", LBREG, D_SIB,
"DIB", LBREG, D_DIB,
"BPB", LBREG, D_BPB,
"R8B", LBREG, D_R8B,
"R9B", LBREG, D_R9B,
"R10B", LBREG, D_R10B,
"R11B", LBREG, D_R11B,
"R12B", LBREG, D_R12B,
"R13B", LBREG, D_R13B,
"R14B", LBREG, D_R14B,
"R15B", LBREG, D_R15B,
"AH", LBREG, D_AH, "AL", LBREG, REG_AL,
"CH", LBREG, D_CH, "CL", LBREG, REG_CL,
"DH", LBREG, D_DH, "DL", LBREG, REG_DL,
"BH", LBREG, D_BH, "BL", LBREG, REG_BL,
/* "SPB", LBREG, REG_SPB, */
"SIB", LBREG, REG_SIB,
"DIB", LBREG, REG_DIB,
"BPB", LBREG, REG_BPB,
"R8B", LBREG, REG_R8B,
"R9B", LBREG, REG_R9B,
"R10B", LBREG, REG_R10B,
"R11B", LBREG, REG_R11B,
"R12B", LBREG, REG_R12B,
"R13B", LBREG, REG_R13B,
"R14B", LBREG, REG_R14B,
"R15B", LBREG, REG_R15B,
"AX", LLREG, D_AX, "AH", LBREG, REG_AH,
"CX", LLREG, D_CX, "CH", LBREG, REG_CH,
"DX", LLREG, D_DX, "DH", LBREG, REG_DH,
"BX", LLREG, D_BX, "BH", LBREG, REG_BH,
/* "SP", LLREG, D_SP, */
"BP", LLREG, D_BP, "AX", LLREG, REG_AX,
"SI", LLREG, D_SI, "CX", LLREG, REG_CX,
"DI", LLREG, D_DI, "DX", LLREG, REG_DX,
"R8", LLREG, D_R8, "BX", LLREG, REG_BX,
"R9", LLREG, D_R9, /* "SP", LLREG, REG_SP, */
"R10", LLREG, D_R10, "BP", LLREG, REG_BP,
"R11", LLREG, D_R11, "SI", LLREG, REG_SI,
"R12", LLREG, D_R12, "DI", LLREG, REG_DI,
"R13", LLREG, D_R13, "R8", LLREG, REG_R8,
"R14", LLREG, D_R14, "R9", LLREG, REG_R9,
"R15", LLREG, D_R15, "R10", LLREG, REG_R10,
"R11", LLREG, REG_R11,
"R12", LLREG, REG_R12,
"R13", LLREG, REG_R13,
"R14", LLREG, REG_R14,
"R15", LLREG, REG_R15,
"RARG", LLREG, REGARG, "RARG", LLREG, REGARG,
"F0", LFREG, D_F0+0, "F0", LFREG, REG_F0+0,
"F1", LFREG, D_F0+1, "F1", LFREG, REG_F0+1,
"F2", LFREG, D_F0+2, "F2", LFREG, REG_F0+2,
"F3", LFREG, D_F0+3, "F3", LFREG, REG_F0+3,
"F4", LFREG, D_F0+4, "F4", LFREG, REG_F0+4,
"F5", LFREG, D_F0+5, "F5", LFREG, REG_F0+5,
"F6", LFREG, D_F0+6, "F6", LFREG, REG_F0+6,
"F7", LFREG, D_F0+7, "F7", LFREG, REG_F0+7,
"M0", LMREG, D_M0+0, "M0", LMREG, REG_M0+0,
"M1", LMREG, D_M0+1, "M1", LMREG, REG_M0+1,
"M2", LMREG, D_M0+2, "M2", LMREG, REG_M0+2,
"M3", LMREG, D_M0+3, "M3", LMREG, REG_M0+3,
"M4", LMREG, D_M0+4, "M4", LMREG, REG_M0+4,
"M5", LMREG, D_M0+5, "M5", LMREG, REG_M0+5,
"M6", LMREG, D_M0+6, "M6", LMREG, REG_M0+6,
"M7", LMREG, D_M0+7, "M7", LMREG, REG_M0+7,
"X0", LXREG, D_X0+0, "X0", LXREG, REG_X0+0,
"X1", LXREG, D_X0+1, "X1", LXREG, REG_X0+1,
"X2", LXREG, D_X0+2, "X2", LXREG, REG_X0+2,
"X3", LXREG, D_X0+3, "X3", LXREG, REG_X0+3,
"X4", LXREG, D_X0+4, "X4", LXREG, REG_X0+4,
"X5", LXREG, D_X0+5, "X5", LXREG, REG_X0+5,
"X6", LXREG, D_X0+6, "X6", LXREG, REG_X0+6,
"X7", LXREG, D_X0+7, "X7", LXREG, REG_X0+7,
"X8", LXREG, D_X0+8, "X8", LXREG, REG_X0+8,
"X9", LXREG, D_X0+9, "X9", LXREG, REG_X0+9,
"X10", LXREG, D_X0+10, "X10", LXREG, REG_X0+10,
"X11", LXREG, D_X0+11, "X11", LXREG, REG_X0+11,
"X12", LXREG, D_X0+12, "X12", LXREG, REG_X0+12,
"X13", LXREG, D_X0+13, "X13", LXREG, REG_X0+13,
"X14", LXREG, D_X0+14, "X14", LXREG, REG_X0+14,
"X15", LXREG, D_X0+15, "X15", LXREG, REG_X0+15,
"CS", LSREG, D_CS, "CS", LSREG, REG_CS,
"SS", LSREG, D_SS, "SS", LSREG, REG_SS,
"DS", LSREG, D_DS, "DS", LSREG, REG_DS,
"ES", LSREG, D_ES, "ES", LSREG, REG_ES,
"FS", LSREG, D_FS, "FS", LSREG, REG_FS,
"GS", LSREG, D_GS, "GS", LSREG, REG_GS,
"GDTR", LBREG, D_GDTR, "GDTR", LBREG, REG_GDTR,
"IDTR", LBREG, D_IDTR, "IDTR", LBREG, REG_IDTR,
"LDTR", LBREG, D_LDTR, "LDTR", LBREG, REG_LDTR,
"MSW", LBREG, D_MSW, "MSW", LBREG, REG_MSW,
"TASK", LBREG, D_TASK, "TASK", LBREG, REG_TASK,
"CR0", LBREG, D_CR+0, "CR0", LBREG, REG_CR+0,
"CR1", LBREG, D_CR+1, "CR1", LBREG, REG_CR+1,
"CR2", LBREG, D_CR+2, "CR2", LBREG, REG_CR+2,
"CR3", LBREG, D_CR+3, "CR3", LBREG, REG_CR+3,
"CR4", LBREG, D_CR+4, "CR4", LBREG, REG_CR+4,
"CR5", LBREG, D_CR+5, "CR5", LBREG, REG_CR+5,
"CR6", LBREG, D_CR+6, "CR6", LBREG, REG_CR+6,
"CR7", LBREG, D_CR+7, "CR7", LBREG, REG_CR+7,
"CR8", LBREG, D_CR+8, "CR8", LBREG, REG_CR+8,
"CR9", LBREG, D_CR+9, "CR9", LBREG, REG_CR+9,
"CR10", LBREG, D_CR+10, "CR10", LBREG, REG_CR+10,
"CR11", LBREG, D_CR+11, "CR11", LBREG, REG_CR+11,
"CR12", LBREG, D_CR+12, "CR12", LBREG, REG_CR+12,
"CR13", LBREG, D_CR+13, "CR13", LBREG, REG_CR+13,
"CR14", LBREG, D_CR+14, "CR14", LBREG, REG_CR+14,
"CR15", LBREG, D_CR+15, "CR15", LBREG, REG_CR+15,
"DR0", LBREG, D_DR+0, "DR0", LBREG, REG_DR+0,
"DR1", LBREG, D_DR+1, "DR1", LBREG, REG_DR+1,
"DR2", LBREG, D_DR+2, "DR2", LBREG, REG_DR+2,
"DR3", LBREG, D_DR+3, "DR3", LBREG, REG_DR+3,
"DR4", LBREG, D_DR+4, "DR4", LBREG, REG_DR+4,
"DR5", LBREG, D_DR+5, "DR5", LBREG, REG_DR+5,
"DR6", LBREG, D_DR+6, "DR6", LBREG, REG_DR+6,
"DR7", LBREG, D_DR+7, "DR7", LBREG, REG_DR+7,
"TR0", LBREG, D_TR+0, "TR0", LBREG, REG_TR+0,
"TR1", LBREG, D_TR+1, "TR1", LBREG, REG_TR+1,
"TR2", LBREG, D_TR+2, "TR2", LBREG, REG_TR+2,
"TR3", LBREG, D_TR+3, "TR3", LBREG, REG_TR+3,
"TR4", LBREG, D_TR+4, "TR4", LBREG, REG_TR+4,
"TR5", LBREG, D_TR+5, "TR5", LBREG, REG_TR+5,
"TR6", LBREG, D_TR+6, "TR6", LBREG, REG_TR+6,
"TR7", LBREG, D_TR+7, "TR7", LBREG, REG_TR+7,
"TLS", LSREG, D_TLS, "TLS", LSREG, REG_TLS,
"AAA", LTYPE0, AAAA, "AAA", LTYPE0, AAAA,
"AAD", LTYPE0, AAAD, "AAD", LTYPE0, AAAD,
...@@ -1052,8 +1053,8 @@ cinit(void) ...@@ -1052,8 +1053,8 @@ cinit(void)
Sym *s; Sym *s;
int i; int i;
nullgen.type = D_NONE; nullgen.type = TYPE_NONE;
nullgen.index = D_NONE; nullgen.index = TYPE_NONE;
nerrors = 0; nerrors = 0;
iostack = I; iostack = I;
......
This diff is collapsed.
...@@ -759,9 +759,10 @@ agenr(Node *n, Node *a, Node *res) ...@@ -759,9 +759,10 @@ agenr(Node *n, Node *a, Node *res)
// nothing to do // nothing to do
} else if(w == 1 || w == 2 || w == 4 || w == 8) { } else if(w == 1 || w == 2 || w == 4 || w == 8) {
p1 = gins(ALEAQ, &n2, &n3); p1 = gins(ALEAQ, &n2, &n3);
p1->from.type = TYPE_MEM;
p1->from.scale = w; p1->from.scale = w;
p1->from.index = p1->from.type; p1->from.index = p1->from.reg;
p1->from.type = p1->to.type + D_INDIR; p1->from.reg = p1->to.reg;
} else { } else {
ginscon(optoas(OMUL, t), w, &n2); ginscon(optoas(OMUL, t), w, &n2);
gins(optoas(OADD, types[tptr]), &n2, &n3); gins(optoas(OADD, types[tptr]), &n2, &n3);
...@@ -941,7 +942,7 @@ igen(Node *n, Node *a, Node *res) ...@@ -941,7 +942,7 @@ igen(Node *n, Node *a, Node *res)
case OINDREG: case OINDREG:
// Increase the refcount of the register so that igen's caller // Increase the refcount of the register so that igen's caller
// has to call regfree. // has to call regfree.
if(n->val.u.reg != D_SP) if(n->val.u.reg != REG_SP)
reg[n->val.u.reg]++; reg[n->val.u.reg]++;
*a = *n; *a = *n;
return; return;
...@@ -979,7 +980,7 @@ igen(Node *n, Node *a, Node *res) ...@@ -979,7 +980,7 @@ igen(Node *n, Node *a, Node *res)
fp = structfirst(&flist, getoutarg(n->left->type)); fp = structfirst(&flist, getoutarg(n->left->type));
memset(a, 0, sizeof *a); memset(a, 0, sizeof *a);
a->op = OINDREG; a->op = OINDREG;
a->val.u.reg = D_SP; a->val.u.reg = REG_SP;
a->addable = 1; a->addable = 1;
a->xoffset = fp->width; a->xoffset = fp->width;
a->type = n->type; a->type = n->type;
...@@ -1401,8 +1402,8 @@ sgen(Node *n, Node *ns, int64 w) ...@@ -1401,8 +1402,8 @@ sgen(Node *n, Node *ns, int64 w)
agenr(n, &nodr, N); agenr(n, &nodr, N);
} }
nodreg(&noddi, types[tptr], D_DI); nodreg(&noddi, types[tptr], REG_DI);
nodreg(&nodsi, types[tptr], D_SI); nodreg(&nodsi, types[tptr], REG_SI);
gmove(&nodl, &noddi); gmove(&nodl, &noddi);
gmove(&nodr, &nodsi); gmove(&nodr, &nodsi);
regfree(&nodl); regfree(&nodl);
...@@ -1411,7 +1412,7 @@ sgen(Node *n, Node *ns, int64 w) ...@@ -1411,7 +1412,7 @@ sgen(Node *n, Node *ns, int64 w)
c = w % 8; // bytes c = w % 8; // bytes
q = w / 8; // quads q = w / 8; // quads
savex(D_CX, &cx, &oldcx, N, types[TINT64]); savex(REG_CX, &cx, &oldcx, N, types[TINT64]);
// if we are copying forward on the stack and // if we are copying forward on the stack and
// the src and dst overlap, then reverse direction // the src and dst overlap, then reverse direction
...@@ -1419,23 +1420,23 @@ sgen(Node *n, Node *ns, int64 w) ...@@ -1419,23 +1420,23 @@ sgen(Node *n, Node *ns, int64 w)
// reverse direction // reverse direction
gins(ASTD, N, N); // set direction flag gins(ASTD, N, N); // set direction flag
if(c > 0) { if(c > 0) {
gconreg(addptr, w-1, D_SI); gconreg(addptr, w-1, REG_SI);
gconreg(addptr, w-1, D_DI); gconreg(addptr, w-1, REG_DI);
gconreg(movptr, c, D_CX); gconreg(movptr, c, REG_CX);
gins(AREP, N, N); // repeat gins(AREP, N, N); // repeat
gins(AMOVSB, N, N); // MOVB *(SI)-,*(DI)- gins(AMOVSB, N, N); // MOVB *(SI)-,*(DI)-
} }
if(q > 0) { if(q > 0) {
if(c > 0) { if(c > 0) {
gconreg(addptr, -7, D_SI); gconreg(addptr, -7, REG_SI);
gconreg(addptr, -7, D_DI); gconreg(addptr, -7, REG_DI);
} else { } else {
gconreg(addptr, w-8, D_SI); gconreg(addptr, w-8, REG_SI);
gconreg(addptr, w-8, D_DI); gconreg(addptr, w-8, REG_DI);
} }
gconreg(movptr, q, D_CX); gconreg(movptr, q, REG_CX);
gins(AREP, N, N); // repeat gins(AREP, N, N); // repeat
gins(AMOVSQ, N, N); // MOVQ *(SI)-,*(DI)- gins(AMOVSQ, N, N); // MOVQ *(SI)-,*(DI)-
} }
...@@ -1444,12 +1445,12 @@ sgen(Node *n, Node *ns, int64 w) ...@@ -1444,12 +1445,12 @@ sgen(Node *n, Node *ns, int64 w)
} else { } else {
// normal direction // normal direction
if(q > 128 || (nacl && q >= 4)) { if(q > 128 || (nacl && q >= 4)) {
gconreg(movptr, q, D_CX); gconreg(movptr, q, REG_CX);
gins(AREP, N, N); // repeat gins(AREP, N, N); // repeat
gins(AMOVSQ, N, N); // MOVQ *(SI)+,*(DI)+ gins(AMOVSQ, N, N); // MOVQ *(SI)+,*(DI)+
} else if (q >= 4) { } else if (q >= 4) {
p = gins(ADUFFCOPY, N, N); p = gins(ADUFFCOPY, N, N);
p->to.type = D_ADDR; p->to.type = TYPE_ADDR;
p->to.sym = linksym(pkglookup("duffcopy", runtimepkg)); p->to.sym = linksym(pkglookup("duffcopy", runtimepkg));
// 14 and 128 = magic constants: see ../../runtime/asm_amd64.s // 14 and 128 = magic constants: see ../../runtime/asm_amd64.s
p->to.offset = 14*(128-q); p->to.offset = 14*(128-q);
......
...@@ -61,8 +61,8 @@ betypeinit(void) ...@@ -61,8 +61,8 @@ betypeinit(void)
zprog.link = P; zprog.link = P;
zprog.as = AGOK; zprog.as = AGOK;
zprog.from.type = D_NONE; zprog.from.type = TYPE_NONE;
zprog.from.index = D_NONE; zprog.from.index = TYPE_NONE;
zprog.from.scale = 0; zprog.from.scale = 0;
zprog.to = zprog.from; zprog.to = zprog.from;
arch.zprog = zprog; arch.zprog = zprog;
...@@ -94,10 +94,6 @@ main(int argc, char **argv) ...@@ -94,10 +94,6 @@ main(int argc, char **argv)
arch.AUNDEF = AUNDEF; arch.AUNDEF = AUNDEF;
arch.AVARDEF = AVARDEF; arch.AVARDEF = AVARDEF;
arch.AVARKILL = AVARKILL; 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.MAXWIDTH = MAXWIDTH;
arch.afunclit = afunclit; arch.afunclit = afunclit;
arch.anyregalloc = anyregalloc; arch.anyregalloc = anyregalloc;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#define TEXTFLAG from.scale #define TEXTFLAG from.scale
EXTERN int32 dynloc; EXTERN int32 dynloc;
EXTERN uchar reg[D_NONE]; EXTERN uchar reg[MAXREG];
EXTERN int32 pcloc; // instruction counter EXTERN int32 pcloc; // instruction counter
EXTERN Strlit emptystring; EXTERN Strlit emptystring;
EXTERN Prog zprog; EXTERN Prog zprog;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include "gg.h" #include "gg.h"
#include "opt.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); static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax);
void void
...@@ -70,36 +70,36 @@ zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax) ...@@ -70,36 +70,36 @@ zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax)
if(cnt == 0) if(cnt == 0)
return p; return p;
if(*ax == 0) { if(*ax == 0) {
p = appendpp(p, AMOVQ, D_CONST, 0, D_AX, 0); p = appendpp(p, AMOVQ, TYPE_CONST, 0, 0, TYPE_REG, REG_AX, 0);
*ax = 1; *ax = 1;
} }
if(cnt % widthreg != 0) { if(cnt % widthreg != 0) {
// should only happen with nacl // should only happen with nacl
if(cnt % widthptr != 0) if(cnt % widthptr != 0)
fatal("zerorange count not a multiple of widthptr %d", cnt); fatal("zerorange count not a multiple of widthptr %d", cnt);
p = appendpp(p, AMOVL, D_AX, 0, D_SP+D_INDIR, frame+lo); p = appendpp(p, AMOVL, TYPE_REG, REG_AX, 0, TYPE_MEM, REG_SP, frame+lo);
lo += widthptr; lo += widthptr;
cnt -= widthptr; cnt -= widthptr;
} }
if(cnt <= 4*widthreg) { if(cnt <= 4*widthreg) {
for(i = 0; i < cnt; i += widthreg) { for(i = 0; i < cnt; i += widthreg) {
p = appendpp(p, AMOVQ, D_AX, 0, D_SP+D_INDIR, frame+lo+i); p = appendpp(p, AMOVQ, TYPE_REG, REG_AX, 0, TYPE_MEM, REG_SP, frame+lo+i);
} }
} else if(!nacl && (cnt <= 128*widthreg)) { } else if(!nacl && (cnt <= 128*widthreg)) {
p = appendpp(p, leaptr, D_SP+D_INDIR, frame+lo, D_DI, 0); p = appendpp(p, leaptr, TYPE_MEM, REG_SP, frame+lo, TYPE_REG, REG_DI, 0);
p = appendpp(p, ADUFFZERO, D_NONE, 0, D_ADDR, 2*(128-cnt/widthreg)); p = appendpp(p, ADUFFZERO, TYPE_NONE, 0, 0, TYPE_ADDR, 0, 2*(128-cnt/widthreg));
p->to.sym = linksym(pkglookup("duffzero", runtimepkg)); p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
} else { } else {
p = appendpp(p, AMOVQ, D_CONST, cnt/widthreg, D_CX, 0); p = appendpp(p, AMOVQ, TYPE_CONST, 0, cnt/widthreg, TYPE_REG, REG_CX, 0);
p = appendpp(p, leaptr, D_SP+D_INDIR, frame+lo, D_DI, 0); p = appendpp(p, leaptr, TYPE_MEM, REG_SP, frame+lo, TYPE_REG, REG_DI, 0);
p = appendpp(p, AREP, D_NONE, 0, D_NONE, 0); p = appendpp(p, AREP, TYPE_NONE, 0, 0, TYPE_NONE, 0, 0);
p = appendpp(p, ASTOSQ, D_NONE, 0, D_NONE, 0); p = appendpp(p, ASTOSQ, TYPE_NONE, 0, 0, TYPE_NONE, 0, 0);
} }
return p; return p;
} }
static Prog* 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; Prog *q;
q = mal(sizeof(*q)); q = mal(sizeof(*q));
...@@ -107,8 +107,10 @@ appendpp(Prog *p, int as, int ftype, vlong foffset, int ttype, vlong toffset) ...@@ -107,8 +107,10 @@ appendpp(Prog *p, int as, int ftype, vlong foffset, int ttype, vlong toffset)
q->as = as; q->as = as;
q->lineno = p->lineno; q->lineno = p->lineno;
q->from.type = ftype; q->from.type = ftype;
q->from.reg = freg;
q->from.offset = foffset; q->from.offset = foffset;
q->to.type = ttype; q->to.type = ttype;
q->to.reg = treg;
q->to.offset = toffset; q->to.offset = toffset;
q->link = p->link; q->link = p->link;
p->link = q; p->link = q;
...@@ -138,7 +140,7 @@ fixautoused(Prog *p) ...@@ -138,7 +140,7 @@ fixautoused(Prog *p)
Prog **lp; Prog **lp;
for (lp=&p; (p=*lp) != P; ) { 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; *lp = p->link;
continue; continue;
} }
...@@ -147,15 +149,13 @@ fixautoused(Prog *p) ...@@ -147,15 +149,13 @@ fixautoused(Prog *p)
// VARDEFs are interspersed with other code, and a jump might be using the // 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 // VARDEF as a target. Replace with a no-op instead. A later pass will remove
// the no-ops. // the no-ops.
p->to.type = D_NONE; nopout(p);
p->to.node = N;
p->as = ANOP;
continue; continue;
} }
if (p->from.type == D_AUTO && p->from.node) if (p->from.name == NAME_AUTO && p->from.node)
p->from.offset += ((Node*)(p->from.node))->stkdelta; p->from.offset += ((Node*)(p->from.node))->stkdelta;
if (p->to.type == D_AUTO && p->to.node) if (p->to.name == NAME_AUTO && p->to.node)
p->to.offset += ((Node*)(p->to.node))->stkdelta; p->to.offset += ((Node*)(p->to.node))->stkdelta;
lp = &p->link; lp = &p->link;
...@@ -205,7 +205,7 @@ ginscall(Node *f, int proc) ...@@ -205,7 +205,7 @@ ginscall(Node *f, int proc)
// x86 NOP 0x90 is really XCHG AX, AX; use that description // x86 NOP 0x90 is really XCHG AX, AX; use that description
// because the NOP pseudo-instruction would be removed by // because the NOP pseudo-instruction would be removed by
// the linker. // the linker.
nodreg(&reg, types[TINT], D_AX); nodreg(&reg, types[TINT], REG_AX);
gins(AXCHGL, &reg, &reg); gins(AXCHGL, &reg, &reg);
} }
p = gins(ACALL, N, f); p = gins(ACALL, N, f);
...@@ -214,8 +214,8 @@ ginscall(Node *f, int proc) ...@@ -214,8 +214,8 @@ ginscall(Node *f, int proc)
gins(AUNDEF, N, N); gins(AUNDEF, N, N);
break; break;
} }
nodreg(&reg, types[tptr], D_DX); nodreg(&reg, types[tptr], REG_DX);
nodreg(&r1, types[tptr], D_BX); nodreg(&r1, types[tptr], REG_BX);
gmove(f, &reg); gmove(f, &reg);
reg.op = OINDREG; reg.op = OINDREG;
gmove(&reg, &r1); gmove(&reg, &r1);
...@@ -231,7 +231,7 @@ ginscall(Node *f, int proc) ...@@ -231,7 +231,7 @@ ginscall(Node *f, int proc)
case 2: // deferred call (defer) case 2: // deferred call (defer)
memset(&stk, 0, sizeof(stk)); memset(&stk, 0, sizeof(stk));
stk.op = OINDREG; stk.op = OINDREG;
stk.val.u.reg = D_SP; stk.val.u.reg = REG_SP;
stk.xoffset = 0; stk.xoffset = 0;
if(widthptr == 8) { if(widthptr == 8) {
...@@ -240,7 +240,7 @@ ginscall(Node *f, int proc) ...@@ -240,7 +240,7 @@ ginscall(Node *f, int proc)
// FuncVal* at 8(SP) // FuncVal* at 8(SP)
stk.xoffset = widthptr; stk.xoffset = widthptr;
nodreg(&reg, types[TINT64], D_AX); nodreg(&reg, types[TINT64], REG_AX);
gmove(f, &reg); gmove(f, &reg);
gins(AMOVQ, &reg, &stk); gins(AMOVQ, &reg, &stk);
} else { } else {
...@@ -249,7 +249,7 @@ ginscall(Node *f, int proc) ...@@ -249,7 +249,7 @@ ginscall(Node *f, int proc)
// FuncVal* at 4(SP) // FuncVal* at 4(SP)
stk.xoffset = widthptr; stk.xoffset = widthptr;
nodreg(&reg, types[TINT32], D_AX); nodreg(&reg, types[TINT32], REG_AX);
gmove(f, &reg); gmove(f, &reg);
gins(AMOVL, &reg, &stk); gins(AMOVL, &reg, &stk);
} }
...@@ -262,7 +262,7 @@ ginscall(Node *f, int proc) ...@@ -262,7 +262,7 @@ ginscall(Node *f, int proc)
ginscall(deferproc, 0); ginscall(deferproc, 0);
} }
if(proc == 2) { if(proc == 2) {
nodreg(&reg, types[TINT32], D_AX); nodreg(&reg, types[TINT32], REG_AX);
gins(ATESTL, &reg, &reg); gins(ATESTL, &reg, &reg);
p = gbranch(AJEQ, T, +1); p = gbranch(AJEQ, T, +1);
cgen_ret(N); cgen_ret(N);
...@@ -304,7 +304,7 @@ cgen_callinter(Node *n, Node *res, int proc) ...@@ -304,7 +304,7 @@ cgen_callinter(Node *n, Node *res, int proc)
// register to hold its address. // register to hold its address.
igen(i, &nodi, res); // REG = &inter igen(i, &nodi, res); // REG = &inter
nodindreg(&nodsp, types[tptr], D_SP); nodindreg(&nodsp, types[tptr], REG_SP);
nodsp.xoffset = 0; nodsp.xoffset = 0;
if(proc != 0) if(proc != 0)
nodsp.xoffset += 2 * widthptr; // leave room for size & fn nodsp.xoffset += 2 * widthptr; // leave room for size & fn
...@@ -412,7 +412,7 @@ cgen_callret(Node *n, Node *res) ...@@ -412,7 +412,7 @@ cgen_callret(Node *n, Node *res)
memset(&nod, 0, sizeof(nod)); memset(&nod, 0, sizeof(nod));
nod.op = OINDREG; nod.op = OINDREG;
nod.val.u.reg = D_SP; nod.val.u.reg = REG_SP;
nod.addable = 1; nod.addable = 1;
nod.xoffset = fp->width; nod.xoffset = fp->width;
...@@ -442,7 +442,7 @@ cgen_aret(Node *n, Node *res) ...@@ -442,7 +442,7 @@ cgen_aret(Node *n, Node *res)
memset(&nod1, 0, sizeof(nod1)); memset(&nod1, 0, sizeof(nod1));
nod1.op = OINDREG; nod1.op = OINDREG;
nod1.val.u.reg = D_SP; nod1.val.u.reg = REG_SP;
nod1.addable = 1; nod1.addable = 1;
nod1.xoffset = fp->width; nod1.xoffset = fp->width;
...@@ -473,7 +473,8 @@ cgen_ret(Node *n) ...@@ -473,7 +473,8 @@ cgen_ret(Node *n)
genlist(curfn->exit); genlist(curfn->exit);
p = gins(ARET, N, N); p = gins(ARET, N, N);
if(n != N && n->op == ORETJMP) { 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); p->to.sym = linksym(n->left->sym);
} }
} }
...@@ -676,14 +677,14 @@ dodiv(int op, Node *nl, Node *nr, Node *res) ...@@ -676,14 +677,14 @@ dodiv(int op, Node *nl, Node *nr, Node *res)
regalloc(&n3, t0, N); regalloc(&n3, t0, N);
if(nl->ullman >= nr->ullman) { if(nl->ullman >= nr->ullman) {
savex(D_AX, &ax, &oldax, res, t0); savex(REG_AX, &ax, &oldax, res, t0);
cgen(nl, &ax); cgen(nl, &ax);
regalloc(&ax, t0, &ax); // mark ax live during cgen regalloc(&ax, t0, &ax); // mark ax live during cgen
cgen(nr, &n3); cgen(nr, &n3);
regfree(&ax); regfree(&ax);
} else { } else {
cgen(nr, &n3); cgen(nr, &n3);
savex(D_AX, &ax, &oldax, res, t0); savex(REG_AX, &ax, &oldax, res, t0);
cgen(nl, &ax); cgen(nl, &ax);
} }
if(t != t0) { if(t != t0) {
...@@ -725,7 +726,7 @@ dodiv(int op, Node *nl, Node *nr, Node *res) ...@@ -725,7 +726,7 @@ dodiv(int op, Node *nl, Node *nr, Node *res)
p2 = gbranch(AJMP, T, 0); p2 = gbranch(AJMP, T, 0);
patch(p1, pc); patch(p1, pc);
} }
savex(D_DX, &dx, &olddx, res, t); savex(REG_DX, &dx, &olddx, res, t);
if(!issigned[t->etype]) { if(!issigned[t->etype]) {
nodconst(&n4, t, 0); nodconst(&n4, t, 0);
gmove(&n4, &dx); gmove(&n4, &dx);
...@@ -929,7 +930,7 @@ cgen_hmul(Node *nl, Node *nr, Node *res) ...@@ -929,7 +930,7 @@ cgen_hmul(Node *nl, Node *nr, Node *res)
} }
cgenr(nl, &n1, res); cgenr(nl, &n1, res);
cgenr(nr, &n2, N); cgenr(nr, &n2, N);
nodreg(&ax, t, D_AX); nodreg(&ax, t, REG_AX);
gmove(&n1, &ax); gmove(&n1, &ax);
gins(a, &n2, N); gins(a, &n2, N);
regfree(&n2); regfree(&n2);
...@@ -937,11 +938,11 @@ cgen_hmul(Node *nl, Node *nr, Node *res) ...@@ -937,11 +938,11 @@ cgen_hmul(Node *nl, Node *nr, Node *res)
if(t->width == 1) { if(t->width == 1) {
// byte multiply behaves differently. // byte multiply behaves differently.
nodreg(&ax, t, D_AH); nodreg(&ax, t, REG_AH);
nodreg(&dx, t, D_DX); nodreg(&dx, t, REG_DX);
gmove(&ax, &dx); gmove(&ax, &dx);
} }
nodreg(&dx, t, D_DX); nodreg(&dx, t, REG_DX);
gmove(&dx, res); gmove(&dx, res);
} }
...@@ -988,8 +989,8 @@ cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res) ...@@ -988,8 +989,8 @@ cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
nr = &n5; nr = &n5;
} }
rcx = reg[D_CX]; rcx = reg[REG_CX];
nodreg(&n1, types[TUINT32], D_CX); nodreg(&n1, types[TUINT32], REG_CX);
// Allow either uint32 or uint64 as shift type, // Allow either uint32 or uint64 as shift type,
// to avoid unnecessary conversion from uint32 to uint64 // to avoid unnecessary conversion from uint32 to uint64
...@@ -1001,7 +1002,7 @@ cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res) ...@@ -1001,7 +1002,7 @@ cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
regalloc(&n1, nr->type, &n1); // to hold the shift type in CX regalloc(&n1, nr->type, &n1); // to hold the shift type in CX
regalloc(&n3, tcount, &n1); // to clear high bits of CX regalloc(&n3, tcount, &n1); // to clear high bits of CX
nodreg(&cx, types[TUINT64], D_CX); nodreg(&cx, types[TUINT64], REG_CX);
memset(&oldcx, 0, sizeof oldcx); memset(&oldcx, 0, sizeof oldcx);
if(rcx > 0 && !samereg(&cx, res)) { if(rcx > 0 && !samereg(&cx, res)) {
regalloc(&oldcx, types[TUINT64], N); regalloc(&oldcx, types[TUINT64], N);
...@@ -1148,19 +1149,19 @@ clearfat(Node *nl) ...@@ -1148,19 +1149,19 @@ clearfat(Node *nl)
return; return;
} }
savex(D_DI, &n1, &oldn1, N, types[tptr]); savex(REG_DI, &n1, &oldn1, N, types[tptr]);
agen(nl, &n1); agen(nl, &n1);
savex(D_AX, &ax, &oldax, N, types[tptr]); savex(REG_AX, &ax, &oldax, N, types[tptr]);
gconreg(AMOVL, 0, D_AX); gconreg(AMOVL, 0, REG_AX);
if(q > 128 || nacl) { if(q > 128 || nacl) {
gconreg(movptr, q, D_CX); gconreg(movptr, q, REG_CX);
gins(AREP, N, N); // repeat gins(AREP, N, N); // repeat
gins(ASTOSQ, N, N); // STOQ AL,*(DI)+ gins(ASTOSQ, N, N); // STOQ AL,*(DI)+
} else { } else {
p = gins(ADUFFZERO, N, N); p = gins(ADUFFZERO, N, N);
p->to.type = D_ADDR; p->to.type = TYPE_ADDR;
p->to.sym = linksym(pkglookup("duffzero", runtimepkg)); p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
// 2 and 128 = magic constants: see ../../runtime/asm_amd64.s // 2 and 128 = magic constants: see ../../runtime/asm_amd64.s
p->to.offset = 2*(128-q); p->to.offset = 2*(128-q);
...@@ -1221,22 +1222,26 @@ expandchecks(Prog *firstp) ...@@ -1221,22 +1222,26 @@ expandchecks(Prog *firstp)
p1->pc = 9999; p1->pc = 9999;
p2->pc = 9999; p2->pc = 9999;
p->as = cmpptr; p->as = cmpptr;
p->to.type = D_CONST; p->to.type = TYPE_CONST;
p->to.offset = 0; p->to.offset = 0;
p1->as = AJNE; p1->as = AJNE;
p1->from.type = D_CONST; p1->from.type = TYPE_CONST;
p1->from.offset = 1; // likely p1->from.offset = 1; // likely
p1->to.type = D_BRANCH; p1->to.type = TYPE_BRANCH;
p1->to.u.branch = p2->link; p1->to.u.branch = p2->link;
// crash by write to memory address 0. // crash by write to memory address 0.
// if possible, since we know arg is 0, use 0(arg), // if possible, since we know arg is 0, use 0(arg),
// which will be shorter to encode than plain 0. // which will be shorter to encode than plain 0.
p2->as = AMOVL; p2->as = AMOVL;
p2->from.type = D_AX; p2->from.type = TYPE_REG;
if(regtyp(&p->from)) p2->from.reg = REG_AX;
p2->to.type = p->from.type + D_INDIR; if(regtyp(&p->from)) {
else p2->to.type = TYPE_MEM;
p2->to.type = D_INDIR+D_NONE; p2->to.reg = p->from.reg;
} else {
p2->to.type = TYPE_MEM;
p2->to.reg = REG_NONE;
}
p2->to.offset = 0; p2->to.offset = 0;
} }
} }
...@@ -38,14 +38,13 @@ dsname(Sym *s, int off, char *t, int n) ...@@ -38,14 +38,13 @@ dsname(Sym *s, int off, char *t, int n)
Prog *p; Prog *p;
p = gins(ADATA, N, N); p = gins(ADATA, N, N);
p->from.type = D_EXTERN; p->from.type = TYPE_MEM;
p->from.index = D_NONE; p->from.name = NAME_EXTERN;
p->from.offset = off; p->from.offset = off;
p->from.scale = n; p->from.scale = n;
p->from.sym = linksym(s); p->from.sym = linksym(s);
p->to.type = D_SCONST; p->to.type = TYPE_SCONST;
p->to.index = D_NONE;
memmove(p->to.u.sval, t, n); memmove(p->to.u.sval, t, n);
return off + n; return off + n;
} }
...@@ -60,7 +59,8 @@ datastring(char *s, int len, Addr *a) ...@@ -60,7 +59,8 @@ datastring(char *s, int len, Addr *a)
Sym *sym; Sym *sym;
sym = stringsym(s, len); sym = stringsym(s, len);
a->type = D_EXTERN; a->type = TYPE_MEM;
a->name = NAME_EXTERN;
a->sym = linksym(sym); a->sym = linksym(sym);
a->node = sym->def; a->node = sym->def;
a->offset = widthptr+widthint; // skip header a->offset = widthptr+widthint; // skip header
...@@ -77,7 +77,8 @@ datagostring(Strlit *sval, Addr *a) ...@@ -77,7 +77,8 @@ datagostring(Strlit *sval, Addr *a)
Sym *sym; Sym *sym;
sym = stringsym(sval->s, sval->len); sym = stringsym(sval->s, sval->len);
a->type = D_EXTERN; a->type = TYPE_MEM;
a->name = NAME_EXTERN;
a->sym = linksym(sym); a->sym = linksym(sym);
a->node = sym->def; a->node = sym->def;
a->offset = 0; // header a->offset = 0; // header
...@@ -114,13 +115,13 @@ gdatacomplex(Node *nam, Mpcplx *cval) ...@@ -114,13 +115,13 @@ gdatacomplex(Node *nam, Mpcplx *cval)
p = gins(ADATA, nam, N); p = gins(ADATA, nam, N);
p->from.scale = w; p->from.scale = w;
p->to.type = D_FCONST; p->to.type = TYPE_FCONST;
p->to.u.dval = mpgetflt(&cval->real); p->to.u.dval = mpgetflt(&cval->real);
p = gins(ADATA, nam, N); p = gins(ADATA, nam, N);
p->from.scale = w; p->from.scale = w;
p->from.offset += w; p->from.offset += w;
p->to.type = D_FCONST; p->to.type = TYPE_FCONST;
p->to.u.dval = mpgetflt(&cval->imag); p->to.u.dval = mpgetflt(&cval->imag);
} }
...@@ -133,8 +134,7 @@ gdatastring(Node *nam, Strlit *sval) ...@@ -133,8 +134,7 @@ gdatastring(Node *nam, Strlit *sval)
p = gins(ADATA, nam, N); p = gins(ADATA, nam, N);
datastring(sval->s, sval->len, &p->to); datastring(sval->s, sval->len, &p->to);
p->from.scale = types[tptr]->width; p->from.scale = types[tptr]->width;
p->to.index = p->to.type; p->to.type = TYPE_ADDR;
p->to.type = D_ADDR;
//print("%P\n", p); //print("%P\n", p);
nodconst(&nod1, types[TINT], sval->len); nodconst(&nod1, types[TINT], sval->len);
...@@ -150,15 +150,14 @@ dstringptr(Sym *s, int off, char *str) ...@@ -150,15 +150,14 @@ dstringptr(Sym *s, int off, char *str)
off = rnd(off, widthptr); off = rnd(off, widthptr);
p = gins(ADATA, N, N); p = gins(ADATA, N, N);
p->from.type = D_EXTERN; p->from.type = TYPE_MEM;
p->from.index = D_NONE; p->from.name = NAME_EXTERN;
p->from.sym = linksym(s); p->from.sym = linksym(s);
p->from.offset = off; p->from.offset = off;
p->from.scale = widthptr; p->from.scale = widthptr;
datastring(str, strlen(str)+1, &p->to); datastring(str, strlen(str)+1, &p->to);
p->to.index = p->to.type; p->to.type = TYPE_ADDR;
p->to.type = D_ADDR;
p->to.etype = simtype[TINT]; p->to.etype = simtype[TINT];
off += widthptr; off += widthptr;
...@@ -175,14 +174,13 @@ dgostrlitptr(Sym *s, int off, Strlit *lit) ...@@ -175,14 +174,13 @@ dgostrlitptr(Sym *s, int off, Strlit *lit)
off = rnd(off, widthptr); off = rnd(off, widthptr);
p = gins(ADATA, N, N); p = gins(ADATA, N, N);
p->from.type = D_EXTERN; p->from.type = TYPE_MEM;
p->from.index = D_NONE; p->from.name = NAME_EXTERN;
p->from.sym = linksym(s); p->from.sym = linksym(s);
p->from.offset = off; p->from.offset = off;
p->from.scale = widthptr; p->from.scale = widthptr;
datagostring(lit, &p->to); datagostring(lit, &p->to);
p->to.index = p->to.type; p->to.type = TYPE_ADDR;
p->to.type = D_ADDR;
p->to.etype = simtype[TINT]; p->to.etype = simtype[TINT];
off += widthptr; off += widthptr;
...@@ -213,13 +211,13 @@ dsymptr(Sym *s, int off, Sym *x, int xoff) ...@@ -213,13 +211,13 @@ dsymptr(Sym *s, int off, Sym *x, int xoff)
off = rnd(off, widthptr); off = rnd(off, widthptr);
p = gins(ADATA, N, N); p = gins(ADATA, N, N);
p->from.type = D_EXTERN; p->from.type = TYPE_MEM;
p->from.index = D_NONE; p->from.name = NAME_EXTERN;
p->from.sym = linksym(s); p->from.sym = linksym(s);
p->from.offset = off; p->from.offset = off;
p->from.scale = widthptr; p->from.scale = widthptr;
p->to.type = D_ADDR; p->to.type = TYPE_ADDR;
p->to.index = D_EXTERN; p->to.name = NAME_EXTERN;
p->to.sym = linksym(x); p->to.sym = linksym(x);
p->to.offset = xoff; p->to.offset = xoff;
off += widthptr; off += widthptr;
...@@ -231,5 +229,7 @@ void ...@@ -231,5 +229,7 @@ void
nopout(Prog *p) nopout(Prog *p)
{ {
p->as = ANOP; p->as = ANOP;
p->from = zprog.from;
p->to = zprog.to;
} }
This diff is collapsed.
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
#define Z N #define Z N
#define Adr Addr #define Adr Addr
#define D_HI D_NONE #define D_HI TYPE_NONE
#define D_LO D_NONE #define D_LO TYPE_NONE
#define BLOAD(r) band(bnot(r->refbehind), r->refahead) #define BLOAD(r) band(bnot(r->refbehind), r->refahead)
#define BSTORE(r) band(bnot(r->calbehind), r->calahead) #define BSTORE(r) band(bnot(r->calbehind), r->calahead)
...@@ -52,8 +52,8 @@ typedef struct Rgn Rgn; ...@@ -52,8 +52,8 @@ typedef struct Rgn Rgn;
extern Node *Z; extern Node *Z;
enum enum
{ {
D_HI = D_NONE, D_HI = TYPE_NONE,
D_LO = D_NONE, D_LO = TYPE_NONE,
CLOAD = 5, CLOAD = 5,
CREF = 5, CREF = 5,
CINF = 1000, CINF = 1000,
......
...@@ -73,7 +73,7 @@ rnops(Flow *r) ...@@ -73,7 +73,7 @@ rnops(Flow *r)
if(r != nil) if(r != nil)
for(;;) { for(;;) {
p = r->prog; 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; break;
r1 = uniqs(r); r1 = uniqs(r);
if(r1 == nil) if(r1 == nil)
...@@ -110,7 +110,7 @@ peep(Prog *firstp) ...@@ -110,7 +110,7 @@ peep(Prog *firstp)
case ALEAQ: case ALEAQ:
if(regtyp(&p->to)) if(regtyp(&p->to))
if(p->from.sym != nil) if(p->from.sym != nil)
if(p->from.index == D_NONE || p->from.index == D_CONST) if(p->from.index == REG_NONE)
conprop(r); conprop(r);
break; break;
...@@ -121,7 +121,7 @@ peep(Prog *firstp) ...@@ -121,7 +121,7 @@ peep(Prog *firstp)
case AMOVSS: case AMOVSS:
case AMOVSD: case AMOVSD:
if(regtyp(&p->to)) 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); conprop(r);
break; break;
} }
...@@ -160,7 +160,7 @@ loop1: ...@@ -160,7 +160,7 @@ loop1:
r1 = rnops(uniqs(r)); r1 = rnops(uniqs(r));
if(r1 != nil) { if(r1 != nil) {
p1 = r1->prog; 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; p1->as = AMOVL;
t++; t++;
} }
...@@ -179,7 +179,7 @@ loop1: ...@@ -179,7 +179,7 @@ loop1:
r1 = rnops(uniqs(r)); r1 = rnops(uniqs(r));
if(r1 != nil) { if(r1 != nil) {
p1 = r1->prog; 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 = AMOVQ; p1->as = AMOVQ;
t++; t++;
} }
...@@ -190,7 +190,7 @@ loop1: ...@@ -190,7 +190,7 @@ loop1:
case AADDL: case AADDL:
case AADDQ: case AADDQ:
case AADDW: case AADDW:
if(p->from.type != D_CONST || needc(p->link)) if(p->from.type != TYPE_CONST || needc(p->link))
break; break;
if(p->from.offset == -1){ if(p->from.offset == -1){
if(p->as == AADDQ) if(p->as == AADDQ)
...@@ -218,7 +218,7 @@ loop1: ...@@ -218,7 +218,7 @@ loop1:
case ASUBL: case ASUBL:
case ASUBQ: case ASUBQ:
case ASUBW: case ASUBW:
if(p->from.type != D_CONST || needc(p->link)) if(p->from.type != TYPE_CONST || needc(p->link))
break; break;
if(p->from.offset == -1) { if(p->from.offset == -1) {
if(p->as == ASUBQ) if(p->as == ASUBQ)
...@@ -264,8 +264,8 @@ loop1: ...@@ -264,8 +264,8 @@ loop1:
p = r->prog; p = r->prog;
if(p->as == AMOVLQZX) if(p->as == AMOVLQZX)
if(regtyp(&p->from)) if(regtyp(&p->from))
if(p->from.type == p->to.type) if(p->from.type == p->to.type && p->from.reg == p->to.reg)
if(prevl(r, p->from.type)) if(prevl(r, p->from.reg))
excise(r); excise(r);
if(p->as == AMOVSD) if(p->as == AMOVSD)
...@@ -369,9 +369,7 @@ excise(Flow *r) ...@@ -369,9 +369,7 @@ excise(Flow *r)
if(debug['P'] && debug['v']) if(debug['P'] && debug['v'])
print("%P ===delete===\n", p); print("%P ===delete===\n", p);
p->as = ANOP; nopout(p);
p->from = zprog.from;
p->to = zprog.to;
ostats.ndelmov++; ostats.ndelmov++;
} }
...@@ -379,14 +377,7 @@ excise(Flow *r) ...@@ -379,14 +377,7 @@ excise(Flow *r)
int int
regtyp(Adr *a) regtyp(Adr *a)
{ {
int t; return a->type == TYPE_REG && (REG_AX <= a->reg && a->reg <= REG_R15 || REG_X0 <= a->reg && a->reg <= REG_X15);
t = a->type;
if(t >= D_AX && t <= D_R15)
return 1;
if(t >= D_X0 && t <= D_X15)
return 1;
return 0;
} }
// movb elimination. // movb elimination.
...@@ -426,7 +417,7 @@ elimshortmov(Graph *g) ...@@ -426,7 +417,7 @@ elimshortmov(Graph *g)
p->as = ANOTQ; p->as = ANOTQ;
break; 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. // move or artihmetic into partial register.
// from another register or constant can be movl. // from another register or constant can be movl.
// we don't switch to 64-bit arithmetic if it can // we don't switch to 64-bit arithmetic if it can
...@@ -471,7 +462,7 @@ elimshortmov(Graph *g) ...@@ -471,7 +462,7 @@ elimshortmov(Graph *g)
p->as = ASHLQ; p->as = ASHLQ;
break; break;
} }
} else if(p->from.type >= D_NONE) { } else if(p->from.type != TYPE_REG) {
// explicit zero extension, but don't // explicit zero extension, but don't
// do that if source is a byte register // do that if source is a byte register
// (only AH can occur and it's forbidden). // (only AH can occur and it's forbidden).
...@@ -495,10 +486,10 @@ regconsttyp(Adr *a) ...@@ -495,10 +486,10 @@ regconsttyp(Adr *a)
if(regtyp(a)) if(regtyp(a))
return 1; return 1;
switch(a->type) { switch(a->type) {
case D_CONST: case TYPE_CONST:
case D_FCONST: case TYPE_FCONST:
case D_SCONST: case TYPE_SCONST:
case D_ADDR: case TYPE_ADDR: // TODO(rsc): Not all TYPE_ADDRs are constants.
return 1; return 1;
} }
return 0; return 0;
...@@ -514,7 +505,7 @@ prevl(Flow *r0, int reg) ...@@ -514,7 +505,7 @@ prevl(Flow *r0, int reg)
for(r=uniqp(r0); r!=nil; r=uniqp(r)) { for(r=uniqp(r0); r!=nil; r=uniqp(r)) {
p = r->prog; p = r->prog;
if(p->to.type == reg) { if(p->to.type == TYPE_REG && p->to.reg == reg) {
proginfo(&info, p); proginfo(&info, p);
if(info.flags & RightWrite) { if(info.flags & RightWrite) {
if(info.flags & SizeL) if(info.flags & SizeL)
...@@ -588,7 +579,7 @@ subprop(Flow *r0) ...@@ -588,7 +579,7 @@ subprop(Flow *r0)
return 0; 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; goto gotit;
if(copyau(&p->from, v2) || if(copyau(&p->from, v2) ||
...@@ -612,7 +603,7 @@ gotit: ...@@ -612,7 +603,7 @@ gotit:
copysub(&p->to, v1, v2, 1); copysub(&p->to, v1, v2, 1);
if(debug['P']) { if(debug['P']) {
print("gotit: %D->%D\n%P", v1, v2, r->prog); 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(" excise");
print("\n"); print("\n");
} }
...@@ -623,9 +614,9 @@ gotit: ...@@ -623,9 +614,9 @@ gotit:
if(debug['P']) if(debug['P'])
print("%P\n", r->prog); print("%P\n", r->prog);
} }
t = v1->type; t = v1->reg;
v1->type = v2->type; v1->reg = v2->reg;
v2->type = t; v2->reg = t;
if(debug['P']) if(debug['P'])
print("%P last\n", r->prog); print("%P last\n", r->prog);
return 1; return 1;
...@@ -768,11 +759,11 @@ copyu(Prog *p, Adr *v, Adr *s) ...@@ -768,11 +759,11 @@ copyu(Prog *p, Adr *v, Adr *s)
return 3; return 3;
case ACALL: case ACALL:
if(REGEXT && v->type <= REGEXT && v->type > exregoffset) if(REGEXT && v->type == TYPE_REG && v->reg <= REGEXT && v->reg > exregoffset)
return 2; return 2;
if(REGARG >= 0 && v->type == (uchar)REGARG) if(REGARG >= 0 && v->type == TYPE_REG && v->reg == (uchar)REGARG)
return 2; return 2;
if(v->type == p->from.type) if(v->type == p->from.type && v->reg == p->from.reg)
return 2; return 2;
if(s != nil) { if(s != nil) {
...@@ -785,7 +776,7 @@ copyu(Prog *p, Adr *v, Adr *s) ...@@ -785,7 +776,7 @@ copyu(Prog *p, Adr *v, Adr *s)
return 3; return 3;
case ATEXT: case ATEXT:
if(REGARG >= 0 && v->type == (uchar)REGARG) if(REGARG >= 0 && v->type == TYPE_REG && v->reg == (uchar)REGARG)
return 3; return 3;
return 0; return 0;
} }
...@@ -794,7 +785,7 @@ copyu(Prog *p, Adr *v, Adr *s) ...@@ -794,7 +785,7 @@ copyu(Prog *p, Adr *v, Adr *s)
return 0; return 0;
proginfo(&info, p); proginfo(&info, p);
if((info.reguse|info.regset) & RtoB(v->type)) if((info.reguse|info.regset) & RtoB(v->reg))
return 2; return 2;
if(info.flags & LeftAddr) if(info.flags & LeftAddr)
...@@ -838,16 +829,16 @@ copyu(Prog *p, Adr *v, Adr *s) ...@@ -838,16 +829,16 @@ copyu(Prog *p, Adr *v, Adr *s)
static int static int
copyas(Adr *a, Adr *v) copyas(Adr *a, Adr *v)
{ {
if(D_AL <= a->type && a->type <= D_R15B) if(REG_AL <= a->reg && a->reg <= REG_R15B)
fatal("use of byte register"); fatal("use of byte register");
if(D_AL <= v->type && v->type <= D_R15B) if(REG_AL <= v->reg && v->reg <= REG_R15B)
fatal("use of byte register"); 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; return 0;
if(regtyp(v)) if(regtyp(v))
return 1; 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) if(v->offset == a->offset)
return 1; return 1;
return 0; return 0;
...@@ -856,11 +847,11 @@ copyas(Adr *a, Adr *v) ...@@ -856,11 +847,11 @@ copyas(Adr *a, Adr *v)
int int
sameaddr(Addr *a, Addr *v) 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; return 0;
if(regtyp(v)) if(regtyp(v))
return 1; 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) if(v->offset == a->offset)
return 1; return 1;
return 0; return 0;
...@@ -879,12 +870,12 @@ copyau(Adr *a, Adr *v) ...@@ -879,12 +870,12 @@ copyau(Adr *a, Adr *v)
return 1; return 1;
} }
if(regtyp(v)) { if(regtyp(v)) {
if(a->type-D_INDIR == v->type) { if(a->type == TYPE_MEM && a->reg == v->reg) {
if(debug['P'] && debug['v']) if(debug['P'] && debug['v'])
print("\tcopyau: found indir use - return 1\n"); print("\tcopyau: found indir use - return 1\n");
return 1; return 1;
} }
if(a->index == v->type) { if(a->index == v->reg) {
if(debug['P'] && debug['v']) if(debug['P'] && debug['v'])
print("\tcopyau: found index use - return 1\n"); print("\tcopyau: found index use - return 1\n");
return 1; return 1;
...@@ -900,28 +891,28 @@ copyau(Adr *a, Adr *v) ...@@ -900,28 +891,28 @@ copyau(Adr *a, Adr *v)
static int static int
copysub(Adr *a, Adr *v, Adr *s, int f) copysub(Adr *a, Adr *v, Adr *s, int f)
{ {
int t; int reg;
if(copyas(a, v)) { if(copyas(a, v)) {
t = s->type; reg = s->reg;
if(t >= D_AX && t <= D_R15 || t >= D_X0 && t <= D_X0+15) { if(reg >= REG_AX && reg <= REG_R15 || reg >= REG_X0 && reg <= REG_X0+15) {
if(f) if(f)
a->type = t; a->reg = reg;
} }
return 0; return 0;
} }
if(regtyp(v)) { if(regtyp(v)) {
t = v->type; reg = v->reg;
if(a->type == t+D_INDIR) { if(a->type == TYPE_MEM && a->reg == reg) {
if((s->type == D_BP || s->type == D_R13) && a->index != D_NONE) if((s->reg == REG_BP || s->reg == REG_R13) && a->index != REG_NONE)
return 1; /* can't use BP-base with index */ return 1; /* can't use BP-base with index */
if(f) if(f)
a->type = s->type+D_INDIR; a->reg = s->reg;
// return 0; // return 0;
} }
if(a->index == t) { if(a->index == reg) {
if(f) if(f)
a->index = s->type; a->index = s->reg;
return 0; return 0;
} }
return 0; return 0;
...@@ -962,10 +953,11 @@ loop: ...@@ -962,10 +953,11 @@ loop:
case 3: // set case 3: // set
if(p->as == p0->as) if(p->as == p0->as)
if(p->from.type == p0->from.type) if(p->from.type == p0->from.type)
if(p->from.reg == p0->from.reg)
if(p->from.node == p0->from.node) if(p->from.node == p0->from.node)
if(p->from.offset == p0->from.offset) if(p->from.offset == p0->from.offset)
if(p->from.scale == p0->from.scale) 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) { if(p->from.index == p0->from.index) {
excise(r); excise(r);
goto loop; goto loop;
...@@ -978,13 +970,13 @@ int ...@@ -978,13 +970,13 @@ int
smallindir(Addr *a, Addr *reg) smallindir(Addr *a, Addr *reg)
{ {
return regtyp(reg) && return regtyp(reg) &&
a->type == D_INDIR + reg->type && a->type == TYPE_MEM && a->reg == reg->reg &&
a->index == D_NONE && a->index == REG_NONE &&
0 <= a->offset && a->offset < 4096; 0 <= a->offset && a->offset < 4096;
} }
int int
stackaddr(Addr *a) stackaddr(Addr *a)
{ {
return regtyp(a) && a->type == D_SP; return a->type == TYPE_REG && a->reg == REG_SP;
} }
...@@ -8,15 +8,15 @@ ...@@ -8,15 +8,15 @@
#include "opt.h" #include "opt.h"
// Matches real RtoB but can be used in global initializer. // 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 { enum {
AX = RtoB(D_AX), AX = RtoB(REG_AX),
BX = RtoB(D_BX), BX = RtoB(REG_BX),
CX = RtoB(D_CX), CX = RtoB(REG_CX),
DX = RtoB(D_DX), DX = RtoB(REG_DX),
DI = RtoB(D_DI), DI = RtoB(REG_DI),
SI = RtoB(D_SI), SI = RtoB(REG_SI),
LeftRdwr = LeftRead | LeftWrite, LeftRdwr = LeftRead | LeftWrite,
RightRdwr = RightRead | RightWrite, RightRdwr = RightRead | RightWrite,
...@@ -294,11 +294,11 @@ proginfo(ProgInfo *info, Prog *p) ...@@ -294,11 +294,11 @@ proginfo(ProgInfo *info, Prog *p)
if(info->flags == 0) if(info->flags == 0)
fatal("unknown instruction %P", p); 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; info->reguse |= CX;
if(info->flags & ImulAXDX) { if(info->flags & ImulAXDX) {
if(p->to.type == D_NONE) { if(p->to.type == TYPE_NONE) {
info->reguse |= AX; info->reguse |= AX;
info->regset |= AX | DX; info->regset |= AX | DX;
} else { } else {
...@@ -307,12 +307,12 @@ proginfo(ProgInfo *info, Prog *p) ...@@ -307,12 +307,12 @@ proginfo(ProgInfo *info, Prog *p)
} }
// Addressing makes some registers used. // Addressing makes some registers used.
if(p->from.type >= D_INDIR) if(p->from.type == TYPE_MEM && p->from.name == NAME_NONE)
info->regindex |= RtoB(p->from.type-D_INDIR); info->regindex |= RtoB(p->from.reg);
if(p->from.index != D_NONE) if(p->from.index != REG_NONE)
info->regindex |= RtoB(p->from.index); info->regindex |= RtoB(p->from.index);
if(p->to.type >= D_INDIR) if(p->to.type == TYPE_MEM && p->to.name == NAME_NONE)
info->regindex |= RtoB(p->to.type-D_INDIR); info->regindex |= RtoB(p->to.reg);
if(p->to.index != D_NONE) if(p->to.index != REG_NONE)
info->regindex |= RtoB(p->to.index); info->regindex |= RtoB(p->to.index);
} }
...@@ -134,7 +134,7 @@ regopt(Prog *firstp) ...@@ -134,7 +134,7 @@ regopt(Prog *firstp)
if(first) { if(first) {
fmtinstall('Q', Qconv); fmtinstall('Q', Qconv);
exregoffset = D_R15; exregoffset = REG_R15;
first = 0; first = 0;
} }
...@@ -153,7 +153,7 @@ regopt(Prog *firstp) ...@@ -153,7 +153,7 @@ regopt(Prog *firstp)
var[i].node = regnodes[i]; var[i].node = regnodes[i];
} }
regbits = RtoB(D_SP); regbits = RtoB(REG_SP);
for(z=0; z<BITS; z++) { for(z=0; z<BITS; z++) {
externs.b[z] = 0; externs.b[z] = 0;
params.b[z] = 0; params.b[z] = 0;
...@@ -185,7 +185,7 @@ regopt(Prog *firstp) ...@@ -185,7 +185,7 @@ regopt(Prog *firstp)
proginfo(&info, p); proginfo(&info, p);
// Avoid making variables for direct-called functions. // 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; continue;
r->use1.b[0] |= info.reguse | info.regindex; r->use1.b[0] |= info.reguse | info.regindex;
...@@ -440,7 +440,7 @@ brk: ...@@ -440,7 +440,7 @@ brk:
for(p=firstp; p!=P; p=p->link) { for(p=firstp; p!=P; p=p->link) {
while(p->link != P && p->link->as == ANOP) while(p->link != P && p->link->as == ANOP)
p->link = p->link->link; 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) while(p->to.u.branch != P && p->to.u.branch->as == ANOP)
p->to.u.branch = p->to.u.branch->link; p->to.u.branch = p->to.u.branch->link;
} }
...@@ -523,7 +523,8 @@ addmove(Reg *r, int bn, int rn, int f) ...@@ -523,7 +523,8 @@ addmove(Reg *r, int bn, int rn, int f)
a = &p1->to; a = &p1->to;
a->offset = v->offset; a->offset = v->offset;
a->etype = v->etype; a->etype = v->etype;
a->type = v->name; a->type = TYPE_MEM;
a->name = v->name;
a->node = v->node; a->node = v->node;
a->sym = linksym(v->node->sym); a->sym = linksym(v->node->sym);
...@@ -559,11 +560,14 @@ addmove(Reg *r, int bn, int rn, int f) ...@@ -559,11 +560,14 @@ addmove(Reg *r, int bn, int rn, int f)
break; break;
} }
p1->from.type = rn; p1->from.type = TYPE_REG;
p1->from.reg = rn;
p1->from.name = NAME_NONE;
if(!f) { if(!f) {
p1->from = *a; p1->from = *a;
*a = zprog.from; *a = zprog.from;
a->type = rn; a->type = TYPE_REG;
a->reg = rn;
if(v->etype == TUINT8) if(v->etype == TUINT8)
p1->as = AMOVB; p1->as = AMOVB;
if(v->etype == TUINT16) if(v->etype == TUINT16)
...@@ -580,18 +584,16 @@ doregbits(int r) ...@@ -580,18 +584,16 @@ doregbits(int r)
uint32 b; uint32 b;
b = 0; b = 0;
if(r >= D_INDIR) if(r >= REG_AX && r <= REG_R15)
r -= D_INDIR;
if(r >= D_AX && r <= D_R15)
b |= RtoB(r); b |= RtoB(r);
else else
if(r >= D_AL && r <= D_R15B) if(r >= REG_AL && r <= REG_R15B)
b |= RtoB(r-D_AL+D_AX); b |= RtoB(r-REG_AL+REG_AX);
else else
if(r >= D_AH && r <= D_BH) if(r >= REG_AH && r <= REG_BH)
b |= RtoB(r-D_AH+D_AX); b |= RtoB(r-REG_AH+REG_AX);
else else
if(r >= D_X0 && r <= D_X0+15) if(r >= REG_X0 && r <= REG_X0+15)
b |= FtoB(r); b |= FtoB(r);
return b; return b;
} }
...@@ -614,7 +616,7 @@ Bits ...@@ -614,7 +616,7 @@ Bits
mkvar(Reg *r, Adr *a) mkvar(Reg *r, Adr *a)
{ {
Var *v; Var *v;
int i, t, n, et, z, flag; int i, n, et, z, flag;
int64 w; int64 w;
uint32 regu; uint32 regu;
int64 o; int64 o;
...@@ -624,40 +626,41 @@ mkvar(Reg *r, Adr *a) ...@@ -624,40 +626,41 @@ mkvar(Reg *r, Adr *a)
/* /*
* mark registers used * mark registers used
*/ */
t = a->type; if(a->type == TYPE_NONE)
if(t == D_NONE)
goto none; goto none;
if(r != R) if(r != R)
r->use1.b[0] |= doregbits(a->index); r->use1.b[0] |= doregbits(a->index);
if(t >= D_INDIR && t < 2*D_INDIR) switch(a->type) {
goto none;
switch(t) {
default: default:
regu = doregbits(t); regu = doregbits(a->reg);
if(regu == 0) if(regu == 0)
goto none; goto none;
bit = zbits; bit = zbits;
bit.b[0] = regu; bit.b[0] = regu;
return bit; return bit;
case D_ADDR: case TYPE_ADDR:
a->type = a->index; a->type = TYPE_MEM;
bit = mkvar(r, a); bit = mkvar(r, a);
setaddrs(bit); setaddrs(bit);
a->type = t; a->type = TYPE_ADDR;
ostats.naddr++; ostats.naddr++;
goto none; goto none;
case D_EXTERN: case TYPE_MEM:
case D_STATIC: switch(a->name) {
case D_PARAM: default:
case D_AUTO: goto none;
n = t; case NAME_EXTERN:
case NAME_STATIC:
case NAME_PARAM:
case NAME_AUTO:
n = a->name;
break; break;
} }
}
node = a->node; node = a->node;
if(node == N || node->op != ONAME || node->orig == N) if(node == N || node->op != ONAME || node->orig == N)
...@@ -730,10 +733,10 @@ mkvar(Reg *r, Adr *a) ...@@ -730,10 +733,10 @@ mkvar(Reg *r, Adr *a)
node->opt = v; node->opt = v;
bit = blsh(i); bit = blsh(i);
if(n == D_EXTERN || n == D_STATIC) if(n == NAME_EXTERN || n == NAME_STATIC)
for(z=0; z<BITS; z++) for(z=0; z<BITS; z++)
externs.b[z] |= bit.b[z]; externs.b[z] |= bit.b[z];
if(n == D_PARAM) if(n == NAME_PARAM)
for(z=0; z<BITS; z++) for(z=0; z<BITS; z++)
params.b[z] |= bit.b[z]; params.b[z] |= bit.b[z];
...@@ -1161,7 +1164,9 @@ addreg(Adr *a, int rn) ...@@ -1161,7 +1164,9 @@ addreg(Adr *a, int rn)
a->sym = nil; a->sym = nil;
a->node = nil; a->node = nil;
a->offset = 0; a->offset = 0;
a->type = rn; a->type = TYPE_REG;
a->reg = rn;
a->name = 0;
ostats.ncvtreg++; ostats.ncvtreg++;
} }
...@@ -1170,9 +1175,9 @@ uint32 ...@@ -1170,9 +1175,9 @@ uint32
RtoB(int r) RtoB(int r)
{ {
if(r < D_AX || r > D_R15) if(r < REG_AX || r > REG_R15)
return 0; return 0;
return 1L << (r-D_AX); return 1L << (r-REG_AX);
} }
int int
...@@ -1180,10 +1185,10 @@ BtoR(uint32 b) ...@@ -1180,10 +1185,10 @@ BtoR(uint32 b)
{ {
b &= 0xffffL; b &= 0xffffL;
if(nacl) if(nacl)
b &= ~((1<<(D_BP-D_AX)) | (1<<(D_R15-D_AX))); b &= ~((1<<(REG_BP-REG_AX)) | (1<<(REG_R15-REG_AX)));
if(b == 0) if(b == 0)
return 0; return 0;
return bitno(b) + D_AX; return bitno(b) + REG_AX;
} }
/* /*
...@@ -1195,9 +1200,9 @@ BtoR(uint32 b) ...@@ -1195,9 +1200,9 @@ BtoR(uint32 b)
uint32 uint32
FtoB(int f) FtoB(int f)
{ {
if(f < D_X0 || f > D_X15) if(f < REG_X0 || f > REG_X15)
return 0; return 0;
return 1L << (f - D_X0 + 16); return 1L << (f - REG_X0 + 16);
} }
int int
...@@ -1207,7 +1212,7 @@ BtoF(uint32 b) ...@@ -1207,7 +1212,7 @@ BtoF(uint32 b)
b &= 0xFFFF0000L; b &= 0xFFFF0000L;
if(b == 0) if(b == 0)
return 0; return 0;
return bitno(b) - 16 + D_X0; return bitno(b) - 16 + REG_X0;
} }
void void
......
...@@ -772,100 +772,96 @@ enum ...@@ -772,100 +772,96 @@ enum
enum enum
{ {
REG_NONE = 0,
REG_AL = 0+16,
REG_CL,
REG_DL,
REG_BL,
REG_SPB,
REG_BPB,
REG_SIB,
REG_DIB,
REG_R8B,
REG_R9B,
REG_R10B,
REG_R11B,
REG_R12B,
REG_R13B,
REG_R14B,
REG_R15B,
REG_AX = 16+16,
REG_CX,
REG_DX,
REG_BX,
REG_SP,
REG_BP,
REG_SI,
REG_DI,
REG_R8,
REG_R9,
REG_R10,
REG_R11,
REG_R12,
REG_R13,
REG_R14,
REG_R15,
REG_AH = 32+16,
REG_CH,
REG_DH,
REG_BH,
REG_F0 = 36+16,
REG_M0 = 44+16,
REG_X0 = 52+16,
REG_X1,
REG_X2,
REG_X3,
REG_X4,
REG_X5,
REG_X6,
REG_X7,
REG_X8,
REG_X9,
REG_X10,
REG_X11,
REG_X12,
REG_X13,
REG_X14,
REG_X15,
REG_CS = 68+16,
REG_SS,
REG_DS,
REG_ES,
REG_FS,
REG_GS,
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 */
REG_CR = 79+16,
REG_DR = 95+16,
REG_TR = 103+16,
REG_TLS = 111+16,
MAXREG,
D_AL = 0, REGARG = -1,
D_CL, REGRET = REG_AX,
D_DL, FREGRET = REG_X0,
D_BL, REGSP = REG_SP,
D_SPB, REGTMP = REG_DI,
D_BPB, REGEXT = REG_R15, /* compiler allocates external registers R15 down */
D_SIB, FREGMIN = REG_X0+5, /* first register variable */
D_DIB, FREGEXT = REG_X0+15, /* first external register */
D_R8B,
D_R9B,
D_R10B,
D_R11B,
D_R12B,
D_R13B,
D_R14B,
D_R15B,
D_AX = 16,
D_CX,
D_DX,
D_BX,
D_SP,
D_BP,
D_SI,
D_DI,
D_R8,
D_R9,
D_R10,
D_R11,
D_R12,
D_R13,
D_R14,
D_R15,
D_AH = 32,
D_CH,
D_DH,
D_BH,
D_F0 = 36,
D_M0 = 44,
D_X0 = 52,
D_X1,
D_X2,
D_X3,
D_X4,
D_X5,
D_X6,
D_X7,
D_X8,
D_X9,
D_X10,
D_X11,
D_X12,
D_X13,
D_X14,
D_X15,
D_CS = 68,
D_SS,
D_DS,
D_ES,
D_FS,
D_GS,
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 */
D_CR = 79,
D_DR = 95,
D_TR = 103,
D_TLS = 111,
D_NONE = 112,
D_BRANCH = 113,
D_EXTERN = 114,
D_STATIC = 115,
D_AUTO = 116,
D_PARAM = 117,
D_CONST = 118,
D_FCONST = 119,
D_SCONST = 120,
D_ADDR = 121,
D_INDIR, /* additive */
D_LAST,
T_TYPE = 1<<0, T_TYPE = 1<<0,
T_INDEX = 1<<1, T_INDEX = 1<<1,
...@@ -875,15 +871,6 @@ enum ...@@ -875,15 +871,6 @@ enum
T_SCONST = 1<<5, T_SCONST = 1<<5,
T_64 = 1<<6, T_64 = 1<<6,
T_GOTYPE = 1<<7, T_GOTYPE = 1<<7,
REGARG = -1,
REGRET = D_AX,
FREGRET = D_X0,
REGSP = D_SP,
REGTMP = D_DI,
REGEXT = D_R15, /* compiler allocates external registers R15 down */
FREGMIN = D_X0+5, /* first register variable */
FREGEXT = D_X0+15 /* first external register */
}; };
/* /*
......
This diff is collapsed.
...@@ -122,41 +122,31 @@ Dconv(Fmt *fp) ...@@ -122,41 +122,31 @@ Dconv(Fmt *fp)
{ {
char str[STRINGSZ], s[STRINGSZ]; char str[STRINGSZ], s[STRINGSZ];
Addr *a; Addr *a;
int i;
a = va_arg(fp->args, Addr*); a = va_arg(fp->args, Addr*);
i = a->type;
if(fp->flags & FmtLong) {
if(i == D_CONST)
sprint(str, "$%lld-%lld", a->offset&0xffffffffLL, a->offset>>32);
else {
// ATEXT dst is not constant
sprint(str, "!!%D", a);
}
goto brk;
}
if(i >= D_INDIR) { switch(a->type) {
if(a->offset)
sprint(str, "%lld(%R)", a->offset, i-D_INDIR);
else
sprint(str, "(%R)", i-D_INDIR);
goto brk;
}
switch(i) {
default: default:
if(a->offset) sprint(str, "type=%d", a->type);
sprint(str, "$%lld,%R", a->offset, i);
else
sprint(str, "%R", i);
break; break;
case D_NONE: case TYPE_NONE:
str[0] = 0; str[0] = 0;
break; break;
case D_BRANCH: 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);
break;
case TYPE_BRANCH:
if(a->sym != nil) if(a->sym != nil)
sprint(str, "%s(SB)", a->sym->name); sprint(str, "%s(SB)", a->sym->name);
else if(bigP != nil && bigP->pcond != nil) else if(bigP != nil && bigP->pcond != nil)
...@@ -167,54 +157,71 @@ Dconv(Fmt *fp) ...@@ -167,54 +157,71 @@ Dconv(Fmt *fp)
sprint(str, "%lld(PC)", a->offset); sprint(str, "%lld(PC)", a->offset);
break; break;
case D_EXTERN: 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); sprint(str, "%s+%lld(SB)", a->sym->name, a->offset);
break; break;
case NAME_STATIC:
case D_STATIC:
sprint(str, "%s<>+%lld(SB)", a->sym->name, a->offset); sprint(str, "%s<>+%lld(SB)", a->sym->name, a->offset);
break; break;
case NAME_AUTO:
case D_AUTO:
if(a->sym) if(a->sym)
sprint(str, "%s+%lld(SP)", a->sym->name, a->offset); sprint(str, "%s+%lld(SP)", a->sym->name, a->offset);
else else
sprint(str, "%lld(SP)", a->offset); sprint(str, "%lld(SP)", a->offset);
break; break;
case NAME_PARAM:
case D_PARAM:
if(a->sym) if(a->sym)
sprint(str, "%s+%lld(FP)", a->sym->name, a->offset); sprint(str, "%s+%lld(FP)", a->sym->name, a->offset);
else else
sprint(str, "%lld(FP)", a->offset); sprint(str, "%lld(FP)", a->offset);
break; break;
}
if(a->index != REG_NONE) {
sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
strcat(str, s);
}
break;
case D_CONST: case TYPE_CONST:
if(fp->flags & FmtLong) {
sprint(str, "$%lld-%lld", a->offset&0xffffffffLL, a->offset>>32);
break;
}
sprint(str, "$%lld", a->offset); 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; break;
case D_FCONST: case TYPE_FCONST:
sprint(str, "$(%.17g)", a->u.dval); sprint(str, "$(%.17g)", a->u.dval);
break; break;
case D_SCONST: case TYPE_SCONST:
sprint(str, "$\"%$\"", a->u.sval); sprint(str, "$\"%$\"", a->u.sval);
break; break;
case D_ADDR: case TYPE_ADDR:
a->type = a->index; a->type = TYPE_MEM;
a->index = D_NONE;
sprint(str, "$%D", a); sprint(str, "$%D", a);
a->index = a->type; a->type = TYPE_ADDR;
a->type = D_ADDR; break;
goto conv;
}
brk:
if(a->index != D_NONE) {
sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
strcat(str, s);
} }
conv:
return fmtstrcpy(fp, str); return fmtstrcpy(fp, str);
} }
...@@ -343,7 +350,7 @@ static char* regstr[] = ...@@ -343,7 +350,7 @@ static char* regstr[] =
"TR7", "TR7",
"TLS", /* [D_TLS] */ "TLS", /* [D_TLS] */
"NONE", /* [D_NONE] */ "MAXREG", /* [MAXREG] */
}; };
static int static int
...@@ -353,8 +360,11 @@ Rconv(Fmt *fp) ...@@ -353,8 +360,11 @@ Rconv(Fmt *fp)
int r; int r;
r = va_arg(fp->args, int); r = va_arg(fp->args, int);
if(r >= D_AL && r <= D_NONE) if(r == REG_NONE)
sprint(str, "%s", regstr[r-D_AL]); return fmtstrcpy(fp, "NONE");
if(REG_AL <= r && r-REG_AL < nelem(regstr))
sprint(str, "%s", regstr[r-REG_AL]);
else else
sprint(str, "gok(%d)", r); sprint(str, "gok(%d)", r);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment