static int test_register(char * n, asm86_t * a) { int r; optype_t optype; /* PSEUDO or JUMP */ if (!a || (a->optype != NONE && a->optype < BYTE)) return isregister(n); /* * as we assume that instructions without specified operand size like * mov use 32bit ones we must make sure that we are not passing * suchinstruction a register of a different size */ if (r = isregister(n)) { if (IS_REG8(r)) { optype = BYTE; } else if (IS_REG16(r)) { optype = WORD; } else if (IS_REG32(r)) { optype = OWORD; } } a->optype = (a->optype > optype ? optype : a->optype); return r; }
static expression_t *gnu_get_oplist(asm86_t * a, int *pn, int deref) /* Get a comma (or colon for jmpf and callf) separated list of instruction * operands. */ { expression_t *e, *o1, *o2; token_t *t; int sreg; if ((e= gnu_get_operand(a, pn, deref)) == nil) return nil; t = get_token(*pn); if (t->symbol == ':' && IS_REGSEG(sreg = isregister(e->name))) { a->seg = segreg2seg(sreg); del_expr(e); (*pn)++; e = gnu_get_oplist(a, pn, deref); } else if (t->symbol == ',' || t->symbol == ':') { o1= e; (*pn)++; if ((o2= gnu_get_oplist(a, pn, deref)) == nil) { del_expr(o1); return nil; } e= new_expr(); e->operator= ','; e->left= o2; e->right= o1; } return e; }
int syms_is_global(const char * n) { struct sym *s; if (!n || is_number(n) || is_local_label_ref(n) || isregister(n)) return 0; /* if not found, it must be extern -> global */ if (!(s = sym_exists(n))) return 1; return s->gl; }
static expression_t *ack_get_operand(int *pn, int deref) /* Get something like: (memory), offset(base)(index*scale), or simpler. */ { expression_t *e, *offset, *base, *index; token_t *t; int c; /* Is it (memory)? */ if (get_token(*pn)->symbol == '(' && ((t= get_token(*pn + 1))->type != T_WORD || !isregister(t->name)) ) { /* A memory dereference. */ (*pn)++; if ((offset= ack_get_C_expression(pn)) == nil) return nil; if (get_token(*pn)->symbol != ')') { parse_err(1, t, "operand syntax error\n"); del_expr(offset); return nil; } (*pn)++; e= new_expr(); e->operator= '('; e->middle= offset; return e; } /* #constant? */ if (dialect == NCC && deref && ((c= get_token(*pn)->symbol) == '#' || c == '*')) { /* NCC: mov ax,#constant -> ACK: mov ax,constant */ (*pn)++; return ack_get_C_expression(pn); } /* @address? */ if (dialect == NCC && get_token(*pn)->symbol == '@') { /* NCC: jmp @address -> ACK: jmp (address) */ (*pn)++; if ((offset= ack_get_operand(pn, deref)) == nil) return nil; e= new_expr(); e->operator= '('; e->middle= offset; return e; } /* Offset? */ if (get_token(*pn)->symbol != '(') { /* There is an offset. */ if ((offset= ack_get_C_expression(pn)) == nil) return nil; } else { /* No offset. */ offset= nil; } /* (base)? */ if (get_token(*pn)->symbol == '(' && (t= get_token(*pn + 1))->type == T_WORD && isregister(t->name) && get_token(*pn + 2)->symbol == ')' ) { /* A base register expression. */ base= new_expr(); base->operator= 'B'; base->name= copystr(t->name); (*pn)+= 3; } else { /* No base register expression. */ base= nil; } /* (index*scale)? */ if (get_token(*pn)->symbol == '(') { /* An index most likely. */ token_t *m= nil; if (!( /* This must be true: */ (t= get_token(*pn + 1))->type == T_WORD && isregister(t->name) && (get_token(*pn + 2)->symbol == ')' || ( get_token(*pn + 2)->symbol == '*' && (m= get_token(*pn + 3))->type == T_WORD && strchr("1248", m->name[0]) != nil && m->name[1] == 0 && get_token(*pn + 4)->symbol == ')' )) )) { /* Alas it isn't */ parse_err(1, t, "operand syntax error\n"); del_expr(offset); del_expr(base); return nil; } /* Found an index. */ index= new_expr(); index->operator= m == nil ? '1' : m->name[0]; index->name= copystr(t->name); (*pn)+= (m == nil ? 3 : 5); } else { /* No index. */ index= nil; } if (dialect == NCC && deref && base == nil && index == nil && !(offset != nil && offset->operator == 'W' && isregister(offset->name)) ) { /* NCC: mov ax,thing -> ACK mov ax,(thing) */ e= new_expr(); e->operator= '('; e->middle= offset; return e; } if (base == nil && index == nil) { /* Return a lone offset as is. */ e= offset; } else { e= new_expr(); e->operator= 'O'; e->left= offset; e->middle= base; e->right= index; } return e; }
static expression_t *gnu_get_operand(asm86_t * a, int *pn, int deref) /* Get something like: $immed, memory, offset(%base,%index,scale), or simpler. */ { expression_t *e, *offset, *base, *index; token_t *t; int c; if (get_token(*pn)->symbol == '$') { /* An immediate value. */ (*pn)++; return gnu_get_C_expression(pn); } if (get_token(*pn)->symbol == '*') { (*pn)++; deref = 1; #if 0 if ((offset= gnu_get_operand(a, pn, deref)) == nil) return nil; #if 0 e= new_expr(); e->operator= '('; e->middle= offset; return e; #endif return offset; #endif } if ((get_token(*pn)->symbol == '%') && (t= get_token(*pn + 1))->type == T_WORD && isregister(t->name) ) { /* A register operand. */ (*pn)+= 2; e= new_expr(); e->operator= 'W'; e->name= copystr(t->name); return e; } /* Offset? */ if (get_token(*pn)->symbol != '(' || get_token(*pn + 1)->symbol != '%') { /* There is an offset. */ if ((offset= gnu_get_C_expression(pn)) == nil) return nil; } else { /* No offset. */ offset= nil; } /* (%base,%index,scale) ? */ base= index= nil; if (get_token(*pn)->symbol == '(') { (*pn)++; /* %base ? */ if (get_token(*pn)->symbol == '%' && (t= get_token(*pn + 1))->type == T_WORD && isregister(t->name) ) { /* A base register expression. */ base= new_expr(); base->operator= 'B'; base->name= copystr(t->name); (*pn)+= 2; } if (get_token(*pn)->symbol == ',') (*pn)++; /* %index ? */ if (get_token(*pn)->symbol == '%' && (t= get_token(*pn + 1))->type == T_WORD && isregister(t->name) ) { /* A index register expression. */ index= new_expr(); index->operator= '1'; /* for now */ index->name= copystr(t->name); (*pn)+= 2; } if (get_token(*pn)->symbol == ',') (*pn)++; /* scale ? */ if ((base != nil || index != nil) && (t= get_token(*pn))->type == T_WORD && strchr("1248", t->name[0]) != nil && t->name[1] == 0 ) { if (index == nil) { /* Base is really an index register. */ index= base; base= nil; } index->operator= t->name[0]; (*pn)++; } if (get_token(*pn)->symbol == ')') { /* Ending paren. */ (*pn)++; } else { /* Alas. */ parse_err(1, t, "operand syntax error\n"); del_expr(offset); del_expr(base); del_expr(index); return nil; } } if (base == nil && index == nil) { if (deref) { /* Return a lone offset as (offset). */ e= new_expr(); e->operator= '('; e->middle= offset; } else { /* Return a lone offset as is. */ e= offset; } } else { e= new_expr(); e->operator= 'O'; e->left= offset; e->middle= base; e->right= index; } return e; }