* 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:
peter 2002-05-14 17:28:08 +00:00
parent 4a176c81bc
commit f6b3e2e37f
12 changed files with 1200 additions and 1421 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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