1 /* atom.c - atomic objects from source */
2 /* (c) in 2010-2018 by Volker Barthelmann and Frank Wille */
3
4 #include "vasm.h"
5
6
7 /* searches mnemonic list and tries to parse (via the cpu module)
8 the operands according to the mnemonic requirements; returns an
9 instruction or 0 */
new_inst(char * inst,int len,int op_cnt,char ** op,int * op_len)10 instruction *new_inst(char *inst,int len,int op_cnt,char **op,int *op_len)
11 {
12 #if MAX_OPERANDS!=0
13 operand ops[MAX_OPERANDS];
14 int j,k,mnemo_opcnt,omitted,skipped;
15 #endif
16 int i,inst_found=0;
17 hashdata data;
18 instruction *new;
19
20 new = mymalloc(sizeof(*new));
21 #if HAVE_INSTRUCTION_EXTENSION
22 init_instruction_ext(&new->ext);
23 #endif
24 #if MAX_OPERANDS!=0 && NEED_CLEARED_OPERANDS!=0
25 /* reset operands to allow the cpu-backend to parse them only once */
26 memset(ops,0,sizeof(ops));
27 #endif
28
29 if (find_namelen_nc(mnemohash,inst,len,&data)) {
30 i = data.idx;
31
32 /* try all mnemonics with the same name until operands match */
33 do {
34 inst_found = 1;
35 if (!MNEMONIC_VALID(i)) {
36 i++;
37 continue; /* try next */
38 }
39
40 #if MAX_OPERANDS!=0
41
42 #if ALLOW_EMPTY_OPS
43 mnemo_opcnt = op_cnt<MAX_OPERANDS ? op_cnt : MAX_OPERANDS;
44 #else
45 for (j=0; j<MAX_OPERANDS; j++)
46 if (mnemonics[i].operand_type[j] == 0)
47 break;
48 mnemo_opcnt = j; /* number of expected operands for this mnemonic */
49 #endif
50 inst_found = 2;
51 save_symbols(); /* make sure we can restore symbols to this point */
52
53 for (j=k=omitted=skipped=0; j<mnemo_opcnt; j++) {
54
55 if (op_cnt+omitted < mnemo_opcnt &&
56 OPERAND_OPTIONAL(&ops[j],mnemonics[i].operand_type[j])) {
57 omitted++;
58 }
59 else {
60 int rc;
61
62 if (k >= op_cnt) /* missing mandatory operands */
63 break;
64
65 rc = parse_operand(op[k],op_len[k],&ops[j],
66 mnemonics[i].operand_type[j]);
67
68 if (rc == PO_CORRUPT) {
69 myfree(new);
70 restore_symbols();
71 return 0;
72 }
73 if (rc == PO_NOMATCH)
74 break;
75
76 /* MATCH, move to next parsed operand */
77 k++;
78 if (rc == PO_SKIP) { /* but skip next operand type from table */
79 j++;
80 skipped++;
81 }
82 }
83 }
84
85 #if IGNORE_FIRST_EXTRA_OP
86 if (mnemo_opcnt > 0)
87 #endif
88 if (j<mnemo_opcnt || k<op_cnt) {
89 /* No match. Try next mnemonic. */
90 i++;
91 restore_symbols();
92 continue;
93 }
94
95 /* Matched! Copy operands. */
96 mnemo_opcnt -= skipped;
97 for (j=0; j<mnemo_opcnt; j++) {
98 new->op[j] = mymalloc(sizeof(operand));
99 *new->op[j] = ops[j];
100 }
101 for(; j<MAX_OPERANDS; j++)
102 new->op[j] = 0;
103
104 #endif /* MAX_OPERANDS!=0 */
105
106 new->code = i;
107 return new;
108 }
109 while (i<mnemonic_cnt && !strnicmp(mnemonics[i].name,inst,len)
110 && mnemonics[i].name[len]==0);
111 }
112
113 switch (inst_found) {
114 case 1:
115 general_error(8); /* instruction not supported by cpu */
116 break;
117 case 2:
118 general_error(0); /* illegal operand types */
119 break;
120 default:
121 general_error(1,cnvstr(inst,len)); /* completely unknown mnemonic */
122 break;
123 }
124 myfree(new);
125 return 0;
126 }
127
128
new_dblock(void)129 dblock *new_dblock(void)
130 {
131 dblock *new = mymalloc(sizeof(*new));
132
133 new->size = 0;
134 new->data = 0;
135 new->relocs = 0;
136 return new;
137 }
138
139
new_sblock(expr * space,size_t size,expr * fill)140 sblock *new_sblock(expr *space,size_t size,expr *fill)
141 {
142 sblock *sb = mymalloc(sizeof(sblock));
143
144 sb->space = 0;
145 sb->space_exp = space;
146 sb->size = size;
147 if (!(sb->fill_exp = fill))
148 memset(sb->fill,0,MAXPADBYTES);
149 sb->relocs = 0;
150 sb->maxalignbytes = 0;
151 return sb;
152 }
153
154
space_size(sblock * sb,section * sec,taddr pc)155 static size_t space_size(sblock *sb,section *sec,taddr pc)
156 {
157 utaddr space=0;
158
159 if (eval_expr(sb->space_exp,&space,sec,pc) || !final_pass)
160 sb->space = space;
161 else
162 general_error(30); /* expression must be constant */
163
164 if (final_pass && sb->fill_exp) {
165 if (sb->size <= sizeof(taddr)) {
166 /* space is filled with an expression which may also need relocations */
167 symbol *base=NULL;
168 taddr fill;
169 utaddr i;
170
171 if (!eval_expr(sb->fill_exp,&fill,sec,pc)) {
172 if (find_base(sb->fill_exp,&base,sec,pc)==BASE_ILLEGAL)
173 general_error(38); /* illegal relocation */
174 }
175 copy_cpu_taddr(sb->fill,fill,sb->size);
176 if (base && !sb->relocs) {
177 /* generate relocations */
178 for (i=0; i<space; i++)
179 add_extnreloc(&sb->relocs,base,fill,REL_ABS,
180 0,sb->size<<3,sb->size*i);
181 }
182 }
183 else
184 general_error(30); /* expression must be constant */
185 }
186
187 return sb->size * space;
188 }
189
190
roffs_size(expr * offsexp,section * sec,taddr pc)191 static size_t roffs_size(expr *offsexp,section *sec,taddr pc)
192 {
193 taddr offs;
194
195 eval_expr(offsexp,&offs,sec,pc);
196 offs = sec->org + offs - pc;
197 return offs>0 ? offs : 0;
198 }
199
200
201 /* adds an atom to the specified section; if sec==0, the current
202 section is used */
add_atom(section * sec,atom * a)203 void add_atom(section *sec,atom *a)
204 {
205 if (!sec) {
206 sec = default_section();
207 if (!sec) {
208 general_error(3);
209 return;
210 }
211 }
212
213 a->changes = 0;
214 a->src = cur_src;
215 a->line = cur_src!=NULL ? cur_src->line : 0;
216
217 if (sec->last) {
218 atom *pa = sec->last;
219
220 pa->next = a;
221 /* make sure that a label on the same line gets the same alignment */
222 if (pa->type==LABEL && pa->line==a->line &&
223 (a->type==INSTRUCTION || a->type==DATADEF || a->type==SPACE))
224 pa->align = a->align;
225 }
226 else
227 sec->first = a;
228 a->next = 0;
229 sec->last = a;
230
231 sec->pc = pcalign(a,sec->pc);
232 a->lastsize = atom_size(a,sec,sec->pc);
233 sec->pc += a->lastsize;
234 if (a->align > sec->align)
235 sec->align = a->align;
236
237 if (listena) {
238 a->list = last_listing;
239 if (last_listing) {
240 if (!last_listing->atom)
241 last_listing->atom = a;
242 }
243 }
244 else
245 a->list = 0;
246 }
247
248
atom_size(atom * p,section * sec,taddr pc)249 size_t atom_size(atom *p,section *sec,taddr pc)
250 {
251 switch(p->type) {
252 case LABEL:
253 case LINE:
254 case OPTS:
255 case PRINTTEXT:
256 case PRINTEXPR:
257 case RORG:
258 case RORGEND:
259 case ASSERT:
260 case NLIST: /* it has a size, but not in the current section */
261 return 0;
262 case DATA:
263 return p->content.db->size;
264 case INSTRUCTION:
265 return p->content.inst->code>=0?
266 instruction_size(p->content.inst,sec,pc):0;
267 case SPACE:
268 return space_size(p->content.sb,sec,pc);
269 case DATADEF:
270 return (p->content.defb->bitsize+7)/8;
271 case ROFFS:
272 return roffs_size(p->content.roffs,sec,pc);
273 default:
274 ierror(0);
275 break;
276 }
277 return 0;
278 }
279
280
print_instruction(FILE * f,instruction * p)281 static void print_instruction(FILE *f,instruction *p)
282 {
283 int i;
284
285 printf("inst %d(%s) ",p->code,p->code>=0?mnemonics[p->code].name:"deleted");
286 #if MAX_OPERANDS!=0
287 for (i=0; i<MAX_OPERANDS; i++)
288 printf("%p ",(void *)p->op[i]);
289 #endif
290 }
291
292
print_atom(FILE * f,atom * p)293 void print_atom(FILE *f,atom *p)
294 {
295 size_t i;
296 rlist *rl;
297
298 switch (p->type) {
299 case LABEL:
300 fprintf(f,"symbol: ");
301 print_symbol(f,p->content.label);
302 break;
303 case DATA:
304 fprintf(f,"data(%lu): ",(unsigned long)p->content.db->size);
305 for (i=0;i<p->content.db->size;i++)
306 fprintf(f,"%02x ",p->content.db->data[i]);
307 for (rl=p->content.db->relocs; rl; rl=rl->next)
308 print_reloc(f,rl->type,rl->reloc);
309 break;
310 case INSTRUCTION:
311 print_instruction(f,p->content.inst);
312 break;
313 case SPACE:
314 fprintf(f,"space(%lu,fill=",
315 (unsigned long)(p->content.sb->space*p->content.sb->size));
316 for (i=0; i<p->content.sb->size; i++)
317 fprintf(f,"%02x%c",(unsigned char)p->content.sb->fill[i],
318 (i==p->content.sb->size-1)?')':' ');
319 for (rl=p->content.sb->relocs; rl; rl=rl->next)
320 print_reloc(f,rl->type,rl->reloc);
321 break;
322 case DATADEF:
323 fprintf(f,"datadef(%lu bits)",(unsigned long)p->content.defb->bitsize);
324 break;
325 case LINE:
326 fprintf(f,"line: %d of %s",p->content.srcline,getdebugname());
327 break;
328 #if HAVE_CPU_OPTS
329 case OPTS:
330 print_cpu_opts(f,p->content.opts);
331 break;
332 #endif
333 case PRINTTEXT:
334 fprintf(f,"text: \"%s\"",p->content.ptext);
335 break;
336 case PRINTEXPR:
337 fprintf(f,"expr: ");
338 print_expr(f,p->content.pexpr->print_exp);
339 break;
340 case ROFFS:
341 fprintf(f,"roffs: offset ");
342 print_expr(f,p->content.roffs);
343 break;
344 case RORG:
345 fprintf(f,"rorg: relocate to 0x%llx",ULLTADDR(*p->content.rorg));
346 break;
347 case RORGEND:
348 fprintf(f,"rorg end");
349 break;
350 case ASSERT:
351 fprintf(f,"assert: %s (message: %s)\n",p->content.assert->expstr,
352 p->content.assert->msgstr?p->content.assert->msgstr:emptystr);
353 break;
354 case NLIST:
355 fprintf(f,"nlist: %s (type %d, other %d, desc %d) with value ",
356 p->content.nlist->name!=NULL ? p->content.nlist->name : "<NULL>",
357 p->content.nlist->type,p->content.nlist->other,
358 p->content.nlist->desc);
359 if (p->content.nlist->value != NULL)
360 print_expr(f,p->content.nlist->value);
361 else
362 fprintf(f,"NULL");
363 break;
364 default:
365 ierror(0);
366 }
367 }
368
369
370 /* prints and formats an expression from a PRINTEXPR atom */
atom_printexpr(printexpr * pexp,section * sec,taddr pc)371 void atom_printexpr(printexpr *pexp,section *sec,taddr pc)
372 {
373 taddr t;
374 long long v;
375 int i;
376
377 eval_expr(pexp->print_exp,&t,sec,pc);
378 if (pexp->type==PEXP_SDEC && (t&(1LL<<(pexp->size-1)))!=0) {
379 /* signed decimal */
380 v = -1;
381 v &= ~(long long)MAKEMASK(pexp->size);
382 }
383 else
384 v = 0;
385 v |= t & MAKEMASK(pexp->size);
386
387 switch (pexp->type) {
388 case PEXP_HEX:
389 printf("%llX",(unsigned long long)v);
390 break;
391 case PEXP_SDEC:
392 printf("%lld",v);
393 break;
394 case PEXP_UDEC:
395 printf("%llu",(unsigned long long)v);
396 break;
397 case PEXP_BIN:
398 for (i=pexp->size-1; i>=0; i--)
399 putchar((v & (1LL<<i)) ? '1' : '0');
400 break;
401 case PEXP_ASC:
402 for (i=((pexp->size+7)>>3)-1; i>=0; i--) {
403 unsigned char c = (v>>(i*8))&0xff;
404 putchar(isprint(c) ? c : '.');
405 }
406 break;
407 default:
408 ierror(0);
409 break;
410 }
411 }
412
413
clone_atom(atom * a)414 atom *clone_atom(atom *a)
415 {
416 atom *new = mymalloc(sizeof(atom));
417 void *p;
418
419 memcpy(new,a,sizeof(atom));
420
421 switch (a->type) {
422 /* INSTRUCTION and DATADEF have to be cloned as well, because they will
423 be deallocated and transformed into DATA during assemble() */
424 case INSTRUCTION:
425 p = mymalloc(sizeof(instruction));
426 memcpy(p,a->content.inst,sizeof(instruction));
427 new->content.inst = p;
428 break;
429 case DATADEF:
430 p = mymalloc(sizeof(defblock));
431 memcpy(p,a->content.defb,sizeof(defblock));
432 new->content.defb = p;
433 break;
434 default:
435 break;
436 }
437
438 new->next = 0;
439 new->src = NULL;
440 new->line = 0;
441 new->list = NULL;
442 return new;
443 }
444
445
new_atom(int type,taddr align)446 static atom *new_atom(int type,taddr align)
447 {
448 atom *new = mymalloc(sizeof(*new));
449
450 new->next = NULL;
451 new->type = type;
452 new->align = align;
453 return new;
454 }
455
456
new_inst_atom(instruction * p)457 atom *new_inst_atom(instruction *p)
458 {
459 atom *new = new_atom(INSTRUCTION,inst_alignment);
460
461 new->content.inst = p;
462 return new;
463 }
464
465
new_data_atom(dblock * p,taddr align)466 atom *new_data_atom(dblock *p,taddr align)
467 {
468 atom *new = new_atom(DATA,align);
469
470 new->content.db = p;
471 return new;
472 }
473
474
new_label_atom(symbol * p)475 atom *new_label_atom(symbol *p)
476 {
477 atom *new = new_atom(LABEL,1);
478
479 new->content.label = p;
480 return new;
481 }
482
483
new_space_atom(expr * space,size_t size,expr * fill)484 atom *new_space_atom(expr *space,size_t size,expr *fill)
485 {
486 atom *new = new_atom(SPACE,1);
487 int i;
488
489 if (size<1)
490 ierror(0); /* usually an error in syntax-module */
491 new->content.sb = new_sblock(space,size,fill);
492 return new;
493 }
494
495
new_datadef_atom(size_t bitsize,operand * op)496 atom *new_datadef_atom(size_t bitsize,operand *op)
497 {
498 atom *new = new_atom(DATADEF,DATA_ALIGN(bitsize));
499
500 new->content.defb = mymalloc(sizeof(*new->content.defb));
501 new->content.defb->bitsize = bitsize;
502 new->content.defb->op = op;
503 return new;
504 }
505
506
new_srcline_atom(int line)507 atom *new_srcline_atom(int line)
508 {
509 atom *new = new_atom(LINE,1);
510
511 new->content.srcline = line;
512 return new;
513 }
514
515
new_opts_atom(void * o)516 atom *new_opts_atom(void *o)
517 {
518 atom *new = new_atom(OPTS,1);
519
520 new->content.opts = o;
521 return new;
522 }
523
524
new_text_atom(char * txt)525 atom *new_text_atom(char *txt)
526 {
527 atom *new = new_atom(PRINTTEXT,1);
528
529 new->content.ptext = txt ? txt : "\n";
530 return new;
531 }
532
533
new_expr_atom(expr * exp,int type,int size)534 atom *new_expr_atom(expr *exp,int type,int size)
535 {
536 atom *new = new_atom(PRINTEXPR,1);
537
538 new->content.pexpr = mymalloc(sizeof(*new->content.pexpr));
539 if (exp==NULL || type<PEXP_HEX || type>PEXP_ASC || size<1
540 || size>sizeof(long long)*8)
541 ierror(0);
542 new->content.pexpr->print_exp = exp;
543 new->content.pexpr->type = type;
544 new->content.pexpr->size = size;
545 return new;
546 }
547
548
new_roffs_atom(expr * offs)549 atom *new_roffs_atom(expr *offs)
550 {
551 atom *new = new_atom(ROFFS,1);
552
553 new->content.roffs = offs;
554 return new;
555 }
556
557
new_rorg_atom(taddr raddr)558 atom *new_rorg_atom(taddr raddr)
559 {
560 atom *new = new_atom(RORG,1);
561 taddr *newrorg = mymalloc(sizeof(taddr));
562
563 *newrorg = raddr;
564 new->content.rorg = newrorg;
565 return new;
566 }
567
568
new_rorgend_atom(void)569 atom *new_rorgend_atom(void)
570 {
571 return new_atom(RORGEND,1);
572 }
573
574
new_assert_atom(expr * aexp,char * exp,char * msg)575 atom *new_assert_atom(expr *aexp,char *exp,char *msg)
576 {
577 atom *new = new_atom(ASSERT,1);
578
579 new->content.assert = mymalloc(sizeof(*new->content.assert));
580 new->content.assert->assert_exp = aexp;
581 new->content.assert->expstr = exp;
582 new->content.assert->msgstr = msg;
583 return new;
584 }
585
586
new_nlist_atom(char * name,int type,int other,int desc,expr * value)587 atom *new_nlist_atom(char *name,int type,int other,int desc,expr *value)
588 {
589 atom *new = new_atom(NLIST,1);
590
591 new->content.nlist = mymalloc(sizeof(*new->content.nlist));
592 new->content.nlist->name = name;
593 new->content.nlist->type = type;
594 new->content.nlist->other = other;
595 new->content.nlist->desc = desc;
596 new->content.nlist->value = value;
597 return new;
598 }
599