ref: c8eab2fc68e164fc11882859499896bbb8e76f3d
parent: b7e1cae8e53b2a4d9cbaf505927d1abdca22f13d
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Thu Jan 25 09:28:25 EST 2018
[as] Remove memory operand from operand() This patchs moves all the logic to the arch and implements the test for z80.
--- a/as/as.h
+++ b/as/as.h
@@ -141,6 +141,12 @@
struct node *right;
};
+union yylval {
+ TUINT val;
+ Symbol *sym;
+};
+
+
/* symbol.c */
extern void cleansecs(void);
extern void isecs(void);
@@ -169,11 +175,16 @@
extern Node *expr(void);
extern void deltree(Node *np);
extern Node *node(int op, Node *l, Node *r);
+extern Node *getreg(void);
+extern void regctx(void);
+extern void unexpected(void);
+extern void expect(int token);
+int next(void);
/* proc.c */
extern void iarch(void);
extern int match(Op *op, Node **args);
-extern Node *addrmode(void);
+extern Node *moperand(void);
/* ins.c */
extern char *tobytes(TUINT v, int n, int inc);
@@ -200,3 +211,6 @@
extern Symbol *linesym, *symlist;
extern char *infile;
extern int endpass;
+extern int yytoken;
+extern size_t yylen;
+extern union yylval yylval;
--- a/as/expr.c
+++ b/as/expr.c
@@ -1,4 +1,4 @@
-static char sccsid[] = "@(#) ./as/node.c";
+static char sccsid[] = "@(#) ./as/expr.c";
#include <ctype.h>
#include <limits.h>
@@ -11,16 +11,12 @@
#define NNODES 10
-union yylval {
- TUINT val;
- Symbol *sym;
-};
+int yytoken;
+size_t yylen;
+union yylval yylval;
static Alloc *arena;
-static int yytoken;
static char yytext[INTIDENTSIZ+1], *textp, *endp;
-static size_t yylen;
-static union yylval yylval;
static int regmode;
#define accept(t) (yytoken == (t) ? next() : 0)
@@ -133,10 +129,8 @@
if (l->op == NUMBER && r->op == NUMBER)
return fold(op, l, r);
- else if (l->addr == AREG && r->addr == ANUMBER)
- addr = AREG_OFF;
- else if (l->addr == AREG && l->addr != ANUMBER)
- error("incorrect operand");
+ else
+ abort();
np = node(op, l, r);
np->addr = addr;
@@ -297,7 +291,7 @@
return c;
}
-static int
+int
next(void)
{
int c;
@@ -337,13 +331,7 @@
return yytoken = c;
}
-static void
-unexpected(void)
-{
- error("unexpected '%s'", yytext);
-}
-
-static void
+void
expect(int token)
{
if (yytoken != token)
@@ -351,6 +339,13 @@
next();
}
+void
+unexpected(void)
+{
+ error("unexpected '%s'", yytext);
+}
+
+
/*************************************************************************/
/* grammar functions */
/*************************************************************************/
@@ -362,9 +357,6 @@
Node *np;
switch (yytoken) {
- case REG:
- addr = AREG;
- goto basic_atom;
case IDEN:
case NUMBER:
addr = ANUMBER;
@@ -509,35 +501,48 @@
}
Node *
+getreg(void)
+{
+ Node *np;
+
+ np = node(REG, NULL, NULL);
+ np->sym = yylval.sym;
+ np->addr = AREG;
+ expect(REG);
+ return np;
+}
+
+void
+regctx(void)
+{
+ regmode = 1;
+}
+
+Node *
operand(char **strp)
{
int imm = 0;
Node *np;
- regmode = 1;
textp = *strp;
+ regctx();
switch (next()) {
case EOS:
np = NULL;
break;
- case '(':
- next();
- np = addrmode();
- expect(')');
- break;
case REG:
- np = node(yytoken, NULL, NULL);
- np->sym = yylval.sym;
- np->addr = AREG;
- next();
+ np = getreg();
break;
case '$':
next();
imm = 1;
default:
- np = expr();
- if (imm)
+ if (!imm) {
+ np = moperand();
+ } else {
+ np = expr();
np->addr = AIMM;
+ }
}
if (yytoken != ',' && yytoken != EOS)
error("trailing characters in expression '%s'", textp);
--- a/as/target/x80/ins.c
+++ b/as/target/x80/ins.c
@@ -148,24 +148,53 @@
return *args == NULL;
}
+/*
+ * (expr) -> ADIRECT
+ * (REG) -> AINDIR
+ * (REG + expr) -> AINDEX
+ * (REG - expr) -> AINDEX
+ * expr (REG) -> AINDEX
+ */
Node *
-addrmode(void)
+moperand(void)
{
int op;
- Node *np = expr();
+ Node *np, *dir, *off, *reg;
- switch (np->addr) {
- case AREG:
- op = AINDIR;
- break;
- case AREG_OFF:
- op = AINDEX;
- break;
- case ANUMBER:
+ dir = off = reg = NULL;
+ if (yytoken == '(') {
+ regctx();
+ if (next() != REG) {
+ dir = expr();
+ } else {
+ reg = getreg();
+ switch (yytoken) {
+ case '+':
+ case '-':
+ off = expr();
+ case ')':
+ break;
+ default:
+ unexpected();
+ }
+ }
+ } else {
+ off = expr();
+ regctx();
+ expect('(');
+ reg = getreg();
+ }
+ expect(')');
+
+ if (dir) {
op = ADIRECT;
- break;
- default:
- abort();
+ np = dir;
+ } else if (off) {
+ np = node(AREG_OFF, reg, off);
+ op = AINDEX;
+ } else {
+ np = reg;
+ op = AINDIR;
}
np = node(op, np, NULL);
np->addr = op;
--- a/as/target/x86/ins.c
+++ b/as/target/x86/ins.c
@@ -38,6 +38,6 @@
}
Node *
-addrmode(void)
+moperand(void)
{
}