Beispiel #1
0
pdblock
build_dblock(pdcluster rc, pdcluster cc, uint l,
	     bool(*admissible) (pdcluster rc, pdcluster cc, uint l,
				uint * rd, uint * cd, void *data), void *data)
{
  pdblock   b;
  uint      rd, cd;
  uint      i, j;

  b = 0;
  if (admissible(rc, cc, l, &rd, &cd, data)) {
    b = new_dblock(rc, cc, rd, cd, 0, 0);
    b->adm = true;
  }
  else if (rc->sons == 0 || cc->sons == 0) {
    b = new_dblock(rc, cc, 0, 0, 0, 0);
  }
  else {
    assert(rc->sons > 0);
    assert(cc->sons > 0);

    b = new_dblock(rc, cc, 0, 0, rc->sons, cc->sons);
    for (j = 0; j < cc->sons; j++)
      for (i = 0; i < rc->sons; i++)
	b->son[i + j * rc->sons] = build_dblock(rc->son[i], cc->son[j], l + 1,
						admissible, data);
  }

  update_dblock(b);

  return b;
}
Beispiel #2
0
static char *string(char *s,dblock **result)
{
  dblock *db=new_dblock();
  taddr size;
  char *p,esc;
  if(*s!='\"')
    ierror(0);
  else
    s++;
  p=s;
  size=0;
  while(*s&&*s!='\"'){
    if(*s=='\\')
      s=escape(s,&esc);
    else
      s++;
    size++;
  }
  db->size=size;
  db->data=mymalloc(db->size);
  s=p;
  p=db->data;
  while(*s&&*s!='\"'){
    if(*s=='\\')
      s=escape(s,p++);
    else
      *p++=*s++;
  }
  *result=db;
  if(*s=!'\"')
    syntax_error(7);
  else
    s++;
  return s;
}
Beispiel #3
0
static taddr new_stabstr(char *name)
{
  section *str;
  taddr index;
  dblock *db;

  if (!(str = find_section(stabstrname,stabstrattr)))
    ierror(0);
  index = str->pc;
  db = new_dblock();
  db->size = strlen(name) + 1;
  db->data = name;
  add_atom(str,new_data_atom(db,1));
  return index;
}
Beispiel #4
0
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 */
}
Beispiel #5
0
Datei: cpu.c Projekt: ezrec/vasm
/* Convert an instruction into a DATA atom including relocations,
   if necessary. */
dblock *eval_instruction(instruction *p,section *sec,taddr pc)
{
  /* Auch simpel. Fehlerchecks fehlen. */
  taddr size=instruction_size(p,sec,pc);
  dblock *db=new_dblock();
  int c=opt_inst(p,sec,pc);
  char *d;
  taddr val;
  db->size=size;
  d=db->data=mymalloc(size);
  *d=c;
  if(p->qualifiers[0]){
    if(c>5)
      cpu_error(1,p->qualifiers[0]);
    else if(!strcmp(p->qualifiers[0],"b"))
      *d|=128;
    else if(strcmp(p->qualifiers[0],"w"))
      cpu_error(1,p->qualifiers[0]);
  }
  d++;
  if(c==5){
    /* addq */
    taddr val;
    if(!eval_expr(p->op[0]->offset,&val,sec,pc)||val>15)
      cpu_error(0);
    *d=((val<<4)|operand_code(p->op[1]));
    return db;
  }
  if(c==7){
    expr *tree=p->op[0]->offset;
    if(!(tree->type==SYM&&tree->c.sym->sec==sec&&tree->c.sym->type==LABSYM&&
	 tree->c.sym->pc-pc>=-128&&tree->c.sym->pc-pc<=127))
      cpu_error(0);
    else
      *d=tree->c.sym->pc-pc;
    return db;
  }

  *d=((operand_code(p->op[0])<<4)|operand_code(p->op[1]));
  d++;
  d=fill_operand(p->op[0],sec,pc,d,&db->relocs,d-db->data);
  d=fill_operand(p->op[1],sec,pc,d,&db->relocs,d-db->data);
  return db;
}
Beispiel #6
0
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);
}
Beispiel #7
0
Datei: cpu.c Projekt: kusma/vasm
/* Convert an instruction into a DATA atom including relocations,
   if necessary. */
dblock *eval_instruction(instruction *p,section *sec,taddr pc)
{
  dblock *db=new_dblock();
  int c,sz,enc,cc,ww,m=0;
  unsigned long code,code2,code3;
  rlist *relocs=0;

  if(p->qualifiers[0]){
    int i;
    for(i=0;i<15;i++){
      if(!strcmp(p->qualifiers[0],ccs[i])){
	cc=i;
	break;
      }
    }
    if(i>15) ierror(0);
  }else
    cc=14;

  c=translate(p,sec,pc);
  enc=mnemonics[c].ext.encoding;

  db->size=sz=oplen(enc);
  db->data=mymalloc(db->size);

  code=mnemonics[c].ext.code;

  switch(enc){
  case EN_ARITHR16:
    if(cc!=14) cpu_error(3);
    code=0x40000000|(code<<24);
    code|=(p->op[0]->reg<<16)|(p->op[1]->reg<<20);
    break;
  case EN_ARITHI16:
    if(cc!=14) cpu_error(3);
    code=0x60000000|((code>>1)<<25);
    code|=(p->op[0]->reg<<16)|(absval(p->op[1]->offset,sec,pc,5,0)<<20);
    break;
  case EN_FIX16:
    if(cc!=14) cpu_error(3);
    break;
  case EN_IBRANCH16:
    if(cc!=14) cpu_error(3);
    code|=(p->op[0]->reg<<16);
    break;
  case EN_RBRANCH16:
    code=0x18000000;
    code|=cc<<23;
    code|=((reloffset(p->op[0]->offset,sec,pc,&relocs,0,7,0xfe)>>1)&127)<<16;
    break;
  case EN_MREG16:
    if(cc!=14) cpu_error(3);
    code|=(p->op[0]->dreg<<21)|(p->op[0]->reg<<16);
    break;
  case EN_RBRANCH32:
    if(code==0x90000000)
      code|=cc<<24;
    else
      code|=((reloffset(p->op[0]->offset,sec,pc,&relocs,8,4,0xF000000)>>24)&0xf)<<24;
    code|=((reloffset(p->op[0]->offset,sec,pc,&relocs,16,16,0x1fffe)>>1)&0x7fffff);
    code|=((reloffset(p->op[0]->offset,sec,pc,&relocs,0,7,0xfe0000)>>17)&0x7f)<<16;
    break;
  case EN_FUNARY32:
    code=0xC0000040|(code<<21);
    code|=p->op[0]->reg<<16;
    code|=p->op[1]->reg<<11;
    code|=cc<<7;
    break;
  case EN_ARITHR32:
    code=0xC0000000|(code<<21);
    code|=p->op[0]->reg<<16;
    if(p->op[2]){
      code|=p->op[1]->reg<<11;
      code|=p->op[2]->reg;
    }else{
      code|=p->op[0]->reg<<11;
      code|=p->op[1]->reg;
    }      
    code|=cc<<7;
    break;
  case EN_ARITHI32:
    code=0xC0000040|(code<<21);
    code|=p->op[0]->reg<<16;
    if(p->op[2]){
      code|=p->op[1]->reg<<11;
      code|=absval(p->op[2]->offset,sec,pc,6,1);
    }else{
      code|=p->op[0]->reg<<11;
      code|=absval(p->op[1]->offset,sec,pc,6,1);
    }
    code|=cc<<7;
    break;
  case EN_ADDCMPB64:
    // Large offset: invert CC, place a long branch after
    // so we really generate the following:
    //   addcmpb<~cc> d, a, b, skip
    //   b <destination>
    // skip:
    //   <rest of code>
    m=1;
    if(cc&1) cc--; else cc++;
  case EN_ADDCMPB32:
    code=0x80000000|(code<<14);
    code|=cc<<24;
    code|=p->op[0]->reg<<16;
    if(code&0x4000){
      code|=absval(p->op[1]->offset,sec,pc,4,1)<<20;
    }else{
      code|=p->op[1]->reg<<20;
    }
    if(code&0x8000){
      code|=absval(p->op[2]->offset,sec,pc,6,0)<<8;
      if(m)
	code|=4;
      else
	code|=((reloffset(p->op[3]->offset,sec,pc,&relocs,16,9,0x1ff)>>1)&0xff);
    }else{