This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Committed: minor tc-cris fix


There's a bug there, in that md_long_jump_size is not equal to
md_short_jump_size for CRIS v32 (the tc-cris.h comment was not
true).  It happened to not matter; all calls meant for
md_short_jump were directed to cris_create_short_jump, because,
as the previously added tests indicate, we don't need a
md_short_jump that can skip 32768 bytes; the 16-bit limit of the
offset that has to reach into the secondary jump table kicks in
before that happens...
 ...except as mentioned if gcc for some reason puts enough labels
before the case-jump...but -freorder-blocks "can't possibly" push
matters that far...

Whatever; I'm not going to worry about that any more than
breaking the inherent limit of the broken-.word machinery.  At
least this change supposedly makes any such breakage apparent
with the extra check.  Call it a minor fix.  Committed after
testing cris-elf.

gas:
	* config/tc-cris.c (cris_create_short_jump): Remove prototype.
	Rename, changing all callers, to...
	(md_create_short_jump): Adjust head comment.  Assert
	word-sized-branch distance for v32.  Bail out calling as_fatal for
	compatibility mode here.
	(md_create_long_jump): ...not here.
	* config/tc-cris.h (md_create_short_jump): Do not define.

Index: config/tc-cris.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-cris.h,v
retrieving revision 1.17
diff -p -u -r1.17 tc-cris.h
--- config/tc-cris.h	3 Jul 2007 11:01:04 -0000	1.17
+++ config/tc-cris.h	11 Mar 2009 03:19:21 -0000
@@ -68,11 +68,6 @@ extern const char FLT_CHARS[];
 #define md_operand(x)
 
 #define md_number_to_chars number_to_chars_littleendian
-
-/* There's no use having different functions for this; the sizes are the
-   same.  Note that we can't #define md_short_jump_size here.  */
-#define md_create_short_jump md_create_long_jump
-
 extern const struct relax_type md_cris_relax_table[];
 #define TC_GENERIC_RELAX_TABLE md_cris_relax_table
 
Index: config/tc-cris.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-cris.c,v
retrieving revision 1.45
diff -p -u -r1.45 tc-cris.c
--- config/tc-cris.c	21 Dec 2008 20:16:47 -0000	1.45
+++ config/tc-cris.c	11 Mar 2009 03:19:21 -0000
@@ -142,8 +142,6 @@ static int branch_disp (int);
 static void gen_cond_branch_32 (char *, char *, fragS *, symbolS *, symbolS *,
 				long int);
 static void cris_number_to_imm (char *, long, int, fixS *, segT);
-static void cris_create_short_jump (char *, addressT, addressT, fragS *,
-				    symbolS *);
 static void s_syntax (int);
 static void s_cris_file (int);
 static void s_cris_loc (int);
@@ -1023,14 +1021,10 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNU
 }
 
 /* Generate a short jump around a secondary jump table.
-   Used by md_create_long_jump.
+   Also called from md_create_long_jump, when sufficient.  */
 
-   This used to be md_create_short_jump, but is now called from
-   md_create_long_jump instead, when sufficient, since the sizes of the
-   jumps are the same for pre-v32.  */
-
-static void
-cris_create_short_jump (char *storep, addressT from_addr, addressT to_addr,
+void
+md_create_short_jump (char *storep, addressT from_addr, addressT to_addr,
 			fragS *fragP ATTRIBUTE_UNUSED,
 			symbolS *to_symbol ATTRIBUTE_UNUSED)
 {
@@ -1039,18 +1033,30 @@ cris_create_short_jump (char *storep, ad
   /* See md_create_long_jump about the comment on the "+ 2".  */
   long int max_minimal_minus_distance;
   long int max_minimal_plus_distance;
+  long int max_minus_distance;
+  long int max_plus_distance;
   int nop_opcode;
 
   if (cris_arch == arch_crisv32)
     {
       max_minimal_minus_distance = BRANCH_BB_V32 + 2;
       max_minimal_plus_distance = BRANCH_BF_V32 + 2;
+      max_minus_distance = BRANCH_WB_V32 + 2;
+      max_plus_distance = BRANCH_WF_V32 + 2;
       nop_opcode = NOP_OPCODE_V32;
     }
+  else if (cris_arch == arch_cris_common_v10_v32)
+    /* Bail out for compatibility mode.  (It seems it can be implemented,
+       perhaps with a 10-byte sequence: "move.d NNNN,$pc/$acr", "jump
+       $acr", "nop"; but doesn't seem worth it at the moment.)  */
+    as_fatal (_("Out-of-range .word offset handling\
+ is not implemented for .arch common_v10_v32"));
   else
     {
       max_minimal_minus_distance = BRANCH_BB + 2;
       max_minimal_plus_distance = BRANCH_BF + 2;
+      max_minus_distance = BRANCH_WB + 2;
+      max_plus_distance = BRANCH_WF + 2;
       nop_opcode = NOP_OPCODE;
     }
 
@@ -1070,7 +1076,8 @@ cris_create_short_jump (char *storep, ad
 	 a nop to keep disassembly sane.  */
       md_number_to_chars (storep + 4, nop_opcode, 2);
     }
-  else
+  else if (max_minus_distance <= distance
+	   && distance <= max_plus_distance)
     {
       /* Make it a "long" short jump: "BA (PC+)".  */
       md_number_to_chars (storep, BA_PC_INCR_OPCODE, 2);
@@ -1085,6 +1092,9 @@ cris_create_short_jump (char *storep, ad
       /* A nop for the delay slot.  */
       md_number_to_chars (storep + 4, nop_opcode, 2);
     }
+  else
+    as_bad_where (fragP->fr_file, fragP->fr_line,
+		  _(".word case-table handling failed: table too large"));
 }
 
 /* Generate a long jump in a secondary jump table.
@@ -1111,19 +1121,12 @@ md_create_long_jump (char *storep, addre
   long int max_short_plus_distance
     = cris_arch != arch_crisv32 ? BRANCH_WF + 3 : BRANCH_WF_V32 + 3;
 
-  /* Bail out for compatibility mode.  (It seems it can be implemented,
-     perhaps with a 10-byte sequence: "move.d NNNN,$pc/$acr", "jump
-     $acr", "nop"; but doesn't seem worth it at the moment.)  */
-  if (cris_arch == arch_cris_common_v10_v32)
-    as_fatal (_("Out-of-range .word offset handling\
- is not implemented for .arch common_v10_v32"));
-
   distance = to_addr - from_addr;
 
   if (max_short_minus_distance <= distance
       && distance <= max_short_plus_distance)
     /* Then make it a "short" long jump.  */
-    cris_create_short_jump (storep, from_addr, to_addr, fragP,
+    md_create_short_jump (storep, from_addr, to_addr, fragP,
 			    to_symbol);
   else
     {

brgds, H-P


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]