mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 01:29:21 +02:00
* synchronized cpubase between powerpc and i386
* moved more tables from cpubase to cpuasm * tai_align_abstract moved to tainst, cpuasm must define the tai_align class now, which may be empty
This commit is contained in:
parent
4a176c81bc
commit
f6b3e2e37f
@ -68,10 +68,11 @@ interface
|
||||
ait_regalloc, { for register,temp allocation debugging }
|
||||
ait_tempalloc,
|
||||
ait_marker,
|
||||
|
||||
{$ifdef alpha}
|
||||
{ the follow is for the DEC Alpha }
|
||||
ait_frame,
|
||||
ait_ent,
|
||||
{$endif alpha}
|
||||
{$ifdef m68k}
|
||||
ait_labeled_instruction,
|
||||
{$endif m68k}
|
||||
@ -205,22 +206,6 @@ interface
|
||||
end;
|
||||
|
||||
|
||||
{ alignment for operator }
|
||||
{$ifdef i386}
|
||||
tai_align_abstract = class(tai)
|
||||
{$else i386}
|
||||
tai_align = class(tai)
|
||||
{$endif i386}
|
||||
buf : array[0..63] of char; { buf used for fill }
|
||||
aligntype : byte; { 1 = no align, 2 = word align, 4 = dword align }
|
||||
fillsize : byte; { real size to fill }
|
||||
fillop : byte; { value to fill with - optional }
|
||||
use_op : boolean;
|
||||
constructor Create(b:byte);
|
||||
constructor Create_op(b: byte; _op: byte);
|
||||
function getfillbuf:pchar;
|
||||
end;
|
||||
|
||||
{ Insert a section/segment directive }
|
||||
tai_section = class(tai)
|
||||
sec : tsection;
|
||||
@ -742,56 +727,6 @@ uses
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{****************************************************************************
|
||||
TAI_ALIGN
|
||||
****************************************************************************}
|
||||
|
||||
{$ifdef i386}
|
||||
constructor tai_align_abstract.Create(b: byte);
|
||||
{$else i386}
|
||||
constructor tai_align.Create(b: byte);
|
||||
{$endif i386}
|
||||
begin
|
||||
inherited Create;
|
||||
typ:=ait_align;
|
||||
if b in [1,2,4,8,16,32] then
|
||||
aligntype := b
|
||||
else
|
||||
aligntype := 1;
|
||||
fillsize:=0;
|
||||
fillop:=0;
|
||||
use_op:=false;
|
||||
end;
|
||||
|
||||
|
||||
{$ifdef i386}
|
||||
constructor tai_align_abstract.Create_op(b: byte; _op: byte);
|
||||
{$else i386}
|
||||
constructor tai_align.Create_op(b: byte; _op: byte);
|
||||
{$endif i386}
|
||||
begin
|
||||
inherited Create;
|
||||
typ:=ait_align;
|
||||
if b in [1,2,4,8,16,32] then
|
||||
aligntype := b
|
||||
else
|
||||
aligntype := 1;
|
||||
fillsize:=0;
|
||||
fillop:=_op;
|
||||
use_op:=true;
|
||||
fillchar(buf,sizeof(buf),_op)
|
||||
end;
|
||||
|
||||
|
||||
{$ifdef i386}
|
||||
function tai_align_abstract.getfillbuf:pchar;
|
||||
{$else i386}
|
||||
function tai_align.getfillbuf:pchar;
|
||||
{$endif i386}
|
||||
begin
|
||||
getfillbuf:=@buf;
|
||||
end;
|
||||
|
||||
{****************************************************************************
|
||||
TAI_CUT
|
||||
****************************************************************************}
|
||||
@ -1135,7 +1070,13 @@ uses
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.23 2002-04-15 18:54:34 carl
|
||||
Revision 1.24 2002-05-14 17:28:08 peter
|
||||
* synchronized cpubase between powerpc and i386
|
||||
* moved more tables from cpubase to cpuasm
|
||||
* tai_align_abstract moved to tainst, cpuasm must define
|
||||
the tai_align class now, which may be empty
|
||||
|
||||
Revision 1.23 2002/04/15 18:54:34 carl
|
||||
- removed tcpuflags
|
||||
|
||||
Revision 1.22 2002/04/07 13:18:19 carl
|
||||
|
@ -91,9 +91,6 @@ uses globals, aoptcpub, cpuinfo;
|
||||
|
||||
Function RefsEqual(Const R1, R2: TReference): Boolean;
|
||||
Begin
|
||||
If R1.is_immediate Then
|
||||
RefsEqual := R2.is_immediate and (R1.Offset = R2.Offset)
|
||||
Else
|
||||
RefsEqual := (R1.Offset+R1.OffsetFixup = R2.Offset+R2.OffsetFixup)
|
||||
And (R1.Base = R2.Base)
|
||||
{$ifdef RefsHaveindex}
|
||||
@ -106,6 +103,7 @@ Begin
|
||||
{$ifdef RefsHaveSegment}
|
||||
And (R1.Segment = R2.Segment)
|
||||
{$endif RefsHaveSegment}
|
||||
;
|
||||
End;
|
||||
|
||||
|
||||
@ -263,7 +261,13 @@ End.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.1 2001-08-26 13:36:35 florian
|
||||
Revision 1.2 2002-05-14 17:28:09 peter
|
||||
* synchronized cpubase between powerpc and i386
|
||||
* moved more tables from cpubase to cpuasm
|
||||
* tai_align_abstract moved to tainst, cpuasm must define
|
||||
the tai_align class now, which may be empty
|
||||
|
||||
Revision 1.1 2001/08/26 13:36:35 florian
|
||||
* some cg reorganisation
|
||||
* some PPC updates
|
||||
|
||||
|
@ -28,15 +28,6 @@ unit cpuasm;
|
||||
|
||||
{$i defines.inc}
|
||||
|
||||
{ Optimize addressing and skip already passed nodes }
|
||||
{$ifndef NASMDEBUG}
|
||||
{$define OPTEA}
|
||||
{$define PASS2FLAG}
|
||||
{$endif ndef NASMDEBUG}
|
||||
|
||||
{ Give warnings when an immediate is found in the reference struct }
|
||||
{.$define REF_IMMEDIATE_WARN}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
@ -51,6 +42,121 @@ const
|
||||
Instruction table
|
||||
*****************************************************************************}
|
||||
|
||||
const
|
||||
{ Operand types }
|
||||
OT_NONE = $00000000;
|
||||
|
||||
OT_BITS8 = $00000001; { size, and other attributes, of the operand }
|
||||
OT_BITS16 = $00000002;
|
||||
OT_BITS32 = $00000004;
|
||||
OT_BITS64 = $00000008; { FPU only }
|
||||
OT_BITS80 = $00000010;
|
||||
OT_FAR = $00000020; { this means 16:16 or 16:32, like in CALL/JMP }
|
||||
OT_NEAR = $00000040;
|
||||
OT_SHORT = $00000080;
|
||||
|
||||
OT_SIZE_MASK = $000000FF; { all the size attributes }
|
||||
OT_NON_SIZE = longint(not OT_SIZE_MASK);
|
||||
|
||||
OT_SIGNED = $00000100; { the operand need to be signed -128-127 }
|
||||
|
||||
OT_TO = $00000200; { operand is followed by a colon }
|
||||
{ reverse effect in FADD, FSUB &c }
|
||||
OT_COLON = $00000400;
|
||||
|
||||
OT_REGISTER = $00001000;
|
||||
OT_IMMEDIATE = $00002000;
|
||||
OT_IMM8 = $00002001;
|
||||
OT_IMM16 = $00002002;
|
||||
OT_IMM32 = $00002004;
|
||||
OT_IMM64 = $00002008;
|
||||
OT_IMM80 = $00002010;
|
||||
OT_REGMEM = $00200000; { for r/m, ie EA, operands }
|
||||
OT_REGNORM = $00201000; { 'normal' reg, qualifies as EA }
|
||||
OT_REG8 = $00201001;
|
||||
OT_REG16 = $00201002;
|
||||
OT_REG32 = $00201004;
|
||||
OT_MMXREG = $00201008; { MMX registers }
|
||||
OT_XMMREG = $00201010; { Katmai registers }
|
||||
OT_MEMORY = $00204000; { register number in 'basereg' }
|
||||
OT_MEM8 = $00204001;
|
||||
OT_MEM16 = $00204002;
|
||||
OT_MEM32 = $00204004;
|
||||
OT_MEM64 = $00204008;
|
||||
OT_MEM80 = $00204010;
|
||||
OT_FPUREG = $01000000; { floating point stack registers }
|
||||
OT_FPU0 = $01000800; { FPU stack register zero }
|
||||
OT_REG_SMASK = $00070000; { special register operands: these may be treated differently }
|
||||
{ a mask for the following }
|
||||
OT_REG_ACCUM = $00211000; { accumulator: AL, AX or EAX }
|
||||
OT_REG_AL = $00211001; { REG_ACCUM | BITSxx }
|
||||
OT_REG_AX = $00211002; { ditto }
|
||||
OT_REG_EAX = $00211004; { and again }
|
||||
OT_REG_COUNT = $00221000; { counter: CL, CX or ECX }
|
||||
OT_REG_CL = $00221001; { REG_COUNT | BITSxx }
|
||||
OT_REG_CX = $00221002; { ditto }
|
||||
OT_REG_ECX = $00221004; { another one }
|
||||
OT_REG_DX = $00241002;
|
||||
|
||||
OT_REG_SREG = $00081002; { any segment register }
|
||||
OT_REG_CS = $01081002; { CS }
|
||||
OT_REG_DESS = $02081002; { DS, ES, SS (non-CS 86 registers) }
|
||||
OT_REG_FSGS = $04081002; { FS, GS (386 extended registers) }
|
||||
|
||||
OT_REG_CDT = $00101004; { CRn, DRn and TRn }
|
||||
OT_REG_CREG = $08101004; { CRn }
|
||||
OT_REG_CR4 = $08101404; { CR4 (Pentium only) }
|
||||
OT_REG_DREG = $10101004; { DRn }
|
||||
OT_REG_TREG = $20101004; { TRn }
|
||||
|
||||
OT_MEM_OFFS = $00604000; { special type of EA }
|
||||
{ simple [address] offset }
|
||||
OT_ONENESS = $00800000; { special type of immediate operand }
|
||||
{ so UNITY == IMMEDIATE | ONENESS }
|
||||
OT_UNITY = $00802000; { for shift/rotate instructions }
|
||||
|
||||
{Instruction flags }
|
||||
IF_NONE = $00000000;
|
||||
IF_SM = $00000001; { size match first two operands }
|
||||
IF_SM2 = $00000002;
|
||||
IF_SB = $00000004; { unsized operands can't be non-byte }
|
||||
IF_SW = $00000008; { unsized operands can't be non-word }
|
||||
IF_SD = $00000010; { unsized operands can't be nondword }
|
||||
IF_AR0 = $00000020; { SB, SW, SD applies to argument 0 }
|
||||
IF_AR1 = $00000040; { SB, SW, SD applies to argument 1 }
|
||||
IF_AR2 = $00000060; { SB, SW, SD applies to argument 2 }
|
||||
IF_ARMASK = $00000060; { mask for unsized argument spec }
|
||||
IF_PRIV = $00000100; { it's a privileged instruction }
|
||||
IF_SMM = $00000200; { it's only valid in SMM }
|
||||
IF_PROT = $00000400; { it's protected mode only }
|
||||
IF_UNDOC = $00001000; { it's an undocumented instruction }
|
||||
IF_FPU = $00002000; { it's an FPU instruction }
|
||||
IF_MMX = $00004000; { it's an MMX instruction }
|
||||
IF_3DNOW = $00008000; { it's a 3DNow! instruction }
|
||||
IF_SSE = $00010000; { it's a SSE (KNI, MMX2) instruction }
|
||||
IF_PMASK =
|
||||
longint($FF000000); { the mask for processor types }
|
||||
IF_PFMASK =
|
||||
longint($F001FF00); { the mask for disassembly "prefer" }
|
||||
IF_8086 = $00000000; { 8086 instruction }
|
||||
IF_186 = $01000000; { 186+ instruction }
|
||||
IF_286 = $02000000; { 286+ instruction }
|
||||
IF_386 = $03000000; { 386+ instruction }
|
||||
IF_486 = $04000000; { 486+ instruction }
|
||||
IF_PENT = $05000000; { Pentium instruction }
|
||||
IF_P6 = $06000000; { P6 instruction }
|
||||
IF_KATMAI = $07000000; { Katmai instructions }
|
||||
IF_CYRIX = $10000000; { Cyrix-specific instruction }
|
||||
IF_AMD = $20000000; { AMD-specific instruction }
|
||||
{ added flags }
|
||||
IF_PRE = $40000000; { it's a prefix instruction }
|
||||
IF_PASS2 =
|
||||
longint($80000000); { if the instruction can change in a second pass }
|
||||
|
||||
{ Size of the instruction table converted by nasmconv.pas }
|
||||
instabentries = {$i i386nop.inc}
|
||||
maxinfolen = 8;
|
||||
|
||||
type
|
||||
tinsentry=packed record
|
||||
opcode : tasmop;
|
||||
@ -79,10 +185,10 @@ type
|
||||
reg : tregister;
|
||||
constructor create(b:byte);
|
||||
constructor create_op(b: byte; _op: byte);
|
||||
function getfillbuf:pchar;
|
||||
function getfillbuf:pchar;override;
|
||||
end;
|
||||
|
||||
taicpu = class(tainstruction)
|
||||
taicpu = class(taicpu_abstract)
|
||||
opsize : topsize;
|
||||
constructor op_none(op : tasmop;_size : topsize);
|
||||
|
||||
@ -159,6 +265,44 @@ uses
|
||||
ogbase,
|
||||
ag386att;
|
||||
|
||||
const
|
||||
{ Intel style operands ! }
|
||||
opsize_2_type:array[0..2,topsize] of longint=(
|
||||
(OT_NONE,
|
||||
OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS16,OT_BITS32,OT_BITS32,
|
||||
OT_BITS16,OT_BITS32,OT_BITS64,
|
||||
OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,
|
||||
OT_NEAR,OT_FAR,OT_SHORT
|
||||
),
|
||||
(OT_NONE,
|
||||
OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS8,OT_BITS8,OT_BITS16,
|
||||
OT_BITS16,OT_BITS32,OT_BITS64,
|
||||
OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,
|
||||
OT_NEAR,OT_FAR,OT_SHORT
|
||||
),
|
||||
(OT_NONE,
|
||||
OT_BITS8,OT_BITS16,OT_BITS32,OT_NONE,OT_NONE,OT_NONE,
|
||||
OT_BITS16,OT_BITS32,OT_BITS64,
|
||||
OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,
|
||||
OT_NEAR,OT_FAR,OT_SHORT
|
||||
)
|
||||
);
|
||||
|
||||
{ Convert reg to operand type }
|
||||
reg2type : array[firstreg..lastreg] of longint = (OT_NONE,
|
||||
OT_REG_EAX,OT_REG_ECX,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,
|
||||
OT_REG_AX,OT_REG_CX,OT_REG_DX,OT_REG16,OT_REG16,OT_REG16,OT_REG16,OT_REG16,
|
||||
OT_REG_AL,OT_REG_CL,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,
|
||||
OT_REG_CS,OT_REG_DESS,OT_REG_DESS,OT_REG_DESS,OT_REG_FSGS,OT_REG_FSGS,
|
||||
OT_FPU0,OT_FPU0,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,
|
||||
OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,
|
||||
OT_REG_CREG,OT_REG_CREG,OT_REG_CREG,OT_REG_CR4,
|
||||
OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,
|
||||
OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,
|
||||
OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG
|
||||
);
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
TAI_ALIGN
|
||||
****************************************************************************}
|
||||
@ -1663,7 +1807,13 @@ end;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.21 2002-05-12 16:53:16 peter
|
||||
Revision 1.22 2002-05-14 17:28:09 peter
|
||||
* synchronized cpubase between powerpc and i386
|
||||
* moved more tables from cpubase to cpuasm
|
||||
* tai_align_abstract moved to tainst, cpuasm must define
|
||||
the tai_align class now, which may be empty
|
||||
|
||||
Revision 1.21 2002/05/12 16:53:16 peter
|
||||
* moved entry and exitcode to ncgutil and cgobj
|
||||
* foreach gets extra argument for passing local data to the
|
||||
iterator function
|
||||
|
@ -4,10 +4,6 @@
|
||||
|
||||
Contains the base types 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.
|
||||
|
||||
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
|
||||
@ -37,173 +33,23 @@ interface
|
||||
uses
|
||||
globals,cutils,cclasses,aasm,cpuinfo,cginfo;
|
||||
|
||||
const
|
||||
{ Size of the instruction table converted by nasmconv.pas }
|
||||
instabentries = {$i i386nop.inc}
|
||||
maxinfolen = 8;
|
||||
|
||||
{ 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 }
|
||||
{$ifdef NORA386INT}
|
||||
{$ifdef NOAG386NSM}
|
||||
{$ifdef NOAG386INT}
|
||||
{$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 }
|
||||
{$ifdef NORA386ATT}
|
||||
{$ifdef NOAG386ATT}
|
||||
{$undef ATTOP}
|
||||
{$ifdef NOAG386DIR}
|
||||
{$undef ATTREG}
|
||||
{$endif}
|
||||
{$endif}
|
||||
{$endif}
|
||||
|
||||
{ We need the AT&T suffix table for both asm readers and AT&T writer }
|
||||
{$define ATTSUF}
|
||||
{$ifdef NORA386INT}
|
||||
{$ifdef NORA386ATT}
|
||||
{$ifdef NOAG386ATT}
|
||||
{$undef ATTSUF}
|
||||
{$endif}
|
||||
{$endif}
|
||||
{$endif}
|
||||
|
||||
const
|
||||
{ Operand types }
|
||||
OT_NONE = $00000000;
|
||||
|
||||
OT_BITS8 = $00000001; { size, and other attributes, of the operand }
|
||||
OT_BITS16 = $00000002;
|
||||
OT_BITS32 = $00000004;
|
||||
OT_BITS64 = $00000008; { FPU only }
|
||||
OT_BITS80 = $00000010;
|
||||
OT_FAR = $00000020; { this means 16:16 or 16:32, like in CALL/JMP }
|
||||
OT_NEAR = $00000040;
|
||||
OT_SHORT = $00000080;
|
||||
|
||||
OT_SIZE_MASK = $000000FF; { all the size attributes }
|
||||
OT_NON_SIZE = longint(not OT_SIZE_MASK);
|
||||
|
||||
OT_SIGNED = $00000100; { the operand need to be signed -128-127 }
|
||||
|
||||
OT_TO = $00000200; { operand is followed by a colon }
|
||||
{ reverse effect in FADD, FSUB &c }
|
||||
OT_COLON = $00000400;
|
||||
|
||||
OT_REGISTER = $00001000;
|
||||
OT_IMMEDIATE = $00002000;
|
||||
OT_IMM8 = $00002001;
|
||||
OT_IMM16 = $00002002;
|
||||
OT_IMM32 = $00002004;
|
||||
OT_IMM64 = $00002008;
|
||||
OT_IMM80 = $00002010;
|
||||
OT_REGMEM = $00200000; { for r/m, ie EA, operands }
|
||||
OT_REGNORM = $00201000; { 'normal' reg, qualifies as EA }
|
||||
OT_REG8 = $00201001;
|
||||
OT_REG16 = $00201002;
|
||||
OT_REG32 = $00201004;
|
||||
OT_MMXREG = $00201008; { MMX registers }
|
||||
OT_XMMREG = $00201010; { Katmai registers }
|
||||
OT_MEMORY = $00204000; { register number in 'basereg' }
|
||||
OT_MEM8 = $00204001;
|
||||
OT_MEM16 = $00204002;
|
||||
OT_MEM32 = $00204004;
|
||||
OT_MEM64 = $00204008;
|
||||
OT_MEM80 = $00204010;
|
||||
OT_FPUREG = $01000000; { floating point stack registers }
|
||||
OT_FPU0 = $01000800; { FPU stack register zero }
|
||||
OT_REG_SMASK = $00070000; { special register operands: these may be treated differently }
|
||||
{ a mask for the following }
|
||||
OT_REG_ACCUM = $00211000; { accumulator: AL, AX or EAX }
|
||||
OT_REG_AL = $00211001; { REG_ACCUM | BITSxx }
|
||||
OT_REG_AX = $00211002; { ditto }
|
||||
OT_REG_EAX = $00211004; { and again }
|
||||
OT_REG_COUNT = $00221000; { counter: CL, CX or ECX }
|
||||
OT_REG_CL = $00221001; { REG_COUNT | BITSxx }
|
||||
OT_REG_CX = $00221002; { ditto }
|
||||
OT_REG_ECX = $00221004; { another one }
|
||||
OT_REG_DX = $00241002;
|
||||
|
||||
OT_REG_SREG = $00081002; { any segment register }
|
||||
OT_REG_CS = $01081002; { CS }
|
||||
OT_REG_DESS = $02081002; { DS, ES, SS (non-CS 86 registers) }
|
||||
OT_REG_FSGS = $04081002; { FS, GS (386 extended registers) }
|
||||
|
||||
OT_REG_CDT = $00101004; { CRn, DRn and TRn }
|
||||
OT_REG_CREG = $08101004; { CRn }
|
||||
OT_REG_CR4 = $08101404; { CR4 (Pentium only) }
|
||||
OT_REG_DREG = $10101004; { DRn }
|
||||
OT_REG_TREG = $20101004; { TRn }
|
||||
|
||||
OT_MEM_OFFS = $00604000; { special type of EA }
|
||||
{ simple [address] offset }
|
||||
OT_ONENESS = $00800000; { special type of immediate operand }
|
||||
{ so UNITY == IMMEDIATE | ONENESS }
|
||||
OT_UNITY = $00802000; { for shift/rotate instructions }
|
||||
|
||||
{Instruction flags }
|
||||
IF_NONE = $00000000;
|
||||
IF_SM = $00000001; { size match first two operands }
|
||||
IF_SM2 = $00000002;
|
||||
IF_SB = $00000004; { unsized operands can't be non-byte }
|
||||
IF_SW = $00000008; { unsized operands can't be non-word }
|
||||
IF_SD = $00000010; { unsized operands can't be nondword }
|
||||
IF_AR0 = $00000020; { SB, SW, SD applies to argument 0 }
|
||||
IF_AR1 = $00000040; { SB, SW, SD applies to argument 1 }
|
||||
IF_AR2 = $00000060; { SB, SW, SD applies to argument 2 }
|
||||
IF_ARMASK = $00000060; { mask for unsized argument spec }
|
||||
IF_PRIV = $00000100; { it's a privileged instruction }
|
||||
IF_SMM = $00000200; { it's only valid in SMM }
|
||||
IF_PROT = $00000400; { it's protected mode only }
|
||||
IF_UNDOC = $00001000; { it's an undocumented instruction }
|
||||
IF_FPU = $00002000; { it's an FPU instruction }
|
||||
IF_MMX = $00004000; { it's an MMX instruction }
|
||||
IF_3DNOW = $00008000; { it's a 3DNow! instruction }
|
||||
IF_SSE = $00010000; { it's a SSE (KNI, MMX2) instruction }
|
||||
IF_PMASK =
|
||||
longint($FF000000); { the mask for processor types }
|
||||
IF_PFMASK =
|
||||
longint($F001FF00); { the mask for disassembly "prefer" }
|
||||
IF_8086 = $00000000; { 8086 instruction }
|
||||
IF_186 = $01000000; { 186+ instruction }
|
||||
IF_286 = $02000000; { 286+ instruction }
|
||||
IF_386 = $03000000; { 386+ instruction }
|
||||
IF_486 = $04000000; { 486+ instruction }
|
||||
IF_PENT = $05000000; { Pentium instruction }
|
||||
IF_P6 = $06000000; { P6 instruction }
|
||||
IF_KATMAI = $07000000; { Katmai instructions }
|
||||
IF_CYRIX = $10000000; { Cyrix-specific instruction }
|
||||
IF_AMD = $20000000; { AMD-specific instruction }
|
||||
{ added flags }
|
||||
IF_PRE = $40000000; { it's a prefix instruction }
|
||||
IF_PASS2 =
|
||||
longint($80000000); { if the instruction can change in a second pass }
|
||||
{*****************************************************************************
|
||||
Assembler Opcodes
|
||||
*****************************************************************************}
|
||||
|
||||
type
|
||||
|
||||
TAsmOp={$i i386op.inc}
|
||||
|
||||
{# This should define the array of instructions as string }
|
||||
op2strtable=array[tasmop] of string[11];
|
||||
|
||||
Const
|
||||
|
||||
{# First value of opcode enumeration }
|
||||
firstop = low(tasmop);
|
||||
{# Last value of opcode enumeration }
|
||||
lastop = high(tasmop);
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
Operand Sizes
|
||||
*****************************************************************************}
|
||||
@ -216,55 +62,6 @@ type
|
||||
S_NEAR,S_FAR,S_SHORT
|
||||
);
|
||||
|
||||
const
|
||||
{ Intel style operands ! }
|
||||
opsize_2_type:array[0..2,topsize] of longint=(
|
||||
(OT_NONE,
|
||||
OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS16,OT_BITS32,OT_BITS32,
|
||||
OT_BITS16,OT_BITS32,OT_BITS64,
|
||||
OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,
|
||||
OT_NEAR,OT_FAR,OT_SHORT
|
||||
),
|
||||
(OT_NONE,
|
||||
OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS8,OT_BITS8,OT_BITS16,
|
||||
OT_BITS16,OT_BITS32,OT_BITS64,
|
||||
OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,
|
||||
OT_NEAR,OT_FAR,OT_SHORT
|
||||
),
|
||||
(OT_NONE,
|
||||
OT_BITS8,OT_BITS16,OT_BITS32,OT_NONE,OT_NONE,OT_NONE,
|
||||
OT_BITS16,OT_BITS32,OT_BITS64,
|
||||
OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,
|
||||
OT_NEAR,OT_FAR,OT_SHORT
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
Conditions
|
||||
*****************************************************************************}
|
||||
|
||||
type
|
||||
TAsmCond=(C_None,
|
||||
C_A,C_AE,C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_NA,C_NAE,
|
||||
C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_NO,C_NP,
|
||||
C_NS,C_NZ,C_O,C_P,C_PE,C_PO,C_S,C_Z
|
||||
);
|
||||
|
||||
const
|
||||
cond2str:array[TAsmCond] of string[3]=('',
|
||||
'a','ae','b','be','c','e','g','ge','l','le','na','nae',
|
||||
'nb','nbe','nc','ne','ng','nge','nl','nle','no','np',
|
||||
'ns','nz','o','p','pe','po','s','z'
|
||||
);
|
||||
inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
|
||||
C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
|
||||
C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
|
||||
C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
|
||||
);
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
Registers
|
||||
*****************************************************************************}
|
||||
@ -323,20 +120,6 @@ const
|
||||
S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D
|
||||
);
|
||||
|
||||
{ Convert reg to operand type }
|
||||
reg2type : array[firstreg..lastreg] of longint = (OT_NONE,
|
||||
OT_REG_EAX,OT_REG_ECX,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,
|
||||
OT_REG_AX,OT_REG_CX,OT_REG_DX,OT_REG16,OT_REG16,OT_REG16,OT_REG16,OT_REG16,
|
||||
OT_REG_AL,OT_REG_CL,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,
|
||||
OT_REG_CS,OT_REG_DESS,OT_REG_DESS,OT_REG_DESS,OT_REG_FSGS,OT_REG_FSGS,
|
||||
OT_FPU0,OT_FPU0,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,
|
||||
OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,
|
||||
OT_REG_CREG,OT_REG_CREG,OT_REG_CREG,OT_REG_CR4,
|
||||
OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,
|
||||
OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,
|
||||
OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG
|
||||
);
|
||||
|
||||
{# Standard opcode string table (for each tasmop enumeration). The
|
||||
opcode strings should conform to the names as defined by the
|
||||
processor manufacturer.
|
||||
@ -360,6 +143,29 @@ const
|
||||
'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
|
||||
);
|
||||
|
||||
{*****************************************************************************
|
||||
Conditions
|
||||
*****************************************************************************}
|
||||
|
||||
type
|
||||
TAsmCond=(C_None,
|
||||
C_A,C_AE,C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_NA,C_NAE,
|
||||
C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_NO,C_NP,
|
||||
C_NS,C_NZ,C_O,C_P,C_PE,C_PO,C_S,C_Z
|
||||
);
|
||||
|
||||
const
|
||||
cond2str:array[TAsmCond] of string[3]=('',
|
||||
'a','ae','b','be','c','e','g','ge','l','le','na','nae',
|
||||
'nb','nbe','nc','ne','ng','nge','nl','nle','no','np',
|
||||
'ns','nz','o','p','pe','po','s','z'
|
||||
);
|
||||
|
||||
inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
|
||||
C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
|
||||
C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
|
||||
C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
|
||||
);
|
||||
|
||||
{*****************************************************************************
|
||||
Flags
|
||||
@ -375,9 +181,8 @@ type
|
||||
type
|
||||
trefoptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
|
||||
|
||||
type
|
||||
{ immediate/reference record }
|
||||
poperreference = ^treference;
|
||||
{ reference record }
|
||||
preference = ^treference;
|
||||
treference = packed record
|
||||
segment,
|
||||
base,
|
||||
@ -401,18 +206,11 @@ type
|
||||
case typ : toptype of
|
||||
top_none : ();
|
||||
top_reg : (reg:tregister);
|
||||
top_ref : (ref:poperreference);
|
||||
top_ref : (ref:preference);
|
||||
top_const : (val:aword);
|
||||
top_symbol : (sym:tasmsymbol;symofs:longint);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
Argument Classification
|
||||
*****************************************************************************}
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
Generic Location
|
||||
*****************************************************************************}
|
||||
@ -435,7 +233,6 @@ type
|
||||
LOC_CSSEREGISTER
|
||||
);
|
||||
|
||||
plocation = ^tlocation;
|
||||
tlocation = packed record
|
||||
loc : TLoc;
|
||||
size : TCGSize;
|
||||
@ -464,8 +261,26 @@ type
|
||||
*****************************************************************************}
|
||||
|
||||
const
|
||||
max_operands = 3;
|
||||
|
||||
lvaluelocations = [LOC_REFERENCE,LOC_CFPUREGISTER,
|
||||
LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER];
|
||||
|
||||
{# Constant defining possibly all registers which might require saving }
|
||||
ALL_REGISTERS = [firstreg..lastreg];
|
||||
|
||||
general_registers = [R_EAX,R_EBX,R_ECX,R_EDX];
|
||||
|
||||
{# low and high of the available maximum width integer general purpose }
|
||||
{ registers }
|
||||
LoGPReg = R_EAX;
|
||||
HiGPReg = R_EDX;
|
||||
|
||||
{# low and high of every possible width general purpose register (same as }
|
||||
{ above on most architctures apart from the 80x86) }
|
||||
LoReg = R_EAX;
|
||||
HiReg = R_DH;
|
||||
|
||||
{# Table of registers which can be allocated by the code generator
|
||||
internally, when generating the code.
|
||||
}
|
||||
@ -478,10 +293,12 @@ const
|
||||
{ passing on ABI's that define this) }
|
||||
{ c_countusableregsxxx = amount of registers in the usableregsxxx set }
|
||||
|
||||
maxintregs = 4;
|
||||
intregs = [R_EAX..R_BL];
|
||||
usableregsint = general_registers;
|
||||
usableregsint = [R_EAX,R_EBX,R_ECX,R_EDX];
|
||||
c_countusableregsint = 4;
|
||||
|
||||
maxfpuregs = 8;
|
||||
fpuregs = [R_ST0..R_ST7];
|
||||
usableregsfpu = [];
|
||||
c_countusableregsfpu = 0;
|
||||
@ -497,15 +314,22 @@ const
|
||||
firstsavemmreg = R_MM0;
|
||||
lastsavemmreg = R_MM7;
|
||||
|
||||
{# Constant defining possibly all registers which might require saving }
|
||||
ALL_REGISTERS = [firstreg..lastreg];
|
||||
maxvarregs = 4;
|
||||
varregs : array[1..maxvarregs] of tregister =
|
||||
(R_EBX,R_EDX,R_ECX,R_EAX);
|
||||
|
||||
lvaluelocations = [LOC_REFERENCE,LOC_CFPUREGISTER,
|
||||
LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER];
|
||||
maxfpuvarregs = 8;
|
||||
|
||||
{# Registers which are defined as scratch and no need to save across
|
||||
routine calls or in assembler blocks.
|
||||
}
|
||||
max_scratch_regs = 1;
|
||||
scratch_regs : array[1..max_scratch_regs] of tregister = (R_EDI);
|
||||
|
||||
{*****************************************************************************
|
||||
Default generic sizes
|
||||
*****************************************************************************}
|
||||
|
||||
{# Defines the default address size for a processor, }
|
||||
OS_ADDR = OS_32;
|
||||
{# the natural int size for a processor, }
|
||||
@ -538,17 +362,11 @@ const
|
||||
fpuresultreg = R_ST;
|
||||
mmresultreg = R_MM0;
|
||||
|
||||
{# Registers which are defined as scratch and no need to save across
|
||||
routine calls or in assembler blocks.
|
||||
}
|
||||
scratch_regs : array[1..1] of tregister = (R_EDI);
|
||||
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
GCC /ABI linking information
|
||||
*****************************************************************************}
|
||||
|
||||
const
|
||||
{# 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.
|
||||
@ -566,26 +384,14 @@ const
|
||||
}
|
||||
std_param_align = 4;
|
||||
|
||||
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
CPU Dependent Constants
|
||||
*****************************************************************************}
|
||||
|
||||
{*****************************************************************************
|
||||
Helpers
|
||||
*****************************************************************************}
|
||||
|
||||
const
|
||||
maxvarregs = 4;
|
||||
varregs : array[1..maxvarregs] of tregister =
|
||||
(R_EBX,R_EDX,R_ECX,R_EAX);
|
||||
|
||||
maxfpuvarregs = 8;
|
||||
max_operands = 3;
|
||||
|
||||
maxintregs = maxvarregs;
|
||||
maxfpuregs = maxfpuvarregs;
|
||||
|
||||
|
||||
function is_calljmp(o:tasmop):boolean;
|
||||
|
||||
function flags_to_cond(const f: TResFlags) : TAsmCond;
|
||||
@ -593,17 +399,10 @@ const
|
||||
|
||||
implementation
|
||||
|
||||
{$ifdef heaptrc}
|
||||
uses
|
||||
ppheap;
|
||||
{$endif heaptrc}
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
Helpers
|
||||
*****************************************************************************}
|
||||
|
||||
|
||||
function is_calljmp(o:tasmop):boolean;
|
||||
begin
|
||||
case o of
|
||||
@ -624,9 +423,6 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function flags_to_cond(const f: TResFlags) : TAsmCond;
|
||||
const
|
||||
flags_2_cond : array[TResFlags] of TAsmCond =
|
||||
@ -635,11 +431,16 @@ implementation
|
||||
result := flags_2_cond[f];
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.19 2002-05-12 16:53:16 peter
|
||||
Revision 1.20 2002-05-14 17:28:09 peter
|
||||
* synchronized cpubase between powerpc and i386
|
||||
* moved more tables from cpubase to cpuasm
|
||||
* tai_align_abstract moved to tainst, cpuasm must define
|
||||
the tai_align class now, which may be empty
|
||||
|
||||
Revision 1.19 2002/05/12 16:53:16 peter
|
||||
* moved entry and exitcode to ncgutil and cgobj
|
||||
* foreach gets extra argument for passing local data to the
|
||||
iterator function
|
||||
|
@ -1616,7 +1616,7 @@ Begin
|
||||
End;
|
||||
|
||||
|
||||
Procedure ReadRef(p: PTaiProp; Const Ref: POperReference);
|
||||
Procedure ReadRef(p: PTaiProp; Const Ref: PReference);
|
||||
Begin
|
||||
If Ref^.Base <> R_NO Then
|
||||
ReadReg(p, Ref^.Base);
|
||||
@ -2591,7 +2591,13 @@ End.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.34 2002-05-12 16:53:16 peter
|
||||
Revision 1.35 2002-05-14 17:28:09 peter
|
||||
* synchronized cpubase between powerpc and i386
|
||||
* moved more tables from cpubase to cpuasm
|
||||
* tai_align_abstract moved to tainst, cpuasm must define
|
||||
the tai_align class now, which may be empty
|
||||
|
||||
Revision 1.34 2002/05/12 16:53:16 peter
|
||||
* moved entry and exitcode to ncgutil and cgobj
|
||||
* foreach gets extra argument for passing local data to the
|
||||
iterator function
|
||||
|
@ -228,14 +228,16 @@ const
|
||||
|
||||
procedure tcgppc.a_call_name(list : taasmoutput;const s : string);
|
||||
|
||||
var
|
||||
href : treference;
|
||||
begin
|
||||
{ save our RTOC register value. Only necessary when doing pointer based }
|
||||
{ calls or cross TOC calls, but currently done always }
|
||||
list.concat(taicpu.op_reg_ref(A_STW,R_RTOC,
|
||||
new_reference(STACK_POINTER_REG,LA_RTOC)));
|
||||
reference_reset_base(href,STACK_POINTER_REG,LA_RTOC);
|
||||
list.concat(taicpu.op_reg_ref(A_STW,R_TOC,href));
|
||||
list.concat(taicpu.op_sym(A_BL,newasmsymbol(s)));
|
||||
list.concat(taicpu.op_reg_ref(A_LWZ,R_RTOC,
|
||||
new_reference(STACK_POINTER_REG,LA_RTOC)));
|
||||
reference_reset_base(href,STACK_POINTER_REG,LA_RTOC);
|
||||
list.concat(taicpu.op_reg_ref(A_LWZ,R_TOC,href));
|
||||
end;
|
||||
|
||||
{********************** load instructions ********************}
|
||||
@ -301,10 +303,6 @@ const
|
||||
tmpreg: tregister;
|
||||
ref2, tmpref: treference;
|
||||
|
||||
begin
|
||||
if ref.is_immediate then
|
||||
a_load_const_reg(list,size,ref.offset,reg)
|
||||
else
|
||||
begin
|
||||
ref2 := ref;
|
||||
fixref(list,ref2);
|
||||
@ -315,7 +313,6 @@ const
|
||||
if size = OS_S8 then
|
||||
list.concat(taicpu.op_reg_reg(A_EXTSB,reg,reg));
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppc.a_load_reg_reg(list : taasmoutput;size : tcgsize;reg1,reg2 : tregister);
|
||||
@ -701,6 +698,7 @@ const
|
||||
{ combined size of ALL the parameters of a procedure called by the current }
|
||||
{ one }
|
||||
var regcounter: TRegister;
|
||||
href : treference;
|
||||
|
||||
begin
|
||||
if (localsize mod 8) <> 0 then internalerror(58991);
|
||||
@ -716,7 +714,8 @@ const
|
||||
{ save return address... }
|
||||
list.concat(taicpu.op_reg_reg(A_MFSPR,R_0,R_LR));
|
||||
{ ... in caller's frame }
|
||||
list.concat(taicpu.op_reg_ref(A_STW,R_0,new_reference(STACK_POINTER_REG,4)));
|
||||
reference_reset_base(href,STACK_POINTER_REG,4);
|
||||
list.concat(taicpu.op_reg_ref(A_STW,R_0,href));
|
||||
a_reg_dealloc(list,R_0);
|
||||
a_reg_alloc(list,R_11);
|
||||
{ save end of fpr save area }
|
||||
@ -761,6 +760,7 @@ const
|
||||
{ combined size of ALL the parameters of a procedure called by the current }
|
||||
{ one }
|
||||
var regcounter: TRegister;
|
||||
href : treference;
|
||||
|
||||
begin
|
||||
if (localsize mod 8) <> 0 then internalerror(58991);
|
||||
@ -776,19 +776,21 @@ const
|
||||
{ save return address... }
|
||||
list.concat(taicpu.op_reg_reg(A_MFSPR,R_0,R_LR));
|
||||
{ ... in caller's frame }
|
||||
list.concat(taicpu.op_reg_ref(A_STW,R_0,new_reference(STACK_POINTER_REG,8)));
|
||||
reference_reset_base(href,STACK_POINTER_REG,8);
|
||||
list.concat(taicpu.op_reg_ref(A_STW,R_0,href));
|
||||
a_reg_dealloc(list,R_0);
|
||||
{ save floating-point registers }
|
||||
{ !!! has to be optimized: only save registers that are used }
|
||||
list.concat(taicpu.op_sym_ofs(A_BL,newasmsymbol('_savef14'),0));
|
||||
{ save gprs in gpr save area }
|
||||
{ !!! has to be optimized: only save registers that are used }
|
||||
list.concat(taicpu.op_reg_ref(A_STMW,R_13,new_reference(STACK_POINTER_REG,-220)));
|
||||
reference_reset_base(href,STACK_POINTER_REG,-220);
|
||||
list.concat(taicpu.op_reg_ref(A_STMW,R_13,href));
|
||||
{ save the CR if necessary ( !!! always done currently ) }
|
||||
a_reg_alloc(list,R_0);
|
||||
list.concat(taicpu.op_reg_reg(A_MFSPR,R_0,R_CR));
|
||||
list.concat(taicpu.op_reg_ref(A_STW,R_0,
|
||||
new_reference(stack_pointer_reg,LA_CR)));
|
||||
reference_reset_base(href,stack_pointer_reg,LA_CR);
|
||||
list.concat(taicpu.op_reg_ref(A_STW,R_0,href));
|
||||
a_reg_dealloc(list,R_0);
|
||||
{ save pointer to incoming arguments }
|
||||
list.concat(taicpu.op_reg_reg_const(A_ORI,R_31,STACK_POINTER_REG,0));
|
||||
@ -840,22 +842,20 @@ const
|
||||
{ reference doesn't have a base, create one }
|
||||
begin
|
||||
tmpreg := get_scratch_reg(list);
|
||||
reset_reference(tmpref);
|
||||
reference_reset(tmpref);
|
||||
tmpref.symbol := ref2.symbol;
|
||||
tmpref.symaddr := refs_ha;
|
||||
tmpref.is_immediate := true;
|
||||
// tmpref.is_immediate := true;
|
||||
if ref2.base <> R_NO then
|
||||
list.concat(taicpu.op_reg_reg_ref(A_ADDIS,tmpreg,
|
||||
ref2.base,newreference(tmpref)))
|
||||
ref2.base,tmpref))
|
||||
else
|
||||
list.concat(taicpu.op_reg_ref(A_LIS,tmpreg,
|
||||
newreference(tmpref)));
|
||||
list.concat(taicpu.op_reg_ref(A_LIS,tmpreg,tmpref));
|
||||
ref2.base := tmpreg;
|
||||
ref2.symaddr := refs_l;
|
||||
{ can be folded with one of the next instructions by the }
|
||||
{ optimizer probably }
|
||||
list.concat(taicpu.op_reg_reg_ref(A_ADDI,tmpreg,tmpreg,
|
||||
newreference(tmpref)));
|
||||
list.concat(taicpu.op_reg_reg_ref(A_ADDI,tmpreg,tmpreg,tmpref));
|
||||
end;
|
||||
if ref2.offset <> 0 Then
|
||||
if ref2.base <> R_NO then
|
||||
@ -890,8 +890,8 @@ const
|
||||
fixref(list,src);
|
||||
dst := dest;
|
||||
fixref(list,dst);
|
||||
reset_reference(src);
|
||||
reset_reference(dst);
|
||||
reference_reset(src);
|
||||
reference_reset(dst);
|
||||
{ load the address of source into src.base }
|
||||
src.base := get_scratch_reg(list);
|
||||
if loadref then
|
||||
@ -922,10 +922,9 @@ const
|
||||
a_reg_alloc(list,R_0);
|
||||
getlabel(lab);
|
||||
a_label(list, lab);
|
||||
list.concat(taicpu.op_reg_ref(A_LWZU,tempreg,
|
||||
newreference(src)));
|
||||
list.concat(taicpu.op_reg_ref(A_LWZU,tempreg,src));
|
||||
list.concat(taicpu.op_reg_reg_const(A_CMPI,R_CR0,countreg,0));
|
||||
list.concat(taicpu.op_reg_ref(A_STWU,tempreg,newreference(dst)));
|
||||
list.concat(taicpu.op_reg_ref(A_STWU,tempreg,dst));
|
||||
list.concat(taicpu.op_reg_reg_const(A_SUBI,countreg,countreg,1));
|
||||
a_jmp(list,A_BC,C_NE,0,lab);
|
||||
free_scratch_reg(list,countreg);
|
||||
@ -1012,7 +1011,7 @@ const
|
||||
|
||||
var
|
||||
regcounter: TRegister;
|
||||
|
||||
href : treference;
|
||||
begin
|
||||
{ release parameter registers }
|
||||
for regcounter := R_3 to R_10 do
|
||||
@ -1022,9 +1021,11 @@ const
|
||||
{ restore SP }
|
||||
list.concat(taicpu.op_reg_reg_const(A_ORI,STACK_POINTER_REG,R_31,0));
|
||||
{ restore gprs }
|
||||
list.concat(taicpu.op_reg_ref(A_LMW,R_13,new_reference(STACK_POINTER_REG,-220)));
|
||||
reference_reset_base(href,STACK_POINTER_REG,-220);
|
||||
list.concat(taicpu.op_reg_ref(A_LMW,R_13,href));
|
||||
{ restore return address ... }
|
||||
list.concat(taicpu.op_reg_ref(A_LWZ,R_0,new_reference(STACK_POINTER_REG,8)));
|
||||
reference_reset_base(href,STACK_POINTER_REG,8);
|
||||
list.concat(taicpu.op_reg_ref(A_LWZ,R_0,href));
|
||||
{ ... and return from _restf14 }
|
||||
list.concat(taicpu.op_sym_ofs(A_B,newasmsymbol('_restf14'),0));
|
||||
end;
|
||||
@ -1137,20 +1138,19 @@ const
|
||||
if assigned(ref.symbol) then
|
||||
begin
|
||||
tmpreg := get_scratch_reg(list);
|
||||
reset_reference(tmpref);
|
||||
reference_reset(tmpref);
|
||||
tmpref.symbol := ref.symbol;
|
||||
tmpref.symaddr := refs_ha;
|
||||
tmpref.is_immediate := true;
|
||||
// tmpref.is_immediate := true;
|
||||
if ref.base <> R_NO then
|
||||
list.concat(taicpu.op_reg_reg_ref(A_ADDIS,tmpreg,
|
||||
ref.base,newreference(tmpref)))
|
||||
ref.base,tmpref))
|
||||
else
|
||||
list.concat(taicpu.op_reg_ref(A_LIS,tmpreg,
|
||||
newreference(tmpref)));
|
||||
list.concat(taicpu.op_reg_ref(A_LIS,tmpreg,tmpref));
|
||||
ref.base := tmpreg;
|
||||
ref.symaddr := refs_l;
|
||||
end;
|
||||
list.concat(taicpu.op_reg_ref(op,reg,newreference(ref)));
|
||||
list.concat(taicpu.op_reg_ref(op,reg,ref));
|
||||
if assigned(ref.symbol) then
|
||||
free_scratch_reg(list,tmpreg);
|
||||
end;
|
||||
@ -1173,7 +1173,13 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.14 2002-05-13 19:52:46 peter
|
||||
Revision 1.15 2002-05-14 17:28:10 peter
|
||||
* synchronized cpubase between powerpc and i386
|
||||
* moved more tables from cpubase to cpuasm
|
||||
* tai_align_abstract moved to tainst, cpuasm must define
|
||||
the tai_align class now, which may be empty
|
||||
|
||||
Revision 1.14 2002/05/13 19:52:46 peter
|
||||
* a ppcppc can be build again
|
||||
|
||||
Revision 1.13 2002/04/20 21:41:51 carl
|
||||
|
@ -32,15 +32,14 @@ uses
|
||||
cpubase;
|
||||
|
||||
type
|
||||
|
||||
taicpu = class(tainstruction)
|
||||
taicpu = class(taicpu_abstract)
|
||||
constructor op_none(op : tasmop);
|
||||
|
||||
constructor op_reg(op : tasmop;_op1 : tregister);
|
||||
constructor op_const(op : tasmop;_op1 : longint);
|
||||
|
||||
constructor op_reg_reg(op : tasmop;_op1,_op2 : tregister);
|
||||
constructor op_reg_ref(op : tasmop;_op1 : tregister;_op2 : preference);
|
||||
constructor op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
|
||||
constructor op_reg_const(op:tasmop; _op1: tregister; _op2: longint);
|
||||
constructor op_const_reg(op:tasmop; _op1: longint; _op2: tregister);
|
||||
|
||||
@ -49,7 +48,7 @@ type
|
||||
constructor op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
|
||||
constructor op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: Longint);
|
||||
constructor op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
|
||||
constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; _op3: preference);
|
||||
constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
|
||||
constructor op_const_reg_reg(op : tasmop;_op1 : longint;_op2, _op3 : tregister);
|
||||
constructor op_const_reg_const(op : tasmop;_op1 : longint;_op2 : tregister;_op3 : longint);
|
||||
|
||||
@ -68,18 +67,17 @@ type
|
||||
constructor op_sym(op : tasmop;_op1 : tasmsymbol);
|
||||
constructor op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
|
||||
constructor op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:tasmsymbol;_op2ofs : longint);
|
||||
constructor op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;_op2 : preference);
|
||||
constructor op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
|
||||
|
||||
procedure loadbool(opidx:longint;_b:boolean);
|
||||
procedure loadconst(opidx:longint;l:longint);
|
||||
procedure loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
|
||||
procedure loadref(opidx:longint;p:preference);
|
||||
procedure loadreg(opidx:longint;r:tregister);
|
||||
procedure loadoper(opidx:longint;o:toper);
|
||||
|
||||
destructor destroy;override;
|
||||
end;
|
||||
|
||||
tai_align = class(tai_align_abstract)
|
||||
{ nothing to add }
|
||||
end;
|
||||
|
||||
procedure InitAsm;
|
||||
procedure DoneAsm;
|
||||
|
||||
@ -90,93 +88,6 @@ implementation
|
||||
taicpu Constructors
|
||||
*****************************************************************************}
|
||||
|
||||
procedure taicpu.loadconst(opidx:longint;l:longint);
|
||||
begin
|
||||
if opidx>=ops then
|
||||
ops:=opidx+1;
|
||||
with oper[opidx] do
|
||||
begin
|
||||
if typ=top_ref then
|
||||
disposereference(ref);
|
||||
val:=l;
|
||||
typ:=top_const;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure taicpu.loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
|
||||
begin
|
||||
if opidx>=ops then
|
||||
ops:=opidx+1;
|
||||
with oper[opidx] do
|
||||
begin
|
||||
if typ=top_ref then
|
||||
disposereference(ref);
|
||||
sym:=s;
|
||||
symofs:=sofs;
|
||||
typ:=top_symbol;
|
||||
end;
|
||||
{ Mark the symbol as used }
|
||||
if assigned(s) then
|
||||
inc(s.refs);
|
||||
end;
|
||||
|
||||
|
||||
procedure taicpu.loadref(opidx:longint;p:preference);
|
||||
begin
|
||||
if opidx>=ops then
|
||||
ops:=opidx+1;
|
||||
with oper[opidx] do
|
||||
begin
|
||||
if typ=top_ref then
|
||||
disposereference(ref);
|
||||
if p^.is_immediate then
|
||||
begin
|
||||
{$ifdef REF_IMMEDIATE_WARN}
|
||||
Comment(V_Warning,'Reference immediate');
|
||||
{$endif}
|
||||
val:=p^.offset;
|
||||
disposereference(p);
|
||||
typ:=top_const;
|
||||
end
|
||||
else
|
||||
begin
|
||||
ref:=p;
|
||||
typ:=top_ref;
|
||||
{ mark symbol as used }
|
||||
if assigned(ref^.symbol) then
|
||||
inc(ref^.symbol.refs);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure taicpu.loadreg(opidx:longint;r:tregister);
|
||||
begin
|
||||
if opidx>=ops then
|
||||
ops:=opidx+1;
|
||||
with oper[opidx] do
|
||||
begin
|
||||
if typ=top_ref then
|
||||
disposereference(ref);
|
||||
reg:=r;
|
||||
typ:=top_reg;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure taicpu.loadoper(opidx:longint;o:toper);
|
||||
begin
|
||||
if opidx>=ops then
|
||||
ops:=opidx+1;
|
||||
if oper[opidx].typ=top_ref then
|
||||
disposereference(oper[opidx].ref);
|
||||
oper[opidx]:=o;
|
||||
{ copy also the reference }
|
||||
if oper[opidx].typ=top_ref then
|
||||
oper[opidx].ref:=newreference(o.ref^);
|
||||
end;
|
||||
|
||||
|
||||
procedure taicpu.loadbool(opidx:longint;_b:boolean);
|
||||
begin
|
||||
if opidx>=ops then
|
||||
@ -184,7 +95,7 @@ implementation
|
||||
with oper[opidx] do
|
||||
begin
|
||||
if typ=top_ref then
|
||||
disposereference(ref);
|
||||
dispose(ref);
|
||||
b:=_b;
|
||||
typ:=top_bool;
|
||||
end;
|
||||
@ -238,7 +149,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
constructor taicpu.op_reg_ref(op : tasmop;_op1 : tregister;_op2 : preference);
|
||||
constructor taicpu.op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
|
||||
begin
|
||||
inherited create(op);
|
||||
ops:=2;
|
||||
@ -283,7 +194,7 @@ implementation
|
||||
loadsymbol(0,_op3,_op3ofs);
|
||||
end;
|
||||
|
||||
constructor taicpu.op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; _op3: preference);
|
||||
constructor taicpu.op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
|
||||
begin
|
||||
inherited create(op);
|
||||
ops:=3;
|
||||
@ -395,7 +306,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
constructor taicpu.op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;_op2 : preference);
|
||||
constructor taicpu.op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
|
||||
begin
|
||||
inherited create(op);
|
||||
ops:=2;
|
||||
@ -426,7 +337,13 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.4 2002-05-13 19:52:46 peter
|
||||
Revision 1.5 2002-05-14 17:28:10 peter
|
||||
* synchronized cpubase between powerpc and i386
|
||||
* moved more tables from cpubase to cpuasm
|
||||
* tai_align_abstract moved to tainst, cpuasm must define
|
||||
the tai_align class now, which may be empty
|
||||
|
||||
Revision 1.4 2002/05/13 19:52:46 peter
|
||||
* a ppcppc can be build again
|
||||
|
||||
Revision 1.3 2001/12/29 15:28:58 jonas
|
||||
|
@ -29,57 +29,11 @@ interface
|
||||
uses
|
||||
strings,cutils,cclasses,aasm,cpuinfo,cginfo;
|
||||
|
||||
{$ifndef NOOPT}
|
||||
Type
|
||||
{What an instruction can change}
|
||||
TInsChange = (Ch_None);
|
||||
{$endif}
|
||||
|
||||
const
|
||||
{ Size of the instruction table converted by nasmconv.pas }
|
||||
instabentries = 1103;
|
||||
maxinfolen = 7;
|
||||
|
||||
{ By default we want everything }
|
||||
{$define ATTOP}
|
||||
{$define ATTREG}
|
||||
{$define INTELOP}
|
||||
{$define ITTABLE}
|
||||
|
||||
{ For TP we can't use asmdebug due the table sizes }
|
||||
{$ifndef TP}
|
||||
{$define ASMDEBUG}
|
||||
{$endif}
|
||||
|
||||
{ We Don't need the intel style opcodes if we don't have a intel }
|
||||
{ reader or generator }
|
||||
{$undef INTELOP}
|
||||
|
||||
{ We Don't need the AT&T style opcodes if we don't have a AT&T
|
||||
reader or generator }
|
||||
{$ifdef NORA386ATT}
|
||||
{$ifdef NOAG386ATT}
|
||||
{$undef ATTOP}
|
||||
{$ifdef NOAG386DIR}
|
||||
{$undef ATTREG}
|
||||
{$endif}
|
||||
{$endif}
|
||||
{$endif}
|
||||
|
||||
{*****************************************************************************
|
||||
Default generic sizes
|
||||
Assembler Opcodes
|
||||
*****************************************************************************}
|
||||
|
||||
{# Defines the default address size for a processor, }
|
||||
OS_ADDR = OS_32;
|
||||
{# the natural int size for a processor, }
|
||||
OS_INT = OS_32;
|
||||
{# the maximum float size for a processor, }
|
||||
OS_FLOAT = OS_F64;
|
||||
{# the size of a vector register for a processor }
|
||||
OS_VECTOR = OS_M128;
|
||||
|
||||
|
||||
type
|
||||
TAsmOp=(A_None,
|
||||
{ normal opcodes }
|
||||
@ -129,13 +83,15 @@ type
|
||||
a_crnot, a_mt {move to special prupose reg}, a_mf {move from special purpose reg},
|
||||
a_nop, a_li, a_lis, a_la, a_mr, a_mr_, a_not, a_mtcr);
|
||||
|
||||
{# This should define the array of instructions as string }
|
||||
op2strtable=array[tasmop] of string[8];
|
||||
|
||||
const
|
||||
Const
|
||||
{# First value of opcode enumeration }
|
||||
firstop = low(tasmop);
|
||||
{# Last value of opcode enumeration }
|
||||
lastop = high(tasmop);
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
Registers
|
||||
*****************************************************************************}
|
||||
@ -150,16 +106,22 @@ type
|
||||
R_M0,R_M1,R_M2,R_M3,R_M4,R_M5,R_M6,R_M7,R_M8,R_M9,R_M10,R_M11,R_M12,
|
||||
R_M13,R_M14,R_M15,R_M16,R_M17,R_M18,R_M19,R_M20,R_M21,R_M22, R_M23,R_M24,
|
||||
R_M25,R_M26,R_M27,R_M28,R_M29,R_M30,R_M31,
|
||||
|
||||
R_CR,R_CR0,R_CR1,R_CR2,R_CR3,R_CR4,R_CR5,R_CR6,R_CR7,
|
||||
R_XER,R_LR,R_CTR,R_FPSCR
|
||||
);
|
||||
|
||||
{# Set type definition for registers }
|
||||
tregisterset = set of tregister;
|
||||
|
||||
{# Type definition for the array of string of register nnames }
|
||||
reg2strtable = array[tregister] of string[5];
|
||||
|
||||
Const
|
||||
{# First register in the tregister enumeration }
|
||||
firstreg = low(tregister);
|
||||
{# Last register in the tregister enumeration }
|
||||
lastreg = high(tregister);
|
||||
|
||||
R_SPR1 = R_XER;
|
||||
R_SPR8 = R_LR;
|
||||
R_SPR9 = R_CTR;
|
||||
@ -181,9 +143,6 @@ Const
|
||||
VX = 6;
|
||||
OX = 7;}
|
||||
|
||||
firstreg = low(tregister);
|
||||
lastreg = high(tregister);
|
||||
|
||||
att_reg2str : reg2strtable = ('',
|
||||
'0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16',
|
||||
'17','18','19','20','21','22','23','24','25','26','27','28','29','30','31',
|
||||
@ -225,18 +184,11 @@ Const
|
||||
'XER','LR','CTR','FPSCR'
|
||||
);
|
||||
|
||||
{ FIX ME !!!!!!!!! }
|
||||
ALL_REGISTERS = [R_0..R_FPSCR];
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
Conditions
|
||||
*****************************************************************************}
|
||||
|
||||
type
|
||||
{$ifndef tp}
|
||||
{$minenumsize 1}
|
||||
{$endif tp}
|
||||
TAsmCondFlag = (C_None { unconditional jumps },
|
||||
{ conditions when not using ctr decrement etc }
|
||||
C_LT,C_LE,C_EQ,C_GE,C_GT,C_NL,C_NE,C_NG,C_SO,C_NS,C_UN,C_NU,
|
||||
@ -250,10 +202,6 @@ const
|
||||
C_CA = C_GT;
|
||||
|
||||
type
|
||||
|
||||
{$ifndef tp}
|
||||
{$minenumsize default}
|
||||
{$endif tp}
|
||||
TAsmCond = packed record
|
||||
case simple: boolean of
|
||||
false: (BO, BI: byte);
|
||||
@ -272,25 +220,25 @@ type
|
||||
const
|
||||
AsmCondFlag2BO: Array[C_T..C_DZF] of Byte =
|
||||
(12,4,16,8,0,18,10,2);
|
||||
|
||||
AsmCondFlag2BI: Array[C_LT..C_NU] of Byte =
|
||||
(0,1,2,0,1,0,2,1,3,3,3,3);
|
||||
|
||||
AsmCondFlagTF: Array[TAsmCondFlag] of Boolean =
|
||||
(false,true,false,true,false,true,false,false,false,true,false,true,false,
|
||||
true,false,false,true,false,false,true,false);
|
||||
|
||||
|
||||
AsmCondFlag2Str: Array[TAsmCondFlag] of string[4] = ({cf_none}'',
|
||||
{ conditions when not using ctr decrement etc}
|
||||
'lt','le','eq','ge','gt','nl','ne','ng','so','ns','un','nu',
|
||||
't','f','dnz','dzt','dnzf','dz','dzt','dzf');
|
||||
|
||||
|
||||
|
||||
const
|
||||
CondAsmOps=3;
|
||||
CondAsmOp:array[0..CondAsmOps-1] of TasmOp=(
|
||||
A_BC, A_TW, A_TWI
|
||||
);
|
||||
|
||||
{*****************************************************************************
|
||||
Flags
|
||||
*****************************************************************************}
|
||||
@ -321,11 +269,11 @@ type
|
||||
{ and low 16 bits of the address of a symbol }
|
||||
trefsymaddr = (refs_full,refs_ha,refs_l);
|
||||
|
||||
{ immediate/reference record }
|
||||
{ reference record }
|
||||
preference = ^treference;
|
||||
treference = packed record
|
||||
is_immediate: boolean; { is this used as reference or immediate }
|
||||
base, index : tregister;
|
||||
base,
|
||||
index : tregister;
|
||||
offset : longint;
|
||||
symbol : tasmsymbol;
|
||||
symaddr : trefsymaddr;
|
||||
@ -334,8 +282,8 @@ type
|
||||
alignment : byte;
|
||||
end;
|
||||
|
||||
const symaddr2str: array[trefsymaddr] of string[3] = ('','@ha','@l');
|
||||
|
||||
const
|
||||
symaddr2str: array[trefsymaddr] of string[3] = ('','@ha','@l');
|
||||
|
||||
{*****************************************************************************
|
||||
Operand
|
||||
@ -349,12 +297,15 @@ type
|
||||
case typ : toptype of
|
||||
top_none : ();
|
||||
top_reg : (reg:tregister);
|
||||
top_ref : (ref:preference);
|
||||
top_ref : (ref:^treference);
|
||||
top_const : (val:aword);
|
||||
top_symbol : (sym:tasmsymbol;symofs:longint);
|
||||
top_bool : (b: boolean);
|
||||
end;
|
||||
|
||||
{*****************************************************************************
|
||||
Operand Sizes
|
||||
*****************************************************************************}
|
||||
|
||||
{*****************************************************************************
|
||||
Generic Location
|
||||
@ -376,7 +327,6 @@ type
|
||||
LOC_FLAGS { boolean results only, flags are set }
|
||||
);
|
||||
|
||||
plocation = ^tlocation;
|
||||
tlocation = packed record
|
||||
size : TCGSize;
|
||||
case loc : tloc of
|
||||
@ -390,26 +340,65 @@ type
|
||||
LOC_REGISTER,LOC_CREGISTER : (
|
||||
case longint of
|
||||
1 : (registerlow,registerhigh : tregister);
|
||||
{ overlay a registerlow }
|
||||
2 : (register : tregister);
|
||||
);
|
||||
|
||||
LOC_JUMP : ();
|
||||
LOC_FLAGS : (resflags : tresflags);
|
||||
LOC_INVALID : ();
|
||||
|
||||
{ segment in reference at the same place as in loc_register }
|
||||
end;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
Constants
|
||||
*****************************************************************************}
|
||||
|
||||
const
|
||||
max_operands = 5;
|
||||
|
||||
lvaluelocations = [LOC_REFERENCE, LOC_CREGISTER, LOC_CFPUREGISTER,
|
||||
LOC_CMMREGISTER];
|
||||
|
||||
{# Constant defining possibly all registers which might require saving }
|
||||
{$warning FIX ME !!!!!!!!! }
|
||||
ALL_REGISTERS = [R_0..R_FPSCR];
|
||||
|
||||
general_registers = [R_0..R_31];
|
||||
|
||||
{# low and high of the available maximum width integer general purpose }
|
||||
{ registers }
|
||||
LoGPReg = R_0;
|
||||
HiGPReg = R_31;
|
||||
|
||||
{# low and high of every possible width general purpose register (same as }
|
||||
{ above on most architctures apart from the 80x86) }
|
||||
LoReg = R_0;
|
||||
HiReg = R_31;
|
||||
|
||||
{# Table of registers which can be allocated by the code generator
|
||||
internally, when generating the code.
|
||||
}
|
||||
{ legend: }
|
||||
{ xxxregs = set of all possibly used registers of that type in the code }
|
||||
{ generator }
|
||||
{ usableregsxxx = set of all 32bit components of registers that can be }
|
||||
{ possible allocated to a regvar or using getregisterxxx (this }
|
||||
{ excludes registers which can be only used for parameter }
|
||||
{ passing on ABI's that define this) }
|
||||
{ c_countusableregsxxx = amount of registers in the usableregsxxx set }
|
||||
|
||||
maxintregs = 18;
|
||||
intregs = [R_0..R_31];
|
||||
usableregsint = [R_13..R_30];
|
||||
c_countusableregsint = 21;
|
||||
|
||||
maxfpuregs = 31-14+1;
|
||||
fpuregs = [R_F0..R_F31];
|
||||
usableregsfpu = [R_F14..R_F31];
|
||||
c_countusableregsfpu = 32;
|
||||
|
||||
mmregs = [R_M0..R_M31];
|
||||
usableregsmm = [R_M14..R_M31];
|
||||
c_countusableregsmm = 32;
|
||||
|
||||
firstsaveintreg = R_13;
|
||||
lastsaveintreg = R_30;
|
||||
@ -419,28 +408,16 @@ const
|
||||
firstsavemmreg = R_NO;
|
||||
lastsavemmreg = R_NO;
|
||||
|
||||
lvaluelocations = [LOC_REFERENCE, LOC_CREGISTER, LOC_CFPUREGISTER,
|
||||
LOC_CMMREGISTER];
|
||||
|
||||
c_countusableregsint = 21;
|
||||
c_countusableregsfpu = 32;
|
||||
c_countusableregsmm = 32;
|
||||
|
||||
max_operands = 5;
|
||||
|
||||
maxvarregs = 18;
|
||||
|
||||
varregs : Array [1..maxvarregs] of Tregister =
|
||||
(R_13,R_14,R_15,R_16,R_17,R_18,R_19,R_20,R_21,R_22,R_23,R_24,R_25,
|
||||
R_26,R_27,R_28,R_29,R_30);
|
||||
|
||||
maxfpuvarregs = 31-14+1;
|
||||
|
||||
fpuvarregs : Array [1..maxfpuvarregs] of Tregister =
|
||||
(R_F14,R_F15,R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23,
|
||||
R_F24,R_F25,R_F26,R_F27,R_F28,R_F29,R_F30,R_F31);
|
||||
|
||||
|
||||
max_param_regs_int = 8;
|
||||
param_regs_int: Array[1..max_param_regs_int] of tregister =
|
||||
(R_3,R_4,R_5,R_6,R_7,R_8,R_9,R_10);
|
||||
@ -449,58 +426,53 @@ const
|
||||
param_regs_fpu: Array[1..max_param_regs_fpu] of tregister =
|
||||
(R_F1,R_F2,R_F3,R_F4,R_F5,R_F6,R_F7,R_F8,R_F9,R_F10,R_F11,R_F12,R_F13);
|
||||
|
||||
|
||||
max_param_regs_mm = 13;
|
||||
param_regs_mm: Array[1..max_param_regs_mm] of tregister =
|
||||
(R_M1,R_M2,R_M3,R_M4,R_M5,R_M6,R_M7,R_M8,R_M9,R_M10,R_M11,R_M12,R_M13);
|
||||
|
||||
general_registers = [R_0..R_31];
|
||||
|
||||
intregs = [R_0..R_31];
|
||||
fpuregs = [R_F0..R_F31];
|
||||
mmregs = [R_M0..R_M31];
|
||||
|
||||
|
||||
|
||||
{ generic register names }
|
||||
stack_pointer_reg= R_1;
|
||||
R_RTOC = R_2;
|
||||
frame_pointer_reg = stack_pointer_reg;
|
||||
self_pointer_reg = R_9;
|
||||
accumulator = R_3;
|
||||
accumulatorhigh = R_4;
|
||||
{$warning I don't know the exact values, please check (PFV) }
|
||||
fpuresultreg = R_F0;
|
||||
mmresultreg = R_M0;
|
||||
{# Registers which are defined as scratch and no need to save across
|
||||
routine calls or in assembler blocks.
|
||||
}
|
||||
max_scratch_regs = 3;
|
||||
scratch_regs: Array[1..max_scratch_regs] of TRegister = (R_11,R_12,R_31);
|
||||
|
||||
maxintregs = maxvarregs;
|
||||
maxfpuregs = maxfpuvarregs;
|
||||
{*****************************************************************************
|
||||
Default generic sizes
|
||||
*****************************************************************************}
|
||||
|
||||
{ low and high of the available maximum width integer general purpose }
|
||||
{ registers }
|
||||
LoGPReg = R_0;
|
||||
HiGPReg = R_31;
|
||||
{# Defines the default address size for a processor, }
|
||||
OS_ADDR = OS_32;
|
||||
{# the natural int size for a processor, }
|
||||
OS_INT = OS_32;
|
||||
{# the maximum float size for a processor, }
|
||||
OS_FLOAT = OS_F64;
|
||||
{# the size of a vector register for a processor }
|
||||
OS_VECTOR = OS_M128;
|
||||
|
||||
{ low and high of every possible width general purpose register (same as }
|
||||
{ above on most architctures apart from the 80x86) }
|
||||
LoReg = R_0;
|
||||
HiReg = R_31;
|
||||
|
||||
{ sizes }
|
||||
extended_size = 8;
|
||||
|
||||
LinkageAreaSize = 24;
|
||||
{ offset in the linkage area for the saved stack pointer }
|
||||
LA_SP = 0;
|
||||
{ offset in the linkage area for the saved conditional register}
|
||||
LA_CR = 4;
|
||||
{ offset in the linkage area for the saved link register}
|
||||
LA_LR = 8;
|
||||
{ offset in the linkage area for the saved RTOC register}
|
||||
LA_RTOC = 20;
|
||||
{*****************************************************************************
|
||||
Generic Register names
|
||||
*****************************************************************************}
|
||||
|
||||
{# Stack pointer register }
|
||||
stack_pointer_reg = R_1;
|
||||
{# Frame pointer register }
|
||||
frame_pointer_reg = stack_pointer_reg;
|
||||
{# Self pointer register : contains the instance address of an
|
||||
object or class. }
|
||||
self_pointer_reg = R_9;
|
||||
{# Register for addressing absolute data in a position independant way,
|
||||
such as in PIC code. The exact meaning is ABI specific }
|
||||
{$warning Needs checking, this is just a dummy (PFV) }
|
||||
pic_offset_reg = R_8;
|
||||
{# Results are returned in this register (32-bit values) }
|
||||
accumulator = R_3;
|
||||
{# Hi-Results are returned in this register (64-bit value high register) }
|
||||
accumulatorhigh = R_4;
|
||||
{ WARNING: don't change to R_ST0!! See comments above implementation of }
|
||||
{ a_loadfpu* methods in rgcpu (JM) }
|
||||
{$warning I don't know the exact values, please check (PFV) }
|
||||
fpuresultreg = R_F0;
|
||||
mmresultreg = R_M0;
|
||||
|
||||
{*****************************************************************************
|
||||
GCC /ABI linking information
|
||||
@ -523,20 +495,24 @@ const
|
||||
}
|
||||
std_param_align = 4; { for 32-bit version only }
|
||||
|
||||
{*****************************************************************************
|
||||
CPU Dependent Constants
|
||||
*****************************************************************************}
|
||||
|
||||
LinkageAreaSize = 24;
|
||||
{ offset in the linkage area for the saved stack pointer }
|
||||
LA_SP = 0;
|
||||
{ offset in the linkage area for the saved conditional register}
|
||||
LA_CR = 4;
|
||||
{ offset in the linkage area for the saved link register}
|
||||
LA_LR = 8;
|
||||
{ offset in the linkage area for the saved RTOC register}
|
||||
LA_RTOC = 20;
|
||||
|
||||
{*****************************************************************************
|
||||
Helpers
|
||||
*****************************************************************************}
|
||||
|
||||
{ resets all values of ref to defaults }
|
||||
procedure reset_reference(var ref : treference);
|
||||
{ set mostly used values of a new reference }
|
||||
function new_reference(base : tregister;offset : longint) : preference;
|
||||
|
||||
function newreference(const r : treference) : preference;
|
||||
procedure disposereference(var r : preference);
|
||||
|
||||
|
||||
function is_calljmp(o:tasmop):boolean;
|
||||
|
||||
procedure inverse_cond(c: TAsmCond;var r : TAsmCond);
|
||||
@ -544,32 +520,16 @@ const
|
||||
procedure create_cond_imm(BO,BI:byte;var r : TAsmCond);
|
||||
procedure create_cond_norm(cond: TAsmCondFlag; cr: byte;var r : TasmCond);
|
||||
|
||||
procedure clear_location(var loc : tlocation);
|
||||
procedure set_location(var destloc,sourceloc : tlocation);
|
||||
procedure swap_location(var destloc,sourceloc : tlocation);
|
||||
|
||||
{*****************************************************************************
|
||||
Init/Done
|
||||
*****************************************************************************}
|
||||
|
||||
procedure InitCpu;
|
||||
procedure DoneCpu;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
verbose
|
||||
{$ifdef heaptrc}
|
||||
,ppheap
|
||||
{$endif heaptrc}
|
||||
;
|
||||
verbose;
|
||||
|
||||
{*****************************************************************************
|
||||
Helpers
|
||||
*****************************************************************************}
|
||||
|
||||
|
||||
|
||||
function is_calljmp(o:tasmop):boolean;
|
||||
begin
|
||||
is_calljmp:=false;
|
||||
@ -579,39 +539,6 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure disposereference(var r : preference);
|
||||
begin
|
||||
dispose(r);
|
||||
r:=nil;
|
||||
end;
|
||||
|
||||
|
||||
function newreference(const r : treference) : preference;
|
||||
var
|
||||
p : preference;
|
||||
begin
|
||||
new(p);
|
||||
p^:=r;
|
||||
newreference:=p;
|
||||
end;
|
||||
|
||||
procedure reset_reference(var ref : treference);
|
||||
begin
|
||||
FillChar(ref,sizeof(treference),0)
|
||||
end;
|
||||
|
||||
function new_reference(base : tregister;offset : longint) : preference;
|
||||
var
|
||||
r : preference;
|
||||
begin
|
||||
new(r);
|
||||
FillChar(r^,sizeof(treference),0);
|
||||
r^.base:=base;
|
||||
r^.offset:=offset;
|
||||
new_reference:=r;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
procedure inverse_cond(c: TAsmCond;var r : TAsmCond);
|
||||
const
|
||||
@ -623,6 +550,7 @@ implementation
|
||||
r := c;
|
||||
end;
|
||||
|
||||
|
||||
function flags_to_cond(const f: TResFlags) : TAsmCond;
|
||||
const
|
||||
flag_2_cond: array[F_EQ..F_SO] of TAsmCondFlag =
|
||||
@ -635,6 +563,7 @@ implementation
|
||||
result.cond := flag_2_cond[f.flag];
|
||||
end;
|
||||
|
||||
|
||||
procedure create_cond_imm(BO,BI:byte;var r : TAsmCond);
|
||||
begin
|
||||
r.simple := false;
|
||||
@ -642,6 +571,7 @@ implementation
|
||||
r.bi := bi;
|
||||
end;
|
||||
|
||||
|
||||
procedure create_cond_norm(cond: TAsmCondFlag; cr: byte;var r : TasmCond);
|
||||
const cr2reg: array[0..7] of tregister =
|
||||
(R_CR0,R_CR1,R_CR2,R_CR3,R_CR4,R_CR5,R_CR6,R_CR7);
|
||||
@ -655,46 +585,16 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure clear_location(var loc : tlocation);
|
||||
|
||||
begin
|
||||
loc.loc:=LOC_INVALID;
|
||||
end;
|
||||
|
||||
{This is needed if you want to be able to delete the string with the nodes !!}
|
||||
procedure set_location(var destloc,sourceloc : tlocation);
|
||||
|
||||
begin
|
||||
destloc:= sourceloc;
|
||||
end;
|
||||
|
||||
procedure swap_location(var destloc,sourceloc : tlocation);
|
||||
|
||||
var
|
||||
swapl : tlocation;
|
||||
|
||||
begin
|
||||
swapl := destloc;
|
||||
destloc := sourceloc;
|
||||
sourceloc := swapl;
|
||||
end;
|
||||
|
||||
{*****************************************************************************
|
||||
Init/Done
|
||||
*****************************************************************************}
|
||||
|
||||
procedure InitCpu;
|
||||
begin
|
||||
end;
|
||||
|
||||
procedure DoneCpu;
|
||||
begin
|
||||
end;
|
||||
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.10 2002-05-13 19:52:46 peter
|
||||
Revision 1.11 2002-05-14 17:28:10 peter
|
||||
* synchronized cpubase between powerpc and i386
|
||||
* moved more tables from cpubase to cpuasm
|
||||
* tai_align_abstract moved to tainst, cpuasm must define
|
||||
the tai_align class now, which may be empty
|
||||
|
||||
Revision 1.10 2002/05/13 19:52:46 peter
|
||||
* a ppcppc can be build again
|
||||
|
||||
Revision 1.9 2002/04/21 15:48:39 carl
|
||||
|
@ -80,7 +80,7 @@ implementation
|
||||
maybe_save(exprasmlist,right.registers32,left.location,saved);
|
||||
secondpass(right);
|
||||
maybe_restore(exprasmlist,left.location,saved);
|
||||
set_location(location,left.location);
|
||||
location_copy(location,left.location);
|
||||
|
||||
resultreg := R_NO;
|
||||
{ put numerator in register }
|
||||
@ -386,36 +386,8 @@ implementation
|
||||
secondpass(left);
|
||||
if is_64bitint(left.resulttype.def) then
|
||||
begin
|
||||
clear_location(location);
|
||||
location.loc:=LOC_REGISTER;
|
||||
case left.location.loc of
|
||||
LOC_REGISTER, LOC_CREGISTER :
|
||||
begin
|
||||
src1 := left.location.registerlow;
|
||||
src2 := left.location.registerhigh;
|
||||
if left.location.loc = LOC_REGISTER then
|
||||
begin
|
||||
location.registerlow:=src1;
|
||||
location.registerhigh:=src2;
|
||||
end
|
||||
else
|
||||
begin
|
||||
location.registerlow := rg.getregisterint(exprasmlist);
|
||||
location.registerhigh := rg.getregisterint(exprasmlist);
|
||||
end;
|
||||
end;
|
||||
LOC_REFERENCE,LOC_CREFERENCE :
|
||||
begin
|
||||
reference_release(exprasmlist,left.location.reference);
|
||||
location.registerlow:=rg.getregisterint(exprasmlist);
|
||||
src1 := location.registerlow;
|
||||
location.registerhigh:=rg.getregisterint(exprasmlist);
|
||||
src2 := location.registerhigh;
|
||||
tcg64f32(cg).a_load64_ref_reg(exprasmlist,left.location.reference,
|
||||
location.registerlow,
|
||||
location.registerhigh);
|
||||
end;
|
||||
end;
|
||||
location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false);
|
||||
location_copy(location,left.location);
|
||||
exprasmlist.concat(taicpu.op_reg_reg(A_NEG,location.registerlow,
|
||||
src1));
|
||||
cg.a_op_reg_reg(exprasmlist,OP_NOT,OS_32,src2,location.registerhigh);
|
||||
@ -546,36 +518,8 @@ implementation
|
||||
else if is_64bitint(left.resulttype.def) then
|
||||
begin
|
||||
secondpass(left);
|
||||
clear_location(location);
|
||||
location.loc:=LOC_REGISTER;
|
||||
{ make sure left is in a register and set the dest register }
|
||||
case left.location.loc of
|
||||
LOC_REFERENCE, LOC_CREFERENCE, LOC_CREGISTER:
|
||||
begin
|
||||
location.registerlow := rg.getregisterint(exprasmlist);
|
||||
location.registerhigh := rg.getregisterint(exprasmlist);
|
||||
if left.location.loc <> LOC_CREGISTER then
|
||||
begin
|
||||
tcg64f32(cg).a_load64_ref_reg(exprasmlist,
|
||||
left.location.reference,location.registerlow,
|
||||
location.registerhigh);
|
||||
regl := location.registerlow;
|
||||
regh := location.registerhigh;
|
||||
end
|
||||
else
|
||||
begin
|
||||
regl := left.location.registerlow;
|
||||
regh := left.location.registerhigh;
|
||||
end;
|
||||
end;
|
||||
LOC_REGISTER:
|
||||
begin
|
||||
regl := left.location.registerlow;
|
||||
location.registerlow := regl;
|
||||
regh := left.location.registerhigh;
|
||||
location.registerhigh := regh;
|
||||
end;
|
||||
end;
|
||||
location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false);
|
||||
location_copy(location,left.location);
|
||||
{ perform the NOT operation }
|
||||
exprasmlist.concat(taicpu.op_reg_reg(A_NOT,location.registerhigh,
|
||||
regh));
|
||||
@ -585,32 +529,13 @@ implementation
|
||||
else
|
||||
begin
|
||||
secondpass(left);
|
||||
clear_location(location);
|
||||
location.loc:=LOC_REGISTER;
|
||||
{ make sure left is in a register and set the dest register }
|
||||
case left.location.loc of
|
||||
LOC_REFERENCE, LOC_CREFERENCE, LOC_CREGISTER:
|
||||
begin
|
||||
location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false);
|
||||
location_copy(location,left.location);
|
||||
if location.loc=LOC_CREGISTER then
|
||||
location.register := rg.getregisterint(exprasmlist);
|
||||
if left.location.loc <> LOC_CREGISTER then
|
||||
begin
|
||||
cg.a_load_ref_reg(exprasmlist,
|
||||
def_cgsize(left.resulttype.def),
|
||||
left.location.reference,location.register);
|
||||
regl := location.register;
|
||||
end
|
||||
else
|
||||
regl := left.location.register;
|
||||
end;
|
||||
LOC_REGISTER:
|
||||
regl := left.location.register;
|
||||
end;
|
||||
{ perform the NOT operation }
|
||||
exprasmlist.concat(taicpu.op_reg_reg(A_NOT,location.register,
|
||||
regl));
|
||||
{ release the source reg if it wasn't reused }
|
||||
if regl <> location.register then
|
||||
rg.ungetregisterint(exprasmlist,regl);
|
||||
left.location.register));
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -622,7 +547,13 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.5 2002-05-13 19:52:46 peter
|
||||
Revision 1.6 2002-05-14 17:28:10 peter
|
||||
* synchronized cpubase between powerpc and i386
|
||||
* moved more tables from cpubase to cpuasm
|
||||
* tai_align_abstract moved to tainst, cpuasm must define
|
||||
the tai_align class now, which may be empty
|
||||
|
||||
Revision 1.5 2002/05/13 19:52:46 peter
|
||||
* a ppcppc can be build again
|
||||
|
||||
Revision 1.4 2002/04/21 15:48:39 carl
|
||||
|
@ -716,7 +716,13 @@ begin
|
||||
2 : size:=S_W{ could be S_IS};
|
||||
4 : size:=S_L{ could be S_IL or S_FS};
|
||||
8 : size:=S_IQ{ could be S_D or S_FL};
|
||||
extended_size : size:=S_FX;
|
||||
else
|
||||
begin
|
||||
{ extended_size can also be 8, resulting in a
|
||||
duplicate label }
|
||||
if _size=extended_size then
|
||||
size:=S_FX;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -1585,7 +1591,13 @@ end;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.31 2002-05-12 16:53:10 peter
|
||||
Revision 1.32 2002-05-14 17:28:09 peter
|
||||
* synchronized cpubase between powerpc and i386
|
||||
* moved more tables from cpubase to cpuasm
|
||||
* tai_align_abstract moved to tainst, cpuasm must define
|
||||
the tai_align class now, which may be empty
|
||||
|
||||
Revision 1.31 2002/05/12 16:53:10 peter
|
||||
* moved entry and exitcode to ncgutil and cgobj
|
||||
* foreach gets extra argument for passing local data to the
|
||||
iterator function
|
||||
|
@ -26,10 +26,10 @@ Unit tainst;
|
||||
|
||||
interface
|
||||
|
||||
Uses aasm,cpubase,cpuinfo,cclasses;
|
||||
Uses
|
||||
cpuinfo,cpubase,aasm,cclasses;
|
||||
|
||||
Type
|
||||
|
||||
tairegalloc = class(tai)
|
||||
allocation : boolean;
|
||||
reg : tregister;
|
||||
@ -37,7 +37,7 @@ Type
|
||||
constructor dealloc(r : tregister);
|
||||
end;
|
||||
|
||||
tainstruction = class(tai)
|
||||
taicpu_abstract = class(tai)
|
||||
condition : TAsmCond;
|
||||
ops : longint;
|
||||
oper : array[0..max_operands-1] of toper;
|
||||
@ -57,6 +57,19 @@ Type
|
||||
procedure SetCondition(const c:TAsmCond);
|
||||
end;
|
||||
|
||||
{ alignment for operator }
|
||||
tai_align_abstract = class(tai)
|
||||
buf : array[0..63] of char; { buf used for fill }
|
||||
aligntype : byte; { 1 = no align, 2 = word align, 4 = dword align }
|
||||
fillsize : byte; { real size to fill }
|
||||
fillop : byte; { value to fill with - optional }
|
||||
use_op : boolean;
|
||||
constructor Create(b:byte);
|
||||
constructor Create_op(b: byte; _op: byte);
|
||||
function getfillbuf:pchar;virtual;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@ -84,13 +97,12 @@ implementation
|
||||
reg:=r;
|
||||
end;
|
||||
|
||||
{ ---------------------------------------------------------------------
|
||||
TaInstruction Constructor/Destructor
|
||||
---------------------------------------------------------------------}
|
||||
|
||||
{*****************************************************************************
|
||||
TaiInstruction
|
||||
*****************************************************************************}
|
||||
|
||||
|
||||
constructor Tainstruction.Create(op : tasmop);
|
||||
constructor taicpu_abstract.Create(op : tasmop);
|
||||
|
||||
begin
|
||||
inherited create;
|
||||
@ -104,7 +116,7 @@ implementation
|
||||
|
||||
|
||||
|
||||
destructor Tainstruction.Destroy;
|
||||
destructor taicpu_abstract.Destroy;
|
||||
|
||||
var
|
||||
i : longint;
|
||||
@ -127,7 +139,7 @@ implementation
|
||||
|
||||
|
||||
|
||||
procedure tainstruction.loadconst(opidx:longint;l:aword);
|
||||
procedure taicpu_abstract.loadconst(opidx:longint;l:aword);
|
||||
begin
|
||||
if opidx>=ops then
|
||||
ops:=opidx+1;
|
||||
@ -142,7 +154,7 @@ implementation
|
||||
|
||||
|
||||
|
||||
procedure tainstruction.loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
|
||||
procedure taicpu_abstract.loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
|
||||
begin
|
||||
if not assigned(s) then
|
||||
internalerror(200204251);
|
||||
@ -161,7 +173,7 @@ implementation
|
||||
|
||||
|
||||
|
||||
procedure tainstruction.loadref(opidx:longint;const r:treference);
|
||||
procedure taicpu_abstract.loadref(opidx:longint;const r:treference);
|
||||
begin
|
||||
if opidx>=ops then
|
||||
ops:=opidx+1;
|
||||
@ -185,7 +197,7 @@ implementation
|
||||
|
||||
|
||||
|
||||
procedure tainstruction.loadreg(opidx:longint;r:tregister);
|
||||
procedure taicpu_abstract.loadreg(opidx:longint;r:tregister);
|
||||
begin
|
||||
if opidx>=ops then
|
||||
ops:=opidx+1;
|
||||
@ -200,7 +212,7 @@ implementation
|
||||
|
||||
|
||||
|
||||
procedure tainstruction.loadoper(opidx:longint;o:toper);
|
||||
procedure taicpu_abstract.loadoper(opidx:longint;o:toper);
|
||||
begin
|
||||
if opidx>=ops then
|
||||
ops:=opidx+1;
|
||||
@ -220,13 +232,13 @@ implementation
|
||||
Miscellaneous methods.
|
||||
---------------------------------------------------------------------}
|
||||
|
||||
procedure tainstruction.SetCondition(const c:TAsmCond);
|
||||
procedure taicpu_abstract.SetCondition(const c:TAsmCond);
|
||||
begin
|
||||
condition:=c;
|
||||
end;
|
||||
|
||||
|
||||
Function tainstruction.getcopy:tlinkedlistitem;
|
||||
Function taicpu_abstract.getcopy:tlinkedlistitem;
|
||||
var
|
||||
i : longint;
|
||||
p : tlinkedlistitem;
|
||||
@ -234,19 +246,63 @@ implementation
|
||||
p:=inherited getcopy;
|
||||
{ make a copy of the references }
|
||||
for i:=1 to ops do
|
||||
if (tainstruction(p).oper[i-1].typ=top_ref) then
|
||||
if (taicpu_abstract(p).oper[i-1].typ=top_ref) then
|
||||
begin
|
||||
new(tainstruction(p).oper[i-1].ref);
|
||||
tainstruction(p).oper[i-1].ref^:=oper[i-1].ref^;
|
||||
new(taicpu_abstract(p).oper[i-1].ref);
|
||||
taicpu_abstract(p).oper[i-1].ref^:=oper[i-1].ref^;
|
||||
end;
|
||||
getcopy:=p;
|
||||
end;
|
||||
|
||||
{****************************************************************************
|
||||
tai_align_abstract
|
||||
****************************************************************************}
|
||||
|
||||
constructor tai_align_abstract.Create(b: byte);
|
||||
begin
|
||||
inherited Create;
|
||||
typ:=ait_align;
|
||||
if b in [1,2,4,8,16,32] then
|
||||
aligntype := b
|
||||
else
|
||||
aligntype := 1;
|
||||
fillsize:=0;
|
||||
fillop:=0;
|
||||
use_op:=false;
|
||||
end;
|
||||
|
||||
|
||||
constructor tai_align_abstract.Create_op(b: byte; _op: byte);
|
||||
begin
|
||||
inherited Create;
|
||||
typ:=ait_align;
|
||||
if b in [1,2,4,8,16,32] then
|
||||
aligntype := b
|
||||
else
|
||||
aligntype := 1;
|
||||
fillsize:=0;
|
||||
fillop:=_op;
|
||||
use_op:=true;
|
||||
fillchar(buf,sizeof(buf),_op)
|
||||
end;
|
||||
|
||||
|
||||
function tai_align_abstract.getfillbuf:pchar;
|
||||
begin
|
||||
getfillbuf:=@buf;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.5 2002-04-25 20:16:39 peter
|
||||
Revision 1.6 2002-05-14 17:28:09 peter
|
||||
* synchronized cpubase between powerpc and i386
|
||||
* moved more tables from cpubase to cpuasm
|
||||
* tai_align_abstract moved to tainst, cpuasm must define
|
||||
the tai_align class now, which may be empty
|
||||
|
||||
Revision 1.5 2002/04/25 20:16:39 peter
|
||||
* moved more routines from cga/n386util
|
||||
|
||||
Revision 1.4 2002/04/02 17:11:32 peter
|
||||
@ -288,13 +344,13 @@ end.
|
||||
because on powerpc it's a record now
|
||||
|
||||
Revision 1.3 1999/08/26 14:52:59 jonas
|
||||
* added segprefix field for i386 in tainstruction object
|
||||
* added segprefix field for i386 in taicpu_abstract object
|
||||
|
||||
Revision 1.2 1999/08/06 16:38:37 jonas
|
||||
* declared getcopy virtual, since it's already declared as such
|
||||
in cobjects.pas (FPC doesn't error on that, TP does)
|
||||
|
||||
Revision 1.1 1999/08/06 16:04:05 michael
|
||||
+ introduced tainstruction
|
||||
+ introduced taicpu_abstract
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
Copyright (c) 1998-2000 by Peter Vreman
|
||||
|
||||
This unit implements support import,export,link routines
|
||||
for the (i386) Linux target
|
||||
for the Linux targets
|
||||
|
||||
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
|
||||
@ -64,7 +64,11 @@ implementation
|
||||
cutils,cclasses,
|
||||
verbose,systems,globtype,globals,
|
||||
symconst,script,
|
||||
fmodule,aasm,cpuasm,cpubase,symsym;
|
||||
fmodule,symsym
|
||||
{$ifdef i386}
|
||||
,aasm,cpuasm,cpubase
|
||||
{$endif i386}
|
||||
;
|
||||
|
||||
{*****************************************************************************
|
||||
TIMPORTLIBLINUX
|
||||
@ -588,8 +592,23 @@ end;
|
||||
res : res_none;
|
||||
script : script_unix;
|
||||
endian : endian_big;
|
||||
stackalignment : 2;
|
||||
maxCrecordalignment : 32;
|
||||
alignment :
|
||||
(
|
||||
procalign : 4;
|
||||
loopalign : 4;
|
||||
jumpalign : 0;
|
||||
constalignmin : 0;
|
||||
constalignmax : 4;
|
||||
varalignmin : 0;
|
||||
varalignmax : 4;
|
||||
localalignmin : 0;
|
||||
localalignmax : 4;
|
||||
paraalign : 4;
|
||||
recordalignmin : 0;
|
||||
recordalignmax : 2;
|
||||
maxCrecordalign : 4
|
||||
);
|
||||
first_parm_offset : 8;
|
||||
heapsize : 128*1024;
|
||||
stacksize : 32*1024*1024;
|
||||
DllScanSupported:false;
|
||||
@ -605,7 +624,6 @@ end;
|
||||
shortname : 'linuxppc';
|
||||
flags : [];
|
||||
cpu : cpu_powerpc;
|
||||
short_name : 'LINUX';
|
||||
unit_env : '';
|
||||
extradefines : 'UNIX';
|
||||
sourceext : '.pp';
|
||||
@ -633,13 +651,30 @@ end;
|
||||
dirsep : '/';
|
||||
files_case_relevent : true;
|
||||
assem : as_powerpc_as;
|
||||
assemsrc : as_powerpc_as;
|
||||
ar : ar_powerpc_ar;
|
||||
assemextern : as_powerpc_as;
|
||||
link : ld_powerpc_linux;
|
||||
linkextern : ld_powerpc_linux;
|
||||
ar : ar_gnu_ar;
|
||||
res : res_none;
|
||||
script : script_unix;
|
||||
endian : endian_big;
|
||||
stackalignment : 8;
|
||||
maxCrecordalignment : 32;
|
||||
alignment :
|
||||
(
|
||||
procalign : 4;
|
||||
loopalign : 4;
|
||||
jumpalign : 0;
|
||||
constalignmin : 0;
|
||||
constalignmax : 4;
|
||||
varalignmin : 0;
|
||||
varalignmax : 4;
|
||||
localalignmin : 0;
|
||||
localalignmax : 4;
|
||||
paraalign : 4;
|
||||
recordalignmin : 0;
|
||||
recordalignmax : 2;
|
||||
maxCrecordalign : 4
|
||||
);
|
||||
first_parm_offset : 8;
|
||||
heapsize : 256*1024;
|
||||
stacksize : 32*1024*1024;
|
||||
DllScanSupported:false;
|
||||
@ -690,9 +725,23 @@ end;
|
||||
res : res_none;
|
||||
script : script_unix;
|
||||
endian : endian_little;
|
||||
stackalignment : 8;
|
||||
maxCrecordalignment : 32;
|
||||
size_of_longint : 4;
|
||||
alignment :
|
||||
(
|
||||
procalign : 4;
|
||||
loopalign : 4;
|
||||
jumpalign : 0;
|
||||
constalignmin : 0;
|
||||
constalignmax : 4;
|
||||
varalignmin : 0;
|
||||
varalignmax : 4;
|
||||
localalignmin : 0;
|
||||
localalignmax : 4;
|
||||
paraalign : 4;
|
||||
recordalignmin : 0;
|
||||
recordalignmax : 2;
|
||||
maxCrecordalign : 4
|
||||
);
|
||||
first_parm_offset : 8;
|
||||
heapsize : 256*1024;
|
||||
stacksize : 32*1024*1024;
|
||||
DllScanSupported:false;
|
||||
@ -800,7 +849,13 @@ initialization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.22 2002-05-06 19:46:36 carl
|
||||
Revision 1.23 2002-05-14 17:28:10 peter
|
||||
* synchronized cpubase between powerpc and i386
|
||||
* moved more tables from cpubase to cpuasm
|
||||
* tai_align_abstract moved to tainst, cpuasm must define
|
||||
the tai_align class now, which may be empty
|
||||
|
||||
Revision 1.22 2002/05/06 19:46:36 carl
|
||||
+ added more patches from Mazen for SPARC port
|
||||
|
||||
Revision 1.21 2002/04/22 18:19:22 carl
|
||||
|
Loading…
Reference in New Issue
Block a user