This is for PR 628.
authorIan Lance Taylor <ian@airs.com>
Wed, 19 Aug 1992 18:27:48 +0000 (18:27 +0000)
committerIan Lance Taylor <ian@airs.com>
Wed, 19 Aug 1992 18:27:48 +0000 (18:27 +0000)
Wed Aug 19 11:20:59 1992  Ian Lance Taylor  (ian@cygnus.com)

* tc-m68k.c, tc-m68kmote.c: the cas2 instruction is supposed to be
written with indirection on the last two operands, which can be
either data or address registers.  Added a new operand type 'r'
which accepts either register type.  Added '(' to notend stuff in
tc-m68kmote.c to accept (a0):(a2) in cas2 instruction.

gas/config/ChangeLog
gas/config/tc-m68k.c
gas/config/tc-m68kmote.c

index 712a82f5811b098d4252f28f39220991120ea483..15b26a73c710d193a46fe6b25f09afa4954fc9ac 100644 (file)
@@ -1,3 +1,11 @@
+Wed Aug 19 11:20:59 1992  Ian Lance Taylor  (ian@cygnus.com)
+
+       * tc-m68k.c, tc-m68kmote.c: the cas2 instruction is supposed to be
+       written with indirection on the last two operands, which can be
+       either data or address registers.  Added a new operand type 'r'
+       which accepts either register type.  Added '(' to notend stuff in
+       tc-m68kmote.c to accept (a0):(a2) in cas2 instruction.
+
 Tue Aug 11 12:58:14 1992  Ken Raeburn  (raeburn@cygnus.com)
 
        * sparc.mt: New file.
@@ -12,7 +20,6 @@ Thu Aug  6 12:08:42 1992  Steve Chamberlain  (sac@thepub.cygnus.com)
        * config/tc-h8300.c: if a :8 is seen after an operand, fill top
        two bytes of any constant with 0xff:
 
-
 Wed Aug  5 01:54:34 1992  John Gilmore  (gnu at cygnus.com)
 
        * tc-m68k.c (try_index):  Error if index scaling specified and
index 0c60c77231320ef463a072e02371b4d460a7a7b9..c3d1b19e7b4e017866c65ecd7a9769856b833f8f 100644 (file)
@@ -117,6 +117,7 @@ static struct obstack robyn;
    *** MSCR  otherreg                  --> Magic
    With -l option
    5.? AOFF  apc@(num)                 --> *(apc+num) -- empty string and ZPC not allowed here still
+   ?.? DINDR dreg@                     --> (dreg) -- cas2 only
 
    examples:
    #foo        #0x35   #12
@@ -151,6 +152,7 @@ enum operand_type {
        ABSL,
        MSCR,
        REGLST,
+       DINDR
 };
 
 
@@ -665,7 +667,9 @@ register struct m68k_op *opP;
                return OK;
        }
 
-       if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) {      /* Can't indirect off non address regs */
+       /* Can't indirect off non address regs, but Dx@ is OK for cas2 */
+       if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL
+          && (str[1] != '\0' || i<DATA+0 || i>DATA+7)) {
                opP->error="Invalid indirect register";
                return FAIL;
        }
@@ -674,7 +678,10 @@ register struct m68k_op *opP;
        str++;
        switch(*str) {
        case '\0':
-               opP->mode=AINDR;
+               if (i < DATA + 0 || i > DATA + 7)
+                 opP->mode=AINDR;
+               else
+                 opP->mode=DINDR;
                return OK;
        case '-':
                opP->mode=ADEC;
@@ -1294,6 +1301,11 @@ void m68k_ip (instring)
            losing++;
          break;
 
+       case 'r':
+         if (opP->mode!=AINDR && opP->mode!=DINDR)
+           losing++;
+         break;
+
        case 's':
          if(opP->mode!=MSCR || !(opP->reg==FPI || opP->reg==FPS || opP->reg==FPC))
            losing++;
@@ -1809,6 +1821,9 @@ void m68k_ip (instring)
          break;
        }
        break;
+      case DINDR:
+       as_bad("invalid indirect register");
+       break;
       case MSCR:
       default:
        as_bad("unknown/incorrect operand");
@@ -2090,6 +2105,7 @@ void m68k_ip (instring)
       break;
 
     case 'R':
+    case 'r':
       /* This depends on the fact that ADDR registers are
         eight more than their corresponding DATA regs, so
         the result will have the ADDR_REG bit set */
index dd18c7ee29feecadcaf2f315e5e15b1d3d111c69..d8e93b07b4c4eabd9431a7aa2c8cd0fddf95198b 100644 (file)
@@ -123,6 +123,7 @@ static struct obstack robyn;
    *** MSCR  otherreg                  --> Magic
    With -l option
    5.? AOFF  apc@(num)                 --> *(apc+num) -- empty string and ZPC not allowed here still
+   ?.? DINDR dreg@                     --> (dreg) -- cas2 only
    
    examples:
    #foo        #0x35   #12
@@ -157,6 +158,7 @@ enum operand_type {
        ABSL,
        MSCR,
        REGLST,
+       DINDR
 };
 
 
@@ -933,8 +935,10 @@ register struct m68k_op *opP;
        if(*str=='(') {
                str++;
                i=m68k_reg_parse(&str);
-               if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) {      
-                       /* Can't indirect off non address regs */
+               if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL
+                  && (*str != ')' || str[1] != '\0' || i<DATA+0 || i>DATA+7)) {
+                       /* Can't indirect off non address regs,
+                          but (dx) is OK for cas2.  */
                        opP->error="Invalid indirect register";
                        return FAIL;
                }
@@ -943,8 +947,12 @@ register struct m68k_op *opP;
                        if(*str==')') {
                                str++;
                                if(*str=='\0') {
-                                       /* "(An)"  Address Register Indirect mode */
-                                       opP->mode=AINDR;
+                                       /* "(An)"  Address Register Indirect mode
+                                          or "(Dn)" for cas2 instruction.  */
+                                       if (i < DATA + 0 || i > DATA + 7)
+                                         opP->mode=AINDR;
+                                       else
+                                         opP->mode=DINDR;
                                        return OK;
                                }
                                if(*str=='+') {
@@ -1209,7 +1217,9 @@ register struct m68k_op *opP;
                return OK;
        }
        
-       if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) {      /* Can't indirect off non address regs */
+       /* Can't indirect off non address regs, but Dx@ is OK for cas2 */
+       if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL
+          && (str[1] != '\0' || i<DATA+0 || i>DATA+7)) {
                opP->error="Invalid indirect register";
                return FAIL;
        }
@@ -1218,7 +1228,10 @@ register struct m68k_op *opP;
        str++;
        switch(*str) {
        case '\0':
-               opP->mode=AINDR;
+               if (i < DATA + 0 || i > DATA + 7)
+                 opP->mode=AINDR;
+               else
+                 opP->mode=DINDR;
                return OK;
        case '-':
                opP->mode=ADEC;
@@ -1863,6 +1876,11 @@ char *instring;
                                            losing++;
                                        break;
                                        
+                               case 'r':
+                                       if(opP->mode!=AINDR && opP->mode!=DINDR)
+                                         losing++;
+                                       break;
+
                                case 's':
                                        if(opP->mode!=MSCR || !(opP->reg==FPI || opP->reg==FPS || opP->reg==FPC))
                                            losing++;
@@ -2327,6 +2345,9 @@ char *instring;
                                        break;
                                }
                                break;
+                       case DINDR:
+                               as_bad("invalid indirect register");
+                               break;
                        case MSCR:
                        default:
                                as_bad("unknown/incorrect operand");
@@ -2608,6 +2629,7 @@ char *instring;
                        break;
                        
                case 'R':
+               case 'r':
                        /* This depends on the fact that ADDR registers are
                           eight more than their corresponding DATA regs, so
                           the result will have the ADDR_REG bit set */
@@ -3015,7 +3037,7 @@ char *s;
            return 0;
        if(*s!=':') return 1;
        /* This kludge here is for the division cmd, which is a kludge */
-       if(index("aAdD#",s[1])) return 0;
+       if(index("aAdD#(",s[1])) return 0;
        return 1;
 }
 #endif
@@ -3296,6 +3318,7 @@ void
        alt_notend_table['#'] = 1;
        alt_notend_table['f'] = 1;
        alt_notend_table['F'] = 1;
+       alt_notend_table['('] = 1;
        
 #ifdef REGISTER_PREFIX
        alt_notend_table[REGISTER_PREFIX] = 1;
@@ -3306,7 +3329,7 @@ void
 
 #if 0
 #define notend(s) ((*s == ',' || *s == '}' || *s == '{' \
-                   || (*s == ':' && strchr("aAdD#", s[1]))) \
+                   || (*s == ':' && strchr("aAdD#(", s[1]))) \
                   ? 0 : 1)
 #endif