Merge pull request #52 from kernigh/pr-relolis
PowerPC: more ha16/lo16 from ncg, new RELOLIS
This commit is contained in:
		
						commit
						8f79699ea8
					
				
					 11 changed files with 483 additions and 579 deletions
				
			
		
							
								
								
									
										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…
	
	Add table
		
		Reference in a new issue