View Issue Details

IDProjectCategoryView StatusLast Update
0037099FPCCompilerpublic2020-06-21 18:57
ReporterChristo Crause Assigned ToFlorian  
PrioritynormalSeverityminorReproducibilityN/A
Status closedResolutionfixed 
Product Version3.3.1 
Fixed in Version3.3.1 
Summary0037099: Xtensa [patch] Add RSR and WSR instructions to compiler
DescriptionAttached a patch that includes instructions to read/write from/to special registers. Some functionality for ESP-IDF require access to e.g. retrieve the core ID on which a task is executing.

Note that only the so called "old" form of the instructions are added for now, which is RSR at, 0..255.
TagsNo tags attached.
Fixed in Revision45671
FPCOldBugId
FPCTarget-
Attached Files

Activities

Christo Crause

2020-05-17 22:06

reporter  

xtensa-instr.patch (697 bytes)   
Index: compiler/xtensa/xtensaatt.inc
===================================================================
--- compiler/xtensa/xtensaatt.inc	(revision 45312)
+++ compiler/xtensa/xtensaatt.inc	(working copy)
@@ -46,6 +46,7 @@
 'or',
 'ret',
 'retw',
+'rsr',
 's8i',
 's16i',
 's32i',
@@ -62,6 +63,7 @@
 'sub',
 'sub.s',
 'syscall',
+'wsr',
 'xor'
 );
 
Index: compiler/xtensa/xtensaop.inc
===================================================================
--- compiler/xtensa/xtensaop.inc	(revision 45312)
+++ compiler/xtensa/xtensaop.inc	(working copy)
@@ -46,6 +46,7 @@
 A_OR,
 A_RET,
 A_RETW,
+A_RSR,
 A_S8I,
 A_S16I,
 A_S32I,
@@ -62,6 +63,7 @@
 A_SUB,
 A_SUB_S,
 A_SYSCALL,
+A_WSR,
 A_XOR
 );
 
xtensa-instr.patch (697 bytes)   

Christo Crause

2020-05-19 21:56

reporter   ~0122943

I added the postfix versions of the special registers instructions RSR, WSR and XSR since I don't like remembering register numbers. Added postfix parsing of assembler to handle new assembler instructions:
raatt.pas - increased op2strtable string size for longer instruction lengths
xtensa/cpubase.pas - increased min scan length for valid instruction

This second patch replaces the first patch.
xtensa-inst2.patch (9,031 bytes)   
Index: raatt.pas
===================================================================
--- raatt.pas	(revision 45312)
+++ raatt.pas	(working copy)
@@ -346,6 +346,23 @@
                end;
            end;
 {$endif riscv}
+{$ifdef xtensa}
+           {
+             Xtensa can have multiple postfixes
+             MULA.DD.LL.LDDEC
+             or postfixes with numbers
+             RSR.CCOMPARE2
+           }
+           case c of
+             '.':
+               begin
+                 repeat
+                   actasmpattern:=actasmpattern+c;
+                   c:=current_scanner.asmgetchar;
+                 until not(c in ['a'..'z','A'..'Z', '0'..'9', '.']);
+               end;
+           end;
+{$endif xtensa}
            { Opcode ? }
            If is_asmopcode(upper(actasmpattern)) then
             Begin
Index: xtensa/cpubase.pas
===================================================================
--- xtensa/cpubase.pas	(revision 45312)
+++ xtensa/cpubase.pas	(working copy)
@@ -46,7 +46,7 @@
       TAsmOp= {$i xtensaop.inc}
 
       { This should define the array of instructions as string }
-      op2strtable=array[tasmop] of string[11];
+      op2strtable=array[tasmop] of string[16];
 
     const
       { First value of opcode enumeration }
Index: xtensa/racpugas.pas
===================================================================
--- xtensa/racpugas.pas	(revision 45312)
+++ xtensa/racpugas.pas	(working copy)
@@ -856,7 +856,7 @@
                   end;
               end;
           end;
-        maxlen:=min(length(hs),7);
+        maxlen:=min(length(hs),16);
         actopcode:=A_NONE;
         j2:=maxlen;
         hs2:=hs;
Index: xtensa/xtensaatt.inc
===================================================================
--- xtensa/xtensaatt.inc	(revision 45312)
+++ xtensa/xtensaatt.inc	(working copy)
@@ -46,6 +46,82 @@
 'or',
 'ret',
 'retw',
+'rsr',
+'rsr.acchi',
+'rsr.acclo',
+'rsr.atomctl',
+'rsr.br',
+'rsr.ccompare0',
+'rsr.ccompare1',
+'rsr.ccompare2',
+'rsr.ccount',
+'rsr.cpenable',
+'rsr.dbreaka0',
+'rsr.dbreaka1',
+'rsr.dbreakc0',
+'rsr.dbreakc1',
+'rsr.ddr',
+'rsr.debugcause',
+'rsr.depc',
+'rsr.dtlbcfg',
+'rsr.epc1',
+'rsr.epc2',
+'rsr.epc3',
+'rsr.epc4',
+'rsr.epc5',
+'rsr.epc6',
+'rsr.epc7',
+'rsr.eps2',
+'rsr.eps3',
+'rsr.eps4',
+'rsr.eps5',
+'rsr.eps6',
+'rsr.eps7',
+'rsr.exccause',
+'rsr.excsave1',
+'rsr.excsave2',
+'rsr.excsave3',
+'rsr.excsave4',
+'rsr.excsave5',
+'rsr.excsave6',
+'rsr.excsave7',
+'rsr.excvaddr',
+'rsr.ibreaka0',
+'rsr.ibreaka1',
+'rsr.ibreakenable',
+'rsr.icount',
+'rsr.icountlevel',
+'rsr.intclear',
+'rsr.intenable',
+'rsr.interrupt',
+'rsr.itlbcfg',
+'rsr.lbeg',
+'rsr.lcount',
+'rsr.lend',
+'rsr.litbase',
+'rsr.m0',
+'rsr.m1',
+'rsr.m2',
+'rsr.m3',
+'rsr.mecr',
+'rsr.mepc',
+'rsr.meps',
+'rsr.mesave',
+'rsr.mesr',
+'rsr.mevaddr',
+'rsr.misc0',
+'rsr.misc1',
+'rsr.misc2',
+'rsr.misc3',
+'rsr.prid',
+'rsr.ps',
+'rsr.ptevaddr',
+'rsr.rasid',
+'rsr.sar',
+'rsr.scompare1',
+'rsr.vecbase',
+'rsr.windowbase',
+'rsr.windowstart',
 's8i',
 's16i',
 's32i',
@@ -62,7 +138,156 @@
 'sub',
 'sub.s',
 'syscall',
-'xor'
+'wsr',
+'wsr.acchi',
+'wsr.acclo',
+'wsr.atomctl',
+'wsr.br',
+'wsr.ccompare0',
+'wsr.ccompare1',
+'wsr.ccompare2',
+'wsr.ccount',
+'wsr.cpenable',
+'wsr.dbreaka0',
+'wsr.dbreaka1',
+'wsr.dbreakc0',
+'wsr.dbreakc1',
+'wsr.ddr',
+'wsr.debugcause',
+'wsr.depc',
+'wsr.dtlbcfg',
+'wsr.epc1',
+'wsr.epc2',
+'wsr.epc3',
+'wsr.epc4',
+'wsr.epc5',
+'wsr.epc6',
+'wsr.epc7',
+'wsr.eps2',
+'wsr.eps3',
+'wsr.eps4',
+'wsr.eps5',
+'wsr.eps6',
+'wsr.eps7',
+'wsr.exccause',
+'wsr.excsave1',
+'wsr.excsave2',
+'wsr.excsave3',
+'wsr.excsave4',
+'wsr.excsave5',
+'wsr.excsave6',
+'wsr.excsave7',
+'wsr.excvaddr',
+'wsr.ibreaka0',
+'wsr.ibreaka1',
+'wsr.ibreakenable',
+'wsr.icount',
+'wsr.icountlevel',
+'wsr.intclear',
+'wsr.intenable',
+'wsr.intset',
+'wsr.itlbcfg',
+'wsr.lbeg',
+'wsr.lcount',
+'wsr.lend',
+'wsr.litbase',
+'wsr.m0',
+'wsr.m1',
+'wsr.m2',
+'wsr.m3',
+'wsr.mecr',
+'wsr.mepc',
+'wsr.meps',
+'wsr.mesave',
+'wsr.mesr',
+'wsr.mevaddr',
+'wsr.misc0',
+'wsr.misc1',
+'wsr.misc2',
+'wsr.misc3',
+'wsr.mmid',
+'wsr.ps',
+'wsr.ptevaddr',
+'wsr.rasid',
+'wsr.sar',
+'wsr.scompare1',
+'wsr.vecbase',
+'wsr.windowbase',
+'wsr.windowstart',
+'xor',
+'xsr',
+'xsr.acchi',
+'xsr.acclo',
+'xsr.atomctl',
+'xsr.br',
+'xsr.ccompare0',
+'xsr.ccompare1',
+'xsr.ccompare2',
+'xsr.ccount',
+'xsr.cpenable',
+'xsr.dbreaka0',
+'xsr.dbreaka1',
+'xsr.dbreakc0',
+'xsr.dbreakc1',
+'xsr.ddr',
+'xsr.debugcause',
+'xsr.depc',
+'xsr.dtlbcfg',
+'xsr.epc1',
+'xsr.epc2',
+'xsr.epc3',
+'xsr.epc4',
+'xsr.epc5',
+'xsr.epc6',
+'xsr.epc7',
+'xsr.eps2',
+'xsr.eps3',
+'xsr.eps4',
+'xsr.eps5',
+'xsr.eps6',
+'xsr.eps7',
+'xsr.exccause',
+'xsr.excsave1',
+'xsr.excsave2',
+'xsr.excsave3',
+'xsr.excsave4',
+'xsr.excsave5',
+'xsr.excsave6',
+'xsr.excsave7',
+'xsr.excvaddr',
+'xsr.ibreaka0',
+'xsr.ibreaka1',
+'xsr.ibreakenable',
+'xsr.icount',
+'xsr.icountlevel',
+'xsr.intenable',
+'xsr.itlbcfg',
+'xsr.lbeg',
+'xsr.lcount',
+'xsr.lend',
+'xsr.litbase',
+'xsr.m0',
+'xsr.m1',
+'xsr.m2',
+'xsr.m3',
+'xsr.mecr',
+'xsr.mepc',
+'xsr.meps',
+'xsr.mesave',
+'xsr.mesr',
+'xsr.mevaddr',
+'xsr.misc0',
+'xsr.misc1',
+'xsr.misc2',
+'xsr.misc3',
+'xsr.ps',
+'xsr.ptevaddr',
+'xsr.rasid',
+'xsr.sar',
+'xsr.scompare1',
+'xsr.vecbase',
+'xsr.windowbase',
+'xsr.windowstart'
 );
 
 
Index: xtensa/xtensaop.inc
===================================================================
--- xtensa/xtensaop.inc	(revision 45312)
+++ xtensa/xtensaop.inc	(working copy)
@@ -46,6 +46,82 @@
 A_OR,
 A_RET,
 A_RETW,
+A_RSR,
+A_RSR_ACCHI,
+A_RSR_ACCLO,
+A_RSR_ATOMCTL,
+A_RSR_BR,
+A_RSR_CCOMPARE0,
+A_RSR_CCOMPARE1,
+A_RSR_CCOMPARE2,
+A_RSR_CCOUNT,
+A_RSR_CPENABLE,
+A_RSR_DBREAKA0,
+A_RSR_DBREAKA1,
+A_RSR_DBREAKC0,
+A_RSR_DBREAKC1,
+A_RSR_DDR,
+A_RSR_DEBUGCAUSE,
+A_RSR_DEPC,
+A_RSR_DTLBCFG,
+A_RSR_EPC1,
+A_RSR_EPC2,
+A_RSR_EPC3,
+A_RSR_EPC4,
+A_RSR_EPC5,
+A_RSR_EPC6,
+A_RSR_EPC7,
+A_RSR_EPS2,
+A_RSR_EPS3,
+A_RSR_EPS4,
+A_RSR_EPS5,
+A_RSR_EPS6,
+A_RSR_EPS7,
+A_RSR_EXCCAUSE,
+A_RSR_EXCSAVE1,
+A_RSR_EXCSAVE2,
+A_RSR_EXCSAVE3,
+A_RSR_EXCSAVE4,
+A_RSR_EXCSAVE5,
+A_RSR_EXCSAVE6,
+A_RSR_EXCSAVE7,
+A_RSR_EXCVADDR,
+A_RSR_IBREAKA0,
+A_RSR_IBREAKA1,
+A_RSR_IBREAKENABLE,
+A_RSR_ICOUNT,
+A_RSR_ICOUNTLEVEL,
+A_RSR_INTCLEAR,
+A_RSR_INTENABLE,
+A_RSR_INTERRUPT,
+A_RSR_ITLBCFG,
+A_RSR_LBEG,
+A_RSR_LCOUNT,
+A_RSR_LEND,
+A_RSR_LITBASE,
+A_RSR_M0,
+A_RSR_M1,
+A_RSR_M2,
+A_RSR_M3,
+A_RSR_MECR,
+A_RSR_MEPC,
+A_RSR_MEPS,
+A_RSR_MESAVE,
+A_RSR_MESR,
+A_RSR_MEVADDR,
+A_RSR_MISC0,
+A_RSR_MISC1,
+A_RSR_MISC2,
+A_RSR_MISC3,
+A_RSR_PRID,
+A_RSR_PS,
+A_RSR_PTEVADDR,
+A_RSR_RASID,
+A_RSR_SAR,
+A_RSR_SCOMPARE1,
+A_RSR_VECBASE,
+A_RSR_WINDOWBASE,
+A_RSR_WINDOWSTART,
 A_S8I,
 A_S16I,
 A_S32I,
@@ -62,7 +138,156 @@
 A_SUB,
 A_SUB_S,
 A_SYSCALL,
-A_XOR
+A_WSR,
+A_WSR_ACCHI,
+A_WSR_ACCLO,
+A_WSR_ATOMCTL,
+A_WSR_BR,
+A_WSR_CCOMPARE0,
+A_WSR_CCOMPARE1,
+A_WSR_CCOMPARE2,
+A_WSR_CCOUNT,
+A_WSR_CPENABLE,
+A_WSR_DBREAKA0,
+A_WSR_DBREAKA1,
+A_WSR_DBREAKC0,
+A_WSR_DBREAKC1,
+A_WSR_DDR,
+A_WSR_DEBUGCAUSE,
+A_WSR_DEPC,
+A_WSR_DTLBCFG,
+A_WSR_EPC1,
+A_WSR_EPC2,
+A_WSR_EPC3,
+A_WSR_EPC4,
+A_WSR_EPC5,
+A_WSR_EPC6,
+A_WSR_EPC7,
+A_WSR_EPS2,
+A_WSR_EPS3,
+A_WSR_EPS4,
+A_WSR_EPS5,
+A_WSR_EPS6,
+A_WSR_EPS7,
+A_WSR_EXCCAUSE,
+A_WSR_EXCSAVE1,
+A_WSR_EXCSAVE2,
+A_WSR_EXCSAVE3,
+A_WSR_EXCSAVE4,
+A_WSR_EXCSAVE5,
+A_WSR_EXCSAVE6,
+A_WSR_EXCSAVE7,
+A_WSR_EXCVADDR,
+A_WSR_IBREAKA0,
+A_WSR_IBREAKA1,
+A_WSR_IBREAKENABLE,
+A_WSR_ICOUNT,
+A_WSR_ICOUNTLEVEL,
+A_WSR_INTCLEAR,
+A_WSR_INTENABLE,
+A_WSR_INTSET,
+A_WSR_ITLBCFG,
+A_WSR_LBEG,
+A_WSR_LCOUNT,
+A_WSR_LEND,
+A_WSR_LITBASE,
+A_WSR_M0,
+A_WSR_M1,
+A_WSR_M2,
+A_WSR_M3,
+A_WSR_MECR,
+A_WSR_MEPC,
+A_WSR_MEPS,
+A_WSR_MESAVE,
+A_WSR_MESR,
+A_WSR_MEVADDR,
+A_WSR_MISC0,
+A_WSR_MISC1,
+A_WSR_MISC2,
+A_WSR_MISC3,
+A_WSR_MMID,
+A_WSR_PS,
+A_WSR_PTEVADDR,
+A_WSR_RASID,
+A_WSR_SAR,
+A_WSR_SCOMPARE1,
+A_WSR_VECBASE,
+A_WSR_WINDOWBASE,
+A_WSR_WINDOWSTART,
+A_XOR,
+A_XSR,
+A_XSR_ACCHI,
+A_XSR_ACCLO,
+A_XSR_ATOMCTL,
+A_XSR_BR,
+A_XSR_CCOMPARE0,
+A_XSR_CCOMPARE1,
+A_XSR_CCOMPARE2,
+A_XSR_CCOUNT,
+A_XSR_CPENABLE,
+A_XSR_DBREAKA0,
+A_XSR_DBREAKA1,
+A_XSR_DBREAKC0,
+A_XSR_DBREAKC1,
+A_XSR_DDR,
+A_XSR_DEBUGCAUSE,
+A_XSR_DEPC,
+A_XSR_DTLBCFG,
+A_XSR_EPC1,
+A_XSR_EPC2,
+A_XSR_EPC3,
+A_XSR_EPC4,
+A_XSR_EPC5,
+A_XSR_EPC6,
+A_XSR_EPC7,
+A_XSR_EPS2,
+A_XSR_EPS3,
+A_XSR_EPS4,
+A_XSR_EPS5,
+A_XSR_EPS6,
+A_XSR_EPS7,
+A_XSR_EXCCAUSE,
+A_XSR_EXCSAVE1,
+A_XSR_EXCSAVE2,
+A_XSR_EXCSAVE3,
+A_XSR_EXCSAVE4,
+A_XSR_EXCSAVE5,
+A_XSR_EXCSAVE6,
+A_XSR_EXCSAVE7,
+A_XSR_EXCVADDR,
+A_XSR_IBREAKA0,
+A_XSR_IBREAKA1,
+A_XSR_IBREAKENABLE,
+A_XSR_ICOUNT,
+A_XSR_ICOUNTLEVEL,
+A_XSR_INTENABLE,
+A_XSR_ITLBCFG,
+A_XSR_LBEG,
+A_XSR_LCOUNT,
+A_XSR_LEND,
+A_XSR_LITBASE,
+A_XSR_M0,
+A_XSR_M1,
+A_XSR_M2,
+A_XSR_M3,
+A_XSR_MECR,
+A_XSR_MEPC,
+A_XSR_MEPS,
+A_XSR_MESAVE,
+A_XSR_MESR,
+A_XSR_MEVADDR,
+A_XSR_MISC0,
+A_XSR_MISC1,
+A_XSR_MISC2,
+A_XSR_MISC3,
+A_XSR_PS,
+A_XSR_PTEVADDR,
+A_XSR_RASID,
+A_XSR_SAR,
+A_XSR_SCOMPARE1,
+A_XSR_VECBASE,
+A_XSR_WINDOWBASE,
+A_XSR_WINDOWSTART
 );
 
 
xtensa-inst2.patch (9,031 bytes)   

Florian

2020-05-21 19:59

administrator   ~0122992

Wouldn't it be usefull in this case to make those postfixes postfixes in the sense of the assembler writer?

Christo Crause

2020-05-21 21:35

reporter   ~0122994

Will have a look, you are probably referring to the way its is implemented for ARM? Will see if I can also include the underscore prefix while I'm busy with this...

Christo Crause

2020-05-22 21:58

reporter   ~0123006

Last edited: 2020-05-22 22:03

View 3 revisions

Attached please find an updated patch to add all the assembler instructions, branch conditions, prefix and postfixes according to the Xtensa ISA from 2010. A list of of changes:
Added postfix parsing in tattreader.GetToken
Removed all postfixed versions of OpCodes from the instruction list
Added all missing OpCodes from Xtensa ISA
Changed branch OpCode to A_B, similar to ARM
Added missing branch condition flags BCI and BSI
Updated existing compiler code that referred to the old postfixed instructions
Added prefix and postfix handling in TxtensaInstrWriter.WriteInstruction
Updated TCPUAddNode.second_addfloat to specify .S postfix
Updated tcpuunaryminusnode.second_float to specify .S postfix
Implemented prefix and postfix identification in txtensaattreader.is_asmopcode
Adapted branch condition extraction to respect postfixes
Changed itcpugas to call findreg_by_name_table from raatt.pas (same as issue 0037121, difficult to test these changes without including a fix for the register name search problem)

Also attached a test case with some assembler code to test the assembler parser.
xtensa-assembler.patch (34,833 bytes)   
Index: raatt.pas
===================================================================
--- raatt.pas	(revision 45312)
+++ raatt.pas	(working copy)
@@ -346,6 +346,23 @@
                end;
            end;
 {$endif riscv}
+{$ifdef xtensa}
+           {
+             Xtensa can have multiple postfixes
+             MULA.DD.LL.LDDEC
+             or postfixes with numbers
+             RSR.CCOMPARE2
+           }
+           case c of
+             '.':
+               begin
+                 repeat
+                   actasmpattern:=actasmpattern+c;
+                   c:=current_scanner.asmgetchar;
+                 until not(c in ['a'..'z','A'..'Z', '0'..'9', '.']);
+               end;
+           end;
+{$endif xtensa}
            { Opcode ? }
            If is_asmopcode(upper(actasmpattern)) then
             Begin
Index: xtensa/aasmcpu.pas
===================================================================
--- xtensa/aasmcpu.pas	(revision 45312)
+++ xtensa/aasmcpu.pas	(working copy)
@@ -39,6 +39,8 @@
 
     type
       taicpu = class(tai_cpu_abstract_sym)
+        oppostfix : TOpPostfix;
+        opIsPrefixed : boolean;
         constructor op_none(op : tasmop);
 
         constructor op_reg(op : tasmop;_op1 : tregister);
@@ -420,11 +422,11 @@
         case regtype of
           R_INTREGISTER:
             result:=
-               (opcode=A_MOV) and
+               (opcode=A_MOV) and (oppostfix in [PF_None, PF_N]) and
                (oper[0]^.reg=oper[1]^.reg);
           R_FPUREGISTER:
             result:=
-               (opcode=A_MOV_S) and
+               (opcode=A_MOV) and (oppostfix=PF_S) and
                (oper[0]^.reg=oper[1]^.reg);
          else
            result:=false;
@@ -443,7 +445,7 @@
           A_S16I,
           A_S32I,
           A_SSI,
-          A_Bcc:
+          A_B:
             result := operand_read;
           else
             ;
Index: xtensa/agcpugas.pas
===================================================================
--- xtensa/agcpugas.pas	(revision 45312)
+++ xtensa/agcpugas.pas	(working copy)
@@ -140,15 +140,19 @@
 
     Procedure TXtensaInstrWriter.WriteInstruction(hp : tai);
     var op: TAsmOp;
-        postfix,s: string;
+        s: string;
         i: byte;
         sep: string[3];
     begin
       op:=taicpu(hp).opcode;
-      postfix:='';
-      s:=#9+gas_op2str[op];
+      if taicpu(hp).opIsPrefixed then
+        s:=#9'_'+gas_op2str[op]
+      else
+        s:=#9+gas_op2str[op];
       if taicpu(hp).condition<>C_None then
         s:=s+cond2str[taicpu(hp).condition];
+      if taicpu(hp).oppostfix <> PF_None then
+        s:=s+'.'+oppostfix2str[taicpu(hp).oppostfix];
       if taicpu(hp).ops<>0 then
         begin
           if length(s)<5 then
Index: xtensa/aoptcpub.pas
===================================================================
--- xtensa/aoptcpub.pas	(revision 45312)
+++ xtensa/aoptcpub.pas	(working copy)
@@ -97,7 +97,7 @@
   StoreDst = 1;
 
   aopt_uncondjmp = A_J;
-  aopt_condjmp = A_Bcc;
+  aopt_condjmp = A_B;
 
 Implementation
 
Index: xtensa/cgcpu.pas
===================================================================
--- xtensa/cgcpu.pas	(revision 45312)
+++ xtensa/cgcpu.pas	(working copy)
@@ -597,7 +597,8 @@
         tmpreg: TRegister;
       begin
         { for now, we use A15 here, however, this is not save as it might contain an argument }
-        ai:=TAiCpu.op_sym_reg(A_J_L,current_asmdata.RefAsmSymbol(s,AT_FUNCTION),NR_A15);
+        ai:=TAiCpu.op_sym_reg(A_J,current_asmdata.RefAsmSymbol(s,AT_FUNCTION),NR_A15);
+        ai.oppostfix := PF_L; // if destination is too far for J then assembler can convert to JX
         ai.is_jmp:=true;
         list.Concat(ai);
       end;
@@ -607,7 +608,7 @@
       var
         instr: taicpu;
       begin
-        instr:=taicpu.op_reg_sym(A_Bcc,f.register,l);
+        instr:=taicpu.op_reg_sym(A_B,f.register,l);
         instr.condition:=flags_to_cond(f.flag);
         list.concat(instr);
       end;
@@ -787,7 +788,7 @@
             else
               Internalerror(2020030801);
             end;     
-            instr:=taicpu.op_reg_sym(A_Bcc,reg,l);
+            instr:=taicpu.op_reg_sym(A_B,reg,l);
             instr.condition:=op;
             list.concat(instr);
           end
@@ -803,7 +804,7 @@
               Internalerror(2020030801);
             end;
 
-            instr:=taicpu.op_reg_const_sym(A_Bcc,reg,a,l);
+            instr:=taicpu.op_reg_const_sym(A_B,reg,a,l);
             instr.condition:=op;
             list.concat(instr);
           end
@@ -817,7 +818,7 @@
               Internalerror(2020030801);
             end;
 
-            instr:=taicpu.op_reg_const_sym(A_Bcc,reg,a,l);
+            instr:=taicpu.op_reg_const_sym(A_B,reg,a,l);
             instr.condition:=op;
             list.concat(instr);
           end
@@ -840,7 +841,7 @@
             reg2:=tmpreg;
           end;
 
-        instr:=taicpu.op_reg_reg_sym(A_Bcc,reg2,reg1,l);
+        instr:=taicpu.op_reg_reg_sym(A_B,reg2,reg1,l);
         instr.condition:=TOpCmp2AsmCond[cmp_op];
         list.concat(instr);
       end;
@@ -851,9 +852,12 @@
         ai : taicpu;
       begin
         if l.bind in [AB_GLOBAL] then
+          begin
           { for now, we use A15 here, however, this is not save as it might contain an argument, I have not figured out a
             solution yet }
-          ai:=taicpu.op_sym_reg(A_J_L,l,NR_A15)
+            ai:=taicpu.op_sym_reg(A_J,l,NR_A15);
+            ai.oppostfix := PF_L;
+          end
         else
           ai:=taicpu.op_sym(A_J,l);
         ai.is_jmp:=true;
@@ -1020,10 +1024,15 @@
 
 
      procedure tcgcpu.a_loadfpu_reg_reg(list: TAsmList; fromsize,tosize: tcgsize; reg1, reg2: tregister);
+       var
+         ai: taicpu;
        begin
          if not(fromsize in [OS_32,OS_F32]) then
            InternalError(2020032603);
-         list.concat(taicpu.op_reg_reg(A_MOV_S,reg2,reg1));
+
+         ai := taicpu.op_reg_reg(A_MOV,reg2,reg1);
+         ai.oppostfix := PF_S;
+         list.concat(ai);
        end;
 
 
@@ -1111,7 +1120,7 @@
                   list.concat(taicpu.op_reg_reg_reg(A_ADD, regdst.reghi, regsrc2.reghi, regsrc1.reghi));
 
                   current_asmdata.getjumplabel(no_carry);
-                  instr:=taicpu.op_reg_reg_sym(A_Bcc,tmplo, regsrc2.reglo, no_carry);
+                  instr:=taicpu.op_reg_reg_sym(A_B,tmplo, regsrc2.reglo, no_carry);
                   instr.condition:=C_GEU;
                   list.concat(instr);
                   list.concat(taicpu.op_reg_reg_const(A_ADDI, regdst.reghi, regdst.reghi, 1));
@@ -1157,7 +1166,7 @@
                   list.concat(taicpu.op_reg_reg_reg(A_SUB, regdst.reghi, regsrc2.reghi, regsrc1.reghi));
 
                   current_asmdata.getjumplabel(no_carry);
-                  instr:=taicpu.op_reg_reg_sym(A_Bcc, regsrc2.reglo, tmplo, no_carry);
+                  instr:=taicpu.op_reg_reg_sym(A_B, regsrc2.reglo, tmplo, no_carry);
                   instr.condition:=C_GEU;
                   list.concat(instr);
                   list.concat(taicpu.op_reg_reg_const(A_ADDI, regdst.reghi, regdst.reghi, -1));
@@ -1261,7 +1270,7 @@
                       list.concat(taicpu.op_reg_reg_const(A_ADDI, regdst.reghi, regsrc.reghi, 0));
 
                       current_asmdata.getjumplabel(no_carry);
-                      instr:=taicpu.op_reg_reg_sym(A_Bcc,tmplo, regsrc.reglo, no_carry);
+                      instr:=taicpu.op_reg_reg_sym(A_B,tmplo, regsrc.reglo, no_carry);
                       instr.condition:=C_GEU;
                       list.concat(instr);
                       list.concat(taicpu.op_reg_reg_const(A_ADDI, regdst.reghi, regdst.reghi, 1));
Index: xtensa/cpubase.pas
===================================================================
--- xtensa/cpubase.pas	(revision 45312)
+++ xtensa/cpubase.pas	(working copy)
@@ -46,7 +46,7 @@
       TAsmOp= {$i xtensaop.inc}
 
       { This should define the array of instructions as string }
-      op2strtable=array[tasmop] of string[11];
+      op2strtable=array[tasmop] of string[7];
 
     const
       { First value of opcode enumeration }
@@ -87,9 +87,6 @@
       { firs flag imaginary register }
       first_flag_imreg     = $10;
 
-      { TODO: Calculate bsstart}
-      regnumber_count_bsstart = 16;
-
       regnumber_table : array[tregisterindex] of tregister = (
         {$i rxtensanum.inc}
       );
@@ -102,6 +99,70 @@
         {$i rxtensadwa.inc}
       );
 
+      {*****************************************************************************
+                                Instruction post fixes
+      *****************************************************************************}
+          type
+            { Xtensa instructions can have several instruction post fixes }
+            TOpPostfix = (PF_None,
+              { On big-endian processors, convert encoded immediate value to little-endian.
+                For J.L, assembler tries to convert into J if target is within reach, else convert to JX }
+              PF_L,
+              { Assembler to generate narrow version of instruction if possible }
+              PF_N,
+              { Opcode operates on single precision floating point register(s)}
+              PF_S,
+              { Indicate MUL operations involving MAC16 accumulator option }
+              PF_AA_LL, PF_AA_HL, PF_AA_LH, PF_AA_HH, PF_AD_LL, PF_AD_HL,
+              PF_AD_LH, PF_AD_HH, PF_DA_LL, PF_DA_HL, PF_DA_LH, PF_DA_HH,
+              PF_DD_LL, PF_DD_HL, PF_DD_LH, PF_DD_HH,
+              PF_DA_LL_LDDEC, PF_DA_HL_LDDEC, PF_DA_LH_LDDEC, PF_DA_HH_LDDEC,
+              PF_DA_LL_LDINC, PF_DA_HL_LDINC, PF_DA_LH_LDINC, PF_DA_HH_LDINC,
+              PF_DD_LL_LDDEC, PF_DD_HL_LDDEC, PF_DD_LH_LDDEC, PF_DD_HH_LDDEC,
+              PF_DD_LL_LDINC, PF_DD_HL_LDINC, PF_DD_LH_LDINC, PF_DD_HH_LDINC,
+              { Special registers accessible via RSR, WSR & XSR instructions }
+              PF_ACCHI, PF_ACCLO, PF_ATOMCTL, PF_BR, PF_CCOMPARE0, PF_CCOMPARE1,
+              PF_CCOMPARE2, PF_CCOUNT, PF_CPENABLE, PF_DBREAKA0, PF_DBREAKA1,
+              PF_DBREAKC0, PF_DBREAKC1, PF_DDR, PF_DEBUGCAUSE, PF_DEPC,
+              PF_DTLBCFG, PF_EPC1, PF_EPC2, PF_EPC3, PF_EPC4, PF_EPC5, PF_EPC6,
+              PF_EPC7, PF_EPS2, PF_EPS3, PF_EPS4, PF_EPS5, PF_EPS6, PF_EPS7,
+              PF_EXCCAUSE, PF_EXCSAVE1, PF_EXCSAVE2, PF_EXCSAVE3, PF_EXCSAVE4,
+              PF_EXCSAVE5, PF_EXCSAVE6, PF_EXCSAVE7, PF_EXCVADDR, PF_IBREAKA0,
+              PF_IBREAKA1, PF_IBREAKENABLE, PF_ICOUNT, PF_ICOUNTLEVEL,
+              PF_INTCLEAR, PF_INTENABLE, PF_INTERRUPT, PF_INTSET, PF_ITLBCFG,
+              PF_LBEG, PF_LCOUNT, PF_LEND, PF_LITBASE, PF_M0, PF_M1, PF_M2,
+              PF_M3, PF_MECR, PF_MEPC, PF_MEPS, PF_MESAVE, PF_MESR, PF_MEVADDR,
+              PF_MISC0, PF_MISC1, PF_MISC2, PF_MISC3, PF_MMID, PF_PRID, PF_PS,
+              PF_PTEVADDR, PF_RASID, PF_SAR, PF_SCOMPARE1, PF_VECBASE,
+              PF_WINDOWBASE, PF_WINDOWSTART);
+
+            TOpPostfixes = set of TOpPostfix;
+
+          const
+            oppostfix2str : array[TOpPostfix] of string[12] = ('',
+              'l', 'n', 's',
+              'aa.ll', 'aa.hl', 'aa.lh', 'aa.hh', 'ad.ll', 'ad.hl',
+              'ad.lh', 'ad.hh', 'da.ll', 'da.hl', 'da.lh', 'da.hh',
+              'dd.ll', 'dd.hl', 'dd.lh', 'dd.hh', 'da.ll.lddec',
+              'da.hl.lddec', 'da.lh.lddec', 'da.hh.lddec', 'da.ll.ldinc',
+              'da.hl.ldinc', 'da.lh.ldinc', 'da.hh.ldinc', 'dd.ll.lddec',
+              'dd.hl.lddec', 'dd.lh.lddec', 'dd.hh.lddec', 'dd.ll.ldinc',
+              'dd.hl.ldinc', 'dd.lh.ldinc', 'dd.hh.ldinc',
+              'acchi', 'acclo', 'atomctl', 'br', 'ccompare0', 'ccompare1',
+              'ccompare2', 'ccount', 'cpenable', 'dbreaka0', 'dbreaka1',
+              'dbreakc0', 'dbreakc1', 'ddr', 'debugcause', 'depc',
+              'dtlbcfg', 'epc1', 'epc2', 'epc3', 'epc4', 'epc5', 'epc6',
+              'epc7', 'eps2', 'eps3', 'eps4', 'eps5', 'eps6', 'eps7',
+              'exccause', 'excsave1', 'excsave2', 'excsave3', 'excsave4',
+              'excsave5', 'excsave6', 'excsave7', 'excvaddr', 'ibreaka0',
+              'ibreaka1', 'ibreakenable', 'icount', 'icountlevel',
+              'intclear', 'intenable', 'interrupt', 'intset', 'itlbcfg',
+              'lbeg', 'lcount', 'lend', 'litbase', 'm0', 'm1', 'm2',
+              'm3', 'mecr', 'mepc', 'meps', 'mesave', 'mesr', 'mevaddr',
+              'misc0', 'misc1', 'misc2', 'misc3', 'mmid', 'prid', 'ps',
+              'ptevaddr', 'rasid', 'sar', 'scompare1', 'vecbase',
+              'windowbase', 'windowstart');
+
 {*****************************************************************************
                                 Conditions
 *****************************************************************************}
@@ -110,7 +171,7 @@
       TAsmCond=(C_None,
         C_EQ,C_NE,
         C_GE,C_LT,C_GEU,C_LTU,
-        C_ANY,C_BNONE,C_ALL,C_NALL,C_BC,C_BS,
+        C_ANY,C_BNONE,C_ALL,C_NALL,C_BC,C_BS,C_BCI,C_BSI,
         C_EQZ,C_NEZ,C_LTZ,C_GEZ,
         C_EQI,C_NEI,C_LTI,C_GEI,C_LTUI,C_GEUI,
         C_F,C_T
@@ -129,7 +190,7 @@
       cond2str : array[TAsmCond] of string[4]=('',
         'eq','ne',                         
         'ge','lt','geu','ltu',
-        'any','none','all','nall','bc','bs',
+        'any','none','all','nall','bc','bs','bci','bsi',
         'eqz','nez','ltz','gez',
         'eqi','nei','lti','gei','ltui','geui',
         'f','t'
@@ -138,7 +199,7 @@
       uppercond2str : array[TAsmCond] of string[4]=('',
         'EQ','NE',
         'GE','LT','GEU','LTU',
-        'ANY','NONE','ALL','NALL','BC','BS',
+        'ANY','NONE','ALL','NALL','BC','BS', 'BCI','BSI',
         'EQZ','NEZ','LTZ','GEZ',
         'EQI','NEI','LTI','GEI','LTUI','GEUI',
         'F','T'
@@ -329,7 +390,7 @@
       begin
         { This isn't 100% perfect because the arm allows jumps also by writing to PC=R15.
           To overcome this problem we simply forbid that FPC generates jumps by loading R15 }
-        is_calljmp:= o in [A_Bcc,A_BT,A_CALL0,A_CALL4,A_CALL8,A_CALL12,A_CALLX0,A_CALLX4,A_CALLX8,A_CALLX12];
+        is_calljmp:= o in [A_B,A_CALL0,A_CALL4,A_CALL8,A_CALL12,A_CALLX0,A_CALLX4,A_CALLX8,A_CALLX12];
       end;
 
 
@@ -362,7 +423,7 @@
         inverse: array[TAsmCond] of TAsmCond=(C_None,
           C_NE,C_EQ,
           C_LT,C_GE,C_LTU,C_GEU,
-          C_BNONE,C_ANY,C_NALL,C_BNONE,C_BS,C_BC,
+          C_BNONE,C_ANY,C_NALL,C_BNONE,C_BS,C_BC,C_BSI,C_BCI,
 
           C_NEZ,C_EQZ,C_GEZ,C_LTZ,
           C_NEI,C_EQI,C_GEI,C_LTI,C_GEUI,C_LTUI,
Index: xtensa/itcpugas.pas
===================================================================
--- xtensa/itcpugas.pas	(revision 45312)
+++ xtensa/itcpugas.pas	(working copy)
@@ -54,28 +54,9 @@
         {$i rxtensasri.inc}
       );
 
-    function findreg_by_gasname(const s:string):tregisterindex;
-      var
-        i,p : tregisterindex;
-      begin
-        {Binary search.}
-        p:=0;
-        i:=regnumber_count_bsstart;
-        repeat
-          if (p+i<=high(tregisterindex)) and (gas_regname_table[gas_regname_index[p+i]]<=s) then
-            p:=p+i;
-          i:=i shr 1;
-        until i=0;
-        if gas_regname_table[gas_regname_index[p]]=s then
-          findreg_by_gasname:=gas_regname_index[p]
-        else
-          findreg_by_gasname:=0;
-      end;
-
-
     function gas_regnum_search(const s:string):Tregister;
       begin
-        result:=regnumber_table[findreg_by_gasname(s)];
+        result:=regnumber_table[findreg_by_name_table(s, gas_regname_table, gas_regname_index)];
       end;
 
 
Index: xtensa/ncpuadd.pas
===================================================================
--- xtensa/ncpuadd.pas	(revision 45312)
+++ xtensa/ncpuadd.pas	(working copy)
@@ -222,6 +222,7 @@
         op    : TAsmOp;
         cmpop,
         singleprec , inv: boolean;
+        ai : taicpu;
       begin
         pass_left_and_right;
         if (nf_swapped in flags) then
@@ -234,36 +235,36 @@
         inv:=false;
         case nodetype of
           addn :
-            op:=A_ADD_S;
+            op:=A_ADD;
           muln :
-            op:=A_MUL_S;
+            op:=A_MUL;
           subn :
-            op:=A_SUB_S;
+            op:=A_SUB;
           unequaln,
           equaln:
             begin
-              op:=A_OEQ_S;
+              op:=A_OEQ;
               cmpop:=true;
             end;
           ltn:
             begin
-              op:=A_OLT_S;
+              op:=A_OLT;
               cmpop:=true;
             end;
           lten:
             begin
-              op:=A_OLE_S;
+              op:=A_OLE;
               cmpop:=true;
             end;
           gtn:
             begin
-              op:=A_OLT_S;
+              op:=A_OLT;
               swapleftright;
               cmpop:=true;
             end;
           gten:
             begin
-              op:=A_OLE_S;
+              op:=A_OLE;
               swapleftright;
               cmpop:=true;
             end;
@@ -288,7 +289,9 @@
         if cmpop then
           begin
             cg.getcpuregister(current_asmdata.CurrAsmList,location.resflags.register);
-            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.resflags.register,left.location.register,right.location.register));
+            ai:=taicpu.op_reg_reg_reg(op,location.resflags.register,left.location.register,right.location.register);
+            ai.oppostfix:=PF_S;
+            current_asmdata.CurrAsmList.concat(ai);
             cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
 
             if inv then
@@ -296,7 +299,9 @@
           end
         else
           begin
-            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register));
+            ai:=taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register);
+            ai.oppostfix := PF_S;
+            current_asmdata.CurrAsmList.concat(ai);
             cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
           end;
       end;
Index: xtensa/ncpumat.pas
===================================================================
--- xtensa/ncpumat.pas	(revision 45312)
+++ xtensa/ncpumat.pas	(working copy)
@@ -119,6 +119,8 @@
       end;
 
     procedure tcpuunaryminusnode.second_float;
+      var
+        ai : taicpu;
       begin
         secondpass(left);
         if (current_settings.fputype=fpu_soft) or (tfloatdef(left.resultdef).floattype<>s32real) or
@@ -150,7 +152,9 @@
               hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,false);
             location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
             location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
-            current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_NEG_S,location.register,left.location.register));
+            ai:=taicpu.op_reg_reg(A_NEG,location.register,left.location.register);
+            ai.oppostfix := PF_S;
+            current_asmdata.CurrAsmList.Concat(ai);
           end;
       end;
 
Index: xtensa/racpugas.pas
===================================================================
--- xtensa/racpugas.pas	(revision 45312)
+++ xtensa/racpugas.pas	(working copy)
@@ -32,6 +32,9 @@
     type
 
       txtensaattreader = class(tattreader)
+        actoppostfix : TOpPostfix;
+        actIsPrefixed: boolean;
+
        function is_asmopcode(const s: string):boolean;override;
         function is_register(const s:string):boolean;override;
 //        function is_targetdirective(const s: string): boolean; override;
@@ -763,6 +766,8 @@
           begin
             Opcode:=ActOpcode;
             condition:=ActCondition;
+            oppostfix:=actoppostfix;
+            opIsPrefixed:=actIsPrefixed;
           end;
 
         { We are reading operands, so opcode will be an AS_ID }
@@ -800,33 +805,58 @@
 
     function txtensaattreader.is_asmopcode(const s: string):boolean;
 
-      //const
-      //  { sorted by length so longer postfixes will match first }
-      //  postfix2strsorted : array[1..70] of string[9] = (
-      //    '.F32.S32','.F32.U32','.S32.F32','.U32.F32','.F64.S32','.F64.U32','.S32.F64','.U32.F64',
-      //    '.F32.S16','.F32.U16','.S16.F32','.U16.F32','.F64.S16','.F64.U16','.S16.F64','.U16.F64',
-      //    '.F32.F64','.F64.F32',
-      //    '.I16','.I32','.I64','.S16','.S32','.S64','.U16','.U32','.U64','.F32','.F64',
-      //    'IAD','DBD','FDD','EAD','IAS','DBS','FDS','EAS','IAX','DBX','FDX','EAX',
-      //    '.16','.32','.64','.I8','.S8','.U8','.P8',
-      //    'EP','SB','BT','SH','IA','IB','DA','DB','FD','FA','ED','EA',
-      //    '.8','S','D','E','P','X','R','B','H','T');
-      //
-      //  postfixsorted : array[1..70] of TOpPostfix = (
-      //    PF_F32S32,PF_F32U32,PF_S32F32,PF_U32F32,PF_F64S32,PF_F64U32,PF_S32F64,PF_U32F64,
-      //    PF_F32S16,PF_F32U16,PF_S16F32,PF_U16F32,PF_F64S16,PF_F64U16,PF_S16F64,PF_U16F64,
-      //    PF_F32F64,PF_F64F32,
-      //    PF_I16,PF_I32,
-      //    PF_I64,PF_S16,PF_S32,PF_S64,PF_U16,PF_U32,PF_U64,PF_F32,
-      //    PF_F64,PF_IAD,PF_DBD,PF_FDD,PF_EAD,
-      //    PF_IAS,PF_DBS,PF_FDS,PF_EAS,PF_IAX,
-      //    PF_DBX,PF_FDX,PF_EAX,PF_16,PF_32,
-      //    PF_64,PF_I8,PF_S8,PF_U8,PF_P8,
-      //    PF_EP,PF_SB,PF_BT,PF_SH,PF_IA,
-      //    PF_IB,PF_DA,PF_DB,PF_FD,PF_FA,
-      //    PF_ED,PF_EA,PF_8,PF_S,PF_D,PF_E,
-      //    PF_P,PF_X,PF_R,PF_B,PF_H,PF_T);
+      const
+        { sorted by length so longer postfixes will match first }
+        postfix2strsorted : array[1..112] of string[13] = (
+          'IBREAKENABLE', 'DA.HH.LDDEC', 'DA.HH.LDINC', 'DA.HL.LDDEC', 'DA.HL.LDINC',
+          'DA.LH.LDDEC', 'DA.LH.LDINC', 'DA.LL.LDDEC', 'DA.LL.LDINC', 'DD.HH.LDDEC',
+          'DD.HH.LDINC', 'DD.HL.LDDEC', 'DD.HL.LDINC', 'DD.LH.LDDEC', 'DD.LH.LDINC',
+          'DD.LL.LDDEC', 'DD.LL.LDINC', 'ICOUNTLEVEL', 'WINDOWSTART', 'DEBUGCAUSE',
+          'WINDOWBASE', 'CCOMPARE0', 'CCOMPARE1', 'CCOMPARE2', 'INTENABLE',
+          'INTERRUPT', 'SCOMPARE1', 'CPENABLE', 'DBREAKA0', 'DBREAKA1',
+          'DBREAKC0', 'DBREAKC1', 'EXCCAUSE', 'EXCSAVE1', 'EXCSAVE2',
+          'EXCSAVE3', 'EXCSAVE4', 'EXCSAVE5', 'EXCSAVE6', 'EXCSAVE7',
+          'EXCVADDR', 'IBREAKA0', 'IBREAKA1', 'INTCLEAR', 'PTEVADDR',
+          'ATOMCTL', 'DTLBCFG', 'ITLBCFG', 'LITBASE', 'MEVADDR',
+          'VECBASE', 'CCOUNT', 'ICOUNT', 'INTSET', 'LCOUNT',
+          'MESAVE', 'AA.HH', 'AA.HL', 'AA.LH', 'AA.LL',
+          'ACCHI', 'ACCLO', 'AD.HH', 'AD.HL', 'AD.LH',
+          'AD.LL', 'DA.HH', 'DA.HL', 'DA.LH', 'DA.LL',
+          'DD.HH', 'DD.HL', 'DD.LH', 'DD.LL', 'MISC0',
+          'MISC1', 'MISC2', 'MISC3', 'RASID', 'DEPC',
+          'EPC1', 'EPC2', 'EPC3', 'EPC4', 'EPC5',
+          'EPC6', 'EPC7', 'EPS2', 'EPS3', 'EPS4',
+          'EPS5', 'EPS6', 'EPS7', 'LBEG', 'LEND',
+          'MECR', 'MEPC', 'MEPS', 'MESR', 'MMID',
+          'PRID', 'DDR', 'SAR', 'BR', 'M0',
+          'M1', 'M2', 'M3', 'PS', 'L',
+          'N', 'S');
 
+        postfixsorted : array[1..112] of TOpPostfix = (
+          PF_IBREAKENABLE, PF_DA_HH_LDDEC, PF_DA_HH_LDINC, PF_DA_HL_LDDEC, PF_DA_HL_LDINC,
+          PF_DA_LH_LDDEC, PF_DA_LH_LDINC, PF_DA_LL_LDDEC, PF_DA_LL_LDINC, PF_DD_HH_LDDEC,
+          PF_DD_HH_LDINC, PF_DD_HL_LDDEC, PF_DD_HL_LDINC, PF_DD_LH_LDDEC, PF_DD_LH_LDINC,
+          PF_DD_LL_LDDEC, PF_DD_LL_LDINC, PF_ICOUNTLEVEL, PF_WINDOWSTART, PF_DEBUGCAUSE,
+          PF_WINDOWBASE, PF_CCOMPARE0, PF_CCOMPARE1, PF_CCOMPARE2, PF_INTENABLE,
+          PF_INTERRUPT, PF_SCOMPARE1, PF_CPENABLE, PF_DBREAKA0, PF_DBREAKA1,
+          PF_DBREAKC0, PF_DBREAKC1, PF_EXCCAUSE, PF_EXCSAVE1, PF_EXCSAVE2,
+          PF_EXCSAVE3, PF_EXCSAVE4, PF_EXCSAVE5, PF_EXCSAVE6, PF_EXCSAVE7,
+          PF_EXCVADDR, PF_IBREAKA0, PF_IBREAKA1, PF_INTCLEAR, PF_PTEVADDR,
+          PF_ATOMCTL, PF_DTLBCFG, PF_ITLBCFG, PF_LITBASE, PF_MEVADDR,
+          PF_VECBASE, PF_CCOUNT, PF_ICOUNT, PF_INTSET, PF_LCOUNT,
+          PF_MESAVE, PF_AA_HH, PF_AA_HL, PF_AA_LH, PF_AA_LL,
+          PF_ACCHI, PF_ACCLO, PF_AD_HH, PF_AD_HL, PF_AD_LH,
+          PF_AD_LL, PF_DA_HH, PF_DA_HL, PF_DA_LH, PF_DA_LL,
+          PF_DD_HH, PF_DD_HL, PF_DD_LH, PF_DD_LL, PF_MISC0,
+          PF_MISC1, PF_MISC2, PF_MISC3, PF_RASID, PF_DEPC,
+          PF_EPC1, PF_EPC2, PF_EPC3, PF_EPC4, PF_EPC5,
+          PF_EPC6, PF_EPC7, PF_EPS2, PF_EPS3, PF_EPS4,
+          PF_EPS5, PF_EPS6, PF_EPS7, PF_LBEG, PF_LEND,
+          PF_MECR, PF_MEPC, PF_MEPS, PF_MESR, PF_MMID,
+          PF_PRID, PF_DDR, PF_SAR, PF_BR, PF_M0,
+          PF_M1, PF_M2, PF_M3, PF_PS, PF_L,
+          PF_N, PF_S);
+
       var
         j, j2 : longint;
         hs,hs2 : string;
@@ -836,94 +866,81 @@
         { making s a value parameter would break other assembler readers }
         hs:=s;
         is_asmopcode:=false;
-
         { clear op code }
-        actopcode:=A_None;
-
+        actopcode:=A_NONE;
         actcondition:=C_None;
-
-        if hs[1]='B' then
+        actoppostfix := PF_None;
+        actIsPrefixed := false;
+        if hs[1]='_' then
           begin
+            actIsPrefixed := true;
+            delete(hs, 1, 1);
+          end;
+        if (hs[1]='B') and not(hs='BREAK') then
+          begin
+            { Branch condition can be followed by a postfix, e.g. BEQZ.N or BBSI.L }
+            j:=pos('.', hs);
+            if j < 2 then
+              j:=length(hs)
+            else
+              dec(j);
+            hs2:=copy(hs, 2, j-1);
             for icond:=low(tasmcond) to high(tasmcond) do
               begin
-                if copy(hs,2,length(hs)-1)=uppercond2str[icond] then
+                if hs2=uppercond2str[icond] then
                   begin
-                    actopcode:=A_Bcc;
+                    actopcode:=A_B;
                     actasmtoken:=AS_OPCODE;
                     actcondition:=icond;
                     is_asmopcode:=true;
-                    exit;
+                    delete(hs, 1, j);
+                    break;
                   end;
               end;
-          end;
-        maxlen:=min(length(hs),7);
-        actopcode:=A_NONE;
-        j2:=maxlen;
-        hs2:=hs;
-        while j2>=1 do
+          end
+        else
           begin
-            hs:=hs2;
-            while j2>=1 do
+            j2:=min(length(hs),7);
+            hs2:=hs;
+            while (j2>=1) and (actopcode=A_NONE) do
               begin
-                actopcode:=tasmop(PtrUInt(iasmops.Find(copy(hs,1,j2))));
-                if actopcode<>A_NONE then
+                hs:=hs2;
+                while j2>=1 do
                   begin
-                    actasmtoken:=AS_OPCODE;
-                    { strip op code }
-                    delete(hs,1,j2);
+                    actopcode:=tasmop(PtrUInt(iasmops.Find(copy(hs,1,j2))));
+                    if actopcode<>A_NONE then
+                      begin
+                        actasmtoken:=AS_OPCODE;
+                        { strip op code }
+                        delete(hs,1,j2);
+                        dec(j2);
+                        break;
+                      end;
                     dec(j2);
-                    break;
                   end;
-                dec(j2);
               end;
+            end;
 
-            if actopcode=A_NONE then
-              exit;
+        if actopcode=A_NONE then
+          exit;
 
+        { check for postfix }
+        if (length(hs)>0) then
+          begin
+            for j:=low(postfixsorted) to high(postfixsorted) do
               begin
-                { search for condition, conditions are always 2 chars }
-                if length(hs)>1 then
+                if copy(hs,2,length(postfix2strsorted[j]))=postfix2strsorted[j] then
                   begin
-                    for icond:=low(tasmcond) to high(tasmcond) do
-                      begin
-                        if copy(hs,1,2)=uppercond2str[icond] then
-                          begin
-                            actcondition:=icond;
-                            { strip condition }
-                            delete(hs,1,2);
-                            break;
-                          end;
-                      end;
+                    actoppostfix:=postfixsorted[j];
+                    { strip postfix }
+                    delete(hs,1,length(postfix2strsorted[j])+1);
+                    break;
                   end;
-                { check for postfix }
-                //if (length(hs)>0) and (actoppostfix=PF_None) then
-                //  begin
-                //    for j:=low(postfixsorted) to high(postfixsorted) do
-                //      begin
-                //        if copy(hs,1,length(postfix2strsorted[j]))=postfix2strsorted[j] then
-                //          begin
-                //            actoppostfix:=postfixsorted[j];
-                //            { strip postfix }
-                //            delete(hs,1,length(postfix2strsorted[j]));
-                //            break;
-                //          end;
-                //      end;
-                //  end;
               end;
-            { check for format postfix }
-            //if length(hs)>0 then
-            //  begin
-            //    if copy(hs,1,2) = '.W' then
-            //      begin
-            //        actwideformat:=true;
-            //        delete(hs,1,2);
-            //      end;
-            //  end;
-            { if we stripped all postfixes, it's a valid opcode }
-            is_asmopcode:=length(hs)=0;
-            if is_asmopcode = true then
-              break;
           end;
+
+        { if we stripped all postfixes, it's a valid opcode }
+        is_asmopcode:=length(hs)=0;
       end;
 
 
Index: xtensa/raxtensa.pas
===================================================================
--- xtensa/raxtensa.pas	(revision 45312)
+++ xtensa/raxtensa.pas	(working copy)
@@ -34,7 +34,12 @@
       TXtensaOperand=class(TOperand)
       end;
 
+      { TXtensaInstruction }
+
       TXtensaInstruction=class(TInstruction)
+        oppostfix : toppostfix;
+        opIsPrefixed : boolean;
+        function ConcatInstruction(p:TAsmList) : tai;override;
       end;
 
   implementation
@@ -42,4 +47,13 @@
     uses
       aasmcpu;
 
+    { TXtensaInstruction }
+
+    function TXtensaInstruction.ConcatInstruction(p:TAsmList) : tai;
+      begin
+        result:=inherited ConcatInstruction(p);
+        (result as taicpu).oppostfix:=oppostfix;
+        (result as taicpu).opIsPrefixed:=opIsPrefixed;
+      end;
+
 end.
Index: xtensa/xtensaatt.inc
===================================================================
--- xtensa/xtensaatt.inc	(revision 45312)
+++ xtensa/xtensaatt.inc	(working copy)
@@ -2,15 +2,20 @@
 '',
 'abs',
 'add',
+'addi',
+'addmi',
 'addx2',
 'addx4',
 'addx8',
-'add.s',
-'addi',
-'addmi',
+'all4',
+'all8',
 'and',
+'andb',
+'andbc',
+'any4',
+'any8',
 'b',
-'bt',
+'break',
 'call0',
 'call4',
 'call8',
@@ -19,50 +24,169 @@
 'callx4',
 'callx8',
 'callx12',
+'ceil',
+'clamps',
+'dhi',
+'dhu',
+'dhwb',
+'dhwbi',
+'dii',
+'diu',
+'diwb',
+'diwbi',
+'dpfl',
+'dpfr',
+'dpfro',
+'dpw',
+'dpwo',
+'dsync',
 'entry',
+'esync',
+'excw',
 'extui',
+'extw',
+'float',
+'floor',
+'idtlb',
+'ihi',
+'ihu',
+'iii',
+'iitlb',
+'iiu',
 'ill',
+'ipf',
+'ipfl',
+'isync',
+'j',
+'jx',
 'l8ui',
 'l16si',
 'l16ui',
+'l32ai',
+'l32e',
 'l32i',
 'l32r',
+'ldct',
+'lddec',
+'ldinc',
+'lict',
+'licw',
+'loop',
+'loopgtz',
+'loopnez',
 'lsi',
-'j',
-'j.l',
+'lsiu',
+'lsx',
+'lsxu',
+'madd',
+'max',
+'maxu',
+'memw',
+'min',
+'minu',
 'mov',
+'moveqz',
+'movf',
+'movgez',
+'movi',
+'movltz',
+'movnez',
 'movsp',
-'mov.s',
-'movnez',
-'movi',
-'mul.s',
+'movt',
+'msub',
+'mul',
+'mul16',
+'mula',
 'mull',
+'muls',
+'mulsh',
+'muluh',
 'neg',
-'neg.s',
 'nop',
-'oeq.s',
-'ole.s',
-'olt.s',
+'nsa',
+'nsau',
+'oeq',
+'ole',
+'olt',
 'or',
+'orb',
+'orbc',
+'pdtlb',
+'pitlb',
+'quos',
+'quou',
+'rdtlb0',
+'rdtlb1',
+'rems',
+'remu',
 'ret',
 'retw',
+'rfdd',
+'rfde',
+'rfe',
+'rfi',
+'rfme',
+'rfr',
+'rfue',
+'rfwo',
+'rfwu',
+'ritlb0',
+'ritlb1',
+'rotw',
+'round',
+'rsil',
+'rsr',
+'rur',
 's8i',
 's16i',
+'s32c1i',
+'s32e',
 's32i',
+'s32ri',
+'sdct',
 'sext',
+'sict',
+'sicw',
+'simcall',
 'sll',
 'slli',
 'sra',
 'srai',
+'src',
 'srl',
 'srli',
+'ssa8b',
+'ssa8l',
+'ssai',
 'ssi',
+'ssiu',
 'ssl',
 'ssr',
+'ssx',
+'ssxu',
 'sub',
-'sub.s',
+'subx2',
+'subx4',
+'subx8',
 'syscall',
-'xor'
+'trunc',
+'ueq',
+'ufloat',
+'ule',
+'ult',
+'umul',
+'un',
+'utrunc',
+'waiti',
+'wdtlb',
+'wer',
+'wfr',
+'witlb',
+'wsr',
+'wur',
+'xor',
+'xorb',
+'xsr'
 );
 
 
Index: xtensa/xtensaop.inc
===================================================================
--- xtensa/xtensaop.inc	(revision 45312)
+++ xtensa/xtensaop.inc	(working copy)
@@ -2,15 +2,20 @@
 A_NONE,
 A_ABS,
 A_ADD,
+A_ADDI,
+A_ADDMI,
 A_ADDX2,
 A_ADDX4,
 A_ADDX8,
-A_ADD_S,
-A_ADDI,
-A_ADDMI,
+A_ALL4,
+A_ALL8,
 A_AND,
-A_Bcc,
-A_BT,
+A_ANDB,
+A_ANDBC,
+A_ANY4,
+A_ANY8,
+A_B,
+A_BREAK,
 A_CALL0,
 A_CALL4,
 A_CALL8,
@@ -19,50 +24,169 @@
 A_CALLX4,
 A_CALLX8,
 A_CALLX12,
+A_CEIL,
+A_CLAMPS,
+A_DHI,
+A_DHU,
+A_DHWB,
+A_DHWBI,
+A_DII,
+A_DIU,
+A_DIWB,
+A_DIWBI,
+A_DPFL,
+A_DPFR,
+A_DPFRO,
+A_DPW,
+A_DPWO,
+A_DSYNC,
 A_ENTRY,
+A_ESYNC,
+A_EXCW,
 A_EXTUI,
+A_EXTW,
+A_FLOAT,
+A_FLOOR,
+A_IDTLB,
+A_IHI,
+A_IHU,
+A_III,
+A_IITLB,
+A_IIU,
 A_ILL,
+A_IPF,
+A_IPFL,
+A_ISYNC,
+A_J,
+A_JX,
 A_L8UI,
 A_L16SI,
 A_L16UI,
+A_L32AI,
+A_L32E,
 A_L32I,
 A_L32R,
+A_LDCT,
+A_LDDEC,
+A_LDINC,
+A_LICT,
+A_LICW,
+A_LOOP,
+A_LOOPGTZ,
+A_LOOPNEZ,
 A_LSI,
-A_J,
-A_J_L,
+A_LSIU,
+A_LSX,
+A_LSXU,
+A_MADD,
+A_MAX,
+A_MAXU,
+A_MEMW,
+A_MIN,
+A_MINU,
 A_MOV,
+A_MOVEQZ,
+A_MOVF,
+A_MOVGEZ,
+A_MOVI,
+A_MOVLTZ,
+A_MOVNEZ,
 A_MOVSP,
-A_MOV_S,
-A_MOVNEZ,
-A_MOVI,
-A_MUL_S,
+A_MOVT,
+A_MSUB,
+A_MUL,
+A_MUL16,
+A_MULA,
 A_MULL,
+A_MULS,
+A_MULSH,
+A_MULUH,
 A_NEG,
-A_NEG_S,
 A_NOP,
-A_OEQ_S,
-A_OLE_S,
-A_OLT_S,
+A_NSA,
+A_NSAU,
+A_OEQ,
+A_OLE,
+A_OLT,
 A_OR,
+A_ORB,
+A_ORBC,
+A_PDTLB,
+A_PITLB,
+A_QUOS,
+A_QUOU,
+A_RDTLB0,
+A_RDTLB1,
+A_REMS,
+A_REMU,
 A_RET,
 A_RETW,
+A_RFDD,
+A_RFDE,
+A_RFE,
+A_RFI,
+A_RFME,
+A_RFR,
+A_RFUE,
+A_RFWO,
+A_RFWU,
+A_RITLB0,
+A_RITLB1,
+A_ROTW,
+A_ROUND,
+A_RSIL,
+A_RSR,
+A_RUR,
 A_S8I,
 A_S16I,
+A_S32C1I,
+A_S32E,
 A_S32I,
+A_S32RI,
+A_SDCT,
 A_SEXT,
+A_SICT,
+A_SICW,
+A_SIMCALL,
 A_SLL,
 A_SLLI,
 A_SRA,
 A_SRAI,
+A_SRC,
 A_SRL,
 A_SRLI,
+A_SSA8B,
+A_SSA8L,
+A_SSAI,
 A_SSI,
+A_SSIU,
 A_SSL,
 A_SSR,
+A_SSX,
+A_SSXU,
 A_SUB,
-A_SUB_S,
+A_SUBX2,
+A_SUBX4,
+A_SUBX8,
 A_SYSCALL,
-A_XOR
+A_TRUNC,
+A_UEQ,
+A_UFLOAT,
+A_ULE,
+A_ULT,
+A_UMUL,
+A_UN,
+A_UTRUNC,
+A_WAITI,
+A_WDTLB,
+A_WER,
+A_WFR,
+A_WITLB,
+A_WSR,
+A_WUR,
+A_XOR,
+A_XORB,
+A_XSR
 );
 
 
xtensa-assembler.patch (34,833 bytes)   
asmtest.pas (332 bytes)   
unit asmtest;

interface

procedure test;

implementation

procedure test; assembler;
label
  lbl, lbl2;
asm
  bbci.l a4, 7, lbl2
  _bnez.n a4, lbl2
  loopnez a5, lbl
  beqz.n a2, lbl
  add a4, a5, a6
lbl:
  bt b9, lbl
  sub.s f1, f9, f13
  _loopgtz a3, lbl2
  rsr.prid a2
  extui a4, a3, 2, 1
lbl2:
  mula.aa.ll a3, a4
end;

end.

asmtest.pas (332 bytes)   

Florian

2020-06-21 16:52

administrator   ~0123497

Last edited: 2020-06-21 16:56

View 2 revisions

Thanks, applied. I wonder how it will turn out with all the postfixes :)

Christo Crause

2020-06-21 18:57

reporter   ~0123501

Thanks!

Issue History

Date Modified Username Field Change
2020-05-17 22:06 Christo Crause New Issue
2020-05-17 22:06 Christo Crause File Added: xtensa-instr.patch
2020-05-19 21:56 Christo Crause Note Added: 0122943
2020-05-19 21:56 Christo Crause File Added: xtensa-inst2.patch
2020-05-21 19:59 Florian Note Added: 0122992
2020-05-21 21:35 Christo Crause Note Added: 0122994
2020-05-22 21:58 Christo Crause Note Added: 0123006
2020-05-22 21:58 Christo Crause File Added: xtensa-assembler.patch
2020-05-22 21:58 Christo Crause File Added: asmtest.pas
2020-05-22 22:03 Christo Crause Note Edited: 0123006 View Revisions
2020-05-22 22:03 Christo Crause Note Edited: 0123006 View Revisions
2020-06-21 16:52 Florian Assigned To => Florian
2020-06-21 16:52 Florian Status new => resolved
2020-06-21 16:52 Florian Resolution open => fixed
2020-06-21 16:52 Florian Fixed in Version => 3.3.1
2020-06-21 16:52 Florian Fixed in Revision => 45671
2020-06-21 16:52 Florian FPCTarget => -
2020-06-21 16:52 Florian Note Added: 0123497
2020-06-21 16:56 Florian Note Edited: 0123497 View Revisions
2020-06-21 18:57 Christo Crause Status resolved => closed
2020-06-21 18:57 Christo Crause Note Added: 0123501