gas/
[deliverable/binutils-gdb.git] / gas / config / tc-ia64.c
index 5da30987bea461ee35af1a0947c0629e79b6ddc5..0740f911966aaed8c548f2d6ffc932195fe97da5 100644 (file)
@@ -124,7 +124,6 @@ enum reg_symbol
     IND_DTR,
     IND_ITR,
     IND_IBR,
-    IND_MEM,
     IND_MSR,
     IND_PKR,
     IND_PMC,
@@ -226,8 +225,6 @@ static struct
     struct hash_control *const_hash;   /* constant hash table */
     struct hash_control *entry_hash;    /* code entry hint hash table */
 
-    symbolS *regsym[REG_NUM];
-
     /* If X_op is != O_absent, the registername for the instruction's
        qualifying predicate.  If NULL, p0 is assumed for instructions
        that are predicatable.  */
@@ -329,6 +326,8 @@ static struct
 
     int pointer_size;       /* size in bytes of a pointer */
     int pointer_size_shift; /* shift size of a pointer for alignment */
+
+    symbolS *indregsym[IND_RR - IND_CPUID + 1];
   }
 md;
 
@@ -355,33 +354,52 @@ static unsigned char le_nop_stop[16] =
 #define AR_BSP         17
 #define AR_BSPSTORE    18
 #define AR_RNAT                19
+#define AR_FCR         21
+#define AR_EFLAG       24
+#define AR_CSD         25
+#define AR_SSD         26
+#define AR_CFLG                27
+#define AR_FSR         28
+#define AR_FIR         29
+#define AR_FDR         30
+#define AR_CCV         32
 #define AR_UNAT                36
 #define AR_FPSR                40
 #define AR_ITC         44
 #define AR_PFS         64
 #define AR_LC          65
+#define AR_EC          66
 
 static const struct
   {
     const char *name;
-    int regnum;
+    unsigned int regnum;
   }
 ar[] =
   {
-    {"ar.k0", 0}, {"ar.k1", 1}, {"ar.k2", 2}, {"ar.k3", 3},
-    {"ar.k4", 4}, {"ar.k5", 5}, {"ar.k6", 6}, {"ar.k7", 7},
-    {"ar.rsc",         16}, {"ar.bsp",         17},
-    {"ar.bspstore",    18}, {"ar.rnat",        19},
-    {"ar.fcr",         21}, {"ar.eflag",       24},
-    {"ar.csd",         25}, {"ar.ssd",         26},
-    {"ar.cflg",                27}, {"ar.fsr",         28},
-    {"ar.fir",         29}, {"ar.fdr",         30},
-    {"ar.ccv",         32}, {"ar.unat",        36},
-    {"ar.fpsr",                40}, {"ar.itc",         44},
-    {"ar.pfs",         64}, {"ar.lc",          65},
-    {"ar.ec",          66},
+    {"ar.k0",          AR_K0},         {"ar.k1",       AR_K0 + 1},
+    {"ar.k2",          AR_K0 + 2},     {"ar.k3",       AR_K0 + 3},
+    {"ar.k4",          AR_K0 + 4},     {"ar.k5",       AR_K0 + 5},
+    {"ar.k6",          AR_K0 + 6},     {"ar.k7",       AR_K7},
+    {"ar.rsc",         AR_RSC},        {"ar.bsp",      AR_BSP},
+    {"ar.bspstore",    AR_BSPSTORE},   {"ar.rnat",     AR_RNAT},
+    {"ar.fcr",         AR_FCR},        {"ar.eflag",    AR_EFLAG},
+    {"ar.csd",         AR_CSD},        {"ar.ssd",      AR_SSD},
+    {"ar.cflg",                AR_CFLG},       {"ar.fsr",      AR_FSR},
+    {"ar.fir",         AR_FIR},        {"ar.fdr",      AR_FDR},
+    {"ar.ccv",         AR_CCV},        {"ar.unat",     AR_UNAT},
+    {"ar.fpsr",                AR_FPSR},       {"ar.itc",      AR_ITC},
+    {"ar.pfs",         AR_PFS},        {"ar.lc",       AR_LC},
+    {"ar.ec",          AR_EC},
   };
 
+/* control registers:  */
+
+#define CR_DCR           0
+#define CR_ITM           1
+#define CR_IVA           2
+#define CR_PTA           8
+#define CR_GPTA          9
 #define CR_IPSR         16
 #define CR_ISR          17
 #define CR_IIP          19
@@ -391,49 +409,52 @@ ar[] =
 #define CR_IFS          23
 #define CR_IIM          24
 #define CR_IHA          25
+#define CR_LID          64
 #define CR_IVR          65
 #define CR_TPR          66
 #define CR_EOI          67
 #define CR_IRR0         68
 #define CR_IRR3         71
+#define CR_ITV          72
+#define CR_PMV          73
+#define CR_CMCV         74
 #define CR_LRR0         80
 #define CR_LRR1         81
 
-/* control registers:  */
 static const struct
   {
     const char *name;
-    int regnum;
+    unsigned int regnum;
   }
 cr[] =
   {
-    {"cr.dcr",  0},
-    {"cr.itm",  1},
-    {"cr.iva",  2},
-    {"cr.pta",  8},
-    {"cr.gpta",         9},
-    {"cr.ipsr",        16},
-    {"cr.isr", 17},
-    {"cr.iip", 19},
-    {"cr.ifa", 20},
-    {"cr.itir",        21},
-    {"cr.iipa",        22},
-    {"cr.ifs", 23},
-    {"cr.iim", 24},
-    {"cr.iha", 25},
-    {"cr.lid", 64},
-    {"cr.ivr", 65},
-    {"cr.tpr", 66},
-    {"cr.eoi", 67},
-    {"cr.irr0",        68},
-    {"cr.irr1",        69},
-    {"cr.irr2",        70},
-    {"cr.irr3",        71},
-    {"cr.itv", 72},
-    {"cr.pmv", 73},
-    {"cr.cmcv",        74},
-    {"cr.lrr0",        80},
-    {"cr.lrr1",        81}
+    {"cr.dcr", CR_DCR},
+    {"cr.itm", CR_ITM},
+    {"cr.iva", CR_IVA},
+    {"cr.pta", CR_PTA},
+    {"cr.gpta",        CR_GPTA},
+    {"cr.ipsr",        CR_IPSR},
+    {"cr.isr", CR_ISR},
+    {"cr.iip", CR_IIP},
+    {"cr.ifa", CR_IFA},
+    {"cr.itir",        CR_ITIR},
+    {"cr.iipa",        CR_IIPA},
+    {"cr.ifs", CR_IFS},
+    {"cr.iim", CR_IIM},
+    {"cr.iha", CR_IHA},
+    {"cr.lid", CR_LID},
+    {"cr.ivr", CR_IVR},
+    {"cr.tpr", CR_TPR},
+    {"cr.eoi", CR_EOI},
+    {"cr.irr0",        CR_IRR0},
+    {"cr.irr1",        CR_IRR0 + 1},
+    {"cr.irr2",        CR_IRR0 + 2},
+    {"cr.irr3",        CR_IRR3},
+    {"cr.itv", CR_ITV},
+    {"cr.pmv", CR_PMV},
+    {"cr.cmcv",        CR_CMCV},
+    {"cr.lrr0",        CR_LRR0},
+    {"cr.lrr1",        CR_LRR1}
   };
 
 #define PSR_MFL         4
@@ -491,7 +512,7 @@ const_bits[] =
 static const struct
   {
     const char *name;
-    int regnum;
+    unsigned int regnum;
   }
 indirect_reg[] =
   {
@@ -811,8 +832,8 @@ static void dot_dv_mode PARAMS ((int));
 static void dot_entry PARAMS ((int));
 static void dot_mem_offset PARAMS ((int));
 static void add_unwind_entry PARAMS((unw_rec_list *, int));
-static symbolS *declare_register PARAMS ((const char *name, int regnum));
-static void declare_register_set PARAMS ((const char *, int, int));
+static symbolS *declare_register PARAMS ((const char *name, unsigned int regnum));
+static void declare_register_set PARAMS ((const char *, unsigned int, unsigned int));
 static unsigned int operand_width PARAMS ((enum ia64_opnd));
 static enum operand_match_result operand_match PARAMS ((const struct ia64_opcode *idesc,
                                                        int index,
@@ -4772,7 +4793,8 @@ static void
 dot_rot (type)
      int type;
 {
-  unsigned num_regs, num_alloced = 0;
+  offsetT num_regs;
+  valueT num_alloced = 0;
   struct dynreg **drpp, *dr;
   int ch, base_reg = 0;
   char *name, *start;
@@ -4817,6 +4839,11 @@ dot_rot (type)
          as_bad ("Expected ']'");
          goto err;
        }
+      if (num_regs <= 0)
+       {
+         as_bad ("Number of elements must be positive");
+         goto err;
+       }
       SKIP_WHITESPACE ();
 
       num_alloced += num_regs;
@@ -5594,7 +5621,7 @@ pseudo_opcode[] =
 static symbolS *
 declare_register (name, regnum)
      const char *name;
-     int regnum;
+     unsigned int regnum;
 {
   const char *err;
   symbolS *sym;
@@ -5612,11 +5639,11 @@ declare_register (name, regnum)
 static void
 declare_register_set (prefix, num_regs, base_regnum)
      const char *prefix;
-     int num_regs;
-     int base_regnum;
+     unsigned int num_regs;
+     unsigned int base_regnum;
 {
   char name[8];
-  int i;
+  unsigned int i;
 
   for (i = 0; i < num_regs; ++i)
     {
@@ -7366,7 +7393,7 @@ extra_goodness (int templ, int slot)
 void
 md_begin ()
 {
-  int i, j, k, t, goodness, best, regnum, ok;
+  int i, j, k, t, goodness, best, ok;
   const char *err;
   char name[8];
 
@@ -7541,81 +7568,52 @@ md_begin ()
   md.entry_hash = hash_new ();
 
   /* general registers:  */
-  for (i = REG_GR; i < REG_GR + 128; ++i)
-    {
-      sprintf (name, "r%d", i - REG_GR);
-      md.regsym[i] = declare_register (name, i);
-    }
+  declare_register_set ("r", 128, REG_GR);
+  declare_register ("gp", REG_GR +  1);
+  declare_register ("sp", REG_GR + 12);
+  declare_register ("tp", REG_GR + 13);
+  declare_register_set ("ret", 4, REG_GR + 8);
 
   /* floating point registers:  */
-  for (i = REG_FR; i < REG_FR + 128; ++i)
-    {
-      sprintf (name, "f%d", i - REG_FR);
-      md.regsym[i] = declare_register (name, i);
-    }
-
-  /* application registers:  */
-  for (i = REG_AR; i < REG_AR + 128; ++i)
-    {
-      sprintf (name, "ar%d", i - REG_AR);
-      md.regsym[i] = declare_register (name, i);
-    }
-
-  /* control registers:  */
-  for (i = REG_CR; i < REG_CR + 128; ++i)
-    {
-      sprintf (name, "cr%d", i - REG_CR);
-      md.regsym[i] = declare_register (name, i);
-    }
-
-  /* predicate registers:  */
-  for (i = REG_P; i < REG_P + 64; ++i)
-    {
-      sprintf (name, "p%d", i - REG_P);
-      md.regsym[i] = declare_register (name, i);
-    }
+  declare_register_set ("f", 128, REG_FR);
+  declare_register_set ("farg", 8, REG_FR + 8);
+  declare_register_set ("fret", 8, REG_FR + 8);
 
   /* branch registers:  */
-  for (i = REG_BR; i < REG_BR + 8; ++i)
-    {
-      sprintf (name, "b%d", i - REG_BR);
-      md.regsym[i] = declare_register (name, i);
-    }
-
-  md.regsym[REG_IP] = declare_register ("ip", REG_IP);
-  md.regsym[REG_CFM] = declare_register ("cfm", REG_CFM);
-  md.regsym[REG_PR] = declare_register ("pr", REG_PR);
-  md.regsym[REG_PR_ROT] = declare_register ("pr.rot", REG_PR_ROT);
-  md.regsym[REG_PSR] = declare_register ("psr", REG_PSR);
-  md.regsym[REG_PSR_L] = declare_register ("psr.l", REG_PSR_L);
-  md.regsym[REG_PSR_UM] = declare_register ("psr.um", REG_PSR_UM);
+  declare_register_set ("b", 8, REG_BR);
+  declare_register ("rp", REG_BR + 0);
 
-  for (i = 0; i < NELEMS (indirect_reg); ++i)
-    {
-      regnum = indirect_reg[i].regnum;
-      md.regsym[regnum] = declare_register (indirect_reg[i].name, regnum);
-    }
+  /* predicate registers:  */
+  declare_register_set ("p", 64, REG_P);
+  declare_register ("pr", REG_PR);
+  declare_register ("pr.rot", REG_PR_ROT);
 
-  /* define synonyms for application registers:  */
+  /* application registers:  */
+  declare_register_set ("ar", 128, REG_AR);
   for (i = 0; i < NELEMS (ar); ++i)
     declare_register (ar[i].name, REG_AR + ar[i].regnum);
 
-  /* define synonyms for control registers:  */
+  /* control registers:  */
+  declare_register_set ("cr", 128, REG_CR);
   for (i = 0; i < NELEMS (cr); ++i)
     declare_register (cr[i].name, REG_CR + cr[i].regnum);
 
-  declare_register ("gp", REG_GR +  1);
-  declare_register ("sp", REG_GR + 12);
-  declare_register ("tp", REG_GR + 13);
-  declare_register ("rp", REG_BR +  0);
+  declare_register ("ip", REG_IP);
+  declare_register ("cfm", REG_CFM);
+  declare_register ("psr", REG_PSR);
+  declare_register ("psr.l", REG_PSR_L);
+  declare_register ("psr.um", REG_PSR_UM);
+
+  for (i = 0; i < NELEMS (indirect_reg); ++i)
+    {
+      unsigned int regnum = indirect_reg[i].regnum;
+
+      md.indregsym[regnum - IND_CPUID] = declare_register (indirect_reg[i].name, regnum);
+    }
 
   /* pseudo-registers used to specify unwind info:  */
   declare_register ("psp", REG_PSP);
 
-  declare_register_set ("ret", 4, REG_GR + 8);
-  declare_register_set ("farg", 8, REG_FR + 8);
-  declare_register_set ("fret", 8, REG_FR + 8);
-
   for (i = 0; i < NELEMS (const_bits); ++i)
     {
       err = hash_insert (md.const_hash, const_bits[i].name,
@@ -7979,39 +7977,51 @@ ia64_optimize_expr (l, op, r)
      operatorT op;
      expressionS *r;
 {
-  unsigned num_regs;
-
-  if (op == O_index)
+  if (op != O_index)
+    return 0;
+  resolve_expression (l);
+  if (l->X_op == O_register)
     {
-      if (l->X_op == O_register && r->X_op == O_constant)
+      unsigned num_regs = l->X_add_number >> 16;
+
+      resolve_expression (r);
+      if (num_regs)
        {
-         num_regs = (l->X_add_number >> 16);
-         if ((unsigned) r->X_add_number >= num_regs)
+         /* Left side is a .rotX-allocated register.  */
+         if (r->X_op != O_constant)
            {
-             if (!num_regs)
-               as_bad ("No current frame");
-             else
-               as_bad ("Index out of range 0..%u", num_regs - 1);
+             as_bad ("Rotating register index must be a non-negative constant");
+             r->X_add_number = 0;
+           }
+         else if ((valueT) r->X_add_number >= num_regs)
+           {
+             as_bad ("Index out of range 0..%u", num_regs - 1);
              r->X_add_number = 0;
            }
          l->X_add_number = (l->X_add_number & 0xffff) + r->X_add_number;
          return 1;
        }
-      else if (l->X_op == O_register && r->X_op == O_register)
+      else if (l->X_add_number >= IND_CPUID && l->X_add_number <= IND_RR)
        {
-         if (l->X_add_number < IND_CPUID || l->X_add_number > IND_RR
-             || l->X_add_number == IND_MEM)
+         if (r->X_op != O_register
+             || r->X_add_number < REG_GR
+             || r->X_add_number > REG_GR + 127)
            {
-             as_bad ("Indirect register set name expected");
-             l->X_add_number = IND_CPUID;
+             as_bad ("Indirect register index must be a general register");
+             r->X_add_number = REG_GR;
            }
          l->X_op = O_index;
-         l->X_op_symbol = md.regsym[l->X_add_number];
+         l->X_op_symbol = md.indregsym[l->X_add_number - IND_CPUID];
          l->X_add_number = r->X_add_number;
          return 1;
        }
     }
-  return 0;
+  as_bad ("Index can only be applied to rotating or indirect registers");
+  /* Fall back to some register use of which has as little as possible
+     side effects, to minimize subsequent error messages.  */
+  l->X_op = O_register;
+  l->X_add_number = REG_GR + 3;
+  return 1;
 }
 
 int
@@ -11020,8 +11030,13 @@ md_operand (e)
        }
       else
        {
-         if (e->X_op != O_register)
-           as_bad ("Register expected as index");
+         if (e->X_op != O_register
+             || e->X_add_number < REG_GR
+             || e->X_add_number > REG_GR + 127)
+           {
+             as_bad ("Index must be a general register");
+             e->X_add_number = REG_GR;
+           }
 
          ++input_line_pointer;
          e->X_op = O_index;
This page took 0.029676 seconds and 4 git commands to generate.