Rework relocations again: add RELO2HI and RELO2HISAD for the high two bytes of
a word.
This commit is contained in:
parent
95dd6f0141
commit
5dfef6f180
3
h/out.h
3
h/out.h
|
@ -69,8 +69,9 @@ struct outname {
|
|||
#define RELOPPC_LIS 5 /* PowerPC lis */
|
||||
#define RELOVC4 6 /* VideoCore IV address in 32-bit instruction */
|
||||
#define RELOMIPS 7 /* MIPS */
|
||||
#define RELO2HI 8 /* high 2 bytes of word */
|
||||
#define RELO2HISAD 9 /* high 2 bytes of word, sign adjusted */
|
||||
|
||||
#define RELS2 0x1000 /* shift result right 16 bits before writing back */
|
||||
#define RELPC 0x2000 /* pc relative */
|
||||
#define RELBR 0x4000 /* High order byte lowest address. */
|
||||
#define RELWR 0x8000 /* High order word lowest address. */
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
*/
|
||||
|
||||
#define THREE_PASS /* branch and offset optimization */
|
||||
#define BYTES_REVERSED /* high order byte has lowest address */
|
||||
#define WORDS_REVERSED /* high order word has lowest address */
|
||||
#define LISTING /* enable listing facilities */
|
||||
#define RELOCATION /* generate relocatable code */
|
||||
#define DEBUG 0
|
||||
|
@ -28,4 +26,4 @@
|
|||
#undef VALWIDTH
|
||||
#define VALWIDTH 8
|
||||
|
||||
#define FIXUPFLAGS (RELBR | RELWR)
|
||||
#define FIXUPFLAGS 0
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
%token <y_word> OP_LI
|
||||
%token <y_word> OP_LA
|
||||
|
||||
%token <y_word> HI
|
||||
%token <y_word> LO
|
||||
%token <y_word> HI16
|
||||
%token <y_word> HA16
|
||||
%token <y_word> LO16
|
||||
|
||||
%type <y_word> gpr fpr
|
||||
%type <y_word> e16 e9
|
||||
|
@ -17,7 +18,6 @@
|
|||
%type <y_word> fcond
|
||||
|
||||
%type <y_word> extmsblsb insmsblsb
|
||||
%type <y_word> hilo
|
||||
%type <y_valu> extabsexp
|
||||
|
||||
#include "definitions.y"
|
||||
|
|
|
@ -76,8 +76,9 @@
|
|||
|
||||
0, OP_LI, 0, "li",
|
||||
0, OP_LA, 0, "la",
|
||||
0, HI, RELO2|RELS2,"hi",
|
||||
0, LO, RELO2, "lo",
|
||||
0, HI16, 0, "hi16",
|
||||
0, HA16, 0, "ha16",
|
||||
0, LO16, 0, "lo16",
|
||||
|
||||
#include "tokens.y"
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
word_t val = $4.val;
|
||||
|
||||
if (type != S_ABS)
|
||||
newrelo($4.typ, RELO2 | RELS2 | FIXUPFLAGS);
|
||||
newrelo($4.typ, RELO2HI | FIXUPFLAGS);
|
||||
emit4(0x3c000000 | (reg<<16) | (val>>16)); /* lui reg, value */
|
||||
if (type != S_ABS)
|
||||
newrelo($4.typ, RELO2 | FIXUPFLAGS);
|
||||
|
@ -33,16 +33,25 @@
|
|||
|
||||
extabsexp
|
||||
: absexp
|
||||
| hilo ASC_LPAR expr ASC_RPAR
|
||||
| LO16 ASC_LPAR expr ASC_RPAR
|
||||
{
|
||||
newrelo($3.typ, $1 | FIXUPFLAGS);
|
||||
newrelo($3.typ, RELO2 | FIXUPFLAGS);
|
||||
$$ = $3.val;
|
||||
}
|
||||
| HI16 ASC_LPAR expr ASC_RPAR
|
||||
{
|
||||
newrelo($3.typ, RELO2HI | FIXUPFLAGS);
|
||||
if ($3.val & 0xffff0000)
|
||||
fatal("relocation offset in hi16[] too big");
|
||||
$$ = $3.val;
|
||||
}
|
||||
| HA16 ASC_LPAR expr ASC_RPAR
|
||||
{
|
||||
newrelo($3.typ, RELO2HISAD | FIXUPFLAGS);
|
||||
if ($3.val & 0xffff0000)
|
||||
fatal("relocation offset in ha16[] too big");
|
||||
$$ = $3.val;
|
||||
}
|
||||
;
|
||||
|
||||
hilo
|
||||
: HI { $$ = $1; }
|
||||
| LO { $$ = $1; }
|
||||
;
|
||||
|
||||
gpr: GPR
|
||||
|
@ -147,7 +156,7 @@ u3
|
|||
offset16
|
||||
: expr
|
||||
{
|
||||
int dist = $1.val - DOTVAL;
|
||||
int dist = $1.val - DOTVAL - 4;
|
||||
fit(fitx(dist, 18));
|
||||
|
||||
if (dist & 0x3)
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
* Only at and f31 may be used.
|
||||
*/
|
||||
|
||||
ori at, zero, hi[.fd_80000000]
|
||||
ldc1 f31, lo[.fd_80000000] (at)
|
||||
ori at, zero, hi16[.fd_80000000]
|
||||
ldc1 f31, lo16[.fd_80000000] (at)
|
||||
c.le.d 0, f31, f0
|
||||
bc1t toobig
|
||||
nop
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
* Only at and f31 may be used.
|
||||
*/
|
||||
|
||||
ori at, zero, hi[.ff_80000000]
|
||||
lwc1 f31, lo[.ff_80000000] (at)
|
||||
ori at, zero, hi16[.ff_80000000]
|
||||
lwc1 f31, lo16[.ff_80000000] (at)
|
||||
c.le.s 0, f31, f0
|
||||
bc1t toobig
|
||||
nop
|
||||
|
|
|
@ -134,6 +134,12 @@ showrelo()
|
|||
case RELO2:
|
||||
printf("\t2 bytes\n");
|
||||
break;
|
||||
case RELO2HI:
|
||||
printf("\ttop 2 bytes of result\n");
|
||||
break;
|
||||
case RELO2HISAD:
|
||||
printf("\ttop 2 bytes of result, sign adjusted\n");
|
||||
break;
|
||||
case RELO4:
|
||||
printf("\t4 bytes\n");
|
||||
break;
|
||||
|
@ -146,6 +152,9 @@ showrelo()
|
|||
case RELOVC4:
|
||||
printf("\tVideoCore IV address in 32-bit instruction\n");
|
||||
break;
|
||||
case RELOMIPS:
|
||||
printf("\tMIPS b or j instruction\n");
|
||||
break;
|
||||
default:
|
||||
printf("\tunknown relocation type %d\n", relrec.or_type & RELSZ);
|
||||
break;
|
||||
|
|
|
@ -213,6 +213,8 @@ static uint32_t getvalu(char* addr, uint16_t type)
|
|||
case RELO1:
|
||||
return UBYTE(addr[0]);
|
||||
case RELO2:
|
||||
case RELO2HI:
|
||||
case RELO2HISAD:
|
||||
return read2(addr, type);
|
||||
case RELO4:
|
||||
return read4(addr, type);
|
||||
|
@ -405,7 +407,7 @@ static void put_mips_valu(char* addr, uint32_t value)
|
|||
fatal("invalid MIPS relocation value 0x%x", value);
|
||||
value >>= 2;
|
||||
|
||||
switch (value >> 26)
|
||||
switch (opcode >> 26)
|
||||
{
|
||||
case 2: /* j */
|
||||
case 3: /* jal */
|
||||
|
@ -440,6 +442,12 @@ static putvalu(uint32_t valu, char* addr, uint16_t type)
|
|||
case RELO2:
|
||||
write2(valu, addr, type);
|
||||
break;
|
||||
case RELO2HI:
|
||||
write2(valu>>16, addr, type);
|
||||
break;
|
||||
case RELO2HISAD:
|
||||
write2((valu>>16) + !!(valu&0x8000), addr, type);
|
||||
break;
|
||||
case RELO4:
|
||||
write4(valu, addr, type);
|
||||
break;
|
||||
|
@ -565,14 +573,6 @@ relocate(head, emit, names, relo, off)
|
|||
if (relo->or_type & RELPC)
|
||||
valu -= relorig[sectindex].org_size+outsect[sectindex].os_base;
|
||||
|
||||
/*
|
||||
* If RELS2 is set, right shift the value by sixteen bits; this
|
||||
* allows 32-bit values to be fixed up as a high word and a low
|
||||
* word.
|
||||
*/
|
||||
if (relo->or_type & RELS2)
|
||||
valu >>= 16;
|
||||
|
||||
/*
|
||||
* Now put the value back.
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue