예제 #1
0
static void handle_text(char *s)
{
  char *opstart = s;
  operand *op;
  dblock *db = NULL;

  if (db = parse_string(&opstart,*s,8)) {
    add_atom(0,new_data_atom(db,1));
    s = opstart;
  }
  if (!db) {
    op = new_operand();
    s = skip_operand(s);
    if (parse_operand(opstart,s-opstart,op,DATA_OPERAND(8))) {
      atom *a;

      a = new_datadef_atom(8,op);
      a->align = 1;
      add_atom(0,a);
    }
    else
      syntax_error(8);  /* invalid data operand */
  }
  eol(s);
}
예제 #2
0
파일: syntax.c 프로젝트: ezrec/vasm
static void handle_stabs(char *s)
{
  char *name;
  int t,o,d;

  if (*s++ == '\"') {
    name = s;
    while (*s && *s!='\"')
      s++;
    name = cnvstr(name,s-name);
  }
  else {
    syntax_error(7);  /* " expected */
    return;
  }
  s++;
  t = comma_constexpr(&s);
  o = comma_constexpr(&s);
  d = comma_constexpr(&s);
  s = skip(s);
  if (*s == ',') {
    s = skip(s+1);
    stab_entry(name,t,o,d,s);
    s = skip_operand(s);
  }
  else
    syntax_error(9);
  eol(s);
}
예제 #3
0
파일: syntax.c 프로젝트: kusma/vasm
static void handle_datadef(char *s,int sz)
{
  for (;;) {
    char *opstart = s;
    operand *op;
    dblock *db = NULL;

    if (OPSZ_BITS(sz)==8 && (*s=='\"' || *s=='\'')) {
      if (db = parse_string(&opstart,*s,8)) {
        add_atom(0,new_data_atom(db,1));
        s = opstart;
      }
    }
    if (!db) {
      op = new_operand();
      s = skip_operand(s);
      if (parse_operand(opstart,s-opstart,op,DATA_OPERAND(sz)))
        add_atom(0,new_datadef_atom(OPSZ_BITS(sz),op));
      else
        syntax_error(8);  /* invalid data operand */
    }

    s = skip(s);
    if (*s == ',')
      s = skip(s+1);
    else
      break;
  }
}
예제 #4
0
static void handle_data_offset(char *s,int size,int offset)
{
  for (;;) {
    char *opstart = s;
    operand *op;
    dblock *db = NULL;

    if (size==8 && (*s=='\"' || *s=='\'')) {
      if (db = parse_string(&opstart,*s,8)) {
        if (offset != 0) {
          int i;

          for (i=0; i<db->size; i++)
            db->data[i] = db->data[i] + offset;
        }
        add_atom(0,new_data_atom(db,1));
        s = opstart;
      }
    }
    if (!db) {
      op = new_operand();
      s = skip_operand(s);
      if (parse_operand(opstart,s-opstart,op,DATA_OPERAND(size))) {
        atom *a;

        if (offset != 0)
          op->value = make_expr(ADD,number_expr(offset),op->value);
        a = new_datadef_atom(abs(size),op);
        a->align = 1;
        add_atom(0,a);
      }
      else
        syntax_error(8);  /* invalid data operand */
    }

    s = skip(s);
    if (*s == ',') {
      s = skip(s+1);
    }
    else if (*s == commentchar) {
      break;
    }
    else if (*s) {
      syntax_error(9);  /* , expected */
      return;
    }
    else
      break;
  }

  eol(s);
}
예제 #5
0
파일: syntax.c 프로젝트: ezrec/vasm
static void handle_stabn(char *s)
{
  int t,o,d;

  t = parse_constexpr(&s);
  o = comma_constexpr(&s);
  d = comma_constexpr(&s);
  s = skip(s);
  if (*s == ',') {
    s = skip(s+1);
    stab_entry(NULL,t,o,d,s);
    s = skip_operand(s);
  }
  else
    syntax_error(9);
  eol(s);
}
예제 #6
0
파일: syntax.c 프로젝트: ezrec/vasm
static void stab_entry(char *name,int type,int othr,int desc,char *s)
{
  section *stabs;

  if (!(stabs = find_section(stabname,stabattr))) {
    section *str;
    dblock *db;

    stabs = new_section(stabname,stabattr,4);
    if (!(str = find_section(stabstrname,stabstrattr))) {
      str = new_section(stabstrname,stabstrattr,1);
    }
    else {
      if (str->pc != 0)
        ierror(0);
    }
    /* first byte of .stabstr is 0 */
    add_atom(str,new_space_atom(number_expr(1),1,0)); 
    /* compilation unit header has to be patched by output module */
    new_stabstr(getfilename());
    db = new_dblock();
    db->size = 12;
    db->data = mymalloc(12);
    add_atom(stabs,new_data_atom(db,1));
  }

  add_const_datadef(stabs,name?new_stabstr(name):0,32,1);
  add_const_datadef(stabs,type,8,1);
  add_const_datadef(stabs,othr,8,1);
  add_const_datadef(stabs,desc,16,1);
  if (s) {
    operand *op = new_operand();
    int len = oplen(skip_operand(s),s);

    if (parse_operand(s,len,op,DATA_OPERAND(32))) {
      atom *a = new_datadef_atom(32,op);

      a->align = 1;
      add_atom(stabs,a);
    }
    else
      syntax_error(8);
  }
  else
    add_atom(stabs,new_space_atom(number_expr(4),1,0));  /* no value */
}
예제 #7
0
파일: syntax.c 프로젝트: kusma/vasm
/* parse next macro argument */
char *parse_macro_arg(struct macro *m,char *s,
                      struct namelen *param,struct namelen *arg)
{
  arg->len = 0;  /* cannot select specific named arguments */
  param->name = s;

  if (*s=='\"' || *s=='\'') {
    s = skip_string(s,*s,NULL);
    param->len = s - param->name;
  }
  else {
    s = skip_operand(s);
    param->len = s - param->name;
  }

  return s;
}
예제 #8
0
파일: syntax.c 프로젝트: ezrec/vasm
static void handle_data(char *s,int size,int noalign)
{
  for (;;) {
    char *opstart = s;
    operand *op;
    dblock *db = NULL;

    if ((size==8 || size==16) && *s=='\"') {
      if (db = parse_string(&opstart,*s,size)) {
        add_atom(0,new_data_atom(db,1));
        s = opstart;
      }
    }
    if (!db) {
      op = new_operand();
      s = skip_operand(s);
      if (parse_operand(opstart,s-opstart,op,DATA_OPERAND(size))) {
        atom *a;

        a = new_datadef_atom(size,op);
        if (noalign)
          a->align=1;
        add_atom(0,a);
      }
      else
        syntax_error(8);  /* invalid data operand */
    }

    s = skip(s);
    if (*s == ',') {
      s = skip(s+1);
    }
    else if (*s==commentchar)
      break;
    else if (*s) {
      syntax_error(9);  /* , expected */
      return;
    }
    else
      break;
  }

  eol(s);
}
예제 #9
0
파일: opcodes.c 프로젝트: ryo/netbsd-src
static long
skip_operand(long ib, int size)
{
    int c = get_byte(ib++);

    switch (c >> 4) { /* mode */
    case 4:		/* indexed */
        ib = skip_operand(ib, 0);
        break;

    case 9:		/* autoincrement deferred */
        if (c == 0x9f) {	/* pc: immediate deferred */
            /*
             * addresses are always longwords!
             */
            ib += 4;
        }
        break;
    case 8:		/* autoincrement */
        if (c == 0x8f) {	/* pc: immediate ==> special syntax */
            ib += size;
        }
        break;

    case 11:	/* byte displacement deferred/ relative deferred  */
    case 10:	/* byte displacement / relative mode */
        ib++;
        break;

    case 13:		/* word displacement deferred */
    case 12:		/* word displacement */
        ib += 2;
        break;

    case 15:		/* long displacement referred */
    case 14:		/* long displacement */
        ib += 4;
        break;
    }

    return ib;
}
예제 #10
0
파일: syntax.c 프로젝트: ezrec/vasm
static void handle_data(char *s,int size,int noalign,int zeroterm)
{
  expr *tree;
  dblock *db;
  do{
    char *opstart=s;
    operand *op;
    if(size==8&&*s=='\"'){
      s=string(s,&db);
      add_atom(0,new_data_atom(db,1));
    }else{
      op=new_operand();
      s=skip_operand(s);
      if(!parse_operand(opstart,s-opstart,op,DATA_OPERAND(size))){
        syntax_error(8);
      }else{
        atom *a=new_datadef_atom(size,op);
        if(noalign)
          a->align=1;
        add_atom(0,a);
      }
    }
    s=skip(s);
    if(*s==','){
      s=skip(s+1);
    }else if(*s)
      syntax_error(9);
  }while(*s);
  if(zeroterm){
    if(size!=8)
      ierror(0);
    db=new_dblock();
    db->size=1;
    db->data=mymalloc(1);
    *db->data=0;
    add_atom(0,new_data_atom(db,1));
  }    
  eol(s);
}
예제 #11
0
파일: syntax.c 프로젝트: ezrec/vasm
/* Very simple, very incomplete. */
void parse(void)
{
  char *s,*line,*inst,*ext[MAX_QUALIFIERS?MAX_QUALIFIERS:1],*op[MAX_OPERANDS];
  int inst_len,ext_len[MAX_QUALIFIERS?MAX_QUALIFIERS:1],op_len[MAX_OPERANDS];
  int i,ext_cnt,op_cnt,par_cnt;
  instruction *ip;
  while(line=read_next_line()){
    s=line;

    if(isalnum((unsigned char)*s)){
      /* Handle labels at beginning of line */
      char *labname,*equ;
      symbol *label;
      while(*s&&!isspace((unsigned char)*s)&&*s!=':')
        s++;
      labname=cnvstr(line,s-line);
      s=skip(s+1);
      if(!strncmp(s,"equ",3)&&isspace((unsigned char)s[3])){
        s=skip(s+3);
        label=new_abs(labname,parse_expr(&s));
      }else{
        label=new_labsym(0,labname);
        add_atom(0,new_label_atom(label));
      }
      free(labname);
    }

    s=parse_cpu_special(s);

    if(handle_directive(s))
      continue;

    /* skip spaces */
    s=skip(s);
    if(!*s)
      continue;

    /* read mnemonic name */
    inst=s;
    if(!ISIDSTART(*s)){
      syntax_error(10);
      continue;
    }
#if MAX_QUALIFIERS==0
    while(*s&&!isspace((unsigned char)*s))
      s++;
#else
    while(*s&&*s!='.'&&!isspace((unsigned char)*s))
      s++;
#endif
    inst_len=s-inst;

    /* read qualifiers */
    ext_cnt=0;
    while(*s=='.'&&ext_cnt<MAX_QUALIFIERS){
      s++;
      ext[ext_cnt]=s;
      while(*s&&*s!='.'&&!isspace((unsigned char)*s))
        s++;
      ext_len[ext_cnt]=s-ext[ext_cnt];
      if(ext_len[ext_cnt]<=0)
        syntax_error(1);
      else
        ext_cnt++;
    }

    if(!isspace((unsigned char)*s)) syntax_error(2);
    
    /* read operands, terminated by comma (unless in parentheses)  */
    s=skip(s);
    op_cnt=0;
    while(*s&&op_cnt<MAX_OPERANDS){
      op[op_cnt]=s;
      s=skip_operand(s);
      op_len[op_cnt]=s-op[op_cnt];
      if(op_len[op_cnt]<=0)
        syntax_error(5);
      else
        op_cnt++;
      s=skip(s);
      if(*s!=','){
        break;
      }else{
        s=skip(s+1);
      }
    }      
    s=skip(s);
    if(*s!=0) syntax_error(6);
    ip=new_inst(inst,inst_len,op_cnt,op,op_len);
#if MAX_QUALIFIERS>0
    if(ip){
      for(i=0;i<ext_cnt;i++)
        ip->qualifiers[i]=cnvstr(ext[i],ext_len[i]);
      for(;i<MAX_QUALIFIERS;i++)
        ip->qualifiers[i]=0;
    }
#endif
    if(ip){
      add_atom(0,new_inst_atom(ip));
    }else
      ;
  }
}
예제 #12
0
파일: syntax.c 프로젝트: ezrec/vasm
void parse(void)
{
  char *s,*line,*ext[MAX_QUALIFIERS?MAX_QUALIFIERS:1],*op[MAX_OPERANDS];
  char *labname,*start;
  int inst_len,ext_len[MAX_QUALIFIERS?MAX_QUALIFIERS:1],op_len[MAX_OPERANDS];
  int ext_cnt,op_cnt;
  instruction *ip;

  while (line=read_next_line()){
    if (clev >= MAXCONDLEV)
      syntax_error(16,clev);  /* nesting depth exceeded */

    if (!cond[clev]) {
      /* skip source until ELSE or ENDIF */
      int idx;

      s = line;
      idx = check_directive(&s);
      if (idx >= 0) {
        if (!strncmp(directives[idx].name,"if",2)) {
          ifnesting++;
        }
        else if (ifnesting==0 && !strncmp(directives[idx].name,"else",4)) {
          cond[clev] = 1;
        }
        else if (directives[idx].func == handle_endif) {
          if (ifnesting == 0) {
            if (clev > 0)
              clev--;
            else
              syntax_error(14);  /* endif without if */
          }
          else
            ifnesting--;
        }
      }
      continue;
    }

    s=skip(line);

    if(handle_directive(s))
      continue;

    /* skip spaces */
    s=skip(s);
    if(!*s||*s==commentchar)
      continue;

    /* check for label */
    start=s;
    if(labname=get_local_label(&s)){   /* local label? */
      if(*s!=':'){
        s=start;
        myfree(labname);
        labname=NULL;
      }
    }
    else if(ISIDSTART(*s)){            /* or global label? */
      s++;
      while(ISIDCHAR(*s)) s++;
      if(*s!=':')
        s=start;
      else
        labname=cnvstr(start,s-start);
    }
    if(labname){
      /* we have found a valid global or local label */
      add_atom(0,new_label_atom(new_labsym(0,labname)));
      s=skip(s+1);
      myfree(labname);
    }

    if(!*s||*s==commentchar)
      continue;

    s=skip(parse_cpu_special(s));
    if(*s==0||*s==commentchar)
      continue;

    if(handle_directive(s))
      continue;

    /* read mnemonic name */
    start=s;
    ext_cnt=0;
    if(!ISIDSTART(*s)){
      syntax_error(10);
      continue;
    }
#if MAX_QUALIFIERS==0
    while(*s&&!isspace((unsigned char)*s))
      s++;
    inst_len=s-start;
#else
    s=parse_instruction(s,&inst_len,ext,ext_len,&ext_cnt);
#endif
    s=skip(s);

    if(execute_macro(start,inst_len,ext,ext_len,ext_cnt,s,clev))
      continue;

    /* read operands, terminated by comma (unless in parentheses)  */
    op_cnt=0;
    while(*s&&*s!=commentchar&&op_cnt<MAX_OPERANDS){
      op[op_cnt]=s;
      s=skip_operand(s);
      op_len[op_cnt]=oplen(s,op[op_cnt]);
#if !ALLOW_EMPTY_OPS
      if(op_len[op_cnt]<=0)
        syntax_error(5);
      else
#endif
        op_cnt++;
      s=skip(s);
      if(*s!=','){
        break;
      }else{
        s=skip(s+1);
      }
    }      
    s=skip(s);
    if(*s!=0&&*s!=commentchar) syntax_error(6);
    ip=new_inst(start,inst_len,op_cnt,op,op_len);
#if MAX_QUALIFIERS>0
    if(ip){
      int i;
      for(i=0;i<ext_cnt;i++)
        ip->qualifiers[i]=cnvstr(ext[i],ext_len[i]);
      for(;i<MAX_QUALIFIERS;i++)
        ip->qualifiers[i]=0;
    }
#endif
    if(ip){
      add_atom(0,new_inst_atom(ip));
    }else
      ;
  }

  if (clev > 0)
    syntax_error(15);  /* if without endif */
}
예제 #13
0
파일: syntax.c 프로젝트: kusma/vasm
void parse(void)
{
  char *s,*line,*inst;
  char *ext[MAX_QUALIFIERS?MAX_QUALIFIERS:1];
  char *op[MAX_OPERANDS];
  int ext_len[MAX_QUALIFIERS?MAX_QUALIFIERS:1];
  int op_len[MAX_OPERANDS];
  int ext_cnt,op_cnt,inst_len;
  instruction *ip;

  while (line = read_next_line()) {

    if (!cond_state()) {
      /* skip source until ELSE or ENDIF */
      int idx = -1;

      s = skip(line);
      if (labname = parse_labeldef(&s,1)) {
        if (*s == ':')
          s++;  /* skip double-colon */
        myfree(labname);
        s = skip(s);
      }
      else {
        if (inst = skip_identifier(s)) {
          inst = skip(inst);
          idx = check_directive(&inst);
        }
      }
      if (idx < 0)
        idx = check_directive(&s);
      if (idx >= 0) {
        if (directives[idx].func == handle_if)
          cond_skipif();
        else if (directives[idx].func == handle_else)
          cond_else();
        else if (directives[idx].func == handle_endif)
          cond_endif();
      }
      continue;
    }

    s = skip(line);
again:
    if (*s=='\0' || *line=='*' || *s==commentchar)
      continue;

    if (labname = parse_labeldef(&s,1)) {
      /* we have found a valid global or local label */
      symbol *sym = new_labsym(0,labname);

      if (*s == ':') {
        /* double colon automatically declares label as exported */
        sym->flags |= EXPORT;
        s++;
      }
      add_atom(0,new_label_atom(sym));
      myfree(labname);
      s = skip(s);
    }
    else {
      /* there can still be a sym. in the 1st fld and an assignm. directive */
      inst = s;
      labname = parse_symbol(&s);
      if (labname == NULL) {
        syntax_error(10);  /* identifier expected */
        continue;
      }
      s = skip(s);

      /* Now we have labname pointing to the first field in the line
         and s pointing to the second. Find out where the directive is. */
      if (!ISEOL(s)) {
#ifdef PARSE_CPU_LABEL
        if (PARSE_CPU_LABEL(labname,&s)) {
          myfree(labname);
          continue;
        }
#endif
        if (handle_directive(s)) {
          myfree(labname);
          continue;
        }
      }

      /* directive or mnemonic must be in the first field */
      myfree(labname);
      s = inst;
    }

    if (!strnicmp(s,".iif",4) || !(strnicmp(s,"iif",3))) {
      /* immediate conditional assembly: parse line after ',' when true */
      s = skip(*s=='.'?s+4:s+3);
      if (do_cond(&s)) {
        s = skip(s);
        if (*s == ',') {
          s = skip(s+1);
          goto again;
        }
        else
          syntax_error(0);  /* malformed immediate-if */
      }
      continue;
    }

    /* check for directives */
    s = parse_cpu_special(s);
    if (ISEOL(s))
      continue;

    if (handle_directive(s))
      continue;

    /* read mnemonic name */
    inst = s;
    ext_cnt = 0;
    if (!ISIDSTART(*s)) {
      syntax_error(10);  /* identifier expected */
      continue;
    }
#if MAX_QUALIFIERS==0
    while (*s && !isspace((unsigned char)*s))
      s++;
    inst_len = s - inst;
#else
    s = parse_instruction(s,&inst_len,ext,ext_len,&ext_cnt);
#endif
    if (!isspace((unsigned char)*s) && *s!='\0')
      syntax_error(2);  /* no space before operands */
    s = skip(s);

    if (execute_macro(inst,inst_len,ext,ext_len,ext_cnt,s))
      continue;

    /* read operands, terminated by comma or blank (unless in parentheses) */
    op_cnt = 0;
    while (!ISEOL(s) && op_cnt<MAX_OPERANDS) {
      op[op_cnt] = s;
      s = skip_operand(s);
      op_len[op_cnt] = oplen(s,op[op_cnt]);
#if !ALLOW_EMPTY_OPS
      if (op_len[op_cnt] <= 0)
        syntax_error(5);  /* missing operand */
      else
#endif
        op_cnt++;
      s = skip(s);
      if (*s != ',')
        break;
      else
        s = skip(s+1);
    }
    eol(s);

    ip = new_inst(inst,inst_len,op_cnt,op,op_len);

#if MAX_QUALIFIERS>0
    if (ip) {
      int i;

      for (i=0; i<ext_cnt; i++)
        ip->qualifiers[i] = cnvstr(ext[i],ext_len[i]);
      for(; i<MAX_QUALIFIERS; i++)
        ip->qualifiers[i] = NULL;
    }
#endif

    if (ip)
      add_atom(0,new_inst_atom(ip));
  }

  cond_check();  /* check for open conditional blocks */
}
예제 #14
0
파일: opcodes.c 프로젝트: ryo/netbsd-src
long
skip_opcode(long ib)
{
    u_int opc;
    int size;
    const char *argp;	/* pointer into argument-list */

    opc = get_byte(ib++);
    if (opc >= 0xfd) {
        /* two byte op-code */
        opc = opc << 8;
        opc += get_byte(ib++);
        argp = vax_inst2[INDEX_OPCODE(opc)].argdesc;
    } else
        argp = vax_inst[opc].argdesc;

    if (argp == NULL || *argp == '\0')
        return ib;

    while (*argp) {
        switch (*argp) {

        case 'b':	/* branch displacement */
            switch (*(++argp)) {
            case 'b':
                ib++;
                break;
            case 'w':
                ib += 2;
                break;
            case 'l':
                ib += 4;
                break;
            }
            break;

        case 'a':	/* absolute addressing mode */
        /* FALLTHROUGH */
        default:
            switch (*(++argp)) {
            case 'b':	/* Byte */
                size = 1;
                break;
            case 'w':	/* Word */
                size = 2;
                break;
            case 'l':	/* Long-Word */
            case 'f':	/* F_Floating */
                size = 4;
                break;
            case 'q':	/* Quad-Word */
            case 'd':	/* D_Floating */
            case 'g':	/* G_Floating */
                size = 8;
                break;
            case 'o':	/* Octa-Word */
            case 'h':	/* H_Floating */
                size = 16;
                break;
            default:
                size = 0;
            }
            ib = skip_operand(ib, size);
        }

        if (!*argp || !*++argp)
            break;
        if (*argp++ != ',')
            break;
    }

    return ib;
}