* moved some tables from ra386*.pas -> i386.pas

+ start of coff writer
  * renamed asmutils unit to rautils
This commit is contained in:
peter 1999-01-10 15:37:51 +00:00
parent efeab84797
commit 1ace0dc9b8
9 changed files with 1170 additions and 381 deletions

836
compiler/ag386cof.pas Normal file
View File

@ -0,0 +1,836 @@
{
$Id$
Copyright (c) 1996-98 by the FPC development team
This unit implements an asmoutput class for i386 coff
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
{$ifdef TP}
{$N+,E+}
{$endif}
unit ag386cof;
interface
uses cobjects,aasm,assemble;
type
pi386coffasmlist=^ti386coffasmlist;
ti386coffasmlist=object(tasmlist)
procedure WriteTree(p:paasmoutput);virtual;
procedure WriteAsmList;virtual;
{$ifdef GDB}
procedure WriteFileLineInfo(var fileinfo : tfileposinfo);
{$endif}
end;
implementation
uses
dos,globtype,globals,systems,i386,
strings,files,verbose
{$ifdef GDB}
,gdb
{$endif GDB}
;
const
line_length = 70;
var
{$ifdef GDB}
n_line : byte; { different types of source lines }
linecount,
includecount : longint;
funcname : pchar;
stabslastfileinfo : tfileposinfo;
{$endif}
lastsec : tsection; { last section type written }
lastsecidx : longint;
lastfileinfo : tfileposinfo;
infile,
lastinfile : pinputfile;
function double2str(d : double) : string;
var
hs : string;
begin
str(d,hs);
{ replace space with + }
if hs[1]=' ' then
hs[1]:='+';
double2str:='0d'+hs
end;
function extended2str(e : extended) : string;
var
hs : string;
begin
str(e,hs);
{ replace space with + }
if hs[1]=' ' then
hs[1]:='+';
extended2str:='0d'+hs
end;
function comp2str(d : bestreal) : string;
type
pdouble = ^double;
var
c : comp;
dd : pdouble;
begin
{$ifdef TP}
c:=d;
{$else}
c:=comp(d);
{$endif}
dd:=pdouble(@c); { this makes a bitwise copy of c into a double }
comp2str:=double2str(dd^);
end;
function getreferencestring(const ref : treference) : string;
var
s : string;
begin
if ref.isintvalue then
s:='$'+tostr(ref.offset)
else
begin
with ref do
begin
{ 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_DEFAULT_SEG then
s:=att_reg2str[segment]+':'
else
s:='';
if assigned(symbol) then
s:=s+symbol^;
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;
if (index<>R_NO) and (base=R_NO) then
Begin
s:=s+'(,'+att_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+'('+att_reg2str[base]+')'
else
if (index<>R_NO) and (base<>R_NO) then
Begin
s:=s+'('+att_reg2str[base]+','+att_reg2str[index];
if scalefactor<>0 then
s:=s+','+tostr(scalefactor)+')'
else
s := s+')';
end;
end;
end;
getreferencestring:=s;
end;
function getopstr(t : byte;o : pointer) : string;
var
hs : string;
begin
case t of
top_reg : getopstr:=att_reg2str[tregister(o)];
top_ref : getopstr:=getreferencestring(preference(o)^);
top_const : getopstr:='$'+tostr(longint(o));
top_symbol : begin
hs:='$'+strpas(pchar(pcsymbol(o)^.symbol));
if pcsymbol(o)^.offset>0 then
hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
else
if pcsymbol(o)^.offset<0 then
hs:=hs+tostr(pcsymbol(o)^.offset);
getopstr:=hs;
end;
else
internalerror(10001);
end;
end;
function getopstr_jmp(t : byte;o : pointer) : string;
var
hs : string;
begin
case t of
top_reg : getopstr_jmp:=att_reg2str[tregister(o)];
top_ref : getopstr_jmp:='*'+getreferencestring(preference(o)^);
top_const : getopstr_jmp:=tostr(longint(o));
top_symbol : begin
hs:=strpas(pchar(pcsymbol(o)^.symbol));
if pcsymbol(o)^.offset>0 then
hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
else
if pcsymbol(o)^.offset<0 then
hs:=hs+tostr(pcsymbol(o)^.offset);
getopstr_jmp:=hs;
end;
else
internalerror(10001);
end;
end;
{****************************************************************************
TI386ATTASMOUTPUT
****************************************************************************}
const
ait_const2str : array[ait_const_32bit..ait_const_8bit] of string[8]=
(#9'.long'#9,#9'.short'#9,#9'.byte'#9);
function ait_section2str(s:tsection;idx:longint):string;
begin
case s of
sec_code : ait_section2str:='.text';
sec_data : ait_section2str:='.data';
sec_bss : if target_info.target=target_i386_Win32 then
ait_section2str:='.section .bss'
else
ait_section2str:='.bss';
sec_idata : ait_section2str:='.section .idata$'+tostr(idx);
sec_edata : ait_section2str:='.section .edata';
else
ait_section2str:='';
end;
{$ifdef GDB}
{ this is needed for line info in data }
funcname:=nil;
case s of
sec_code : n_line:=n_textline;
sec_data : n_line:=n_dataline;
sec_bss : n_line:=n_bssline;
else
n_line:=n_dataline;
end;
{$endif GDB}
LastSec:=s;
LastSecIdx:=idx;
end;
{$ifdef GDB}
procedure ti386attasmlist.WriteFileLineInfo(var fileinfo : tfileposinfo);
var
curr_n : byte;
begin
if not (cs_debuginfo in aktmoduleswitches) then
exit;
{ file changed ? (must be before line info) }
if (fileinfo.fileindex<>0) and
(stabslastfileinfo.fileindex<>fileinfo.fileindex) then
begin
infile:=current_module^.sourcefiles^.get_file(fileinfo.fileindex);
if includecount=0 then
curr_n:=n_sourcefile
else
curr_n:=n_includefile;
if (infile^.path^<>'') then
begin
AsmWriteLn(#9'.stabs "'+lower(BsToSlash(FixPath(infile^.path^,false)))+'",'+
tostr(curr_n)+',0,0,'+'Ltext'+ToStr(IncludeCount));
end;
AsmWriteLn(#9'.stabs "'+lower(FixFileName(infile^.name^))+'",'+
tostr(curr_n)+',0,0,'+'Ltext'+ToStr(IncludeCount));
AsmWriteLn('Ltext'+ToStr(IncludeCount)+':');
inc(includecount);
end;
{ line changed ? }
if (stabslastfileinfo.line<>fileinfo.line) and (fileinfo.line<>0) then
begin
if (n_line=n_textline) and assigned(funcname) and
(target_os.use_function_relative_addresses) then
begin
AsmWriteLn(target_asm.labelprefix+'l'+tostr(linecount)+':');
AsmWrite(#9'.stabn '+tostr(n_line)+',0,'+tostr(fileinfo.line)+','+
target_asm.labelprefix+'l'+tostr(linecount)+' - ');
AsmWritePChar(FuncName);
AsmLn;
inc(linecount);
end
else
AsmWriteLn(#9'.stabd'#9+tostr(n_line)+',0,'+tostr(fileinfo.line));
end;
stabslastfileinfo:=fileinfo;
end;
{$endif GDB}
function getops(p:pai386;var optyp1,optyp2,optyp3:longint):longint;
function doop(ot:longint;op:pointer):longint;
begin
case ot of
top_reg :
begin
doop:=reg_2_type[tregister(op)];
end;
else
internalerror(191918);
end;
end;
var
ops,opx : longint;
begin
ops:=0;
optyp1:=0;
optyp2:=0;
optyp3:=0;
with p^ do
begin
if opxt=0 then
exit;
optyp1:=doop(opx and $f,op1);
optyp2:=doop((opx shr 4) and $f,op2);
end;
getops:=ops;
end;
procedure ti386coffasmlist.WriteTree(p:paasmoutput);
type
twowords=record
word1,word2:word;
end;
textendedarray = array[0..9] of byte; { last longint will be and $ffff }
var
ch : char;
hp : pai;
consttyp : tait;
s : string;
found : boolean;
i,pos,l : longint;
e : extended;
calljmp,
do_line : boolean;
instruc : tasmop;
insops : longint;
fits : boolean;
optyp1,
optyp2,
optyp3 : longint;
begin
if not assigned(p) then
exit;
do_line:=(cs_debuginfo in aktmoduleswitches) or (cs_asm_source in aktglobalswitches);
hp:=pai(p^.first);
while assigned(hp) do
begin
if do_line then
begin
{ I think it is better to write stabs before source line PM }
{$ifdef GDB}
{ write stabs }
if cs_debuginfo in aktmoduleswitches then
begin
if not (hp^.typ in [ait_external,ait_regalloc, ait_regdealloc,ait_stabn,ait_stabs,
ait_label,ait_cut,ait_marker,ait_align,ait_stab_function_name]) then
begin
WriteFileLineInfo(hp^.fileinfo);
end;
end;
{$endif GDB}
{ load infile }
if lastfileinfo.fileindex<>hp^.fileinfo.fileindex then
begin
infile:=current_module^.sourcefiles^.get_file(hp^.fileinfo.fileindex);
{ open only if needed !! }
if (cs_asm_source in aktglobalswitches) then
infile^.open;
{ avoid unnecessary reopens of the same file !! }
lastfileinfo.fileindex:=hp^.fileinfo.fileindex;
{ be sure to change line !! }
lastfileinfo.line:=-1;
end;
{ write source }
if (cs_asm_source in aktglobalswitches) and
not (hp^.typ in [ait_external,ait_stabn,ait_stabs,ait_section,
ait_label,ait_cut,ait_align,ait_stab_function_name]) then
begin
if (infile<>lastinfile) and assigned(lastinfile) then
begin
AsmWriteLn(target_asm.comment+'['+infile^.name^+']');
lastinfile^.close;
end;
if (hp^.fileinfo.line<>lastfileinfo.line) and
(hp^.fileinfo.line<infile^.maxlinebuf) then
begin
if infile^.linebuf^[hp^.fileinfo.line]>=0 then
AsmWriteLn(target_asm.comment+'['+tostr(hp^.fileinfo.line)+'] '+
trimspace(infile^.GetLineStr(hp^.fileinfo.line)));
{ set it to a negative value !
to make that is has been read already !! PM }
infile^.linebuf^[hp^.fileinfo.line]:=-infile^.linebuf^[hp^.fileinfo.line]-1;
end;
lastfileinfo:=hp^.fileinfo;
lastinfile:=infile;
end;
end;
case hp^.typ of
ait_external : ; { external is ignored }
ait_comment : Begin
AsmWrite(target_asm.comment);
AsmWritePChar(pai_asm_comment(hp)^.str);
AsmLn;
End;
{$ifdef DRegAlloc}
ait_regalloc : AsmWriteLn(target_asm.comment+'Register '+att_reg2str[pairegalloc(hp)^.reg]+' allocated');
ait_regdealloc : AsmWriteLn(target_asm.comment+'Register '+att_reg2str[pairegalloc(hp)^.reg]+' released');
{$Else DRegAlloc}
ait_regalloc, ait_regdealloc:;
{$endif DRegAlloc}
ait_align : begin
{ Fix Align bytes for Go32 which uses empty bits }
l:=pai_align(hp)^.aligntype;
if (target_info.target in [target_i386_GO32V1,target_i386_GO32V2]) then
begin
i:=0;
while l>1 do
begin
l:=l shr 1;
inc(i);
end;
l:=i;
end;
{ use correct align opcode }
AsmWrite(#9'.align '+tostr(l));
if pai_align(hp)^.use_op then
AsmWrite(','+tostr(pai_align(hp)^.op));
AsmLn;
end;
ait_section : begin
if pai_section(hp)^.sec<>sec_none then
begin
AsmLn;
AsmWriteLn(ait_section2str(pai_section(hp)^.sec,pai_section(hp)^.idataidx));
end;
end;
ait_datablock : begin
if pai_datablock(hp)^.is_global then
AsmWrite(#9'.comm'#9)
else
AsmWrite(#9'.lcomm'#9);
AsmWritePChar(pai_datablock(hp)^.name);
AsmWriteLn(','+tostr(pai_datablock(hp)^.size));
end;
ait_const_32bit,
ait_const_16bit,
ait_const_8bit : begin
AsmWrite(ait_const2str[hp^.typ]+tostr(pai_const(hp)^.value));
consttyp:=hp^.typ;
l:=0;
repeat
found:=(not (Pai(hp^.next)=nil)) and (Pai(hp^.next)^.typ=consttyp);
if found then
begin
hp:=Pai(hp^.next);
s:=','+tostr(pai_const(hp)^.value);
AsmWrite(s);
inc(l,length(s));
end;
until (not found) or (l>line_length);
AsmLn;
end;
ait_const_symbol : begin
AsmWrite(#9'.long'#9);
AsmWritePChar(pchar(pai_const(hp)^.value));
AsmLn;
end;
ait_const_symbol_offset : begin
AsmWrite(#9'.long'#9);
AsmWritePChar(pai_const_symbol_offset(hp)^.name);
if pai_const_symbol_offset(hp)^.offset>0 then
AsmWrite('+'+tostr(pai_const_symbol_offset(hp)^.offset))
else if pai_const_symbol_offset(hp)^.offset<0 then
AsmWrite(tostr(pai_const_symbol_offset(hp)^.offset));
AsmLn;
end;
ait_const_rva : begin
AsmWrite(#9'.rva'#9);
AsmWritePChar(pchar(pai_const(hp)^.value));
AsmLn;
end;
ait_real_64bit : AsmWriteLn(#9'.double'#9+double2str(pai_double(hp)^.value));
ait_real_32bit : AsmWriteLn(#9'.single'#9+double2str(pai_single(hp)^.value));
ait_real_extended : begin
{$ifdef EXTDEBUG}
AsmWriteLn('# workaround for Extended '+extended2str(pai_extended(hp)^.value));
{$endif}
{ Make sure e is a extended type, bestreal could be
a different type (bestreal) !! (PFV) }
e:=pai_extended(hp)^.value;
AsmWrite(#9'.byte'#9);
for i:=0 to 9 do
begin
if i<>0 then
AsmWrite(',');
AsmWrite(tostr(textendedarray(e)[i]));
end;
AsmLn;
end;
ait_comp : begin
{ comp type is difficult to write so use double }
AsmWriteLn(#9'.double'#9+comp2str(pai_comp(hp)^.value));
end;
ait_direct : begin
AsmWritePChar(pai_direct(hp)^.str);
AsmLn;
{$IfDef GDB}
if strpos(pai_direct(hp)^.str,'.data')<>nil then
n_line:=n_dataline
else if strpos(pai_direct(hp)^.str,'.text')<>nil then
n_line:=n_textline
else if strpos(pai_direct(hp)^.str,'.bss')<>nil then
n_line:=n_bssline;
{$endif GDB}
end;
ait_string : begin
pos:=0;
for i:=1 to pai_string(hp)^.len do
begin
if pos=0 then
begin
AsmWrite(#9'.ascii'#9'"');
pos:=20;
end;
ch:=pai_string(hp)^.str[i-1];
case ch of
#0, {This can't be done by range, because a bug in FPC}
#1..#31,
#128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
'"' : s:='\"';
'\' : s:='\\';
else
s:=ch;
end;
AsmWrite(s);
inc(pos,length(s));
if (pos>line_length) or (i=pai_string(hp)^.len) then
begin
AsmWriteLn('"');
pos:=0;
end;
end;
end;
ait_label : begin
if (pai_label(hp)^.l^.is_used) then
begin
if pai_label(hp)^.l^.is_data and (cs_smartlink in aktmoduleswitches) then
AsmWriteLn('.globl'#9+lab2str(pai_label(hp)^.l));
AsmWriteLn(lab2str(pai_label(hp)^.l)+':');
end;
end;
ait_labeled_instruction : begin
AsmWriteLn(#9+att_op2str[pai_labeled(hp)^._operator]+#9+lab2str(pai_labeled(hp)^.lab));
end;
ait_symbol : begin
if pai_symbol(hp)^.is_global then
begin
AsmWrite('.globl'#9);
AsmWritePChar(pai_symbol(hp)^.name);
AsmLn;
end;
if target_info.target=target_i386_linux then
begin
AsmWrite(#9'.type'#9);
AsmWritePChar(pai_symbol(hp)^.name);
if assigned(pai(hp^.next)) and
(pai(hp^.next)^.typ in [ait_const_symbol,ait_const_symbol_offset,
ait_const_32bit,ait_const_16bit,ait_const_8bit,ait_datablock,
ait_real_64bit,ait_real_32bit,ait_real_extended,ait_comp]) then
AsmWriteLn(',@object')
else
AsmWriteLn(',@function');
end;
AsmWritePChar(pai_symbol(hp)^.name);
AsmWriteLn(':');
end;
ait_instruction :
begin { writes an instruction, highly table driven }
{ get local info }
instruc:=pai386(hp)^._operator;
insops:=getops(pai386(hp),optyp1,optyp2,optyp3);
{ get the correct instruction from the it table }
if itcache^[instruc]<>-1 then
i:=itcache^[instruc]
else
i:=0;
fits:=false;
while (not fits) do
begin
if (it[i].i=instruc) and (itcache^[instruc]=-1) then
itcache^[instruc]:=i;
if (it[i].i=instruc) and (it[i].ops=insops) then
begin
{ first fit }
case insops of
0 : begin
fits:=true;
break;
end;
1 : Begin
if (optyp1 and it[i].o1)<>0 then
Begin
fits:=true;
break;
end;
{ I consider sign-extended 8bit value to }
{ be equal to immediate 8bit therefore }
{ convert... }
if (optyp1 = ao_imm8) then
Begin
{ check if this is a simple sign extend. }
if (it[i].o1<>ao_imm8s) then
Begin
fits:=true;
break;
end;
end;
end;
2 : if ((optyp1 and it[i].o1)<>0) and
((optyp2 and it[i].o2)<>0) then
Begin
fits:=true;
break;
end
{ if the operands can be swaped }
{ then swap them }
else if ((it[i].m and af_d)<>0) and
((optyp1 and it[i].o2)<>0) and
((optyp2 and it[i].o1)<>0) then
begin
fits:=true;
break;
end;
3 : if ((optyp1 and it[i].o1)<>0) and
((optyp2 and it[i].o2)<>0) and
((optyp3 and it[i].o3)<>0) then
Begin
fits:=true;
break;
end;
end; { end case }
end;
if it[i].i=A_NONE then
InternalError(191919);
end;
{ Old Writer code }
if (pai386(hp)^._operator=A_PUSH) and
(pai386(hp)^.size=S_W) and
(pai386(hp)^.op1t=top_const) then
begin
{$ifdef EXTDEBUG}
AsmWriteLn('# workaround for pushw'#9+tostr(longint(pai386(hp)^.op1)));
{$endif}
AsmWriteLn(#9'.byte 0x66,0x68');
AsmWriteLn(#9'.word '+tostr(longint(pai386(hp)^.op1)));
end
else
begin
calljmp:=(pai386(hp)^._operator=A_CALL) or (pai386(hp)^._operator=A_JMP);
{ call maybe not translated to calll }
if calljmp then
s:=#9+att_op2str[pai386(hp)^._operator]
else
s:=#9+att_op2str[pai386(hp)^._operator]+att_opsize2str[pai386(hp)^.size];
{ process operands }
if pai386(hp)^.op1t<>top_none then
begin
{ call and jmp need an extra handling }
{ this code is only called if jmp isn't a labeled instruction }
if calljmp then
s:=s+#9+getopstr_jmp(pai386(hp)^.op1t,pai386(hp)^.op1)
else
begin
s:=s+#9+getopstr(pai386(hp)^.op1t,pai386(hp)^.op1);
if pai386(hp)^.op3t<>top_none then
begin
if pai386(hp)^.op2t<>top_none then
s:=s+','+getopstr(pai386(hp)^.op2t,
pointer(longint(twowords(pai386(hp)^.op2).word1)));
s:=s+','+getopstr(pai386(hp)^.op3t,
pointer(longint(twowords(pai386(hp)^.op2).word2)));
end
else
if pai386(hp)^.op2t<>top_none then
s:=s+','+getopstr(pai386(hp)^.op2t,pai386(hp)^.op2);
end;
end;
AsmWriteLn(s);
end;
end;
{$ifdef GDB}
ait_stabs : begin
AsmWrite(#9'.stabs ');
AsmWritePChar(pai_stabs(hp)^.str);
AsmLn;
end;
ait_stabn : begin
AsmWrite(#9'.stabn ');
AsmWritePChar(pai_stabn(hp)^.str);
AsmLn;
end;
ait_force_line : begin
stabslastfileinfo.line:=0;
end;
ait_stab_function_name:
funcname:=pai_stab_function_name(hp)^.str;
{$endif GDB}
ait_cut : begin
{ only reset buffer if nothing has changed }
if AsmSize=AsmStartSize then
AsmClear
else
begin
AsmClose;
DoAssemble;
if pai_cut(hp)^.EndName then
IsEndFile:=true;
AsmCreate;
end;
{ avoid empty files }
while assigned(hp^.next) and (pai(hp^.next)^.typ in [ait_cut,ait_section,ait_comment]) do
begin
if pai(hp^.next)^.typ=ait_section then
begin
lastsec:=pai_section(hp^.next)^.sec;
lastsecidx:=pai_section(hp^.next)^.idataidx;
end;
hp:=pai(hp^.next);
end;
{$ifdef GDB}
{ force write of filename }
FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
includecount:=0;
funcname:=nil;
WriteFileLineInfo(hp^.fileinfo);
{$endif GDB}
if lastsec<>sec_none then
AsmWriteLn(ait_section2str(lastsec,lastsecidx));
AsmStartSize:=AsmSize;
end;
ait_marker : ;
else
internalerror(10000);
end;
hp:=pai(hp^.next);
end;
end;
procedure ti386coffasmlist.WriteAsmList;
var
p:dirstr;
n:namestr;
e:extstr;
{$ifdef GDB}
fileinfo : tfileposinfo;
{$endif GDB}
begin
{$ifdef EXTDEBUG}
if assigned(current_module^.mainsource) then
Comment(v_info,'Start writing att-styled assembler output for '+current_module^.mainsource^);
{$endif}
LastSec:=sec_none;
{$ifdef GDB}
FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
{$endif GDB}
FillChar(lastfileinfo,sizeof(lastfileinfo),0);
LastInfile:=nil;
if assigned(current_module^.mainsource) then
fsplit(current_module^.mainsource^,p,n,e)
else
begin
p:=inputdir;
n:=inputfile;
e:=inputextension;
end;
{ to get symify to work }
AsmWriteLn(#9'.file "'+FixFileName(n+e)+'"');
{$ifdef GDB}
n_line:=n_bssline;
funcname:=nil;
linecount:=1;
includecount:=0;
fileinfo.fileindex:=1;
fileinfo.line:=1;
{ Write main file }
WriteFileLineInfo(fileinfo);
{$endif GDB}
AsmStartSize:=AsmSize;
countlabelref:=false;
If (cs_debuginfo in aktmoduleswitches) then
WriteTree(debuglist);
WriteTree(codesegment);
WriteTree(datasegment);
WriteTree(consts);
WriteTree(rttilist);
WriteTree(bsssegment);
Writetree(importssection);
Writetree(exportssection);
Writetree(resourcesection);
countlabelref:=true;
AsmLn;
{$ifdef EXTDEBUG}
if assigned(current_module^.mainsource) then
comment(v_info,'Done writing att-styled assembler output for '+current_module^.mainsource^);
{$endif EXTDEBUG}
end;
end.
{
$Log$
Revision 1.1 1999-01-10 15:37:51 peter
* moved some tables from ra386*.pas -> i386.pas
+ start of coff writer
* renamed asmutils unit to rautils
}

View File

@ -94,6 +94,9 @@ uses
{$ifndef NoAg386Int}
,ag386int
{$endif NoAg386Int}
{$ifdef Ag386Cof}
,ag386cof
{$endif Ag386Cof}
{$endif}
{$ifdef m68k}
{$ifndef NoAg68kGas}
@ -472,6 +475,10 @@ var
begin
case aktoutputformat of
{$ifdef i386}
{$ifdef Ag386Cof}
as_i386_coff :
a:=new(pi386coffasmlist,Init);
{$endif Ag386Cof}
{$ifndef NoAg386Att}
as_i386_o,
as_i386_o_aout,
@ -533,7 +540,12 @@ end;
end.
{
$Log$
Revision 1.33 1998-12-11 00:02:45 peter
Revision 1.34 1999-01-10 15:37:52 peter
* moved some tables from ra386*.pas -> i386.pas
+ start of coff writer
* renamed asmutils unit to rautils
Revision 1.33 1998/12/11 00:02:45 peter
+ globtype,tokens,version unit splitted from globals
Revision 1.32 1998/11/06 09:46:46 pierre

View File

@ -24,20 +24,34 @@ unit i386;
interface
{ By default we want everything }
{$define ATTOP}
{$define INTELOP}
{$define ITTABLE}
{ We Don't need the intel style opcodes if we don't have a intel
reader or generator (PFV) }
{$ifdef NORA386INT}
{$ifdef NOAG386NSM}
{$ifdef NOAG386INT}
{$define NOINTOP}
{$undef INTELOP}
{$endif}
{$endif}
{$endif}
{ We Don't need the AT&T style opcodes if we don't have a AT&T
reader or generator (PFV) }
{$ifdef NORA386ATT}
{$ifdef NOAG386ATT}
{$undef ATTOP}
{$endif}
{$endif}
{ We Don't need the it table if no assembler parser is selected }
{$define ITTABLE}
{$ifdef NORA386INT}
{$ifdef NORA386ATT}
{$define NOITTABLE}
{.$undef ITTABLE}
{$endif}
{$endif}
@ -47,6 +61,57 @@ unit i386;
const
extended_size = 10;
ao_unknown = $0;
ao_none = $ff;
ao_reg8 = $1; { 8 bit reg }
ao_reg16 = $2; { 16 bit reg }
ao_reg32 = $4; { 32 bit reg }
ao_reg = (ao_reg8 or ao_reg16 or ao_reg32);
ao_wordreg = (ao_reg16 or ao_reg32);
ao_acc = $8; { Accumulat or %al or %ax or %eax }
ao_sreg2 = $10; { 2 bit segment register }
ao_sreg3 = $20; { 3 bit segment register }
ao_mmxreg = $40; { mmx register }
ao_floatacc = $80; { Float stack top %st(0) }
ao_otherfloatreg = $100; { Float register different from st0 }
ao_floatreg = ao_otherfloatreg or ao_floatacc; { all float regs }
ao_imm8 = $200; { 8 bit immediate }
ao_imm8S = $400; { 8 bit immediate sign extended }
ao_imm16 = $800; { 16 bit immediate }
ao_imm32 = $1000; { 32 bit immediate }
ao_imm1 = $2000; { 1 bit immediate }
ao_imm = (ao_imm8 or ao_imm8S or ao_imm16 or ao_imm32);
ao_immunknown = ao_imm32; { for unknown expressions }
ao_disp8 = $4000; { 8 bit displacement (for jumps) }
ao_disp16 = $8000; { 16 bit displacement }
ao_disp32 = $10000; { 32 bit displacement }
ao_disp = (ao_disp8 or ao_disp16 or ao_disp32);
ao_dispunknown = ao_disp32;
ao_mem8 = $20000;
ao_mem16 = $40000;
ao_mem32 = $80000;
ao_baseindex = $100000;
ao_mem = (ao_disp or ao_mem8 or ao_mem16 or ao_mem32 or ao_baseindex);
ao_wordmem = (ao_mem16 or ao_mem32 or ao_disp or ao_baseindex);
ao_bytemem = (ao_mem8 or ao_disp or ao_baseindex);
ao_inoutportreg = $200000; { register to hold in/out port addr = dx }
ao_shiftcount = $400000; { register to hold shift cound = cl }
ao_control = $800000; { Control register }
ao_debug = $1000000; { Debug register }
ao_test = $2000000; { Test register }
ao_abs32 = $4000000;
ao_jumpabsolute = $8000000;
ao_implicitregister = (ao_inoutportreg or ao_shiftcount or ao_acc or ao_floatacc);
type
tasmop = (
A_MOV,A_MOVZX,A_MOVSX,A_LABEL,A_ADD,
@ -104,42 +169,46 @@ unit i386;
A_PSUBUSB,A_PSUBUSW,A_PSUBW,A_PUNPCKHBW,A_PUNPCKHDQ,
A_PUNPCKHWD,A_PUNPCKLBW,A_PUNPCKLDQ,A_PUNPCKLWD,A_PXOR,
{ KNI instructions: (intel katmai) }
A_ADDPS,A_ADDSS,A_ANDNPS,A_ANDNSS,A_ANDPS,A_ANDSS,A_CMPEQPS,A_CMPEQSS,
A_CMPLEPS,A_CMPLESS,A_CMPLTPS,A_CMPLTSS,A_CMPNEQPS,A_CMPNEQSS,
A_CMPNLEPS,A_CMPNLESS,A_CMPNLTPS,A_CMPNLTSS,A_CMPORDPS,A_CMPORDSS,
A_CMPUNORDPS,A_CMPUNORDSS,A_COMISS,A_CVTPI2PS,A_CVTPS2PI,
A_CVTSI2SS,A_CVTTPS2PI,A_CVTTSS2SI,A_DIVPS,A_DIVSS,A_FXRSTOR,A_FXSAVE,
A_LDMXCSR,A_MASKMOVQ,A_MAXPS,A_MAXSS,A_MINPS,A_MINSS,A_MOVAPS,
A_MOVHPS,A_MOVLPS,A_MOVMSKPS,A_MOVNTPS,A_MOVNTQ,A_MOVSS,A_MOVUPS,
A_MULPS,A_MULSS,A_ORPS,A_PAVGB,A_PAVGW,A_PEXTRW,A_PINSRW,A_PMAXSW,
A_PMAXUB,A_PMINSW,A_PMINUB,A_PMOVMSKB,A_PMULHUW,A_PREFETCHNT,
A_PREFETCH0,A_PREFETCH1,A_PREFETCH2,A_PSADBW,A_PSHUFW,A_RCPPS,A_RCPSS,
A_RSQRTPS,A_RSQRTSS,A_SFENCE,A_SHUFPS,A_SQRTPS,A_SQRTSS,A_STMXCSR,
A_SUBPS,A_SUBSS,A_UCOMISS,A_UNPCKHPS,A_UNPCKLPS,A_XORPS,
A_ADDPS,A_ADDSS,A_ANDNPS,A_ANDNSS,A_ANDPS,A_ANDSS,A_CMPEQPS,A_CMPEQSS,
A_CMPLEPS,A_CMPLESS,A_CMPLTPS,A_CMPLTSS,A_CMPNEQPS,A_CMPNEQSS,
A_CMPNLEPS,A_CMPNLESS,A_CMPNLTPS,A_CMPNLTSS,A_CMPORDPS,A_CMPORDSS,
A_CMPUNORDPS,A_CMPUNORDSS,A_COMISS,A_CVTPI2PS,A_CVTPS2PI,
A_CVTSI2SS,A_CVTTPS2PI,A_CVTTSS2SI,A_DIVPS,A_DIVSS,A_FXRSTOR,A_FXSAVE,
A_LDMXCSR,A_MASKMOVQ,A_MAXPS,A_MAXSS,A_MINPS,A_MINSS,A_MOVAPS,
A_MOVHPS,A_MOVLPS,A_MOVMSKPS,A_MOVNTPS,A_MOVNTQ,A_MOVSS,A_MOVUPS,
A_MULPS,A_MULSS,A_ORPS,A_PAVGB,A_PAVGW,A_PEXTRW,A_PINSRW,A_PMAXSW,
A_PMAXUB,A_PMINSW,A_PMINUB,A_PMOVMSKB,A_PMULHUW,A_PREFETCHNT,
A_PREFETCH0,A_PREFETCH1,A_PREFETCH2,A_PSADBW,A_PSHUFW,A_RCPPS,A_RCPSS,
A_RSQRTPS,A_RSQRTSS,A_SFENCE,A_SHUFPS,A_SQRTPS,A_SQRTSS,A_STMXCSR,
A_SUBPS,A_SUBSS,A_UCOMISS,A_UNPCKHPS,A_UNPCKLPS,A_XORPS,
{ 3Dnow instructions: (amd k6-2) }
A_FEMMS,A_PAVGUSB,A_PF2ID,A_PFACC,A_PFADD,A_PFCMPEQ,A_PFCMPGE,
A_PFCMPGT,A_PFMAX,A_PFMIN,A_PFMUL,A_PFRCP,A_PFRCPIT1,A_PFRCPIT2,
A_PFRSQIT1,A_PFRSQRT,A_PFSUB,A_PFSUBR,A_PI2FD,A_PMULHRW,A_PREFETCH,
A_PREFETCHW
A_FEMMS,A_PAVGUSB,A_PF2ID,A_PFACC,A_PFADD,A_PFCMPEQ,A_PFCMPGE,
A_PFCMPGT,A_PFMAX,A_PFMIN,A_PFMUL,A_PFRCP,A_PFRCPIT1,A_PFRCPIT2,
A_PFRSQIT1,A_PFRSQRT,A_PFSUB,A_PFSUBR,A_PI2FD,A_PMULHRW,A_PREFETCH,
A_PREFETCHW
);
const
firstop = A_MOV;
lastop = A_PREFETCHW;
firstop = low(tasmop);
lastop = high(tasmop);
type
{ enumeration for registers, don't change order. }
{ this enum is used by the register size conversions }
tregister = (
R_NO,R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
{ enumeration for registers, don't change this }
{ it's used by the register size converstaions }
tregister = (R_NO,
R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI,
R_AL,R_CL,R_DL,R_BL,R_AH,R_CH,R_BH,R_DH,
{ for an easier assembler generation }
R_DEFAULT_SEG,R_CS,R_DS,R_ES,R_FS,R_GS,R_SS,
R_ST,R_ST0,R_ST1,R_ST2,R_ST3,R_ST4,R_ST5,R_ST6,R_ST7,
R_MM0,R_MM1,R_MM2,R_MM3,R_MM4,R_MM5,R_MM6,R_MM7,
R_XMM0,R_XMM1,R_XMM2,R_XMM3,R_XMM4,R_XMM5,R_XMM6,R_XMM7
);
R_XMM0,R_XMM1,R_XMM2,R_XMM3,R_XMM4,R_XMM5,R_XMM6,R_XMM7);
const
firstreg = low(tregister);
lastreg = high(tregister);
type
{ S_NO = No Size of operand }
{ S_B = Byte size operand }
{ S_W = Word size operand }
@ -159,17 +228,12 @@ unit i386;
{ S_FV = floating point vector 4*32 bit = 128 bit (for KNI) }
topsize = (S_NO,S_B,S_W,S_L,S_BW,S_BL,S_WL,
S_IS,S_IL,S_IQ,S_FS,S_FL,S_FX,S_D,S_FV);
{ S_FS and S_FL added
S_X renamed to S_FX
S_IL added
S_S and S_Q renamed to S_IQ and S_IS
S_F? means a real load or store or read
added to distinguish between longint l suffix like 'movl'
and double l suffix 'fldl'
distinction needed for intel output !! }
const
firstopsize = low(topsize);
lastopsize = high(topsize);
plocation = ^tlocation;
type
{ information about the location of an operand }
{ LOC_FPUSTACK FPU stack }
{ LOC_REGISTER in a processor register }
@ -179,7 +243,6 @@ unit i386;
{ LOC_FLAGS boolean results only, flags are set }
{ LOC_CREGISTER register which shouldn't be modified }
{ LOC_INVALID added for tracking problems}
tloc = (LOC_INVALID,LOC_FPU,LOC_REGISTER,LOC_MEM,LOC_REFERENCE,LOC_JUMP,
LOC_FLAGS,LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER);
@ -187,7 +250,6 @@ unit i386;
F_A,F_AE,F_B,F_BE);
preference = ^treference;
treference = record
base,segment,index : tregister;
offset : longint;
@ -198,6 +260,7 @@ unit i386;
scalefactor : byte;
end;
plocation = ^tlocation;
tlocation = record
case loc : tloc of
LOC_MEM,LOC_REFERENCE : (reference : treference);
@ -230,20 +293,47 @@ unit i386;
(A_JE,A_JNE,A_JG,A_JL,A_JGE,A_JLE,A_JC,A_JNC,
A_JA,A_JAE,A_JB,A_JBE);
flag_2_set : array[F_E..F_BE] of tasmop = { v-- the GAS didn't know setc }
flag_2_set : array[F_E..F_BE] of tasmop =
(A_SETE,A_SETNE,A_SETG,A_SETL,A_SETGE,A_SETLE,A_SETB,A_SETAE,
A_SETA,A_SETAE,A_SETB,A_SETBE);
const
{ arrays for size and type determination }
reg_2_size: array[firstreg..lastreg] of topsize = (
S_NO,S_L,S_L,S_L,S_L,S_L,S_L,S_L,S_L,
S_W,S_W,S_W,S_W,S_W,S_W,S_W,S_W,
S_B,S_B,S_B,S_B,S_B,S_B,S_B,S_B,
{ segment register }
S_W,S_W,S_W,S_W,S_W,S_W,S_W,
{ can also be S_S or S_T - must be checked at run-time }
S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,
S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D,
S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D
);
{ register type definition table for easier searching }
reg_2_type:array[firstreg..lastreg] of longint = (
ao_none,ao_reg32,ao_reg32,ao_reg32,ao_reg32,ao_reg32,ao_reg32,ao_reg32,ao_reg32,
ao_reg16,ao_reg16,ao_reg16,ao_reg16,ao_reg16,ao_reg16,ao_reg16,ao_reg16,
ao_reg8,ao_reg8,ao_reg8,ao_reg8,ao_reg8,ao_reg8,ao_reg8,ao_reg8,
ao_none,ao_sreg2,ao_sreg2,ao_sreg2,ao_sreg3,ao_sreg3,ao_sreg2,
ao_floatacc,ao_floatacc,ao_floatreg,ao_floatreg,ao_floatreg,ao_floatreg,
ao_floatreg,ao_floatreg,ao_floatreg,ao_mmxreg,ao_mmxreg,ao_mmxreg,ao_mmxreg,
ao_mmxreg,ao_mmxreg,ao_mmxreg,ao_mmxreg,ao_mmxreg,ao_mmxreg,ao_mmxreg,ao_mmxreg,
ao_mmxreg,ao_mmxreg,ao_mmxreg,ao_mmxreg
);
const_2_type: array[S_NO..S_FS] of longint =
(0,ao_imm8,ao_imm16,ao_imm32,0,0,0,ao_imm16,ao_imm32,0,ao_imm32);
const
{ operand types }
top_none = 0;
top_reg = 1;
top_ref = 2;
{ a constant can be also written as treference }
top_const = 3;
{ this is for calls }
top_symbol = 4;
top_none = 0;
top_reg = 1;
top_ref = 2;
top_const = 3; { a constant can be also written as treference }
top_symbol = 4; { this is for calls }
stack_pointer = R_ESP;
@ -372,96 +462,8 @@ unit i386;
{ generates an help record for constants }
function newcsymbol(const s : string;l : longint) : pcsymbol;
const
ao_unknown = $0;
{ 8 bit reg }
ao_reg8 = $1;
{ 16 bit reg }
ao_reg16 = $2;
{ 32 bit reg }
ao_reg32 = $4;
{ see far below for ao_reg const assignment }
{ for push/pop operands }
ao_wordreg = (ao_reg16 or ao_reg32);
ao_imm8 = $8; { 8 bit immediate }
ao_imm8S = $10; { 8 bit immediate sign extended }
ao_imm16 = $20; { 16 bit immediate }
ao_imm32 = $40; { 32 bit immediate }
ao_imm1 = $80; { 1 bit immediate }
{ for unknown expressions }
ao_immunknown = ao_imm32;
{ gen'l immediate }
ao_imm = (ao_imm8 or ao_imm8S or ao_imm16 or ao_imm32);
ao_disp8 = $200; { 8 bit displacement (for jumps) }
ao_disp16 = $400; { 16 bit displacement }
ao_disp32 = $800; { 32 bit displacement }
{ general displacement }
ao_disp = (ao_disp8 or ao_disp16 or ao_disp32);
{ for unknown size displacements }
ao_dispunknown = ao_disp32;
ao_mem8 = $1000;
ao_mem16 = $2000;
ao_mem32 = $4000;
ao_baseindex = $8000;
{ general mem }
ao_mem = (ao_disp or ao_mem8 or ao_mem16 or ao_mem32 or ao_baseindex);
ao_wordmem = (ao_mem16 or ao_mem32 or ao_disp or ao_baseindex);
ao_bytemem = (ao_mem8 or ao_disp or ao_baseindex);
{ register to hold in/out port addr = dx }
ao_inoutportreg = $10000;
{ register to hold shift cound = cl }
ao_shiftcount = $20000;
ao_control = $40000; { Control register }
ao_debug = $80000; { Debug register }
ao_test = $100000; { Test register }
{ suggestion from PM }
{ st0 is also a float reg }
{ao_floatreg = $200000; }{ Float register }
ao_otherfloatreg = $200000; { Float register different from st0 }
ao_floatacc = $400000; { Float stack top %st(0) }
ao_floatreg = ao_otherfloatreg or ao_floatacc; { all float regs }
{ Florian correct this if it is wrong
but it seems necessary for ratti386 to accept the code
in i386/math.inc !! }
{ 2 bit segment register }
ao_sreg2 = $800000;
{ 3 bit segment register }
ao_sreg3 = $1000000;
{ Accumulat or %al or %ax or %eax }
ao_acc = $2000000;
ao_implicitregister = (ao_inoutportreg or ao_shiftcount or ao_acc or ao_floatacc);
ao_jumpabsolute = $4000000;
ao_abs8 = $08000000;
ao_abs16 = $10000000;
ao_abs32 = $20000000;
ao_abs = (ao_abs8 or ao_abs16 or ao_abs32);
{ packed int or float number, 8*8 bit = 4*16 bit = 2*32 bit = 64 bit
- for MMX and 3DNow! }
ao_reg64 = $40000000;
{ floating point vector, 4*32 bit = 128 bit
- for KNI }
ao_reg128 = $80000000;
{ bitmask for any possible register }
ao_reg = (ao_reg8 or ao_reg16 or ao_reg32 or ao_reg64 or ao_reg128);
ao_none = $ff;
{ this is for the code generator }
{ set if operands are words or dwords }
af_w = $1;
@ -497,15 +499,18 @@ unit i386;
o1,o2,o3 : longint;
end;
const
last_instruction_in_cache = A_EMMS;
{$ifdef ITTABLE}
type
tins_cache = array[A_MOV..last_instruction_in_cache] of longint;
titcache = array[firstop..lastop] of longint;
pitcache = ^titcache;
var
ins_cache : tins_cache;
itcache : pitcache;
{$ifndef NOITTABLE}
const
{ only tokens up to and including lastop_ittable }
{ are checked for validity, otherwise... }
lastop_ittable = A_EMMS;
it : array[0..442] of ttemplate = (
(i : A_MOV;ops : 2;oc : $a0;eb : ao_none;m : af_dw or NoModrm;o1 : ao_disp32;o2 : ao_acc;o3 : 0 ),
(i : A_MOV;ops : 2;oc : $88;eb : ao_none;m : af_dw or Modrm;o1 : ao_reg;o2 : ao_reg or ao_mem;o3 : 0 ),
@ -969,9 +974,9 @@ unit i386;
(i : A_REPE;ops : 0;oc : $f3;eb : ao_none;m : NoModrm;o1 : 0;o2 : 0;o3 : 0),
(i : A_REPNE;ops : 0;oc : $f2;eb : ao_none;m : NoModrm;o1 : 0;o2 : 0;o3 : 0),
(i : A_CPUID;ops : 0;oc : $0fa2;eb : ao_none;m : NoModrm;o1 : 0;o2 : 0;o3 : 0),
(i : A_EMMS;ops : 0;oc : $0f77;eb : ao_none;m : NoModrm;o1 : 0;o2 : 0;o3 : 0),
(i : A_EMMS;ops : 0;oc : $0f77;eb : ao_none;m : NoModrm;o1 : 0;o2 : 0;o3 : 0),
{ MMX instructions: }
(* TODO
(* TODO
A_EMMS,A_MOVD,A_MOVQ,A_PACKSSDW,A_PACKSSWB,A_PACKUSWB,
A_PADDB,A_PADDD,A_PADDSB,A_PADDSW,A_PADDUSB,A_PADDUSW,
A_PADDW,A_PAND,A_PANDN,A_PCMPEQB,A_PCMPEQD,A_PCMPEQW,
@ -984,33 +989,34 @@ unit i386;
{ KNI instructions: (intel katmai) }
(* TODO - add syntax description for these opcodes:
really required for the first turn??
A_ADDPS,A_ADDSS,A_ANDNPS,A_ANDNSS,A_ANDPS,A_ANDSS,A_CMPEQPS,A_CMPEQSS,
A_CMPLEPS,A_CMPLESS,A_CMPLTPS,A_CMPLTSS,A_CMPNEQPS,A_CMPNEQSS,
A_CMPNLEPS,A_CMPNLESS,A_CMPNLTPS,A_CMPNLTSS,A_CMPORDPS,A_CMPORDSS,
A_CMPUNORDPS,A_CMPUNORDSS,A_COMISS,A_CVTPI2PS,A_CVTPS2PI,
A_CVTSI2SS,A_CVTTPS2PI,A_CVTTSS2SI,A_DIVPS,A_DIVSS,A_FXRSTOR,A_FXSAVE,
A_LDMXCSR,A_MASKMOVQ,A_MAXPS,A_MAXSS,A_MINPS,A_MINSS,A_MOVAPS,
A_MOVHPS,A_MOVLPS,A_MOVMSKPS,A_MOVNTPS,A_MOVNTQ,A_MOVSS,A_MOVUPS,
A_MULPS,A_MULSS,A_ORPS,A_PAVGB,A_PAVGW,A_PEXTRW,A_PINSRW,A_PMAXSW,
A_PMAXUB,A_PMINSW,A_PMINUB,A_PMOVMSKB,A_PMULHUW,A_PREFETCHNT,
A_PREFETCH0,A_PREFETCH1,A_PREFETCH2,A_PSADBW,A_PSHUFW,A_RCPPS,A_RCPSS,
A_RSQRTPS,A_RSQRTSS,A_SFENCE,A_SHUFPS,A_SQRTPS,A_SQRTSS,A_STMXCSR,
A_SUBPS,A_SUBSS,A_UCOMISS,A_UNPCKHPS,A_UNPCKLPS,A_XORPS,
*)
A_ADDPS,A_ADDSS,A_ANDNPS,A_ANDNSS,A_ANDPS,A_ANDSS,A_CMPEQPS,A_CMPEQSS,
A_CMPLEPS,A_CMPLESS,A_CMPLTPS,A_CMPLTSS,A_CMPNEQPS,A_CMPNEQSS,
A_CMPNLEPS,A_CMPNLESS,A_CMPNLTPS,A_CMPNLTSS,A_CMPORDPS,A_CMPORDSS,
A_CMPUNORDPS,A_CMPUNORDSS,A_COMISS,A_CVTPI2PS,A_CVTPS2PI,
A_CVTSI2SS,A_CVTTPS2PI,A_CVTTSS2SI,A_DIVPS,A_DIVSS,A_FXRSTOR,A_FXSAVE,
A_LDMXCSR,A_MASKMOVQ,A_MAXPS,A_MAXSS,A_MINPS,A_MINSS,A_MOVAPS,
A_MOVHPS,A_MOVLPS,A_MOVMSKPS,A_MOVNTPS,A_MOVNTQ,A_MOVSS,A_MOVUPS,
A_MULPS,A_MULSS,A_ORPS,A_PAVGB,A_PAVGW,A_PEXTRW,A_PINSRW,A_PMAXSW,
A_PMAXUB,A_PMINSW,A_PMINUB,A_PMOVMSKB,A_PMULHUW,A_PREFETCHNT,
A_PREFETCH0,A_PREFETCH1,A_PREFETCH2,A_PSADBW,A_PSHUFW,A_RCPPS,A_RCPSS,
A_RSQRTPS,A_RSQRTSS,A_SFENCE,A_SHUFPS,A_SQRTPS,A_SQRTSS,A_STMXCSR,
A_SUBPS,A_SUBSS,A_UCOMISS,A_UNPCKHPS,A_UNPCKLPS,A_XORPS,
*)
{ 3Dnow instructions: (amd k6-2) }
(* TODO
A_FEMMS,A_PAVGUSB,A_PF2ID,A_PFACC,A_PFADD,A_PFCMPEQ,A_PFCMPGE,
A_PFCMPGT,A_PFMAX,A_PFMIN,A_PFMUL,A_PFRCP,A_PFRCPIT1,A_PFRCPIT2,
A_PFRSQIT1,A_PFRSQRT,A_PFSUB,A_PFSUBR,A_PI2FD,A_PMULHRW,A_PREFETCH,
A_PREFETCHW,
*)
(* TODO
A_FEMMS,A_PAVGUSB,A_PF2ID,A_PFACC,A_PFADD,A_PFCMPEQ,A_PFCMPGE,
A_PFCMPGT,A_PFMAX,A_PFMIN,A_PFMUL,A_PFRCP,A_PFRCPIT1,A_PFRCPIT2,
A_PFRSQIT1,A_PFRSQRT,A_PFSUB,A_PFSUBR,A_PI2FD,A_PMULHRW,A_PREFETCH,
A_PREFETCHW,
*)
(i : A_NONE));
{$endif NOITTABLE}
{$endif ITTABLE}
{****************************************************************************
Assembler Mnemoics
****************************************************************************}
{$ifdef ATTOP}
const
att_op2str : array[firstop..lastop] of string[7] =
('mov','movz','movs','','add',
@ -1066,26 +1072,26 @@ unit i386;
'psrld','psrlq','psrlw','psubb','psubd','psubsb','psubsw',
'psubusb','psubusw','psubw','punpckhbw','punpckhdq',
'punpckhwd','punpcklbw','punpckldq','punpcklwd','pxor',
{ KNI instructions (intel katmai)
{ KNI instructions (intel katmai)
- sorry, dont know how ATT mnemonics will be called }
'addps','addss','andnps','andnss','andps','andss','cmpeqps','cmpeqps',
'cmpleps','cmpless','cmpltps','cmpltss','cmpneqps','cmpneqss',
'cmpnleps','cmpnless','cmpnltps','cmpnltss','cmpordps','cmpordss',
'cmpunordps','cmpunordss','comiss','cvtpi2ps','cvtps2pi','cvtsi2ss',
'cvttps2pi','cvttss2si','divps','divss','fxrstor','fxsave','ldmxcsr',
'maskmovq','maxps','maxss','minps','minss','movaps','movhps','movlps',
'movmskps','movntps','movntq','movss','movups','mulps','mulss','orps',
'pavgb','pavgw','pextrw','pinsrw','pmaxsw','pmaxub','pminsw','pminub',
'pmovmskb','pmulhuw','prefetchnt','prefetch0','prefetch1','prefetch2',
'psadbw','pshufw','rcpps','rcpss','rsqrtps','rsqrtss','sfence',
'shufps','sqrtps','sqrtss','stmxcsr','subps','subss','ucomiss',
'unpckhps','unpcklps','xorps',
{ 3Dnow instructions (amd k6-2)
'addps','addss','andnps','andnss','andps','andss','cmpeqps','cmpeqps',
'cmpleps','cmpless','cmpltps','cmpltss','cmpneqps','cmpneqss',
'cmpnleps','cmpnless','cmpnltps','cmpnltss','cmpordps','cmpordss',
'cmpunordps','cmpunordss','comiss','cvtpi2ps','cvtps2pi','cvtsi2ss',
'cvttps2pi','cvttss2si','divps','divss','fxrstor','fxsave','ldmxcsr',
'maskmovq','maxps','maxss','minps','minss','movaps','movhps','movlps',
'movmskps','movntps','movntq','movss','movups','mulps','mulss','orps',
'pavgb','pavgw','pextrw','pinsrw','pmaxsw','pmaxub','pminsw','pminub',
'pmovmskb','pmulhuw','prefetchnt','prefetch0','prefetch1','prefetch2',
'psadbw','pshufw','rcpps','rcpss','rsqrtps','rsqrtss','sfence',
'shufps','sqrtps','sqrtss','stmxcsr','subps','subss','ucomiss',
'unpckhps','unpcklps','xorps',
{ 3Dnow instructions (amd k6-2)
- sorry, dont know how ATT mnemonics are called }
'femms','pavgusb','pf2id','pfacc','pfadd','pfcmpeq','pfcmpge',
'pfcmpgt','pfmax','pfmin','pfmul','pfrcp','pfrcpit1','pfrcpit2',
'pfrsqit1','pfrsqrt','pfsub','pfsubr','pi2fd','pmulhrw','prefetch',
'prefetchw'
'femms','pavgusb','pf2id','pfacc','pfadd','pfcmpeq','pfcmpge',
'pfcmpgt','pfmax','pfmin','pfmul','pfrcp','pfrcpit1','pfrcpit2',
'pfrsqit1','pfrsqrt','pfsub','pfsubr','pi2fd','pmulhrw','prefetch',
'prefetchw'
);
{ topsize = (S_NO,S_B,S_W,S_L,S_BW,S_BL,S_WL,
@ -1104,10 +1110,10 @@ unit i386;
'%mm0','%mm1','%mm2','%mm3',
'%mm4','%mm5','%mm6','%mm7',
'%xmm0','%xmm1','%xmm2','%xmm3',
'%xmm4','%xmm5','%xmm6','%xmm7'
);
'%xmm4','%xmm5','%xmm6','%xmm7');
{$endif ATTOP}
{$ifndef NOINTOP}
{$ifdef INTELOP}
int_op2str : array[firstop..lastop] of string[9] =
('mov','movzx','movsx','','add',
'call','idiv','imul','jmp','lea','mul','neg','not',
@ -1163,23 +1169,23 @@ unit i386;
'psubusb','psubusw','psubw','punpckhbw','punpckhdq',
'punpckhwd','punpcklbw','punpckldq','punpcklwd','pxor',
{ KNI instructions (intel katmai) }
'addps','addss','andnps','andnss','andps','andss','cmpeqps','cmpeqps',
'cmpleps','cmpless','cmpltps','cmpltss','cmpneqps','cmpneqss',
'cmpnleps','cmpnless','cmpnltps','cmpnltss','cmpordps','cmpordss',
'cmpunordps','cmpunordss','comiss','cvtpi2ps','cvtps2pi','cvtsi2ss',
'cvttps2pi','cvttss2si','divps','divss','fxrstor','fxsave','ldmxcsr',
'maskmovq','maxps','maxss','minps','minss','movaps','movhps','movlps',
'movmskps','movntps','movntq','movss','movups','mulps','mulss','orps',
'pavgb','pavgw','pextrw','pinsrw','pmaxsw','pmaxub','pminsw','pminub',
'pmovmskb','pmulhuw','prefetchnt','prefetch0','prefetch1','prefetch2',
'psadbw','pshufw','rcpps','rcpss','rsqrtps','rsqrtss','sfence',
'shufps','sqrtps','sqrtss','stmxcsr','subps','subss','ucomiss',
'unpckhps','unpcklps','xorps',
'addps','addss','andnps','andnss','andps','andss','cmpeqps','cmpeqps',
'cmpleps','cmpless','cmpltps','cmpltss','cmpneqps','cmpneqss',
'cmpnleps','cmpnless','cmpnltps','cmpnltss','cmpordps','cmpordss',
'cmpunordps','cmpunordss','comiss','cvtpi2ps','cvtps2pi','cvtsi2ss',
'cvttps2pi','cvttss2si','divps','divss','fxrstor','fxsave','ldmxcsr',
'maskmovq','maxps','maxss','minps','minss','movaps','movhps','movlps',
'movmskps','movntps','movntq','movss','movups','mulps','mulss','orps',
'pavgb','pavgw','pextrw','pinsrw','pmaxsw','pmaxub','pminsw','pminub',
'pmovmskb','pmulhuw','prefetchnt','prefetch0','prefetch1','prefetch2',
'psadbw','pshufw','rcpps','rcpss','rsqrtps','rsqrtss','sfence',
'shufps','sqrtps','sqrtss','stmxcsr','subps','subss','ucomiss',
'unpckhps','unpcklps','xorps',
{ 3Dnow instructions (amd k6-2) }
'femms','pavgusb','pf2id','pfacc','pfadd','pfcmpeq','pfcmpge',
'pfcmpgt','pfmax','pfmin','pfmul','pfrcp','pfrcpit1','pfrcpit2',
'pfrsqit1','pfrsqrt','pfsub','pfsubr','pi2fd','pmulhrw','prefetch',
'prefetchw'
'femms','pavgusb','pf2id','pfacc','pfadd','pfcmpeq','pfcmpge',
'pfcmpgt','pfmax','pfmin','pfmul','pfrcp','pfrcpit1','pfrcpit2',
'pfrsqit1','pfrsqrt','pfsub','pfsubr','pi2fd','pmulhrw','prefetch',
'prefetchw'
);
int_reg2str : array[tregister] of string[5] =
@ -1201,7 +1207,7 @@ unit i386;
'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
);
{$endif}
{$endif INTELOP}
implementation
@ -1886,10 +1892,39 @@ unit i386;
inherited done;
end;
{****************************************************************************
Initialize
****************************************************************************}
var
old_exit: pointer;
procedure i386_exit;{$ifndef FPC}far;{$endif}
begin
{$ifdef ITTABLE}
dispose(itcache);
{$endif}
exitproc:=old_exit;
end;
Begin
{$ifdef ITTABLE}
{ create the itcache and reset to -1 }
new(itcache);
FillChar(ItCache^,sizeof(titcache),$ff);
{$endif}
old_exit := exitproc;
exitproc := @i386_exit;
end.
{
$Log$
Revision 1.26 1999-01-08 12:39:24 florian
Revision 1.27 1999-01-10 15:37:53 peter
* moved some tables from ra386*.pas -> i386.pas
+ start of coff writer
* renamed asmutils unit to rautils
Revision 1.26 1999/01/08 12:39:24 florian
Changes of Alexander Stohr integrated:
+ added KNI opcodes
+ added KNI registers

View File

@ -61,10 +61,6 @@ const
_asmsorted: boolean = FALSE;
firstreg = R_EAX;
lastreg = R_ST7;
{ Hack to support all opcodes in the i386 table }
{ only tokens up to and including lastop_in_table }
{ are checked for validity, otherwise... }
lastop_in_table = A_EMMS;
type
tiasmops = array[firstop..lastop] of string[7];
@ -81,8 +77,9 @@ var
Implementation
Uses
files,aasm,globals,AsmUtils,strings,hcodegen,scanner,systems,
cobjects,verbose,symtable,types;
strings,cobjects,systems,verbose,globals,
files,aasm,types,symtable,scanner,hcodegen,
rautils;
type
tinteltoken = (
@ -133,28 +130,6 @@ const
A_SCAS,A_SCAS,A_SCAS,A_STOS,A_STOS,A_STOS,A_MOVS,A_MOVS,A_MOVS,
A_LODS,A_LODS,A_LODS,A_LOCK,A_NONE,A_NONE,A_NONE,A_NONE);
{------------------------------------------------------------------}
{ register type definition table for easier searching }
_regtypes:array[firstreg..lastreg] of longint =
(ao_reg32,ao_reg32,ao_reg32,ao_reg32,ao_reg32,ao_reg32,ao_reg32,ao_reg32,
ao_reg16,ao_reg16,ao_reg16,ao_reg16,ao_reg16,ao_reg16,ao_reg16,ao_reg16,
ao_reg8,ao_reg8,ao_reg8,ao_reg8,ao_reg8,ao_reg8,ao_reg8,ao_reg8,
ao_none,ao_sreg2,ao_sreg2,ao_sreg2,ao_sreg3,ao_sreg3,ao_sreg2,
ao_floatacc,ao_floatacc,ao_floatreg,ao_floatreg,ao_floatreg,ao_floatreg,
ao_floatreg,ao_floatreg,ao_floatreg);
_regsizes: array[firstreg..lastreg] of topsize =
(S_L,S_L,S_L,S_L,S_L,S_L,S_L,S_L,
S_W,S_W,S_W,S_W,S_W,S_W,S_W,S_W,
S_B,S_B,S_B,S_B,S_B,S_B,S_B,S_B,
{ segment register }
S_W,S_W,S_W,S_W,S_W,S_W,S_W,
{ can also be S_S or S_T - must be checked at run-time }
S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL);
{topsize = (S_NO,S_B,S_W,S_L,S_BW,S_BL,S_WL,
S_IS,S_IL,S_IQ,S_FS,S_FL,S_FX,S_D);}
_constsizes: array[S_NO..S_FS] of longint =
(0,ao_imm8,ao_imm16,ao_imm32,0,0,0,ao_imm16,ao_imm32,0,ao_imm32);
{ converts from AT&T style to non-specific style... }
_fpusizes:array[A_FILDQ..A_FIDIVRS] of topsize = (
@ -929,7 +904,7 @@ var
{ check if there is not already a default size }
if opr.size <> S_NO then
Begin
findtype := _constsizes[opr.size];
findtype := const_2_type[opr.size];
exit;
end;
if val < $ff then
@ -949,7 +924,7 @@ var
end
end;
OPR_REGISTER: Begin
findtype := _regtypes[reg];
findtype := reg_2_type[reg];
exit;
end;
OPR_SYMBOL: Begin
@ -1098,7 +1073,7 @@ var
Begin
case instr.operands[i].operandtype of
OPR_REGISTER: instr.operands[i].size :=
_regsizes[instr.operands[i].reg];
reg_2_size[instr.operands[i].reg];
end; { end case }
end; { endif }
{ setup specific instructions for first pass }
@ -1580,14 +1555,15 @@ var
{ after reading the operands }
{ search the instruction }
{ setup startvalue from cache }
if ins_cache[instruc]<>-1 then
i:=ins_cache[instruc]
else i:=0;
if itcache^[instruc]<>-1 then
i:=itcache^[instruc]
else
i:=0;
{ I think this is too dangerous for me therefore i decided that for }
{ the att version only if the processor > i386 or we are compiling }
{ the system unit then this will be allowed... }
if (instruc > lastop_in_table) then
if (instruc > lastop_ittable) then
begin
Message1(assem_w_opcode_not_in_table,upper(att_op2str[instruc]));
fits:=true;
@ -1596,8 +1572,8 @@ var
begin
{ set the instruction cache, if the instruction }
{ occurs the first time }
if (it[i].i=instruc) and (ins_cache[instruc]=-1) then
ins_cache[instruc]:=i;
if (it[i].i=instruc) and (itcache^[instruc]=-1) then
itcache^[instruc]:=i;
if (it[i].i=instruc) and (instr.numops=it[i].ops) then
begin
@ -3103,18 +3079,14 @@ Begin
begin
expr := actasmpattern;
Consume(AS_ID);
case actasmtoken of
AS_DOT:
Begin
GetRecordOffsetSize(expr,toffset,tsize);
inc(instr.operands[operandnum].ref.offset,toffset);
SetOperandSize(instr,operandnum,tsize);
end;
AS_SEPARATOR,
AS_COMMA: ;
else
Message(assem_e_syntax_error);
end; { end case }
if actasmtoken=AS_DOT then
begin
GetRecordOffsetSize(expr,toffset,tsize);
inc(instr.operands[operandnum].ref.offset,toffset);
SetOperandSize(instr,operandnum,tsize);
end;
if actasmtoken=AS_LPAREN then
BuildReference(instr);
end;
end; { end if }
end; { end if }
@ -3710,16 +3682,18 @@ end;
Begin
{ you will get range problems here }
if lastop_in_table > last_instruction_in_cache then
Internalerror(2111);
old_exit := exitproc;
exitproc := @ra386att_exit;
end.
{
$Log$
Revision 1.28 1998-12-28 15:47:09 peter
Revision 1.29 1999-01-10 15:37:54 peter
* moved some tables from ra386*.pas -> i386.pas
+ start of coff writer
* renamed asmutils unit to rautils
Revision 1.28 1998/12/28 15:47:09 peter
* general constant solution. Constant expressions are now almost
everywhere allowed and correctly parsed

View File

@ -33,7 +33,7 @@ unit Ra386dir;
uses
comphook,files,i386,hcodegen,globals,scanner,aasm,
cobjects,symtable,types,verbose,asmutils;
cobjects,symtable,types,verbose,rautils;
function assemble : ptree;
@ -288,7 +288,12 @@ unit Ra386dir;
end.
{
$Log$
Revision 1.11 1998-11-17 00:26:12 peter
Revision 1.12 1999-01-10 15:37:57 peter
* moved some tables from ra386*.pas -> i386.pas
+ start of coff writer
* renamed asmutils unit to rautils
Revision 1.11 1998/11/17 00:26:12 peter
* fixed for $H+
Revision 1.10 1998/11/13 15:40:28 pierre

View File

@ -79,8 +79,9 @@ var
Implementation
Uses
systems,files,aasm,globals,AsmUtils,strings,hcodegen,scanner,
cobjects,verbose,types;
strings,cobjects,systems,verbose,globals,
files,aasm,types,scanner,hcodegen,
rautils;
type
@ -106,11 +107,6 @@ const
lastoperator = AS_XOR;
firstsreg = R_CS;
lastsreg = R_SS;
{ this is a hack to accept all opcodes }
{ in the opcode table. }
{ check is done until A_EMMS }
{ otherwise no check. }
lastop_in_table = A_EMMS;
_count_asmdirectives = longint(lastdirective)-longint(firstdirective);
_count_asmoperators = longint(lastoperator)-longint(firstoperator);
@ -151,31 +147,6 @@ const
A_SCAS,A_SCAS,A_SCAS,A_STOS,A_STOS,A_STOS,A_MOVS,A_MOVS,A_MOVS,
A_LODS,A_LODS,A_LODS,A_LOCK,A_NONE,A_NONE,A_NONE,A_NONE);
{------------------------------------------------------------------}
{ register type definition table for easier searching }
_regtypes:array[firstreg..lastreg] of longint =
(ao_reg32,ao_reg32,ao_reg32,ao_reg32,ao_reg32,ao_reg32,ao_reg32,ao_reg32,
ao_reg16,ao_reg16,ao_reg16,ao_reg16,ao_reg16,ao_reg16,ao_reg16,ao_reg16,
ao_reg8,ao_reg8,ao_reg8,ao_reg8,ao_reg8,ao_reg8,ao_reg8,ao_reg8,
ao_none,ao_sreg2,ao_sreg2,ao_sreg2,ao_sreg3,ao_sreg3,ao_sreg2,
ao_floatacc,ao_floatacc,ao_floatreg,ao_floatreg,ao_floatreg,ao_floatreg,
ao_floatreg,ao_floatreg,ao_floatreg);
_regsizes: array[firstreg..lastreg] of topsize =
(S_L,S_L,S_L,S_L,S_L,S_L,S_L,S_L,
S_W,S_W,S_W,S_W,S_W,S_W,S_W,S_W,
S_B,S_B,S_B,S_B,S_B,S_B,S_B,S_B,
{ segment register }
S_W,S_W,S_W,S_W,S_W,S_W,S_W,
{ can also be S_S or S_T - must be checked at run-time }
S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL);
{topsize = (S_NO,S_B,S_W,S_L,S_BW,S_BL,S_WL,
S_IS,S_IL,S_IQ,S_FS,S_FL,S_FX,S_D);}
_constsizes: array[S_NO..S_FS] of longint =
(0,ao_imm8,ao_imm16,ao_imm32,0,0,0,ao_imm16,ao_imm32,0,ao_imm32);
const
newline = #10;
@ -743,7 +714,7 @@ var
{ check if there is not already a default size }
if opr.size <> S_NO then
Begin
findtype := _constsizes[opr.size];
findtype := const_2_type[opr.size];
exit;
end;
if val < $ff then
@ -763,7 +734,7 @@ var
end
end;
OPR_REGISTER: Begin
findtype := _regtypes[reg];
findtype := reg_2_type[reg];
exit;
end;
OPR_SYMBOL: Begin
@ -936,7 +907,7 @@ var
Begin
case instr.operands[i].operandtype of
OPR_REGISTER: instr.operands[i].size :=
_regsizes[instr.operands[i].reg];
reg_2_size[instr.operands[i].reg];
end; { end case }
end; { endif }
{ setup specific instructions for first pass }
@ -1324,14 +1295,15 @@ var
{ after reading the operands }
{ search the instruction }
{ setup startvalue from cache }
if ins_cache[instruc]<>-1 then
i:=ins_cache[instruc]
else i:=0;
if itcache^[instruc]<>-1 then
i:=itcache^[instruc]
else
i:=0;
{ this makes cpu.pp uncompilable, but i think this code should be }
{ inserted in the system unit anyways. }
if (instruc > lastop_in_table) then
if (instruc > lastop_ittable) then
begin
Message1(assem_w_opcode_not_in_table,upper(int_op2str[instruc]));
fits:=true;
@ -1340,8 +1312,8 @@ var
begin
{ set the instruction cache, if the instruction }
{ occurs the first time }
if (it[i].i=instruc) and (ins_cache[instruc]=-1) then
ins_cache[instruc]:=i;
if (it[i].i=instruc) and (itcache^[instruc]=-1) then
itcache^[instruc]:=i;
if (it[i].i=instruc) and (instr.numops=it[i].ops) then
begin
@ -3497,14 +3469,16 @@ end;
begin
old_exit:=exitproc;
{ you will get range problems here }
if lastop_in_table > last_instruction_in_cache then
Internalerror(2111);
exitproc:=@ra386int_exit;
end.
{
$Log$
Revision 1.19 1998-12-23 22:55:57 peter
Revision 1.20 1999-01-10 15:37:58 peter
* moved some tables from ra386*.pas -> i386.pas
+ start of coff writer
* renamed asmutils unit to rautils
Revision 1.19 1998/12/23 22:55:57 peter
+ rec.field(%esi) support
+ [esi+rec.field] support

View File

@ -73,7 +73,7 @@ var
Implementation
uses
files,globals,systems,AsmUtils,strings,hcodegen,scanner,aasm,
files,globals,systems,RAUtils,strings,hcodegen,scanner,aasm,
cobjects,verbose,symtable;
@ -2178,7 +2178,12 @@ Begin
end.
{
$Log$
Revision 1.7 1998-12-11 00:03:45 peter
Revision 1.8 1999-01-10 15:37:59 peter
* moved some tables from ra386*.pas -> i386.pas
+ start of coff writer
* renamed asmutils unit to rautils
Revision 1.7 1998/12/11 00:03:45 peter
+ globtype,tokens,version unit splitted from globals
Revision 1.6 1998/10/13 16:50:19 pierre

View File

@ -3,6 +3,7 @@
Copyright (c) 1998 Carl Eric Codere
This unit implements some support routines for assembler parsing
independent of the processor
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -20,7 +21,7 @@
**********************************************************************}
Unit AsmUtils;
Unit RAUtils;
{*************************************************************************}
{ This unit implements some objects as well as utilities which will be }
@ -1802,77 +1803,9 @@ end;
end.
{
$Log$
Revision 1.17 1998-12-23 22:55:55 peter
+ rec.field(%esi) support
+ [esi+rec.field] support
Revision 1.1 1999-01-10 15:38:00 peter
* moved some tables from ra386*.pas -> i386.pas
+ start of coff writer
* renamed asmutils unit to rautils
Revision 1.16 1998/12/11 00:02:44 peter
+ globtype,tokens,version unit splitted from globals
Revision 1.15 1998/11/17 00:26:11 peter
* fixed for $H+
Revision 1.14 1998/11/05 23:48:17 peter
* recordtype.field support in constant expressions
* fixed imul for oa_imm8 which was not allowed
* fixed reading of local typed constants
* fixed comment reading which is not any longer a separator
Revision 1.13 1998/10/28 00:08:45 peter
+ leal procsym,eax is now allowed
+ constants are now handled also when starting an expression
+ call *pointer is now allowed
Revision 1.12 1998/10/14 11:28:13 florian
* emitpushreferenceaddress gets now the asmlist as parameter
* m68k version compiles with -duseansistrings
Revision 1.11 1998/10/13 16:49:59 pierre
* undid some changes of Peter that made the compiler wrong
for m68k (I had to reinsert some ifdefs)
* removed several memory leaks under m68k
* removed the meory leaks for assembler readers
* cross compiling shoud work again better
( crosscompiling sysamiga works
but as68k still complain about some code !)
Revision 1.10 1998/10/13 13:10:10 peter
* new style for m68k/i386 infos and enums
Revision 1.9 1998/09/24 17:54:15 carl
* bugfixes from fix branch
Revision 1.8.2.1 1998/09/24 17:46:25 carl
* support for objects in asm statements
Revision 1.8 1998/08/27 00:43:06 carl
+} now record offsets searches set the operand sizes
Revision 1.7 1998/08/18 20:51:32 peter
* fixed bug 42
Revision 1.6 1998/08/10 14:49:40 peter
+ localswitches, moduleswitches, globalswitches splitting
Revision 1.5 1998/07/14 21:46:38 peter
* updated messages file
Revision 1.4 1998/06/04 23:51:31 peter
* m68k compiles
+ .def file creation moved to gendef.pas so it could also be used
for win32
Revision 1.3 1998/05/31 14:13:30 peter
* fixed call bugs with assembler readers
+ OPR_SYMBOL to hold a symbol in the asm parser
* fixed staticsymtable vars which were acessed through %ebp instead of
name
Revision 1.2 1998/04/29 10:33:43 pierre
+ added some code for ansistring (not complete nor working yet)
* corrected operator overloading
* corrected nasm output
+ started inline procedures
+ added starstarn : use ** for exponentiation (^ gave problems)
+ started UseTokenInfo cond to get accurate positions
}

View File

@ -67,11 +67,12 @@ unit systems;
tasm = (as_none
,as_i386_o,as_i386_o_aout,as_i386_asw,
as_i386_nasmcoff,as_i386_nasmelf,as_i386_nasmobj,
as_i386_tasm,as_i386_masm
as_i386_tasm,as_i386_masm,
as_i386_coff
,as_m68k_o,as_m68k_gas,as_m68k_mit,as_m68k_mot,as_m68k_mpw
);
const
{$ifdef i386} i386asmcnt=8; {$else} i386asmcnt=0; {$endif}
{$ifdef i386} i386asmcnt=9; {$else} i386asmcnt=0; {$endif}
{$ifdef m68k} m68kasmcnt=5; {$else} m68kasmcnt=0; {$endif}
asmcnt=i386asmcnt+m68kasmcnt+1;
@ -522,6 +523,15 @@ implementation
labelprefix : '.L';
comment : '; '
)
,(
id : as_i386_coff;
idtxt : 'COFF';
asmbin : 'as';
asmcmd : '-o $OBJ $ASM';
externals : false;
labelprefix : '.L';
comment : '# '
)
{$endif i386}
{$ifdef m68k}
,(
@ -1314,7 +1324,12 @@ begin
end.
{
$Log$
Revision 1.55 1999-01-06 22:58:47 florian
Revision 1.56 1999-01-10 15:38:01 peter
* moved some tables from ra386*.pas -> i386.pas
+ start of coff writer
* renamed asmutils unit to rautils
Revision 1.55 1999/01/06 22:58:47 florian
+ some stuff for the new code generator
Revision 1.54 1998/12/28 23:26:26 peter