aboutsummaryrefslogtreecommitdiff
path: root/gas/subsegs.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/subsegs.c')
-rw-r--r--gas/subsegs.c448
1 files changed, 238 insertions, 210 deletions
diff --git a/gas/subsegs.c b/gas/subsegs.c
index 00937ea..e872a83 100644
--- a/gas/subsegs.c
+++ b/gas/subsegs.c
@@ -1,23 +1,21 @@
/* subsegs.c - subsegments -
Copyright (C) 1987, 1990, 1991 Free Software Foundation, Inc.
-
-This file is part of GAS, the GNU Assembler.
-
-GAS is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
-any later version.
-
-GAS is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GAS; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* static const char rcsid[] = "$Id$"; */
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
* Segments & sub-segments.
@@ -28,65 +26,90 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "subsegs.h"
#include "obstack.h"
+#ifdef MANY_SEGMENTS
+segment_info_type segment_info[SEG_MAXIMUM_ORDINAL];
+
frchainS* frchain_root,
- * frchain_now, /* Commented in "subsegs.h". */
- * data0_frchainP;
+ * frchain_now;
+#else
+frchainS* frchain_root,
+ * frchain_now, /* Commented in "subsegs.h". */
+ * data0_frchainP;
+#endif
char * const /* in: segT out: char* */
-seg_name[] = {
- "absolute",
- "text",
- "data",
- "bss",
- "unknown",
- "absent",
- "pass1",
- "ASSEMBLER-INTERNAL-LOGIC-ERROR!",
- "bignum/flonum",
- "difference",
- "debug",
- "transfert vector preload",
- "transfert vector postload",
- "register",
- "",
-}; /* Used by error reporters, dumpers etc. */
+ seg_name[] = {
+ "absolute",
+#ifdef MANY_SEGMENTS
+ "e0","e1","e2","e3","e4","e5","e6","e7","e8","e9",
+#else
+ "text",
+ "data",
+ "bss",
+#endif
+ "unknown",
+ "absent",
+ "pass1",
+ "ASSEMBLER-INTERNAL-LOGIC-ERROR!",
+ "bignum/flonum",
+ "difference",
+ "debug",
+ "transfert vector preload",
+ "transfert vector postload",
+ "register",
+ "",
+ }; /* Used by error reporters, dumpers etc. */
void
-subsegs_begin()
+ subsegs_begin()
{
- /* Check table(s) seg_name[], seg_N_TYPE[] is in correct order */
- know( SEG_ABSOLUTE == 0 );
- know( SEG_TEXT == 1 );
- know( SEG_DATA == 2 );
- know( SEG_BSS == 3 );
- know( SEG_UNKNOWN == 4 );
- know( SEG_ABSENT == 5 );
- know( SEG_PASS1 == 6 );
- know( SEG_GOOF == 7 );
- know( SEG_BIG == 8 );
- know( SEG_DIFFERENCE == 9 );
- know( SEG_DEBUG == 10 );
- know( SEG_NTV == 11 );
- know( SEG_PTV == 12 );
- know( SEG_REGISTER == 13 );
- know( SEG_MAXIMUM_ORDINAL == SEG_REGISTER );
- know( segment_name (SEG_MAXIMUM_ORDINAL + 1) [0] == 0 );
-
- obstack_begin( &frags, 5000);
- frchain_root = NULL;
- frchain_now = NULL; /* Warn new_subseg() that we are booting. */
- /* Fake up 1st frag. */
- /* It won't be used=> is ok if obstack... */
- /* pads the end of it for alignment. */
- frag_now=(fragS *)obstack_alloc(&frags,SIZEOF_STRUCT_FRAG);
- /* obstack_1blank( &frags, SIZEOF_STRUCT_FRAG, & frag_now ); */
- /* This 1st frag will not be in any frchain. */
- /* We simply give subseg_new somewhere to scribble. */
- now_subseg = 42; /* Lie for 1st call to subseg_new. */
- subseg_new (SEG_DATA, 0); /* .data 0 */
- data0_frchainP = frchain_now;
+ /* Check table(s) seg_name[], seg_N_TYPE[] is in correct order */
+#ifdef MANY_SEGMENTS
+#else
+ know( SEG_ABSOLUTE == 0 );
+ know( SEG_TEXT == 1 );
+ know( SEG_DATA == 2 );
+ know( SEG_BSS == 3 );
+ know( SEG_UNKNOWN == 4 );
+ know( SEG_ABSENT == 5 );
+ know( SEG_PASS1 == 6 );
+ know( SEG_GOOF == 7 );
+ know( SEG_BIG == 8 );
+ know( SEG_DIFFERENCE == 9 );
+ know( SEG_DEBUG == 10 );
+ know( SEG_NTV == 11 );
+ know( SEG_PTV == 12 );
+ know( SEG_REGISTER == 13 );
+ know( SEG_MAXIMUM_ORDINAL == SEG_REGISTER );
+ /* know( segment_name (SEG_MAXIMUM_ORDINAL + 1) [0] == 0 );*/
+#endif
+
+ obstack_begin( &frags, 5000);
+ frchain_root = NULL;
+ frchain_now = NULL; /* Warn new_subseg() that we are booting. */
+ /* Fake up 1st frag. */
+ /* It won't be used=> is ok if obstack... */
+ /* pads the end of it for alignment. */
+ frag_now=(fragS *)obstack_alloc(&frags,SIZEOF_STRUCT_FRAG);
+ memset(frag_now, SIZEOF_STRUCT_FRAG, 0);
+ /* This 1st frag will not be in any frchain. */
+ /* We simply give subseg_new somewhere to scribble. */
+ now_subseg = 42; /* Lie for 1st call to subseg_new. */
+#ifdef MANY_SEGMENTS
+ {
+ int i;
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++) {
+ subseg_new(i, 0);
+ segment_info[i].frchainP = frchain_now;
+ }
+ }
+#else
+ subseg_new (SEG_DATA, 0); /* .data 0 */
+ data0_frchainP = frchain_now;
+#endif
+
}
/*
@@ -100,23 +123,28 @@ subsegs_begin()
* segment context correct.
*/
void
-subseg_change (seg, subseg)
- register segT seg;
- register int subseg;
+ subseg_change (seg, subseg)
+register segT seg;
+register int subseg;
{
- now_seg = seg;
- now_subseg = subseg;
- if (seg == SEG_DATA)
- {
- seg_fix_rootP = & data_fix_root;
- seg_fix_tailP = & data_fix_tail;
- }
- else
- {
- know (seg == SEG_TEXT);
- seg_fix_rootP = & text_fix_root;
- seg_fix_tailP = & text_fix_tail;
- }
+ now_seg = seg;
+ now_subseg = subseg;
+#ifdef MANY_SEGMENTS
+ seg_fix_rootP = & segment_info[seg].fix_root;
+ seg_fix_tailP = & segment_info[seg].fix_tail;
+#else
+ if (seg == SEG_DATA)
+ {
+ seg_fix_rootP = & data_fix_root;
+ seg_fix_tailP = & data_fix_tail;
+ }
+ else
+ {
+ know (seg == SEG_TEXT);
+ seg_fix_rootP = & text_fix_root;
+ seg_fix_tailP = & text_fix_tail;
+ }
+#endif
}
/*
@@ -136,137 +164,137 @@ subseg_change (seg, subseg)
*/
void
-subseg_new (seg, subseg) /* begin assembly for a new sub-segment */
- register segT seg; /* SEG_DATA or SEG_TEXT */
- register subsegT subseg;
+ subseg_new (seg, subseg) /* begin assembly for a new sub-segment */
+register segT seg; /* SEG_DATA or SEG_TEXT */
+register subsegT subseg;
{
- long tmp; /* JF for obstack alignment hacking */
-
- know( seg == SEG_DATA || seg == SEG_TEXT );
-
- if (seg != now_seg || subseg != now_subseg)
- { /* we just changed sub-segments */
- register frchainS * frcP; /* crawl frchain chain */
- register frchainS** lastPP; /* address of last pointer */
- frchainS * newP; /* address of new frchain */
- register fragS * former_last_fragP;
- register fragS * new_fragP;
-
- if (frag_now) /* If not bootstrapping. */
- {
- frag_now -> fr_fix = obstack_next_free(& frags) - frag_now -> fr_literal;
- frag_wane(frag_now); /* Close off any frag in old subseg. */
- }
-/*
- * It would be nice to keep an obstack for each subsegment, if we swap
- * subsegments a lot. Hence we would have much fewer frag_wanes().
- */
- {
-
- obstack_finish( &frags);
- /*
- * If we don't do the above, the next object we put on obstack frags
- * will appear to start at the fr_literal of the current frag.
- * Also, above ensures that the next object will begin on a
- * address that is aligned correctly for the engine that runs
- * this program.
- */
- }
- subseg_change (seg, (int)subseg);
- /*
- * Attempt to find or make a frchain for that sub seg.
- * Crawl along chain of frchainSs, begins @ frchain_root.
- * If we need to make a frchainS, link it into correct
- * position of chain rooted in frchain_root.
- */
- for (frcP = * (lastPP = & frchain_root);
- frcP
- && (int)(frcP -> frch_seg) <= (int)seg;
- frcP = * ( lastPP = & frcP -> frch_next)
- )
- {
- if ( (int)(frcP -> frch_seg) == (int)seg
- && frcP -> frch_subseg >= subseg)
- {
- break;
- }
- }
- /*
- * frcP: Address of the 1st frchainS in correct segment with
- * frch_subseg >= subseg.
- * We want to either use this frchainS, or we want
- * to insert a new frchainS just before it.
- *
- * If frcP==NULL, then we are at the end of the chain
- * of frchainS-s. A NULL frcP means we fell off the end
- * of the chain looking for a
- * frch_subseg >= subseg, so we
- * must make a new frchainS.
- *
- * If we ever maintain a pointer to
- * the last frchainS in the chain, we change that pointer
- * ONLY when frcP==NULL.
- *
- * lastPP: Address of the pointer with value frcP;
- * Never NULL.
- * May point to frchain_root.
- *
- */
- if ( ! frcP
- || ( (int)(frcP -> frch_seg) > (int)seg
- || frcP->frch_subseg > subseg)) /* Kinky logic only works with 2 segments. */
- {
- /*
- * This should be the only code that creates a frchainS.
- */
- newP=(frchainS *)obstack_alloc(&frags,sizeof(frchainS));
- /* obstack_1blank( &frags, sizeof(frchainS), &newP); */
+ long tmp; /* JF for obstack alignment hacking */
+#ifndef MANY_SEGMENTS
+ know( seg == SEG_DATA || seg == SEG_TEXT );
+#endif
+ if (seg != now_seg || subseg != now_subseg)
+ { /* we just changed sub-segments */
+ register frchainS * frcP; /* crawl frchain chain */
+ register frchainS** lastPP; /* address of last pointer */
+ frchainS * newP; /* address of new frchain */
+ register fragS * former_last_fragP;
+ register fragS * new_fragP;
+
+ if (frag_now) /* If not bootstrapping. */
+ {
+ frag_now -> fr_fix = obstack_next_free(& frags) - frag_now -> fr_literal;
+ frag_wane(frag_now); /* Close off any frag in old subseg. */
+ }
+ /*
+ * It would be nice to keep an obstack for each subsegment, if we swap
+ * subsegments a lot. Hence we would have much fewer frag_wanes().
+ */
+ {
+
+ obstack_finish( &frags);
+ /*
+ * If we don't do the above, the next object we put on obstack frags
+ * will appear to start at the fr_literal of the current frag.
+ * Also, above ensures that the next object will begin on a
+ * address that is aligned correctly for the engine that runs
+ * this program.
+ */
+ }
+ subseg_change (seg, (int)subseg);
+ /*
+ * Attempt to find or make a frchain for that sub seg.
+ * Crawl along chain of frchainSs, begins @ frchain_root.
+ * If we need to make a frchainS, link it into correct
+ * position of chain rooted in frchain_root.
+ */
+ for (frcP = * (lastPP = & frchain_root);
+ frcP
+ && (int)(frcP -> frch_seg) <= (int)seg;
+ frcP = * ( lastPP = & frcP -> frch_next)
+ )
+ {
+ if ( (int)(frcP -> frch_seg) == (int)seg
+ && frcP -> frch_subseg >= subseg)
+ {
+ break;
+ }
+ }
+ /*
+ * frcP: Address of the 1st frchainS in correct segment with
+ * frch_subseg >= subseg.
+ * We want to either use this frchainS, or we want
+ * to insert a new frchainS just before it.
+ *
+ * If frcP==NULL, then we are at the end of the chain
+ * of frchainS-s. A NULL frcP means we fell off the end
+ * of the chain looking for a
+ * frch_subseg >= subseg, so we
+ * must make a new frchainS.
+ *
+ * If we ever maintain a pointer to
+ * the last frchainS in the chain, we change that pointer
+ * ONLY when frcP==NULL.
+ *
+ * lastPP: Address of the pointer with value frcP;
+ * Never NULL.
+ * May point to frchain_root.
+ *
+ */
+ if ( ! frcP
+ || ( (int)(frcP -> frch_seg) > (int)seg
+ || frcP->frch_subseg > subseg)) /* Kinky logic only works with 2 segments. */
+ {
+ /*
+ * This should be the only code that creates a frchainS.
+ */
+ newP=(frchainS *)obstack_alloc(&frags,sizeof(frchainS));
+ memset(newP, sizeof(frchainS), 0);
/* This begines on a good boundary */
/* because a obstack_done() preceeded it. */
/* It implies an obstack_done(), so we */
/* expect the next object allocated to */
/* begin on a correct boundary. */
- *lastPP = newP;
- newP -> frch_next = frcP; /* perhaps NULL */
- (frcP = newP) -> frch_subseg = subseg;
- newP -> frch_seg = seg;
- newP -> frch_last = NULL;
- }
- /*
- * Here with frcP ->ing to the frchainS for subseg.
- */
- frchain_now = frcP;
- /*
- * Make a fresh frag for the subsegment.
- */
- /* We expect this to happen on a correct */
- /* boundary since it was proceeded by a */
- /* obstack_done(). */
- tmp=obstack_alignment_mask(&frags); /* JF disable alignment */
- obstack_alignment_mask(&frags)=0;
- frag_now=(fragS *)obstack_alloc(&frags,SIZEOF_STRUCT_FRAG);
- obstack_alignment_mask(&frags)=tmp;
- /* know( frags . obstack_c_next_free == frag_now -> fr_literal ); */
- /* But we want any more chars to come */
- /* immediately after the structure we just made. */
- new_fragP = frag_now;
- new_fragP -> fr_next = NULL;
- /*
- * Append new frag to current frchain.
- */
- former_last_fragP = frcP -> frch_last;
- if (former_last_fragP)
- {
- know( former_last_fragP -> fr_next == NULL );
- know( frchain_now -> frch_root );
- former_last_fragP -> fr_next = new_fragP;
- }
- else
- {
- frcP -> frch_root = new_fragP;
- }
- frcP -> frch_last = new_fragP;
- } /* if (changing subsegments) */
+ *lastPP = newP;
+ newP -> frch_next = frcP; /* perhaps NULL */
+ (frcP = newP) -> frch_subseg = subseg;
+ newP -> frch_seg = seg;
+ newP -> frch_last = NULL;
+ }
+ /*
+ * Here with frcP ->ing to the frchainS for subseg.
+ */
+ frchain_now = frcP;
+ /*
+ * Make a fresh frag for the subsegment.
+ */
+ /* We expect this to happen on a correct */
+ /* boundary since it was proceeded by a */
+ /* obstack_done(). */
+ tmp=obstack_alignment_mask(&frags); /* JF disable alignment */
+ obstack_alignment_mask(&frags)=0;
+ frag_now=(fragS *)obstack_alloc(&frags,SIZEOF_STRUCT_FRAG);
+ obstack_alignment_mask(&frags)=tmp;
+ /* know( frags . obstack_c_next_free == frag_now -> fr_literal ); */
+ /* But we want any more chars to come */
+ /* immediately after the structure we just made. */
+ new_fragP = frag_now;
+ new_fragP -> fr_next = NULL;
+ /*
+ * Append new frag to current frchain.
+ */
+ former_last_fragP = frcP -> frch_last;
+ if (former_last_fragP)
+ {
+ know( former_last_fragP -> fr_next == NULL );
+ know( frchain_now -> frch_root );
+ former_last_fragP -> fr_next = new_fragP;
+ }
+ else
+ {
+ frcP -> frch_root = new_fragP;
+ }
+ frcP -> frch_last = new_fragP;
+ } /* if (changing subsegments) */
} /* subseg_new() */
/*