* Xtensa: completed compiler skeleton

git-svn-id: trunk@44323 -
This commit is contained in:
florian 2020-03-21 12:49:45 +00:00
parent 28c0a47a95
commit 73c68236b6
15 changed files with 1072 additions and 38 deletions

3
.gitattributes vendored
View File

@ -1024,6 +1024,9 @@ compiler/xtensa/cpupi.pas svneol=native#text/pascal
compiler/xtensa/cputarg.pas svneol=native#text/pascal
compiler/xtensa/hlcgcpu.pas svneol=native#text/pascal
compiler/xtensa/itcpugas.pas svneol=native#text/pascal
compiler/xtensa/ncpuadd.pas svneol=native#text/pascal
compiler/xtensa/ncpucnv.pas svneol=native#text/pascal
compiler/xtensa/ncpumat.pas svneol=native#text/pascal
compiler/xtensa/racpugas.pas svneol=native#text/pascal
compiler/xtensa/raxtensa.pas svneol=native#text/pascal
compiler/xtensa/rgcpu.pas svneol=native#text/pascal

View File

@ -39,7 +39,7 @@
{ This fake CPU is used to allow incorporation of globtype unit
into utils/ppudump without any CPU specific code PM }
{$ifdef generic_cpu}
{$define cpu32bit}
{$define #cpu32bit}
{$define cpu32bitaddr}
{$define cpu32bitalu}
{$define cpuflags}

View File

@ -3751,6 +3751,7 @@ procedure read_arguments(cmd:TCmdStr);
def_system_macro('FPC_COMP_IS_INT64');
def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
{$endif riscv32}
{$ifdef riscv64}
def_system_macro('CPURISCV');
def_system_macro('CPURISCV64');
@ -3760,6 +3761,14 @@ procedure read_arguments(cmd:TCmdStr);
def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
{$endif riscv64}
{$ifdef xtensa}
def_system_macro('CPUXTENSA');
def_system_macro('CPU32');
def_system_macro('FPC_CURRENCY_IS_INT64');
def_system_macro('FPC_COMP_IS_INT64');
def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
{$endif xtensa}
{$if defined(cpu8bitalu)}
def_system_macro('CPUINT8');
{$elseif defined(cpu16bitalu)}

View File

@ -370,6 +370,10 @@ implementation
create_fpu_types;
s64currencytype:=corddef.create(scurrency,low(int64),high(int64),true);
{$endif jvm}
{$ifdef xtensa}
create_fpu_types;
s64currencytype:=corddef.create(scurrency,low(int64),high(int64),true);
{$endif xtensa}
set_default_int_types;
{ some other definitions }
charpointertype:=cpointerdef.create(cansichartype);

View File

@ -75,6 +75,7 @@
,asmmode_i8086_intel
,asmmode_i8086_att
,asmmode_arm_gas_unified
,asmmode_xtensa_gas
);
(* IMPORTANT NOTE:

View File

@ -1110,6 +1110,11 @@ begin
{$ifdef riscv64}
default_target(system_riscv64_linux);
{$endif riscv64}
{$ifdef xtensa}
default_target(system_xtensa_embedded);
{$endif xtensa}
end;

View File

@ -65,7 +65,7 @@ unit agcpugas;
function TXtensaGNUAssembler.MakeCmdLine: TCmdStr;
begin
Result:='';
result:=inherited MakeCmdLine;
end;
{****************************************************************************}
@ -121,7 +121,7 @@ unit agcpugas;
top_reg:
getopstr:=gas_regname(o.reg);
top_const:
getopstr:='#'+tostr(longint(o.val));
getopstr:=tostr(longint(o.val));
top_ref:
if o.ref^.refaddr=addr_full then
begin
@ -182,3 +182,4 @@ unit agcpugas;
begin
RegisterAssembler(as_xtensa_gas_info,TXtensaGNUAssembler);
end.

View File

@ -31,10 +31,38 @@ interface
aasmbase,aasmtai,aasmdata,aasmcpu,
cpubase,cpuinfo,
node,symconst,SymType,symdef,
rgcpu;
rgcpu,
cg64f32;
type
tcgcpu=class(tcg)
public
procedure init_register_allocators;override;
procedure done_register_allocators;override;
{ move instructions }
procedure a_load_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister);override;
procedure a_load_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister;const ref: TReference);override;
procedure a_load_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: TReference; reg: tregister);override;
procedure a_load_const_reg(list: TAsmList; size: tcgsize; a: tcgint; reg: tregister);override;
procedure a_loadaddr_ref_reg(list: TAsmList; const ref: TReference; r: tregister);override;
procedure a_op_reg_reg(list: TAsmList; op: topcg; size: tcgsize; src, dst: tregister);override;
procedure a_op_const_reg(list: TAsmList; op: topcg; size: tcgsize; a: tcgint; reg: tregister);override;
procedure a_op_reg_reg_reg(list: TAsmList; op: topcg; size: tcgsize; src1, src2, dst: tregister);override;
procedure a_call_name(list:TAsmList;const s:string; weak: boolean);override;
procedure a_call_reg(list:TAsmList;Reg:tregister);override;
procedure a_jmp_name(list: TAsmList; const s: string);override;
procedure g_proc_entry(list: TAsmList; localsize: longint; nostackframe: boolean);override;
procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe: boolean);override;
{ comparison operations }
procedure a_cmp_reg_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel);override;
procedure a_jmp_always(list: TAsmList; l: TAsmLabel);override;
procedure g_concatcopy(list: TAsmList; const source, dest: treference; len: tcgint);override;
{$ifdef dummy}
protected
{ changes register size without adding register allocation info }
@ -46,60 +74,34 @@ interface
procedure make_simple_ref(list:TAsmList; var op: tasmop; size: tcgsize; oppostfix: toppostfix; var ref: treference; preferred_newbasereg: tregister);
function getfpuregister(list: TAsmList; size: Tcgsize): Tregister; override;
procedure handle_reg_imm12_reg(list: TAsmList; op: Tasmop; size: tcgsize; src: tregister; a: tcgint; dst: tregister; tmpreg: tregister; setflags, usedest: boolean);
procedure init_register_allocators;override;
procedure done_register_allocators;override;
function getmmregister(list:TAsmList;size:tcgsize):tregister;override;
function handle_load_store(list:TAsmList; op: tasmop; size: tcgsize; oppostfix: toppostfix; reg: tregister; ref: treference):treference;
procedure a_call_name(list:TAsmList;const s:string; weak: boolean);override;
procedure a_call_reg(list:TAsmList;Reg:tregister);override;
{ General purpose instructions }
procedure maybeadjustresult(list: TAsmList; op: topcg; size: tcgsize; dst: tregister);
procedure a_op_const_reg(list: TAsmList; op: topcg; size: tcgsize; a: tcgint; reg: tregister);override;
procedure a_op_reg_reg(list: TAsmList; op: topcg; size: tcgsize; src, dst: tregister);override;
procedure a_op_const_reg_reg(list: TAsmList; op: topcg; size: tcgsize; a: tcgint; src, dst: tregister);override;
procedure a_op_reg_reg_reg(list: TAsmList; op: topcg; size: tcgsize; src1, src2, dst: tregister);override;
procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: topcg; size: tcgsize; a: tcgint; src, dst: tregister; setflags : boolean; var ovloc : tlocation);override;
procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: topcg; size: tcgsize; src1, src2, dst: tregister; setflags : boolean; var ovloc : tlocation);override;
{ move instructions }
procedure a_load_const_reg(list: TAsmList; size: tcgsize; a: tcgint; reg: tregister);override;
procedure a_load_const_ref(list: TAsmList; size: tcgsize; a: tcgint; const ref: treference); override;
procedure a_load_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister;const ref: TReference);override;
procedure a_load_reg_ref_unaligned(list: TAsmList; fromsize, tosize: tcgsize; register: tregister; const ref: treference); override;
procedure a_load_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: TReference; reg: tregister);override;
procedure a_load_ref_reg_unaligned(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; register: tregister); override;
procedure a_load_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister);override;
procedure a_loadaddr_ref_reg(list: TAsmList; const ref: TReference; r: tregister);override;
{ fpu move instructions (not used, all floating point is vector unit-based) }
procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override;
procedure a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister); override;
procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); override;
procedure a_loadmm_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister;shuffle : pmmshuffle);override;
procedure a_loadmm_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: TReference; reg: tregister; shuffle: pmmshuffle);override;
procedure a_loadmm_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: TReference; shuffle: pmmshuffle);override;
procedure a_loadmm_intreg_reg(list: TAsmList; fromsize, tosize: tcgsize; intreg, mmreg: tregister; shuffle: pmmshuffle); override;
procedure a_loadmm_reg_intreg(list: TAsmList; fromsize, tosize: tcgsize; mmreg, intreg: tregister; shuffle: pmmshuffle); override;
procedure a_opmm_reg_reg(list: TAsmList; Op: TOpCG; size: tcgsize; src, dst: tregister; shuffle: pmmshuffle); override;
procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tcgsize; src, dst: TRegister); override;
{ comparison operations }
procedure a_cmp_const_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel);override;
procedure a_cmp_reg_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel);override;
procedure a_jmp_always(list: TAsmList; l: TAsmLabel);override;
procedure a_jmp_name(list: TAsmList; const s: string);override;
procedure a_jmp_cond(list: TAsmList; cond: TOpCmp; l: tasmlabel);{ override;}
procedure a_jmp_flags(list: TAsmList; const f: tresflags; l: tasmlabel);override;
procedure g_flags2reg(list: TAsmList; size: tcgsize; const f:tresflags; reg: tregister);override;
procedure g_overflowcheck(list: TAsmList; const loc: tlocation; def: tdef);override;
procedure g_overflowcheck_loc(list: TAsmList; const loc: tlocation; def: tdef; ovloc: tlocation);override;
procedure g_proc_entry(list: TAsmList; localsize: longint; nostackframe: boolean);override;
procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe: boolean);override;
procedure g_maybe_got_init(list: TAsmList); override;
procedure g_restore_registers(list: TAsmList);override;
procedure g_save_registers(list: TAsmList);override;
procedure g_concatcopy_move(list: TAsmList; const source, dest: treference; len: tcgint);
procedure g_concatcopy(list: TAsmList; const source, dest: treference; len: tcgint);override;
procedure g_adjust_self_value(list: TAsmList; procdef: tprocdef; ioffset: tcgint);override;
procedure g_check_for_fpu_exception(list: TAsmList; force, clear: boolean);override;
procedure g_profilecode(list: TAsmList);override;
@ -109,6 +111,18 @@ interface
{$endif dummy}
end;
tcg64fxtensa = class(tcg64f32)
procedure a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);override;
procedure a_op64_const_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64);override;
procedure a_op64_const_reg(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);override;
//procedure a_op64_reg_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);override;
//procedure a_op64_reg_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);override;
//procedure a_op64_const_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);override;
//procedure a_op64_reg_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);override;
//procedure a_loadmm_intreg64_reg(list: TAsmList; mmsize: tcgsize; intreg: tregister64; mmreg: tregister);override;
//procedure a_loadmm_reg_intreg64(list: TAsmList; mmsize: tcgsize; mmreg: tregister; intreg: tregister64);override;
end;
procedure create_codegen;
{
const
@ -130,10 +144,158 @@ implementation
paramgr,fmodule,
symtable,symsym,
tgobj,
procinfo,cpupi,
cg64f32;
procinfo,cpupi;
{$ifdef dummy}
procedure tcgcpu.init_register_allocators;
begin
inherited init_register_allocators;
rg[R_INTREGISTER]:=trgintcpu.create(R_INTREGISTER,R_SUBWHOLE,
[RS_A2,RS_A3,RS_A4,RS_A5,RS_A6,RS_A7,RS_A8,RS_A9,
RS_A10,RS_A11,RS_A12,RS_A13,RS_A14,RS_A15],first_int_imreg,[]);
rg[R_FPUREGISTER]:=trgcpu.create(R_FPUREGISTER,R_SUBNONE,
[RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7,RS_F8,RS_F9,
RS_F10,RS_F11,RS_F12,RS_F13,RS_F14,RS_F15],first_fpu_imreg,[]);
end;
procedure tcgcpu.done_register_allocators;
begin
rg[R_INTREGISTER].free;
rg[R_FPUREGISTER].free;
inherited done_register_allocators;
end;
procedure tcgcpu.a_load_reg_reg(list : TAsmList; fromsize,tosize : tcgsize;
reg1,reg2 : tregister);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcgcpu.a_load_reg_ref(list : TAsmList; fromsize,tosize : tcgsize;
reg : tregister; const ref : TReference);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcgcpu.a_load_ref_reg(list : TAsmList; fromsize,tosize : tcgsize;
const ref : TReference; reg : tregister);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcgcpu.a_load_const_reg(list : TAsmList; size : tcgsize;
a : tcgint; reg : tregister);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcgcpu.a_loadaddr_ref_reg(list : TAsmList;
const ref : TReference; r : tregister);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcgcpu.a_op_reg_reg(list : TAsmList; op : topcg; size : tcgsize;
src,dst : tregister);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcgcpu.a_op_const_reg(list : TAsmList; op : topcg;
size : tcgsize; a : tcgint; reg : tregister);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcgcpu.a_op_reg_reg_reg(list : TAsmList; op : topcg;
size : tcgsize; src1,src2,dst : tregister);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcgcpu.a_call_name(list : TAsmList; const s : string;
weak : boolean);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcgcpu.a_call_reg(list : TAsmList; Reg : tregister);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcgcpu.a_jmp_name(list : TAsmList; const s : string);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcgcpu.g_proc_entry(list : TAsmList; localsize : longint;
nostackframe : boolean);
begin
list.Concat(taicpu.op_reg_const(A_ENTRY,NR_STACK_POINTER_REG,32));
end;
procedure tcgcpu.g_proc_exit(list : TAsmList; parasize : longint;
nostackframe : boolean);
begin
list.Concat(taicpu.op_none(A_RETW));
end;
procedure tcgcpu.a_cmp_reg_reg_label(list : TAsmList; size : tcgsize;
cmp_op : topcmp; reg1,reg2 : tregister; l : tasmlabel);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcgcpu.a_jmp_always(list : TAsmList; l : TAsmLabel);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcgcpu.g_concatcopy(list : TAsmList; const source,
dest : treference; len : tcgint);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcg64fxtensa.a_op64_reg_reg(list : TAsmList; op : TOpCG;
size : tcgsize; regsrc,regdst : tregister64);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcg64fxtensa.a_op64_const_reg_reg(list : TAsmList; op : TOpCG;
size : tcgsize; value : int64; regsrc,regdst : tregister64);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
procedure tcg64fxtensa.a_op64_const_reg(list : TAsmList; op : TOpCG;
size : tcgsize; value : int64; reg : tregister64);
begin
list.Concat(taicpu.op_none(A_NOP));
end;
{$ifdef dummy}
procedure tcgaarch64.make_simple_ref(list:TAsmList; var op: tasmop; size: tcgsize; oppostfix: toppostfix; var ref: treference; preferred_newbasereg: tregister);
var
href: treference;
@ -2317,10 +2479,11 @@ implementation
end;
{$endif dummy}
{$warnings off}
procedure create_codegen;
begin
//!!! cg:=tcgcpu.Create;
//!!! cg64:=tcg64.Create;
cg:=tcgcpu.Create;
cg64:=tcg64fxtensa.Create;
end;
end.

View File

@ -30,12 +30,12 @@ the behaviour of such a unit having just a USES clause! }
implementation
uses
ncgbas,ncgflw,ncgcal,ncgcnv,ncgld,ncgmem,ncgcon,ncgset,ncgobjc,
ncgadd,ncginl,ncgmat,ncgbas,ncgflw,ncgcal,ncgcnv,ncgld,ncgmem,ncgcon,ncgset,ncgobjc,
{ symtable }
symcpu,
aasmdef
{$ifndef llvm}
//,ncpuadd,ncpumat,ncpumem,ncpuinl,ncpucnv,ncpuset,ncpucon
,ncpuadd,ncpumat,ncpucnv//,ncpumem,ncpuset,ncpucon
{$else llvm}
llvmnode
{$endif llvm}

261
compiler/xtensa/ncpuadd.pas Normal file
View File

@ -0,0 +1,261 @@
{
Copyright (c) 2008 by Florian Klaempfl
Code generation for add nodes on the Xtensa
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
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit ncpuadd;
{$i fpcdefs.inc}
interface
uses
node,ncgadd,cpubase;
type
TCPUAddNode = class(tcgaddnode)
protected
function pass_1 : tnode;override;
procedure second_cmpordinal;override;
procedure second_cmpsmallset;override;
procedure second_cmp64bit;override;
procedure second_cmp;
end;
implementation
uses
globtype,systems,
cutils,verbose,globals,
symconst,symdef,paramgr,
aasmbase,aasmtai,aasmdata,aasmcpu,defutil,htypechk,
cgbase,cgutils,cgcpu,
cpuinfo,pass_1,pass_2,procinfo,
cpupara,
ncon,nset,nadd,
ncgutil,tgobj,rgobj,rgcpu,cgobj,cg64f32,
hlcgobj;
{*****************************************************************************
TAVRAddNode
*****************************************************************************}
procedure TCPUAddNode.second_cmpsmallset;
procedure gencmp(tmpreg1,tmpreg2 : tregister);
var
i : byte;
begin
//current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,tmpreg1,tmpreg2));
//for i:=2 to tcgsize2size[left.location.size] do
// begin
// tmpreg1:=cg.GetNextReg(tmpreg1);
// tmpreg2:=cg.GetNextReg(tmpreg2);
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
// end;
end;
var
tmpreg : tregister;
begin
//pass_left_right;
//location_reset(location,LOC_FLAGS,OS_NO);
//force_reg_left_right(false,false);
//
//case nodetype of
// equaln:
// begin
// gencmp(left.location.register,right.location.register);
// location.resflags:=F_EQ;
// end;
// unequaln:
// begin
// gencmp(left.location.register,right.location.register);
// location.resflags:=F_NE;
// end;
// lten,
// gten:
// begin
// if (not(nf_swapped in flags) and
// (nodetype = lten)) or
// ((nf_swapped in flags) and
// (nodetype = gten)) then
// swapleftright;
// tmpreg:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
// cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_AND,location.size,
// left.location.register,right.location.register,tmpreg);
// gencmp(tmpreg,right.location.register);
// location.resflags:=F_EQ;
// end;
// else
// internalerror(2004012401);
//end;
end;
procedure TCPUAddNode.second_cmp;
var
unsigned : boolean;
tmpreg1,tmpreg2 : tregister;
i : longint;
begin
pass_left_right;
force_reg_left_right(true,true);
//
//unsigned:=not(is_signed(left.resultdef)) or
// not(is_signed(right.resultdef));
//
//if getresflags(unsigned)=F_NotPossible then
// begin
// swapleftright;
// { if we have to swap back and left is a constant, force it to a register because we cannot generate
// the needed code using a constant }
// if (left.location.loc=LOC_CONSTANT) and (left.location.value<>0) then
// hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
// end;
//
//if (not unsigned) and
// (right.location.loc=LOC_CONSTANT) and
// (right.location.value=0) and
// (getresflags(unsigned) in [F_LT,F_GE]) then
// begin
// { This is a simple sign test, where we can just test the msb }
// tmpreg1:=left.location.register;
// for i:=2 to tcgsize2size[left.location.size] do
// begin
// if i=5 then
// tmpreg1:=left.location.registerhi
// else
// tmpreg1:=cg.GetNextReg(tmpreg1);
// end;
//
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,tmpreg1,GetDefaultZeroReg));
//
// location_reset(location,LOC_FLAGS,OS_NO);
// location.resflags:=getresflags(unsigned);
//
// exit;
// end;
//
//if right.location.loc=LOC_CONSTANT then
// begin
// { decrease register pressure on registers >= r16 }
// if (right.location.value and $ff)=0 then
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,left.location.register,GetDefaultZeroReg))
// else
// begin
// cg.getcpuregister(current_asmdata.CurrAsmList,NR_R26);
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LDI,NR_R26,right.location.value and $ff));
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,left.location.register,NR_R26));
// cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R26);
// end;
// end
//{ on the left side, we allow only a constant if it is 0 }
//else if (left.location.loc=LOC_CONSTANT) and (left.location.value=0) then
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,GetDefaultZeroReg,right.location.register))
//else
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,left.location.register,right.location.register));
//
//tmpreg1:=left.location.register;
//tmpreg2:=right.location.register;
//
//for i:=2 to tcgsize2size[left.location.size] do
// begin
// if i=5 then
// begin
// if left.location.loc<>LOC_CONSTANT then
// tmpreg1:=left.location.registerhi;
// if right.location.loc<>LOC_CONSTANT then
// tmpreg2:=right.location.registerhi;
// end
// else
// begin
// if left.location.loc<>LOC_CONSTANT then
// tmpreg1:=cg.GetNextReg(tmpreg1);
// if right.location.loc<>LOC_CONSTANT then
// tmpreg2:=cg.GetNextReg(tmpreg2);
// end;
// if right.location.loc=LOC_CONSTANT then
// begin
// { just use R1? }
// if ((right.location.value64 shr ((i-1)*8)) and $ff)=0 then
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,GetDefaultZeroReg))
// else
// begin
// tmpreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_8);
// cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_8,(right.location.value64 shr ((i-1)*8)) and $ff,tmpreg2);
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
// end;
// end
// { above it is checked, if left=0, then a constant is allowed }
// else if (left.location.loc=LOC_CONSTANT) and (left.location.value=0) then
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,GetDefaultZeroReg,tmpreg2))
// else
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
// end;
//
//location_reset(location,LOC_FLAGS,OS_NO);
//location.resflags:=getresflags(unsigned);
location.loc:=LOC_REGISTER;
current_asmdata.CurrAsmList.Concat(taicpu.op_none(A_NOP));
end;
procedure TCPUAddNode.second_cmp64bit;
begin
second_cmp;
location.loc:=LOC_REGISTER;
end;
function TCPUAddNode.pass_1 : tnode;
begin
result:=inherited pass_1;
{$ifdef dummy}
if not(assigned(result)) then
begin
unsigned:=not(is_signed(left.resultdef)) or
not(is_signed(right.resultdef));
if is_64bit(left.resultdef) and
((nodetype in [equaln,unequaln]) or
(unsigned and (nodetype in [ltn,lten,gtn,gten]))
) then
expectloc:=LOC_FLAGS;
end;
{ handling boolean expressions }
if not(assigned(result)) and
(
not(is_boolean(left.resultdef)) or
not(is_boolean(right.resultdef)) or
is_dynamic_array(left.resultdef)
) then
expectloc:=LOC_FLAGS;
{$endif dummy}
end;
procedure TCPUAddNode.second_cmpordinal;
begin
second_cmp;
end;
begin
caddnode:=tcpuaddnode;
end.

198
compiler/xtensa/ncpucnv.pas Normal file
View File

@ -0,0 +1,198 @@
{
Copyright (c) 1998-2002 by Florian Klaempfl
Generate Xtensa assembler for type converting nodes
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
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit ncpucnv;
{$i fpcdefs.inc}
interface
uses
node,ncnv,ncgcnv;
type
tcputypeconvnode = class(tcgtypeconvnode)
protected
// function first_int_to_real: tnode;override;
// function first_real_to_real: tnode; override;
{ procedure second_int_to_int;override; }
{ procedure second_string_to_string;override; }
{ procedure second_cstring_to_pchar;override; }
{ procedure second_string_to_chararray;override; }
{ procedure second_array_to_pointer;override; }
// function first_int_to_real: tnode; override;
{ procedure second_pointer_to_array;override; }
{ procedure second_chararray_to_string;override; }
{ procedure second_char_to_string;override; }
// procedure second_int_to_real;override;
// procedure second_real_to_real;override;
{ procedure second_cord_to_pointer;override; }
{ procedure second_proc_to_procvar;override; }
{ procedure second_bool_to_int;override; }
procedure second_int_to_bool;override;
{ procedure second_load_smallset;override; }
{ procedure second_ansistring_to_pchar;override; }
{ procedure second_pchar_to_string;override; }
{ procedure second_class_to_intf;override; }
{ procedure second_char_to_char;override; }
end;
implementation
uses
verbose,globtype,globals,symdef,aasmbase,aasmtai,aasmdata,symtable,
defutil,
cgbase,cgutils,
pass_1,pass_2,procinfo,ncal,
ncgutil,
cpubase,cpuinfo,aasmcpu,cgobj,hlcgobj,cgcpu;
{*****************************************************************************
FirstTypeConv
*****************************************************************************}
procedure tcputypeconvnode.second_int_to_bool;
var
hreg1,
hregister : tregister;
href : treference;
resflags : tresflags;
hlabel : tasmlabel;
newsize : tcgsize;
begin
// secondpass(left);
// if codegenerror then
// exit;
//
// { Explicit typecasts from any ordinal type to a boolean type }
// { must not change the ordinal value }
// if (nf_explicit in flags) and
// not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
// begin
// location_copy(location,left.location);
// newsize:=def_cgsize(resultdef);
// { change of size? change sign only if location is LOC_(C)REGISTER? Then we have to sign/zero-extend }
// if (tcgsize2size[newsize]<>tcgsize2size[left.location.size]) or
// ((newsize<>left.location.size) and (location.loc in [LOC_REGISTER,LOC_CREGISTER])) then
// hlcg.location_force_reg(current_asmdata.CurrAsmList,location,left.resultdef,resultdef,true)
// else
// location.size:=newsize;
// exit;
// end;
//
// { Load left node into flag F_NE/F_E }
// resflags:=F_NE;
//
// if (left.location.loc in [LOC_SUBSETREG,LOC_CSUBSETREG,LOC_SUBSETREF,LOC_CSUBSETREF]) then
// hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
//
// case left.location.loc of
// LOC_CREFERENCE,
// LOC_REFERENCE :
// begin
// if left.location.size in [OS_64,OS_S64] then
// begin
// hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
// cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.reference,hregister);
// href:=left.location.reference;
// inc(href.offset,4);
// tbasecgarm(cg).cgsetflags:=true;
// cg.a_op_ref_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,href,hregister);
// tbasecgarm(cg).cgsetflags:=false;
// end
// else
// begin
// hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
// tbasecgarm(cg).cgsetflags:=true;
// cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register);
// tbasecgarm(cg).cgsetflags:=false;
// end;
// end;
// LOC_FLAGS :
// begin
// resflags:=left.location.resflags;
// end;
// LOC_REGISTER,LOC_CREGISTER :
// begin
// if left.location.size in [OS_64,OS_S64] then
// begin
// hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
// cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.register64.reglo,hregister);
// tbasecgarm(cg).cgsetflags:=true;
// cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reghi,hregister);
// tbasecgarm(cg).cgsetflags:=false;
// end
// else
// begin
// tbasecgarm(cg).cgsetflags:=true;
// cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register);
// tbasecgarm(cg).cgsetflags:=false;
// end;
// end;
// LOC_JUMP :
// begin
// hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
// current_asmdata.getjumplabel(hlabel);
// cg.a_label(current_asmdata.CurrAsmList,left.location.truelabel);
// cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,1,hregister);
// cg.a_jmp_always(current_asmdata.CurrAsmList,hlabel);
// cg.a_label(current_asmdata.CurrAsmList,left.location.falselabel);
// cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,0,hregister);
// cg.a_label(current_asmdata.CurrAsmList,hlabel);
// tbasecgarm(cg).cgsetflags:=true;
// cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_INT,hregister,hregister);
// tbasecgarm(cg).cgsetflags:=false;
// end;
// else
// internalerror(200311301);
// end;
// { load flags to register }
// location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
// hreg1:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
// cg.g_flags2reg(current_asmdata.CurrAsmList,location.size,resflags,hreg1);
// cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
// if (is_cbool(resultdef)) then
// cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_NEG,location.size,hreg1,hreg1);
//
//{$ifndef cpu64bitalu}
// if (location.size in [OS_64,OS_S64]) then
// begin
// location.register64.reglo:=hreg1;
// location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
// if (is_cbool(resultdef)) then
// { reglo is either 0 or -1 -> reghi has to become the same }
// cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,location.register64.reglo,location.register64.reghi)
// else
// { unsigned }
// cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_32,0,location.register64.reghi);
// end
// else
//{$endif cpu64bitalu}
// location.register:=hreg1;
location.loc:=LOC_REGISTER;
current_asmdata.CurrAsmList.Concat(taicpu.op_none(A_NOP));
end;
begin
ctypeconvnode:=tcputypeconvnode;
end.

373
compiler/xtensa/ncpumat.pas Normal file
View File

@ -0,0 +1,373 @@
{
Copyright (c) 1998-2002 by Florian Klaempfl
Generate Xtensa assembler for math nodes
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
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit ncpumat;
{$i fpcdefs.inc}
interface
uses
node,nmat,ncgmat;
type
tcpumoddivnode = class(tmoddivnode)
procedure pass_generate_code;override;
end;
tcpunotnode = class(tcgnotnode)
procedure second_boolean;override;
end;
tcpuunaryminusnode = class(tcgunaryminusnode)
function pass_1: tnode; override;
procedure second_float;override;
end;
tcpushlshrnode = class(tcgshlshrnode)
procedure second_64bit;override;
end;
implementation
uses
globtype,compinnr,
cutils,verbose,globals,constexp,
aasmbase,aasmcpu,aasmtai,aasmdata,
defutil,
symtype,symconst,symtable,
cgbase,cgobj,hlcgobj,cgutils,
pass_2,procinfo,
ncon,ncnv,ncal,ninl,
cpubase,cpuinfo,
ncgutil,
nadd,pass_1,symdef;
{*****************************************************************************
TCPUMODDIVNODE
*****************************************************************************}
procedure tcpumoddivnode.pass_generate_code;
begin
location.loc:=LOC_REGISTER;
end;
{*****************************************************************************
TCPUNOTNODE
*****************************************************************************}
procedure tcpunotnode.second_boolean;
var
tmpreg : TRegister;
begin
location.loc:=LOC_REGISTER;
//{ if the location is LOC_JUMP, we do the secondpass after the
// labels are allocated
//}
//if not handle_locjump then
// begin
// secondpass(left);
// case left.location.loc of
// LOC_FLAGS :
// begin
// location_copy(location,left.location);
// inverse_flags(location.resflags);
// end;
// LOC_REGISTER,LOC_CREGISTER,LOC_REFERENCE,LOC_CREFERENCE,
// LOC_SUBSETREG,LOC_CSUBSETREG,LOC_SUBSETREF,LOC_CSUBSETREF :
// begin
// hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
// cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
// if is_64bit(resultdef) then
// begin
// tmpreg:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_INT);
// { OR low and high parts together }
// current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ORR,tmpreg,left.location.register64.reglo,left.location.register64.reghi),PF_S));
// end
// else
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CMP,left.location.register,0));
// location_reset(location,LOC_FLAGS,OS_NO);
// location.resflags:=F_EQ;
// end;
// else
// internalerror(2003042401);
// end;
// end;
end;
{*****************************************************************************
TARMUNARYMINUSNODE
*****************************************************************************}
function tcpuunaryminusnode.pass_1: tnode;
var
procname: string[31];
fdef : tdef;
begin
Result:=nil;
//if (current_settings.fputype=fpu_soft) and
// (left.resultdef.typ=floatdef) then
// begin
// result:=nil;
// firstpass(left);
// expectloc:=LOC_REGISTER;
// exit;
// end;
//
//if not(FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype]) or
// (tfloatdef(resultdef).floattype=s32real) then
// exit(inherited pass_1);
//
//result:=nil;
//firstpass(left);
//if codegenerror then
// exit;
//
//if (left.resultdef.typ=floatdef) then
// begin
// case tfloatdef(resultdef).floattype of
// s64real:
// begin
// procname:='float64_sub';
// fdef:=search_system_type('FLOAT64').typedef;
// end;
// else
// internalerror(2005082801);
// end;
// result:=ctypeconvnode.create_internal(ccallnode.createintern(procname,ccallparanode.create(
// ctypeconvnode.create_internal(left,fDef),
// ccallparanode.create(ctypeconvnode.create_internal(crealconstnode.create(0,resultdef),fdef),nil))),resultdef);
//
// left:=nil;
// end
//else
// begin
// if (left.resultdef.typ=floatdef) then
// expectloc:=LOC_FPUREGISTER
// else if (left.resultdef.typ=orddef) then
// expectloc:=LOC_REGISTER;
// end;
end;
procedure tcpuunaryminusnode.second_float;
begin
//secondpass(left);
//case current_settings.fputype of
// fpu_fpa,
// fpu_fpa10,
// fpu_fpa11:
// begin
// hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,false);
// location:=left.location;
// current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_const(A_RSF,
// location.register,left.location.register,0),
// cgsize2fpuoppostfix[def_cgsize(resultdef)]));
// end;
// fpu_soft:
// begin
// hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
// location:=left.location;
// case location.size of
// OS_32:
// cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.register);
// OS_64:
// cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.registerhi);
// else
// internalerror(2014033101);
// end;
// end
// else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[init_settings.fputype] then
// begin
// hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
// location:=left.location;
// if (left.location.loc=LOC_CMMREGISTER) then
// location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
//
// if (tfloatdef(left.resultdef).floattype=s32real) then
// pf:=PF_F32
// else
// pf:=PF_F64;
//
// current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VNEG,
// location.register,left.location.register), pf));
// cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
// end
// else if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[init_settings.fputype] then
// begin
// hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
// location:=left.location;
// if (left.location.loc=LOC_CMMREGISTER) then
// location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
// current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VNEG,
// location.register,left.location.register), PF_F32));
// cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
// end
// else
// internalerror(2009112602);
//end;
end;
procedure tcpushlshrnode.second_64bit;
var
v : TConstExprInt;
so: tshifterop;
lreg, resreg: TRegister64;
procedure emit_instr(p: tai);
begin
current_asmdata.CurrAsmList.concat(p);
end;
{This code is build like it gets called with sm=SM_LSR all the time, for SM_LSL dst* and src* have to be reversed
This will generate
mov shiftval1, shiftval
cmp shiftval1, #64
movcs shiftval1, #64
rsb shiftval2, shiftval1, #32
mov dstlo, srclo, lsr shiftval1
mov dsthi, srchi, lsr shiftval1
orr dstlo, srchi, lsl shiftval2
subs shiftval2, shiftval1, #32
movpl dstlo, srchi, lsr shiftval2
}
procedure shift_by_variable(srchi, srclo, dsthi, dstlo, shiftval: TRegister; sm: TShiftMode);
var
shiftval1,shiftval2:TRegister;
begin
//shifterop_reset(so);
//shiftval1:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
//shiftval2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
//
//cg.a_load_reg_reg(current_asmdata.CurrAsmList, OS_INT, OS_INT, shiftval, shiftval1);
//
//{The ARM barrel shifter only considers the lower 8 bits of a register for the shift}
//cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
//emit_instr(taicpu.op_reg_const(A_CMP, shiftval1, 64));
//emit_instr(setcondition(taicpu.op_reg_const(A_MOV, shiftval1, 64), C_CS));
//cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
//
//{Calculate how much the upper register needs to be shifted left}
//emit_instr(taicpu.op_reg_reg_const(A_RSB, shiftval2, shiftval1, 32));
//
//so.shiftmode:=sm;
//so.rs:=shiftval1;
//
//{Shift and zerofill the hi+lo register}
//emit_instr(taicpu.op_reg_reg_shifterop(A_MOV, dstlo, srclo, so));
//emit_instr(taicpu.op_reg_reg_shifterop(A_MOV, dsthi, srchi, so));
//
//{Fold in the lower 32-shiftval bits}
//if sm = SM_LSR then so.shiftmode:=SM_LSL else so.shiftmode:=SM_LSR;
//so.rs:=shiftval2;
//emit_instr(taicpu.op_reg_reg_reg_shifterop(A_ORR, dstlo, dstlo, srchi, so));
//
//cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
//emit_instr(setoppostfix(taicpu.op_reg_reg_const(A_SUB, shiftval2, shiftval1, 32), PF_S));
//
//so.shiftmode:=sm;
//emit_instr(setcondition(taicpu.op_reg_reg_shifterop(A_MOV, dstlo, srchi, so), C_PL));
//cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
end;
begin
//if GenerateThumbCode or GenerateThumb2Code then
//begin
// inherited;
// exit;
//end;
//
location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
//location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
//location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
//
//{ load left operator in a register }
//if not(left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) or
// (left.location.size<>OS_64) then
// hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,resultdef,true);
//
//lreg := left.location.register64;
//resreg := location.register64;
//shifterop_reset(so);
//
//{ shifting by a constant directly coded: }
//if (right.nodetype=ordconstn) then
// begin
// v:=Tordconstnode(right).value and 63;
// {Single bit shift}
// if v = 1 then
// if nodetype=shln then
// begin
// {Shift left by one by 2 simple 32bit additions}
// cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
// emit_instr(setoppostfix(taicpu.op_reg_reg_reg(A_ADD, resreg.reglo, lreg.reglo, lreg.reglo), PF_S));
// emit_instr(taicpu.op_reg_reg_reg(A_ADC, resreg.reghi, lreg.reghi, lreg.reghi));
// cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
// end
// else
// begin
// {Shift right by first shifting hi by one and then using RRX (rotate right extended), which rotates through the carry}
// shifterop_reset(so); so.shiftmode:=SM_LSR; so.shiftimm:=1;
// cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
// emit_instr(setoppostfix(taicpu.op_reg_reg_shifterop(A_MOV, resreg.reghi, lreg.reghi, so), PF_S));
// so.shiftmode:=SM_RRX; so.shiftimm:=0; {RRX does NOT have a shift amount}
// emit_instr(taicpu.op_reg_reg_shifterop(A_MOV, resreg.reglo, lreg.reglo, so));
// cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
// end
// {Clear one register and use the cg to generate a normal 32-bit shift}
// else if v >= 32 then
// if nodetype=shln then
// begin
// emit_instr(taicpu.op_reg_const(A_MOV, resreg.reglo, 0));
// cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHL,OS_32,v.uvalue-32,lreg.reglo,resreg.reghi);
// end
// else
// begin
// emit_instr(taicpu.op_reg_const(A_MOV, resreg.reghi, 0));
// cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHR,OS_32,v.uvalue-32,lreg.reghi,resreg.reglo);
// end
// {Shift LESS than 32, thats the tricky one}
// else if (v < 32) and (v > 1) then
// if nodetype=shln then
// shift_less_than_32(lreg.reglo, lreg.reghi, resreg.reglo, resreg.reghi, v.uvalue, SM_LSL)
// else
// shift_less_than_32(lreg.reghi, lreg.reglo, resreg.reghi, resreg.reglo, v.uvalue, SM_LSR);
// end
//else
// begin
// { force right operator into a register }
// if not(right.location.loc in [LOC_CREGISTER,LOC_REGISTER]) or
// (right.location.size<>OS_32) then
// hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,u32inttype,true);
//
// if nodetype = shln then
// shift_by_variable(lreg.reglo, lreg.reghi, resreg.reglo, resreg.reghi, right.location.register, SM_LSL)
// else
// shift_by_variable(lreg.reghi, lreg.reglo, resreg.reghi, resreg.reglo, right.location.register, SM_LSR);
// end;
end;
begin
cmoddivnode:=tcpumoddivnode;
cnotnode:=tcpunotnode;
cunaryminusnode:=tcpuunaryminusnode;
cshlshrnode:=tcpushlshrnode;
end.

View File

@ -1024,12 +1024,20 @@ Unit racpugas;
const
asmmode_xtensa_att_info : tasmmodeinfo =
(
id : asmmode_arm_gas;
id : asmmode_xtensa_gas;
idtxt : 'DIVIDED';
casmreader : txtensaattreader;
);
asmmode_xtensa_standard_info : tasmmodeinfo =
(
id : asmmode_standard;
idtxt : 'STANDARD';
casmreader : txtensaattreader;
);
initialization
RegisterAsmMode(asmmode_xtensa_att_info);
RegisterAsmMode(asmmode_xtensa_standard_info);
end.

View File

@ -10,12 +10,16 @@
'callx4',
'callx8',
'callx12',
'entry',
'l32i',
'lsi',
'j',
'mov',
'mov.s',
'movi',
'nop',
'ret',
'retw',
's32i',
'ssi'
);

View File

@ -10,12 +10,16 @@ A_CALLX0,
A_CALLX4,
A_CALLX8,
A_CALLX12,
A_ENTRY,
A_L32I,
A_LSI,
A_J,
A_MOV,
A_MOV_S,
A_MOVI,
A_NOP,
A_RET,
A_RETW,
A_S32I,
A_SSI
);