Commit 0d599909 authored by Russ Cox's avatar Russ Cox

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

Change-Id: I06762d4fb3bb2616087339b6ae1eb5267a39c46a
Reviewed-on: https://go-review.googlesource.com/3516Reviewed-by: default avatarAustin Clements <austin@google.com>
parent 5a2771e2
...@@ -111,53 +111,53 @@ inst: ...@@ -111,53 +111,53 @@ inst:
} }
| LTYPE1 cond imsr ',' reg | LTYPE1 cond imsr ',' reg
{ {
outcode($1, $2, &$3, NREG, &$5); outcode($1, $2, &$3, 0, &$5);
} }
/* /*
* MVN * MVN
*/ */
| LTYPE2 cond imsr ',' reg | LTYPE2 cond imsr ',' reg
{ {
outcode($1, $2, &$3, NREG, &$5); outcode($1, $2, &$3, 0, &$5);
} }
/* /*
* MOVW * MOVW
*/ */
| LTYPE3 cond gen ',' gen | LTYPE3 cond gen ',' gen
{ {
outcode($1, $2, &$3, NREG, &$5); outcode($1, $2, &$3, 0, &$5);
} }
/* /*
* B/BL * B/BL
*/ */
| LTYPE4 cond comma rel | LTYPE4 cond comma rel
{ {
outcode($1, $2, &nullgen, NREG, &$4); outcode($1, $2, &nullgen, 0, &$4);
} }
| LTYPE4 cond comma nireg | LTYPE4 cond comma nireg
{ {
outcode($1, $2, &nullgen, NREG, &$4); outcode($1, $2, &nullgen, 0, &$4);
} }
/* /*
* BX * BX
*/ */
| LTYPEBX comma ireg | LTYPEBX comma ireg
{ {
outcode($1, Always, &nullgen, NREG, &$3); outcode($1, Always, &nullgen, 0, &$3);
} }
/* /*
* BEQ * BEQ
*/ */
| LTYPE5 comma rel | LTYPE5 comma rel
{ {
outcode($1, Always, &nullgen, NREG, &$3); outcode($1, Always, &nullgen, 0, &$3);
} }
/* /*
* SWI * SWI
*/ */
| LTYPE6 cond comma gen | LTYPE6 cond comma gen
{ {
outcode($1, $2, &nullgen, NREG, &$4); outcode($1, $2, &nullgen, 0, &$4);
} }
/* /*
* CMP * CMP
...@@ -174,18 +174,18 @@ inst: ...@@ -174,18 +174,18 @@ inst:
Addr g; Addr g;
g = nullgen; g = nullgen;
g.type = D_CONST; g.type = TYPE_CONST;
g.offset = $6; g.offset = $6;
outcode($1, $2, &$3, NREG, &g); outcode($1, $2, &$3, 0, &g);
} }
| LTYPE8 cond '[' reglist ']' ',' ioreg | LTYPE8 cond '[' reglist ']' ',' ioreg
{ {
Addr g; Addr g;
g = nullgen; g = nullgen;
g.type = D_CONST; g.type = TYPE_CONST;
g.offset = $4; g.offset = $4;
outcode($1, $2, &g, NREG, &$7); outcode($1, $2, &g, 0, &$7);
} }
/* /*
* SWAP * SWAP
...@@ -207,7 +207,7 @@ inst: ...@@ -207,7 +207,7 @@ inst:
*/ */
| LTYPEA cond comma | LTYPEA cond comma
{ {
outcode($1, $2, &nullgen, NREG, &nullgen); outcode($1, $2, &nullgen, 0, &nullgen);
} }
/* /*
* TEXT/GLOBL * TEXT/GLOBL
...@@ -215,22 +215,22 @@ inst: ...@@ -215,22 +215,22 @@ inst:
| LTYPEB name ',' imm | LTYPEB name ',' imm
{ {
settext($2.sym); settext($2.sym);
$4.type = D_CONST2; $4.type = TYPE_TEXTSIZE;
$4.offset2 = ArgsSizeUnknown; $4.u.argsize = ArgsSizeUnknown;
outcode($1, Always, &$2, 0, &$4); outcode($1, Always, &$2, 0, &$4);
} }
| LTYPEB name ',' con ',' imm | LTYPEB name ',' con ',' imm
{ {
settext($2.sym); settext($2.sym);
$6.type = D_CONST2; $6.type = TYPE_TEXTSIZE;
$6.offset2 = ArgsSizeUnknown; $6.u.argsize = ArgsSizeUnknown;
outcode($1, Always, &$2, $4, &$6); outcode($1, Always, &$2, $4, &$6);
} }
| LTYPEB name ',' con ',' imm '-' con | LTYPEB name ',' con ',' imm '-' con
{ {
settext($2.sym); settext($2.sym);
$6.type = D_CONST2; $6.type = TYPE_TEXTSIZE;
$6.offset2 = $8; $6.u.argsize = $8;
outcode($1, Always, &$2, $4, &$6); outcode($1, Always, &$2, $4, &$6);
} }
/* /*
...@@ -245,25 +245,25 @@ inst: ...@@ -245,25 +245,25 @@ inst:
*/ */
| LTYPED cond reg comma | LTYPED cond reg comma
{ {
outcode($1, $2, &$3, NREG, &nullgen); outcode($1, $2, &$3, 0, &nullgen);
} }
/* /*
* word * word
*/ */
| LTYPEH comma ximm | LTYPEH comma ximm
{ {
outcode($1, Always, &nullgen, NREG, &$3); outcode($1, Always, &nullgen, 0, &$3);
} }
/* /*
* floating-point coprocessor * floating-point coprocessor
*/ */
| LTYPEI cond freg ',' freg | LTYPEI cond freg ',' freg
{ {
outcode($1, $2, &$3, NREG, &$5); outcode($1, $2, &$3, 0, &$5);
} }
| LTYPEK cond frcon ',' freg | LTYPEK cond frcon ',' freg
{ {
outcode($1, $2, &$3, NREG, &$5); outcode($1, $2, &$3, 0, &$5);
} }
| LTYPEK cond frcon ',' LFREG ',' freg | LTYPEK cond frcon ',' LFREG ',' freg
{ {
...@@ -281,7 +281,7 @@ inst: ...@@ -281,7 +281,7 @@ inst:
Addr g; Addr g;
g = nullgen; g = nullgen;
g.type = D_CONST; g.type = TYPE_CONST;
g.offset = g.offset =
(0xe << 24) | /* opcode */ (0xe << 24) | /* opcode */
($1 << 20) | /* MCR/MRC */ ($1 << 20) | /* MCR/MRC */
...@@ -293,7 +293,7 @@ inst: ...@@ -293,7 +293,7 @@ inst:
(($11 & 15) << 0) | /* Crm */ (($11 & 15) << 0) | /* Crm */
(($12 & 7) << 5) | /* coprocessor information */ (($12 & 7) << 5) | /* coprocessor information */
(1<<4); /* must be set */ (1<<4); /* must be set */
outcode(AMRC, Always, &nullgen, NREG, &g); outcode(AMRC, Always, &nullgen, 0, &g);
} }
/* /*
* MULL r1,r2,(hi,lo) * MULL r1,r2,(hi,lo)
...@@ -308,7 +308,7 @@ inst: ...@@ -308,7 +308,7 @@ inst:
*/ */
| LTYPEN cond reg ',' reg ',' reg ',' spreg | LTYPEN cond reg ',' reg ',' reg ',' spreg
{ {
$7.type = D_REGREG2; $7.type = TYPE_REGREG2;
$7.offset = $9; $7.offset = $9;
outcode($1, $2, &$3, $5.reg, &$7); outcode($1, $2, &$3, $5.reg, &$7);
} }
...@@ -317,34 +317,34 @@ inst: ...@@ -317,34 +317,34 @@ inst:
*/ */
| LTYPEPLD oreg | LTYPEPLD oreg
{ {
outcode($1, Always, &$2, NREG, &nullgen); outcode($1, Always, &$2, 0, &nullgen);
} }
/* /*
* PCDATA * PCDATA
*/ */
| LTYPEPC gen ',' gen | LTYPEPC gen ',' gen
{ {
if($2.type != D_CONST || $4.type != D_CONST) if($2.type != TYPE_CONST || $4.type != TYPE_CONST)
yyerror("arguments to PCDATA must be integer constants"); yyerror("arguments to PCDATA must be integer constants");
outcode($1, Always, &$2, NREG, &$4); outcode($1, Always, &$2, 0, &$4);
} }
/* /*
* FUNCDATA * FUNCDATA
*/ */
| LTYPEF gen ',' gen | LTYPEF gen ',' gen
{ {
if($2.type != D_CONST) if($2.type != TYPE_CONST)
yyerror("index for FUNCDATA must be integer constant"); yyerror("index for FUNCDATA must be integer constant");
if($4.type != D_EXTERN && $4.type != D_STATIC && $4.type != D_OREG) if($4.type != NAME_EXTERN && $4.type != NAME_STATIC && $4.type != TYPE_MEM)
yyerror("value for FUNCDATA must be symbol reference"); yyerror("value for FUNCDATA must be symbol reference");
outcode($1, Always, &$2, NREG, &$4); outcode($1, Always, &$2, 0, &$4);
} }
/* /*
* END * END
*/ */
| LTYPEE comma | LTYPEE comma
{ {
outcode($1, Always, &nullgen, NREG, &nullgen); outcode($1, Always, &nullgen, 0, &nullgen);
} }
cond: cond:
...@@ -367,7 +367,7 @@ rel: ...@@ -367,7 +367,7 @@ rel:
con '(' LPC ')' con '(' LPC ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_BRANCH; $$.type = TYPE_BRANCH;
$$.offset = $1 + pc; $$.offset = $1 + pc;
} }
| LNAME offset | LNAME offset
...@@ -376,30 +376,25 @@ rel: ...@@ -376,30 +376,25 @@ 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;
} }
ximm: '$' con ximm: '$' con
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_CONST; $$.type = TYPE_CONST;
$$.offset = $2; $$.offset = $2;
} }
| '$' oreg | '$' oreg
{ {
$$ = $2; $$ = $2;
$$.type = D_CONST; $$.type = TYPE_CONST;
}
| '$' '*' '$' oreg
{
$$ = $4;
$$.type = D_OCONST;
} }
| '$' LSCONST | '$' LSCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_SCONST; $$.type = TYPE_SCONST;
memcpy($$.u.sval, $2, sizeof($$.u.sval)); memcpy($$.u.sval, $2, sizeof($$.u.sval));
} }
| fcon | fcon
...@@ -408,13 +403,13 @@ fcon: ...@@ -408,13 +403,13 @@ fcon:
'$' 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;
} }
...@@ -449,19 +444,19 @@ gen: ...@@ -449,19 +444,19 @@ gen:
| LPSR | LPSR
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_PSR; $$.type = TYPE_REG;
$$.reg = $1; $$.reg = $1;
} }
| LFCR | LFCR
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FPCR; $$.type = TYPE_REG;
$$.reg = $1; $$.reg = $1;
} }
| con | con
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_OREG; $$.type = TYPE_MEM;
$$.offset = $1; $$.offset = $1;
} }
| oreg | oreg
...@@ -472,7 +467,7 @@ nireg: ...@@ -472,7 +467,7 @@ nireg:
| name | name
{ {
$$ = $1; $$ = $1;
if($1.name != D_EXTERN && $1.name != D_STATIC) { if($1.name != NAME_EXTERN && $1.name != NAME_STATIC) {
} }
} }
...@@ -480,7 +475,7 @@ ireg: ...@@ -480,7 +475,7 @@ ireg:
'(' spreg ')' '(' spreg ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_OREG; $$.type = TYPE_MEM;
$$.reg = $2; $$.reg = $2;
$$.offset = 0; $$.offset = 0;
} }
...@@ -490,7 +485,7 @@ ioreg: ...@@ -490,7 +485,7 @@ ioreg:
| con '(' sreg ')' | con '(' sreg ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_OREG; $$.type = TYPE_MEM;
$$.reg = $3; $$.reg = $3;
$$.offset = $1; $$.offset = $1;
} }
...@@ -500,7 +495,7 @@ oreg: ...@@ -500,7 +495,7 @@ oreg:
| name '(' sreg ')' | name '(' sreg ')'
{ {
$$ = $1; $$ = $1;
$$.type = D_OREG; $$.type = TYPE_MEM;
$$.reg = $3; $$.reg = $3;
} }
| ioreg | ioreg
...@@ -513,7 +508,7 @@ imsr: ...@@ -513,7 +508,7 @@ imsr:
imm: '$' con imm: '$' con
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_CONST; $$.type = TYPE_CONST;
$$.offset = $2; $$.offset = $2;
} }
...@@ -521,7 +516,7 @@ reg: ...@@ -521,7 +516,7 @@ reg:
spreg spreg
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_REG; $$.type = TYPE_REG;
$$.reg = $1; $$.reg = $1;
} }
...@@ -529,7 +524,7 @@ regreg: ...@@ -529,7 +524,7 @@ regreg:
'(' spreg ',' spreg ')' '(' spreg ',' spreg ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_REGREG; $$.type = TYPE_REGREG;
$$.reg = $2; $$.reg = $2;
$$.offset = $4; $$.offset = $4;
} }
...@@ -538,33 +533,33 @@ shift: ...@@ -538,33 +533,33 @@ shift:
spreg '<' '<' rcon spreg '<' '<' rcon
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_SHIFT; $$.type = TYPE_SHIFT;
$$.offset = $1 | $4 | (0 << 5); $$.offset = $1&15 | $4 | (0 << 5);
} }
| spreg '>' '>' rcon | spreg '>' '>' rcon
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_SHIFT; $$.type = TYPE_SHIFT;
$$.offset = $1 | $4 | (1 << 5); $$.offset = $1&15 | $4 | (1 << 5);
} }
| spreg '-' '>' rcon | spreg '-' '>' rcon
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_SHIFT; $$.type = TYPE_SHIFT;
$$.offset = $1 | $4 | (2 << 5); $$.offset = $1&15 | $4 | (2 << 5);
} }
| spreg LAT '>' rcon | spreg LAT '>' rcon
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_SHIFT; $$.type = TYPE_SHIFT;
$$.offset = $1 | $4 | (3 << 5); $$.offset = $1&15 | $4 | (3 << 5);
} }
rcon: rcon:
spreg spreg
{ {
if($$ < 0 || $$ >= 16) if($$ < REG_R0 || $$ > REG_R15)
print("register value out of range\n"); print("register value out of range in shift\n");
$$ = (($1&15) << 8) | (1 << 4); $$ = (($1&15) << 8) | (1 << 4);
} }
| con | con
...@@ -583,8 +578,8 @@ sreg: ...@@ -583,8 +578,8 @@ sreg:
| LR '(' expr ')' | LR '(' expr ')'
{ {
if($3 < 0 || $3 >= NREG) if($3 < 0 || $3 >= NREG)
print("register value out of range\n"); print("register value out of range in R(...)\n");
$$ = $3; $$ = REG_R0 + $3;
} }
spreg: spreg:
...@@ -599,8 +594,8 @@ creg: ...@@ -599,8 +594,8 @@ creg:
| LC '(' expr ')' | LC '(' expr ')'
{ {
if($3 < 0 || $3 >= NREG) if($3 < 0 || $3 >= NREG)
print("register value out of range\n"); print("register value out of range in C(...)\n");
$$ = $3; $$ = $3; // TODO(rsc): REG_C0+$3
} }
frcon: frcon:
...@@ -611,21 +606,21 @@ freg: ...@@ -611,21 +606,21 @@ freg:
LFREG LFREG
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FREG; $$.type = TYPE_REG;
$$.reg = $1; $$.reg = $1;
} }
| LF '(' con ')' | LF '(' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FREG; $$.type = TYPE_REG;
$$.reg = $3; $$.reg = REG_F0 + $3;
} }
name: name:
con '(' pointer ')' con '(' pointer ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_OREG; $$.type = TYPE_MEM;
$$.name = $3; $$.name = $3;
$$.sym = nil; $$.sym = nil;
$$.offset = $1; $$.offset = $1;
...@@ -633,7 +628,7 @@ name: ...@@ -633,7 +628,7 @@ name:
| LNAME offset '(' pointer ')' | LNAME offset '(' pointer ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_OREG; $$.type = TYPE_MEM;
$$.name = $4; $$.name = $4;
$$.sym = linklookup(ctxt, $1->name, 0); $$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2; $$.offset = $2;
...@@ -641,8 +636,8 @@ name: ...@@ -641,8 +636,8 @@ name:
| LNAME '<' '>' offset '(' LSB ')' | LNAME '<' '>' offset '(' LSB ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_OREG; $$.type = TYPE_MEM;
$$.name = D_STATIC; $$.name = NAME_STATIC;
$$.sym = linklookup(ctxt, $1->name, 1); $$.sym = linklookup(ctxt, $1->name, 1);
$$.offset = $4; $$.offset = $4;
} }
......
...@@ -187,47 +187,48 @@ struct ...@@ -187,47 +187,48 @@ 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, "PC", LPC, TYPE_BRANCH,
"R", LR, 0, "R", LR, REG_F0,
"R0", LREG, 0,
"R1", LREG, 1, "R0", LREG, REG_R0,
"R2", LREG, 2, "R1", LREG, REG_R1,
"R3", LREG, 3, "R2", LREG, REG_R2,
"R4", LREG, 4, "R3", LREG, REG_R3,
"R5", LREG, 5, "R4", LREG, REG_R4,
"R6", LREG, 6, "R5", LREG, REG_R5,
"R7", LREG, 7, "R6", LREG, REG_R6,
"R8", LREG, 8, "R7", LREG, REG_R7,
"R9", LREG, 9, "R8", LREG, REG_R8,
"g", LREG, 10, // avoid unintentionally clobber g using R10 "R9", LREG, REG_R9,
"R11", LREG, 11, "g", LREG, REG_R10, // avoid unintentionally clobber g using R10
"R12", LREG, 12, "R11", LREG, REG_R11,
"R13", LREG, 13, "R12", LREG, REG_R12,
"R14", LREG, 14, "R13", LREG, REG_R13,
"R15", LREG, 15, "R14", LREG, REG_R14,
"R15", LREG, REG_R15,
"F", LF, 0,
"F", LF, REG_F0,
"F0", LFREG, 0,
"F1", LFREG, 1, "F0", LFREG, REG_F0,
"F2", LFREG, 2, "F1", LFREG, REG_F1,
"F3", LFREG, 3, "F2", LFREG, REG_F2,
"F4", LFREG, 4, "F3", LFREG, REG_F3,
"F5", LFREG, 5, "F4", LFREG, REG_F4,
"F6", LFREG, 6, "F5", LFREG, REG_F5,
"F7", LFREG, 7, "F6", LFREG, REG_F6,
"F8", LFREG, 8, "F7", LFREG, REG_F7,
"F9", LFREG, 9, "F8", LFREG, REG_F8,
"F10", LFREG, 10, "F9", LFREG, REG_F9,
"F11", LFREG, 11, "F10", LFREG, REG_F10,
"F12", LFREG, 12, "F11", LFREG, REG_F11,
"F13", LFREG, 13, "F12", LFREG, REG_F12,
"F14", LFREG, 14, "F13", LFREG, REG_F13,
"F15", LFREG, 15, "F14", LFREG, REG_F14,
"F15", LFREG, REG_F15,
"C", LC, 0, "C", LC, 0,
...@@ -248,11 +249,11 @@ struct ...@@ -248,11 +249,11 @@ struct
"C14", LCREG, 14, "C14", LCREG, 14,
"C15", LCREG, 15, "C15", LCREG, 15,
"CPSR", LPSR, 0, "CPSR", LPSR, REG_CPSR,
"SPSR", LPSR, 1, "SPSR", LPSR, REG_SPSR,
"FPSR", LFCR, 0, "FPSR", LFCR, REG_FPSR,
"FPCR", LFCR, 1, "FPCR", LFCR, REG_FPCR,
".EQ", LCOND, 0, ".EQ", LCOND, 0,
".NE", LCOND, 1, ".NE", LCOND, 1,
...@@ -437,9 +438,8 @@ cinit(void) ...@@ -437,9 +438,8 @@ cinit(void)
Sym *s; Sym *s;
int i; int i;
nullgen.type = D_NONE; nullgen.type = TYPE_NONE;
nullgen.name = D_NONE; nullgen.name = NAME_NONE;
nullgen.reg = NREG;
nerrors = 0; nerrors = 0;
iostack = I; iostack = I;
...@@ -474,7 +474,7 @@ isreg(Addr *g) ...@@ -474,7 +474,7 @@ isreg(Addr *g)
void void
cclean(void) cclean(void)
{ {
outcode(AEND, Always, &nullgen, NREG, &nullgen); outcode(AEND, Always, &nullgen, 0, &nullgen);
} }
static int bcode[] = static int bcode[] =
......
...@@ -436,16 +436,16 @@ union yyalloc ...@@ -436,16 +436,16 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */ /* YYFINAL -- State number of the termination state. */
#define YYFINAL 2 #define YYFINAL 2
/* YYLAST -- Last index in YYTABLE. */ /* YYLAST -- Last index in YYTABLE. */
#define YYLAST 640 #define YYLAST 624
/* YYNTOKENS -- Number of terminals. */ /* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 71 #define YYNTOKENS 71
/* YYNNTS -- Number of nonterminals. */ /* YYNNTS -- Number of nonterminals. */
#define YYNNTS 34 #define YYNNTS 34
/* YYNRULES -- Number of rules. */ /* YYNRULES -- Number of rules. */
#define YYNRULES 130 #define YYNRULES 129
/* YYNRULES -- Number of states. */ /* YYNRULES -- Number of states. */
#define YYNSTATES 333 #define YYNSTATES 330
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2 #define YYUNDEFTOK 2
...@@ -500,15 +500,14 @@ static const yytype_uint16 yyprhs[] = ...@@ -500,15 +500,14 @@ static const yytype_uint16 yyprhs[] =
80, 84, 89, 96, 104, 112, 120, 127, 134, 138, 80, 84, 89, 96, 104, 112, 120, 127, 134, 138,
143, 150, 159, 166, 171, 175, 181, 187, 195, 202, 143, 150, 159, 166, 171, 175, 181, 187, 195, 202,
215, 223, 233, 236, 241, 246, 249, 250, 253, 256, 215, 223, 233, 236, 241, 246, 249, 250, 253, 256,
257, 260, 265, 268, 271, 274, 279, 282, 284, 287, 257, 260, 265, 268, 271, 274, 277, 279, 282, 286,
291, 293, 297, 301, 303, 305, 307, 312, 314, 316, 288, 292, 296, 298, 300, 302, 307, 309, 311, 313,
318, 320, 322, 324, 326, 330, 332, 337, 339, 344, 315, 317, 319, 321, 325, 327, 332, 334, 339, 341,
346, 348, 350, 352, 355, 357, 363, 368, 373, 378, 343, 345, 347, 350, 352, 358, 363, 368, 373, 378,
383, 385, 387, 389, 391, 396, 398, 400, 402, 407, 380, 382, 384, 386, 391, 393, 395, 397, 402, 404,
409, 411, 413, 418, 423, 429, 437, 438, 441, 444, 406, 408, 413, 418, 424, 432, 433, 436, 439, 441,
446, 448, 450, 452, 454, 457, 460, 463, 467, 468, 443, 445, 447, 449, 452, 455, 458, 462, 463, 466,
471, 473, 477, 481, 485, 489, 493, 498, 503, 507, 468, 472, 476, 480, 484, 488, 493, 498, 502, 506
511
}; };
/* YYRHS -- A `-1'-separated list of the rules' RHS. */ /* YYRHS -- A `-1'-separated list of the rules' RHS. */
...@@ -541,31 +540,30 @@ static const yytype_int8 yyrhs[] = ...@@ -541,31 +540,30 @@ static const yytype_int8 yyrhs[] =
-1, 44, 83, 64, 83, -1, 26, 78, -1, -1, -1, 44, 83, 64, 83, -1, 26, 78, -1, -1,
77, 53, -1, 77, 54, -1, -1, 64, 78, -1, 77, 53, -1, 77, 54, -1, -1, 64, 78, -1,
102, 67, 41, 68, -1, 58, 100, -1, 69, 102, 102, 67, 41, 68, -1, 58, 100, -1, 69, 102,
-1, 69, 87, -1, 69, 10, 69, 87, -1, 69, -1, 69, 87, -1, 69, 57, -1, 81, -1, 69,
57, -1, 81, -1, 69, 56, -1, 69, 9, 56, 56, -1, 69, 9, 56, -1, 95, -1, 95, 9,
-1, 95, -1, 95, 9, 95, -1, 95, 78, 82, 95, -1, 95, 78, 82, -1, 90, -1, 80, -1,
-1, 90, -1, 80, -1, 92, -1, 92, 67, 95, 92, -1, 92, 67, 95, 68, -1, 51, -1, 52,
68, -1, 51, -1, 52, -1, 102, -1, 87, -1, -1, 102, -1, 87, -1, 98, -1, 85, -1, 99,
98, -1, 85, -1, 99, -1, 67, 95, 68, -1, -1, 67, 95, 68, -1, 85, -1, 102, 67, 94,
85, -1, 102, 67, 94, 68, -1, 99, -1, 99, 68, -1, 99, -1, 99, 67, 94, 68, -1, 86,
67, 94, 68, -1, 86, -1, 90, -1, 89, -1, -1, 90, -1, 89, -1, 92, -1, 69, 102, -1,
92, -1, 69, 102, -1, 95, -1, 67, 95, 64, 95, -1, 67, 95, 64, 95, 68, -1, 95, 6,
95, 68, -1, 95, 6, 6, 93, -1, 95, 7, 6, 93, -1, 95, 7, 7, 93, -1, 95, 9,
7, 93, -1, 95, 9, 7, 93, -1, 95, 55, 7, 93, -1, 95, 55, 7, 93, -1, 95, -1,
7, 93, -1, 95, -1, 102, -1, 46, -1, 41, 102, -1, 46, -1, 41, -1, 45, 67, 104, 68,
-1, 45, 67, 104, 68, -1, 94, -1, 38, -1, -1, 94, -1, 38, -1, 50, -1, 49, 67, 104,
50, -1, 49, 67, 104, 68, -1, 98, -1, 81, 68, -1, 98, -1, 81, -1, 48, -1, 47, 67,
-1, 48, -1, 47, 67, 102, 68, -1, 102, 67, 102, 68, -1, 102, 67, 101, 68, -1, 58, 100,
101, 68, -1, 58, 100, 67, 101, 68, -1, 58, 67, 101, 68, -1, 58, 6, 7, 100, 67, 39,
6, 7, 100, 67, 39, 68, -1, -1, 8, 102, 68, -1, -1, 8, 102, -1, 9, 102, -1, 39,
-1, 9, 102, -1, 39, -1, 38, -1, 40, -1, -1, 38, -1, 40, -1, 37, -1, 60, -1, 9,
37, -1, 60, -1, 9, 102, -1, 8, 102, -1, 102, -1, 8, 102, -1, 70, 102, -1, 67, 104,
70, 102, -1, 67, 104, 68, -1, -1, 64, 104, 68, -1, -1, 64, 104, -1, 102, -1, 104, 8,
-1, 102, -1, 104, 8, 104, -1, 104, 9, 104, 104, -1, 104, 9, 104, -1, 104, 10, 104, -1,
-1, 104, 10, 104, -1, 104, 11, 104, -1, 104, 104, 11, 104, -1, 104, 12, 104, -1, 104, 6,
12, 104, -1, 104, 6, 6, 104, -1, 104, 7, 6, 104, -1, 104, 7, 7, 104, -1, 104, 5,
7, 104, -1, 104, 5, 104, -1, 104, 4, 104, 104, -1, 104, 4, 104, -1, 104, 3, 104, -1
-1, 104, 3, 104, -1
}; };
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
...@@ -576,15 +574,14 @@ static const yytype_uint16 yyrline[] = ...@@ -576,15 +574,14 @@ static const yytype_uint16 yyrline[] =
151, 158, 165, 172, 181, 193, 197, 201, 208, 215, 151, 158, 165, 172, 181, 193, 197, 201, 208, 215,
222, 229, 239, 246, 253, 260, 264, 268, 272, 279, 222, 229, 239, 246, 253, 260, 264, 268, 272, 279,
301, 309, 318, 325, 334, 345, 351, 354, 358, 363, 301, 309, 318, 325, 334, 345, 351, 354, 358, 363,
364, 367, 373, 383, 389, 394, 399, 405, 408, 414, 364, 367, 373, 383, 389, 394, 400, 403, 409, 417,
422, 426, 435, 441, 442, 443, 444, 449, 455, 461, 421, 430, 436, 437, 438, 439, 444, 450, 456, 462,
467, 468, 471, 472, 480, 489, 490, 499, 500, 506, 463, 466, 467, 475, 484, 485, 494, 495, 501, 504,
509, 510, 511, 513, 521, 529, 538, 544, 550, 556, 505, 506, 508, 516, 524, 533, 539, 545, 551, 559,
564, 570, 578, 579, 583, 591, 592, 598, 599, 607, 565, 573, 574, 578, 586, 587, 593, 594, 602, 603,
608, 611, 617, 625, 633, 641, 651, 654, 658, 664, 606, 612, 620, 628, 636, 646, 649, 653, 659, 660,
665, 666, 669, 670, 674, 678, 682, 686, 692, 695, 661, 664, 665, 669, 673, 677, 681, 687, 690, 696,
701, 702, 706, 710, 714, 718, 722, 726, 730, 734, 697, 701, 705, 709, 713, 717, 721, 725, 729, 733
738
}; };
#endif #endif
...@@ -633,15 +630,14 @@ static const yytype_uint8 yyr1[] = ...@@ -633,15 +630,14 @@ static const yytype_uint8 yyr1[] =
76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
76, 76, 76, 76, 76, 76, 77, 77, 77, 78, 76, 76, 76, 76, 76, 76, 77, 77, 77, 78,
78, 79, 79, 80, 80, 80, 80, 80, 81, 81, 78, 79, 79, 80, 80, 80, 80, 81, 81, 82,
82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83,
83, 83, 84, 84, 85, 86, 86, 87, 87, 87, 83, 84, 84, 85, 86, 86, 87, 87, 87, 88,
88, 88, 88, 89, 90, 91, 92, 92, 92, 92, 88, 88, 89, 90, 91, 92, 92, 92, 92, 93,
93, 93, 94, 94, 94, 95, 95, 96, 96, 97, 93, 94, 94, 94, 95, 95, 96, 96, 97, 97,
97, 98, 98, 99, 99, 99, 100, 100, 100, 101, 98, 98, 99, 99, 99, 100, 100, 100, 101, 101,
101, 101, 102, 102, 102, 102, 102, 102, 103, 103, 101, 102, 102, 102, 102, 102, 102, 103, 103, 104,
104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104
104
}; };
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
...@@ -652,15 +648,14 @@ static const yytype_uint8 yyr2[] = ...@@ -652,15 +648,14 @@ static const yytype_uint8 yyr2[] =
3, 4, 6, 7, 7, 7, 6, 6, 3, 4, 3, 4, 6, 7, 7, 7, 6, 6, 3, 4,
6, 8, 6, 4, 3, 5, 5, 7, 6, 12, 6, 8, 6, 4, 3, 5, 5, 7, 6, 12,
7, 9, 2, 4, 4, 2, 0, 2, 2, 0, 7, 9, 2, 4, 4, 2, 0, 2, 2, 0,
2, 4, 2, 2, 2, 4, 2, 1, 2, 3, 2, 4, 2, 2, 2, 2, 1, 2, 3, 1,
1, 3, 3, 1, 1, 1, 4, 1, 1, 1, 3, 3, 1, 1, 1, 4, 1, 1, 1, 1,
1, 1, 1, 1, 3, 1, 4, 1, 4, 1, 1, 1, 1, 3, 1, 4, 1, 4, 1, 1,
1, 1, 1, 2, 1, 5, 4, 4, 4, 4, 1, 1, 2, 1, 5, 4, 4, 4, 4, 1,
1, 1, 1, 1, 4, 1, 1, 1, 4, 1, 1, 1, 1, 4, 1, 1, 1, 4, 1, 1,
1, 1, 4, 4, 5, 7, 0, 2, 2, 1, 1, 4, 4, 5, 7, 0, 2, 2, 1, 1,
1, 1, 1, 1, 2, 2, 2, 3, 0, 2, 1, 1, 1, 2, 2, 2, 3, 0, 2, 1,
1, 3, 3, 3, 3, 3, 4, 4, 3, 3, 3, 3, 3, 3, 3, 4, 4, 3, 3, 3
3
}; };
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
...@@ -672,238 +667,232 @@ static const yytype_uint8 yydefact[] = ...@@ -672,238 +667,232 @@ static const yytype_uint8 yydefact[] =
46, 46, 46, 46, 46, 0, 0, 46, 49, 49, 46, 46, 46, 46, 46, 0, 0, 46, 49, 49,
46, 46, 46, 46, 46, 46, 49, 0, 0, 0, 46, 46, 46, 46, 46, 46, 49, 0, 0, 0,
0, 0, 9, 4, 0, 11, 0, 0, 0, 49, 0, 0, 9, 4, 0, 11, 0, 0, 0, 49,
49, 0, 49, 0, 0, 49, 49, 0, 0, 112, 49, 0, 49, 0, 0, 49, 49, 0, 0, 111,
106, 113, 0, 0, 0, 0, 0, 0, 45, 0, 105, 112, 0, 0, 0, 0, 0, 0, 45, 0,
0, 0, 0, 0, 0, 0, 0, 0, 75, 79, 0, 0, 0, 0, 0, 0, 0, 0, 74, 78,
42, 77, 0, 96, 93, 0, 92, 0, 101, 67, 42, 76, 0, 95, 92, 0, 91, 0, 100, 66,
68, 0, 64, 57, 0, 70, 63, 65, 95, 84, 67, 0, 63, 56, 0, 69, 62, 64, 94, 83,
71, 69, 0, 5, 0, 0, 10, 47, 48, 0, 70, 68, 0, 5, 0, 0, 10, 47, 48, 0,
0, 81, 80, 82, 0, 0, 0, 50, 106, 20, 0, 80, 79, 81, 0, 0, 0, 50, 105, 20,
0, 0, 0, 0, 0, 0, 0, 0, 84, 28, 0, 0, 0, 0, 0, 0, 0, 0, 83, 28,
115, 114, 0, 0, 0, 0, 120, 0, 116, 0, 114, 113, 0, 0, 0, 0, 119, 0, 115, 0,
0, 0, 49, 34, 0, 0, 0, 100, 0, 99, 0, 0, 49, 34, 0, 0, 0, 99, 0, 98,
0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0,
0, 0, 58, 56, 54, 53, 0, 0, 0, 0, 0, 57, 55, 54, 53, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 105,
106, 17, 18, 72, 73, 0, 52, 0, 21, 0, 17, 18, 71, 72, 0, 52, 0, 21, 0, 0,
0, 49, 0, 0, 0, 0, 106, 107, 108, 0, 49, 0, 0, 0, 0, 105, 106, 107, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116,
117, 29, 0, 110, 109, 111, 0, 0, 33, 0, 29, 0, 109, 108, 110, 0, 0, 33, 0, 0,
0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0,
0, 59, 0, 43, 0, 0, 0, 0, 0, 44, 58, 43, 0, 0, 0, 0, 0, 44, 6, 7,
6, 7, 8, 14, 84, 15, 16, 52, 0, 0, 8, 14, 83, 15, 16, 52, 0, 0, 49, 0,
49, 0, 0, 0, 0, 0, 49, 0, 0, 130, 0, 0, 0, 0, 49, 0, 0, 129, 128, 127,
129, 128, 0, 0, 121, 122, 123, 124, 125, 0, 0, 0, 120, 121, 122, 123, 124, 0, 102, 0,
103, 0, 35, 0, 101, 36, 49, 0, 0, 78, 35, 0, 100, 36, 49, 0, 0, 77, 75, 93,
76, 94, 102, 55, 66, 86, 90, 91, 87, 88, 101, 65, 85, 89, 90, 86, 87, 88, 13, 51,
89, 13, 51, 22, 0, 61, 62, 0, 27, 49, 22, 0, 60, 61, 0, 27, 49, 26, 0, 103,
26, 0, 104, 126, 127, 30, 32, 0, 0, 38, 125, 126, 30, 32, 0, 0, 38, 0, 0, 12,
0, 0, 12, 24, 23, 25, 0, 0, 0, 37, 24, 23, 25, 0, 0, 0, 37, 0, 40, 0,
0, 40, 0, 105, 31, 0, 0, 0, 0, 97, 104, 31, 0, 0, 0, 0, 96, 0, 0, 41,
0, 0, 41, 0, 0, 0, 0, 118, 85, 98, 0, 0, 0, 0, 117, 84, 97, 0, 39, 118
0, 39, 119
}; };
/* YYDEFGOTO[NTERM-NUM]. */ /* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int16 yydefgoto[] = static const yytype_int16 yydefgoto[] =
{ {
-1, 1, 3, 33, 163, 34, 36, 107, 109, 82, -1, 1, 3, 33, 162, 34, 36, 107, 109, 82,
83, 180, 84, 172, 68, 69, 85, 100, 101, 86, 83, 179, 84, 171, 68, 69, 85, 100, 101, 86,
311, 87, 275, 88, 118, 320, 138, 90, 71, 125, 308, 87, 272, 88, 118, 317, 138, 90, 71, 125,
206, 126, 331, 127 205, 126, 328, 127
}; };
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */ STATE-NUM. */
#define YYPACT_NINF -125 #define YYPACT_NINF -124
static const yytype_int16 yypact[] = static const yytype_int16 yypact[] =
{ {
-125, 7, -125, 308, -41, -125, -125, -125, -125, -19, -124, 5, -124, 329, -61, -124, -124, -124, -124, -57,
-125, -125, -125, -125, -125, 80, 80, -125, -19, -19, -124, -124, -124, -124, -124, 157, 157, -124, -57, -57,
-125, -125, -125, -125, -125, -125, -19, 405, 364, 364, -124, -124, -124, -124, -124, -124, -57, 264, 385, 385,
-31, -15, -125, -125, -2, -125, 528, 528, 337, -18, -31, -22, -124, -124, -12, -124, 512, 512, 358, -16,
-19, 409, -18, 528, 230, 187, -18, 448, 448, -125, -57, 268, -16, 512, 191, 337, -16, 432, 432, -124,
257, -125, 448, 448, -6, 15, 94, 309, -125, 49, 164, -124, 432, 432, 0, 9, 58, 450, -124, 15,
19, 44, 95, 19, 309, 309, 63, 391, -125, -125, 172, 49, 235, 172, 450, 450, 11, 34, -124, -124,
-125, 90, 137, -125, -125, 145, -125, 146, -125, -125, -124, 14, 21, -124, -124, 32, -124, 46, -124, -124,
-125, 66, -125, -125, 52, -125, -125, 150, -125, 147, -124, 87, -124, -124, 59, -124, -124, 69, -124, 91,
-125, 137, 57, -125, 448, 448, -125, -125, -125, 448, -124, 21, 75, -124, 432, 432, -124, -124, -124, 432,
167, -125, -125, -125, 184, 200, 431, -125, 47, -125, 85, -124, -124, -124, 129, 141, 405, -124, 37, -124,
201, 364, 217, 189, 223, 221, 63, 228, -125, -125, 84, 385, 147, 80, 152, 151, 11, 178, -124, -124,
-125, -125, 289, 448, 448, 231, -125, 181, -125, 411, -124, -124, 236, 432, 432, 180, -124, 173, -124, 411,
54, 448, -19, -125, 237, 238, 12, -125, 240, -125, 231, 432, -57, -124, 185, 186, 18, -124, 189, -124,
241, 244, 246, 189, -125, 245, 114, 319, 448, 448, 193, 200, 201, 80, -124, 199, 107, 471, 432, 432,
417, 243, -125, -125, -125, 137, 364, 189, 293, 312, 430, -124, -124, -124, 21, 385, 80, 269, 273, 274,
313, 341, 364, 308, 542, 552, -125, 189, 189, 364, 277, 385, 329, 526, 536, -124, 80, 80, 385, 164,
257, -125, -125, -125, -125, 282, -125, 315, -125, 189, -124, -124, -124, -124, 218, -124, 261, -124, 80, 243,
287, 42, 296, 114, 303, 63, 47, -125, -125, 54, 56, 260, 107, 263, 11, 37, -124, -124, 231, 432,
448, 448, 448, 363, 369, 448, 448, 448, 448, 448, 432, 432, 323, 326, 432, 432, 432, 432, 432, -124,
-125, -125, 306, -125, -125, -125, 311, 316, -125, 53, -124, 272, -124, -124, -124, 303, 276, -124, 44, 432,
448, 321, 65, 53, 189, 189, -125, 318, 324, 250, 281, 63, 44, 80, 80, -124, 306, 308, 288, 311,
325, -125, 405, -125, 326, 391, 391, 391, 391, -125, -124, -124, 312, 34, 34, 34, 34, -124, -124, -124,
-125, -125, -125, -125, 317, -125, -125, 231, 130, 328, -124, -124, 317, -124, -124, 180, 148, 316, -57, 321,
-19, 323, 189, 189, 189, 189, 334, 336, 340, 602, 80, 80, 80, 80, 322, 330, 320, 586, 605, 612,
621, 628, 448, 448, 197, 197, -125, -125, -125, 352, 432, 432, 296, 296, -124, -124, -124, 331, -124, 15,
-125, 49, -125, 516, 359, -125, -19, 366, 371, -125, -124, 516, 334, -124, -57, 338, 343, -124, -124, -124,
-125, -125, -125, -125, -125, -125, -125, -125, -125, -125, -124, -124, -124, -124, -124, -124, -124, -124, 80, -124,
-125, 189, -125, -125, 474, -125, -125, 361, -125, 165, -124, 448, -124, -124, 275, -124, 214, -124, 369, -124,
-125, 399, -125, 235, 235, 432, -125, 189, 53, -125, 225, 225, 406, -124, 80, 44, -124, 350, 80, -124,
376, 189, -125, -125, -125, -125, 377, 448, 380, -125, -124, -124, -124, 353, 432, 360, -124, 80, -124, 365,
189, -125, 383, -125, -125, 112, 385, 189, 386, -125, -124, -124, 82, 370, 80, 368, -124, 380, 80, -124,
388, 189, -125, 448, 112, 382, 267, 395, -125, -125, 432, 82, 378, 309, 383, -124, -124, 432, -124, 597
448, -125, 613
}; };
/* YYPGOTO[NTERM-NUM]. */ /* YYPGOTO[NTERM-NUM]. */
static const yytype_int16 yypgoto[] = static const yytype_int16 yypgoto[] =
{ {
-125, -125, -125, 292, -125, -125, 578, 45, 354, -56, -124, -124, -124, 287, -124, -124, 562, 10, 344, -55,
400, -48, -25, -125, -7, -42, -21, -5, -124, 5, 389, -19, 3, -124, -43, -41, -15, -17, -123, 25,
-125, -10, 89, -118, -28, 140, -125, -46, 4, -90, -124, 132, 144, -122, -28, 137, -124, -49, 2, -92,
277, -4, -125, -16 265, 6, -124, 12
}; };
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says. number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */ If YYTABLE_NINF, syntax error. */
#define YYTABLE_NINF -61 #define YYTABLE_NINF -60
static const yytype_int16 yytable[] = static const yytype_int16 yytable[] =
{ {
89, 89, 114, 133, 92, 201, 70, 2, 89, 89, 89, 89, 35, 114, 133, 2, 200, 40, 89, 89,
89, 55, 55, 105, 134, 89, 139, 140, 176, 54, 89, 134, 70, 139, 140, 89, 175, 54, 56, 41,
56, 211, 35, 72, 91, 91, 103, 103, 217, 218, 104, 55, 55, 144, 216, 217, 112, 210, 58, 59,
93, 94, 104, 103, 91, 97, 98, 110, 112, 145, 93, 94, 92, 72, 91, 91, 66, 97, 98, 145,
115, 102, 102, 120, 121, 40, 40, 95, 102, 128, 95, 105, 47, 48, 91, 123, 124, 110, 40, 106,
117, 242, 47, 48, 41, 123, 124, 135, 129, 144, 115, 96, 111, 120, 121, 116, 119, 47, 48, 128,
154, 96, 132, 58, 59, 218, 77, 78, 152, 141, 217, 102, 102, 172, 129, 240, 153, 135, 102, 131,
142, 66, 97, 98, 47, 150, 151, 155, 164, 165, 117, 49, 73, 183, 151, 74, 130, 235, 143, 75,
237, 49, 130, 89, 106, 181, 178, 111, 47, 48, 76, 146, 132, 89, 81, 180, 49, 154, 147, 141,
116, 119, 203, 204, 205, 166, 247, 97, 98, 173, 142, 77, 78, 245, 51, 47, 150, 157, 158, 148,
77, 78, 175, 49, 51, 131, 40, 91, -60, 184, 159, 52, 97, 98, 53, 165, 163, 164, 173, 51,
174, 52, 77, 264, 53, 145, 156, 49, 81, 187, 77, 262, 174, 149, 177, 145, 52, 91, 73, 53,
188, 162, 152, 153, 50, 202, 51, 207, 89, 224, 40, 74, -59, 155, 49, 75, 76, 89, 222, 186,
143, 223, 219, 67, 89, 295, 53, 229, 50, 234, 187, 315, 316, 89, 292, 201, 156, 206, 232, 161,
51, 89, 77, 78, 236, 220, 121, 52, 97, 98, 89, 244, 207, 151, 152, 50, 160, 51, 74, 166,
53, 240, 91, 158, 159, 74, 160, 146, 91, 75, 238, 176, 75, 76, 67, 219, 121, 53, 221, 260,
76, 318, 319, 262, 136, 91, 265, 266, 203, 204, 218, 91, 263, 264, 227, 47, 48, 91, 103, 103,
205, 239, 233, 235, 249, 250, 251, 208, 246, 254, 122, 234, 123, 124, 91, 103, 189, 190, 191, 192,
255, 256, 257, 258, 190, 191, 192, 193, 194, 195, 193, 194, 195, 196, 197, 198, 202, 203, 204, 237,
196, 197, 198, 199, 263, 286, 287, 276, 276, 276, 241, 231, 233, 167, 49, 273, 273, 273, 273, 47,
276, 273, 161, 73, 147, 296, 74, 197, 198, 199, 48, 247, 248, 249, 293, 168, 252, 253, 254, 255,
75, 76, 148, 149, 285, 181, 181, 157, 72, 267, 256, 178, 282, 180, 180, 50, 181, 51, 182, 77,
268, 277, 277, 277, 277, 73, 243, 73, 74, 40, 78, 261, 283, 284, 52, 97, 98, 53, 49, 274,
74, 167, 75, 76, 75, 76, 293, 294, 47, 48, 274, 274, 274, 194, 195, 196, 197, 198, 265, 266,
97, 98, 303, 195, 196, 197, 198, 199, 168, 200, 300, 199, 184, 185, 97, 98, 306, 188, 280, 208,
288, 40, 309, 190, 191, 192, 193, 194, 195, 196, 209, 51, 73, 211, 287, 74, 113, 212, 67, 75,
197, 198, 199, 122, 169, 123, 124, 49, 177, 308, 76, 53, 290, 291, 213, 214, 305, 215, 285, 202,
190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 203, 204, 47, 48, 296, 223, 47, 48, 40, 313,
115, 179, 316, 97, 98, 283, 302, 182, 183, 322, 224, 225, 77, 78, 226, 236, 319, 115, 97, 98,
51, 290, 185, 325, 305, 113, 186, 67, 189, 225, 322, 189, 190, 191, 192, 193, 194, 195, 196, 197,
53, 209, 210, 314, 212, 213, 312, 326, 214, 4, 198, 49, 237, 299, 136, 49, 196, 197, 198, 239,
215, 299, 222, 216, 332, 278, 279, 280, 271, 226, 311, 302, 189, 190, 191, 192, 193, 194, 195, 196,
227, 5, 6, 7, 8, 9, 10, 11, 12, 13, 197, 198, 50, 309, 51, 242, 108, 243, 51, 250,
14, 15, 16, 17, 18, 329, 19, 20, 21, 22, 4, 67, 323, 251, 53, 52, 257, 220, 53, 329,
23, 24, 25, 26, 27, 47, 48, 73, 228, 238, 259, 301, 5, 6, 7, 8, 9, 10, 11, 12,
74, 28, 29, 241, 75, 76, 239, 203, 204, 205, 13, 14, 15, 16, 17, 18, 269, 19, 20, 21,
74, 244, 97, 98, 75, 76, 30, 245, 31, 252, 22, 23, 24, 25, 26, 27, 47, 48, 275, 276,
259, 32, 47, 48, 49, 73, 253, 221, 74, 260, 277, 258, 28, 29, 267, 73, 268, 326, 74, 270,
261, 281, 75, 76, 77, 78, 269, 284, 79, 80, 271, 278, 75, 76, 279, 281, 286, 30, 289, 31,
97, 98, 270, 272, 274, 50, 282, 51, 289, 47, 97, 98, 32, 47, 48, 49, 73, 288, 295, 74,
48, 49, 73, 291, 67, 74, 81, 53, 292, 75, 99, 40, 297, 75, 76, 77, 78, 298, 303, 79,
76, 77, 78, 47, 48, 79, 80, 47, 48, 47, 80, 97, 98, 47, 48, 304, 50, 307, 51, 47,
48, 99, 50, 298, 51, 47, 48, 304, 49, 73, 48, 310, 49, 73, 312, 67, 74, 81, 53, 314,
300, 67, 74, 81, 53, 301, 75, 76, 306, 47, 75, 76, 77, 78, 318, 320, 79, 80, 47, 48,
48, 307, 49, 310, 315, 313, 49, 317, 49, 321, 47, 48, 49, 50, 321, 51, 325, 327, 49, 228,
328, 51, 324, 323, 49, 230, 47, 48, 52, 330, 170, 137, 67, 246, 81, 53, 47, 48, 324, 0,
171, 53, 137, 50, 327, 51, 248, 108, 49, 51, 0, 0, 0, 169, 0, 51, 0, 49, 0, 49,
0, 51, 67, 221, 0, 53, 52, 51, 52, 53, 0, 51, 67, 0, 0, 53, 0, 0, 52, 0,
99, 53, 47, 48, 52, 49, 0, 53, 0, 170, 99, 53, 0, 0, 0, 49, 220, 0, 73, 0,
0, 51, 0, 0, 0, 0, 0, 0, 67, 0, 51, 74, 51, 0, 0, 75, 76, 52, 0, 52,
0, 53, 0, 0, 0, 0, 0, 0, 51, 0, 53, 0, 53, 97, 98, 0, 0, 0, 51, 202,
0, 49, 0, 0, 0, 52, 0, 0, 53, 190, 203, 204, 74, 0, 0, 67, 75, 76, 53, 189,
191, 192, 193, 194, 195, 196, 197, 198, 199, 0, 190, 191, 192, 193, 194, 195, 196, 197, 198, 189,
0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 190, 191, 192, 193, 194, 195, 196, 197, 198, 189,
0, 67, 0, 0, 53, 190, 191, 192, 193, 194, 190, 191, 192, 193, 194, 195, 196, 197, 198, 0,
195, 196, 197, 198, 199, 190, 191, 192, 193, 194, 73, 0, 0, 74, 0, 0, 0, 75, 76, 0,
195, 196, 197, 198, 199, 0, 73, 0, 0, 74, 0, 0, 0, 0, 0, 97, 98, 0, 37, 38,
0, 0, 0, 75, 76, 0, 0, 0, 0, 0, 39, 0, 42, 43, 44, 45, 46, 0, 0, 57,
297, 97, 98, 0, 37, 38, 39, 0, 42, 43, 294, 99, 60, 61, 62, 63, 64, 65, 0, 229,
44, 45, 46, 0, 0, 57, 0, 99, 60, 61, 190, 191, 192, 193, 194, 195, 196, 197, 198, 230,
62, 63, 64, 65, 0, 231, 191, 192, 193, 194, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
195, 196, 197, 198, 199, 232, 190, 191, 192, 193, 191, 192, 193, 194, 195, 196, 197, 198, 192, 193,
194, 195, 196, 197, 198, 199, 192, 193, 194, 195, 194, 195, 196, 197, 198
196, 197, 198, 199, 193, 194, 195, 196, 197, 198,
199
}; };
static const yytype_int16 yycheck[] = static const yytype_int16 yycheck[] =
{ {
28, 29, 44, 59, 29, 129, 27, 0, 36, 37, 28, 29, 63, 44, 59, 0, 129, 64, 36, 37,
38, 15, 16, 38, 60, 43, 62, 63, 108, 15, 38, 60, 27, 62, 63, 43, 108, 15, 16, 9,
16, 9, 63, 27, 28, 29, 36, 37, 146, 147, 37, 15, 16, 66, 146, 147, 43, 9, 18, 19,
61, 62, 37, 43, 38, 53, 54, 41, 43, 67, 61, 62, 29, 27, 28, 29, 26, 53, 54, 67,
44, 36, 37, 47, 48, 64, 64, 62, 43, 53, 62, 38, 8, 9, 38, 8, 9, 41, 64, 39,
45, 9, 8, 9, 9, 8, 9, 61, 64, 66, 44, 63, 42, 47, 48, 45, 46, 8, 9, 53,
81, 63, 57, 18, 19, 183, 47, 48, 56, 64, 182, 36, 37, 106, 64, 9, 81, 61, 43, 11,
65, 26, 53, 54, 8, 9, 10, 81, 94, 95, 45, 37, 38, 116, 56, 41, 67, 169, 67, 45,
170, 37, 67, 111, 39, 113, 111, 42, 8, 9, 46, 67, 57, 111, 69, 113, 37, 81, 67, 64,
45, 46, 38, 39, 40, 99, 186, 53, 54, 106, 65, 47, 48, 185, 60, 8, 9, 6, 7, 67,
47, 48, 106, 37, 60, 11, 64, 111, 66, 116, 9, 67, 53, 54, 70, 99, 94, 95, 106, 60,
106, 67, 47, 48, 70, 143, 64, 37, 69, 123, 47, 48, 106, 67, 111, 143, 67, 111, 38, 70,
124, 64, 56, 57, 58, 129, 60, 131, 156, 157, 64, 41, 66, 64, 37, 45, 46, 155, 156, 123,
67, 156, 148, 67, 162, 259, 70, 162, 58, 167, 124, 49, 50, 161, 257, 129, 67, 131, 166, 64,
60, 169, 47, 48, 169, 149, 150, 67, 53, 54, 168, 184, 132, 56, 57, 58, 55, 60, 41, 64,
70, 179, 156, 6, 7, 41, 9, 67, 162, 45, 178, 67, 45, 46, 67, 149, 150, 70, 155, 208,
46, 49, 50, 209, 69, 169, 212, 213, 38, 39, 148, 155, 211, 212, 161, 8, 9, 161, 36, 37,
40, 41, 167, 168, 190, 191, 192, 132, 185, 195, 6, 168, 8, 9, 168, 43, 3, 4, 5, 6,
196, 197, 198, 199, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, 11, 12, 38, 39, 40, 41,
9, 10, 11, 12, 210, 243, 244, 225, 226, 227, 180, 166, 167, 64, 37, 223, 224, 225, 226, 8,
228, 222, 55, 38, 67, 261, 41, 10, 11, 12, 9, 189, 190, 191, 259, 64, 194, 195, 196, 197,
45, 46, 67, 67, 242, 243, 244, 67, 222, 214, 198, 64, 240, 241, 242, 58, 64, 60, 67, 47,
215, 225, 226, 227, 228, 38, 181, 38, 41, 64, 48, 209, 241, 242, 67, 53, 54, 70, 37, 223,
41, 64, 45, 46, 45, 46, 252, 253, 8, 9, 224, 225, 226, 8, 9, 10, 11, 12, 213, 214,
53, 54, 284, 8, 9, 10, 11, 12, 64, 68, 281, 68, 64, 7, 53, 54, 295, 67, 238, 64,
245, 64, 298, 3, 4, 5, 6, 7, 8, 9, 64, 60, 38, 64, 244, 41, 65, 64, 67, 45,
10, 11, 12, 6, 64, 8, 9, 37, 67, 297, 46, 70, 250, 251, 64, 64, 294, 68, 243, 38,
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 39, 40, 8, 9, 264, 6, 8, 9, 64, 307,
284, 64, 310, 53, 54, 240, 281, 64, 67, 317, 7, 7, 47, 48, 7, 67, 314, 281, 53, 54,
60, 246, 64, 321, 289, 65, 7, 67, 67, 6, 318, 3, 4, 5, 6, 7, 8, 9, 10, 11,
70, 64, 64, 307, 64, 64, 301, 323, 64, 1, 12, 37, 41, 278, 69, 37, 10, 11, 12, 66,
64, 266, 69, 68, 330, 226, 227, 228, 68, 7, 304, 286, 3, 4, 5, 6, 7, 8, 9, 10,
7, 13, 14, 15, 16, 17, 18, 19, 20, 21, 11, 12, 58, 298, 60, 65, 58, 64, 60, 6,
22, 23, 24, 25, 26, 68, 28, 29, 30, 31, 1, 67, 320, 7, 70, 67, 64, 56, 70, 327,
32, 33, 34, 35, 36, 8, 9, 38, 7, 67, 64, 66, 13, 14, 15, 16, 17, 18, 19, 20,
41, 43, 44, 66, 45, 46, 41, 38, 39, 40, 21, 22, 23, 24, 25, 26, 68, 28, 29, 30,
41, 65, 53, 54, 45, 46, 58, 64, 60, 6, 31, 32, 33, 34, 35, 36, 8, 9, 224, 225,
64, 63, 8, 9, 37, 38, 7, 56, 41, 68, 226, 68, 43, 44, 68, 38, 68, 68, 41, 68,
64, 64, 45, 46, 47, 48, 68, 64, 51, 52, 68, 64, 45, 46, 68, 64, 64, 58, 68, 60,
53, 54, 68, 68, 68, 58, 68, 60, 64, 8, 53, 54, 63, 8, 9, 37, 38, 67, 64, 41,
9, 37, 38, 67, 67, 41, 69, 70, 68, 45, 69, 64, 64, 45, 46, 47, 48, 64, 39, 51,
46, 47, 48, 8, 9, 51, 52, 8, 9, 8, 52, 53, 54, 8, 9, 9, 58, 67, 60, 8,
9, 69, 58, 64, 60, 8, 9, 66, 37, 38, 9, 68, 37, 38, 64, 67, 41, 69, 70, 64,
64, 67, 41, 69, 70, 64, 45, 46, 39, 8, 45, 46, 47, 48, 64, 67, 51, 52, 8, 9,
9, 9, 37, 67, 64, 68, 37, 64, 37, 64, 8, 9, 37, 58, 64, 60, 68, 64, 37, 162,
68, 60, 64, 67, 37, 163, 8, 9, 67, 64, 106, 62, 67, 188, 69, 70, 8, 9, 321, -1,
106, 70, 62, 58, 324, 60, 189, 58, 37, 60, -1, -1, -1, 58, -1, 60, -1, 37, -1, 37,
-1, 60, 67, 56, -1, 70, 67, 60, 67, 70, -1, 60, 67, -1, -1, 70, -1, -1, 67, -1,
69, 70, 8, 9, 67, 37, -1, 70, -1, 58, 69, 70, -1, -1, -1, 37, 56, -1, 38, -1,
-1, 60, -1, -1, -1, -1, -1, -1, 67, -1, 60, 41, 60, -1, -1, 45, 46, 67, -1, 67,
-1, 70, -1, -1, -1, -1, -1, -1, 60, -1, 70, -1, 70, 53, 54, -1, -1, -1, 60, 38,
-1, 37, -1, -1, -1, 67, -1, -1, 70, 3, 39, 40, 41, -1, -1, 67, 45, 46, 70, 3,
4, 5, 6, 7, 8, 9, 10, 11, 12, 3,
4, 5, 6, 7, 8, 9, 10, 11, 12, 3,
4, 5, 6, 7, 8, 9, 10, 11, 12, -1, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1,
-1, -1, -1, -1, 60, -1, -1, -1, -1, -1, 38, -1, -1, 41, -1, -1, -1, 45, 46, -1,
-1, 67, -1, -1, 70, 3, 4, 5, 6, 7, -1, -1, -1, -1, -1, 53, 54, -1, 6, 7,
8, 9, 10, 11, 12, 3, 4, 5, 6, 7, 8, -1, 10, 11, 12, 13, 14, -1, -1, 17,
8, 9, 10, 11, 12, -1, 38, -1, -1, 41, 64, 69, 20, 21, 22, 23, 24, 25, -1, 63,
-1, -1, -1, 45, 46, -1, -1, -1, -1, -1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 63,
64, 53, 54, -1, 6, 7, 8, -1, 10, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
12, 13, 14, -1, -1, 17, -1, 69, 20, 21, 5, 6, 7, 8, 9, 10, 11, 12, 6, 7,
22, 23, 24, 25, -1, 63, 4, 5, 6, 7, 8, 9, 10, 11, 12
8, 9, 10, 11, 12, 63, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 5, 6, 7, 8,
9, 10, 11, 12, 6, 7, 8, 9, 10, 11,
12
}; };
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
...@@ -925,25 +914,24 @@ static const yytype_uint8 yystos[] = ...@@ -925,25 +914,24 @@ static const yytype_uint8 yystos[] =
102, 102, 6, 8, 9, 100, 102, 104, 102, 64, 102, 102, 6, 8, 9, 100, 102, 104, 102, 64,
67, 11, 90, 80, 98, 102, 69, 81, 97, 98, 67, 11, 90, 80, 98, 102, 69, 81, 97, 98,
98, 90, 90, 67, 85, 95, 67, 67, 67, 67, 98, 90, 90, 67, 85, 95, 67, 67, 67, 67,
9, 10, 56, 57, 87, 102, 64, 67, 6, 7, 9, 56, 57, 87, 102, 64, 67, 6, 7, 9,
9, 55, 64, 75, 104, 104, 102, 64, 64, 64, 55, 64, 75, 104, 104, 102, 64, 64, 64, 58,
58, 79, 84, 85, 99, 102, 100, 67, 83, 64, 79, 84, 85, 99, 102, 100, 67, 83, 64, 82,
82, 95, 64, 67, 85, 64, 7, 102, 102, 67, 95, 64, 67, 85, 64, 7, 102, 102, 67, 3,
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 4, 5, 6, 7, 8, 9, 10, 11, 12, 68,
68, 89, 102, 38, 39, 40, 101, 102, 78, 64, 89, 102, 38, 39, 40, 101, 102, 78, 64, 64,
64, 9, 64, 64, 64, 64, 68, 94, 94, 104, 9, 64, 64, 64, 64, 68, 94, 94, 104, 102,
102, 56, 69, 83, 95, 6, 7, 7, 7, 83, 56, 83, 95, 6, 7, 7, 7, 83, 74, 63,
74, 63, 63, 90, 95, 90, 83, 100, 67, 41, 63, 90, 95, 90, 83, 100, 67, 41, 95, 66,
95, 66, 9, 78, 65, 64, 85, 100, 101, 104, 9, 78, 65, 64, 85, 100, 101, 104, 104, 104,
104, 104, 6, 7, 104, 104, 104, 104, 104, 64, 6, 7, 104, 104, 104, 104, 104, 64, 68, 64,
68, 64, 98, 104, 48, 98, 98, 90, 90, 68, 98, 104, 48, 98, 98, 90, 90, 68, 68, 68,
68, 68, 68, 87, 68, 93, 95, 102, 93, 93, 68, 68, 93, 95, 102, 93, 93, 93, 64, 68,
93, 64, 68, 78, 64, 95, 82, 82, 90, 64, 78, 64, 95, 82, 82, 90, 64, 78, 67, 68,
78, 67, 68, 104, 104, 89, 80, 64, 64, 78, 104, 104, 89, 80, 64, 64, 78, 64, 64, 90,
64, 64, 90, 86, 66, 90, 39, 9, 95, 98, 86, 66, 90, 39, 9, 95, 98, 67, 91, 90,
67, 91, 90, 68, 102, 64, 95, 64, 49, 50, 68, 102, 64, 95, 64, 49, 50, 96, 64, 95,
96, 64, 95, 67, 64, 95, 104, 96, 68, 68, 67, 64, 95, 104, 96, 68, 68, 64, 103, 104
64, 103, 104
}; };
#define yyerrok (yyerrstatus = 0) #define yyerrok (yyerrstatus = 0)
...@@ -1809,56 +1797,56 @@ yyreduce: ...@@ -1809,56 +1797,56 @@ yyreduce:
case 14: case 14:
#line 113 "a.y" #line 113 "a.y"
{ {
outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr)); outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
} }
break; break;
case 15: case 15:
#line 120 "a.y" #line 120 "a.y"
{ {
outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr)); outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
} }
break; break;
case 16: case 16:
#line 127 "a.y" #line 127 "a.y"
{ {
outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr)); outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
} }
break; break;
case 17: case 17:
#line 134 "a.y" #line 134 "a.y"
{ {
outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, NREG, &(yyvsp[(4) - (4)].addr)); outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, 0, &(yyvsp[(4) - (4)].addr));
} }
break; break;
case 18: case 18:
#line 138 "a.y" #line 138 "a.y"
{ {
outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, NREG, &(yyvsp[(4) - (4)].addr)); outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, 0, &(yyvsp[(4) - (4)].addr));
} }
break; break;
case 19: case 19:
#line 145 "a.y" #line 145 "a.y"
{ {
outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, NREG, &(yyvsp[(3) - (3)].addr)); outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, 0, &(yyvsp[(3) - (3)].addr));
} }
break; break;
case 20: case 20:
#line 152 "a.y" #line 152 "a.y"
{ {
outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, NREG, &(yyvsp[(3) - (3)].addr)); outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, 0, &(yyvsp[(3) - (3)].addr));
} }
break; break;
case 21: case 21:
#line 159 "a.y" #line 159 "a.y"
{ {
outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, NREG, &(yyvsp[(4) - (4)].addr)); outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, 0, &(yyvsp[(4) - (4)].addr));
} }
break; break;
...@@ -1875,9 +1863,9 @@ yyreduce: ...@@ -1875,9 +1863,9 @@ yyreduce:
Addr g; Addr g;
g = nullgen; g = nullgen;
g.type = D_CONST; g.type = TYPE_CONST;
g.offset = (yyvsp[(6) - (7)].lval); g.offset = (yyvsp[(6) - (7)].lval);
outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].addr), NREG, &g); outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].addr), 0, &g);
} }
break; break;
...@@ -1887,9 +1875,9 @@ yyreduce: ...@@ -1887,9 +1875,9 @@ yyreduce:
Addr g; Addr g;
g = nullgen; g = nullgen;
g.type = D_CONST; g.type = TYPE_CONST;
g.offset = (yyvsp[(4) - (7)].lval); g.offset = (yyvsp[(4) - (7)].lval);
outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &g, NREG, &(yyvsp[(7) - (7)].addr)); outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &g, 0, &(yyvsp[(7) - (7)].addr));
} }
break; break;
...@@ -1917,7 +1905,7 @@ yyreduce: ...@@ -1917,7 +1905,7 @@ yyreduce:
case 28: case 28:
#line 209 "a.y" #line 209 "a.y"
{ {
outcode((yyvsp[(1) - (3)].lval), (yyvsp[(2) - (3)].lval), &nullgen, NREG, &nullgen); outcode((yyvsp[(1) - (3)].lval), (yyvsp[(2) - (3)].lval), &nullgen, 0, &nullgen);
} }
break; break;
...@@ -1925,8 +1913,8 @@ yyreduce: ...@@ -1925,8 +1913,8 @@ yyreduce:
#line 216 "a.y" #line 216 "a.y"
{ {
settext((yyvsp[(2) - (4)].addr).sym); settext((yyvsp[(2) - (4)].addr).sym);
(yyvsp[(4) - (4)].addr).type = D_CONST2; (yyvsp[(4) - (4)].addr).type = TYPE_TEXTSIZE;
(yyvsp[(4) - (4)].addr).offset2 = ArgsSizeUnknown; (yyvsp[(4) - (4)].addr).u.argsize = ArgsSizeUnknown;
outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr)); outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
} }
break; break;
...@@ -1935,8 +1923,8 @@ yyreduce: ...@@ -1935,8 +1923,8 @@ yyreduce:
#line 223 "a.y" #line 223 "a.y"
{ {
settext((yyvsp[(2) - (6)].addr).sym); settext((yyvsp[(2) - (6)].addr).sym);
(yyvsp[(6) - (6)].addr).type = D_CONST2; (yyvsp[(6) - (6)].addr).type = TYPE_TEXTSIZE;
(yyvsp[(6) - (6)].addr).offset2 = ArgsSizeUnknown; (yyvsp[(6) - (6)].addr).u.argsize = ArgsSizeUnknown;
outcode((yyvsp[(1) - (6)].lval), Always, &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr)); outcode((yyvsp[(1) - (6)].lval), Always, &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
} }
break; break;
...@@ -1945,8 +1933,8 @@ yyreduce: ...@@ -1945,8 +1933,8 @@ yyreduce:
#line 230 "a.y" #line 230 "a.y"
{ {
settext((yyvsp[(2) - (8)].addr).sym); settext((yyvsp[(2) - (8)].addr).sym);
(yyvsp[(6) - (8)].addr).type = D_CONST2; (yyvsp[(6) - (8)].addr).type = TYPE_TEXTSIZE;
(yyvsp[(6) - (8)].addr).offset2 = (yyvsp[(8) - (8)].lval); (yyvsp[(6) - (8)].addr).u.argsize = (yyvsp[(8) - (8)].lval);
outcode((yyvsp[(1) - (8)].lval), Always, &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].lval), &(yyvsp[(6) - (8)].addr)); outcode((yyvsp[(1) - (8)].lval), Always, &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].lval), &(yyvsp[(6) - (8)].addr));
} }
break; break;
...@@ -1961,28 +1949,28 @@ yyreduce: ...@@ -1961,28 +1949,28 @@ yyreduce:
case 33: case 33:
#line 247 "a.y" #line 247 "a.y"
{ {
outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &(yyvsp[(3) - (4)].addr), NREG, &nullgen); outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &(yyvsp[(3) - (4)].addr), 0, &nullgen);
} }
break; break;
case 34: case 34:
#line 254 "a.y" #line 254 "a.y"
{ {
outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, NREG, &(yyvsp[(3) - (3)].addr)); outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, 0, &(yyvsp[(3) - (3)].addr));
} }
break; break;
case 35: case 35:
#line 261 "a.y" #line 261 "a.y"
{ {
outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr)); outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
} }
break; break;
case 36: case 36:
#line 265 "a.y" #line 265 "a.y"
{ {
outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr)); outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
} }
break; break;
...@@ -2006,7 +1994,7 @@ yyreduce: ...@@ -2006,7 +1994,7 @@ yyreduce:
Addr g; Addr g;
g = nullgen; g = nullgen;
g.type = D_CONST; g.type = TYPE_CONST;
g.offset = g.offset =
(0xe << 24) | /* opcode */ (0xe << 24) | /* opcode */
((yyvsp[(1) - (12)].lval) << 20) | /* MCR/MRC */ ((yyvsp[(1) - (12)].lval) << 20) | /* MCR/MRC */
...@@ -2018,7 +2006,7 @@ yyreduce: ...@@ -2018,7 +2006,7 @@ yyreduce:
(((yyvsp[(11) - (12)].lval) & 15) << 0) | /* Crm */ (((yyvsp[(11) - (12)].lval) & 15) << 0) | /* Crm */
(((yyvsp[(12) - (12)].lval) & 7) << 5) | /* coprocessor information */ (((yyvsp[(12) - (12)].lval) & 7) << 5) | /* coprocessor information */
(1<<4); /* must be set */ (1<<4); /* must be set */
outcode(AMRC, Always, &nullgen, NREG, &g); outcode(AMRC, Always, &nullgen, 0, &g);
} }
break; break;
...@@ -2032,7 +2020,7 @@ yyreduce: ...@@ -2032,7 +2020,7 @@ yyreduce:
case 41: case 41:
#line 310 "a.y" #line 310 "a.y"
{ {
(yyvsp[(7) - (9)].addr).type = D_REGREG2; (yyvsp[(7) - (9)].addr).type = TYPE_REGREG2;
(yyvsp[(7) - (9)].addr).offset = (yyvsp[(9) - (9)].lval); (yyvsp[(7) - (9)].addr).offset = (yyvsp[(9) - (9)].lval);
outcode((yyvsp[(1) - (9)].lval), (yyvsp[(2) - (9)].lval), &(yyvsp[(3) - (9)].addr), (yyvsp[(5) - (9)].addr).reg, &(yyvsp[(7) - (9)].addr)); outcode((yyvsp[(1) - (9)].lval), (yyvsp[(2) - (9)].lval), &(yyvsp[(3) - (9)].addr), (yyvsp[(5) - (9)].addr).reg, &(yyvsp[(7) - (9)].addr));
} }
...@@ -2041,34 +2029,34 @@ yyreduce: ...@@ -2041,34 +2029,34 @@ yyreduce:
case 42: case 42:
#line 319 "a.y" #line 319 "a.y"
{ {
outcode((yyvsp[(1) - (2)].lval), Always, &(yyvsp[(2) - (2)].addr), NREG, &nullgen); outcode((yyvsp[(1) - (2)].lval), Always, &(yyvsp[(2) - (2)].addr), 0, &nullgen);
} }
break; break;
case 43: case 43:
#line 326 "a.y" #line 326 "a.y"
{ {
if((yyvsp[(2) - (4)].addr).type != D_CONST || (yyvsp[(4) - (4)].addr).type != D_CONST) if((yyvsp[(2) - (4)].addr).type != TYPE_CONST || (yyvsp[(4) - (4)].addr).type != TYPE_CONST)
yyerror("arguments to PCDATA must be integer constants"); yyerror("arguments to PCDATA must be integer constants");
outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr)); outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
} }
break; break;
case 44: case 44:
#line 335 "a.y" #line 335 "a.y"
{ {
if((yyvsp[(2) - (4)].addr).type != D_CONST) if((yyvsp[(2) - (4)].addr).type != TYPE_CONST)
yyerror("index for FUNCDATA must be integer constant"); yyerror("index for FUNCDATA must be integer constant");
if((yyvsp[(4) - (4)].addr).type != D_EXTERN && (yyvsp[(4) - (4)].addr).type != D_STATIC && (yyvsp[(4) - (4)].addr).type != D_OREG) if((yyvsp[(4) - (4)].addr).type != NAME_EXTERN && (yyvsp[(4) - (4)].addr).type != NAME_STATIC && (yyvsp[(4) - (4)].addr).type != TYPE_MEM)
yyerror("value for FUNCDATA must be symbol reference"); yyerror("value for FUNCDATA must be symbol reference");
outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr)); outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
} }
break; break;
case 45: case 45:
#line 346 "a.y" #line 346 "a.y"
{ {
outcode((yyvsp[(1) - (2)].lval), Always, &nullgen, NREG, &nullgen); outcode((yyvsp[(1) - (2)].lval), Always, &nullgen, 0, &nullgen);
} }
break; break;
...@@ -2097,7 +2085,7 @@ yyreduce: ...@@ -2097,7 +2085,7 @@ yyreduce:
#line 368 "a.y" #line 368 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_BRANCH; (yyval.addr).type = TYPE_BRANCH;
(yyval.addr).offset = (yyvsp[(1) - (4)].lval) + pc; (yyval.addr).offset = (yyvsp[(1) - (4)].lval) + pc;
} }
break; break;
...@@ -2109,7 +2097,7 @@ yyreduce: ...@@ -2109,7 +2097,7 @@ yyreduce:
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
if(pass == 2 && (yyvsp[(1) - (2)].sym)->type != LLAB) if(pass == 2 && (yyvsp[(1) - (2)].sym)->type != LLAB)
yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->labelname); 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); (yyval.addr).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
} }
break; break;
...@@ -2118,7 +2106,7 @@ yyreduce: ...@@ -2118,7 +2106,7 @@ yyreduce:
#line 384 "a.y" #line 384 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_CONST; (yyval.addr).type = TYPE_CONST;
(yyval.addr).offset = (yyvsp[(2) - (2)].lval); (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
} }
break; break;
...@@ -2127,54 +2115,46 @@ yyreduce: ...@@ -2127,54 +2115,46 @@ yyreduce:
#line 390 "a.y" #line 390 "a.y"
{ {
(yyval.addr) = (yyvsp[(2) - (2)].addr); (yyval.addr) = (yyvsp[(2) - (2)].addr);
(yyval.addr).type = D_CONST; (yyval.addr).type = TYPE_CONST;
} }
break; break;
case 55: case 55:
#line 395 "a.y" #line 395 "a.y"
{
(yyval.addr) = (yyvsp[(4) - (4)].addr);
(yyval.addr).type = D_OCONST;
}
break;
case 56:
#line 400 "a.y"
{ {
(yyval.addr) = nullgen; (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)); memcpy((yyval.addr).u.sval, (yyvsp[(2) - (2)].sval), sizeof((yyval.addr).u.sval));
} }
break; break;
case 58: case 57:
#line 409 "a.y" #line 404 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_FCONST; (yyval.addr).type = TYPE_FCONST;
(yyval.addr).u.dval = (yyvsp[(2) - (2)].dval); (yyval.addr).u.dval = (yyvsp[(2) - (2)].dval);
} }
break; break;
case 59: case 58:
#line 415 "a.y" #line 410 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_FCONST; (yyval.addr).type = TYPE_FCONST;
(yyval.addr).u.dval = -(yyvsp[(3) - (3)].dval); (yyval.addr).u.dval = -(yyvsp[(3) - (3)].dval);
} }
break; break;
case 60: case 59:
#line 423 "a.y" #line 418 "a.y"
{ {
(yyval.lval) = 1 << (yyvsp[(1) - (1)].lval); (yyval.lval) = 1 << (yyvsp[(1) - (1)].lval);
} }
break; break;
case 61: case 60:
#line 427 "a.y" #line 422 "a.y"
{ {
int i; int i;
(yyval.lval)=0; (yyval.lval)=0;
...@@ -2185,161 +2165,161 @@ yyreduce: ...@@ -2185,161 +2165,161 @@ yyreduce:
} }
break; break;
case 62: case 61:
#line 436 "a.y" #line 431 "a.y"
{ {
(yyval.lval) = (1<<(yyvsp[(1) - (3)].lval)) | (yyvsp[(3) - (3)].lval); (yyval.lval) = (1<<(yyvsp[(1) - (3)].lval)) | (yyvsp[(3) - (3)].lval);
} }
break; break;
case 66: case 65:
#line 445 "a.y" #line 440 "a.y"
{ {
(yyval.addr) = (yyvsp[(1) - (4)].addr); (yyval.addr) = (yyvsp[(1) - (4)].addr);
(yyval.addr).reg = (yyvsp[(3) - (4)].lval); (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
} }
break; break;
case 67: case 66:
#line 450 "a.y" #line 445 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_PSR; (yyval.addr).type = TYPE_REG;
(yyval.addr).reg = (yyvsp[(1) - (1)].lval); (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
} }
break; break;
case 68: case 67:
#line 456 "a.y" #line 451 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_FPCR; (yyval.addr).type = TYPE_REG;
(yyval.addr).reg = (yyvsp[(1) - (1)].lval); (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
} }
break; break;
case 69: case 68:
#line 462 "a.y" #line 457 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_OREG; (yyval.addr).type = TYPE_MEM;
(yyval.addr).offset = (yyvsp[(1) - (1)].lval); (yyval.addr).offset = (yyvsp[(1) - (1)].lval);
} }
break; break;
case 73: case 72:
#line 473 "a.y" #line 468 "a.y"
{ {
(yyval.addr) = (yyvsp[(1) - (1)].addr); (yyval.addr) = (yyvsp[(1) - (1)].addr);
if((yyvsp[(1) - (1)].addr).name != D_EXTERN && (yyvsp[(1) - (1)].addr).name != D_STATIC) { if((yyvsp[(1) - (1)].addr).name != NAME_EXTERN && (yyvsp[(1) - (1)].addr).name != NAME_STATIC) {
} }
} }
break; break;
case 74: case 73:
#line 481 "a.y" #line 476 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_OREG; (yyval.addr).type = TYPE_MEM;
(yyval.addr).reg = (yyvsp[(2) - (3)].lval); (yyval.addr).reg = (yyvsp[(2) - (3)].lval);
(yyval.addr).offset = 0; (yyval.addr).offset = 0;
} }
break; break;
case 76: case 75:
#line 491 "a.y" #line 486 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_OREG; (yyval.addr).type = TYPE_MEM;
(yyval.addr).reg = (yyvsp[(3) - (4)].lval); (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
(yyval.addr).offset = (yyvsp[(1) - (4)].lval); (yyval.addr).offset = (yyvsp[(1) - (4)].lval);
} }
break; break;
case 78: case 77:
#line 501 "a.y" #line 496 "a.y"
{ {
(yyval.addr) = (yyvsp[(1) - (4)].addr); (yyval.addr) = (yyvsp[(1) - (4)].addr);
(yyval.addr).type = D_OREG; (yyval.addr).type = TYPE_MEM;
(yyval.addr).reg = (yyvsp[(3) - (4)].lval); (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
} }
break; break;
case 83: case 82:
#line 514 "a.y" #line 509 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_CONST; (yyval.addr).type = TYPE_CONST;
(yyval.addr).offset = (yyvsp[(2) - (2)].lval); (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
} }
break; break;
case 84: case 83:
#line 522 "a.y" #line 517 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_REG; (yyval.addr).type = TYPE_REG;
(yyval.addr).reg = (yyvsp[(1) - (1)].lval); (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
} }
break; break;
case 85: case 84:
#line 530 "a.y" #line 525 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_REGREG; (yyval.addr).type = TYPE_REGREG;
(yyval.addr).reg = (yyvsp[(2) - (5)].lval); (yyval.addr).reg = (yyvsp[(2) - (5)].lval);
(yyval.addr).offset = (yyvsp[(4) - (5)].lval); (yyval.addr).offset = (yyvsp[(4) - (5)].lval);
} }
break; break;
case 86: case 85:
#line 539 "a.y" #line 534 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_SHIFT; (yyval.addr).type = TYPE_SHIFT;
(yyval.addr).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (0 << 5); (yyval.addr).offset = (yyvsp[(1) - (4)].lval)&15 | (yyvsp[(4) - (4)].lval) | (0 << 5);
} }
break; break;
case 87: case 86:
#line 545 "a.y" #line 540 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_SHIFT; (yyval.addr).type = TYPE_SHIFT;
(yyval.addr).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (1 << 5); (yyval.addr).offset = (yyvsp[(1) - (4)].lval)&15 | (yyvsp[(4) - (4)].lval) | (1 << 5);
} }
break; break;
case 88: case 87:
#line 551 "a.y" #line 546 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_SHIFT; (yyval.addr).type = TYPE_SHIFT;
(yyval.addr).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (2 << 5); (yyval.addr).offset = (yyvsp[(1) - (4)].lval)&15 | (yyvsp[(4) - (4)].lval) | (2 << 5);
} }
break; break;
case 89: case 88:
#line 557 "a.y" #line 552 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_SHIFT; (yyval.addr).type = TYPE_SHIFT;
(yyval.addr).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (3 << 5); (yyval.addr).offset = (yyvsp[(1) - (4)].lval)&15 | (yyvsp[(4) - (4)].lval) | (3 << 5);
} }
break; break;
case 90: case 89:
#line 565 "a.y" #line 560 "a.y"
{ {
if((yyval.lval) < 0 || (yyval.lval) >= 16) if((yyval.lval) < REG_R0 || (yyval.lval) > REG_R15)
print("register value out of range\n"); print("register value out of range in shift\n");
(yyval.lval) = (((yyvsp[(1) - (1)].lval)&15) << 8) | (1 << 4); (yyval.lval) = (((yyvsp[(1) - (1)].lval)&15) << 8) | (1 << 4);
} }
break; break;
case 91: case 90:
#line 571 "a.y" #line 566 "a.y"
{ {
if((yyval.lval) < 0 || (yyval.lval) >= 32) if((yyval.lval) < 0 || (yyval.lval) >= 32)
print("shift value out of range\n"); print("shift value out of range\n");
...@@ -2347,224 +2327,224 @@ yyreduce: ...@@ -2347,224 +2327,224 @@ yyreduce:
} }
break; break;
case 93: case 92:
#line 580 "a.y" #line 575 "a.y"
{ {
(yyval.lval) = REGPC; (yyval.lval) = REGPC;
} }
break; break;
case 94: case 93:
#line 584 "a.y" #line 579 "a.y"
{ {
if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG) if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG)
print("register value out of range\n"); print("register value out of range in R(...)\n");
(yyval.lval) = (yyvsp[(3) - (4)].lval); (yyval.lval) = REG_R0 + (yyvsp[(3) - (4)].lval);
} }
break; break;
case 96: case 95:
#line 593 "a.y" #line 588 "a.y"
{ {
(yyval.lval) = REGSP; (yyval.lval) = REGSP;
} }
break; break;
case 98: case 97:
#line 600 "a.y" #line 595 "a.y"
{ {
if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG) if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG)
print("register value out of range\n"); print("register value out of range in C(...)\n");
(yyval.lval) = (yyvsp[(3) - (4)].lval); (yyval.lval) = (yyvsp[(3) - (4)].lval); // TODO(rsc): REG_C0+$3
} }
break; break;
case 101: case 100:
#line 612 "a.y" #line 607 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_FREG; (yyval.addr).type = TYPE_REG;
(yyval.addr).reg = (yyvsp[(1) - (1)].lval); (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
} }
break; break;
case 102: case 101:
#line 618 "a.y" #line 613 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_FREG; (yyval.addr).type = TYPE_REG;
(yyval.addr).reg = (yyvsp[(3) - (4)].lval); (yyval.addr).reg = REG_F0 + (yyvsp[(3) - (4)].lval);
} }
break; break;
case 103: case 102:
#line 626 "a.y" #line 621 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_OREG; (yyval.addr).type = TYPE_MEM;
(yyval.addr).name = (yyvsp[(3) - (4)].lval); (yyval.addr).name = (yyvsp[(3) - (4)].lval);
(yyval.addr).sym = nil; (yyval.addr).sym = nil;
(yyval.addr).offset = (yyvsp[(1) - (4)].lval); (yyval.addr).offset = (yyvsp[(1) - (4)].lval);
} }
break; break;
case 104: case 103:
#line 634 "a.y" #line 629 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_OREG; (yyval.addr).type = TYPE_MEM;
(yyval.addr).name = (yyvsp[(4) - (5)].lval); (yyval.addr).name = (yyvsp[(4) - (5)].lval);
(yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (5)].sym)->name, 0); (yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (5)].sym)->name, 0);
(yyval.addr).offset = (yyvsp[(2) - (5)].lval); (yyval.addr).offset = (yyvsp[(2) - (5)].lval);
} }
break; break;
case 105: case 104:
#line 642 "a.y" #line 637 "a.y"
{ {
(yyval.addr) = nullgen; (yyval.addr) = nullgen;
(yyval.addr).type = D_OREG; (yyval.addr).type = TYPE_MEM;
(yyval.addr).name = D_STATIC; (yyval.addr).name = NAME_STATIC;
(yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (7)].sym)->name, 1); (yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (7)].sym)->name, 1);
(yyval.addr).offset = (yyvsp[(4) - (7)].lval); (yyval.addr).offset = (yyvsp[(4) - (7)].lval);
} }
break; break;
case 106: case 105:
#line 651 "a.y" #line 646 "a.y"
{ {
(yyval.lval) = 0; (yyval.lval) = 0;
} }
break; break;
case 107: case 106:
#line 655 "a.y" #line 650 "a.y"
{ {
(yyval.lval) = (yyvsp[(2) - (2)].lval); (yyval.lval) = (yyvsp[(2) - (2)].lval);
} }
break; break;
case 108: case 107:
#line 659 "a.y" #line 654 "a.y"
{ {
(yyval.lval) = -(yyvsp[(2) - (2)].lval); (yyval.lval) = -(yyvsp[(2) - (2)].lval);
} }
break; break;
case 113: case 112:
#line 671 "a.y" #line 666 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (1)].sym)->value; (yyval.lval) = (yyvsp[(1) - (1)].sym)->value;
} }
break; break;
case 114: case 113:
#line 675 "a.y" #line 670 "a.y"
{ {
(yyval.lval) = -(yyvsp[(2) - (2)].lval); (yyval.lval) = -(yyvsp[(2) - (2)].lval);
} }
break; break;
case 115: case 114:
#line 679 "a.y" #line 674 "a.y"
{ {
(yyval.lval) = (yyvsp[(2) - (2)].lval); (yyval.lval) = (yyvsp[(2) - (2)].lval);
} }
break; break;
case 116: case 115:
#line 683 "a.y" #line 678 "a.y"
{ {
(yyval.lval) = ~(yyvsp[(2) - (2)].lval); (yyval.lval) = ~(yyvsp[(2) - (2)].lval);
} }
break; break;
case 117: case 116:
#line 687 "a.y" #line 682 "a.y"
{ {
(yyval.lval) = (yyvsp[(2) - (3)].lval); (yyval.lval) = (yyvsp[(2) - (3)].lval);
} }
break; break;
case 118: case 117:
#line 692 "a.y" #line 687 "a.y"
{ {
(yyval.lval) = 0; (yyval.lval) = 0;
} }
break; break;
case 119: case 118:
#line 696 "a.y" #line 691 "a.y"
{ {
(yyval.lval) = (yyvsp[(2) - (2)].lval); (yyval.lval) = (yyvsp[(2) - (2)].lval);
} }
break; break;
case 121: case 120:
#line 703 "a.y" #line 698 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval);
} }
break; break;
case 122: case 121:
#line 707 "a.y" #line 702 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval);
} }
break; break;
case 123: case 122:
#line 711 "a.y" #line 706 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval);
} }
break; break;
case 124: case 123:
#line 715 "a.y" #line 710 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval);
} }
break; break;
case 125: case 124:
#line 719 "a.y" #line 714 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval);
} }
break; break;
case 126: case 125:
#line 723 "a.y" #line 718 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval); (yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval);
} }
break; break;
case 127: case 126:
#line 727 "a.y" #line 722 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval); (yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval);
} }
break; break;
case 128: case 127:
#line 731 "a.y" #line 726 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval);
} }
break; break;
case 129: case 128:
#line 735 "a.y" #line 730 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval);
} }
break; break;
case 130: case 129:
#line 739 "a.y" #line 734 "a.y"
{ {
(yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval); (yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval);
} }
...@@ -2572,7 +2552,7 @@ yyreduce: ...@@ -2572,7 +2552,7 @@ yyreduce:
/* Line 1267 of yacc.c. */ /* Line 1267 of yacc.c. */
#line 2576 "y.tab.c" #line 2556 "y.tab.c"
default: break; default: break;
} }
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
......
...@@ -1029,7 +1029,7 @@ agenr(Node *n, Node *a, Node *res) ...@@ -1029,7 +1029,7 @@ agenr(Node *n, Node *a, Node *res)
regalloc(&n3, types[tptr], res); regalloc(&n3, types[tptr], res);
p1 = gins(AMOVW, N, &n3); p1 = gins(AMOVW, N, &n3);
datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from); datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
p1->from.type = D_CONST; p1->from.type = TYPE_CONST;
} else } else
if(isslice(nl->type) || nl->type->etype == TSTRING) { if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3; n1 = n3;
...@@ -1552,7 +1552,7 @@ sgen(Node *n, Node *res, int64 w) ...@@ -1552,7 +1552,7 @@ sgen(Node *n, Node *res, int64 w)
regalloc(&nend, types[TUINT32], N); regalloc(&nend, types[TUINT32], N);
p = gins(AMOVW, &src, &nend); p = gins(AMOVW, &src, &nend);
p->from.type = D_CONST; p->from.type = TYPE_CONST;
if(dir < 0) if(dir < 0)
p->from.offset = dir; p->from.offset = dir;
else else
...@@ -1562,24 +1562,24 @@ sgen(Node *n, Node *res, int64 w) ...@@ -1562,24 +1562,24 @@ sgen(Node *n, Node *res, int64 w)
// move src and dest to the end of block if necessary // move src and dest to the end of block if necessary
if(dir < 0) { if(dir < 0) {
p = gins(AMOVW, &src, &src); p = gins(AMOVW, &src, &src);
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->from.offset = w + dir; p->from.offset = w + dir;
p = gins(AMOVW, &dst, &dst); p = gins(AMOVW, &dst, &dst);
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->from.offset = w + dir; p->from.offset = w + dir;
} }
// move // move
if(c >= 4) { if(c >= 4) {
p = gins(op, &src, &tmp); p = gins(op, &src, &tmp);
p->from.type = D_OREG; p->from.type = TYPE_MEM;
p->from.offset = dir; p->from.offset = dir;
p->scond |= C_PBIT; p->scond |= C_PBIT;
ploop = p; ploop = p;
p = gins(op, &tmp, &dst); p = gins(op, &tmp, &dst);
p->to.type = D_OREG; p->to.type = TYPE_MEM;
p->to.offset = dir; p->to.offset = dir;
p->scond |= C_PBIT; p->scond |= C_PBIT;
...@@ -1591,12 +1591,12 @@ sgen(Node *n, Node *res, int64 w) ...@@ -1591,12 +1591,12 @@ sgen(Node *n, Node *res, int64 w)
} else { } else {
while(c-- > 0) { while(c-- > 0) {
p = gins(op, &src, &tmp); p = gins(op, &src, &tmp);
p->from.type = D_OREG; p->from.type = TYPE_MEM;
p->from.offset = dir; p->from.offset = dir;
p->scond |= C_PBIT; p->scond |= C_PBIT;
p = gins(op, &tmp, &dst); p = gins(op, &tmp, &dst);
p->to.type = D_OREG; p->to.type = TYPE_MEM;
p->to.offset = dir; p->to.offset = dir;
p->scond |= C_PBIT; p->scond |= C_PBIT;
} }
......
...@@ -163,30 +163,30 @@ cgen64(Node *n, Node *res) ...@@ -163,30 +163,30 @@ cgen64(Node *n, Node *res)
// bl * cl -> ah al // bl * cl -> ah al
p1 = gins(AMULLU, N, N); p1 = gins(AMULLU, N, N);
p1->from.type = D_REG; p1->from.type = TYPE_REG;
p1->from.reg = bl.val.u.reg; p1->from.reg = bl.val.u.reg;
p1->reg = cl.val.u.reg; p1->reg = cl.val.u.reg;
p1->to.type = D_REGREG; p1->to.type = TYPE_REGREG;
p1->to.reg = ah.val.u.reg; p1->to.reg = ah.val.u.reg;
p1->to.offset = al.val.u.reg; p1->to.offset = al.val.u.reg;
//print("%P\n", p1); //print("%P\n", p1);
// bl * ch + ah -> ah // bl * ch + ah -> ah
p1 = gins(AMULA, N, N); p1 = gins(AMULA, N, N);
p1->from.type = D_REG; p1->from.type = TYPE_REG;
p1->from.reg = bl.val.u.reg; p1->from.reg = bl.val.u.reg;
p1->reg = ch.val.u.reg; p1->reg = ch.val.u.reg;
p1->to.type = D_REGREG2; p1->to.type = TYPE_REGREG2;
p1->to.reg = ah.val.u.reg; p1->to.reg = ah.val.u.reg;
p1->to.offset = ah.val.u.reg; p1->to.offset = ah.val.u.reg;
//print("%P\n", p1); //print("%P\n", p1);
// bh * cl + ah -> ah // bh * cl + ah -> ah
p1 = gins(AMULA, N, N); p1 = gins(AMULA, N, N);
p1->from.type = D_REG; p1->from.type = TYPE_REG;
p1->from.reg = bh.val.u.reg; p1->from.reg = bh.val.u.reg;
p1->reg = cl.val.u.reg; p1->reg = cl.val.u.reg;
p1->to.type = D_REGREG2; p1->to.type = TYPE_REGREG2;
p1->to.reg = ah.val.u.reg; p1->to.reg = ah.val.u.reg;
p1->to.offset = ah.val.u.reg; p1->to.offset = ah.val.u.reg;
//print("%P\n", p1); //print("%P\n", p1);
......
...@@ -36,14 +36,8 @@ betypeinit(void) ...@@ -36,14 +36,8 @@ betypeinit(void)
widthint = 4; widthint = 4;
widthreg = 4; widthreg = 4;
zprog.link = P;
zprog.as = AGOK; zprog.as = AGOK;
zprog.scond = C_SCOND_NONE; zprog.scond = C_SCOND_NONE;
zprog.reg = NREG;
zprog.from.type = D_NONE;
zprog.from.name = D_NONE;
zprog.from.reg = NREG;
zprog.to = zprog.from;
arch.zprog = zprog; arch.zprog = zprog;
listinit5(); listinit5();
...@@ -73,10 +67,6 @@ main(int argc, char **argv) ...@@ -73,10 +67,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;
......
...@@ -13,10 +13,10 @@ ...@@ -13,10 +13,10 @@
enum enum
{ {
REGALLOC_R0 = 0, REGALLOC_R0 = REG_R0,
REGALLOC_RMAX = REGEXT, REGALLOC_RMAX = REGEXT,
REGALLOC_F0 = NREG, REGALLOC_F0 = REG_F0,
REGALLOC_FMAX = REGALLOC_F0 + FREGEXT, REGALLOC_FMAX = FREGEXT,
}; };
EXTERN int32 dynloc; EXTERN int32 dynloc;
......
...@@ -22,8 +22,8 @@ defframe(Prog *ptxt) ...@@ -22,8 +22,8 @@ defframe(Prog *ptxt)
Node *n; Node *n;
// fill in argument size // fill in argument size
ptxt->to.type = D_CONST2; ptxt->to.type = TYPE_TEXTSIZE;
ptxt->to.offset2 = rnd(curfn->type->argwid, widthptr); ptxt->to.u.argsize = rnd(curfn->type->argwid, widthptr);
// fill in final stack size // fill in final stack size
frame = rnd(stksize+maxarg, widthptr); frame = rnd(stksize+maxarg, widthptr);
...@@ -70,30 +70,30 @@ zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *r0) ...@@ -70,30 +70,30 @@ zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *r0)
if(cnt == 0) if(cnt == 0)
return p; return p;
if(*r0 == 0) { if(*r0 == 0) {
p = appendpp(p, AMOVW, D_CONST, NREG, 0, D_REG, 0, 0); p = appendpp(p, AMOVW, TYPE_CONST, 0, 0, TYPE_REG, REG_R0, 0);
*r0 = 1; *r0 = 1;
} }
if(cnt < 4*widthptr) { if(cnt < 4*widthptr) {
for(i = 0; i < cnt; i += widthptr) for(i = 0; i < cnt; i += widthptr)
p = appendpp(p, AMOVW, D_REG, 0, 0, D_OREG, REGSP, 4+frame+lo+i); p = appendpp(p, AMOVW, TYPE_REG, REG_R0, 0, TYPE_MEM, REGSP, 4+frame+lo+i);
} else if(!nacl && (cnt <= 128*widthptr)) { } else if(!nacl && (cnt <= 128*widthptr)) {
p = appendpp(p, AADD, D_CONST, NREG, 4+frame+lo, D_REG, 1, 0); p = appendpp(p, AADD, TYPE_CONST, 0, 4+frame+lo, TYPE_REG, REG_R1, 0);
p->reg = REGSP; p->reg = REGSP;
p = appendpp(p, ADUFFZERO, D_NONE, NREG, 0, D_OREG, NREG, 0); p = appendpp(p, ADUFFZERO, TYPE_NONE, 0, 0, TYPE_MEM, 0, 0);
f = sysfunc("duffzero"); f = sysfunc("duffzero");
naddr(f, &p->to, 1); naddr(f, &p->to, 1);
afunclit(&p->to, f); afunclit(&p->to, f);
p->to.offset = 4*(128-cnt/widthptr); p->to.offset = 4*(128-cnt/widthptr);
} else { } else {
p = appendpp(p, AADD, D_CONST, NREG, 4+frame+lo, D_REG, 1, 0); p = appendpp(p, AADD, TYPE_CONST, 0, 4+frame+lo, TYPE_REG, REG_R1, 0);
p->reg = REGSP; p->reg = REGSP;
p = appendpp(p, AADD, D_CONST, NREG, cnt, D_REG, 2, 0); p = appendpp(p, AADD, TYPE_CONST, 0, cnt, TYPE_REG, REG_R2, 0);
p->reg = 1; p->reg = REG_R1;
p1 = p = appendpp(p, AMOVW, D_REG, 0, 0, D_OREG, 1, 4); p1 = p = appendpp(p, AMOVW, TYPE_REG, REG_R0, 0, TYPE_MEM, REG_R1, 4);
p->scond |= C_PBIT; p->scond |= C_PBIT;
p = appendpp(p, ACMP, D_REG, 1, 0, D_NONE, 0, 0); p = appendpp(p, ACMP, TYPE_REG, REG_R1, 0, TYPE_NONE, 0, 0);
p->reg = 2; p->reg = REG_R2;
p = appendpp(p, ABNE, D_NONE, NREG, 0, D_BRANCH, NREG, 0); p = appendpp(p, ABNE, TYPE_NONE, 0, 0, TYPE_BRANCH, 0, 0);
patch(p, p1); patch(p, p1);
} }
return p; return p;
...@@ -142,7 +142,7 @@ fixautoused(Prog* p) ...@@ -142,7 +142,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.name == 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;
} }
...@@ -151,16 +151,14 @@ fixautoused(Prog* p) ...@@ -151,16 +151,14 @@ 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.name == 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.name == 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;
...@@ -208,7 +206,7 @@ ginscall(Node *f, int proc) ...@@ -208,7 +206,7 @@ ginscall(Node *f, int proc)
// ARM NOP 0x00000000 is really AND.EQ R0, R0, R0. // ARM NOP 0x00000000 is really AND.EQ R0, R0, R0.
// Use the latter form because the NOP pseudo-instruction // Use the latter form because the NOP pseudo-instruction
// would be removed by the linker. // would be removed by the linker.
nodreg(&r, types[TINT], 0); nodreg(&r, types[TINT], REG_R0);
p = gins(AAND, &r, &r); p = gins(AAND, &r, &r);
p->scond = C_SCOND_EQ; p->scond = C_SCOND_EQ;
} }
...@@ -218,8 +216,8 @@ ginscall(Node *f, int proc) ...@@ -218,8 +216,8 @@ ginscall(Node *f, int proc)
gins(AUNDEF, N, N); gins(AUNDEF, N, N);
break; break;
} }
nodreg(&r, types[tptr], 7); nodreg(&r, types[tptr], REG_R7);
nodreg(&r1, types[tptr], 1); nodreg(&r1, types[tptr], REG_R1);
gmove(f, &r); gmove(f, &r);
r.op = OINDREG; r.op = OINDREG;
gmove(&r, &r1); gmove(&r, &r1);
...@@ -238,7 +236,7 @@ ginscall(Node *f, int proc) ...@@ -238,7 +236,7 @@ ginscall(Node *f, int proc)
nodconst(&con, types[TINT32], argsize(f->type)); nodconst(&con, types[TINT32], argsize(f->type));
gins(AMOVW, &con, &r); gins(AMOVW, &con, &r);
p = gins(AMOVW, &r, N); p = gins(AMOVW, &r, N);
p->to.type = D_OREG; p->to.type = TYPE_MEM;
p->to.reg = REGSP; p->to.reg = REGSP;
p->to.offset = 4; p->to.offset = 4;
...@@ -247,7 +245,7 @@ ginscall(Node *f, int proc) ...@@ -247,7 +245,7 @@ ginscall(Node *f, int proc)
n1.left = f; n1.left = f;
gins(AMOVW, &n1, &r); gins(AMOVW, &n1, &r);
p = gins(AMOVW, &r, N); p = gins(AMOVW, &r, N);
p->to.type = D_OREG; p->to.type = TYPE_MEM;
p->to.reg = REGSP; p->to.reg = REGSP;
p->to.offset = 8; p->to.offset = 8;
...@@ -261,7 +259,7 @@ ginscall(Node *f, int proc) ...@@ -261,7 +259,7 @@ ginscall(Node *f, int proc)
if(proc == 2) { if(proc == 2) {
nodconst(&con, types[TINT32], 0); nodconst(&con, types[TINT32], 0);
p = gins(ACMP, &con, N); p = gins(ACMP, &con, N);
p->reg = 0; p->reg = REG_R0;
p = gbranch(ABEQ, T, +1); p = gbranch(ABEQ, T, +1);
cgen_ret(N); cgen_ret(N);
patch(p, pc); patch(p, pc);
...@@ -337,7 +335,7 @@ cgen_callinter(Node *n, Node *res, int proc) ...@@ -337,7 +335,7 @@ cgen_callinter(Node *n, Node *res, int proc)
} else { } else {
// go/defer. generate go func value. // go/defer. generate go func value.
p = gins(AMOVW, &nodo, &nodr); p = gins(AMOVW, &nodo, &nodr);
p->from.type = D_CONST; // REG = &(20+offset(REG)) -- i.tab->fun[f] p->from.type = TYPE_CONST; // REG = &(20+offset(REG)) -- i.tab->fun[f]
} }
nodr.type = n->left->type; nodr.type = n->left->type;
...@@ -484,8 +482,8 @@ cgen_ret(Node *n) ...@@ -484,8 +482,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.name = D_EXTERN; p->to.name = NAME_EXTERN;
p->to.type = D_CONST; p->to.type = TYPE_CONST;
p->to.sym = linksym(n->left->sym); p->to.sym = linksym(n->left->sym);
} }
} }
...@@ -674,7 +672,7 @@ cgen_hmul(Node *nl, Node *nr, Node *res) ...@@ -674,7 +672,7 @@ cgen_hmul(Node *nl, Node *nr, Node *res)
p = gins(AMULLU, &n2, N); p = gins(AMULLU, &n2, N);
// n2 * n1 -> (n1 n2) // n2 * n1 -> (n1 n2)
p->reg = n1.val.u.reg; p->reg = n1.val.u.reg;
p->to.type = D_REGREG; p->to.type = TYPE_REGREG;
p->to.reg = n1.val.u.reg; p->to.reg = n1.val.u.reg;
p->to.offset = n2.val.u.reg; p->to.offset = n2.val.u.reg;
break; break;
...@@ -862,11 +860,11 @@ clearfat(Node *nl) ...@@ -862,11 +860,11 @@ clearfat(Node *nl)
if(q > 128) { if(q > 128) {
regalloc(&end, types[tptr], N); regalloc(&end, types[tptr], N);
p = gins(AMOVW, &dst, &end); p = gins(AMOVW, &dst, &end);
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->from.offset = q*4; p->from.offset = q*4;
p = gins(AMOVW, &nz, &dst); p = gins(AMOVW, &nz, &dst);
p->to.type = D_OREG; p->to.type = TYPE_MEM;
p->to.offset = 4; p->to.offset = 4;
p->scond |= C_PBIT; p->scond |= C_PBIT;
pl = p; pl = p;
...@@ -885,7 +883,7 @@ clearfat(Node *nl) ...@@ -885,7 +883,7 @@ clearfat(Node *nl)
} else } else
while(q > 0) { while(q > 0) {
p = gins(AMOVW, &nz, &dst); p = gins(AMOVW, &nz, &dst);
p->to.type = D_OREG; p->to.type = TYPE_MEM;
p->to.offset = 4; p->to.offset = 4;
p->scond |= C_PBIT; p->scond |= C_PBIT;
//print("1. %P\n", p); //print("1. %P\n", p);
...@@ -894,7 +892,7 @@ clearfat(Node *nl) ...@@ -894,7 +892,7 @@ clearfat(Node *nl)
while(c > 0) { while(c > 0) {
p = gins(AMOVB, &nz, &dst); p = gins(AMOVB, &nz, &dst);
p->to.type = D_OREG; p->to.type = TYPE_MEM;
p->to.offset = 1; p->to.offset = 1;
p->scond |= C_PBIT; p->scond |= C_PBIT;
//print("2. %P\n", p); //print("2. %P\n", p);
...@@ -917,7 +915,7 @@ expandchecks(Prog *firstp) ...@@ -917,7 +915,7 @@ expandchecks(Prog *firstp)
continue; continue;
if(debug_checknil && p->lineno > 1) // p->lineno==1 in generated wrappers if(debug_checknil && p->lineno > 1) // p->lineno==1 in generated wrappers
warnl(p->lineno, "generated nil check"); warnl(p->lineno, "generated nil check");
if(p->from.type != D_REG) if(p->from.type != TYPE_REG)
fatal("invalid nil check %P", p); fatal("invalid nil check %P", p);
reg = p->from.reg; reg = p->from.reg;
// check is // check is
...@@ -930,15 +928,15 @@ expandchecks(Prog *firstp) ...@@ -930,15 +928,15 @@ expandchecks(Prog *firstp)
p1->lineno = p->lineno; p1->lineno = p->lineno;
p1->pc = 9999; p1->pc = 9999;
p1->as = AMOVW; p1->as = AMOVW;
p1->from.type = D_REG; p1->from.type = TYPE_REG;
p1->from.reg = reg; p1->from.reg = reg;
p1->to.type = D_OREG; p1->to.type = TYPE_MEM;
p1->to.reg = reg; p1->to.reg = reg;
p1->to.offset = 0; p1->to.offset = 0;
p1->scond = C_SCOND_EQ; p1->scond = C_SCOND_EQ;
p->as = ACMP; p->as = ACMP;
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->from.reg = NREG; p->from.reg = 0;
p->from.offset = 0; p->from.offset = 0;
p->reg = reg; p->reg = reg;
} }
......
...@@ -38,18 +38,18 @@ dsname(Sym *sym, int off, char *t, int n) ...@@ -38,18 +38,18 @@ dsname(Sym *sym, int off, char *t, int n)
Prog *p; Prog *p;
p = gins(ADATA, N, N); p = gins(ADATA, N, N);
p->from.type = D_OREG; p->from.type = TYPE_MEM;
p->from.name = D_EXTERN; p->from.name = NAME_EXTERN;
p->from.etype = TINT32; p->from.etype = TINT32;
p->from.offset = off; p->from.offset = off;
p->from.reg = NREG; p->from.reg = 0;
p->from.sym = linksym(sym); p->from.sym = linksym(sym);
p->reg = n; p->reg = n;
p->to.type = D_SCONST; p->to.type = TYPE_SCONST;
p->to.name = D_NONE; p->to.name = NAME_NONE;
p->to.reg = NREG; p->to.reg = 0;
p->to.offset = 0; p->to.offset = 0;
memmove(p->to.u.sval, t, n); memmove(p->to.u.sval, t, n);
return off + n; return off + n;
...@@ -65,11 +65,11 @@ datastring(char *s, int len, Addr *a) ...@@ -65,11 +65,11 @@ datastring(char *s, int len, Addr *a)
Sym *sym; Sym *sym;
sym = stringsym(s, len); sym = stringsym(s, len);
a->type = D_OREG; a->type = TYPE_MEM;
a->name = D_EXTERN; a->name = NAME_EXTERN;
a->etype = TINT32; a->etype = TINT32;
a->offset = widthptr+4; // skip header a->offset = widthptr+4; // skip header
a->reg = NREG; a->reg = 0;
a->sym = linksym(sym); a->sym = linksym(sym);
a->node = sym->def; a->node = sym->def;
} }
...@@ -84,11 +84,11 @@ datagostring(Strlit *sval, Addr *a) ...@@ -84,11 +84,11 @@ datagostring(Strlit *sval, Addr *a)
Sym *sym; Sym *sym;
sym = stringsym(sval->s, sval->len); sym = stringsym(sval->s, sval->len);
a->type = D_OREG; a->type = TYPE_MEM;
a->name = D_EXTERN; a->name = NAME_EXTERN;
a->etype = TSTRING; a->etype = TSTRING;
a->offset = 0; // header a->offset = 0; // header
a->reg = NREG; a->reg = 0;
a->sym = linksym(sym); a->sym = linksym(sym);
a->node = sym->def; a->node = sym->def;
} }
...@@ -134,13 +134,13 @@ gdatacomplex(Node *nam, Mpcplx *cval) ...@@ -134,13 +134,13 @@ gdatacomplex(Node *nam, Mpcplx *cval)
p = gins(ADATA, nam, N); p = gins(ADATA, nam, N);
p->reg = w; p->reg = 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->reg = w; p->reg = 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);
} }
...@@ -153,7 +153,7 @@ gdatastring(Node *nam, Strlit *sval) ...@@ -153,7 +153,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->reg = types[tptr]->width; p->reg = types[tptr]->width;
p->to.type = D_CONST; p->to.type = TYPE_CONST;
p->to.etype = TINT32; p->to.etype = TINT32;
//print("%P\n", p); //print("%P\n", p);
...@@ -170,14 +170,14 @@ dstringptr(Sym *s, int off, char *str) ...@@ -170,14 +170,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_OREG; p->from.type = TYPE_MEM;
p->from.name = D_EXTERN; p->from.name = NAME_EXTERN;
p->from.sym = linksym(s); p->from.sym = linksym(s);
p->from.offset = off; p->from.offset = off;
p->reg = widthptr; p->reg = widthptr;
datastring(str, strlen(str)+1, &p->to); datastring(str, strlen(str)+1, &p->to);
p->to.type = D_CONST; p->to.type = TYPE_CONST;
p->to.etype = TINT32; p->to.etype = TINT32;
off += widthptr; off += widthptr;
...@@ -194,13 +194,13 @@ dgostrlitptr(Sym *s, int off, Strlit *lit) ...@@ -194,13 +194,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_OREG; p->from.type = TYPE_MEM;
p->from.name = D_EXTERN; p->from.name = NAME_EXTERN;
p->from.sym = linksym(s); p->from.sym = linksym(s);
p->from.offset = off; p->from.offset = off;
p->reg = widthptr; p->reg = widthptr;
datagostring(lit, &p->to); datagostring(lit, &p->to);
p->to.type = D_CONST; p->to.type = TYPE_CONST;
p->to.etype = TINT32; p->to.etype = TINT32;
off += widthptr; off += widthptr;
...@@ -231,13 +231,13 @@ dsymptr(Sym *s, int off, Sym *x, int xoff) ...@@ -231,13 +231,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_OREG; p->from.type = TYPE_MEM;
p->from.name = D_EXTERN; p->from.name = NAME_EXTERN;
p->from.sym = linksym(s); p->from.sym = linksym(s);
p->from.offset = off; p->from.offset = off;
p->reg = widthptr; p->reg = widthptr;
p->to.type = D_CONST; p->to.type = TYPE_CONST;
p->to.name = 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;
...@@ -249,4 +249,8 @@ void ...@@ -249,4 +249,8 @@ void
nopout(Prog *p) nopout(Prog *p)
{ {
p->as = ANOP; p->as = ANOP;
p->scond = zprog.scond;
p->from = zprog.from;
p->to = zprog.to;
p->reg = zprog.reg;
} }
...@@ -42,14 +42,14 @@ void ...@@ -42,14 +42,14 @@ void
clearp(Prog *p) clearp(Prog *p)
{ {
p->as = AEND; p->as = AEND;
p->reg = NREG; p->reg = 0;
p->scond = C_SCOND_NONE; p->scond = C_SCOND_NONE;
p->from.type = D_NONE; p->from.type = TYPE_NONE;
p->from.name = D_NONE; p->from.name = NAME_NONE;
p->from.reg = NREG; p->from.reg = 0;
p->to.type = D_NONE; p->to.type = TYPE_NONE;
p->to.name = D_NONE; p->to.name = NAME_NONE;
p->to.reg = NREG; p->to.reg = 0;
p->pc = pcloc; p->pc = pcloc;
pcloc++; pcloc++;
} }
...@@ -124,7 +124,7 @@ gbranch(int as, Type *t, int likely) ...@@ -124,7 +124,7 @@ gbranch(int as, Type *t, int likely)
USED(likely); // TODO: record this for linker USED(likely); // TODO: record this for linker
p = prog(as); p = prog(as);
p->to.type = D_BRANCH; p->to.type = TYPE_BRANCH;
p->to.u.branch = P; p->to.u.branch = P;
return p; return p;
} }
...@@ -135,7 +135,7 @@ gbranch(int as, Type *t, int likely) ...@@ -135,7 +135,7 @@ gbranch(int as, Type *t, int likely)
void void
patch(Prog *p, Prog *to) patch(Prog *p, Prog *to)
{ {
if(p->to.type != D_BRANCH) if(p->to.type != TYPE_BRANCH)
fatal("patch: not a branch"); fatal("patch: not a branch");
p->to.u.branch = to; p->to.u.branch = to;
p->to.offset = to->pc; p->to.offset = to->pc;
...@@ -146,7 +146,7 @@ unpatch(Prog *p) ...@@ -146,7 +146,7 @@ unpatch(Prog *p)
{ {
Prog *q; Prog *q;
if(p->to.type != D_BRANCH) if(p->to.type != TYPE_BRANCH)
fatal("unpatch: not a branch"); fatal("unpatch: not a branch");
q = p->to.u.branch; q = p->to.u.branch;
p->to.u.branch = P; p->to.u.branch = P;
...@@ -197,7 +197,7 @@ ggloblnod(Node *nam) ...@@ -197,7 +197,7 @@ ggloblnod(Node *nam)
p->lineno = nam->lineno; p->lineno = nam->lineno;
p->from.sym->gotype = linksym(ngotype(nam)); p->from.sym->gotype = linksym(ngotype(nam));
p->to.sym = nil; p->to.sym = nil;
p->to.type = D_CONST; p->to.type = TYPE_CONST;
p->to.offset = nam->type->width; p->to.offset = nam->type->width;
if(nam->readonly) if(nam->readonly)
p->reg = RODATA; p->reg = RODATA;
...@@ -211,11 +211,11 @@ ggloblsym(Sym *s, int32 width, int8 flags) ...@@ -211,11 +211,11 @@ ggloblsym(Sym *s, int32 width, int8 flags)
Prog *p; Prog *p;
p = gins(AGLOBL, N, N); p = gins(AGLOBL, N, N);
p->from.type = D_OREG; p->from.type = TYPE_MEM;
p->from.name = D_EXTERN; p->from.name = NAME_EXTERN;
p->from.sym = linksym(s); p->from.sym = linksym(s);
p->to.type = D_CONST; p->to.type = TYPE_CONST;
p->to.name = D_NONE; p->to.name = NAME_NONE;
p->to.offset = width; p->to.offset = width;
p->reg = flags; p->reg = flags;
} }
...@@ -226,8 +226,8 @@ gtrack(Sym *s) ...@@ -226,8 +226,8 @@ gtrack(Sym *s)
Prog *p; Prog *p;
p = gins(AUSEFIELD, N, N); p = gins(AUSEFIELD, N, N);
p->from.type = D_OREG; p->from.type = TYPE_MEM;
p->from.name = D_EXTERN; p->from.name = NAME_EXTERN;
p->from.sym = linksym(s); p->from.sym = linksym(s);
} }
...@@ -249,13 +249,13 @@ isfat(Type *t) ...@@ -249,13 +249,13 @@ isfat(Type *t)
* naddr of func generates code for address of func. * naddr of func generates code for address of func.
* if using opcode that can take address implicitly, * if using opcode that can take address implicitly,
* call afunclit to fix up the argument. * call afunclit to fix up the argument.
* also fix up direct register references to be D_OREG. * also fix up direct register references to be TYPE_MEM.
*/ */
void void
afunclit(Addr *a, Node *n) afunclit(Addr *a, Node *n)
{ {
if(a->type == D_CONST && a->name == D_EXTERN || a->type == D_REG) { if(a->type == TYPE_CONST && a->name == NAME_EXTERN || a->type == TYPE_REG) {
a->type = D_OREG; a->type = TYPE_MEM;
if(n->op == ONAME) if(n->op == ONAME)
a->sym = linksym(n->sym); a->sym = linksym(n->sym);
} }
...@@ -385,7 +385,7 @@ regalloc(Node *n, Type *t, Node *o) ...@@ -385,7 +385,7 @@ regalloc(Node *n, Type *t, Node *o)
yyerror("regalloc: unknown type %T", t); yyerror("regalloc: unknown type %T", t);
err: err:
nodreg(n, t, 0); nodreg(n, t, REG_R0);
return; return;
out: out:
...@@ -852,9 +852,9 @@ gmove(Node *f, Node *t) ...@@ -852,9 +852,9 @@ gmove(Node *f, Node *t)
regalloc(&r2, thi.type, N); regalloc(&r2, thi.type, N);
gmove(f, &r1); gmove(f, &r1);
p1 = gins(AMOVW, &r1, &r2); p1 = gins(AMOVW, &r1, &r2);
p1->from.type = D_SHIFT; p1->from.type = TYPE_SHIFT;
p1->from.offset = 2 << 5 | 31 << 7 | r1.val.u.reg; // r1->31 p1->from.offset = 2 << 5 | 31 << 7 | (r1.val.u.reg&15); // r1->31
p1->from.reg = NREG; p1->from.reg = 0;
//print("gmove: %P\n", p1); //print("gmove: %P\n", p1);
gins(AMOVW, &r1, &tlo); gins(AMOVW, &r1, &tlo);
gins(AMOVW, &r2, &thi); gins(AMOVW, &r2, &thi);
...@@ -1124,12 +1124,12 @@ raddr(Node *n, Prog *p) ...@@ -1124,12 +1124,12 @@ raddr(Node *n, Prog *p)
Addr a; Addr a;
naddr(n, &a, 1); naddr(n, &a, 1);
if(a.type != D_REG && a.type != D_FREG) { if(a.type != TYPE_REG) {
if(n) if(n)
fatal("bad in raddr: %O", n->op); fatal("bad in raddr: %O", n->op);
else else
fatal("bad in raddr: <null>"); fatal("bad in raddr: <null>");
p->reg = NREG; p->reg = 0;
} else } else
p->reg = a.reg; p->reg = a.reg;
} }
...@@ -1164,8 +1164,8 @@ gshift(int as, Node *lhs, int32 stype, int32 sval, Node *rhs) ...@@ -1164,8 +1164,8 @@ gshift(int as, Node *lhs, int32 stype, int32 sval, Node *rhs)
sval = sval&0x1f; sval = sval&0x1f;
p = gins(as, N, rhs); p = gins(as, N, rhs);
p->from.type = D_SHIFT; p->from.type = TYPE_SHIFT;
p->from.offset = stype | sval<<7 | lhs->val.u.reg; p->from.offset = stype | sval<<7 | (lhs->val.u.reg&15);
return p; return p;
} }
...@@ -1176,8 +1176,8 @@ gregshift(int as, Node *lhs, int32 stype, Node *reg, Node *rhs) ...@@ -1176,8 +1176,8 @@ gregshift(int as, Node *lhs, int32 stype, Node *reg, Node *rhs)
{ {
Prog *p; Prog *p;
p = gins(as, N, rhs); p = gins(as, N, rhs);
p->from.type = D_SHIFT; p->from.type = TYPE_SHIFT;
p->from.offset = stype | reg->val.u.reg << 8 | 1<<4 | lhs->val.u.reg; p->from.offset = stype | (reg->val.u.reg&15) << 8 | 1<<4 | (lhs->val.u.reg&15);
return p; return p;
} }
...@@ -1190,9 +1190,9 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1190,9 +1190,9 @@ naddr(Node *n, Addr *a, int canemitcode)
{ {
Sym *s; Sym *s;
a->type = D_NONE; a->type = TYPE_NONE;
a->name = D_NONE; a->name = NAME_NONE;
a->reg = NREG; a->reg = 0;
a->gotype = nil; a->gotype = nil;
a->node = N; a->node = N;
a->etype = 0; a->etype = 0;
...@@ -1210,13 +1210,8 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1210,13 +1210,8 @@ naddr(Node *n, Addr *a, int canemitcode)
break; break;
case OREGISTER: case OREGISTER:
if(n->val.u.reg <= REGALLOC_RMAX) { a->type = TYPE_REG;
a->type = D_REG; a->reg = n->val.u.reg;
a->reg = n->val.u.reg;
} else {
a->type = D_FREG;
a->reg = n->val.u.reg - REGALLOC_F0;
}
a->sym = nil; a->sym = nil;
break; break;
...@@ -1227,12 +1222,12 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1227,12 +1222,12 @@ naddr(Node *n, Addr *a, int canemitcode)
// if(a->type >= D_AX && a->type <= D_DI) // if(a->type >= D_AX && a->type <= D_DI)
// a->type += D_INDIR; // a->type += D_INDIR;
// else // else
// if(a->type == D_CONST) // if(a->type == TYPE_CONST)
// a->type = D_NONE+D_INDIR; // a->type = TYPE_NONE+D_INDIR;
// else // else
// if(a->type == D_ADDR) { // if(a->type == TYPE_ADDR) {
// a->type = a->index; // a->type = a->index;
// a->index = D_NONE; // a->index = TYPE_NONE;
// } else // } else
// goto bad; // goto bad;
// if(n->op == OINDEX) { // if(n->op == OINDEX) {
...@@ -1242,7 +1237,7 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1242,7 +1237,7 @@ naddr(Node *n, Addr *a, int canemitcode)
// break; // break;
case OINDREG: case OINDREG:
a->type = D_OREG; a->type = TYPE_MEM;
a->reg = n->val.u.reg; a->reg = n->val.u.reg;
a->sym = linksym(n->sym); a->sym = linksym(n->sym);
a->offset = n->xoffset; a->offset = n->xoffset;
...@@ -1255,16 +1250,16 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1255,16 +1250,16 @@ naddr(Node *n, Addr *a, int canemitcode)
a->width = n->left->type->width; a->width = n->left->type->width;
a->offset = n->xoffset; a->offset = n->xoffset;
a->sym = linksym(n->left->sym); a->sym = linksym(n->left->sym);
a->type = D_OREG; a->type = TYPE_MEM;
a->name = D_PARAM; a->name = NAME_PARAM;
a->node = n->left->orig; a->node = n->left->orig;
break; break;
case OCLOSUREVAR: case OCLOSUREVAR:
if(!curfn->needctxt) if(!curfn->needctxt)
fatal("closurevar without needctxt"); fatal("closurevar without needctxt");
a->type = D_OREG; a->type = TYPE_MEM;
a->reg = 7; a->reg = REG_R7;
a->offset = n->xoffset; a->offset = n->xoffset;
a->sym = nil; a->sym = nil;
break; break;
...@@ -1277,7 +1272,7 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1277,7 +1272,7 @@ naddr(Node *n, Addr *a, int canemitcode)
case ONAME: case ONAME:
a->etype = 0; a->etype = 0;
a->width = 0; a->width = 0;
a->reg = NREG; a->reg = 0;
if(n->type != T) { if(n->type != T) {
a->etype = simtype[n->type->etype]; a->etype = simtype[n->type->etype];
a->width = n->type->width; a->width = n->type->width;
...@@ -1296,23 +1291,23 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1296,23 +1291,23 @@ naddr(Node *n, Addr *a, int canemitcode)
s = pkglookup(s->name, n->type->sym->pkg); s = pkglookup(s->name, n->type->sym->pkg);
} }
a->type = D_OREG; a->type = TYPE_MEM;
switch(n->class) { switch(n->class) {
default: default:
fatal("naddr: ONAME class %S %d\n", n->sym, n->class); fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
case PEXTERN: case PEXTERN:
a->name = D_EXTERN; a->name = NAME_EXTERN;
break; break;
case PAUTO: case PAUTO:
a->name = D_AUTO; a->name = NAME_AUTO;
break; break;
case PPARAM: case PPARAM:
case PPARAMOUT: case PPARAMOUT:
a->name = D_PARAM; a->name = NAME_PARAM;
break; break;
case PFUNC: case PFUNC:
a->name = D_EXTERN; a->name = NAME_EXTERN;
a->type = D_CONST; a->type = TYPE_CONST;
s = funcsym(s); s = funcsym(s);
break; break;
} }
...@@ -1325,13 +1320,13 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1325,13 +1320,13 @@ naddr(Node *n, Addr *a, int canemitcode)
fatal("naddr: const %lT", n->type); fatal("naddr: const %lT", n->type);
break; break;
case CTFLT: case CTFLT:
a->type = D_FCONST; a->type = TYPE_FCONST;
a->u.dval = mpgetflt(n->val.u.fval); a->u.dval = mpgetflt(n->val.u.fval);
break; break;
case CTINT: case CTINT:
case CTRUNE: case CTRUNE:
a->sym = nil; a->sym = nil;
a->type = D_CONST; a->type = TYPE_CONST;
a->offset = mpgetfix(n->val.u.xval); a->offset = mpgetfix(n->val.u.xval);
break; break;
case CTSTR: case CTSTR:
...@@ -1339,12 +1334,12 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1339,12 +1334,12 @@ naddr(Node *n, Addr *a, int canemitcode)
break; break;
case CTBOOL: case CTBOOL:
a->sym = nil; a->sym = nil;
a->type = D_CONST; a->type = TYPE_CONST;
a->offset = n->val.u.bval; a->offset = n->val.u.bval;
break; break;
case CTNIL: case CTNIL:
a->sym = nil; a->sym = nil;
a->type = D_CONST; a->type = TYPE_CONST;
a->offset = 0; a->offset = 0;
break; break;
} }
...@@ -1354,7 +1349,7 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1354,7 +1349,7 @@ naddr(Node *n, Addr *a, int canemitcode)
// itable of interface value // itable of interface value
naddr(n->left, a, canemitcode); naddr(n->left, a, canemitcode);
a->etype = simtype[tptr]; a->etype = simtype[tptr];
if(a->type == D_CONST && a->offset == 0) if(a->type == TYPE_CONST && a->offset == 0)
break; // len(nil) break; // len(nil)
a->width = widthptr; a->width = widthptr;
break; break;
...@@ -1362,7 +1357,7 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1362,7 +1357,7 @@ naddr(Node *n, Addr *a, int canemitcode)
case OSPTR: case OSPTR:
// pointer in a string or slice // pointer in a string or slice
naddr(n->left, a, canemitcode); naddr(n->left, a, canemitcode);
if(a->type == D_CONST && a->offset == 0) if(a->type == TYPE_CONST && a->offset == 0)
break; // ptr(nil) break; // ptr(nil)
a->etype = simtype[tptr]; a->etype = simtype[tptr];
a->offset += Array_array; a->offset += Array_array;
...@@ -1373,7 +1368,7 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1373,7 +1368,7 @@ naddr(Node *n, Addr *a, int canemitcode)
// len of string or slice // len of string or slice
naddr(n->left, a, canemitcode); naddr(n->left, a, canemitcode);
a->etype = TINT32; a->etype = TINT32;
if(a->type == D_CONST && a->offset == 0) if(a->type == TYPE_CONST && a->offset == 0)
break; // len(nil) break; // len(nil)
a->offset += Array_nel; a->offset += Array_nel;
break; break;
...@@ -1382,7 +1377,7 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1382,7 +1377,7 @@ naddr(Node *n, Addr *a, int canemitcode)
// cap of string or slice // cap of string or slice
naddr(n->left, a, canemitcode); naddr(n->left, a, canemitcode);
a->etype = TINT32; a->etype = TINT32;
if(a->type == D_CONST && a->offset == 0) if(a->type == TYPE_CONST && a->offset == 0)
break; // cap(nil) break; // cap(nil)
a->offset += Array_cap; a->offset += Array_cap;
break; break;
...@@ -1391,12 +1386,12 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1391,12 +1386,12 @@ naddr(Node *n, Addr *a, int canemitcode)
naddr(n->left, a, canemitcode); naddr(n->left, a, canemitcode);
a->etype = tptr; a->etype = tptr;
switch(a->type) { switch(a->type) {
case D_OREG: case TYPE_MEM:
a->type = D_CONST; a->type = TYPE_CONST;
break; break;
case D_REG: case TYPE_REG:
case D_CONST: case TYPE_CONST:
break; break;
default: default:
...@@ -1903,8 +1898,8 @@ odot: ...@@ -1903,8 +1898,8 @@ odot:
n1.xoffset = -(oary[i]+1); n1.xoffset = -(oary[i]+1);
} }
a->type = D_NONE; a->type = TYPE_NONE;
a->name = D_NONE; a->name = NAME_NONE;
n1.type = n->type; n1.type = n->type;
naddr(&n1, a, 1); naddr(&n1, a, 1);
goto yes; goto yes;
...@@ -2022,7 +2017,7 @@ oindex: ...@@ -2022,7 +2017,7 @@ oindex:
} }
naddr(reg1, a, 1); naddr(reg1, a, 1);
a->type = D_OREG; a->type = TYPE_MEM;
a->reg = reg->val.u.reg; a->reg = reg->val.u.reg;
a->offset = 0; a->offset = 0;
goto yes; goto yes;
...@@ -2069,8 +2064,8 @@ oindex_const: ...@@ -2069,8 +2064,8 @@ oindex_const:
n2 = *reg; n2 = *reg;
n2.op = OINDREG; n2.op = OINDREG;
n2.xoffset = v * (*w); n2.xoffset = v * (*w);
a->type = D_NONE; a->type = TYPE_NONE;
a->name = D_NONE; a->name = NAME_NONE;
naddr(&n2, a, 1); naddr(&n2, a, 1);
goto yes; goto yes;
......
...@@ -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,
...@@ -116,8 +116,6 @@ struct Rgn ...@@ -116,8 +116,6 @@ struct Rgn
short regno; short regno;
}; };
EXTERN int32 exregoffset; // not set
EXTERN int32 exfregoffset; // not set
EXTERN Reg zreg; EXTERN Reg zreg;
EXTERN Reg* freer; EXTERN Reg* freer;
EXTERN Reg** rpo2r; EXTERN Reg** rpo2r;
...@@ -126,7 +124,6 @@ EXTERN Rgn* rgp; ...@@ -126,7 +124,6 @@ EXTERN Rgn* rgp;
EXTERN int nregion; EXTERN int nregion;
EXTERN int nvar; EXTERN int nvar;
EXTERN int32 regbits; EXTERN int32 regbits;
EXTERN int32 exregbits;
EXTERN Bits externs; EXTERN Bits externs;
EXTERN Bits params; EXTERN Bits params;
EXTERN Bits consts; EXTERN Bits consts;
......
...@@ -46,6 +46,7 @@ static int copysub1(Prog*, Adr*, Adr*, int); ...@@ -46,6 +46,7 @@ static int copysub1(Prog*, Adr*, Adr*, int);
static Flow* findpre(Flow *r, Adr *v); static Flow* findpre(Flow *r, Adr *v);
static int copyau1(Prog *p, Adr *v); static int copyau1(Prog *p, Adr *v);
static int isdconst(Addr *a); static int isdconst(Addr *a);
static int isfloatreg(Addr*);
static uint32 gactive; static uint32 gactive;
...@@ -54,6 +55,7 @@ int shiftprop(Flow *r); ...@@ -54,6 +55,7 @@ int shiftprop(Flow *r);
void constprop(Adr *c1, Adr *v1, Flow *r); void constprop(Adr *c1, Adr *v1, Flow *r);
void predicate(Graph*); void predicate(Graph*);
void void
peep(Prog *firstp) peep(Prog *firstp)
{ {
...@@ -79,7 +81,7 @@ loop1: ...@@ -79,7 +81,7 @@ loop1:
case ASRL: case ASRL:
case ASRA: case ASRA:
/* /*
* elide shift into D_SHIFT operand of subsequent instruction * elide shift into TYPE_SHIFT operand of subsequent instruction
*/ */
// if(shiftprop(r)) { // if(shiftprop(r)) {
// excise(r); // excise(r);
...@@ -94,7 +96,7 @@ loop1: ...@@ -94,7 +96,7 @@ loop1:
case AMOVF: case AMOVF:
case AMOVD: case AMOVD:
if(regtyp(&p->from)) if(regtyp(&p->from))
if(p->from.type == p->to.type) if(p->from.type == p->to.type && isfloatreg(&p->from) == isfloatreg(&p->to))
if(p->scond == C_SCOND_NONE) { if(p->scond == C_SCOND_NONE) {
if(copyprop(g, r)) { if(copyprop(g, r)) {
excise(r); excise(r);
...@@ -113,13 +115,14 @@ loop1: ...@@ -113,13 +115,14 @@ loop1:
case AMOVHU: case AMOVHU:
case AMOVBS: case AMOVBS:
case AMOVBU: case AMOVBU:
if(p->from.type == D_REG) { if(p->from.type == TYPE_REG) {
if(shortprop(r)) if(shortprop(r))
t++; t++;
} }
break; break;
#ifdef NOTDEF #ifdef NOTDEF
XXX
if(p->scond == C_SCOND_NONE) if(p->scond == C_SCOND_NONE)
if(regtyp(&p->to)) if(regtyp(&p->to))
if(isdconst(&p->from)) { if(isdconst(&p->from)) {
...@@ -141,12 +144,12 @@ loop1: ...@@ -141,12 +144,12 @@ loop1:
*/ */
if(isdconst(&p->from) && p->from.offset == -1) { if(isdconst(&p->from) && p->from.offset == -1) {
p->as = AMVN; p->as = AMVN;
p->from.type = D_REG; p->from.type = TYPE_REG;
if(p->reg != NREG) if(p->reg != 0)
p->from.reg = p->reg; p->from.reg = p->reg;
else else
p->from.reg = p->to.reg; p->from.reg = p->to.reg;
p->reg = NREG; p->reg = 0;
} }
break; break;
} }
...@@ -159,10 +162,10 @@ loop1: ...@@ -159,10 +162,10 @@ loop1:
case AMOVB: case AMOVB:
case AMOVBS: case AMOVBS:
case AMOVBU: case AMOVBU:
if(p->from.type == D_OREG && p->from.offset == 0) if(p->from.type == TYPE_MEM && p->from.offset == 0)
xtramodes(g, r, &p->from); xtramodes(g, r, &p->from);
else else
if(p->to.type == D_OREG && p->to.offset == 0) if(p->to.type == TYPE_MEM && p->to.offset == 0)
xtramodes(g, r, &p->to); xtramodes(g, r, &p->to);
else else
continue; continue;
...@@ -205,17 +208,17 @@ loop1: ...@@ -205,17 +208,17 @@ loop1:
// if(r1 == nil) // if(r1 == nil)
// continue; // continue;
// p1 = r1->prog; // p1 = r1->prog;
// if(p1->to.type != D_REG) // if(p1->to.type != TYPE_REG)
// continue; // continue;
// if(p1->to.reg != p->reg) // if(p1->to.reg != p->reg)
// if(!(p1->as == AMOVW && p1->from.type == D_REG && p1->from.reg == p->reg)) // if(!(p1->as == AMOVW && p1->from.type == TYPE_REG && p1->from.reg == p->reg))
// continue; // continue;
// //
// switch(p1->as) { // switch(p1->as) {
// default: // default:
// continue; // continue;
// case AMOVW: // case AMOVW:
// if(p1->from.type != D_REG) // if(p1->from.type != TYPE_REG)
// continue; // continue;
// case AAND: // case AAND:
// case AEOR: // case AEOR:
...@@ -245,12 +248,7 @@ loop1: ...@@ -245,12 +248,7 @@ loop1:
int int
regtyp(Adr *a) regtyp(Adr *a)
{ {
return a->type == TYPE_REG && (REG_R0 <= a->reg && a->reg <= REG_R15 || REG_F0 <= a->reg && a->reg <= REG_F15);
if(a->type == D_REG)
return 1;
if(a->type == D_FREG)
return 1;
return 0;
} }
/* /*
...@@ -293,7 +291,7 @@ subprop(Flow *r0) ...@@ -293,7 +291,7 @@ subprop(Flow *r0)
if(info.flags & Call) if(info.flags & Call)
return 0; return 0;
if((info.flags & CanRegRead) && p->to.type == D_REG) { if((info.flags & CanRegRead) && p->to.type == TYPE_REG) {
info.flags |= RegRead; info.flags |= RegRead;
info.flags &= ~(CanRegRead | RightRead); info.flags &= ~(CanRegRead | RightRead);
p->reg = p->to.reg; p->reg = p->to.reg;
...@@ -575,12 +573,12 @@ shiftprop(Flow *r) ...@@ -575,12 +573,12 @@ shiftprop(Flow *r)
Adr a; Adr a;
p = r->prog; p = r->prog;
if(p->to.type != D_REG) if(p->to.type != TYPE_REG)
FAIL("BOTCH: result not reg"); FAIL("BOTCH: result not reg");
n = p->to.reg; n = p->to.reg;
a = zprog.from; a = zprog.from;
if(p->reg != NREG && p->reg != p->to.reg) { if(p->reg != 0 && p->reg != p->to.reg) {
a.type = D_REG; a.type = TYPE_REG;
a.reg = p->reg; a.reg = p->reg;
} }
if(debug['P']) if(debug['P'])
...@@ -598,8 +596,8 @@ shiftprop(Flow *r) ...@@ -598,8 +596,8 @@ shiftprop(Flow *r)
print("\n%P", p1); print("\n%P", p1);
switch(copyu(p1, &p->to, nil)) { switch(copyu(p1, &p->to, nil)) {
case 0: /* not used or set */ case 0: /* not used or set */
if((p->from.type == D_REG && copyu(p1, &p->from, nil) > 1) || if((p->from.type == TYPE_REG && copyu(p1, &p->from, nil) > 1) ||
(a.type == D_REG && copyu(p1, &a, nil) > 1)) (a.type == TYPE_REG && copyu(p1, &a, nil) > 1))
FAIL("args modified"); FAIL("args modified");
continue; continue;
case 3: /* set, not used */ case 3: /* set, not used */
...@@ -620,8 +618,8 @@ shiftprop(Flow *r) ...@@ -620,8 +618,8 @@ shiftprop(Flow *r)
case ASBC: case ASBC:
case ARSB: case ARSB:
case ARSC: case ARSC:
if(p1->reg == n || (p1->reg == NREG && p1->to.type == D_REG && p1->to.reg == n)) { if(p1->reg == n || (p1->reg == 0 && p1->to.type == TYPE_REG && p1->to.reg == n)) {
if(p1->from.type != D_REG) if(p1->from.type != TYPE_REG)
FAIL("can't swap"); FAIL("can't swap");
p1->reg = p1->from.reg; p1->reg = p1->from.reg;
p1->from.reg = n; p1->from.reg = n;
...@@ -648,12 +646,12 @@ shiftprop(Flow *r) ...@@ -648,12 +646,12 @@ shiftprop(Flow *r)
case ACMN: case ACMN:
if(p1->reg == n) if(p1->reg == n)
FAIL("can't swap"); FAIL("can't swap");
if(p1->reg == NREG && p1->to.reg == n) if(p1->reg == 0 && p1->to.reg == n)
FAIL("shift result used twice"); FAIL("shift result used twice");
// case AMVN: // case AMVN:
if(p1->from.type == D_SHIFT) if(p1->from.type == TYPE_SHIFT)
FAIL("shift result used in shift"); FAIL("shift result used in shift");
if(p1->from.type != D_REG || p1->from.reg != n) if(p1->from.type != TYPE_REG || p1->from.reg != n)
FAIL("BOTCH: where is it used?"); FAIL("BOTCH: where is it used?");
break; break;
} }
...@@ -679,18 +677,19 @@ shiftprop(Flow *r) ...@@ -679,18 +677,19 @@ shiftprop(Flow *r)
} }
/* make the substitution */ /* make the substitution */
p2->from.type = D_SHIFT; p2->from.type = TYPE_SHIFT;
p2->from.reg = NREG; p2->from.reg = 0;
o = p->reg; o = p->reg;
if(o == NREG) if(o == 0)
o = p->to.reg; o = p->to.reg;
o &= 15;
switch(p->from.type){ switch(p->from.type){
case D_CONST: case TYPE_CONST:
o |= (p->from.offset&0x1f)<<7; o |= (p->from.offset&0x1f)<<7;
break; break;
case D_REG: case TYPE_REG:
o |= (1<<4) | (p->from.reg<<8); o |= (1<<4) | ((p->from.reg&15)<<8);
break; break;
} }
switch(p->as){ switch(p->as){
...@@ -774,16 +773,16 @@ nochange(Flow *r, Flow *r2, Prog *p) ...@@ -774,16 +773,16 @@ nochange(Flow *r, Flow *r2, Prog *p)
if(r == r2) if(r == r2)
return 1; return 1;
n = 0; n = 0;
if(p->reg != NREG && p->reg != p->to.reg) { if(p->reg != 0 && p->reg != p->to.reg) {
a[n].type = D_REG; a[n].type = TYPE_REG;
a[n++].reg = p->reg; a[n++].reg = p->reg;
} }
switch(p->from.type) { switch(p->from.type) {
case D_SHIFT: case TYPE_SHIFT:
a[n].type = D_REG; a[n].type = TYPE_REG;
a[n++].reg = p->from.offset&0xf; a[n++].reg = REG_R0 + (p->from.offset&0xf);
case D_REG: case TYPE_REG:
a[n].type = D_REG; a[n].type = TYPE_REG;
a[n++].reg = p->from.reg; a[n++].reg = p->from.reg;
} }
if(n == 0) if(n == 0)
...@@ -851,55 +850,55 @@ xtramodes(Graph *g, Flow *r, Adr *a) ...@@ -851,55 +850,55 @@ xtramodes(Graph *g, Flow *r, Adr *a)
p = r->prog; p = r->prog;
v = *a; v = *a;
v.type = D_REG; v.type = TYPE_REG;
r1 = findpre(r, &v); r1 = findpre(r, &v);
if(r1 != nil) { if(r1 != nil) {
p1 = r1->prog; p1 = r1->prog;
if(p1->to.type == D_REG && p1->to.reg == v.reg) if(p1->to.type == TYPE_REG && p1->to.reg == v.reg)
switch(p1->as) { switch(p1->as) {
case AADD: case AADD:
if(p1->scond & C_SBIT) if(p1->scond & C_SBIT)
// avoid altering ADD.S/ADC sequences. // avoid altering ADD.S/ADC sequences.
break; break;
if(p1->from.type == D_REG || if(p1->from.type == TYPE_REG ||
(p1->from.type == D_SHIFT && (p1->from.offset&(1<<4)) == 0 && (p1->from.type == TYPE_SHIFT && (p1->from.offset&(1<<4)) == 0 &&
((p->as != AMOVB && p->as != AMOVBS) || (a == &p->from && (p1->from.offset&~0xf) == 0))) || ((p->as != AMOVB && p->as != AMOVBS) || (a == &p->from && (p1->from.offset&~0xf) == 0))) ||
(p1->from.type == D_CONST && (p1->from.type == TYPE_CONST &&
p1->from.offset > -4096 && p1->from.offset < 4096)) p1->from.offset > -4096 && p1->from.offset < 4096))
if(nochange(uniqs(r1), r, p1)) { if(nochange(uniqs(r1), r, p1)) {
if(a != &p->from || v.reg != p->to.reg) if(a != &p->from || v.reg != p->to.reg)
if (finduse(g, r->s1, &v)) { if (finduse(g, r->s1, &v)) {
if(p1->reg == NREG || p1->reg == v.reg) if(p1->reg == 0 || p1->reg == v.reg)
/* pre-indexing */ /* pre-indexing */
p->scond |= C_WBIT; p->scond |= C_WBIT;
else return 0; else return 0;
} }
switch (p1->from.type) { switch (p1->from.type) {
case D_REG: case TYPE_REG:
/* register offset */ /* register offset */
if(nacl) if(nacl)
return 0; return 0;
a->type = D_SHIFT; a->type = TYPE_SHIFT;
a->offset = p1->from.reg; a->offset = p1->from.reg&15;
break; break;
case D_SHIFT: case TYPE_SHIFT:
/* scaled register offset */ /* scaled register offset */
if(nacl) if(nacl)
return 0; return 0;
a->type = D_SHIFT; a->type = TYPE_SHIFT;
case D_CONST: case TYPE_CONST:
/* immediate offset */ /* immediate offset */
a->offset = p1->from.offset; a->offset = p1->from.offset;
break; break;
} }
if(p1->reg != NREG) if(p1->reg != 0)
a->reg = p1->reg; a->reg = p1->reg;
excise(r1); excise(r1);
return 1; return 1;
} }
break; break;
case AMOVW: case AMOVW:
if(p1->from.type == D_REG) if(p1->from.type == TYPE_REG)
if((r2 = findinc(r1, r, &p1->from)) != nil) { if((r2 = findinc(r1, r, &p1->from)) != nil) {
for(r3=uniqs(r2); r3->prog->as==ANOP; r3=uniqs(r3)) for(r3=uniqs(r2); r3->prog->as==ANOP; r3=uniqs(r3))
; ;
...@@ -948,9 +947,9 @@ copyu(Prog *p, Adr *v, Adr *s) ...@@ -948,9 +947,9 @@ copyu(Prog *p, Adr *v, Adr *s)
return 2; return 2;
case AMOVM: case AMOVM:
if(v->type != D_REG) if(v->type != TYPE_REG)
return 0; return 0;
if(p->from.type == D_CONST) { /* read reglist, read/rar */ if(p->from.type == TYPE_CONST) { /* read reglist, read/rar */
if(s != nil) { if(s != nil) {
if(p->from.offset&(1<<v->reg)) if(p->from.offset&(1<<v->reg))
return 1; return 1;
...@@ -1002,8 +1001,8 @@ copyu(Prog *p, Adr *v, Adr *s) ...@@ -1002,8 +1001,8 @@ copyu(Prog *p, Adr *v, Adr *s)
case AMOVFD: case AMOVFD:
case AMOVDF: case AMOVDF:
if(p->scond&(C_WBIT|C_PBIT)) if(p->scond&(C_WBIT|C_PBIT))
if(v->type == D_REG) { if(v->type == TYPE_REG) {
if(p->from.type == D_OREG || p->from.type == D_SHIFT) { if(p->from.type == TYPE_MEM || p->from.type == TYPE_SHIFT) {
if(p->from.reg == v->reg) if(p->from.reg == v->reg)
return 2; return 2;
} else { } else {
...@@ -1084,7 +1083,7 @@ copyu(Prog *p, Adr *v, Adr *s) ...@@ -1084,7 +1083,7 @@ copyu(Prog *p, Adr *v, Adr *s)
if(copyas(&p->to, v)) { if(copyas(&p->to, v)) {
if(p->scond != C_SCOND_NONE) if(p->scond != C_SCOND_NONE)
return 2; return 2;
if(p->reg == NREG) if(p->reg == 0)
p->reg = p->to.reg; p->reg = p->to.reg;
if(copyau(&p->from, v)) if(copyau(&p->from, v))
return 4; return 4;
...@@ -1143,16 +1142,20 @@ copyu(Prog *p, Adr *v, Adr *s) ...@@ -1143,16 +1142,20 @@ copyu(Prog *p, Adr *v, Adr *s)
return 3; return 3;
case ABL: /* funny */ case ABL: /* funny */
if(v->type == D_REG) { if(v->type == TYPE_REG) {
if(v->reg <= REGEXT && v->reg > exregoffset) // TODO(rsc): REG_R0 and REG_F0 used to be
// (when register numbers started at 0) exregoffset and exfregoffset,
// which are unset entirely.
// It's strange that this handles R0 and F0 differently from the other
// registers. Possible failure to optimize?
if(REG_R0 < v->reg && v->reg <= REGEXT)
return 2; return 2;
if(v->reg == REGARG) if(v->reg == REGARG)
return 2; return 2;
} if(REG_F0 < v->reg && v->reg <= FREGEXT)
if(v->type == D_FREG)
if(v->reg <= FREGEXT && v->reg > exfregoffset)
return 2; return 2;
if(p->from.type == D_REG && v->type == D_REG && p->from.reg == v->reg) }
if(p->from.type == TYPE_REG && v->type == TYPE_REG && p->from.reg == v->reg)
return 2; return 2;
if(s != nil) { if(s != nil) {
...@@ -1166,7 +1169,7 @@ copyu(Prog *p, Adr *v, Adr *s) ...@@ -1166,7 +1169,7 @@ copyu(Prog *p, Adr *v, Adr *s)
case ADUFFZERO: case ADUFFZERO:
// R0 is zero, used by DUFFZERO, cannot be substituted. // R0 is zero, used by DUFFZERO, cannot be substituted.
// R1 is ptr to memory, used and set, cannot be substituted. // R1 is ptr to memory, used and set, cannot be substituted.
if(v->type == D_REG) { if(v->type == TYPE_REG) {
if(v->reg == REGALLOC_R0) if(v->reg == REGALLOC_R0)
return 1; return 1;
if(v->reg == REGALLOC_R0+1) if(v->reg == REGALLOC_R0+1)
...@@ -1176,7 +1179,7 @@ copyu(Prog *p, Adr *v, Adr *s) ...@@ -1176,7 +1179,7 @@ copyu(Prog *p, Adr *v, Adr *s)
case ADUFFCOPY: case ADUFFCOPY:
// R0 is scratch, set by DUFFCOPY, cannot be substituted. // R0 is scratch, set by DUFFCOPY, cannot be substituted.
// R1, R2 areptr to src, dst, used and set, cannot be substituted. // R1, R2 areptr to src, dst, used and set, cannot be substituted.
if(v->type == D_REG) { if(v->type == TYPE_REG) {
if(v->reg == REGALLOC_R0) if(v->reg == REGALLOC_R0)
return 3; return 3;
if(v->reg == REGALLOC_R0+1 || v->reg == REGALLOC_R0+2) if(v->reg == REGALLOC_R0+1 || v->reg == REGALLOC_R0+2)
...@@ -1185,7 +1188,7 @@ copyu(Prog *p, Adr *v, Adr *s) ...@@ -1185,7 +1188,7 @@ copyu(Prog *p, Adr *v, Adr *s)
return 0; return 0;
case ATEXT: /* funny */ case ATEXT: /* funny */
if(v->type == D_REG) if(v->type == TYPE_REG)
if(v->reg == REGARG) if(v->reg == REGARG)
return 3; return 3;
return 0; return 0;
...@@ -1212,7 +1215,7 @@ copyas(Adr *a, Adr *v) ...@@ -1212,7 +1215,7 @@ copyas(Adr *a, Adr *v)
if(a->reg == v->reg) if(a->reg == v->reg)
return 1; return 1;
} else } else
if(v->type == D_CONST) { /* for constprop */ if(v->type == TYPE_CONST) { /* for constprop */
if(a->type == v->type) if(a->type == v->type)
if(a->name == v->name) if(a->name == v->name)
if(a->sym == v->sym) if(a->sym == v->sym)
...@@ -1230,10 +1233,11 @@ sameaddr(Adr *a, Adr *v) ...@@ -1230,10 +1233,11 @@ sameaddr(Adr *a, Adr *v)
return 0; return 0;
if(regtyp(v) && a->reg == v->reg) if(regtyp(v) && a->reg == v->reg)
return 1; return 1;
if(v->type == D_AUTO || v->type == D_PARAM) { // TODO(rsc): Change v->type to v->name and enable.
if(v->offset == a->offset) //if(v->type == NAME_AUTO || v->type == NAME_PARAM) {
return 1; // if(v->offset == a->offset)
} // return 1;
//}
return 0; return 0;
} }
...@@ -1246,94 +1250,31 @@ copyau(Adr *a, Adr *v) ...@@ -1246,94 +1250,31 @@ copyau(Adr *a, Adr *v)
if(copyas(a, v)) if(copyas(a, v))
return 1; return 1;
if(v->type == D_REG) { if(v->type == TYPE_REG) {
if(a->type == D_CONST && a->reg != NREG) { if(a->type == TYPE_CONST && a->reg != 0) {
if(a->reg == v->reg) if(a->reg == v->reg)
return 1; return 1;
} else } else
if(a->type == D_OREG) { if(a->type == TYPE_MEM) {
if(a->reg == v->reg) if(a->reg == v->reg)
return 1; return 1;
} else } else
if(a->type == D_REGREG || a->type == D_REGREG2) { if(a->type == TYPE_REGREG || a->type == TYPE_REGREG2) {
if(a->reg == v->reg) if(a->reg == v->reg)
return 1; return 1;
if(a->offset == v->reg) if(a->offset == v->reg)
return 1; return 1;
} else } else
if(a->type == D_SHIFT) { if(a->type == TYPE_SHIFT) {
if((a->offset&0xf) == v->reg) if((a->offset&0xf) == v->reg - REG_R0)
return 1; return 1;
if((a->offset&(1<<4)) && (a->offset>>8) == v->reg) if((a->offset&(1<<4)) && ((a->offset>>8)&0xf) == v->reg - REG_R0)
return 1; return 1;
} }
} }
return 0; return 0;
} }
static int
a2type(Prog *p)
{
if(p->reg == NREG)
return D_NONE;
switch(p->as) {
default:
fatal("a2type: unhandled %P", p);
case AAND:
case AEOR:
case ASUB:
case ARSB:
case AADD:
case AADC:
case ASBC:
case ARSC:
case ATST:
case ATEQ:
case ACMP:
case ACMN:
case AORR:
case ABIC:
case AMVN:
case ASRL:
case ASRA:
case ASLL:
case AMULU:
case ADIVU:
case AMUL:
case ADIV:
case AMOD:
case AMODU:
case AMULA:
case AMULL:
case AMULAL:
case AMULLU:
case AMULALU:
case AMULWT:
case AMULWB:
case AMULAWT:
case AMULAWB:
return D_REG;
case ACMPF:
case ACMPD:
case AADDF:
case AADDD:
case ASUBF:
case ASUBD:
case AMULF:
case AMULD:
case ADIVF:
case ADIVD:
case ASQRTF:
case ASQRTD:
case AABSF:
case AABSD:
return D_FREG;
}
}
/* /*
* compare v to the center * compare v to the center
* register in p (p->reg) * register in p (p->reg)
...@@ -1341,9 +1282,9 @@ a2type(Prog *p) ...@@ -1341,9 +1282,9 @@ a2type(Prog *p)
static int static int
copyau1(Prog *p, Adr *v) copyau1(Prog *p, Adr *v)
{ {
if(v->type == D_REG && v->reg == NREG) if(v->type == TYPE_REG && v->reg == 0)
return 0; return 0;
return p->reg == v->reg && a2type(p) == v->type; return p->reg == v->reg;
} }
/* /*
...@@ -1356,13 +1297,13 @@ copysub(Adr *a, Adr *v, Adr *s, int f) ...@@ -1356,13 +1297,13 @@ copysub(Adr *a, Adr *v, Adr *s, int f)
if(f) if(f)
if(copyau(a, v)) { if(copyau(a, v)) {
if(a->type == D_SHIFT) { if(a->type == TYPE_SHIFT) {
if((a->offset&0xf) == v->reg) if((a->offset&0xf) == v->reg - REG_R0)
a->offset = (a->offset&~0xf)|s->reg; a->offset = (a->offset&~0xf)|(s->reg&0xf);
if((a->offset&(1<<4)) && (a->offset>>8) == v->reg) if((a->offset&(1<<4)) && ((a->offset>>8)&0xf) == v->reg - REG_R0)
a->offset = (a->offset&~(0xf<<8))|(s->reg<<8); a->offset = (a->offset&~(0xf<<8))|((s->reg&0xf)<<8);
} else } else
if(a->type == D_REGREG || a->type == D_REGREG2) { if(a->type == TYPE_REGREG || a->type == TYPE_REGREG2) {
if(a->offset == v->reg) if(a->offset == v->reg)
a->offset = s->reg; a->offset = s->reg;
if(a->reg == v->reg) if(a->reg == v->reg)
...@@ -1609,11 +1550,17 @@ predicate(Graph *g) ...@@ -1609,11 +1550,17 @@ predicate(Graph *g)
static int static int
isdconst(Addr *a) isdconst(Addr *a)
{ {
if(a->type == D_CONST && a->reg == NREG) if(a->type == TYPE_CONST && a->reg == 0)
return 1; return 1;
return 0; return 0;
} }
static int
isfloatreg(Addr *a)
{
return REG_F0 <= a->reg && a->reg <= REG_F15;
}
int int
stackaddr(Addr *a) stackaddr(Addr *a)
{ {
...@@ -1623,7 +1570,7 @@ stackaddr(Addr *a) ...@@ -1623,7 +1570,7 @@ stackaddr(Addr *a)
int int
smallindir(Addr *a, Addr *reg) smallindir(Addr *a, Addr *reg)
{ {
return reg->type == D_REG && a->type == D_OREG && return reg->type == TYPE_REG && a->type == TYPE_MEM &&
a->reg == reg->reg && a->reg == reg->reg &&
0 <= a->offset && a->offset < 4096; 0 <= a->offset && a->offset < 4096;
} }
...@@ -136,12 +136,12 @@ proginfo(ProgInfo *info, Prog *p) ...@@ -136,12 +136,12 @@ proginfo(ProgInfo *info, Prog *p)
if(info->flags == 0) if(info->flags == 0)
fatal("unknown instruction %P", p); fatal("unknown instruction %P", p);
if(p->from.type == D_CONST && p->from.sym != nil && (info->flags & LeftRead)) { if(p->from.type == TYPE_CONST && p->from.sym != nil && (info->flags & LeftRead)) {
info->flags &= ~LeftRead; info->flags &= ~LeftRead;
info->flags |= LeftAddr; info->flags |= LeftAddr;
} }
if((info->flags & RegRead) && p->reg == NREG) { if((info->flags & RegRead) && p->reg == 0) {
info->flags &= ~RegRead; info->flags &= ~RegRead;
info->flags |= CanRegRead | RightRead; info->flags |= CanRegRead | RightRead;
} }
......
...@@ -67,11 +67,7 @@ excise(Flow *r) ...@@ -67,11 +67,7 @@ excise(Flow *r)
Prog *p; Prog *p;
p = r->prog; p = r->prog;
p->as = ANOP; nopout(p);
p->scond = zprog.scond;
p->from = zprog.from;
p->to = zprog.to;
p->reg = zprog.reg;
} }
static void static void
...@@ -199,7 +195,7 @@ regopt(Prog *firstp) ...@@ -199,7 +195,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 == ABL && p->to.name == D_EXTERN) if(p->as == ABL && p->to.name == NAME_EXTERN)
continue; continue;
bit = mkvar(r, &p->from); bit = mkvar(r, &p->from);
...@@ -209,12 +205,8 @@ regopt(Prog *firstp) ...@@ -209,12 +205,8 @@ regopt(Prog *firstp)
if(info.flags & LeftAddr) if(info.flags & LeftAddr)
setaddrs(bit); setaddrs(bit);
if(info.flags & RegRead) { if(info.flags & RegRead)
if(p->from.type != D_FREG) r->use1.b[0] |= RtoB(p->reg);
r->use1.b[0] |= RtoB(p->reg);
else
r->use1.b[0] |= FtoB(p->reg);
}
if(info.flags & (RightAddr | RightRead | RightWrite)) { if(info.flags & (RightAddr | RightRead | RightWrite)) {
bit = mkvar(r, &p->to); bit = mkvar(r, &p->to);
...@@ -230,7 +222,7 @@ regopt(Prog *firstp) ...@@ -230,7 +222,7 @@ regopt(Prog *firstp)
/* the mod/div runtime routines smash R12 */ /* the mod/div runtime routines smash R12 */
if(p->as == ADIV || p->as == ADIVU || p->as == AMOD || p->as == AMODU) if(p->as == ADIV || p->as == ADIVU || p->as == AMOD || p->as == AMODU)
r->set.b[0] |= RtoB(12); r->set.b[0] |= RtoB(REG_R12);
} }
if(firstr == R) if(firstr == R)
return; return;
...@@ -463,18 +455,11 @@ brk: ...@@ -463,18 +455,11 @@ brk:
vreg = paint2(rgp->enter, rgp->varno, 0); vreg = paint2(rgp->enter, rgp->varno, 0);
vreg = allreg(vreg, rgp); vreg = allreg(vreg, rgp);
if(debug['R']) { if(debug['R']) {
if(rgp->regno >= NREG) print("%L $%d %R: %Q\n",
print("%L $%d F%d: %Q\n", rgp->enter->f.prog->lineno,
rgp->enter->f.prog->lineno, rgp->cost,
rgp->cost, rgp->regno,
rgp->regno-NREG, bit);
bit);
else
print("%L $%d R%d: %Q\n",
rgp->enter->f.prog->lineno,
rgp->cost,
rgp->regno,
bit);
} }
if(rgp->regno != 0) if(rgp->regno != 0)
paint3(rgp->enter, rgp->varno, vreg, rgp->regno); paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
...@@ -529,7 +514,7 @@ brk: ...@@ -529,7 +514,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;
if(p->as == AMOVW && p->to.reg == 13) { if(p->as == AMOVW && p->to.reg == 13) {
...@@ -538,7 +523,7 @@ brk: ...@@ -538,7 +523,7 @@ brk:
// print("%P adjusting %d\n", p, vreg); // print("%P adjusting %d\n", p, vreg);
continue; continue;
} }
if(p->from.type == D_CONST && p->to.type == D_REG) { if(p->from.type == TYPE_CONST && p->to.type == TYPE_REG) {
if(p->from.offset != vreg) if(p->from.offset != vreg)
print("in and out different\n"); print("in and out different\n");
// print("%P finish %d\n", p, vreg); // print("%P finish %d\n", p, vreg);
...@@ -546,18 +531,18 @@ brk: ...@@ -546,18 +531,18 @@ brk:
continue; continue;
} }
// print("%P %d %d from type\n", p, p->from.type, D_CONST); // print("%P %d %d from type\n", p, p->from.type, TYPE_CONST);
// print("%P %d %d to type\n\n", p, p->to.type, D_REG); // print("%P %d %d to type\n\n", p, p->to.type, TYPE_REG);
} }
if(p->as == AMOVW && vreg != 0) { if(p->as == AMOVW && vreg != 0) {
if(p->from.sym != nil) if(p->from.sym != nil)
if(p->from.name == D_AUTO || p->from.name == D_PARAM) { if(p->from.name == NAME_AUTO || p->from.name == NAME_PARAM) {
p->from.offset += vreg; p->from.offset += vreg;
// print("%P adjusting from %d %d\n", p, vreg, p->from.type); // print("%P adjusting from %d %d\n", p, vreg, p->from.type);
} }
if(p->to.sym != nil) if(p->to.sym != nil)
if(p->to.name == D_AUTO || p->to.name == D_PARAM) { if(p->to.name == NAME_AUTO || p->to.name == NAME_PARAM) {
p->to.offset += vreg; p->to.offset += vreg;
// print("%P adjusting to %d %d\n", p, vreg, p->from.type); // print("%P adjusting to %d %d\n", p, vreg, p->from.type);
} }
...@@ -640,7 +625,7 @@ addmove(Reg *r, int bn, int rn, int f) ...@@ -640,7 +625,7 @@ addmove(Reg *r, int bn, int rn, int f)
// If there's a stack fixup coming (after BL newproc or BL deferproc), // If there's a stack fixup coming (after BL newproc or BL deferproc),
// delay the load until after the fixup. // delay the load until after the fixup.
p2 = p->link; p2 = p->link;
if(p2 && p2->as == AMOVW && p2->from.type == D_CONST && p2->from.reg == REGSP && p2->to.reg == REGSP && p2->to.type == D_REG) if(p2 && p2->as == AMOVW && p2->from.type == TYPE_CONST && p2->from.reg == REGSP && p2->to.reg == REGSP && p2->to.type == TYPE_REG)
p = p2; p = p2;
p1->link = p->link; p1->link = p->link;
...@@ -655,9 +640,9 @@ addmove(Reg *r, int bn, int rn, int f) ...@@ -655,9 +640,9 @@ addmove(Reg *r, int bn, int rn, int f)
a->sym = linksym(v->node->sym); a->sym = linksym(v->node->sym);
a->offset = v->offset; a->offset = v->offset;
a->etype = v->etype; a->etype = v->etype;
a->type = D_OREG; a->type = TYPE_MEM;
if(a->etype == TARRAY || a->sym == nil) if(a->etype == TARRAY || a->sym == nil)
a->type = D_CONST; a->type = TYPE_CONST;
if(v->addr) if(v->addr)
fatal("addmove: shouldn't be doing this %A\n", a); fatal("addmove: shouldn't be doing this %A\n", a);
...@@ -693,21 +678,13 @@ addmove(Reg *r, int bn, int rn, int f) ...@@ -693,21 +678,13 @@ addmove(Reg *r, int bn, int rn, int f)
break; break;
} }
p1->from.type = D_REG; p1->from.type = TYPE_REG;
p1->from.reg = rn; p1->from.reg = rn;
if(rn >= NREG) {
p1->from.type = D_FREG;
p1->from.reg = rn-NREG;
}
if(!f) { if(!f) {
p1->from = *a; p1->from = *a;
*a = zprog.from; *a = zprog.from;
a->type = D_REG; a->type = TYPE_REG;
a->reg = rn; a->reg = rn;
if(rn >= NREG) {
a->type = D_FREG;
a->reg = rn-NREG;
}
if(v->etype == TUINT8 || v->etype == TBOOL) if(v->etype == TUINT8 || v->etype == TBOOL)
p1->as = AMOVBU; p1->as = AMOVBU;
if(v->etype == TUINT16) if(v->etype == TUINT16)
...@@ -749,33 +726,33 @@ mkvar(Reg *r, Adr *a) ...@@ -749,33 +726,33 @@ mkvar(Reg *r, Adr *a)
print("type %d %d %D\n", t, a->name, a); print("type %d %d %D\n", t, a->name, a);
goto none; goto none;
case D_NONE: case TYPE_NONE:
case D_FCONST: case TYPE_FCONST:
case D_BRANCH: case TYPE_BRANCH:
break; break;
case D_REGREG: case TYPE_REGREG:
case D_REGREG2: case TYPE_REGREG2:
bit = zbits; bit = zbits;
if(a->offset != NREG) if(a->offset != 0)
bit.b[0] |= RtoB(a->offset); bit.b[0] |= RtoB(a->offset);
if(a->reg != NREG) if(a->reg != 0)
bit.b[0] |= RtoB(a->reg); bit.b[0] |= RtoB(a->reg);
return bit; return bit;
case D_CONST: case TYPE_CONST:
case D_REG: case TYPE_REG:
case D_SHIFT: case TYPE_SHIFT:
if(a->reg != NREG) { if(a->reg != 0) {
bit = zbits; bit = zbits;
bit.b[0] = RtoB(a->reg); bit.b[0] = RtoB(a->reg);
return bit; return bit;
} }
break; break;
case D_OREG: case TYPE_MEM:
if(a->reg != NREG) { if(a->reg != 0) {
if(a == &r->f.prog->from) if(a == &r->f.prog->from)
r->use1.b[0] |= RtoB(a->reg); r->use1.b[0] |= RtoB(a->reg);
else else
...@@ -784,24 +761,16 @@ mkvar(Reg *r, Adr *a) ...@@ -784,24 +761,16 @@ mkvar(Reg *r, Adr *a)
r->set.b[0] |= RtoB(a->reg); r->set.b[0] |= RtoB(a->reg);
} }
break; break;
case D_FREG:
if(a->reg != NREG) {
bit = zbits;
bit.b[0] = FtoB(a->reg);
return bit;
}
break;
} }
switch(a->name) { switch(a->name) {
default: default:
goto none; goto none;
case D_EXTERN: case NAME_EXTERN:
case D_STATIC: case NAME_STATIC:
case D_AUTO: case NAME_AUTO:
case D_PARAM: case NAME_PARAM:
n = a->name; n = a->name;
break; break;
} }
...@@ -878,10 +847,10 @@ mkvar(Reg *r, Adr *a) ...@@ -878,10 +847,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];
...@@ -1103,8 +1072,8 @@ allreg(uint32 b, Rgn *r) ...@@ -1103,8 +1072,8 @@ allreg(uint32 b, Rgn *r)
case TFLOAT64: case TFLOAT64:
i = BtoF(~b); i = BtoF(~b);
if(i && r->cost >= 0) { if(i && r->cost >= 0) {
r->regno = i+NREG; r->regno = i;
return FtoB(i); return RtoB(i);
} }
break; break;
...@@ -1329,13 +1298,9 @@ addreg(Adr *a, int rn) ...@@ -1329,13 +1298,9 @@ addreg(Adr *a, int rn)
{ {
a->sym = nil; a->sym = nil;
a->node = nil; a->node = nil;
a->name = D_NONE; a->name = NAME_NONE;
a->type = D_REG; a->type = TYPE_REG;
a->reg = rn; a->reg = rn;
if(rn >= NREG) {
a->type = D_FREG;
a->reg = rn-NREG;
}
} }
/* /*
...@@ -1345,13 +1310,29 @@ addreg(Adr *a, int rn) ...@@ -1345,13 +1310,29 @@ addreg(Adr *a, int rn)
* ... ... * ... ...
* 10 R10 * 10 R10
* 12 R12 * 12 R12
*
* bit reg
* 18 F2
* 19 F3
* ... ...
* 31 F15
*/ */
uint32 uint32
RtoB(int r) RtoB(int r)
{ {
if(r >= REGTMP-2 && r != 12) // excluded R9 and R10 for m and g, but not R12 if(REG_R0 <= r && r <= REG_R15) {
return 0; if(r >= REGTMP-2 && r != REG_R12) // excluded R9 and R10 for m and g, but not R12
return 1L << r; return 0;
return 1L << (r - REG_R0);
}
if(REG_F0 <= r && r <= REG_F15) {
if(r < REG_F2 || r > REG_F0+NFREG-1)
return 0;
return 1L << ((r - REG_F0) + 16);
}
return 0;
} }
int int
...@@ -1362,33 +1343,16 @@ BtoR(uint32 b) ...@@ -1362,33 +1343,16 @@ BtoR(uint32 b)
b &= 0x11fcL; // excluded R9 and R10 for m and g, but not R12 b &= 0x11fcL; // excluded R9 and R10 for m and g, but not R12
if(b == 0) if(b == 0)
return 0; return 0;
return bitno(b); return bitno(b) + REG_R0;
}
/*
* bit reg
* 18 F2
* 19 F3
* ... ...
* 31 F15
*/
uint32
FtoB(int f)
{
if(f < 2 || f > NFREG-1)
return 0;
return 1L << (f + 16);
} }
int int
BtoF(uint32 b) BtoF(uint32 b)
{ {
b &= 0xfffc0000L; b &= 0xfffc0000L;
if(b == 0) if(b == 0)
return 0; return 0;
return bitno(b) - 16; return bitno(b) - 16 + REG_F0;
} }
void void
......
...@@ -42,24 +42,64 @@ enum ...@@ -42,24 +42,64 @@ enum
enum enum
{ {
REGRET = 0, REG_R0 = 32, // must be 16-aligned
REG_R1,
REG_R2,
REG_R3,
REG_R4,
REG_R5,
REG_R6,
REG_R7,
REG_R8,
REG_R9,
REG_R10,
REG_R11,
REG_R12,
REG_R13,
REG_R14,
REG_R15,
REG_F0, // must be 16-aligned
REG_F1,
REG_F2,
REG_F3,
REG_F4,
REG_F5,
REG_F6,
REG_F7,
REG_F8,
REG_F9,
REG_F10,
REG_F11,
REG_F12,
REG_F13,
REG_F14,
REG_F15,
REG_FPSR, // must be 2-aligned
REG_FPCR,
REG_CPSR, // must be 2-aligned
REG_SPSR,
REGRET = REG_R0,
/* compiler allocates R1 up as temps */ /* compiler allocates R1 up as temps */
/* compiler allocates register variables R3 up */ /* compiler allocates register variables R3 up */
/* compiler allocates external registers R10 down */ /* compiler allocates external registers R10 down */
REGEXT = 10, REGEXT = REG_R10,
/* these two registers are declared in runtime.h */ /* these two registers are declared in runtime.h */
REGG = REGEXT-0, REGG = REGEXT-0,
REGM = REGEXT-1, REGM = REGEXT-1,
REGTMP = 11, REGTMP = REG_R11,
REGSP = 13, REGSP = REG_R13,
REGLINK = 14, REGLINK = REG_R14,
REGPC = 15, REGPC = REG_R15,
NFREG = 16, NFREG = 16,
FREGRET = 0, FREGRET = REG_F0,
FREGEXT = 7, FREGEXT = REG_F7,
FREGTMP = 15, FREGTMP = REG_F15,
}; };
/* compiler allocates register variables F0 up */ /* compiler allocates register variables F0 up */
/* compiler allocates external registers F7 down */ /* compiler allocates external registers F7 down */
...@@ -304,43 +344,6 @@ enum ...@@ -304,43 +344,6 @@ enum
SHIFT_RR = 3<<5, SHIFT_RR = 3<<5,
}; };
enum
{
/* type/name */
D_GOK = 0,
D_NONE = 1,
/* type */
D_BRANCH = (D_NONE+1),
D_OREG = (D_NONE+2),
D_CONST = (D_NONE+7),
D_FCONST = (D_NONE+8),
D_SCONST = (D_NONE+9),
D_PSR = (D_NONE+10),
D_REG = (D_NONE+12),
D_FREG = (D_NONE+13),
D_FILE = (D_NONE+16),
D_OCONST = (D_NONE+17),
D_FILE1 = (D_NONE+18),
D_SHIFT = (D_NONE+19),
D_FPCR = (D_NONE+20),
D_REGREG = (D_NONE+21), // (reg, reg)
D_ADDR = (D_NONE+22),
D_SBIG = (D_NONE+23),
D_CONST2 = (D_NONE+24),
D_REGREG2 = (D_NONE+25), // reg, reg
/* name */
D_EXTERN = (D_NONE+3),
D_STATIC = (D_NONE+4),
D_AUTO = (D_NONE+5),
D_PARAM = (D_NONE+6),
D_LAST = (D_NONE+26),
};
/* /*
* this is the ranlib header * this is the ranlib header
......
...@@ -355,17 +355,6 @@ static uchar xcmp[C_GOK+1][C_GOK+1]; ...@@ -355,17 +355,6 @@ static uchar xcmp[C_GOK+1][C_GOK+1];
static Prog zprg = { static Prog zprg = {
.as = AGOK, .as = AGOK,
.scond = C_SCOND_NONE, .scond = C_SCOND_NONE,
.reg = NREG,
.from = {
.name = D_NONE,
.type = D_NONE,
.reg = NREG,
},
.to = {
.name = D_NONE,
.type = D_NONE,
.reg = NREG,
},
}; };
static LSym *deferreturn; static LSym *deferreturn;
...@@ -441,20 +430,20 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out) ...@@ -441,20 +430,20 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
break; break;
case AB: case AB:
case ABL: case ABL:
if(p->to.type != D_OREG) { if(p->to.type != TYPE_MEM) {
if(out != nil) if(out != nil)
asmout(ctxt, p, o, out); asmout(ctxt, p, o, out);
} else { } else {
if(p->to.offset != 0 || size != 4 || p->to.reg >= 16 || p->to.reg < 0) if(p->to.offset != 0 || size != 4 || p->to.reg > REG_R15 || p->to.reg < REG_R0)
ctxt->diag("unsupported instruction: %P", p); ctxt->diag("unsupported instruction: %P", p);
if((p->pc&15) == 12) if((p->pc&15) == 12)
p->pc += 4; p->pc += 4;
if(out != nil) { if(out != nil) {
out[0] = ((p->scond&C_SCOND)<<28) | 0x03c0013f | (p->to.reg << 12) | (p->to.reg << 16); // BIC $0xc000000f, Rx out[0] = ((p->scond&C_SCOND)<<28) | 0x03c0013f | ((p->to.reg&15) << 12) | ((p->to.reg&15) << 16); // BIC $0xc000000f, Rx
if(p->as == AB) if(p->as == AB)
out[1] = ((p->scond&C_SCOND)<<28) | 0x012fff10 | p->to.reg; // BX Rx out[1] = ((p->scond&C_SCOND)<<28) | 0x012fff10 | (p->to.reg&15)<<0; // BX Rx
else // ABL else // ABL
out[1] = ((p->scond&C_SCOND)<<28) | 0x012fff30 | p->to.reg; // BLX Rx out[1] = ((p->scond&C_SCOND)<<28) | 0x012fff30 | (p->to.reg&15)<<0; // BLX Rx
} }
size = 8; size = 8;
} }
...@@ -482,7 +471,7 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out) ...@@ -482,7 +471,7 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
case AMOVW: case AMOVW:
case ASTREX: case ASTREX:
case ASTREXD: case ASTREXD:
if(p->to.type == D_REG && p->to.reg == 15 && p->from.reg == 13) { // MOVW.W x(R13), PC if(p->to.type == TYPE_REG && p->to.reg == REG_R15 && p->from.reg == REG_R13) { // MOVW.W x(R13), PC
if(out != nil) if(out != nil)
asmout(ctxt, p, o, out); asmout(ctxt, p, o, out);
if(size == 4) { if(size == 4) {
...@@ -514,10 +503,10 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out) ...@@ -514,10 +503,10 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
} }
} }
if(p->to.type == D_REG && p->to.reg == 15) if(p->to.type == TYPE_REG && p->to.reg == REG_R15)
ctxt->diag("unsupported instruction (move to another register and use indirect jump instead): %P", p); ctxt->diag("unsupported instruction (move to another register and use indirect jump instead): %P", p);
if(p->to.type == D_OREG && p->to.reg == 13 && (p->scond & C_WBIT) && size > 4) { if(p->to.type == TYPE_MEM && p->to.reg == REG_R13 && (p->scond & C_WBIT) && size > 4) {
// function prolog with very large frame size: MOVW.W R14,-100004(R13) // function prolog with very large frame size: MOVW.W R14,-100004(R13)
// split it into two instructions: // split it into two instructions:
// ADD $-100004, R13 // ADD $-100004, R13
...@@ -526,7 +515,7 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out) ...@@ -526,7 +515,7 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
p->scond &= ~C_WBIT; p->scond &= ~C_WBIT;
*q = *p; *q = *p;
a = &p->to; a = &p->to;
if(p->to.type == D_OREG) if(p->to.type == TYPE_MEM)
a2 = &q->to; a2 = &q->to;
else else
a2 = &q->from; a2 = &q->from;
...@@ -539,37 +528,37 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out) ...@@ -539,37 +528,37 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
// make p into ADD $X, R13 // make p into ADD $X, R13
p->as = AADD; p->as = AADD;
p->from = *a; p->from = *a;
p->from.reg = NREG; p->from.reg = 0;
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->to = zprg.to; p->to = zprg.to;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = 13; p->to.reg = REG_R13;
// make q into p but load/store from 0(R13) // make q into p but load/store from 0(R13)
q->spadj = 0; q->spadj = 0;
*a2 = zprg.from; *a2 = zprg.from;
a2->type = D_OREG; a2->type = TYPE_MEM;
a2->reg = 13; a2->reg = REG_R13;
a2->sym = nil; a2->sym = nil;
a2->offset = 0; a2->offset = 0;
size = oplook(ctxt, p)->size; size = oplook(ctxt, p)->size;
break; break;
} }
if((p->to.type == D_OREG && p->to.reg != 13 && p->to.reg != 9) || // MOVW Rx, X(Ry), y != 13 && y != 9 if((p->to.type == TYPE_MEM && p->to.reg != REG_R13 && p->to.reg != REG_R9) || // MOVW Rx, X(Ry), y != 13 && y != 9
(p->from.type == D_OREG && p->from.reg != 13 && p->from.reg != 9)) { // MOVW X(Rx), Ry, x != 13 && x != 9 (p->from.type == TYPE_MEM && p->from.reg != REG_R13 && p->from.reg != REG_R9)) { // MOVW X(Rx), Ry, x != 13 && x != 9
if(p->to.type == D_OREG) if(p->to.type == TYPE_MEM)
a = &p->to; a = &p->to;
else else
a = &p->from; a = &p->from;
reg = a->reg; reg = a->reg;
if(size == 4) { if(size == 4) {
// if addr.reg == NREG, then it is probably load from x(FP) with small x, no need to modify. // if addr.reg == 0, then it is probably load from x(FP) with small x, no need to modify.
if(reg == NREG) { if(reg == 0) {
if(out != nil) if(out != nil)
asmout(ctxt, p, o, out); asmout(ctxt, p, o, out);
} else { } else {
if(out != nil) if(out != nil)
out[0] = ((p->scond&C_SCOND)<<28) | 0x03c00103 | (reg << 16) | (reg << 12); // BIC $0xc0000000, Rx out[0] = ((p->scond&C_SCOND)<<28) | 0x03c00103 | ((reg&15) << 16) | ((reg&15) << 12); // BIC $0xc0000000, Rx
if((p->pc&15) == 12) if((p->pc&15) == 12)
p->pc += 4; p->pc += 4;
size += 4; size += 4;
...@@ -587,7 +576,7 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out) ...@@ -587,7 +576,7 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
ctxt->diag("unsupported instruction (.P/.W): %P", p); ctxt->diag("unsupported instruction (.P/.W): %P", p);
q = ctxt->arch->prg(); q = ctxt->arch->prg();
*q = *p; *q = *p;
if(p->to.type == D_OREG) if(p->to.type == TYPE_MEM)
a2 = &q->to; a2 = &q->to;
else else
a2 = &q->from; a2 = &q->from;
...@@ -600,14 +589,14 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out) ...@@ -600,14 +589,14 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
// make p into MOVW $X(R), R11 // make p into MOVW $X(R), R11
p->as = AMOVW; p->as = AMOVW;
p->from = *a; p->from = *a;
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->to = zprg.to; p->to = zprg.to;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = 11; p->to.reg = REG_R11;
// make q into p but load/store from 0(R11) // make q into p but load/store from 0(R11)
*a2 = zprg.from; *a2 = zprg.from;
a2->type = D_OREG; a2->type = TYPE_MEM;
a2->reg = 11; a2->reg = REG_R11;
a2->sym = nil; a2->sym = nil;
a2->offset = 0; a2->offset = 0;
size = oplook(ctxt, p)->size; size = oplook(ctxt, p)->size;
...@@ -619,12 +608,12 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out) ...@@ -619,12 +608,12 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
} }
// destination register specific // destination register specific
if(p->to.type == D_REG) { if(p->to.type == TYPE_REG) {
switch(p->to.reg) { switch(p->to.reg) {
case 9: case REG_R9:
ctxt->diag("invalid instruction, cannot write to R9: %P", p); ctxt->diag("invalid instruction, cannot write to R9: %P", p);
break; break;
case 13: case REG_R13:
if(out != nil) if(out != nil)
out[size/4] = 0xe3cdd103; // BIC $0xc0000000, R13 out[size/4] = 0xe3cdd103; // BIC $0xc0000000, R13
if(((p->pc+size) & 15) == 0) if(((p->pc+size) & 15) == 0)
...@@ -707,7 +696,7 @@ span5(Link *ctxt, LSym *cursym) ...@@ -707,7 +696,7 @@ span5(Link *ctxt, LSym *cursym)
flushpool(ctxt, p, 0, 0); flushpool(ctxt, p, 0, 0);
break; break;
} }
if(p->as==AMOVW && p->to.type==D_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == C_SCOND_NONE) if(p->as==AMOVW && p->to.type==TYPE_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == C_SCOND_NONE)
flushpool(ctxt, p, 0, 0); flushpool(ctxt, p, 0, 0);
c += m; c += m;
} }
...@@ -742,14 +731,14 @@ span5(Link *ctxt, LSym *cursym) ...@@ -742,14 +731,14 @@ span5(Link *ctxt, LSym *cursym)
q->link = p->link; q->link = p->link;
p->link = q; p->link = q;
q->as = AB; q->as = AB;
q->to.type = D_BRANCH; q->to.type = TYPE_BRANCH;
q->pcond = p->pcond; q->pcond = p->pcond;
p->pcond = q; p->pcond = q;
q = ctxt->arch->prg(); q = ctxt->arch->prg();
q->link = p->link; q->link = p->link;
p->link = q; p->link = q;
q->as = AB; q->as = AB;
q->to.type = D_BRANCH; q->to.type = TYPE_BRANCH;
q->pcond = q->link->link; q->pcond = q->link->link;
bflag = 1; bflag = 1;
} }
...@@ -865,7 +854,7 @@ flushpool(Link *ctxt, Prog *p, int skip, int force) ...@@ -865,7 +854,7 @@ flushpool(Link *ctxt, Prog *p, int skip, int force)
if(0 && skip==1)print("note: flush literal pool at %llux: len=%ud ref=%ux\n", p->pc+4, pool.size, pool.start); if(0 && skip==1)print("note: flush literal pool at %llux: len=%ud ref=%ux\n", p->pc+4, pool.size, pool.start);
q = ctxt->arch->prg(); q = ctxt->arch->prg();
q->as = AB; q->as = AB;
q->to.type = D_BRANCH; q->to.type = TYPE_BRANCH;
q->pcond = p->link; q->pcond = p->link;
q->link = ctxt->blitrl; q->link = ctxt->blitrl;
q->lineno = p->lineno; q->lineno = p->lineno;
...@@ -931,7 +920,7 @@ addpool(Link *ctxt, Prog *p, Addr *a) ...@@ -931,7 +920,7 @@ addpool(Link *ctxt, Prog *p, Addr *a)
case C_SAUTO: case C_SAUTO:
case C_LAUTO: case C_LAUTO:
case C_LACON: case C_LACON:
t.to.type = D_CONST; t.to.type = TYPE_CONST;
t.to.offset = ctxt->instoffset; t.to.offset = ctxt->instoffset;
break; break;
} }
...@@ -1038,31 +1027,33 @@ aclass(Link *ctxt, Addr *a) ...@@ -1038,31 +1027,33 @@ aclass(Link *ctxt, Addr *a)
int t; int t;
switch(a->type) { switch(a->type) {
case D_NONE: case TYPE_NONE:
return C_NONE; return C_NONE;
case D_REG: case TYPE_REG:
return C_REG; if(REG_R0 <= a->reg && a->reg <= REG_R15)
return C_REG;
if(REG_F0 <= a->reg && a->reg <= REG_F15)
return C_FREG;
if(a->reg == REG_FPSR || a->reg == REG_FPCR)
return C_FCR;
if(a->reg == REG_CPSR || a->reg == REG_SPSR)
return C_PSR;
return C_GOK;
case D_REGREG: case TYPE_REGREG:
return C_REGREG; return C_REGREG;
case D_REGREG2: case TYPE_REGREG2:
return C_REGREG2; return C_REGREG2;
case D_SHIFT: case TYPE_SHIFT:
return C_SHIFT; return C_SHIFT;
case D_FREG: case TYPE_MEM:
return C_FREG;
case D_FPCR:
return C_FCR;
case D_OREG:
switch(a->name) { switch(a->name) {
case D_EXTERN: case NAME_EXTERN:
case D_STATIC: case NAME_STATIC:
if(a->sym == 0 || a->sym->name == 0) { if(a->sym == 0 || a->sym->name == 0) {
print("null sym external\n"); print("null sym external\n");
return C_GOK; return C_GOK;
...@@ -1070,7 +1061,7 @@ aclass(Link *ctxt, Addr *a) ...@@ -1070,7 +1061,7 @@ aclass(Link *ctxt, Addr *a)
ctxt->instoffset = 0; // s.b. unused but just in case ctxt->instoffset = 0; // s.b. unused but just in case
return C_ADDR; return C_ADDR;
case D_AUTO: case NAME_AUTO:
ctxt->instoffset = ctxt->autosize + a->offset; ctxt->instoffset = ctxt->autosize + a->offset;
t = immaddr(ctxt->instoffset); t = immaddr(ctxt->instoffset);
if(t){ if(t){
...@@ -1085,7 +1076,7 @@ aclass(Link *ctxt, Addr *a) ...@@ -1085,7 +1076,7 @@ aclass(Link *ctxt, Addr *a)
} }
return C_LAUTO; return C_LAUTO;
case D_PARAM: case NAME_PARAM:
ctxt->instoffset = ctxt->autosize + a->offset + 4L; ctxt->instoffset = ctxt->autosize + a->offset + 4L;
t = immaddr(ctxt->instoffset); t = immaddr(ctxt->instoffset);
if(t){ if(t){
...@@ -1099,7 +1090,7 @@ aclass(Link *ctxt, Addr *a) ...@@ -1099,7 +1090,7 @@ aclass(Link *ctxt, Addr *a)
return C_SAUTO; return C_SAUTO;
} }
return C_LAUTO; return C_LAUTO;
case D_NONE: case TYPE_NONE:
ctxt->instoffset = a->offset; ctxt->instoffset = a->offset;
t = immaddr(ctxt->instoffset); t = immaddr(ctxt->instoffset);
if(t) { if(t) {
...@@ -1124,32 +1115,20 @@ aclass(Link *ctxt, Addr *a) ...@@ -1124,32 +1115,20 @@ aclass(Link *ctxt, Addr *a)
} }
return C_GOK; return C_GOK;
case D_PSR: case TYPE_FCONST:
return C_PSR;
case D_OCONST:
switch(a->name) {
case D_EXTERN:
case D_STATIC:
ctxt->instoffset = 0; // s.b. unused but just in case
return C_ADDR;
}
return C_GOK;
case D_FCONST:
if(chipzero5(ctxt, a->u.dval) >= 0) if(chipzero5(ctxt, a->u.dval) >= 0)
return C_ZFCON; return C_ZFCON;
if(chipfloat5(ctxt, a->u.dval) >= 0) if(chipfloat5(ctxt, a->u.dval) >= 0)
return C_SFCON; return C_SFCON;
return C_LFCON; return C_LFCON;
case D_CONST: case TYPE_CONST:
case D_CONST2: case TYPE_TEXTSIZE:
switch(a->name) { switch(a->name) {
case D_NONE: case TYPE_NONE:
ctxt->instoffset = a->offset; ctxt->instoffset = a->offset;
if(a->reg != NREG) if(a->reg != 0)
return aconsize(ctxt); return aconsize(ctxt);
t = immrot(ctxt->instoffset); t = immrot(ctxt->instoffset);
...@@ -1160,25 +1139,25 @@ aclass(Link *ctxt, Addr *a) ...@@ -1160,25 +1139,25 @@ aclass(Link *ctxt, Addr *a)
return C_NCON; return C_NCON;
return C_LCON; return C_LCON;
case D_EXTERN: case NAME_EXTERN:
case D_STATIC: case NAME_STATIC:
s = a->sym; s = a->sym;
if(s == nil) if(s == nil)
break; break;
ctxt->instoffset = 0; // s.b. unused but just in case ctxt->instoffset = 0; // s.b. unused but just in case
return C_LCONADDR; return C_LCONADDR;
case D_AUTO: case NAME_AUTO:
ctxt->instoffset = ctxt->autosize + a->offset; ctxt->instoffset = ctxt->autosize + a->offset;
return aconsize(ctxt); return aconsize(ctxt);
case D_PARAM: case NAME_PARAM:
ctxt->instoffset = ctxt->autosize + a->offset + 4L; ctxt->instoffset = ctxt->autosize + a->offset + 4L;
return aconsize(ctxt); return aconsize(ctxt);
} }
return C_GOK; return C_GOK;
case D_BRANCH: case TYPE_BRANCH:
return C_SBRA; return C_SBRA;
} }
return C_GOK; return C_GOK;
...@@ -1224,7 +1203,7 @@ oplook(Link *ctxt, Prog *p) ...@@ -1224,7 +1203,7 @@ oplook(Link *ctxt, Prog *p)
} }
a3--; a3--;
a2 = C_NONE; a2 = C_NONE;
if(p->reg != NREG) if(p->reg != 0)
a2 = C_REG; a2 = C_REG;
r = p->as; r = p->as;
o = oprange[r].start; o = oprange[r].start;
...@@ -1535,14 +1514,14 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1535,14 +1514,14 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
rf = p->from.reg; rf = p->from.reg;
rt = p->to.reg; rt = p->to.reg;
r = p->reg; r = p->reg;
if(p->to.type == D_NONE) if(p->to.type == TYPE_NONE)
rt = 0; rt = 0;
if(p->as == AMOVB || p->as == AMOVH || p->as == AMOVW || p->as == AMVN) if(p->as == AMOVB || p->as == AMOVH || p->as == AMOVW || p->as == AMVN)
r = 0; r = 0;
else else
if(r == NREG) if(r == 0)
r = rt; r = rt;
o1 |= rf | (r<<16) | (rt<<12); o1 |= ((rf&15)<<0) | ((r&15)<<16) | ((rt&15)<<12);
break; break;
case 2: /* movbu $I,[R],R */ case 2: /* movbu $I,[R],R */
...@@ -1551,13 +1530,13 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1551,13 +1530,13 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o1 |= immrot(ctxt->instoffset); o1 |= immrot(ctxt->instoffset);
rt = p->to.reg; rt = p->to.reg;
r = p->reg; r = p->reg;
if(p->to.type == D_NONE) if(p->to.type == TYPE_NONE)
rt = 0; rt = 0;
if(p->as == AMOVW || p->as == AMVN) if(p->as == AMOVW || p->as == AMVN)
r = 0; r = 0;
else if(r == NREG) else if(r == 0)
r = rt; r = rt;
o1 |= (r<<16) | (rt<<12); o1 |= ((r&15)<<16) | ((rt&15)<<12);
break; break;
case 3: /* add R<<[IR],[R],R */ case 3: /* add R<<[IR],[R],R */
...@@ -1569,10 +1548,10 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1569,10 +1548,10 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o1 = oprrr(ctxt, AADD, p->scond); o1 = oprrr(ctxt, AADD, p->scond);
o1 |= immrot(ctxt->instoffset); o1 |= immrot(ctxt->instoffset);
r = p->from.reg; r = p->from.reg;
if(r == NREG) if(r == 0)
r = o->param; r = o->param;
o1 |= r << 16; o1 |= (r&15) << 16;
o1 |= p->to.reg << 12; o1 |= (p->to.reg&15) << 12;
break; break;
case 5: /* bra s */ case 5: /* bra s */
...@@ -1597,8 +1576,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1597,8 +1576,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
aclass(ctxt, &p->to); aclass(ctxt, &p->to);
o1 = oprrr(ctxt, AADD, p->scond); o1 = oprrr(ctxt, AADD, p->scond);
o1 |= immrot(ctxt->instoffset); o1 |= immrot(ctxt->instoffset);
o1 |= p->to.reg << 16; o1 |= (p->to.reg&15) << 16;
o1 |= REGPC << 12; o1 |= (REGPC&15) << 12;
break; break;
case 7: /* bl (R) -> blx R */ case 7: /* bl (R) -> blx R */
...@@ -1606,7 +1585,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1606,7 +1585,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(ctxt->instoffset != 0) if(ctxt->instoffset != 0)
ctxt->diag("%P: doesn't support BL offset(REG) where offset != 0", p); ctxt->diag("%P: doesn't support BL offset(REG) where offset != 0", p);
o1 = oprrr(ctxt, ABL, p->scond); o1 = oprrr(ctxt, ABL, p->scond);
o1 |= p->to.reg; o1 |= (p->to.reg&15) << 0;
rel = addrel(ctxt->cursym); rel = addrel(ctxt->cursym);
rel->off = ctxt->pc; rel->off = ctxt->pc;
rel->siz = 0; rel->siz = 0;
...@@ -1617,26 +1596,26 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1617,26 +1596,26 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
aclass(ctxt, &p->from); aclass(ctxt, &p->from);
o1 = oprrr(ctxt, p->as, p->scond); o1 = oprrr(ctxt, p->as, p->scond);
r = p->reg; r = p->reg;
if(r == NREG) if(r == 0)
r = p->to.reg; r = p->to.reg;
o1 |= r; o1 |= (r&15) << 0;
o1 |= (ctxt->instoffset&31) << 7; o1 |= (ctxt->instoffset&31) << 7;
o1 |= p->to.reg << 12; o1 |= (p->to.reg&15) << 12;
break; break;
case 9: /* sll R,[R],R -> mov (R<<R),R */ case 9: /* sll R,[R],R -> mov (R<<R),R */
o1 = oprrr(ctxt, p->as, p->scond); o1 = oprrr(ctxt, p->as, p->scond);
r = p->reg; r = p->reg;
if(r == NREG) if(r == 0)
r = p->to.reg; r = p->to.reg;
o1 |= r; o1 |= (r&15) << 0;
o1 |= (p->from.reg << 8) | (1<<4); o1 |= ((p->from.reg&15) << 8) | (1<<4);
o1 |= p->to.reg << 12; o1 |= (p->to.reg&15) << 12;
break; break;
case 10: /* swi [$con] */ case 10: /* swi [$con] */
o1 = oprrr(ctxt, p->as, p->scond); o1 = oprrr(ctxt, p->as, p->scond);
if(p->to.type != D_NONE) { if(p->to.type != TYPE_NONE) {
aclass(ctxt, &p->to); aclass(ctxt, &p->to);
o1 |= ctxt->instoffset & 0xffffff; o1 |= ctxt->instoffset & 0xffffff;
} }
...@@ -1676,7 +1655,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1676,7 +1655,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
case 12: /* movw $lcon, reg */ case 12: /* movw $lcon, reg */
o1 = omvl(ctxt, p, &p->from, p->to.reg); o1 = omvl(ctxt, p, &p->from, p->to.reg);
if(o->flag & LPCREL) { if(o->flag & LPCREL) {
o2 = oprrr(ctxt, AADD, p->scond) | p->to.reg | REGPC << 16 | p->to.reg << 12; o2 = oprrr(ctxt, AADD, p->scond) | (p->to.reg&15) << 0 | (REGPC&15) << 16 | (p->to.reg&15) << 12;
} }
break; break;
...@@ -1685,15 +1664,15 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1685,15 +1664,15 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(!o1) if(!o1)
break; break;
o2 = oprrr(ctxt, p->as, p->scond); o2 = oprrr(ctxt, p->as, p->scond);
o2 |= REGTMP; o2 |= (REGTMP&15);
r = p->reg; r = p->reg;
if(p->as == AMOVW || p->as == AMVN) if(p->as == AMOVW || p->as == AMVN)
r = 0; r = 0;
else if(r == NREG) else if(r == 0)
r = p->to.reg; r = p->to.reg;
o2 |= r << 16; o2 |= (r&15) << 16;
if(p->to.type != D_NONE) if(p->to.type != TYPE_NONE)
o2 |= p->to.reg << 12; o2 |= (p->to.reg&15) << 12;
break; break;
case 14: /* movb/movbu/movh/movhu R,R */ case 14: /* movb/movbu/movh/movhu R,R */
...@@ -1705,8 +1684,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1705,8 +1684,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o2 = oprrr(ctxt, ASRA, p->scond); o2 = oprrr(ctxt, ASRA, p->scond);
r = p->to.reg; r = p->to.reg;
o1 |= (p->from.reg)|(r<<12); o1 |= ((p->from.reg&15)<<0)|((r&15)<<12);
o2 |= (r)|(r<<12); o2 |= (r&15)|((r&15)<<12);
if(p->as == AMOVB || p->as == AMOVBS || p->as == AMOVBU) { if(p->as == AMOVB || p->as == AMOVBS || p->as == AMOVBU) {
o1 |= (24<<7); o1 |= (24<<7);
o2 |= (24<<7); o2 |= (24<<7);
...@@ -1721,18 +1700,18 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1721,18 +1700,18 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
rf = p->from.reg; rf = p->from.reg;
rt = p->to.reg; rt = p->to.reg;
r = p->reg; r = p->reg;
if(r == NREG) if(r == 0)
r = rt; r = rt;
if(rt == r) { if(rt == r) {
r = rf; r = rf;
rf = rt; rf = rt;
} }
if(0) if(0)
if(rt == r || rf == REGPC || r == REGPC || rt == REGPC) { if(rt == r || rf == (REGPC&15) || r == (REGPC&15) || rt == (REGPC&15)) {
ctxt->diag("bad registers in MUL"); ctxt->diag("bad registers in MUL");
prasm(p); prasm(p);
} }
o1 |= (rf<<8) | r | (rt<<16); o1 |= ((rf&15)<<8) | ((r&15)<<0) | ((rt&15)<<16);
break; break;
...@@ -1747,13 +1726,13 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1747,13 +1726,13 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
rt = p->to.reg; rt = p->to.reg;
rt2 = p->to.offset; rt2 = p->to.offset;
r = p->reg; r = p->reg;
o1 |= (rf<<8) | r | (rt<<16) | (rt2<<12); o1 |= ((rf&15)<<8) | ((r&15)<<0) | ((rt&15)<<16) | ((rt2&15)<<12);
break; break;
case 20: /* mov/movb/movbu R,O(R) */ case 20: /* mov/movb/movbu R,O(R) */
aclass(ctxt, &p->to); aclass(ctxt, &p->to);
r = p->to.reg; r = p->to.reg;
if(r == NREG) if(r == 0)
r = o->param; r = o->param;
o1 = osr(ctxt, p->as, p->from.reg, ctxt->instoffset, r, p->scond); o1 = osr(ctxt, p->as, p->from.reg, ctxt->instoffset, r, p->scond);
break; break;
...@@ -1761,7 +1740,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1761,7 +1740,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
case 21: /* mov/movbu O(R),R -> lr */ case 21: /* mov/movbu O(R),R -> lr */
aclass(ctxt, &p->from); aclass(ctxt, &p->from);
r = p->from.reg; r = p->from.reg;
if(r == NREG) if(r == 0)
r = o->param; r = o->param;
o1 = olr(ctxt, ctxt->instoffset, r, p->to.reg, p->scond); o1 = olr(ctxt, ctxt->instoffset, r, p->to.reg, p->scond);
if(p->as != AMOVW) if(p->as != AMOVW)
...@@ -1773,9 +1752,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1773,9 +1752,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(!o1) if(!o1)
break; break;
r = p->to.reg; r = p->to.reg;
if(r == NREG) if(r == 0)
r = o->param; r = o->param;
o2 = osrr(ctxt, p->from.reg, REGTMP,r, p->scond); o2 = osrr(ctxt, p->from.reg, REGTMP&15, r, p->scond);
if(p->as != AMOVW) if(p->as != AMOVW)
o2 |= 1<<22; o2 |= 1<<22;
break; break;
...@@ -1785,9 +1764,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1785,9 +1764,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(!o1) if(!o1)
break; break;
r = p->from.reg; r = p->from.reg;
if(r == NREG) if(r == 0)
r = o->param; r = o->param;
o2 = olrr(ctxt, REGTMP,r, p->to.reg, p->scond); o2 = olrr(ctxt, REGTMP&15, r, p->to.reg, p->scond);
if(p->as == AMOVBU || p->as == AMOVBS || p->as == AMOVB) if(p->as == AMOVBU || p->as == AMOVBS || p->as == AMOVB)
o2 |= 1<<22; o2 |= 1<<22;
break; break;
...@@ -1798,20 +1777,20 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1798,20 +1777,20 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
break; break;
o2 = oprrr(ctxt, AADD, p->scond); o2 = oprrr(ctxt, AADD, p->scond);
o2 |= REGTMP; o2 |= (REGTMP&15);
r = p->from.reg; r = p->from.reg;
if(r == NREG) if(r == 0)
r = o->param; r = o->param;
o2 |= r << 16; o2 |= (r&15) << 16;
if(p->to.type != D_NONE) if(p->to.type != TYPE_NONE)
o2 |= p->to.reg << 12; o2 |= (p->to.reg&15) << 12;
break; break;
case 35: /* mov PSR,R */ case 35: /* mov PSR,R */
o1 = (2<<23) | (0xf<<16) | (0<<0); o1 = (2<<23) | (0xf<<16) | (0<<0);
o1 |= (p->scond & C_SCOND) << 28; o1 |= (p->scond & C_SCOND) << 28;
o1 |= (p->from.reg & 1) << 22; o1 |= (p->from.reg & 1) << 22;
o1 |= p->to.reg << 12; o1 |= (p->to.reg&15) << 12;
break; break;
case 36: /* mov R,PSR */ case 36: /* mov R,PSR */
...@@ -1820,7 +1799,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1820,7 +1799,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o1 ^= 0x010 << 12; o1 ^= 0x010 << 12;
o1 |= (p->scond & C_SCOND) << 28; o1 |= (p->scond & C_SCOND) << 28;
o1 |= (p->to.reg & 1) << 22; o1 |= (p->to.reg & 1) << 22;
o1 |= p->from.reg << 0; o1 |= (p->from.reg&15) << 0;
break; break;
case 37: /* mov $con,PSR */ case 37: /* mov $con,PSR */
...@@ -1831,7 +1810,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1831,7 +1810,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o1 |= (p->scond & C_SCOND) << 28; o1 |= (p->scond & C_SCOND) << 28;
o1 |= immrot(ctxt->instoffset); o1 |= immrot(ctxt->instoffset);
o1 |= (p->to.reg & 1) << 22; o1 |= (p->to.reg & 1) << 22;
o1 |= p->from.reg << 0; o1 |= (p->from.reg&15) << 0;
break; break;
case 38: case 38:
...@@ -1840,14 +1819,14 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1840,14 +1819,14 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
case 38: /* movm $con,oreg -> stm */ case 38: /* movm $con,oreg -> stm */
o1 = (0x4 << 25); o1 = (0x4 << 25);
o1 |= p->from.offset & 0xffff; o1 |= p->from.offset & 0xffff;
o1 |= p->to.reg << 16; o1 |= (p->to.reg&15) << 16;
aclass(ctxt, &p->to); aclass(ctxt, &p->to);
break; break;
case 39: /* movm oreg,$con -> ldm */ case 39: /* movm oreg,$con -> ldm */
o1 = (0x4 << 25) | (1 << 20); o1 = (0x4 << 25) | (1 << 20);
o1 |= p->to.offset & 0xffff; o1 |= p->to.offset & 0xffff;
o1 |= p->from.reg << 16; o1 |= (p->from.reg&15) << 16;
aclass(ctxt, &p->from); aclass(ctxt, &p->from);
break; break;
} }
...@@ -1871,9 +1850,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1871,9 +1850,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o1 = (0x2<<23) | (0x9<<4); o1 = (0x2<<23) | (0x9<<4);
if(p->as != ASWPW) if(p->as != ASWPW)
o1 |= 1 << 22; o1 |= 1 << 22;
o1 |= p->from.reg << 16; o1 |= (p->from.reg&15) << 16;
o1 |= p->reg << 0; o1 |= (p->reg&15) << 0;
o1 |= p->to.reg << 12; o1 |= (p->to.reg&15) << 12;
o1 |= (p->scond & C_SCOND) << 28; o1 |= (p->scond & C_SCOND) << 28;
break; break;
...@@ -1884,7 +1863,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1884,7 +1863,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
case 50: /* floating point store */ case 50: /* floating point store */
v = regoff(ctxt, &p->to); v = regoff(ctxt, &p->to);
r = p->to.reg; r = p->to.reg;
if(r == NREG) if(r == 0)
r = o->param; r = o->param;
o1 = ofsr(ctxt, p->as, p->from.reg, v, r, p->scond, p); o1 = ofsr(ctxt, p->as, p->from.reg, v, r, p->scond, p);
break; break;
...@@ -1892,7 +1871,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1892,7 +1871,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
case 51: /* floating point load */ case 51: /* floating point load */
v = regoff(ctxt, &p->from); v = regoff(ctxt, &p->from);
r = p->from.reg; r = p->from.reg;
if(r == NREG) if(r == 0)
r = o->param; r = o->param;
o1 = ofsr(ctxt, p->as, p->to.reg, v, r, p->scond, p) | (1<<20); o1 = ofsr(ctxt, p->as, p->to.reg, v, r, p->scond, p) | (1<<20);
break; break;
...@@ -1902,9 +1881,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1902,9 +1881,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(!o1) if(!o1)
break; break;
r = p->to.reg; r = p->to.reg;
if(r == NREG) if(r == 0)
r = o->param; r = o->param;
o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r; o2 = oprrr(ctxt, AADD, p->scond) | ((REGTMP&15) << 12) | ((REGTMP&15) << 16) | ((r&15) << 0);
o3 = ofsr(ctxt, p->as, p->from.reg, 0, REGTMP, p->scond, p); o3 = ofsr(ctxt, p->as, p->from.reg, 0, REGTMP, p->scond, p);
break; break;
...@@ -1913,10 +1892,10 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1913,10 +1892,10 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(!o1) if(!o1)
break; break;
r = p->from.reg; r = p->from.reg;
if(r == NREG) if(r == 0)
r = o->param; r = o->param;
o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r; o2 = oprrr(ctxt, AADD, p->scond) | ((REGTMP&15) << 12) | ((REGTMP&15) << 16) | ((r&15) << 0);
o3 = ofsr(ctxt, p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20); o3 = ofsr(ctxt, p->as, p->to.reg, 0, (REGTMP&15), p->scond, p) | (1<<20);
break; break;
case 54: /* floating point arith */ case 54: /* floating point arith */
...@@ -1924,38 +1903,38 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1924,38 +1903,38 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
rf = p->from.reg; rf = p->from.reg;
rt = p->to.reg; rt = p->to.reg;
r = p->reg; r = p->reg;
if(r == NREG) { if(r == 0) {
r = rt; r = rt;
if(p->as == AMOVF || p->as == AMOVD || p->as == AMOVFD || p->as == AMOVDF || if(p->as == AMOVF || p->as == AMOVD || p->as == AMOVFD || p->as == AMOVDF ||
p->as == ASQRTF || p->as == ASQRTD || p->as == AABSF || p->as == AABSD) p->as == ASQRTF || p->as == ASQRTD || p->as == AABSF || p->as == AABSD)
r = 0; r = 0;
} }
o1 |= rf | (r<<16) | (rt<<12); o1 |= ((rf&15)<<0) | ((r&15)<<16) | ((rt&15)<<12);
break; break;
case 56: /* move to FP[CS]R */ case 56: /* move to FP[CS]R */
o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4); o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4);
o1 |= ((p->to.reg+1)<<21) | (p->from.reg << 12); o1 |= (((p->to.reg&1)+1)<<21) | ((p->from.reg&15) << 12);
break; break;
case 57: /* move from FP[CS]R */ case 57: /* move from FP[CS]R */
o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4); o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4);
o1 |= ((p->from.reg+1)<<21) | (p->to.reg<<12) | (1<<20); o1 |= (((p->from.reg&1)+1)<<21) | ((p->to.reg&15)<<12) | (1<<20);
break; break;
case 58: /* movbu R,R */ case 58: /* movbu R,R */
o1 = oprrr(ctxt, AAND, p->scond); o1 = oprrr(ctxt, AAND, p->scond);
o1 |= immrot(0xff); o1 |= immrot(0xff);
rt = p->to.reg; rt = p->to.reg;
r = p->from.reg; r = p->from.reg;
if(p->to.type == D_NONE) if(p->to.type == TYPE_NONE)
rt = 0; rt = 0;
if(r == NREG) if(r == 0)
r = rt; r = rt;
o1 |= (r<<16) | (rt<<12); o1 |= ((r&15)<<16) | ((rt&15)<<12);
break; break;
case 59: /* movw/bu R<<I(R),R -> ldr indexed */ case 59: /* movw/bu R<<I(R),R -> ldr indexed */
if(p->from.reg == NREG) { if(p->from.reg == 0) {
if(p->as != AMOVW) if(p->as != AMOVW)
ctxt->diag("byte MOV from shifter operand"); ctxt->diag("byte MOV from shifter operand");
o1 = mov(ctxt, p); o1 = mov(ctxt, p);
...@@ -1969,7 +1948,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1969,7 +1948,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
break; break;
case 60: /* movb R(R),R -> ldrsb indexed */ case 60: /* movb R(R),R -> ldrsb indexed */
if(p->from.reg == NREG) { if(p->from.reg == 0) {
ctxt->diag("byte MOV from shifter operand"); ctxt->diag("byte MOV from shifter operand");
o1 = mov(ctxt, p); o1 = mov(ctxt, p);
break; break;
...@@ -1981,7 +1960,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1981,7 +1960,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
break; break;
case 61: /* movw/b/bu R,R<<[IR](R) -> str indexed */ case 61: /* movw/b/bu R,R<<[IR](R) -> str indexed */
if(p->to.reg == NREG) if(p->to.reg == 0)
ctxt->diag("MOV to shifter operand"); ctxt->diag("MOV to shifter operand");
o1 = osrr(ctxt, p->from.reg, p->to.offset, p->to.reg, p->scond); o1 = osrr(ctxt, p->from.reg, p->to.offset, p->to.reg, p->scond);
if(p->as == AMOVB || p->as == AMOVBS || p->as == AMOVBU) if(p->as == AMOVB || p->as == AMOVBS || p->as == AMOVBU)
...@@ -1990,12 +1969,12 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -1990,12 +1969,12 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
case 62: /* case R -> movw R<<2(PC),PC */ case 62: /* case R -> movw R<<2(PC),PC */
if(o->flag & LPCREL) { if(o->flag & LPCREL) {
o1 = oprrr(ctxt, AADD, p->scond) | immrot(1) | p->from.reg << 16 | REGTMP << 12; o1 = oprrr(ctxt, AADD, p->scond) | immrot(1) | (p->from.reg&15) << 16 | (REGTMP&15) << 12;
o2 = olrr(ctxt, REGTMP, REGPC, REGTMP, p->scond); o2 = olrr(ctxt, REGTMP&15, REGPC, REGTMP, p->scond);
o2 |= 2<<7; o2 |= 2<<7;
o3 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGPC << 12; o3 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGPC&15) << 12;
} else { } else {
o1 = olrr(ctxt, p->from.reg, REGPC, REGPC, p->scond); o1 = olrr(ctxt, p->from.reg&15, REGPC, REGPC, p->scond);
o1 |= 2<<7; o1 |= 2<<7;
} }
break; break;
...@@ -2029,7 +2008,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -2029,7 +2008,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o2 = osr(ctxt, p->as, p->from.reg, 0, REGTMP, p->scond); o2 = osr(ctxt, p->as, p->from.reg, 0, REGTMP, p->scond);
if(o->flag & LPCREL) { if(o->flag & LPCREL) {
o3 = o2; o3 = o2;
o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12; o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
} }
break; break;
...@@ -2042,7 +2021,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -2042,7 +2021,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o2 |= 1<<22; o2 |= 1<<22;
if(o->flag & LPCREL) { if(o->flag & LPCREL) {
o3 = o2; o3 = o2;
o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12; o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
} }
break; break;
...@@ -2053,7 +2032,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -2053,7 +2032,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o2 = ofsr(ctxt, p->as, p->from.reg, 0, REGTMP, p->scond, p); o2 = ofsr(ctxt, p->as, p->from.reg, 0, REGTMP, p->scond, p);
if(o->flag & LPCREL) { if(o->flag & LPCREL) {
o3 = o2; o3 = o2;
o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12; o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
} }
break; break;
...@@ -2061,10 +2040,10 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -2061,10 +2040,10 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o1 = omvl(ctxt, p, &p->from, REGTMP); o1 = omvl(ctxt, p, &p->from, REGTMP);
if(!o1) if(!o1)
break; break;
o2 = ofsr(ctxt, p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20); o2 = ofsr(ctxt, p->as, p->to.reg, 0, (REGTMP&15), p->scond, p) | (1<<20);
if(o->flag & LPCREL) { if(o->flag & LPCREL) {
o3 = o2; o3 = o2;
o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12; o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
} }
break; break;
...@@ -2072,14 +2051,14 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -2072,14 +2051,14 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
case 70: /* movh/movhu R,O(R) -> strh */ case 70: /* movh/movhu R,O(R) -> strh */
aclass(ctxt, &p->to); aclass(ctxt, &p->to);
r = p->to.reg; r = p->to.reg;
if(r == NREG) if(r == 0)
r = o->param; r = o->param;
o1 = oshr(ctxt, p->from.reg, ctxt->instoffset, r, p->scond); o1 = oshr(ctxt, p->from.reg, ctxt->instoffset, r, p->scond);
break; break;
case 71: /* movb/movh/movhu O(R),R -> ldrsb/ldrsh/ldrh */ case 71: /* movb/movh/movhu O(R),R -> ldrsb/ldrsh/ldrh */
aclass(ctxt, &p->from); aclass(ctxt, &p->from);
r = p->from.reg; r = p->from.reg;
if(r == NREG) if(r == 0)
r = o->param; r = o->param;
o1 = olhr(ctxt, ctxt->instoffset, r, p->to.reg, p->scond); o1 = olhr(ctxt, ctxt->instoffset, r, p->to.reg, p->scond);
if(p->as == AMOVB || p->as == AMOVBS) if(p->as == AMOVB || p->as == AMOVBS)
...@@ -2092,18 +2071,18 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -2092,18 +2071,18 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(!o1) if(!o1)
break; break;
r = p->to.reg; r = p->to.reg;
if(r == NREG) if(r == 0)
r = o->param; r = o->param;
o2 = oshrr(ctxt, p->from.reg, REGTMP,r, p->scond); o2 = oshrr(ctxt, p->from.reg, REGTMP&15, r, p->scond);
break; break;
case 73: /* movb/movh/movhu L(R),R -> ldrsb/ldrsh/ldrh */ case 73: /* movb/movh/movhu L(R),R -> ldrsb/ldrsh/ldrh */
o1 = omvl(ctxt, p, &p->from, REGTMP); o1 = omvl(ctxt, p, &p->from, REGTMP);
if(!o1) if(!o1)
break; break;
r = p->from.reg; r = p->from.reg;
if(r == NREG) if(r == 0)
r = o->param; r = o->param;
o2 = olhrr(ctxt, REGTMP, r, p->to.reg, p->scond); o2 = olhrr(ctxt, REGTMP&15, r, p->to.reg, p->scond);
if(p->as == AMOVB || p->as == AMOVBS) if(p->as == AMOVB || p->as == AMOVBS)
o2 ^= (1<<5)|(1<<6); o2 ^= (1<<5)|(1<<6);
else if(p->as == AMOVH || p->as == AMOVHS) else if(p->as == AMOVH || p->as == AMOVHS)
...@@ -2117,16 +2096,16 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -2117,16 +2096,16 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(ctxt->instoffset != 0) if(ctxt->instoffset != 0)
ctxt->diag("non-zero offset in ABX"); ctxt->diag("non-zero offset in ABX");
/* /*
o1 = oprrr(ctxt, AADD, p->scond) | immrot(0) | (REGPC<<16) | (REGLINK<<12); // mov PC, LR o1 = oprrr(ctxt, AADD, p->scond) | immrot(0) | ((REGPC&15)<<16) | ((REGLINK&15)<<12); // mov PC, LR
o2 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | p->to.reg; // BX R o2 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | ((p->to.reg&15) << 0); // BX R
*/ */
// p->to.reg may be REGLINK // p->to.reg may be REGLINK
o1 = oprrr(ctxt, AADD, p->scond); o1 = oprrr(ctxt, AADD, p->scond);
o1 |= immrot(ctxt->instoffset); o1 |= immrot(ctxt->instoffset);
o1 |= p->to.reg << 16; o1 |= (p->to.reg&15) << 16;
o1 |= REGTMP << 12; o1 |= (REGTMP&15) << 12;
o2 = oprrr(ctxt, AADD, p->scond) | immrot(0) | (REGPC<<16) | (REGLINK<<12); // mov PC, LR o2 = oprrr(ctxt, AADD, p->scond) | immrot(0) | ((REGPC&15)<<16) | ((REGLINK&15)<<12); // mov PC, LR
o3 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | REGTMP; // BX Rtmp o3 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | (REGTMP&15); // BX Rtmp
break; break;
case 76: /* bx O(R) when returning from fn*/ case 76: /* bx O(R) when returning from fn*/
ctxt->diag("ABXRET"); ctxt->diag("ABXRET");
...@@ -2136,8 +2115,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -2136,8 +2115,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(ctxt->instoffset != 0) if(ctxt->instoffset != 0)
ctxt->diag("offset must be zero in LDREX"); ctxt->diag("offset must be zero in LDREX");
o1 = (0x19<<20) | (0xf9f); o1 = (0x19<<20) | (0xf9f);
o1 |= p->from.reg << 16; o1 |= (p->from.reg&15) << 16;
o1 |= p->to.reg << 12; o1 |= (p->to.reg&15) << 12;
o1 |= (p->scond & C_SCOND) << 28; o1 |= (p->scond & C_SCOND) << 28;
break; break;
case 78: /* strex reg,oreg,reg */ case 78: /* strex reg,oreg,reg */
...@@ -2145,9 +2124,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -2145,9 +2124,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(ctxt->instoffset != 0) if(ctxt->instoffset != 0)
ctxt->diag("offset must be zero in STREX"); ctxt->diag("offset must be zero in STREX");
o1 = (0x18<<20) | (0xf90); o1 = (0x18<<20) | (0xf90);
o1 |= p->from.reg << 16; o1 |= (p->from.reg&15) << 16;
o1 |= p->reg << 0; o1 |= (p->reg&15) << 0;
o1 |= p->to.reg << 12; o1 |= (p->to.reg&15) << 12;
o1 |= (p->scond & C_SCOND) << 28; o1 |= (p->scond & C_SCOND) << 28;
break; break;
case 80: /* fmov zfcon,freg */ case 80: /* fmov zfcon,freg */
...@@ -2159,88 +2138,88 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -2159,88 +2138,88 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o2 = oprrr(ctxt, ASUBF, p->scond); o2 = oprrr(ctxt, ASUBF, p->scond);
} }
v = 0x70; // 1.0 v = 0x70; // 1.0
r = p->to.reg; r = (p->to.reg&15) << 0;
// movf $1.0, r // movf $1.0, r
o1 |= (p->scond & C_SCOND) << 28; o1 |= (p->scond & C_SCOND) << 28;
o1 |= r << 12; o1 |= (r&15) << 12;
o1 |= (v&0xf) << 0; o1 |= (v&0xf) << 0;
o1 |= (v&0xf0) << 12; o1 |= (v&0xf0) << 12;
// subf r,r,r // subf r,r,r
o2 |= r | (r<<16) | (r<<12); o2 |= ((r&15)<<0) | ((r&15)<<16) | ((r&15)<<12);
break; break;
case 81: /* fmov sfcon,freg */ case 81: /* fmov sfcon,freg */
o1 = 0x0eb00a00; // VMOV imm 32 o1 = 0x0eb00a00; // VMOV imm 32
if(p->as == AMOVD) if(p->as == AMOVD)
o1 = 0xeeb00b00; // VMOV imm 64 o1 = 0xeeb00b00; // VMOV imm 64
o1 |= (p->scond & C_SCOND) << 28; o1 |= (p->scond & C_SCOND) << 28;
o1 |= p->to.reg << 12; o1 |= (p->to.reg&15) << 12;
v = chipfloat5(ctxt, p->from.u.dval); v = chipfloat5(ctxt, p->from.u.dval);
o1 |= (v&0xf) << 0; o1 |= (v&0xf) << 0;
o1 |= (v&0xf0) << 12; o1 |= (v&0xf0) << 12;
break; break;
case 82: /* fcmp freg,freg, */ case 82: /* fcmp freg,freg, */
o1 = oprrr(ctxt, p->as, p->scond); o1 = oprrr(ctxt, p->as, p->scond);
o1 |= (p->reg<<12) | (p->from.reg<<0); o1 |= ((p->reg&15)<<12) | ((p->from.reg&15)<<0);
o2 = 0x0ef1fa10; // VMRS R15 o2 = 0x0ef1fa10; // VMRS R15
o2 |= (p->scond & C_SCOND) << 28; o2 |= (p->scond & C_SCOND) << 28;
break; break;
case 83: /* fcmp freg,, */ case 83: /* fcmp freg,, */
o1 = oprrr(ctxt, p->as, p->scond); o1 = oprrr(ctxt, p->as, p->scond);
o1 |= (p->from.reg<<12) | (1<<16); o1 |= ((p->from.reg&15)<<12) | (1<<16);
o2 = 0x0ef1fa10; // VMRS R15 o2 = 0x0ef1fa10; // VMRS R15
o2 |= (p->scond & C_SCOND) << 28; o2 |= (p->scond & C_SCOND) << 28;
break; break;
case 84: /* movfw freg,freg - truncate float-to-fix */ case 84: /* movfw freg,freg - truncate float-to-fix */
o1 = oprrr(ctxt, p->as, p->scond); o1 = oprrr(ctxt, p->as, p->scond);
o1 |= (p->from.reg<<0); o1 |= ((p->from.reg&15)<<0);
o1 |= (p->to.reg<<12); o1 |= ((p->to.reg&15)<<12);
break; break;
case 85: /* movwf freg,freg - fix-to-float */ case 85: /* movwf freg,freg - fix-to-float */
o1 = oprrr(ctxt, p->as, p->scond); o1 = oprrr(ctxt, p->as, p->scond);
o1 |= (p->from.reg<<0); o1 |= ((p->from.reg&15)<<0);
o1 |= (p->to.reg<<12); o1 |= ((p->to.reg&15)<<12);
break; break;
case 86: /* movfw freg,reg - truncate float-to-fix */ case 86: /* movfw freg,reg - truncate float-to-fix */
// macro for movfw freg,FTMP; movw FTMP,reg // macro for movfw freg,FTMP; movw FTMP,reg
o1 = oprrr(ctxt, p->as, p->scond); o1 = oprrr(ctxt, p->as, p->scond);
o1 |= (p->from.reg<<0); o1 |= ((p->from.reg&15)<<0);
o1 |= (FREGTMP<<12); o1 |= ((FREGTMP&15)<<12);
o2 = oprrr(ctxt, AMOVFW+AEND, p->scond); o2 = oprrr(ctxt, AMOVFW+AEND, p->scond);
o2 |= (FREGTMP<<16); o2 |= ((FREGTMP&15)<<16);
o2 |= (p->to.reg<<12); o2 |= ((p->to.reg&15)<<12);
break; break;
case 87: /* movwf reg,freg - fix-to-float */ case 87: /* movwf reg,freg - fix-to-float */
// macro for movw reg,FTMP; movwf FTMP,freg // macro for movw reg,FTMP; movwf FTMP,freg
o1 = oprrr(ctxt, AMOVWF+AEND, p->scond); o1 = oprrr(ctxt, AMOVWF+AEND, p->scond);
o1 |= (p->from.reg<<12); o1 |= ((p->from.reg&15)<<12);
o1 |= (FREGTMP<<16); o1 |= ((FREGTMP&15)<<16);
o2 = oprrr(ctxt, p->as, p->scond); o2 = oprrr(ctxt, p->as, p->scond);
o2 |= (FREGTMP<<0); o2 |= ((FREGTMP&15)<<0);
o2 |= (p->to.reg<<12); o2 |= ((p->to.reg&15)<<12);
break; break;
case 88: /* movw reg,freg */ case 88: /* movw reg,freg */
o1 = oprrr(ctxt, AMOVWF+AEND, p->scond); o1 = oprrr(ctxt, AMOVWF+AEND, p->scond);
o1 |= (p->from.reg<<12); o1 |= ((p->from.reg&15)<<12);
o1 |= (p->to.reg<<16); o1 |= ((p->to.reg&15)<<16);
break; break;
case 89: /* movw freg,reg */ case 89: /* movw freg,reg */
o1 = oprrr(ctxt, AMOVFW+AEND, p->scond); o1 = oprrr(ctxt, AMOVFW+AEND, p->scond);
o1 |= (p->from.reg<<16); o1 |= ((p->from.reg&15)<<16);
o1 |= (p->to.reg<<12); o1 |= ((p->to.reg&15)<<12);
break; break;
case 90: /* tst reg */ case 90: /* tst reg */
o1 = oprrr(ctxt, ACMP+AEND, p->scond); o1 = oprrr(ctxt, ACMP+AEND, p->scond);
o1 |= p->from.reg<<16; o1 |= (p->from.reg&15)<<16;
break; break;
case 91: /* ldrexd oreg,reg */ case 91: /* ldrexd oreg,reg */
aclass(ctxt, &p->from); aclass(ctxt, &p->from);
if(ctxt->instoffset != 0) if(ctxt->instoffset != 0)
ctxt->diag("offset must be zero in LDREX"); ctxt->diag("offset must be zero in LDREX");
o1 = (0x1b<<20) | (0xf9f); o1 = (0x1b<<20) | (0xf9f);
o1 |= p->from.reg << 16; o1 |= (p->from.reg&15) << 16;
o1 |= p->to.reg << 12; o1 |= (p->to.reg&15) << 12;
o1 |= (p->scond & C_SCOND) << 28; o1 |= (p->scond & C_SCOND) << 28;
break; break;
case 92: /* strexd reg,oreg,reg */ case 92: /* strexd reg,oreg,reg */
...@@ -2248,9 +2227,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -2248,9 +2227,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(ctxt->instoffset != 0) if(ctxt->instoffset != 0)
ctxt->diag("offset must be zero in STREX"); ctxt->diag("offset must be zero in STREX");
o1 = (0x1a<<20) | (0xf90); o1 = (0x1a<<20) | (0xf90);
o1 |= p->from.reg << 16; o1 |= (p->from.reg&15) << 16;
o1 |= p->reg << 0; o1 |= (p->reg&15) << 0;
o1 |= p->to.reg << 12; o1 |= (p->to.reg&15) << 12;
o1 |= (p->scond & C_SCOND) << 28; o1 |= (p->scond & C_SCOND) << 28;
break; break;
case 93: /* movb/movh/movhu addr,R -> ldrsb/ldrsh/ldrh */ case 93: /* movb/movh/movhu addr,R -> ldrsb/ldrsh/ldrh */
...@@ -2264,7 +2243,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -2264,7 +2243,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o2 ^= (1<<6); o2 ^= (1<<6);
if(o->flag & LPCREL) { if(o->flag & LPCREL) {
o3 = o2; o3 = o2;
o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12; o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
} }
break; break;
case 94: /* movh/movhu R,addr -> strh */ case 94: /* movh/movhu R,addr -> strh */
...@@ -2274,12 +2253,12 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -2274,12 +2253,12 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o2 = oshr(ctxt, p->from.reg, 0, REGTMP, p->scond); o2 = oshr(ctxt, p->from.reg, 0, REGTMP, p->scond);
if(o->flag & LPCREL) { if(o->flag & LPCREL) {
o3 = o2; o3 = o2;
o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12; o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
} }
break; break;
case 95: /* PLD off(reg) */ case 95: /* PLD off(reg) */
o1 = 0xf5d0f000; o1 = 0xf5d0f000;
o1 |= p->from.reg << 16; o1 |= (p->from.reg&15) << 16;
if(p->from.offset < 0) { if(p->from.offset < 0) {
o1 &= ~(1 << 23); o1 &= ~(1 << 23);
o1 |= (-p->from.offset) & 0xfff; o1 |= (-p->from.offset) & 0xfff;
...@@ -2296,21 +2275,21 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na ...@@ -2296,21 +2275,21 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
break; break;
case 97: /* CLZ Rm, Rd */ case 97: /* CLZ Rm, Rd */
o1 = oprrr(ctxt, p->as, p->scond); o1 = oprrr(ctxt, p->as, p->scond);
o1 |= p->to.reg << 12; o1 |= (p->to.reg&15) << 12;
o1 |= p->from.reg; o1 |= (p->from.reg&15) << 0;
break; break;
case 98: /* MULW{T,B} Rs, Rm, Rd */ case 98: /* MULW{T,B} Rs, Rm, Rd */
o1 = oprrr(ctxt, p->as, p->scond); o1 = oprrr(ctxt, p->as, p->scond);
o1 |= p->to.reg << 16; o1 |= (p->to.reg&15) << 16;
o1 |= p->from.reg << 8; o1 |= (p->from.reg&15) << 8;
o1 |= p->reg; o1 |= (p->reg&15) << 0;
break; break;
case 99: /* MULAW{T,B} Rs, Rm, Rn, Rd */ case 99: /* MULAW{T,B} Rs, Rm, Rn, Rd */
o1 = oprrr(ctxt, p->as, p->scond); o1 = oprrr(ctxt, p->as, p->scond);
o1 |= p->to.reg << 12; o1 |= (p->to.reg&15) << 12;
o1 |= p->from.reg << 8; o1 |= (p->from.reg&15) << 8;
o1 |= p->reg; o1 |= (p->reg&15) << 0;
o1 |= p->to.offset << 16; o1 |= (p->to.offset&15) << 16;
break; break;
case 100: case 100:
// DATABUNDLE: BKPT $0x5be0, signify the start of NaCl data bundle; // DATABUNDLE: BKPT $0x5be0, signify the start of NaCl data bundle;
...@@ -2339,14 +2318,14 @@ mov(Link *ctxt, Prog *p) ...@@ -2339,14 +2318,14 @@ mov(Link *ctxt, Prog *p)
o1 = oprrr(ctxt, p->as, p->scond); o1 = oprrr(ctxt, p->as, p->scond);
o1 |= p->from.offset; o1 |= p->from.offset;
rt = p->to.reg; rt = p->to.reg;
r = p->reg; if(p->to.type == TYPE_NONE)
if(p->to.type == D_NONE)
rt = 0; rt = 0;
r = p->reg;
if(p->as == AMOVW || p->as == AMVN) if(p->as == AMOVW || p->as == AMVN)
r = 0; r = 0;
else if(r == NREG) else if(r == 0)
r = rt; r = rt;
o1 |= (r<<16) | (rt<<12); o1 |= ((r&15)<<16) | ((rt&15)<<12);
return o1; return o1;
} }
...@@ -2523,8 +2502,8 @@ olr(Link *ctxt, int32 v, int b, int r, int sc) ...@@ -2523,8 +2502,8 @@ olr(Link *ctxt, int32 v, int b, int r, int sc)
if(v >= (1<<12) || v < 0) if(v >= (1<<12) || v < 0)
ctxt->diag("literal span too large: %d (R%d)\n%P", v, b, ctxt->printp); ctxt->diag("literal span too large: %d (R%d)\n%P", v, b, ctxt->printp);
o |= v; o |= v;
o |= b << 16; o |= (b&15) << 16;
o |= r << 12; o |= (r&15) << 12;
return o; return o;
} }
...@@ -2548,8 +2527,8 @@ olhr(Link *ctxt, int32 v, int b, int r, int sc) ...@@ -2548,8 +2527,8 @@ olhr(Link *ctxt, int32 v, int b, int r, int sc)
if(v >= (1<<8) || v < 0) if(v >= (1<<8) || v < 0)
ctxt->diag("literal span too large: %d (R%d)\n%P", v, b, ctxt->printp); ctxt->diag("literal span too large: %d (R%d)\n%P", v, b, ctxt->printp);
o |= (v&0xf)|((v>>4)<<8)|(1<<22); o |= (v&0xf)|((v>>4)<<8)|(1<<22);
o |= b << 16; o |= (b&15) << 16;
o |= r << 12; o |= (r&15) << 12;
return o; return o;
} }
...@@ -2623,8 +2602,8 @@ ofsr(Link *ctxt, int a, int r, int32 v, int b, int sc, Prog *p) ...@@ -2623,8 +2602,8 @@ ofsr(Link *ctxt, int a, int r, int32 v, int b, int sc, Prog *p)
if(v >= (1<<10) || v < 0) if(v >= (1<<10) || v < 0)
ctxt->diag("literal span too large: %d\n%P", v, p); ctxt->diag("literal span too large: %d\n%P", v, p);
o |= (v>>2) & 0xFF; o |= (v>>2) & 0xFF;
o |= b << 16; o |= (b&15) << 16;
o |= r << 12; o |= (r&15) << 12;
switch(a) { switch(a) {
default: default:
...@@ -2652,7 +2631,7 @@ omvl(Link *ctxt, Prog *p, Addr *a, int dr) ...@@ -2652,7 +2631,7 @@ omvl(Link *ctxt, Prog *p, Addr *a, int dr)
} }
o1 = oprrr(ctxt, AMVN, p->scond&C_SCOND); o1 = oprrr(ctxt, AMVN, p->scond&C_SCOND);
o1 |= v; o1 |= v;
o1 |= dr << 12; o1 |= (dr&15) << 12;
} else { } else {
v = p->pcond->pc - p->pc - 8; v = p->pcond->pc - p->pc - 8;
o1 = olr(ctxt, v, REGPC, dr, p->scond&C_SCOND); o1 = olr(ctxt, v, REGPC, dr, p->scond&C_SCOND);
......
...@@ -99,10 +99,10 @@ Pconv(Fmt *fp) ...@@ -99,10 +99,10 @@ Pconv(Fmt *fp)
if(s & C_UBIT) /* ambiguous with FBIT */ if(s & C_UBIT) /* ambiguous with FBIT */
strcat(sc, ".U"); strcat(sc, ".U");
if(a == AMOVM) { if(a == AMOVM) {
if(p->from.type == D_CONST) if(p->from.type == TYPE_CONST)
sprint(str, "%.5lld (%L) %A%s %@,%D", p->pc, p->lineno, a, sc, &p->from, &p->to); sprint(str, "%.5lld (%L) %A%s %@,%D", p->pc, p->lineno, a, sc, &p->from, &p->to);
else else
if(p->to.type == D_CONST) if(p->to.type == TYPE_CONST)
sprint(str, "%.5lld (%L) %A%s %D,%@", p->pc, p->lineno, a, sc, &p->from, &p->to); sprint(str, "%.5lld (%L) %A%s %D,%@", p->pc, p->lineno, a, sc, &p->from, &p->to);
else else
sprint(str, "%.5lld (%L) %A%s %D,%D", p->pc, p->lineno, a, sc, &p->from, &p->to); sprint(str, "%.5lld (%L) %A%s %D,%D", p->pc, p->lineno, a, sc, &p->from, &p->to);
...@@ -113,13 +113,10 @@ Pconv(Fmt *fp) ...@@ -113,13 +113,10 @@ Pconv(Fmt *fp)
if(p->as == ATEXT) if(p->as == ATEXT)
sprint(str, "%.5lld (%L) %A %D,%d,%D", p->pc, p->lineno, a, &p->from, p->reg, &p->to); sprint(str, "%.5lld (%L) %A %D,%d,%D", p->pc, p->lineno, a, &p->from, p->reg, &p->to);
else else
if(p->reg == NREG) if(p->reg == 0)
sprint(str, "%.5lld (%L) %A%s %D,%D", p->pc, p->lineno, a, sc, &p->from, &p->to); sprint(str, "%.5lld (%L) %A%s %D,%D", p->pc, p->lineno, a, sc, &p->from, &p->to);
else else
if(p->from.type != D_FREG) sprint(str, "%.5lld (%L) %A%s %D,%R,%D", p->pc, p->lineno, a, sc, &p->from, p->reg, &p->to);
sprint(str, "%.5lld (%L) %A%s %D,R%d,%D", p->pc, p->lineno, a, sc, &p->from, p->reg, &p->to);
else
sprint(str, "%.5lld (%L) %A%s %D,F%d,%D", p->pc, p->lineno, a, sc, &p->from, p->reg, &p->to);
bigP = nil; bigP = nil;
return fmtstrcpy(fp, str); return fmtstrcpy(fp, str);
} }
...@@ -152,60 +149,48 @@ Dconv(Fmt *fp) ...@@ -152,60 +149,48 @@ Dconv(Fmt *fp)
sprint(str, "GOK-type(%d)", a->type); sprint(str, "GOK-type(%d)", a->type);
break; break;
case D_NONE: case TYPE_NONE:
str[0] = 0; str[0] = 0;
if(a->name != D_NONE || a->reg != NREG || a->sym != nil) if(a->name != TYPE_NONE || a->reg != 0 || a->sym != nil)
sprint(str, "%M(R%d)(NONE)", a, a->reg); sprint(str, "%M(%R)(NONE)", a, a->reg);
break; break;
case D_CONST: case TYPE_CONST:
if(a->reg != NREG) if(a->reg != 0)
sprint(str, "$%M(R%d)", a, a->reg); sprint(str, "$%M(%R)", a, a->reg);
else else
sprint(str, "$%M", a); sprint(str, "$%M", a);
break; break;
case D_CONST2: case TYPE_TEXTSIZE:
sprint(str, "$%lld-%d", a->offset, a->offset2); sprint(str, "$%lld-%d", a->offset, a->u.argsize);
break; break;
case D_SHIFT: case TYPE_SHIFT:
v = a->offset; v = a->offset;
op = &"<<>>->@>"[(((v>>5) & 3) << 1)]; op = &"<<>>->@>"[(((v>>5) & 3) << 1)];
if(v & (1<<4)) if(v & (1<<4))
sprint(str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15); sprint(str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
else else
sprint(str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31); sprint(str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
if(a->reg != NREG) if(a->reg != 0)
sprint(str+strlen(str), "(R%d)", a->reg); sprint(str+strlen(str), "(%R)", a->reg);
break; break;
case D_OREG: case TYPE_MEM:
if(a->reg != NREG) if(a->reg != 0)
sprint(str, "%M(R%d)", a, a->reg); sprint(str, "%M(%R)", a, a->reg);
else else
sprint(str, "%M", a); sprint(str, "%M", a);
break; break;
case D_REG: case TYPE_REG:
sprint(str, "R%d", a->reg); sprint(str, "%R", a->reg);
if(a->name != D_NONE || a->sym != nil) if(a->name != TYPE_NONE || a->sym != nil)
sprint(str, "%M(R%d)(REG)", a, a->reg); sprint(str, "%M(%R)(REG)", a, a->reg);
break;
case D_FREG:
sprint(str, "F%d", a->reg);
if(a->name != D_NONE || a->sym != nil)
sprint(str, "%M(R%d)(REG)", a, a->reg);
break;
case D_PSR:
sprint(str, "PSR");
if(a->name != D_NONE || a->sym != nil)
sprint(str, "%M(PSR)(REG)", a);
break; break;
case D_BRANCH: 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)
...@@ -216,11 +201,11 @@ Dconv(Fmt *fp) ...@@ -216,11 +201,11 @@ Dconv(Fmt *fp)
sprint(str, "%lld(PC)", a->offset/*-pc*/); sprint(str, "%lld(PC)", a->offset/*-pc*/);
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;
} }
...@@ -237,9 +222,9 @@ RAconv(Fmt *fp) ...@@ -237,9 +222,9 @@ RAconv(Fmt *fp)
a = va_arg(fp->args, Addr*); a = va_arg(fp->args, Addr*);
sprint(str, "GOK-reglist"); sprint(str, "GOK-reglist");
switch(a->type) { switch(a->type) {
case D_CONST: case TYPE_CONST:
case D_CONST2: case TYPE_TEXTSIZE:
if(a->reg != NREG) if(a->reg != 0)
break; break;
if(a->sym != nil) if(a->sym != nil)
break; break;
...@@ -310,11 +295,27 @@ static int ...@@ -310,11 +295,27 @@ static int
Rconv(Fmt *fp) Rconv(Fmt *fp)
{ {
int r; int r;
char str[STRINGSZ];
r = va_arg(fp->args, int); r = va_arg(fp->args, int);
sprint(str, "R%d", r); if(r == 0)
return fmtstrcpy(fp, str); return fmtstrcpy(fp, "NONE");
if(REG_R0 <= r && r <= REG_R15)
return fmtprint(fp, "R%d", r-REG_R0);
if(REG_F0 <= r && r <= REG_F15)
return fmtprint(fp, "F%d", r-REG_F0);
switch(r) {
case REG_FPSR:
return fmtstrcpy(fp, "FPSR");
case REG_FPCR:
return fmtstrcpy(fp, "FPCR");
case REG_CPSR:
return fmtstrcpy(fp, "CPSR");
case REG_SPSR:
return fmtstrcpy(fp, "SPSR");
}
return fmtprint(fp, "badreg(%d)", r);
} }
static int static int
...@@ -348,23 +349,23 @@ Mconv(Fmt *fp) ...@@ -348,23 +349,23 @@ Mconv(Fmt *fp)
sprint(str, "GOK-name(%d)", a->name); sprint(str, "GOK-name(%d)", a->name);
break; break;
case D_NONE: case NAME_NONE:
sprint(str, "%lld", a->offset); sprint(str, "%lld", a->offset);
break; break;
case D_EXTERN: case NAME_EXTERN:
sprint(str, "%s+%d(SB)", s->name, (int)a->offset); sprint(str, "%s+%d(SB)", s->name, (int)a->offset);
break; break;
case D_STATIC: case NAME_STATIC:
sprint(str, "%s<>+%d(SB)", s->name, (int)a->offset); sprint(str, "%s<>+%d(SB)", s->name, (int)a->offset);
break; break;
case D_AUTO: case NAME_AUTO:
sprint(str, "%s-%d(SP)", s->name, (int)-a->offset); sprint(str, "%s-%d(SP)", s->name, (int)-a->offset);
break; break;
case D_PARAM: case NAME_PARAM:
sprint(str, "%s+%d(FP)", s->name, (int)a->offset); sprint(str, "%s+%d(FP)", s->name, (int)a->offset);
break; break;
} }
......
...@@ -38,25 +38,8 @@ ...@@ -38,25 +38,8 @@
static Prog zprg5 = { static Prog zprg5 = {
.as = AGOK, .as = AGOK,
.scond = C_SCOND_NONE, .scond = C_SCOND_NONE,
.reg = NREG,
.from = {
.name = D_NONE,
.type = D_NONE,
.reg = NREG,
},
.to = {
.name = D_NONE,
.type = D_NONE,
.reg = NREG,
},
}; };
static int
symtype(Addr *a)
{
return a->name;
}
static int static int
isdata(Prog *p) isdata(Prog *p)
{ {
...@@ -97,14 +80,14 @@ progedit(Link *ctxt, Prog *p) ...@@ -97,14 +80,14 @@ progedit(Link *ctxt, Prog *p)
p->from.class = 0; p->from.class = 0;
p->to.class = 0; p->to.class = 0;
// Rewrite B/BL to symbol as D_BRANCH. // Rewrite B/BL to symbol as TYPE_BRANCH.
switch(p->as) { switch(p->as) {
case AB: case AB:
case ABL: case ABL:
case ADUFFZERO: case ADUFFZERO:
case ADUFFCOPY: case ADUFFCOPY:
if(p->to.type == D_OREG && (p->to.name == D_EXTERN || p->to.name == D_STATIC) && p->to.sym != nil) if(p->to.type == TYPE_MEM && (p->to.name == NAME_EXTERN || p->to.name == NAME_STATIC) && p->to.sym != nil)
p->to.type = D_BRANCH; p->to.type = TYPE_BRANCH;
break; break;
} }
...@@ -124,24 +107,24 @@ progedit(Link *ctxt, Prog *p) ...@@ -124,24 +107,24 @@ progedit(Link *ctxt, Prog *p)
tlsfallback = linklookup(ctxt, "runtime.read_tls_fallback", 0); tlsfallback = linklookup(ctxt, "runtime.read_tls_fallback", 0);
// MOVW LR, R11 // MOVW LR, R11
p->as = AMOVW; p->as = AMOVW;
p->from.type = D_REG; p->from.type = TYPE_REG;
p->from.reg = REGLINK; p->from.reg = REGLINK;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = REGTMP; p->to.reg = REGTMP;
// BL runtime.read_tls_fallback(SB) // BL runtime.read_tls_fallback(SB)
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = ABL; p->as = ABL;
p->to.type = D_BRANCH; p->to.type = TYPE_BRANCH;
p->to.sym = tlsfallback; p->to.sym = tlsfallback;
p->to.offset = 0; p->to.offset = 0;
// MOVW R11, LR // MOVW R11, LR
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->from.type = D_REG; p->from.type = TYPE_REG;
p->from.reg = REGTMP; p->from.reg = REGTMP;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = REGLINK; p->to.reg = REGLINK;
break; break;
} }
...@@ -154,7 +137,7 @@ progedit(Link *ctxt, Prog *p) ...@@ -154,7 +137,7 @@ progedit(Link *ctxt, Prog *p)
// Rewrite float constants to values stored in memory. // Rewrite float constants to values stored in memory.
switch(p->as) { switch(p->as) {
case AMOVF: case AMOVF:
if(p->from.type == D_FCONST && chipfloat5(ctxt, p->from.u.dval) < 0 && if(p->from.type == TYPE_FCONST && chipfloat5(ctxt, p->from.u.dval) < 0 &&
(chipzero5(ctxt, p->from.u.dval) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) { (chipzero5(ctxt, p->from.u.dval) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) {
uint32 i32; uint32 i32;
float32 f32; float32 f32;
...@@ -167,15 +150,15 @@ progedit(Link *ctxt, Prog *p) ...@@ -167,15 +150,15 @@ progedit(Link *ctxt, Prog *p)
adduint32(ctxt, s, i32); adduint32(ctxt, s, i32);
s->reachable = 0; s->reachable = 0;
} }
p->from.type = D_OREG; p->from.type = TYPE_MEM;
p->from.sym = s; p->from.sym = s;
p->from.name = D_EXTERN; p->from.name = NAME_EXTERN;
p->from.offset = 0; p->from.offset = 0;
} }
break; break;
case AMOVD: case AMOVD:
if(p->from.type == D_FCONST && chipfloat5(ctxt, p->from.u.dval) < 0 && if(p->from.type == TYPE_FCONST && chipfloat5(ctxt, p->from.u.dval) < 0 &&
(chipzero5(ctxt, p->from.u.dval) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) { (chipzero5(ctxt, p->from.u.dval) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) {
uint64 i64; uint64 i64;
memmove(&i64, &p->from.u.dval, 8); memmove(&i64, &p->from.u.dval, 8);
...@@ -186,9 +169,9 @@ progedit(Link *ctxt, Prog *p) ...@@ -186,9 +169,9 @@ progedit(Link *ctxt, Prog *p)
adduint64(ctxt, s, i64); adduint64(ctxt, s, i64);
s->reachable = 0; s->reachable = 0;
} }
p->from.type = D_OREG; p->from.type = TYPE_MEM;
p->from.sym = s; p->from.sym = s;
p->from.name = D_EXTERN; p->from.name = NAME_EXTERN;
p->from.offset = 0; p->from.offset = 0;
} }
break; break;
...@@ -203,10 +186,10 @@ progedit(Link *ctxt, Prog *p) ...@@ -203,10 +186,10 @@ progedit(Link *ctxt, Prog *p)
if(ctxt->tlsg == nil) if(ctxt->tlsg == nil)
ctxt->tlsg = linklookup(ctxt, "runtime.tlsg", 0); ctxt->tlsg = linklookup(ctxt, "runtime.tlsg", 0);
if(p->from.type == D_CONST && p->from.name == D_EXTERN && p->from.sym == ctxt->tlsg) if(p->from.type == TYPE_CONST && p->from.name == NAME_EXTERN && p->from.sym == ctxt->tlsg)
p->from.type = D_OREG; p->from.type = TYPE_MEM;
if(p->to.type == D_CONST && p->to.name == D_EXTERN && p->to.sym == ctxt->tlsg) if(p->to.type == TYPE_CONST && p->to.name == NAME_EXTERN && p->to.sym == ctxt->tlsg)
p->to.type = D_OREG; p->to.type = TYPE_MEM;
} }
} }
...@@ -255,7 +238,7 @@ nocache5(Prog *p) ...@@ -255,7 +238,7 @@ nocache5(Prog *p)
} }
static void static void
addstacksplit(Link *ctxt, LSym *cursym) preprocess(Link *ctxt, LSym *cursym)
{ {
Prog *p, *pl, *p1, *p2, *q, *q1, *q2; Prog *p, *pl, *p1, *p2, *q, *q1, *q2;
int o; int o;
...@@ -282,35 +265,35 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -282,35 +265,35 @@ addstacksplit(Link *ctxt, LSym *cursym)
if(autoffset < 0) if(autoffset < 0)
autoffset = 0; autoffset = 0;
cursym->locals = autoffset; cursym->locals = autoffset;
cursym->args = p->to.offset2; cursym->args = p->to.u.argsize;
if(ctxt->debugzerostack) { if(ctxt->debugzerostack) {
if(autoffset && !(p->reg&NOSPLIT)) { if(autoffset && !(p->reg&NOSPLIT)) {
// MOVW $4(R13), R1 // MOVW $4(R13), R1
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->from.reg = 13; p->from.reg = REG_R13;
p->from.offset = 4; p->from.offset = 4;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = 1; p->to.reg = REG_R1;
// MOVW $n(R13), R2 // MOVW $n(R13), R2
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->from.reg = 13; p->from.reg = REG_R13;
p->from.offset = 4 + autoffset; p->from.offset = 4 + autoffset;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = 2; p->to.reg = REG_R2;
// MOVW $0, R3 // MOVW $0, R3
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->from.offset = 0; p->from.offset = 0;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = 3; p->to.reg = REG_R3;
// L: // L:
// MOVW.nil R3, 0(R1) +4 // MOVW.nil R3, 0(R1) +4
...@@ -318,22 +301,22 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -318,22 +301,22 @@ addstacksplit(Link *ctxt, LSym *cursym)
// BNE L // BNE L
p = pl = appendp(ctxt, p); p = pl = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->from.type = D_REG; p->from.type = TYPE_REG;
p->from.reg = 3; p->from.reg = REG_R3;
p->to.type = D_OREG; p->to.type = TYPE_MEM;
p->to.reg = 1; p->to.reg = REG_R1;
p->to.offset = 4; p->to.offset = 4;
p->scond |= C_PBIT; p->scond |= C_PBIT;
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = ACMP; p->as = ACMP;
p->from.type = D_REG; p->from.type = TYPE_REG;
p->from.reg = 1; p->from.reg = REG_R1;
p->reg = 2; p->reg = REG_R2;
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = ABNE; p->as = ABNE;
p->to.type = D_BRANCH; p->to.type = TYPE_BRANCH;
p->pcond = pl; p->pcond = pl;
} }
} }
...@@ -445,9 +428,9 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -445,9 +428,9 @@ addstacksplit(Link *ctxt, LSym *cursym)
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->scond |= C_WBIT; p->scond |= C_WBIT;
p->from.type = D_REG; p->from.type = TYPE_REG;
p->from.reg = REGLINK; p->from.reg = REGLINK;
p->to.type = D_OREG; p->to.type = TYPE_MEM;
p->to.offset = -autosize; p->to.offset = -autosize;
p->to.reg = REGSP; p->to.reg = REGSP;
p->spadj = autosize; p->spadj = autosize;
...@@ -472,64 +455,64 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -472,64 +455,64 @@ addstacksplit(Link *ctxt, LSym *cursym)
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->from.type = D_OREG; p->from.type = TYPE_MEM;
p->from.reg = REGG; p->from.reg = REGG;
p->from.offset = 4*ctxt->arch->ptrsize; // G.panic p->from.offset = 4*ctxt->arch->ptrsize; // G.panic
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = 1; p->to.reg = REG_R1;
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = ACMP; p->as = ACMP;
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->from.offset = 0; p->from.offset = 0;
p->reg = 1; p->reg = REG_R1;
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = ABEQ; p->as = ABEQ;
p->to.type = D_BRANCH; p->to.type = TYPE_BRANCH;
p1 = p; p1 = p;
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->from.type = D_OREG; p->from.type = TYPE_MEM;
p->from.reg = 1; p->from.reg = REG_R1;
p->from.offset = 0; // Panic.argp p->from.offset = 0; // Panic.argp
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = 2; p->to.reg = REG_R2;
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AADD; p->as = AADD;
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->from.offset = autosize+4; p->from.offset = autosize+4;
p->reg = 13; p->reg = REG_R13;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = 3; p->to.reg = REG_R3;
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = ACMP; p->as = ACMP;
p->from.type = D_REG; p->from.type = TYPE_REG;
p->from.reg = 2; p->from.reg = REG_R2;
p->reg = 3; p->reg = REG_R3;
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = ABNE; p->as = ABNE;
p->to.type = D_BRANCH; p->to.type = TYPE_BRANCH;
p2 = p; p2 = p;
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AADD; p->as = AADD;
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->from.offset = 4; p->from.offset = 4;
p->reg = 13; p->reg = REG_R13;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = 4; p->to.reg = REG_R4;
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->from.type = D_REG; p->from.type = TYPE_REG;
p->from.reg = 4; p->from.reg = REG_R4;
p->to.type = D_OREG; p->to.type = TYPE_MEM;
p->to.reg = 1; p->to.reg = REG_R1;
p->to.offset = 0; // Panic.argp p->to.offset = 0; // Panic.argp
p = appendp(ctxt, p); p = appendp(ctxt, p);
...@@ -546,9 +529,9 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -546,9 +529,9 @@ addstacksplit(Link *ctxt, LSym *cursym)
p->as = AB; p->as = AB;
p->from = zprg5.from; p->from = zprg5.from;
if(p->to.sym) { // retjmp if(p->to.sym) { // retjmp
p->to.type = D_BRANCH; p->to.type = TYPE_BRANCH;
} else { } else {
p->to.type = D_OREG; p->to.type = TYPE_MEM;
p->to.offset = 0; p->to.offset = 0;
p->to.reg = REGLINK; p->to.reg = REGLINK;
} }
...@@ -558,10 +541,10 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -558,10 +541,10 @@ addstacksplit(Link *ctxt, LSym *cursym)
p->as = AMOVW; p->as = AMOVW;
p->scond |= C_PBIT; p->scond |= C_PBIT;
p->from.type = D_OREG; p->from.type = TYPE_MEM;
p->from.offset = autosize; p->from.offset = autosize;
p->from.reg = REGSP; p->from.reg = REGSP;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = REGPC; p->to.reg = REGPC;
// If there are instructions following // If there are instructions following
// this ARET, they come from a branch // this ARET, they come from a branch
...@@ -571,7 +554,7 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -571,7 +554,7 @@ addstacksplit(Link *ctxt, LSym *cursym)
p->to.reg = REGLINK; p->to.reg = REGLINK;
q2 = appendp(ctxt, p); q2 = appendp(ctxt, p);
q2->as = AB; q2->as = AB;
q2->to.type = D_BRANCH; q2->to.type = TYPE_BRANCH;
q2->to.sym = p->to.sym; q2->to.sym = p->to.sym;
p->to.sym = nil; p->to.sym = nil;
p = q2; p = q2;
...@@ -579,12 +562,12 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -579,12 +562,12 @@ addstacksplit(Link *ctxt, LSym *cursym)
break; break;
case AADD: case AADD:
if(p->from.type == D_CONST && p->from.reg == NREG && p->to.type == D_REG && p->to.reg == REGSP) if(p->from.type == TYPE_CONST && p->from.reg == 0 && p->to.type == TYPE_REG && p->to.reg == REGSP)
p->spadj = -p->from.offset; p->spadj = -p->from.offset;
break; break;
case ASUB: case ASUB:
if(p->from.type == D_CONST && p->from.reg == NREG && p->to.type == D_REG && p->to.reg == REGSP) if(p->from.type == TYPE_CONST && p->from.reg == 0 && p->to.type == TYPE_REG && p->to.reg == REGSP)
p->spadj = p->from.offset; p->spadj = p->from.offset;
break; break;
...@@ -594,9 +577,9 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -594,9 +577,9 @@ addstacksplit(Link *ctxt, LSym *cursym)
case AMODU: case AMODU:
if(ctxt->debugdivmod) if(ctxt->debugdivmod)
break; break;
if(p->from.type != D_REG) if(p->from.type != TYPE_REG)
break; break;
if(p->to.type != D_REG) if(p->to.type != TYPE_REG)
break; break;
q1 = p; q1 = p;
...@@ -604,9 +587,9 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -604,9 +587,9 @@ addstacksplit(Link *ctxt, LSym *cursym)
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->lineno = q1->lineno; p->lineno = q1->lineno;
p->from.type = D_REG; p->from.type = TYPE_REG;
p->from.reg = q1->from.reg; p->from.reg = q1->from.reg;
p->to.type = D_OREG; p->to.type = TYPE_MEM;
p->to.reg = REGSP; p->to.reg = REGSP;
p->to.offset = 4; p->to.offset = 4;
...@@ -614,11 +597,11 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -614,11 +597,11 @@ addstacksplit(Link *ctxt, LSym *cursym)
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->lineno = q1->lineno; p->lineno = q1->lineno;
p->from.type = D_REG; p->from.type = TYPE_REG;
p->from.reg = q1->reg; p->from.reg = q1->reg;
if(q1->reg == NREG) if(q1->reg == 0)
p->from.reg = q1->to.reg; p->from.reg = q1->to.reg;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = REGTMP; p->to.reg = REGTMP;
p->to.offset = 0; p->to.offset = 0;
...@@ -626,7 +609,7 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -626,7 +609,7 @@ addstacksplit(Link *ctxt, LSym *cursym)
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = ABL; p->as = ABL;
p->lineno = q1->lineno; p->lineno = q1->lineno;
p->to.type = D_BRANCH; p->to.type = TYPE_BRANCH;
switch(o) { switch(o) {
case ADIV: case ADIV:
p->to.sym = ctxt->sym_div; p->to.sym = ctxt->sym_div;
...@@ -646,21 +629,21 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -646,21 +629,21 @@ addstacksplit(Link *ctxt, LSym *cursym)
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->lineno = q1->lineno; p->lineno = q1->lineno;
p->from.type = D_REG; p->from.type = TYPE_REG;
p->from.reg = REGTMP; p->from.reg = REGTMP;
p->from.offset = 0; p->from.offset = 0;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = q1->to.reg; p->to.reg = q1->to.reg;
/* ADD $8,SP */ /* ADD $8,SP */
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AADD; p->as = AADD;
p->lineno = q1->lineno; p->lineno = q1->lineno;
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->from.reg = NREG; p->from.reg = 0;
p->from.offset = 8; p->from.offset = 8;
p->reg = NREG; p->reg = 0;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = REGSP; p->to.reg = REGSP;
p->spadj = -8; p->spadj = -8;
...@@ -668,20 +651,20 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -668,20 +651,20 @@ addstacksplit(Link *ctxt, LSym *cursym)
/* MOVW 0(SP), REGTMP; MOVW REGTMP, -8!(SP) */ /* MOVW 0(SP), REGTMP; MOVW REGTMP, -8!(SP) */
/* TODO: Remove SP adjustments; see issue 6699. */ /* TODO: Remove SP adjustments; see issue 6699. */
q1->as = AMOVW; q1->as = AMOVW;
q1->from.type = D_OREG; q1->from.type = TYPE_MEM;
q1->from.reg = REGSP; q1->from.reg = REGSP;
q1->from.offset = 0; q1->from.offset = 0;
q1->reg = NREG; q1->reg = 0;
q1->to.type = D_REG; q1->to.type = TYPE_REG;
q1->to.reg = REGTMP; q1->to.reg = REGTMP;
/* SUB $8,SP */ /* SUB $8,SP */
q1 = appendp(ctxt, q1); q1 = appendp(ctxt, q1);
q1->as = AMOVW; q1->as = AMOVW;
q1->from.type = D_REG; q1->from.type = TYPE_REG;
q1->from.reg = REGTMP; q1->from.reg = REGTMP;
q1->reg = NREG; q1->reg = 0;
q1->to.type = D_OREG; q1->to.type = TYPE_MEM;
q1->to.reg = REGSP; q1->to.reg = REGSP;
q1->to.offset = -8; q1->to.offset = -8;
q1->scond |= C_WBIT; q1->scond |= C_WBIT;
...@@ -689,17 +672,23 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -689,17 +672,23 @@ addstacksplit(Link *ctxt, LSym *cursym)
break; break;
case AMOVW: case AMOVW:
if((p->scond & C_WBIT) && p->to.type == D_OREG && p->to.reg == REGSP) if((p->scond & C_WBIT) && p->to.type == TYPE_MEM && p->to.reg == REGSP)
p->spadj = -p->to.offset; p->spadj = -p->to.offset;
if((p->scond & C_PBIT) && p->from.type == D_OREG && p->from.reg == REGSP && p->to.reg != REGPC) if((p->scond & C_PBIT) && p->from.type == TYPE_MEM && p->from.reg == REGSP && p->to.reg != REGPC)
p->spadj = -p->from.offset; p->spadj = -p->from.offset;
if(p->from.type == D_CONST && p->from.reg == REGSP && p->to.type == D_REG && p->to.reg == REGSP) if(p->from.type == TYPE_CONST && p->from.reg == REGSP && p->to.type == TYPE_REG && p->to.reg == REGSP)
p->spadj = -p->from.offset; p->spadj = -p->from.offset;
break; break;
} }
} }
} }
static int
isfloatreg(Addr *a)
{
return a->type == TYPE_REG && REG_F0 <= a->reg && a->reg <= REG_F15;
}
static void static void
softfloat(Link *ctxt, LSym *cursym) softfloat(Link *ctxt, LSym *cursym)
{ {
...@@ -719,7 +708,7 @@ softfloat(Link *ctxt, LSym *cursym) ...@@ -719,7 +708,7 @@ softfloat(Link *ctxt, LSym *cursym)
for(p = cursym->text; p != nil; p = p->link) { for(p = cursym->text; p != nil; p = p->link) {
switch(p->as) { switch(p->as) {
case AMOVW: case AMOVW:
if(p->to.type == D_FREG || p->from.type == D_FREG) if(isfloatreg(&p->to) || isfloatreg(&p->from))
goto soft; goto soft;
goto notsoft; goto notsoft;
...@@ -761,7 +750,7 @@ softfloat(Link *ctxt, LSym *cursym) ...@@ -761,7 +750,7 @@ softfloat(Link *ctxt, LSym *cursym)
*p = zprg5; *p = zprg5;
p->link = next; p->link = next;
p->as = ABL; p->as = ABL;
p->to.type = D_BRANCH; p->to.type = TYPE_BRANCH;
p->to.sym = symsfloat; p->to.sym = symsfloat;
p->lineno = next->lineno; p->lineno = next->lineno;
...@@ -781,21 +770,21 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt) ...@@ -781,21 +770,21 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
// MOVW g_stackguard(g), R1 // MOVW g_stackguard(g), R1
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->from.type = D_OREG; p->from.type = TYPE_MEM;
p->from.reg = REGG; p->from.reg = REGG;
p->from.offset = 2*ctxt->arch->ptrsize; // G.stackguard0 p->from.offset = 2*ctxt->arch->ptrsize; // G.stackguard0
if(ctxt->cursym->cfunc) if(ctxt->cursym->cfunc)
p->from.offset = 3*ctxt->arch->ptrsize; // G.stackguard1 p->from.offset = 3*ctxt->arch->ptrsize; // G.stackguard1
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = 1; p->to.reg = REG_R1;
if(framesize <= StackSmall) { if(framesize <= StackSmall) {
// small stack: SP < stackguard // small stack: SP < stackguard
// CMP stackguard, SP // CMP stackguard, SP
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = ACMP; p->as = ACMP;
p->from.type = D_REG; p->from.type = TYPE_REG;
p->from.reg = 1; p->from.reg = REG_R1;
p->reg = REGSP; p->reg = REGSP;
} else if(framesize <= StackBig) { } else if(framesize <= StackBig) {
// large stack: SP-framesize < stackguard-StackSmall // large stack: SP-framesize < stackguard-StackSmall
...@@ -803,17 +792,17 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt) ...@@ -803,17 +792,17 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
// CMP stackguard, R2 // CMP stackguard, R2
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->from.reg = REGSP; p->from.reg = REGSP;
p->from.offset = -framesize; p->from.offset = -framesize;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = 2; p->to.reg = REG_R2;
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = ACMP; p->as = ACMP;
p->from.type = D_REG; p->from.type = TYPE_REG;
p->from.reg = 1; p->from.reg = REG_R1;
p->reg = 2; p->reg = REG_R2;
} else { } else {
// Such a large stack we need to protect against wraparound // Such a large stack we need to protect against wraparound
// if SP is close to zero. // if SP is close to zero.
...@@ -827,40 +816,40 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt) ...@@ -827,40 +816,40 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
// CMP.NE R3, R2 // CMP.NE R3, R2
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = ACMP; p->as = ACMP;
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->from.offset = (uint32)StackPreempt; p->from.offset = (uint32)StackPreempt;
p->reg = 1; p->reg = REG_R1;
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->from.reg = REGSP; p->from.reg = REGSP;
p->from.offset = StackGuard; p->from.offset = StackGuard;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = 2; p->to.reg = REG_R2;
p->scond = C_SCOND_NE; p->scond = C_SCOND_NE;
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = ASUB; p->as = ASUB;
p->from.type = D_REG; p->from.type = TYPE_REG;
p->from.reg = 1; p->from.reg = REG_R1;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = 2; p->to.reg = REG_R2;
p->scond = C_SCOND_NE; p->scond = C_SCOND_NE;
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->from.type = D_CONST; p->from.type = TYPE_CONST;
p->from.offset = framesize + (StackGuard - StackSmall); p->from.offset = framesize + (StackGuard - StackSmall);
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = 3; p->to.reg = REG_R3;
p->scond = C_SCOND_NE; p->scond = C_SCOND_NE;
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = ACMP; p->as = ACMP;
p->from.type = D_REG; p->from.type = TYPE_REG;
p->from.reg = 3; p->from.reg = REG_R3;
p->reg = 2; p->reg = REG_R2;
p->scond = C_SCOND_NE; p->scond = C_SCOND_NE;
} }
...@@ -868,16 +857,16 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt) ...@@ -868,16 +857,16 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = AMOVW; p->as = AMOVW;
p->scond = C_SCOND_LS; p->scond = C_SCOND_LS;
p->from.type = D_REG; p->from.type = TYPE_REG;
p->from.reg = REGLINK; p->from.reg = REGLINK;
p->to.type = D_REG; p->to.type = TYPE_REG;
p->to.reg = 3; p->to.reg = REG_R3;
// BL.LS runtime.morestack(SB) // modifies LR, returns with LO still asserted // BL.LS runtime.morestack(SB) // modifies LR, returns with LO still asserted
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = ABL; p->as = ABL;
p->scond = C_SCOND_LS; p->scond = C_SCOND_LS;
p->to.type = D_BRANCH; p->to.type = TYPE_BRANCH;
if(ctxt->cursym->cfunc) if(ctxt->cursym->cfunc)
p->to.sym = linklookup(ctxt, "runtime.morestackc", 0); p->to.sym = linklookup(ctxt, "runtime.morestackc", 0);
else else
...@@ -886,7 +875,7 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt) ...@@ -886,7 +875,7 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
// BLS start // BLS start
p = appendp(ctxt, p); p = appendp(ctxt, p);
p->as = ABLS; p->as = ABLS;
p->to.type = D_BRANCH; p->to.type = TYPE_BRANCH;
p->pcond = ctxt->cursym->text->link; p->pcond = ctxt->cursym->text->link;
return p; return p;
...@@ -1011,7 +1000,7 @@ loop: ...@@ -1011,7 +1000,7 @@ loop:
q = ctxt->arch->prg(); q = ctxt->arch->prg();
q->as = a; q->as = a;
q->lineno = p->lineno; q->lineno = p->lineno;
q->to.type = D_BRANCH; q->to.type = TYPE_BRANCH;
q->to.offset = p->pc; q->to.offset = p->pc;
q->pcond = p; q->pcond = p;
p = q; p = q;
...@@ -1051,7 +1040,7 @@ LinkArch linkarm = { ...@@ -1051,7 +1040,7 @@ LinkArch linkarm = {
.thechar = '5', .thechar = '5',
.endian = LittleEndian, .endian = LittleEndian,
.addstacksplit = addstacksplit, .preprocess = preprocess,
.assemble = span5, .assemble = span5,
.datasize = datasize, .datasize = datasize,
.follow = follow, .follow = follow,
...@@ -1060,25 +1049,12 @@ LinkArch linkarm = { ...@@ -1060,25 +1049,12 @@ LinkArch linkarm = {
.prg = prg, .prg = prg,
.progedit = progedit, .progedit = progedit,
.settextflag = settextflag, .settextflag = settextflag,
.symtype = symtype,
.textflag = textflag, .textflag = textflag,
.minlc = 4, .minlc = 4,
.ptrsize = 4, .ptrsize = 4,
.regsize = 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,
.D_OREG = D_OREG,
.ACALL = ABL, .ACALL = ABL,
.ADATA = ADATA, .ADATA = ADATA,
.AEND = AEND, .AEND = AEND,
......
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