diff --git a/src/x86.h b/src/x86.h new file mode 100644 index 0000000..8550f0c --- /dev/null +++ b/src/x86.h @@ -0,0 +1,35 @@ +#pragma once + +// Can expression be expressed as a single x86 operand? +#define XOP_NOT_XOP 0 +#define XOP_NOT_MEM 1 +#define XOP_MEM 2 +static inline int is_xop(AST *e) { + if(e->nodeKind == AST_EXPR_PRIMITIVE) { + return XOP_NOT_MEM; + } else if(e->nodeKind == AST_EXPR_VAR) { + return e->exprVar.thing->kind == VARTABLEENTRY_VAR ? XOP_NOT_MEM : XOP_MEM; + } else if(e->nodeKind == AST_EXPR_UNARY_OP && e->exprUnOp.operator == UNOP_DEREF && e->exprUnOp.operand->nodeKind == AST_EXPR_BINARY_OP && e->exprUnOp.operand->exprBinOp.operator == BINOP_ADD && e->exprUnOp.operand->exprBinOp.operands[0]->nodeKind == AST_EXPR_VAR && e->exprUnOp.operand->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR && e->exprUnOp.operand->exprBinOp.operands[0]->exprVar.thing->kind == VARTABLEENTRY_VAR && e->exprUnOp.operand->exprBinOp.operands[1]->exprVar.thing->kind == VARTABLEENTRY_VAR) { + return XOP_MEM; + } else if(e->nodeKind == AST_EXPR_UNARY_OP && e->exprUnOp.operator == UNOP_REF && e->exprUnOp.operand->nodeKind == AST_EXPR_VAR && e->exprUnOp.operand->exprVar.thing->kind == VARTABLEENTRY_SYMBOL) { + return XOP_NOT_MEM; + } else if(e->nodeKind == AST_EXPR_UNARY_OP && e->exprUnOp.operator == UNOP_DEREF) { + AST *c = e->exprUnOp.operand; + + if(c->nodeKind == AST_EXPR_VAR && c->exprVar.thing->kind == VARTABLEENTRY_VAR) { + return XOP_MEM; + } else if(c->nodeKind == AST_EXPR_BINARY_OP && c->exprBinOp.operator == BINOP_ADD && c->exprBinOp.operands[0]->nodeKind == AST_EXPR_UNARY_OP && c->exprBinOp.operands[0]->exprUnOp.operator == UNOP_REF && c->exprBinOp.operands[0]->exprUnOp.operand->nodeKind == AST_EXPR_VAR) { + if(c->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR) { + return XOP_MEM; + } else if(c->exprBinOp.operands[1]->nodeKind == AST_EXPR_BINARY_OP && c->exprBinOp.operands[1]->exprBinOp.operator == BINOP_MUL && c->exprBinOp.operands[1]->exprBinOp.operands[0]->nodeKind == AST_EXPR_PRIMITIVE && c->exprBinOp.operands[1]->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR) { + int scale = c->exprBinOp.operands[1]->exprBinOp.operands[0]->exprPrim.val; + + if(scale == 1 || scale == 2 || scale == 4 || scale == 8) { + return XOP_MEM; + } + } + } + } + + return XOP_NOT_XOP; +}