* config/tc-alpha.h (alpha_do_align): Don't declare.
authorIan Lance Taylor <ian@airs.com>
Thu, 6 Jul 1995 16:59:29 +0000 (16:59 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 6 Jul 1995 16:59:29 +0000 (16:59 +0000)
(md_do_align): Don't define.
(tc_frob_label): Define.
(alpha_define_label): Declare.
(md_flush_pending_output): Define.
(alpha_flush_pending_output): Declare.
* config/tc-alpha.c (insn_label): New static variable.
(auto_align): New static variable.
(md_pseudo_table): Add cases for .text, .data, .align, .byte,
.hword, .int, .long, .octa, .quad, .short, .word, .double, .float,
and .single.  Change .t_floating, .s_floating, .f_floating,
.g_floating, and .d_floating to use s_alpha_float_cons rather than
float_cons.
(s_alpha_text, s_alpha_data): New static functions.
(s_rdata, s_sdata): Clear insn_label and set auto_align.
(s_gprel32): If auto_align, align.  Clear insn_label.
(emit_insn): Clear insn_label.
(s_alpha_align): New static function.
(alpha_align): Make static.  Take label argument.
(alpha_flush_pending_output): New static function.
(s_alpha_cons, s_alpha_float_cons): New static functions.
(alpha_define_label): New function.
PR 7148.

gas/ChangeLog
gas/config/tc-alpha.c
gas/config/tc-alpha.h

index 9f3e6564f9485734523b68d8bdce61f18929d6f3..a8659fe621f80f60b2e3d5829d3e76d92ce0f12b 100644 (file)
@@ -1,3 +1,28 @@
+Thu Jul  6 12:54:27 1995  Ian Lance Taylor  <ian@cygnus.com>
+
+       * config/tc-alpha.h (alpha_do_align): Don't declare.
+       (md_do_align): Don't define.
+       (tc_frob_label): Define.
+       (alpha_define_label): Declare.
+       (md_flush_pending_output): Define.
+       (alpha_flush_pending_output): Declare.
+       * config/tc-alpha.c (insn_label): New static variable.
+       (auto_align): New static variable.
+       (md_pseudo_table): Add cases for .text, .data, .align, .byte,
+       .hword, .int, .long, .octa, .quad, .short, .word, .double, .float,
+       and .single.  Change .t_floating, .s_floating, .f_floating,
+       .g_floating, and .d_floating to use s_alpha_float_cons rather than
+       float_cons.
+       (s_alpha_text, s_alpha_data): New static functions.
+       (s_rdata, s_sdata): Clear insn_label and set auto_align.
+       (s_gprel32): If auto_align, align.  Clear insn_label.
+       (emit_insn): Clear insn_label.
+       (s_alpha_align): New static function.
+       (alpha_align): Make static.  Take label argument.
+       (alpha_flush_pending_output): New static function.
+       (s_alpha_cons, s_alpha_float_cons): New static functions.
+       (alpha_define_label): New function.
+
 Wed Jul  5 22:49:31 1995  Ken Raeburn  <raeburn@cygnus.com>
 
        * conf.in: Regenerate with autoreconf.
index 25de02d26686230a16f8d52323944975a7359236..f4d711b8c78fd027c654b786eb7777b165d1f2b7 100644 (file)
@@ -65,7 +65,6 @@
 
 /* These are exported to relaxing code, even though we don't do any
    relaxing on this processor currently.  */
-const relax_typeS md_relax_table[1];
 int md_short_jump_size = 4;
 int md_long_jump_size = 4;
 
@@ -85,7 +84,7 @@ static symbolS *gp;
 
 /* We'll probably be using this relocation frequently, and we
    will want to compare for it.  */
-static const reloc_howto_type *gpdisp_hi16_howto;
+static reloc_howto_type *gpdisp_hi16_howto;
 
 /* These are exported to ECOFF code.  */
 unsigned long alpha_gprmask, alpha_fprmask;
@@ -99,6 +98,17 @@ static expressionS lituse_basereg, lituse_byteoff, lituse_jsr;
    Some other systems may want this option too.  */
 static int addr32;
 
+/* Symbol labelling the current insn.  When the Alpha gas sees
+     foo:
+       .quad 0
+   and the section happens to not be on an eight byte boundary, it
+   will align both the symbol and the .quad to an eight byte boundary.  */
+static symbolS *insn_label;
+
+/* Whether we should automatically align data generation pseudo-ops.
+   .align 0 will turn this off.  */
+static int auto_align = 1;
+
 /* Imported functions -- they should be defined in header files somewhere.  */
 extern segT subseg_get ();
 extern PTR bfd_alloc_by_size_t ();
@@ -108,6 +118,11 @@ extern void s_globl (), s_long (), s_short (), s_space (), cons (), s_text (),
 /* Static functions, needing forward declarations.  */
 static void s_base (), s_proc (), s_alpha_set ();
 static void s_gprel32 (), s_rdata (), s_sdata (), s_alpha_comm ();
+static void s_alpha_text PARAMS ((int));
+static void s_alpha_data PARAMS ((int));
+static void s_alpha_align PARAMS ((int));
+static void s_alpha_cons PARAMS ((int));
+static void s_alpha_float_cons PARAMS ((int));
 static int alpha_ip ();
 
 static void emit_unaligned_io PARAMS ((char *, int, valueT, int));
@@ -127,19 +142,22 @@ static void emit_addq_r PARAMS ((int, int, int));
 static void emit_lda_n PARAMS ((int, bfd_vma, int));
 static void emit_add64 PARAMS ((int, int, bfd_vma));
 static int in_range_signed PARAMS ((bfd_vma, int));
+static void alpha_align PARAMS ((int, int, symbolS *));
 
 const pseudo_typeS md_pseudo_table[] =
 {
   {"common", s_comm, 0},       /* is this used? */
   {"comm", s_alpha_comm, 0},   /* osf1 compiler does this */
+  {"text", s_alpha_text, 0},
+  {"data", s_alpha_data, 0},
   {"rdata", s_rdata, 0},
   {"sdata", s_sdata, 0},
   {"gprel32", s_gprel32, 0},
-  {"t_floating", float_cons, 'd'},
-  {"s_floating", float_cons, 'f'},
-  {"f_floating", float_cons, 'F'},
-  {"g_floating", float_cons, 'G'},
-  {"d_floating", float_cons, 'D'},
+  {"t_floating", s_alpha_float_cons, 'd'},
+  {"s_floating", s_alpha_float_cons, 'f'},
+  {"f_floating", s_alpha_float_cons, 'F'},
+  {"g_floating", s_alpha_float_cons, 'G'},
+  {"d_floating", s_alpha_float_cons, 'D'},
 
   {"proc", s_proc, 0},
   {"aproc", s_proc, 1},
@@ -153,6 +171,19 @@ const pseudo_typeS md_pseudo_table[] =
   {"aent", s_ignore, 0},
   {"ugen", s_ignore, 0},
 
+  {"align", s_alpha_align, 0},
+  {"byte", s_alpha_cons, 0},
+  {"hword", s_alpha_cons, 1},
+  {"int", s_alpha_cons, 2},
+  {"long", s_alpha_cons, 2},
+  {"octa", s_alpha_cons, 4},
+  {"quad", s_alpha_cons, 3},
+  {"short", s_alpha_cons, 1},
+  {"word", s_alpha_cons, 1},
+  {"double", s_alpha_float_cons, 'd'},
+  {"float", s_alpha_float_cons, 'f'},
+  {"single", s_alpha_float_cons, 'f'},
+
 /* We don't do any optimizing, so we can safely ignore these.  */
   {"noalias", s_ignore, 0},
   {"alias", s_ignore, 0},
@@ -265,6 +296,30 @@ tc_get_register (frame)
   return framereg;
 }
 
+/* Handle the .text pseudo-op.  This is like the usual one, but it
+   clears insn_label and restores auto alignment.  */
+
+static void
+s_alpha_text (i)
+     int i;
+{
+  s_text (i);
+  insn_label = NULL;
+  auto_align = 1;
+}  
+
+/* Handle the .data pseudo-op.  This is like the usual one, but it
+   clears insn_label and restores auto alignment.  */
+
+static void
+s_alpha_data (i)
+     int i;
+{
+  s_data (i);
+  insn_label = NULL;
+  auto_align = 1;
+}  
+
 static void
 s_rdata (ignore)
      int ignore;
@@ -280,6 +335,8 @@ s_rdata (ignore)
   rdata = subseg_new (".rdata", 0);
 #endif
   demand_empty_rest_of_line ();
+  insn_label = NULL;
+  auto_align = 1;
 }
 
 static void
@@ -297,6 +354,8 @@ s_sdata (ignore)
   sdata = subseg_new (".sdata", 0);
 #endif
   demand_empty_rest_of_line ();
+  insn_label = NULL;
+  auto_align = 1;
 }
 
 static void
@@ -439,7 +498,7 @@ static int in_range_signed (val, nbits)
 
   mask = (one << nbits) - 1;
   stored_value = val & mask;
-  top_bit = stored_value & (one << nbits - 1);
+  top_bit = stored_value & (one << (nbits - 1));
   missing_bits = val & ~mask;
   /* will sign-extend */
   if (top_bit)
@@ -495,10 +554,13 @@ s_gprel32 ()
     default:
       abort ();
     }
+  if (auto_align)
+    alpha_align (2, 0, insn_label);
   p = frag_more (4);
   memset (p, 0, 4);
   fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &e, 0,
               BFD_RELOC_GPREL32);
+  insn_label = NULL;
 }
 
 static void
@@ -592,7 +654,7 @@ md_begin ()
          char *q2 = p;
 
          for (; *q; q++)
-           if (*q /= '/')
+           if (*q != '/')
              *q2++ = *q;
 
          *q2++ = 0;
@@ -658,14 +720,16 @@ emit_insn (insn)
            }
          f = fix_new_exp (frag_now, (toP - frag_now->fr_literal), 4,
                           &r->exp, r->pcrel, r->code);
-       }
-      if (r->code == BFD_RELOC_ALPHA_GPDISP_LO16)
-       {
-         static bit_fixS cookie;
-         /* @@ This'll make the range checking in write.c shut up.  */
-         f->fx_bit_fixP = &cookie;
+         if (r->code == BFD_RELOC_ALPHA_GPDISP_LO16)
+           {
+             static bit_fixS cookie;
+             /* @@ This'll make the range checking in write.c shut up.  */
+             f->fx_bit_fixP = &cookie;
+           }
        }
     }
+
+  insn_label = NULL;
 }
 
 void
@@ -1185,11 +1249,11 @@ alpha_ip (str, insns)
   struct alpha_opcode *pattern;
   char *argsStart;
   unsigned int opcode;
-  unsigned int mask;
+  unsigned int mask = 0;
   int match = 0, num_gen = 1;
   int comma = 0;
-  int do_add64, add64_in, add64_out;
-  bfd_vma add64_addend;
+  int do_add64, add64_in = 0, add64_out = 0;
+  bfd_vma add64_addend = 0;
 
   for (s = str;
        islower (*s) || *s == '_' || *s == '/' || *s == '4' || *s == '8';
@@ -1644,7 +1708,7 @@ alpha_ip (str, insns)
              else if (insns[0].reloc[0].exp.X_op == O_symbol)
                {
                  unsigned long old_opcode = opcode;
-                 int tmp_reg;
+                 int tmp_reg = -1;
 
                  if (!macro_ok)
                    as_bad ("insn requires expansion but `nomacro' specified");
@@ -1816,10 +1880,10 @@ alpha_ip (str, insns)
                     manipulation, with t9 and t10 as temporaries.  */
                  {
                    /* Characteristics of access.  */
-                   int is_load, is_unsigned = 0, is_unaligned = 0;
+                   int is_load = 99, is_unsigned = 0, is_unaligned = 0;
                    int mode_size, mode;
                    /* Register operand.  */
-                   int reg;
+                   int reg = -1;
                    /* Addend for loads and stores.  */
                    valueT addend;
                    /* Which register do we use for the address?  */
@@ -1937,7 +2001,7 @@ alpha_ip (str, insns)
 
                    if (is_load)
                      {
-                       int reg2, reg3;
+                       int reg2, reg3 = -1;
 
                        if (is_unaligned)
                          reg2 = T9, reg3 = T10;
@@ -2328,21 +2392,143 @@ md_pcrel_from (fixP)
     }
 }
 
-int
-alpha_do_align (n, fill)
+/* Handle the .align pseudo-op.  This aligns to a power of two.  It
+   also adjusts any current instruction label.  We treat this the same
+   way the MIPS port does: .align 0 turns off auto alignment.  */
+
+static void
+s_alpha_align (ignore)
+     int ignore;
+{
+  register int temp;
+  register long temp_fill;
+  long max_alignment = 15;
+
+  temp = get_absolute_expression ();
+  if (temp > max_alignment)
+    as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
+  else if (temp < 0)
+    {
+      as_warn ("Alignment negative: 0 assumed.");
+      temp = 0;
+    }
+  if (*input_line_pointer == ',')
+    {
+      input_line_pointer++;
+      temp_fill = get_absolute_expression ();
+    }
+  else
+    temp_fill = 0;
+  if (temp)
+    {
+      auto_align = 1;
+      alpha_align (temp, (int) temp_fill, insn_label);
+    }
+  else
+    {
+      auto_align = 0;
+    }
+
+  demand_empty_rest_of_line ();
+}
+
+static void
+alpha_align (n, fill, label)
      int n;
-     const char *fill;
+     int fill;
+     symbolS *label;
 {
-  if (!fill
+  if (fill == 0
       && (now_seg == text_section
          || !strcmp (now_seg->name, ".init")
          || !strcmp (now_seg->name, ".fini")))
     {
       static const unsigned char nop_pattern[] = { 0x1f, 0x04, 0xff, 0x47 };
       frag_align_pattern (n, nop_pattern, sizeof (nop_pattern));
-      return 1;
     }
-  return 0;
+  else
+    frag_align (n, fill);
+
+  if (label != NULL)
+    {
+      assert (S_GET_SEGMENT (label) == now_seg);
+      label->sy_frag = frag_now;
+      S_SET_VALUE (label, (valueT) frag_now_fix ());
+    }
+}
+
+/* This function is called just before the generic pseudo-ops output
+   something.  It just clears insn_label.  */
+
+void
+alpha_flush_pending_output ()
+{
+  insn_label = NULL;
+}
+
+/* Handle data allocation pseudo-ops.  This is like the generic
+   version, but it makes sure the current label, if any, is correctly
+   aligned.  */
+
+static void
+s_alpha_cons (log_size)
+     int log_size;
+{
+  if (log_size > 0 && auto_align)
+    alpha_align (log_size, 0, insn_label);
+  insn_label = NULL;
+  cons (1 << log_size);
+}
+
+/* Handle floating point allocation pseudo-ops.  This is like the
+   generic vresion, but it makes sure the current label, if any, is
+   correctly aligned.  */
+
+static void
+s_alpha_float_cons (type)
+     int type;
+{
+  if (auto_align)
+    {
+      int log_size;
+
+      switch (type)
+       {
+       default:
+       case 'f':
+       case 'F':
+         log_size = 2;
+         break;
+
+       case 'd':
+       case 'D':
+       case 'G':
+         log_size = 3;
+         break;
+
+       case 'x':
+       case 'X':
+       case 'p':
+       case 'P':
+         log_size = 4;
+         break;
+       }
+
+      alpha_align (log_size, 0, insn_label);
+    }
+
+  insn_label = NULL;
+  float_cons (type);
+}
+
+/* This function is called whenever a label is defined.  It is used to
+   adjust the label when an automatic alignment occurs.  */
+
+void
+alpha_define_label (sym)
+     symbolS *sym;
+{
+  insn_label = sym;
 }
 
 int
index 809bc67b5edfa47665b4079451a4959abf41e57a..837b4fe63e6318e2fb0a8957c5ac3057bdf16a84 100644 (file)
@@ -47,9 +47,7 @@ extern valueT alpha_gp_value;
 #define md_create_short_jump(p,f,t,fr,s) as_fatal("alpha_create_short_jump")
 #define md_estimate_size_before_relax(f,s) \
                        (as_fatal("estimate_size_before_relax called"),1)
-#define md_operand(x)                  0
-
-extern unsigned long md_section_align PARAMS ((segT, unsigned long));
+#define md_operand(x)                  ((void) (0))
 
 #define md_undefined_symbol(name)      (0)
 
@@ -57,8 +55,11 @@ extern unsigned long md_section_align PARAMS ((segT, unsigned long));
 
 #define md_number_to_chars             number_to_chars_littleendian
 
-extern int alpha_do_align ();
-#define md_do_align(n,fill,l)  if (alpha_do_align(n,fill)) goto l
+extern int tc_get_register PARAMS ((int frame));
+extern void alpha_frob_ecoff_data PARAMS ((void));
+
+#define tc_frob_label(sym) alpha_define_label (sym)
+extern void alpha_define_label PARAMS ((struct symbol *));
 
-extern void alpha_frob_file ();
-#define tc_frob_file           alpha_frob_file
+#define md_flush_pending_output alpha_flush_pending_output
+extern void alpha_flush_pending_output PARAMS ((void));