[PATCH] Fix for ldm/stm instructions in H8S
Asgari J. Jinia
AsgariJ@KPITCummins.com
Mon Nov 10 04:56:00 GMT 2003
Hi Kazu,
Thanks for your suggestion. The test for register validity suggested by you is simpler so we can go ahead with that. Please find attached a test program which was used for testing and results were found ok. Please find below patch.
Regards,
Asgari Jinia
------------------ Start Of Patch ---------------------------
2003-11-07 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 technical
note TN-H8*-193A/E from Renesas.
--- tc-h8300.old.c Fri Nov 7 17:59:46 2003
+++ tc-h8300.c Fri Nov 7 18:17:20 2003
@@ -622,14 +622,14 @@ 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 (!(low == 0 && (high == 1 || high == 2 || high == 3))
+ && !(low == 2 && high == 3)
+ && !(low == 4 && (high == 5 || high == 6)))
+ {
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 +1965,32 @@ md_assemble (str)
*op_end = c;
prev_instruction = instruction;
+ /* Now we have operands from instuction. Let's check them out for
+ ldm and stm. */
+ if (OP_KIND (instruction->opcode->how) == O_LDM)
+ {
+ /* The first operand must be @er7+, and the second operand must
+ be a 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)
+ {
+ /* The first operand must be a register pair, and the 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 ---------------------------
-----Original Message-----
From: Kazu Hirata [mailto:kazu@cs.umass.edu]
Sent: Thursday, November 06, 2003 4:24 AM
To: Asgari J. Jinia
Cc: binutils@sources.redhat.com
Subject: Re: [PATCH] Fix for ldm/stm instructions in H8S
Hi Asgari,
> 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.
What about a simpler test that checks all possibilities of low and
high (see attached)? Someone reading the code does not have to
decipher it.
By the way, I fixed minor things like formatting. Next time you
contribute something, please follow the GNU Coding Standards,
available at:
http://www.gnu.org/prep/standards_toc.html
I assume you actually fed some invalid code to get these error
messages. The patch looks good. I leave the approval up to other
people.
Otherwise
Kazu Hirata
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 technical
note TN-H8*-193A/E from Renesas.
Index: tc-h8300.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-h8300.c,v
retrieving revision 1.37
diff -c -r1.37 tc-h8300.c
*** tc-h8300.c 17 Oct 2003 10:23:33 -0000 1.37
--- tc-h8300.c 5 Nov 2003 22:36:46 -0000
***************
*** 622,635 ****
low = src[2] - '0';
high = src[6] - '0';
! if (high == low)
! as_bad (_("Invalid register list for ldm/stm\n"));
!
! if (high < 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
--- 622,635 ----
low = src[2] - '0';
high = src[6] - '0';
! /* Check register pair's validity as per tech note TN-H8*-193A/E
! from Renesas. */
! if (!(low == 0 && (high == 1 || high == 2 || high == 3))
! && !(low == 2 && high == 3)
! && !(low == 4 && (high == 5 || high == 6)))
! {
! 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,1970 ****
--- 1965,1995 ----
*op_end = c;
prev_instruction = instruction;
+ /* Now we have operands from instuction. Let's check them out for
+ ldm and stm. */
+ if (OP_KIND (instruction->opcode->how) == O_LDM)
+ {
+ /* The first operand must be @er7+, and the second operand must
+ be a 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)
+ {
+ /* The first operand must be a register pair, and the 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)
{
-------------- next part --------------
A non-text attachment was scrubbed...
Name: main.s
Type: application/octet-stream
Size: 1049 bytes
Desc: main.s
URL: <https://sourceware.org/pipermail/binutils/attachments/20031110/fd0ec29b/attachment.obj>
More information about the Binutils
mailing list