Ensure we null-terminate the string we copy at the start of
authorMichael Tiemann <tiemann@cygnus>
Sun, 24 Nov 1991 17:24:52 +0000 (17:24 +0000)
committerMichael Tiemann <tiemann@cygnus>
Sun, 24 Nov 1991 17:24:52 +0000 (17:24 +0000)
m68k_reg_parse.

gas/config/tc-m68k.c

index 3b9f7dc4c0805bdef5fe2fd8c6592939e1741008..546e5381ae6e35794feec82c3229d249c0aaff67 100644 (file)
@@ -314,8 +314,11 @@ struct m68k_it {
        } reloc[5];             /* Five is enough??? */
 };
 
+#define cpu_of_arch(x)         ((x) & m68000up)
+#define float_of_arch(x)       ((x) & mfloat)
+#define mmu_of_arch(x)         ((x) & mmmu)
+
 static struct m68k_it the_ins;         /* the instruction being assembled */
-static enum m68k_architecture max_arch_this_insn;
 
 /* Macros for adding things to the m68k_it struct */
 
@@ -412,14 +415,7 @@ static void s_proc();
 
 #endif /* __STDC__ */
 
-static enum m68k_architecture current_architecture = m68020
-#ifndef NO_68881
-    | m68881
-#endif
-#ifndef NO_68851
-    | m68851
-#endif
-    ;
+static enum m68k_architecture current_architecture = 0;
 
 /* BCC68000 is for patching in an extra jmp instruction for long offsets
    on the 68000.  The 68000 doesn't support long branches with branchs */
@@ -558,9 +554,16 @@ register char **ccp;
        } /* need prefix */
 #endif
 
-       for (p = c, q = ccp[0]; p < c + MAX_REG_NAME_LEN && *q != 0; ++p, ++q) {
-               *p = mklower(*q);
-       } /* downcase */
+       for (p = c, q = ccp[0]; p < c + MAX_REG_NAME_LEN; ++p, ++q)
+         {
+           if (*q == 0)
+             {
+               *p = 0;
+               break;
+             }
+           else
+             *p = mklower(*q);
+         } /* downcase */
 
        switch(c[0]) {
        case 'a':
@@ -835,38 +838,37 @@ register struct m68k_op *opP;
 
                if(i!=FAIL && (*str=='/' || *str=='-')) {
                        opP->mode=REGLST;
-                       return get_regs(i,str,opP);
+                       return(get_regs(i,str,opP));
                }
                if ((stmp=strchr(str,'@')) != '\0') {
                        opP->con1=add_exp(str,stmp-1);
                        if(stmp==strend) {
                                opP->mode=AINDX;
-                               return OK;
+                               return(OK);
                        }
+
+                       if ((current_architecture & m68020up) == 0) {
+                               return(FAIL);
+                       } /* if target is not a '20 or better */
+
                        stmp++;
                        if(*stmp++!='(' || *strend--!=')') {
                                opP->error="Malformed operand";
-                               return FAIL;
+                               return(FAIL);
                        }
                        i=try_index(&stmp,opP);
                        opP->con2=add_exp(stmp,strend);
                        
                        if (i == FAIL) {
                                opP->mode=AMIND;
-                               if (max_arch_this_insn < m68020) {
-                                       max_arch_this_insn = m68020;
-                               } /* bump arch */
                        } else {
                                opP->mode=APODX;
-                               if (max_arch_this_insn < m68020) {
-                                       max_arch_this_insn = m68020;
-                               } /* bump arch */
                        }
-                       return OK;
+                       return(OK);
                } /* if there's an '@' */
-               opP->mode=ABSL;
-               opP->con1=add_exp(str,strend);
-               return OK;
+               opP->mode = ABSL;
+               opP->con1 = add_exp(str,strend);
+               return(OK);
        } /* not a register, not exactly a register, or no '@' */
 
        opP->reg=i;
@@ -957,89 +959,84 @@ register struct m68k_op *opP;
        }
                /* We've now got offset)   offset,reg)   or    reg) */
 
-       if(*str=='\0') {
+       if (*str == '\0') {
                /* Th-the-thats all folks */
-               if(opP->reg==FAIL) opP->mode=AINDX;     /* Other form of indirect */
-               else if(opP->ireg==FAIL) opP->mode=AOFF;
-               else opP->mode=AINDX;
-               return OK;
+               if (opP->reg == FAIL) opP->mode = AINDX;        /* Other form of indirect */
+               else if(opP->ireg == FAIL) opP->mode = AOFF;
+               else opP->mode = AINDX;
+               return(OK);
        }
                /* Next thing had better be another @ */
        if(*str!='@' || str[1]!='(') {
-               opP->error="junk after indirect";
-               return FAIL;
+               opP->error = "junk after indirect";
+               return(FAIL);
        }
+       
+       if ((current_architecture & m68020up) == 0) {
+               return(FAIL);
+       } /* if target is not a '20 or better */
+
        str+=2;
-       if(opP->ireg!=FAIL) {
-               opP->mode=APRDX;
-               
-               if (max_arch_this_insn < m68020) {
-                       max_arch_this_insn = m68020;
-               } /* bump arch */
-               
-               i=try_index(&str,opP);
-               if(i!=FAIL) {
-                       opP->error="Two index registers!  not allowed!";
-                       return FAIL;
+
+       if(opP->ireg != FAIL) {
+               opP->mode = APRDX;
+
+               i = try_index(&str, opP);
+               if (i != FAIL) {
+                       opP->error = "Two index registers!  not allowed!";
+                       return(FAIL);
                }
-       } else
-               i=try_index(&str,opP);
+       } else {
+               i = try_index(&str, opP);
+       }
 
        if (i == FAIL) {
                char *beg_str;
 
-               beg_str=str;
-               for(i=1;i;) {
+               beg_str = str;
+
+               for (i = 1; i; ) {
                        switch(*str++) {
                        case '\0':
                                opP->error="Missing )";
-                               return FAIL;
+                               return(FAIL);
                        case ',': i=0; break;
                        case '(': i++; break;
                        case ')': --i; break;
                        }
                }
+
                opP->con2=add_exp(beg_str,str-2);
-               if(str[-1]==',') {
-                       if(opP->ireg!=FAIL) {
-                               opP->error="Can't have two index regs";
-                               return FAIL;
+
+               if (str[-1] == ',') {
+                       if (opP->ireg != FAIL) {
+                               opP->error = "Can't have two index regs";
+                               return(FAIL);
                        }
-                       i=try_index(&str,opP);
-                       if(i==FAIL) {
-                               opP->error="malformed index reg";
-                               return FAIL;
+
+                       i = try_index(&str, opP);
+
+                       if (i == FAIL) {
+                               opP->error = "malformed index reg";
+                               return(FAIL);
                        }
-                       opP->mode=APODX;
-                       if (max_arch_this_insn < m68020) {
-                               max_arch_this_insn = m68020;
-                       } /* bump arch */
-               } else if(opP->ireg!=FAIL) {
-                       opP->mode=APRDX;
-                       
-                       if (max_arch_this_insn < m68020) {
-                               max_arch_this_insn = m68020;
-                       } /* bump arch */
+
+                       opP->mode = APODX;
+               } else if (opP->ireg != FAIL) {
+                       opP->mode = APRDX;
                } else {
-                       opP->mode=AMIND;
-                       
-                       if (max_arch_this_insn < m68020) {
-                               max_arch_this_insn = m68020;
-                       } /* bump arch */
+                       opP->mode = AMIND;
                }
        } else {
-               opP->mode=APODX;
-               if (max_arch_this_insn < m68020) {
-                       max_arch_this_insn = m68020;
-               } /* bump arch */
+               opP->mode = APODX;
        }
 
        if(*str!='\0') {
                opP->error="Junk after indirect";
                return FAIL;
        }
-       return OK;
-}
+       return(OK);
+} /* m68k_ip_op() */
 
 /*
  * 
@@ -1206,8 +1203,6 @@ char *instring;
        LITTLENUM_TYPE words[6];
        LITTLENUM_TYPE *wordp;
        
-       max_arch_this_insn = m68000;
-       
        if (*instring == ' ')
            instring++;                 /* skip leading whitespace */
        
@@ -1253,7 +1248,7 @@ char *instring;
                }
        }
        
-       opsfound=opP- &the_ins.operands[0];
+       opsfound = opP - &the_ins.operands[0];
        
        /* This ugly hack is to support the floating pt opcodes in their standard form */
        /* Essentially, we fake a first enty of type COP#1 */
@@ -1272,13 +1267,13 @@ char *instring;
        
        /* We've got the operands.  Find an opcode that'll accept them */
        for (losing = 0; ; ) {
-               /* if we didn't get the right number of ops, or either
-                  the modes of our args or this op line itself are out
-                  of order... */
+               /* if we didn't get the right number of ops,
+                  or we have no common model with this pattern
+                  then reject this pattern. */
                
-               if ((opsfound != opcode->m_opnum)
-                   || ((max_arch_this_insn > current_architecture)
-                       || (opcode->m_arch > current_architecture))) {
+               if (opsfound != opcode->m_opnum
+                   || ((opcode->m_arch & current_architecture) == 0)) {
+
                        ++losing;
                        
                } else {
@@ -1291,8 +1286,10 @@ char *instring;
                                   it belongs to.  I hope this makes sense. */
                                switch(*s) {
                                case '!':
-                                       if(opP->mode==MSCR || opP->mode==IMMED ||
-                                          opP->mode==DREG || opP->mode==AREG || opP->mode==AINC || opP->mode==ADEC || opP->mode==REGLST)
+                                       if (opP->mode == MSCR || opP->mode == IMMED
+                                           || opP->mode == DREG || opP->mode == AREG
+                                           || opP->mode == AINC || opP->mode == ADEC
+                                           || opP->mode == REGLST)
                                            losing++;
                                        break;
                                        
@@ -1429,13 +1426,13 @@ char *instring;
                                        if (opP->mode != MSCR
                                            || opP->reg < USP
                                            || opP->reg > URP
-                                           || (current_architecture & m68000up) < m68010 /* before 68010 had none */
-                                           || ((current_architecture & m68020up) == 0
+                                           || cpu_of_arch(current_architecture) < m68010 /* before 68010 had none */
+                                           || (cpu_of_arch(current_architecture) < m68020
                                                && opP->reg != SFC
                                                && opP->reg != DFC
                                                && opP->reg != USP
                                                && opP->reg != VBR) /* 68010's had only these */
-                                           || ((current_architecture & m68040) == 0
+                                           || (cpu_of_arch(current_architecture) < m68040
                                                && opP->reg != SFC
                                                && opP->reg != DFC
                                                && opP->reg != USP
@@ -1444,7 +1441,7 @@ char *instring;
                                                && opP->reg != CAAR
                                                && opP->reg != MSP
                                                && opP->reg != ISP) /* 680[23]0's have only these */
-                                           || ((current_architecture & m68040) /* 68040 has all but this */
+                                           || (cpu_of_arch(current_architecture) == m68040 /* 68040 has all but this */
                                                && opP->reg == CAAR)) {
                                                losing++;
                                        } /* doesn't cut it */
@@ -1609,7 +1606,8 @@ char *instring;
                losing = 0;
        }
        
-       
+       /* now assemble it */
+
        the_ins.args=opcode->m_operands;
        the_ins.numargs=opcode->m_opnum;
        the_ins.numo=opcode->m_codenum;
@@ -1778,9 +1776,7 @@ char *instring;
                        case APODX:
                        case AMIND:
                        case APRDX:
-                               if (max_arch_this_insn < m68020) {
-                                       max_arch_this_insn = m68020;
-                               } /* bump arch */
+                               know(current_architecture & m68020up);
                                /* intentional fall-through */
                        case AINDX:
                                nextword=0;
@@ -1839,7 +1835,7 @@ char *instring;
                                /* It aint simple */
                                nextword|=0x100;
                                /* If the guy specified a width, we assume that
-                                  it is wide enough.  Maybe it isn't.  Ifso, we lose
+                                  it is wide enough.  Maybe it isn't.  If so, we lose
                                   */
                                switch(siz1) {
                                case 0:
@@ -1934,7 +1930,7 @@ char *instring;
                                           && !subs(opP->con1)
                                           && seg(opP->con1) == SEG_TEXT
                                           && now_seg == SEG_TEXT
-                                          && (current_architecture & m68000up) <= m68010
+                                          && cpu_of_arch(current_architecture) < m68020
                                           && !flagseen['S']
                                           && !strchr("~%&$?", s[0])) {
                                                tmpreg=0x3A; /* 7.2 */
@@ -2045,7 +2041,7 @@ char *instring;
                                break;
                        case 'L':
                        long_branch:
-                               if(current_architecture <= m68010)      /* 68000 or 010 */
+                               if (cpu_of_arch(current_architecture) < m68020)         /* 68000 or 010 */
                                    as_warn("Can't use long branches on 68000/68010");
                                the_ins.opcode[the_ins.numo-1]|=0xff;
                                /* Offset the displacement to be relative to byte disp location */
@@ -2066,7 +2062,7 @@ char *instring;
                                   where opnd is absolute (it needs
                                   to use the 68000 hack since no
                                   conditional abs jumps).  */
-                               if (((current_architecture <= m68010) || (0==adds(opP->con1)))
+                               if (((cpu_of_arch(current_architecture) < m68020) || (0==adds(opP->con1)))
                                    && (the_ins.opcode[0] >= 0x6200)
                                    && (the_ins.opcode[0] <= 0x6f00)) {
                                        add_frag(adds(opP->con1),offs(opP->con1),TAB(BCC68000,SZ_UNDEF));
@@ -2667,6 +2663,18 @@ char *str;
        char    *to_beg_P;
        int     shorts_this_frag;
 
+
+       if (current_architecture == 0) {
+               current_architecture = (m68020
+#ifndef NO_68881
+                                       | m68881
+#endif
+#ifndef NO_68851
+                                       | m68851
+#endif
+                                       );
+       } /* default current_architecture */
+
        bzero((char *)(&the_ins),sizeof(the_ins));      /* JF for paranoia sake */
        m68k_ip(str);
        er=the_ins.error;
@@ -2759,7 +2767,7 @@ char *str;
                            the_ins.reloc[m].pcrel,
                                NO_RELOC);
                }
-               know(the_ins.fragb[n].fadd);
+               /* know(the_ins.fragb[n].fadd); */
                (void)frag_var(rs_machine_dependent,10,0,(relax_substateT)(the_ins.fragb[n].fragty),
  the_ins.fragb[n].fadd,the_ins.fragb[n].foff,to_beg_P);
        }
@@ -3054,7 +3062,7 @@ register fragS *fragP;
     ext=2;
     break;
   case TAB(BRANCH,LONG):
-    if (current_architecture <= m68010) {
+    if (cpu_of_arch(current_architecture) < m68020) {
       if (fragP->fr_opcode[0]==0x61) {
        fragP->fr_opcode[0]= 0x4E;
        fragP->fr_opcode[1]= 0xB9;      /* JBSR with ABSL LONG offset */
@@ -3276,7 +3284,7 @@ segT segment;
                   && S_GET_SEGMENT(fragP->fr_symbol) == segment) {
                         fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE);
                         break;
-               } else if((fragP->fr_symbol == 0) || (current_architecture <= m68010)) {
+               } else if((fragP->fr_symbol == 0) || (cpu_of_arch(current_architecture) < m68020)) {
                        /* On 68000, or for absolute value, switch to abs long */
                        /* FIXME, we should check abs val, pick short or long */
                        if(fragP->fr_opcode[0]==0x61) {
@@ -3453,7 +3461,7 @@ symbolS   *to_symbol;
 {
        long offset;
 
-       if (current_architecture <= m68010) {
+       if (cpu_of_arch(current_architecture) < m68020) {
                offset=to_addr-S_GET_VALUE(to_symbol);
                md_number_to_chars(ptr  ,(long)0x4EF9,2);
                md_number_to_chars(ptr+2,(long)offset,4);
@@ -3752,14 +3760,16 @@ char ***vecP;
                        current_architecture |= m68040;
 
 #ifndef NO_68881
-               } else if (!strcmp(*argP, "68881")
-                          || !strcmp(*argP, "68882")) { 
-                       current_architecture |= m68040;
+               } else if (!strcmp(*argP, "68881")) {
+                       current_architecture |= m68881;
+
+               } else if (!strcmp(*argP, "68882")) {
+                       current_architecture |= m68882;
 
 #endif /* NO_68881 */
 #ifndef NO_68851
                } else if (!strcmp(*argP,"68851")) { 
-                       current_architecture |= m68040;
+                       current_architecture |= m68851;
 
 #endif /* NO_68851 */
                } else {