#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <mach-o/i860/reloc.h>
#include "i860-opcode.h"
#include "as.h"
#include "flonum.h"
#include "expr.h"
#include "hash.h"
#include "frags.h"
#include "fixes.h"
#include "read.h"
#include "md.h"
#include "symbols.h"
#include "messages.h"
#include "sections.h"
const cpu_type_t md_cputype = CPU_TYPE_I860;
cpu_subtype_t md_cpusubtype = CPU_SUBTYPE_I860_ALL;
const enum byte_sex md_target_byte_sex = BIG_ENDIAN_BYTE_SEX;
static int i860_ip(
char *str);
static void md_insn_to_chars(
unsigned char *buf,
int32_t val,
int n);
const relax_typeS md_relax_table[] = { {0} };
static struct hash_control *op_hash = NULL;
static void s_dual(
uintptr_t mode);
static void s_i860_align(
uintptr_t value);
static void s_i860_org(
uintptr_t value);
const pseudo_typeS md_pseudo_table[] = {
{ "float", float_cons, 'f' },
{ "int", cons, 4 },
{ "align", s_i860_align, 0 },
{ "blkb", s_space, 0 },
{ "dual", s_dual, 1 },
{ "enddual",s_dual, 0 },
{ "extern", s_globl, 0 },
{ "ln", s_line, 0 },
{ "org", s_i860_org, 0 },
#ifndef NeXT_MOD
{ "quad", big_cons, 16 },
#endif
{ "string", stringer, 1 },
{ NULL, 0, 0 },
};
static int dual_insn_mode = 0;
const char md_comment_chars[] = "|!";
const char md_line_comment_chars[] = "#";
const char md_EXP_CHARS[] = "eE";
const char md_FLT_CHARS[] = "rRsSfFdDxXpP";
int size_reloc_info = sizeof(struct relocation_info);
static unsigned char octal[256];
#define isoctal(c) octal[c]
static unsigned char toHex[256];
static int I860_errors;
static int insn_count;
struct i860_it {
char *error;
uint32_t opcode;
nlist_t *nlistp;
expressionS exp;
int pcrel;
int reloc;
};
static struct i860_it the_insn;
#ifdef I860_DEBUG
static void print_insn(
struct i860_it *insn);
#endif
static int getExpression(
char *str);
static char *expr_end;
#define INSERT_NOP 0x00000001
static
void
s_dual(
uintptr_t mode)
{
dual_insn_mode = mode;
}
static
void
s_i860_align(
uintptr_t value)
{
register unsigned int temp;
register int32_t temp_fill;
unsigned int i = 0;
unsigned int bytes;
char *toP, fill;
bytes = temp = get_absolute_expression ();
#define MAX_ALIGNMENT (1 << 15)
if ( temp > MAX_ALIGNMENT ) {
as_warn("Alignment too large: %d. assumed.", temp = MAX_ALIGNMENT);
}
if (temp != 0) {
for (i = 0; (temp & 1) == 0; temp >>= 1, ++i)
;
}
if (temp != 1) {
as_warn("Alignment not a power of 2");
}
temp = i;
if (*input_line_pointer == ',') {
input_line_pointer ++;
temp_fill = get_absolute_expression ();
} else {
if ( frchain_now->frch_nsect == text_nsect )
temp_fill = OP_NOP;
else
temp_fill = 0;
}
if ( frchain_now->frch_nsect == text_nsect )
{
if ( bytes & 3 )
as_warn( "Instruction alignment must be a multiple of 4." );
bytes &= ~3;
while ( bytes && ((insn_count * 4) % bytes) != 0 )
{
toP = frag_more(4);
md_insn_to_chars((unsigned char *)toP, temp_fill, 4);
insn_count++;
}
demand_empty_rest_of_line();
return;
}
if (temp) {
md_number_to_chars(&fill, temp_fill, 1);
frag_align(temp, &fill, 1, 0);
}
if(frchain_now->frch_section.align < temp)
frchain_now->frch_section.align = temp;
demand_empty_rest_of_line();
return;
}
static
void
s_i860_org(
uintptr_t value)
{
register segT segment;
expressionS exp;
register int32_t temp_fill;
register char *p;
extern segT get_known_segmented_expression();
segment = get_known_segmented_expression(& exp);
if ( *input_line_pointer == ',' ) {
input_line_pointer ++;
temp_fill = get_absolute_expression ();
} else
temp_fill = 0;
if((segment != SEG_SECT ||
exp.X_add_symbol->sy_other != frchain_now->frch_nsect) &&
segment != SEG_ABSOLUTE)
as_warn("Illegal expression. current section assumed.");
if ( exp.X_add_symbol != NULL )
as_warn("Symbol relative .org may corrupt alignment.");
else if ( exp.X_add_number & 3 )
{
exp.X_add_number &= ~3;
as_warn(".org not on instruction boundry. Adjusted to \".org "
"%lld\"", exp.X_add_number);
}
if ( exp.X_add_symbol == NULL )
insn_count = exp.X_add_number >> 2;
p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp . X_add_symbol,
exp . X_add_number, (char *)0);
* p = temp_fill;
demand_empty_rest_of_line();
}
void
md_begin(
void)
{
const char *retval = NULL;
uint32_t i;
int j = 0;
insn_count = 0;
if ((op_hash = hash_new()) == NULL)
as_fatal("Virtual memory exhausted");
for (i = 0; i < NUMOPCODES; ++i) {
if (~i860_opcodes[i].mask & i860_opcodes[i].match) {
printf("bad opcode - `%s %s'\n",
i860_opcodes[i].name, i860_opcodes[i].args);
++j;
}
}
if (j)
exit(1);
for (i = 0; i < NUMOPCODES; ++i) {
retval = hash_insert(op_hash, (char *)i860_opcodes[i].name,
(char *)&i860_opcodes[i]);
if(retval && *retval) {
as_fatal("Internal Error: Can't hash %s: %s",
i860_opcodes[i].name, retval);
}
while (!i860_opcodes[i].last)
++i;
}
for (i = '0'; i < '8'; ++i)
octal[i] = 1;
for (i = '0'; i <= '9'; ++i)
toHex[i] = i - '0';
for (i = 'a'; i <= 'f'; ++i)
toHex[i] = i + 10 - 'a';
for (i = 'A'; i <= 'F'; ++i)
toHex[i] = i + 10 - 'A';
I860_errors = 0;
return;
}
void
md_end(
void)
{
if ( I860_errors )
{
fprintf( stderr, "%d fatal %s encountered during assembly.\n", I860_errors,
(I860_errors == 1 ? "error" : "errors") );
exit( 42 );
}
return;
}
void
md_assemble(
char *str)
{
char *toP;
int flags;
assert(str);
flags = i860_ip(str);
if ( flags & INSERT_NOP )
{
toP = frag_more(4);
md_insn_to_chars((unsigned char *)toP, OP_NOP, 4);
++insn_count;
}
toP = frag_more(4);
md_insn_to_chars((unsigned char *)toP, the_insn.opcode, 4);
++insn_count;
if (the_insn.reloc != NO_RELOC) {
fix_new(
frag_now,
(toP - frag_now->fr_literal),
4,
the_insn.exp.X_add_symbol,
the_insn.exp.X_subtract_symbol,
the_insn.exp.X_add_number,
the_insn.pcrel, 0,
the_insn.reloc
);
}
}
static
int
i860_ip(
char *str)
{
char *s;
char *op;
const char *args;
char c;
struct i860_opcode *insn;
char *argsStart;
char *s1;
uint32_t opcode;
unsigned int mask;
int this_insn_is_dual = 0;
int adjustment;
int align_mask;
int match = FALSE;
int comma = 0;
int flags = 0;
static int expect_int_insn;
for (s = str; islower(*s) || *s == '.' || isdigit(*s); ++s)
;
switch (*s) {
case '\0':
break;
case ',':
comma = 1;
case ' ':
case '\t':
*s++ = '\0';
break;
default:
as_warn("Unknown opcode: `%s'", str);
exit(1);
}
op = str;
if ( *op == 'd' && *(op + 1) == '.' )
{
op += 2;
this_insn_is_dual = 1;
}
if ((insn = (struct i860_opcode *) hash_find(op_hash, op)) == NULL) {
as_warn("Unknown instruction or format: `%s'.", str);
memset(&the_insn, '\0', sizeof(the_insn));
the_insn.reloc = NO_RELOC;
the_insn.opcode = OP_NOP;
++I860_errors;
return flags;
}
if (comma) {
*--s = ',';
}
argsStart = s;
for (;;) {
opcode = insn->match;
memset(&the_insn, '\0', sizeof(the_insn));
the_insn.reloc = NO_RELOC;
for (args = insn->args; ; ++args) {
align_mask = 0;
switch (*args) {
case '\0':
if (*s == '\0') {
match = TRUE;
}
break;
case '+':
case '(':
case ')':
case ',':
case ' ':
if (*s++ == *args)
continue;
break;
case 'C':
if (strncmp(s, "fir", 3) == 0) {
s += 3;
SET_RS2(opcode, 0);
continue;
}
if (strncmp(s, "psr", 3) == 0) {
s += 3;
SET_RS2(opcode, 1);
continue;
}
if (strncmp(s, "dirbase", 7) == 0) {
s += 7;
SET_RS2(opcode, 2);
continue;
}
if (strncmp(s, "db", 2) == 0) {
s += 2;
SET_RS2(opcode, 3);
continue;
}
if (strncmp(s, "fsr", 3) == 0) {
s += 3;
SET_RS2(opcode, 4);
continue;
}
if (strncmp(s, "epsr", 4) == 0) {
s += 4;
SET_RS2(opcode, 5);
continue;
}
break;
case '1':
case '2':
case 'd':
{
switch (c = *s++) {
case 'f':
if (*s++ == 'p') {
mask = 3;
break;
}
goto error;
case 's':
if (*s++ == 'p') {
mask = 2;
break;
}
goto error;
case 'r':
if (!isdigit(c = *s++)) {
goto error;
}
if (isdigit(*s)) {
if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) {
goto error;
}
} else {
c -= '0';
}
mask= c;
break;
default:
goto error;
}
switch (*args) {
case '1':
SET_RS1(opcode, mask);
continue;
case '2':
SET_RS2(opcode, mask);
continue;
case 'd':
SET_RD(opcode, mask);
continue;
}
}
break;
case 'e':
case 'f':
case 'g':
case 'E':
case 'F':
case 'G':
case 'H':
if (*s++ == 'f' && isdigit(*s)) {
mask = *s++;
if (isdigit(*s)) {
mask = 10 * (mask - '0') + (*s++ - '0');
if (mask >= 32) {
break;
}
} else {
mask -= '0';
}
if ( (*args == 'E' || *args == 'F' || *args == 'G') && (mask & 1) )
{
as_warn( "f%d: Even register required. Adjusted to f%d.",
mask, mask & 0x1E );
mask &= 0x1E;
}
else if ( *args == 'H' && (mask & 3) )
{
as_warn( "f%d: Quad register required. Adjusted to f%d.",
mask, mask & 0x1C );
mask &= 0x1C;
}
switch (*args) {
case 'e':
case 'E':
SET_RS1(opcode, mask);
continue;
case 'f':
case 'F':
SET_RS2(opcode, mask);
continue;
case 'g':
case 'G':
case 'H':
SET_RD(opcode, mask);
continue;
}
}
break;
case 'B':
(void)getExpression(s);
s = expr_end;
if ( the_insn.exp.X_seg != SEG_ABSOLUTE )
{
as_warn( "Constant expression expected" );
++I860_errors;
}
if ( the_insn.exp.X_add_number < 0 || the_insn.exp.X_add_number > 31 )
as_warn( "Constant must be between 0 and 31. Modulo 32 applied." );
SET_RS1(opcode, the_insn.exp.X_add_number);
continue;
case 'D':
(void)getExpression(s);
s = expr_end;
if ( the_insn.exp.X_seg != SEG_ABSOLUTE )
{
as_warn( "Constant expression expected" );
++I860_errors;
}
if ( the_insn.exp.X_add_number < 0 || the_insn.exp.X_add_number > 31 )
as_warn( "Constant must be between 0 and 31. Modulo 32 applied." );
opcode |= (the_insn.exp.X_add_number & 0x1F);
continue;
case 'i':
the_insn.reloc = I860_RELOC_LOW0;
goto immediate;
case 'I':
the_insn.reloc = I860_RELOC_HIGH;
goto immediate;
case 'j':
the_insn.reloc = I860_RELOC_LOW1;
align_mask = 1;
goto immediate;
case 'k':
the_insn.reloc = I860_RELOC_LOW2;
align_mask = 3;
goto immediate;
case 'l':
the_insn.reloc = I860_RELOC_LOW3;
align_mask = 7;
goto immediate;
case 'm':
the_insn.reloc = I860_RELOC_LOW4;
align_mask = 15;
goto immediate;
case 'n':
the_insn.reloc = I860_RELOC_SPLIT0;
goto immediate;
case 'o':
the_insn.reloc = I860_RELOC_SPLIT1;
align_mask = 1;
goto immediate;
case 'p':
the_insn.reloc = I860_RELOC_SPLIT2;
align_mask = 3;
goto immediate;
case 'J':
the_insn.reloc = I860_RELOC_HIGHADJ;
goto immediate;
case 'K':
the_insn.reloc = I860_RELOC_BRADDR;
the_insn.pcrel = 1;
goto immediate;
case 'L':
the_insn.reloc = I860_RELOC_SPLIT0;
the_insn.pcrel = 1;
goto immediate;
immediate:
if(*s==' ')
s++;
adjustment = 0;
if ( *s == 'h' && *(s + 1) == '%' )
{
adjustment = I860_RELOC_HIGH;
if ( the_insn.reloc == I860_RELOC_LOW0 && the_insn.pcrel == 0 )
{
the_insn.reloc = I860_RELOC_HIGH;
}
else
as_warn("Improper use of h%%.");
s += 2;
}
else if ( *s == 'h' && *(s + 1) == 'a' && *(s + 2) == '%' )
{
adjustment = I860_RELOC_HIGHADJ;
if ( the_insn.reloc == I860_RELOC_LOW0 && the_insn.pcrel == 0 )
{
the_insn.reloc = I860_RELOC_HIGHADJ;
}
else
as_warn("Improper use of ha%%.");
s += 3;
}
else if ( *s == 'l' && *(s + 1) == '%' )
{
adjustment = I860_RELOC_LOW0;
s += 2;
}
for(s1=s;*s1 && *s1!=','&& *s1!=')';s1++)
;
if( s1 != s && *s1 == '(' && s1[1] == 'r' && isdigit(s1[2])
&& (s1[3]==')' || (isdigit(s1[3]) && s1[4] == ')')) ) {
*s1='\0';
(void)getExpression(s);
*s1='(';
s=s1;
}
else
{
(void)getExpression(s);
s = expr_end;
}
if ( ! adjustment && *op != 'b' && *op != 'c' )
{
if ( the_insn.exp.X_seg != SEG_ABSOLUTE )
{
as_warn(
"Non-absolute expression requires h%%, l%%, or ha%% prefix."
);
}
else
{
if ( IS_LOGOP(opcode) )
{
if ( ((unsigned)the_insn.exp.X_add_number) > 0xFFFF )
as_warn("%lld is too big for 16 bit unsigned value!",
the_insn.exp.X_add_number);
}
else
{
if ( ((int)the_insn.exp.X_add_number) > 32767 ||
((int)the_insn.exp.X_add_number) < -32768 )
as_warn("%lld is out of range for 16 bit signed value!",
the_insn.exp.X_add_number);
if ((align_mask & the_insn.exp.X_add_number) != 0)
as_warn("Const offset 0x%x incorrectly aligned.",
(unsigned int)the_insn.exp.X_add_number);
}
}
}
continue;
default:
abort();
}
break;
}
error:
if (match == FALSE) {
if (!insn->last) {
++insn;
s = argsStart;
continue;
} else {
as_warn("Illegal operands (%s %s).", str, argsStart);
++I860_errors;
return flags;
}
}
break;
}
if ( expect_int_insn && (dual_insn_mode || this_insn_is_dual) )
{
if ( (opcode & OP_PREFIX_MASK) == PREFIX_FPU || opcode == OP_FNOP )
{
as_warn( "Core half of prev dual insn pair missing." );
}
expect_int_insn = 0;
}
if ( dual_insn_mode || this_insn_is_dual )
{
if ( (opcode & OP_PREFIX_MASK) == PREFIX_FPU || opcode == OP_FNOP )
{
if ( insn_count & 1 )
{
as_warn( "Dual FP insn on odd addr." );
}
opcode |= DUAL_INSN_MODE_BIT;
expect_int_insn = 1;
}
else if ( this_insn_is_dual )
{
as_warn("d. prefix not allowed for `%s'. (Ignored!)", op);
}
}
else
expect_int_insn = 0;
if ( (the_insn.reloc == I860_RELOC_BRADDR
|| (the_insn.pcrel && the_insn.reloc == I860_RELOC_SPLIT0)
) && (the_insn.exp.X_add_number & 3) )
as_warn( "Branch offset is not aligned to instruction boundry!" );
the_insn.opcode = opcode;
return flags;
}
static
int
getExpression(
char *str)
{
char *save_in;
segT seg;
save_in = input_line_pointer;
input_line_pointer = str;
switch (seg = expression(&the_insn.exp)) {
case SEG_ABSOLUTE:
case SEG_SECT:
case SEG_DIFFSECT:
case SEG_UNKNOWN:
case SEG_BIG:
case SEG_NONE:
break;
default:
the_insn.error = "bad segment";
expr_end = input_line_pointer;
input_line_pointer=save_in;
return 1;
}
expr_end = input_line_pointer;
input_line_pointer = save_in;
return 0;
}
#define MAX_LITTLENUMS 6
char *
md_atof(
int type,
char *litP,
int *sizeP)
{
int prec;
LITTLENUM_TYPE words[MAX_LITTLENUMS];
LITTLENUM_TYPE *wordP;
char *t;
char *atof_ieee();
switch(type) {
case 'f':
case 'F':
case 's':
case 'S':
prec = 2;
break;
case 'd':
case 'D':
case 'r':
case 'R':
prec = 4;
break;
case 'x':
case 'X':
type = 'd';
prec = 4;
break;
case 'p':
case 'P':
type = 'd';
prec = 4;
break;
default:
*sizeP=0;
return "Bad call to MD_ATOF()";
}
t=atof_ieee(input_line_pointer,type,words);
if(t)
input_line_pointer=t;
*sizeP=prec * sizeof(LITTLENUM_TYPE);
for(wordP=words;prec--;) {
md_number_to_chars(litP,(int32_t)(*wordP++),sizeof(LITTLENUM_TYPE));
litP+=sizeof(LITTLENUM_TYPE);
}
return "";
}
void
md_number_to_chars(
char *buf,
signed_expr_t val,
int n)
{
switch(n) {
case 4:
*buf++ = val >> 24;
*buf++ = val >> 16;
case 2:
*buf++ = val >> 8;
case 1:
*buf = val;
break;
default:
abort();
}
return;
}
#ifdef BYTE_SWAP
static
void
md_insn_to_chars(
unsigned char *buf,
int32_t val,
int n)
{
switch(n) {
case 4:
*buf++ = val;
*buf++ = val >> 8;
*buf++ = val >> 16;
*buf++ = val >> 24;
break;
case 2:
*buf++ = val;
*buf++ = val >> 8;
break;
case 1:
*buf = val;
break;
default:
abort();
}
return;
}
#else
static
void
md_insn_to_chars(
unsigned char *buf,
int32_t val,
int n)
{
md_number_to_chars((char *)buf,val,n);
}
#endif
void
md_number_to_imm(
unsigned char *buf,
signed_expr_t val,
int n,
fixS *fixP,
int nsect)
{
uint32_t opcode;
if ( nsect == (int)text_nsect && (n % 4) != 0 )
as_warn("Immediate write of non-aligned data into text segment." );
if (nsect != (int)text_nsect ||
fixP->fx_r_type == NO_RELOC ||
fixP->fx_r_type == I860_RELOC_VANILLA)
{
switch (n) {
case 1:
*buf = val;
break;
case 2:
*buf++ = (val>>8);
*buf = val;
break;
case 4:
*buf++ = (val>>24);
*buf++ = (val>>16);
*buf++ = (val>>8);
*buf = val;
break;
default:
abort();
}
return;
}
assert(n == 4);
assert(fixP->fx_r_type < NO_RELOC && fixP->fx_r_type > I860_RELOC_VANILLA);
#ifdef BYTE_SWAP
opcode = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
#else
opcode = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
#endif
switch (fixP->fx_r_type) {
case I860_RELOC_PAIR:
as_warn("questionable relocation type I860_RELOC_PAIR");
break;
case I860_RELOC_HIGH:
opcode &= ~0xFFFF;
opcode |= ((val >> 16) & 0xFFFF);
break;
case I860_RELOC_LOW0:
opcode &= ~0xFFFF;
opcode |= (val & 0xFFFF);
break;
case I860_RELOC_LOW1:
opcode &= 0xFFFF0001;
opcode |= (val & 0xFFFE);
break;
case I860_RELOC_LOW2:
opcode &= 0xFFFF0003;
opcode |= (val & 0xFFFC);
break;
case I860_RELOC_LOW3:
opcode &= 0xFFFF0007;
opcode |= (val & 0xFFF8);
break;
case I860_RELOC_LOW4:
opcode &= 0xFFFF000F;
opcode |= (val & 0xFFF0);
break;
case I860_RELOC_SPLIT0:
opcode &= 0xFFE0F800;
if ( fixP->fx_pcrel )
val >>= 2;
opcode |= ((val & 0xF800) << 5) | (val & 0x7FF);
break;
case I860_RELOC_SPLIT1:
opcode &= 0xFFE0F801;
opcode |= ((val & 0xF800) << 5) | (val & 0x7FE);
break;
case I860_RELOC_SPLIT2:
opcode &= 0xFFE0F803;
opcode |= ((val & 0xF800) << 5) | (val & 0x7FC);
break;
case I860_RELOC_HIGHADJ:
opcode &= ~0xFFFF;
if ( (val & 0x8000) != 0 )
val = (val >> 16) + 1;
else
val = (val >> 16);
opcode |= (val & 0xFFFF);
break;
case I860_RELOC_BRADDR:
if ( fixP->fx_pcrel )
val >>= 2;
opcode &= 0xFC000000;
opcode |= (val & 0x03FFFFFF);
break;
default:
as_warn("bad relocation type: 0x%02x", fixP->fx_r_type);
break;
}
#ifdef BYTE_SWAP
buf[0] = opcode;
buf[1] = opcode >> 8;
buf[2] = opcode >> 16;
buf[3] = opcode >> 24;
#else
buf[3] = opcode;
buf[2] = opcode >> 8;
buf[1] = opcode >> 16;
buf[0] = opcode >> 24;
#endif
return;
}
void
md_convert_frag(
fragS *fragP)
{
fprintf(stderr, "i860_convert_frag\n");
abort();
}
int
md_estimate_size_before_relax(
fragS *fragP,
int nsect)
{
fprintf(stderr, "i860_estimate_size_before_relax\n");
abort();
return 0;
}
#ifdef I860_DEBUG
static void
print_insn(
struct i860_it *insn)
{
char *Reloc[] = {
"RELOC_8",
"RELOC_16",
"RELOC_32",
"RELOC_DISP8",
"RELOC_DISP16",
"RELOC_DISP32",
"RELOC_WDISP30",
"RELOC_WDISP22",
"RELOC_HI22",
"RELOC_22",
"RELOC_13",
"RELOC_LO10",
"RELOC_SFA_BASE",
"RELOC_SFA_OFF13",
"RELOC_BASE10",
"RELOC_BASE13",
"RELOC_BASE22",
"RELOC_PC10",
"RELOC_PC22",
"RELOC_JMP_TBL",
"RELOC_SEGOFF16",
"RELOC_GLOB_DAT",
"RELOC_JMP_SLOT",
"RELOC_RELATIVE",
"NO_RELOC"
};
if (insn->error) {
fprintf(stderr, "ERROR: %s\n");
}
fprintf(stderr, "opcode=0x%08x\n", insn->opcode);
fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]);
fprintf(stderr, "exp = {\n");
fprintf(stderr, "\t\tX_add_symbol = %s\n",
insn->exp.X_add_symbol ?
(insn->exp.X_add_symbol->sy_name ?
insn->exp.X_add_symbol->sy_name : "???") : "0");
fprintf(stderr, "\t\tX_sub_symbol = %s\n",
insn->exp.X_subtract_symbol ?
(insn->exp.X_subtract_symbol->sy_name ?
insn->exp.X_subtract_symbol->sy_name : "???") : "0");
fprintf(stderr, "\t\tX_add_number = %d\n",
insn->exp.X_add_number);
fprintf(stderr, "}\n");
return;
}
#endif
int
md_parse_option(
char **argP,
int *cntP,
char ***vecP)
{
return 1;
}