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

[openrisc] Patches for or1ksim -- addc support



Hi everybody,

existing version of or1ksim does not support "add with carry"
instructions, and generates an illegal instruction exception when it
runs over such opcode.

I've just finished gcc modifications to generate "l.addc" when adding
64-bit values, so support on or1ksim is needed as well. Here are the
patches. If everything is right I will commit them to CVS.

Best regards,

	Carlos


diff -Naur or1k-old/or1ksim/cpu/or1k/opcode/or32.h or1k/or1ksim/cpu/or1k/opcode/or32.h
--- or1k-old/or1ksim/cpu/or1k/opcode/or32.h	2003-07-01 12:14:03.000000000 +0200
+++ or1k/or1ksim/cpu/or1k/opcode/or32.h	2003-07-01 12:15:29.000000000 +0200
@@ -104,6 +104,7 @@
 extern void l_sfne PARAMS((void));
 extern void l_bf PARAMS((void));
 extern void l_add PARAMS((void));
+extern void l_addc PARAMS((void));
 extern void l_sw PARAMS((void));
 extern void l_sb PARAMS((void));
 extern void l_sh PARAMS((void));
diff -Naur or1k-old/or1ksim/cpu/or32/execgen.c or1k/or1ksim/cpu/or32/execgen.c
--- or1k-old/or1ksim/cpu/or32/execgen.c	2003-07-01 12:14:03.000000000 +0200
+++ or1k/or1ksim/cpu/or32/execgen.c	2003-07-01 12:15:47.000000000 +0200
@@ -5350,17 +5350,23 @@
             tmp = ((insn  >> 11) & 0x0000001f) << 0;
             c = tmp;
             {   /* "l_add" */
-              signed long temp1;
+              signed long temp1, temp2, temp3;
               signed char temp4;
               
               IFF (config.cpu.dependstats) current->func_unit = it_arith;  
-              temp1 = (signed long)(reg[c])+(signed long)(reg[b]);
+              temp2 = (signed long)(reg[c]);
+	      temp3 = (signed long)(reg[b]);
+	      temp1 = temp2 + temp3;
               reg[a] = ( temp1);
               set_ov_flag (temp1);
               if (ARITH_SET_FLAG) {
                 flag = temp1 == 0;
                 setsprbits(SPR_SR, SPR_SR_F, flag);
               }
+	      if ((unsigned long) temp1 < (unsigned long) temp2)
+		      setsprbits(SPR_SR, SPR_SR_CY, 1);
+	      else
+		      setsprbits(SPR_SR, SPR_SR_CY, 0);
             
               temp4 = temp1;
               if (temp4 == temp1)
@@ -5402,7 +5408,27 @@
             tmp = ((insn  >> 11) & 0x0000001f) << 0;
             c = tmp;
             {
-              l_invalid ();
+              signed long temp1, temp2, temp3;
+	      signed char temp4;
+
+	      IFF (config.cpu.dependstats) current->func_unit = it_arith;
+	      temp2 = (signed long)(reg[c]);
+	      temp3 = (signed long)(reg[b]);
+	      temp1 = temp2 + temp3 + getsprbits(SPR_SR, SPR_SR_CY);
+	      reg[a] = ( temp1 );
+	      set_ov_flag (temp1);
+	      if (ARITH_SET_FLAG) {
+	        flag = temp1 == 0;
+		setsprbits(SPR_SR, SPR_SR_F, flag);
+	      }
+	      if ((unsigned long) temp1 < (unsigned long) temp2)
+		setsprbits(SPR_SR, SPR_SR_CY, 1);
+	      else
+		setsprbits(SPR_SR, SPR_SR_CY, 0);
+
+	      temp4 = temp1;
+	      if (temp4 == temp1)
+	        mstats.byteadd++;
             }
             if (do_stats) {
               num_op = 3;
diff -Naur or1k-old/or1ksim/cpu/or32/insnset.c or1k/or1ksim/cpu/or32/insnset.c
--- or1k-old/or1ksim/cpu/or32/insnset.c	2003-07-01 12:14:03.000000000 +0200
+++ or1k/or1ksim/cpu/or32/insnset.c	2003-07-01 12:16:06.000000000 +0200
@@ -19,17 +19,46 @@
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 INSTRUCTION (l_add) {
-  signed long temp1;
+  signed long temp1i, temp2, temp3;
   signed char temp4;
   
   IFF (config.cpu.dependstats) current->func_unit = it_arith;  
-  temp1 = (signed long)eval_operand32(2, &breakpoint)+(signed long)eval_operand32(1, &breakpoint);
+  temp2 = (signed long)eval_operand32(2, &breakpoint);
+  temp3 = (signed long)eval_operand32(1, &breakpoint);
+  temp1 = temp2 + temp3;
   set_operand32(0, temp1, &breakpoint);
   set_ov_flag (temp1);
   if (ARITH_SET_FLAG) {
     flag = temp1 == 0;
     setsprbits(SPR_SR, SPR_SR_F, flag);
   }
+  if ((unsigned long) temp1 < (unsigned long) temp2)
+	  setsprbits(SPR_SR, SPR_SR_CY, 1);
+  else
+	  setsprbits(SPR_SR, SPR_SR_CY, 0);
+
+  temp4 = temp1;
+  if (temp4 == temp1)
+    mstats.byteadd++;
+}
+INSTRUCTION (l_addc) {
+  signed long temp1, temp2, temp3;
+  signed char temp4;
+  
+  IFF (config.cpu.dependstats) current->func_unit = it_arith;
+  temp2 = (signed long)eval_operand32(2, &breakpoint);
+  temp3 = (signed long)eval_operand32(1, &breakpoint);
+  temp1 = temp2 + temp3 + getsprbits(SPR_SR, SPR_SR_CY);
+  set_operand32(0, temp1, &breakpoint);
+  set_ov_flag (temp1);
+  if (ARITH_SET_FLAG) {
+    flag = temp1 == 0;
+    setsprbits(SPR_SR, SPR_SR_F, flag);
+  }
+  if ((unsigned long) temp1 < (unsigned long) temp2)
+	setsprbits(SPR_SR, SPR_SR_CY, 1);
+  else
+	setsprbits(SPR_SR, SPR_SR_CY, 0);
 
   temp4 = temp1;
   if (temp4 == temp1)
diff -Naur or1k-old/or1ksim/cpu/or32/or32.c or1k/or1ksim/cpu/or32/or32.c
--- or1k-old/or1ksim/cpu/or32/or32.c	2003-07-01 12:14:03.000000000 +0200
+++ or1k/or1ksim/cpu/or32/or32.c	2003-07-01 12:16:16.000000000 +0200
@@ -285,7 +285,7 @@
 { "l.sh",      "I(rA),rB",     "11 0x7  IIIII AAAAA BBBB BIII IIII IIII", EF(l_sh), 0 },
 
 { "l.add",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x0", EF(l_add), OR32_W_FLAG },
-{ "l.addc",    "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x1", EFI, 0 },
+{ "l.addc",    "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x1", EF(l_addc), OR32_W_FLAG },
 { "l.sub",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x2", EF(l_sub), 0 },
 { "l.and",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x3", EF(l_and), OR32_W_FLAG },
 { "l.or",      "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x4", EF(l_or), 0 },

Esta parte del mensaje esta firmada digitalmente