Add special relocation type for VC4 jump instructions.

--HG--
branch : dtrg-videocore
This commit is contained in:
David Given 2013-05-17 22:40:50 +01:00
parent 5b4aa07dee
commit 5378e3fe53
4 changed files with 44 additions and 0 deletions

View file

@ -64,6 +64,7 @@ struct outname {
#define RELO4 3 /* 4 bytes */
#define RELOPPC 4 /* PowerPC 26-bit address */
#define RELOH2 5 /* write top 2 bytes of 4 byte word */
#define RELOVC4 6 /* VideoCore IV address in 32-bit instruction */
#define RELPC 0x08 /* pc relative */
#define RELBR 0x10 /* High order byte lowest address. */

View file

@ -143,6 +143,9 @@ showrelo()
case RELOH2:
printf("\ttop 2 bytes of a 4 byte word\n");
break;
case RELOVC4:
printf("\tVideoCore IV address in 32-bit instruction\n");
break;
default:
printf("\tunknown relocation type %d\n", relrec.or_type & RELSZ);
break;

View file

@ -164,6 +164,7 @@ struct outrelo {
#define RELO4 0x03 /* 4 bytes */
#define RELOPPC 0x04 /* 26-bit PowerPC address */
#define RELOH2 0x05 /* write top 2 bytes of 4 byte word */
#define RELOVC4 0x06 /* VideoCore IV address in 32-bit insruction */
#define RELPC 0x08 /* pc relative */
#define RELBR 0x10 /* High order byte lowest address. */
#define RELWR 0x20 /* High order word lowest address. */

View file

@ -8,6 +8,7 @@ static char rcsid[] = "$Id$";
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "out.h"
#include "const.h"
#include "debug.h"
@ -63,6 +64,22 @@ getvalu(addr, type)
return read4(addr, type) & 0x03FFFFFD;
case RELOH2:
return read2(addr, type) << 16;
case RELOVC4:
{
long i = read4(addr, type);
if (i & 0x00800000)
{
/* Branch instruction. */
return (i<<9)>>9;
}
else
{
/* Branch-link instruction. */
long hi = (i<<4)>>28;
long lo = (i & 0x007fffff);
return lo | (hi<<23);
}
}
default:
fatal("bad relocation size");
}
@ -138,6 +155,28 @@ putvalu(valu, addr, type)
case RELOH2:
write2(valu>>16, addr, type);
break;
case RELOVC4:
{
long i = read4(addr, type);
if (i & 0x00800000)
{
/* Branch instruction. */
unsigned v = (valu/2) & 0x007fffff;
i &= ~0x007fffff;
i |= v;
}
else
{
/* Branch-link instruction. */
unsigned v = (valu/2) & 0x07ffffff;
unsigned hiv = v >> 23;
unsigned lov = v & 0x007fffff;
i &= ~0x0f7fffff;
i |= (lov>>16) | (hiv<<24);
}
write4(i, addr, type);
break;
}
default:
fatal("bad relocation size");
}