From 87054bc49bdf220f39d2eec50c03ab0629bf9342 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 30 Apr 2002 21:07:31 +0000 Subject: 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 ..@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 +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: , 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 "); 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 -- cgit v1.2.1