* assembler output format fixed

This commit is contained in:
mazen 2002-10-13 21:46:07 +00:00
parent fb36caedf1
commit 3a3b8a3dc4
5 changed files with 397 additions and 438 deletions

View File

@ -1,18 +1,7 @@
{*****************************************************************************}
{ File : aasmcpu.pas }
{ Author : Mazen NEIFER }
{ Project : Free Pascal Compiler (FPC) }
{ Creation date : 2002\05\01 }
{ Last modification date : 2002\08\20 }
{ Licence : GPL }
{ Bug report : mazen.neifer.01@supaero.org }
{*****************************************************************************}
{
{******************************************************************************
$Id$
Copyright (c) 1998-2000 by Florian Klaempfl and Peter Vreman
Contains the assembler object for the i386
* This code was inspired by the NASM sources
The Netwide Assembler is copyright (C) 1996 Simon Tatham and
Julian Hall. All rights reserved.
@ -30,22 +19,19 @@
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.
****************************************************************************
}
UNIT aasmcpu;
****************************************************************************}
unit aasmcpu;
{$INCLUDE fpcdefs.inc}
INTERFACE
USES
interface
uses
cclasses,globals,verbose,
cpuinfo,cpubase,
symppu,
aasmbase,aasmtai;
CONST
const
MaxPrefixes=4;
type
TOperandOrder=(op_intel,op_att);
{ alignment for operator }
tai_align=class(tai_align_abstract)
reg:tregister;
@ -53,27 +39,21 @@ type
constructor create_op(b:byte; _op:byte);
function getfillbuf:pchar;override;
end;
taicpu = class(taicpu_abstract)
opsize:topsize;
constructor op_none(op:tasmop;_size:topsize);
constructor op_reg(op:tasmop;_size:topsize;_op1:tregister);
constructor op_const(op:tasmop;_size:topsize;_op1:aword);
constructor op_ref(op:tasmop;_size:topsize;const _op1:treference);
constructor op_reg_reg(op:tasmop;_size:topsize;_op1,_op2:tregister);
constructor op_reg_ref(op:tasmop;_size:topsize;_op1:tregister;const _op2:treference);
constructor op_reg_const(op:tasmop; _size:topsize; _op1:tregister; _op2:aword);
constructor op_const_reg(op:tasmop;_size:topsize;_op1:aword;_op2:tregister);
constructor op_const_const(op:tasmop;_size:topsize;_op1,_op2:aword);
constructor op_const_ref(op:tasmop;_size:topsize;_op1:aword;const _op2:treference);
constructor op_ref_reg(op:tasmop;_size:topsize;const _op1:treference;_op2:tregister);
{ this is only allowed if _op1 is an int value (_op1^.isintvalue=true) }
constructor op_ref_ref(op:tasmop;_size:topsize;const _op1,_op2:treference);
constructor op_reg_reg_reg(op:tasmop;_size:topsize;_op1,_op2,_op3:tregister);
constructor op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:aWord;_op3:tregister);
constructor op_const_ref_reg(op:tasmop;_size:topsize;_op1:aword;const _op2:treference;_op3:tregister);
@ -82,14 +62,11 @@ type
{ this is for Jmp instructions }
constructor op_cond_sym(op:tasmop;cond:TAsmCond;_size:topsize;_op1:tasmsymbol);
constructor op_sym(op:tasmop;_size:topsize;_op1:tasmsymbol);
constructor op_sym_ofs(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint);
constructor op_sym_ofs_reg(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;_op2:tregister);
constructor op_sym_ofs_ref(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;const _op2:treference);
procedure changeopsize(siz:topsize);
function GetString:string;
procedure CheckNonCommutativeOpcodes;
private
@ -120,28 +97,22 @@ type
PROCEDURE DoneAsm;
PROCEDURE InitAsm;
implementation
uses
cutils,
CpuGas;
{****************************************************************************
TAI_ALIGN
****************************************************************************}
constructor tai_align.create(b:byte);
begin
inherited create(b);
reg:= R_NONE;
end;
constructor tai_align.create_op(b:byte; _op:byte);
begin
inherited create_op(b,_op);
reg:= R_NONE;
end;
function tai_align.getfillbuf:pchar;
const
alignarray:array[0..5] of string[8]=(
@ -171,12 +142,9 @@ uses
end;
getfillbuf:=pchar(@buf);
end;
{*****************************************************************************
Taicpu Constructors
*****************************************************************************}
procedure taicpu.changeopsize(siz:topsize);
begin
opsize:=siz;
@ -1183,8 +1151,6 @@ begin
until false;
calcsize:=len;
end;
{$endif NOAG386BIN}
PROCEDURE DoneAsm;
BEGIN
@ -1193,3 +1159,9 @@ PROCEDURE InitAsm;
BEGIN
END;
end.
{
$Log$
Revision 1.4 2002-10-13 21:46:07 mazen
* assembler output format fixed
}

View File

@ -843,11 +843,11 @@ procedure tcgSPARC.g_return_from_proc(list:TAasmOutput;parasize:aword);
which is genereted in the g_restore_frame_pointer. Notice that SPARC has no
RETURN instruction and that JMPL is used instead. The JMPL instrucion have one
delay slot, so an inversion is possible such as
JMPL %i6+8,%g0
JMPL %i7+8,%g0
RESTORE %g0,0,%g0
If no inversion we can use just
RESTORE %g0,0,%g0
JMPL %i6+8,%g0
JMPL %i7+8,%g0
NOP}
with list do
begin
@ -1264,7 +1264,10 @@ BEGIN
END.
{
$Log$
Revision 1.15 2002-10-11 13:35:14 mazen
Revision 1.16 2002-10-13 21:46:07 mazen
* assembler output format fixed
Revision 1.15 2002/10/11 13:35:14 mazen
*** empty log message ***
Revision 1.14 2002/10/10 19:57:51 mazen

View File

@ -1,17 +1,7 @@
{*****************************************************************************}
{ File : cpugas.pas }
{ Author : Mazen NEIFER }
{ Project : Free Pascal Compiler (FPC) }
{ Creation date : 2002\05\01 }
{ Last modification date : 2002\08\22 }
{ Licence : GPL }
{ Bug report : mazen.neifer.01@supaero.org }
{*****************************************************************************}
{ $Id$
{******************************************************************************
$Id$
Copyright (c) 1998-2000 by Florian Klaempfl
This unit implements an asmoutput class for SPARC AT&T syntax
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
@ -27,29 +17,27 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************}
UNIT CpuGas;
unit CpuGas;
{This unit implements an asmoutput class for SPARC AT&T syntax}
{$MACRO ON}{$INCLUDE fpcdefs.inc}
INTERFACE
USES
interface
uses
cclasses,cpubase,
globals,
aasmbase,aasmtai,aasmcpu,assemble,aggas;
TYPE
type
TGasSPARC=class(TGnuAssembler)
PROCEDURE WriteInstruction(hp:Tai);OVERRIDE;
END;
IMPLEMENTATION
USES
strings,
dos,
globtype,
fmodule,finput,
procedure WriteInstruction(hp:Tai);override;
end;
implementation
uses
finput,
cutils,systems,
verbose;
{$DEFINE gas_reg2str:=std_reg2str}
CONST
const
line_length = 70;
VAR
var
{$ifdef GDB}
n_line:byte; { different types of source lines }
linecount,
@ -62,11 +50,8 @@ VAR
infile,
lastinfile:tinputfile;
symendcount:longint;
function fixline(s:string):string;
{
return s with all leading and ending spaces and tabs removed
}
{return s with all leading and ending spaces and tabs removed}
var
i,j,k:longint;
begin
@ -77,46 +62,45 @@ VAR
while (j<i) and (s[j] in [#9,' ']) do
inc(j);
for k:=j to i do
if s[k] in [#0..#31,#127..#255] then
if s[k] in [#0..#31,#127..#255]
then
s[k]:='.';
fixline:=Copy(s,j,i-j+1);
end;
function single2str(d:single):string;
var
hs:string;
begin
str(d,hs);
{replace space with +}
if hs[1]=' ' then
if hs[1]=' '
then
hs[1]:='+';
single2str:='0d'+hs
end;
function double2str(d:double):string;
var
hs:string;
begin
str(d,hs);
{ replace space with + }
if hs[1]=' ' then
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
if hs[1]=' '
then
hs[1]:='+';
extended2str:='0d'+hs
end;
function getreferencestring(var ref : treference) : string;
function GetReferenceString(var ref:TReference):string;
var
s:string;
begin
@ -128,72 +112,78 @@ VAR
{ These are probably not correctly handled under GAS }
{ should be replaced by coding the segment override }
{ directly! - DJGPP FAQ }
if segment<>R_NONE then
if segment<>R_NONE
then
s:=gas_reg2str[segment]+':'
else
s:='';
if assigned(symbol) then
if assigned(symbol)
then
s:=s+symbol.name;
if offset<0 then
if offset<0
then
s:=s+tostr(offset)
else
if (offset>0) then
else if (offset>0)
then
begin
if assigned(symbol) then
if assigned(symbol)
then
s:=s+'+'+tostr(offset)
else
s:=s+tostr(offset);
end
else if (index=R_NONE) and (base=R_NONE) and not assigned(symbol) then
else if (index=R_NONE) and (base=R_NONE) and not assigned(symbol)
then
s:=s+'0';
if (index<>R_NONE) and (base=R_NONE) then
if (index<>R_NONE) and (base=R_NONE)
then
begin
s:=s+'(,'+gas_reg2str[index];
if scalefactor<>0 then
s:=s+','+tostr(scalefactor)+')'
else
s:=s+')';
s:='['+gas_reg2str[index]+s;
if scalefactor<>0
then
s:=tostr(scalefactor)+'+'+s;
s:=s+']';
end
else
if (index=R_NONE) and (base<>R_NONE) then
s:=s+'('+gas_reg2str[base]+')'
else
if (index<>R_NONE) and (base<>R_NONE) then
else if (index=R_NONE) and (base<>R_NONE)
then
s:='['+gas_reg2str[base]+'+'+s+']'
else if (index<>R_NONE) and (base<>R_NONE)
then
begin
s:=s+'('+gas_reg2str[base]+','+gas_reg2str[index];
if scalefactor<>0 then
s:=s+','+tostr(scalefactor)+')'
else
s := s+')';
s:='['+gas_reg2str[base]+'+'+gas_reg2str[index];
if scalefactor<>0
then
s:=tostr(scalefactor)+'+'+s;
s:= s+']';
end;
end;
getreferencestring:=s;
end;
function getopstr(const o:toper) : string;
function getopstr(const Oper:TOper):string;
var
hs:string;
begin
case o.typ of
with Oper do
case typ of
top_reg:
getopstr:=gas_reg2str[o.reg];
getopstr:=gas_reg2str[reg];
top_ref:
getopstr:=getreferencestring(o.ref^);
getopstr:=getreferencestring(ref^);
top_const:
getopstr:='$'+tostr(longint(o.val));
getopstr:={'$'+}tostr(longint(val));
top_symbol:
begin
if assigned(o.sym) then
hs:='$'+o.sym.name
if assigned(sym) then
hs:={'$'+}sym.name
else
hs:='$';
if o.symofs>0 then
hs:=hs+'+'+tostr(o.symofs)
if symofs>0 then
hs:=hs+'+'+tostr(symofs)
else
if o.symofs<0 then
hs:=hs+tostr(o.symofs)
if symofs<0 then
hs:=hs+tostr(symofs)
else
if not(assigned(o.sym)) then
if not(assigned(sym)) then
hs:=hs+'0';
getopstr:=hs;
end;
@ -202,44 +192,40 @@ VAR
end;
end;
function getopstr_jmp(const o:toper) : string;
function getopstr_jmp(const Oper:TOper):string;
var
hs:string;
begin
case o.typ of
with Oper do
case typ of
top_reg:
getopstr_jmp:='*'+gas_reg2str[o.reg];
getopstr_jmp:=gas_reg2str[reg]+'+';
top_ref:
getopstr_jmp:='*'+getreferencestring(o.ref^);
getopstr_jmp:=GetReferenceString(ref^);
top_const:
getopstr_jmp:=tostr(longint(o.val));
getopstr_jmp:=tostr(longint(val));
top_symbol:
begin
hs:=o.sym.name;
if o.symofs>0 then
hs:=hs+'+'+tostr(o.symofs)
hs:=sym.name;
if symofs>0 then
hs:=hs+'+'+tostr(symofs)
else
if o.symofs<0 then
hs:=hs+tostr(o.symofs);
if symofs<0 then
hs:=hs+tostr(symofs);
getopstr_jmp:=hs;
end;
else
internalerror(10001);
end;
end;
{****************************************************************************
TISPARCATTASMOUTPUT
****************************************************************************}
const
ait_const2str:array[ait_const_32bit..ait_const_8bit]of string[8]=(#9'.long'#9,#9'.short'#9,#9'.byte'#9);
procedure TGasSPARC.WriteInstruction(hp:Tai);
var
Op:TAsmOp;
s:STRING;
s:String;
i:Integer;
sep:STRING[3];
begin
if hp.typ<>ait_instruction
then
@ -248,39 +234,21 @@ procedure TGasSPARC.WriteInstruction(hp:Tai);
op:=taicpu(hp).opcode;
{call maybe not translated to call}
s:=#9+std_op2str[op]+cond2str[taicpu(hp).condition];
if is_CallJmp(op)
then
{ 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 }
begin
s:=#9+std_op2str[op]+#9+getopstr_jmp(taicpu(hp).oper[0]);
end
ELSE
BEGIN {process operands}
{process operands}
s:=#9+std_op2str[op];
IF taicpu(hp).ops<>0
THEN
BEGIN
{
if not is_calljmp(op) then
sep:=','
else
}
sep:=#9;
FOR i:=0 TO taicpu(hp).ops-1 DO
BEGIN
s:=s+sep+getopstr(taicpu(hp).oper[i]);
sep:=',';
END;
END;
END;
if taicpu(hp).ops>0
then
begin
s+=#9+getopstr(taicpu(hp).oper[0]);
for i:=1 to taicpu(hp).ops-1 do
s+=','+getopstr(taicpu(hp).oper[i]);
end;
AsmWriteLn(s);
END;
end;
{*****************************************************************************
Initialize
*****************************************************************************}
CONST
const
as_SPARC_as_info:TAsmInfo=(
id:as_gas;
idtxt:'AS';
@ -292,7 +260,7 @@ CONST
needar:true;
labelprefix_only_inside_procedure:false;
labelprefix:'.L';
comment : '# ';
comment:'; ';
secnames:({sec_none}'', {no section}
{sec_code}'.text', {executable code}
{sec_data}'.data', {initialized R/W data}

View File

@ -27,8 +27,13 @@ uses
symconst,symbase,symtype,symdef,paramgr;
type
TSparcParaManager=class(TParaManager)
{Returns a structure giving the information on the storage of the parameter
(which must be an integer parameter)
@param(nr Parameter number of routine, starting from 1)}
function GetIntParaLoc(nr:longint):TParaLocation;override;
procedure create_param_loc_info(p:TAbstractProcDef);override;
{Returns the location where the invisible parameter for structured function
results will be passed.}
function GetFuncRetParaLoc(p:TAbstractProcDef):TParaLocation;override;
end;
implementation
@ -232,22 +237,23 @@ WriteLn('***********************************************');
end;
function tSparcParaManager.GetFuncRetParaLoc(p:TAbstractProcDef):TParaLocation;
begin
with GetFuncRetParaLoc do
case p.rettype.def.deftype of
orddef,enumdef:
begin
WriteLn('Allocating i0 as return register');
GetFuncRetParaLoc.loc:=LOC_REGISTER;
GetFuncRetParaLoc.register:=R_I0;
GetFuncRetParaLoc.size:=def_cgsize(p.rettype.def);
if GetFuncRetParaLoc.size in [OS_S64,OS_64]
loc:=LOC_REGISTER;
register:=R_I0;
size:=def_cgsize(p.rettype.def);
if size in [OS_S64,OS_64]
then
GetFuncRetParaLoc.RegisterHigh:=R_I1;
RegisterHigh:=R_I1;
end;
floatdef:
begin
GetFuncRetParaLoc.loc:=LOC_FPUREGISTER;
GetFuncRetParaLoc.register:=R_F1;
GetFuncRetParaLoc.size:=def_cgsize(p.rettype.def);
loc:=LOC_FPUREGISTER;
register:=R_F1;
size:=def_cgsize(p.rettype.def);
end;
setdef,
variantdef,
@ -262,9 +268,10 @@ function tSparcParaManager.GetFuncRetParaLoc(p:TAbstractProcDef):TParaLocation;
arraydef,
errordef:
begin
GetFuncRetParaLoc.loc:=LOC_REGISTER;
GetFuncRetParaLoc.register:=R_I0;
GetFuncRetParaLoc.size:=OS_ADDR;
loc:=LOC_REFERENCE;
reference.index:=frame_pointer_reg;
reference.offset:=64;
size:=OS_ADDR;
end;
else
internalerror(2002090903);
@ -275,7 +282,10 @@ begin
end.
{
$Log$
Revision 1.7 2002-10-10 19:57:51 mazen
Revision 1.8 2002-10-13 21:46:07 mazen
* assembler output format fixed
Revision 1.7 2002/10/10 19:57:51 mazen
* Just to update repsitory
Revision 1.6 2002/10/10 15:10:39 mazen

View File

@ -28,10 +28,13 @@ uses
aasmtai,
cclasses,globtype,cgbase,aasmbase,rgobj;
type
{This class implements the cpu spaecific register allocator. It is used by the
code generator to allocate and free registers which might be valid across
nodes. It also contains utility routines related to registers. Some of the
methods in this class overrides generic implementations in rgobj.pas.}
trgcpu=class(trgobj)
{ to keep the same allocation order as with the old routines }
procedure UngetregisterInt(list:taasmoutput;Reg:tregister);override;
function GetExplicitRegisterInt(list:taasmoutput;Reg:tregister):tregister;override;
procedure UngetregisterInt(list:taasmoutput;Reg:tregister);override;
end;
implementation
uses
@ -59,7 +62,10 @@ initialization
end.
{
$Log$
Revision 1.3 2002-10-12 19:03:23 mazen
Revision 1.4 2002-10-13 21:46:07 mazen
* assembler output format fixed
Revision 1.3 2002/10/12 19:03:23 mazen
* Get/Unget expilit registers to be re-examined
}