From 4892e510641d3b60d7bda1d59909c2e6c187078d Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 25 Nov 2003 16:13:36 +0000 Subject: [PATCH] Catch illegal register pairings in ldm/stm instructions. Update test files to avoid illegal pairings. --- gas/ChangeLog | 7 ++++++ gas/config/tc-h8300.c | 37 +++++++++++++++++++++++------ gas/testsuite/ChangeLog | 8 +++++++ gas/testsuite/gas/h8300/h8300.exp | 9 ++++++- gas/testsuite/gas/h8300/multiples.s | 7 ++++++ gas/testsuite/gas/h8300/t01_mov.exp | 16 ++++++------- gas/testsuite/gas/h8300/t01_mov.s | 4 ++-- 7 files changed, 70 insertions(+), 18 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index b3b757a8798..03c79a7b24a 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2003-11-25 Asgari Jinia + + * 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 for H8s and for H8Sx manual. + 2003-11-24 Kazu Hirata * listing.c: Convert to ISO-C. diff --git a/gas/config/tc-h8300.c b/gas/config/tc-h8300.c index d518acae55f..73e73c93347 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) { diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 21bc55e9174..5b013e9ef36 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2003-11-25 Asgari Jinia + + * gas/h8300/multiples.s : Add instructions for H8s. + * gas/h8300/h8300.exp (do_h8300s_multiple) : Add more test + conditions for instructions for H8s. + * gas/h8300/t01_mov.s: Correct illegal ldm/stm register pairings. + * gas/h8300/t01_mov.exp: Update expected results. + 2003-11-22 Alan Modra * gas/i386/divide.s: New. diff --git a/gas/testsuite/gas/h8300/h8300.exp b/gas/testsuite/gas/h8300/h8300.exp index a34876e019c..a13c16aa347 100644 --- a/gas/testsuite/gas/h8300/h8300.exp +++ b/gas/testsuite/gas/h8300/h8300.exp @@ -2070,6 +2070,13 @@ proc do_h8300s_multiple {} { -re " +\[0-9\]+ 000c 01106DF0\[^\n\]*\n" { set x [expr $x+1] } -re " +\[0-9\]+ 0010 01206DF0\[^\n\]*\n" { set x [expr $x+1] } -re " +\[0-9\]+ 0014 01306DF0\[^\n\]*\n" { set x [expr $x+1] } + -re " +\[0-9\]+ 0018 01106D73\[^\n\]*\n" { set x [expr $x+1] } + -re " +\[0-9\]+ 001c 01106DF2\[^\n\]*\n" { set x [expr $x+1] } + -re " +\[0-9\]+ 0020 01106D75\[^\n\]*\n" { set x [expr $x+1] } + -re " +\[0-9\]+ 0024 01206D76\[^\n\]*\n" { set x [expr $x+1] } + -re " +\[0-9\]+ 0028 01106DF4\[^\n\]*\n" { set x [expr $x+1] } + -re " +\[0-9\]+ 002c 01206DF4\[^\n\]*\n" { set x [expr $x+1] } + eof { break } } } @@ -2079,7 +2086,7 @@ proc do_h8300s_multiple {} { gas_finish # Did we find what we were looking for? If not, flunk it. - if [expr $x == 6] then { pass $testname } else { fail $testname } + if [expr $x == 12] then { pass $testname } else { fail $testname } } proc do_h8300h_mov32bug {} { diff --git a/gas/testsuite/gas/h8300/multiples.s b/gas/testsuite/gas/h8300/multiples.s index 52079b6d219..658f79294ac 100644 --- a/gas/testsuite/gas/h8300/multiples.s +++ b/gas/testsuite/gas/h8300/multiples.s @@ -7,4 +7,11 @@ h8300s_multiple: stm.l er0-er1,@-sp stm.l er0-er2,@-sp stm.l er0-er3,@-sp + ldm.l @sp+,er2-er3 + stm.l er2-er3,@-sp + ldm.l @sp+,er4-er5 + ldm.l @sp+,er4-er6 + stm.l er4-er5,@-sp + stm.l er4-er6,@-sp + diff --git a/gas/testsuite/gas/h8300/t01_mov.exp b/gas/testsuite/gas/h8300/t01_mov.exp index 802fde3c55f..40a943d4472 100644 --- a/gas/testsuite/gas/h8300/t01_mov.exp +++ b/gas/testsuite/gas/h8300/t01_mov.exp @@ -11,7 +11,7 @@ proc do_t01_mov_test {} { set x 0 expect { - -re ".* 7 0000 F312" { set x [expr $x+1]; exp_continue; } + -re ".* 7 0000 F312" { set x [expr $x+1]; exp_continue; } -re ".* 8 0002 017D0312" { set x [expr $x+1]; exp_continue; } -re ".* 9 0006 017D1312" { set x [expr $x+1]; exp_continue; } -re ".* 10 000a 017DB312" { set x [expr $x+1]; exp_continue; } @@ -19,15 +19,15 @@ proc do_t01_mov_test {} { -re ".* 12 0012 017DA312" { set x [expr $x+1]; exp_continue; } -re ".* 13 0016 017D9312" { set x [expr $x+1]; exp_continue; } -re ".* 14 001a 017DC312" { set x [expr $x+1]; exp_continue; } - -re ".* 14 1234" { set x [expr $x+1]; exp_continue; } + -re ".* 14 1234" { set x [expr $x+1]; exp_continue; } -re ".* 15 0020 017DCB12" { set x [expr $x+1]; exp_continue; } -re ".* 15 12345678" { set x [expr $x+1]; exp_continue; } -re ".* 16 0028 017DD312" { set x [expr $x+1]; exp_continue; } - -re ".* 16 1234" { set x [expr $x+1]; exp_continue; } + -re ".* 16 1234" { set x [expr $x+1]; exp_continue; } -re ".* 17 002e 017DE312" { set x [expr $x+1]; exp_continue; } - -re ".* 17 1234" { set x [expr $x+1]; exp_continue; } + -re ".* 17 1234" { set x [expr $x+1]; exp_continue; } -re ".* 18 0034 017DF312" { set x [expr $x+1]; exp_continue; } - -re ".* 18 1234" { set x [expr $x+1]; exp_continue; } + -re ".* 18 1234" { set x [expr $x+1]; exp_continue; } -re ".* 19 003a 017DDB12" { set x [expr $x+1]; exp_continue; } -re ".* 19 12345678" { set x [expr $x+1]; exp_continue; } -re ".* 20 0042 017DEB12" { set x [expr $x+1]; exp_continue; } @@ -35,7 +35,7 @@ proc do_t01_mov_test {} { -re ".* 21 004a 017DFB12" { set x [expr $x+1]; exp_continue; } -re ".* 21 12345678" { set x [expr $x+1]; exp_continue; } -re ".* 22 0052 017D4012" { set x [expr $x+1]; exp_continue; } - -re ".* 22 1234" { set x [expr $x+1]; exp_continue; } + -re ".* 22 1234" { set x [expr $x+1]; exp_continue; } -re ".* 23 0058 017D4812" { set x [expr $x+1]; exp_continue; } -re ".* 23 12345678" { set x [expr $x+1]; exp_continue; } -re ".* 24 " { @@ -2890,7 +2890,7 @@ proc do_t01_mov_test {} { -re ".* 1067 1c60 01306D74" { set x [expr $x+1]; exp_continue; } -re ".* 1068 1c64 01306D75" { set x [expr $x+1]; exp_continue; } -re ".* 1069 1c68 01306D76" { set x [expr $x+1]; exp_continue; } - -re ".* 1070 1c6c 01306D77" { set x [expr $x+1]; exp_continue; } + -re ".* 1070 1c6c 01206D77" { set x [expr $x+1]; exp_continue; } -re ".* 1071 " { if [expr $x == 5] then { pass "$testname: ldm @sp+,(er0-er3)" @@ -2944,7 +2944,7 @@ proc do_t01_mov_test {} { -re ".* 1088 1ca8 01306DF1" { set x [expr $x+1]; exp_continue; } -re ".* 1089 1cac 01306DF2" { set x [expr $x+1]; exp_continue; } -re ".* 1090 1cb0 01306DF3" { set x [expr $x+1]; exp_continue; } - -re ".* 1091 1cb4 01306DF4" { set x [expr $x+1]; exp_continue; } + -re ".* 1091 1cb4 01206DF5" { set x [expr $x+1]; exp_continue; } -re ".* 1092 " { if [expr $x == 5] then { pass "$testname: stm (er0-er3),@-sp" diff --git a/gas/testsuite/gas/h8300/t01_mov.s b/gas/testsuite/gas/h8300/t01_mov.s index c8d35de7564..606fee7d6cb 100644 --- a/gas/testsuite/gas/h8300/t01_mov.s +++ b/gas/testsuite/gas/h8300/t01_mov.s @@ -1067,7 +1067,7 @@ _start: ldm @sp+,(er1-er4) ;01306d74 ldm @sp+,(er2-er5) ;01306d75 ldm @sp+,(er3-er6) ;01306d76 - ldm @sp+,(er4-er7) ;01306d77 + ldm @sp+,(er5-er7) ;01206d77 stm (er0-er1),@-sp ;01106df0 stm (er1-er2),@-sp ;01106df1 @@ -1088,7 +1088,7 @@ _start: stm (er1-er4),@-sp ;01306df1 stm (er2-er5),@-sp ;01306df2 stm (er3-er6),@-sp ;01306df3 - stm (er4-er7),@-sp ;01306df4 + stm (er5-er7),@-sp ;01206df5 eepmov.b ;7b5c598f -- 2.30.2