|
@@ -1,18 +1,7 @@
|
|
-{*****************************************************************************}
|
|
|
|
-{ File : aasmcpu.pas }
|
|
|
|
-{ Author : Mazen NEIFER }
|
|
|
|
-{ Project : Free Pascal Compiler (FPC) }
|
|
|
|
-{ Creation date : 2002\05\01 }
|
|
|
|
-{ Last modification date : 2002\08\20 }
|
|
|
|
-{ Licence : GPL }
|
|
|
|
-{ Bug report : [email protected] }
|
|
|
|
-{*****************************************************************************}
|
|
|
|
-{
|
|
|
|
|
|
+{******************************************************************************
|
|
$Id$
|
|
$Id$
|
|
Copyright (c) 1998-2000 by Florian Klaempfl and Peter Vreman
|
|
Copyright (c) 1998-2000 by Florian Klaempfl and Peter Vreman
|
|
|
|
|
|
- Contains the assembler object for the i386
|
|
|
|
-
|
|
|
|
* This code was inspired by the NASM sources
|
|
* This code was inspired by the NASM sources
|
|
The Netwide Assembler is copyright (C) 1996 Simon Tatham and
|
|
The Netwide Assembler is copyright (C) 1996 Simon Tatham and
|
|
Julian Hall. All rights reserved.
|
|
Julian Hall. All rights reserved.
|
|
@@ -30,71 +19,59 @@
|
|
You should have received a copy of the GNU General Public License
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
-
|
|
|
|
- ****************************************************************************
|
|
|
|
-}
|
|
|
|
-UNIT aasmcpu;
|
|
|
|
|
|
+ ****************************************************************************}
|
|
|
|
+unit aasmcpu;
|
|
{$INCLUDE fpcdefs.inc}
|
|
{$INCLUDE fpcdefs.inc}
|
|
-INTERFACE
|
|
|
|
-USES
|
|
|
|
|
|
+interface
|
|
|
|
+uses
|
|
cclasses,globals,verbose,
|
|
cclasses,globals,verbose,
|
|
cpuinfo,cpubase,
|
|
cpuinfo,cpubase,
|
|
symppu,
|
|
symppu,
|
|
aasmbase,aasmtai;
|
|
aasmbase,aasmtai;
|
|
-CONST
|
|
|
|
|
|
+const
|
|
MaxPrefixes=4;
|
|
MaxPrefixes=4;
|
|
type
|
|
type
|
|
- TOperandOrder = (op_intel,op_att);
|
|
|
|
-
|
|
|
|
|
|
+ TOperandOrder=(op_intel,op_att);
|
|
{ alignment for operator }
|
|
{ alignment for operator }
|
|
- tai_align = class(tai_align_abstract)
|
|
|
|
- reg : tregister;
|
|
|
|
|
|
+ tai_align=class(tai_align_abstract)
|
|
|
|
+ reg:tregister;
|
|
constructor create(b:byte);
|
|
constructor create(b:byte);
|
|
- constructor create_op(b: byte; _op: byte);
|
|
|
|
|
|
+ constructor create_op(b:byte; _op:byte);
|
|
function getfillbuf:pchar;override;
|
|
function getfillbuf:pchar;override;
|
|
end;
|
|
end;
|
|
-
|
|
|
|
taicpu = class(taicpu_abstract)
|
|
taicpu = class(taicpu_abstract)
|
|
- opsize : topsize;
|
|
|
|
- constructor op_none(op : tasmop;_size : topsize);
|
|
|
|
-
|
|
|
|
- constructor op_reg(op : tasmop;_size : topsize;_op1 : tregister);
|
|
|
|
- constructor op_const(op : tasmop;_size : topsize;_op1 : aword);
|
|
|
|
- constructor op_ref(op : tasmop;_size : topsize;const _op1 : treference);
|
|
|
|
-
|
|
|
|
- constructor op_reg_reg(op : tasmop;_size : topsize;_op1,_op2 : tregister);
|
|
|
|
- constructor op_reg_ref(op : tasmop;_size : topsize;_op1 : tregister;const _op2 : treference);
|
|
|
|
- constructor op_reg_const(op:tasmop; _size: topsize; _op1: tregister; _op2: aword);
|
|
|
|
-
|
|
|
|
- constructor op_const_reg(op : tasmop;_size : topsize;_op1 : aword;_op2 : tregister);
|
|
|
|
- constructor op_const_const(op : tasmop;_size : topsize;_op1,_op2 : aword);
|
|
|
|
- constructor op_const_ref(op : tasmop;_size : topsize;_op1 : aword;const _op2 : treference);
|
|
|
|
-
|
|
|
|
- constructor op_ref_reg(op : tasmop;_size : topsize;const _op1 : treference;_op2 : tregister);
|
|
|
|
|
|
+ opsize:topsize;
|
|
|
|
+ constructor op_none(op:tasmop;_size:topsize);
|
|
|
|
+ constructor op_reg(op:tasmop;_size:topsize;_op1:tregister);
|
|
|
|
+ constructor op_const(op:tasmop;_size:topsize;_op1:aword);
|
|
|
|
+ constructor op_ref(op:tasmop;_size:topsize;const _op1:treference);
|
|
|
|
+ constructor op_reg_reg(op:tasmop;_size:topsize;_op1,_op2:tregister);
|
|
|
|
+ constructor op_reg_ref(op:tasmop;_size:topsize;_op1:tregister;const _op2:treference);
|
|
|
|
+ constructor op_reg_const(op:tasmop; _size:topsize; _op1:tregister; _op2:aword);
|
|
|
|
+ constructor op_const_reg(op:tasmop;_size:topsize;_op1:aword;_op2:tregister);
|
|
|
|
+ constructor op_const_const(op:tasmop;_size:topsize;_op1,_op2:aword);
|
|
|
|
+ constructor op_const_ref(op:tasmop;_size:topsize;_op1:aword;const _op2:treference);
|
|
|
|
+ constructor op_ref_reg(op:tasmop;_size:topsize;const _op1:treference;_op2:tregister);
|
|
{ this is only allowed if _op1 is an int value (_op1^.isintvalue=true) }
|
|
{ this is only allowed if _op1 is an int value (_op1^.isintvalue=true) }
|
|
- constructor op_ref_ref(op : tasmop;_size : topsize;const _op1,_op2 : treference);
|
|
|
|
-
|
|
|
|
- constructor op_reg_reg_reg(op : tasmop;_size : topsize;_op1,_op2,_op3 : tregister);
|
|
|
|
|
|
+ constructor op_ref_ref(op:tasmop;_size:topsize;const _op1,_op2:treference);
|
|
|
|
+ constructor op_reg_reg_reg(op:tasmop;_size:topsize;_op1,_op2,_op3:tregister);
|
|
constructor op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:aWord;_op3:tregister);
|
|
constructor op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:aWord;_op3:tregister);
|
|
- constructor op_const_ref_reg(op : tasmop;_size : topsize;_op1 : aword;const _op2 : treference;_op3 : tregister);
|
|
|
|
- constructor op_reg_reg_ref(op : tasmop;_size : topsize;_op1,_op2 : tregister; const _op3 : treference);
|
|
|
|
- constructor op_const_reg_ref(op : tasmop;_size : topsize;_op1 : aword;_op2 : tregister;const _op3 : treference);
|
|
|
|
|
|
+ constructor op_const_ref_reg(op:tasmop;_size:topsize;_op1:aword;const _op2:treference;_op3:tregister);
|
|
|
|
+ constructor op_reg_reg_ref(op:tasmop;_size:topsize;_op1,_op2:tregister; const _op3:treference);
|
|
|
|
+ constructor op_const_reg_ref(op:tasmop;_size:topsize;_op1:aword;_op2:tregister;const _op3:treference);
|
|
|
|
|
|
{ this is for Jmp instructions }
|
|
{ this is for Jmp instructions }
|
|
- constructor op_cond_sym(op : tasmop;cond:TAsmCond;_size : topsize;_op1 : tasmsymbol);
|
|
|
|
-
|
|
|
|
- constructor op_sym(op : tasmop;_size : topsize;_op1 : tasmsymbol);
|
|
|
|
- constructor op_sym_ofs(op : tasmop;_size : topsize;_op1 : tasmsymbol;_op1ofs:longint);
|
|
|
|
- constructor op_sym_ofs_reg(op : tasmop;_size : topsize;_op1 : tasmsymbol;_op1ofs:longint;_op2 : tregister);
|
|
|
|
- constructor op_sym_ofs_ref(op : tasmop;_size : topsize;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
|
|
|
|
-
|
|
|
|
|
|
+ constructor op_cond_sym(op:tasmop;cond:TAsmCond;_size:topsize;_op1:tasmsymbol);
|
|
|
|
+ constructor op_sym(op:tasmop;_size:topsize;_op1:tasmsymbol);
|
|
|
|
+ constructor op_sym_ofs(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint);
|
|
|
|
+ constructor op_sym_ofs_reg(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;_op2:tregister);
|
|
|
|
+ constructor op_sym_ofs_ref(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;const _op2:treference);
|
|
procedure changeopsize(siz:topsize);
|
|
procedure changeopsize(siz:topsize);
|
|
-
|
|
|
|
function GetString:string;
|
|
function GetString:string;
|
|
procedure CheckNonCommutativeOpcodes;
|
|
procedure CheckNonCommutativeOpcodes;
|
|
private
|
|
private
|
|
- FOperandOrder : TOperandOrder;
|
|
|
|
- procedure init(_size : topsize); { this need to be called by all constructor }
|
|
|
|
|
|
+ FOperandOrder:TOperandOrder;
|
|
|
|
+ procedure init(_size:topsize);{this need to be called by all constructor}
|
|
{$ifndef NOAG386BIN}
|
|
{$ifndef NOAG386BIN}
|
|
public
|
|
public
|
|
{ the next will reset all instructions that can change in pass 2 }
|
|
{ the next will reset all instructions that can change in pass 2 }
|
|
@@ -105,10 +82,10 @@ type
|
|
procedure SetOperandOrder(order:TOperandOrder);
|
|
procedure SetOperandOrder(order:TOperandOrder);
|
|
private
|
|
private
|
|
{ next fields are filled in pass1, so pass2 is faster }
|
|
{ next fields are filled in pass1, so pass2 is faster }
|
|
- insentry : PInsEntry;
|
|
|
|
|
|
+ insentry:PInsEntry;
|
|
insoffset,
|
|
insoffset,
|
|
- inssize : longint;
|
|
|
|
- LastInsOffset : longint; { need to be public to be reset }
|
|
|
|
|
|
+ inssize:longint;
|
|
|
|
+ LastInsOffset:longint; { need to be public to be reset }
|
|
function InsEnd:longint;
|
|
function InsEnd:longint;
|
|
procedure create_ot;
|
|
procedure create_ot;
|
|
function Matches(p:PInsEntry):longint;
|
|
function Matches(p:PInsEntry):longint;
|
|
@@ -120,28 +97,22 @@ type
|
|
PROCEDURE DoneAsm;
|
|
PROCEDURE DoneAsm;
|
|
PROCEDURE InitAsm;
|
|
PROCEDURE InitAsm;
|
|
implementation
|
|
implementation
|
|
-
|
|
|
|
uses
|
|
uses
|
|
cutils,
|
|
cutils,
|
|
CpuGas;
|
|
CpuGas;
|
|
{****************************************************************************
|
|
{****************************************************************************
|
|
TAI_ALIGN
|
|
TAI_ALIGN
|
|
****************************************************************************}
|
|
****************************************************************************}
|
|
-
|
|
|
|
- constructor tai_align.create(b: byte);
|
|
|
|
|
|
+ constructor tai_align.create(b:byte);
|
|
begin
|
|
begin
|
|
inherited create(b);
|
|
inherited create(b);
|
|
- reg := R_NONE;
|
|
|
|
|
|
+ reg:= R_NONE;
|
|
end;
|
|
end;
|
|
-
|
|
|
|
-
|
|
|
|
- constructor tai_align.create_op(b: byte; _op: byte);
|
|
|
|
|
|
+ constructor tai_align.create_op(b:byte; _op:byte);
|
|
begin
|
|
begin
|
|
inherited create_op(b,_op);
|
|
inherited create_op(b,_op);
|
|
- reg := R_NONE;
|
|
|
|
|
|
+ reg:= R_NONE;
|
|
end;
|
|
end;
|
|
-
|
|
|
|
-
|
|
|
|
function tai_align.getfillbuf:pchar;
|
|
function tai_align.getfillbuf:pchar;
|
|
const
|
|
const
|
|
alignarray:array[0..5] of string[8]=(
|
|
alignarray:array[0..5] of string[8]=(
|
|
@@ -153,8 +124,8 @@ uses
|
|
#$90
|
|
#$90
|
|
);
|
|
);
|
|
var
|
|
var
|
|
- bufptr : pchar;
|
|
|
|
- j : longint;
|
|
|
|
|
|
+ bufptr:pchar;
|
|
|
|
+ j:longint;
|
|
begin
|
|
begin
|
|
if not use_op then
|
|
if not use_op then
|
|
begin
|
|
begin
|
|
@@ -171,19 +142,16 @@ uses
|
|
end;
|
|
end;
|
|
getfillbuf:=pchar(@buf);
|
|
getfillbuf:=pchar(@buf);
|
|
end;
|
|
end;
|
|
-
|
|
|
|
-
|
|
|
|
{*****************************************************************************
|
|
{*****************************************************************************
|
|
Taicpu Constructors
|
|
Taicpu Constructors
|
|
*****************************************************************************}
|
|
*****************************************************************************}
|
|
-
|
|
|
|
procedure taicpu.changeopsize(siz:topsize);
|
|
procedure taicpu.changeopsize(siz:topsize);
|
|
begin
|
|
begin
|
|
opsize:=siz;
|
|
opsize:=siz;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- procedure taicpu.init(_size : topsize);
|
|
|
|
|
|
+ procedure taicpu.init(_size:topsize);
|
|
begin
|
|
begin
|
|
{ default order is att }
|
|
{ default order is att }
|
|
FOperandOrder:=op_att;
|
|
FOperandOrder:=op_att;
|
|
@@ -198,14 +166,14 @@ uses
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_none(op : tasmop;_size : topsize);
|
|
|
|
|
|
+ constructor taicpu.op_none(op:tasmop;_size:topsize);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_reg(op : tasmop;_size : topsize;_op1 : tregister);
|
|
|
|
|
|
+ constructor taicpu.op_reg(op:tasmop;_size:topsize;_op1:tregister);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -214,7 +182,7 @@ uses
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_const(op : tasmop;_size : topsize;_op1 : aword);
|
|
|
|
|
|
+ constructor taicpu.op_const(op:tasmop;_size:topsize;_op1:aword);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -223,7 +191,7 @@ uses
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_ref(op : tasmop;_size : topsize;const _op1 : treference);
|
|
|
|
|
|
+ constructor taicpu.op_ref(op:tasmop;_size:topsize;const _op1:treference);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -232,7 +200,7 @@ uses
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_reg_reg(op : tasmop;_size : topsize;_op1,_op2 : tregister);
|
|
|
|
|
|
+ constructor taicpu.op_reg_reg(op:tasmop;_size:topsize;_op1,_op2:tregister);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -242,7 +210,7 @@ uses
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_reg_const(op:tasmop; _size: topsize; _op1: tregister; _op2: aword);
|
|
|
|
|
|
+ constructor taicpu.op_reg_const(op:tasmop; _size:topsize; _op1:tregister; _op2:aword);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -252,7 +220,7 @@ uses
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_reg_ref(op : tasmop;_size : topsize;_op1 : tregister;const _op2 : treference);
|
|
|
|
|
|
+ constructor taicpu.op_reg_ref(op:tasmop;_size:topsize;_op1:tregister;const _op2:treference);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -262,7 +230,7 @@ uses
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_const_reg(op : tasmop;_size : topsize;_op1 : aword;_op2 : tregister);
|
|
|
|
|
|
+ constructor taicpu.op_const_reg(op:tasmop;_size:topsize;_op1:aword;_op2:tregister);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -272,7 +240,7 @@ uses
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_const_const(op : tasmop;_size : topsize;_op1,_op2 : aword);
|
|
|
|
|
|
+ constructor taicpu.op_const_const(op:tasmop;_size:topsize;_op1,_op2:aword);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -282,7 +250,7 @@ uses
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_const_ref(op : tasmop;_size : topsize;_op1 : aword;const _op2 : treference);
|
|
|
|
|
|
+ constructor taicpu.op_const_ref(op:tasmop;_size:topsize;_op1:aword;const _op2:treference);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -302,7 +270,7 @@ constructor taicpu.op_ref_reg(op:tasmop;_size:topsize;const _op1:treference;_op2
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_ref_ref(op : tasmop;_size : topsize;const _op1,_op2 : treference);
|
|
|
|
|
|
+ constructor taicpu.op_ref_ref(op:tasmop;_size:topsize;const _op1,_op2:treference);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -312,7 +280,7 @@ constructor taicpu.op_ref_reg(op:tasmop;_size:topsize;const _op1:treference;_op2
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_reg_reg_reg(op : tasmop;_size : topsize;_op1,_op2,_op3 : tregister);
|
|
|
|
|
|
+ constructor taicpu.op_reg_reg_reg(op:tasmop;_size:topsize;_op1,_op2,_op3:tregister);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -331,7 +299,7 @@ CONSTRUCTOR taicpu.op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:
|
|
LoadReg(2,_op3);
|
|
LoadReg(2,_op3);
|
|
END;
|
|
END;
|
|
|
|
|
|
- constructor taicpu.op_reg_reg_ref(op : tasmop;_size : topsize;_op1,_op2 : tregister;const _op3 : treference);
|
|
|
|
|
|
+ constructor taicpu.op_reg_reg_ref(op:tasmop;_size:topsize;_op1,_op2:tregister;const _op3:treference);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -342,7 +310,7 @@ CONSTRUCTOR taicpu.op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_const_ref_reg(op : tasmop;_size : topsize;_op1 : aword;const _op2 : treference;_op3 : tregister);
|
|
|
|
|
|
+ constructor taicpu.op_const_ref_reg(op:tasmop;_size:topsize;_op1:aword;const _op2:treference;_op3:tregister);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -353,7 +321,7 @@ CONSTRUCTOR taicpu.op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_const_reg_ref(op : tasmop;_size : topsize;_op1 : aword;_op2 : tregister;const _op3 : treference);
|
|
|
|
|
|
+ constructor taicpu.op_const_reg_ref(op:tasmop;_size:topsize;_op1:aword;_op2:tregister;const _op3:treference);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -364,7 +332,7 @@ CONSTRUCTOR taicpu.op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_cond_sym(op : tasmop;cond:TAsmCond;_size : topsize;_op1 : tasmsymbol);
|
|
|
|
|
|
+ constructor taicpu.op_cond_sym(op:tasmop;cond:TAsmCond;_size:topsize;_op1:tasmsymbol);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -374,7 +342,7 @@ CONSTRUCTOR taicpu.op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_sym(op : tasmop;_size : topsize;_op1 : tasmsymbol);
|
|
|
|
|
|
+ constructor taicpu.op_sym(op:tasmop;_size:topsize;_op1:tasmsymbol);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -383,7 +351,7 @@ CONSTRUCTOR taicpu.op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_sym_ofs(op : tasmop;_size : topsize;_op1 : tasmsymbol;_op1ofs:longint);
|
|
|
|
|
|
+ constructor taicpu.op_sym_ofs(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -392,7 +360,7 @@ CONSTRUCTOR taicpu.op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_sym_ofs_reg(op : tasmop;_size : topsize;_op1 : tasmsymbol;_op1ofs:longint;_op2 : tregister);
|
|
|
|
|
|
+ constructor taicpu.op_sym_ofs_reg(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;_op2:tregister);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -402,7 +370,7 @@ CONSTRUCTOR taicpu.op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor taicpu.op_sym_ofs_ref(op : tasmop;_size : topsize;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
|
|
|
|
|
|
+ constructor taicpu.op_sym_ofs_ref(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;const _op2:treference);
|
|
begin
|
|
begin
|
|
inherited create(op);
|
|
inherited create(op);
|
|
init(_size);
|
|
init(_size);
|
|
@@ -413,9 +381,9 @@ CONSTRUCTOR taicpu.op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:
|
|
|
|
|
|
function taicpu.GetString:string;
|
|
function taicpu.GetString:string;
|
|
var
|
|
var
|
|
- i : longint;
|
|
|
|
- s : string;
|
|
|
|
- addsize : boolean;
|
|
|
|
|
|
+ i:longint;
|
|
|
|
+ s:string;
|
|
|
|
+ addsize:boolean;
|
|
begin
|
|
begin
|
|
s:='['+std_op2str[opcode];
|
|
s:='['+std_op2str[opcode];
|
|
for i:=1to ops do
|
|
for i:=1to ops do
|
|
@@ -478,17 +446,17 @@ CONSTRUCTOR taicpu.op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:
|
|
|
|
|
|
procedure taicpu.Swatoperands;
|
|
procedure taicpu.Swatoperands;
|
|
var
|
|
var
|
|
- p : TOper;
|
|
|
|
|
|
+ p:TOper;
|
|
begin
|
|
begin
|
|
{ Fix the operands which are in AT&T style and we need them in Intel style }
|
|
{ Fix the operands which are in AT&T style and we need them in Intel style }
|
|
case ops of
|
|
case ops of
|
|
- 2 : begin
|
|
|
|
|
|
+ 2:begin
|
|
{ 0,1 -> 1,0 }
|
|
{ 0,1 -> 1,0 }
|
|
p:=oper[0];
|
|
p:=oper[0];
|
|
oper[0]:=oper[1];
|
|
oper[0]:=oper[1];
|
|
oper[1]:=p;
|
|
oper[1]:=p;
|
|
end;
|
|
end;
|
|
- 3 : begin
|
|
|
|
|
|
+ 3:begin
|
|
{ 0,1,2 -> 2,1,0 }
|
|
{ 0,1,2 -> 2,1,0 }
|
|
p:=oper[0];
|
|
p:=oper[0];
|
|
oper[0]:=oper[2];
|
|
oper[0]:=oper[2];
|
|
@@ -556,11 +524,11 @@ end;
|
|
|
|
|
|
type
|
|
type
|
|
ea=packed record
|
|
ea=packed record
|
|
- sib_present : boolean;
|
|
|
|
- bytes : byte;
|
|
|
|
- size : byte;
|
|
|
|
- modrm : byte;
|
|
|
|
- sib : byte;
|
|
|
|
|
|
+ sib_present:boolean;
|
|
|
|
+ bytes:byte;
|
|
|
|
+ size:byte;
|
|
|
|
+ modrm:byte;
|
|
|
|
+ sib:byte;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure taicpu.create_ot;
|
|
procedure taicpu.create_ot;
|
|
@@ -568,7 +536,7 @@ procedure taicpu.create_ot;
|
|
this function will also fix some other fields which only needs to be once
|
|
this function will also fix some other fields which only needs to be once
|
|
}
|
|
}
|
|
var
|
|
var
|
|
- i,l,relsize : longint;
|
|
|
|
|
|
+ i,l,relsize:longint;
|
|
begin
|
|
begin
|
|
if ops=0 then
|
|
if ops=0 then
|
|
exit;
|
|
exit;
|
|
@@ -577,9 +545,9 @@ begin
|
|
with oper[i] do
|
|
with oper[i] do
|
|
begin
|
|
begin
|
|
case typ of
|
|
case typ of
|
|
- top_reg :
|
|
|
|
|
|
+ top_reg:
|
|
{ot:=reg2type[reg]};
|
|
{ot:=reg2type[reg]};
|
|
- top_ref :
|
|
|
|
|
|
+ top_ref:
|
|
begin
|
|
begin
|
|
{ create ot field }
|
|
{ create ot field }
|
|
if (ot and OT_SIZE_MASK)=0 then
|
|
if (ot and OT_SIZE_MASK)=0 then
|
|
@@ -595,14 +563,14 @@ begin
|
|
if (ref^.scalefactor=0) then
|
|
if (ref^.scalefactor=0) then
|
|
ref^.scalefactor:=1;
|
|
ref^.scalefactor:=1;
|
|
end;
|
|
end;
|
|
- top_const :
|
|
|
|
|
|
+ top_const:
|
|
begin
|
|
begin
|
|
if (opsize<>S_W) and (longint(val)>=-128) and (val<=127) then
|
|
if (opsize<>S_W) and (longint(val)>=-128) and (val<=127) then
|
|
ot:=OT_IMM8 or OT_SIGNED
|
|
ot:=OT_IMM8 or OT_SIGNED
|
|
else
|
|
else
|
|
ot:=OT_IMMEDIATE or opsize_2_type[i,opsize];
|
|
ot:=OT_IMMEDIATE or opsize_2_type[i,opsize];
|
|
end;
|
|
end;
|
|
- top_symbol :
|
|
|
|
|
|
+ top_symbol:
|
|
begin
|
|
begin
|
|
if LastInsOffset=-1 then
|
|
if LastInsOffset=-1 then
|
|
l:=0
|
|
l:=0
|
|
@@ -632,18 +600,18 @@ end;
|
|
|
|
|
|
|
|
|
|
function taicpu.Matches(p:PInsEntry):longint;
|
|
function taicpu.Matches(p:PInsEntry):longint;
|
|
-{ * IF_SM stands for Size Match: any operand whose size is not
|
|
|
|
|
|
+{ * IF_SM stands for Size Match:any operand whose size is not
|
|
* explicitly specified by the template is `really' intended to be
|
|
* explicitly specified by the template is `really' intended to be
|
|
* the same size as the first size-specified operand.
|
|
* the same size as the first size-specified operand.
|
|
* Non-specification is tolerated in the input instruction, but
|
|
* Non-specification is tolerated in the input instruction, but
|
|
* _wrong_ specification is not.
|
|
* _wrong_ specification is not.
|
|
*
|
|
*
|
|
* IF_SM2 invokes Size Match on only the first _two_ operands, for
|
|
* IF_SM2 invokes Size Match on only the first _two_ operands, for
|
|
- * three-operand instructions such as SHLD: it implies that the
|
|
|
|
|
|
+ * three-operand instructions such as SHLD:it implies that the
|
|
* first two operands must match in size, but that the third is
|
|
* first two operands must match in size, but that the third is
|
|
* required to be _unspecified_.
|
|
* required to be _unspecified_.
|
|
*
|
|
*
|
|
- * IF_SB invokes Size Byte: operands with unspecified size in the
|
|
|
|
|
|
+ * IF_SB invokes Size Byte:operands with unspecified size in the
|
|
* template are really bytes, and so no non-byte specification in
|
|
* template are really bytes, and so no non-byte specification in
|
|
* the input instruction will be tolerated. IF_SW similarly invokes
|
|
* the input instruction will be tolerated. IF_SW similarly invokes
|
|
* Size Word, and IF_SD invokes Size Doubleword.
|
|
* Size Word, and IF_SD invokes Size Doubleword.
|
|
@@ -653,8 +621,8 @@ function taicpu.Matches(p:PInsEntry):longint;
|
|
* required to have unspecified size in the instruction too...)
|
|
* required to have unspecified size in the instruction too...)
|
|
}
|
|
}
|
|
var
|
|
var
|
|
- i,j,asize,oprs : longint;
|
|
|
|
- siz : array[0..2] of longint;
|
|
|
|
|
|
+ i,j,asize,oprs:longint;
|
|
|
|
+ siz:array[0..2] of longint;
|
|
begin
|
|
begin
|
|
Matches:=100;
|
|
Matches:=100;
|
|
|
|
|
|
@@ -782,7 +750,7 @@ end;
|
|
|
|
|
|
function taicpu.CheckIfValid:boolean;
|
|
function taicpu.CheckIfValid:boolean;
|
|
var
|
|
var
|
|
- m,i : longint;
|
|
|
|
|
|
+ m,i:longint;
|
|
begin
|
|
begin
|
|
CheckIfValid:=false;
|
|
CheckIfValid:=false;
|
|
{ Things which may only be done once, not when a second pass is done to
|
|
{ Things which may only be done once, not when a second pass is done to
|
|
@@ -899,7 +867,7 @@ begin
|
|
end;
|
|
end;
|
|
function taicpu.NeedAddrPrefix(opidx:byte):boolean;
|
|
function taicpu.NeedAddrPrefix(opidx:byte):boolean;
|
|
var
|
|
var
|
|
- i,b : tregister;
|
|
|
|
|
|
+ i,b:tregister;
|
|
begin
|
|
begin
|
|
{ if (OT_MEMORY and (not oper[opidx].ot))=0 then
|
|
{ if (OT_MEMORY and (not oper[opidx].ot))=0 then
|
|
begin
|
|
begin
|
|
@@ -919,21 +887,21 @@ end;
|
|
function regval(r:tregister):byte;
|
|
function regval(r:tregister):byte;
|
|
begin
|
|
begin
|
|
{case r of
|
|
{case r of
|
|
- R_EAX,R_AX,R_AL,R_ES,R_CR0,R_DR0,R_ST,R_ST0,R_MM0,R_XMM0 :
|
|
|
|
|
|
+ R_EAX,R_AX,R_AL,R_ES,R_CR0,R_DR0,R_ST,R_ST0,R_MM0,R_XMM0:
|
|
regval:=0;
|
|
regval:=0;
|
|
- R_ECX,R_CX,R_CL,R_CS,R_DR1,R_ST1,R_MM1,R_XMM1 :
|
|
|
|
|
|
+ R_ECX,R_CX,R_CL,R_CS,R_DR1,R_ST1,R_MM1,R_XMM1:
|
|
regval:=1;
|
|
regval:=1;
|
|
- R_EDX,R_DX,R_DL,R_SS,R_CR2,R_DR2,R_ST2,R_MM2,R_XMM2 :
|
|
|
|
|
|
+ R_EDX,R_DX,R_DL,R_SS,R_CR2,R_DR2,R_ST2,R_MM2,R_XMM2:
|
|
regval:=2;
|
|
regval:=2;
|
|
- R_EBX,R_BX,R_BL,R_DS,R_CR3,R_DR3,R_TR3,R_ST3,R_MM3,R_XMM3 :
|
|
|
|
|
|
+ R_EBX,R_BX,R_BL,R_DS,R_CR3,R_DR3,R_TR3,R_ST3,R_MM3,R_XMM3:
|
|
regval:=3;
|
|
regval:=3;
|
|
- R_ESP,R_SP,R_AH,R_FS,R_CR4,R_TR4,R_ST4,R_MM4,R_XMM4 :
|
|
|
|
|
|
+ R_ESP,R_SP,R_AH,R_FS,R_CR4,R_TR4,R_ST4,R_MM4,R_XMM4:
|
|
regval:=4;
|
|
regval:=4;
|
|
- R_EBP,R_BP,R_CH,R_GS,R_TR5,R_ST5,R_MM5,R_XMM5 :
|
|
|
|
|
|
+ R_EBP,R_BP,R_CH,R_GS,R_TR5,R_ST5,R_MM5,R_XMM5:
|
|
regval:=5;
|
|
regval:=5;
|
|
- R_ESI,R_SI,R_DH,R_DR6,R_TR6,R_ST6,R_MM6,R_XMM6 :
|
|
|
|
|
|
+ R_ESI,R_SI,R_DH,R_DR6,R_TR6,R_ST6,R_MM6,R_XMM6:
|
|
regval:=6;
|
|
regval:=6;
|
|
- R_EDI,R_DI,R_BH,R_DR7,R_TR7,R_ST7,R_MM7,R_XMM7 :
|
|
|
|
|
|
+ R_EDI,R_DI,R_BH,R_DR7,R_TR7,R_ST7,R_MM7,R_XMM7:
|
|
regval:=7;
|
|
regval:=7;
|
|
else}
|
|
else}
|
|
begin
|
|
begin
|
|
@@ -946,7 +914,7 @@ end;
|
|
|
|
|
|
function process_ea(const input:toper;var output:ea;rfield:longint):boolean;
|
|
function process_ea(const input:toper;var output:ea;rfield:longint):boolean;
|
|
{const
|
|
{const
|
|
- regs : array[0..63] of tregister=(
|
|
|
|
|
|
+ regs:array[0..63] of tregister=(
|
|
R_MM0, R_EAX, R_AX, R_AL, R_XMM0, R_NONE, R_NONE, R_NONE,
|
|
R_MM0, R_EAX, R_AX, R_AL, R_XMM0, R_NONE, R_NONE, R_NONE,
|
|
R_MM1, R_ECX, R_CX, R_CL, R_XMM1, R_NONE, R_NONE, R_NONE,
|
|
R_MM1, R_ECX, R_CX, R_CL, R_XMM1, R_NONE, R_NONE, R_NONE,
|
|
R_MM2, R_EDX, R_DX, R_DL, R_XMM2, R_NONE, R_NONE, R_NONE,
|
|
R_MM2, R_EDX, R_DX, R_DL, R_XMM2, R_NONE, R_NONE, R_NONE,
|
|
@@ -957,12 +925,12 @@ function process_ea(const input:toper;var output:ea;rfield:longint):boolean;
|
|
R_MM7, R_EDI, R_DI, R_BH, R_XMM7, R_NONE, R_NONE, R_NONE
|
|
R_MM7, R_EDI, R_DI, R_BH, R_XMM7, R_NONE, R_NONE, R_NONE
|
|
);}
|
|
);}
|
|
var
|
|
var
|
|
- j : longint;
|
|
|
|
- i,b : tregister;
|
|
|
|
- sym : tasmsymbol;
|
|
|
|
- md,s : byte;
|
|
|
|
|
|
+ j:longint;
|
|
|
|
+ i,b:tregister;
|
|
|
|
+ sym:tasmsymbol;
|
|
|
|
+ md,s:byte;
|
|
base,index,scalefactor,
|
|
base,index,scalefactor,
|
|
- o : longint;
|
|
|
|
|
|
+ o:longint;
|
|
begin
|
|
begin
|
|
process_ea:=false;
|
|
process_ea:=false;
|
|
{ register ? }
|
|
{ register ? }
|
|
@@ -1033,37 +1001,37 @@ begin
|
|
exit;}
|
|
exit;}
|
|
{ base }
|
|
{ base }
|
|
{ case b of
|
|
{ case b of
|
|
- R_EAX : base:=0;
|
|
|
|
- R_ECX : base:=1;
|
|
|
|
- R_EDX : base:=2;
|
|
|
|
- R_EBX : base:=3;
|
|
|
|
- R_ESP : base:=4;
|
|
|
|
|
|
+ R_EAX:base:=0;
|
|
|
|
+ R_ECX:base:=1;
|
|
|
|
+ R_EDX:base:=2;
|
|
|
|
+ R_EBX:base:=3;
|
|
|
|
+ R_ESP:base:=4;
|
|
R_NONE,
|
|
R_NONE,
|
|
- R_EBP : base:=5;
|
|
|
|
- R_ESI : base:=6;
|
|
|
|
- R_EDI : base:=7;
|
|
|
|
|
|
+ R_EBP:base:=5;
|
|
|
|
+ R_ESI:base:=6;
|
|
|
|
+ R_EDI:base:=7;
|
|
else
|
|
else
|
|
exit;
|
|
exit;
|
|
end;}
|
|
end;}
|
|
{ index }
|
|
{ index }
|
|
{ case i of
|
|
{ case i of
|
|
- R_EAX : index:=0;
|
|
|
|
- R_ECX : index:=1;
|
|
|
|
- R_EDX : index:=2;
|
|
|
|
- R_EBX : index:=3;
|
|
|
|
- R_NONE : index:=4;
|
|
|
|
- R_EBP : index:=5;
|
|
|
|
- R_ESI : index:=6;
|
|
|
|
- R_EDI : index:=7;
|
|
|
|
|
|
+ R_EAX:index:=0;
|
|
|
|
+ R_ECX:index:=1;
|
|
|
|
+ R_EDX:index:=2;
|
|
|
|
+ R_EBX:index:=3;
|
|
|
|
+ R_NONE:index:=4;
|
|
|
|
+ R_EBP:index:=5;
|
|
|
|
+ R_ESI:index:=6;
|
|
|
|
+ R_EDI:index:=7;
|
|
else
|
|
else
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
case s of
|
|
case s of
|
|
0,
|
|
0,
|
|
- 1 : scalefactor:=0;
|
|
|
|
- 2 : scalefactor:=1;
|
|
|
|
- 4 : scalefactor:=2;
|
|
|
|
- 8 : scalefactor:=3;
|
|
|
|
|
|
+ 1:scalefactor:=0;
|
|
|
|
+ 2:scalefactor:=1;
|
|
|
|
+ 4:scalefactor:=2;
|
|
|
|
+ 8:scalefactor:=3;
|
|
else
|
|
else
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
@@ -1102,10 +1070,10 @@ end;
|
|
|
|
|
|
function taicpu.calcsize(p:PInsEntry):longint;
|
|
function taicpu.calcsize(p:PInsEntry):longint;
|
|
var
|
|
var
|
|
- codes : pchar;
|
|
|
|
- c : byte;
|
|
|
|
- len : longint;
|
|
|
|
- ea_data : ea;
|
|
|
|
|
|
+ codes:pchar;
|
|
|
|
+ c:byte;
|
|
|
|
+ len:longint;
|
|
|
|
+ ea_data:ea;
|
|
begin
|
|
begin
|
|
len:=0;
|
|
len:=0;
|
|
codes:=@p^.code;
|
|
codes:=@p^.code;
|
|
@@ -1113,19 +1081,19 @@ begin
|
|
c:=ord(codes^);
|
|
c:=ord(codes^);
|
|
inc(codes);
|
|
inc(codes);
|
|
case c of
|
|
case c of
|
|
- 0 :
|
|
|
|
|
|
+ 0:
|
|
break;
|
|
break;
|
|
- 1,2,3 :
|
|
|
|
|
|
+ 1,2,3:
|
|
begin
|
|
begin
|
|
inc(codes,c);
|
|
inc(codes,c);
|
|
inc(len,c);
|
|
inc(len,c);
|
|
end;
|
|
end;
|
|
- 8,9,10 :
|
|
|
|
|
|
+ 8,9,10:
|
|
begin
|
|
begin
|
|
inc(codes);
|
|
inc(codes);
|
|
inc(len);
|
|
inc(len);
|
|
end;
|
|
end;
|
|
- 4,5,6,7 :
|
|
|
|
|
|
+ 4,5,6,7:
|
|
begin
|
|
begin
|
|
if opsize=S_W then
|
|
if opsize=S_W then
|
|
inc(len,2)
|
|
inc(len,2)
|
|
@@ -1136,34 +1104,34 @@ begin
|
|
12,13,14,
|
|
12,13,14,
|
|
16,17,18,
|
|
16,17,18,
|
|
20,21,22,
|
|
20,21,22,
|
|
- 40,41,42 :
|
|
|
|
|
|
+ 40,41,42:
|
|
inc(len);
|
|
inc(len);
|
|
24,25,26,
|
|
24,25,26,
|
|
31,
|
|
31,
|
|
- 48,49,50 :
|
|
|
|
|
|
+ 48,49,50:
|
|
inc(len,2);
|
|
inc(len,2);
|
|
28,29,30, { we don't have 16 bit immediates code }
|
|
28,29,30, { we don't have 16 bit immediates code }
|
|
32,33,34,
|
|
32,33,34,
|
|
52,53,54,
|
|
52,53,54,
|
|
- 56,57,58 :
|
|
|
|
|
|
+ 56,57,58:
|
|
inc(len,4);
|
|
inc(len,4);
|
|
- 192,193,194 :
|
|
|
|
|
|
+ 192,193,194:
|
|
if NeedAddrPrefix(c-192) then
|
|
if NeedAddrPrefix(c-192) then
|
|
inc(len);
|
|
inc(len);
|
|
- 208 :
|
|
|
|
|
|
+ 208:
|
|
inc(len);
|
|
inc(len);
|
|
200,
|
|
200,
|
|
201,
|
|
201,
|
|
202,
|
|
202,
|
|
209,
|
|
209,
|
|
210,
|
|
210,
|
|
- 217,218,219 : ;
|
|
|
|
- 216 :
|
|
|
|
|
|
+ 217,218,219:;
|
|
|
|
+ 216:
|
|
begin
|
|
begin
|
|
inc(codes);
|
|
inc(codes);
|
|
inc(len);
|
|
inc(len);
|
|
end;
|
|
end;
|
|
- 224,225,226 :
|
|
|
|
|
|
+ 224,225,226:
|
|
begin
|
|
begin
|
|
InternalError(777002);
|
|
InternalError(777002);
|
|
end;
|
|
end;
|
|
@@ -1183,8 +1151,6 @@ begin
|
|
until false;
|
|
until false;
|
|
calcsize:=len;
|
|
calcsize:=len;
|
|
end;
|
|
end;
|
|
-
|
|
|
|
-
|
|
|
|
{$endif NOAG386BIN}
|
|
{$endif NOAG386BIN}
|
|
PROCEDURE DoneAsm;
|
|
PROCEDURE DoneAsm;
|
|
BEGIN
|
|
BEGIN
|
|
@@ -1193,3 +1159,9 @@ PROCEDURE InitAsm;
|
|
BEGIN
|
|
BEGIN
|
|
END;
|
|
END;
|
|
end.
|
|
end.
|
|
|
|
+{
|
|
|
|
+ $Log$
|
|
|
|
+ Revision 1.4 2002-10-13 21:46:07 mazen
|
|
|
|
+ * assembler output format fixed
|
|
|
|
+
|
|
|
|
+}
|