Add assembler support for fixing up arbitrary oris/addi pairs of instructions;
this should allow oris/lwz constant value loads, which will save an opcode.
This commit is contained in:
parent
fd83b09c58
commit
8edbff9795
|
@ -84,6 +84,9 @@
|
||||||
%token <y_word> OP_LA
|
%token <y_word> OP_LA
|
||||||
%token <y_word> OP_LI32
|
%token <y_word> OP_LI32
|
||||||
|
|
||||||
|
%token <y_word> OP_POWERPC_FIXUP
|
||||||
|
%token <y_word> OP_HI OP_LO
|
||||||
|
|
||||||
/* Other token types */
|
/* Other token types */
|
||||||
|
|
||||||
%type <y_word> c
|
%type <y_word> c
|
||||||
|
|
|
@ -102,6 +102,9 @@
|
||||||
0, OP_LA, 0, "la",
|
0, OP_LA, 0, "la",
|
||||||
0, OP_LA, 0, "li",
|
0, OP_LA, 0, "li",
|
||||||
0, OP_RS_RA_RA_C, 31<<26 | 444<<1, "mr",
|
0, OP_RS_RA_RA_C, 31<<26 | 444<<1, "mr",
|
||||||
|
0, OP_POWERPC_FIXUP, 0, ".powerpcfixup",
|
||||||
|
0, OP_HI, 0, "hi",
|
||||||
|
0, OP_LO, 0, "lo",
|
||||||
|
|
||||||
/* Branch processor instructions (page 20) */
|
/* Branch processor instructions (page 20) */
|
||||||
|
|
||||||
|
@ -270,7 +273,7 @@
|
||||||
0, OP_RS_RA_SH_ME6_SH_C, 30<<26 | 1<<2, "rldicr",
|
0, OP_RS_RA_SH_ME6_SH_C, 30<<26 | 1<<2, "rldicr",
|
||||||
0, OP_RS_RA_SH_MB6_SH_C, 30<<26 | 2<<2, "rldic",
|
0, OP_RS_RA_SH_MB6_SH_C, 30<<26 | 2<<2, "rldic",
|
||||||
0, OP_RS_RA_SH_MB5_ME5_C, 21<<26, "rlwinm",
|
0, OP_RS_RA_SH_MB5_ME5_C, 21<<26, "rlwinm",
|
||||||
0, OP_RS_RA_RB_MB6_C, 30<<26 | 8<<1, "rldcl",
|
0, OP_RS_RA_RB_MB6_C, 30<<26 | 8<<1, "rldcl",
|
||||||
0, OP_RS_RA_RB_ME6_C, 30<<26 | 9<<1, "rldcr",
|
0, OP_RS_RA_RB_ME6_C, 30<<26 | 9<<1, "rldcr",
|
||||||
0, OP_RS_RA_RB_MB5_ME5_C, 23<<26, "rlwnm",
|
0, OP_RS_RA_RB_MB5_ME5_C, 23<<26, "rlwnm",
|
||||||
0, OP_RS_RA_SH_MB6_SH_C, 30<<26 | 3<<2, "rldimi",
|
0, OP_RS_RA_SH_MB6_SH_C, 30<<26 | 3<<2, "rldimi",
|
||||||
|
|
|
@ -19,9 +19,9 @@ operation
|
||||||
| OP_FRS_RA_D FPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
|
| OP_FRS_RA_D FPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
|
||||||
| OP_FRS_RA_RB FPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
|
| OP_FRS_RA_RB FPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
|
||||||
| OP_FRT_FRA_FRB_C c FPR ',' FPR ',' FPR { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($7<<11)); }
|
| OP_FRT_FRA_FRB_C c FPR ',' FPR ',' FPR { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($7<<11)); }
|
||||||
| OP_FRT_FRA_FRC_FRB_C c FPR ',' FPR ',' FPR ',' FPR { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($9<<11) | ($7<<6)); }
|
| OP_FRT_FRA_FRC_FRB_C c FPR ',' FPR ',' FPR ',' FPR { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($9<<11) | ($7<<6)); }
|
||||||
| OP_FRT_FRA_FRC_C c FPR ',' FPR ',' FPR { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($7<<6)); }
|
| OP_FRT_FRA_FRC_C c FPR ',' FPR ',' FPR { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($7<<6)); }
|
||||||
| OP_FRT_FRB_C c FPR ',' FPR { emit4($1 | $2 | ($3<<21) | ($5<<11)); }
|
| OP_FRT_FRB_C c FPR ',' FPR { emit4($1 | $2 | ($3<<21) | ($5<<11)); }
|
||||||
| OP_FRT_RA_D FPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
|
| OP_FRT_RA_D FPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
|
||||||
| OP_FRT_RA_RB FPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
|
| OP_FRT_RA_RB FPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
|
||||||
| OP_FRT_C c FPR { emit4($1 | $2 | ($3<<21)); }
|
| OP_FRT_C c FPR { emit4($1 | $2 | ($3<<21)); }
|
||||||
|
@ -40,15 +40,15 @@ operation
|
||||||
| OP_RS_RA_D GPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
|
| OP_RS_RA_D GPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
|
||||||
| OP_RS_RA_DS GPR ',' ds '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
|
| OP_RS_RA_DS GPR ',' ds '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
|
||||||
| OP_RS_RA_NB GPR ',' GPR ',' nb { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
|
| OP_RS_RA_NB GPR ',' GPR ',' nb { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
|
||||||
| OP_RS_RA_UI GPR ',' GPR ',' e16 { emit4($1 | ($4<<21) | ($2<<16) | $6); }
|
| OP_RS_RA_UI GPR ',' GPR ',' e16 { emit4($1 | ($4<<21) | ($2<<16) | $6); }
|
||||||
| OP_RS_RA_UI_CC C GPR ',' GPR ',' e16 { emit4($1 | ($5<<21) | ($3<<16) | $7); }
|
| OP_RS_RA_UI_CC C GPR ',' GPR ',' e16 { emit4($1 | ($5<<21) | ($3<<16) | $7); }
|
||||||
| OP_RS_RA_RB GPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
|
| OP_RS_RA_RB GPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
|
||||||
| OP_RS_RA_RB_C c GPR ',' GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
|
| OP_RS_RA_RB_C c GPR ',' GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
|
||||||
| OP_RS_RA_RA_C c GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($5<<11)); }
|
| OP_RS_RA_RA_C c GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($5<<11)); }
|
||||||
| OP_RS_RA_RB_MB5_ME5_C c GPR ',' GPR ',' GPR ',' u5 ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | ($9<<6) | ($11<<1)); }
|
| OP_RS_RA_RB_MB5_ME5_C c GPR ',' GPR ',' GPR ',' u5 ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | ($9<<6) | ($11<<1)); }
|
||||||
| OP_RS_RA_RB_MB6_C c GPR ',' GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | (($9&0x1F)<<6) | (($9&0x20)>>0)); }
|
| OP_RS_RA_RB_MB6_C c GPR ',' GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | (($9&0x1F)<<6) | (($9&0x20)>>0)); }
|
||||||
| OP_RS_RA_RB_ME6_C c GPR ',' GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | (($9&0x1F)<<6) | (($9&0x20)>>0)); }
|
| OP_RS_RA_RB_ME6_C c GPR ',' GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | (($9&0x1F)<<6) | (($9&0x20)>>0)); }
|
||||||
| OP_RS_RA_SH_MB5_ME5_C c GPR ',' GPR ',' u5 ',' u5 ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | ($9<<6) | ($11<<1)); }
|
| OP_RS_RA_SH_MB5_ME5_C c GPR ',' GPR ',' u5 ',' u5 ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | ($9<<6) | ($11<<1)); }
|
||||||
| OP_RS_RA_SH_MB6_SH_C c GPR ',' GPR ',' u6 ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | ($9<<6) | (($7&0x20)>>4)); }
|
| OP_RS_RA_SH_MB6_SH_C c GPR ',' GPR ',' u6 ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | ($9<<6) | (($7&0x20)>>4)); }
|
||||||
| OP_RS_RA_SH_ME6_SH_C c GPR ',' GPR ',' u6 ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | ($9<<6) | (($7&0x20)>>4)); }
|
| OP_RS_RA_SH_ME6_SH_C c GPR ',' GPR ',' u6 ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | ($9<<6) | (($7&0x20)>>4)); }
|
||||||
| OP_RS_RA_SH5_C c GPR ',' GPR ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
|
| OP_RS_RA_SH5_C c GPR ',' GPR ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
|
||||||
|
@ -60,13 +60,14 @@ operation
|
||||||
| OP_LIA lia { emit4($1 | $2); }
|
| OP_LIA lia { emit4($1 | $2); }
|
||||||
| OP_LIL lil { emit4($1 | $2); }
|
| OP_LIL lil { emit4($1 | $2); }
|
||||||
| OP_LI32 li32 /* emitted in subrule */
|
| OP_LI32 li32 /* emitted in subrule */
|
||||||
|
| OP_POWERPC_FIXUP powerpcfixup /* emitted in subrule */
|
||||||
;
|
;
|
||||||
|
|
||||||
c
|
c
|
||||||
: /* nothing */ { $$ = 0; }
|
: /* nothing */ { $$ = 0; }
|
||||||
| C { $$ = 1; }
|
| C { $$ = 1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
e16
|
e16
|
||||||
: absexp
|
: absexp
|
||||||
{
|
{
|
||||||
|
@ -75,8 +76,34 @@ e16
|
||||||
serror("16-bit value out of range");
|
serror("16-bit value out of range");
|
||||||
$$ = (uint16_t) $1;
|
$$ = (uint16_t) $1;
|
||||||
}
|
}
|
||||||
|
| OP_HI expr
|
||||||
|
{
|
||||||
|
/* If this is a symbol reference, discard the symbol and keep only the
|
||||||
|
* offset part. */
|
||||||
|
quad type = $2.typ & S_TYP;
|
||||||
|
quad val = $2.val;
|
||||||
|
|
||||||
|
/* If the assembler stored a symbol for relocation later, we need to
|
||||||
|
* abandon it (because we're not going to generate a relocation). */
|
||||||
|
if (type != S_ABS)
|
||||||
|
relonami = 0;
|
||||||
|
|
||||||
|
$$ = ((quad)val) >> 16;
|
||||||
|
}
|
||||||
|
| OP_LO expr
|
||||||
|
{
|
||||||
|
quad type = $2.typ & S_TYP;
|
||||||
|
quad val = $2.val;
|
||||||
|
|
||||||
|
/* If the assembler stored a symbol for relocation later, we need to
|
||||||
|
* abandon it (because we're not going to generate a relocation). */
|
||||||
|
if (type != S_ABS)
|
||||||
|
relonami = 0;
|
||||||
|
|
||||||
|
$$ = val & 0xffff;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
u8
|
u8
|
||||||
: absexp
|
: absexp
|
||||||
{
|
{
|
||||||
|
@ -85,7 +112,7 @@ u8
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
u7
|
u7
|
||||||
: absexp
|
: absexp
|
||||||
{
|
{
|
||||||
|
@ -94,7 +121,7 @@ u7
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
u6
|
u6
|
||||||
: absexp
|
: absexp
|
||||||
{
|
{
|
||||||
|
@ -103,7 +130,7 @@ u6
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
u5
|
u5
|
||||||
: absexp
|
: absexp
|
||||||
{
|
{
|
||||||
|
@ -112,7 +139,7 @@ u5
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
u4
|
u4
|
||||||
: absexp
|
: absexp
|
||||||
{
|
{
|
||||||
|
@ -121,7 +148,7 @@ u4
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
u1
|
u1
|
||||||
: absexp
|
: absexp
|
||||||
{
|
{
|
||||||
|
@ -130,7 +157,7 @@ u1
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
u2
|
u2
|
||||||
: absexp
|
: absexp
|
||||||
{
|
{
|
||||||
|
@ -139,7 +166,7 @@ u2
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
ds
|
ds
|
||||||
: e16
|
: e16
|
||||||
{
|
{
|
||||||
|
@ -148,26 +175,26 @@ ds
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
nb
|
nb
|
||||||
: absexp
|
: absexp
|
||||||
{
|
{
|
||||||
if (($1 < 1) || ($1 > 32))
|
if (($1 < 1) || ($1 > 32))
|
||||||
serror("register count must be in the range 1..32");
|
serror("register count must be in the range 1..32");
|
||||||
|
|
||||||
if ($1 == 32)
|
if ($1 == 32)
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
else
|
else
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
bdl
|
bdl
|
||||||
: expr
|
: expr
|
||||||
{
|
{
|
||||||
int dist = $1.val - DOTVAL;
|
int dist = $1.val - DOTVAL;
|
||||||
fit(fitx(dist, 25));
|
fit(fitx(dist, 25));
|
||||||
|
|
||||||
if (dist & 0x3)
|
if (dist & 0x3)
|
||||||
serror("jump targets must be 4-aligned");
|
serror("jump targets must be 4-aligned");
|
||||||
|
|
||||||
|
@ -183,7 +210,7 @@ bda
|
||||||
{
|
{
|
||||||
int target = $1.val;
|
int target = $1.val;
|
||||||
fit(fitx(target, 16));
|
fit(fitx(target, 16));
|
||||||
|
|
||||||
if (target & 0x3)
|
if (target & 0x3)
|
||||||
serror("jump targets must be 4-aligned");
|
serror("jump targets must be 4-aligned");
|
||||||
|
|
||||||
|
@ -193,7 +220,7 @@ bda
|
||||||
$$ = target & 0xFFFD;
|
$$ = target & 0xFFFD;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
li32
|
li32
|
||||||
: GPR ',' expr
|
: GPR ',' expr
|
||||||
{
|
{
|
||||||
|
@ -215,7 +242,7 @@ lil
|
||||||
{
|
{
|
||||||
int dist = $1.val - DOTVAL;
|
int dist = $1.val - DOTVAL;
|
||||||
fit(fitx(dist, 26));
|
fit(fitx(dist, 26));
|
||||||
|
|
||||||
if (dist & 0x3)
|
if (dist & 0x3)
|
||||||
serror("jump targets must be 4-aligned");
|
serror("jump targets must be 4-aligned");
|
||||||
|
|
||||||
|
@ -223,13 +250,13 @@ lil
|
||||||
$$ = dist & 0x03FFFFFD;
|
$$ = dist & 0x03FFFFFD;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
lia
|
lia
|
||||||
: expr
|
: expr
|
||||||
{
|
{
|
||||||
int target = $1.val;
|
int target = $1.val;
|
||||||
fit(fitx(target, 26));
|
fit(fitx(target, 26));
|
||||||
|
|
||||||
if (target & 0x3)
|
if (target & 0x3)
|
||||||
serror("jump targets must be 4-aligned");
|
serror("jump targets must be 4-aligned");
|
||||||
|
|
||||||
|
@ -248,3 +275,14 @@ spr_num
|
||||||
$$ = ($1 >> 5) | (($1 & 0x1f) << 5);
|
$$ = ($1 >> 5) | (($1 & 0x1f) << 5);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
powerpcfixup
|
||||||
|
: expr
|
||||||
|
{
|
||||||
|
quad type = $1.typ & S_TYP;
|
||||||
|
quad val = $1.val;
|
||||||
|
if (type == S_ABS)
|
||||||
|
serror(".powerpcfixup is useless on absolute values");
|
||||||
|
newrelo($1.typ, RELOPPC | FIXUPFLAGS);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
|
@ -2,4 +2,3 @@
|
||||||
* $Source$
|
* $Source$
|
||||||
* $State$
|
* $State$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -169,11 +169,14 @@ TOKENS
|
||||||
/* Used only in instruction descriptions (to generate the correct syntax). */
|
/* Used only in instruction descriptions (to generate the correct syntax). */
|
||||||
|
|
||||||
GPRINDIRECT = { GPR reg; INT off; } 4 off "(" reg ")".
|
GPRINDIRECT = { GPR reg; INT off; } 4 off "(" reg ")".
|
||||||
|
GPRINDIRECT_OFFSET_LO = { GPR reg; ADDR adr; } 4 "lo [" adr "](" reg ")".
|
||||||
CONST = { INT val; } 4 val.
|
CONST = { INT val; } 4 val.
|
||||||
|
|
||||||
/* Primitives */
|
/* Primitives */
|
||||||
|
|
||||||
LABEL = { ADDR adr; } 4 adr.
|
LABEL = { ADDR adr; } 4 adr.
|
||||||
|
LABEL_OFFSET_HI = { ADDR adr; } 4 "hi " adr.
|
||||||
|
LABEL_OFFSET_LO = { ADDR adr; } 4 "lo " adr.
|
||||||
LOCAL = { INT off; } 4.
|
LOCAL = { INT off; } 4.
|
||||||
|
|
||||||
/* Allows us to use regvar() to refer to registers */
|
/* Allows us to use regvar() to refer to registers */
|
||||||
|
@ -282,7 +285,7 @@ INSTRUCTIONS
|
||||||
add GPR:wo, GPR:ro, GPR:ro.
|
add GPR:wo, GPR:ro, GPR:ro.
|
||||||
addX "add." GPR:wo, GPR:ro, GPR:ro.
|
addX "add." GPR:wo, GPR:ro, GPR:ro.
|
||||||
addi GPR:wo, GPR:ro, CONST:ro.
|
addi GPR:wo, GPR:ro, CONST:ro.
|
||||||
addis GPR:wo, GPR:ro, CONST:ro.
|
addis GPR:wo, GPR:ro, CONST+LABEL_OFFSET_HI:ro.
|
||||||
and GPR:wo, GPR:ro, GPR:ro.
|
and GPR:wo, GPR:ro, GPR:ro.
|
||||||
andc GPR:wo, GPR:ro, GPR:ro.
|
andc GPR:wo, GPR:ro, GPR:ro.
|
||||||
andiX "andi." GPR:wo:cc, GPR:ro, CONST:ro.
|
andiX "andi." GPR:wo:cc, GPR:ro, CONST:ro.
|
||||||
|
@ -329,10 +332,9 @@ INSTRUCTIONS
|
||||||
lhz GPR:wo, GPRINDIRECT:ro cost(4, 3).
|
lhz GPR:wo, GPRINDIRECT:ro cost(4, 3).
|
||||||
lhzx GPR:wo, GPR:ro, GPR:ro cost(4, 3).
|
lhzx GPR:wo, GPR:ro, GPR:ro cost(4, 3).
|
||||||
li32 GPR:wo, CONST:ro cost(8, 2).
|
li32 GPR:wo, CONST:ro cost(8, 2).
|
||||||
li32 GPR:wo, LABEL:ro cost(8, 2).
|
|
||||||
lwzu GPR:wo, GPRINDIRECT:ro cost(4, 3).
|
lwzu GPR:wo, GPRINDIRECT:ro cost(4, 3).
|
||||||
lwzx GPR:wo, GPR:ro, GPR:ro cost(4, 3).
|
lwzx GPR:wo, GPR:ro, GPR:ro cost(4, 3).
|
||||||
lwz GPR:wo, GPRINDIRECT:ro cost(4, 3).
|
lwz GPR:wo, GPRINDIRECT+GPRINDIRECT_OFFSET_LO:ro cost(4, 3).
|
||||||
nand GPR:wo, GPR:ro, GPR:ro.
|
nand GPR:wo, GPR:ro, GPR:ro.
|
||||||
neg GPR:wo, GPR:ro.
|
neg GPR:wo, GPR:ro.
|
||||||
nor GPR:wo, GPR:ro, GPR:ro.
|
nor GPR:wo, GPR:ro, GPR:ro.
|
||||||
|
@ -342,7 +344,7 @@ INSTRUCTIONS
|
||||||
mtspr SPR:wo, GPR:ro cost(4, 2).
|
mtspr SPR:wo, GPR:ro cost(4, 2).
|
||||||
or GPR:wo, GPR:ro, GPR:ro.
|
or GPR:wo, GPR:ro, GPR:ro.
|
||||||
orc GPR:wo, GPR:ro, GPR:ro.
|
orc GPR:wo, GPR:ro, GPR:ro.
|
||||||
ori GPR:wo, GPR:ro, CONST:ro.
|
ori GPR:wo, GPR:ro, CONST+LABEL_OFFSET_LO:ro.
|
||||||
oris GPR:wo, GPR:ro, CONST:ro.
|
oris GPR:wo, GPR:ro, CONST:ro.
|
||||||
orX "or." GPR:wo:cc, GPR:ro, GPR:ro.
|
orX "or." GPR:wo:cc, GPR:ro, GPR:ro.
|
||||||
rlwinm GPR:wo, GPR:ro, CONST:ro, CONST:ro, CONST:ro.
|
rlwinm GPR:wo, GPR:ro, CONST:ro, CONST:ro, CONST:ro.
|
||||||
|
@ -368,7 +370,8 @@ INSTRUCTIONS
|
||||||
xori GPR:wo, GPR:ro, CONST:ro.
|
xori GPR:wo, GPR:ro, CONST:ro.
|
||||||
xoris GPR:wo, GPR:ro, CONST:ro.
|
xoris GPR:wo, GPR:ro, CONST:ro.
|
||||||
|
|
||||||
comment "!" LABEL:ro cost(0, 0).
|
fixup ".powerpcfixup" LABEL:ro.
|
||||||
|
comment "!" LABEL:ro cost(0, 0).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -405,7 +408,9 @@ MOVES
|
||||||
from LABEL to GPR
|
from LABEL to GPR
|
||||||
gen
|
gen
|
||||||
COMMENT("move LABEL->GPR")
|
COMMENT("move LABEL->GPR")
|
||||||
li32 %2, {LABEL, %1.adr}
|
fixup {LABEL, %1.adr}
|
||||||
|
addis %2, R0, {LABEL_OFFSET_HI, %1.adr}
|
||||||
|
ori %2, %2, {LABEL_OFFSET_LO, %1.adr}
|
||||||
|
|
||||||
/* Sign extension */
|
/* Sign extension */
|
||||||
|
|
||||||
|
@ -1142,6 +1147,13 @@ PATTERNS
|
||||||
yields {IND_RC_H, %1.reg, %1.off}
|
yields {IND_RC_H, %1.reg, %1.off}
|
||||||
|
|
||||||
pat loi $1==INT32 /* Load word indirect */
|
pat loi $1==INT32 /* Load word indirect */
|
||||||
|
with LABEL
|
||||||
|
uses REG
|
||||||
|
gen
|
||||||
|
fixup {LABEL, %1.adr}
|
||||||
|
addis %a, R0, {LABEL_OFFSET_HI, %1.adr}
|
||||||
|
lwz %a, {GPRINDIRECT_OFFSET_LO, %a, %1.adr}
|
||||||
|
yields %a
|
||||||
with GPR
|
with GPR
|
||||||
yields {IND_RC_W, %1, 0}
|
yields {IND_RC_W, %1, 0}
|
||||||
with SUM_RC
|
with SUM_RC
|
||||||
|
|
|
@ -119,14 +119,13 @@ static uint32_t get_powerpc_valu(char* addr, uint16_t type)
|
||||||
/* branch instruction */
|
/* branch instruction */
|
||||||
return opcode1 & 0x03fffffd;
|
return opcode1 & 0x03fffffd;
|
||||||
}
|
}
|
||||||
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) &&
|
else
|
||||||
((opcode2 & 0xfc000000) == 0x60000000))
|
|
||||||
{
|
{
|
||||||
/* addis / ori instruction pair */
|
/* If it's not a branch, we're just going to assume that the user
|
||||||
|
* knows what they're doing and this is a addis/ori pair (or
|
||||||
|
* compatible). */
|
||||||
return ((opcode1 & 0xffff) << 16) | (opcode2 & 0xffff);
|
return ((opcode1 & 0xffff) << 16) | (opcode2 & 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(0 && "unrecognised PowerPC instruction");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -260,17 +259,17 @@ static void put_powerpc_valu(char* addr, uint32_t value, uint16_t type)
|
||||||
i |= value & 0x03fffffd;
|
i |= value & 0x03fffffd;
|
||||||
write4(i, addr, type);
|
write4(i, addr, type);
|
||||||
}
|
}
|
||||||
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) &&
|
else
|
||||||
((opcode2 & 0xfc000000) == 0x60000000))
|
|
||||||
{
|
{
|
||||||
|
/* If it's not a branch, we're just going to assume that the user
|
||||||
|
* knows what they're doing and this is a addis/ori pair (or
|
||||||
|
* compatible). */
|
||||||
uint16_t hi = value >> 16;
|
uint16_t hi = value >> 16;
|
||||||
uint16_t lo = value & 0xffff;
|
uint16_t lo = value & 0xffff;
|
||||||
|
|
||||||
write4((opcode1 & 0xffff0000) | hi, addr+0, type);
|
write4((opcode1 & 0xffff0000) | hi, addr+0, type);
|
||||||
write4((opcode2 & 0xffff0000) | lo, addr+4, type);
|
write4((opcode2 & 0xffff0000) | lo, addr+4, type);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
assert(0 && "unrecognised PowerPC instruction");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -339,7 +338,7 @@ addrelo(relo, names, valu_out)
|
||||||
extern int hash();
|
extern int hash();
|
||||||
extern struct outname *searchname();
|
extern struct outname *searchname();
|
||||||
extern unsigned indexof();
|
extern unsigned indexof();
|
||||||
extern struct outhead outhead;
|
extern struct outhead outhead;
|
||||||
|
|
||||||
name = searchname(local->on_mptr, hash(local->on_mptr));
|
name = searchname(local->on_mptr, hash(local->on_mptr));
|
||||||
if (name == (struct outname *)0)
|
if (name == (struct outname *)0)
|
||||||
|
|
Loading…
Reference in a new issue