-/* tc-h8500.c -- Assemble code for the Hitachi H8/500
- Copyright (C) 1993, 94, 95, 98, 2000 Free Software Foundation.
+/* tc-h8500.c -- Assemble code for the Renesas H8/500
+ Copyright 1993, 1994, 1995, 1998, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-/*
- Written By Steve Chamberlain
- sac@cygnus.com
- */
+/* Written By Steve Chamberlain <sac@cygnus.com>. */
#include <stdio.h>
#include "as.h"
#define DEFINE_TABLE
#define ASSEMBLER_TABLE
#include "opcodes/h8500-opc.h"
-#include <ctype.h>
+#include "safe-ctype.h"
const char comment_chars[] = "!";
const char line_separator_chars[] = ";";
Integer arg to pass to the function
*/
-void cons ();
-
const pseudo_typeS md_pseudo_table[] =
{
{"int", cons, 2},
#define WORD_F 32767
#define WORD_B 32768
-relax_typeS md_relax_table[C (END, 0)];
+relax_typeS md_relax_table[C (END, 0)] = {
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+
+ /* BRANCH */
+ { 0, 0, 0, 0 },
+ { BYTE_F, BYTE_B, 2, C (BRANCH, WORD_DISP) },
+ { WORD_F, WORD_B, 3, 0 },
+ { 0, 0, 3, 0 },
+
+ /* SCB_F */
+ { 0, 0, 0, 0 },
+ { BYTE_F, BYTE_B, 3, C (SCB_F, WORD_DISP) },
+ { WORD_F, WORD_B, 8, 0 },
+ { 0, 0, 8, 0 },
+
+ /* SCB_TST */
+ { 0, 0, 0, 0 },
+ { BYTE_F, BYTE_B, 3, C (SCB_TST, WORD_DISP) },
+ { WORD_F, WORD_B, 10, 0 },
+ { 0, 0, 10, 0 }
+
+};
static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
void
md_begin ()
{
- h8500_opcode_info *opcode;
+ const h8500_opcode_info *opcode;
char prev_buffer[100];
int idx = 0;
- register relax_typeS *table;
opcode_hash_control = hash_new ();
prev_buffer[0] = 0;
idx++;
}
}
-
- /* Initialize the relax table. We use a local variable to avoid
- warnings about modifying a supposedly const data structure. */
- table = (relax_typeS *) md_relax_table;
- table[C (BRANCH, BYTE_DISP)].rlx_forward = BYTE_F;
- table[C (BRANCH, BYTE_DISP)].rlx_backward = BYTE_B;
- table[C (BRANCH, BYTE_DISP)].rlx_length = 2;
- table[C (BRANCH, BYTE_DISP)].rlx_more = C (BRANCH, WORD_DISP);
-
- table[C (BRANCH, WORD_DISP)].rlx_forward = WORD_F;
- table[C (BRANCH, WORD_DISP)].rlx_backward = WORD_B;
- table[C (BRANCH, WORD_DISP)].rlx_length = 3;
- table[C (BRANCH, WORD_DISP)].rlx_more = 0;
-
- table[C (SCB_F, BYTE_DISP)].rlx_forward = BYTE_F;
- table[C (SCB_F, BYTE_DISP)].rlx_backward = BYTE_B;
- table[C (SCB_F, BYTE_DISP)].rlx_length = 3;
- table[C (SCB_F, BYTE_DISP)].rlx_more = C (SCB_F, WORD_DISP);
-
- table[C (SCB_F, WORD_DISP)].rlx_forward = WORD_F;
- table[C (SCB_F, WORD_DISP)].rlx_backward = WORD_B;
- table[C (SCB_F, WORD_DISP)].rlx_length = 8;
- table[C (SCB_F, WORD_DISP)].rlx_more = 0;
-
- table[C (SCB_TST, BYTE_DISP)].rlx_forward = BYTE_F;
- table[C (SCB_TST, BYTE_DISP)].rlx_backward = BYTE_B;
- table[C (SCB_TST, BYTE_DISP)].rlx_length = 3;
- table[C (SCB_TST, BYTE_DISP)].rlx_more = C (SCB_TST, WORD_DISP);
-
- table[C (SCB_TST, WORD_DISP)].rlx_forward = WORD_F;
- table[C (SCB_TST, WORD_DISP)].rlx_backward = WORD_B;
- table[C (SCB_TST, WORD_DISP)].rlx_length = 10;
- table[C (SCB_TST, WORD_DISP)].rlx_more = 0;
-
}
static int rn; /* register number used by RN */
static int cr; /* unknown size cr */
static expressionS displacement;/* displacement expression */
-static int displacement_size; /* and size if given */
static int immediate_inpage;
static expressionS immediate; /* immediate expression */
-static int immediate_size; /* and size if given */
static expressionS absolute; /* absolute expression */
-static int absolute_size; /* and size if given */
typedef struct
{
/* Try to parse a reg name. Return the number of chars consumed. */
+static int parse_reg PARAMS ((char *, int *, int *));
+
static int
parse_reg (src, mode, reg)
char *src;
return 0;
}
+static char *parse_exp PARAMS ((char *, expressionS *, int *));
+
static char *
parse_exp (s, op, page)
char *s;
exp_signed, exp_unsigned, exp_sandu
} sign_type;
+static char *skip_colonthing
+ PARAMS ((sign_type, char *, h8500_operand_info *, int, int, int, int));
static char *
skip_colonthing (sign, ptr, exp, def, size8, size16, size24)
ptr++;
exp->type = size8;
}
- else if (ptr[0] == '1' & ptr[1] == '6')
+ else if (ptr[0] == '1' && ptr[1] == '6')
{
ptr += 2;
exp->type = size16;
}
- else if (ptr[0] == '2' & ptr[1] == '4')
+ else if (ptr[0] == '2' && ptr[1] == '4')
{
if (!size24)
{
return ptr;
}
+static int parse_reglist PARAMS ((char *, h8500_operand_info *));
+
static int
parse_reglist (src, op)
char *src;
*/
+static void get_operand PARAMS ((char **, h8500_operand_info *, char));
+
static void
get_operand (ptr, op, ispage)
char **ptr;
}
}
+static char *get_operands
+ PARAMS ((h8500_opcode_info *, char *, h8500_operand_info *));
+
static char *
get_operands (info, args, operand)
h8500_opcode_info *info;
char *args;
h8500_operand_info *operand;
-
{
char *ptr = args;
int pcrel8; /* Set when we've seen a pcrel operand */
+static h8500_opcode_info *get_specific
+ PARAMS ((h8500_opcode_info *, h8500_operand_info *));
+
static h8500_opcode_info *
get_specific (opcode, operands)
h8500_opcode_info *opcode;
h8500_opcode_info *this_try = opcode;
int found = 0;
unsigned int noperands = opcode->nargs;
-
- unsigned int this_index = opcode->idx;
+ int this_index = opcode->idx;
while (this_index == opcode->idx && !found)
{
return 0;
}
-int
+static int check PARAMS ((expressionS *, int, int));
+
+static int
check (operand, low, high)
expressionS *operand;
int low;
return operand->X_add_number;
}
+static void insert PARAMS ((char *, int, expressionS *, int, int));
+
static void
insert (output, index, exp, reloc, pcrel)
char *output;
reloc);
}
-void
+static void build_relaxable_instruction
+ PARAMS ((h8500_opcode_info *, h8500_operand_info *));
+
+static void
build_relaxable_instruction (opcode, operand)
h8500_opcode_info *opcode;
- h8500_operand_info *operand;
+ h8500_operand_info *operand ATTRIBUTE_UNUSED;
{
/* All relaxable instructions start life as two bytes but can become
three bytes long if a lonely branch and up to 9 bytes if long
/* Now we know what sort of opcodes it is, let's build the bytes. */
+static void build_bytes PARAMS ((h8500_opcode_info *, h8500_operand_info *));
+
static void
build_bytes (opcode, operand)
h8500_opcode_info *opcode;
h8500_operand_info *operand;
-
{
int index;
void
tc_crawl_symbol_chain (headers)
- object_headers *headers;
+ object_headers *headers ATTRIBUTE_UNUSED;
{
printf (_("call to tc_crawl_symbol_chain \n"));
}
symbolS *
md_undefined_symbol (name)
- char *name;
+ char *name ATTRIBUTE_UNUSED;
{
return 0;
}
void
tc_headers_hook (headers)
- object_headers *headers;
+ object_headers *headers ATTRIBUTE_UNUSED;
{
printf (_("call to tc_headers_hook \n"));
}
LITTLENUM_TYPE words[MAX_LITTLENUMS];
LITTLENUM_TYPE *wordP;
char *t;
- char *atof_ieee ();
switch (type)
{
return 0;
}
\f
-CONST char *md_shortopts = "";
+const char *md_shortopts = "";
struct option md_longopts[] = {
{NULL, no_argument, NULL, 0}
};
int
md_parse_option (c, arg)
- int c;
- char *arg;
+ int c ATTRIBUTE_UNUSED;
+ char *arg ATTRIBUTE_UNUSED;
{
return 0;
}
void
md_show_usage (stream)
- FILE *stream;
+ FILE *stream ATTRIBUTE_UNUSED;
{
}
\f
-void
-tc_aout_fix_to_chars ()
-{
- printf (_("call to tc_aout_fix_to_chars \n"));
- abort ();
-}
+static void wordify_scb PARAMS ((char *, int *, int *));
static void
wordify_scb (buffer, disp_size, inst_size)
*buffer++ = 0x04; /* cmp #0xff:8, rn */
*buffer++ = 0xff;
*buffer++ = 0x70 | rn;
- *buffer++ = 0x36; /* bne ... */
+ *buffer++ = 0x36; /* bne ... */
*buffer++ = 0;
*buffer++ = 0;
}
void
md_convert_frag (headers, seg, fragP)
- object_headers *headers;
- segT seg;
+ object_headers *headers ATTRIBUTE_UNUSED;
+ segT seg ATTRIBUTE_UNUSED;
fragS *fragP;
{
int disp_size = 0;
R_H8500_PCREL16);
fragP->fr_fix += disp_size + inst_size;
- fragP->fr_var = 0;
return;
break;
default:
md_number_to_chars (buffer + inst_size, disp, disp_size);
fragP->fr_fix += disp_size + inst_size;
- fragP->fr_var = 0;
}
}
}
void
-md_apply_fix (fixP, val)
+md_apply_fix3 (fixP, valP, seg)
fixS *fixP;
- long val;
+ valueT * valP;
+ segT seg ATTRIBUTE_UNUSED;
{
+ long val = * (long *) valP;
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
if (fixP->fx_r_type == 0)
- {
- fixP->fx_r_type = fixP->fx_size == 4 ? R_H8500_IMM32 : R_H8500_IMM16;
- }
+ fixP->fx_r_type = fixP->fx_size == 4 ? R_H8500_IMM32 : R_H8500_IMM16;
switch (fixP->fx_r_type)
{
-
case R_H8500_IMM8:
case R_H8500_PCREL8:
*buf++ = val;
break;
default:
abort ();
-
}
+
+ if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
+ fixP->fx_done = 1;
}
-/*
-called just before address relaxation, return the length
-by which a fragment must grow to reach it's destination
-*/
+/* Called just before address relaxation, return the length
+ by which a fragment must grow to reach it's destination. */
+
int
md_estimate_size_before_relax (fragP, segment_type)
register fragS *fragP;
register segT segment_type;
{
- int what = GET_WHAT (fragP->fr_subtype);
+ int what;
switch (fragP->fr_subtype)
{
default:
abort ();
+
case C (BRANCH, UNDEF_BYTE_DISP):
case C (SCB_F, UNDEF_BYTE_DISP):
case C (SCB_TST, UNDEF_BYTE_DISP):
+ what = GET_WHAT (fragP->fr_subtype);
/* used to be a branch to somewhere which was unknown */
if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
{
/* Got a symbol and it's defined in this segment, become byte
sized - maybe it will fix up. */
fragP->fr_subtype = C (what, BYTE_DISP);
- fragP->fr_var = md_relax_table[C (what, BYTE_DISP)].rlx_length;
}
else
{
/* Its got a segment, but its not ours, so it will always be
long. */
fragP->fr_subtype = C (what, UNDEF_WORD_DISP);
- fragP->fr_var = md_relax_table[C (what, WORD_DISP)].rlx_length;
- return md_relax_table[C (what, WORD_DISP)].rlx_length;
}
+ break;
+
+ case C (BRANCH, BYTE_DISP):
+ case C (BRANCH, WORD_DISP):
+ case C (BRANCH, UNDEF_WORD_DISP):
+ case C (SCB_F, BYTE_DISP):
+ case C (SCB_F, WORD_DISP):
+ case C (SCB_F, UNDEF_WORD_DISP):
+ case C (SCB_TST, BYTE_DISP):
+ case C (SCB_TST, WORD_DISP):
+ case C (SCB_TST, UNDEF_WORD_DISP):
+ /* When relaxing a section for the second time, we don't need to
+ do anything besides return the current size. */
+ break;
}
- return fragP->fr_var;
+
+ return md_relax_table[fragP->fr_subtype].rlx_length;
}
/* Put number into target byte order. */
void
tc_coff_symbol_emit_hook (ignore)
- symbolS *ignore;
+ symbolS *ignore ATTRIBUTE_UNUSED;
{
}
char *ptr;
{
/* Check for :s.w */
- if (isalpha (ptr[1]) && ptr[2] == '.')
+ if (ISALPHA (ptr[1]) && ptr[2] == '.')
return 0;
/* Check for :s */
- if (isalpha (ptr[1]) && !isalpha (ptr[2]))
+ if (ISALPHA (ptr[1]) && !ISALPHA (ptr[2]))
return 0;
return 1;
}