-/* $Id: bytecode.h,v 1.8 2001/06/28 21:22:01 peter Exp $
+/* $Id: bytecode.h,v 1.9 2001/07/05 08:37:59 mu Exp $
* Bytecode utility functions header file
*
* Copyright (C) 2001 Peter Johnson
} effaddr;
typedef struct immval_s {
- unsigned long val;
+ struct expr_s *val;
unsigned char len; /* length of val (in bytes), 0 if none */
unsigned char isrel;
-/* $Id: expr.h,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: expr.h,v 1.2 2001/07/05 08:37:59 mu Exp $
* Expression handling header file
*
* Copyright (C) 2001 Michael Urman
typedef union expritem_u {
struct symrec_s *sym;
struct expr_s *expr;
- int num;
+ unsigned long num;
} ExprItem;
typedef struct expr_s {
} expr;
expr *expr_new (ExprType, ExprItem, ExprOp, ExprType, ExprItem);
+/*expr *expr_new_tree (ExprItem, ExprOp, ExprItem);
+expr *expr_new_branch (ExprOp, ExprItem);
+expr *expr_new_ident (ExprType, ExprItem);*/
+#define expr_new_tree(l,o,r) \
+ expr_new (EXPR_EXPR, (ExprItem)(l), (ExprOp)(o), EXPR_EXPR, (ExprItem)(r))
+#define expr_new_branch(o,r) \
+ expr_new (EXPR_NONE, (ExprItem)0UL, (ExprOp)(o), EXPR_EXPR, (ExprItem)(r))
+#define expr_new_ident(t,r) \
+ expr_new (EXPR_NONE, (ExprItem)0UL, EXPR_IDENT, (ExprType)(t), (ExprItem)(r))
int expr_simplify (expr *);
+void expr_print (expr *);
+
+/* get the value if possible. return value is IF POSSIBLE, not the val */
+int expr_get_value (expr *, unsigned long *);
+
#endif
-/* $Id: bytecode.c,v 1.8 2001/05/30 07:41:03 peter Exp $
+/* $Id: bytecode.c,v 1.9 2001/07/05 08:37:59 mu Exp $
* Bytecode utility functions
*
* Copyright (C) 2001 Peter Johnson
#include "globals.h"
#include "bytecode.h"
#include "errwarn.h"
+#include "expr.h"
static effaddr eff_static;
static immval im_static;
effaddr *ConvertImmToEA(effaddr *ptr, immval *im_ptr, unsigned char im_len)
{
+ int gotexprval;
if(!ptr)
ptr = &eff_static;
- ptr->disp = im_ptr->val;
+ /* FIXME: warn when gotexprval is 0, and/or die */
+ gotexprval = expr_get_value (im_ptr->val, &ptr->disp);
if(im_ptr->len > im_len)
Warning(WARN_VALUE_EXCEEDS_BOUNDS, (char *)NULL, "word");
ptr->len = im_len;
if(!ptr)
ptr = &im_static;
- ptr->val = int_val;
+ /* FIXME: this will leak expr's if static is used */
+ ptr->val = expr_new_ident(EXPR_NUM, int_val);
if((int_val & 0xFF) == int_val)
ptr->len = 1;
return ptr;
}
+immval *ConvertExprToImm(immval *ptr, expr *expr_ptr)
+{
+ if(!ptr)
+ ptr = &im_static;
+
+ ptr->val = expr_ptr;
+
+ ptr->isrel = 0;
+ ptr->isneg = 0;
+
+ return ptr;
+}
+
void SetEASegment(effaddr *ptr, unsigned char segment)
{
if(!ptr)
(unsigned int)bc->data.insn.ea.valid_sib,
(unsigned int)bc->data.insn.ea.need_sib);
printf("Immediate/Relative Value:\n");
- printf(" Val=%lx\n", bc->data.insn.imm.val);
+ printf(" Val=");
+ expr_print(bc->data.insn.imm.val);
+ printf("\n");
printf(" Len=%u, IsRel=%u, IsNeg=%u\n",
(unsigned int)bc->data.insn.imm.len,
(unsigned int)bc->data.insn.imm.isrel,
-/* $Id: bytecode.h,v 1.8 2001/06/28 21:22:01 peter Exp $
+/* $Id: bytecode.h,v 1.9 2001/07/05 08:37:59 mu Exp $
* Bytecode utility functions header file
*
* Copyright (C) 2001 Peter Johnson
} effaddr;
typedef struct immval_s {
- unsigned long val;
+ struct expr_s *val;
unsigned char len; /* length of val (in bytes), 0 if none */
unsigned char isrel;
-/* $Id: expr.c,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: expr.c,v 1.2 2001/07/05 08:37:59 mu Exp $
* Expression handling
*
* Copyright (C) 2001 Michael Urman
return simplified;
}
+
+int expr_get_value (expr *e, unsigned long *retval)
+{
+ while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+ && expr_simplify (e));
+
+ if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+ {
+ *retval = e->right.num;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+void expr_print (expr *e)
+{
+ if (e->op != EXPR_IDENT) {
+ switch (e->ltype) {
+ case EXPR_NUM: printf ("%d", e->left.num); break;
+ case EXPR_SYM: printf ("%s", e->left.sym->name); break;
+ case EXPR_EXPR: printf ("("); expr_print (e->left.expr); printf(")");
+ case EXPR_NONE: break;
+ }
+ }
+ switch (e->op) {
+ case EXPR_ADD: printf ("+"); break;
+ case EXPR_SUB: printf ("-"); break;
+ case EXPR_MUL: printf ("*"); break;
+ case EXPR_DIV: printf ("/"); break;
+ case EXPR_MOD: printf ("%"); break;
+ case EXPR_NEG: printf ("-"); break;
+ case EXPR_NOT: printf ("~"); break;
+ case EXPR_OR: printf ("|"); break;
+ case EXPR_AND: printf ("&"); break;
+ case EXPR_XOR: printf ("^"); break;
+ case EXPR_SHL: printf ("<<"); break;
+ case EXPR_SHR: printf (">>"); break;
+ case EXPR_LOR: printf ("||"); break;
+ case EXPR_LAND: printf ("&&"); break;
+ case EXPR_LNOT: printf ("!"); break;
+ case EXPR_LT: printf ("<"); break;
+ case EXPR_GT: printf (">"); break;
+ case EXPR_LE: printf ("<="); break;
+ case EXPR_GE: printf (">="); break;
+ case EXPR_NE: printf ("!="); break;
+ case EXPR_IDENT: break;
+ }
+ switch (e->rtype) {
+ case EXPR_NUM: printf ("%d", e->right.num); break;
+ case EXPR_SYM: printf ("%s", e->right.sym->name); break;
+ case EXPR_EXPR: printf ("("); expr_print (e->right.expr); printf(")");
+ case EXPR_NONE: break;
+ }
+}
-/* $Id: expr.h,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: expr.h,v 1.2 2001/07/05 08:37:59 mu Exp $
* Expression handling header file
*
* Copyright (C) 2001 Michael Urman
typedef union expritem_u {
struct symrec_s *sym;
struct expr_s *expr;
- int num;
+ unsigned long num;
} ExprItem;
typedef struct expr_s {
} expr;
expr *expr_new (ExprType, ExprItem, ExprOp, ExprType, ExprItem);
+/*expr *expr_new_tree (ExprItem, ExprOp, ExprItem);
+expr *expr_new_branch (ExprOp, ExprItem);
+expr *expr_new_ident (ExprType, ExprItem);*/
+#define expr_new_tree(l,o,r) \
+ expr_new (EXPR_EXPR, (ExprItem)(l), (ExprOp)(o), EXPR_EXPR, (ExprItem)(r))
+#define expr_new_branch(o,r) \
+ expr_new (EXPR_NONE, (ExprItem)0UL, (ExprOp)(o), EXPR_EXPR, (ExprItem)(r))
+#define expr_new_ident(t,r) \
+ expr_new (EXPR_NONE, (ExprItem)0UL, EXPR_IDENT, (ExprType)(t), (ExprItem)(r))
int expr_simplify (expr *);
+void expr_print (expr *);
+
+/* get the value if possible. return value is IF POSSIBLE, not the val */
+int expr_get_value (expr *, unsigned long *);
+
#endif
-/* $Id: expr.c,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: expr.c,v 1.2 2001/07/05 08:37:59 mu Exp $
* Expression handling
*
* Copyright (C) 2001 Michael Urman
return simplified;
}
+
+int expr_get_value (expr *e, unsigned long *retval)
+{
+ while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+ && expr_simplify (e));
+
+ if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+ {
+ *retval = e->right.num;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+void expr_print (expr *e)
+{
+ if (e->op != EXPR_IDENT) {
+ switch (e->ltype) {
+ case EXPR_NUM: printf ("%d", e->left.num); break;
+ case EXPR_SYM: printf ("%s", e->left.sym->name); break;
+ case EXPR_EXPR: printf ("("); expr_print (e->left.expr); printf(")");
+ case EXPR_NONE: break;
+ }
+ }
+ switch (e->op) {
+ case EXPR_ADD: printf ("+"); break;
+ case EXPR_SUB: printf ("-"); break;
+ case EXPR_MUL: printf ("*"); break;
+ case EXPR_DIV: printf ("/"); break;
+ case EXPR_MOD: printf ("%"); break;
+ case EXPR_NEG: printf ("-"); break;
+ case EXPR_NOT: printf ("~"); break;
+ case EXPR_OR: printf ("|"); break;
+ case EXPR_AND: printf ("&"); break;
+ case EXPR_XOR: printf ("^"); break;
+ case EXPR_SHL: printf ("<<"); break;
+ case EXPR_SHR: printf (">>"); break;
+ case EXPR_LOR: printf ("||"); break;
+ case EXPR_LAND: printf ("&&"); break;
+ case EXPR_LNOT: printf ("!"); break;
+ case EXPR_LT: printf ("<"); break;
+ case EXPR_GT: printf (">"); break;
+ case EXPR_LE: printf ("<="); break;
+ case EXPR_GE: printf (">="); break;
+ case EXPR_NE: printf ("!="); break;
+ case EXPR_IDENT: break;
+ }
+ switch (e->rtype) {
+ case EXPR_NUM: printf ("%d", e->right.num); break;
+ case EXPR_SYM: printf ("%s", e->right.sym->name); break;
+ case EXPR_EXPR: printf ("("); expr_print (e->right.expr); printf(")");
+ case EXPR_NONE: break;
+ }
+}
-/* $Id: x86expr.c,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: x86expr.c,v 1.2 2001/07/05 08:37:59 mu Exp $
* Expression handling
*
* Copyright (C) 2001 Michael Urman
return simplified;
}
+
+int expr_get_value (expr *e, unsigned long *retval)
+{
+ while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+ && expr_simplify (e));
+
+ if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+ {
+ *retval = e->right.num;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+void expr_print (expr *e)
+{
+ if (e->op != EXPR_IDENT) {
+ switch (e->ltype) {
+ case EXPR_NUM: printf ("%d", e->left.num); break;
+ case EXPR_SYM: printf ("%s", e->left.sym->name); break;
+ case EXPR_EXPR: printf ("("); expr_print (e->left.expr); printf(")");
+ case EXPR_NONE: break;
+ }
+ }
+ switch (e->op) {
+ case EXPR_ADD: printf ("+"); break;
+ case EXPR_SUB: printf ("-"); break;
+ case EXPR_MUL: printf ("*"); break;
+ case EXPR_DIV: printf ("/"); break;
+ case EXPR_MOD: printf ("%"); break;
+ case EXPR_NEG: printf ("-"); break;
+ case EXPR_NOT: printf ("~"); break;
+ case EXPR_OR: printf ("|"); break;
+ case EXPR_AND: printf ("&"); break;
+ case EXPR_XOR: printf ("^"); break;
+ case EXPR_SHL: printf ("<<"); break;
+ case EXPR_SHR: printf (">>"); break;
+ case EXPR_LOR: printf ("||"); break;
+ case EXPR_LAND: printf ("&&"); break;
+ case EXPR_LNOT: printf ("!"); break;
+ case EXPR_LT: printf ("<"); break;
+ case EXPR_GT: printf (">"); break;
+ case EXPR_LE: printf ("<="); break;
+ case EXPR_GE: printf (">="); break;
+ case EXPR_NE: printf ("!="); break;
+ case EXPR_IDENT: break;
+ }
+ switch (e->rtype) {
+ case EXPR_NUM: printf ("%d", e->right.num); break;
+ case EXPR_SYM: printf ("%s", e->right.sym->name); break;
+ case EXPR_EXPR: printf ("("); expr_print (e->right.expr); printf(")");
+ case EXPR_NONE: break;
+ }
+}
-/* $Id: bison.y.in,v 1.15 2001/07/05 07:21:35 peter Exp $
+/* $Id: bison.y.in,v 1.16 2001/07/05 08:37:59 mu Exp $
* Main bison parser
*
* Copyright (C) 2001 Peter Johnson, Michael Urman
#include "globals.h"
#include "bytecode.h"
#include "errwarn.h"
+#include "expr.h"
#define YYDEBUG 1
} syminfo;
unsigned char groupdata[3];
effaddr ea_val;
+ expr *exp;
immval im_val;
bytecode bc;
}
%type <ea_val> mem8 mem16 mem32 mem64 mem80 mem128 mem1632
%type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
%type <ea_val> rm8 rm16 rm32 rm64 rm128
-%type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <exp> immexp
+%type <syminfo> immlabel
%type <sym> label_id
%left '-' '+'
/* immediate values */
/* TODO: formula expansion */
-immexp: INTNUM { (void)ConvertIntToImm(&$$, $1); }
-;
-
-imm: immexp
+immexp: /*INTNUM { (void)ConvertIntToImm(&$$, $1); } */
+ INTNUM { $$ = expr_new_ident (EXPR_NUM, $1); }
+ | immlabel { $$ = expr_new_ident (EXPR_SYM, sym_use_get ($1.name, SYM_LABEL)); }
+ /*| immexp '||' immexp { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/
+ | immexp '|' immexp { $$ = expr_new_tree ($1, EXPR_OR, $3); }
+ | immexp '^' immexp { $$ = expr_new_tree ($1, EXPR_XOR, $3); }
+ /*| immexp '&&' immexp { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/
+ | immexp '&' immexp { $$ = expr_new_tree ($1, EXPR_AND, $3); }
+ /*| immexp '==' immexp { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/
+ /*| immexp '>' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+ /*| immexp '<' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+ /*| immexp '>=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+ /*| immexp '<=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+ /*| immexp '!=' immexp { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/
+ | immexp LEFT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHL, $3); }
+ | immexp RIGHT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHR, $3); }
+ | immexp '+' immexp { $$ = expr_new_tree ($1, EXPR_ADD, $3); }
+ | immexp '-' immexp { $$ = expr_new_tree ($1, EXPR_SUB, $3); }
+ | immexp '*' immexp { $$ = expr_new_tree ($1, EXPR_MUL, $3); }
+ | immexp '/' immexp { $$ = expr_new_tree ($1, EXPR_DIV, $3); }
+ | immexp '%' immexp { $$ = expr_new_tree ($1, EXPR_MOD, $3); }
+ | '-' immexp { $$ = expr_new_branch (EXPR_NEG, $2); }
+ /*| '!' immexp { $$ = expr_new_branch (EXPR_LNOT, $2); }*/
+ | '~' immexp { $$ = expr_new_branch (EXPR_NOT, $2); }
+ | '(' immexp ')' { $$ = $2; }
+;
+
+immlabel: ID | SPECIAL_ID | LOCAL_ID ;
+
+imm: immexp { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
;
/* explicit immediates */
-/* $Id: nasm-bison.y,v 1.15 2001/07/05 07:21:35 peter Exp $
+/* $Id: nasm-bison.y,v 1.16 2001/07/05 08:37:59 mu Exp $
* Main bison parser
*
* Copyright (C) 2001 Peter Johnson, Michael Urman
#include "globals.h"
#include "bytecode.h"
#include "errwarn.h"
+#include "expr.h"
#define YYDEBUG 1
} syminfo;
unsigned char groupdata[3];
effaddr ea_val;
+ expr *exp;
immval im_val;
bytecode bc;
}
%type <ea_val> mem8 mem16 mem32 mem64 mem80 mem128 mem1632
%type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
%type <ea_val> rm8 rm16 rm32 rm64 rm128
-%type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <exp> immexp
+%type <syminfo> immlabel
%type <sym> label_id
%left '-' '+'
/* immediate values */
/* TODO: formula expansion */
-immexp: INTNUM { (void)ConvertIntToImm(&$$, $1); }
-;
-
-imm: immexp
+immexp: /*INTNUM { (void)ConvertIntToImm(&$$, $1); } */
+ INTNUM { $$ = expr_new_ident (EXPR_NUM, $1); }
+ | immlabel { $$ = expr_new_ident (EXPR_SYM, sym_use_get ($1.name, SYM_LABEL)); }
+ /*| immexp '||' immexp { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/
+ | immexp '|' immexp { $$ = expr_new_tree ($1, EXPR_OR, $3); }
+ | immexp '^' immexp { $$ = expr_new_tree ($1, EXPR_XOR, $3); }
+ /*| immexp '&&' immexp { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/
+ | immexp '&' immexp { $$ = expr_new_tree ($1, EXPR_AND, $3); }
+ /*| immexp '==' immexp { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/
+ /*| immexp '>' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+ /*| immexp '<' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+ /*| immexp '>=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+ /*| immexp '<=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+ /*| immexp '!=' immexp { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/
+ | immexp LEFT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHL, $3); }
+ | immexp RIGHT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHR, $3); }
+ | immexp '+' immexp { $$ = expr_new_tree ($1, EXPR_ADD, $3); }
+ | immexp '-' immexp { $$ = expr_new_tree ($1, EXPR_SUB, $3); }
+ | immexp '*' immexp { $$ = expr_new_tree ($1, EXPR_MUL, $3); }
+ | immexp '/' immexp { $$ = expr_new_tree ($1, EXPR_DIV, $3); }
+ | immexp '%' immexp { $$ = expr_new_tree ($1, EXPR_MOD, $3); }
+ | '-' immexp { $$ = expr_new_branch (EXPR_NEG, $2); }
+ /*| '!' immexp { $$ = expr_new_branch (EXPR_LNOT, $2); }*/
+ | '~' immexp { $$ = expr_new_branch (EXPR_NOT, $2); }
+ | '(' immexp ')' { $$ = $2; }
+;
+
+immlabel: ID | SPECIAL_ID | LOCAL_ID ;
+
+imm: immexp { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
;
/* explicit immediates */
-/* $Id: token.l.in,v 1.8 2001/06/29 05:11:40 peter Exp $
+/* $Id: token.l.in,v 1.9 2001/07/05 08:37:59 mu Exp $
* Main lexer
*
* Copyright (C) 2001 Peter Johnson
#include "symrec.h"
#include "bytecode.h"
#include "errwarn.h"
+#include "expr.h"
#include "bison.h"
%}
-/* $Id: expr.c,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: expr.c,v 1.2 2001/07/05 08:37:59 mu Exp $
* Expression handling
*
* Copyright (C) 2001 Michael Urman
return simplified;
}
+
+int expr_get_value (expr *e, unsigned long *retval)
+{
+ while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+ && expr_simplify (e));
+
+ if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+ {
+ *retval = e->right.num;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+void expr_print (expr *e)
+{
+ if (e->op != EXPR_IDENT) {
+ switch (e->ltype) {
+ case EXPR_NUM: printf ("%d", e->left.num); break;
+ case EXPR_SYM: printf ("%s", e->left.sym->name); break;
+ case EXPR_EXPR: printf ("("); expr_print (e->left.expr); printf(")");
+ case EXPR_NONE: break;
+ }
+ }
+ switch (e->op) {
+ case EXPR_ADD: printf ("+"); break;
+ case EXPR_SUB: printf ("-"); break;
+ case EXPR_MUL: printf ("*"); break;
+ case EXPR_DIV: printf ("/"); break;
+ case EXPR_MOD: printf ("%"); break;
+ case EXPR_NEG: printf ("-"); break;
+ case EXPR_NOT: printf ("~"); break;
+ case EXPR_OR: printf ("|"); break;
+ case EXPR_AND: printf ("&"); break;
+ case EXPR_XOR: printf ("^"); break;
+ case EXPR_SHL: printf ("<<"); break;
+ case EXPR_SHR: printf (">>"); break;
+ case EXPR_LOR: printf ("||"); break;
+ case EXPR_LAND: printf ("&&"); break;
+ case EXPR_LNOT: printf ("!"); break;
+ case EXPR_LT: printf ("<"); break;
+ case EXPR_GT: printf (">"); break;
+ case EXPR_LE: printf ("<="); break;
+ case EXPR_GE: printf (">="); break;
+ case EXPR_NE: printf ("!="); break;
+ case EXPR_IDENT: break;
+ }
+ switch (e->rtype) {
+ case EXPR_NUM: printf ("%d", e->right.num); break;
+ case EXPR_SYM: printf ("%s", e->right.sym->name); break;
+ case EXPR_EXPR: printf ("("); expr_print (e->right.expr); printf(")");
+ case EXPR_NONE: break;
+ }
+}
-/* $Id: x86expr.c,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: x86expr.c,v 1.2 2001/07/05 08:37:59 mu Exp $
* Expression handling
*
* Copyright (C) 2001 Michael Urman
return simplified;
}
+
+int expr_get_value (expr *e, unsigned long *retval)
+{
+ while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+ && expr_simplify (e));
+
+ if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+ {
+ *retval = e->right.num;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+void expr_print (expr *e)
+{
+ if (e->op != EXPR_IDENT) {
+ switch (e->ltype) {
+ case EXPR_NUM: printf ("%d", e->left.num); break;
+ case EXPR_SYM: printf ("%s", e->left.sym->name); break;
+ case EXPR_EXPR: printf ("("); expr_print (e->left.expr); printf(")");
+ case EXPR_NONE: break;
+ }
+ }
+ switch (e->op) {
+ case EXPR_ADD: printf ("+"); break;
+ case EXPR_SUB: printf ("-"); break;
+ case EXPR_MUL: printf ("*"); break;
+ case EXPR_DIV: printf ("/"); break;
+ case EXPR_MOD: printf ("%"); break;
+ case EXPR_NEG: printf ("-"); break;
+ case EXPR_NOT: printf ("~"); break;
+ case EXPR_OR: printf ("|"); break;
+ case EXPR_AND: printf ("&"); break;
+ case EXPR_XOR: printf ("^"); break;
+ case EXPR_SHL: printf ("<<"); break;
+ case EXPR_SHR: printf (">>"); break;
+ case EXPR_LOR: printf ("||"); break;
+ case EXPR_LAND: printf ("&&"); break;
+ case EXPR_LNOT: printf ("!"); break;
+ case EXPR_LT: printf ("<"); break;
+ case EXPR_GT: printf (">"); break;
+ case EXPR_LE: printf ("<="); break;
+ case EXPR_GE: printf (">="); break;
+ case EXPR_NE: printf ("!="); break;
+ case EXPR_IDENT: break;
+ }
+ switch (e->rtype) {
+ case EXPR_NUM: printf ("%d", e->right.num); break;
+ case EXPR_SYM: printf ("%s", e->right.sym->name); break;
+ case EXPR_EXPR: printf ("("); expr_print (e->right.expr); printf(")");
+ case EXPR_NONE: break;
+ }
+}
-/* $Id: bison.y.in,v 1.15 2001/07/05 07:21:35 peter Exp $
+/* $Id: bison.y.in,v 1.16 2001/07/05 08:37:59 mu Exp $
* Main bison parser
*
* Copyright (C) 2001 Peter Johnson, Michael Urman
#include "globals.h"
#include "bytecode.h"
#include "errwarn.h"
+#include "expr.h"
#define YYDEBUG 1
} syminfo;
unsigned char groupdata[3];
effaddr ea_val;
+ expr *exp;
immval im_val;
bytecode bc;
}
%type <ea_val> mem8 mem16 mem32 mem64 mem80 mem128 mem1632
%type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
%type <ea_val> rm8 rm16 rm32 rm64 rm128
-%type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <exp> immexp
+%type <syminfo> immlabel
%type <sym> label_id
%left '-' '+'
/* immediate values */
/* TODO: formula expansion */
-immexp: INTNUM { (void)ConvertIntToImm(&$$, $1); }
-;
-
-imm: immexp
+immexp: /*INTNUM { (void)ConvertIntToImm(&$$, $1); } */
+ INTNUM { $$ = expr_new_ident (EXPR_NUM, $1); }
+ | immlabel { $$ = expr_new_ident (EXPR_SYM, sym_use_get ($1.name, SYM_LABEL)); }
+ /*| immexp '||' immexp { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/
+ | immexp '|' immexp { $$ = expr_new_tree ($1, EXPR_OR, $3); }
+ | immexp '^' immexp { $$ = expr_new_tree ($1, EXPR_XOR, $3); }
+ /*| immexp '&&' immexp { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/
+ | immexp '&' immexp { $$ = expr_new_tree ($1, EXPR_AND, $3); }
+ /*| immexp '==' immexp { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/
+ /*| immexp '>' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+ /*| immexp '<' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+ /*| immexp '>=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+ /*| immexp '<=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+ /*| immexp '!=' immexp { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/
+ | immexp LEFT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHL, $3); }
+ | immexp RIGHT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHR, $3); }
+ | immexp '+' immexp { $$ = expr_new_tree ($1, EXPR_ADD, $3); }
+ | immexp '-' immexp { $$ = expr_new_tree ($1, EXPR_SUB, $3); }
+ | immexp '*' immexp { $$ = expr_new_tree ($1, EXPR_MUL, $3); }
+ | immexp '/' immexp { $$ = expr_new_tree ($1, EXPR_DIV, $3); }
+ | immexp '%' immexp { $$ = expr_new_tree ($1, EXPR_MOD, $3); }
+ | '-' immexp { $$ = expr_new_branch (EXPR_NEG, $2); }
+ /*| '!' immexp { $$ = expr_new_branch (EXPR_LNOT, $2); }*/
+ | '~' immexp { $$ = expr_new_branch (EXPR_NOT, $2); }
+ | '(' immexp ')' { $$ = $2; }
+;
+
+immlabel: ID | SPECIAL_ID | LOCAL_ID ;
+
+imm: immexp { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
;
/* explicit immediates */
-/* $Id: bytecode.c,v 1.8 2001/05/30 07:41:03 peter Exp $
+/* $Id: bytecode.c,v 1.9 2001/07/05 08:37:59 mu Exp $
* Bytecode utility functions
*
* Copyright (C) 2001 Peter Johnson
#include "globals.h"
#include "bytecode.h"
#include "errwarn.h"
+#include "expr.h"
static effaddr eff_static;
static immval im_static;
effaddr *ConvertImmToEA(effaddr *ptr, immval *im_ptr, unsigned char im_len)
{
+ int gotexprval;
if(!ptr)
ptr = &eff_static;
- ptr->disp = im_ptr->val;
+ /* FIXME: warn when gotexprval is 0, and/or die */
+ gotexprval = expr_get_value (im_ptr->val, &ptr->disp);
if(im_ptr->len > im_len)
Warning(WARN_VALUE_EXCEEDS_BOUNDS, (char *)NULL, "word");
ptr->len = im_len;
if(!ptr)
ptr = &im_static;
- ptr->val = int_val;
+ /* FIXME: this will leak expr's if static is used */
+ ptr->val = expr_new_ident(EXPR_NUM, int_val);
if((int_val & 0xFF) == int_val)
ptr->len = 1;
return ptr;
}
+immval *ConvertExprToImm(immval *ptr, expr *expr_ptr)
+{
+ if(!ptr)
+ ptr = &im_static;
+
+ ptr->val = expr_ptr;
+
+ ptr->isrel = 0;
+ ptr->isneg = 0;
+
+ return ptr;
+}
+
void SetEASegment(effaddr *ptr, unsigned char segment)
{
if(!ptr)
(unsigned int)bc->data.insn.ea.valid_sib,
(unsigned int)bc->data.insn.ea.need_sib);
printf("Immediate/Relative Value:\n");
- printf(" Val=%lx\n", bc->data.insn.imm.val);
+ printf(" Val=");
+ expr_print(bc->data.insn.imm.val);
+ printf("\n");
printf(" Len=%u, IsRel=%u, IsNeg=%u\n",
(unsigned int)bc->data.insn.imm.len,
(unsigned int)bc->data.insn.imm.isrel,
-/* $Id: bytecode.h,v 1.8 2001/06/28 21:22:01 peter Exp $
+/* $Id: bytecode.h,v 1.9 2001/07/05 08:37:59 mu Exp $
* Bytecode utility functions header file
*
* Copyright (C) 2001 Peter Johnson
} effaddr;
typedef struct immval_s {
- unsigned long val;
+ struct expr_s *val;
unsigned char len; /* length of val (in bytes), 0 if none */
unsigned char isrel;
-/* $Id: expr.c,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: expr.c,v 1.2 2001/07/05 08:37:59 mu Exp $
* Expression handling
*
* Copyright (C) 2001 Michael Urman
return simplified;
}
+
+int expr_get_value (expr *e, unsigned long *retval)
+{
+ while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+ && expr_simplify (e));
+
+ if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+ {
+ *retval = e->right.num;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+void expr_print (expr *e)
+{
+ if (e->op != EXPR_IDENT) {
+ switch (e->ltype) {
+ case EXPR_NUM: printf ("%d", e->left.num); break;
+ case EXPR_SYM: printf ("%s", e->left.sym->name); break;
+ case EXPR_EXPR: printf ("("); expr_print (e->left.expr); printf(")");
+ case EXPR_NONE: break;
+ }
+ }
+ switch (e->op) {
+ case EXPR_ADD: printf ("+"); break;
+ case EXPR_SUB: printf ("-"); break;
+ case EXPR_MUL: printf ("*"); break;
+ case EXPR_DIV: printf ("/"); break;
+ case EXPR_MOD: printf ("%"); break;
+ case EXPR_NEG: printf ("-"); break;
+ case EXPR_NOT: printf ("~"); break;
+ case EXPR_OR: printf ("|"); break;
+ case EXPR_AND: printf ("&"); break;
+ case EXPR_XOR: printf ("^"); break;
+ case EXPR_SHL: printf ("<<"); break;
+ case EXPR_SHR: printf (">>"); break;
+ case EXPR_LOR: printf ("||"); break;
+ case EXPR_LAND: printf ("&&"); break;
+ case EXPR_LNOT: printf ("!"); break;
+ case EXPR_LT: printf ("<"); break;
+ case EXPR_GT: printf (">"); break;
+ case EXPR_LE: printf ("<="); break;
+ case EXPR_GE: printf (">="); break;
+ case EXPR_NE: printf ("!="); break;
+ case EXPR_IDENT: break;
+ }
+ switch (e->rtype) {
+ case EXPR_NUM: printf ("%d", e->right.num); break;
+ case EXPR_SYM: printf ("%s", e->right.sym->name); break;
+ case EXPR_EXPR: printf ("("); expr_print (e->right.expr); printf(")");
+ case EXPR_NONE: break;
+ }
+}
-/* $Id: expr.h,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: expr.h,v 1.2 2001/07/05 08:37:59 mu Exp $
* Expression handling header file
*
* Copyright (C) 2001 Michael Urman
typedef union expritem_u {
struct symrec_s *sym;
struct expr_s *expr;
- int num;
+ unsigned long num;
} ExprItem;
typedef struct expr_s {
} expr;
expr *expr_new (ExprType, ExprItem, ExprOp, ExprType, ExprItem);
+/*expr *expr_new_tree (ExprItem, ExprOp, ExprItem);
+expr *expr_new_branch (ExprOp, ExprItem);
+expr *expr_new_ident (ExprType, ExprItem);*/
+#define expr_new_tree(l,o,r) \
+ expr_new (EXPR_EXPR, (ExprItem)(l), (ExprOp)(o), EXPR_EXPR, (ExprItem)(r))
+#define expr_new_branch(o,r) \
+ expr_new (EXPR_NONE, (ExprItem)0UL, (ExprOp)(o), EXPR_EXPR, (ExprItem)(r))
+#define expr_new_ident(t,r) \
+ expr_new (EXPR_NONE, (ExprItem)0UL, EXPR_IDENT, (ExprType)(t), (ExprItem)(r))
int expr_simplify (expr *);
+void expr_print (expr *);
+
+/* get the value if possible. return value is IF POSSIBLE, not the val */
+int expr_get_value (expr *, unsigned long *);
+
#endif
-/* $Id: bison.y.in,v 1.15 2001/07/05 07:21:35 peter Exp $
+/* $Id: bison.y.in,v 1.16 2001/07/05 08:37:59 mu Exp $
* Main bison parser
*
* Copyright (C) 2001 Peter Johnson, Michael Urman
#include "globals.h"
#include "bytecode.h"
#include "errwarn.h"
+#include "expr.h"
#define YYDEBUG 1
} syminfo;
unsigned char groupdata[3];
effaddr ea_val;
+ expr *exp;
immval im_val;
bytecode bc;
}
%type <ea_val> mem8 mem16 mem32 mem64 mem80 mem128 mem1632
%type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
%type <ea_val> rm8 rm16 rm32 rm64 rm128
-%type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <exp> immexp
+%type <syminfo> immlabel
%type <sym> label_id
%left '-' '+'
/* immediate values */
/* TODO: formula expansion */
-immexp: INTNUM { (void)ConvertIntToImm(&$$, $1); }
-;
-
-imm: immexp
+immexp: /*INTNUM { (void)ConvertIntToImm(&$$, $1); } */
+ INTNUM { $$ = expr_new_ident (EXPR_NUM, $1); }
+ | immlabel { $$ = expr_new_ident (EXPR_SYM, sym_use_get ($1.name, SYM_LABEL)); }
+ /*| immexp '||' immexp { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/
+ | immexp '|' immexp { $$ = expr_new_tree ($1, EXPR_OR, $3); }
+ | immexp '^' immexp { $$ = expr_new_tree ($1, EXPR_XOR, $3); }
+ /*| immexp '&&' immexp { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/
+ | immexp '&' immexp { $$ = expr_new_tree ($1, EXPR_AND, $3); }
+ /*| immexp '==' immexp { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/
+ /*| immexp '>' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+ /*| immexp '<' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+ /*| immexp '>=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+ /*| immexp '<=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+ /*| immexp '!=' immexp { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/
+ | immexp LEFT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHL, $3); }
+ | immexp RIGHT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHR, $3); }
+ | immexp '+' immexp { $$ = expr_new_tree ($1, EXPR_ADD, $3); }
+ | immexp '-' immexp { $$ = expr_new_tree ($1, EXPR_SUB, $3); }
+ | immexp '*' immexp { $$ = expr_new_tree ($1, EXPR_MUL, $3); }
+ | immexp '/' immexp { $$ = expr_new_tree ($1, EXPR_DIV, $3); }
+ | immexp '%' immexp { $$ = expr_new_tree ($1, EXPR_MOD, $3); }
+ | '-' immexp { $$ = expr_new_branch (EXPR_NEG, $2); }
+ /*| '!' immexp { $$ = expr_new_branch (EXPR_LNOT, $2); }*/
+ | '~' immexp { $$ = expr_new_branch (EXPR_NOT, $2); }
+ | '(' immexp ')' { $$ = $2; }
+;
+
+immlabel: ID | SPECIAL_ID | LOCAL_ID ;
+
+imm: immexp { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
;
/* explicit immediates */
-/* $Id: nasm-bison.y,v 1.15 2001/07/05 07:21:35 peter Exp $
+/* $Id: nasm-bison.y,v 1.16 2001/07/05 08:37:59 mu Exp $
* Main bison parser
*
* Copyright (C) 2001 Peter Johnson, Michael Urman
#include "globals.h"
#include "bytecode.h"
#include "errwarn.h"
+#include "expr.h"
#define YYDEBUG 1
} syminfo;
unsigned char groupdata[3];
effaddr ea_val;
+ expr *exp;
immval im_val;
bytecode bc;
}
%type <ea_val> mem8 mem16 mem32 mem64 mem80 mem128 mem1632
%type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
%type <ea_val> rm8 rm16 rm32 rm64 rm128
-%type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <exp> immexp
+%type <syminfo> immlabel
%type <sym> label_id
%left '-' '+'
/* immediate values */
/* TODO: formula expansion */
-immexp: INTNUM { (void)ConvertIntToImm(&$$, $1); }
-;
-
-imm: immexp
+immexp: /*INTNUM { (void)ConvertIntToImm(&$$, $1); } */
+ INTNUM { $$ = expr_new_ident (EXPR_NUM, $1); }
+ | immlabel { $$ = expr_new_ident (EXPR_SYM, sym_use_get ($1.name, SYM_LABEL)); }
+ /*| immexp '||' immexp { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/
+ | immexp '|' immexp { $$ = expr_new_tree ($1, EXPR_OR, $3); }
+ | immexp '^' immexp { $$ = expr_new_tree ($1, EXPR_XOR, $3); }
+ /*| immexp '&&' immexp { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/
+ | immexp '&' immexp { $$ = expr_new_tree ($1, EXPR_AND, $3); }
+ /*| immexp '==' immexp { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/
+ /*| immexp '>' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+ /*| immexp '<' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+ /*| immexp '>=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+ /*| immexp '<=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+ /*| immexp '!=' immexp { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/
+ | immexp LEFT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHL, $3); }
+ | immexp RIGHT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHR, $3); }
+ | immexp '+' immexp { $$ = expr_new_tree ($1, EXPR_ADD, $3); }
+ | immexp '-' immexp { $$ = expr_new_tree ($1, EXPR_SUB, $3); }
+ | immexp '*' immexp { $$ = expr_new_tree ($1, EXPR_MUL, $3); }
+ | immexp '/' immexp { $$ = expr_new_tree ($1, EXPR_DIV, $3); }
+ | immexp '%' immexp { $$ = expr_new_tree ($1, EXPR_MOD, $3); }
+ | '-' immexp { $$ = expr_new_branch (EXPR_NEG, $2); }
+ /*| '!' immexp { $$ = expr_new_branch (EXPR_LNOT, $2); }*/
+ | '~' immexp { $$ = expr_new_branch (EXPR_NOT, $2); }
+ | '(' immexp ')' { $$ = $2; }
+;
+
+immlabel: ID | SPECIAL_ID | LOCAL_ID ;
+
+imm: immexp { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
;
/* explicit immediates */
-/* $Id: token.l.in,v 1.8 2001/06/29 05:11:40 peter Exp $
+/* $Id: token.l.in,v 1.9 2001/07/05 08:37:59 mu Exp $
* Main lexer
*
* Copyright (C) 2001 Peter Johnson
#include "symrec.h"
#include "bytecode.h"
#include "errwarn.h"
+#include "expr.h"
#include "bison.h"
%}
-/* $Id: token.l.in,v 1.8 2001/06/29 05:11:40 peter Exp $
+/* $Id: token.l.in,v 1.9 2001/07/05 08:37:59 mu Exp $
* Main lexer
*
* Copyright (C) 2001 Peter Johnson
#include "symrec.h"
#include "bytecode.h"
#include "errwarn.h"
+#include "expr.h"
#include "bison.h"
%}