From: Michael Urman Date: Thu, 5 Jul 2001 08:37:59 +0000 (-0000) Subject: Long hairy integration of expression handling into the grammar. X-Git-Tag: v0.1.0~402 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=84bae30656182c2734bb5dd632a9109b82a553c5;p=yasm Long hairy integration of expression handling into the grammar. Added printing, getvalue functionality to expr.[ch] Changed immval to house an expr* instead of an unsigned long. gen_instr.pl needs to be updated for ONE cases to fix pointer compares. bison s/r conflicts still need to be handled. svn path=/trunk/yasm/; revision=109 --- diff --git a/include/bytecode.h b/include/bytecode.h index d17ec0a6..ce8ee6bd 100644 --- a/include/bytecode.h +++ b/include/bytecode.h @@ -1,4 +1,4 @@ -/* $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 @@ -38,7 +38,7 @@ typedef struct effaddr_s { } 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; diff --git a/include/expr.h b/include/expr.h index 18d6eee1..3ca1ec68 100644 --- a/include/expr.h +++ b/include/expr.h @@ -1,4 +1,4 @@ -/* $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 @@ -57,7 +57,7 @@ typedef enum { typedef union expritem_u { struct symrec_s *sym; struct expr_s *expr; - int num; + unsigned long num; } ExprItem; typedef struct expr_s { @@ -67,6 +67,20 @@ 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 diff --git a/libyasm/bytecode.c b/libyasm/bytecode.c index f9d92a01..5812dbd2 100644 --- a/libyasm/bytecode.c +++ b/libyasm/bytecode.c @@ -1,4 +1,4 @@ -/* $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 @@ -23,6 +23,7 @@ #include "globals.h" #include "bytecode.h" #include "errwarn.h" +#include "expr.h" static effaddr eff_static; static immval im_static; @@ -70,10 +71,12 @@ effaddr *ConvertRegToEA(effaddr *ptr, unsigned long reg) 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; @@ -91,7 +94,8 @@ immval *ConvertIntToImm(immval *ptr, unsigned long int_val) 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; @@ -106,6 +110,19 @@ immval *ConvertIntToImm(immval *ptr, unsigned long int_val) 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) @@ -240,7 +257,9 @@ void DebugPrintBC(bytecode *bc) (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, diff --git a/libyasm/bytecode.h b/libyasm/bytecode.h index d17ec0a6..ce8ee6bd 100644 --- a/libyasm/bytecode.h +++ b/libyasm/bytecode.h @@ -1,4 +1,4 @@ -/* $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 @@ -38,7 +38,7 @@ typedef struct effaddr_s { } 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; diff --git a/libyasm/expr.c b/libyasm/expr.c index e6210957..0d7f7221 100644 --- a/libyasm/expr.c +++ b/libyasm/expr.c @@ -1,4 +1,4 @@ -/* $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 @@ -189,3 +189,58 @@ int expr_simplify (expr *e) 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; + } +} diff --git a/libyasm/expr.h b/libyasm/expr.h index 18d6eee1..3ca1ec68 100644 --- a/libyasm/expr.h +++ b/libyasm/expr.h @@ -1,4 +1,4 @@ -/* $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 @@ -57,7 +57,7 @@ typedef enum { typedef union expritem_u { struct symrec_s *sym; struct expr_s *expr; - int num; + unsigned long num; } ExprItem; typedef struct expr_s { @@ -67,6 +67,20 @@ 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 diff --git a/modules/arch/x86/expr.c b/modules/arch/x86/expr.c index e6210957..0d7f7221 100644 --- a/modules/arch/x86/expr.c +++ b/modules/arch/x86/expr.c @@ -1,4 +1,4 @@ -/* $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 @@ -189,3 +189,58 @@ int expr_simplify (expr *e) 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; + } +} diff --git a/modules/arch/x86/x86expr.c b/modules/arch/x86/x86expr.c index f653822a..1bf3c884 100644 --- a/modules/arch/x86/x86expr.c +++ b/modules/arch/x86/x86expr.c @@ -1,4 +1,4 @@ -/* $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 @@ -189,3 +189,58 @@ int expr_simplify (expr *e) 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; + } +} diff --git a/modules/parsers/nasm/bison.y.in b/modules/parsers/nasm/bison.y.in index 72b0b96d..f1644f07 100644 --- a/modules/parsers/nasm/bison.y.in +++ b/modules/parsers/nasm/bison.y.in @@ -1,4 +1,4 @@ -/* $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 @@ -26,6 +26,7 @@ #include "globals.h" #include "bytecode.h" #include "errwarn.h" +#include "expr.h" #define YYDEBUG 1 @@ -46,6 +47,7 @@ extern void yyerror(char *); } syminfo; unsigned char groupdata[3]; effaddr ea_val; + expr *exp; immval im_val; bytecode bc; } @@ -83,7 +85,9 @@ extern void yyerror(char *); %type mem8 mem16 mem32 mem64 mem80 mem128 mem1632 %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 -%type immexp imm imm8x imm16x imm32x imm8 imm16 imm32 +%type imm imm8x imm16x imm32x imm8 imm16 imm32 +%type immexp +%type immlabel %type label_id %left '-' '+' @@ -271,10 +275,36 @@ rm128: XMMREG { (void)ConvertRegToEA(&$$, $1); } /* 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 */ diff --git a/modules/parsers/nasm/nasm-bison.y b/modules/parsers/nasm/nasm-bison.y index 7a32a80e..6c1a66bb 100644 --- a/modules/parsers/nasm/nasm-bison.y +++ b/modules/parsers/nasm/nasm-bison.y @@ -1,4 +1,4 @@ -/* $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 @@ -26,6 +26,7 @@ #include "globals.h" #include "bytecode.h" #include "errwarn.h" +#include "expr.h" #define YYDEBUG 1 @@ -46,6 +47,7 @@ extern void yyerror(char *); } syminfo; unsigned char groupdata[3]; effaddr ea_val; + expr *exp; immval im_val; bytecode bc; } @@ -83,7 +85,9 @@ extern void yyerror(char *); %type mem8 mem16 mem32 mem64 mem80 mem128 mem1632 %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 -%type immexp imm imm8x imm16x imm32x imm8 imm16 imm32 +%type imm imm8x imm16x imm32x imm8 imm16 imm32 +%type immexp +%type immlabel %type label_id %left '-' '+' @@ -271,10 +275,36 @@ rm128: XMMREG { (void)ConvertRegToEA(&$$, $1); } /* 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 */ diff --git a/modules/parsers/nasm/token.l.in b/modules/parsers/nasm/token.l.in index 4aa92c49..2a19cdc8 100644 --- a/modules/parsers/nasm/token.l.in +++ b/modules/parsers/nasm/token.l.in @@ -1,4 +1,4 @@ -/* $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 @@ -34,6 +34,7 @@ #include "symrec.h" #include "bytecode.h" #include "errwarn.h" +#include "expr.h" #include "bison.h" %} diff --git a/src/arch/x86/expr.c b/src/arch/x86/expr.c index e6210957..0d7f7221 100644 --- a/src/arch/x86/expr.c +++ b/src/arch/x86/expr.c @@ -1,4 +1,4 @@ -/* $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 @@ -189,3 +189,58 @@ int expr_simplify (expr *e) 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; + } +} diff --git a/src/arch/x86/x86expr.c b/src/arch/x86/x86expr.c index f653822a..1bf3c884 100644 --- a/src/arch/x86/x86expr.c +++ b/src/arch/x86/x86expr.c @@ -1,4 +1,4 @@ -/* $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 @@ -189,3 +189,58 @@ int expr_simplify (expr *e) 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; + } +} diff --git a/src/bison.y.in b/src/bison.y.in index 72b0b96d..f1644f07 100644 --- a/src/bison.y.in +++ b/src/bison.y.in @@ -1,4 +1,4 @@ -/* $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 @@ -26,6 +26,7 @@ #include "globals.h" #include "bytecode.h" #include "errwarn.h" +#include "expr.h" #define YYDEBUG 1 @@ -46,6 +47,7 @@ extern void yyerror(char *); } syminfo; unsigned char groupdata[3]; effaddr ea_val; + expr *exp; immval im_val; bytecode bc; } @@ -83,7 +85,9 @@ extern void yyerror(char *); %type mem8 mem16 mem32 mem64 mem80 mem128 mem1632 %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 -%type immexp imm imm8x imm16x imm32x imm8 imm16 imm32 +%type imm imm8x imm16x imm32x imm8 imm16 imm32 +%type immexp +%type immlabel %type label_id %left '-' '+' @@ -271,10 +275,36 @@ rm128: XMMREG { (void)ConvertRegToEA(&$$, $1); } /* 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 */ diff --git a/src/bytecode.c b/src/bytecode.c index f9d92a01..5812dbd2 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -1,4 +1,4 @@ -/* $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 @@ -23,6 +23,7 @@ #include "globals.h" #include "bytecode.h" #include "errwarn.h" +#include "expr.h" static effaddr eff_static; static immval im_static; @@ -70,10 +71,12 @@ effaddr *ConvertRegToEA(effaddr *ptr, unsigned long reg) 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; @@ -91,7 +94,8 @@ immval *ConvertIntToImm(immval *ptr, unsigned long int_val) 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; @@ -106,6 +110,19 @@ immval *ConvertIntToImm(immval *ptr, unsigned long int_val) 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) @@ -240,7 +257,9 @@ void DebugPrintBC(bytecode *bc) (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, diff --git a/src/bytecode.h b/src/bytecode.h index d17ec0a6..ce8ee6bd 100644 --- a/src/bytecode.h +++ b/src/bytecode.h @@ -1,4 +1,4 @@ -/* $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 @@ -38,7 +38,7 @@ typedef struct effaddr_s { } 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; diff --git a/src/expr.c b/src/expr.c index e6210957..0d7f7221 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1,4 +1,4 @@ -/* $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 @@ -189,3 +189,58 @@ int expr_simplify (expr *e) 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; + } +} diff --git a/src/expr.h b/src/expr.h index 18d6eee1..3ca1ec68 100644 --- a/src/expr.h +++ b/src/expr.h @@ -1,4 +1,4 @@ -/* $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 @@ -57,7 +57,7 @@ typedef enum { typedef union expritem_u { struct symrec_s *sym; struct expr_s *expr; - int num; + unsigned long num; } ExprItem; typedef struct expr_s { @@ -67,6 +67,20 @@ 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 diff --git a/src/parsers/nasm/bison.y.in b/src/parsers/nasm/bison.y.in index 72b0b96d..f1644f07 100644 --- a/src/parsers/nasm/bison.y.in +++ b/src/parsers/nasm/bison.y.in @@ -1,4 +1,4 @@ -/* $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 @@ -26,6 +26,7 @@ #include "globals.h" #include "bytecode.h" #include "errwarn.h" +#include "expr.h" #define YYDEBUG 1 @@ -46,6 +47,7 @@ extern void yyerror(char *); } syminfo; unsigned char groupdata[3]; effaddr ea_val; + expr *exp; immval im_val; bytecode bc; } @@ -83,7 +85,9 @@ extern void yyerror(char *); %type mem8 mem16 mem32 mem64 mem80 mem128 mem1632 %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 -%type immexp imm imm8x imm16x imm32x imm8 imm16 imm32 +%type imm imm8x imm16x imm32x imm8 imm16 imm32 +%type immexp +%type immlabel %type label_id %left '-' '+' @@ -271,10 +275,36 @@ rm128: XMMREG { (void)ConvertRegToEA(&$$, $1); } /* 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 */ diff --git a/src/parsers/nasm/nasm-bison.y b/src/parsers/nasm/nasm-bison.y index 7a32a80e..6c1a66bb 100644 --- a/src/parsers/nasm/nasm-bison.y +++ b/src/parsers/nasm/nasm-bison.y @@ -1,4 +1,4 @@ -/* $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 @@ -26,6 +26,7 @@ #include "globals.h" #include "bytecode.h" #include "errwarn.h" +#include "expr.h" #define YYDEBUG 1 @@ -46,6 +47,7 @@ extern void yyerror(char *); } syminfo; unsigned char groupdata[3]; effaddr ea_val; + expr *exp; immval im_val; bytecode bc; } @@ -83,7 +85,9 @@ extern void yyerror(char *); %type mem8 mem16 mem32 mem64 mem80 mem128 mem1632 %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 -%type immexp imm imm8x imm16x imm32x imm8 imm16 imm32 +%type imm imm8x imm16x imm32x imm8 imm16 imm32 +%type immexp +%type immlabel %type label_id %left '-' '+' @@ -271,10 +275,36 @@ rm128: XMMREG { (void)ConvertRegToEA(&$$, $1); } /* 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 */ diff --git a/src/parsers/nasm/token.l.in b/src/parsers/nasm/token.l.in index 4aa92c49..2a19cdc8 100644 --- a/src/parsers/nasm/token.l.in +++ b/src/parsers/nasm/token.l.in @@ -1,4 +1,4 @@ -/* $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 @@ -34,6 +34,7 @@ #include "symrec.h" #include "bytecode.h" #include "errwarn.h" +#include "expr.h" #include "bison.h" %} diff --git a/src/token.l.in b/src/token.l.in index 4aa92c49..2a19cdc8 100644 --- a/src/token.l.in +++ b/src/token.l.in @@ -1,4 +1,4 @@ -/* $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 @@ -34,6 +34,7 @@ #include "symrec.h" #include "bytecode.h" #include "errwarn.h" +#include "expr.h" #include "bison.h" %}