Thu Jun 4 11:59:13 1992 Steve Chamberlain (sac@thepub.cygnus.com)
* expr.c(expr): allow SEG_REGISTER in expressions. * read.c(pseudo_set): register expressions can be the source of a set. * subsegs.c (subseg_new): Now -R forces all changes to SEG_DATA to goto SEG_TEXT (if a.out) * write.c (write_object_file): If a.out don't use the old way for -R. * config/obj-a.out (s_sect): complain if the user tries to use a subsegment with a value which might interfere with out -R hackery. * config/tc-m68k.c (m68k_reg_parse): lookup names in symbol table rather than use ugly if tree. (init_regtable): insert register names into symbol table.
This commit is contained in:
parent
f4a0f42d8a
commit
f8701a3ff8
6 changed files with 4684 additions and 4543 deletions
|
@ -1,3 +1,18 @@
|
|||
Thu Jun 4 11:59:13 1992 Steve Chamberlain (sac@thepub.cygnus.com)
|
||||
|
||||
* expr.c(expr): allow SEG_REGISTER in expressions.
|
||||
* read.c(pseudo_set): register expressions can be the source of a
|
||||
set.
|
||||
* subsegs.c (subseg_new): Now -R forces all changes to SEG_DATA to
|
||||
goto SEG_TEXT (if a.out)
|
||||
* write.c (write_object_file): If a.out don't use the old way for
|
||||
-R.
|
||||
* config/obj-a.out (s_sect): complain if the user tries to use a
|
||||
subsegment with a value which might interfere with out -R hackery.
|
||||
* config/tc-m68k.c (m68k_reg_parse): lookup names in symbol table
|
||||
rather than use ugly if tree. (init_regtable): insert register
|
||||
names into symbol table.
|
||||
|
||||
Tue Jun 2 16:47:09 1992 Steve Chamberlain (sac@cygnus.com)
|
||||
|
||||
* write.c (write_object_file): keep the fix_tail clean, which
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#define NO_RELOC 0
|
||||
#include "as.h"
|
||||
|
||||
#include "obstack.h"
|
||||
|
@ -540,252 +540,29 @@ static char alt_notend_table[256];
|
|||
enum _register m68k_reg_parse(ccp)
|
||||
register char **ccp;
|
||||
{
|
||||
#ifndef MAX_REG_NAME_LEN
|
||||
#define MAX_REG_NAME_LEN (6)
|
||||
#endif /* MAX_REG_NAME_LEN */
|
||||
register char c[MAX_REG_NAME_LEN];
|
||||
char *p, *q;
|
||||
register int n = 0,
|
||||
ret = FAIL;
|
||||
char *start = *ccp;
|
||||
|
||||
c[0] = mklower(ccp[0][0]);
|
||||
#ifdef REGISTER_PREFIX
|
||||
if (c[0] != REGISTER_PREFIX) {
|
||||
return(FAIL);
|
||||
} /* need prefix */
|
||||
#endif
|
||||
if (isalpha(*start) && is_name_beginner(*start))
|
||||
{
|
||||
char c;
|
||||
char *p = start;
|
||||
symbolS *symbolP;
|
||||
|
||||
for (p = c, q = ccp[0]; p < c + MAX_REG_NAME_LEN; ++p, ++q)
|
||||
{
|
||||
if (*q == 0)
|
||||
{
|
||||
*p = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
*p = mklower(*q);
|
||||
} /* downcase */
|
||||
while (is_part_of_name(c = *p++))
|
||||
;
|
||||
* -- p = 0;
|
||||
symbolP = symbol_find(start);
|
||||
*p = c;
|
||||
|
||||
switch(c[0]) {
|
||||
case 'a':
|
||||
if(c[1]>='0' && c[1]<='7') {
|
||||
n=2;
|
||||
ret=ADDR+c[1]-'0';
|
||||
}
|
||||
#ifndef NO_68851
|
||||
else if (c[1] == 'c') {
|
||||
n = 2;
|
||||
ret = AC;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#ifndef NO_68851
|
||||
case 'b':
|
||||
if (c[1] == 'a') {
|
||||
if (c[2] == 'd') {
|
||||
if (c[3] >= '0' && c[3] <= '7') {
|
||||
n = 4;
|
||||
ret = BAD + c[3] - '0';
|
||||
}
|
||||
} /* BAD */
|
||||
if (c[2] == 'c') {
|
||||
if (c[3] >= '0' && c[3] <= '7') {
|
||||
n = 4;
|
||||
ret = BAC + c[3] - '0';
|
||||
}
|
||||
} /* BAC */
|
||||
} else if (c[1] == 'c') {
|
||||
n = 2;
|
||||
ret = BC;
|
||||
} /* BC */
|
||||
break;
|
||||
#endif
|
||||
case 'c':
|
||||
#ifndef NO_68851
|
||||
if (c[1] == 'a' && c[2] == 'l') {
|
||||
n = 3;
|
||||
ret = CAL;
|
||||
} else
|
||||
#endif
|
||||
/* This supports both CCR and CC as the ccr reg. */
|
||||
if(c[1]=='c' && c[2]=='r') {
|
||||
n=3;
|
||||
ret = CCR;
|
||||
} else if(c[1]=='c') {
|
||||
n=2;
|
||||
ret = CCR;
|
||||
} else if(c[1]=='a' && (c[2]=='a' || c[2]=='c') && c[3]=='r') {
|
||||
n=4;
|
||||
ret = c[2]=='a' ? CAAR : CACR;
|
||||
}
|
||||
#ifndef NO_68851
|
||||
else if (c[1] == 'r' && c[2] == 'p') {
|
||||
n = 3;
|
||||
ret = (CRP);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 'd':
|
||||
if (c[1] >= '0' && c[1] <= '7') {
|
||||
n = 2;
|
||||
ret = DATA + c[1] - '0';
|
||||
} else if (c[1] == 'f' && c[2] == 'c') {
|
||||
n = 3;
|
||||
ret = DFC;
|
||||
} else if (c[1] == 'c') {
|
||||
n = 2;
|
||||
ret = DC;
|
||||
} else if (c[1] == 't' && c[2] == 't') {
|
||||
if ('0' <= c[3] && c[3] <= '1') {
|
||||
n = 4;
|
||||
ret = DTT0 + (c[3] - '0');
|
||||
} /* DTT[01] */
|
||||
}
|
||||
#ifndef NO_68851
|
||||
else if (c[1] == 'r' && c[2] == 'p') {
|
||||
n = 3;
|
||||
ret = (DRP);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 'f':
|
||||
if(c[1]=='p') {
|
||||
if(c[2]>='0' && c[2]<='7') {
|
||||
n=3;
|
||||
ret = FPREG+c[2]-'0';
|
||||
if(c[3]==':')
|
||||
ccp[0][3]=',';
|
||||
} else if(c[2]=='i') {
|
||||
n=3;
|
||||
ret = FPI;
|
||||
} else if(c[2]=='s') {
|
||||
n= (c[3] == 'r' ? 4 : 3);
|
||||
ret = FPS;
|
||||
} else if(c[2]=='c') {
|
||||
n= (c[3] == 'r' ? 4 : 3);
|
||||
ret = FPC;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
if (c[1] == 's' && c[2] == 'p') {
|
||||
n = 3;
|
||||
ret = ISP;
|
||||
} else if (c[1] == 'c') {
|
||||
n = 2;
|
||||
ret = IC;
|
||||
} else if (c[1] == 't' && c[2] == 't') {
|
||||
if ('0' <= c[3] && c[3] <= '1') {
|
||||
n = 4;
|
||||
ret = ITT0 + (c[3] - '0');
|
||||
} /* ITT[01] */
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
if (c[1] == 's' && c[2] == 'p') {
|
||||
n = 3;
|
||||
ret = MSP;
|
||||
} else if (c[1] == 'm' && c[2] == 'u' && c[3] == 's' && c[4] == 'r') {
|
||||
n = 5;
|
||||
ret = MMUSR;
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
if (c[1] == 'c') {
|
||||
n = 2;
|
||||
ret = NC;
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
if(c[1]=='c') {
|
||||
#ifndef NO_68851
|
||||
if(c[2] == 's' && c[3]=='r') {
|
||||
n=4;
|
||||
ret = (PCSR);
|
||||
} else
|
||||
#endif
|
||||
if (symbolP && S_GET_SEGMENT(symbolP) == SEG_REGISTER)
|
||||
{
|
||||
n=2;
|
||||
ret = PC;
|
||||
*ccp = p;
|
||||
return S_GET_VALUE(symbolP);
|
||||
}
|
||||
}
|
||||
#ifndef NO_68851
|
||||
else if (c[1] == 's' && c[2] == 'r') {
|
||||
n = 3;
|
||||
ret = (PSR);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 's':
|
||||
#ifndef NO_68851
|
||||
if (c[1] == 'c' && c[2] == 'c') {
|
||||
n = 3;
|
||||
ret = (SCC);
|
||||
} else
|
||||
#endif
|
||||
if (c[1] == 'r') {
|
||||
if (c[2] == 'p') {
|
||||
n = 3;
|
||||
ret = SRP;
|
||||
} else {
|
||||
n = 2;
|
||||
ret = SR;
|
||||
} /* srp else sr */
|
||||
} else if (c[1] == 'p') {
|
||||
n = 2;
|
||||
ret = SP;
|
||||
} else if (c[1] == 'f' && c[2] == 'c') {
|
||||
n = 3;
|
||||
ret = SFC;
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
if (c[1] == 'c') {
|
||||
n = 2;
|
||||
ret = TC;
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
if (c[1] == 's' && c[2] == 'p') {
|
||||
n=3;
|
||||
ret = USP;
|
||||
} else if (c[1] == 'r' && c[2] == 'p') {
|
||||
n = 3;
|
||||
ret = URP;
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
#ifndef NO_68851
|
||||
if (c[1] == 'a' && c[2] == 'l') {
|
||||
n = 3;
|
||||
ret = (VAL);
|
||||
} else
|
||||
#endif
|
||||
if(c[1]=='b' && c[2]=='r') {
|
||||
n=3;
|
||||
ret = VBR;
|
||||
}
|
||||
break;
|
||||
case 'z':
|
||||
if(c[1]=='p' && c[2]=='c') {
|
||||
n=3;
|
||||
ret = ZPC;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(n) {
|
||||
#ifdef REGISTER_PREFIX
|
||||
n++;
|
||||
#endif
|
||||
if(isalnum(ccp[0][n]) || ccp[0][n]=='_')
|
||||
ret=FAIL;
|
||||
else
|
||||
ccp[0]+=n;
|
||||
} else
|
||||
ret = FAIL;
|
||||
return ret;
|
||||
return FAIL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#define SKIP_WHITE() { str++; if(*str==' ') str++;}
|
||||
|
@ -1136,7 +913,7 @@ main()
|
|||
for(;;) {
|
||||
if(!gets(buf))
|
||||
break;
|
||||
bzero(&thark,sizeof(thark));
|
||||
memset(&thark, '\0', sizeof(thark));
|
||||
if(!m68k_ip_op(buf,&thark)) printf("FAIL:");
|
||||
if(thark.error)
|
||||
printf("op1 error %s in %s\n",thark.error,buf);
|
||||
|
@ -1259,8 +1036,8 @@ void m68k_ip (instring)
|
|||
for(n=opsfound;n>0;--n)
|
||||
the_ins.operands[n]=the_ins.operands[n-1];
|
||||
|
||||
/* bcopy((char *)(&the_ins.operands[0]),(char *)(&the_ins.operands[1]),opsfound*sizeof(the_ins.operands[0])); */
|
||||
bzero((char *)(&the_ins.operands[0]),sizeof(the_ins.operands[0]));
|
||||
/* memcpy((char *)(&the_ins.operands[1]), (char *)(&the_ins.operands[0]), opsfound*sizeof(the_ins.operands[0])); */
|
||||
memset((char *)(&the_ins.operands[0]), '\0', sizeof(the_ins.operands[0]));
|
||||
the_ins.operands[0].mode=MSCR;
|
||||
the_ins.operands[0].reg=COPNUM; /* COP #1 */
|
||||
opsfound++;
|
||||
|
@ -2676,7 +2453,7 @@ char *str;
|
|||
);
|
||||
} /* default current_architecture */
|
||||
|
||||
bzero((char *)(&the_ins),sizeof(the_ins)); /* JF for paranoia sake */
|
||||
memset((char *)(&the_ins), '\0', sizeof(the_ins)); /* JF for paranoia sake */
|
||||
m68k_ip(str);
|
||||
er=the_ins.error;
|
||||
if(!er) {
|
||||
|
@ -2806,6 +2583,140 @@ char *str;
|
|||
/* This function is called once, at assembler startup time. This should
|
||||
set up all the tables, etc that the MD part of the assembler needs
|
||||
*/
|
||||
|
||||
void
|
||||
insert_reg(regname, regnum)
|
||||
char *regname;
|
||||
int regnum;
|
||||
{
|
||||
char buf[100];
|
||||
int i;
|
||||
symbol_table_insert(symbol_new(regname, SEG_REGISTER, regnum, &zero_address_frag));
|
||||
|
||||
for (i = 0; regname[i]; i++)
|
||||
buf[i] = islower (regname[i]) ? toupper (regname[i]) : regname[i];
|
||||
buf[i] = '\0';
|
||||
|
||||
symbol_table_insert(symbol_new(buf, SEG_REGISTER, regnum, &zero_address_frag));
|
||||
}
|
||||
|
||||
static struct {
|
||||
char *name;
|
||||
int number;
|
||||
} init_table[] =
|
||||
{
|
||||
"d0", DATA0,
|
||||
"d1", DATA1,
|
||||
"d2", DATA2,
|
||||
"d3", DATA3,
|
||||
"d4", DATA4,
|
||||
"d5", DATA5,
|
||||
"d6", DATA6,
|
||||
"d7", DATA7,
|
||||
"a0", ADDR0,
|
||||
"a1", ADDR1,
|
||||
"a2", ADDR2,
|
||||
"a3", ADDR3,
|
||||
"a4", ADDR4,
|
||||
"a5", ADDR5,
|
||||
"a6", ADDR6,
|
||||
"fp", ADDR6,
|
||||
"a7", ADDR7,
|
||||
"sp", ADDR7,
|
||||
"fp0", FP0,
|
||||
"fp1", FP1,
|
||||
"fp2", FP2,
|
||||
"fp3", FP3,
|
||||
"fp4", FP4,
|
||||
"fp5", FP5,
|
||||
"fp6", FP6,
|
||||
"fp7", FP7,
|
||||
"fpi", FPI,
|
||||
"fps", FPS,
|
||||
"fpc", FPC,
|
||||
|
||||
"cop0", COP0,
|
||||
"cop1", COP1,
|
||||
"cop2", COP2,
|
||||
"cop3", COP3,
|
||||
"cop4", COP4,
|
||||
"cop5", COP5,
|
||||
"cop6", COP6,
|
||||
"cop7", COP7,
|
||||
"pc", PC,
|
||||
"zpc", ZPC,
|
||||
"sr", SR,
|
||||
|
||||
"ccr", CCR,
|
||||
"cc", CCR,
|
||||
|
||||
"usp", USP,
|
||||
"isp", ISP,
|
||||
"sfc", SFC,
|
||||
"dfc", DFC,
|
||||
"cacr", CACR,
|
||||
"caar", CAAR,
|
||||
|
||||
"vbr", VBR,
|
||||
|
||||
"msp", MSP,
|
||||
"itt0", ITT0,
|
||||
"itt1", ITT1,
|
||||
"dtt0", DTT0,
|
||||
"dtt1", DTT1,
|
||||
"mmusr", MMUSR,
|
||||
"tc", TC,
|
||||
"srp", SRP,
|
||||
"urp", URP,
|
||||
|
||||
#ifndef NO_68851
|
||||
"ac", AC,
|
||||
"bc", BC,
|
||||
"cal", CAL,
|
||||
"crp", CRP,
|
||||
"drp", DRP,
|
||||
"pcsr", PCSR,
|
||||
"psr", PSR,
|
||||
"scc", SCC,
|
||||
"val", VAL,
|
||||
"bad0", BAD0,
|
||||
"bad1", BAD1,
|
||||
"bad2", BAD2,
|
||||
"bad3", BAD3,
|
||||
"bad4", BAD4,
|
||||
"bad5", BAD5,
|
||||
"bad6", BAD6,
|
||||
"bad7", BAD7,
|
||||
"bac0", BAC0,
|
||||
"bac1", BAC1,
|
||||
"bac2", BAC2,
|
||||
"bac3", BAC3,
|
||||
"bac4", BAC4,
|
||||
"bac5", BAC5,
|
||||
"bac6", BAC6,
|
||||
"bac7", BAC7,
|
||||
#endif
|
||||
|
||||
"ic", IC,
|
||||
"dc", DC,
|
||||
"nc", NC,
|
||||
|
||||
0,
|
||||
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
init_regtable()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; init_table[i].name; i++)
|
||||
{
|
||||
insert_reg(init_table[i].name, init_table[i].number);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
md_begin()
|
||||
{
|
||||
|
@ -2877,6 +2788,8 @@ void
|
|||
#ifdef REGISTER_PREFIX
|
||||
alt_notend_table[REGISTER_PREFIX] = 1;
|
||||
#endif
|
||||
|
||||
init_regtable();
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -3414,29 +3327,23 @@ void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
|
|||
*/
|
||||
|
||||
static unsigned char nbytes_r_length [] = { 42, 0, 1, 42, 2 };
|
||||
|
||||
long r_extern;
|
||||
long r_symbolnum;
|
||||
|
||||
/* this is easy */
|
||||
know(fixP->fx_addsy != NULL);
|
||||
|
||||
md_number_to_chars(where,
|
||||
fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
|
||||
4);
|
||||
|
||||
/* now the fun stuff */
|
||||
if (S_GET_TYPE(fixP->fx_addsy) == N_UNDF) {
|
||||
r_extern = 1;
|
||||
r_symbolnum = fixP->fx_addsy->sy_number;
|
||||
} else {
|
||||
r_extern = 0;
|
||||
r_symbolnum = S_GET_TYPE(fixP->fx_addsy);
|
||||
}
|
||||
r_symbolnum = (S_IS_DEFINED(fixP->fx_addsy)
|
||||
? S_GET_TYPE(fixP->fx_addsy)
|
||||
: fixP->fx_addsy->sy_number);
|
||||
|
||||
where[4] = (r_symbolnum >> 16) & 0x0ff;
|
||||
where[5] = (r_symbolnum >> 8) & 0x0ff;
|
||||
where[6] = r_symbolnum & 0x0ff;
|
||||
where[7] = (((fixP->fx_pcrel << 7) & 0x80) | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60) |
|
||||
((r_extern << 4) & 0x10));
|
||||
(((!S_IS_DEFINED(fixP->fx_addsy)) << 4) & 0x10));
|
||||
|
||||
return;
|
||||
} /* tc_aout_fix_to_chars() */
|
||||
|
@ -3839,7 +3746,7 @@ main()
|
|||
*cp=' ';
|
||||
if(is_label(buf))
|
||||
continue;
|
||||
bzero(&the_ins,sizeof(the_ins));
|
||||
memset(&the_ins, '\0', sizeof(the_ins));
|
||||
m68k_ip(&the_ins,buf);
|
||||
if(the_ins.error) {
|
||||
printf("Error %s in %s\n",the_ins.error,buf);
|
||||
|
@ -3909,23 +3816,6 @@ abort()
|
|||
exit(12);
|
||||
}
|
||||
|
||||
char *index(s,c)
|
||||
char *s;
|
||||
{
|
||||
while(*s!=c) {
|
||||
if(!*s) return 0;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
bzero(s,n)
|
||||
char *s;
|
||||
{
|
||||
while(n--)
|
||||
*s++=0;
|
||||
}
|
||||
|
||||
print_frags()
|
||||
{
|
||||
fragS *fragP;
|
||||
|
@ -3991,7 +3881,7 @@ long
|
|||
md_pcrel_from (fixP)
|
||||
fixS *fixP;
|
||||
{
|
||||
return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
|
||||
return(fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
139
gas/expr.c
139
gas/expr.c
|
@ -39,10 +39,6 @@ static void clean_up_expression(); /* Internal. */
|
|||
extern const char EXP_CHARS[]; /* JF hide MD floating pt stuff all the same place */
|
||||
extern const char FLT_CHARS[];
|
||||
|
||||
#ifdef LOCAL_LABELS_DOLLAR
|
||||
extern int local_label_defined[];
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Build any floating-point literal here.
|
||||
* Also build any bignum literal here.
|
||||
|
@ -101,8 +97,6 @@ expressionS *expressionP;
|
|||
integer_constant(radix, expressionP)
|
||||
int radix;
|
||||
expressionS *expressionP;
|
||||
|
||||
|
||||
{
|
||||
register char * digit_2; /*->2nd digit of number. */
|
||||
char c;
|
||||
|
@ -217,25 +211,18 @@ expressionS *expressionP;
|
|||
number = leader - generic_bignum + 1; /* number of littlenums in the bignum. */
|
||||
}
|
||||
}
|
||||
if (small)
|
||||
{
|
||||
if (small) {
|
||||
/*
|
||||
* here with number, in correct radix. c is the next char.
|
||||
* note that unlike un*x, we allow "011f" "0x9f" to
|
||||
* both mean the same as the (conventional) "9f". this is simply easier
|
||||
* than checking for strict canonical form. syntax sux!
|
||||
*/
|
||||
if (number<10)
|
||||
{
|
||||
if (0
|
||||
|
||||
switch (c) {
|
||||
|
||||
#ifdef LOCAL_LABELS_FB
|
||||
|| c=='b'
|
||||
#endif
|
||||
#ifdef LOCAL_LABELS_DOLLAR
|
||||
|| (c=='$' && local_label_defined[number])
|
||||
#endif
|
||||
)
|
||||
{
|
||||
case 'b': {
|
||||
/*
|
||||
* backward ref to local label.
|
||||
* because it is backward, expect it to be defined.
|
||||
|
@ -243,45 +230,37 @@ expressionS *expressionP;
|
|||
/*
|
||||
* construct a local label.
|
||||
*/
|
||||
name = local_label_name ((int)number, 0);
|
||||
if (((symbolP = symbol_find(name)) != NULL) /* seen before */
|
||||
&& (S_IS_DEFINED(symbolP))) /* symbol is defined: ok */
|
||||
{ /* expected path: symbol defined. */
|
||||
name = fb_label_name((int) number, 0);
|
||||
|
||||
/* seen before, or symbol is defined: ok */
|
||||
symbolP = symbol_find(name);
|
||||
if ((symbolP != NULL) && (S_IS_DEFINED(symbolP))) {
|
||||
|
||||
/* local labels are never absolute. don't waste time checking absoluteness. */
|
||||
know(SEG_NORMAL(S_GET_SEGMENT(symbolP)));
|
||||
|
||||
expressionP->X_add_symbol = symbolP;
|
||||
expressionP->X_add_number = 0;
|
||||
expressionP->X_seg = S_GET_SEGMENT(symbolP);
|
||||
}
|
||||
else
|
||||
{ /* either not seen or not defined. */
|
||||
as_bad("backw. ref to unknown label \"%d:\", 0 assumed.",
|
||||
number);
|
||||
expressionP->X_add_number = 0;
|
||||
|
||||
} else { /* either not seen or not defined. */
|
||||
as_bad("backw. ref to unknown label \"%d:\", 0 assumed.", number);
|
||||
expressionP->X_seg = SEG_ABSOLUTE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0
|
||||
#ifdef LOCAL_LABELS_FB
|
||||
|| c == 'f'
|
||||
#endif
|
||||
#ifdef LOCAL_LABELS_DOLLAR
|
||||
|| (c=='$' && !local_label_defined[number])
|
||||
#endif
|
||||
)
|
||||
{
|
||||
|
||||
expressionP->X_add_number = 0;
|
||||
break;
|
||||
} /* case 'b' */
|
||||
|
||||
case 'f': {
|
||||
/*
|
||||
* forward reference. expect symbol to be undefined or
|
||||
* unknown. undefined: seen it before. unknown: never seen
|
||||
* it in this pass.
|
||||
* it before.
|
||||
* construct a local label name, then an undefined symbol.
|
||||
* don't create a xseg frag for it: caller may do that.
|
||||
* just return it as never seen before.
|
||||
*/
|
||||
name = local_label_name((int)number, 1);
|
||||
name = fb_label_name((int) number, 1);
|
||||
symbolP = symbol_find_or_make(name);
|
||||
/* we have no need to check symbol properties. */
|
||||
#ifndef many_segments
|
||||
|
@ -293,29 +272,54 @@ expressionS *expressionP;
|
|||
expressionP->X_seg = SEG_UNKNOWN;
|
||||
expressionP->X_subtract_symbol = NULL;
|
||||
expressionP->X_add_number = 0;
|
||||
|
||||
break;
|
||||
} /* case 'f' */
|
||||
|
||||
#endif /* LOCAL_LABELS_FB */
|
||||
|
||||
#ifdef LOCAL_LABELS_DOLLAR
|
||||
|
||||
case '$': {
|
||||
|
||||
/* if the dollar label is *currently* defined, then this is just another
|
||||
reference to it. If it is not *currently* defined, then this is a
|
||||
fresh instantiation of that number, so create it. */
|
||||
|
||||
if (dollar_label_defined(number)) {
|
||||
name = dollar_label_name(number, 0);
|
||||
symbolP = symbol_find(name);
|
||||
know(symbolP != NULL);
|
||||
} else {
|
||||
name = dollar_label_name(number, 1);
|
||||
symbolP = symbol_find_or_make(name);
|
||||
}
|
||||
else
|
||||
{ /* really a number, not a local label. */
|
||||
|
||||
expressionP->X_add_symbol = symbolP;
|
||||
expressionP->X_add_number = 0;
|
||||
expressionP->X_seg = S_GET_SEGMENT(symbolP);
|
||||
|
||||
break;
|
||||
} /* case '$' */
|
||||
|
||||
#endif /* LOCAL_LABELS_DOLLAR */
|
||||
|
||||
default: {
|
||||
expressionP->X_add_number = number;
|
||||
expressionP->X_seg = SEG_ABSOLUTE;
|
||||
input_line_pointer--; /* restore following character. */
|
||||
} /* if (c=='f') */
|
||||
} /* if (c=='b') */
|
||||
}
|
||||
else
|
||||
{ /* really a number. */
|
||||
expressionP->X_add_number = number;
|
||||
expressionP->X_seg = SEG_ABSOLUTE;
|
||||
input_line_pointer --; /* restore following character. */
|
||||
} /* if (number<10) */
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
} /* really just a number */
|
||||
|
||||
} /* switch on char following the number */
|
||||
|
||||
|
||||
} else { /* not a small number */
|
||||
expressionP->X_add_number = number;
|
||||
expressionP->X_seg = SEG_BIG;
|
||||
input_line_pointer --; /*->char following number. */
|
||||
} /* if (small) */
|
||||
}
|
||||
} /* integer_constant() */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -390,10 +394,21 @@ operand (expressionP)
|
|||
{
|
||||
|
||||
default:
|
||||
if (c && strchr(FLT_CHARS,c))
|
||||
{
|
||||
input_line_pointer++;
|
||||
floating_constant(expressionP);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
/* The string was only zero */
|
||||
expressionP->X_add_symbol = 0;
|
||||
expressionP->X_add_number = 0;
|
||||
expressionP->X_seg = SEG_ABSOLUTE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
|
@ -435,7 +450,7 @@ operand (expressionP)
|
|||
case 'd':
|
||||
case 'D':
|
||||
case 'F':
|
||||
|
||||
case 'r':
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'g':
|
||||
|
@ -459,7 +474,7 @@ operand (expressionP)
|
|||
}
|
||||
/* here with input_line_pointer->char after "(...)" */
|
||||
}
|
||||
return;
|
||||
return expressionP->X_seg;
|
||||
|
||||
|
||||
case '\'':
|
||||
|
@ -931,7 +946,9 @@ register expressionS *resultP; /* Deliver result here. */
|
|||
segT seg1;
|
||||
segT seg2;
|
||||
#ifndef MANY_SEGMENTS
|
||||
know(resultP->X_seg == SEG_DATA || resultP->X_seg == SEG_TEXT || resultP->X_seg == SEG_BSS || resultP->X_seg == SEG_UNKNOWN || resultP->X_seg == SEG_DIFFERENCE || resultP->X_seg == SEG_ABSOLUTE || resultP->X_seg == SEG_PASS1);
|
||||
know(resultP->X_seg == SEG_DATA || resultP->X_seg == SEG_TEXT || resultP->X_seg == SEG_BSS || resultP->X_seg ==
|
||||
SEG_UNKNOWN || resultP->X_seg == SEG_DIFFERENCE || resultP->X_seg == SEG_ABSOLUTE || resultP->X_seg == SEG_PASS1
|
||||
|| resultP->X_seg == SEG_REGISTER);
|
||||
know(right.X_seg == SEG_DATA || right.X_seg == SEG_TEXT || right.X_seg == SEG_BSS || right.X_seg == SEG_UNKNOWN || right.X_seg == SEG_DIFFERENCE || right.X_seg == SEG_ABSOLUTE || right.X_seg == SEG_PASS1);
|
||||
#endif
|
||||
clean_up_expression (& right);
|
||||
|
|
360
gas/read.c
360
gas/read.c
|
@ -1,6 +1,5 @@
|
|||
/* read.c - read a source file -
|
||||
|
||||
Copyright (C) 1986, 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
Copyright (C) 1986, 1987, 1990, 1991 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
|
||||
|
@ -36,12 +35,9 @@
|
|||
#include "as.h"
|
||||
|
||||
#include "obstack.h"
|
||||
|
||||
#include "listing.h"
|
||||
char *input_line_pointer; /*->next char of source file to parse. */
|
||||
|
||||
#ifndef NOP_OPCODE
|
||||
# define NOP_OPCODE 0x00
|
||||
#endif
|
||||
|
||||
#if BITS_PER_CHAR != 8
|
||||
The following table is indexed by [ (char) ] and will break if
|
||||
|
@ -123,7 +119,7 @@ struct broken_word *broken_words;
|
|||
int new_broken_words = 0;
|
||||
#endif
|
||||
|
||||
#if __STDC__ == 1
|
||||
#ifdef __STDC__
|
||||
|
||||
static char *demand_copy_string(int *lenP);
|
||||
int is_it_end_of_statement(void);
|
||||
|
@ -143,7 +139,7 @@ static void grow_bignum();
|
|||
static void pobegin();
|
||||
void stringer();
|
||||
|
||||
#endif /* not __STDC__ */
|
||||
#endif /* __STDC__ */
|
||||
|
||||
extern int listing;
|
||||
|
||||
|
@ -174,6 +170,11 @@ void
|
|||
struct hash_control *
|
||||
po_hash = NULL; /* use before set up: NULL->address error */
|
||||
|
||||
#ifdef DONTDEF
|
||||
void s_gdbline(), s_gdblinetab();
|
||||
void s_gdbbeg(), s_gdbblock(), s_gdbend(), s_gdbsym();
|
||||
#endif
|
||||
|
||||
static const pseudo_typeS
|
||||
potable[] =
|
||||
{
|
||||
|
@ -183,17 +184,12 @@ static const pseudo_typeS
|
|||
{ "asciz", stringer, 1 },
|
||||
/* block */
|
||||
{ "byte", cons, 1 },
|
||||
{ "bss", s_bss, 0 },
|
||||
{ "comm", s_comm, 0 },
|
||||
{ "data", s_data, 0 },
|
||||
/* dim */
|
||||
{ "double", float_cons, 'd' },
|
||||
/* dsect */
|
||||
#ifdef NO_LISTING
|
||||
{ "eject", s_ignore, 0 }, /* Formfeed listing */
|
||||
#else
|
||||
{ "eject", listing_eject, 0 }, /* Formfeed listing */
|
||||
#endif /* NO_LISTING */
|
||||
{ "else", s_else, 0 },
|
||||
{ "end", s_end, 0 },
|
||||
{ "endif", s_endif, 0 },
|
||||
|
@ -206,6 +202,14 @@ static const pseudo_typeS
|
|||
{ "file", s_app_file, 0 },
|
||||
{ "fill", s_fill, 0 },
|
||||
{ "float", float_cons, 'f' },
|
||||
#ifdef DONTDEF
|
||||
{ "gdbbeg", s_gdbbeg, 0 },
|
||||
{ "gdbblock", s_gdbblock, 0 },
|
||||
{ "gdbend", s_gdbend, 0 },
|
||||
{ "gdbsym", s_gdbsym, 0 },
|
||||
{ "gdbline", s_gdbline, 0 },
|
||||
{ "gdblinetab",s_gdblinetab, 0 },
|
||||
#endif
|
||||
{ "global", s_globl, 0 },
|
||||
{ "globl", s_globl, 0 },
|
||||
{ "hword", cons, 2 },
|
||||
|
@ -218,34 +222,17 @@ static const pseudo_typeS
|
|||
{ "include", s_include, 0 },
|
||||
{ "int", cons, 4 },
|
||||
{ "lcomm", s_lcomm, 0 },
|
||||
#ifdef NO_LISTING
|
||||
{ "lflags", s_ignore, 0 }, /* Listing flags */
|
||||
{ "list", s_ignore, 1 }, /* Turn listing on */
|
||||
#else
|
||||
{ "lflags", listing_flags, 0 }, /* Listing flags */
|
||||
{ "list", listing_list, 1 }, /* Turn listing on */
|
||||
#endif /* NO_LISTING */
|
||||
{ "long", cons, 4 },
|
||||
{ "lsym", s_lsym, 0 },
|
||||
#ifdef NO_LISTING
|
||||
{ "nolist", s_ignore, 0 }, /* Turn listing off */
|
||||
#else
|
||||
{ "nolist", listing_list, 0 }, /* Turn listing off */
|
||||
#endif /* NO_LISTING */
|
||||
{ "octa", big_cons, 16 },
|
||||
{ "org", s_org, 0 },
|
||||
#ifdef NO_LISTING
|
||||
{ "psize", s_ignore, 0 }, /* set paper size */
|
||||
#else
|
||||
{ "psize", listing_psize, 0 }, /* set paper size */
|
||||
#endif /* NO_LISTING */
|
||||
/* print */
|
||||
{ "quad", big_cons, 8 },
|
||||
#ifdef NO_LISTING
|
||||
{ "sbttl", s_ignore, 1 }, /* Subtitle of listing */
|
||||
#else
|
||||
{ "sbttl", listing_title, 1 }, /* Subtitle of listing */
|
||||
#endif /* NO_LISTING */
|
||||
/* scl */
|
||||
/* sect */
|
||||
{ "set", s_set, 0 },
|
||||
|
@ -255,11 +242,7 @@ static const pseudo_typeS
|
|||
{ "space", s_space, 0 },
|
||||
/* tag */
|
||||
{ "text", s_text, 0 },
|
||||
#ifdef NO_LISTING
|
||||
{ "title", s_ignore, 0 }, /* Listing title */
|
||||
#else
|
||||
{ "title", listing_title, 0 }, /* Listing title */
|
||||
#endif /* NO_LISTING */
|
||||
/* type */
|
||||
/* use */
|
||||
/* val */
|
||||
|
@ -337,6 +320,12 @@ char *name;
|
|||
register int temp;
|
||||
/* register struct frag * fragP; JF unused */ /* a frag we just made */
|
||||
pseudo_typeS *pop;
|
||||
#ifdef DONTDEF
|
||||
void gdb_block_beg();
|
||||
void gdb_block_position();
|
||||
void gdb_block_end();
|
||||
void gdb_symbols_fixup();
|
||||
#endif
|
||||
|
||||
buffer = input_scrub_new_file(name);
|
||||
|
||||
|
@ -356,10 +345,26 @@ char *name;
|
|||
*/
|
||||
if (input_line_pointer[-1] == '\n') {
|
||||
bump_line_counters();
|
||||
|
||||
#ifdef MRI
|
||||
/* Text at the start of a line must be a label, we run down and stick a colon in */
|
||||
if (is_name_beginner(*input_line_pointer))
|
||||
{
|
||||
char *line_start = input_line_pointer;
|
||||
char c = get_symbol_end();
|
||||
colon(line_start);
|
||||
*input_line_pointer = c;
|
||||
if (c == ':')
|
||||
input_line_pointer++;
|
||||
|
||||
}
|
||||
#endif
|
||||
} /* just passed a newline */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* We are at the begining of a line, or similar place.
|
||||
* We expect a well-formed assembler statement.
|
||||
|
@ -406,6 +411,10 @@ char *name;
|
|||
equals(s);
|
||||
demand_empty_rest_of_line();
|
||||
} else { /* expect pseudo-op or machine instruction */
|
||||
#ifdef MRI
|
||||
if(!done_pseudo(s))
|
||||
|
||||
#else
|
||||
if (*s == '.') {
|
||||
/*
|
||||
* PSEUDO - OP.
|
||||
|
@ -443,17 +452,23 @@ char *name;
|
|||
} else {
|
||||
(*pop->poc_handler)(pop->poc_val);
|
||||
} /* if we have one */
|
||||
} else { /* machine instruction */
|
||||
} else
|
||||
#endif
|
||||
{ /* machine instruction */
|
||||
/* WARNING: c has char, which may be end-of-line. */
|
||||
/* Also: input_line_pointer->`\0` where c was. */
|
||||
* input_line_pointer = c;
|
||||
while (!is_end_of_line[*input_line_pointer]) {
|
||||
input_line_pointer++;
|
||||
}
|
||||
|
||||
c = *input_line_pointer;
|
||||
*input_line_pointer = '\0';
|
||||
|
||||
md_assemble(s); /* Assemble 1 instruction. */
|
||||
|
||||
*input_line_pointer++ = c;
|
||||
|
||||
/* We resume loop AFTER the end-of-line from this instruction */
|
||||
} /* if (*s=='.') */
|
||||
|
||||
|
@ -467,26 +482,45 @@ char *name;
|
|||
} /* empty statement */
|
||||
|
||||
|
||||
#if defined(LOCAL_LABELS_DOLLAR) || defined(LOCAL_LABELS_FB)
|
||||
if (isdigit(c)) { /* local label ("4:") */
|
||||
char *backup = input_line_pointer;
|
||||
|
||||
HANDLE_CONDITIONAL_ASSEMBLY ();
|
||||
|
||||
temp = c - '0';
|
||||
|
||||
while (isdigit(*input_line_pointer)) {
|
||||
temp = (temp * 10) + *input_line_pointer - '0';
|
||||
++input_line_pointer;
|
||||
} /* read the whole number */
|
||||
|
||||
#ifdef LOCAL_LABELS_DOLLAR
|
||||
if (*input_line_pointer=='$')
|
||||
input_line_pointer++;
|
||||
#endif
|
||||
if (* input_line_pointer ++ == ':')
|
||||
{
|
||||
local_colon (temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
as_bad("Spurious digit %d.", temp);
|
||||
input_line_pointer -- ;
|
||||
ignore_rest_of_line();
|
||||
if (*input_line_pointer == '$'
|
||||
&& *(input_line_pointer + 1) == ':') {
|
||||
input_line_pointer += 2;
|
||||
|
||||
if (dollar_label_defined(temp)) {
|
||||
as_fatal("label \"%d$\" redefined", temp);
|
||||
}
|
||||
|
||||
define_dollar_label(temp);
|
||||
colon(dollar_label_name(temp, 0));
|
||||
continue;
|
||||
}
|
||||
#endif /* LOCAL_LABELS_DOLLAR */
|
||||
|
||||
#ifdef LOCAL_LABELS_FB
|
||||
if (*input_line_pointer++ == ':') {
|
||||
fb_label_instance_inc(temp);
|
||||
colon(fb_label_name(temp, 0));
|
||||
continue;
|
||||
}
|
||||
#endif /* LOCAL_LABELS_FB */
|
||||
|
||||
input_line_pointer = backup;
|
||||
} /* local label ("4:") */
|
||||
#endif /* LOCAL_LABELS_DOLLAR or LOCAL_LABELS_FB */
|
||||
|
||||
if (c && strchr(line_comment_chars,c)) { /* Its a comment. Better say APP or NO_APP */
|
||||
char *ends;
|
||||
|
@ -514,7 +548,7 @@ char *name;
|
|||
guarentee it. . . */
|
||||
tmp_len=buffer_limit-s;
|
||||
tmp_buf=xmalloc(tmp_len);
|
||||
memcpy(tmp_buf, s, tmp_len);
|
||||
bcopy(s,tmp_buf,tmp_len);
|
||||
do {
|
||||
new_tmp = input_scrub_next_buffer(&buffer);
|
||||
if (!new_tmp)
|
||||
|
@ -529,7 +563,7 @@ char *name;
|
|||
num=buffer_limit-buffer;
|
||||
|
||||
tmp_buf = xrealloc(tmp_buf, tmp_len + num);
|
||||
memcpy(tmp_buf + tmp_len, buffer, num);
|
||||
bcopy(buffer,tmp_buf+tmp_len,num);
|
||||
tmp_len+=num;
|
||||
} while(!ends);
|
||||
|
||||
|
@ -630,7 +664,7 @@ int arg;
|
|||
input_line_pointer ++;
|
||||
temp_fill = get_absolute_expression ();
|
||||
} else {
|
||||
temp_fill = NOP_OPCODE;
|
||||
temp_fill = 0;
|
||||
}
|
||||
/* Only make a frag if we HAVE to. . . */
|
||||
if (temp && ! need_pass_2)
|
||||
|
@ -656,7 +690,7 @@ void s_align_ptwo() {
|
|||
input_line_pointer ++;
|
||||
temp_fill = get_absolute_expression ();
|
||||
} else
|
||||
temp_fill = NOP_OPCODE;
|
||||
temp_fill = 0;
|
||||
/* Only make a frag if we HAVE to. . . */
|
||||
if (temp && ! need_pass_2)
|
||||
frag_align (temp, (int)temp_fill);
|
||||
|
@ -666,17 +700,6 @@ void s_align_ptwo() {
|
|||
demand_empty_rest_of_line();
|
||||
} /* s_align_ptwo() */
|
||||
|
||||
|
||||
void s_bss()
|
||||
{
|
||||
register int temp;
|
||||
|
||||
temp = get_absolute_expression ();
|
||||
subseg_new (SEG_BSS, (subsegT)temp);
|
||||
demand_empty_rest_of_line();
|
||||
}
|
||||
|
||||
|
||||
void s_comm() {
|
||||
register char *name;
|
||||
register char c;
|
||||
|
@ -794,7 +817,7 @@ void s_fill() {
|
|||
temp_fill = get_absolute_expression ();
|
||||
if (temp_size && !need_pass_2) {
|
||||
p = frag_var(rs_fill, (int)temp_size, (int)temp_size, (relax_substateT)0, (symbolS *)0, temp_repeat, (char *)0);
|
||||
memset(p, '\0', (int) temp_size);
|
||||
bzero (p, (int)temp_size);
|
||||
/*
|
||||
* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX flavoured AS.
|
||||
* The following bizzare behaviour is to be compatible with above.
|
||||
|
@ -812,6 +835,118 @@ void s_fill() {
|
|||
demand_empty_rest_of_line();
|
||||
}
|
||||
|
||||
#ifdef DONTDEF
|
||||
void
|
||||
s_gdbbeg()
|
||||
{
|
||||
register int temp;
|
||||
|
||||
temp = get_absolute_expression ();
|
||||
if (temp < 0)
|
||||
as_warn("Block number <0. Ignored.");
|
||||
else if (flagseen ['G'])
|
||||
gdb_block_beg ((long) temp, frag_now, (long)(obstack_next_free(& frags) - frag_now->fr_literal));
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
||||
void
|
||||
s_gdbblock()
|
||||
{
|
||||
register int position;
|
||||
int temp;
|
||||
|
||||
if (get_absolute_expression_and_terminator (&temp) != ',') {
|
||||
as_bad("expected comma before position in .gdbblock");
|
||||
--input_line_pointer;
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
position = get_absolute_expression ();
|
||||
if (flagseen ['G'])
|
||||
gdb_block_position ((long) temp, (long) position);
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
||||
void
|
||||
s_gdbend()
|
||||
{
|
||||
register int temp;
|
||||
|
||||
temp = get_absolute_expression ();
|
||||
if (temp < 0)
|
||||
as_warn("Block number <0. Ignored.");
|
||||
else if (flagseen ['G'])
|
||||
gdb_block_end ((long) temp, frag_now, (long)(obstack_next_free(& frags) - frag_now->fr_literal));
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
||||
void
|
||||
s_gdbsym()
|
||||
{
|
||||
register char *name,
|
||||
*p;
|
||||
register char c;
|
||||
register symbolS * symbolP;
|
||||
register int temp;
|
||||
|
||||
name = input_line_pointer;
|
||||
c = get_symbol_end();
|
||||
p = input_line_pointer;
|
||||
symbolP = symbol_find_or_make(name);
|
||||
*p = c;
|
||||
SKIP_WHITESPACE();
|
||||
if (* input_line_pointer != ',') {
|
||||
as_bad("Expected comma after name");
|
||||
ignore_rest_of_line();
|
||||
return;
|
||||
}
|
||||
input_line_pointer ++;
|
||||
if ((temp = get_absolute_expression ()) < 0) {
|
||||
as_bad("Bad GDB symbol file offset (%d.) <0! Ignored.", temp);
|
||||
ignore_rest_of_line();
|
||||
return;
|
||||
}
|
||||
if (flagseen ['G'])
|
||||
gdb_symbols_fixup (symbolP, (long)temp);
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
||||
void
|
||||
s_gdbline()
|
||||
{
|
||||
int file_number,
|
||||
lineno;
|
||||
|
||||
if (get_absolute_expression_and_terminator(&file_number) != ',') {
|
||||
as_bad("expected comman after filenum in .gdbline");
|
||||
ignore_rest_of_line();
|
||||
return;
|
||||
}
|
||||
lineno=get_absolute_expression();
|
||||
if (flagseen['G'])
|
||||
gdb_line(file_number,lineno);
|
||||
demand_empty_rest_of_line();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
s_gdblinetab()
|
||||
{
|
||||
int file_number,
|
||||
offset;
|
||||
|
||||
if (get_absolute_expression_and_terminator(&file_number) != ',') {
|
||||
as_bad("expected comma after filenum in .gdblinetab");
|
||||
ignore_rest_of_line();
|
||||
return;
|
||||
}
|
||||
offset=get_absolute_expression();
|
||||
if (flagseen['G'])
|
||||
gdb_line_tab(file_number,offset);
|
||||
demand_empty_rest_of_line();
|
||||
}
|
||||
#endif
|
||||
|
||||
void s_globl() {
|
||||
register char *name;
|
||||
register int c;
|
||||
|
@ -1229,6 +1364,12 @@ symbolS * symbolP;
|
|||
|
||||
switch (segment)
|
||||
{
|
||||
case SEG_REGISTER:
|
||||
S_SET_SEGMENT(symbolP, SEG_REGISTER);
|
||||
S_SET_VALUE(symbolP, exp.X_add_number);
|
||||
symbolP->sy_frag = & zero_address_frag;
|
||||
break;
|
||||
|
||||
case SEG_BIG:
|
||||
as_bad("%s number invalid. Absolute 0 assumed.",
|
||||
exp . X_add_number > 0 ? "Bignum" : "Floating-Point");
|
||||
|
@ -1283,6 +1424,7 @@ symbolS * symbolP;
|
|||
case SEG_DATA: S_SET_SEGMENT(symbolP, SEG_DATA); break;
|
||||
case SEG_TEXT: S_SET_SEGMENT(symbolP, SEG_TEXT); break;
|
||||
case SEG_BSS: S_SET_SEGMENT(symbolP, SEG_BSS); break;
|
||||
|
||||
default: as_fatal("failed sanity check.");
|
||||
} /* switch on segment */
|
||||
#endif
|
||||
|
@ -1386,7 +1528,53 @@ register unsigned int nbytes; /* 1=.byte, 2=.word, 4=.long */
|
|||
/* used for error messages and rescanning */
|
||||
char *hold = input_line_pointer;
|
||||
#endif /* WANT_BITFIELDS */
|
||||
#ifdef MRI
|
||||
if (*input_line_pointer == '\'')
|
||||
{
|
||||
/* An MRI style string, cut into as many bytes as will fit
|
||||
into a nbyte chunk, left justify if necessary, and sepatate
|
||||
with commas so we can try again later */
|
||||
int scan = 0;
|
||||
unsigned int result = 0;
|
||||
input_line_pointer++;
|
||||
for (scan = 0; scan < nbytes; scan++)
|
||||
{
|
||||
if (*input_line_pointer == '\'')
|
||||
{
|
||||
if (input_line_pointer[1] == '\'')
|
||||
{
|
||||
input_line_pointer++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
result = (result << 8) | (*input_line_pointer++);
|
||||
}
|
||||
|
||||
/* Left justify */
|
||||
while (scan < nbytes)
|
||||
{
|
||||
result <<=8;
|
||||
scan++;
|
||||
}
|
||||
/* Create correct expression */
|
||||
exp.X_add_symbol = 0;
|
||||
exp.X_add_number = result;
|
||||
exp.X_seg = segment = SEG_ABSOLUTE;
|
||||
/* Fake it so that we can read the next char too */
|
||||
if (input_line_pointer[0] != '\'' ||
|
||||
(input_line_pointer[0] == '\'' && input_line_pointer[1] == '\''))
|
||||
{
|
||||
input_line_pointer-=2;
|
||||
input_line_pointer[0] = ',';
|
||||
input_line_pointer[1] = '\'';
|
||||
}
|
||||
else
|
||||
input_line_pointer++;
|
||||
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* At least scan over the expression. */
|
||||
segment = expression(&exp);
|
||||
|
||||
|
@ -1558,9 +1746,23 @@ register unsigned int nbytes; /* 1=.byte, 2=.word, 4=.long */
|
|||
exp . X_add_symbol, exp . X_subtract_symbol,
|
||||
exp . X_add_number, 0, 0, 2, 0, 0);
|
||||
#else
|
||||
# if defined(TC_SPARC) || defined(TC_A29K)
|
||||
fix_new (frag_now, p - frag_now->fr_literal, nbytes,
|
||||
exp . X_add_symbol, exp . X_subtract_symbol,
|
||||
exp . X_add_number, 0, RELOC_32);
|
||||
# else
|
||||
# if defined(TC_H8300)
|
||||
fix_new (frag_now, p - frag_now->fr_literal, nbytes,
|
||||
exp . X_add_symbol, exp . X_subtract_symbol,
|
||||
exp . X_add_number, 0, R_RELWORD);
|
||||
|
||||
# else
|
||||
fix_new (frag_now, p - frag_now->fr_literal, nbytes,
|
||||
exp . X_add_symbol, exp . X_subtract_symbol,
|
||||
exp . X_add_number, 0, 0);
|
||||
|
||||
# endif /* tc_h8300 */
|
||||
# endif /* tc_sparc|tc_a29k */
|
||||
#endif /* TC_NS32K */
|
||||
break;
|
||||
} /* switch(segment) */
|
||||
|
@ -1693,7 +1895,7 @@ register int nbytes;
|
|||
if (! need_pass_2)
|
||||
{
|
||||
p = frag_more (nbytes);
|
||||
memcpy(p, bignum_low, (int) nbytes);
|
||||
bcopy (bignum_low, p, (int)nbytes);
|
||||
}
|
||||
/* C contains character after number. */
|
||||
SKIP_WHITESPACE();
|
||||
|
@ -1763,7 +1965,8 @@ register int float_type; /* 'f':.ffloat ... 'F':.float ... */
|
|||
{
|
||||
c = ','; /* Do loop. */
|
||||
}
|
||||
while (c == ',') {
|
||||
while (c == ',')
|
||||
{
|
||||
/* input_line_pointer->1st char of a flonum (we hope!). */
|
||||
SKIP_WHITESPACE();
|
||||
/* Skip any 0{letter} that may be present. Don't even check if the
|
||||
|
@ -1778,15 +1981,19 @@ register int float_type; /* 'f':.ffloat ... 'F':.float ... */
|
|||
err = md_atof (float_type, temp, &length);
|
||||
know(length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
|
||||
know(length > 0);
|
||||
if (* err) {
|
||||
if (* err)
|
||||
{
|
||||
as_bad("Bad floating literal: %s", err);
|
||||
ignore_rest_of_line();
|
||||
/* Input_line_pointer->just after end-of-line. */
|
||||
c = 0; /* Break out of loop. */
|
||||
} else {
|
||||
if (! need_pass_2) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! need_pass_2)
|
||||
{
|
||||
p = frag_more (length);
|
||||
memcpy(p, temp, length);
|
||||
bcopy (temp, p, length);
|
||||
}
|
||||
SKIP_WHITESPACE();
|
||||
c = * input_line_pointer ++;
|
||||
|
@ -1811,7 +2018,12 @@ void stringer(append_zero ) /* Worker to do .ascii etc statements. */
|
|||
/* Checks end-of-line. */
|
||||
register int append_zero; /* 0: don't append '\0', else 1 */
|
||||
{
|
||||
unsigned int c;
|
||||
/* register char * p; JF unused */
|
||||
/* register int length; JF unused */ /* Length of string we read, excluding */
|
||||
/* trailing '\0' implied by closing quote. */
|
||||
/* register char * where; JF unused */
|
||||
/* register fragS * fragP; JF unused */
|
||||
register unsigned int c;
|
||||
|
||||
/*
|
||||
* The following awkward logic is to parse ZERO or more strings,
|
||||
|
@ -1821,13 +2033,15 @@ register int append_zero; /* 0: don't append '\0', else 1 */
|
|||
* a 1st, expression. We keep demanding expressions for each
|
||||
* ','.
|
||||
*/
|
||||
if (is_it_end_of_statement()) {
|
||||
if (is_it_end_of_statement())
|
||||
{
|
||||
c = 0; /* Skip loop. */
|
||||
++ input_line_pointer; /* Compensate for end of loop. */
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
c = ','; /* Do loop. */
|
||||
}
|
||||
|
||||
while (c == ',' || c == '<' || c == '"' ) {
|
||||
SKIP_WHITESPACE();
|
||||
switch (*input_line_pointer) {
|
||||
|
|
|
@ -35,8 +35,7 @@ frchainS* frchain_root,
|
|||
#else
|
||||
frchainS* frchain_root,
|
||||
* frchain_now, /* Commented in "subsegs.h". */
|
||||
* data0_frchainP,
|
||||
* bss0_frchainP;
|
||||
* data0_frchainP;
|
||||
|
||||
#endif
|
||||
char * const /* in: segT out: char* */
|
||||
|
@ -109,8 +108,6 @@ void
|
|||
#else
|
||||
subseg_new (SEG_DATA, 0); /* .data 0 */
|
||||
data0_frchainP = frchain_now;
|
||||
subseg_new (SEG_BSS, 0);
|
||||
bss0_frchainP = frchain_now;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -136,12 +133,7 @@ register int subseg;
|
|||
seg_fix_rootP = & segment_info[seg].fix_root;
|
||||
seg_fix_tailP = & segment_info[seg].fix_tail;
|
||||
#else
|
||||
if (seg == SEG_BSS)
|
||||
{
|
||||
seg_fix_rootP = & bss_fix_root;
|
||||
seg_fix_tailP = & bss_fix_tail;
|
||||
}
|
||||
else if (seg == SEG_DATA)
|
||||
if (seg == SEG_DATA)
|
||||
{
|
||||
seg_fix_rootP = & data_fix_root;
|
||||
seg_fix_tailP = & data_fix_tail;
|
||||
|
@ -173,13 +165,25 @@ register int subseg;
|
|||
|
||||
void
|
||||
subseg_new (seg, subseg) /* begin assembly for a new sub-segment */
|
||||
register segT seg; /* SEG_DATA or SEG_TEXT or SEG_BSS */
|
||||
register segT seg; /* SEG_DATA or SEG_TEXT */
|
||||
register subsegT subseg;
|
||||
{
|
||||
long tmp; /* JF for obstack alignment hacking */
|
||||
#ifndef MANY_SEGMENTS
|
||||
know( seg == SEG_DATA || seg == SEG_TEXT || seg == SEG_BSS);
|
||||
know(seg == SEG_DATA || seg == SEG_TEXT);
|
||||
#endif
|
||||
#ifdef OBJ_AOUT
|
||||
/* If -R specifed, always put stuff into the data section */
|
||||
if (flagseen['R'])
|
||||
{
|
||||
if (seg == SEG_DATA)
|
||||
{
|
||||
subseg += 1000;
|
||||
seg = SEG_TEXT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (seg != now_seg || subseg != now_subseg)
|
||||
{ /* we just changed sub-segments */
|
||||
register frchainS * frcP; /* crawl frchain chain */
|
||||
|
|
|
@ -215,6 +215,7 @@ void write_object_file()
|
|||
* data frags into the text segment. Do this before relaxing so
|
||||
* we know to take advantage of -R and make shorter addresses.
|
||||
*/
|
||||
#ifndef OBJ_AOUT
|
||||
if (flagseen[ 'R' ]) {
|
||||
fixS *tmp;
|
||||
|
||||
|
@ -230,7 +231,7 @@ void write_object_file()
|
|||
text_fix_root=data_fix_root;
|
||||
data_fix_root=NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
relax_segment(text_frag_root, SEG_TEXT);
|
||||
relax_segment(data_frag_root, SEG_DATA);
|
||||
/*
|
||||
|
|
Loading…
Add table
Reference in a new issue