diff options
author | Nick Clifton <nickc@redhat.com> | 2003-11-25 16:13:36 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2003-11-25 16:13:36 +0000 |
commit | 4892e510641d3b60d7bda1d59909c2e6c187078d (patch) | |
tree | 723a5d1cc3113a76daed4ff81eb9a4ba22ed0fca /gas/config/tc-h8300.c | |
parent | aff6338aa94b864c1023667204ba26874599b662 (diff) | |
download | binutils-4892e510641d3b60d7bda1d59909c2e6c187078d.zip binutils-4892e510641d3b60d7bda1d59909c2e6c187078d.tar.gz binutils-4892e510641d3b60d7bda1d59909c2e6c187078d.tar.bz2 |
Catch illegal register pairings in ldm/stm instructions.
Update test files to avoid illegal pairings.
Diffstat (limited to 'gas/config/tc-h8300.c')
-rw-r--r-- | gas/config/tc-h8300.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/gas/config/tc-h8300.c b/gas/config/tc-h8300.c index d518aca..73e73c9 100644 --- a/gas/config/tc-h8300.c +++ b/gas/config/tc-h8300.c @@ -598,15 +598,17 @@ get_operand (char **ptr, struct h8_op *op, int direction) low = src[2] - '0'; high = src[6] - '0'; - if (high == low) + /* Check register pair's validity as per tech note TN-H8*-193A/E + from Renesas for H8S and H8SX hardware manual. */ + if ( !(low == 0 && (high == 1 || high == 2 || high == 3)) + && !(low == 1 && (high == 2 || high == 3 || high == 4) && SXmode) + && !(low == 2 && (high == 3 || ((high == 4 || high == 5) && SXmode))) + && !(low == 3 && (high == 4 || high == 5 || high == 6) && SXmode) + && !(low == 4 && (high == 5 || high == 6)) + && !(low == 5 && (high == 6 || high == 7) && SXmode) + && !(low == 6 && high == 7 && SXmode)) 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 register to save; we also set the high bit in op->reg @@ -1924,6 +1926,27 @@ md_assemble (char *str) *op_end = c; prev_instruction = instruction; + /* Now we have operands from instruction. + 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")); + } + else 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) { |