overall structure much more modular.
The test files, which need access to the internals of the structures being
tested, now include the source file instead of the header file to gain access
to all internal formats and functions.
svn path=/trunk/yasm/; revision=261
RCSID("$IdPath$");
-/* Static structures for when NULL is passed to conversion functions. */
-/* for Convert*ToImm() */
-static immval im_static;
+struct effaddr {
+ expr *disp; /* address displacement */
+ unsigned char len; /* length of disp (in bytes), 0 if none */
+
+ unsigned char segment; /* segment override, 0 if none */
+
+ unsigned char modrm;
+ unsigned char valid_modrm; /* 1 if Mod/RM byte currently valid, 0 if not */
+ unsigned char need_modrm; /* 1 if Mod/RM byte needed, 0 if not */
+
+ unsigned char sib;
+ unsigned char valid_sib; /* 1 if SIB byte currently valid, 0 if not */
+ unsigned char need_sib; /* 1 if SIB byte needed, 0 if not */
+};
+
+struct immval {
+ expr *val;
+
+ unsigned char len; /* length of val (in bytes), 0 if none */
+ unsigned char isneg; /* the value has been explicitly negated */
+
+ unsigned char f_len; /* final imm length */
+ unsigned char f_sign; /* 1 if final imm should be signed */
+};
+
+struct dataval {
+ STAILQ_ENTRY(dataval) link;
+ enum { DV_EMPTY, DV_EXPR, DV_FLOAT, DV_STRING } type;
+
+ union {
+ expr *expn;
+ floatnum *flt;
+ char *str_val;
+ } data;
+};
+
+struct bytecode {
+ STAILQ_ENTRY(bytecode) link;
+
+ enum { BC_EMPTY, BC_INSN, BC_JMPREL, BC_DATA, BC_RESERVE } type;
+
+ /* This union has been somewhat tweaked to get it as small as possible
+ * on the 4-byte-aligned x86 architecture (without resorting to
+ * bitfields). In particular, insn and jmprel are the largest structures
+ * in the union, and are also the same size (after padding). jmprel
+ * can have another unsigned char added to the end without affecting
+ * its size.
+ *
+ * Don't worry about this too much, but keep it in mind when changing
+ * this structure. We care about the size of bytecode in particular
+ * because it accounts for the majority of the memory usage in the
+ * assembler when assembling a large file.
+ */
+ union {
+ struct {
+ effaddr *ea; /* effective address */
+
+ immval imm; /* immediate or relative value */
+
+ unsigned char opcode[3]; /* opcode */
+ unsigned char opcode_len;
+
+ unsigned char addrsize; /* 0 indicates no override */
+ unsigned char opersize; /* 0 indicates no override */
+ unsigned char lockrep_pre; /* 0 indicates no prefix */
+
+ /* HACK, but a space-saving one: shift opcodes have an immediate
+ * form and a ,1 form (with no immediate). In the parser, we
+ * set this and opcode_len=1, but store the ,1 version in the
+ * second byte of the opcode array. We then choose between the
+ * two versions once we know the actual value of imm (because we
+ * don't know it in the parser module).
+ *
+ * A override to force the imm version should just leave this at
+ * 0. Then later code won't know the ,1 version even exists.
+ * TODO: Figure out how this affects CPU flags processing.
+ *
+ * Call SetInsnShiftFlag() to set this flag to 1.
+ */
+ unsigned char shift_op;
+ } insn;
+ struct {
+ expr *target; /* target location */
+
+ struct {
+ unsigned char opcode[3];
+ unsigned char opcode_len; /* 0 = no opc for this version */
+ } shortop, nearop;
+
+ /* which opcode are we using? */
+ /* The *FORCED forms are specified in the source as such */
+ jmprel_opcode_sel op_sel;
+
+ unsigned char addrsize; /* 0 indicates no override */
+ unsigned char opersize; /* 0 indicates no override */
+ unsigned char lockrep_pre; /* 0 indicates no prefix */
+ } jmprel;
+ struct {
+ /* non-converted data (linked list) */
+ datavalhead datahead;
+
+ /* final (converted) size of each element (in bytes) */
+ unsigned char size;
+ } data;
+ struct {
+ expr *numitems; /* number of items to reserve */
+ unsigned char itemsize; /* size of each item (in bytes) */
+ } reserve;
+ } data;
+
+ unsigned long len; /* total length of entire bytecode */
+
+ /* where it came from */
+ char *filename;
+ unsigned int lineno;
+
+ /* other assembler state info */
+ unsigned long offset;
+ unsigned char mode_bits;
+};
+
+/* Static structures for when NULL is passed to conversion functions. */
/* for Convert*ToBytes() */
unsigned char bytes_static[16];
}
immval *
-ConvertIntToImm(immval *ptr, unsigned long int_val)
+immval_new_int(unsigned long int_val)
{
- if (!ptr)
- ptr = &im_static;
+ immval *im = xmalloc(sizeof(immval));
- /* FIXME: this will leak expr's if static is used */
- ptr->val = expr_new_ident(EXPR_INT, ExprInt(int_val));
+ im->val = expr_new_ident(ExprInt(int_val));
if ((int_val & 0xFF) == int_val)
- ptr->len = 1;
+ im->len = 1;
else if ((int_val & 0xFFFF) == int_val)
- ptr->len = 2;
+ im->len = 2;
else
- ptr->len = 4;
+ im->len = 4;
- ptr->isneg = 0;
+ im->isneg = 0;
- return ptr;
+ return im;
}
immval *
-ConvertExprToImm(immval *ptr, expr *expr_ptr)
+immval_new_expr(expr *expr_ptr)
{
- if (!ptr)
- ptr = &im_static;
+ immval *im = xmalloc(sizeof(immval));
- ptr->val = expr_ptr;
+ im->val = expr_ptr;
- ptr->isneg = 0;
+ im->isneg = 0;
- return ptr;
+ return im;
}
void
if (!ptr)
return;
- if (ptr->segment != 0)
+ if (segment != 0 && ptr->segment != 0)
Warning(_("multiple segment overrides, using leftmost"));
ptr->segment = segment;
ptr->len = len;
}
+effaddr *
+GetInsnEA(bytecode *bc)
+{
+ if (!bc)
+ return NULL;
+
+ if (bc->type != BC_INSN)
+ InternalError(__LINE__, __FILE__,
+ _("Trying to get EA of non-instruction"));
+
+ return bc->data.insn.ea;
+}
+
void
SetInsnOperSizeOverride(bytecode *bc, unsigned char opersize)
{
if (!old_sel)
return;
- if ((*old_sel == JR_SHORT_FORCED) || (*old_sel == JR_NEAR_FORCED))
+ if (new_sel != JR_NONE && ((*old_sel == JR_SHORT_FORCED) ||
+ (*old_sel == JR_NEAR_FORCED)))
Warning(_("multiple SHORT or NEAR specifiers, using leftmost"));
*old_sel = new_sel;
}
return retval;
}
+dataval *
+datavals_append(datavalhead *headp, dataval *dv)
+{
+ if (dv) {
+ STAILQ_INSERT_TAIL(headp, dv, link);
+ return dv;
+ }
+ return (dataval *)NULL;
+}
+
void
dataval_print(datavalhead *head)
{
#ifndef YASM_BYTECODE_H
#define YASM_BYTECODE_H
-struct section_s;
-
-typedef struct effaddr_s {
- struct expr_s *disp; /* address displacement */
- unsigned char len; /* length of disp (in bytes), 0 if none */
-
- unsigned char segment; /* segment override, 0 if none */
-
- unsigned char modrm;
- unsigned char valid_modrm; /* 1 if Mod/RM byte currently valid, 0 if not */
- unsigned char need_modrm; /* 1 if Mod/RM byte needed, 0 if not */
-
- unsigned char sib;
- unsigned char valid_sib; /* 1 if SIB byte currently valid, 0 if not */
- unsigned char need_sib; /* 1 if SIB byte needed, 0 if not */
-} effaddr;
-
-typedef struct immval_s {
- struct expr_s *val;
-
- unsigned char len; /* length of val (in bytes), 0 if none */
- unsigned char isneg; /* the value has been explicitly negated */
-
- unsigned char f_len; /* final imm length */
- unsigned char f_sign; /* 1 if final imm should be signed */
-} immval;
+#ifndef YASM_SECTION
+#define YASM_SECTION
+typedef struct section section;
+#endif
-typedef STAILQ_HEAD(datavalhead_s, dataval_s) datavalhead;
+#ifndef YASM_EXPR
+#define YASM_EXPR
+typedef struct expr expr;
+#endif
-typedef struct dataval_s {
- STAILQ_ENTRY(dataval_s) link;
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
- enum { DV_EMPTY, DV_EXPR, DV_FLOAT, DV_STRING } type;
+typedef struct effaddr effaddr;
+typedef struct immval immval;
+typedef STAILQ_HEAD(datavalhead, dataval) datavalhead;
+typedef struct dataval dataval;
+typedef STAILQ_HEAD(bytecodehead, bytecode) bytecodehead;
- union {
- struct expr_s *expn;
- struct floatnum_s *flt;
- char *str_val;
- } data;
-} dataval;
+#ifndef YASM_BYTECODE
+#define YASM_BYTECODE
+typedef struct bytecode bytecode;
+#endif
-typedef enum jmprel_opcode_sel_e {
+typedef enum {
JR_NONE,
JR_SHORT,
JR_NEAR,
} jmprel_opcode_sel;
typedef struct targetval_s {
- struct expr_s *val;
+ expr *val;
jmprel_opcode_sel op_sel;
} targetval;
-typedef STAILQ_HEAD(bytecodehead_s, bytecode_s) bytecodehead;
-
-typedef struct bytecode_s {
- STAILQ_ENTRY(bytecode_s) link;
-
- enum { BC_EMPTY, BC_INSN, BC_JMPREL, BC_DATA, BC_RESERVE } type;
-
- /* This union has been somewhat tweaked to get it as small as possible
- * on the 4-byte-aligned x86 architecture (without resorting to
- * bitfields). In particular, insn and jmprel are the largest structures
- * in the union, and are also the same size (after padding). jmprel
- * can have another unsigned char added to the end without affecting
- * its size.
- *
- * Don't worry about this too much, but keep it in mind when changing
- * this structure. We care about the size of bytecode in particular
- * because it accounts for the majority of the memory usage in the
- * assembler when assembling a large file.
- */
- union {
- struct {
- effaddr *ea; /* effective address */
-
- immval imm; /* immediate or relative value */
-
- unsigned char opcode[3]; /* opcode */
- unsigned char opcode_len;
-
- unsigned char addrsize; /* 0 indicates no override */
- unsigned char opersize; /* 0 indicates no override */
- unsigned char lockrep_pre; /* 0 indicates no prefix */
-
- /* HACK, but a space-saving one: shift opcodes have an immediate
- * form and a ,1 form (with no immediate). In the parser, we
- * set this and opcode_len=1, but store the ,1 version in the
- * second byte of the opcode array. We then choose between the
- * two versions once we know the actual value of imm (because we
- * don't know it in the parser module).
- *
- * A override to force the imm version should just leave this at
- * 0. Then later code won't know the ,1 version even exists.
- * TODO: Figure out how this affects CPU flags processing.
- *
- * Call SetInsnShiftFlag() to set this flag to 1.
- */
- unsigned char shift_op;
- } insn;
- struct {
- struct expr_s *target; /* target location */
-
- struct {
- unsigned char opcode[3];
- unsigned char opcode_len; /* 0 = no opc for this version */
- } shortop, nearop;
-
- /* which opcode are we using? */
- /* The *FORCED forms are specified in the source as such */
- jmprel_opcode_sel op_sel;
-
- unsigned char addrsize; /* 0 indicates no override */
- unsigned char opersize; /* 0 indicates no override */
- unsigned char lockrep_pre; /* 0 indicates no prefix */
- } jmprel;
- struct {
- /* non-converted data (linked list) */
- datavalhead datahead;
-
- /* final (converted) size of each element (in bytes) */
- unsigned char size;
- } data;
- struct {
- struct expr_s *numitems; /* number of items to reserve */
- unsigned char itemsize; /* size of each item (in bytes) */
- } reserve;
- } data;
-
- unsigned long len; /* total length of entire bytecode */
-
- /* where it came from */
- char *filename;
- unsigned int lineno;
-
- /* other assembler state info */
- unsigned long offset;
- unsigned char mode_bits;
-} bytecode;
-
effaddr *effaddr_new_reg(unsigned long reg);
effaddr *effaddr_new_imm(immval *im_ptr, unsigned char im_len);
-effaddr *effaddr_new_expr(struct expr_s *expr_ptr);
+effaddr *effaddr_new_expr(expr *expr_ptr);
-immval *ConvertIntToImm(immval *ptr, unsigned long int_val);
-immval *ConvertExprToImm(immval *ptr, struct expr_s *expr_ptr);
+immval *immval_new_int(unsigned long int_val);
+immval *immval_new_expr(expr *expr_ptr);
void SetEASegment(effaddr *ptr, unsigned char segment);
void SetEALen(effaddr *ptr, unsigned char len);
+effaddr *GetInsnEA(bytecode *bc);
+
void SetInsnOperSizeOverride(bytecode *bc, unsigned char opersize);
void SetInsnAddrSizeOverride(bytecode *bc, unsigned char addrsize);
void SetInsnLockRepPrefix(bytecode *bc, unsigned char prefix);
bytecode *bytecode_new_data(datavalhead *datahead, unsigned long size);
-bytecode *bytecode_new_reserve(struct expr_s *numitems,
- unsigned long itemsize);
+bytecode *bytecode_new_reserve(expr *numitems, unsigned long itemsize);
/* Gets the offset of the bytecode specified by bc if possible.
* Return value is IF POSSIBLE, not the value.
*/
-int bytecode_get_offset(struct section_s *sect, bytecode *bc,
- unsigned long *ret_val);
+int bytecode_get_offset(section *sect, bytecode *bc, unsigned long *ret_val);
void bytecode_print(bytecode *bc);
*/
bytecode *bytecodes_append(bytecodehead *headp, bytecode *bc);
-dataval *dataval_new_expr(struct expr_s *expn);
-dataval *dataval_new_float(struct floatnum_s *flt);
+dataval *dataval_new_expr(expr *expn);
+dataval *dataval_new_float(floatnum *flt);
dataval *dataval_new_string(char *str_val);
+/* void datavals_initialize(datavalhead *headp); */
+#define datavals_initialize(headp) STAILQ_INIT(headp)
+
+/* Adds dv to the list of datavals headp.
+ * NOTE: Does not make a copy of dv; so don't pass this function
+ * static or local variables, and discard the dv pointer after calling
+ * this function. If dv was actually appended (it wasn't NULL), then
+ * returns dv, otherwise returns NULL.
+ */
+dataval *datavals_append(datavalhead *headp, dataval *dv);
+
void dataval_print(datavalhead *head);
#endif
# include <string.h>
#endif
+#include <libintl.h>
+#define _(String) gettext(String)
+#ifdef gettext_noop
+#define N_(String) gettext_noop(String)
+#else
+#define N_(String) (String)
+#endif
+
#include "globals.h"
#include "errwarn.h"
#include "floatnum.h"
RCSID("$IdPath$");
+typedef enum {
+ EXPR_NONE, /* for left side of a NOT, NEG, etc. */
+ EXPR_SYM,
+ EXPR_EXPR,
+ EXPR_INT,
+ EXPR_FLOAT
+} ExprType;
+
+struct ExprItem {
+ ExprType type;
+ union {
+ symrec *sym;
+ expr *expn;
+ unsigned long int_val;
+ floatnum *flt;
+ } data;
+};
+
+struct expr {
+ ExprItem left, right;
+ ExprOp op;
+};
+
/* allocate a new expression node, with children as defined.
* If it's a unary operator, put the element on the right */
expr *
-expr_new(ExprType ltype,
- ExprItem left,
- ExprOp op,
- ExprType rtype,
- ExprItem right)
+expr_new(ExprItem *left, ExprOp op, ExprItem *right)
{
expr *ptr;
ptr = xmalloc(sizeof(expr));
- ptr->ltype = ltype;
+ ptr->left.type = EXPR_NONE;
ptr->op = op;
- ptr->rtype = rtype;
- switch (ltype) {
- case EXPR_SYM:
- case EXPR_EXPR:
- case EXPR_INT:
- case EXPR_FLOAT:
- memcpy(&ptr->left, &left, sizeof(ExprItem));
- break;
- case EXPR_NONE:
- break;
+ ptr->right.type = EXPR_NONE;
+ if (left) {
+ memcpy(&ptr->left, left, sizeof(ExprItem));
+ free(left);
}
- switch (rtype) {
- case EXPR_SYM:
- case EXPR_EXPR:
- case EXPR_INT:
- case EXPR_FLOAT:
- memcpy(&ptr->right, &right, sizeof(ExprItem));
- break;
- case EXPR_NONE:
- Fatal(FATAL_UNKNOWN); /* TODO: better error? */
- break;
+ if (right) {
+ memcpy(&ptr->right, right, sizeof(ExprItem));
+ free(right);
+ } else {
+ InternalError(__LINE__, __FILE__,
+ _("Right side of expression must exist"));
}
return ptr;
}
/* helpers */
-ExprItem
-ExprSym(struct symrec_s *s)
+ExprItem *
+ExprSym(symrec *s)
{
- ExprItem e;
-
- e.sym = s;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_SYM;
+ e->data.sym = s;
return e;
}
-ExprItem
+ExprItem *
ExprExpr(expr *x)
{
- ExprItem e;
- e.exp = x;
-
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_EXPR;
+ e->data.expn = x;
return e;
}
-ExprItem
+ExprItem *
ExprInt(unsigned long i)
{
- ExprItem e;
-
- e.int_val = i;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_INT;
+ e->data.int_val = i;
return e;
}
-ExprItem
+ExprItem *
ExprFloat(floatnum *f)
{
- ExprItem e;
-
- e.flt = f;
- return e;
-}
-
-ExprItem
-ExprNone(void)
-{
- ExprItem e;
-
- e.int_val = 0;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_FLOAT;
+ e->data.flt = f;
return e;
}
unsigned long int_val;
/* try to simplify the left side */
- if (e->ltype == EXPR_EXPR) {
+ if (e->left.type == EXPR_EXPR) {
/* if the left subexpr isn't an IDENT, recurse simplification */
- if (e->left.exp->op != EXPR_IDENT)
- simplified |= expr_simplify(e->left.exp);
+ if (e->left.data.expn->op != EXPR_IDENT)
+ simplified |= expr_simplify(e->left.data.expn);
/* if the left subexpr is just an IDENT (or string thereof),
* pull it up into the current node */
- while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
+ while (e->left.type == EXPR_EXPR && e->left.data.expn->op == EXPR_IDENT) {
ExprItem tmp;
- e->ltype = e->left.exp->rtype;
- memcpy(&tmp, &(e->left.exp->right), sizeof(ExprItem));
- free(e->left.exp);
- memcpy(&(e->left.int_val), &tmp, sizeof(ExprItem));
+ e->left.type = e->left.data.expn->right.type;
+ memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
+ free(e->left.data.expn);
+ memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
simplified = 1;
}
- } else if (e->ltype == EXPR_SYM) {
+ } else if (e->left.type == EXPR_SYM) {
/* try to get value of symbol */
- if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
- e->ltype = EXPR_INT;
+ if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
+ e->left.type = EXPR_INT;
/* don't try to free the symrec here. */
- e->left.int_val = int_val;
+ e->left.data.int_val = int_val;
simplified = 1;
}
}
/* ditto on the right */
- if (e->rtype == EXPR_EXPR) {
- if (e->right.exp->op != EXPR_IDENT)
- simplified |= expr_simplify(e->right.exp);
+ if (e->right.type == EXPR_EXPR) {
+ if (e->right.data.expn->op != EXPR_IDENT)
+ simplified |= expr_simplify(e->right.data.expn);
- while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
+ while (e->right.type == EXPR_EXPR && e->right.data.expn->op == EXPR_IDENT) {
ExprItem tmp;
- e->rtype = e->right.exp->rtype;
- memcpy(&tmp, &(e->right.exp->right), sizeof(ExprItem));
- free(e->right.exp);
- memcpy(&(e->right.int_val), &tmp, sizeof(ExprItem));
+ e->right.type = e->right.data.expn->right.type;
+ memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
+ free(e->right.data.expn);
+ memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
simplified = 1;
}
- } else if (e->rtype == EXPR_SYM) {
- if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
- e->rtype = EXPR_INT;
+ } else if (e->right.type == EXPR_SYM) {
+ if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
+ e->right.type = EXPR_INT;
/* don't try to free the symrec here. */
- e->right.int_val = int_val;
+ e->right.data.int_val = int_val;
simplified = 1;
}
}
- if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
- && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
+ if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE)
+ && e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
switch (e->op) {
case EXPR_ADD:
- e->right.int_val = e->left.int_val + e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val + e->right.data.int_val;
break;
case EXPR_SUB:
- e->right.int_val = e->left.int_val - e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val - e->right.data.int_val;
break;
case EXPR_MUL:
- e->right.int_val = e->left.int_val * e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val * e->right.data.int_val;
break;
case EXPR_DIV:
- e->right.int_val = e->left.int_val / e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val / e->right.data.int_val;
break;
case EXPR_MOD:
- e->right.int_val = e->left.int_val % e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val % e->right.data.int_val;
break;
case EXPR_NEG:
- e->right.int_val = -(e->right.int_val);
+ e->right.data.int_val = -(e->right.data.int_val);
break;
case EXPR_NOT:
- e->right.int_val = ~(e->right.int_val);
+ e->right.data.int_val = ~(e->right.data.int_val);
break;
case EXPR_OR:
- e->right.int_val = e->left.int_val | e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val | e->right.data.int_val;
break;
case EXPR_AND:
- e->right.int_val = e->left.int_val & e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val & e->right.data.int_val;
break;
case EXPR_XOR:
- e->right.int_val = e->left.int_val ^ e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val ^ e->right.data.int_val;
break;
case EXPR_SHL:
- e->right.int_val = e->right.int_val << e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
break;
case EXPR_SHR:
- e->right.int_val = e->right.int_val << e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
break;
case EXPR_LOR:
- e->right.int_val = e->left.int_val || e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val || e->right.data.int_val;
break;
case EXPR_LAND:
- e->right.int_val = e->left.int_val && e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val && e->right.data.int_val;
break;
case EXPR_LNOT:
- e->right.int_val = !e->right.int_val;
+ e->right.data.int_val = !e->right.data.int_val;
break;
case EXPR_EQ:
- e->right.int_val = e->right.int_val == e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val == e->left.data.int_val;
break;
case EXPR_LT:
- e->right.int_val = e->right.int_val < e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val < e->left.data.int_val;
break;
case EXPR_GT:
- e->right.int_val = e->right.int_val > e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val > e->left.data.int_val;
break;
case EXPR_LE:
- e->right.int_val = e->right.int_val <= e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val <= e->left.data.int_val;
break;
case EXPR_GE:
- e->right.int_val = e->right.int_val >= e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val >= e->left.data.int_val;
break;
case EXPR_NE:
- e->right.int_val = e->right.int_val != e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val != e->left.data.int_val;
break;
case EXPR_IDENT:
break;
}
/* catch simple identities like 0+x, 1*x, etc., for x not a num */
- else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
- || (e->left.int_val == 0 &&
+ else if (e->left.type == EXPR_INT && ((e->left.data.int_val == 1 && e->op == EXPR_MUL)
+ || (e->left.data.int_val == 0 &&
e->op == EXPR_ADD)
- || (e->left.int_val == -1 &&
+ || (e->left.data.int_val == -1 &&
e->op == EXPR_AND)
- || (e->left.int_val == 0 &&
+ || (e->left.data.int_val == 0 &&
e->op == EXPR_OR))) {
e->op = EXPR_IDENT;
simplified = 1;
}
/* and the corresponding x+|-0, x*&/1 */
- else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
- || (e->right.int_val == 1 &&
+ else if (e->right.type == EXPR_INT && ((e->right.data.int_val == 1 && e->op == EXPR_MUL)
+ || (e->right.data.int_val == 1 &&
e->op == EXPR_DIV)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_ADD)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SUB)
- || (e->right.int_val == -1 &&
+ || (e->right.data.int_val == -1 &&
e->op == EXPR_AND)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_OR)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SHL)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SHR))) {
e->op = EXPR_IDENT;
- e->rtype = e->ltype;
+ e->right.type = e->left.type;
memcpy(&e->right, &e->left, sizeof(ExprItem));
simplified = 1;
}
int
expr_get_value(expr *e, unsigned long *retval)
{
- while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
+ while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
&& expr_simplify(e)) ;
- if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
- *retval = e->right.int_val;
+ if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
+ *retval = e->right.data.int_val;
return 1;
} else
return 0;
expr_print(expr *e)
{
if (e->op != EXPR_IDENT) {
- switch (e->ltype) {
+ switch (e->left.type) {
case EXPR_SYM:
- printf("%s", e->left.sym->name);
+ printf("%s", symrec_get_name(e->left.data.sym));
break;
case EXPR_EXPR:
printf("(");
- expr_print(e->left.exp);
+ expr_print(e->left.data.expn);
printf(")");
break;
case EXPR_INT:
- printf("%lu", e->left.int_val);
+ printf("%lu", e->left.data.int_val);
break;
case EXPR_FLOAT:
- floatnum_print(e->left.flt);
+ floatnum_print(e->left.data.flt);
break;
case EXPR_NONE:
break;
case EXPR_IDENT:
break;
}
- switch (e->rtype) {
+ switch (e->right.type) {
case EXPR_SYM:
- printf("%s", e->right.sym->name);
+ printf("%s", symrec_get_name(e->right.data.sym));
break;
case EXPR_EXPR:
printf("(");
- expr_print(e->right.exp);
+ expr_print(e->right.data.expn);
printf(")");
break;
case EXPR_INT:
- printf("%lu", e->right.int_val);
+ printf("%lu", e->right.data.int_val);
break;
case EXPR_FLOAT:
- floatnum_print(e->right.flt);
+ floatnum_print(e->right.data.flt);
break;
case EXPR_NONE:
break;
#ifndef YASM_EXPR_H
#define YASM_EXPR_H
+#ifndef YASM_SYMREC
+#define YASM_SYMREC
+typedef struct symrec symrec;
+#endif
+
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
+
typedef enum {
EXPR_ADD,
EXPR_SUB,
EXPR_IDENT /* if right is IDENT, then the entire expr is just a num */
} ExprOp;
-typedef enum {
- EXPR_NONE, /* for left side of a NOT, NEG, etc. */
- EXPR_SYM,
- EXPR_EXPR,
- EXPR_INT,
- EXPR_FLOAT
-} ExprType;
-
-typedef union expritem_u {
- struct symrec_s *sym;
- struct expr_s *exp;
- unsigned long int_val;
- struct floatnum_s *flt;
-} ExprItem;
+typedef struct ExprItem ExprItem;
-typedef struct expr_s {
- ExprType ltype, rtype;
- ExprItem left, right;
- ExprOp op;
-} expr;
+#ifndef YASM_EXPR
+#define YASM_EXPR
+typedef struct expr expr;
+#endif
-expr *expr_new(ExprType, ExprItem, ExprOp, ExprType, ExprItem);
+expr *expr_new(ExprItem *, ExprOp, ExprItem *);
-ExprItem ExprSym(struct symrec_s *);
-ExprItem ExprExpr(expr *);
-ExprItem ExprInt(unsigned long);
-ExprItem ExprFloat(struct floatnum_s *);
-ExprItem ExprNone(void);
+ExprItem *ExprSym(symrec *);
+ExprItem *ExprExpr(expr *);
+ExprItem *ExprInt(unsigned long);
+ExprItem *ExprFloat(floatnum *);
#define expr_new_tree(l,o,r) \
- expr_new (EXPR_EXPR, ExprExpr(l), (o), EXPR_EXPR, ExprExpr(r))
+ expr_new (ExprExpr(l), (o), ExprExpr(r))
#define expr_new_branch(o,r) \
- expr_new (EXPR_NONE, ExprNone(), (o), EXPR_EXPR, ExprExpr(r))
-#define expr_new_ident(t,r) \
- expr_new (EXPR_NONE, ExprNone(), EXPR_IDENT, (ExprType)(t), (r))
+ expr_new ((ExprItem *)NULL, (o), ExprExpr(r))
+#define expr_new_ident(r) \
+ expr_new ((ExprItem *)NULL, EXPR_IDENT, (r))
int expr_simplify(expr *);
void expr_print(expr *);
RCSID("$IdPath$");
+/* 97-bit internal floating point format:
+ * xxxxxxxs eeeeeeee eeeeeeee m.....................................m
+ * Sign exponent mantissa (80 bits)
+ * 79 0
+ *
+ * Only L.O. bit of Sign byte is significant. The rest is garbage.
+ * Exponent is bias 32767.
+ * Mantissa does NOT have an implied one bit (it's explicit).
+ */
+struct floatnum {
+ unsigned int *mantissa; /* Allocated to 64 bits */
+ unsigned short exponent;
+ unsigned char sign;
+ unsigned char flags;
+};
+
/* constants describing parameters of internal floating point format */
#define MANT_BITS 80
#define MANT_BYTES 10
#ifndef YASM_FLOATNUM_H
#define YASM_FLOATNUM_H
-/* 97-bit internal floating point format:
- * xxxxxxxs eeeeeeee eeeeeeee m.....................................m
- * Sign exponent mantissa (80 bits)
- * 79 0
- *
- * Only L.O. bit of Sign byte is significant. The rest is garbage.
- * Exponent is bias 32767.
- * Mantissa does NOT have an implied one bit (it's explicit).
- */
-typedef struct floatnum_s {
- unsigned int *mantissa; /* Allocated to 64 bits */
- unsigned short exponent;
- unsigned char sign;
- unsigned char flags;
-} floatnum;
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
floatnum *floatnum_new(const char *str);
void floatnum_delete(floatnum *flt);
RCSID("$IdPath$");
+struct section {
+ STAILQ_ENTRY(section) link;
+
+ enum { SECTION_GENERAL, SECTION_ABSOLUTE } type;
+
+ char *name; /* strdup()'ed name (given by user) */
+
+ union {
+ /* SECTION_GENERAL data */
+ /* SECTION_ABSOLUTE data */
+ unsigned long start;
+ } data;
+
+ bytecodehead bc; /* the bytecodes for the section's contents */
+};
+
section *
sections_initialize(sectionhead *headp, objfmt *of)
{
return s;
}
+
+bytecodehead *
+section_get_bytecodes(section *sect)
+{
+ return §->bc;
+}
struct objfmt_s;
-typedef STAILQ_HEAD(sectionhead_s, section_s) sectionhead;
+typedef STAILQ_HEAD(sectionhead, section) sectionhead;
-typedef struct section_s {
- STAILQ_ENTRY(section_s) link;
-
- enum { SECTION_GENERAL, SECTION_ABSOLUTE } type;
-
- char *name; /* strdup()'ed name (given by user) */
-
- union {
- /* SECTION_GENERAL data */
- /* SECTION_ABSOLUTE data */
- unsigned long start;
- } data;
-
- bytecodehead bc; /* the bytecodes for the section's contents */
-} section;
+#ifndef YASM_SECTION
+#define YASM_SECTION
+typedef struct section section;
+#endif
section *sections_initialize(sectionhead *headp, struct objfmt_s *of);
section *sections_switch(sectionhead *headp, struct objfmt_s *of,
const char *name);
+bytecodehead *section_get_bytecodes(section *sect);
#endif
RCSID("$IdPath$");
+struct symrec {
+ char *name;
+ SymType type;
+ SymStatus status;
+ SymVisibility visibility;
+ char *filename; /* file and line */
+ unsigned long line; /* symbol was first declared or used on */
+ union {
+ unsigned long int_val; /* integer constant */
+ floatnum *flt; /* floating point constant */
+ struct label_s { /* bytecode immediately preceding a label */
+ section *sect;
+ bytecode *bc;
+ } label;
+ } value;
+};
+
/* private functions */
static symrec *symrec_get_or_new(const char *);
static symrec *symrec_define(const char *, SymType type);
/* We can't get the value right now. */
return 0;
}
+
+const char *
+symrec_get_name(const symrec *sym)
+{
+ return sym->name;
+}
#ifndef YASM_SYMREC_H
#define YASM_SYMREC_H
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
+
+#ifndef YASM_SECTION
+#define YASM_SECTION
+typedef struct section section;
+#endif
+
+#ifndef YASM_BYTECODE
+#define YASM_BYTECODE
+typedef struct bytecode bytecode;
+#endif
+
/* DEFINED is set with EXTERN and COMMON below */
typedef enum {
SYM_NOSTATUS = 0,
SYM_LABEL /* for labels */
} SymType;
-typedef struct symrec_s {
- char *name;
- SymType type;
- SymStatus status;
- SymVisibility visibility;
- char *filename; /* file and line */
- unsigned long line; /* symbol was first declared or used on */
- union {
- unsigned long int_val; /* integer constant */
- struct floatnum_s *flt; /* floating point constant */
- struct label_s { /* bytecode immediately preceding a label */
- struct section_s *sect;
- struct bytecode_s *bc;
- } label;
- } value;
-} symrec;
+#ifndef YASM_SYMREC
+#define YASM_SYMREC
+typedef struct symrec symrec;
+#endif
symrec *symrec_use(const char *name);
symrec *symrec_define_constant_int(const char *name, unsigned long int_val);
-symrec *symrec_define_constant_float(const char *name, struct floatnum_s *flt);
-symrec *symrec_define_label(const char *name, struct section_s *sect,
- struct bytecode_s *precbc);
+symrec *symrec_define_constant_float(const char *name, floatnum *flt);
+symrec *symrec_define_label(const char *name, section *sect, bytecode *precbc);
symrec *symrec_declare(const char *name, SymVisibility vis);
/* Get the numeric 32-bit value of a symbol if possible.
int symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
int resolve_label);
+const char *symrec_get_name(const symrec *sym);
+
void symrec_foreach(int (*func) (const char *name, symrec *rec));
#endif
floatnum_test_SOURCES = \
floatnum_test.c
-INCLUDES= -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/check
+INCLUDES= -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/check \
+ -I$(top_builddir)/intl
LDADD = \
$(top_builddir)/check/libcheck.a \
$(top_builddir)/src/parsers/nasm/libparser.a \
#include "check.h"
-#include "util.h"
-
-#include "bytecode.h"
+#include "bytecode.c"
START_TEST(test_effaddr_new_reg)
{
#include "check.h"
-#include "bitvect.h"
-
-#include "floatnum.h"
+#include "floatnum.c"
/* constants describing parameters of internal floating point format.
* (these should match those in src/floatnum.c !)
# include <string.h>
#endif
+#include <libintl.h>
+#define _(String) gettext(String)
+#ifdef gettext_noop
+#define N_(String) gettext_noop(String)
+#else
+#define N_(String) (String)
+#endif
+
#include "globals.h"
#include "errwarn.h"
#include "floatnum.h"
RCSID("$IdPath$");
+typedef enum {
+ EXPR_NONE, /* for left side of a NOT, NEG, etc. */
+ EXPR_SYM,
+ EXPR_EXPR,
+ EXPR_INT,
+ EXPR_FLOAT
+} ExprType;
+
+struct ExprItem {
+ ExprType type;
+ union {
+ symrec *sym;
+ expr *expn;
+ unsigned long int_val;
+ floatnum *flt;
+ } data;
+};
+
+struct expr {
+ ExprItem left, right;
+ ExprOp op;
+};
+
/* allocate a new expression node, with children as defined.
* If it's a unary operator, put the element on the right */
expr *
-expr_new(ExprType ltype,
- ExprItem left,
- ExprOp op,
- ExprType rtype,
- ExprItem right)
+expr_new(ExprItem *left, ExprOp op, ExprItem *right)
{
expr *ptr;
ptr = xmalloc(sizeof(expr));
- ptr->ltype = ltype;
+ ptr->left.type = EXPR_NONE;
ptr->op = op;
- ptr->rtype = rtype;
- switch (ltype) {
- case EXPR_SYM:
- case EXPR_EXPR:
- case EXPR_INT:
- case EXPR_FLOAT:
- memcpy(&ptr->left, &left, sizeof(ExprItem));
- break;
- case EXPR_NONE:
- break;
+ ptr->right.type = EXPR_NONE;
+ if (left) {
+ memcpy(&ptr->left, left, sizeof(ExprItem));
+ free(left);
}
- switch (rtype) {
- case EXPR_SYM:
- case EXPR_EXPR:
- case EXPR_INT:
- case EXPR_FLOAT:
- memcpy(&ptr->right, &right, sizeof(ExprItem));
- break;
- case EXPR_NONE:
- Fatal(FATAL_UNKNOWN); /* TODO: better error? */
- break;
+ if (right) {
+ memcpy(&ptr->right, right, sizeof(ExprItem));
+ free(right);
+ } else {
+ InternalError(__LINE__, __FILE__,
+ _("Right side of expression must exist"));
}
return ptr;
}
/* helpers */
-ExprItem
-ExprSym(struct symrec_s *s)
+ExprItem *
+ExprSym(symrec *s)
{
- ExprItem e;
-
- e.sym = s;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_SYM;
+ e->data.sym = s;
return e;
}
-ExprItem
+ExprItem *
ExprExpr(expr *x)
{
- ExprItem e;
- e.exp = x;
-
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_EXPR;
+ e->data.expn = x;
return e;
}
-ExprItem
+ExprItem *
ExprInt(unsigned long i)
{
- ExprItem e;
-
- e.int_val = i;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_INT;
+ e->data.int_val = i;
return e;
}
-ExprItem
+ExprItem *
ExprFloat(floatnum *f)
{
- ExprItem e;
-
- e.flt = f;
- return e;
-}
-
-ExprItem
-ExprNone(void)
-{
- ExprItem e;
-
- e.int_val = 0;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_FLOAT;
+ e->data.flt = f;
return e;
}
unsigned long int_val;
/* try to simplify the left side */
- if (e->ltype == EXPR_EXPR) {
+ if (e->left.type == EXPR_EXPR) {
/* if the left subexpr isn't an IDENT, recurse simplification */
- if (e->left.exp->op != EXPR_IDENT)
- simplified |= expr_simplify(e->left.exp);
+ if (e->left.data.expn->op != EXPR_IDENT)
+ simplified |= expr_simplify(e->left.data.expn);
/* if the left subexpr is just an IDENT (or string thereof),
* pull it up into the current node */
- while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
+ while (e->left.type == EXPR_EXPR && e->left.data.expn->op == EXPR_IDENT) {
ExprItem tmp;
- e->ltype = e->left.exp->rtype;
- memcpy(&tmp, &(e->left.exp->right), sizeof(ExprItem));
- free(e->left.exp);
- memcpy(&(e->left.int_val), &tmp, sizeof(ExprItem));
+ e->left.type = e->left.data.expn->right.type;
+ memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
+ free(e->left.data.expn);
+ memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
simplified = 1;
}
- } else if (e->ltype == EXPR_SYM) {
+ } else if (e->left.type == EXPR_SYM) {
/* try to get value of symbol */
- if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
- e->ltype = EXPR_INT;
+ if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
+ e->left.type = EXPR_INT;
/* don't try to free the symrec here. */
- e->left.int_val = int_val;
+ e->left.data.int_val = int_val;
simplified = 1;
}
}
/* ditto on the right */
- if (e->rtype == EXPR_EXPR) {
- if (e->right.exp->op != EXPR_IDENT)
- simplified |= expr_simplify(e->right.exp);
+ if (e->right.type == EXPR_EXPR) {
+ if (e->right.data.expn->op != EXPR_IDENT)
+ simplified |= expr_simplify(e->right.data.expn);
- while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
+ while (e->right.type == EXPR_EXPR && e->right.data.expn->op == EXPR_IDENT) {
ExprItem tmp;
- e->rtype = e->right.exp->rtype;
- memcpy(&tmp, &(e->right.exp->right), sizeof(ExprItem));
- free(e->right.exp);
- memcpy(&(e->right.int_val), &tmp, sizeof(ExprItem));
+ e->right.type = e->right.data.expn->right.type;
+ memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
+ free(e->right.data.expn);
+ memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
simplified = 1;
}
- } else if (e->rtype == EXPR_SYM) {
- if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
- e->rtype = EXPR_INT;
+ } else if (e->right.type == EXPR_SYM) {
+ if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
+ e->right.type = EXPR_INT;
/* don't try to free the symrec here. */
- e->right.int_val = int_val;
+ e->right.data.int_val = int_val;
simplified = 1;
}
}
- if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
- && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
+ if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE)
+ && e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
switch (e->op) {
case EXPR_ADD:
- e->right.int_val = e->left.int_val + e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val + e->right.data.int_val;
break;
case EXPR_SUB:
- e->right.int_val = e->left.int_val - e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val - e->right.data.int_val;
break;
case EXPR_MUL:
- e->right.int_val = e->left.int_val * e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val * e->right.data.int_val;
break;
case EXPR_DIV:
- e->right.int_val = e->left.int_val / e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val / e->right.data.int_val;
break;
case EXPR_MOD:
- e->right.int_val = e->left.int_val % e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val % e->right.data.int_val;
break;
case EXPR_NEG:
- e->right.int_val = -(e->right.int_val);
+ e->right.data.int_val = -(e->right.data.int_val);
break;
case EXPR_NOT:
- e->right.int_val = ~(e->right.int_val);
+ e->right.data.int_val = ~(e->right.data.int_val);
break;
case EXPR_OR:
- e->right.int_val = e->left.int_val | e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val | e->right.data.int_val;
break;
case EXPR_AND:
- e->right.int_val = e->left.int_val & e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val & e->right.data.int_val;
break;
case EXPR_XOR:
- e->right.int_val = e->left.int_val ^ e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val ^ e->right.data.int_val;
break;
case EXPR_SHL:
- e->right.int_val = e->right.int_val << e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
break;
case EXPR_SHR:
- e->right.int_val = e->right.int_val << e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
break;
case EXPR_LOR:
- e->right.int_val = e->left.int_val || e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val || e->right.data.int_val;
break;
case EXPR_LAND:
- e->right.int_val = e->left.int_val && e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val && e->right.data.int_val;
break;
case EXPR_LNOT:
- e->right.int_val = !e->right.int_val;
+ e->right.data.int_val = !e->right.data.int_val;
break;
case EXPR_EQ:
- e->right.int_val = e->right.int_val == e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val == e->left.data.int_val;
break;
case EXPR_LT:
- e->right.int_val = e->right.int_val < e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val < e->left.data.int_val;
break;
case EXPR_GT:
- e->right.int_val = e->right.int_val > e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val > e->left.data.int_val;
break;
case EXPR_LE:
- e->right.int_val = e->right.int_val <= e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val <= e->left.data.int_val;
break;
case EXPR_GE:
- e->right.int_val = e->right.int_val >= e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val >= e->left.data.int_val;
break;
case EXPR_NE:
- e->right.int_val = e->right.int_val != e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val != e->left.data.int_val;
break;
case EXPR_IDENT:
break;
}
/* catch simple identities like 0+x, 1*x, etc., for x not a num */
- else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
- || (e->left.int_val == 0 &&
+ else if (e->left.type == EXPR_INT && ((e->left.data.int_val == 1 && e->op == EXPR_MUL)
+ || (e->left.data.int_val == 0 &&
e->op == EXPR_ADD)
- || (e->left.int_val == -1 &&
+ || (e->left.data.int_val == -1 &&
e->op == EXPR_AND)
- || (e->left.int_val == 0 &&
+ || (e->left.data.int_val == 0 &&
e->op == EXPR_OR))) {
e->op = EXPR_IDENT;
simplified = 1;
}
/* and the corresponding x+|-0, x*&/1 */
- else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
- || (e->right.int_val == 1 &&
+ else if (e->right.type == EXPR_INT && ((e->right.data.int_val == 1 && e->op == EXPR_MUL)
+ || (e->right.data.int_val == 1 &&
e->op == EXPR_DIV)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_ADD)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SUB)
- || (e->right.int_val == -1 &&
+ || (e->right.data.int_val == -1 &&
e->op == EXPR_AND)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_OR)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SHL)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SHR))) {
e->op = EXPR_IDENT;
- e->rtype = e->ltype;
+ e->right.type = e->left.type;
memcpy(&e->right, &e->left, sizeof(ExprItem));
simplified = 1;
}
int
expr_get_value(expr *e, unsigned long *retval)
{
- while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
+ while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
&& expr_simplify(e)) ;
- if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
- *retval = e->right.int_val;
+ if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
+ *retval = e->right.data.int_val;
return 1;
} else
return 0;
expr_print(expr *e)
{
if (e->op != EXPR_IDENT) {
- switch (e->ltype) {
+ switch (e->left.type) {
case EXPR_SYM:
- printf("%s", e->left.sym->name);
+ printf("%s", symrec_get_name(e->left.data.sym));
break;
case EXPR_EXPR:
printf("(");
- expr_print(e->left.exp);
+ expr_print(e->left.data.expn);
printf(")");
break;
case EXPR_INT:
- printf("%lu", e->left.int_val);
+ printf("%lu", e->left.data.int_val);
break;
case EXPR_FLOAT:
- floatnum_print(e->left.flt);
+ floatnum_print(e->left.data.flt);
break;
case EXPR_NONE:
break;
case EXPR_IDENT:
break;
}
- switch (e->rtype) {
+ switch (e->right.type) {
case EXPR_SYM:
- printf("%s", e->right.sym->name);
+ printf("%s", symrec_get_name(e->right.data.sym));
break;
case EXPR_EXPR:
printf("(");
- expr_print(e->right.exp);
+ expr_print(e->right.data.expn);
printf(")");
break;
case EXPR_INT:
- printf("%lu", e->right.int_val);
+ printf("%lu", e->right.data.int_val);
break;
case EXPR_FLOAT:
- floatnum_print(e->right.flt);
+ floatnum_print(e->right.data.flt);
break;
case EXPR_NONE:
break;
# include <string.h>
#endif
+#include <libintl.h>
+#define _(String) gettext(String)
+#ifdef gettext_noop
+#define N_(String) gettext_noop(String)
+#else
+#define N_(String) (String)
+#endif
+
#include "globals.h"
#include "errwarn.h"
#include "floatnum.h"
RCSID("$IdPath$");
+typedef enum {
+ EXPR_NONE, /* for left side of a NOT, NEG, etc. */
+ EXPR_SYM,
+ EXPR_EXPR,
+ EXPR_INT,
+ EXPR_FLOAT
+} ExprType;
+
+struct ExprItem {
+ ExprType type;
+ union {
+ symrec *sym;
+ expr *expn;
+ unsigned long int_val;
+ floatnum *flt;
+ } data;
+};
+
+struct expr {
+ ExprItem left, right;
+ ExprOp op;
+};
+
/* allocate a new expression node, with children as defined.
* If it's a unary operator, put the element on the right */
expr *
-expr_new(ExprType ltype,
- ExprItem left,
- ExprOp op,
- ExprType rtype,
- ExprItem right)
+expr_new(ExprItem *left, ExprOp op, ExprItem *right)
{
expr *ptr;
ptr = xmalloc(sizeof(expr));
- ptr->ltype = ltype;
+ ptr->left.type = EXPR_NONE;
ptr->op = op;
- ptr->rtype = rtype;
- switch (ltype) {
- case EXPR_SYM:
- case EXPR_EXPR:
- case EXPR_INT:
- case EXPR_FLOAT:
- memcpy(&ptr->left, &left, sizeof(ExprItem));
- break;
- case EXPR_NONE:
- break;
+ ptr->right.type = EXPR_NONE;
+ if (left) {
+ memcpy(&ptr->left, left, sizeof(ExprItem));
+ free(left);
}
- switch (rtype) {
- case EXPR_SYM:
- case EXPR_EXPR:
- case EXPR_INT:
- case EXPR_FLOAT:
- memcpy(&ptr->right, &right, sizeof(ExprItem));
- break;
- case EXPR_NONE:
- Fatal(FATAL_UNKNOWN); /* TODO: better error? */
- break;
+ if (right) {
+ memcpy(&ptr->right, right, sizeof(ExprItem));
+ free(right);
+ } else {
+ InternalError(__LINE__, __FILE__,
+ _("Right side of expression must exist"));
}
return ptr;
}
/* helpers */
-ExprItem
-ExprSym(struct symrec_s *s)
+ExprItem *
+ExprSym(symrec *s)
{
- ExprItem e;
-
- e.sym = s;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_SYM;
+ e->data.sym = s;
return e;
}
-ExprItem
+ExprItem *
ExprExpr(expr *x)
{
- ExprItem e;
- e.exp = x;
-
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_EXPR;
+ e->data.expn = x;
return e;
}
-ExprItem
+ExprItem *
ExprInt(unsigned long i)
{
- ExprItem e;
-
- e.int_val = i;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_INT;
+ e->data.int_val = i;
return e;
}
-ExprItem
+ExprItem *
ExprFloat(floatnum *f)
{
- ExprItem e;
-
- e.flt = f;
- return e;
-}
-
-ExprItem
-ExprNone(void)
-{
- ExprItem e;
-
- e.int_val = 0;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_FLOAT;
+ e->data.flt = f;
return e;
}
unsigned long int_val;
/* try to simplify the left side */
- if (e->ltype == EXPR_EXPR) {
+ if (e->left.type == EXPR_EXPR) {
/* if the left subexpr isn't an IDENT, recurse simplification */
- if (e->left.exp->op != EXPR_IDENT)
- simplified |= expr_simplify(e->left.exp);
+ if (e->left.data.expn->op != EXPR_IDENT)
+ simplified |= expr_simplify(e->left.data.expn);
/* if the left subexpr is just an IDENT (or string thereof),
* pull it up into the current node */
- while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
+ while (e->left.type == EXPR_EXPR && e->left.data.expn->op == EXPR_IDENT) {
ExprItem tmp;
- e->ltype = e->left.exp->rtype;
- memcpy(&tmp, &(e->left.exp->right), sizeof(ExprItem));
- free(e->left.exp);
- memcpy(&(e->left.int_val), &tmp, sizeof(ExprItem));
+ e->left.type = e->left.data.expn->right.type;
+ memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
+ free(e->left.data.expn);
+ memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
simplified = 1;
}
- } else if (e->ltype == EXPR_SYM) {
+ } else if (e->left.type == EXPR_SYM) {
/* try to get value of symbol */
- if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
- e->ltype = EXPR_INT;
+ if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
+ e->left.type = EXPR_INT;
/* don't try to free the symrec here. */
- e->left.int_val = int_val;
+ e->left.data.int_val = int_val;
simplified = 1;
}
}
/* ditto on the right */
- if (e->rtype == EXPR_EXPR) {
- if (e->right.exp->op != EXPR_IDENT)
- simplified |= expr_simplify(e->right.exp);
+ if (e->right.type == EXPR_EXPR) {
+ if (e->right.data.expn->op != EXPR_IDENT)
+ simplified |= expr_simplify(e->right.data.expn);
- while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
+ while (e->right.type == EXPR_EXPR && e->right.data.expn->op == EXPR_IDENT) {
ExprItem tmp;
- e->rtype = e->right.exp->rtype;
- memcpy(&tmp, &(e->right.exp->right), sizeof(ExprItem));
- free(e->right.exp);
- memcpy(&(e->right.int_val), &tmp, sizeof(ExprItem));
+ e->right.type = e->right.data.expn->right.type;
+ memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
+ free(e->right.data.expn);
+ memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
simplified = 1;
}
- } else if (e->rtype == EXPR_SYM) {
- if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
- e->rtype = EXPR_INT;
+ } else if (e->right.type == EXPR_SYM) {
+ if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
+ e->right.type = EXPR_INT;
/* don't try to free the symrec here. */
- e->right.int_val = int_val;
+ e->right.data.int_val = int_val;
simplified = 1;
}
}
- if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
- && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
+ if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE)
+ && e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
switch (e->op) {
case EXPR_ADD:
- e->right.int_val = e->left.int_val + e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val + e->right.data.int_val;
break;
case EXPR_SUB:
- e->right.int_val = e->left.int_val - e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val - e->right.data.int_val;
break;
case EXPR_MUL:
- e->right.int_val = e->left.int_val * e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val * e->right.data.int_val;
break;
case EXPR_DIV:
- e->right.int_val = e->left.int_val / e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val / e->right.data.int_val;
break;
case EXPR_MOD:
- e->right.int_val = e->left.int_val % e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val % e->right.data.int_val;
break;
case EXPR_NEG:
- e->right.int_val = -(e->right.int_val);
+ e->right.data.int_val = -(e->right.data.int_val);
break;
case EXPR_NOT:
- e->right.int_val = ~(e->right.int_val);
+ e->right.data.int_val = ~(e->right.data.int_val);
break;
case EXPR_OR:
- e->right.int_val = e->left.int_val | e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val | e->right.data.int_val;
break;
case EXPR_AND:
- e->right.int_val = e->left.int_val & e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val & e->right.data.int_val;
break;
case EXPR_XOR:
- e->right.int_val = e->left.int_val ^ e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val ^ e->right.data.int_val;
break;
case EXPR_SHL:
- e->right.int_val = e->right.int_val << e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
break;
case EXPR_SHR:
- e->right.int_val = e->right.int_val << e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
break;
case EXPR_LOR:
- e->right.int_val = e->left.int_val || e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val || e->right.data.int_val;
break;
case EXPR_LAND:
- e->right.int_val = e->left.int_val && e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val && e->right.data.int_val;
break;
case EXPR_LNOT:
- e->right.int_val = !e->right.int_val;
+ e->right.data.int_val = !e->right.data.int_val;
break;
case EXPR_EQ:
- e->right.int_val = e->right.int_val == e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val == e->left.data.int_val;
break;
case EXPR_LT:
- e->right.int_val = e->right.int_val < e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val < e->left.data.int_val;
break;
case EXPR_GT:
- e->right.int_val = e->right.int_val > e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val > e->left.data.int_val;
break;
case EXPR_LE:
- e->right.int_val = e->right.int_val <= e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val <= e->left.data.int_val;
break;
case EXPR_GE:
- e->right.int_val = e->right.int_val >= e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val >= e->left.data.int_val;
break;
case EXPR_NE:
- e->right.int_val = e->right.int_val != e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val != e->left.data.int_val;
break;
case EXPR_IDENT:
break;
}
/* catch simple identities like 0+x, 1*x, etc., for x not a num */
- else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
- || (e->left.int_val == 0 &&
+ else if (e->left.type == EXPR_INT && ((e->left.data.int_val == 1 && e->op == EXPR_MUL)
+ || (e->left.data.int_val == 0 &&
e->op == EXPR_ADD)
- || (e->left.int_val == -1 &&
+ || (e->left.data.int_val == -1 &&
e->op == EXPR_AND)
- || (e->left.int_val == 0 &&
+ || (e->left.data.int_val == 0 &&
e->op == EXPR_OR))) {
e->op = EXPR_IDENT;
simplified = 1;
}
/* and the corresponding x+|-0, x*&/1 */
- else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
- || (e->right.int_val == 1 &&
+ else if (e->right.type == EXPR_INT && ((e->right.data.int_val == 1 && e->op == EXPR_MUL)
+ || (e->right.data.int_val == 1 &&
e->op == EXPR_DIV)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_ADD)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SUB)
- || (e->right.int_val == -1 &&
+ || (e->right.data.int_val == -1 &&
e->op == EXPR_AND)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_OR)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SHL)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SHR))) {
e->op = EXPR_IDENT;
- e->rtype = e->ltype;
+ e->right.type = e->left.type;
memcpy(&e->right, &e->left, sizeof(ExprItem));
simplified = 1;
}
int
expr_get_value(expr *e, unsigned long *retval)
{
- while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
+ while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
&& expr_simplify(e)) ;
- if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
- *retval = e->right.int_val;
+ if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
+ *retval = e->right.data.int_val;
return 1;
} else
return 0;
expr_print(expr *e)
{
if (e->op != EXPR_IDENT) {
- switch (e->ltype) {
+ switch (e->left.type) {
case EXPR_SYM:
- printf("%s", e->left.sym->name);
+ printf("%s", symrec_get_name(e->left.data.sym));
break;
case EXPR_EXPR:
printf("(");
- expr_print(e->left.exp);
+ expr_print(e->left.data.expn);
printf(")");
break;
case EXPR_INT:
- printf("%lu", e->left.int_val);
+ printf("%lu", e->left.data.int_val);
break;
case EXPR_FLOAT:
- floatnum_print(e->left.flt);
+ floatnum_print(e->left.data.flt);
break;
case EXPR_NONE:
break;
case EXPR_IDENT:
break;
}
- switch (e->rtype) {
+ switch (e->right.type) {
case EXPR_SYM:
- printf("%s", e->right.sym->name);
+ printf("%s", symrec_get_name(e->right.data.sym));
break;
case EXPR_EXPR:
printf("(");
- expr_print(e->right.exp);
+ expr_print(e->right.data.expn);
printf(")");
break;
case EXPR_INT:
- printf("%lu", e->right.int_val);
+ printf("%lu", e->right.data.int_val);
break;
case EXPR_FLOAT:
- floatnum_print(e->right.flt);
+ floatnum_print(e->right.data.flt);
break;
case EXPR_NONE:
break;
unsigned char groupdata[4];
effaddr *ea;
expr *exp;
- immval im_val;
+ immval *im_val;
targetval tgt_val;
datavalhead datahead;
dataval *data;
%%
input: /* empty */
| input line {
- nasm_parser_temp_bc = bytecodes_append(&nasm_parser_cur_section->bc,
+ nasm_parser_temp_bc = bytecodes_append(section_get_bytecodes(nasm_parser_cur_section),
$2);
if (nasm_parser_temp_bc)
nasm_parser_prev_bc = nasm_parser_temp_bc;
;
datavals: dataval {
- STAILQ_INIT(&$$);
- if ($1)
- STAILQ_INSERT_TAIL(&$$, $1, link);
+ datavals_initialize(&$$);
+ datavals_append(&$$, $1);
}
| datavals ',' dataval {
- if ($3)
- STAILQ_INSERT_TAIL(&$1, $3, link);
+ datavals_append(&$1, $3);
$$ = $1;
}
;
memexp: expr { expr_simplify ($1); $$ = effaddr_new_expr($1); }
;
-memaddr: memexp { $$ = $1; $$->segment = 0; }
+memaddr: memexp { $$ = $1; SetEASegment($$, 0); }
| REG_CS ':' memaddr { $$ = $3; SetEASegment($$, 0x2E); }
| REG_SS ':' memaddr { $$ = $3; SetEASegment($$, 0x36); }
| REG_DS ':' memaddr { $$ = $3; SetEASegment($$, 0x3E); }
;
/* immediate values */
-imm: expr { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
+imm: expr { expr_simplify($1); $$ = immval_new_expr($1); }
;
/* explicit immediates */
;
/* jump targets */
-target: expr { $$.val = $1; $$.op_sel = JR_NONE; }
+target: expr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); }
| SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); }
| NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); }
;
/* expression trees */
-expr_no_string: INTNUM { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
- | explabel {
- $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1)));
- }
+expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); }
+ | explabel { $$ = expr_new_ident(ExprSym(symrec_use($1))); }
/*| expr '||' expr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
| expr '|' expr { $$ = expr_new_tree($1, EXPR_OR, $3); }
| expr '^' expr { $$ = expr_new_tree($1, EXPR_XOR, $3); }
expr: expr_no_string
| STRING {
- $$ = expr_new_ident (EXPR_INT, ExprInt(ConvertCharConstToInt($1)));
+ $$ = expr_new_ident(ExprInt(ConvertCharConstToInt($1)));
}
;
instr: instrbase
| OPERSIZE instr { $$ = $2; SetInsnOperSizeOverride($$, $1); }
| ADDRSIZE instr { $$ = $2; SetInsnAddrSizeOverride($$, $1); }
- | REG_CS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x2E); }
- | REG_SS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x36); }
- | REG_DS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x3E); }
- | REG_ES instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x26); }
- | REG_FS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x64); }
- | REG_GS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x65); }
+ | REG_CS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x2E); }
+ | REG_SS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x36); }
+ | REG_DS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x3E); }
+ | REG_ES instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x26); }
+ | REG_FS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x64); }
+ | REG_GS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x65); }
| LOCK instr { $$ = $2; SetInsnLockRepPrefix($$, 0xF0); }
| REPNZ instr { $$ = $2; SetInsnLockRepPrefix($$, 0xF2); }
| REP instr { $$ = $2; SetInsnLockRepPrefix($$, 0xF3); }
#$args[-1] =~ s/(\$\d+[ri]?)(?!\.)/\&$1/; # Just the first!
$args[-1] =~ s/(\$\d+)r/effaddr_new_reg($1)/;
$args[-1] =~ s[(\$\d+)i,\s*(\d+)]
- ["effaddr_new_imm(\&$1, ".($2/8)."), 0"]e;
+ ["effaddr_new_imm($1, ".($2/8)."), 0"]e;
$args[-1] .= ',';
die $args[-1] if $args[-1] =~ m/\d+[ri]/;
$args[-1] =~ s/nil/(immval *)NULL, 0/;
# don't match $0.\d in the following rules.
$args[-1] =~ s/\$(\d+)(?!\.)/"\$".($1*2+$to).($2||'')/eg;
- $args[-1] =~ s/(\$\d+)(?!\.)/\&$1/; # Just the first!
$args[-1] =~ s[^([0-9A-Fa-f]+),]
- [ConvertIntToImm((immval *)NULL, 0x$1),];
+ [immval_new_int(0x$1),];
$args[-1] =~ s[^\$0.(\d+),]
- [ConvertIntToImm((immval *)NULL, \$1\[$1\]),];
+ [immval_new_int(\$1\[$1\]),];
# divide the second, and only the second, by 8 bits/byte
$args[-1] =~ s#(,\s*)(\d+)(s)?#$1 . ($2/8)#eg;
unsigned char groupdata[4];
effaddr *ea;
expr *exp;
- immval im_val;
+ immval *im_val;
targetval tgt_val;
datavalhead datahead;
dataval *data;
%%
input: /* empty */
| input line {
- nasm_parser_temp_bc = bytecodes_append(&nasm_parser_cur_section->bc,
+ nasm_parser_temp_bc = bytecodes_append(section_get_bytecodes(nasm_parser_cur_section),
$2);
if (nasm_parser_temp_bc)
nasm_parser_prev_bc = nasm_parser_temp_bc;
;
datavals: dataval {
- STAILQ_INIT(&$$);
- if ($1)
- STAILQ_INSERT_TAIL(&$$, $1, link);
+ datavals_initialize(&$$);
+ datavals_append(&$$, $1);
}
| datavals ',' dataval {
- if ($3)
- STAILQ_INSERT_TAIL(&$1, $3, link);
+ datavals_append(&$1, $3);
$$ = $1;
}
;
memexp: expr { expr_simplify ($1); $$ = effaddr_new_expr($1); }
;
-memaddr: memexp { $$ = $1; $$->segment = 0; }
+memaddr: memexp { $$ = $1; SetEASegment($$, 0); }
| REG_CS ':' memaddr { $$ = $3; SetEASegment($$, 0x2E); }
| REG_SS ':' memaddr { $$ = $3; SetEASegment($$, 0x36); }
| REG_DS ':' memaddr { $$ = $3; SetEASegment($$, 0x3E); }
;
/* immediate values */
-imm: expr { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
+imm: expr { expr_simplify($1); $$ = immval_new_expr($1); }
;
/* explicit immediates */
;
/* jump targets */
-target: expr { $$.val = $1; $$.op_sel = JR_NONE; }
+target: expr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); }
| SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); }
| NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); }
;
/* expression trees */
-expr_no_string: INTNUM { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
- | explabel {
- $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1)));
- }
+expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); }
+ | explabel { $$ = expr_new_ident(ExprSym(symrec_use($1))); }
/*| expr '||' expr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
| expr '|' expr { $$ = expr_new_tree($1, EXPR_OR, $3); }
| expr '^' expr { $$ = expr_new_tree($1, EXPR_XOR, $3); }
expr: expr_no_string
| STRING {
- $$ = expr_new_ident (EXPR_INT, ExprInt(ConvertCharConstToInt($1)));
+ $$ = expr_new_ident(ExprInt(ConvertCharConstToInt($1)));
}
;
instr: instrbase
| OPERSIZE instr { $$ = $2; SetInsnOperSizeOverride($$, $1); }
| ADDRSIZE instr { $$ = $2; SetInsnAddrSizeOverride($$, $1); }
- | REG_CS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x2E); }
- | REG_SS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x36); }
- | REG_DS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x3E); }
- | REG_ES instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x26); }
- | REG_FS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x64); }
- | REG_GS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x65); }
+ | REG_CS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x2E); }
+ | REG_SS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x36); }
+ | REG_DS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x3E); }
+ | REG_ES instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x26); }
+ | REG_FS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x64); }
+ | REG_GS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x65); }
| LOCK instr { $$ = $2; SetInsnLockRepPrefix($$, 0xF0); }
| REPNZ instr { $$ = $2; SetInsnLockRepPrefix($$, 0xF2); }
| REP instr { $$ = $2; SetInsnLockRepPrefix($$, 0xF3); }
# include <string.h>
#endif
+#include <libintl.h>
+#define _(String) gettext(String)
+#ifdef gettext_noop
+#define N_(String) gettext_noop(String)
+#else
+#define N_(String) (String)
+#endif
+
#include "globals.h"
#include "errwarn.h"
#include "floatnum.h"
RCSID("$IdPath$");
+typedef enum {
+ EXPR_NONE, /* for left side of a NOT, NEG, etc. */
+ EXPR_SYM,
+ EXPR_EXPR,
+ EXPR_INT,
+ EXPR_FLOAT
+} ExprType;
+
+struct ExprItem {
+ ExprType type;
+ union {
+ symrec *sym;
+ expr *expn;
+ unsigned long int_val;
+ floatnum *flt;
+ } data;
+};
+
+struct expr {
+ ExprItem left, right;
+ ExprOp op;
+};
+
/* allocate a new expression node, with children as defined.
* If it's a unary operator, put the element on the right */
expr *
-expr_new(ExprType ltype,
- ExprItem left,
- ExprOp op,
- ExprType rtype,
- ExprItem right)
+expr_new(ExprItem *left, ExprOp op, ExprItem *right)
{
expr *ptr;
ptr = xmalloc(sizeof(expr));
- ptr->ltype = ltype;
+ ptr->left.type = EXPR_NONE;
ptr->op = op;
- ptr->rtype = rtype;
- switch (ltype) {
- case EXPR_SYM:
- case EXPR_EXPR:
- case EXPR_INT:
- case EXPR_FLOAT:
- memcpy(&ptr->left, &left, sizeof(ExprItem));
- break;
- case EXPR_NONE:
- break;
+ ptr->right.type = EXPR_NONE;
+ if (left) {
+ memcpy(&ptr->left, left, sizeof(ExprItem));
+ free(left);
}
- switch (rtype) {
- case EXPR_SYM:
- case EXPR_EXPR:
- case EXPR_INT:
- case EXPR_FLOAT:
- memcpy(&ptr->right, &right, sizeof(ExprItem));
- break;
- case EXPR_NONE:
- Fatal(FATAL_UNKNOWN); /* TODO: better error? */
- break;
+ if (right) {
+ memcpy(&ptr->right, right, sizeof(ExprItem));
+ free(right);
+ } else {
+ InternalError(__LINE__, __FILE__,
+ _("Right side of expression must exist"));
}
return ptr;
}
/* helpers */
-ExprItem
-ExprSym(struct symrec_s *s)
+ExprItem *
+ExprSym(symrec *s)
{
- ExprItem e;
-
- e.sym = s;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_SYM;
+ e->data.sym = s;
return e;
}
-ExprItem
+ExprItem *
ExprExpr(expr *x)
{
- ExprItem e;
- e.exp = x;
-
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_EXPR;
+ e->data.expn = x;
return e;
}
-ExprItem
+ExprItem *
ExprInt(unsigned long i)
{
- ExprItem e;
-
- e.int_val = i;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_INT;
+ e->data.int_val = i;
return e;
}
-ExprItem
+ExprItem *
ExprFloat(floatnum *f)
{
- ExprItem e;
-
- e.flt = f;
- return e;
-}
-
-ExprItem
-ExprNone(void)
-{
- ExprItem e;
-
- e.int_val = 0;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_FLOAT;
+ e->data.flt = f;
return e;
}
unsigned long int_val;
/* try to simplify the left side */
- if (e->ltype == EXPR_EXPR) {
+ if (e->left.type == EXPR_EXPR) {
/* if the left subexpr isn't an IDENT, recurse simplification */
- if (e->left.exp->op != EXPR_IDENT)
- simplified |= expr_simplify(e->left.exp);
+ if (e->left.data.expn->op != EXPR_IDENT)
+ simplified |= expr_simplify(e->left.data.expn);
/* if the left subexpr is just an IDENT (or string thereof),
* pull it up into the current node */
- while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
+ while (e->left.type == EXPR_EXPR && e->left.data.expn->op == EXPR_IDENT) {
ExprItem tmp;
- e->ltype = e->left.exp->rtype;
- memcpy(&tmp, &(e->left.exp->right), sizeof(ExprItem));
- free(e->left.exp);
- memcpy(&(e->left.int_val), &tmp, sizeof(ExprItem));
+ e->left.type = e->left.data.expn->right.type;
+ memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
+ free(e->left.data.expn);
+ memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
simplified = 1;
}
- } else if (e->ltype == EXPR_SYM) {
+ } else if (e->left.type == EXPR_SYM) {
/* try to get value of symbol */
- if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
- e->ltype = EXPR_INT;
+ if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
+ e->left.type = EXPR_INT;
/* don't try to free the symrec here. */
- e->left.int_val = int_val;
+ e->left.data.int_val = int_val;
simplified = 1;
}
}
/* ditto on the right */
- if (e->rtype == EXPR_EXPR) {
- if (e->right.exp->op != EXPR_IDENT)
- simplified |= expr_simplify(e->right.exp);
+ if (e->right.type == EXPR_EXPR) {
+ if (e->right.data.expn->op != EXPR_IDENT)
+ simplified |= expr_simplify(e->right.data.expn);
- while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
+ while (e->right.type == EXPR_EXPR && e->right.data.expn->op == EXPR_IDENT) {
ExprItem tmp;
- e->rtype = e->right.exp->rtype;
- memcpy(&tmp, &(e->right.exp->right), sizeof(ExprItem));
- free(e->right.exp);
- memcpy(&(e->right.int_val), &tmp, sizeof(ExprItem));
+ e->right.type = e->right.data.expn->right.type;
+ memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
+ free(e->right.data.expn);
+ memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
simplified = 1;
}
- } else if (e->rtype == EXPR_SYM) {
- if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
- e->rtype = EXPR_INT;
+ } else if (e->right.type == EXPR_SYM) {
+ if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
+ e->right.type = EXPR_INT;
/* don't try to free the symrec here. */
- e->right.int_val = int_val;
+ e->right.data.int_val = int_val;
simplified = 1;
}
}
- if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
- && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
+ if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE)
+ && e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
switch (e->op) {
case EXPR_ADD:
- e->right.int_val = e->left.int_val + e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val + e->right.data.int_val;
break;
case EXPR_SUB:
- e->right.int_val = e->left.int_val - e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val - e->right.data.int_val;
break;
case EXPR_MUL:
- e->right.int_val = e->left.int_val * e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val * e->right.data.int_val;
break;
case EXPR_DIV:
- e->right.int_val = e->left.int_val / e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val / e->right.data.int_val;
break;
case EXPR_MOD:
- e->right.int_val = e->left.int_val % e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val % e->right.data.int_val;
break;
case EXPR_NEG:
- e->right.int_val = -(e->right.int_val);
+ e->right.data.int_val = -(e->right.data.int_val);
break;
case EXPR_NOT:
- e->right.int_val = ~(e->right.int_val);
+ e->right.data.int_val = ~(e->right.data.int_val);
break;
case EXPR_OR:
- e->right.int_val = e->left.int_val | e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val | e->right.data.int_val;
break;
case EXPR_AND:
- e->right.int_val = e->left.int_val & e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val & e->right.data.int_val;
break;
case EXPR_XOR:
- e->right.int_val = e->left.int_val ^ e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val ^ e->right.data.int_val;
break;
case EXPR_SHL:
- e->right.int_val = e->right.int_val << e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
break;
case EXPR_SHR:
- e->right.int_val = e->right.int_val << e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
break;
case EXPR_LOR:
- e->right.int_val = e->left.int_val || e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val || e->right.data.int_val;
break;
case EXPR_LAND:
- e->right.int_val = e->left.int_val && e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val && e->right.data.int_val;
break;
case EXPR_LNOT:
- e->right.int_val = !e->right.int_val;
+ e->right.data.int_val = !e->right.data.int_val;
break;
case EXPR_EQ:
- e->right.int_val = e->right.int_val == e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val == e->left.data.int_val;
break;
case EXPR_LT:
- e->right.int_val = e->right.int_val < e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val < e->left.data.int_val;
break;
case EXPR_GT:
- e->right.int_val = e->right.int_val > e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val > e->left.data.int_val;
break;
case EXPR_LE:
- e->right.int_val = e->right.int_val <= e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val <= e->left.data.int_val;
break;
case EXPR_GE:
- e->right.int_val = e->right.int_val >= e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val >= e->left.data.int_val;
break;
case EXPR_NE:
- e->right.int_val = e->right.int_val != e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val != e->left.data.int_val;
break;
case EXPR_IDENT:
break;
}
/* catch simple identities like 0+x, 1*x, etc., for x not a num */
- else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
- || (e->left.int_val == 0 &&
+ else if (e->left.type == EXPR_INT && ((e->left.data.int_val == 1 && e->op == EXPR_MUL)
+ || (e->left.data.int_val == 0 &&
e->op == EXPR_ADD)
- || (e->left.int_val == -1 &&
+ || (e->left.data.int_val == -1 &&
e->op == EXPR_AND)
- || (e->left.int_val == 0 &&
+ || (e->left.data.int_val == 0 &&
e->op == EXPR_OR))) {
e->op = EXPR_IDENT;
simplified = 1;
}
/* and the corresponding x+|-0, x*&/1 */
- else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
- || (e->right.int_val == 1 &&
+ else if (e->right.type == EXPR_INT && ((e->right.data.int_val == 1 && e->op == EXPR_MUL)
+ || (e->right.data.int_val == 1 &&
e->op == EXPR_DIV)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_ADD)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SUB)
- || (e->right.int_val == -1 &&
+ || (e->right.data.int_val == -1 &&
e->op == EXPR_AND)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_OR)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SHL)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SHR))) {
e->op = EXPR_IDENT;
- e->rtype = e->ltype;
+ e->right.type = e->left.type;
memcpy(&e->right, &e->left, sizeof(ExprItem));
simplified = 1;
}
int
expr_get_value(expr *e, unsigned long *retval)
{
- while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
+ while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
&& expr_simplify(e)) ;
- if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
- *retval = e->right.int_val;
+ if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
+ *retval = e->right.data.int_val;
return 1;
} else
return 0;
expr_print(expr *e)
{
if (e->op != EXPR_IDENT) {
- switch (e->ltype) {
+ switch (e->left.type) {
case EXPR_SYM:
- printf("%s", e->left.sym->name);
+ printf("%s", symrec_get_name(e->left.data.sym));
break;
case EXPR_EXPR:
printf("(");
- expr_print(e->left.exp);
+ expr_print(e->left.data.expn);
printf(")");
break;
case EXPR_INT:
- printf("%lu", e->left.int_val);
+ printf("%lu", e->left.data.int_val);
break;
case EXPR_FLOAT:
- floatnum_print(e->left.flt);
+ floatnum_print(e->left.data.flt);
break;
case EXPR_NONE:
break;
case EXPR_IDENT:
break;
}
- switch (e->rtype) {
+ switch (e->right.type) {
case EXPR_SYM:
- printf("%s", e->right.sym->name);
+ printf("%s", symrec_get_name(e->right.data.sym));
break;
case EXPR_EXPR:
printf("(");
- expr_print(e->right.exp);
+ expr_print(e->right.data.expn);
printf(")");
break;
case EXPR_INT:
- printf("%lu", e->right.int_val);
+ printf("%lu", e->right.data.int_val);
break;
case EXPR_FLOAT:
- floatnum_print(e->right.flt);
+ floatnum_print(e->right.data.flt);
break;
case EXPR_NONE:
break;
# include <string.h>
#endif
+#include <libintl.h>
+#define _(String) gettext(String)
+#ifdef gettext_noop
+#define N_(String) gettext_noop(String)
+#else
+#define N_(String) (String)
+#endif
+
#include "globals.h"
#include "errwarn.h"
#include "floatnum.h"
RCSID("$IdPath$");
+typedef enum {
+ EXPR_NONE, /* for left side of a NOT, NEG, etc. */
+ EXPR_SYM,
+ EXPR_EXPR,
+ EXPR_INT,
+ EXPR_FLOAT
+} ExprType;
+
+struct ExprItem {
+ ExprType type;
+ union {
+ symrec *sym;
+ expr *expn;
+ unsigned long int_val;
+ floatnum *flt;
+ } data;
+};
+
+struct expr {
+ ExprItem left, right;
+ ExprOp op;
+};
+
/* allocate a new expression node, with children as defined.
* If it's a unary operator, put the element on the right */
expr *
-expr_new(ExprType ltype,
- ExprItem left,
- ExprOp op,
- ExprType rtype,
- ExprItem right)
+expr_new(ExprItem *left, ExprOp op, ExprItem *right)
{
expr *ptr;
ptr = xmalloc(sizeof(expr));
- ptr->ltype = ltype;
+ ptr->left.type = EXPR_NONE;
ptr->op = op;
- ptr->rtype = rtype;
- switch (ltype) {
- case EXPR_SYM:
- case EXPR_EXPR:
- case EXPR_INT:
- case EXPR_FLOAT:
- memcpy(&ptr->left, &left, sizeof(ExprItem));
- break;
- case EXPR_NONE:
- break;
+ ptr->right.type = EXPR_NONE;
+ if (left) {
+ memcpy(&ptr->left, left, sizeof(ExprItem));
+ free(left);
}
- switch (rtype) {
- case EXPR_SYM:
- case EXPR_EXPR:
- case EXPR_INT:
- case EXPR_FLOAT:
- memcpy(&ptr->right, &right, sizeof(ExprItem));
- break;
- case EXPR_NONE:
- Fatal(FATAL_UNKNOWN); /* TODO: better error? */
- break;
+ if (right) {
+ memcpy(&ptr->right, right, sizeof(ExprItem));
+ free(right);
+ } else {
+ InternalError(__LINE__, __FILE__,
+ _("Right side of expression must exist"));
}
return ptr;
}
/* helpers */
-ExprItem
-ExprSym(struct symrec_s *s)
+ExprItem *
+ExprSym(symrec *s)
{
- ExprItem e;
-
- e.sym = s;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_SYM;
+ e->data.sym = s;
return e;
}
-ExprItem
+ExprItem *
ExprExpr(expr *x)
{
- ExprItem e;
- e.exp = x;
-
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_EXPR;
+ e->data.expn = x;
return e;
}
-ExprItem
+ExprItem *
ExprInt(unsigned long i)
{
- ExprItem e;
-
- e.int_val = i;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_INT;
+ e->data.int_val = i;
return e;
}
-ExprItem
+ExprItem *
ExprFloat(floatnum *f)
{
- ExprItem e;
-
- e.flt = f;
- return e;
-}
-
-ExprItem
-ExprNone(void)
-{
- ExprItem e;
-
- e.int_val = 0;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_FLOAT;
+ e->data.flt = f;
return e;
}
unsigned long int_val;
/* try to simplify the left side */
- if (e->ltype == EXPR_EXPR) {
+ if (e->left.type == EXPR_EXPR) {
/* if the left subexpr isn't an IDENT, recurse simplification */
- if (e->left.exp->op != EXPR_IDENT)
- simplified |= expr_simplify(e->left.exp);
+ if (e->left.data.expn->op != EXPR_IDENT)
+ simplified |= expr_simplify(e->left.data.expn);
/* if the left subexpr is just an IDENT (or string thereof),
* pull it up into the current node */
- while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
+ while (e->left.type == EXPR_EXPR && e->left.data.expn->op == EXPR_IDENT) {
ExprItem tmp;
- e->ltype = e->left.exp->rtype;
- memcpy(&tmp, &(e->left.exp->right), sizeof(ExprItem));
- free(e->left.exp);
- memcpy(&(e->left.int_val), &tmp, sizeof(ExprItem));
+ e->left.type = e->left.data.expn->right.type;
+ memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
+ free(e->left.data.expn);
+ memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
simplified = 1;
}
- } else if (e->ltype == EXPR_SYM) {
+ } else if (e->left.type == EXPR_SYM) {
/* try to get value of symbol */
- if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
- e->ltype = EXPR_INT;
+ if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
+ e->left.type = EXPR_INT;
/* don't try to free the symrec here. */
- e->left.int_val = int_val;
+ e->left.data.int_val = int_val;
simplified = 1;
}
}
/* ditto on the right */
- if (e->rtype == EXPR_EXPR) {
- if (e->right.exp->op != EXPR_IDENT)
- simplified |= expr_simplify(e->right.exp);
+ if (e->right.type == EXPR_EXPR) {
+ if (e->right.data.expn->op != EXPR_IDENT)
+ simplified |= expr_simplify(e->right.data.expn);
- while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
+ while (e->right.type == EXPR_EXPR && e->right.data.expn->op == EXPR_IDENT) {
ExprItem tmp;
- e->rtype = e->right.exp->rtype;
- memcpy(&tmp, &(e->right.exp->right), sizeof(ExprItem));
- free(e->right.exp);
- memcpy(&(e->right.int_val), &tmp, sizeof(ExprItem));
+ e->right.type = e->right.data.expn->right.type;
+ memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
+ free(e->right.data.expn);
+ memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
simplified = 1;
}
- } else if (e->rtype == EXPR_SYM) {
- if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
- e->rtype = EXPR_INT;
+ } else if (e->right.type == EXPR_SYM) {
+ if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
+ e->right.type = EXPR_INT;
/* don't try to free the symrec here. */
- e->right.int_val = int_val;
+ e->right.data.int_val = int_val;
simplified = 1;
}
}
- if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
- && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
+ if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE)
+ && e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
switch (e->op) {
case EXPR_ADD:
- e->right.int_val = e->left.int_val + e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val + e->right.data.int_val;
break;
case EXPR_SUB:
- e->right.int_val = e->left.int_val - e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val - e->right.data.int_val;
break;
case EXPR_MUL:
- e->right.int_val = e->left.int_val * e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val * e->right.data.int_val;
break;
case EXPR_DIV:
- e->right.int_val = e->left.int_val / e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val / e->right.data.int_val;
break;
case EXPR_MOD:
- e->right.int_val = e->left.int_val % e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val % e->right.data.int_val;
break;
case EXPR_NEG:
- e->right.int_val = -(e->right.int_val);
+ e->right.data.int_val = -(e->right.data.int_val);
break;
case EXPR_NOT:
- e->right.int_val = ~(e->right.int_val);
+ e->right.data.int_val = ~(e->right.data.int_val);
break;
case EXPR_OR:
- e->right.int_val = e->left.int_val | e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val | e->right.data.int_val;
break;
case EXPR_AND:
- e->right.int_val = e->left.int_val & e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val & e->right.data.int_val;
break;
case EXPR_XOR:
- e->right.int_val = e->left.int_val ^ e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val ^ e->right.data.int_val;
break;
case EXPR_SHL:
- e->right.int_val = e->right.int_val << e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
break;
case EXPR_SHR:
- e->right.int_val = e->right.int_val << e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
break;
case EXPR_LOR:
- e->right.int_val = e->left.int_val || e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val || e->right.data.int_val;
break;
case EXPR_LAND:
- e->right.int_val = e->left.int_val && e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val && e->right.data.int_val;
break;
case EXPR_LNOT:
- e->right.int_val = !e->right.int_val;
+ e->right.data.int_val = !e->right.data.int_val;
break;
case EXPR_EQ:
- e->right.int_val = e->right.int_val == e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val == e->left.data.int_val;
break;
case EXPR_LT:
- e->right.int_val = e->right.int_val < e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val < e->left.data.int_val;
break;
case EXPR_GT:
- e->right.int_val = e->right.int_val > e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val > e->left.data.int_val;
break;
case EXPR_LE:
- e->right.int_val = e->right.int_val <= e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val <= e->left.data.int_val;
break;
case EXPR_GE:
- e->right.int_val = e->right.int_val >= e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val >= e->left.data.int_val;
break;
case EXPR_NE:
- e->right.int_val = e->right.int_val != e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val != e->left.data.int_val;
break;
case EXPR_IDENT:
break;
}
/* catch simple identities like 0+x, 1*x, etc., for x not a num */
- else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
- || (e->left.int_val == 0 &&
+ else if (e->left.type == EXPR_INT && ((e->left.data.int_val == 1 && e->op == EXPR_MUL)
+ || (e->left.data.int_val == 0 &&
e->op == EXPR_ADD)
- || (e->left.int_val == -1 &&
+ || (e->left.data.int_val == -1 &&
e->op == EXPR_AND)
- || (e->left.int_val == 0 &&
+ || (e->left.data.int_val == 0 &&
e->op == EXPR_OR))) {
e->op = EXPR_IDENT;
simplified = 1;
}
/* and the corresponding x+|-0, x*&/1 */
- else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
- || (e->right.int_val == 1 &&
+ else if (e->right.type == EXPR_INT && ((e->right.data.int_val == 1 && e->op == EXPR_MUL)
+ || (e->right.data.int_val == 1 &&
e->op == EXPR_DIV)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_ADD)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SUB)
- || (e->right.int_val == -1 &&
+ || (e->right.data.int_val == -1 &&
e->op == EXPR_AND)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_OR)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SHL)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SHR))) {
e->op = EXPR_IDENT;
- e->rtype = e->ltype;
+ e->right.type = e->left.type;
memcpy(&e->right, &e->left, sizeof(ExprItem));
simplified = 1;
}
int
expr_get_value(expr *e, unsigned long *retval)
{
- while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
+ while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
&& expr_simplify(e)) ;
- if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
- *retval = e->right.int_val;
+ if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
+ *retval = e->right.data.int_val;
return 1;
} else
return 0;
expr_print(expr *e)
{
if (e->op != EXPR_IDENT) {
- switch (e->ltype) {
+ switch (e->left.type) {
case EXPR_SYM:
- printf("%s", e->left.sym->name);
+ printf("%s", symrec_get_name(e->left.data.sym));
break;
case EXPR_EXPR:
printf("(");
- expr_print(e->left.exp);
+ expr_print(e->left.data.expn);
printf(")");
break;
case EXPR_INT:
- printf("%lu", e->left.int_val);
+ printf("%lu", e->left.data.int_val);
break;
case EXPR_FLOAT:
- floatnum_print(e->left.flt);
+ floatnum_print(e->left.data.flt);
break;
case EXPR_NONE:
break;
case EXPR_IDENT:
break;
}
- switch (e->rtype) {
+ switch (e->right.type) {
case EXPR_SYM:
- printf("%s", e->right.sym->name);
+ printf("%s", symrec_get_name(e->right.data.sym));
break;
case EXPR_EXPR:
printf("(");
- expr_print(e->right.exp);
+ expr_print(e->right.data.expn);
printf(")");
break;
case EXPR_INT:
- printf("%lu", e->right.int_val);
+ printf("%lu", e->right.data.int_val);
break;
case EXPR_FLOAT:
- floatnum_print(e->right.flt);
+ floatnum_print(e->right.data.flt);
break;
case EXPR_NONE:
break;
RCSID("$IdPath$");
-/* Static structures for when NULL is passed to conversion functions. */
-/* for Convert*ToImm() */
-static immval im_static;
+struct effaddr {
+ expr *disp; /* address displacement */
+ unsigned char len; /* length of disp (in bytes), 0 if none */
+
+ unsigned char segment; /* segment override, 0 if none */
+
+ unsigned char modrm;
+ unsigned char valid_modrm; /* 1 if Mod/RM byte currently valid, 0 if not */
+ unsigned char need_modrm; /* 1 if Mod/RM byte needed, 0 if not */
+
+ unsigned char sib;
+ unsigned char valid_sib; /* 1 if SIB byte currently valid, 0 if not */
+ unsigned char need_sib; /* 1 if SIB byte needed, 0 if not */
+};
+
+struct immval {
+ expr *val;
+
+ unsigned char len; /* length of val (in bytes), 0 if none */
+ unsigned char isneg; /* the value has been explicitly negated */
+
+ unsigned char f_len; /* final imm length */
+ unsigned char f_sign; /* 1 if final imm should be signed */
+};
+
+struct dataval {
+ STAILQ_ENTRY(dataval) link;
+ enum { DV_EMPTY, DV_EXPR, DV_FLOAT, DV_STRING } type;
+
+ union {
+ expr *expn;
+ floatnum *flt;
+ char *str_val;
+ } data;
+};
+
+struct bytecode {
+ STAILQ_ENTRY(bytecode) link;
+
+ enum { BC_EMPTY, BC_INSN, BC_JMPREL, BC_DATA, BC_RESERVE } type;
+
+ /* This union has been somewhat tweaked to get it as small as possible
+ * on the 4-byte-aligned x86 architecture (without resorting to
+ * bitfields). In particular, insn and jmprel are the largest structures
+ * in the union, and are also the same size (after padding). jmprel
+ * can have another unsigned char added to the end without affecting
+ * its size.
+ *
+ * Don't worry about this too much, but keep it in mind when changing
+ * this structure. We care about the size of bytecode in particular
+ * because it accounts for the majority of the memory usage in the
+ * assembler when assembling a large file.
+ */
+ union {
+ struct {
+ effaddr *ea; /* effective address */
+
+ immval imm; /* immediate or relative value */
+
+ unsigned char opcode[3]; /* opcode */
+ unsigned char opcode_len;
+
+ unsigned char addrsize; /* 0 indicates no override */
+ unsigned char opersize; /* 0 indicates no override */
+ unsigned char lockrep_pre; /* 0 indicates no prefix */
+
+ /* HACK, but a space-saving one: shift opcodes have an immediate
+ * form and a ,1 form (with no immediate). In the parser, we
+ * set this and opcode_len=1, but store the ,1 version in the
+ * second byte of the opcode array. We then choose between the
+ * two versions once we know the actual value of imm (because we
+ * don't know it in the parser module).
+ *
+ * A override to force the imm version should just leave this at
+ * 0. Then later code won't know the ,1 version even exists.
+ * TODO: Figure out how this affects CPU flags processing.
+ *
+ * Call SetInsnShiftFlag() to set this flag to 1.
+ */
+ unsigned char shift_op;
+ } insn;
+ struct {
+ expr *target; /* target location */
+
+ struct {
+ unsigned char opcode[3];
+ unsigned char opcode_len; /* 0 = no opc for this version */
+ } shortop, nearop;
+
+ /* which opcode are we using? */
+ /* The *FORCED forms are specified in the source as such */
+ jmprel_opcode_sel op_sel;
+
+ unsigned char addrsize; /* 0 indicates no override */
+ unsigned char opersize; /* 0 indicates no override */
+ unsigned char lockrep_pre; /* 0 indicates no prefix */
+ } jmprel;
+ struct {
+ /* non-converted data (linked list) */
+ datavalhead datahead;
+
+ /* final (converted) size of each element (in bytes) */
+ unsigned char size;
+ } data;
+ struct {
+ expr *numitems; /* number of items to reserve */
+ unsigned char itemsize; /* size of each item (in bytes) */
+ } reserve;
+ } data;
+
+ unsigned long len; /* total length of entire bytecode */
+
+ /* where it came from */
+ char *filename;
+ unsigned int lineno;
+
+ /* other assembler state info */
+ unsigned long offset;
+ unsigned char mode_bits;
+};
+
+/* Static structures for when NULL is passed to conversion functions. */
/* for Convert*ToBytes() */
unsigned char bytes_static[16];
}
immval *
-ConvertIntToImm(immval *ptr, unsigned long int_val)
+immval_new_int(unsigned long int_val)
{
- if (!ptr)
- ptr = &im_static;
+ immval *im = xmalloc(sizeof(immval));
- /* FIXME: this will leak expr's if static is used */
- ptr->val = expr_new_ident(EXPR_INT, ExprInt(int_val));
+ im->val = expr_new_ident(ExprInt(int_val));
if ((int_val & 0xFF) == int_val)
- ptr->len = 1;
+ im->len = 1;
else if ((int_val & 0xFFFF) == int_val)
- ptr->len = 2;
+ im->len = 2;
else
- ptr->len = 4;
+ im->len = 4;
- ptr->isneg = 0;
+ im->isneg = 0;
- return ptr;
+ return im;
}
immval *
-ConvertExprToImm(immval *ptr, expr *expr_ptr)
+immval_new_expr(expr *expr_ptr)
{
- if (!ptr)
- ptr = &im_static;
+ immval *im = xmalloc(sizeof(immval));
- ptr->val = expr_ptr;
+ im->val = expr_ptr;
- ptr->isneg = 0;
+ im->isneg = 0;
- return ptr;
+ return im;
}
void
if (!ptr)
return;
- if (ptr->segment != 0)
+ if (segment != 0 && ptr->segment != 0)
Warning(_("multiple segment overrides, using leftmost"));
ptr->segment = segment;
ptr->len = len;
}
+effaddr *
+GetInsnEA(bytecode *bc)
+{
+ if (!bc)
+ return NULL;
+
+ if (bc->type != BC_INSN)
+ InternalError(__LINE__, __FILE__,
+ _("Trying to get EA of non-instruction"));
+
+ return bc->data.insn.ea;
+}
+
void
SetInsnOperSizeOverride(bytecode *bc, unsigned char opersize)
{
if (!old_sel)
return;
- if ((*old_sel == JR_SHORT_FORCED) || (*old_sel == JR_NEAR_FORCED))
+ if (new_sel != JR_NONE && ((*old_sel == JR_SHORT_FORCED) ||
+ (*old_sel == JR_NEAR_FORCED)))
Warning(_("multiple SHORT or NEAR specifiers, using leftmost"));
*old_sel = new_sel;
}
return retval;
}
+dataval *
+datavals_append(datavalhead *headp, dataval *dv)
+{
+ if (dv) {
+ STAILQ_INSERT_TAIL(headp, dv, link);
+ return dv;
+ }
+ return (dataval *)NULL;
+}
+
void
dataval_print(datavalhead *head)
{
#ifndef YASM_BYTECODE_H
#define YASM_BYTECODE_H
-struct section_s;
-
-typedef struct effaddr_s {
- struct expr_s *disp; /* address displacement */
- unsigned char len; /* length of disp (in bytes), 0 if none */
-
- unsigned char segment; /* segment override, 0 if none */
-
- unsigned char modrm;
- unsigned char valid_modrm; /* 1 if Mod/RM byte currently valid, 0 if not */
- unsigned char need_modrm; /* 1 if Mod/RM byte needed, 0 if not */
-
- unsigned char sib;
- unsigned char valid_sib; /* 1 if SIB byte currently valid, 0 if not */
- unsigned char need_sib; /* 1 if SIB byte needed, 0 if not */
-} effaddr;
-
-typedef struct immval_s {
- struct expr_s *val;
-
- unsigned char len; /* length of val (in bytes), 0 if none */
- unsigned char isneg; /* the value has been explicitly negated */
-
- unsigned char f_len; /* final imm length */
- unsigned char f_sign; /* 1 if final imm should be signed */
-} immval;
+#ifndef YASM_SECTION
+#define YASM_SECTION
+typedef struct section section;
+#endif
-typedef STAILQ_HEAD(datavalhead_s, dataval_s) datavalhead;
+#ifndef YASM_EXPR
+#define YASM_EXPR
+typedef struct expr expr;
+#endif
-typedef struct dataval_s {
- STAILQ_ENTRY(dataval_s) link;
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
- enum { DV_EMPTY, DV_EXPR, DV_FLOAT, DV_STRING } type;
+typedef struct effaddr effaddr;
+typedef struct immval immval;
+typedef STAILQ_HEAD(datavalhead, dataval) datavalhead;
+typedef struct dataval dataval;
+typedef STAILQ_HEAD(bytecodehead, bytecode) bytecodehead;
- union {
- struct expr_s *expn;
- struct floatnum_s *flt;
- char *str_val;
- } data;
-} dataval;
+#ifndef YASM_BYTECODE
+#define YASM_BYTECODE
+typedef struct bytecode bytecode;
+#endif
-typedef enum jmprel_opcode_sel_e {
+typedef enum {
JR_NONE,
JR_SHORT,
JR_NEAR,
} jmprel_opcode_sel;
typedef struct targetval_s {
- struct expr_s *val;
+ expr *val;
jmprel_opcode_sel op_sel;
} targetval;
-typedef STAILQ_HEAD(bytecodehead_s, bytecode_s) bytecodehead;
-
-typedef struct bytecode_s {
- STAILQ_ENTRY(bytecode_s) link;
-
- enum { BC_EMPTY, BC_INSN, BC_JMPREL, BC_DATA, BC_RESERVE } type;
-
- /* This union has been somewhat tweaked to get it as small as possible
- * on the 4-byte-aligned x86 architecture (without resorting to
- * bitfields). In particular, insn and jmprel are the largest structures
- * in the union, and are also the same size (after padding). jmprel
- * can have another unsigned char added to the end without affecting
- * its size.
- *
- * Don't worry about this too much, but keep it in mind when changing
- * this structure. We care about the size of bytecode in particular
- * because it accounts for the majority of the memory usage in the
- * assembler when assembling a large file.
- */
- union {
- struct {
- effaddr *ea; /* effective address */
-
- immval imm; /* immediate or relative value */
-
- unsigned char opcode[3]; /* opcode */
- unsigned char opcode_len;
-
- unsigned char addrsize; /* 0 indicates no override */
- unsigned char opersize; /* 0 indicates no override */
- unsigned char lockrep_pre; /* 0 indicates no prefix */
-
- /* HACK, but a space-saving one: shift opcodes have an immediate
- * form and a ,1 form (with no immediate). In the parser, we
- * set this and opcode_len=1, but store the ,1 version in the
- * second byte of the opcode array. We then choose between the
- * two versions once we know the actual value of imm (because we
- * don't know it in the parser module).
- *
- * A override to force the imm version should just leave this at
- * 0. Then later code won't know the ,1 version even exists.
- * TODO: Figure out how this affects CPU flags processing.
- *
- * Call SetInsnShiftFlag() to set this flag to 1.
- */
- unsigned char shift_op;
- } insn;
- struct {
- struct expr_s *target; /* target location */
-
- struct {
- unsigned char opcode[3];
- unsigned char opcode_len; /* 0 = no opc for this version */
- } shortop, nearop;
-
- /* which opcode are we using? */
- /* The *FORCED forms are specified in the source as such */
- jmprel_opcode_sel op_sel;
-
- unsigned char addrsize; /* 0 indicates no override */
- unsigned char opersize; /* 0 indicates no override */
- unsigned char lockrep_pre; /* 0 indicates no prefix */
- } jmprel;
- struct {
- /* non-converted data (linked list) */
- datavalhead datahead;
-
- /* final (converted) size of each element (in bytes) */
- unsigned char size;
- } data;
- struct {
- struct expr_s *numitems; /* number of items to reserve */
- unsigned char itemsize; /* size of each item (in bytes) */
- } reserve;
- } data;
-
- unsigned long len; /* total length of entire bytecode */
-
- /* where it came from */
- char *filename;
- unsigned int lineno;
-
- /* other assembler state info */
- unsigned long offset;
- unsigned char mode_bits;
-} bytecode;
-
effaddr *effaddr_new_reg(unsigned long reg);
effaddr *effaddr_new_imm(immval *im_ptr, unsigned char im_len);
-effaddr *effaddr_new_expr(struct expr_s *expr_ptr);
+effaddr *effaddr_new_expr(expr *expr_ptr);
-immval *ConvertIntToImm(immval *ptr, unsigned long int_val);
-immval *ConvertExprToImm(immval *ptr, struct expr_s *expr_ptr);
+immval *immval_new_int(unsigned long int_val);
+immval *immval_new_expr(expr *expr_ptr);
void SetEASegment(effaddr *ptr, unsigned char segment);
void SetEALen(effaddr *ptr, unsigned char len);
+effaddr *GetInsnEA(bytecode *bc);
+
void SetInsnOperSizeOverride(bytecode *bc, unsigned char opersize);
void SetInsnAddrSizeOverride(bytecode *bc, unsigned char addrsize);
void SetInsnLockRepPrefix(bytecode *bc, unsigned char prefix);
bytecode *bytecode_new_data(datavalhead *datahead, unsigned long size);
-bytecode *bytecode_new_reserve(struct expr_s *numitems,
- unsigned long itemsize);
+bytecode *bytecode_new_reserve(expr *numitems, unsigned long itemsize);
/* Gets the offset of the bytecode specified by bc if possible.
* Return value is IF POSSIBLE, not the value.
*/
-int bytecode_get_offset(struct section_s *sect, bytecode *bc,
- unsigned long *ret_val);
+int bytecode_get_offset(section *sect, bytecode *bc, unsigned long *ret_val);
void bytecode_print(bytecode *bc);
*/
bytecode *bytecodes_append(bytecodehead *headp, bytecode *bc);
-dataval *dataval_new_expr(struct expr_s *expn);
-dataval *dataval_new_float(struct floatnum_s *flt);
+dataval *dataval_new_expr(expr *expn);
+dataval *dataval_new_float(floatnum *flt);
dataval *dataval_new_string(char *str_val);
+/* void datavals_initialize(datavalhead *headp); */
+#define datavals_initialize(headp) STAILQ_INIT(headp)
+
+/* Adds dv to the list of datavals headp.
+ * NOTE: Does not make a copy of dv; so don't pass this function
+ * static or local variables, and discard the dv pointer after calling
+ * this function. If dv was actually appended (it wasn't NULL), then
+ * returns dv, otherwise returns NULL.
+ */
+dataval *datavals_append(datavalhead *headp, dataval *dv);
+
void dataval_print(datavalhead *head);
#endif
# include <string.h>
#endif
+#include <libintl.h>
+#define _(String) gettext(String)
+#ifdef gettext_noop
+#define N_(String) gettext_noop(String)
+#else
+#define N_(String) (String)
+#endif
+
#include "globals.h"
#include "errwarn.h"
#include "floatnum.h"
RCSID("$IdPath$");
+typedef enum {
+ EXPR_NONE, /* for left side of a NOT, NEG, etc. */
+ EXPR_SYM,
+ EXPR_EXPR,
+ EXPR_INT,
+ EXPR_FLOAT
+} ExprType;
+
+struct ExprItem {
+ ExprType type;
+ union {
+ symrec *sym;
+ expr *expn;
+ unsigned long int_val;
+ floatnum *flt;
+ } data;
+};
+
+struct expr {
+ ExprItem left, right;
+ ExprOp op;
+};
+
/* allocate a new expression node, with children as defined.
* If it's a unary operator, put the element on the right */
expr *
-expr_new(ExprType ltype,
- ExprItem left,
- ExprOp op,
- ExprType rtype,
- ExprItem right)
+expr_new(ExprItem *left, ExprOp op, ExprItem *right)
{
expr *ptr;
ptr = xmalloc(sizeof(expr));
- ptr->ltype = ltype;
+ ptr->left.type = EXPR_NONE;
ptr->op = op;
- ptr->rtype = rtype;
- switch (ltype) {
- case EXPR_SYM:
- case EXPR_EXPR:
- case EXPR_INT:
- case EXPR_FLOAT:
- memcpy(&ptr->left, &left, sizeof(ExprItem));
- break;
- case EXPR_NONE:
- break;
+ ptr->right.type = EXPR_NONE;
+ if (left) {
+ memcpy(&ptr->left, left, sizeof(ExprItem));
+ free(left);
}
- switch (rtype) {
- case EXPR_SYM:
- case EXPR_EXPR:
- case EXPR_INT:
- case EXPR_FLOAT:
- memcpy(&ptr->right, &right, sizeof(ExprItem));
- break;
- case EXPR_NONE:
- Fatal(FATAL_UNKNOWN); /* TODO: better error? */
- break;
+ if (right) {
+ memcpy(&ptr->right, right, sizeof(ExprItem));
+ free(right);
+ } else {
+ InternalError(__LINE__, __FILE__,
+ _("Right side of expression must exist"));
}
return ptr;
}
/* helpers */
-ExprItem
-ExprSym(struct symrec_s *s)
+ExprItem *
+ExprSym(symrec *s)
{
- ExprItem e;
-
- e.sym = s;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_SYM;
+ e->data.sym = s;
return e;
}
-ExprItem
+ExprItem *
ExprExpr(expr *x)
{
- ExprItem e;
- e.exp = x;
-
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_EXPR;
+ e->data.expn = x;
return e;
}
-ExprItem
+ExprItem *
ExprInt(unsigned long i)
{
- ExprItem e;
-
- e.int_val = i;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_INT;
+ e->data.int_val = i;
return e;
}
-ExprItem
+ExprItem *
ExprFloat(floatnum *f)
{
- ExprItem e;
-
- e.flt = f;
- return e;
-}
-
-ExprItem
-ExprNone(void)
-{
- ExprItem e;
-
- e.int_val = 0;
+ ExprItem *e = xmalloc(sizeof(ExprItem));
+ e->type = EXPR_FLOAT;
+ e->data.flt = f;
return e;
}
unsigned long int_val;
/* try to simplify the left side */
- if (e->ltype == EXPR_EXPR) {
+ if (e->left.type == EXPR_EXPR) {
/* if the left subexpr isn't an IDENT, recurse simplification */
- if (e->left.exp->op != EXPR_IDENT)
- simplified |= expr_simplify(e->left.exp);
+ if (e->left.data.expn->op != EXPR_IDENT)
+ simplified |= expr_simplify(e->left.data.expn);
/* if the left subexpr is just an IDENT (or string thereof),
* pull it up into the current node */
- while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
+ while (e->left.type == EXPR_EXPR && e->left.data.expn->op == EXPR_IDENT) {
ExprItem tmp;
- e->ltype = e->left.exp->rtype;
- memcpy(&tmp, &(e->left.exp->right), sizeof(ExprItem));
- free(e->left.exp);
- memcpy(&(e->left.int_val), &tmp, sizeof(ExprItem));
+ e->left.type = e->left.data.expn->right.type;
+ memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
+ free(e->left.data.expn);
+ memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
simplified = 1;
}
- } else if (e->ltype == EXPR_SYM) {
+ } else if (e->left.type == EXPR_SYM) {
/* try to get value of symbol */
- if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
- e->ltype = EXPR_INT;
+ if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
+ e->left.type = EXPR_INT;
/* don't try to free the symrec here. */
- e->left.int_val = int_val;
+ e->left.data.int_val = int_val;
simplified = 1;
}
}
/* ditto on the right */
- if (e->rtype == EXPR_EXPR) {
- if (e->right.exp->op != EXPR_IDENT)
- simplified |= expr_simplify(e->right.exp);
+ if (e->right.type == EXPR_EXPR) {
+ if (e->right.data.expn->op != EXPR_IDENT)
+ simplified |= expr_simplify(e->right.data.expn);
- while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
+ while (e->right.type == EXPR_EXPR && e->right.data.expn->op == EXPR_IDENT) {
ExprItem tmp;
- e->rtype = e->right.exp->rtype;
- memcpy(&tmp, &(e->right.exp->right), sizeof(ExprItem));
- free(e->right.exp);
- memcpy(&(e->right.int_val), &tmp, sizeof(ExprItem));
+ e->right.type = e->right.data.expn->right.type;
+ memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
+ free(e->right.data.expn);
+ memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
simplified = 1;
}
- } else if (e->rtype == EXPR_SYM) {
- if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
- e->rtype = EXPR_INT;
+ } else if (e->right.type == EXPR_SYM) {
+ if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
+ e->right.type = EXPR_INT;
/* don't try to free the symrec here. */
- e->right.int_val = int_val;
+ e->right.data.int_val = int_val;
simplified = 1;
}
}
- if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
- && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
+ if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE)
+ && e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
switch (e->op) {
case EXPR_ADD:
- e->right.int_val = e->left.int_val + e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val + e->right.data.int_val;
break;
case EXPR_SUB:
- e->right.int_val = e->left.int_val - e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val - e->right.data.int_val;
break;
case EXPR_MUL:
- e->right.int_val = e->left.int_val * e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val * e->right.data.int_val;
break;
case EXPR_DIV:
- e->right.int_val = e->left.int_val / e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val / e->right.data.int_val;
break;
case EXPR_MOD:
- e->right.int_val = e->left.int_val % e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val % e->right.data.int_val;
break;
case EXPR_NEG:
- e->right.int_val = -(e->right.int_val);
+ e->right.data.int_val = -(e->right.data.int_val);
break;
case EXPR_NOT:
- e->right.int_val = ~(e->right.int_val);
+ e->right.data.int_val = ~(e->right.data.int_val);
break;
case EXPR_OR:
- e->right.int_val = e->left.int_val | e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val | e->right.data.int_val;
break;
case EXPR_AND:
- e->right.int_val = e->left.int_val & e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val & e->right.data.int_val;
break;
case EXPR_XOR:
- e->right.int_val = e->left.int_val ^ e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val ^ e->right.data.int_val;
break;
case EXPR_SHL:
- e->right.int_val = e->right.int_val << e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
break;
case EXPR_SHR:
- e->right.int_val = e->right.int_val << e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
break;
case EXPR_LOR:
- e->right.int_val = e->left.int_val || e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val || e->right.data.int_val;
break;
case EXPR_LAND:
- e->right.int_val = e->left.int_val && e->right.int_val;
+ e->right.data.int_val = e->left.data.int_val && e->right.data.int_val;
break;
case EXPR_LNOT:
- e->right.int_val = !e->right.int_val;
+ e->right.data.int_val = !e->right.data.int_val;
break;
case EXPR_EQ:
- e->right.int_val = e->right.int_val == e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val == e->left.data.int_val;
break;
case EXPR_LT:
- e->right.int_val = e->right.int_val < e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val < e->left.data.int_val;
break;
case EXPR_GT:
- e->right.int_val = e->right.int_val > e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val > e->left.data.int_val;
break;
case EXPR_LE:
- e->right.int_val = e->right.int_val <= e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val <= e->left.data.int_val;
break;
case EXPR_GE:
- e->right.int_val = e->right.int_val >= e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val >= e->left.data.int_val;
break;
case EXPR_NE:
- e->right.int_val = e->right.int_val != e->left.int_val;
+ e->right.data.int_val = e->right.data.int_val != e->left.data.int_val;
break;
case EXPR_IDENT:
break;
}
/* catch simple identities like 0+x, 1*x, etc., for x not a num */
- else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
- || (e->left.int_val == 0 &&
+ else if (e->left.type == EXPR_INT && ((e->left.data.int_val == 1 && e->op == EXPR_MUL)
+ || (e->left.data.int_val == 0 &&
e->op == EXPR_ADD)
- || (e->left.int_val == -1 &&
+ || (e->left.data.int_val == -1 &&
e->op == EXPR_AND)
- || (e->left.int_val == 0 &&
+ || (e->left.data.int_val == 0 &&
e->op == EXPR_OR))) {
e->op = EXPR_IDENT;
simplified = 1;
}
/* and the corresponding x+|-0, x*&/1 */
- else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
- || (e->right.int_val == 1 &&
+ else if (e->right.type == EXPR_INT && ((e->right.data.int_val == 1 && e->op == EXPR_MUL)
+ || (e->right.data.int_val == 1 &&
e->op == EXPR_DIV)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_ADD)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SUB)
- || (e->right.int_val == -1 &&
+ || (e->right.data.int_val == -1 &&
e->op == EXPR_AND)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_OR)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SHL)
- || (e->right.int_val == 0 &&
+ || (e->right.data.int_val == 0 &&
e->op == EXPR_SHR))) {
e->op = EXPR_IDENT;
- e->rtype = e->ltype;
+ e->right.type = e->left.type;
memcpy(&e->right, &e->left, sizeof(ExprItem));
simplified = 1;
}
int
expr_get_value(expr *e, unsigned long *retval)
{
- while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
+ while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
&& expr_simplify(e)) ;
- if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
- *retval = e->right.int_val;
+ if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
+ *retval = e->right.data.int_val;
return 1;
} else
return 0;
expr_print(expr *e)
{
if (e->op != EXPR_IDENT) {
- switch (e->ltype) {
+ switch (e->left.type) {
case EXPR_SYM:
- printf("%s", e->left.sym->name);
+ printf("%s", symrec_get_name(e->left.data.sym));
break;
case EXPR_EXPR:
printf("(");
- expr_print(e->left.exp);
+ expr_print(e->left.data.expn);
printf(")");
break;
case EXPR_INT:
- printf("%lu", e->left.int_val);
+ printf("%lu", e->left.data.int_val);
break;
case EXPR_FLOAT:
- floatnum_print(e->left.flt);
+ floatnum_print(e->left.data.flt);
break;
case EXPR_NONE:
break;
case EXPR_IDENT:
break;
}
- switch (e->rtype) {
+ switch (e->right.type) {
case EXPR_SYM:
- printf("%s", e->right.sym->name);
+ printf("%s", symrec_get_name(e->right.data.sym));
break;
case EXPR_EXPR:
printf("(");
- expr_print(e->right.exp);
+ expr_print(e->right.data.expn);
printf(")");
break;
case EXPR_INT:
- printf("%lu", e->right.int_val);
+ printf("%lu", e->right.data.int_val);
break;
case EXPR_FLOAT:
- floatnum_print(e->right.flt);
+ floatnum_print(e->right.data.flt);
break;
case EXPR_NONE:
break;
#ifndef YASM_EXPR_H
#define YASM_EXPR_H
+#ifndef YASM_SYMREC
+#define YASM_SYMREC
+typedef struct symrec symrec;
+#endif
+
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
+
typedef enum {
EXPR_ADD,
EXPR_SUB,
EXPR_IDENT /* if right is IDENT, then the entire expr is just a num */
} ExprOp;
-typedef enum {
- EXPR_NONE, /* for left side of a NOT, NEG, etc. */
- EXPR_SYM,
- EXPR_EXPR,
- EXPR_INT,
- EXPR_FLOAT
-} ExprType;
-
-typedef union expritem_u {
- struct symrec_s *sym;
- struct expr_s *exp;
- unsigned long int_val;
- struct floatnum_s *flt;
-} ExprItem;
+typedef struct ExprItem ExprItem;
-typedef struct expr_s {
- ExprType ltype, rtype;
- ExprItem left, right;
- ExprOp op;
-} expr;
+#ifndef YASM_EXPR
+#define YASM_EXPR
+typedef struct expr expr;
+#endif
-expr *expr_new(ExprType, ExprItem, ExprOp, ExprType, ExprItem);
+expr *expr_new(ExprItem *, ExprOp, ExprItem *);
-ExprItem ExprSym(struct symrec_s *);
-ExprItem ExprExpr(expr *);
-ExprItem ExprInt(unsigned long);
-ExprItem ExprFloat(struct floatnum_s *);
-ExprItem ExprNone(void);
+ExprItem *ExprSym(symrec *);
+ExprItem *ExprExpr(expr *);
+ExprItem *ExprInt(unsigned long);
+ExprItem *ExprFloat(floatnum *);
#define expr_new_tree(l,o,r) \
- expr_new (EXPR_EXPR, ExprExpr(l), (o), EXPR_EXPR, ExprExpr(r))
+ expr_new (ExprExpr(l), (o), ExprExpr(r))
#define expr_new_branch(o,r) \
- expr_new (EXPR_NONE, ExprNone(), (o), EXPR_EXPR, ExprExpr(r))
-#define expr_new_ident(t,r) \
- expr_new (EXPR_NONE, ExprNone(), EXPR_IDENT, (ExprType)(t), (r))
+ expr_new ((ExprItem *)NULL, (o), ExprExpr(r))
+#define expr_new_ident(r) \
+ expr_new ((ExprItem *)NULL, EXPR_IDENT, (r))
int expr_simplify(expr *);
void expr_print(expr *);
RCSID("$IdPath$");
+/* 97-bit internal floating point format:
+ * xxxxxxxs eeeeeeee eeeeeeee m.....................................m
+ * Sign exponent mantissa (80 bits)
+ * 79 0
+ *
+ * Only L.O. bit of Sign byte is significant. The rest is garbage.
+ * Exponent is bias 32767.
+ * Mantissa does NOT have an implied one bit (it's explicit).
+ */
+struct floatnum {
+ unsigned int *mantissa; /* Allocated to 64 bits */
+ unsigned short exponent;
+ unsigned char sign;
+ unsigned char flags;
+};
+
/* constants describing parameters of internal floating point format */
#define MANT_BITS 80
#define MANT_BYTES 10
#ifndef YASM_FLOATNUM_H
#define YASM_FLOATNUM_H
-/* 97-bit internal floating point format:
- * xxxxxxxs eeeeeeee eeeeeeee m.....................................m
- * Sign exponent mantissa (80 bits)
- * 79 0
- *
- * Only L.O. bit of Sign byte is significant. The rest is garbage.
- * Exponent is bias 32767.
- * Mantissa does NOT have an implied one bit (it's explicit).
- */
-typedef struct floatnum_s {
- unsigned int *mantissa; /* Allocated to 64 bits */
- unsigned short exponent;
- unsigned char sign;
- unsigned char flags;
-} floatnum;
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
floatnum *floatnum_new(const char *str);
void floatnum_delete(floatnum *flt);
unsigned char groupdata[4];
effaddr *ea;
expr *exp;
- immval im_val;
+ immval *im_val;
targetval tgt_val;
datavalhead datahead;
dataval *data;
%%
input: /* empty */
| input line {
- nasm_parser_temp_bc = bytecodes_append(&nasm_parser_cur_section->bc,
+ nasm_parser_temp_bc = bytecodes_append(section_get_bytecodes(nasm_parser_cur_section),
$2);
if (nasm_parser_temp_bc)
nasm_parser_prev_bc = nasm_parser_temp_bc;
;
datavals: dataval {
- STAILQ_INIT(&$$);
- if ($1)
- STAILQ_INSERT_TAIL(&$$, $1, link);
+ datavals_initialize(&$$);
+ datavals_append(&$$, $1);
}
| datavals ',' dataval {
- if ($3)
- STAILQ_INSERT_TAIL(&$1, $3, link);
+ datavals_append(&$1, $3);
$$ = $1;
}
;
memexp: expr { expr_simplify ($1); $$ = effaddr_new_expr($1); }
;
-memaddr: memexp { $$ = $1; $$->segment = 0; }
+memaddr: memexp { $$ = $1; SetEASegment($$, 0); }
| REG_CS ':' memaddr { $$ = $3; SetEASegment($$, 0x2E); }
| REG_SS ':' memaddr { $$ = $3; SetEASegment($$, 0x36); }
| REG_DS ':' memaddr { $$ = $3; SetEASegment($$, 0x3E); }
;
/* immediate values */
-imm: expr { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
+imm: expr { expr_simplify($1); $$ = immval_new_expr($1); }
;
/* explicit immediates */
;
/* jump targets */
-target: expr { $$.val = $1; $$.op_sel = JR_NONE; }
+target: expr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); }
| SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); }
| NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); }
;
/* expression trees */
-expr_no_string: INTNUM { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
- | explabel {
- $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1)));
- }
+expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); }
+ | explabel { $$ = expr_new_ident(ExprSym(symrec_use($1))); }
/*| expr '||' expr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
| expr '|' expr { $$ = expr_new_tree($1, EXPR_OR, $3); }
| expr '^' expr { $$ = expr_new_tree($1, EXPR_XOR, $3); }
expr: expr_no_string
| STRING {
- $$ = expr_new_ident (EXPR_INT, ExprInt(ConvertCharConstToInt($1)));
+ $$ = expr_new_ident(ExprInt(ConvertCharConstToInt($1)));
}
;
instr: instrbase
| OPERSIZE instr { $$ = $2; SetInsnOperSizeOverride($$, $1); }
| ADDRSIZE instr { $$ = $2; SetInsnAddrSizeOverride($$, $1); }
- | REG_CS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x2E); }
- | REG_SS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x36); }
- | REG_DS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x3E); }
- | REG_ES instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x26); }
- | REG_FS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x64); }
- | REG_GS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x65); }
+ | REG_CS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x2E); }
+ | REG_SS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x36); }
+ | REG_DS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x3E); }
+ | REG_ES instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x26); }
+ | REG_FS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x64); }
+ | REG_GS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x65); }
| LOCK instr { $$ = $2; SetInsnLockRepPrefix($$, 0xF0); }
| REPNZ instr { $$ = $2; SetInsnLockRepPrefix($$, 0xF2); }
| REP instr { $$ = $2; SetInsnLockRepPrefix($$, 0xF3); }
#$args[-1] =~ s/(\$\d+[ri]?)(?!\.)/\&$1/; # Just the first!
$args[-1] =~ s/(\$\d+)r/effaddr_new_reg($1)/;
$args[-1] =~ s[(\$\d+)i,\s*(\d+)]
- ["effaddr_new_imm(\&$1, ".($2/8)."), 0"]e;
+ ["effaddr_new_imm($1, ".($2/8)."), 0"]e;
$args[-1] .= ',';
die $args[-1] if $args[-1] =~ m/\d+[ri]/;
$args[-1] =~ s/nil/(immval *)NULL, 0/;
# don't match $0.\d in the following rules.
$args[-1] =~ s/\$(\d+)(?!\.)/"\$".($1*2+$to).($2||'')/eg;
- $args[-1] =~ s/(\$\d+)(?!\.)/\&$1/; # Just the first!
$args[-1] =~ s[^([0-9A-Fa-f]+),]
- [ConvertIntToImm((immval *)NULL, 0x$1),];
+ [immval_new_int(0x$1),];
$args[-1] =~ s[^\$0.(\d+),]
- [ConvertIntToImm((immval *)NULL, \$1\[$1\]),];
+ [immval_new_int(\$1\[$1\]),];
# divide the second, and only the second, by 8 bits/byte
$args[-1] =~ s#(,\s*)(\d+)(s)?#$1 . ($2/8)#eg;
unsigned char groupdata[4];
effaddr *ea;
expr *exp;
- immval im_val;
+ immval *im_val;
targetval tgt_val;
datavalhead datahead;
dataval *data;
%%
input: /* empty */
| input line {
- nasm_parser_temp_bc = bytecodes_append(&nasm_parser_cur_section->bc,
+ nasm_parser_temp_bc = bytecodes_append(section_get_bytecodes(nasm_parser_cur_section),
$2);
if (nasm_parser_temp_bc)
nasm_parser_prev_bc = nasm_parser_temp_bc;
;
datavals: dataval {
- STAILQ_INIT(&$$);
- if ($1)
- STAILQ_INSERT_TAIL(&$$, $1, link);
+ datavals_initialize(&$$);
+ datavals_append(&$$, $1);
}
| datavals ',' dataval {
- if ($3)
- STAILQ_INSERT_TAIL(&$1, $3, link);
+ datavals_append(&$1, $3);
$$ = $1;
}
;
memexp: expr { expr_simplify ($1); $$ = effaddr_new_expr($1); }
;
-memaddr: memexp { $$ = $1; $$->segment = 0; }
+memaddr: memexp { $$ = $1; SetEASegment($$, 0); }
| REG_CS ':' memaddr { $$ = $3; SetEASegment($$, 0x2E); }
| REG_SS ':' memaddr { $$ = $3; SetEASegment($$, 0x36); }
| REG_DS ':' memaddr { $$ = $3; SetEASegment($$, 0x3E); }
;
/* immediate values */
-imm: expr { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
+imm: expr { expr_simplify($1); $$ = immval_new_expr($1); }
;
/* explicit immediates */
;
/* jump targets */
-target: expr { $$.val = $1; $$.op_sel = JR_NONE; }
+target: expr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); }
| SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); }
| NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); }
;
/* expression trees */
-expr_no_string: INTNUM { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
- | explabel {
- $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1)));
- }
+expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); }
+ | explabel { $$ = expr_new_ident(ExprSym(symrec_use($1))); }
/*| expr '||' expr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
| expr '|' expr { $$ = expr_new_tree($1, EXPR_OR, $3); }
| expr '^' expr { $$ = expr_new_tree($1, EXPR_XOR, $3); }
expr: expr_no_string
| STRING {
- $$ = expr_new_ident (EXPR_INT, ExprInt(ConvertCharConstToInt($1)));
+ $$ = expr_new_ident(ExprInt(ConvertCharConstToInt($1)));
}
;
instr: instrbase
| OPERSIZE instr { $$ = $2; SetInsnOperSizeOverride($$, $1); }
| ADDRSIZE instr { $$ = $2; SetInsnAddrSizeOverride($$, $1); }
- | REG_CS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x2E); }
- | REG_SS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x36); }
- | REG_DS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x3E); }
- | REG_ES instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x26); }
- | REG_FS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x64); }
- | REG_GS instr { $$ = $2; SetEASegment($$->data.insn.ea, 0x65); }
+ | REG_CS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x2E); }
+ | REG_SS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x36); }
+ | REG_DS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x3E); }
+ | REG_ES instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x26); }
+ | REG_FS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x64); }
+ | REG_GS instr { $$ = $2; SetEASegment(GetInsnEA($$), 0x65); }
| LOCK instr { $$ = $2; SetInsnLockRepPrefix($$, 0xF0); }
| REPNZ instr { $$ = $2; SetInsnLockRepPrefix($$, 0xF2); }
| REP instr { $$ = $2; SetInsnLockRepPrefix($$, 0xF3); }
RCSID("$IdPath$");
+struct section {
+ STAILQ_ENTRY(section) link;
+
+ enum { SECTION_GENERAL, SECTION_ABSOLUTE } type;
+
+ char *name; /* strdup()'ed name (given by user) */
+
+ union {
+ /* SECTION_GENERAL data */
+ /* SECTION_ABSOLUTE data */
+ unsigned long start;
+ } data;
+
+ bytecodehead bc; /* the bytecodes for the section's contents */
+};
+
section *
sections_initialize(sectionhead *headp, objfmt *of)
{
return s;
}
+
+bytecodehead *
+section_get_bytecodes(section *sect)
+{
+ return §->bc;
+}
struct objfmt_s;
-typedef STAILQ_HEAD(sectionhead_s, section_s) sectionhead;
+typedef STAILQ_HEAD(sectionhead, section) sectionhead;
-typedef struct section_s {
- STAILQ_ENTRY(section_s) link;
-
- enum { SECTION_GENERAL, SECTION_ABSOLUTE } type;
-
- char *name; /* strdup()'ed name (given by user) */
-
- union {
- /* SECTION_GENERAL data */
- /* SECTION_ABSOLUTE data */
- unsigned long start;
- } data;
-
- bytecodehead bc; /* the bytecodes for the section's contents */
-} section;
+#ifndef YASM_SECTION
+#define YASM_SECTION
+typedef struct section section;
+#endif
section *sections_initialize(sectionhead *headp, struct objfmt_s *of);
section *sections_switch(sectionhead *headp, struct objfmt_s *of,
const char *name);
+bytecodehead *section_get_bytecodes(section *sect);
#endif
RCSID("$IdPath$");
+struct symrec {
+ char *name;
+ SymType type;
+ SymStatus status;
+ SymVisibility visibility;
+ char *filename; /* file and line */
+ unsigned long line; /* symbol was first declared or used on */
+ union {
+ unsigned long int_val; /* integer constant */
+ floatnum *flt; /* floating point constant */
+ struct label_s { /* bytecode immediately preceding a label */
+ section *sect;
+ bytecode *bc;
+ } label;
+ } value;
+};
+
/* private functions */
static symrec *symrec_get_or_new(const char *);
static symrec *symrec_define(const char *, SymType type);
/* We can't get the value right now. */
return 0;
}
+
+const char *
+symrec_get_name(const symrec *sym)
+{
+ return sym->name;
+}
#ifndef YASM_SYMREC_H
#define YASM_SYMREC_H
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
+
+#ifndef YASM_SECTION
+#define YASM_SECTION
+typedef struct section section;
+#endif
+
+#ifndef YASM_BYTECODE
+#define YASM_BYTECODE
+typedef struct bytecode bytecode;
+#endif
+
/* DEFINED is set with EXTERN and COMMON below */
typedef enum {
SYM_NOSTATUS = 0,
SYM_LABEL /* for labels */
} SymType;
-typedef struct symrec_s {
- char *name;
- SymType type;
- SymStatus status;
- SymVisibility visibility;
- char *filename; /* file and line */
- unsigned long line; /* symbol was first declared or used on */
- union {
- unsigned long int_val; /* integer constant */
- struct floatnum_s *flt; /* floating point constant */
- struct label_s { /* bytecode immediately preceding a label */
- struct section_s *sect;
- struct bytecode_s *bc;
- } label;
- } value;
-} symrec;
+#ifndef YASM_SYMREC
+#define YASM_SYMREC
+typedef struct symrec symrec;
+#endif
symrec *symrec_use(const char *name);
symrec *symrec_define_constant_int(const char *name, unsigned long int_val);
-symrec *symrec_define_constant_float(const char *name, struct floatnum_s *flt);
-symrec *symrec_define_label(const char *name, struct section_s *sect,
- struct bytecode_s *precbc);
+symrec *symrec_define_constant_float(const char *name, floatnum *flt);
+symrec *symrec_define_label(const char *name, section *sect, bytecode *precbc);
symrec *symrec_declare(const char *name, SymVisibility vis);
/* Get the numeric 32-bit value of a symbol if possible.
int symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
int resolve_label);
+const char *symrec_get_name(const symrec *sym);
+
void symrec_foreach(int (*func) (const char *name, symrec *rec));
#endif
floatnum_test_SOURCES = \
floatnum_test.c
-INCLUDES= -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/check
+INCLUDES= -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/check \
+ -I$(top_builddir)/intl
LDADD = \
$(top_builddir)/check/libcheck.a \
$(top_builddir)/src/parsers/nasm/libparser.a \
#include "check.h"
-#include "util.h"
-
-#include "bytecode.h"
+#include "bytecode.c"
START_TEST(test_effaddr_new_reg)
{
#include "check.h"
-#include "bitvect.h"
-
-#include "floatnum.h"
+#include "floatnum.c"
/* constants describing parameters of internal floating point format.
* (these should match those in src/floatnum.c !)