Merge pull request #52 from kernigh/pr-relolis
PowerPC: more ha16/lo16 from ncg, new RELOLIS
This commit is contained in:
commit
8f79699ea8
6
h/out.h
6
h/out.h
|
@ -65,9 +65,9 @@ struct outname {
|
|||
#define RELO1 1 /* 1 byte */
|
||||
#define RELO2 2 /* 2 bytes */
|
||||
#define RELO4 3 /* 4 bytes */
|
||||
#define RELOPPC 4 /* PowerPC 26-bit address */
|
||||
/* relo 5 is unused */
|
||||
#define RELOVC4 6 /* VideoCore IV address in 32-bit instruction */
|
||||
#define RELOPPC 4 /* PowerPC 26-bit address */
|
||||
#define RELOLIS 5 /* PowerPC lis */
|
||||
#define RELOVC4 6 /* VideoCore IV address in 32-bit instruction */
|
||||
|
||||
#define RELPC 0x2000 /* pc relative */
|
||||
#define RELBR 0x4000 /* High order byte lowest address. */
|
||||
|
|
|
@ -11,15 +11,13 @@
|
|||
#define DEBUG 0
|
||||
|
||||
#undef valu_t
|
||||
#define valu_t long
|
||||
#define valu_t int32_t
|
||||
|
||||
#undef ADDR_T
|
||||
#define ADDR_T long
|
||||
#define ADDR_T uint32_t
|
||||
|
||||
#undef word_t
|
||||
#define word_t long
|
||||
|
||||
typedef uint32_t quad;
|
||||
#define word_t uint32_t
|
||||
|
||||
#undef ALIGNWORD
|
||||
#define ALIGNWORD 4
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
* $State$
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
/*
|
||||
* Do not #include anything here. Do it in mach/proto/as/comm0.h
|
||||
*/
|
||||
|
||||
extern quad emit_hi(struct expr_t* expr, bool is_signed);
|
||||
extern quad emit_lo(struct expr_t* expr);
|
||||
void no_hl(void);
|
||||
word_t eval_hl(struct expr_t* expr, int token);
|
||||
void emit_hl(word_t in);
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
%token <y_word> OP_LIA
|
||||
%token <y_word> OP_LIL
|
||||
%token <y_word> OP_LI32
|
||||
%token <y_word> OP_RA_RS_C
|
||||
%token <y_word> OP_RA_RS_RB_C
|
||||
%token <y_word> OP_RA_RS_RB_MB5_ME5_C
|
||||
%token <y_word> OP_RA_RS_RB_MB6_C
|
||||
|
@ -58,17 +59,16 @@
|
|||
%token <y_word> OP_RA_RS_SH5_MB5_ME5_C
|
||||
%token <y_word> OP_RA_RS_SH6_C
|
||||
%token <y_word> OP_RA_RS_SH6_MB6_C
|
||||
%token <y_word> OP_RA_RS_UI
|
||||
%token <y_word> OP_RA_RS_UI_CC
|
||||
%token <y_word> OP_RS_FXM
|
||||
%token <y_word> OP_RS_RA
|
||||
%token <y_word> OP_RS_RA_C
|
||||
%token <y_word> OP_RS_RA_D
|
||||
%token <y_word> OP_RS_RA_DS
|
||||
%token <y_word> OP_RS_RA_NB
|
||||
%token <y_word> OP_RS_RA_RB
|
||||
%token <y_word> OP_RS_RA_RB_C
|
||||
%token <y_word> OP_RS_RA_RA_C
|
||||
%token <y_word> OP_RS_RA_UI
|
||||
%token <y_word> OP_RS_RA_UI_CC
|
||||
%token <y_word> OP_RS_RB
|
||||
%token <y_word> OP_RS_SPR
|
||||
%token <y_word> OP_RS_SR
|
||||
|
|
|
@ -498,25 +498,25 @@
|
|||
0, OP_TOX_RA_SI, 3<<26 | 31<<21, "twui",
|
||||
|
||||
/* page 62 */
|
||||
0, OP_RS_RA_UI_CC, 28<<26, "andi", /* C compulsory */
|
||||
0, OP_RS_RA_UI_CC, 29<<26, "andis", /* C compulsory */
|
||||
0, OP_RS_RA_UI, 24<<26, "ori",
|
||||
0, OP_RS_RA_UI, 25<<26, "oris",
|
||||
0, OP_RS_RA_UI, 26<<26, "xori",
|
||||
0, OP_RS_RA_UI, 27<<26, "xoris",
|
||||
0, OP_RS_RA_RB_C, 31<<26 | 28<<1, "and",
|
||||
0, OP_RS_RA_RB_C, 31<<26 | 444<<1, "or",
|
||||
0, OP_RS_RA_RB_C, 31<<26 | 316<<1, "xor",
|
||||
0, OP_RS_RA_RB_C, 31<<26 | 476<<1, "nand",
|
||||
0, OP_RS_RA_RB_C, 31<<26 | 124<<1, "nor",
|
||||
0, OP_RS_RA_RB_C, 31<<26 | 284<<1, "eqv",
|
||||
0, OP_RS_RA_RB_C, 31<<26 | 60<<1, "andc",
|
||||
0, OP_RS_RA_RB_C, 31<<26 | 412<<1, "orc",
|
||||
0, OP_RS_RA_C, 31<<26 | 954<<1, "extsb",
|
||||
0, OP_RS_RA_C, 31<<26 | 922<<1, "extsh",
|
||||
0, OP_RS_RA_C, 31<<26 | 986<<1, "extsw",
|
||||
0, OP_RS_RA_C, 31<<26 | 58<<1, "cntlzd",
|
||||
0, OP_RS_RA_C, 31<<26 | 26<<1, "cntlzw",
|
||||
0, OP_RA_RS_UI_CC, 28<<26, "andi", /* C compulsory */
|
||||
0, OP_RA_RS_UI_CC, 29<<26, "andis", /* C compulsory */
|
||||
0, OP_RA_RS_UI, 24<<26, "ori",
|
||||
0, OP_RA_RS_UI, 25<<26, "oris",
|
||||
0, OP_RA_RS_UI, 26<<26, "xori",
|
||||
0, OP_RA_RS_UI, 27<<26, "xoris",
|
||||
0, OP_RA_RS_RB_C, 31<<26 | 28<<1, "and",
|
||||
0, OP_RA_RS_RB_C, 31<<26 | 444<<1, "or",
|
||||
0, OP_RA_RS_RB_C, 31<<26 | 316<<1, "xor",
|
||||
0, OP_RA_RS_RB_C, 31<<26 | 476<<1, "nand",
|
||||
0, OP_RA_RS_RB_C, 31<<26 | 124<<1, "nor",
|
||||
0, OP_RA_RS_RB_C, 31<<26 | 284<<1, "eqv",
|
||||
0, OP_RA_RS_RB_C, 31<<26 | 60<<1, "andc",
|
||||
0, OP_RA_RS_RB_C, 31<<26 | 412<<1, "orc",
|
||||
0, OP_RA_RS_C, 31<<26 | 954<<1, "extsb",
|
||||
0, OP_RA_RS_C, 31<<26 | 922<<1, "extsh",
|
||||
0, OP_RA_RS_C, 31<<26 | 986<<1, "extsw",
|
||||
0, OP_RA_RS_C, 31<<26 | 58<<1, "cntlzd",
|
||||
0, OP_RA_RS_C, 31<<26 | 26<<1, "cntlzw",
|
||||
|
||||
/* extended m using logic */
|
||||
0, OP_RS_RA_RA_C, 31<<26 | 444<<1, "mr",
|
||||
|
|
|
@ -10,11 +10,11 @@ operation
|
|||
| OP_BF_BFA CR ',' CR { emit4($1 | ($2<<23) | ($4<<18)); }
|
||||
| OP_BF_FRA_FRB CR ',' FPR ',' FPR { emit4($1 | ($2<<23) | ($4<<16) | ($6<<11)); }
|
||||
| OP_BF_L_RA_RB CR ',' u1 ',' GPR ',' GPR { emit4($1 | ($2<<23) | ($4<<21) | ($6<<16) | ($8<<11)); }
|
||||
| OP_BF_L_RA_SI CR ',' u1 ',' GPR ',' e16 { emit4($1 | ($2<<23) | ($4<<21) | ($6<<16) | $8); }
|
||||
| OP_BF_L_RA_UI CR ',' u1 ',' GPR ',' e16 { emit4($1 | ($2<<23) | ($4<<21) | ($6<<16) | $8); }
|
||||
| OP_BF_L_RA_SI CR ',' u1 ',' GPR ',' e16 { emit_hl($1 | ($2<<23) | ($4<<21) | ($6<<16) | $8); }
|
||||
| OP_BF_L_RA_UI CR ',' u1 ',' GPR ',' e16 { emit_hl($1 | ($2<<23) | ($4<<21) | ($6<<16) | $8); }
|
||||
| OP_BF_RA_RB cr_opt GPR ',' GPR { emit4($1 | ($2<<23) | ($3<<16) | ($5<<11)); }
|
||||
| OP_BF_RA_SI cr_opt GPR ',' e16 { emit4($1 | ($2<<23) | ($3<<16) | $5); }
|
||||
| OP_BF_RA_UI cr_opt GPR ',' e16 { emit4($1 | ($2<<23) | ($3<<16) | $5); }
|
||||
| OP_BF_RA_SI cr_opt GPR ',' e16 { emit_hl($1 | ($2<<23) | ($3<<16) | $5); }
|
||||
| OP_BF_RA_UI cr_opt GPR ',' e16 { emit_hl($1 | ($2<<23) | ($3<<16) | $5); }
|
||||
| OP_BF_U_C c CR ',' u4 { emit4($1 | $2 | ($3<<23) | ($5<<12)); }
|
||||
| OP_BH { emit4($1); }
|
||||
| OP_BH u2 { emit4($1 | ($2<<11)); }
|
||||
|
@ -33,15 +33,16 @@ operation
|
|||
| OP_BT_BT_BT u5 { emit4($1 | ($2<<21) | ($2<<16) | ($2<<11)); }
|
||||
| OP_BT_C c u5 { emit4($1 | $2 | ($3<<21)); }
|
||||
| OP_FLM_FRB_C c u8 ',' FPR { emit4($1 | $2 | ($3<<17) | ($5<<11)); }
|
||||
| OP_FRS_RA_D FPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
|
||||
| OP_FRS_RA_D FPR ',' e16 '(' GPR ')' { emit_hl($1 | ($2<<21) | ($6<<16) | $4); }
|
||||
| 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_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_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 ')' { emit_hl($1 | ($2<<21) | ($6<<16) | $4); }
|
||||
| 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_RA_RS_C c GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16)); }
|
||||
| OP_RA_RS_RB_C c GPR ',' GPR ',' GPR
|
||||
{ emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
|
||||
| OP_RA_RS_RB_MB5_ME5_C c GPR ',' GPR ',' GPR ',' u5 ',' u5
|
||||
|
@ -58,35 +59,34 @@ operation
|
|||
{ emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6($7)); }
|
||||
| OP_RA_RS_SH6_MB6_C c GPR ',' GPR ',' u6 ',' u6
|
||||
{ emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6($7) | MB6($9)); }
|
||||
| OP_RA_RS_UI GPR ',' GPR ',' e16 { emit_hl($1 | ($4<<21) | ($2<<16) | $6); }
|
||||
| OP_RA_RS_UI_CC C GPR ',' GPR ',' e16 { emit_hl($1 | ($5<<21) | ($3<<16) | $7); }
|
||||
| OP_RT GPR { emit4($1 | ($2<<21)); }
|
||||
| OP_RT_RA_C c GPR ',' GPR { emit4($1 | $2 | ($3<<21) | ($5<<16)); }
|
||||
| OP_RT_RA_D GPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
|
||||
| OP_RT_RA_DS GPR ',' ds '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); }
|
||||
| OP_RT_RA_D GPR ',' e16 '(' GPR ')' { emit_hl($1 | ($2<<21) | ($6<<16) | $4); }
|
||||
| OP_RT_RA_DS GPR ',' ds '(' GPR ')' { emit_hl($1 | ($2<<21) | ($6<<16) | $4); }
|
||||
| OP_RT_RA_NB GPR ',' GPR ',' nb { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
|
||||
| OP_RT_RA_RB GPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
|
||||
| OP_RT_RA_RB_C c GPR ',' GPR ',' GPR { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($7<<11)); }
|
||||
| OP_RT_RA_SI GPR ',' GPR ',' e16 { emit4($1 | ($2<<21) | ($4<<16) | $6); }
|
||||
| OP_RT_RA_SI_addic c GPR ',' GPR ',' e16 { emit4($1 | ($2<<26) | ($3<<21) | ($5<<16) | $7); }
|
||||
| OP_RT_RA_SI GPR ',' GPR ',' e16 { emit_hl($1 | ($2<<21) | ($4<<16) | $6); }
|
||||
| OP_RT_RA_SI_addic c GPR ',' GPR ',' e16 { emit_hl($1 | ($2<<26) | ($3<<21) | ($5<<16) | $7); }
|
||||
| OP_RT_RA_SI_subi GPR ',' GPR ',' negate16 { emit4($1 | ($2<<21) | ($4<<16) | $6); }
|
||||
| OP_RT_RA_SI_subic c GPR ',' GPR ',' negate16 { emit4($1 | ($2<<26) | ($3<<21) | ($5<<16) | $7); }
|
||||
| OP_RT_RB_RA_C c GPR ',' GPR ',' GPR { emit4($1 | $2 | ($3<<21) | ($7<<16) | ($5<<11)); }
|
||||
| OP_RT_SI GPR ',' e16 { emit4($1 | ($2<<21) | $4); }
|
||||
| OP_RT_SI GPR ',' e16 { emit_hl($1 | ($2<<21) | $4); }
|
||||
| OP_RT_SPR GPR ',' spr_num { emit4($1 | ($2<<21) | ($4<<11)); }
|
||||
| OP_RS_FXM u7 ',' GPR { emit4($1 | ($4<<21) | ($2<<12)); }
|
||||
| OP_RS_RA_C c GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16)); }
|
||||
| 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_D GPR ',' e16 '(' GPR ')' { emit_hl($1 | ($2<<21) | ($6<<16) | $4); }
|
||||
| OP_RS_RA_DS GPR ',' ds '(' GPR ')' { emit_hl($1 | ($2<<21) | ($6<<16) | $4); }
|
||||
| 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_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_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_SPR spr_num ',' GPR { emit4($1 | ($4<<21) | ($2<<11)); }
|
||||
| OP_TO_RA_RB u5 ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
|
||||
| OP_TO_RA_SI u5 ',' GPR ',' e16 { emit4($1 | ($2<<21) | ($4<<16) | $6); }
|
||||
| OP_TO_RA_SI u5 ',' GPR ',' e16 { emit_hl($1 | ($2<<21) | ($4<<16) | $6); }
|
||||
| OP_TOX_RA_RB GPR ',' GPR { emit4($1 | ($2<<16) | ($4<<11)); }
|
||||
| OP_TOX_RA_SI GPR ',' e16 { emit4($1 | ($2<<16) | $4); }
|
||||
| OP_TOX_RA_SI GPR ',' e16 { emit_hl($1 | ($2<<16) | $4); }
|
||||
| OP_LEV { emit4($1); }
|
||||
| OP_LEV u7 { emit4($1 | ($2<<5)); }
|
||||
| OP_LIA lia { emit4($1 | $2); }
|
||||
|
@ -94,7 +94,7 @@ operation
|
|||
| OP_LI32 li32 /* emitted in subrule */
|
||||
| OP_clrlsldi c GPR ',' GPR ',' u6 ',' u6
|
||||
{
|
||||
quad mb = ($7 - $9) & 0x3f;
|
||||
word_t mb = ($7 - $9) & 0x3f;
|
||||
fit($9 <= $7);
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6($9) | MB6(mb));
|
||||
}
|
||||
|
@ -104,41 +104,41 @@ operation
|
|||
}
|
||||
| OP_clrrdi c GPR ',' GPR ',' u6
|
||||
{
|
||||
quad me = 63 - $7;
|
||||
word_t me = 63 - $7;
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6(0) | MB6(me));
|
||||
}
|
||||
| OP_extldi c GPR ',' GPR ',' u6 ',' u6
|
||||
{
|
||||
quad me = ($7 - 1) & 0x3f;
|
||||
word_t me = ($7 - 1) & 0x3f;
|
||||
fit($7 > 0);
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6($9) | MB6(me));
|
||||
}
|
||||
| OP_extrdi c GPR ',' GPR ',' u6 ',' u6
|
||||
{
|
||||
quad sh = ($9 + $7) & 0x3f;
|
||||
quad mb = (64 - $7) & 0x3f;
|
||||
word_t sh = ($9 + $7) & 0x3f;
|
||||
word_t mb = (64 - $7) & 0x3f;
|
||||
fit($7 > 0);
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6(sh) | MB6(mb));
|
||||
}
|
||||
| OP_rotrdi c GPR ',' GPR ',' u6
|
||||
{
|
||||
quad sh = (64 - $7) & 0x3f;
|
||||
word_t sh = (64 - $7) & 0x3f;
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6(sh) | MB6(0));
|
||||
}
|
||||
| OP_sldi c GPR ',' GPR ',' u6
|
||||
{
|
||||
quad me = 63 - $7;
|
||||
word_t me = 63 - $7;
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6($7) | MB6(me));
|
||||
}
|
||||
| OP_srdi c GPR ',' GPR ',' u6
|
||||
{
|
||||
quad sh = (64 - $7) & 0x3f;
|
||||
word_t sh = (64 - $7) & 0x3f;
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6(sh) | MB6($7));
|
||||
}
|
||||
| OP_clrlslwi c GPR ',' GPR ',' u5 ',' u5
|
||||
{
|
||||
quad mb = ($7 - $9) & 0x1f;
|
||||
quad me = 31 - $9;
|
||||
word_t mb = ($7 - $9) & 0x1f;
|
||||
word_t me = 31 - $9;
|
||||
fit($9 <= $7);
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) |
|
||||
($9<<11) | (mb<<6) | (me<<1));
|
||||
|
@ -150,56 +150,56 @@ operation
|
|||
}
|
||||
| OP_clrrwi c GPR ',' GPR ',' u5
|
||||
{
|
||||
quad me = 31 - $7;
|
||||
word_t me = 31 - $7;
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) |
|
||||
(0<<11) | (0<<6) | (me<<1));
|
||||
}
|
||||
| OP_extlwi c GPR ',' GPR ',' u5 ',' u5
|
||||
{
|
||||
quad me = ($7 - 1) & 0x1f;
|
||||
word_t me = ($7 - 1) & 0x1f;
|
||||
fit($7 > 0);
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) |
|
||||
($9<<11) | (0<<6) | (me<<1));
|
||||
}
|
||||
| OP_extrwi c GPR ',' GPR ',' u5 ',' u5
|
||||
{
|
||||
quad sh = ($9 + $7) & 0x1f;
|
||||
quad mb = (32 - $7) & 0x1f;
|
||||
word_t sh = ($9 + $7) & 0x1f;
|
||||
word_t mb = (32 - $7) & 0x1f;
|
||||
fit($7 > 0);
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) |
|
||||
(sh<<11) | (mb<<6) | (31<<1));
|
||||
}
|
||||
| OP_inslwi c GPR ',' GPR ',' u5 ',' u5
|
||||
{
|
||||
quad sh = (32 - $9) & 0x1f;
|
||||
quad me = ($9 + $7 - 1) & 0x1f;
|
||||
word_t sh = (32 - $9) & 0x1f;
|
||||
word_t me = ($9 + $7 - 1) & 0x1f;
|
||||
fit($7 > 0);
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) |
|
||||
(sh<<11) | ($9<<6) | (me<<1));
|
||||
}
|
||||
| OP_insrwi c GPR ',' GPR ',' u5 ',' u5
|
||||
{
|
||||
quad sh = (32 - $9 - $7) & 0x1f;
|
||||
quad me = ($9 + $7 - 1) & 0x1f;
|
||||
word_t sh = (32 - $9 - $7) & 0x1f;
|
||||
word_t me = ($9 + $7 - 1) & 0x1f;
|
||||
fit($7 > 0);
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) |
|
||||
(sh<<11) | ($9<<6) | (me<<1));
|
||||
}
|
||||
| OP_rotrwi c GPR ',' GPR ',' u5
|
||||
{
|
||||
quad sh = (32 - $7) & 0x1f;
|
||||
word_t sh = (32 - $7) & 0x1f;
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) |
|
||||
(sh<<11) | (0<<6) | (31<<1));
|
||||
}
|
||||
| OP_slwi c GPR ',' GPR ',' u5
|
||||
{
|
||||
quad me = 31 - $7;
|
||||
word_t me = 31 - $7;
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) |
|
||||
($7<<11) | (0<<6) | (me<<1));
|
||||
}
|
||||
| OP_srwi c GPR ',' GPR ',' u5
|
||||
{
|
||||
quad sh = (32 - $7) & 0x1f;
|
||||
word_t sh = (32 - $7) & 0x1f;
|
||||
emit4($1 | $2 | ($5<<21) | ($3<<16) |
|
||||
(sh<<11) | ($7<<6) | (31<<1));
|
||||
}
|
||||
|
@ -217,10 +217,11 @@ e16
|
|||
if (($1 < -0x8000) || ($1 > 0xffff))
|
||||
serror("16-bit value out of range");
|
||||
$$ = (uint16_t) $1;
|
||||
no_hl();
|
||||
}
|
||||
| OP_HI ASC_LPAR expr ASC_RPAR { $$ = emit_hi(&$3, false); }
|
||||
| OP_HA ASC_LPAR expr ASC_RPAR { $$ = emit_hi(&$3, true); }
|
||||
| OP_LO ASC_LPAR expr ASC_RPAR { $$ = emit_lo(&$3); }
|
||||
| OP_HI ASC_LPAR expr ASC_RPAR { $$ = eval_hl(&$3, OP_HI); }
|
||||
| OP_HA ASC_LPAR expr ASC_RPAR { $$ = eval_hl(&$3, OP_HA); }
|
||||
| OP_LO ASC_LPAR expr ASC_RPAR { $$ = eval_hl(&$3, OP_LO); }
|
||||
;
|
||||
|
||||
negate16
|
||||
|
@ -367,8 +368,8 @@ bda
|
|||
li32
|
||||
: GPR ',' expr
|
||||
{
|
||||
quad type = $3.typ & S_TYP;
|
||||
quad val = $3.val;
|
||||
word_t type = $3.typ & S_TYP;
|
||||
word_t val = $3.val;
|
||||
if ((type == S_ABS) && (val <= 0xffff))
|
||||
emit4((14<<26) | ($1<<21) | (0<<16) | val); /* addi */
|
||||
else
|
||||
|
|
|
@ -1,38 +1,75 @@
|
|||
static int hl_token;
|
||||
static expr_t hl_expr;
|
||||
|
||||
quad emit_hi(struct expr_t* expr, bool is_signed)
|
||||
{
|
||||
/* If this is a symbol reference, discard the symbol and keep only the
|
||||
* offset part. */
|
||||
quad type = expr->typ & S_TYP;
|
||||
quad val = expr->val;
|
||||
uint16_t hi = val >> 16;
|
||||
uint16_t lo = val & 0xffff;
|
||||
|
||||
if (type != S_ABS)
|
||||
newrelo(expr->typ, RELOPPC | FIXUPFLAGS);
|
||||
|
||||
/* If the low half of this relocation is going to be a memory operation,
|
||||
* then it'll be treated as a signed value. That means that values greater
|
||||
* than 0x7fff will cause the high word to have 1 subtracted from it; so
|
||||
* we apply an adjustment here.
|
||||
*/
|
||||
|
||||
if (is_signed && (lo > 0x7fff))
|
||||
hi++;
|
||||
|
||||
return hi;
|
||||
void no_hl(void) {
|
||||
hl_token = 0;
|
||||
}
|
||||
|
||||
quad emit_lo(struct expr_t* expr)
|
||||
word_t eval_hl(expr_t* expr, int token)
|
||||
{
|
||||
quad type = expr->typ & S_TYP;
|
||||
quad val = expr->val;
|
||||
word_t val = expr->val;
|
||||
uint16_t hi = val >> 16;
|
||||
uint16_t lo = val & 0xffff;
|
||||
|
||||
/* If the assembler stored a symbol for relocation later, we need to
|
||||
* abandon it (because the relocation was generated by emit_ha). */
|
||||
hl_token = token;
|
||||
hl_expr = *expr;
|
||||
|
||||
if (type != S_ABS)
|
||||
relonami = 0;
|
||||
|
||||
return val & 0xffff;
|
||||
switch (token) {
|
||||
case OP_HI: /* hi16[expr] */
|
||||
return hi;
|
||||
case OP_HA: /* ha16[expr]*/
|
||||
/*
|
||||
* If the low half will be treated as a signed value,
|
||||
* then values greater than 0x7fff will cause the high
|
||||
* half to have 1 subtracted from it; so we apply an
|
||||
* adjustment here.
|
||||
*/
|
||||
if (lo > 0x7fff)
|
||||
hi++;
|
||||
return hi;
|
||||
case OP_LO: /* lo16[expr] */
|
||||
return lo;
|
||||
}
|
||||
}
|
||||
|
||||
void emit_hl(word_t in)
|
||||
{
|
||||
word_t reg;
|
||||
int type;
|
||||
|
||||
switch (hl_token) {
|
||||
case OP_HI: /* hi16[expr] */
|
||||
case OP_HA: /* ha16[expr] */
|
||||
if (PASS_RELO && (hl_expr.typ & S_TYP) != S_ABS) {
|
||||
/*
|
||||
* RELOLIS only works with lis _, _ (same as
|
||||
* addis _, r0, _). Check if instruction
|
||||
* isn't addis or register RA isn't r0.
|
||||
*/
|
||||
if ((in & 0xfc1f0000) != (0x3c000000))
|
||||
serror("relocation only works with lis");
|
||||
|
||||
/*
|
||||
* High bit: ha16 flag
|
||||
* Next 5 bits: register RT
|
||||
* Low 26 bits: signed offset
|
||||
*/
|
||||
fit(fitx(hl_expr.val, 26));
|
||||
newrelo(hl_expr.typ, RELOLIS | FIXUPFLAGS);
|
||||
reg = (in >> 21) & 0x1f;
|
||||
in = (hl_token == OP_HA) << 31;
|
||||
in |= reg << 26;
|
||||
in |= hl_expr.val & 0x03ffffff;
|
||||
}
|
||||
break;
|
||||
case OP_LO: /* lo16[expr] */
|
||||
if (PASS_RELO && (hl_expr.typ & S_TYP) != S_ABS) {
|
||||
DOTVAL += 2;
|
||||
newrelo(hl_expr.typ, RELO2 | FIXUPFLAGS);
|
||||
DOTVAL -= 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
emit4(in);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -140,6 +140,9 @@ showrelo()
|
|||
case RELOPPC:
|
||||
printf("\tPowerPC 26-bit address\n");
|
||||
break;
|
||||
case RELOLIS:
|
||||
printf("\tPowerPC lis instruction\n");
|
||||
break;
|
||||
case RELOVC4:
|
||||
printf("\tVideoCore IV address in 32-bit instruction\n");
|
||||
break;
|
||||
|
|
|
@ -161,12 +161,13 @@ struct outrelo {
|
|||
/*
|
||||
* relocation type bits
|
||||
*/
|
||||
#define RELSZ 0x0fff /* relocation length */
|
||||
#define RELSZ 0x0fff /* relocation length */
|
||||
#define RELO1 0x01 /* 1 byte */
|
||||
#define RELO2 0x02 /* 2 bytes */
|
||||
#define RELO4 0x03 /* 4 bytes */
|
||||
#define RELOPPC 0x04 /* 26-bit PowerPC address */
|
||||
#define RELOVC4 0x06 /* VideoCore IV address in 32-bit insruction */
|
||||
#define RELOLIS 0x05 /* PowerPC lis */
|
||||
#define RELOVC4 0x06 /* VideoCore IV address in 32-bit insruction */
|
||||
#define RELPC 0x2000 /* pc relative */
|
||||
#define RELBR 0x4000 /* High order byte lowest address. */
|
||||
#define RELWR 0x8000 /* High order word lowest address. */
|
||||
|
@ -225,10 +226,23 @@ is an absolute number, and the datum is relocated pc relative.
|
|||
The relocatable datum must then be relocated with respect to the
|
||||
base address of its section.
|
||||
.PP
|
||||
For RELOPPC and RELOVC4, the relocatable datum is a PowerPC or
|
||||
VideoCore IV instruction.
|
||||
The relocation depends on the instruction, and uses an offset encoded
|
||||
in the instruction.
|
||||
.PP
|
||||
RELOLIS assembles a PowerPC \fBlis\fR instruction.
|
||||
The relocatable datum is a 4-byte integer.
|
||||
The high bit is set for ha16 or clear for hi16.
|
||||
The next 5 bits are the register \fIRT\fR.
|
||||
The low 26 bits are a signed offset.
|
||||
The relocation replaces the datum with the PowerPC instruction
|
||||
\(oq\fBlis\fR\ \fIRT\fR,\ ha16[\fIsymbol\fR\ +\ \fIoffset\fR]\(cq.
|
||||
.PP
|
||||
.B The symbol table.
|
||||
.br
|
||||
This table contains definitions of symbols. It is referred to by
|
||||
outrelo-structures, and can be used by debuggers.
|
||||
This table contains definitions of symbols.
|
||||
It is referred to by outrelo-structures, and can be used by debuggers.
|
||||
Entries in this table have the following structure:
|
||||
.PP
|
||||
.nf
|
||||
|
|
|
@ -165,8 +165,17 @@ static uint32_t get_powerpc_valu(char* addr, uint16_t type)
|
|||
return ((hi << 16) | lo);
|
||||
}
|
||||
|
||||
fatal("Don't know how to read from PowerPC fixup on instructions 0x%08x+0x%08x",
|
||||
opcode1, opcode2);
|
||||
fatal("Don't know how to read from PowerPC fixup on instructions 0x%08lx+0x%08lx",
|
||||
(unsigned long)opcode1, (unsigned long)opcode2);
|
||||
}
|
||||
|
||||
/* RELOLIS stores a signed 26-bit offset in the low bits. */
|
||||
static uint32_t get_lis_valu(char *addr, uint16_t type)
|
||||
{
|
||||
uint32_t valu = read4(addr, type) & 0x03ffffff;
|
||||
if (valu & 0x02000000)
|
||||
valu |= 0xfc000000; /* sign extension */
|
||||
return valu;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -184,6 +193,8 @@ static uint32_t getvalu(char* addr, uint16_t type)
|
|||
return read4(addr, type);
|
||||
case RELOPPC:
|
||||
return get_powerpc_valu(addr, type);
|
||||
case RELOLIS:
|
||||
return get_lis_valu(addr, type);
|
||||
case RELOVC4:
|
||||
return get_vc4_valu(addr);
|
||||
default:
|
||||
|
@ -327,8 +338,34 @@ static void put_powerpc_valu(char* addr, uint32_t value, uint16_t type)
|
|||
}
|
||||
|
||||
else
|
||||
fatal("Don't know how to write a PowerPC fixup to instructions 0x%08x+0x%08x",
|
||||
opcode1, opcode2);
|
||||
fatal("Don't know how to write a PowerPC fixup to instructions 0x%08lx+0x%08lx",
|
||||
(unsigned long)opcode1, (unsigned long)opcode2);
|
||||
}
|
||||
|
||||
/* Writes a PowerPC lis instruction. */
|
||||
static void put_lis_valu(char* addr, uint32_t value, uint16_t type)
|
||||
{
|
||||
uint32_t opcode, reg;
|
||||
uint16_t hi, lo;
|
||||
bool ha16;
|
||||
|
||||
/* ha16 flag in high bit, register in next 5 bits */
|
||||
opcode = read4(addr, type);
|
||||
ha16 = opcode >> 31;
|
||||
reg = (opcode >> 26) & 0x1f;
|
||||
|
||||
/*
|
||||
* Apply the sign adjustment if the ha16 flag is set and the
|
||||
* low half is a negative signed 16-bit integer.
|
||||
*/
|
||||
hi = value >> 16;
|
||||
lo = value & 0xffff;
|
||||
if (ha16 && lo > 0x7fff)
|
||||
hi++;
|
||||
|
||||
/* Assemble lis reg, hi == addis reg, r0, hi. */
|
||||
opcode = (15 << 26) | (reg << 21) | (0 << 16) | hi;
|
||||
write4(opcode, addr, type);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -352,6 +389,9 @@ static putvalu(uint32_t valu, char* addr, uint16_t type)
|
|||
case RELOPPC:
|
||||
put_powerpc_valu(addr, valu, type);
|
||||
break;
|
||||
case RELOLIS:
|
||||
put_lis_valu(addr, valu, type);
|
||||
break;
|
||||
case RELOVC4:
|
||||
put_vc4_valu(addr, valu);
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue