ns32k changes.

This commit is contained in:
phil 1994-04-08 08:38:40 +00:00
parent 69ca046de0
commit 454544a141
5 changed files with 175 additions and 59 deletions

View File

@ -0,0 +1,4 @@
# $Id: Makefile.ns32k,v 1.1 1994/04/08 08:39:04 phil Exp $
CFLAGS+= -DPIC -DNS32532 -DNS32381
SRCS+= tc-ns32k.c atof-ns32k.c

View File

@ -394,7 +394,13 @@ struct relocation_info {
/* Address (within segment) to be relocated. */
int r_address;
/* The meaning of r_symbolnum depends on r_extern. */
#if defined(TC_NS32K) && !defined(TE_SEQUENT)
unsigned int r_symbolnum:22;
unsigned int r_copy:1;
unsigned int r_relative:1;
#else
unsigned int r_symbolnum:24;
#endif
/* Nonzero means value is a pc-relative offset
and it should be relocated for changes in its own address
as well as for changes in the symbol or section specified. */
@ -409,19 +415,23 @@ struct relocation_info {
r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS
(the N_EXT bit may be set also, but signifies nothing). */
unsigned int r_extern:1;
#ifdef TC_NS32K
#ifdef TE_SEQUENT
unsigned int r_bsr:1;
#else
unsigned int r_jmptable:1;
#endif
unsigned int r_disp:2;
unsigned int r_baserel:1;
#else
/* The next three bits are for SunOS shared libraries, and seem to
be undocumented. */
unsigned int r_baserel:1; /* Linkage table relative */
unsigned int r_jmptable:1; /* pc-relative to jump table */
#ifdef TC_NS32K
#define r_bsr r_baserel
#define r_disp r_jmptable
#endif /* TC_NS32K */
unsigned int r_relative:1; /* "relative relocation" */
/* unused */
unsigned int r_pad:1; /* Padding -- set to zero */
#endif
};
#endif /* CUSTOM_RELOC_FORMAT */

View File

@ -338,8 +338,8 @@ const relax_typeS md_relax_table[] = {
{ 1, 1, 0, 0 },
{ 1, 1, 0, 0 },
{ (63), (-64), 1, IND(BRANCH,WORD) },
{ (8192), (-8192), 2, IND(BRANCH,DOUBLE) },
{ (63), (-64), 1, IND(BRANCH,WORD) },
{ (8191), (-8192), 2, IND(BRANCH,DOUBLE) },
{ 0, 0, 4, 0 },
{ 1, 1, 0, 0 }
};
@ -348,13 +348,23 @@ const relax_typeS md_relax_table[] = {
Value is true if mode contains displacement. */
char disp_test[] = { 0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,
1,1,1,0,0,1,1,0,
1,1,1,1,1,1,1,1 };
1,1,1,1,1,1,1,1,
1,1,1,0,0,1,1,0,
1,1,1,1,1,1,1,1 };
/* Array used to calculate max size of displacements */
char disp_size[] = { 4,1,2,0,4 };
#ifdef PIC
/* In pic-mode all external pc-relative references are jmpslot
references except references to __GLOBAL_OFFSET_TABLE_. */
static symbolS *got_symbol;
/* The size of got-offsets. */
static int got_offset_size = 2;
#endif
#if __STDC__ == 1
@ -821,7 +831,8 @@ char opcode_bit_ptr;
pcrel=1;
iif.instr_size+=suffixP[i] ? suffixP[i] : 4;
IIF(12, 2, suffixP[i], (unsigned long)argv[i], 0,
pcrel, pcrel_adjust, 1, IND(BRANCH,BYTE), NULL,-1,1);break;
pcrel, pcrel_adjust, 1, IND(BRANCH,BYTE), NULL,-1, 1);
break;
case 'q': /* quick */
opcode_bit_ptr-=4;
IIF(11,2,42,(unsigned long)argv[i],0,0,0,0,0,
@ -1024,10 +1035,10 @@ int recursive_level;
*/
void convert_iif() {
int i;
int j;
bit_fixS *bit_fixP;
fragS *inst_frag;
char *inst_offset;
char **inst_opcode;
char *inst_opcode;
char *memP;
segT segment;
int l;
@ -1036,39 +1047,50 @@ void convert_iif() {
char type;
char size = 0;
int size_so_far = 0; /* used to calculate pcrel_adjust */
int pcrel_symbols=0; /* kludge by jkp@hut.fi to make
int pcrel_symbols = 0;/* kludge by jkp@hut.fi to make
movd _foo(pc),_bar(pc) work.
It should be done with two frags
for one insn, but I don't understand
enough to make it work */
rem_size=iif.instr_size;
memP=frag_more(iif.instr_size); /* make sure we have enough bytes for instruction */
inst_opcode=memP;
inst_offset=(char*)(memP-frag_now->fr_literal);
inst_frag=frag_now;
for (i=0;i<IIF_ENTRIES;i++) { /* jkp kludge alert */
rem_size = iif.instr_size;
memP = frag_more(iif.instr_size); /* make sure we have enough bytes for instruction */
inst_opcode = memP;
inst_offset = (char *)(memP-frag_now->fr_literal);
inst_frag = frag_now;
for (i=0; i < IIF_ENTRIES; i++) { /* jkp kludge alert */
if (iif.iifP[i].type && iif.iifP[i].size == 0 &&
iif.iifP[i].pcrel) {
evaluate_expr(&exprP,(char*)iif.iifP[i].object);
evaluate_expr(&exprP, (char *)iif.iifP[i].object);
if (exprP.X_add_symbol || exprP.X_subtract_symbol)
pcrel_symbols++;
}
}
for (i=0;i<IIF_ENTRIES;i++) {
if (type=iif.iifP[i].type) { /* the object exist, so handle it */
#ifdef PIC
int reloc_mode;
if ((i == 4 || i == 6)
&& flagseen['k']
&& (iif.iifP[i].addr_mode == 18 || iif.iifP[i].addr_mode == 26))
reloc_mode = RELOC_GLOB_DAT;
else
reloc_mode = NO_RELOC;
#else
int reloc_mode = NO_RELOC;
#endif
switch (size=iif.iifP[i].size) {
case 42: size=0; /* it's a bitfix that operates on an existing object*/
if (iif.iifP[i].bit_fixP->fx_bit_base) { /* expand fx_bit_base to point at opcode */
iif.iifP[i].bit_fixP->fx_bit_base=(long)inst_opcode;
iif.iifP[i].bit_fixP->fx_bit_base = (long) inst_opcode;
}
case 8: /* bignum or doublefloat */
memset(memP, '\0', 8);
case 1:case 2:case 3:case 4:/* the final size in objectmemory is known */
j=(unsigned long)iif.iifP[i].bit_fixP;
bit_fixP = iif.iifP[i].bit_fixP;
switch (type) {
case 1: /* the object is pure binary */
if (j || iif.iifP[i].pcrel) {
if (bit_fixP || iif.iifP[i].pcrel) {
fix_new_ns32k(frag_now,
(long)(memP-frag_now->fr_literal),
size,
@ -1078,8 +1100,9 @@ void convert_iif() {
iif.iifP[i].pcrel,
(char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/
iif.iifP[i].im_disp,
j,
iif.iifP[i].bsr); /* sequent hack */
bit_fixP,
iif.iifP[i].bsr, /* sequent hack */
reloc_mode);
} else { /* good, just put them bytes out */
switch (iif.iifP[i].im_disp) {
case 0:
@ -1126,7 +1149,7 @@ void convert_iif() {
rem_size-=size;
break;
}
if (j ||
if (bit_fixP ||
exprP.X_add_symbol ||
exprP.X_subtract_symbol ||
iif.iifP[i].pcrel) { /* fixit */
@ -1142,8 +1165,9 @@ void convert_iif() {
iif.iifP[i].pcrel,
(char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/
iif.iifP[i].im_disp,
j,
iif.iifP[i].bsr); /* sequent hack */
bit_fixP,
iif.iifP[i].bsr, /* sequent hack */
reloc_mode);
} else { /* good, just put them bytes out */
switch (iif.iifP[i].im_disp) {
@ -1171,6 +1195,13 @@ void convert_iif() {
segment = evaluate_expr(&exprP, (char*)iif.iifP[i].object);
if (((exprP.X_add_symbol || exprP.X_subtract_symbol) &&
!iif.iifP[i].pcrel) || pcrel_symbols >= 2 /*jkp*/) { /* OVE: hack, clamp to 4 bytes */
#ifdef PIC
if (reloc_mode == RELOC_GLOB_DAT && got_offset_size == 2) {
size = 2;
/* rewind the bytes not used */
obstack_blank_fast(&frags, -2);
} else
#endif
size=4; /* we dont wan't to frag this, use 4 so it reaches */
fix_new_ns32k(frag_now,
(long)(memP-frag_now->fr_literal),
@ -1181,7 +1212,8 @@ void convert_iif() {
pcrel_symbols >= 2 ? iif.iifP[i].pcrel : 0, /*jkp*//* never iif.iifP[i].pcrel, */
(char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/
1, /* always iif.iifP[i].im_disp, */
0,0);
0,0,
reloc_mode);
memP+=size;
rem_size-=4;
break; /* exit this absolute hack */
@ -1208,7 +1240,7 @@ void convert_iif() {
IND(BRANCH,UNDEF), /* expecting the worst */
exprP.X_add_symbol,
exprP.X_add_number,
(char*)inst_opcode,
inst_opcode,
(char)size_so_far, /*iif.iifP[i].pcrel_adjust);*/
iif.iifP[i].bsr); /* sequent linker hack */
rem_size -= 4;
@ -1305,6 +1337,7 @@ int *sizeP;
int prec;
LITTLENUM_TYPE words[MAX_LITTLENUMS];
LITTLENUM_TYPE *wordP;
extern char *atof_ns32k();
char *t;
switch (type) {
@ -1369,7 +1402,10 @@ char n;
switch (n) {
case 1:
if (val < -64 || val > 63)
{
fprintf(stderr, "val = %d\n", val);
as_warn("Byte displacement out of range. line number not valid");
}
val &= 0x7f;
#ifdef SHOW_NUM
printf("%x ",val & 0xff);
@ -1502,38 +1538,76 @@ struct reloc_info_generic *ri;
#ifdef OBJ_AOUT
void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
char *where;
struct fix *fixP;
fixS *fixP;
relax_addressT segment_address_in_file;
{
/*
* In: length of relocation (or of address) in chars: 1, 2 or 4.
* Out: GNU LD relocation length code: 0, 1, or 2.
*/
static unsigned char nbytes_r_length[] = { 42, 0, 1, 42, 2 };
long r_symbolnum;
int r_flags;
know(fixP->fx_addsy != NULL);
md_number_to_chars(where,
fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
4);
r_symbolnum = (S_IS_DEFINED(fixP->fx_addsy)
? S_GET_TYPE(fixP->fx_addsy)
: fixP->fx_addsy->sy_number);
md_number_to_chars(where,
((long)(r_symbolnum)
| (long)(fixP->fx_pcrel << 24)
| (long)(nbytes_r_length[fixP->fx_size] << 25)
| (long)((!S_IS_DEFINED(fixP->fx_addsy)) << 27)
| (long)(fixP->fx_bsr << 28)
| (long)(fixP->fx_im_disp << 29)),
4);
r_flags = (fixP->fx_pcrel ? 1 : 0)
| ((nbytes_r_length[fixP->fx_size] & 3) << 1)
| (!S_IS_DEFINED(fixP->fx_addsy) ? 8 : 0)
#if defined(TE_SEQUENT)
| (fixP->fx_bsr ? 0x10 : 0)
#elif defined(PIC)
/* Undefined pc-relative relocations are of type jmpslot */
| ((!S_IS_DEFINED(fixP->fx_addsy)
&& fixP->fx_pcrel
&& fixP->fx_addsy != got_symbol
&& flagseen['k']) ? 0x10 : 0)
#endif
| (fixP->fx_im_disp & 3) << 5;
#ifdef PIC
switch (fixP->fx_r_type) {
case NO_RELOC:
break;
case RELOC_32:
if (flagseen['k'] && S_IS_EXTERNAL(fixP->fx_addsy)) {
fprintf(stderr, "reloc_32, flags = %02x\n", r_flags);
r_symbolnum = fixP->fx_addsy->sy_number;
r_flags |= 8; /* set extern bit */
}
break;
case RELOC_GLOB_DAT:
if (!fixP->fx_pcrel) {
r_flags |= 0x80; /* set baserel bit */
r_symbolnum = fixP->fx_addsy->sy_number;
if (S_IS_EXTERNAL(fixP->fx_addsy))
r_flags |= 8;
}
break;
case RELOC_RELATIVE:
/* should never happen */
as_fatal("relocation botch");
break;
}
#endif /* PIC */
where[4] = r_symbolnum & 0x0ff;
where[5] = (r_symbolnum >> 8) & 0x0ff;
where[6] = (r_symbolnum >> 16) & 0x0ff;
where[7] = r_flags;
return;
} /* tc_aout_fix_to_chars() */
#endif /* OBJ_AOUT */
/* fast bitfiddling support */
@ -1690,13 +1764,13 @@ register fragS *fragP;
case IND(BRANCH,BYTE):
ext = 1;
break;
case IND(BRANCH,WORD):
ext = 2;
case IND(BRANCH,WORD):
ext = 2;
break;
case IND(BRANCH,DOUBLE):
ext = 4;
case IND(BRANCH,DOUBLE):
ext = 4;
break;
}
}
if (ext) {
md_number_to_disp(buffer_address, (long)disp, (int)ext);
fragP->fr_fix += ext;
@ -1733,7 +1807,8 @@ segT segment;
fragP->fr_pcrel_adjust,
1,
0,
fragP->fr_bsr); /*sequent hack */
fragP->fr_bsr, /*sequent hack */
NO_RELOC);
fragP->fr_fix+=4;
/* fragP->fr_opcode[1]=0xff; */
frag_wane(fragP);
@ -1805,7 +1880,16 @@ char ***vecP;
while (**argP)
(*argP)++;
break;
#ifdef PIC
case 'K':
got_offset_size = 4;
break;
case 'k':
got_symbol = symbol_find_or_make("__GLOBAL_OFFSET_TABLE_");
break;
#endif
default:
return 0;
}
@ -1845,7 +1929,7 @@ long add; /* Add mask, used for huffman prefix */
void
fix_new_ns32k(frag, where, size, add_symbol, sub_symbol, offset, pcrel,
pcrel_adjust, im_disp, bit_fixP, bsr)
pcrel_adjust, im_disp, bit_fixP, bsr, r_type)
fragS *frag; /* Which frag? */
int where; /* Where in that frag? */
int size; /* 1, 2 or 4 usually. */
@ -1857,15 +1941,24 @@ char pcrel_adjust; /* not zero if adjustment of pcrel offset is needed */
char im_disp; /* true if the value to write is a displacement */
bit_fixS *bit_fixP; /* pointer at struct of bit_fix's, ignored if NULL */
char bsr; /* sequent-linker-hack: 1 when relocobject is a bsr */
int r_type; /* Relocation type */
{
#ifdef PIC
fixS *fixP = fix_new(frag, where, size, add_symbol, sub_symbol,
offset, pcrel, NO_RELOC);
offset, pcrel, r_type, NULL);
#else
fixS *fixP = fix_new(frag, where, size, add_symbol, sub_symbol,
offset, pcrel, r_type);
#endif /* PIC */
fixP->fx_pcrel_adjust = pcrel_adjust;
fixP->fx_im_disp = im_disp;
fixP->fx_bit_fixP = bit_fixP;
fixP->fx_bsr = bsr;
#ifdef PIC
if (r_type == RELOC_GLOB_DAT)
add_symbol->sy_forceout = 1;
#endif /* PIC */
} /* fix_new_ns32k() */
/* We have no need to default values of symbols. */

View File

@ -17,8 +17,12 @@
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef TC_NS32K
#define TC_NS32K 1
#include "bit_fix.h"
#define LOCAL_LABELS_FB
#define NO_LISTING
#define tc_aout_pre_write_hook(x) {;} /* not used */
@ -48,7 +52,8 @@ void fix_new_ns32k(fragS *frag,
int pcrel_adjust,
int im_disp,
bit_fixS *bit_fixP, /* really bit_fixS */
int bsr);
int bsr,
int r_type);
#else /* not __STDC__ */
@ -56,5 +61,6 @@ void fix_new_ns32k();
#endif /* not __STDC__ */
#endif /* TC_NS32K */
/* end of tc-ns32k.h */

View File

@ -21,7 +21,7 @@
/* This thing should be set up to do byteordering correctly. But... */
#ifndef lint
static char rcsid[] = "$Id: write.c,v 1.10 1994/02/04 14:15:57 pk Exp $";
static char rcsid[] = "$Id: write.c,v 1.11 1994/04/08 08:38:40 phil Exp $";
#endif
#include "as.h"
@ -399,7 +399,7 @@ void write_object_file()
lie->add,
lie->sub,
lie->addnum,
0, 0, 2, 0, 0);
0, 0, 2, 0, 0, NO_RELOC);
#else /* TC_NS32K */
#ifdef PIC
fix_new(lie->frag, lie->word_goes_here - lie->frag->fr_literal,
@ -1079,6 +1079,9 @@ segT this_segment_type; /* N_TYPE bits for segment. */
* even if defined here.
*/
if (!flagseen['k'] ||
#ifdef TC_NS32K
fixP->fx_pcrel ||
#endif
(fixP->fx_r_type != RELOC_GLOB_DAT &&
#ifdef TC_I386
/* XXX - This must be rationalized */