* config/tc-mep.c (mep_check_ivc2_scheduling): For IVC2, allocate
authorDJ Delorie <dj@redhat.com>
Wed, 24 Jun 2009 00:51:09 +0000 (00:51 +0000)
committerDJ Delorie <dj@redhat.com>
Wed, 24 Jun 2009 00:51:09 +0000 (00:51 +0000)
32 bits for relaxable branches so that we can relax them later.
(md_estimate_size_before_relax): Assume IVC2 branches will be relaxed.
(mep_relax_frag): New.
(md_convert_frag): Relax IVC2 branches in-place.
* config/tc-mep.h ((mep_relax_frag): New.

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

index 311d75b1d1c115342c6b6066b3d7f886141b01f9..b981f2a35d639e9a7d9582439222411584b32b78 100644 (file)
@@ -1,3 +1,12 @@
+2009-06-23  DJ Delorie  <dj@redhat.com>
+
+       * config/tc-mep.c (mep_check_ivc2_scheduling): For IVC2, allocate
+       32 bits for relaxable branches so that we can relax them later.
+       (md_estimate_size_before_relax): Assume IVC2 branches will be relaxed.
+       (mep_relax_frag): New.
+       (md_convert_frag): Relax IVC2 branches in-place.
+       * config/tc-mep.h ((mep_relax_frag): New.
+
 2009-06-22  Martin Thuresson  <martin@mtme.org>
        
        * gas/app, gas/as.c, gas/as.h, gas/atof-generic.c, gas/cgen.c,
index a47138b226f569399d89eab44c39616fc846027e..6b4b540df01caca8f9154b6bd338d821e07b0019 100644 (file)
@@ -914,7 +914,7 @@ mep_check_ivc2_scheduling (void)
   */
 
   int slots[5]; /* Indexed off the SLOTS_ATTR enum.  */
-  int corelength;
+  int corelength, realcorelength;
   int i;
   bfd_byte temp[4];
   bfd_byte *f;
@@ -932,10 +932,19 @@ mep_check_ivc2_scheduling (void)
   if (slot_ok (0, SLOTS_CORE))
     {
       slots[SLOTS_CORE] = 0;
-      corelength = CGEN_FIELDS_BITSIZE (& saved_insns[0].fields);
+      realcorelength = corelength = CGEN_FIELDS_BITSIZE (& saved_insns[0].fields);
+
+      /* If we encounter one of these, it may get relaxed later into a
+        longer instruction.  We can't just push the other opcodes
+        away, the bigger insn has to fit into the existing slot.  So,
+        we make room for the relaxed instruction here.  */
+
+      if (saved_insns[0].insn->base->num == MEP_INSN_BSR12
+         || saved_insns[0].insn->base->num == MEP_INSN_BRA)
+       corelength = 32;
     }
   else
-    corelength = 0;
+    realcorelength = corelength = 0;
 
   if (corelength == 16)
     {
@@ -1070,10 +1079,10 @@ mep_check_ivc2_scheduling (void)
   /* Allocate whatever bytes remain in our insn word.  Adjust the
      pointer to point (as if it were) to the beginning of the whole
      word, so that we don't have to adjust for it elsewhere.  */
-  f = (bfd_byte *) frag_more (8 - corelength / 8);
+  f = (bfd_byte *) frag_more (8 - realcorelength / 8);
   /* Unused slots are filled with NOPs, which happen to be all zeros.  */
-  memset (f, 0, 8 - corelength / 8);
-  f -= corelength / 8;
+  memset (f, 0, 8 - realcorelength / 8);
+  f -= realcorelength / 8;
 
   for (i=1; i<5; i++)
     {
@@ -1499,7 +1508,12 @@ md_estimate_size_before_relax (fragS * fragP, segT segment)
   if (fragP->fr_subtype == 1)
     fragP->fr_subtype = insn_to_subtype (fragP->fr_cgen.insn->base->num);
 
-  if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
+  if (S_GET_SEGMENT (fragP->fr_symbol) != segment
+#ifdef MEP_IVC2_SUPPORTED
+      || (mep_cop == EF_MEP_COP_IVC2
+         && bfd_get_section_flags (stdoutput, segment) & SEC_MEP_VLIW)
+#endif /* MEP_IVC2_SUPPORTED */
+      )
     {
       int new_insn;
 
@@ -1539,9 +1553,29 @@ md_estimate_size_before_relax (fragS * fragP, segT segment)
        }
     }
 
+#ifdef MEP_IVC2_SUPPORTED
+  if (mep_cop == EF_MEP_COP_IVC2
+      && bfd_get_section_flags (stdoutput, segment) & SEC_MEP_VLIW)
+    return 0;
+#endif /* MEP_IVC2_SUPPORTED */
+
   return subtype_mappings[fragP->fr_subtype].growth;
 }
 
+/* VLIW does relaxing, but not growth.  */
+
+long
+mep_relax_frag (segT segment, fragS *fragP, long stretch)
+{
+  long rv = relax_frag (segment, fragP, stretch);
+#ifdef MEP_IVC2_SUPPORTED
+  if (mep_cop == EF_MEP_COP_IVC2
+      && bfd_get_section_flags (stdoutput, segment) & SEC_MEP_VLIW)
+    return 0;
+#endif
+  return rv;
+}
+
 /* *fragP has been relaxed to its final size, and now needs to have
    the bytes inside it modified to conform to the new size.
 
@@ -1563,19 +1597,29 @@ target_address_for (fragS *frag)
 
 void
 md_convert_frag (bfd *abfd  ATTRIBUTE_UNUSED, 
-                segT sec ATTRIBUTE_UNUSED,
+                segT seg ATTRIBUTE_UNUSED,
                 fragS *fragP)
 {
   int addend, rn, bit = 0;
   int operand;
   int where = fragP->fr_opcode - fragP->fr_literal;
   int e = target_big_endian ? 0 : 1;
+  int core_mode;
+
+#ifdef MEP_IVC2_SUPPORTED
+  if (bfd_get_section_flags (stdoutput, seg) & SEC_MEP_VLIW
+      && mep_cop == EF_MEP_COP_IVC2)
+    core_mode = 0;
+  else
+#endif /* MEP_IVC2_SUPPORTED */
+    core_mode = 1;
 
   addend = target_address_for (fragP) - (fragP->fr_address + where);
 
   if (subtype_mappings[fragP->fr_subtype].insn == -1)
     {
-      fragP->fr_fix += subtype_mappings[fragP->fr_subtype].growth;
+      if (core_mode)
+       fragP->fr_fix += subtype_mappings[fragP->fr_subtype].growth;
       switch (subtype_mappings[fragP->fr_subtype].insn_for_extern)
        {
        case MEP_PSEUDO64_16BITCC:
@@ -1617,7 +1661,8 @@ md_convert_frag (bfd *abfd  ATTRIBUTE_UNUSED,
        break;
 
       case MEP_INSN_BSR24:
-       fragP->fr_fix += 2;
+       if (core_mode)
+         fragP->fr_fix += 2;
        fragP->fr_opcode[0^e] = 0xd8 | ((addend >> 5) & 0x07);
        fragP->fr_opcode[1^e] = 0x09 | ((addend << 3) & 0xf0);
        fragP->fr_opcode[2^e] = 0x00 | ((addend >>16) & 0xff);
@@ -1637,7 +1682,8 @@ md_convert_frag (bfd *abfd  ATTRIBUTE_UNUSED,
           instructions to JMP.  */
        if (addend <= 65535 && addend >= -65536)
          {
-           fragP->fr_fix += 2;
+           if (core_mode)
+             fragP->fr_fix += 2;
            fragP->fr_opcode[0^e] = 0xe0;
            fragP->fr_opcode[1^e] = 0x01;
            fragP->fr_opcode[2^e] = 0x00 | ((addend >> 9) & 0xff);
@@ -1649,7 +1695,8 @@ md_convert_frag (bfd *abfd  ATTRIBUTE_UNUSED,
 
       case MEP_INSN_JMP:
        addend = target_address_for (fragP);
-       fragP->fr_fix += 2;
+       if (core_mode)
+         fragP->fr_fix += 2;
        fragP->fr_opcode[0^e] = 0xd8 | ((addend >> 5) & 0x07);
        fragP->fr_opcode[1^e] = 0x08 | ((addend << 3) & 0xf0);
        fragP->fr_opcode[2^e] = 0x00 | ((addend >>16) & 0xff);
@@ -1669,7 +1716,8 @@ md_convert_frag (bfd *abfd  ATTRIBUTE_UNUSED,
       case MEP_INSN_BEQI:
        if (subtype_mappings[fragP->fr_subtype].growth)
          {
-           fragP->fr_fix += subtype_mappings[fragP->fr_subtype].growth;
+           if (core_mode)
+             fragP->fr_fix += subtype_mappings[fragP->fr_subtype].growth;
            rn = fragP->fr_opcode[0^e] & 0x0f;
            fragP->fr_opcode[0^e] = 0xe0 | rn;
            fragP->fr_opcode[1^e] = bit;
@@ -1695,7 +1743,7 @@ md_convert_frag (bfd *abfd  ATTRIBUTE_UNUSED,
        abort ();
       }
 
-  if (S_GET_SEGMENT (fragP->fr_symbol) != sec
+  if (S_GET_SEGMENT (fragP->fr_symbol) != seg
       || operand == MEP_OPERAND_PCABS24A2)
     {
       gas_assert (fragP->fr_cgen.insn != 0);
index 0861909ce5137a68b5465ec4f1a29d3198b976ec..dd5118c3d3c0c4eb712f00b79e355a7a88f5e3ef 100644 (file)
@@ -80,6 +80,9 @@ extern int mep_flush_pending_output(void);
 extern const struct relax_type md_relax_table[];
 #define TC_GENERIC_RELAX_TABLE md_relax_table
 
+extern long mep_relax_frag (segT, fragS *, long);
+#define md_relax_frag mep_relax_frag
+
 /* Account for inserting a jmp after the insn.  */
 #define TC_CGEN_MAX_RELAX(insn, len) ((len) + 4)