mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-03 08:18:27 +02:00
* started to fix and clean up the sparc port
This commit is contained in:
parent
161618df2d
commit
a8eb2ab740
@ -154,14 +154,12 @@ const
|
||||
uses
|
||||
globtype,globals,verbose,systems,cutils,symconst,symdef,symsym,rgobj,tgobj,cpupi;
|
||||
|
||||
{ parameter passing... Still needs extra support from the processor }
|
||||
{ independent code generator }
|
||||
{ parameter passing... Still needs extra support from the processor }
|
||||
{ independent code generator }
|
||||
|
||||
procedure tcgppc.a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);
|
||||
|
||||
var
|
||||
ref: treference;
|
||||
|
||||
begin
|
||||
case locpara.loc of
|
||||
LOC_REGISTER,LOC_CREGISTER:
|
||||
@ -249,9 +247,9 @@ const
|
||||
var
|
||||
href : treference;
|
||||
begin
|
||||
{MacOS: The linker on MacOS (PPCLink) inserts a call to glue code,
|
||||
if it is a cross-TOC call. If so, it also replaces the NOP
|
||||
with some restore code.}
|
||||
{ MacOS: The linker on MacOS (PPCLink) inserts a call to glue code,
|
||||
if it is a cross-TOC call. If so, it also replaces the NOP
|
||||
with some restore code.}
|
||||
list.concat(taicpu.op_sym(A_BL,objectlibrary.newasmsymbol(s)));
|
||||
if target_info.system=system_powerpc_macos then
|
||||
list.concat(taicpu.op_none(A_NOP));
|
||||
@ -2442,7 +2440,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.96 2003-05-24 11:59:42 jonas
|
||||
Revision 1.97 2003-05-28 23:18:31 florian
|
||||
* started to fix and clean up the sparc port
|
||||
|
||||
Revision 1.96 2003/05/24 11:59:42 jonas
|
||||
* fixed integer typeconversion problems
|
||||
|
||||
Revision 1.95 2003/05/23 18:51:26 jonas
|
||||
|
@ -1,7 +1,7 @@
|
||||
{*****************************************************************************
|
||||
$Id$
|
||||
Copyright (c) 1998-2000 by Florian Klaempfl and Peter Vreman
|
||||
|
||||
|
||||
* This code was inspired by the NASM sources
|
||||
The Netwide Assembler is copyright (C) 1996 Simon Tatham and
|
||||
Julian Hall. All rights reserved.
|
||||
@ -10,7 +10,7 @@
|
||||
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
|
||||
@ -50,6 +50,7 @@ type
|
||||
constructor op_ref_reg(Op:TAsmOp;const Ref:TReference;Reg:TRegister);
|
||||
constructor op_ref_ref(op:tasmop;_size:topsize;const _op1,_op2:treference);
|
||||
constructor op_reg_reg_reg(op:tasmop;_op1,_op2,_op3:tregister);
|
||||
constructor op_reg_ref_reg(op:tasmop;_op1:TRegister;_op2:TReference;_op3:tregister);
|
||||
constructor op_reg_const_reg(Op:TAsmOp;SrcReg:TRegister;value:aWord;DstReg:TRegister);
|
||||
constructor op_const_ref_reg(op:tasmop;_size:topsize;_op1:aword;const _op2:treference;_op3:tregister);
|
||||
constructor op_const_reg_ref(op:tasmop;_size:topsize;_op1:aword;_op2:tregister;const _op3:treference);
|
||||
@ -60,11 +61,7 @@ type
|
||||
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);
|
||||
constructor op_caddr_reg(op:TAsmOp;rgb:TRegister;cnst:Integer;reg:TRegister);
|
||||
constructor op_raddr_reg(op:TAsmOp;rg1,rg2:TRegister;reg:TRegister);
|
||||
procedure changeopsize(siz:topsize);
|
||||
procedure loadcaddr(opidx:longint;aReg:TRegister;cnst:Integer);
|
||||
procedure loadraddr(opidx:longint;rg1,rg2:TRegister);
|
||||
private
|
||||
procedure init(_size:topsize);{this need to be called by all constructor}
|
||||
public
|
||||
@ -195,6 +192,15 @@ constructor taicpu.op_reg_reg_reg(op:tasmop;_op1,_op2,_op3:tregister);
|
||||
loadreg(1,_op2);
|
||||
loadreg(2,_op3);
|
||||
end;
|
||||
constructor taicpu.op_reg_ref_reg(op:tasmop;_op1:TRegister;_op2:TReference;_op3:tregister);
|
||||
begin
|
||||
inherited create(op);
|
||||
init(_size);
|
||||
ops:=3;
|
||||
loadreg(0,_op1);
|
||||
loadref(1,_op2);
|
||||
loadreg(2,_op3);
|
||||
end;
|
||||
constructor taicpu.op_reg_const_reg(op:TAsmOp;SrcReg:TRegister;Value:aWord;DstReg:TRegister);
|
||||
begin
|
||||
inherited Create(Op);
|
||||
@ -263,22 +269,6 @@ constructor taicpu.op_sym_ofs_ref(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1of
|
||||
loadref(1,_op2);
|
||||
end;
|
||||
|
||||
constructor taicpu.op_caddr_reg(op:TAsmOp;rgb:TRegister;cnst:Integer;reg:TRegister);
|
||||
begin
|
||||
inherited create(op);
|
||||
init(S_SW);
|
||||
ops:=2;
|
||||
loadcaddr(0,rgb,cnst);
|
||||
loadreg(1,reg);
|
||||
end;
|
||||
constructor taicpu.op_raddr_reg(op:TAsmOp;rg1,rg2,reg:TRegister);
|
||||
begin
|
||||
inherited create(op);
|
||||
init(S_SW);
|
||||
ops:=2;
|
||||
loadraddr(0,rg1,rg2);
|
||||
loadreg(1,reg);
|
||||
end;
|
||||
procedure taicpu.Swatoperands;
|
||||
var
|
||||
p:TOper;
|
||||
@ -322,30 +312,6 @@ A_BCS,A_BPOS,A_NEG,A_BVC,A_BVS,A_BA,A_BNE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_N
|
||||
{$ENDIF EXTDEBUG}
|
||||
end;
|
||||
end;
|
||||
procedure taicpu.loadcaddr(opidx:longint;aReg:TRegister;cnst:Integer);
|
||||
begin
|
||||
if opidx>=ops
|
||||
then
|
||||
ops:=opidx+1;
|
||||
with oper[opidx] do
|
||||
begin
|
||||
typ:=top_caddr;
|
||||
regb:=aReg;
|
||||
const13:=cnst;
|
||||
end;
|
||||
end;
|
||||
procedure taicpu.loadraddr(opidx:longint;rg1,rg2:TRegister);
|
||||
begin
|
||||
if opidx>=ops
|
||||
then
|
||||
ops:=opidx+1;
|
||||
with oper[opidx] do
|
||||
begin
|
||||
typ:=top_caddr;
|
||||
reg1:=rg1;
|
||||
reg2:=rg2;
|
||||
end;
|
||||
end;
|
||||
procedure DoneAsm;
|
||||
begin
|
||||
end;
|
||||
@ -355,7 +321,10 @@ procedure InitAsm;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.25 2003-05-07 11:45:02 mazen
|
||||
Revision 1.26 2003-05-28 23:18:31 florian
|
||||
* started to fix and clean up the sparc port
|
||||
|
||||
Revision 1.25 2003/05/07 11:45:02 mazen
|
||||
- removed unused code
|
||||
|
||||
Revision 1.24 2003/05/07 11:28:26 mazen
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,9 +19,14 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
****************************************************************************}
|
||||
unit cpuBase;
|
||||
{$INCLUDE fpcdefs.inc}
|
||||
|
||||
{$i fpcdefs.inc}
|
||||
|
||||
interface
|
||||
uses globals,cutils,cclasses,aasmbase,cpuinfo,cginfo;
|
||||
|
||||
uses
|
||||
globals,cutils,cclasses,aasmbase,cpuinfo,cginfo;
|
||||
|
||||
const
|
||||
{Size of the instruction table converted by nasmconv.pas}
|
||||
maxinfolen=8;
|
||||
@ -481,31 +486,36 @@ type
|
||||
type
|
||||
TRefOptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
|
||||
|
||||
{ since we have no full 32 bit offsets, we need to be able to specify the high
|
||||
and low bits of the address of a symbol }
|
||||
trefsymaddr = (refs_full,refs_hi,refs_lo);
|
||||
|
||||
{ immediate/reference record }
|
||||
poperreference = ^treference;
|
||||
Preference=^Treference;
|
||||
treference = packed record
|
||||
segment,
|
||||
base,
|
||||
index : tregister;
|
||||
scalefactor : byte;
|
||||
offset : LongInt;
|
||||
symbol : tasmsymbol;
|
||||
symaddr : trefsymaddr;
|
||||
offsetfixup : LongInt;
|
||||
options : trefoptions;
|
||||
alignment : byte;
|
||||
end;
|
||||
{ reference record }
|
||||
|
||||
{ reference record }
|
||||
PParaReference=^TParaReference;
|
||||
TParaReference=PACKED RECORD
|
||||
Index:TRegister;
|
||||
Offset:longint;
|
||||
TParaReference = packed record
|
||||
Index : TRegister;
|
||||
Offset : longint;
|
||||
end;
|
||||
|
||||
{*****************************************************************************
|
||||
Operands
|
||||
*****************************************************************************}
|
||||
{ Types of operand }
|
||||
toptype=(top_none,top_reg,top_ref,top_const,top_symbol,top_raddr,top_caddr);
|
||||
toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
|
||||
toper=record
|
||||
ot:LongInt;
|
||||
case typ:toptype of
|
||||
@ -514,8 +524,6 @@ type
|
||||
top_ref:(ref:poperreference);
|
||||
top_const:(val:aword);
|
||||
top_symbol:(sym:tasmsymbol;symofs:LongInt);
|
||||
top_raddr:(reg1,reg2:TRegister);
|
||||
top_caddr:(regb:TRegister;const13:Integer);
|
||||
end;
|
||||
{*****************************************************************************
|
||||
Argument Classification
|
||||
@ -536,10 +544,10 @@ type
|
||||
Generic Location
|
||||
*****************************************************************************}
|
||||
type
|
||||
{tparamlocation describes where a parameter for a procedure is stored.
|
||||
References are given from the caller's point of view. The usual TLocation isn't
|
||||
used, because contains a lot of unnessary fields.}
|
||||
TParaLocation=PACKED RECORD
|
||||
{ tparamlocation describes where a parameter for a procedure is stored.
|
||||
References are given from the caller's point of view. The usual TLocation isn't
|
||||
used, because contains a lot of unnessary fields. }
|
||||
TParaLocation=packed record
|
||||
Size:TCGSize;
|
||||
Loc:TCGLoc;
|
||||
sp_fixup:LongInt;
|
||||
@ -555,10 +563,11 @@ used, because contains a lot of unnessary fields.}
|
||||
3 : (reg64 : tregister64);
|
||||
4 : (register64 : tregister64);
|
||||
);
|
||||
{ it's only for better handling }
|
||||
{ it's only for better handling }
|
||||
LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
|
||||
end;
|
||||
TLocation=PACKED RECORD
|
||||
|
||||
TLocation=packed record
|
||||
loc : TCGLoc;
|
||||
size : TCGSize;
|
||||
case TCGLoc of
|
||||
@ -669,35 +678,40 @@ const
|
||||
accumulatorhigh = R_O1;
|
||||
NR_ACCUMULATORHIGH = NR_O1;
|
||||
RS_ACCUMULATORHIGH = RS_O1;
|
||||
fpu_result_reg =R_F0;
|
||||
mmresultreg =R_G0;
|
||||
fpu_result_reg = R_F0;
|
||||
mmresultreg = R_G0;
|
||||
|
||||
{*****************************************************************************}
|
||||
{ GCC /ABI linking information }
|
||||
{*****************************************************************************}
|
||||
{# Registers which must be saved when calling a routine declared as cppdecl,
|
||||
cdecl, stdcall, safecall, palmossyscall. The registers saved should be the ones
|
||||
as defined in the target ABI and / or GCC.
|
||||
{ Registers which must be saved when calling a routine declared as cppdecl,
|
||||
cdecl, stdcall, safecall, palmossyscall. The registers saved should be the ones
|
||||
as defined in the target ABI and / or GCC.
|
||||
|
||||
This value can be deduced from the CALLED_USED_REGISTERS array in the GCC
|
||||
source.}
|
||||
std_saved_registers=[RS_O6];
|
||||
{# Required parameter alignment when calling a routine declared as stdcall and
|
||||
cdecl. The alignment value should be the one defined by GCC or the target ABI.
|
||||
This value can be deduced from the CALLED_USED_REGISTERS array in the GCC
|
||||
source.
|
||||
}
|
||||
std_saved_registers=[];
|
||||
|
||||
The value of this constant is equal to the constant
|
||||
PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.}
|
||||
{ Required parameter alignment when calling a routine declared as stdcall and
|
||||
cdecl. The alignment value should be the one defined by GCC or the target ABI.
|
||||
|
||||
The value of this constant is equal to the constant
|
||||
PARM_BOUNDARY / BITS_PER_UNIT in the GCC source. }
|
||||
std_param_align=4;
|
||||
{# Registers which are defined as scratch and no need to save across routine
|
||||
calls or in assembler blocks.}
|
||||
ScratchRegsCount=8;
|
||||
scratch_regs:array[1..ScratchRegsCount] OF Tsuperregister=(RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6,RS_L7);
|
||||
{ low and high of the available maximum width integer general purpose }
|
||||
{ registers }
|
||||
|
||||
{ Registers which are defined as scratch and no need to save across routine
|
||||
calls or in assembler blocks.}
|
||||
ScratchRegsCount=2;
|
||||
scratch_regs:array[1..ScratchRegsCount] OF Tsuperregister=(RS_O7,RS_G2);
|
||||
|
||||
{ low and high of the available maximum width integer general purpose
|
||||
registers }
|
||||
LoGPReg = R_G0;
|
||||
HiGPReg = R_I7;
|
||||
|
||||
{ low and high of every possible width general purpose register (same as }
|
||||
{ above on most architctures apart from the 80x86) }
|
||||
{ low and high of every possible width general purpose register (same as
|
||||
above on most architctures apart from the 80x86) }
|
||||
LoReg = R_G0;
|
||||
HiReg = R_I7;
|
||||
|
||||
@ -705,7 +719,7 @@ calls or in assembler blocks.}
|
||||
|
||||
{ sizes }
|
||||
pointersize = 4;
|
||||
extended_size = 8;{SPARC architecture uses IEEE floating point numbers}
|
||||
extended_size = 8; { SPARC architecture uses IEEE floating point numbers}
|
||||
mmreg_size = 8;
|
||||
SizePostfix_pointer = S_SW;
|
||||
|
||||
@ -734,12 +748,9 @@ VAR
|
||||
Helpers
|
||||
*****************************************************************************}
|
||||
const
|
||||
maxvarregs=30;
|
||||
maxvarregs=8;
|
||||
VarRegs:array[1..maxvarregs] of tnewregister = (
|
||||
RS_G0,RS_G1,RS_G2,RS_G3,RS_G4,RS_G5,RS_G6,RS_G7,
|
||||
RS_O0,RS_O1,RS_O2,RS_O3,RS_O4,RS_O5,{RS_R14=RS_SP}RS_O7,
|
||||
RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6,RS_L7,
|
||||
RS_I0,RS_I1,RS_I2,RS_I3,RS_I4,RS_I5,{RS_R30=RS_FP}RS_I7
|
||||
RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6,RS_L7
|
||||
);
|
||||
maxfpuvarregs = 8;
|
||||
max_operands = 3;
|
||||
@ -752,19 +763,23 @@ function is_calljmp(o:tasmop):boolean;
|
||||
function flags_to_cond(CONST f:TResFlags):TAsmCond;
|
||||
procedure convert_register_to_enum(var Reg:Tregister);
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
|
||||
implementation
|
||||
uses
|
||||
verbose;
|
||||
const
|
||||
CallJmpOp=[A_JMPL..A_CBccc];
|
||||
function is_calljmp(o:tasmop):boolean;
|
||||
begin
|
||||
if o in CallJmpOp
|
||||
then
|
||||
is_calljmp:=true
|
||||
else
|
||||
is_calljmp:=false;
|
||||
end;
|
||||
|
||||
uses
|
||||
verbose;
|
||||
const
|
||||
CallJmpOp=[A_JMPL..A_CBccc];
|
||||
|
||||
function is_calljmp(o:tasmop):boolean;
|
||||
begin
|
||||
if o in CallJmpOp
|
||||
then
|
||||
is_calljmp:=true
|
||||
else
|
||||
is_calljmp:=false;
|
||||
end;
|
||||
|
||||
function flags_to_cond(const f:TResFlags):TAsmCond;
|
||||
CONST
|
||||
flags_2_cond:array[TResFlags]OF TAsmCond=
|
||||
@ -772,6 +787,7 @@ function flags_to_cond(const f:TResFlags):TAsmCond;
|
||||
BEGIN
|
||||
result:=flags_2_cond[f];
|
||||
end;
|
||||
|
||||
procedure convert_register_to_enum(var Reg:Tregister);
|
||||
begin
|
||||
with Reg do
|
||||
@ -788,6 +804,7 @@ procedure convert_register_to_enum(var Reg:Tregister);
|
||||
else
|
||||
internalerror(200301082);
|
||||
end;
|
||||
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
begin
|
||||
cgsize2subreg:=R_SUBWHOLE;
|
||||
@ -795,7 +812,10 @@ end;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.33 2003-05-26 22:08:42 mazen
|
||||
Revision 1.34 2003-05-28 23:18:31 florian
|
||||
* started to fix and clean up the sparc port
|
||||
|
||||
Revision 1.33 2003/05/26 22:08:42 mazen
|
||||
+ RegEnum2Number to ease handling register pairs
|
||||
* changed convert_register_to_enum to use above
|
||||
array
|
||||
|
@ -17,182 +17,192 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
****************************************************************************}
|
||||
unit CpuGas;
|
||||
{This unit implements an asmoutput class for SPARC AT&T syntax}
|
||||
{$MACRO ON}{$INCLUDE fpcdefs.inc}
|
||||
interface
|
||||
uses
|
||||
cpubase,
|
||||
aasmtai,aasmcpu,assemble,aggas;
|
||||
type
|
||||
TGasSPARC=class(TGnuAssembler)
|
||||
procedure WriteInstruction(hp:Tai);override;
|
||||
end;
|
||||
implementation
|
||||
uses
|
||||
cutils,systems,
|
||||
verbose;
|
||||
{$DEFINE gas_reg2str:=std_reg2str}
|
||||
function GetReferenceString(var ref:TReference):string;
|
||||
begin
|
||||
GetReferenceString:='+';
|
||||
with ref do
|
||||
if assigned(symbol)
|
||||
then
|
||||
GetReferenceString:=symbol.name
|
||||
else
|
||||
begin
|
||||
inc(offset,offsetfixup);
|
||||
if base.enum<>R_NONE
|
||||
then
|
||||
GetReferenceString:=gas_reg2str[base.enum]+'+';
|
||||
if index.enum<>R_NONE
|
||||
then
|
||||
begin
|
||||
if ScaleFactor<>0
|
||||
then
|
||||
GetReferenceString:=GetReferenceString+ToStr(ScaleFactor)+'*';
|
||||
GetReferenceString:=GetReferenceString+gas_reg2str[index.enum]+'+';
|
||||
end;
|
||||
if Offset=0
|
||||
then
|
||||
SetLength(GetReferenceString,Length(GetReferenceString)-1)
|
||||
else if offset<0
|
||||
then
|
||||
begin
|
||||
SetLength(GetReferenceString,Length(GetReferenceString)-1);
|
||||
GetReferenceString:=GetReferenceString+tostr(offset);
|
||||
end
|
||||
else if offset>0
|
||||
then
|
||||
GetReferenceString:=GetReferenceString+tostr(offset);
|
||||
end;
|
||||
end;
|
||||
function getopstr(const Oper:TOper):string;
|
||||
var
|
||||
hs:string;
|
||||
begin
|
||||
with Oper do
|
||||
case typ of
|
||||
top_reg:
|
||||
getopstr:=gas_reg2str[reg.enum];
|
||||
top_ref:
|
||||
getopstr:='['+getreferencestring(ref^)+']';
|
||||
top_const:
|
||||
getopstr:={'$'+}tostr(longint(val));
|
||||
top_symbol:
|
||||
begin
|
||||
if assigned(sym) then
|
||||
hs:={'$'+}sym.name
|
||||
else
|
||||
hs:='$';
|
||||
if symofs>0 then
|
||||
hs:=hs+'+'+tostr(symofs)
|
||||
else
|
||||
if symofs<0 then
|
||||
hs:=hs+tostr(symofs)
|
||||
else
|
||||
if not(assigned(sym)) then
|
||||
hs:=hs+'0';
|
||||
getopstr:=hs;
|
||||
end;
|
||||
top_raddr:
|
||||
getopstr:=std_reg2str[reg1.enum]+'+'+std_reg2str[reg2.enum];
|
||||
top_caddr:
|
||||
getopstr:=std_reg2str[regb.enum]+'+'+ToStr(const13);
|
||||
else
|
||||
internalerror(10001);
|
||||
{
|
||||
This unit implements an asmoutput class for SPARC AT&T syntax
|
||||
}
|
||||
unit cpugas;
|
||||
|
||||
{$i fpcdefs.inc}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
cpubase,
|
||||
aasmtai,aasmcpu,assemble,aggas;
|
||||
|
||||
type
|
||||
TGasSPARC=class(TGnuAssembler)
|
||||
procedure WriteInstruction(hp:Tai);override;
|
||||
end;
|
||||
end;
|
||||
(*
|
||||
function getopstr_jmp(const Oper:TOper):string;
|
||||
var
|
||||
hs:string;
|
||||
begin
|
||||
with Oper do
|
||||
case typ of
|
||||
top_reg:
|
||||
getopstr_jmp:=gas_reg2str[reg]+'+';
|
||||
top_ref:
|
||||
getopstr_jmp:=GetReferenceString(ref^);
|
||||
top_const:
|
||||
getopstr_jmp:=tostr(longint(val));
|
||||
top_symbol:
|
||||
begin
|
||||
hs:=sym.name;
|
||||
if symofs>0 then
|
||||
hs:=hs+'+'+tostr(symofs)
|
||||
else
|
||||
if symofs<0 then
|
||||
hs:=hs+tostr(symofs);
|
||||
getopstr_jmp:=hs;
|
||||
end;
|
||||
else
|
||||
internalerror(10001);
|
||||
end;
|
||||
end;*)
|
||||
{****************************************************************************
|
||||
TSPARCATTASMOUTPUT
|
||||
****************************************************************************}
|
||||
procedure TGasSPARC.WriteInstruction(hp:Tai);
|
||||
var
|
||||
Op:TAsmOp;
|
||||
s:String;
|
||||
i:Integer;
|
||||
begin
|
||||
if hp.typ<>ait_instruction
|
||||
then
|
||||
Exit;
|
||||
op:=taicpu(hp).opcode;
|
||||
{call maybe not translated to call}
|
||||
s:=#9+std_op2str[op]+cond2str[taicpu(hp).condition];
|
||||
{process operands}
|
||||
s:=#9+std_op2str[op];
|
||||
if taicpu(hp).ops>0
|
||||
then
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
cutils,systems,
|
||||
verbose;
|
||||
|
||||
function GetReferenceString(var ref:TReference):string;
|
||||
begin
|
||||
s:=s+#9+getopstr(taicpu(hp).oper[0]);
|
||||
for i:=1 to taicpu(hp).ops-1 do
|
||||
s:=s+','+getopstr(taicpu(hp).oper[i]);
|
||||
GetReferenceString:='';
|
||||
with ref do
|
||||
begin
|
||||
inc(offset,offsetfixup);
|
||||
offsetfixup:=0;
|
||||
if base.enum>lastreg then
|
||||
internalerror(200301081);
|
||||
if index.enum>lastreg then
|
||||
internalerror(200301081);
|
||||
|
||||
if assigned(symbol) then
|
||||
begin
|
||||
GetReferenceString:=symbol.name;
|
||||
if offset>0 then
|
||||
GetReferenceString:=GetReferenceString+'+'+ToStr(offset)
|
||||
else if offset<0 then
|
||||
GetReferenceString:=GetReferenceString+ToStr(offset);
|
||||
if (base.enum<>R_NONE) or (index.enum<>R_NONE) then
|
||||
internalerror(2003052601);
|
||||
if symaddr=refs_hi then
|
||||
GetReferenceString:='%hi('+GetReferenceString+')'
|
||||
else if symaddr=refs_lo then
|
||||
GetReferenceString:='%lo('+GetReferenceString+')'
|
||||
else
|
||||
internalerror(2003052602);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if base.enum<>R_NONE then
|
||||
GetReferenceString:=std_reg2str[base.enum]+'+';
|
||||
if index.enum<>R_NONE then
|
||||
GetReferenceString:=GetReferenceString+std_reg2str[index.enum]+'+';
|
||||
if Offset<>0 then
|
||||
internalerror(2003052603);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
AsmWriteLn(s);
|
||||
end;
|
||||
{*****************************************************************************
|
||||
Initialize
|
||||
*****************************************************************************}
|
||||
const
|
||||
as_SPARC_as_info:TAsmInfo=(
|
||||
id:as_gas;
|
||||
idtxt:'AS';
|
||||
asmbin:'as';
|
||||
asmcmd:'-o $OBJ $ASM';
|
||||
supported_target:system_any;
|
||||
outputbinary:false;
|
||||
allowdirect:true;
|
||||
needar:true;
|
||||
labelprefix_only_inside_procedure:false;
|
||||
labelprefix:'.L';
|
||||
comment:';#';
|
||||
secnames:({sec_none}'', {no section}
|
||||
{sec_code}'.text', {executable code}
|
||||
{sec_data}'.data', {initialized R/W data}
|
||||
{sec_bss}'.section ".bss"', {uninitialized R/W data}
|
||||
{sec_idata2}'.comment', {comments}
|
||||
{sec_idata4}'.debug', {debugging information}
|
||||
{sec_idata5}'.rodata', {RO data}
|
||||
{sec_idata6}'.line', {line numbers info for symbolic debug}
|
||||
{sec_idata7}'.init', {runtime intialization code}
|
||||
{sec_edata}'.fini', {runtime finalization code}
|
||||
{sec_stab}'.stab',
|
||||
{sec_stabstr} '.stabstr',
|
||||
{sec_common}'.note') {note info}
|
||||
);
|
||||
initialization
|
||||
|
||||
|
||||
function getopstr(const Oper:TOper):string;
|
||||
var
|
||||
hs:string;
|
||||
begin
|
||||
with Oper do
|
||||
case typ of
|
||||
top_reg:
|
||||
getopstr:=std_reg2str[reg.enum];
|
||||
top_ref:
|
||||
getopstr:=getreferencestring(ref^);
|
||||
top_const:
|
||||
getopstr:=tostr(longint(val));
|
||||
top_symbol:
|
||||
begin
|
||||
if assigned(sym) then
|
||||
hs:={'$'+}sym.name
|
||||
else
|
||||
hs:='$';
|
||||
if symofs>0 then
|
||||
hs:=hs+'+'+tostr(symofs)
|
||||
else
|
||||
if symofs<0 then
|
||||
hs:=hs+tostr(symofs)
|
||||
else
|
||||
if not(assigned(sym)) then
|
||||
hs:=hs+'0';
|
||||
getopstr:=hs;
|
||||
end;
|
||||
else
|
||||
internalerror(10001);
|
||||
end;
|
||||
end;
|
||||
(*
|
||||
function getopstr_jmp(const Oper:TOper):string;
|
||||
var
|
||||
hs:string;
|
||||
begin
|
||||
with Oper do
|
||||
case typ of
|
||||
top_reg:
|
||||
getopstr_jmp:=gas_reg2str[reg]+'+';
|
||||
top_ref:
|
||||
getopstr_jmp:=GetReferenceString(ref^);
|
||||
top_const:
|
||||
getopstr_jmp:=tostr(longint(val));
|
||||
top_symbol:
|
||||
begin
|
||||
hs:=sym.name;
|
||||
if symofs>0 then
|
||||
hs:=hs+'+'+tostr(symofs)
|
||||
else
|
||||
if symofs<0 then
|
||||
hs:=hs+tostr(symofs);
|
||||
getopstr_jmp:=hs;
|
||||
end;
|
||||
else
|
||||
internalerror(10001);
|
||||
end;
|
||||
end;*)
|
||||
|
||||
procedure TGasSPARC.WriteInstruction(hp:Tai);
|
||||
var
|
||||
Op:TAsmOp;
|
||||
s:String;
|
||||
i:Integer;
|
||||
begin
|
||||
if hp.typ<>ait_instruction then
|
||||
exit;
|
||||
op:=taicpu(hp).opcode;
|
||||
{ call maybe not translated to call }
|
||||
s:=#9+std_op2str[op]+cond2str[taicpu(hp).condition];
|
||||
{ process operands }
|
||||
s:=#9+std_op2str[op];
|
||||
if taicpu(hp).ops>0
|
||||
then
|
||||
begin
|
||||
s:=s+#9+getopstr(taicpu(hp).oper[0]);
|
||||
for i:=1 to taicpu(hp).ops-1 do
|
||||
s:=s+','+getopstr(taicpu(hp).oper[i]);
|
||||
end;
|
||||
AsmWriteLn(s);
|
||||
end;
|
||||
|
||||
|
||||
const
|
||||
as_SPARC_as_info:TAsmInfo=(
|
||||
id:as_gas;
|
||||
idtxt:'AS';
|
||||
asmbin:'as';
|
||||
asmcmd:'-o $OBJ $ASM';
|
||||
supported_target:system_any;
|
||||
outputbinary:false;
|
||||
allowdirect:true;
|
||||
needar:true;
|
||||
labelprefix_only_inside_procedure:false;
|
||||
labelprefix:'.L';
|
||||
comment:';#';
|
||||
secnames:({sec_none}'', {no section}
|
||||
{sec_code}'.text', {executable code}
|
||||
{sec_data}'.data', {initialized R/W data}
|
||||
{sec_bss}'.section ".bss"', {uninitialized R/W data}
|
||||
{sec_idata2}'.comment', {comments}
|
||||
{sec_idata4}'.debug', {debugging information}
|
||||
{sec_idata5}'.rodata', {RO data}
|
||||
{sec_idata6}'.line', {line numbers info for symbolic debug}
|
||||
{sec_idata7}'.init', {runtime intialization code}
|
||||
{sec_edata}'.fini', {runtime finalization code}
|
||||
{sec_stab}'.stab',
|
||||
{sec_stabstr} '.stabstr',
|
||||
{sec_common}'.note') {note info}
|
||||
);
|
||||
|
||||
begin
|
||||
RegisterAssembler(as_SPARC_as_info,TGasSPARC);
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.14 2003-05-07 11:55:34 mazen
|
||||
Revision 1.15 2003-05-28 23:18:31 florian
|
||||
* started to fix and clean up the sparc port
|
||||
|
||||
Revision 1.14 2003/05/07 11:55:34 mazen
|
||||
- unused units removed from uses clause
|
||||
- unused variables removed from implemntation declarations
|
||||
|
||||
|
@ -111,8 +111,8 @@ interface
|
||||
system_x86_64_linux, { 26 }
|
||||
system_powerpc_darwin, { 27 }
|
||||
system_i386_EMX, { 28 }
|
||||
system_powerpc_netbsd, { 29 }
|
||||
system_powerpc_openbsd { 30 }
|
||||
system_powerpc_netbsd, { 29 }
|
||||
system_powerpc_openbsd { 30 }
|
||||
);
|
||||
|
||||
tasm = (as_none
|
||||
@ -685,7 +685,10 @@ finalization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.63 2003-05-25 23:15:04 marco
|
||||
Revision 1.64 2003-05-28 23:18:31 florian
|
||||
* started to fix and clean up the sparc port
|
||||
|
||||
Revision 1.63 2003/05/25 23:15:04 marco
|
||||
* NetBSD target support. OpenBSD reserved in the enum, for future use.
|
||||
|
||||
Revision 1.62 2003/05/20 23:54:00 florian
|
||||
@ -782,4 +785,4 @@ end.
|
||||
|
||||
Revision 1.38 2002/04/14 16:56:30 carl
|
||||
- remove duplicate comment
|
||||
}
|
||||
}
|
@ -377,12 +377,14 @@ initialization
|
||||
{$ifdef NetBSD}
|
||||
set_source_info(system_powerpc_netbsd_info);
|
||||
{$endif}
|
||||
|
||||
{$endif cpu68}
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.2 2003-05-25 23:15:04 marco
|
||||
Revision 1.3 2003-05-28 23:18:31 florian
|
||||
* started to fix and clean up the sparc port
|
||||
|
||||
Revision 1.2 2003/05/25 23:15:04 marco
|
||||
* NetBSD target support. OpenBSD reserved in the enum, for future use.
|
||||
|
||||
Revision 1.1 2003/05/20 23:54:00 florian
|
||||
@ -409,4 +411,4 @@ end.
|
||||
|
||||
Revision 1.1 2002/07/26 21:15:38 florian
|
||||
* rewrote the system handling
|
||||
}
|
||||
}
|
@ -63,16 +63,17 @@ interface
|
||||
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.enum>lastreg then
|
||||
internalerror(200301081);
|
||||
if base.enum>lastreg then
|
||||
internalerror(200301081);
|
||||
if index.enum>lastreg then
|
||||
internalerror(200301081);
|
||||
|
||||
{ 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.enum<>R_NO then
|
||||
AsmWrite(gas_reg2str[segment.enum]+':');
|
||||
if assigned(symbol) then
|
||||
@ -347,7 +348,10 @@ initialization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.2 2003-05-22 21:33:31 peter
|
||||
Revision 1.3 2003-05-28 23:18:31 florian
|
||||
* started to fix and clean up the sparc port
|
||||
|
||||
Revision 1.2 2003/05/22 21:33:31 peter
|
||||
* removed some unit dependencies
|
||||
|
||||
Revision 1.1 2003/04/25 12:04:31 florian
|
||||
|
Loading…
Reference in New Issue
Block a user