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