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