From 154e5920a1ee2c816e502b70fe0c4ab3ea6ab7c1 Mon Sep 17 00:00:00 2001 From: Victor van den Elzen Date: Wed, 25 Feb 2009 17:32:00 +0100 Subject: [PATCH] Do not confuse segmentless adresses and unknown forward references Also be optimistic with immediate forward references. --- assemble.c | 2 +- nasm.h | 2 ++ parser.c | 8 ++++++++ test/convergence.asm | 39 ++++++++++++++++++++++++++------------- 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/assemble.c b/assemble.c index 6fcb7482..d4e7f25c 100644 --- a/assemble.c +++ b/assemble.c @@ -263,7 +263,7 @@ static bool jmp_match(int32_t segment, int64_t offset, int bits, isize = calcsize(segment, offset, bits, ins, code); - if (passn == 1 && ins->oprs[0].segment == NO_SEG) + if (ins->oprs[0].opflags & OPFLAG_UNKNOWN) /* Be optimistic in pass 1 */ return true; diff --git a/nasm.h b/nasm.h index 77c6aa48..7add093a 100644 --- a/nasm.h +++ b/nasm.h @@ -654,6 +654,8 @@ typedef struct operand { /* operand to an instruction */ #define OPFLAG_FORWARD 1 /* operand is a forward reference */ #define OPFLAG_EXTERN 2 /* operand is an external reference */ +#define OPFLAG_UNKNOWN 4 /* operand is an unknown reference */ + /* (always a forward reference also) */ typedef struct extop { /* extended operand */ struct extop *next; /* linked list */ diff --git a/parser.c b/parser.c index 91b7abf5..0f640430 100644 --- a/parser.c +++ b/parser.c @@ -737,6 +737,7 @@ restart_parse: return result; } else { if (e->type == EXPR_UNKNOWN) { + result->oprs[operand].opflags |= OPFLAG_UNKNOWN; o = 0; /* doesn't matter what */ result->oprs[operand].wrt = NO_SEG; /* nor this */ result->oprs[operand].segment = NO_SEG; /* or this */ @@ -818,9 +819,16 @@ restart_parse: if (is_just_unknown(value)) { /* it's immediate but unknown */ result->oprs[operand].type |= IMMEDIATE; + result->oprs[operand].opflags |= OPFLAG_UNKNOWN; result->oprs[operand].offset = 0; /* don't care */ result->oprs[operand].segment = NO_SEG; /* don't care again */ result->oprs[operand].wrt = NO_SEG; /* still don't care */ + + if(optimizing >= 0 && !(result->oprs[operand].type & STRICT)) + { + /* Be optimistic */ + result->oprs[operand].type |= SBYTE16 | SBYTE32 | SBYTE64; + } } else if (is_reloc(value)) { /* it's immediate */ result->oprs[operand].type |= IMMEDIATE; result->oprs[operand].offset = reloc_value(value); diff --git a/test/convergence.asm b/test/convergence.asm index 02ef2e1f..d037886e 100644 --- a/test/convergence.asm +++ b/test/convergence.asm @@ -4,34 +4,47 @@ BITS 32 +; Simple jmp foo times 124 nop foo: -jmp bar -times 125 nop -bar: - -db 0 - -jmp baz -times 126 nop -baz: - +; Must start short to converge optimally jmp car times 127 nop car: +; Always near +jmp cdr +times 128 nop +cdr: + + +; Simple add eax, quux2 - quux1 quux1: times 127 nop quux2: -; currently fails - short add possible but converges to long form +; Must start short corge1: add eax, corge2 - corge1 -times 124 nop +times 127 - 3 nop corge2: -; this needs to actually *work*... + +; Simple +lea eax, [bolug2-bolug1] +bolug1: +times 127 nop +bolug2: + +; Must start short +calog1: +lea eax, [calog2-calog1] +times 127 - 3 nop +calog2: + + +; Do not confuse forward references and segmentless addresses! jmp 12345 -- 2.11.4.GIT