[Nasm-commits] [nasm:branch-0_98_24-gasalign] NASM 0.98.24p1

nasm-bot for H. Peter Anvin hpa at zytor.com
Thu Jun 4 19:56:12 PDT 2020


Commit-ID:  87054bc49bdf220f39d2eec50c03ab0629bf9342
Gitweb:     http://repo.or.cz/w/nasm.git?a=commitdiff;h=87054bc49bdf220f39d2eec50c03ab0629bf9342
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Tue, 30 Apr 2002 21:07:31 +0000
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Tue, 30 Apr 2002 21:07:31 +0000

NASM 0.98.24p1



---
 README.1st | 257 ++++++++++++++---------------------------
 nasm.c     | 378 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 nasm.h     |   2 +-
 3 files changed, 427 insertions(+), 210 deletions(-)

diff --git a/README.1st b/README.1st
index b1bf2dad..aa9557bb 100644
--- a/README.1st
+++ b/README.1st
@@ -1,187 +1,100 @@
-This is a specially patched version of NASM.  It can be used to supplement
-building of Crystal Space, the Open Source 3D Engine project.  You can find
-Crystal Space at the following locations:
-
-http://crystal.linuxgames.com/
-http://crystal.sourceforge.net/
-
-Details of changes in this version of NASM follow.
-
--*- A new keyword %xdefine and its case-insensitive counterpart %ixdefine.
-    They work almost the same way as %define and %idefine but expand
-    the definition immediately, not on the invocation. Something like a cross
-    between %define and %assign. The "x" suffix stands for "eXpand", so
-    "xdefine" can be deciphered as "expand-and-define". Thus you can do
-    things like this:
-
-	%assign ofs	0
+PROLOGUE
+
+One day someone wrote that nasm needs:
+
+> - A good ALIGN mechanism, similar to GAS's. GAS pads out space by       
+>   means of the following (32-bit) instructions:
+>           8DB42600000000    lea esi,[esi+0x0]
+>           8DB600000000      lea esi,[esi+0x0]
+>           8D742600          lea esi,[esi+0x0]
+>           8D7600            lea esi,[esi+0x0]
+>           8D36              lea esi,[esi]
+>           90                nop
+>   It uses up to two of these instructions to do up to 14-byte pads;
+>   when more than 14 bytes are needed, it issues a (short) jump to
+>   the end of the padded section and then NOPs the rest. Come up with
+>   a similar scheme for 16 bit mode, and also come up with a way to
+>   use it - internal to the assembler, so that programs using ALIGN
+>   don't knock over preprocess-only mode.
+>     Also re-work the macro form so that when given one argument in a
+>   code section it calls this feature.
+
+Well palign is your friend.
+
+
+	This is a modified version of nasm-0.98.24 that can accept
+two new directives.The two new directives that control
+the align mechanism are 'palign' and  'p2align'.They are nasm directives 
+that don't depend on preprocessor but rather align the code while assembling
+in a gas-like style.
+	The syntax of these directives is 
+
+[palign n] where '0 <= n <= 6' and
+[p2align n] where '0 <= n <=6'
+
+	The use of these directives is
+
+[palign n]
+
+   Pad the location counter to a particular storage boundary.
+The n is a number between 0 and 6 of low-order zero bits the location counter
+must have after advancement.
+For example `palign 3' advances the location counter until 
+it a multiple of 8.If the location counter is already a multiple of 8,
+no change is needed.
+If n=0 then nothing is done
+if n => 6 then palign advances the location counter until it a multiple 
+of 64.For now the maximum is 64 bytes,if you want more use the ALIGN macro.
+
+[p2align n] 
+
+	This directive do almost the same thing with a little exception.
+It will continue aligning until a directive [p2align 0] meet or until
+the current section changes.So this piece of code
+
+	BITS 32
+	SECTION .text
+	[p2align 5]
 	
-	%macro	arg	1
-		%xdefine %1 dword [esp+ofs]
-		%assign ofs ofs+4
-	%endmacro
-
--*- Changed the place where the expansion of %$name macros are expanded.
-    Now they are converted into .. at ctxnum.name form when detokenizing, so
-    there are no quirks as before when using %$name arguments to macros,
-    in macros etc. For example:
-
-	%macro	abc	1
-		%define	%1 hello
-	%endm
-
-	abc	%$here
-	%$here
-
-    Now last line will be expanded to "hello" as expected. This also allows
-    for lots of goodies, a good example are extended "proc" macros included
-    in this archive.
-
--*- Added a check for "cstk" in smacro_defined() before calling get_ctx() -
-    this allows for things like:
-
-	%ifdef %$abc
-	%endif
-
-    to work without warnings even in no context.
-
--*- Added a check for "cstk" in %if*ctx and %elif*ctx directives -
-    this allows to use %ifctx without excessive warnings. If there is
-    no active context, %ifctx goes through "false" branch.
-
--*- Removed "user error: " prefix with %error directive: it just clobbers the
-    output and has absolutely no functionality. Besides, this allows to write
-    macros that does not differ from build-in functions in any way.
-
--*- Added expansion of string that is output by %error directive. Now you
-    can do things like:
-
-	%define hello(x) Hello, x!
-
-	%define %$name andy
-	%error "hello(%$name)"
-
-    Same happened with %include directive.
-
--*- Now all directives that expect an identifier will try to expand and
-    concatenate everything without whitespaces in between before usage.
-    For example, with "unfixed" nasm the commands
-
-	%define %$abc hello
-	%define __%$abc goodbye
-	__%$abc
-
-    would produce "incorrect" output: last line will expand to
-
-	hello goodbyehello
-
-    Not quite what you expected, eh? :-) The answer is that preprocessor
-    treats the %define construct as if it would be
-
-	%define __ %$abc goodbye
-
-    (note the white space between __ and %$abc). After my "fix" it
-    will "correctly" expand into
-
-	goodbye
-
-    as expected. Note that I use quotes around words "correct", "incorrect"
-    etc because this is rather a feature not a bug; however current behaviour
-    is more logical (and allows more advanced macro usage :-).
-
-    Same change was applied to:
-	%push,%macro,%imacro,%define,%idefine,%xdefine,%ixdefine,
-	%assign,%iassign,%undef
-
--*- A new directive [WARNING {+|-}warning-id] have been added. It works only
-    if the assembly phase is enabled (i.e. it doesn't work with nasm -e).
-
--*- A new warning type: macro-selfref. By default this warning is disabled;
-    when enabled NASM warns when a macro self-references itself; for example
-    the following source:
-
-	[WARNING macro-selfref]
-
-	%macro		push	1-*
-		%rep	%0
-			push	%1
-			%rotate	1
-		%endrep
-	%endmacro
-
-			push	eax,ebx,ecx
-
-    will produce a warning, but if we remove the first line we won't see it
-    anymore (which is The Right Thing To Do {tm} IMHO since C preprocessor
-    eats such constructs without warnings at all).
-
--*- Added a "error" routine to preprocessor which always will set ERR_PASS1
-    bit in severity_code. This removes annoying repeated errors on first
-    and second passes from preprocessor.
-
--*- Added the %+ operator in single-line macros for concatenating two
-    identifiers. Usage example:
-
-	%define _myfunc _otherfunc
-	%define cextern(x) _ %+ x
-	cextern (myfunc)
-
-    After first expansion, third line will become "_myfunc". After this
-    expansion is performed again so it becomes "_otherunc".
-
--*- Now if preprocessor is in a non-emmitting state, no warning or error
-    will be emmitted. Example:
-
-	%if 1
-		mov	eax,ebx
-	%else
-		put anything you want between these two brackets,
-		even macro-parameter references %1 or local labels %$zz
-		or macro-local labels %%zz - no warning will be emmitted.
-	%endif
+	;some code here
 
--*- Context-local variables on expansion as a last resort are looked up
-    in outer contexts. For example, the following piece:
 
-	%push	outer
-	%define	%$a [esp]
+	SECTION .data
 
-		%push	inner
-		%$a
-		%pop
-	%pop
+	;some data here
 
-    will expand correctly the fourth line to [esp]; if we'll define another
-    %$a inside the "inner" context, it will take precedence over outer
-    definition. However, this modification has been applied only to
-    expand_smacro and not to smacro_define: as a consequence expansion
-    looks in outer contexts, but %ifdef won't look in outer contexts.
+guarantee that all the instructions in the code segment will be aligned 
+in a 32 byte boundary so than no instruction break the cache line on a
+pentium processor.
 
-    This behaviour is needed because we don't want nested contexts to
-    act on already defined local macros. Example:
+BUGS
 
-	%define %$arg1	[esp+4]
-	test	eax,eax
-	if	nz
-		mov	eax,%$arg1
-	endif
+Well my english are very very bad. 
+This optimization will not work 
+for now for 16-bit code.
+Also there may be a problem with the prefixes like ds,es,rep,lock etc
 
-    In this example the "if" mmacro enters into the "if" context, so %$arg1
-    is not valid anymore inside "if". Of course it could be worked around
-    by using explicitely %$$arg1 but this is ugly IMHO.
+so this code will work 
 
--------------------------------// fixes for 0.98 //-----------------------------
+	'rep movsd'
 
--*- Fixed memory leak in %undef. The origline wasn't freed before
-    exiting on success.
+but this may not work
 
------------------------------// Fixes for 0.98.01 //----------------------------
+	'rep'
+	'movsd'
 
--*- Fixed trap in preprocessor when line expanded to empty set of tokens.
-    This happens, for example, in the following case:
+if you want to be sure put the prefix in the same line 
+with the instruction.
 
-	#define SOMETHING
-	SOMETHING
+Also don't try this in a data or a bss segment.Use the ALIGN macro better
 
+FEEDBACK 
 
-Andrew Zabolotny <bit at eltech.ru>
+If you have any suggestion, comment or found a bug please email me 
+and i will try to reply immediately.
+From your feedback it depends this project to get better as i intend
+to implement more things and improve the code in the next version of nasm.
+   
+AUTHOR 
+Panos Minos								03-04-2002 
+email: <panosminos at mycosmos.gr> , <panosminos1 at mycosmos.gr>
diff --git a/nasm.c b/nasm.c
index 14ef45bc..9f3eebcd 100644
--- a/nasm.c
+++ b/nasm.c
@@ -1,5 +1,4 @@
-/* The Netwide Assembler main program module
- *
+ /*
  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
  * Julian Hall. All rights reserved. The software is
  * redistributable under the licence given in the file "Licence"
@@ -22,6 +21,7 @@
 #include "labels.h"
 #include "outform.h"
 #include "listing.h"
+#define CACHE_ALIGN
 
 struct forwrefinfo {		       /* info held on forward refs. */
     int lineno;
@@ -36,6 +36,15 @@ static void assemble_file (char *);
 static int getkw (char *buf, char **value);
 static void register_output_formats(void);
 static void usage(void);
+#ifdef CACHE_ALIGN
+static int get_alignv (char *value);
+void nop(void);
+static int isdirective(char * line);
+typedef struct lline {
+		struct lline * next;
+		char * line;
+} lline;
+#endif
 
 static int using_debug_info;
 int	   tasm_compatible_mode = FALSE;
@@ -55,6 +64,10 @@ int optimizing = -1;		/* number of optimization passes to take */
 static int sb, cmd_sb = 16;		       /* by default */
 static unsigned long cmd_cpu = IF_PLEVEL;	/* highest level by default */
 static unsigned long cpu = IF_PLEVEL;		/* passed to insn_size & assemble.c */
+#ifdef CACHE_ALIGN
+static int alignv = 0;
+static int alignseg;
+#endif
 int global_offset_changed;             /* referenced in labels.c */
 
 static loc_t location;
@@ -370,7 +383,10 @@ static int process_arg (char *p, char *q)
 	  case 'l':
 	  case 'E':
 	  case 'F':
-	    if ( !(param = get_param (p, q, &advance)) )
+#ifdef 0/*CACHE_ALIGN*/
+	  case 'A':		  
+#endif
+  		  if ( !(param = get_param (p, q, &advance)) )
 		break;
 	    if (p[1]=='o') {	       /* output file */
 		strcpy (outname, param);
@@ -384,8 +400,20 @@ static int process_arg (char *p, char *q)
 		}
 		else
 		    ofmt->current_dfmt = ofmt->debug_formats[0];
-	    } else if (p[1]=='O') {		    /* Optimization level */
+		}
+#ifdef 0 /*CACHE_ALIGN*/
+		else if (p[1]=='A') {
 		int opt;
+			if (!isdigit(*param)) report_error(ERR_FATAL,
+				"command line alignment level must be 0..6");
+			opt = atoi(param);
+			if (opt<=0) alignv = 0;
+			else if (opt>=6) alignv = 64;
+			else alignv = (1 << opt);
+		}
+#endif
+		else if (p[1]=='O') {		    /* Optimization level */
+				int opt;
 	        if (!isdigit(*param)) report_error(ERR_FATAL,
 	             "command line optimization level must be 0..3 or <nn>");
 	    	opt = atoi(param);
@@ -745,6 +773,29 @@ static void assemble_file (char *fname)
 {
     char   * value, * p, * q, * special, * line, debugid[80];
     insn   output_ins;
+
+	#ifdef CACHE_ALIGN
+	lline * prevlline, * curlline, * lastlline;
+	char * nextline;
+	insn  pad_ins[15] ;
+	char * pad_line[] = { 
+	" db 0x90 " ,
+	" db 0x8D,0x36 " ,
+	" db 0x8D,0x76,0x00 " ,
+	" db 0x8D,0x74,0x26,0x00 " ,
+	" db 0x8D,0x74,0x26,0x00,0x90 " ,
+	" db 0x8D,0xB6,0x00,0x00,0x00,0x00 " ,
+	" db 0x8D,0xB4,0x26,0x00,0x00,0x00,0x00 " ,
+	" db 0x8D,0xB4,0x26,0x00,0x00,0x00,0x00,0x90 " ,
+	" db 0x8D,0xB4,0x26,0x00,0x00,0x00,0x00,0x8D,0x36 " ,
+	" db 0x8D,0xB4,0x26,0x00,0x00,0x00,0x00,0x8D,0x76,0x00 " ,
+	" db 0x8D,0xB4,0x26,0x00,0x00,0x00,0x00,0x8D,0x74,0x26,0x00 " ,
+	" db 0x8D,0xB6,0x00,0x00,0x00,0x00,0x8D,0xB6,0x00,0x00,0x00,0x00 " ,
+	" db 0x8D,0xB4,0x26,0x00,0x00,0x00,0x00,0x8D,0xB6,0x00,0x00,0x00,0x00 " ,
+	" db 0x8D,0xB4,0x26,0x00,0x00,0x00,0x00,0x8D,0xB4,0x26,0x00,0x00,0x00,0x00 ",
+	" db 0xEB,0x00 " } ;
+	#endif
+
     int    i, rn_error, validid;
     long   seg, offs;
     struct tokenval tokval;
@@ -752,11 +803,19 @@ static void assemble_file (char *fname)
     int pass, pass_max;
     int pass_cnt = 0;		/* count actual passes */
 
-    if (cmd_sb == 32 && cmd_cpu < IF_386)
+	#ifdef CACHE_ALIGN
+	for (i=0 ; i<15 ; i++) {
+		parse_line ( 1 , pad_line[i], &pad_ins[i],
+		report_error, evaluate, define_label); 
+	}
+	#endif
+	
+	if (cmd_sb == 32 && cmd_cpu < IF_386)
       report_error(ERR_FATAL, "command line: "
                     "32-bit segment size requires a higher cpu");
 
-   pass_max = (optimizing>0 ? optimizing : 0) + 2;    /* passes 1, optimizing, then 2 */
+   pass_max = (optimizing>0 ? optimizing : 0) + 2;    /* passes 1, optimizing, 
+then 2 */
    pass0 = !(optimizing>0);		/* start at 1 if not optimizing */
    for (pass = 1; pass <= pass_max  &&  pass0 <= 2; pass++) {
       int pass1, pass2;
@@ -788,10 +847,20 @@ static void assemble_file (char *fname)
       globallineno = 0;
       if (pass == 1) location.known = TRUE;
       location.offset = offs = GET_CURR_OFFS;
-
-      while ( (line = preproc->getline()) )
+#ifdef CACHE_ALIGN
+	  alignv=0;
+	  curlline=nasm_malloc(sizeof(lline));
+	  curlline->next=NULL;
+	  curlline->line = preproc->getline();
+	  prevlline=lastlline=curlline;
+	  while (curlline->line!=NULL)
       {
-         globallineno++;
+		line=curlline->line;
+#else
+	 while ( (line = preproc->getline()) )
+     {
+#endif	 		  
+		globallineno++;
 
          /* here we parse our directives; this is not handled by the 'real'
             * parser. */
@@ -807,7 +876,7 @@ static void assemble_file (char *fname)
                   } else {
                      in_abs_seg = FALSE;
                      location.segment = seg;
-                  }
+					}
                   break;
                case 2:               /* [EXTERN label:special] */
                   if (*value == '$') value++;   /* skip initial $ if present */
@@ -839,11 +908,13 @@ static void assemble_file (char *fname)
                            special = q;
                         } else
                            special = NULL;
-                        if (!is_extern(value)) {   /* allow re-EXTERN to be ignored */
+                        if (!is_extern(value)) {   /* allow re-EXTERN to be 
+ignored */
                            int temp = pass0;
                            pass0 = 1;	/* fake pass 1 in labels.c */
                            declare_as_global (value, special, report_error);
-                           define_label (value, seg_alloc(), 0L, NULL, FALSE, TRUE,
+                           define_label (value, seg_alloc(), 0L, NULL, FALSE, 
+TRUE,
                                           ofmt, report_error);
                            pass0 = temp;
                         }
@@ -942,7 +1013,8 @@ static void assemble_file (char *fname)
                   stdscan_reset();
                   stdscan_bufptr = value;
                   tokval.t_type = TOKEN_INVALID;
-                  e = evaluate(stdscan, NULL, &tokval, NULL, pass2, report_error,
+                  e = evaluate(stdscan, NULL, &tokval, NULL, pass2, 
+report_error,
                               NULL);
                   if (e) {
                      if (!is_reloc(e))
@@ -954,7 +1026,8 @@ static void assemble_file (char *fname)
                            abs_offset = reloc_value(e);
                      }
                   } else
-                     if (pass==1) abs_offset = 0x100;/* don't go near zero in case of / */
+                     if (pass==1) abs_offset = 0x100;/* don't go near zero in 
+case of / */
                      else report_error (ERR_PANIC, "invalid ABSOLUTE address "
                                     "in pass two");
                   in_abs_seg = TRUE;
@@ -978,7 +1051,8 @@ static void assemble_file (char *fname)
                      break;
                   }
                   while (*p && isspace(*p)) p++;
-                  if (pass==pass_max) ofmt->current_dfmt->debug_directive (debugid, p);
+                  if (pass==pass_max) ofmt->current_dfmt->debug_directive 
+(debugid, p);
                   break;
                case 8:			/* [WARNING {+|-}warn-name] */
                   if (pass1 == 1) {
@@ -1019,6 +1093,56 @@ static void assemble_file (char *fname)
                           }
                       }
                   break;
+			#ifdef CACHE_ALIGN
+			   case 11:
+					do {
+						int alignv;
+						int pad_len;
+						insn * pad_temp;
+						extop * pad_eop;
+						alignv = get_alignv(value);
+						if (alignv) {
+							if (pass1 == 1) {
+								offs = offs + ((alignv - 1) & (-offs));
+		            			SET_CURR_OFFS (offs);
+	        				}
+							else {
+								pad_len = ((alignv -1 ) & (-offs));
+								if (pad_len >= 15) {
+									pad_temp = &pad_ins[14];
+									pad_eop = pad_temp->eops  ;
+									pad_eop = pad_eop->next ;
+									pad_eop->offset = pad_len - 2 ;
+									offs += assemble (location.segment, offs, sb, cpu,
+										&pad_ins[14], ofmt, report_error,
+										&nasmlist);
+									SET_CURR_OFFS (offs);
+									pad_len-=2 ;
+									while (pad_len)
+									{
+										offs += assemble (location.segment, offs, sb, cpu,
+											&pad_ins[0], ofmt, report_error,
+											&nasmlist);
+										SET_CURR_OFFS (offs);
+									pad_len--;
+									}
+								}
+								else if (pad_len > 0)
+								{
+									offs += assemble (location.segment, offs, sb, cpu,
+										&pad_ins[pad_len - 1], ofmt, report_error,
+										&nasmlist);
+									SET_CURR_OFFS (offs);
+								}
+							}			
+						}
+					} while (0) ;
+					break;
+				case 12:
+					alignv = get_alignv(value);
+					alignseg = seg;
+					break;
+			#endif				
                default:
                   if (!ofmt->directive (line+1, value, pass2))
                      report_error (pass1==1 ? ERR_NONFATAL : ERR_PANIC,
@@ -1036,9 +1160,11 @@ static void assemble_file (char *fname)
                   if (forwref != NULL && globallineno == forwref->lineno) {
                      output_ins.forw_ref = TRUE;
                      do {
-                        output_ins.oprs[forwref->operand].opflags |= OPFLAG_FORWARD;
+                        output_ins.oprs[forwref->operand].opflags |= 
+OPFLAG_FORWARD;
                         forwref = saa_rstruct (forwrefs);
-                     } while (forwref != NULL && forwref->lineno == globallineno);
+                     } while (forwref != NULL && forwref->lineno == 
+globallineno);
                   } else
                      output_ins.forw_ref = FALSE;
                }
@@ -1052,7 +1178,8 @@ static void assemble_file (char *fname)
                            if (output_ins.oprs[i].opflags & OPFLAG_FORWARD)
                            {
                                     struct forwrefinfo *fwinf =
-                                       (struct forwrefinfo *)saa_wstruct(forwrefs);
+                                       (struct forwrefinfo 
+*)saa_wstruct(forwrefs);
                                  fwinf->lineno = globallineno;
                                  fwinf->operand = i;
                            }
@@ -1108,11 +1235,13 @@ static void assemble_file (char *fname)
                                  (output_ins.oprs[0].type & IMMEDIATE) &&
                                  output_ins.oprs[0].wrt == NO_SEG)
                            {
-                              int isext = output_ins.oprs[0].opflags & OPFLAG_EXTERN;
+                              int isext = output_ins.oprs[0].opflags & 
+OPFLAG_EXTERN;
                               def_label (output_ins.label,
                                              output_ins.oprs[0].segment,
                                              output_ins.oprs[0].offset,
-                                             NULL, FALSE, isext, ofmt, report_error);
+                                             NULL, FALSE, isext, ofmt, 
+report_error);
                            }
                            else if (output_ins.operands == 2 &&
                                        (output_ins.oprs[0].type & IMMEDIATE) &&
@@ -1124,9 +1253,11 @@ static void assemble_file (char *fname)
                                        output_ins.oprs[1].wrt == NO_SEG)
                            {
                                  def_label (output_ins.label,
-                                             output_ins.oprs[0].offset | SEG_ABS,
+                                             output_ins.oprs[0].offset | 
+SEG_ABS,
                                              output_ins.oprs[1].offset,
-                                             NULL, FALSE, FALSE, ofmt, report_error);
+                                             NULL, FALSE, FALSE, ofmt, 
+report_error);
                            }
                            else
                                  report_error(ERR_NONFATAL, "bad syntax for EQU");
@@ -1145,7 +1276,8 @@ static void assemble_file (char *fname)
                                  define_label (output_ins.label,
                                              output_ins.oprs[0].segment,
                                              output_ins.oprs[0].offset,
-                                             NULL, FALSE, FALSE, ofmt, report_error);
+                                             NULL, FALSE, FALSE, ofmt, 
+report_error);
                            }
                            else if (output_ins.operands == 2 &&
                                        (output_ins.oprs[0].type & IMMEDIATE) &&
@@ -1155,9 +1287,11 @@ static void assemble_file (char *fname)
                                        output_ins.oprs[1].segment == NO_SEG)
                            {
                                  define_label (output_ins.label,
-                                             output_ins.oprs[0].offset | SEG_ABS,
+                                             output_ins.oprs[0].offset | 
+SEG_ABS,
                                              output_ins.oprs[1].offset,
-                                             NULL, FALSE, FALSE, ofmt, report_error);
+                                             NULL, FALSE, FALSE, ofmt, 
+report_error);
                            }
                            else
                                  report_error(ERR_NONFATAL, "bad syntax for EQU");
@@ -1178,19 +1312,24 @@ static void assemble_file (char *fname)
                            long typeinfo = TYS_ELEMENTS(output_ins.operands);
                            switch (output_ins.opcode) {
                                     case I_RESB:
-                                        typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_BYTE;
+                                        typeinfo = 
+TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_BYTE;
                                         break;
                                     case I_RESW:
-                                        typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_WORD;
+                                        typeinfo = 
+TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_WORD;
                                         break;
                                     case I_RESD:
-                                        typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_DWORD;
+                                        typeinfo = 
+TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_DWORD;
                                         break;
                                     case I_RESQ:
-                                        typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_QWORD;
+                                        typeinfo = 
+TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_QWORD;
                                         break;
                                     case I_REST:
-                                        typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_TBYTE;
+                                        typeinfo = 
+TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_TBYTE;
                                         break;
                                     case I_DB:
                                         typeinfo |= TY_BYTE;
@@ -1219,8 +1358,50 @@ static void assemble_file (char *fname)
 
                         }
                         if (l != -1) {
-                           offs += l;
-                           SET_CURR_OFFS (offs);
+							offs += l;
+							SET_CURR_OFFS (offs);
+							#ifdef CACHE_ALIGN
+							if (alignv && (seg == alignseg))
+							{
+								lline * nextlline;
+								insn next_ins;
+								long l;
+								nextlline=curlline;
+								while(1)
+								{
+									if (nextlline==lastlline)
+									{
+										lastlline=lastlline->next=nasm_malloc(sizeof(lline));
+										lastlline->next=NULL;
+										lastlline->line=preproc->getline();
+									}
+									nextlline=nextlline->next;
+									nextline=nextlline->line;
+									if(!nextline) break;
+									if ((isdirective(nextline)==1))
+									{
+										alignv=0;
+										break;
+									}		
+									if ((isdirective(nextline)==0)) 
+									{					
+										if (in_abs_seg) break;
+										parse_line (pass1, nextline, &next_ins,report_error, evaluate,nop);
+										l = insn_size (location.segment, offs, sb, cpu,&next_ins, report_error);
+										if ( l > 0 )
+										{
+											if (((((offs & (alignv - 1)) + l) > alignv) && (l <= alignv) ))		
+											{	
+												offs = offs + ((alignv - 1)	& (-offs));	
+												SET_CURR_OFFS (offs);
+											}
+											break;
+										}
+									}
+								}
+									
+							}							
+							#endif
                         }
                         /*
                         * else l == -1 => invalid instruction, which will be
@@ -1228,9 +1409,82 @@ static void assemble_file (char *fname)
                         */
 
                      } else { /* pass == 2 */
-                        offs += assemble (location.segment, offs, sb, cpu,
-                                       &output_ins, ofmt, report_error, &nasmlist);
+						offs += assemble (location.segment, offs, sb, cpu,
+                                       &output_ins, ofmt, report_error, 
+&nasmlist);
                         SET_CURR_OFFS (offs);
+						#ifdef CACHE_ALIGN
+						if (alignv && (seg==alignseg))
+						{
+							insn next_ins;
+							int pad_len ;
+							insn * pad_temp;
+							extop * pad_eop;
+							long l;
+							lline * nextlline;
+							nextlline=curlline;
+							while(1)
+							{	
+								if (nextlline==lastlline)
+								{
+									lastlline=lastlline->next=nasm_malloc(sizeof(lline));
+									lastlline->next=NULL;
+									lastlline->line=preproc->getline();
+								}
+								nextlline=nextlline->next;
+								nextline=nextlline->line;
+								if (!nextline) break;
+								if ((isdirective(nextline)==1))
+								{
+									alignv=0;
+									break;
+								}
+								if ((isdirective(nextline)==0))
+								{	
+									if (in_abs_seg) break;
+									parse_line (pass1, nextline, &next_ins,report_error, evaluate,nop);
+									l = insn_size (location.segment, offs, sb, cpu,&next_ins, report_error);
+									if ( l > 0 )
+									{
+										if (((((offs & (alignv - 1)) + l) > alignv) && (l <= alignv) ))
+										{	
+											pad_len = ((alignv - 1) & (-offs));
+											if (pad_len >= 15)
+   											{
+												pad_temp = &pad_ins[14];
+												pad_eop = pad_temp->eops  ;
+												pad_eop = pad_eop->next ;
+												pad_eop->offset = pad_len - 2 ;
+												offs += assemble (location.segment, offs, sb, cpu,
+													&pad_ins[14], ofmt, report_error,
+													&nasmlist);
+												SET_CURR_OFFS (offs);
+												pad_len-=2 ;
+												while (pad_len)
+	   											{
+													offs += assemble (location.segment, offs, sb, cpu,
+													&pad_ins[0], ofmt, report_error,
+													&nasmlist);
+													SET_CURR_OFFS (offs);
+													pad_len--;
+												}
+											}
+											else if (pad_len > 0)
+   		 									{
+												offs += assemble (location.segment, offs, sb, cpu,
+													&pad_ins[pad_len - 1], ofmt, report_error,
+													&nasmlist);
+												SET_CURR_OFFS (offs);
+											}
+										}
+										break;	
+									}
+								}
+							} 	
+									
+						}
+						#endif
+
 
                      }
                } /* not an EQU */
@@ -1238,7 +1492,18 @@ static void assemble_file (char *fname)
          }
          nasm_free (line);
          location.offset = offs = GET_CURR_OFFS;
-      } /* end while (line = preproc->getline... */
+#ifdef CACHE_ALIGN
+		 prevlline=curlline;
+		 if (curlline==lastlline)
+		 {
+			lastlline=curlline=nasm_malloc(sizeof(lline));
+			curlline->next=NULL;
+			curlline->line=preproc->getline();
+		 }
+		 else curlline=curlline->next;
+		 nasm_free(prevlline);
+#endif
+	 } /* end while (line = preproc->getline... */
 
       if (pass1==2 && global_offset_changed)
          report_error(ERR_NONFATAL, "phase error detected at end of assembly.");
@@ -1334,7 +1599,13 @@ static int getkw (char *buf, char **value)
 	return 9;
     if (!nasm_stricmp(p, "list"))    /* fbk 9/2/00 */
         return 10;
-    return -1;
+#ifdef CACHE_ALIGN
+	if (!nasm_stricmp(p, "palign"))
+		return 11;
+	if (!nasm_stricmp(p, "p2align"))
+		return 12;
+#endif
+	return -1;
 }
 
 static void report_error (int severity, char *fmt, ...)
@@ -1390,7 +1661,8 @@ static void report_error (int severity, char *fmt, ...)
 	/* no further action, by definition */
 	break;
       case ERR_NONFATAL:
-/*     terminate_after_phase = TRUE;   *//**//* hack enables listing(!) on errors */
+/*     terminate_after_phase = TRUE;   *//**//* hack enables listing(!) on 
+errors */
         terminate_after_phase = TRUE;
 	break;
       case ERR_FATAL:
@@ -1550,5 +1822,37 @@ static int get_bits (char *value)
     }
     return i;
 }
+#ifdef CACHE_ALIGN
+static int get_alignv (char *value)
+{
+	int i,j;
+
+	i = atoi(value);
+	if (i<=0) j = 0;
+    else if (i>=6) j = 64;
+	else j = (1 << i);
+	return j;
+}	
+
+void nop(void)
+{
+}
+
+static int isdirective(char * line)
+{
+		int ret;
+		char * templine;
+		char * tempvalue;
+		templine=nasm_malloc(strlen(line)+1);
+		strcpy(templine,line);
+		ret=getkw(templine,&tempvalue);
+		nasm_free(templine);
+		return ret;
+}
+
+
+#endif
+
+
 
 /* end of nasm.c */
diff --git a/nasm.h b/nasm.h
index 6445a324..51e26708 100644
--- a/nasm.h
+++ b/nasm.h
@@ -13,7 +13,7 @@
 
 #define NASM_MAJOR_VER 0
 #define NASM_MINOR_VER 98
-#define NASM_VER "0.98.24"
+#define NASM_VER "0.98.24p1 (Panos Minos)"
 
 #ifndef NULL
 #define NULL 0


More information about the Nasm-commits mailing list