This is the mail archive of the binutils@sources.redhat.com 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]

[PATCH] Fix for ldm/stm instructions in H8S


Hi,
Please find below a patch for H8 assembler which fixes few bugs for ldm/stm instructions for H8S.
Description:

1. For LDM the first operand cannot be register list and for STM.L second operand cannot be register list. 
   At present the assembler accepts this.
2. In LDM first operand must be @er7+ and in STM second operand must be @-er7. At present it accepts other 
   than er7.
3. According to technical note ( TN-H8*-193A/E ) by Renesas available at 
   http://www.eu.renesas.com/documents/mpumcu/tech/h8193e.pdf , er7 cannot be used in register list with 
   LDM/STM instructions. It checks register pair as per this technical note.

Regards,
Asgari Jinia

-------------------- Start Of Patch -------------------------------
gas/Changelog-
2003-11-05 Asgari Jinia <asgarij@kpitcummins.com>
	* config/tc-h8300.c (md_assemble) : Check operands validity for ldm/stm.
	(get_operand) : Check register pair's validity as per tech note TN-H8*-193A/E from Renesas.


--- gas/config/tc-h8300.old.c	Fri Oct 17 15:53:34 2003
+++ gas/config/tc-h8300.c	Wed Nov  5 16:44:31 2003
@@ -622,14 +622,13 @@ get_operand (ptr, op, direction)
       low = src[2] - '0';
       high = src[6] - '0';
 
-      if (high == low)
-	as_bad (_("Invalid register list for ldm/stm\n"));
-
-      if (high < low)
+      /*check register pair's validity as per tech note TN-H8*-193A/E
+        from Renesas*/
+      if ((high <= low) || (high - low > 3) || (low % 2) || (low > 4)
+           || ((high - low == 2) && (low % 4)) || ((high - low == 3) && low))
+        {
 	as_bad (_("Invalid register list for ldm/stm\n"));
-
-      if (high - low > 3)
-	as_bad (_("Invalid register list for ldm/stm)\n"));
+        }
 
       /* Even sicker.  We encode two registers into op->reg.  One
 	 for the low register to save, the other for the high
@@ -1965,6 +1964,25 @@ md_assemble (str)
   *op_end = c;
   prev_instruction = instruction;
 
+  /* now we have operands from instuction. Lets check out them for ldm and stm*/
+  if (OP_KIND (instruction->opcode->how) == O_LDM)
+    {
+      /*first operand must be @er7+ and second operand must be register pair*/
+      if ((operand[0].mode != RSINC) || (operand[0].reg != 7) || ((operand[1].reg & 0x80000000) == 0))
+        {
+          as_bad (_("invalid operand in ldm"));
+        }
+    }
+
+  if (OP_KIND (instruction->opcode->how) == O_STM)
+    {
+      /*first operand must be register pair and second operand must be @-er7 */
+      if (((operand[0].reg & 0x80000000) == 0) || (operand[1].mode != RDDEC) || (operand[1].reg != 7))
+        {
+          as_bad (_("invalid operand in stm"));
+        }
+    }
+
   size = SN;
   if (dot)
     {
-------------------- End Of Patch -------------------------------



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