[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

fw: gcc v4 interworking patch



I should have sent this somewhere useful a while ago, but thought I
should test it first, then got tied up in 'stuff not working' as
evidenced in mails to this list a while ago. Then other stuff (mostly
new job and house) got in the way.

I understand George France has built a compiler using this and was
testing it last I heard.

Can someone try this, because if it works we can support strongarm
with armel, which I think is worth doing. 

Apologies again for letting it moulder in my inbox, and kudos to
Richard K. Pixley for doing the work. 

----- Forwarded message from "K. Richard Pixley" <rich.pixley@palmsource.com> -----

From: "K. Richard Pixley" <rich.pixley@palmsource.com>
Date: Fri, 09 Mar 2007 16:45:58 -0800
To: Wookey <wookey@aleph1.co.uk>
Subject: Re: dpkg patch for armel support
X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00 autolearn=ham 
	version=3.0.3, No

Thanks.

It's a little more complicated than two extra instructions.  It's 
actually three.  In order to mimick a bx<cc> we have to test the inverse 
of <cc> and perhaps jump around our little three-step.

I don't have much time to put into this just now, but here's a first 
pass.  I haven't even compiled it, (first pass attempt out of the box to 
build gcc-4.1.2 for "arm-linux-gnueabi" didn't build), so I'm sure it's 
not clean.  But it'll point out the general idea of what probably needs 
to be done.

There's probably also some code to check that -mthumb-interwork and 
-march=armv4 aren't compatible.  That code needs to be lifted.  I didn't 
find it on a quick search.  Easiest thing to do is throw gcc into gdb 
and trip it.  But since I couldn't build 4.1.2 quickly...

Anyway, here's the pointers/patches.  This should be a start.  Paul 
Brooks should be able to crank this sort of thing out in no time, I'd think.

--rich


-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.


diff -u -r gcc-4.1.2/gcc/config/arm/arm.c gcc-4.1.2-new/gcc/config/arm/arm.c
--- gcc-4.1.2/gcc/config/arm/arm.c	2006-10-16 18:04:38.000000000 -0700
+++ gcc-4.1.2-new/gcc/config/arm/arm.c	2007-03-09 16:20:07.000000000 -0800
@@ -8513,7 +8513,12 @@
 
   output_asm_insn ("mov%?\t%|lr, %|pc", operands);
 
-  if (TARGET_INTERWORK || arm_arch4t)
+  if (TARGET_INTERWORK && arm_arch4)
+    output_asm_insn("add%!\tpc,pc,8", operands);
+    output_asm_insn("tst\t%0,#1", operands);
+    output_asm_insn("moveq\tpc,%0", operands);
+    output_asm_insn("bx\t%0", operands);
+  else if (TARGET_INTERWORK || arm_arch4t)
     output_asm_insn ("bx%?\t%0", operands);
   else
     output_asm_insn ("mov%?\t%|pc, %0", operands);
@@ -8525,7 +8530,16 @@
 const char *
 output_call_mem (rtx *operands)
 {
-  if (TARGET_INTERWORK && !arm_arch5)
+  if (TARGET_INTERWORK && arm_arch4)
+    {
+      output_asm_insn ("add%!\tpc,pc,#16", operands);
+      output_asm_insn ("ldr\t%|ip, %0", operands);
+      output_asm_insn ("mov\t%|lr, %|pc", operands);
+      output_asm_insn("tst\t%|lr,#1", operands);
+      output_asm_insn("moveq\t%|pc,%|lr", operands);
+      output_asm_insn ("bx\t%|ip", operands);
+    }
+  else if (TARGET_INTERWORK && !arm_arch5)
     {
       output_asm_insn ("ldr%?\t%|ip, %0", operands);
       output_asm_insn ("mov%?\t%|lr, %|pc", operands);
@@ -9580,26 +9594,44 @@
 	case ARM_FT_ISR:
 	case ARM_FT_FIQ:
 	  sprintf (instr, "sub%ss\t%%|pc, %%|lr, #4", conditional);
+	  output_asm_insn (instr, & operand);
 	  break;
 
 	case ARM_FT_INTERWORKED:
-	  sprintf (instr, "bx%s\t%%|lr", conditional);
+	  if (!arm_arch4)
+	    {
+	      sprintf (instr, "bx%s\t%%|lr", conditional);
+	      output_asm_insn (instr, & operand);
+	    }
+	  else
+	    {
+	      /* reverse the condition code */
+	      sprintf (conditional, "%%?%%%c0", reverse ? 'd' : 'D');
+	      sprintf (instr, "add%s\tpc,pc,8", conditional); /* marker */
+	      output_asm_insn (instr, & operand);
+
+	      output_asm_insn("tst\tlr,#1", &operands);
+	      output_asm_insn("moveq\tpc,lr", &operands);
+	      output_asm_insn("bx\tlr", &operands);
+	    }
 	  break;
 
 	case ARM_FT_EXCEPTION:
 	  sprintf (instr, "mov%ss\t%%|pc, %%|lr", conditional);
+	  output_asm_insn (instr, & operand);
 	  break;
 
 	default:
 	  /* Use bx if it's available.  */
 	  if (arm_arch5 || arm_arch4t)
-	    sprintf (instr, "bx%s\t%%|lr", conditional);
+	      sprintf (instr, "bx%s\t%%|lr", conditional);
 	  else
-	    sprintf (instr, "mov%s\t%%|pc, %%|lr", conditional);
+	      sprintf (instr, "mov%s\t%%|pc, %%|lr", conditional);
+
+	  output_asm_insn (instr, & operand);
 	  break;
 	}
 
-      output_asm_insn (instr, & operand);
     }
 
   return "";
@@ -10048,7 +10080,14 @@
       break;
 
     case ARM_FT_INTERWORKED:
-      asm_fprintf (f, "\tbx\t%r\n", LR_REGNUM);
+      if (!arm_arch4)
+	asm_fprintf (f, "\tbx\t%r\n", LR_REGNUM);
+      else
+	{
+	  asm_fprintf (f, "\ttst\t%r\n", LR_REGNUM);
+	  asm_fprintf (f, "\tmoveq\t%r,%r\n", PC_REGNUM, LR_REGNUM);
+	  asm_fprintf (f, "\tbx\t%r\n", LR_REGNUM);
+	}
       break;
 
     default:
@@ -10899,6 +10938,8 @@
 void
 arm_print_operand (FILE *stream, rtx x, int code)
 {
+  int inverting_condition_code = 0;
+
   switch (code)
     {
     case '@':
@@ -10913,9 +10954,14 @@
       fputs (REGISTER_PREFIX, stream);
       return;
 
+    case '!':
+      inverting_condition_code = 1;
+      /* intentional fallthrough */
     case '?':
       if (arm_ccfsm_state == 3 || arm_ccfsm_state == 4)
 	{
+	  char *const maybe_inverted_condition;
+
 	  if (TARGET_THUMB)
 	    {
 	      output_operand_lossage ("predicated Thumb instruction");
@@ -10928,11 +10974,17 @@
 	      break;
 	    }
 
-	  fputs (arm_condition_codes[arm_current_cc], stream);
+	  if (inverting_condition_code)
+	    maybe_inverted_condition =
+	      arm_condition_codes[ARM_INVERSE_CONDITION_CODE(arm_current_cc)];
+	  else
+	    maybe_inverted_condition = arm_condition_codes[arm_current_cc];
+	  fputs (maybe_inverted_condition, stream);
 	}
       else if (current_insn_predicate)
 	{
 	  enum arm_cond_code code;
+	  char *const maybe_inverted_condition;
 
 	  if (TARGET_THUMB)
 	    {
@@ -10941,7 +10993,12 @@
 	    }
 
 	  code = get_arm_condition_code (current_insn_predicate);
-	  fputs (arm_condition_codes[code], stream);
+	  if (inverting_condition_code)
+	    maybe_inverted_condition =
+	      arm_condition_codes[ARM_INVERSE_CONDITION_CODE(code)];
+	  else
+	    maybe_inverted_condition = arm_condition_codes[code];
+	  fputs (maybe_inverted_condition, stream);
 	}
       return;
 
Only in gcc-4.1.2-new/gcc/config/arm: arm.c.~1~
Only in gcc-4.1.2-new/gcc/config/arm: TAGS
Only in gcc-4.1.2-new/gcc/cp: TAGS
Only in gcc-4.1.2-new/gcc/cp: TAGS.sub
Only in gcc-4.1.2-new/gcc/java: TAGS
Only in gcc-4.1.2-new/gcc/java: TAGS.sub
Only in gcc-4.1.2-new/gcc/objc: TAGS
Only in gcc-4.1.2-new/gcc/objc: TAGS.sub
Only in gcc-4.1.2-new/gcc: TAGS


----- End forwarded message -----
Wookey
-- 
Principal hats:  Balloonz - Toby Churchill - Aleph One - Debian
http://wookware.org/



Reply to: