Sfoglia il codice sorgente

* Xtensa: completed compiler skeleton

git-svn-id: trunk@44323 -
florian 5 anni fa
parent
commit
73c68236b6

+ 3 - 0
.gitattributes

@@ -1024,6 +1024,9 @@ compiler/xtensa/cpupi.pas svneol=native#text/pascal
 compiler/xtensa/cputarg.pas svneol=native#text/pascal
 compiler/xtensa/cputarg.pas svneol=native#text/pascal
 compiler/xtensa/hlcgcpu.pas svneol=native#text/pascal
 compiler/xtensa/hlcgcpu.pas svneol=native#text/pascal
 compiler/xtensa/itcpugas.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/racpugas.pas svneol=native#text/pascal
 compiler/xtensa/raxtensa.pas svneol=native#text/pascal
 compiler/xtensa/raxtensa.pas svneol=native#text/pascal
 compiler/xtensa/rgcpu.pas svneol=native#text/pascal
 compiler/xtensa/rgcpu.pas svneol=native#text/pascal

+ 1 - 1
compiler/fpcdefs.inc

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

+ 9 - 0
compiler/options.pas

@@ -3751,6 +3751,7 @@ procedure read_arguments(cmd:TCmdStr);
         def_system_macro('FPC_COMP_IS_INT64');
         def_system_macro('FPC_COMP_IS_INT64');
         def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
         def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
       {$endif riscv32}
       {$endif riscv32}
+
       {$ifdef riscv64}
       {$ifdef riscv64}
         def_system_macro('CPURISCV');
         def_system_macro('CPURISCV');
         def_system_macro('CPURISCV64');
         def_system_macro('CPURISCV64');
@@ -3760,6 +3761,14 @@ procedure read_arguments(cmd:TCmdStr);
         def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
         def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
       {$endif riscv64}
       {$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)}
       {$if defined(cpu8bitalu)}
         def_system_macro('CPUINT8');
         def_system_macro('CPUINT8');
       {$elseif defined(cpu16bitalu)}
       {$elseif defined(cpu16bitalu)}

+ 4 - 0
compiler/psystem.pas

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

+ 1 - 0
compiler/systems.inc

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

+ 5 - 0
compiler/systems.pas

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

+ 3 - 2
compiler/xtensa/agcpugas.pas

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

+ 195 - 32
compiler/xtensa/cgcpu.pas

@@ -31,10 +31,38 @@ interface
        aasmbase,aasmtai,aasmdata,aasmcpu,
        aasmbase,aasmtai,aasmdata,aasmcpu,
        cpubase,cpuinfo,
        cpubase,cpuinfo,
        node,symconst,SymType,symdef,
        node,symconst,SymType,symdef,
-       rgcpu;
+       rgcpu,
+       cg64f32;
 
 
     type
     type
       tcgcpu=class(tcg)
       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}
 {$ifdef dummy}
        protected
        protected
         { changes register size without adding register allocation info }
         { 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);
         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;
         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 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  getmmregister(list:TAsmList;size:tcgsize):tregister;override;
         function handle_load_store(list:TAsmList; op: tasmop; size: tcgsize; oppostfix: toppostfix; reg: tregister; ref: treference):treference;
         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 }
         { General purpose instructions }
         procedure maybeadjustresult(list: TAsmList; op: topcg; size: tcgsize; dst: tregister);
         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_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_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;
         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 }
         { 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_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_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_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) }
         { 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_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_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_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;
         procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tcgsize; src, dst: TRegister); override;
         { comparison operations }
         { 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_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_cond(list: TAsmList; cond: TOpCmp; l: tasmlabel);{ override;}
         procedure a_jmp_flags(list: TAsmList; const f: tresflags; 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_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(list: TAsmList; const loc: tlocation; def: tdef);override;
         procedure g_overflowcheck_loc(list: TAsmList; const loc: tlocation; def: tdef; ovloc: tlocation);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_maybe_got_init(list: TAsmList); override;
         procedure g_restore_registers(list: TAsmList);override;
         procedure g_restore_registers(list: TAsmList);override;
         procedure g_save_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_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_adjust_self_value(list: TAsmList; procdef: tprocdef; ioffset: tcgint);override;
         procedure g_check_for_fpu_exception(list: TAsmList; force, clear: boolean);override;
         procedure g_check_for_fpu_exception(list: TAsmList; force, clear: boolean);override;
         procedure g_profilecode(list: TAsmList);override;
         procedure g_profilecode(list: TAsmList);override;
@@ -109,6 +111,18 @@ interface
 {$endif dummy}
 {$endif dummy}
       end;
       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;
     procedure create_codegen;
 {
 {
     const
     const
@@ -130,10 +144,158 @@ implementation
     paramgr,fmodule,
     paramgr,fmodule,
     symtable,symsym,
     symtable,symsym,
     tgobj,
     tgobj,
-    procinfo,cpupi,
-    cg64f32;
+    procinfo,cpupi;
+
+    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;
+
 
 
- {$ifdef dummy}
+    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);
     procedure tcgaarch64.make_simple_ref(list:TAsmList; var op: tasmop; size: tcgsize; oppostfix: toppostfix; var ref: treference; preferred_newbasereg: tregister);
       var
       var
         href: treference;
         href: treference;
@@ -2317,10 +2479,11 @@ implementation
       end;
       end;
 {$endif dummy}
 {$endif dummy}
 
 
+{$warnings off}
     procedure create_codegen;
     procedure create_codegen;
       begin
       begin
-//!!!        cg:=tcgcpu.Create;
-//!!!        cg64:=tcg64.Create;
+        cg:=tcgcpu.Create;
+        cg64:=tcg64fxtensa.Create;
       end;
       end;
 
 
 end.
 end.

+ 2 - 2
compiler/xtensa/cpunode.pas

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

+ 261 - 0
compiler/xtensa/ncpuadd.pas

@@ -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 - 0
compiler/xtensa/ncpucnv.pas

@@ -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 - 0
compiler/xtensa/ncpumat.pas

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

+ 9 - 1
compiler/xtensa/racpugas.pas

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

+ 4 - 0
compiler/xtensa/xtensaatt.inc

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

+ 4 - 0
compiler/xtensa/xtensaop.inc

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