start-sanitize-d10v
Mon Jul 22 11:32:36 1996 Martin M. Hunt <hunt@pizza.cygnus.com> * config/tc-d10v.c: Many changes to get relocs working. (register_name): No longer creates a symbol for register names. (pre_defined_registers): moved to opcodes/d10v-opc.c. (d10v_insert_operand): Now works correctly for either container. * config/tc-d10v.h (d10v_cleanup): Declare. end-sanitize-d10v
This commit is contained in:
parent
d82a4ac0aa
commit
0ef325594a
@ -1,3 +1,13 @@
|
||||
start-sanitize-d10v
|
||||
Mon Jul 22 11:32:36 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
|
||||
|
||||
* config/tc-d10v.c: Many changes to get relocs working.
|
||||
(register_name): No longer creates a symbol for register names.
|
||||
(pre_defined_registers): moved to opcodes/d10v-opc.c.
|
||||
(d10v_insert_operand): Now works correctly for either container.
|
||||
* config/tc-d10v.h (d10v_cleanup): Declare.
|
||||
|
||||
end-sanitize-d10v
|
||||
Mon Jul 22 14:01:33 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* config/tc-mips.c (tc_gen_reloc): BFD_RELOC_PCREL_HI16_S and
|
||||
|
@ -33,29 +33,40 @@ const char *md_shortopts = "";
|
||||
const char EXP_CHARS[] = "eE";
|
||||
const char FLT_CHARS[] = "dD";
|
||||
|
||||
/* local functions */
|
||||
static int reg_name_search PARAMS ((char *name));
|
||||
static void register_name PARAMS ((expressionS *expressionP));
|
||||
static int postfix PARAMS ((char *p));
|
||||
static bfd_reloc_code_real_type get_reloc PARAMS ((struct d10v_operand *op));
|
||||
static int get_operands PARAMS ((expressionS exp[]));
|
||||
static unsigned long build_insn PARAMS ((struct d10v_opcode *opcode, expressionS *opers));
|
||||
static void write_long PARAMS ((struct d10v_opcode *opcode, unsigned long insn));
|
||||
static void write_1_short PARAMS ((struct d10v_opcode *opcode, unsigned long insn));
|
||||
static int write_2_short PARAMS ((struct d10v_opcode *opcode1, unsigned long insn1,
|
||||
struct d10v_opcode *opcode2, unsigned long insn2, int exec_type));
|
||||
static unsigned long do_assemble PARAMS ((char *str, struct d10v_opcode **opcode));
|
||||
|
||||
/* fixups */
|
||||
#define MAX_INSN_FIXUPS (5)
|
||||
struct d10v_fixup
|
||||
{
|
||||
expressionS exp;
|
||||
int opindex;
|
||||
bfd_reloc_code_real_type reloc;
|
||||
};
|
||||
struct d10v_fixup fixups[MAX_INSN_FIXUPS];
|
||||
static int fc;
|
||||
|
||||
typedef struct _fixups
|
||||
{
|
||||
int fc;
|
||||
struct d10v_fixup fix[MAX_INSN_FIXUPS];
|
||||
struct _fixups *next;
|
||||
} Fixups;
|
||||
|
||||
static Fixups FixUps[2];
|
||||
static Fixups *fixups;
|
||||
|
||||
/* local functions */
|
||||
static int reg_name_search PARAMS ((char *name));
|
||||
static int register_name PARAMS ((expressionS *expressionP));
|
||||
static int postfix PARAMS ((char *p));
|
||||
static bfd_reloc_code_real_type get_reloc PARAMS ((struct d10v_operand *op));
|
||||
static int get_operands PARAMS ((expressionS exp[]));
|
||||
static unsigned long build_insn PARAMS ((struct d10v_opcode *opcode, expressionS *opers));
|
||||
static void write_long PARAMS ((struct d10v_opcode *opcode, unsigned long insn, Fixups *fx));
|
||||
static void write_1_short PARAMS ((struct d10v_opcode *opcode, unsigned long insn, Fixups *fx));
|
||||
static int write_2_short PARAMS ((struct d10v_opcode *opcode1, unsigned long insn1,
|
||||
struct d10v_opcode *opcode2, unsigned long insn2, int exec_type, Fixups *fx));
|
||||
static unsigned long do_assemble PARAMS ((char *str, struct d10v_opcode **opcode));
|
||||
static unsigned long d10v_insert_operand PARAMS (( unsigned long insn, int op_type,
|
||||
offsetT value, int left));
|
||||
|
||||
|
||||
struct option md_longopts[] = {
|
||||
{NULL, no_argument, NULL, 0}
|
||||
@ -65,71 +76,12 @@ size_t md_longopts_size = sizeof(md_longopts);
|
||||
/* The target specific pseudo-ops which we support. */
|
||||
const pseudo_typeS md_pseudo_table[] =
|
||||
{
|
||||
/*
|
||||
{ "byte", ppc_byte, 0 },
|
||||
{ "long", ppc_elf_cons, 4 },
|
||||
{ "word", ppc_elf_cons, 2 },
|
||||
{ "short", ppc_elf_cons, 2 },
|
||||
{ "rdata", ppc_elf_rdata, 0 },
|
||||
{ "rodata", ppc_elf_rdata, 0 },
|
||||
{ "lcomm", ppc_elf_lcomm, 0 },
|
||||
*/
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
/* Opcode hash table. */
|
||||
static struct hash_control *d10v_hash;
|
||||
|
||||
/* Structure to hold information about predefined registers. */
|
||||
struct pd_reg
|
||||
{
|
||||
char *name;
|
||||
int value;
|
||||
};
|
||||
|
||||
|
||||
/* an expressionS only has one register type, so we fake it */
|
||||
/* by setting high bits to indicate type */
|
||||
#define REGISTER_MASK 0xFF
|
||||
|
||||
/* The table is sorted. Suitable for searching by a binary search. */
|
||||
static const struct pd_reg pre_defined_registers[] =
|
||||
{
|
||||
{ "a0", OPERAND_ACC+0 },
|
||||
{ "a1", OPERAND_ACC+1 },
|
||||
{ "bpc", OPERAND_CONTROL+3 },
|
||||
{ "bpsw", OPERAND_CONTROL+1 },
|
||||
{ "c", OPERAND_FLAG+3 },
|
||||
{ "f0", OPERAND_FLAG+0 },
|
||||
{ "f1", OPERAND_FLAG+1 },
|
||||
{ "iba", OPERAND_CONTROL+14 },
|
||||
{ "mod_e", OPERAND_CONTROL+11 },
|
||||
{ "mod_s", OPERAND_CONTROL+10 },
|
||||
{ "pc", OPERAND_CONTROL+2 },
|
||||
{ "psw", OPERAND_CONTROL+0 },
|
||||
{ "r0", 0 },
|
||||
{ "r1", 1 },
|
||||
{ "r10", 10 },
|
||||
{ "r11", 11 },
|
||||
{ "r12", 12 },
|
||||
{ "r13", 13 },
|
||||
{ "r14", 14 },
|
||||
{ "r15", 15 },
|
||||
{ "r2", 2 },
|
||||
{ "r3", 3 },
|
||||
{ "r4", 4 },
|
||||
{ "r5", 5 },
|
||||
{ "r6", 6 },
|
||||
{ "r7", 7 },
|
||||
{ "r8", 8 },
|
||||
{ "r9", 9 },
|
||||
{ "rpt_c", OPERAND_CONTROL+7 },
|
||||
{ "rpt_e", OPERAND_CONTROL+9 },
|
||||
{ "rpt_s", OPERAND_CONTROL+8 },
|
||||
{ "sp", 15 },
|
||||
};
|
||||
#define REG_NAME_CNT (sizeof(pre_defined_registers) / sizeof(struct pd_reg))
|
||||
|
||||
/* reg_name_search does a binary search of the pre_defined_registers
|
||||
array to see if "name" is a valid regiter name. Returns the register
|
||||
number from the array on success, or -1 on failure. */
|
||||
@ -142,7 +94,7 @@ reg_name_search (name)
|
||||
int cmp;
|
||||
|
||||
low = 0;
|
||||
high = REG_NAME_CNT - 1;
|
||||
high = reg_name_cnt() - 1;
|
||||
|
||||
do
|
||||
{
|
||||
@ -159,30 +111,37 @@ reg_name_search (name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* register_name() checks the string at input_line_pointer
|
||||
to see if it is a valid register name */
|
||||
|
||||
/* register_name check to see if an expression is a valid
|
||||
register name. If it is, it marks the expression type
|
||||
as O_register. */
|
||||
|
||||
static void
|
||||
static int
|
||||
register_name (expressionP)
|
||||
expressionS *expressionP;
|
||||
{
|
||||
int reg_number;
|
||||
char *name;
|
||||
char c, *p = input_line_pointer;
|
||||
|
||||
while (*p && *p!='\n' && *p!='\r' && *p !=',' && *p!=' ' && *p!=')')
|
||||
p++;
|
||||
|
||||
if (expressionP->X_op == O_symbol)
|
||||
c = *p;
|
||||
if (c)
|
||||
*p++ = 0;
|
||||
|
||||
/* look to see if it's in the register table */
|
||||
reg_number = reg_name_search (input_line_pointer);
|
||||
if (reg_number >= 0)
|
||||
{
|
||||
name = (char *)S_GET_NAME (expressionP->X_add_symbol);
|
||||
reg_number = reg_name_search (name);
|
||||
|
||||
/* look to see if it's in the register table */
|
||||
if (reg_number >= 0)
|
||||
{
|
||||
expressionP->X_op = O_register;
|
||||
expressionP->X_add_number = reg_number;
|
||||
}
|
||||
expressionP->X_op = O_register;
|
||||
/* temporarily store a pointer to the string here */
|
||||
expressionP->X_op_symbol = (struct symbol *)input_line_pointer;
|
||||
expressionP->X_add_number = reg_number;
|
||||
input_line_pointer = p;
|
||||
return 1;
|
||||
}
|
||||
if (c)
|
||||
*(p-1) = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -223,7 +182,7 @@ md_convert_frag (abfd, sec, fragP)
|
||||
asection *sec;
|
||||
fragS *fragP;
|
||||
{
|
||||
/* printf ("call to md_convert_frag \n"); */
|
||||
printf ("call to md_convert_frag \n");
|
||||
abort ();
|
||||
}
|
||||
|
||||
@ -236,6 +195,7 @@ md_section_align (seg, addr)
|
||||
return ((addr + (1 << align) - 1) & (-1 << align));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
md_begin ()
|
||||
{
|
||||
@ -256,6 +216,10 @@ md_begin ()
|
||||
hash_insert (d10v_hash, opcode->name, (char *) opcode);
|
||||
}
|
||||
}
|
||||
|
||||
fixups = &FixUps[0];
|
||||
FixUps[0].next = &FixUps[1];
|
||||
FixUps[1].next = &FixUps[0];
|
||||
}
|
||||
|
||||
|
||||
@ -299,8 +263,8 @@ get_reloc (op)
|
||||
|
||||
if (op->flags & OPERAND_ADDR)
|
||||
{
|
||||
if (bits == 8)
|
||||
return (BFD_RELOC_D10V_10_PCREL_R);
|
||||
if (bits == 8)
|
||||
return (BFD_RELOC_D10V_10_PCREL_R);
|
||||
else
|
||||
return (BFD_RELOC_D10V_18_PCREL);
|
||||
}
|
||||
@ -357,10 +321,14 @@ get_operands (exp)
|
||||
}
|
||||
|
||||
input_line_pointer = p;
|
||||
/* create an expression */
|
||||
expression (&exp[numops]);
|
||||
|
||||
|
||||
/* check to see if it might be a register name */
|
||||
register_name (&exp[numops]);
|
||||
if (!register_name (&exp[numops]))
|
||||
{
|
||||
/* parse as an expression */
|
||||
expression (&exp[numops]);
|
||||
}
|
||||
|
||||
if (exp[numops].X_op == O_illegal)
|
||||
as_bad ("illegal operand");
|
||||
@ -388,14 +356,18 @@ get_operands (exp)
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
d10v_insert_operand (insn, op_type, value)
|
||||
d10v_insert_operand (insn, op_type, value, left)
|
||||
unsigned long insn;
|
||||
int op_type;
|
||||
offsetT value;
|
||||
int left;
|
||||
{
|
||||
int shift, bits;
|
||||
|
||||
shift = d10v_operands[op_type].shift;
|
||||
if (left)
|
||||
shift += 15;
|
||||
|
||||
bits = d10v_operands[op_type].bits;
|
||||
/* truncate to the proper number of bits */
|
||||
/* FIXME: overflow checking here? */
|
||||
@ -443,14 +415,14 @@ build_insn (opcode, opers)
|
||||
printf("\n");
|
||||
*/
|
||||
|
||||
if (fc >= MAX_INSN_FIXUPS)
|
||||
if (fixups->fc >= MAX_INSN_FIXUPS)
|
||||
as_fatal ("too many fixups");
|
||||
fixups[fc].exp = opers[i];
|
||||
fixups->fix[fixups->fc].exp = opers[i];
|
||||
|
||||
/* put the operand number here for now. We can look up
|
||||
the reloc type and/or fixup the instruction in md_apply_fix() */
|
||||
fixups[fc].reloc = opcode->operands[i];
|
||||
fc++;
|
||||
fixups->fix[fixups->fc].reloc = opcode->operands[i];
|
||||
(fixups->fc)++;
|
||||
}
|
||||
|
||||
/* truncate to the proper number of bits */
|
||||
@ -463,84 +435,92 @@ build_insn (opcode, opers)
|
||||
|
||||
/* write out a long form instruction */
|
||||
static void
|
||||
write_long (opcode, insn)
|
||||
write_long (opcode, insn, fx)
|
||||
struct d10v_opcode *opcode;
|
||||
unsigned long insn;
|
||||
Fixups *fx;
|
||||
{
|
||||
int i;
|
||||
char *f = frag_more(4);
|
||||
|
||||
insn |= FM11;
|
||||
/* printf("INSN: %08x\n",insn); */
|
||||
/* printf("INSN: %08x\n",insn); */
|
||||
number_to_chars_bigendian (f, insn, 4);
|
||||
|
||||
for (i=0; i<fc; i++)
|
||||
for (i=0; i < fx->fc; i++)
|
||||
{
|
||||
if (get_reloc((struct d10v_operand *)&d10v_operands[fixups[i].reloc]))
|
||||
if (get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].reloc]))
|
||||
{
|
||||
/*
|
||||
printf("fix_new_exp: where:%x size:4\n ",f - frag_now->fr_literal);
|
||||
print_expr_1(stdout,&fixups[i].exp);
|
||||
print_expr_1(stdout,&(fx->fix[i].exp));
|
||||
printf("\n");
|
||||
*/
|
||||
|
||||
|
||||
fix_new_exp (frag_now,
|
||||
f - frag_now->fr_literal,
|
||||
4,
|
||||
&fixups[i].exp,
|
||||
&(fx->fix[i].exp),
|
||||
1,
|
||||
fixups[i].reloc);
|
||||
fx->fix[i].reloc);
|
||||
}
|
||||
}
|
||||
fx->fc = 0;
|
||||
}
|
||||
|
||||
|
||||
/* write out a short form instruction by itself */
|
||||
static void
|
||||
write_1_short (opcode, insn)
|
||||
write_1_short (opcode, insn, fx)
|
||||
struct d10v_opcode *opcode;
|
||||
unsigned long insn;
|
||||
Fixups *fx;
|
||||
{
|
||||
char *f = frag_more(4);
|
||||
int i;
|
||||
|
||||
insn |= FM00 | (NOP << 15);
|
||||
/* printf("INSN: %08x\n",insn); */
|
||||
/* printf("INSN: %08x\n",insn); */
|
||||
number_to_chars_bigendian (f, insn, 4);
|
||||
for (i=0; i<fc; i++)
|
||||
for (i=0; i < fx->fc; i++)
|
||||
{
|
||||
if (get_reloc((struct d10v_operand *)&d10v_operands[fixups[i].reloc]))
|
||||
if (get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].reloc]))
|
||||
{
|
||||
/*
|
||||
printf("fix_new_exp: where:%x size:4\n ",f - frag_now->fr_literal);
|
||||
print_expr_1(stdout,&fixups[i].exp);
|
||||
print_expr_1(stdout,&(fx->fix[i].exp));
|
||||
printf("\n");
|
||||
*/
|
||||
|
||||
fix_new_exp (frag_now,
|
||||
f - frag_now->fr_literal,
|
||||
4,
|
||||
&fixups[i].exp,
|
||||
&(fx->fix[i].exp),
|
||||
1,
|
||||
fixups[i].reloc);
|
||||
fx->fix[i].reloc);
|
||||
}
|
||||
}
|
||||
fx->fc = 0;
|
||||
}
|
||||
|
||||
/* write out a short form instruction if possible */
|
||||
/* return number of instructions not written out */
|
||||
static int
|
||||
write_2_short (opcode1, insn1, opcode2, insn2, exec_type)
|
||||
write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
|
||||
struct d10v_opcode *opcode1, *opcode2;
|
||||
unsigned long insn1, insn2;
|
||||
int exec_type;
|
||||
Fixups *fx;
|
||||
{
|
||||
unsigned long insn;
|
||||
char *f;
|
||||
int i,j;
|
||||
|
||||
if(opcode1->exec_type == BRANCH_LINK)
|
||||
{
|
||||
/* subroutines must be called from 32-bit boundaries */
|
||||
/* so the return address will be correct */
|
||||
write_1_short (opcode1, insn1);
|
||||
write_1_short (opcode1, insn1, fx->next);
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -549,18 +529,22 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type)
|
||||
case 0:
|
||||
if (opcode1->unit == IU)
|
||||
{
|
||||
/* reverse sequential */
|
||||
insn = FM10 | (insn2 << 15) | insn1;
|
||||
}
|
||||
else
|
||||
{
|
||||
insn = FM01 | (insn1 << 15) | insn2;
|
||||
insn = FM01 | (insn1 << 15) | insn2;
|
||||
fx = fx->next;
|
||||
}
|
||||
break;
|
||||
case 1: /* parallel */
|
||||
insn = FM00 | (insn1 << 15) | insn2;
|
||||
fx = fx->next;
|
||||
break;
|
||||
case 2: /* sequential */
|
||||
insn = FM01 | (insn1 << 15) | insn2;
|
||||
fx = fx->next;
|
||||
break;
|
||||
case 3: /* reverse sequential */
|
||||
insn = FM10 | (insn1 << 15) | insn2;
|
||||
@ -570,7 +554,37 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type)
|
||||
}
|
||||
|
||||
/* printf("INSN: %08x\n",insn); */
|
||||
number_to_chars_bigendian (frag_more(4), insn, 4);
|
||||
f = frag_more(4);
|
||||
number_to_chars_bigendian (f, insn, 4);
|
||||
|
||||
for (j=0; j<2; j++)
|
||||
{
|
||||
bfd_reloc_code_real_type reloc;
|
||||
for (i=0; i < fx->fc; i++)
|
||||
{
|
||||
reloc = get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].reloc]);
|
||||
if (reloc)
|
||||
{
|
||||
if ( (reloc == BFD_RELOC_D10V_10_PCREL_R) && (j == 0) )
|
||||
fx->fix[i].reloc |= 1024;
|
||||
|
||||
/*
|
||||
printf("fix_new_exp: where:%x reloc:%d\n ",f - frag_now->fr_literal,fx->fix[i].reloc);
|
||||
print_expr_1(stdout,&(fx->fix[i].exp));
|
||||
printf("\n");
|
||||
*/
|
||||
fix_new_exp (frag_now,
|
||||
f - frag_now->fr_literal,
|
||||
4,
|
||||
&(fx->fix[i].exp),
|
||||
1,
|
||||
fx->fix[i].reloc);
|
||||
}
|
||||
}
|
||||
fx->fc = 0;
|
||||
fx = fx->next;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -583,6 +597,8 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type)
|
||||
|
||||
static unsigned long prev_insn;
|
||||
static struct d10v_opcode *prev_opcode = 0;
|
||||
static subsegT prev_subseg;
|
||||
static segT prev_seg;
|
||||
|
||||
void
|
||||
md_assemble (str)
|
||||
@ -594,8 +610,7 @@ md_assemble (str)
|
||||
char *str2;
|
||||
|
||||
/* printf("md_assemble: str=%s\n",str); */
|
||||
fc = 0;
|
||||
|
||||
|
||||
/* look for the special multiple instruction seperators */
|
||||
str2 = strstr (str, "||");
|
||||
if (str2)
|
||||
@ -622,10 +637,11 @@ md_assemble (str)
|
||||
/* if two instructions are present and we already have one saved
|
||||
then first write it out */
|
||||
if (prev_opcode)
|
||||
write_1_short (prev_opcode, prev_insn);
|
||||
write_1_short (prev_opcode, prev_insn, fixups->next);
|
||||
|
||||
/* assemble first instruction and save it */
|
||||
prev_insn = do_assemble (str, &prev_opcode);
|
||||
fixups = fixups->next;
|
||||
str = str2 + 2;
|
||||
}
|
||||
|
||||
@ -638,15 +654,15 @@ md_assemble (str)
|
||||
as_fatal("Unable to mix instructions as specified");
|
||||
if (prev_opcode)
|
||||
{
|
||||
write_1_short (prev_opcode, prev_insn);
|
||||
write_1_short (prev_opcode, prev_insn, fixups->next);
|
||||
prev_opcode = NULL;
|
||||
}
|
||||
write_long (opcode, insn);
|
||||
write_long (opcode, insn, fixups);
|
||||
prev_opcode = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (prev_opcode && (write_2_short (prev_opcode, prev_insn, opcode, insn, t) == 0))
|
||||
if (prev_opcode && (write_2_short (prev_opcode, prev_insn, opcode, insn, t, fixups) == 0))
|
||||
{
|
||||
/* no instructions saved */
|
||||
prev_opcode = NULL;
|
||||
@ -658,6 +674,9 @@ md_assemble (str)
|
||||
/* save off last instruction so it may be packed on next pass */
|
||||
prev_opcode = opcode;
|
||||
prev_insn = insn;
|
||||
prev_seg = now_seg;
|
||||
prev_subseg = now_subseg;
|
||||
fixups = fixups->next;
|
||||
}
|
||||
}
|
||||
|
||||
@ -675,7 +694,7 @@ do_assemble (str, opcode)
|
||||
expressionS myops[6];
|
||||
unsigned long insn;
|
||||
|
||||
/* printf("do_assemble: str=%s\n",str);*/
|
||||
/* printf("do_assemble: str=%s\n",str); */
|
||||
|
||||
/* Drop leading whitespace */
|
||||
while (*str == ' ')
|
||||
@ -780,7 +799,9 @@ do_assemble (str, opcode)
|
||||
if (!(d10v_operands[(*opcode)->operands[i]].flags & OPERAND_REG))
|
||||
{
|
||||
myops[i].X_op = O_symbol;
|
||||
myops[i].X_add_symbol = symbol_find_or_make ((char *)myops[i].X_op_symbol);
|
||||
myops[i].X_add_number = 0;
|
||||
myops[i].X_op_symbol = NULL;
|
||||
/* FIXME create a fixup */
|
||||
}
|
||||
}
|
||||
@ -849,6 +870,7 @@ md_apply_fix3 (fixp, valuep, seg)
|
||||
char *where;
|
||||
unsigned long insn;
|
||||
int op_type;
|
||||
int left=0;
|
||||
|
||||
if (fixp->fx_addsy == (symbolS *) NULL)
|
||||
{
|
||||
@ -873,20 +895,25 @@ md_apply_fix3 (fixp, valuep, seg)
|
||||
}
|
||||
}
|
||||
|
||||
/* printf("md_apply_fix: value=0x%x type=%d\n", value, fixp->fx_r_type); */
|
||||
/* printf("md_apply_fix: value=0x%x type=%d\n", value, fixp->fx_r_type); */
|
||||
|
||||
op_type = fixp->fx_r_type;
|
||||
fixp->fx_r_type = get_reloc((struct d10v_operand *)&d10v_operands[op_type]);
|
||||
|
||||
/* printf("reloc=%d\n",fixp->fx_r_type); */
|
||||
if (op_type & 1024)
|
||||
{
|
||||
op_type -= 1024;
|
||||
fixp->fx_r_type = BFD_RELOC_D10V_10_PCREL_L;
|
||||
left = 1;
|
||||
}
|
||||
else
|
||||
fixp->fx_r_type = get_reloc((struct d10v_operand *)&d10v_operands[op_type]);
|
||||
|
||||
/* Fetch the instruction, insert the fully resolved operand
|
||||
value, and stuff the instruction back again. */
|
||||
where = fixp->fx_frag->fr_literal + fixp->fx_where;
|
||||
insn = bfd_getb32 ((unsigned char *) where);
|
||||
/* printf(" insn=%x value=%x\n",insn,value); */
|
||||
/* printf(" insn=%x value=%x\n",insn,value); */
|
||||
|
||||
insn = d10v_insert_operand (insn, op_type, (offsetT) value);
|
||||
insn = d10v_insert_operand (insn, op_type, (offsetT) value, left);
|
||||
|
||||
/* printf(" new insn=%x\n",insn); */
|
||||
|
||||
@ -899,29 +926,24 @@ md_apply_fix3 (fixp, valuep, seg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This is called after the assembler has finished parsing the input
|
||||
file. Because the D10V assembler sometimes saves short instructions
|
||||
to see if it can package them with the next instruction, there may
|
||||
|
||||
/* d10v_cleanup() is called after the assembler has finished parsing the input
|
||||
file or after a label is defined. Because the D10V assembler sometimes saves short
|
||||
instructions to see if it can package them with the next instruction, there may
|
||||
be a short instruction that still needs written. */
|
||||
|
||||
int md_after_pass()
|
||||
{
|
||||
if (prev_opcode)
|
||||
{
|
||||
write_1_short (prev_opcode, prev_insn);
|
||||
prev_opcode = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* there is a label to be defined. Any saved instruction must
|
||||
be written out. */
|
||||
int
|
||||
start_label()
|
||||
d10v_cleanup()
|
||||
{
|
||||
segT seg;
|
||||
subsegT subseg;
|
||||
|
||||
if (prev_opcode)
|
||||
{
|
||||
write_1_short (prev_opcode, prev_insn);
|
||||
seg = now_seg;
|
||||
subseg = now_subseg;
|
||||
subseg_set (prev_seg, prev_subseg);
|
||||
write_1_short (prev_opcode, prev_insn, fixups);
|
||||
subseg_set (seg, subseg);
|
||||
prev_opcode = NULL;
|
||||
}
|
||||
return 1;
|
||||
|
@ -46,12 +46,10 @@
|
||||
/* We don't need to handle .word strangely. */
|
||||
#define WORKING_DOT_WORD
|
||||
|
||||
|
||||
#define md_number_to_chars number_to_chars_bigendian
|
||||
|
||||
#define md_after_pass_hook md_after_pass
|
||||
|
||||
extern int start_label PARAMS ((void));
|
||||
#define TC_START_LABEL(ch, ptr) (ch == ':' && start_label())
|
||||
int d10v_cleanup PARAMS ((void));
|
||||
#define md_after_pass_hook() d10v_cleanup()
|
||||
#define TC_START_LABEL(ch, ptr) (ch == ':' && d10v_cleanup())
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user