From: Cyrill G. <gor...@gm...> - 2009-10-08 16:20:20
|
[H. Peter Anvin - Thu, Oct 08, 2009 at 08:12:05AM -0700] | On 10/08/2009 08:02 AM, Cyrill Gorcunov wrote: | > | > ok, something like this? | > | | Yes, but rather than changing int32_t to uint32_t, we should change it | to opflags_t... we already have the typedef, it's just not widely used. | | > | > +#define is_class(class, op) (((op) & class) == class) | > + | | We might as well use the form that we have been using before, that also | avoids using the arguments to the macro more than one. We should | probably add explicit casts, too: | | #define is_class(class, op) (!((opflags_t)(class) & ~(opflags_t)(op))) | | -hpa | | -- | H. Peter Anvin, Intel Open Source Technology Center | I work for Intel. I don't speak on their behalf. | ok, done -- Cyrill --- From: Cyrill Gorcunov <gor...@gm...> Date: Thu, 8 Oct 2009 20:17:43 +0400 Subject: [PATCH] introduce is_class macro Signed-off-by: Cyrill Gorcunov <gor...@gm...> --- assemble.c | 8 ++++---- nasm.h | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/assemble.c b/assemble.c index 8f13793..24e78d6 100644 --- a/assemble.c +++ b/assemble.c @@ -2027,7 +2027,7 @@ static enum match_result find_match(const struct itemplate **tempp, * never try to fuzzy-match on them. This also resolves the case * when we have e.g. "xmmrm128" in two different positions. */ - if ((REGISTER & ~instruction->oprs[i].type) == 0) + if (is_class(REGISTER, instruction->oprs[i].type)) continue; /* This tests if xsizeflags[i] has more than one bit set */ @@ -2141,7 +2141,7 @@ static enum match_result matches(const struct itemplate *itemp, * Check that the operand flags all match up */ for (i = 0; i < itemp->operands; i++) { - int32_t type = instruction->oprs[i].type; + uint32_t type = instruction->oprs[i].type; if (!(type & SIZE_MASK)) type |= size[i]; @@ -2155,7 +2155,7 @@ static enum match_result matches(const struct itemplate *itemp, ((itemp->opd[i] ^ type) & SIZE_MASK))) { if ((itemp->opd[i] & ~type & ~SIZE_MASK) || (type & SIZE_MASK)) { return MERR_INVALOP; - } else if ((REGISTER & type) != REGISTER) { + } else if (!is_class(REGISTER, type)) { /* * Note: we don't honor extrinsic operand sizes for registers, * so "missing operand size" for a register should be @@ -2224,7 +2224,7 @@ static ea *process_ea(operand * input, ea * output, int bits, /* REX flags for the rfield operand */ output->rex |= rexflags(rfield, rflags, REX_R|REX_P|REX_W|REX_H); - if (!(REGISTER & ~input->type)) { /* register direct */ + if (is_class(REGISTER, input->type)) { /* register direct */ int i; int32_t f; diff --git a/nasm.h b/nasm.h index 9e233fc..7fb2896 100644 --- a/nasm.h +++ b/nasm.h @@ -539,6 +539,8 @@ typedef uint32_t opflags_t; #define MEMORY 0x0000c000U #define REGMEM 0x00008000U /* for r/m, ie EA, operands */ +#define is_class(class, op) (!((opflags_t)(class) & ~(opflags_t)(op))) + /* Register classes */ #define REG_EA 0x00009000U /* 'normal' reg, qualifies as EA */ #define RM_GPR 0x00208000U /* integer operand */ @@ -682,7 +684,7 @@ enum eval_hint { /* values for `hinttype' */ }; typedef struct operand { /* operand to an instruction */ - int32_t type; /* type of operand */ + opflags_t type; /* type of operand */ int disp_size; /* 0 means default; 16; 32; 64 */ enum reg_enum basereg, indexreg; /* address registers */ int scale; /* index scale */ -- 1.6.4.13.ge6580 |