From 2d13cc9d04341792bd08512c0018ae8202c29aae Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 24 Dec 2002 18:10:34 +0000 Subject: [PATCH] * Long symbol names support --- compiler/i386/ag386att.pas | 316 +++++++++++++++---------------- compiler/i386/ag386int.pas | 359 +++++++++++++++++------------------ compiler/i386/ag386nsm.pas | 371 +++++++++++++++++++------------------ 3 files changed, 525 insertions(+), 521 deletions(-) diff --git a/compiler/i386/ag386att.pas b/compiler/i386/ag386att.pas index e46dc4cbf4..2c6f91cf2a 100644 --- a/compiler/i386/ag386att.pas +++ b/compiler/i386/ag386att.pas @@ -35,6 +35,10 @@ interface type T386ATTAssembler=class(TGNUassembler) + private + procedure WriteReference(var ref : treference); + procedure WriteOper(const o:toper); + procedure WriteOper_jmp(const o:toper); public procedure WriteInstruction(hp: tai);override; end; @@ -72,176 +76,161 @@ interface verbose; - - function getreferencestring(var ref : treference) : string; - var - s : string; - begin - with ref do - begin - inc(offset,offsetfixup); - offsetfixup:=0; - { have we a segment prefix ? } - { These are probably not correctly handled under GAS } - { should be replaced by coding the segment override } - { directly! - DJGPP FAQ } - if segment<>R_NO then - s:=gas_reg2str[segment]+':' - else - s:=''; - if assigned(symbol) then - s:=s+symbol.name; - if offset<0 then - s:=s+tostr(offset) - else - if (offset>0) then - begin - if assigned(symbol) then - s:=s+'+'+tostr(offset) - else - s:=s+tostr(offset); - end - else if (index=R_NO) and (base=R_NO) and not assigned(symbol) then - s:=s+'0'; - if (index<>R_NO) and (base=R_NO) then - begin - s:=s+'(,'+gas_reg2str[index]; - if scalefactor<>0 then - s:=s+','+tostr(scalefactor)+')' - else - s:=s+')'; - end - else - if (index=R_NO) and (base<>R_NO) then - s:=s+'('+gas_reg2str[base]+')' - else - if (index<>R_NO) and (base<>R_NO) then - begin - s:=s+'('+gas_reg2str[base]+','+gas_reg2str[index]; - if scalefactor<>0 then - s:=s+','+tostr(scalefactor)+')' - else - s := s+')'; - end; - end; - getreferencestring:=s; - end; - - function getopstr(const o:toper) : string; - var - hs : string; - begin - case o.typ of - top_reg : - getopstr:=gas_reg2str[o.reg]; - top_ref : - getopstr:=getreferencestring(o.ref^); - top_const : - getopstr:='$'+tostr(longint(o.val)); - top_symbol : - begin - if assigned(o.sym) then - hs:='$'+o.sym.name - else - hs:='$'; - if o.symofs>0 then - hs:=hs+'+'+tostr(o.symofs) - else - if o.symofs<0 then - hs:=hs+tostr(o.symofs) - else - if not(assigned(o.sym)) then - hs:=hs+'0'; - getopstr:=hs; - end; - else - internalerror(10001); - end; - end; - - function getopstr_jmp(const o:toper) : string; - var - hs : string; - begin - case o.typ of - top_reg : - getopstr_jmp:='*'+gas_reg2str[o.reg]; - top_ref : - getopstr_jmp:='*'+getreferencestring(o.ref^); - top_const : - getopstr_jmp:=tostr(longint(o.val)); - top_symbol : - begin - hs:=o.sym.name; - if o.symofs>0 then - hs:=hs+'+'+tostr(o.symofs) - else - if o.symofs<0 then - hs:=hs+tostr(o.symofs); - getopstr_jmp:=hs; - end; - else - internalerror(10001); - end; - end; - - {**************************************************************************** TI386ATTASMOUTPUT ****************************************************************************} - - - procedure T386AttAssembler. WriteInstruction(hp: tai); - var - op : tasmop; - s : string; - sep : char; - calljmp : boolean; - i : integer; - begin - if hp.typ <> ait_instruction then exit; - taicpu(hp).SetOperandOrder(op_att); - op:=taicpu(hp).opcode; - calljmp:=is_calljmp(op); - { call maybe not translated to call } - s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]; - { suffix needed ? fnstsw,fldcw don't support suffixes - with binutils 2.9.5 under linux } - if (not calljmp) and - (gas_needsuffix[op]<>AttSufNONE) and - (op<>A_FNSTSW) and (op<>A_FSTSW) and - (op<>A_FNSTCW) and (op<>A_FSTCW) and - (op<>A_FLDCW) and not( - (taicpu(hp).oper[0].typ=top_reg) and - (taicpu(hp).oper[0].reg in [R_ST..R_ST7]) - ) then - s:=s+gas_opsize2str[taicpu(hp).opsize]; - { process operands } - if taicpu(hp).ops<>0 then + procedure T386AttAssembler.WriteReference(var ref : treference); + begin + with ref do begin - { call and jmp need an extra handling } - { this code is only called if jmp isn't a labeled instruction } - { quick hack to overcome a problem with manglednames=255 chars } - if calljmp then - begin - AsmWrite(s+#9); - s:=getopstr_jmp(taicpu(hp).oper[0]); - end + inc(offset,offsetfixup); + offsetfixup:=0; + { have we a segment prefix ? } + { These are probably not correctly handled under GAS } + { should be replaced by coding the segment override } + { directly! - DJGPP FAQ } + if segment<>R_NO then + AsmWrite(gas_reg2str[segment]+':'); + if assigned(symbol) then + AsmWrite(symbol.name); + if offset<0 then + AsmWrite(tostr(offset)) + else + if (offset>0) then + begin + if assigned(symbol) then + AsmWrite('+'+tostr(offset)) + else + AsmWrite(tostr(offset)); + end + else if (index=R_NO) and (base=R_NO) and not assigned(symbol) then + AsmWrite('0'); + if (index<>R_NO) and (base=R_NO) then + begin + AsmWrite('(,'+gas_reg2str[index]); + if scalefactor<>0 then + AsmWrite(','+tostr(scalefactor)+')') + else + AsmWrite(')'); + end + else + if (index=R_NO) and (base<>R_NO) then + AsmWrite('('+gas_reg2str[base]+')') else + if (index<>R_NO) and (base<>R_NO) then begin - for i:=0 to taicpu(hp).ops-1 do - begin - if i=0 then - sep:=#9 - else - sep:=','; - s:=s+sep+getopstr(taicpu(hp).oper[i]) - end; + AsmWrite('('+gas_reg2str[base]+','+gas_reg2str[index]); + if scalefactor<>0 then + AsmWrite(','+tostr(scalefactor)); + AsmWrite(')'); end; end; - AsmWriteLn(s); - end; + end; + + + procedure T386AttAssembler.WriteOper(const o:toper); + begin + case o.typ of + top_reg : + AsmWrite(gas_reg2str[o.reg]); + top_ref : + WriteReference(o.ref^); + top_const : + AsmWrite('$'+tostr(longint(o.val))); + top_symbol : + begin + AsmWrite('$'); + if assigned(o.sym) then + AsmWrite(o.sym.name); + if o.symofs>0 then + AsmWrite('+'+tostr(o.symofs)) + else + if o.symofs<0 then + AsmWrite(tostr(o.symofs)) + else + if not(assigned(o.sym)) then + AsmWrite('0'); + end; + else + internalerror(10001); + end; + end; + + + procedure T386AttAssembler.WriteOper_jmp(const o:toper); + begin + case o.typ of + top_reg : + AsmWrite('*'+gas_reg2str[o.reg]); + top_ref : + begin + AsmWrite('*'); + WriteReference(o.ref^); + end; + top_const : + AsmWrite(tostr(longint(o.val))); + top_symbol : + begin + AsmWrite(o.sym.name); + if o.symofs>0 then + AsmWrite('+'+tostr(o.symofs)) + else + if o.symofs<0 then + AsmWrite(tostr(o.symofs)); + end; + else + internalerror(10001); + end; + end; + + + procedure T386AttAssembler.WriteInstruction(hp: tai); + var + op : tasmop; + calljmp : boolean; + i : integer; + begin + if hp.typ <> ait_instruction then + exit; + taicpu(hp).SetOperandOrder(op_att); + op:=taicpu(hp).opcode; + calljmp:=is_calljmp(op); + { call maybe not translated to call } + AsmWrite(#9+gas_op2str[op]+cond2str[taicpu(hp).condition]); + { suffix needed ? fnstsw,fldcw don't support suffixes + with binutils 2.9.5 under linux } + if (not calljmp) and + (gas_needsuffix[op]<>AttSufNONE) and + (op<>A_FNSTSW) and (op<>A_FSTSW) and + (op<>A_FNSTCW) and (op<>A_FSTCW) and + (op<>A_FLDCW) and not( + (taicpu(hp).oper[0].typ=top_reg) and + (taicpu(hp).oper[0].reg in [R_ST..R_ST7]) + ) then + AsmWrite(gas_opsize2str[taicpu(hp).opsize]); + { process operands } + if taicpu(hp).ops<>0 then + begin + if calljmp then + begin + AsmWrite(#9); + WriteOper_jmp(taicpu(hp).oper[0]); + end + else + begin + for i:=0 to taicpu(hp).ops-1 do + begin + if i=0 then + AsmWrite(#9) + else + AsmWrite(','); + WriteOper(taicpu(hp).oper[i]); + end; + end; + end; + AsmLn; + end; {***************************************************************************** @@ -314,7 +303,10 @@ initialization end. { $Log$ - Revision 1.26 2002-08-12 15:08:40 carl + Revision 1.27 2002-12-24 18:10:34 peter + * Long symbol names support + + Revision 1.26 2002/08/12 15:08:40 carl + stab register indexes for powerpc (moved from gdb to cpubase) + tprocessor enumeration moved to cpuinfo + linker in target_info is now a class diff --git a/compiler/i386/ag386int.pas b/compiler/i386/ag386int.pas index c5be7bb9ec..27050894ca 100644 --- a/compiler/i386/ag386int.pas +++ b/compiler/i386/ag386int.pas @@ -29,10 +29,17 @@ unit ag386int; interface - uses aasmbase,aasmtai,aasmcpu,assemble; + uses + cpubase, + aasmbase,aasmtai,aasmcpu,assemble; type T386IntelAssembler = class(TExternalAssembler) + private + procedure WriteReference(var ref : treference); + procedure WriteOper(const o:toper;s : topsize; opcode: tasmop;dest : boolean); + procedure WriteOper_jmp(const o:toper;s : topsize); + public procedure WriteTree(p:TAAsmoutput);override; procedure WriteAsmList;override; Function DoAssemble:boolean;override; @@ -49,7 +56,7 @@ interface sysutils, {$endif} cutils,globtype,globals,systems,cclasses, - verbose,cpubase,finput,fmodule,script,cpuinfo + verbose,finput,fmodule,script,cpuinfo ; const @@ -120,157 +127,6 @@ interface comp2str:=double2str(dd^); end; - function getreferencestring(var ref : treference) : string; - var - s : string; - first : boolean; - begin - with ref do - begin - first:=true; - inc(offset,offsetfixup); - offsetfixup:=0; - if ref.segment<>R_NO then - s:=std_reg2str[segment]+':[' - else - s:='['; - if assigned(symbol) then - begin - if (aktoutputformat = as_i386_tasm) then - s:=s+'dword ptr '; - s:=s+symbol.name; - first:=false; - end; - if (base<>R_NO) then - begin - if not(first) then - s:=s+'+' - else - first:=false; - s:=s+std_reg2str[base]; - end; - if (index<>R_NO) then - begin - if not(first) then - s:=s+'+' - else - first:=false; - s:=s+std_reg2str[index]; - if scalefactor<>0 then - s:=s+'*'+tostr(scalefactor); - end; - if offset<0 then - s:=s+tostr(offset) - else if (offset>0) then - s:=s+'+'+tostr(offset); - if s[length(s)]='[' then - s:=s+'0'; - s:=s+']'; - end; - getreferencestring:=s; - end; - - - function getopstr(const o:toper;s : topsize; opcode: tasmop;dest : boolean) : string; - var - hs : string; - begin - case o.typ of - top_reg : - getopstr:=std_reg2str[o.reg]; - top_const : - getopstr:=tostr(longint(o.val)); - top_symbol : - begin - if assigned(o.sym) then - hs:='offset '+o.sym.name - else - hs:='offset '; - if o.symofs>0 then - hs:=hs+'+'+tostr(o.symofs) - else - if o.symofs<0 then - hs:=hs+tostr(o.symofs) - else - if not(assigned(o.sym)) then - hs:=hs+'0'; - getopstr:=hs; - end; - top_ref : - begin - hs:=getreferencestring(o.ref^); - if ((opcode <> A_LGS) and (opcode <> A_LSS) and - (opcode <> A_LFS) and (opcode <> A_LDS) and - (opcode <> A_LES)) then - Begin - case s of - S_B : hs:='byte ptr '+hs; - S_W : hs:='word ptr '+hs; - S_L : hs:='dword ptr '+hs; - S_IS : hs:='word ptr '+hs; - S_IL : hs:='dword ptr '+hs; - S_IQ : hs:='qword ptr '+hs; - S_FS : hs:='dword ptr '+hs; - S_FL : hs:='qword ptr '+hs; - S_FX : hs:='tbyte ptr '+hs; - S_BW : if dest then - hs:='word ptr '+hs - else - hs:='byte ptr '+hs; - S_BL : if dest then - hs:='dword ptr '+hs - else - hs:='byte ptr '+hs; - S_WL : if dest then - hs:='dword ptr '+hs - else - hs:='word ptr '+hs; - end; - end; - getopstr:=hs; - end; - else - internalerror(10001); - end; - end; - - function getopstr_jmp(const o:toper;s : topsize) : string; - var - hs : string; - begin - case o.typ of - top_reg : - getopstr_jmp:=std_reg2str[o.reg]; - top_const : - getopstr_jmp:=tostr(longint(o.val)); - top_symbol : - begin - hs:=o.sym.name; - if o.symofs>0 then - hs:=hs+'+'+tostr(o.symofs) - else - if o.symofs<0 then - hs:=hs+tostr(o.symofs); - getopstr_jmp:=hs; - end; - top_ref : - { what about lcall or ljmp ??? } - begin - if (aktoutputformat = as_i386_tasm) then - hs:='' - else - begin - if s=S_FAR then - hs:='far ptr ' - else - hs:='dword ptr '; - end; - getopstr_jmp:=hs+getreferencestring(o.ref^); - end; - else - internalerror(10001); - end; - end; function fixline(s:string):string; { @@ -296,6 +152,154 @@ interface T386IntelAssembler ****************************************************************************} + procedure T386IntelAssembler.WriteReference(var ref : treference); + var + first : boolean; + begin + with ref do + begin + first:=true; + inc(offset,offsetfixup); + offsetfixup:=0; + if ref.segment<>R_NO then + AsmWrite(std_reg2str[segment]+':[') + else + AsmWrite('['); + if assigned(symbol) then + begin + if (aktoutputformat = as_i386_tasm) then + AsmWrite('dword ptr '); + AsmWrite(symbol.name); + first:=false; + end; + if (base<>R_NO) then + begin + if not(first) then + AsmWrite('+') + else + first:=false; + AsmWrite(std_reg2str[base]); + end; + if (index<>R_NO) then + begin + if not(first) then + AsmWrite('+') + else + first:=false; + AsmWrite(std_reg2str[index]); + if scalefactor<>0 then + AsmWrite('*'+tostr(scalefactor)); + end; + if offset<0 then + begin + AsmWrite(tostr(offset)); + first:=false; + end + else if (offset>0) then + begin + AsmWrite('+'+tostr(offset)); + first:=false; + end; + if first then + AsmWrite('0'); + AsmWrite(']'); + end; + end; + + + procedure T386IntelAssembler.WriteOper(const o:toper;s : topsize; opcode: tasmop;dest : boolean); + begin + case o.typ of + top_reg : + AsmWrite(std_reg2str[o.reg]); + top_const : + AsmWrite(tostr(longint(o.val))); + top_symbol : + begin + AsmWrite('offset '); + if assigned(o.sym) then + AsmWrite(o.sym.name); + if o.symofs>0 then + AsmWrite('+'+tostr(o.symofs)) + else + if o.symofs<0 then + AsmWrite(tostr(o.symofs)) + else + if not(assigned(o.sym)) then + AsmWrite('0'); + end; + top_ref : + begin + if ((opcode <> A_LGS) and (opcode <> A_LSS) and + (opcode <> A_LFS) and (opcode <> A_LDS) and + (opcode <> A_LES)) then + Begin + case s of + S_B : AsmWrite('byte ptr '); + S_W : AsmWrite('word ptr '); + S_L : AsmWrite('dword ptr '); + S_IS : AsmWrite('word ptr '); + S_IL : AsmWrite('dword ptr '); + S_IQ : AsmWrite('qword ptr '); + S_FS : AsmWrite('dword ptr '); + S_FL : AsmWrite('qword ptr '); + S_FX : AsmWrite('tbyte ptr '); + S_BW : if dest then + AsmWrite('word ptr ') + else + AsmWrite('byte ptr '); + S_BL : if dest then + AsmWrite('dword ptr ') + else + AsmWrite('byte ptr '); + S_WL : if dest then + AsmWrite('dword ptr ') + else + AsmWrite('word ptr '); + end; + end; + WriteReference(o.ref^); + end; + else + internalerror(10001); + end; + end; + + + procedure T386IntelAssembler.WriteOper_jmp(const o:toper;s : topsize); + begin + case o.typ of + top_reg : + AsmWrite(std_reg2str[o.reg]); + top_const : + AsmWrite(tostr(longint(o.val))); + top_symbol : + begin + AsmWrite(o.sym.name); + if o.symofs>0 then + AsmWrite('+'+tostr(o.symofs)) + else + if o.symofs<0 then + AsmWrite(tostr(o.symofs)); + end; + top_ref : + { what about lcall or ljmp ??? } + begin + if (aktoutputformat <> as_i386_tasm) then + begin + if s=S_FAR then + AsmWrite('far ptr ') + else + AsmWrite('dword ptr '); + end; + WriteReference(o.ref^); + end; + else + internalerror(10001); + end; + end; + + var LasTSec : TSection; lastfileinfo : tfileposinfo; @@ -342,7 +346,6 @@ interface found, do_line,DoNotSplitLine, quoted : boolean; - sep : char; begin if not assigned(p) then exit; @@ -591,23 +594,21 @@ interface end; ait_instruction : begin taicpu(hp).CheckNonCommutativeOpcodes; - { We need intel order, no At&t } taicpu(hp).SetOperandOrder(op_intel); - { Reset } + { Reset } suffix:=''; prefix:= ''; - s:=''; - { We need to explicitely set - word prefix to get selectors - to be pushed in 2 bytes PM } - if (taicpu(hp).opsize=S_W) and - ((taicpu(hp).opcode=A_PUSH) or - (taicpu(hp).opcode=A_POP)) and - (taicpu(hp).oper[0].typ=top_reg) and - ((taicpu(hp).oper[0].reg>=firstsreg) and - (taicpu(hp).oper[0].reg<=lastsreg)) then - AsmWriteln(#9#9'DB'#9'066h'); - { added prefix instructions, must be on same line as opcode } + { We need to explicitely set + word prefix to get selectors + to be pushed in 2 bytes PM } + if (taicpu(hp).opsize=S_W) and + ((taicpu(hp).opcode=A_PUSH) or + (taicpu(hp).opcode=A_POP)) and + (taicpu(hp).oper[0].typ=top_reg) and + ((taicpu(hp).oper[0].reg>=firstsreg) and + (taicpu(hp).oper[0].reg<=lastsreg)) then + AsmWriteln(#9#9'DB'#9'066h'); + { added prefix instructions, must be on same line as opcode } if (taicpu(hp).ops = 0) and ((taicpu(hp).opcode = A_REP) or (taicpu(hp).opcode = A_LOCK) or @@ -621,8 +622,7 @@ interface { this is theorically impossible... } if hp=nil then begin - s:=#9#9+prefix; - AsmWriteLn(s); + AsmWriteLn(#9#9+prefix); break; end; { nasm prefers prefix on a line alone @@ -636,23 +636,27 @@ interface end else prefix:= ''; + AsmWrite(#9#9+prefix+std_op2str[taicpu(hp).opcode]+cond2str[taicpu(hp).condition]+suffix); if taicpu(hp).ops<>0 then begin if is_calljmp(taicpu(hp).opcode) then - s:=#9+getopstr_jmp(taicpu(hp).oper[0],taicpu(hp).opsize) + begin + AsmWrite(#9); + WriteOper_jmp(taicpu(hp).oper[0],taicpu(hp).opsize); + end else begin for i:=0to taicpu(hp).ops-1 do begin if i=0 then - sep:=#9 + AsmWrite(#9) else - sep:=','; - s:=s+sep+getopstr(taicpu(hp).oper[i],taicpu(hp).opsize,taicpu(hp).opcode,(i=2)); + AsmWrite(','); + WriteOper(taicpu(hp).oper[i],taicpu(hp).opsize,taicpu(hp).opcode,(i=2)); end; end; end; - AsmWriteLn(#9#9+prefix+std_op2str[taicpu(hp).opcode]+cond2str[taicpu(hp).condition]+suffix+s); + AsmLn; end; {$ifdef GDB} ait_stabn, @@ -840,7 +844,10 @@ initialization end. { $Log$ - Revision 1.30 2002-11-17 16:31:58 carl + Revision 1.31 2002-12-24 18:10:34 peter + * Long symbol names support + + Revision 1.30 2002/11/17 16:31:58 carl * memory optimization (3-4%) : cleanup of tai fields, cleanup of tdef and tsym fields. * make it work for m68k diff --git a/compiler/i386/ag386nsm.pas b/compiler/i386/ag386nsm.pas index 02b9f66530..c0cf2a09ad 100644 --- a/compiler/i386/ag386nsm.pas +++ b/compiler/i386/ag386nsm.pas @@ -27,10 +27,17 @@ unit ag386nsm; interface - uses aasmbase,aasmtai,aasmcpu,assemble; + uses + cpubase, + aasmbase,aasmtai,aasmcpu,assemble; type T386NasmAssembler = class(texternalassembler) + private + procedure WriteReference(var ref : treference); + procedure WriteOper(const o:toper;s : topsize; opcode: tasmop;ops:longint;dest : boolean); + procedure WriteOper_jmp(const o:toper; op : tasmop); + public procedure WriteTree(p:taasmoutput);override; procedure WriteAsmList;override; procedure WriteExternals; @@ -45,7 +52,7 @@ interface sysutils, {$endif} cutils,globtype,globals,systems,cclasses, - fmodule,finput,verbose,cpubase,cpuinfo + fmodule,finput,verbose,cpuinfo ; const @@ -154,54 +161,6 @@ interface end; - function getreferencestring(var ref : treference) : string; - var - s : string; - first : boolean; - begin - with ref do - begin - first:=true; - inc(offset,offsetfixup); - offsetfixup:=0; - if ref.segment<>R_NO then - s:='['+std_reg2str[segment]+':' - else - s:='['; - if assigned(symbol) then - begin - s:=s+symbol.name; - first:=false; - end; - if (base<>R_NO) then - begin - if not(first) then - s:=s+'+' - else - first:=false; - s:=s+std_reg2str[base]; - end; - if (index<>R_NO) then - begin - if not(first) then - s:=s+'+' - else - first:=false; - s:=s+std_reg2str[index]; - if scalefactor<>0 then - s:=s+'*'+tostr(scalefactor); - end; - if offset<0 then - s:=s+tostr(offset) - else if (offset>0) then - s:=s+'+'+tostr(offset); - if s[length(s)]='[' then - s:=s+'0'; - s:=s+']'; - end; - getreferencestring:=s; - end; - function sizestr(s:topsize;dest:boolean):string; begin case s of @@ -232,85 +191,23 @@ interface end; - function getopstr(const o:toper;s : topsize; opcode: tasmop;ops:longint;dest : boolean) : string; + Function PadTabs(const p:string;addch:char):string; var - hs : string; + s : string; + i : longint; begin - case o.typ of - top_reg : - getopstr:=int_nasmreg2str[o.reg]; - top_const : - begin - if (ops=1) and (opcode<>A_RET) then - getopstr:=sizestr(s,dest)+tostr(longint(o.val)) - else - getopstr:=tostr(longint(o.val)); - end; - top_symbol : - begin - if assigned(o.sym) then - hs:='dword '+o.sym.name - else - hs:='dword '; - if o.symofs>0 then - hs:=hs+'+'+tostr(o.symofs) - else - if o.symofs<0 then - hs:=hs+tostr(o.symofs) - else - if not(assigned(o.sym)) then - hs:=hs+'0'; - getopstr:=hs; - end; - top_ref : - begin - hs:=getreferencestring(o.ref^); - if not ((opcode = A_LEA) or (opcode = A_LGS) or - (opcode = A_LSS) or (opcode = A_LFS) or - (opcode = A_LES) or (opcode = A_LDS) or - (opcode = A_SHR) or (opcode = A_SHL) or - (opcode = A_SAR) or (opcode = A_SAL) or - (opcode = A_OUT) or (opcode = A_IN)) then - begin - hs:=sizestr(s,dest)+hs; - end; - getopstr:=hs; - end; - else - internalerror(10001); - end; - end; - - function getopstr_jmp(const o:toper; op : tasmop) : string; - var - hs : string; - begin - case o.typ of - top_reg : - getopstr_jmp:=int_nasmreg2str[o.reg]; - top_ref : - getopstr_jmp:=getreferencestring(o.ref^); - top_const : - getopstr_jmp:=tostr(longint(o.val)); - top_symbol : - begin - hs:=o.sym.name; - if o.symofs>0 then - hs:=hs+'+'+tostr(o.symofs) - else - if o.symofs<0 then - hs:=hs+tostr(o.symofs); - if (op=A_JCXZ) or (op=A_JECXZ) or - (op=A_LOOP) or (op=A_LOOPE) or - (op=A_LOOPNE) or (op=A_LOOPNZ) or - (op=A_LOOPZ) then - getopstr_jmp:=hs - else - getopstr_jmp:='NEAR '+hs; - end; - else - internalerror(10001); - end; + i:=length(p); + if addch<>#0 then + begin + inc(i); + s:=p+addch; + end + else + s:=p; + if i<8 then + PadTabs:=s+#9#9 + else + PadTabs:=s+#9; end; @@ -318,6 +215,131 @@ interface T386NasmAssembler ****************************************************************************} + procedure T386NasmAssembler.WriteReference(var ref : treference); + var + first : boolean; + begin + with ref do + begin + AsmWrite('['); + first:=true; + inc(offset,offsetfixup); + offsetfixup:=0; + if ref.segment<>R_NO then + AsmWrite(std_reg2str[segment]+':'); + if assigned(symbol) then + begin + AsmWrite(symbol.name); + first:=false; + end; + if (base<>R_NO) then + begin + if not(first) then + AsmWrite('+') + else + first:=false; + AsmWrite(int_nasmreg2str[base]); + end; + if (index<>R_NO) then + begin + if not(first) then + AsmWrite('+') + else + first:=false; + AsmWrite(int_nasmreg2str[index]); + if scalefactor<>0 then + AsmWrite('*'+tostr(scalefactor)); + end; + if offset<0 then + begin + AsmWrite(tostr(offset)); + first:=false; + end + else if (offset>0) then + begin + AsmWrite('+'+tostr(offset)); + first:=false; + end; + if first then + AsmWrite('0'); + AsmWrite(']'); + end; + end; + + + procedure T386NasmAssembler.WriteOper(const o:toper;s : topsize; opcode: tasmop;ops:longint;dest : boolean); + begin + case o.typ of + top_reg : + AsmWrite(int_nasmreg2str[o.reg]); + top_const : + begin + if (ops=1) and (opcode<>A_RET) then + AsmWrite(sizestr(s,dest)); + AsmWrite(tostr(longint(o.val))); + end; + top_symbol : + begin + AsmWrite('dword '); + if assigned(o.sym) then + AsmWrite(o.sym.name); + if o.symofs>0 then + AsmWrite('+'+tostr(o.symofs)) + else + if o.symofs<0 then + AsmWrite(tostr(o.symofs)) + else + if not(assigned(o.sym)) then + AsmWrite('0'); + end; + top_ref : + begin + if not ((opcode = A_LEA) or (opcode = A_LGS) or + (opcode = A_LSS) or (opcode = A_LFS) or + (opcode = A_LES) or (opcode = A_LDS) or + (opcode = A_SHR) or (opcode = A_SHL) or + (opcode = A_SAR) or (opcode = A_SAL) or + (opcode = A_OUT) or (opcode = A_IN)) then + AsmWrite(sizestr(s,dest)); + WriteReference(o.ref^); + end; + else + internalerror(10001); + end; + end; + + + procedure T386NasmAssembler.WriteOper_jmp(const o:toper; op : tasmop); + begin + case o.typ of + top_reg : + AsmWrite(int_nasmreg2str[o.reg]); + top_ref : + WriteReference(o.ref^); + top_const : + AsmWrite(tostr(longint(o.val))); + top_symbol : + begin + if not( + (op=A_JCXZ) or (op=A_JECXZ) or + (op=A_LOOP) or (op=A_LOOPE) or + (op=A_LOOPNE) or (op=A_LOOPNZ) or + (op=A_LOOPZ) + ) then + AsmWrite('NEAR '); + AsmWrite(o.sym.name); + if o.symofs>0 then + AsmWrite('+'+tostr(o.symofs)) + else + if o.symofs<0 then + AsmWrite(tostr(o.symofs)); + end; + else + internalerror(10001); + end; + end; + + var LasTSec : TSection; @@ -325,26 +347,6 @@ interface ait_const2str:array[ait_const_32bit..ait_const_8bit] of string[8]= (#9'DD'#9,#9'DW'#9,#9'DB'#9); - Function PadTabs(const p:string;addch:char):string; - var - s : string; - i : longint; - begin - i:=length(p); - if addch<>#0 then - begin - inc(i); - s:=p+addch; - end - else - s:=p; - if i<8 then - PadTabs:=s+#9#9 - else - PadTabs:=s+#9; - end; - - procedure T386NasmAssembler.WriteTree(p:taasmoutput); const allocstr : array[boolean] of string[10]=(' released',' allocated'); @@ -360,7 +362,6 @@ interface found, do_line, quoted : boolean; - sep : char; begin if not assigned(p) then exit; @@ -375,7 +376,7 @@ interface if not(hp.typ in SkipLineInfo) then begin - hp1:=hp as tailineinfo; + hp1:=hp as tailineinfo; aktfilepos:=hp1.fileinfo; if do_line then begin @@ -633,11 +634,8 @@ interface ait_instruction : begin taicpu(hp).CheckNonCommutativeOpcodes; - { We need intel order, no At&t } + { We need intel order, no At&t } taicpu(hp).SetOperandOrder(op_intel); - { Reset - suffix:=''; - prefix:='';} s:=''; if ((taicpu(hp).opcode=A_FADDP) or (taicpu(hp).opcode=A_FMULP)) @@ -649,38 +647,42 @@ interface taicpu(hp).oper[1].typ:=top_reg; taicpu(hp).oper[1].reg:=R_ST; end; - if taicpu(hp).ops<>0 then - begin - if is_calljmp(taicpu(hp).opcode) then - s:=#9+getopstr_jmp(taicpu(hp).oper[0],taicpu(hp).opcode) - else - begin - { We need to explicitely set - word prefix to get selectors - to be pushed in 2 bytes PM } - if (taicpu(hp).opsize=S_W) and - ((taicpu(hp).opcode=A_PUSH) or - (taicpu(hp).opcode=A_POP)) and - (taicpu(hp).oper[0].typ=top_reg) and - ((taicpu(hp).oper[0].reg>=firstsreg) and - (taicpu(hp).oper[0].reg<=lastsreg)) then - AsmWriteln(#9#9'DB'#9'066h'); - for i:=0 to taicpu(hp).ops-1 do - begin - if i=0 then - sep:=#9 - else - sep:=','; - s:=s+sep+getopstr(taicpu(hp).oper[i],taicpu(hp).opsize,taicpu(hp).opcode, - taicpu(hp).ops,(i=2)); - end; - end; - end; if taicpu(hp).opcode=A_FWAIT then AsmWriteln(#9#9'DB'#9'09bh') else - AsmWriteLn(#9#9+{prefix+}std_op2str[taicpu(hp).opcode]+ - cond2str[taicpu(hp).condition]+{suffix+}s); + begin + { We need to explicitely set + word prefix to get selectors + to be pushed in 2 bytes PM } + if (taicpu(hp).opsize=S_W) and + ((taicpu(hp).opcode=A_PUSH) or + (taicpu(hp).opcode=A_POP)) and + (taicpu(hp).oper[0].typ=top_reg) and + ((taicpu(hp).oper[0].reg>=firstsreg) and + (taicpu(hp).oper[0].reg<=lastsreg)) then + AsmWriteln(#9#9'DB'#9'066h'); + AsmWrite(#9#9+std_op2str[taicpu(hp).opcode]+cond2str[taicpu(hp).condition]); + if taicpu(hp).ops<>0 then + begin + if is_calljmp(taicpu(hp).opcode) then + begin + AsmWrite(#9); + WriteOper_jmp(taicpu(hp).oper[0],taicpu(hp).opcode); + end + else + begin + for i:=0 to taicpu(hp).ops-1 do + begin + if i=0 then + AsmWrite(#9) + else + AsmWrite(','); + WriteOper(taicpu(hp).oper[i],taicpu(hp).opsize,taicpu(hp).opcode,taicpu(hp).ops,(i=2)); + end; + end; + end; + AsmLn; + end; end; {$ifdef GDB} ait_stabn, @@ -893,7 +895,10 @@ initialization end. { $Log$ - Revision 1.28 2002-11-17 16:31:59 carl + Revision 1.29 2002-12-24 18:10:34 peter + * Long symbol names support + + Revision 1.28 2002/11/17 16:31:59 carl * memory optimization (3-4%) : cleanup of tai fields, cleanup of tdef and tsym fields. * make it work for m68k