/* tc-crx.c -- Assembler code for the CRX CPU core.
- Copyright 2004 Free Software Foundation, Inc.
+ Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
Contributed by Tomer Levi, NSC, Israel.
Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
+ the Free Software Foundation; either version 3, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
static int get_opflags (operand_type);
static int get_number_of_operands (void);
static void parse_operand (char *, ins *);
-static int gettrap (char *);
-static void handle_LoadStor (char *);
-static int get_cinv_parameters (char *);
+static int gettrap (const char *);
+static void handle_LoadStor (const char *);
+static int get_cinv_parameters (const char *);
static long getconstant (long, int);
static op_err check_range (long *, int, unsigned int, int);
static int getreg_image (reg);
static reg
get_register (char *reg_name)
{
- const reg_entry *reg;
+ const reg_entry *rreg;
- reg = (const reg_entry *) hash_find (reg_hash, reg_name);
+ rreg = (const reg_entry *) hash_find (reg_hash, reg_name);
- if (reg != NULL)
- return reg->value.reg_val;
+ if (rreg != NULL)
+ return rreg->value.reg_val;
else
return nullregister;
}
static copreg
get_copregister (char *copreg_name)
{
- const reg_entry *copreg;
+ const reg_entry *coreg;
- copreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
+ coreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
- if (copreg != NULL)
- return copreg->value.copreg_val;
+ if (coreg != NULL)
+ return coreg->value.copreg_val;
else
return nullcopregister;
}
}
}
- assert ((int) fixP->fx_r_type > 0);
+ gas_assert ((int) fixP->fx_r_type > 0);
reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
if (reloc->howto == (reloc_howto_type *) NULL)
bfd_get_reloc_code_name (fixP->fx_r_type));
return NULL;
}
- assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
+ gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
return reloc;
}
return;
}
-/* Turn a string in input_line_pointer into a floating point constant
- of type TYPE, and store the appropriate bytes in *LITP. The number
- of LITTLENUMS emitted is stored in *SIZEP. An error message is
- returned, or NULL on OK. */
-
char *
md_atof (int type, char *litP, int *sizeP)
{
- int prec;
- LITTLENUM_TYPE words[4];
- char *t;
- int i;
-
- switch (type)
- {
- case 'f':
- prec = 2;
- break;
-
- case '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 * 2;
-
- if (! target_big_endian)
- {
- for (i = prec - 1; i >= 0; i--)
- {
- md_number_to_chars (litP, (valueT) words[i], 2);
- litP += 2;
- }
- }
- else
- {
- for (i = 0; i < prec; i++)
- {
- md_number_to_chars (litP, (valueT) words[i], 2);
- litP += 2;
- }
- }
-
- return NULL;
+ return ieee_md_atof (type, litP, sizeP, target_big_endian);
}
/* Apply a fixS (fixup of an instruction or data that we didn't have
const char *mnemonic = crx_instruction[i].mnemonic;
hashret = hash_insert (crx_inst_hash, mnemonic,
- (PTR) &crx_instruction[i]);
+ (void *) &crx_instruction[i]);
if (hashret != NULL && *hashret != '\0')
as_fatal (_("Can't hash `%s': %s\n"), crx_instruction[i].mnemonic,
for (regtab = crx_regtab;
regtab < (crx_regtab + NUMREGS); regtab++)
{
- hashret = hash_insert (reg_hash, regtab->name, (PTR) regtab);
+ hashret = hash_insert (reg_hash, regtab->name, (void *) regtab);
if (hashret)
as_fatal (_("Internal Error: Can't hash %s: %s"),
regtab->name,
for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
copregtab++)
{
- hashret = hash_insert (copreg_hash, copregtab->name, (PTR) copregtab);
+ hashret = hash_insert (copreg_hash, copregtab->name,
+ (void *) copregtab);
if (hashret)
as_fatal (_("Internal Error: Can't hash %s: %s"),
copregtab->name,
This routine is used by assembling the 'excp' instruction. */
static int
-gettrap (char *s)
+gettrap (const char *s)
{
const trap_entry *trap;
Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS. */
static void
-handle_LoadStor (char *operands)
+handle_LoadStor (const char *operands)
{
/* Post-Increment instructions precede Store-Immediate instructions in
CRX instruction table, hence they are handled before.
/* Cinv instruction requires special handling. */
static int
-get_cinv_parameters (char * operand)
+get_cinv_parameters (const char *operand)
{
- char *p = operand;
+ const char *p = operand;
int d_used = 0, i_used = 0, u_used = 0, b_used = 0;
while (*++p != ']')
static int
getreg_image (reg r)
{
- const reg_entry *reg;
+ const reg_entry *rreg;
char *reg_name;
int is_procreg = 0; /* Nonzero means argument should be processor reg. */
/* Check whether the register is in registers table. */
if (r < MAX_REG)
- reg = &crx_regtab[r];
+ rreg = &crx_regtab[r];
/* Check whether the register is in coprocessor registers table. */
- else if (r < MAX_COPREG)
- reg = &crx_copregtab[r-MAX_REG];
+ else if (r < (int) MAX_COPREG)
+ rreg = &crx_copregtab[r-MAX_REG];
/* Register not found. */
else
{
return 0;
}
- reg_name = reg->name;
+ reg_name = rreg->name;
/* Issue a error message when register is illegal. */
#define IMAGE_ERR \
reg_name, ins_parse); \
break;
- switch (reg->type)
+ switch (rreg->type)
{
case CRX_U_REGTYPE:
if (is_procreg || (instruction->flags & USER_REG))
- return reg->image;
+ return rreg->image;
else
IMAGE_ERR;
case CRX_CFG_REGTYPE:
if (is_procreg)
- return reg->image;
+ return rreg->image;
else
IMAGE_ERR;
case CRX_R_REGTYPE:
if (! is_procreg)
- return reg->image;
+ return rreg->image;
else
IMAGE_ERR;
case CRX_C_REGTYPE:
case CRX_CS_REGTYPE:
- return reg->image;
+ return rreg->image;
break;
default:
/* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
always filling the upper part of output_opcode[1]. If we mistakenly
write it to output_opcode[0], the constant prefix (that is, 'match')
- will be overriden.
+ will be overridden.
0 1 2 3
+---------+---------+---------+---------+
| 'match' | | X X X X | |
long upper_64kb = 0xFFFF0000;
long value = *num;
+ /* For hosts witah longs bigger than 32-bits make sure that the top
+ bits of a 32-bit negative value read in by the parser are set,
+ so that the correct comparisons are made. */
+ if (value & 0x80000000)
+ value |= (-1L << 31);
+
/* Verify operand value is even. */
if (flags & OP_EVEN)
{
if (instruction == NULL)
{
as_bad (_("Unknown opcode: `%s'"), op);
+ param[-1] = c;
return;
}
/* Assemble the instruction - return upon failure. */
if (assemble_insn (op, &crx_ins) == 0)
- return;
+ {
+ param[-1] = c;
+ return;
+ }
/* Print the instruction. */
+ param[-1] = c;
print_insn (&crx_ins);
}