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