Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Enumerations | Functions | Variables
tc-frv.c File Reference
#include "as.h"
#include "subsegs.h"
#include "symcat.h"
#include "opcodes/frv-desc.h"
#include "opcodes/frv-opc.h"
#include "cgen.h"
#include "libbfd.h"
#include "elf/common.h"
#include "elf/frv.h"

Go to the source code of this file.

Classes

struct  frv_insn
struct  vliw_insn_list
struct  vliw_chain

Defines

#define INSN_VALUE(buf)   (buf)
#define NOP_KEEP   1 /* Keep these NOPS. */
#define NOP_DELETE   2 /* Delete these NOPS. */
#define DO_COUNT   TRUE
#define DONT_COUNT   FALSE
#define DEFAULT_MACHINE   bfd_mach_fr500
#define DEFAULT_FLAGS   EF_FRV_CPU_FR500
#define DEFAULT_FDPIC   0
#define FRV_SHORTOPTS   "G:"
#define OPTION_GPR_32   (OPTION_MD_BASE)
#define OPTION_GPR_64   (OPTION_MD_BASE + 1)
#define OPTION_FPR_32   (OPTION_MD_BASE + 2)
#define OPTION_FPR_64   (OPTION_MD_BASE + 3)
#define OPTION_SOFT_FLOAT   (OPTION_MD_BASE + 4)
#define OPTION_DWORD_YES   (OPTION_MD_BASE + 5)
#define OPTION_DWORD_NO   (OPTION_MD_BASE + 6)
#define OPTION_DOUBLE   (OPTION_MD_BASE + 7)
#define OPTION_NO_DOUBLE   (OPTION_MD_BASE + 8)
#define OPTION_MEDIA   (OPTION_MD_BASE + 9)
#define OPTION_NO_MEDIA   (OPTION_MD_BASE + 10)
#define OPTION_CPU   (OPTION_MD_BASE + 11)
#define OPTION_PIC   (OPTION_MD_BASE + 12)
#define OPTION_BIGPIC   (OPTION_MD_BASE + 13)
#define OPTION_LIBPIC   (OPTION_MD_BASE + 14)
#define OPTION_MULADD   (OPTION_MD_BASE + 15)
#define OPTION_NO_MULADD   (OPTION_MD_BASE + 16)
#define OPTION_TOMCAT_DEBUG   (OPTION_MD_BASE + 17)
#define OPTION_TOMCAT_STATS   (OPTION_MD_BASE + 18)
#define OPTION_PACK   (OPTION_MD_BASE + 19)
#define OPTION_NO_PACK   (OPTION_MD_BASE + 20)
#define OPTION_FDPIC   (OPTION_MD_BASE + 21)
#define OPTION_NOPIC   (OPTION_MD_BASE + 22)
#define FRV_IS_NOP(insn)   (insn.buffer[0] == FRV_NOP_PACK || insn.buffer[0] == FRV_NOP_NOPACK)
#define FRV_NOP_PACK   0x00880000 /* ori.p gr0,0,gr0 */
#define FRV_NOP_NOPACK   0x80880000 /* ori gr0,0,gr0 */
#define FRV_SET_VLIW_WINDOW(VLIW1, VLIW2, VLIW3)
#define MAX_LITTLENUMS   6
#define DPRINTF1(A)
#define DPRINTF2(A, B)
#define DPRINTF3(A, B, C)

Enumerations

enum  vliw_insn_type {
  VLIW_GENERIC_TYPE, VLIW_BRANCH_TYPE, VLIW_LABEL_TYPE, VLIW_NOP_TYPE,
  VLIW_BRANCH_HAS_NOPS
}
enum  vliw_nop_type { VLIW_SINGLE_NOP, VLIW_DOUBLE_NOP, VLIW_DOUBLE_THEN_SINGLE_NOP }

Functions

static void frv_set_flags PARAMS ((int))
static void frv_frob_file_section PARAMS ((bfd *, asection *, PTR))
int md_parse_option (int c, char *arg)
void md_show_usage (FILE *stream)
void md_begin ()
bfd_boolean frv_md_fdpic_enabled (void)
struct vliw_insn_listfrv_insert_vliw_insn (bfd_boolean count)
static struct vliw_insn_list
*frv_find_in_vliw 
PARAMS ((enum vliw_insn_type, struct vliw_chain *, symbolS *))
static struct vliw_insn_listfrv_find_in_vliw (enum vliw_insn_type vliw_insn_type, struct vliw_chain *this_chain, symbolS *label_sym)
static void frv_debug_tomcat PARAMS ((struct vliw_chain *))
static void frv_debug_tomcat (struct vliw_chain *start_chain)
static void frv_adjust_vliw_count (struct vliw_chain *this_chain)
static struct vliw_chain
*frv_tomcat_shuffle 
PARAMS ((enum vliw_nop_type, struct vliw_chain *, struct vliw_insn_list *))
static struct vliw_chainfrv_tomcat_shuffle (enum vliw_nop_type this_nop_type, struct vliw_chain *vliw_to_split, struct vliw_insn_list *insert_before_insn)
static void
frv_tomcat_analyze_vliw_chains 
PARAMS ((void))
static void frv_tomcat_analyze_vliw_chains ()
void frv_tomcat_workaround ()
static int fr550_check_insn_acc_range (frv_insn *insn, int low, int hi)
static int fr550_check_acc_range (FRV_VLIW *vliw, frv_insn *insn)
static bfd_boolean target_implements_insn_p (const CGEN_INSN *insn)
void md_assemble (char *str)
void md_operand (expressionS *expressionP)
valueT md_section_align (segT segment, valueT size)
symbolS * md_undefined_symbol (name)
long frv_relax_frag (fragP, stretch)
int md_estimate_size_before_relax (fragS *fragP, segment)
void md_convert_frag (abfd, sec, fragS *fragP)
long md_pcrel_from_section (fixS *fixP, segT sec)
bfd_reloc_code_real_type md_cgen_lookup_reloc (insn, const CGEN_OPERAND *operand, fixS *fixP) const
int frv_force_relocation (fixS *fix)
void md_apply_fix (fixS *fixP, valueT *valP, segT seg)
void frv_md_number_to_chars (char *buf, valueT val, int n)
char * md_atof (char type, char *litP, int *sizeP)
bfd_boolean frv_fix_adjustable (fixS *fixP)
void frv_set_flags (arg)
void frv_pic_ptr (int nbytes)
static void frv_frob_file_section (bfd *abfd, asection *sec, ptr)
void frv_frob_file ()
void frv_frob_label (symbolS *this_label)
fixS * frv_cgen_record_fixup_exp (fragS *frag, int where, const CGEN_INSN *insn, int length, const CGEN_OPERAND *operand, int opinfo, expressionS *exp)

Variables

static struct vliw_insn_list
static struct vliw_chainvliw_chain_top
static struct vliw_chaincurrent_vliw_chain
static struct vliw_chainprevious_vliw_chain
static struct vliw_insn_listcurrent_vliw_insn
const char comment_chars [] = ";"
const char line_comment_chars [] = "#"
const char line_separator_chars [] = "!"
const char EXP_CHARS [] = "eE"
const char FLT_CHARS [] = "dD"
static FRV_VLIW vliw
static unsigned long frv_mach = bfd_mach_frv
static bfd_boolean fr400_audio
static flagword frv_flags = DEFAULT_FLAGS | DEFAULT_FDPIC
static int frv_user_set_flags_p = 0
static int frv_pic_p = 0
static const char * frv_pic_flag = "-mfdpic" : (const char *)0
static int tomcat_debug = 0
static int tomcat_stats = 0
static int tomcat_doubles = 0
static int tomcat_singles = 0
const pseudo_typeS md_pseudo_table []
const char * md_shortopts = FRV_SHORTOPTS
size_t md_longopts_size = sizeof (md_longopts)
static int g_switch_value = 8
int chain_num = 0
const relax_typeS md_relax_table []

Class Documentation

struct frv_insn

Definition at line 33 of file tc-frv.c.

Class Members
char * addr
unsigned char buffer
CGEN_FIELDS fields
fixS * fixups
fragS * frag
int indices
const CGEN_INSN * insn
int num_fixups
const CGEN_INSN * orig_insn
struct vliw_insn_list

Definition at line 72 of file tc-frv.c.

Collaboration diagram for vliw_insn_list:
Class Members
enum vliw_insn_type const
CGEN_INSN *insn symbolS *sym
fragS *snop_frag fragS
*dnop_frag char *address
struct vliw_insn_list *
next
struct vliw_chain

Definition at line 102 of file tc-frv.c.

Collaboration diagram for vliw_chain:
Class Members
int insn_count
struct vliw_insn_list * insn_list
struct vliw_chain * next
int num

Define Documentation

#define DEFAULT_FDPIC   0

Definition at line 167 of file tc-frv.c.

Definition at line 156 of file tc-frv.c.

Definition at line 155 of file tc-frv.c.

#define DO_COUNT   TRUE

Definition at line 68 of file tc-frv.c.

#define DONT_COUNT   FALSE

Definition at line 69 of file tc-frv.c.

#define DPRINTF1 (   A)

Definition at line 1737 of file tc-frv.c.

#define DPRINTF2 (   A,
  B 
)

Definition at line 1738 of file tc-frv.c.

#define DPRINTF3 (   A,
  B,
  C 
)

Definition at line 1739 of file tc-frv.c.

#define FRV_IS_NOP (   insn)    (insn.buffer[0] == FRV_NOP_PACK || insn.buffer[0] == FRV_NOP_NOPACK)

Definition at line 589 of file tc-frv.c.

#define FRV_NOP_NOPACK   0x80880000 /* ori gr0,0,gr0 */

Definition at line 591 of file tc-frv.c.

#define FRV_NOP_PACK   0x00880000 /* ori.p gr0,0,gr0 */

Definition at line 590 of file tc-frv.c.

#define FRV_SET_VLIW_WINDOW (   VLIW1,
  VLIW2,
  VLIW3 
)
Value:
if (VLIW1 && VLIW1->next)                  \
    VLIW2 = VLIW1->next;                   \
  else                                     \
    VLIW2 = NULL;                          \
  if (VLIW2 && VLIW2->next)                \
    VLIW3 = VLIW2->next;                   \
  else                                     \
    VLIW3 = NULL
#define FRV_SHORTOPTS   "G:"

Definition at line 203 of file tc-frv.c.

#define INSN_VALUE (   buf)    (buf)

Definition at line 43 of file tc-frv.c.

#define MAX_LITTLENUMS   6

Definition at line 1566 of file tc-frv.c.

#define NOP_DELETE   2 /* Delete these NOPS. */

Definition at line 66 of file tc-frv.c.

#define NOP_KEEP   1 /* Keep these NOPS. */

Definition at line 65 of file tc-frv.c.

#define OPTION_BIGPIC   (OPTION_MD_BASE + 13)

Definition at line 219 of file tc-frv.c.

#define OPTION_CPU   (OPTION_MD_BASE + 11)

Definition at line 217 of file tc-frv.c.

#define OPTION_DOUBLE   (OPTION_MD_BASE + 7)

Definition at line 213 of file tc-frv.c.

#define OPTION_DWORD_NO   (OPTION_MD_BASE + 6)

Definition at line 212 of file tc-frv.c.

#define OPTION_DWORD_YES   (OPTION_MD_BASE + 5)

Definition at line 211 of file tc-frv.c.

#define OPTION_FDPIC   (OPTION_MD_BASE + 21)

Definition at line 227 of file tc-frv.c.

#define OPTION_FPR_32   (OPTION_MD_BASE + 2)

Definition at line 208 of file tc-frv.c.

#define OPTION_FPR_64   (OPTION_MD_BASE + 3)

Definition at line 209 of file tc-frv.c.

#define OPTION_GPR_32   (OPTION_MD_BASE)

Definition at line 206 of file tc-frv.c.

#define OPTION_GPR_64   (OPTION_MD_BASE + 1)

Definition at line 207 of file tc-frv.c.

#define OPTION_LIBPIC   (OPTION_MD_BASE + 14)

Definition at line 220 of file tc-frv.c.

#define OPTION_MEDIA   (OPTION_MD_BASE + 9)

Definition at line 215 of file tc-frv.c.

#define OPTION_MULADD   (OPTION_MD_BASE + 15)

Definition at line 221 of file tc-frv.c.

#define OPTION_NO_DOUBLE   (OPTION_MD_BASE + 8)

Definition at line 214 of file tc-frv.c.

#define OPTION_NO_MEDIA   (OPTION_MD_BASE + 10)

Definition at line 216 of file tc-frv.c.

#define OPTION_NO_MULADD   (OPTION_MD_BASE + 16)

Definition at line 222 of file tc-frv.c.

#define OPTION_NO_PACK   (OPTION_MD_BASE + 20)

Definition at line 226 of file tc-frv.c.

#define OPTION_NOPIC   (OPTION_MD_BASE + 22)

Definition at line 228 of file tc-frv.c.

#define OPTION_PACK   (OPTION_MD_BASE + 19)

Definition at line 225 of file tc-frv.c.

#define OPTION_PIC   (OPTION_MD_BASE + 12)

Definition at line 218 of file tc-frv.c.

#define OPTION_SOFT_FLOAT   (OPTION_MD_BASE + 4)

Definition at line 210 of file tc-frv.c.

#define OPTION_TOMCAT_DEBUG   (OPTION_MD_BASE + 17)

Definition at line 223 of file tc-frv.c.

#define OPTION_TOMCAT_STATS   (OPTION_MD_BASE + 18)

Definition at line 224 of file tc-frv.c.


Enumeration Type Documentation

Enumerator:
VLIW_GENERIC_TYPE 
VLIW_BRANCH_TYPE 
VLIW_LABEL_TYPE 
VLIW_NOP_TYPE 
VLIW_BRANCH_HAS_NOPS 

Definition at line 53 of file tc-frv.c.

{
  VLIW_GENERIC_TYPE,        /* Don't care about this insn.  */
  VLIW_BRANCH_TYPE,         /* A Branch.  */
  VLIW_LABEL_TYPE,          /* A Label.  */
  VLIW_NOP_TYPE,            /* A NOP.  */
  VLIW_BRANCH_HAS_NOPS             /* A Branch that requires NOPS.  */
};
Enumerator:
VLIW_SINGLE_NOP 
VLIW_DOUBLE_NOP 
VLIW_DOUBLE_THEN_SINGLE_NOP 

Definition at line 620 of file tc-frv.c.

{
  /* A Vliw insn containing a single nop insn.  */
  VLIW_SINGLE_NOP,
  
  /* A Vliw insn containing two nop insns.  */
  VLIW_DOUBLE_NOP,

  /* Two vliw insns.  The first containing two nop insns.  
     The second contain a single nop insn.  */
  VLIW_DOUBLE_THEN_SINGLE_NOP
};

Function Documentation

static int fr550_check_acc_range ( FRV_VLIW vliw,
frv_insn insn 
) [static]

Definition at line 1065 of file tc-frv.c.

{
  switch ((*vliw->current_vliw)[vliw->next_slot - 1])
    {
    case UNIT_FM0:
    case UNIT_FM2:
      return fr550_check_insn_acc_range (insn, 0, 3);
    case UNIT_FM1:
    case UNIT_FM3:
      return fr550_check_insn_acc_range (insn, 4, 7);
    default:
      break;
    }
  return 0; /* all is ok */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int fr550_check_insn_acc_range ( frv_insn insn,
int  low,
int  hi 
) [static]

Definition at line 995 of file tc-frv.c.

{
  int acc;
  switch (CGEN_INSN_NUM (insn->insn))
    {
    case FRV_INSN_MADDACCS:
    case FRV_INSN_MSUBACCS:
    case FRV_INSN_MDADDACCS:
    case FRV_INSN_MDSUBACCS:
    case FRV_INSN_MASACCS:
    case FRV_INSN_MDASACCS:
      acc = insn->fields.f_ACC40Si;
      if (acc < low || acc > hi)
       return 1; /* out of range */
      acc = insn->fields.f_ACC40Sk;
      if (acc < low || acc > hi)
       return 1; /* out of range */
      break;
    case FRV_INSN_MMULHS:
    case FRV_INSN_MMULHU:
    case FRV_INSN_MMULXHS:
    case FRV_INSN_MMULXHU:
    case FRV_INSN_CMMULHS:
    case FRV_INSN_CMMULHU:
    case FRV_INSN_MQMULHS:
    case FRV_INSN_MQMULHU:
    case FRV_INSN_MQMULXHS:
    case FRV_INSN_MQMULXHU:
    case FRV_INSN_CMQMULHS:
    case FRV_INSN_CMQMULHU:
    case FRV_INSN_MMACHS:
    case FRV_INSN_MMRDHS:
    case FRV_INSN_CMMACHS: 
    case FRV_INSN_MQMACHS:
    case FRV_INSN_CMQMACHS:
    case FRV_INSN_MQXMACHS:
    case FRV_INSN_MQXMACXHS:
    case FRV_INSN_MQMACXHS:
    case FRV_INSN_MCPXRS:
    case FRV_INSN_MCPXIS:
    case FRV_INSN_CMCPXRS:
    case FRV_INSN_CMCPXIS:
    case FRV_INSN_MQCPXRS:
    case FRV_INSN_MQCPXIS:
     acc = insn->fields.f_ACC40Sk;
      if (acc < low || acc > hi)
       return 1; /* out of range */
      break;
    case FRV_INSN_MMACHU:
    case FRV_INSN_MMRDHU:
    case FRV_INSN_CMMACHU:
    case FRV_INSN_MQMACHU:
    case FRV_INSN_CMQMACHU:
    case FRV_INSN_MCPXRU:
    case FRV_INSN_MCPXIU:
    case FRV_INSN_CMCPXRU:
    case FRV_INSN_CMCPXIU:
    case FRV_INSN_MQCPXRU:
    case FRV_INSN_MQCPXIU:
      acc = insn->fields.f_ACC40Uk;
      if (acc < low || acc > hi)
       return 1; /* out of range */
      break;
    default:
      break;
    }
  return 0; /* all is ok */
}

Here is the caller graph for this function:

static void frv_adjust_vliw_count ( struct vliw_chain this_chain) [static]

Definition at line 666 of file tc-frv.c.

{
  struct vliw_insn_list *this_insn;

  this_chain->insn_count = 0;

  for (this_insn = this_chain->insn_list;
       this_insn;
       this_insn = this_insn->next)
    {
      if (this_insn->type != VLIW_LABEL_TYPE)
       this_chain->insn_count++;
    }

}

Here is the caller graph for this function:

fixS* frv_cgen_record_fixup_exp ( fragS *  frag,
int  where,
const CGEN_INSN *  insn,
int  length,
const CGEN_OPERAND operand,
int  opinfo,
expressionS exp 
)

Definition at line 1916 of file tc-frv.c.

{
  fixS * fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
                                           operand, opinfo, exp);

  if (frv_mach == bfd_mach_frvtomcat
      && current_vliw_insn
      && current_vliw_insn->type == VLIW_BRANCH_TYPE
      && exp != NULL)
    current_vliw_insn->sym = exp->X_add_symbol;
    
  return fixP;
}

Here is the call graph for this function:

static void frv_debug_tomcat ( struct vliw_chain start_chain) [static]

Definition at line 636 of file tc-frv.c.

{
   struct vliw_chain *this_chain;
   struct vliw_insn_list *this_insn;
   int i = 1;

  for (this_chain = start_chain; this_chain; this_chain = this_chain->next, i++)
    {
      fprintf (stderr, "\nVliw Insn #%d, #insns: %d\n", i, this_chain->insn_count);

      for (this_insn = this_chain->insn_list; this_insn; this_insn = this_insn->next)
       {
         if (this_insn->type == VLIW_LABEL_TYPE)
           fprintf (stderr, "Label Value: %p\n", this_insn->sym);
         else if (this_insn->type == VLIW_BRANCH_TYPE)
           fprintf (stderr, "%s to %p\n", this_insn->insn->base->name, this_insn->sym);
         else if (this_insn->type == VLIW_BRANCH_HAS_NOPS)
           fprintf (stderr, "nop'd %s to %p\n", this_insn->insn->base->name, this_insn->sym);
         else if (this_insn->type == VLIW_NOP_TYPE)
           fprintf (stderr, "Nop\n");
         else
           fprintf (stderr, "      %s\n", this_insn->insn->base->name);
       }
   }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct vliw_insn_list* frv_find_in_vliw ( enum vliw_insn_type  vliw_insn_type,
struct vliw_chain this_chain,
symbolS *  label_sym 
) [static, read]

Definition at line 599 of file tc-frv.c.

{

  struct vliw_insn_list *the_insn;

  if (!this_chain)
    return NULL;

  for (the_insn = this_chain->insn_list; the_insn; the_insn = the_insn->next)
    {
      if (the_insn->type == vliw_insn_type
         && the_insn->sym == label_sym)
       return the_insn;
    }

  return NULL;
}

Here is the caller graph for this function:

bfd_boolean frv_fix_adjustable ( fixS *  fixP)

Definition at line 1618 of file tc-frv.c.

{
  bfd_reloc_code_real_type reloc_type;

  if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
    {
      const CGEN_INSN *insn = NULL;
      int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
      const CGEN_OPERAND *operand = cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);
      reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
    }
  else
    reloc_type = fixP->fx_r_type;

  /* We need the symbol name for the VTABLE entries */
  if (   reloc_type == BFD_RELOC_VTABLE_INHERIT
      || reloc_type == BFD_RELOC_VTABLE_ENTRY
      || reloc_type == BFD_RELOC_FRV_GPREL12
      || reloc_type == BFD_RELOC_FRV_GPRELU12)
    return 0;

  return 1;
}

Here is the call graph for this function:

int frv_force_relocation ( fixS *  fix)
void frv_frob_file ( )

Definition at line 1893 of file tc-frv.c.

Here is the call graph for this function:

static void frv_frob_file_section ( bfd abfd,
asection sec,
ptr   
) [static]

Definition at line 1748 of file tc-frv.c.

{
  segment_info_type *seginfo = seg_info (sec);
  fixS *fixp;
  CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
  flagword flags = bfd_get_section_flags (abfd, sec);

  /* Skip relocations in known sections (.ctors, .dtors, and .gcc_except_table)
     since we can fix those up by hand.  */
  int known_section_p = (sec->name
                      && sec->name[0] == '.'
                      && ((sec->name[1] == 'c'
                           && strcmp (sec->name, ".ctor") == 0)
                          || (sec->name[1] == 'd'
                             && strcmp (sec->name, ".dtor") == 0)
                          || (sec->name[1] == 'g'
                             && strcmp (sec->name, ".gcc_except_table") == 0)));

  DPRINTF3 ("\nFrv section %s%s\n", sec->name, (known_section_p) ? ", known section" : "");
  if ((flags & SEC_ALLOC) == 0)
    {
      DPRINTF1 ("\tSkipping non-loaded section\n");
      return;
    }

  for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
    {
      symbolS *s = fixp->fx_addsy;
      bfd_reloc_code_real_type reloc;
      int non_pic_p;
      int opindex;
      const CGEN_OPERAND *operand;
      const CGEN_INSN *insn = fixp->fx_cgen.insn;

      if (fixp->fx_done)
       {
         DPRINTF1 ("\tSkipping reloc that has already been done\n");
         continue;
       }

      if (fixp->fx_pcrel)
       {
         DPRINTF1 ("\tSkipping reloc that is PC relative\n");
         continue;
       }

      if (! s)
       {
         DPRINTF1 ("\tSkipping reloc without symbol\n");
         continue;
       }

      if (fixp->fx_r_type < BFD_RELOC_UNUSED)
       {
         opindex = -1;
         reloc = fixp->fx_r_type;
       }
      else
       {
         opindex = (int) fixp->fx_r_type - (int) BFD_RELOC_UNUSED;
         operand = cgen_operand_lookup_by_num (cd, opindex);
         reloc = md_cgen_lookup_reloc (insn, operand, fixp);
       }

      DPRINTF3 ("\treloc %s\t%s", bfd_get_reloc_code_name (reloc), S_GET_NAME (s));

      non_pic_p = 0;
      switch (reloc)
       {
       default:
         break;

       case BFD_RELOC_32:
         /* Skip relocations in known sections (.ctors, .dtors, and
            .gcc_except_table) since we can fix those up by hand.  Also
            skip forward references to constants.  Also skip a difference
            of two symbols, which still uses the BFD_RELOC_32 at this
            point.  */
         if (! known_section_p
             && S_GET_SEGMENT (s) != absolute_section
             && !fixp->fx_subsy
             && (flags & (SEC_READONLY | SEC_CODE)) == 0)
           {
             non_pic_p = 1;
           }
         break;

         /* FIXME -- should determine if any of the GP relocation really uses
            gr16 (which is not pic safe) or not.  Right now, assume if we
            aren't being compiled with -mpic, the usage is non pic safe, but
            is safe with -mpic.  */
       case BFD_RELOC_FRV_GPREL12:
       case BFD_RELOC_FRV_GPRELU12:
       case BFD_RELOC_FRV_GPREL32:
       case BFD_RELOC_FRV_GPRELHI:
       case BFD_RELOC_FRV_GPRELLO:
         non_pic_p = ! frv_pic_p;
         break;

       case BFD_RELOC_FRV_LO16:
       case BFD_RELOC_FRV_HI16:
         if (S_GET_SEGMENT (s) != absolute_section)
           non_pic_p = 1;
         break;

       case BFD_RELOC_VTABLE_INHERIT:
       case BFD_RELOC_VTABLE_ENTRY:
         non_pic_p = 1;
         break;

         /* If this is a blessed BFD_RELOC_32, convert it back to the normal
             relocation.  */
       case BFD_RELOC_CTOR:
         fixp->fx_r_type = BFD_RELOC_32;
         break;
       }

      if (non_pic_p)
       {
         DPRINTF1 (" (Non-pic relocation)\n");
         if (frv_pic_p)
           as_warn_where (fixp->fx_file, fixp->fx_line,
                        _("Relocation %s is not safe for %s"),
                        bfd_get_reloc_code_name (reloc), frv_pic_flag);

         else if ((frv_flags & EF_FRV_NON_PIC_RELOCS) == 0)
           {
             frv_flags |= EF_FRV_NON_PIC_RELOCS;
             bfd_set_private_flags (abfd, frv_flags);
           }
       }
#ifdef DEBUG
      else
       DPRINTF1 ("\n");
#endif
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void frv_frob_label ( symbolS *  this_label)

Definition at line 1899 of file tc-frv.c.

{
  struct vliw_insn_list *vliw_insn_list_entry;

  if (frv_mach != bfd_mach_frvtomcat)
    return;

  if (now_seg != text_section)
    return;

  vliw_insn_list_entry = frv_insert_vliw_insn(DONT_COUNT);
  vliw_insn_list_entry->type = VLIW_LABEL_TYPE;
  vliw_insn_list_entry->sym  = this_label; 
}

Here is the call graph for this function:

Definition at line 525 of file tc-frv.c.

{
  struct vliw_insn_list *vliw_insn_list_entry;
  struct vliw_chain     *vliw_chain_entry;

  if (current_vliw_chain == NULL)
    {
      vliw_chain_entry = (struct vliw_chain *) xmalloc (sizeof (struct vliw_chain));
      vliw_chain_entry->insn_count = 0;
      vliw_chain_entry->insn_list  = NULL;
      vliw_chain_entry->next       = NULL;
      vliw_chain_entry->num        = chain_num++;

      if (!vliw_chain_top)
       vliw_chain_top = vliw_chain_entry;
      current_vliw_chain = vliw_chain_entry;
      if (previous_vliw_chain)
       previous_vliw_chain->next = vliw_chain_entry;
    }

  vliw_insn_list_entry = (struct vliw_insn_list *) xmalloc (sizeof (struct vliw_insn_list));
  vliw_insn_list_entry->type      = VLIW_GENERIC_TYPE;
  vliw_insn_list_entry->insn      = NULL;
  vliw_insn_list_entry->sym       = NULL;
  vliw_insn_list_entry->snop_frag = NULL;
  vliw_insn_list_entry->dnop_frag = NULL;
  vliw_insn_list_entry->next      = NULL;

  if (count)
    current_vliw_chain->insn_count++;

  if (current_vliw_insn)
    current_vliw_insn->next = vliw_insn_list_entry;
  current_vliw_insn = vliw_insn_list_entry;

  if (!current_vliw_chain->insn_list)
    current_vliw_chain->insn_list = current_vliw_insn;

  return vliw_insn_list_entry;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 515 of file tc-frv.c.

{
  return (frv_flags & EF_FRV_FDPIC) != 0;
}
void frv_md_number_to_chars ( char *  buf,
valueT  val,
int  n 
)

Definition at line 1552 of file tc-frv.c.

Here is the call graph for this function:

void frv_pic_ptr ( int  nbytes)

Definition at line 1668 of file tc-frv.c.

{
  expressionS exp;
  char *p;

  if (nbytes != 4)
    abort ();

#ifdef md_flush_pending_output
  md_flush_pending_output ();
#endif

  if (is_it_end_of_statement ())
    {
      demand_empty_rest_of_line ();
      return;
    }

#ifdef md_cons_align
  md_cons_align (nbytes);
#endif

  do
    {
      bfd_reloc_code_real_type reloc_type = BFD_RELOC_CTOR;
      
      if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0)
       {
         input_line_pointer += 9;
         expression (&exp);
         if (*input_line_pointer == ')')
           input_line_pointer++;
         else
           as_bad ("missing ')'");
         reloc_type = BFD_RELOC_FRV_FUNCDESC;
       }
      else if (strncasecmp (input_line_pointer, "tlsmoff(", 8) == 0)
       {
         input_line_pointer += 8;
         expression (&exp);
         if (*input_line_pointer == ')')
           input_line_pointer++;
         else
           as_bad ("missing ')'");
         reloc_type = BFD_RELOC_FRV_TLSMOFF;
       }
      else
       expression (&exp);

      p = frag_more (4);
      memset (p, 0, 4);
      fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
                 reloc_type);
    }
  while (*input_line_pointer++ == ',');

  input_line_pointer--;                   /* Put terminator back into stream. */
  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

long frv_relax_frag ( fragP  ,
stretch   
)

Definition at line 1280 of file tc-frv.c.

{
  return 0;
}
void frv_set_flags ( arg  )

Definition at line 1645 of file tc-frv.c.

{
  flagword new_flags = get_absolute_expression ();
  flagword new_mask = ~ (flagword)0;

  frv_user_set_flags_p = 1;
  if (*input_line_pointer == ',')
    {
      ++input_line_pointer;
      new_mask = get_absolute_expression ();
    }

  frv_flags = (frv_flags & ~new_mask) | (new_flags & new_mask);
  bfd_set_private_flags (stdoutput, frv_flags);
}

Here is the call graph for this function:

static void frv_tomcat_analyze_vliw_chains ( ) [static]

Definition at line 860 of file tc-frv.c.

{
  struct vliw_chain *vliw1 = NULL;
  struct vliw_chain *vliw2 = NULL;
  struct vliw_chain *vliw3 = NULL;

  struct vliw_insn_list *this_insn = NULL;
  struct vliw_insn_list *temp_insn = NULL;

  /* We potentially need to look at three VLIW insns to determine if the
     workaround is required.  Set them up.  Ignore existing nops during analysis. */

#define FRV_SET_VLIW_WINDOW(VLIW1, VLIW2, VLIW3) \
  if (VLIW1 && VLIW1->next)                \
    VLIW2 = VLIW1->next;                   \
  else                                     \
    VLIW2 = NULL;                          \
  if (VLIW2 && VLIW2->next)                \
    VLIW3 = VLIW2->next;                   \
  else                                     \
    VLIW3 = NULL

  vliw1 = vliw_chain_top;

workaround_top:

  FRV_SET_VLIW_WINDOW (vliw1, vliw2, vliw3);

  if (!vliw1)
    return;

  if (vliw1->insn_count == 1)
    {
      /* check vliw1 for a label. */
      if (vliw1->insn_list->type == VLIW_LABEL_TYPE)
       {
         temp_insn = frv_find_in_vliw (VLIW_BRANCH_TYPE, vliw2, vliw1->insn_list->sym);
         if (temp_insn)
           {
             vliw1 = frv_tomcat_shuffle (VLIW_DOUBLE_NOP, vliw2, vliw1->insn_list);
             temp_insn->dnop_frag->fr_subtype = NOP_KEEP;
             vliw1 = vliw1->next;
             if (tomcat_stats)
              tomcat_doubles++;
             goto workaround_top;
           }
         else if (vliw2 
                 && vliw2->insn_count == 1
                 && (temp_insn = frv_find_in_vliw (VLIW_BRANCH_TYPE, vliw3, vliw1->insn_list->sym)) != NULL)
           {
             temp_insn->snop_frag->fr_subtype = NOP_KEEP;
             vliw1 = frv_tomcat_shuffle (VLIW_SINGLE_NOP, vliw3, vliw3->insn_list);
             if (tomcat_stats)
              tomcat_singles++;
             goto workaround_top;
           }
       }
    }

  if (vliw1->insn_count == 2)
    {
      struct vliw_insn_list *this_insn;
 
      /* check vliw1 for a label. */
      for (this_insn = vliw1->insn_list; this_insn; this_insn = this_insn->next)
       {
         if (this_insn->type == VLIW_LABEL_TYPE)
           {
             if ((temp_insn = frv_find_in_vliw (VLIW_BRANCH_TYPE, vliw2, this_insn->sym)) != NULL)
              {
                temp_insn->snop_frag->fr_subtype = NOP_KEEP;
                vliw1 = frv_tomcat_shuffle (VLIW_SINGLE_NOP, vliw2, this_insn);
                if (tomcat_stats)
                  tomcat_singles++;
              }
             else
              vliw1 = vliw1->next;
              goto workaround_top;
            }
       }
    }
  /* Examine each insn in this VLIW.  Look for the workaround criteria.  */
  for (this_insn = vliw1->insn_list; this_insn; this_insn = this_insn->next)
    {
      /* Don't look at labels or nops.  */
      while (this_insn
            && (this_insn->type == VLIW_LABEL_TYPE
                 || this_insn->type == VLIW_NOP_TYPE
               || this_insn->type == VLIW_BRANCH_HAS_NOPS))
       this_insn = this_insn->next;

      if (!this_insn)
        {
         vliw1 = vliw2;
         goto workaround_top;
       }

      if (frv_is_branch_insn (this_insn->insn))
       {
         if ((temp_insn = frv_find_in_vliw (VLIW_LABEL_TYPE, vliw1, this_insn->sym)) != NULL)
           {
             /* Insert [nop/nop] [nop] before branch.  */
             this_insn->snop_frag->fr_subtype = NOP_KEEP;
             this_insn->dnop_frag->fr_subtype = NOP_KEEP;
             vliw1 = frv_tomcat_shuffle (VLIW_DOUBLE_THEN_SINGLE_NOP, vliw1, this_insn);
             goto workaround_top;
           }
       }


    }
  /* This vliw insn checks out okay.  Take a look at the next one.  */
  vliw1 = vliw1->next;
  goto workaround_top;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct vliw_chain* frv_tomcat_shuffle ( enum vliw_nop_type  this_nop_type,
struct vliw_chain vliw_to_split,
struct vliw_insn_list insert_before_insn 
) [static, read]

Definition at line 690 of file tc-frv.c.

{

  bfd_boolean pack_prev = FALSE;
  struct vliw_chain *return_me = NULL;
  struct vliw_insn_list *prev_insn = NULL;
  struct vliw_insn_list *curr_insn = vliw_to_split->insn_list;

  struct vliw_chain *double_nop = (struct vliw_chain *) xmalloc (sizeof (struct vliw_chain));
  struct vliw_chain *single_nop = (struct vliw_chain *) xmalloc (sizeof (struct vliw_chain));
  struct vliw_chain *second_part = (struct vliw_chain *) xmalloc (sizeof (struct vliw_chain));
  struct vliw_chain *curr_vliw = vliw_chain_top;
  struct vliw_chain *prev_vliw = NULL;

  while (curr_insn && curr_insn != insert_before_insn)
    {
      /* We can't set the packing bit on a label.  If we have the case
        label 1:
        label 2:
        label 3:
          branch that needs nops
       Then don't set pack bit later.  */

      if (curr_insn->type != VLIW_LABEL_TYPE)
       pack_prev = TRUE;
      prev_insn = curr_insn;
      curr_insn = curr_insn->next;
    } 

  while (curr_vliw && curr_vliw != vliw_to_split)
    {
      prev_vliw = curr_vliw;
      curr_vliw = curr_vliw->next;
    }

  switch (this_nop_type)
    {
    case VLIW_SINGLE_NOP:
      if (!prev_insn)
       {
       /* Branch is first,  Insert the NOP prior to this vliw insn.  */
       if (prev_vliw)
         prev_vliw->next = single_nop;
       else
         vliw_chain_top = single_nop;
       single_nop->next = vliw_to_split;
       vliw_to_split->insn_list->type = VLIW_BRANCH_HAS_NOPS;
       return_me = vliw_to_split;
       }
      else
       {
         /* Set the packing bit on the previous insn.  */
         if (pack_prev)
           {
             char *buffer = prev_insn->address;
             buffer[0] |= 0x80;
           }
         /* The branch is in the middle.  Split this vliw insn into first
            and second parts.  Insert the NOP inbetween.  */

          second_part->insn_list = insert_before_insn;
         second_part->insn_list->type = VLIW_BRANCH_HAS_NOPS;
          second_part->next      = vliw_to_split->next;
         frv_adjust_vliw_count (second_part);

          single_nop->next       = second_part;
 
          vliw_to_split->next    = single_nop;
          prev_insn->next        = NULL;
 
          return_me = second_part;
         frv_adjust_vliw_count (vliw_to_split);
       }
      break;

    case VLIW_DOUBLE_NOP:
      if (!prev_insn)
       {
       /* Branch is first,  Insert the NOP prior to this vliw insn.  */
        if (prev_vliw)
          prev_vliw->next = double_nop;
        else
          vliw_chain_top = double_nop;

       double_nop->next = vliw_to_split;
       return_me = vliw_to_split;
       vliw_to_split->insn_list->type = VLIW_BRANCH_HAS_NOPS;
       }
      else
       {
         /* Set the packing bit on the previous insn.  */
         if (pack_prev)
           {
             char *buffer = prev_insn->address;
             buffer[0] |= 0x80;
           }

       /* The branch is in the middle.  Split this vliw insn into first
          and second parts.  Insert the NOP inbetween.  */
          second_part->insn_list = insert_before_insn;
         second_part->insn_list->type = VLIW_BRANCH_HAS_NOPS;
          second_part->next      = vliw_to_split->next;
         frv_adjust_vliw_count (second_part);
 
          double_nop->next       = second_part;
 
          vliw_to_split->next    = single_nop;
          prev_insn->next        = NULL;
         frv_adjust_vliw_count (vliw_to_split);
 
          return_me = second_part;
       }
      break;

    case VLIW_DOUBLE_THEN_SINGLE_NOP:
      double_nop->next = single_nop;
      double_nop->insn_count = 2;
      double_nop->insn_list = &double_nop_insn;
      single_nop->insn_count = 1;
      single_nop->insn_list = &single_nop_insn;

      if (!prev_insn)
       {
         /* The branch is the first insn in this vliw.  Don't split the vliw.  Insert
            the nops prior to this vliw.  */
          if (prev_vliw)
            prev_vliw->next = double_nop;
          else
            vliw_chain_top = double_nop;
 
         single_nop->next = vliw_to_split;
         return_me = vliw_to_split;
         vliw_to_split->insn_list->type = VLIW_BRANCH_HAS_NOPS;
       }
      else
       {
         /* Set the packing bit on the previous insn.  */
         if (pack_prev)
           {
             char *buffer = prev_insn->address;
             buffer[0] |= 0x80;
           }

         /* The branch is in the middle of this vliw insn.  Split into first and
            second parts.  Insert the nop vliws in between.  */  
         second_part->insn_list = insert_before_insn;
         second_part->insn_list->type = VLIW_BRANCH_HAS_NOPS;
         second_part->next      = vliw_to_split->next;
         frv_adjust_vliw_count (second_part);

         single_nop->next       = second_part;

         vliw_to_split->next        = double_nop;
         prev_insn->next     = NULL;
         frv_adjust_vliw_count (vliw_to_split);

         return_me = second_part;
       }
      break;
    }

  return return_me;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 977 of file tc-frv.c.

{
  if (frv_mach != bfd_mach_frvtomcat)
    return;

  if (tomcat_debug)
    frv_debug_tomcat (vliw_chain_top);

  frv_tomcat_analyze_vliw_chains ();

  if (tomcat_stats)
    {
      fprintf (stderr, "Inserted %d Single Nops\n", tomcat_singles);
      fprintf (stderr, "Inserted %d Double Nops\n", tomcat_doubles);
    }
}

Here is the call graph for this function:

void md_apply_fix ( fixS *  fixP,
valueT valP,
segT seg   
)

Definition at line 1470 of file tc-frv.c.

{
  if (fixP->fx_addsy == 0)
    switch (fixP->fx_cgen.opinfo)
      {
      case BFD_RELOC_FRV_HI16:
       *valP >>= 16;
       /* Fall through.  */
      case BFD_RELOC_FRV_LO16:
       *valP &= 0xffff;
       break;

       /* We need relocations for these, even if their symbols reduce
          to constants.  */
      case BFD_RELOC_FRV_GPREL12:
      case BFD_RELOC_FRV_GPRELU12:
      case BFD_RELOC_FRV_GPREL32:
      case BFD_RELOC_FRV_GPRELHI:
      case BFD_RELOC_FRV_GPRELLO:
      case BFD_RELOC_FRV_GOT12:
      case BFD_RELOC_FRV_GOTHI:
      case BFD_RELOC_FRV_GOTLO:
      case BFD_RELOC_FRV_FUNCDESC_VALUE:
      case BFD_RELOC_FRV_FUNCDESC_GOTOFF12:
      case BFD_RELOC_FRV_FUNCDESC_GOTOFFHI:
      case BFD_RELOC_FRV_FUNCDESC_GOTOFFLO:
      case BFD_RELOC_FRV_GOTOFF12:
      case BFD_RELOC_FRV_GOTOFFHI:
      case BFD_RELOC_FRV_GOTOFFLO:
      case BFD_RELOC_FRV_GETTLSOFF:
      case BFD_RELOC_FRV_TLSDESC_VALUE:
      case BFD_RELOC_FRV_GOTTLSDESC12:
      case BFD_RELOC_FRV_GOTTLSDESCHI:
      case BFD_RELOC_FRV_GOTTLSDESCLO:
      case BFD_RELOC_FRV_TLSMOFF12:
      case BFD_RELOC_FRV_TLSMOFFHI:
      case BFD_RELOC_FRV_TLSMOFFLO:
      case BFD_RELOC_FRV_GOTTLSOFF12:
      case BFD_RELOC_FRV_GOTTLSOFFHI:
      case BFD_RELOC_FRV_GOTTLSOFFLO:
      case BFD_RELOC_FRV_TLSOFF:
      case BFD_RELOC_FRV_TLSDESC_RELAX:
      case BFD_RELOC_FRV_GETTLSOFF_RELAX:
      case BFD_RELOC_FRV_TLSOFF_RELAX:
       fixP->fx_addsy = expr_build_uconstant (0);
       break;
      }
  else
    switch (fixP->fx_cgen.opinfo)
      {
      case BFD_RELOC_FRV_GETTLSOFF:
      case BFD_RELOC_FRV_TLSDESC_VALUE:
      case BFD_RELOC_FRV_GOTTLSDESC12:
      case BFD_RELOC_FRV_GOTTLSDESCHI:
      case BFD_RELOC_FRV_GOTTLSDESCLO:
      case BFD_RELOC_FRV_TLSMOFF12:
      case BFD_RELOC_FRV_TLSMOFFHI:
      case BFD_RELOC_FRV_TLSMOFFLO:
      case BFD_RELOC_FRV_GOTTLSOFF12:
      case BFD_RELOC_FRV_GOTTLSOFFHI:
      case BFD_RELOC_FRV_GOTTLSOFFLO:
      case BFD_RELOC_FRV_TLSOFF:
      case BFD_RELOC_FRV_TLSDESC_RELAX:
      case BFD_RELOC_FRV_GETTLSOFF_RELAX:
      case BFD_RELOC_FRV_TLSOFF_RELAX:
       /* Mark TLS symbols as such.  */
       if (S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
         S_SET_THREAD_LOCAL (fixP->fx_addsy);
       break;
      }

  gas_cgen_md_apply_fix (fixP, valP, seg);
  return;
}

Here is the call graph for this function:

void md_assemble ( char *  str)

Definition at line 1112 of file tc-frv.c.

{
  frv_insn insn;
  char *errmsg;
  int packing_constraint;
  finished_insnS  finished_insn;
  fragS *double_nop_frag = NULL;
  fragS *single_nop_frag = NULL;
  struct vliw_insn_list *vliw_insn_list_entry = NULL;

  /* Initialize GAS's cgen interface for a new instruction.  */
  gas_cgen_init_parse ();

  memset (&insn, 0, sizeof (insn));

  insn.insn = frv_cgen_assemble_insn
    (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, &errmsg);
  
  if (!insn.insn)
    {
      as_bad (errmsg);
      return;
    }
  
  /* If the cpu is tomcat, then we need to insert nops to workaround
     hardware limitations.  We need to keep track of each vliw unit
     and examine the length of the unit and the individual insns
     within the unit to determine the number and location of the
     required nops.  */
  if (frv_mach == bfd_mach_frvtomcat)
    {
      /* If we've just finished a VLIW insn OR this is a branch,
        then start up a new frag.  Fill it with nops.  We will get rid
        of those that are not required after we've seen all of the 
        instructions but before we start resolving fixups.  */
      if ( !FRV_IS_NOP (insn)
         && (frv_is_branch_insn (insn.insn) || insn.fields.f_pack))
       {
         char *buffer;

         frag_wane (frag_now);
         frag_new (0);
         double_nop_frag = frag_now;
         buffer = frag_var (rs_machine_dependent, 8, 8, NOP_DELETE, NULL, 0, 0);
         md_number_to_chars (buffer, FRV_NOP_PACK, 4);
         md_number_to_chars (buffer+4, FRV_NOP_NOPACK, 4);

         frag_wane (frag_now);
         frag_new (0);
         single_nop_frag = frag_now;
         buffer = frag_var (rs_machine_dependent, 4, 4, NOP_DELETE, NULL, 0, 0);
         md_number_to_chars (buffer, FRV_NOP_NOPACK, 4);
       }

      vliw_insn_list_entry = frv_insert_vliw_insn (DO_COUNT);
      vliw_insn_list_entry->insn   = insn.insn;
      if (frv_is_branch_insn (insn.insn))
       vliw_insn_list_entry->type = VLIW_BRANCH_TYPE;

      if ( !FRV_IS_NOP (insn)
         && (frv_is_branch_insn (insn.insn) || insn.fields.f_pack))
       {
         vliw_insn_list_entry->snop_frag = single_nop_frag;
         vliw_insn_list_entry->dnop_frag = double_nop_frag;
       }
    }

  /* Make sure that this insn does not violate the VLIW packing constraints.  */
  /* -mno-pack disallows any packing whatsoever.  */
  if (frv_flags & EF_FRV_NOPACK)
    {
      if (! insn.fields.f_pack)
       {
         as_bad (_("VLIW packing used for -mno-pack"));
         return;
       }
    }
  /* -mcpu=FRV is an idealized FR-V implementation that supports all of the
     instructions, don't do vliw checking.  */
  else if (frv_mach != bfd_mach_frv)
    {
      if (!target_implements_insn_p (insn.insn))
       {
         as_bad (_("Instruction not supported by this architecture"));
         return;
       }
      packing_constraint = frv_vliw_add_insn (& vliw, insn.insn);
      if (frv_mach == bfd_mach_fr550 && ! packing_constraint)
       packing_constraint = fr550_check_acc_range (& vliw, & insn);
      if (insn.fields.f_pack)
       frv_vliw_reset (& vliw, frv_mach, frv_flags);
      if (packing_constraint)
       {
         as_bad (_("VLIW packing constraint violation"));
         return;
       }
    }

  /* Doesn't really matter what we pass for RELAX_P here.  */
  gas_cgen_finish_insn (insn.insn, insn.buffer,
                     CGEN_FIELDS_BITSIZE (& insn.fields), 1, &finished_insn);


  /* If the cpu is tomcat, then we need to insert nops to workaround
     hardware limitations.  We need to keep track of each vliw unit
     and examine the length of the unit and the individual insns
     within the unit to determine the number and location of the
     required nops.  */
  if (frv_mach == bfd_mach_frvtomcat)
    {
      if (vliw_insn_list_entry)
        vliw_insn_list_entry->address = finished_insn.addr;
      else
       abort();

      if (insn.fields.f_pack)
       {
         /* We've completed a VLIW insn.  */
         previous_vliw_chain = current_vliw_chain;
         current_vliw_chain = NULL;
         current_vliw_insn  = NULL;
        } 
    }
}

Here is the call graph for this function:

char* md_atof ( char type  ,
char *  litP,
int sizeP 
)

Definition at line 1569 of file tc-frv.c.

{
  int              i;
  int              prec;
  LITTLENUM_TYPE   words [MAX_LITTLENUMS];
  char *           t;

  switch (type)
    {
    case 'f':
    case 'F':
    case 's':
    case 'S':
      prec = 2;
      break;

    case 'd':
    case 'D':
    case 'r':
    case 'R':
      prec = 4;
      break;

   /* FIXME: Some targets allow other format chars for bigger sizes here.  */

    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 (i = 0; i < prec; i++)
    {
      md_number_to_chars (litP, (valueT) words[i],
                       sizeof (LITTLENUM_TYPE));
      litP += sizeof (LITTLENUM_TYPE);
    }
     
  return 0;
}

Here is the call graph for this function:

void md_begin ( void  )

Definition at line 487 of file tc-frv.c.

{
  /* Initialize the `cgen' interface.  */
  
  /* Set the machine number and endian.  */
  gas_cgen_cpu_desc = frv_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
                                    CGEN_CPU_OPEN_ENDIAN,
                                    CGEN_ENDIAN_BIG,
                                    CGEN_CPU_OPEN_END);
  frv_cgen_init_asm (gas_cgen_cpu_desc);

  /* This is a callback from cgen to gas to parse operands.  */
  cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);

  /* Set the ELF flags if desired. */
  if (frv_flags)
    bfd_set_private_flags (stdoutput, frv_flags);

  /* Set the machine type */
  bfd_default_set_arch_mach (stdoutput, bfd_arch_frv, frv_mach);

  /* Set up gp size so we can put local common items in .sbss */
  bfd_set_gp_size (stdoutput, g_switch_value);

  frv_vliw_reset (& vliw, frv_mach, frv_flags);
}

Here is the call graph for this function:

bfd_reloc_code_real_type md_cgen_lookup_reloc ( insn  ,
const CGEN_OPERAND operand,
fixS *  fixP 
) const

Definition at line 1369 of file tc-frv.c.

{
  switch (operand->type)
    {
    case FRV_OPERAND_LABEL16:
      fixP->fx_pcrel = TRUE;
      return BFD_RELOC_FRV_LABEL16;

    case FRV_OPERAND_LABEL24:
      fixP->fx_pcrel = TRUE;

      if (fixP->fx_cgen.opinfo != 0)
       return fixP->fx_cgen.opinfo;

      return BFD_RELOC_FRV_LABEL24;

    case FRV_OPERAND_UHI16:
    case FRV_OPERAND_ULO16:
    case FRV_OPERAND_SLO16:
    case FRV_OPERAND_CALLANN:
    case FRV_OPERAND_LDANN:
    case FRV_OPERAND_LDDANN:
      /* The relocation type should be recorded in opinfo */
      if (fixP->fx_cgen.opinfo != 0)
        return fixP->fx_cgen.opinfo;
      break;

    case FRV_OPERAND_D12:
    case FRV_OPERAND_S12:
      if (fixP->fx_cgen.opinfo != 0)
       return fixP->fx_cgen.opinfo;

      return BFD_RELOC_FRV_GPREL12;

    case FRV_OPERAND_U12:
      return BFD_RELOC_FRV_GPRELU12;

    default: 
      break;
    }
  return BFD_RELOC_NONE;
}
void md_convert_frag ( abfd  ,
sec  ,
fragS *  fragP 
)

Definition at line 1322 of file tc-frv.c.

{
  switch (fragP->fr_subtype)
    {
    default:
    case NOP_DELETE:
      return;

    case NOP_KEEP:
      fragP->fr_fix = fragP->fr_var;
      fragP->fr_var = 0;
      return;   
    }
}
int md_estimate_size_before_relax ( fragS *  fragP,
segment   
)

Definition at line 1299 of file tc-frv.c.

{
  switch (fragP->fr_subtype)
    {
    case NOP_KEEP:
      return fragP->fr_var;

    default:
    case NOP_DELETE:
      return 0;
    }     
} 
void md_operand ( expressionS expressionP)

Definition at line 1242 of file tc-frv.c.

{
  if (* input_line_pointer == '#')
    {
      input_line_pointer ++;
      expression (expressionP);
    }
}
int md_parse_option ( int c  ,
char *  arg 
)

Definition at line 265 of file tc-frv.c.

{
  switch (c)
    {
    default:
      return 0;

    case 'G':
      g_switch_value = atoi (arg);
      if (! g_switch_value)
       frv_flags |= EF_FRV_G0;
      break;

    case OPTION_GPR_32:
      frv_flags = (frv_flags & ~EF_FRV_GPR_MASK) | EF_FRV_GPR_32;
      break;

    case OPTION_GPR_64:
      frv_flags = (frv_flags & ~EF_FRV_GPR_MASK) | EF_FRV_GPR_64;
      break;

    case OPTION_FPR_32:
      frv_flags = (frv_flags & ~EF_FRV_FPR_MASK) | EF_FRV_FPR_32;
      break;

    case OPTION_FPR_64:
      frv_flags = (frv_flags & ~EF_FRV_FPR_MASK) | EF_FRV_FPR_64;
      break;

    case OPTION_SOFT_FLOAT:
      frv_flags = (frv_flags & ~EF_FRV_FPR_MASK) | EF_FRV_FPR_NONE;
      break;

    case OPTION_DWORD_YES:
      frv_flags = (frv_flags & ~EF_FRV_DWORD_MASK) | EF_FRV_DWORD_YES;
      break;

    case OPTION_DWORD_NO:
      frv_flags = (frv_flags & ~EF_FRV_DWORD_MASK) | EF_FRV_DWORD_NO;
      break;

    case OPTION_DOUBLE:
      frv_flags |= EF_FRV_DOUBLE;
      break;

    case OPTION_NO_DOUBLE:
      frv_flags &= ~EF_FRV_DOUBLE;
      break;

    case OPTION_MEDIA:
      frv_flags |= EF_FRV_MEDIA;
      break;

    case OPTION_NO_MEDIA:
      frv_flags &= ~EF_FRV_MEDIA;
      break;

    case OPTION_MULADD:
      frv_flags |= EF_FRV_MULADD;
      break;

    case OPTION_NO_MULADD:
      frv_flags &= ~EF_FRV_MULADD;
      break;

    case OPTION_PACK:
      frv_flags &= ~EF_FRV_NOPACK;
      break;

    case OPTION_NO_PACK:
      frv_flags |= EF_FRV_NOPACK;
      break;

    case OPTION_CPU:
      {
       char *p;
       int cpu_flags = EF_FRV_CPU_GENERIC;

       /* Identify the processor type */
       p = arg;
       if (strcmp (p, "frv") == 0)
         {
           cpu_flags = EF_FRV_CPU_GENERIC;
           frv_mach = bfd_mach_frv;
         }

       else if (strcmp (p, "fr500") == 0)
         {
           cpu_flags = EF_FRV_CPU_FR500;
           frv_mach = bfd_mach_fr500;
         }

       else if (strcmp (p, "fr550") == 0)
         {
           cpu_flags = EF_FRV_CPU_FR550;
           frv_mach = bfd_mach_fr550;
         }

       else if (strcmp (p, "fr450") == 0)
         {
           cpu_flags = EF_FRV_CPU_FR450;
           frv_mach = bfd_mach_fr450;
         }

       else if (strcmp (p, "fr405") == 0)
         {
           cpu_flags = EF_FRV_CPU_FR405;
           frv_mach = bfd_mach_fr400;
           fr400_audio = TRUE;
         }

       else if (strcmp (p, "fr400") == 0)
         {
           cpu_flags = EF_FRV_CPU_FR400;
           frv_mach = bfd_mach_fr400;
           fr400_audio = FALSE;
         }

       else if (strcmp (p, "fr300") == 0)
         {
           cpu_flags = EF_FRV_CPU_FR300;
           frv_mach = bfd_mach_fr300;
         }

       else if (strcmp (p, "simple") == 0)
         {
           cpu_flags = EF_FRV_CPU_SIMPLE;
           frv_mach = bfd_mach_frvsimple;
           frv_flags |= EF_FRV_NOPACK;
         }

        else if (strcmp (p, "tomcat") == 0)
          {
            cpu_flags = EF_FRV_CPU_TOMCAT;
            frv_mach = bfd_mach_frvtomcat;
          }

       else
         {
           as_fatal ("Unknown cpu -mcpu=%s", arg);
           return 0;
         }

       frv_flags = (frv_flags & ~EF_FRV_CPU_MASK) | cpu_flags;
      }
      break;

    case OPTION_PIC:
      frv_flags |= EF_FRV_PIC;
      frv_pic_p = 1;
      frv_pic_flag = "-fpic";
      break;

    case OPTION_BIGPIC:
      frv_flags |= EF_FRV_BIGPIC;
      frv_pic_p = 1;
      frv_pic_flag = "-fPIC";
      break;

    case OPTION_LIBPIC:
      frv_flags |= (EF_FRV_LIBPIC | EF_FRV_G0);
      frv_pic_p = 1;
      frv_pic_flag = "-mlibrary-pic";
      g_switch_value = 0;
      break;

    case OPTION_FDPIC:
      frv_flags |= EF_FRV_FDPIC;
      frv_pic_flag = "-mfdpic";
      break;

    case OPTION_NOPIC:
      frv_flags &= ~(EF_FRV_FDPIC | EF_FRV_PIC
                   | EF_FRV_BIGPIC | EF_FRV_LIBPIC);
      frv_pic_flag = 0;
      break;

    case OPTION_TOMCAT_DEBUG:
      tomcat_debug = 1;
      break;

    case OPTION_TOMCAT_STATS:
      tomcat_stats = 1;
      break;
    }

  return 1;
}

Here is the call graph for this function:

long md_pcrel_from_section ( fixS *  fixP,
segT sec   
)

Definition at line 1346 of file tc-frv.c.

{
  if (TC_FORCE_RELOCATION (fixP)
      || (fixP->fx_addsy != (symbolS *) NULL
         && S_GET_SEGMENT (fixP->fx_addsy) != sec))
    {
      /* If we can't adjust this relocation, or if it references a
        local symbol in a different section (which
        TC_FORCE_RELOCATION can't check), let the linker figure it
        out.  */
      return 0;
    }

  return (fixP->fx_frag->fr_address + fixP->fx_where) & ~1;
}

Here is the call graph for this function:

valueT md_section_align ( segT segment  ,
valueT size   
)

Definition at line 1253 of file tc-frv.c.

{
  int align = bfd_get_section_alignment (stdoutput, segment);
  return ((size + (1 << align) - 1) & (-1 << align));
}

Here is the call graph for this function:

void md_show_usage ( FILE *  stream)

Definition at line 457 of file tc-frv.c.

{
  fprintf (stream, _("FRV specific command line options:\n"));
  fprintf (stream, _("-G n         Data >= n bytes is in small data area\n"));
  fprintf (stream, _("-mgpr-32     Note 32 gprs are used\n"));
  fprintf (stream, _("-mgpr-64     Note 64 gprs are used\n"));
  fprintf (stream, _("-mfpr-32     Note 32 fprs are used\n"));
  fprintf (stream, _("-mfpr-64     Note 64 fprs are used\n"));
  fprintf (stream, _("-msoft-float Note software fp is used\n"));
  fprintf (stream, _("-mdword      Note stack is aligned to a 8 byte boundary\n"));
  fprintf (stream, _("-mno-dword   Note stack is aligned to a 4 byte boundary\n"));
  fprintf (stream, _("-mdouble     Note fp double insns are used\n"));
  fprintf (stream, _("-mmedia      Note media insns are used\n"));
  fprintf (stream, _("-mmuladd     Note multiply add/subtract insns are used\n"));
  fprintf (stream, _("-mpack       Note instructions are packed\n"));
  fprintf (stream, _("-mno-pack    Do not allow instructions to be packed\n"));
  fprintf (stream, _("-mpic        Note small position independent code\n"));
  fprintf (stream, _("-mPIC        Note large position independent code\n"));
  fprintf (stream, _("-mlibrary-pic Compile library for large position indepedent code\n"));
  fprintf (stream, _("-mfdpic      Assemble for the FDPIC ABI\n"));
  fprintf (stream, _("-mnopic      Disable -mpic, -mPIC, -mlibrary-pic and -mfdpic\n"));
  fprintf (stream, _("-mcpu={fr500|fr550|fr400|fr405|fr450|fr300|frv|simple|tomcat}\n"));
  fprintf (stream, _("             Record the cpu type\n"));
  fprintf (stream, _("-mtomcat-stats Print out stats for tomcat workarounds\n"));
  fprintf (stream, _("-mtomcat-debug Debug tomcat workarounds\n"));
} 

Here is the call graph for this function:

symbolS* md_undefined_symbol ( name  )

Definition at line 1262 of file tc-frv.c.

{
  return 0;
}
static void frv_set_flags PARAMS ( (int ) [static]
static void frv_frob_file_section PARAMS ( (bfd *, asection *, PTR ) [static]
static struct vliw_insn_list* frv_find_in_vliw PARAMS ( (enum vliw_insn_type, struct vliw_chain *, symbolS *)  ) [static, read]
static void frv_debug_tomcat PARAMS ( (struct vliw_chain *)  ) [static]
static void frv_tomcat_analyze_vliw_chains PARAMS ( (void)  ) [static]
static bfd_boolean target_implements_insn_p ( const CGEN_INSN *  insn) [static]

Definition at line 1084 of file tc-frv.c.

Here is the caller graph for this function:


Variable Documentation

Definition at line 520 of file tc-frv.c.

const char comment_chars[] = ";"

Definition at line 115 of file tc-frv.c.

Definition at line 111 of file tc-frv.c.

Definition at line 113 of file tc-frv.c.

const char EXP_CHARS[] = "eE"

Definition at line 118 of file tc-frv.c.

const char FLT_CHARS[] = "dD"

Definition at line 119 of file tc-frv.c.

Definition at line 171 of file tc-frv.c.

Definition at line 174 of file tc-frv.c.

Definition at line 170 of file tc-frv.c.

const char* frv_pic_flag = "-mfdpic" : (const char *)0 [static]

Definition at line 178 of file tc-frv.c.

int frv_pic_p = 0 [static]

Definition at line 177 of file tc-frv.c.

int frv_user_set_flags_p = 0 [static]

Definition at line 176 of file tc-frv.c.

int g_switch_value = 8 [static]

Definition at line 262 of file tc-frv.c.

const char line_comment_chars[] = "#"

Definition at line 116 of file tc-frv.c.

Definition at line 117 of file tc-frv.c.

size_t md_longopts_size = sizeof (md_longopts)

Definition at line 259 of file tc-frv.c.

const pseudo_typeS md_pseudo_table[]
Initial value:
{
  { "eflags", frv_set_flags,              0 },
  { "word",   cons,                4 },
  { "picptr", frv_pic_ptr,         4 },
  { NULL,     NULL,                0 }
}

Definition at line 194 of file tc-frv.c.

const relax_typeS md_relax_table[]
Initial value:
{
  {1, 1, 0, 0},
  {511 - 2 - 2, -512 - 2 + 2, 0, 2 },
  {0x2000000 - 1 - 2, -0x2000000 - 2, 2, 0 },
  {0x2000000 - 1 - 2, -0x2000000 - 2, 4, 0 }
}

Definition at line 1271 of file tc-frv.c.

Definition at line 204 of file tc-frv.c.

Definition at line 112 of file tc-frv.c.

int tomcat_debug = 0 [static]

Definition at line 181 of file tc-frv.c.

int tomcat_doubles = 0 [static]

Definition at line 185 of file tc-frv.c.

int tomcat_singles = 0 [static]

Definition at line 186 of file tc-frv.c.

int tomcat_stats = 0 [static]

Definition at line 184 of file tc-frv.c.

FRV_VLIW vliw [static]

Definition at line 121 of file tc-frv.c.

Definition at line 110 of file tc-frv.c.

static struct vliw_insn_list [static]
Initial value:
 {
   VLIW_NOP_TYPE, NULL, NULL, NULL, NULL, NULL, NULL }

Definition at line 96 of file tc-frv.c.