static unsigned int avr_operand (struct avr_opcodes_s *opcode,
int where, char *op, char **line);
static unsigned int avr_operands (struct avr_opcodes_s *opcode, char **line);
-static unsigned int avr_get_constant (char * str, unsigned int max);
+static unsigned int avr_get_constant (char * str, int max);
static char *parse_exp (char *s, expressionS * op);
static bfd_reloc_code_real_type avr_ldi_expression (expressionS *exp);
long md_pcrel_from_section PARAMS ((fixS *, segT));
int
md_estimate_size_before_relax (fragp, seg)
- fragS *fragp;
- asection *seg;
+ fragS *fragp ATTRIBUTE_UNUSED;
+ asection *seg ATTRIBUTE_UNUSED;
{
abort ();
return 0;
static void
avr_set_arch (dummy)
- int dummy;
+ int dummy ATTRIBUTE_UNUSED;
{
char * str;
str = (char *)alloca (20);
symbolS *
md_undefined_symbol(name)
- char *name;
+ char *name ATTRIBUTE_UNUSED;
{
return 0;
}
void
md_convert_frag (abfd, sec, fragP)
- bfd *abfd;
- asection *sec;
- fragS *fragP;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *sec ATTRIBUTE_UNUSED;
+ fragS *fragP ATTRIBUTE_UNUSED;
{
abort ();
}
void
md_begin ()
{
- int i;
+ unsigned int i;
struct avr_opcodes_s *opcode;
avr_hash = hash_new();
for (i = 0; i < sizeof (exp_mod) / sizeof (exp_mod[0]); ++i)
hash_insert (avr_mod_hash, EXP_MOD_NAME(i), (void*)(i+10));
-
- /* Construct symbols for each register */
- /* FIXME: register names are in the same namespace as labels.
- This means that C functions or global variables with the same
- name as a register will cause assembler errors, even though
- such names (r0-r31) are perfectly valid in C. I'd suggest to
- put '%' or "." in front of register names both here and in avr-gcc. */
-
- for (i = 0; i < 32; i++)
- {
- char buf[10];
-
- sprintf (buf, "r%d", i);
- symbol_table_insert (symbol_new (buf, reg_section, i,
- &zero_address_frag));
- sprintf (buf, "R%d", i);
- symbol_table_insert (symbol_new (buf, reg_section, i,
- &zero_address_frag));
- }
bfd_set_arch_mach (stdoutput, TARGET_ARCH, avr_mcu->mach);
}
+/* Resolve STR as a constant expression and return the result.
+ If result greater than MAX then error. */
+
+static unsigned int
+avr_get_constant (str, max)
+ char * str;
+ int max;
+{
+ expressionS ex;
+ str = skip_space (str);
+ input_line_pointer = str;
+ expression (&ex);
+
+ if (ex.X_op != O_constant)
+ as_bad (_("constant value required"));
+
+ if (ex.X_add_number > max || ex.X_add_number < 0)
+ as_bad (_("number must be less than %d"), max+1);
+ return ex.X_add_number;
+}
+
+
+/* Parse instruction operands.
+ Returns binary opcode. */
+
static unsigned int
avr_operands (opcode, line)
struct avr_opcodes_s *opcode;
return bin;
}
-static unsigned int
-avr_get_constant (str, max)
- char * str;
- unsigned int max;
-{
- expressionS ex;
- str = skip_space (str);
- input_line_pointer = str;
- expression (&ex);
-
- if (ex.X_op != O_constant)
- as_bad (_("constant value required"));
-
- if (ex.X_add_number > max)
- as_bad (_("number must be less than %d"), max+1);
- return ex.X_add_number;
-}
+/* Parse one instruction operand.
+ Returns operand bitmask. Also fixups can be generated. */
+
static unsigned int
avr_operand (opcode, where, op, line)
struct avr_opcodes_s *opcode;
char *op;
char **line;
{
- unsigned int op_mask = 0;
- char *str = *line;
expressionS op_expr;
+ unsigned int op_mask = 0;
+ char *str = skip_space (*line);
- str = skip_space (str);
switch (*op)
{
/* Any register operand. */
case 'a':
case 'v':
{
- char r_name[256];
op_mask = -1;
- str = extract_word (str, r_name, sizeof (r_name));
- if (r_name[0] == 'r' || r_name[0] == 'R')
- {
+ if (*str == 'r' || *str == 'R')
+ {
+ char r_name[20];
+
+ str = extract_word (str, r_name, sizeof (r_name));
if (isdigit(r_name[1]))
{
if (r_name[2] == '\0')
}
else
{
- parse_exp (r_name, &op_expr);
- if (op_expr.X_op == O_register)
- op_mask = op_expr.X_add_number;
+ op_mask = avr_get_constant (str, 31);
+ str = input_line_pointer;
}
- if (op_mask <= 31 && op_mask >= 0)
+ if (op_mask <= 31)
{
switch (*op)
{
}
break;
}
- as_bad (_ ("register required"));
+ as_bad (_ ("register name or number from 0 to 31 required"));
}
break;
arelent *
tc_gen_reloc (seg, fixp)
- asection *seg;
+ asection *seg ATTRIBUTE_UNUSED;
fixS *fixp;
{
arelent *reloc;
struct avr_opcodes_s * opcode;
char op[11];
- str = extract_word (str, op, sizeof(op));
+ str = skip_space (extract_word (str, op, sizeof(op)));
if (!op[0])
as_bad (_ ("can't find opcode "));