浏览代码

* basic framework for integrated arm assembler

git-svn-id: trunk@1061 -
florian 20 年之前
父节点
当前提交
14fca113bf

+ 7 - 0
.gitattributes

@@ -38,6 +38,12 @@ compiler/arm/aoptcpu.pas svneol=native#text/plain
 compiler/arm/aoptcpub.pas svneol=native#text/plain
 compiler/arm/aoptcpub.pas svneol=native#text/plain
 compiler/arm/aoptcpuc.pas svneol=native#text/plain
 compiler/arm/aoptcpuc.pas svneol=native#text/plain
 compiler/arm/aoptcpud.pas svneol=native#text/plain
 compiler/arm/aoptcpud.pas svneol=native#text/plain
+compiler/arm/armatt.inc svneol=native#text/plain
+compiler/arm/armatts.inc svneol=native#text/plain
+compiler/arm/armins.dat -text
+compiler/arm/armnop.inc svneol=native#text/plain
+compiler/arm/armop.inc svneol=native#text/plain
+compiler/arm/armtab.inc svneol=native#text/plain
 compiler/arm/cgcpu.pas svneol=native#text/plain
 compiler/arm/cgcpu.pas svneol=native#text/plain
 compiler/arm/cpubase.pas svneol=native#text/plain
 compiler/arm/cpubase.pas svneol=native#text/plain
 compiler/arm/cpuinfo.pas svneol=native#text/plain
 compiler/arm/cpuinfo.pas svneol=native#text/plain
@@ -439,6 +445,7 @@ compiler/utils/fpimpdef.pp svneol=native#text/plain
 compiler/utils/fppkg.pp svneol=native#text/plain
 compiler/utils/fppkg.pp svneol=native#text/plain
 compiler/utils/gppc386.pp svneol=native#text/plain
 compiler/utils/gppc386.pp svneol=native#text/plain
 compiler/utils/mk68kreg.pp svneol=native#text/plain
 compiler/utils/mk68kreg.pp svneol=native#text/plain
+compiler/utils/mkarmins.pp svneol=native#text/plain
 compiler/utils/mkarmreg.pp svneol=native#text/plain
 compiler/utils/mkarmreg.pp svneol=native#text/plain
 compiler/utils/mkmpsreg.pp svneol=native#text/plain
 compiler/utils/mkmpsreg.pp svneol=native#text/plain
 compiler/utils/mkppcreg.pp svneol=native#text/plain
 compiler/utils/mkppcreg.pp svneol=native#text/plain

+ 1090 - 2
compiler/arm/aasmcpu.pas

@@ -26,8 +26,9 @@ unit aasmcpu;
 interface
 interface
 
 
 uses
 uses
-  cclasses,aasmtai,
-  aasmbase,globtype,globals,verbose,
+  cclasses,globtype,globals,verbose,
+  aasmbase,aasmtai,
+  symtype,
   cpubase,cpuinfo,cgbase,cgutils;
   cpubase,cpuinfo,cgbase,cgutils;
 
 
     const
     const
@@ -36,7 +37,25 @@ uses
       { "mov reg,reg" source operand number }
       { "mov reg,reg" source operand number }
       O_MOV_DEST = 0;
       O_MOV_DEST = 0;
 
 
+      maxinfolen = 5;
+
+      IF_NONE   = $00000000;
+
+      IF_ARMMASK    = $000F0000;
+      { if the instruction can change in a second pass }
+      IF_PASS2  = longint($80000000);
+
     type
     type
+      tinsentry = record
+        opcode  : tasmop;
+        ops     : byte;
+        optypes : array[0..2] of longint;
+        code    : array[0..maxinfolen] of char;
+        flags   : longint;
+      end;
+
+      pinsentry=^tinsentry;
+
       taicpu = class(tai_cpu_abstract)
       taicpu = class(tai_cpu_abstract)
          oppostfix : TOpPostfix;
          oppostfix : TOpPostfix;
          roundingmode : troundingmode;
          roundingmode : troundingmode;
@@ -75,7 +94,36 @@ uses
          function is_same_reg_move(regtype: Tregistertype):boolean; override;
          function is_same_reg_move(regtype: Tregistertype):boolean; override;
 
 
          function spilling_get_operation_type(opnr: longint): topertype;override;
          function spilling_get_operation_type(opnr: longint): topertype;override;
+
+         { assembler }
+      public
+         { the next will reset all instructions that can change in pass 2 }
+         procedure ResetPass1;
+         procedure ResetPass2;
+         function  CheckIfValid:boolean;
+         function  Pass1(offset:longint):longint;virtual;
+         procedure Pass2(objdata:TAsmObjectdata);virtual;
+      protected
+         procedure ppuloadoper(ppufile:tcompilerppufile;var o:toper);override;
+         procedure ppuwriteoper(ppufile:tcompilerppufile;const o:toper);override;
+         procedure ppubuildderefimploper(var o:toper);override;
+         procedure ppuderefoper(var o:toper);override;
+      private
+         { next fields are filled in pass1, so pass2 is faster }
+         inssize   : shortint;
+         insoffset : longint;
+         LastInsOffset : longint; { need to be public to be reset }
+         insentry  : PInsEntry;
+         function  InsEnd:longint;
+         procedure create_ot;
+         function  Matches(p:PInsEntry):longint;
+         function  calcsize(p:PInsEntry):shortint;
+         procedure gencode(objdata:TAsmObjectData);
+         function  NeedAddrPrefix(opidx:byte):boolean;
+         procedure Swapoperands;
+         function  FindInsentry:boolean;
       end;
       end;
+
       tai_align = class(tai_align_abstract)
       tai_align = class(tai_align_abstract)
         { nothing to add }
         { nothing to add }
       end;
       end;
@@ -514,4 +562,1044 @@ implementation
         curdata.free;
         curdata.free;
       end;
       end;
 
 
+
+    procedure taicpu.ResetPass1;
+      begin
+        { we need to reset everything here, because the choosen insentry
+          can be invalid for a new situation where the previously optimized
+          insentry is not correct }
+        InsEntry:=nil;
+        InsSize:=0;
+        LastInsOffset:=-1;
+      end;
+
+
+    procedure taicpu.ResetPass2;
+      begin
+        { we are here in a second pass, check if the instruction can be optimized }
+        if assigned(InsEntry) and
+           ((InsEntry^.flags and IF_PASS2)<>0) then
+         begin
+           InsEntry:=nil;
+           InsSize:=0;
+         end;
+        LastInsOffset:=-1;
+      end;
+
+
+    function taicpu.CheckIfValid:boolean;
+      begin
+      end;
+
+
+    function taicpu.Pass1(offset:longint):longint;
+      begin
+      end;
+
+
+    procedure taicpu.Pass2(objdata:TAsmObjectdata);
+      begin
+      end;
+
+
+    procedure taicpu.ppuloadoper(ppufile:tcompilerppufile;var o:toper);
+      begin
+      end;
+
+
+    procedure taicpu.ppuwriteoper(ppufile:tcompilerppufile;const o:toper);
+      begin
+      end;
+
+
+    procedure taicpu.ppubuildderefimploper(var o:toper);
+      begin
+      end;
+
+
+    procedure taicpu.ppuderefoper(var o:toper);
+      begin
+      end;
+
+
+    function  taicpu.InsEnd:longint;
+      begin
+      end;
+
+
+    procedure taicpu.create_ot;
+      begin
+      end;
+
+
+    function  taicpu.Matches(p:PInsEntry):longint;
+      begin
+      end;
+
+
+    function  taicpu.calcsize(p:PInsEntry):shortint;
+      begin
+      end;
+
+
+    procedure taicpu.gencode(objdata:TAsmObjectData);
+      begin
+      end;
+
+
+    function  taicpu.NeedAddrPrefix(opidx:byte):boolean;
+      begin
+      end;
+
+
+    procedure taicpu.Swapoperands;
+      begin
+      end;
+
+
+    function  taicpu.FindInsentry:boolean;
+      begin
+      end;
+
+
+
 end.
 end.
+
+{$ifdef dummy}
+      (*
+static void gencode (long segment, long offset, int bits,
+		     insn *ins, char *codes, long insn_end)
+{
+    int has_S_code;		/* S - setflag */
+    int has_B_code;		/* B - setflag */
+    int has_T_code;		/* T - setflag */
+    int has_W_code;		/* ! => W flag */
+    int has_F_code;		/* ^ => S flag */
+    int keep;
+    unsigned char c;
+    unsigned char bytes[4];
+    long          data, size;
+    static int cc_code[] =	/* bit pattern of cc */
+  {				/* order as enum in  */
+    0x0E, 0x03, 0x02, 0x00,	/* nasm.h	     */
+    0x0A, 0x0C, 0x08, 0x0D,
+    0x09, 0x0B, 0x04, 0x01,
+    0x05, 0x07, 0x06,
+  };
+
+(*
+#ifdef DEBUG
+static char *CC[] =
+  {				       /* condition code names */
+    "AL", "CC", "CS", "EQ",
+    "GE", "GT", "HI", "LE",
+    "LS", "LT", "MI", "NE",
+    "PL", "VC", "VS", "",
+    "S"
+};
+*)
+
+    has_S_code = (ins->condition & C_SSETFLAG);
+    has_B_code = (ins->condition & C_BSETFLAG);
+    has_T_code = (ins->condition & C_TSETFLAG);
+    has_W_code = (ins->condition & C_EXSETFLAG);
+    has_F_code = (ins->condition & C_FSETFLAG);
+    ins->condition = (ins->condition & 0x0F);
+
+(*
+    if (rt_debug)
+      {
+    printf ("gencode: instruction: %s%s", insn_names[ins->opcode],
+	    CC[ins->condition & 0x0F]);
+    if (has_S_code)
+      printf ("S");
+    if (has_B_code)
+      printf ("B");
+    if (has_T_code)
+      printf ("T");
+    if (has_W_code)
+      printf ("!");
+    if (has_F_code)
+      printf ("^");
+
+    printf ("\n");
+
+    c = *codes;
+
+    printf ("   (%d)  decode - '0x%02X'\n", ins->operands, c);
+
+
+    bytes[0] = 0xB;
+    bytes[1] = 0xE;
+    bytes[2] = 0xE;
+    bytes[3] = 0xF;
+      }
+*)
+    // First condition code in upper nibble
+    if (ins->condition < C_NONE)
+      {
+	c = cc_code[ins->condition] << 4;
+      }
+    else
+      {
+	c = cc_code[C_AL] << 4;	// is often ALWAYS but not always
+      }
+
+
+    switch (keep = *codes)
+      {
+	case 1:
+	  // B, BL
+	  ++codes;
+	  c |= *codes++;
+	  bytes[0] = c;
+
+	  if (ins->oprs[0].segment != segment)
+	    {
+	      // fais une relocation
+	      c = 1;
+	      data = 0;	// Let the linker locate ??
+	    }
+	  else
+	    {
+	      c = 0;
+	      data = ins->oprs[0].offset - (offset + 8);
+	
+	      if (data % 4)
+		{
+		  errfunc (ERR_NONFATAL, "offset not aligned on 4 bytes");
+		}
+	    }
+	
+	  if (data >= 0x1000)
+	    {
+	      errfunc (ERR_NONFATAL, "too long offset");
+	    }
+
+	  data = data >> 2;
+	  bytes[1] = (data >> 16) & 0xFF;
+	  bytes[2] = (data >> 8)  & 0xFF;
+	  bytes[3] = (data )      & 0xFF;
+
+	  if (c == 1)
+	    {
+//	      out (offset, segment, &bytes[0], OUT_RAWDATA+1, NO_SEG, NO_SEG);
+	      out (offset, segment, &bytes[0], OUT_REL3ADR+4, ins->oprs[0].segment, NO_SEG);
+	    }
+	  else
+	    {
+	      out (offset, segment, &bytes[0], OUT_RAWDATA+4, NO_SEG, NO_SEG);
+	    }
+	  return;
+
+	case 2:
+	  // SWI
+	  ++codes;
+	  c |= *codes++;
+	  bytes[0] = c;
+	  data = ins->oprs[0].offset;
+	  bytes[1] = (data >> 16) & 0xFF;
+	  bytes[2] = (data >> 8) & 0xFF;
+	  bytes[3] = (data) & 0xFF;
+	  out (offset, segment, &bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG);
+	  return;
+        case 3:
+	  // BX
+	  ++codes;
+	  c |= *codes++;
+	  bytes[0] = c;
+	  bytes[1] = *codes++;
+	  bytes[2] = *codes++;
+	  bytes[3] = *codes++;
+	  c = regval (&ins->oprs[0],1);
+	  if (c == 15)	// PC
+	    {
+	      errfunc (ERR_WARNING, "'BX' with R15 has undefined behaviour");
+	    }
+	  else if (c > 15)
+	    {
+	      errfunc (ERR_NONFATAL, "Illegal register specified for 'BX'");
+	    }
+
+	  bytes[3] |= (c & 0x0F);
+	  out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG);
+	  return;
+
+        case 4:		// AND Rd,Rn,Rm
+        case 5:		// AND Rd,Rn,Rm,<shift>Rs
+        case 6:		// AND Rd,Rn,Rm,<shift>imm
+        case 7:		// AND Rd,Rn,<shift>imm
+	  ++codes;
+#ifdef DEBUG
+	  if (rt_debug)
+	    {
+	      printf ("         decode - '0x%02X'\n", keep);
+	      printf ("           code - '0x%02X'\n", (unsigned char) ( *codes));
+	    }
+#endif
+	  bytes[0] = c | *codes;
+	  ++codes;
+	
+	  bytes[1] = *codes;
+	  if (has_S_code)
+	    bytes[1] |= 0x10;
+	  c = regval (&ins->oprs[1],1);
+	  // Rn in low nibble
+	  bytes[1] |= c;
+
+	  // Rd in high nibble
+	  bytes[2] = regval (&ins->oprs[0],1) << 4;
+
+	  if (keep != 7)
+	    {
+	      // Rm in low nibble
+	      bytes[3] = regval (&ins->oprs[2],1);
+	    }
+
+	  // Shifts if any
+	  if (keep == 5 || keep == 6)
+	    {
+	      // Shift in bytes 2 and 3
+	      if (keep == 5)
+		{
+		  // Rs
+		  c = regval (&ins->oprs[3],1);
+		  bytes[2] |= c;
+
+		  c = 0x10;		// Set bit 4 in byte[3]
+		}
+	      if (keep == 6)
+		{
+		  c = (ins->oprs[3].offset) & 0x1F;
+		
+		  // #imm
+		  bytes[2] |= c >> 1;
+		  if (c & 0x01)
+		    {
+		      bytes[3] |= 0x80;
+		    }
+		  c = 0;		// Clr bit 4 in byte[3]
+		}
+	      // <shift>
+	      c |= shiftval (&ins->oprs[3]) << 5;
+
+	      bytes[3] |= c;
+	    }
+	
+	  // reg,reg,imm
+	  if (keep == 7)
+	    {
+	      int shimm;
+	
+	      shimm = imm_shift (ins->oprs[2].offset);
+
+	      if (shimm == -1)
+		{
+		  errfunc (ERR_NONFATAL, "cannot create that constant");
+		}
+	      bytes[3] = shimm & 0xFF;
+	      bytes[2] |= (shimm & 0xF00) >> 8;
+	    }
+	
+	  out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG);
+	  return;
+
+        case 8:		// MOV Rd,Rm
+        case 9:		// MOV Rd,Rm,<shift>Rs
+        case 0xA:	// MOV Rd,Rm,<shift>imm
+        case 0xB:	// MOV Rd,<shift>imm
+	  ++codes;
+#ifdef DEBUG
+	  if (rt_debug)
+	    {
+	      printf ("         decode - '0x%02X'\n", keep);
+	      printf ("           code - '0x%02X'\n", (unsigned char) ( *codes));
+	    }
+#endif
+	  bytes[0] = c | *codes;
+	  ++codes;
+	
+	  bytes[1] = *codes;
+	  if (has_S_code)
+	    bytes[1] |= 0x10;
+
+	  // Rd in high nibble
+	  bytes[2] = regval (&ins->oprs[0],1) << 4;
+
+	  if (keep != 0x0B)
+	    {
+	      // Rm in low nibble
+	      bytes[3] = regval (&ins->oprs[1],1);
+	    }
+
+	  // Shifts if any
+	  if (keep == 0x09 || keep == 0x0A)
+	    {
+	      // Shift in bytes 2 and 3
+	      if (keep == 0x09)
+		{
+		  // Rs
+		  c = regval (&ins->oprs[2],1);
+		  bytes[2] |= c;
+
+		  c = 0x10;		// Set bit 4 in byte[3]
+		}
+	      if (keep == 0x0A)
+		{
+		  c = (ins->oprs[2].offset) & 0x1F;
+		
+		  // #imm
+		  bytes[2] |= c >> 1;
+		  if (c & 0x01)
+		    {
+		      bytes[3] |= 0x80;
+		    }
+		  c = 0;		// Clr bit 4 in byte[3]
+		}
+	      // <shift>
+	      c |= shiftval (&ins->oprs[2]) << 5;
+
+	      bytes[3] |= c;
+	    }
+	
+	  // reg,imm
+	  if (keep == 0x0B)
+	    {
+	      int shimm;
+	
+	      shimm = imm_shift (ins->oprs[1].offset);
+
+	      if (shimm == -1)
+		{
+		  errfunc (ERR_NONFATAL, "cannot create that constant");
+		}
+	      bytes[3] = shimm & 0xFF;
+	      bytes[2] |= (shimm & 0xF00) >> 8;
+	    }
+	
+	  out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG);
+	  return;
+	
+
+        case 0xC:	// CMP Rn,Rm
+        case 0xD:	// CMP Rn,Rm,<shift>Rs
+        case 0xE:	// CMP Rn,Rm,<shift>imm
+        case 0xF:	// CMP Rn,<shift>imm
+	  ++codes;
+
+	  bytes[0] = c | *codes++;
+	
+	  bytes[1] = *codes;
+
+	  // Implicit S code
+	  bytes[1] |= 0x10;
+
+	  c = regval (&ins->oprs[0],1);
+	  // Rn in low nibble
+	  bytes[1] |= c;
+
+	  // No destination
+	  bytes[2] = 0;
+
+	  if (keep != 0x0B)
+	    {
+	      // Rm in low nibble
+	      bytes[3] = regval (&ins->oprs[1],1);
+	    }
+
+	  // Shifts if any
+	  if (keep == 0x0D || keep == 0x0E)
+	    {
+	      // Shift in bytes 2 and 3
+	      if (keep == 0x0D)
+		{
+		  // Rs
+		  c = regval (&ins->oprs[2],1);
+		  bytes[2] |= c;
+
+		  c = 0x10;		// Set bit 4 in byte[3]
+		}
+	      if (keep == 0x0E)
+		{
+		  c = (ins->oprs[2].offset) & 0x1F;
+		
+		  // #imm
+		  bytes[2] |= c >> 1;
+		  if (c & 0x01)
+		    {
+		      bytes[3] |= 0x80;
+		    }
+		  c = 0;		// Clr bit 4 in byte[3]
+		}
+	      // <shift>
+	      c |= shiftval (&ins->oprs[2]) << 5;
+
+	      bytes[3] |= c;
+	    }
+	
+	  // reg,imm
+	  if (keep == 0x0F)
+	    {
+	      int shimm;
+	
+	      shimm = imm_shift (ins->oprs[1].offset);
+
+	      if (shimm == -1)
+		{
+		  errfunc (ERR_NONFATAL, "cannot create that constant");
+		}
+	      bytes[3] = shimm & 0xFF;
+	      bytes[2] |= (shimm & 0xF00) >> 8;
+	    }
+	
+	  out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG);
+	  return;
+	
+        case 0x10:	// MRS Rd,<psr>
+	  ++codes;
+
+	  bytes[0] = c | *codes++;
+	
+	  bytes[1] = *codes++;
+
+	  // Rd
+	  c = regval (&ins->oprs[0],1);
+
+	  bytes[2] = c << 4;
+
+	  bytes[3] = 0;
+
+	  c = ins->oprs[1].basereg;
+
+	  if (c == R_CPSR || c == R_SPSR)
+	    {
+	      if (c == R_SPSR)
+		{
+		  bytes[1] |= 0x40;
+		}
+	    }
+	  else
+	    {
+	      errfunc (ERR_NONFATAL, "CPSR or SPSR expected");
+	    }
+
+	  out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG);
+
+	  return;
+	
+        case 0x11:	// MSR <psr>,Rm
+	case 0x12:	// MSR <psrf>,Rm
+        case 0x13:	// MSR <psrf>,#expression
+	  ++codes;
+
+	  bytes[0] = c | *codes++;
+	
+	  bytes[1] = *codes++;
+
+	  bytes[2] = *codes;
+
+
+	  if (keep == 0x11 || keep == 0x12)
+	    {
+	      // Rm
+	      c = regval (&ins->oprs[1],1);
+
+	      bytes[3] = c;
+	    }
+	  else
+	    {
+	      int shimm;
+	
+	      shimm = imm_shift (ins->oprs[1].offset);
+
+	      if (shimm == -1)
+		{
+		  errfunc (ERR_NONFATAL, "cannot create that constant");
+		}
+	      bytes[3] = shimm & 0xFF;
+	      bytes[2] |= (shimm & 0xF00) >> 8;
+	    }
+	
+	  c = ins->oprs[0].basereg;
+
+	  if ( keep == 0x11)
+	    {
+	      if ( c == R_CPSR || c == R_SPSR)
+		{
+		if ( c== R_SPSR)
+		  {
+		    bytes[1] |= 0x40;
+		  }
+		}
+	    else
+	      {
+		errfunc (ERR_NONFATAL, "CPSR or SPSR expected");
+	      }
+	    }
+	  else
+	    {
+	      if ( c == R_CPSR_FLG || c == R_SPSR_FLG)
+		{
+		  if ( c== R_SPSR_FLG)
+		    {
+		      bytes[1] |= 0x40;
+		    }
+		}
+	      else
+		{
+		  errfunc (ERR_NONFATAL, "CPSR_flg or SPSR_flg expected");
+		}
+	    }
+	  break;
+
+        case 0x14:	// MUL  Rd,Rm,Rs
+        case 0x15:	// MULA Rd,Rm,Rs,Rn
+	  ++codes;
+	
+	  bytes[0] = c | *codes++;
+	
+	  bytes[1] = *codes++;
+
+	  bytes[3] = *codes;
+
+	  // Rd
+	  bytes[1] |= regval (&ins->oprs[0],1);
+	  if (has_S_code)
+	    bytes[1] |= 0x10;
+
+	  // Rm
+	  bytes[3] |= regval (&ins->oprs[1],1);
+
+	  // Rs
+	  bytes[2] = regval (&ins->oprs[2],1);
+
+	  if (keep == 0x15)
+	    {
+	      bytes[2] |= regval (&ins->oprs[3],1) << 4;
+	    }
+	  break;
+
+        case 0x16:	// SMLAL RdHi,RdLo,Rm,Rs
+	  ++codes;
+	
+	  bytes[0] = c | *codes++;
+	
+	  bytes[1] = *codes++;
+
+	  bytes[3] = *codes;
+
+	  // RdHi
+	  bytes[1] |= regval (&ins->oprs[1],1);
+	  if (has_S_code)
+	    bytes[1] |= 0x10;
+
+	  // RdLo
+	  bytes[2] = regval (&ins->oprs[0],1) << 4;
+	  // Rm
+	  bytes[3] |= regval (&ins->oprs[2],1);
+
+	  // Rs
+	  bytes[2] |= regval (&ins->oprs[3],1);
+
+	  break;
+	
+        case 0x17:	// LDR Rd, expression
+	  ++codes;
+
+	  bytes[0] = c | *codes++;
+
+	  bytes[1] = *codes++;
+
+	  // Rd
+	  bytes[2] = regval (&ins->oprs[0],1) << 4;
+	  if (has_B_code)
+	    bytes[1] |= 0x40;
+	  if (has_T_code)
+	    {
+	      errfunc (ERR_NONFATAL, "'T' not allowed in pre-index mode");
+	    }
+	  if (has_W_code)
+	    {
+	      errfunc (ERR_NONFATAL, "'!' not allowed");
+	    }
+
+	  // Rn - implicit R15
+	  bytes[1] |= 0xF;
+
+	  if (ins->oprs[1].segment != segment)
+	    {
+	      errfunc (ERR_NONFATAL, "label not in same segment");
+	    }
+	
+	  data = ins->oprs[1].offset - (offset + 8);
+
+	  if (data < 0)
+	    {
+	      data = -data;
+	    }
+	  else
+	    {
+	      bytes[1] |= 0x80;
+	    }
+
+	  if (data >= 0x1000)
+	    {
+	      errfunc (ERR_NONFATAL, "too long offset");
+	    }
+
+	  bytes[2] |= ((data & 0xF00) >> 8);
+	  bytes[3] = data & 0xFF;
+	  break;
+	
+        case 0x18:	// LDR Rd, [Rn]
+	  ++codes;
+	
+	  bytes[0] = c | *codes++;
+	
+	  bytes[1] = *codes++;
+
+	  // Rd
+	  bytes[2] = regval (&ins->oprs[0],1) << 4;
+	  if (has_B_code)
+	    bytes[1] |= 0x40;
+	  if (has_T_code)
+	    {
+	      bytes[1] |= 0x20;		// write-back
+	    }
+	  else
+	    {
+	      bytes[0] |= 0x01;		// implicit pre-index mode
+	    }
+
+	  if (has_W_code)
+	    {
+	      bytes[1] |= 0x20;		// write-back
+	    }
+
+	  // Rn
+	  c = regval (&ins->oprs[1],1);
+	  bytes[1] |= c;
+
+	  if (c == 0x15)		// R15
+	    data = -8;
+	  else
+	    data = 0;
+
+	  if (data < 0)
+	    {
+	      data = -data;
+	    }
+	  else
+	    {
+	      bytes[1] |= 0x80;
+	    }
+
+	  bytes[2] |= ((data & 0xF00) >> 8);
+	  bytes[3] = data & 0xFF;
+	  break;
+	
+        case 0x19:	// LDR Rd, [Rn,#expression]
+	case 0x20:	// LDR Rd, [Rn,Rm]
+	case 0x21:	// LDR Rd, [Rn,Rm,shift]
+	  ++codes;
+	
+	  bytes[0] = c | *codes++;
+	
+	  bytes[1] = *codes++;
+
+	  // Rd
+	  bytes[2] = regval (&ins->oprs[0],1) << 4;
+	  if (has_B_code)
+	    bytes[1] |= 0x40;
+
+	  // Rn
+	  c = regval (&ins->oprs[1],1);
+	  bytes[1] |= c;
+
+	  if (ins->oprs[ins->operands-1].bracket)	// FIXME: Bracket on last operand -> pre-index  <--
+	    {
+	      bytes[0] |= 0x01;		// pre-index mode
+	      if (has_W_code)
+		{
+		  bytes[1] |= 0x20;
+		}
+	      if (has_T_code)
+		{
+		  errfunc (ERR_NONFATAL, "'T' not allowed in pre-index mode");
+		}
+	    }
+	  else
+	    {
+	      if (has_T_code)		// Forced write-back in post-index mode
+		{
+		  bytes[1] |= 0x20;
+		}
+	      if (has_W_code)
+		{
+		  errfunc (ERR_NONFATAL, "'!' not allowed in post-index mode");
+		}
+	    }
+
+	  if (keep == 0x19)
+	    {
+	      data = ins->oprs[2].offset;
+
+	      if (data < 0)
+		{
+		  data = -data;
+		}
+	      else
+		{
+		  bytes[1] |= 0x80;
+		}
+
+	      if (data >= 0x1000)
+		{
+		  errfunc (ERR_NONFATAL, "too long offset");
+		}
+	
+	      bytes[2] |= ((data & 0xF00) >> 8);
+	      bytes[3] = data & 0xFF;
+	    }
+	  else
+	    {
+	      if (ins->oprs[2].minus == 0)
+		{
+		  bytes[1] |= 0x80;
+		}
+	      c = regval (&ins->oprs[2],1);
+	      bytes[3] = c;
+
+	      if (keep == 0x21)
+		{
+		  c = ins->oprs[3].offset;
+		  if (c > 0x1F)
+		    {
+		      errfunc (ERR_NONFATAL, "too large shiftvalue");
+		      c = c & 0x1F;
+		    }
+		
+		  bytes[2] |= c >> 1;
+		  if (c & 0x01)
+		    {
+		      bytes[3] |= 0x80;
+		    }
+		  bytes[3] |= shiftval (&ins->oprs[3]) << 5;
+		}
+	    }
+	
+	  break;
+	
+        case 0x22:	// LDRH Rd, expression
+	  ++codes;
+	
+	  bytes[0] = c | 0x01;		// Implicit pre-index
+
+	  bytes[1] = *codes++;
+
+	  // Rd
+	  bytes[2] = regval (&ins->oprs[0],1) << 4;
+	
+	  // Rn - implicit R15
+	  bytes[1] |= 0xF;
+
+	  if (ins->oprs[1].segment != segment)
+	    {
+	      errfunc (ERR_NONFATAL, "label not in same segment");
+	    }
+	
+	  data = ins->oprs[1].offset - (offset + 8);
+
+	  if (data < 0)
+	    {
+	      data = -data;
+	    }
+	  else
+	    {
+	      bytes[1] |= 0x80;
+	    }
+
+	  if (data >= 0x100)
+	    {
+	      errfunc (ERR_NONFATAL, "too long offset");
+	    }
+	  bytes[3] = *codes++;
+
+	  bytes[2] |= ((data & 0xF0) >> 4);
+	  bytes[3] |= data & 0xF;
+	  break;
+	
+        case 0x23:	// LDRH Rd, Rn
+	  ++codes;
+	
+	  bytes[0] = c | 0x01;		// Implicit pre-index
+	
+	  bytes[1] = *codes++;
+
+	  // Rd
+	  bytes[2] = regval (&ins->oprs[0],1) << 4;
+	
+	  // Rn
+	  c = regval (&ins->oprs[1],1);
+	  bytes[1] |= c;
+
+	  if (c == 0x15)		// R15
+	    data = -8;
+	  else
+	    data = 0;
+	
+	  if (data < 0)
+	    {
+	      data = -data;
+	    }
+	  else
+	    {
+	      bytes[1] |= 0x80;
+	    }
+
+	  if (data >= 0x100)
+	    {
+	      errfunc (ERR_NONFATAL, "too long offset");
+	    }
+	  bytes[3] = *codes++;
+
+	  bytes[2] |= ((data & 0xF0) >> 4);
+	  bytes[3] |= data & 0xF;
+	  break;
+	
+        case 0x24:	// LDRH Rd, Rn, expression
+        case 0x25:	// LDRH Rd, Rn, Rm
+	  ++codes;
+
+	  bytes[0] = c;
+	
+	  bytes[1] = *codes++;
+
+	  // Rd
+	  bytes[2] = regval (&ins->oprs[0],1) << 4;
+
+	  // Rn
+	  c = regval (&ins->oprs[1],1);
+	  bytes[1] |= c;
+
+	  if (ins->oprs[ins->operands-1].bracket)	// FIXME: Bracket on last operand -> pre-index  <--
+	    {
+	      bytes[0] |= 0x01;		// pre-index mode
+	      if (has_W_code)
+		{
+		  bytes[1] |= 0x20;
+		}
+	    }
+	  else
+	    {
+	      if (has_W_code)
+		{
+		  errfunc (ERR_NONFATAL, "'!' not allowed in post-index mode");
+		}
+	    }
+
+	  bytes[3] = *codes++;
+
+	  if (keep == 0x24)
+	    {
+	      data = ins->oprs[2].offset;
+
+	      if (data < 0)
+		{
+		  data = -data;
+		}
+	      else
+		{
+		  bytes[1] |= 0x80;
+		}
+	
+	      if (data >= 0x100)
+		{
+		  errfunc (ERR_NONFATAL, "too long offset");
+		}
+
+	      bytes[2] |= ((data & 0xF0) >> 4);
+	      bytes[3] |= data & 0xF;
+	    }
+	  else
+	    {
+	      if (ins->oprs[2].minus == 0)
+		{
+		  bytes[1] |= 0x80;
+		}
+	      c = regval (&ins->oprs[2],1);
+	      bytes[3] |= c;
+
+	    }
+	  break;
+	
+        case 0x26:	// LDM/STM Rn, {reg-list}
+	  ++codes;
+
+	  bytes[0] = c;
+
+	  bytes[0] |= ( *codes >> 4) & 0xF;
+	  bytes[1] = ( *codes << 4) & 0xF0;
+	  ++codes;
+
+	  if (has_W_code)
+	    {
+	      bytes[1] |= 0x20;
+	    }
+	  if (has_F_code)
+	    {
+	      bytes[1] |= 0x40;
+	    }
+	
+	  // Rn
+	  bytes[1] |= regval (&ins->oprs[0],1);
+
+	  data = ins->oprs[1].basereg;
+
+	  bytes[2] = ((data >> 8) & 0xFF);
+	  bytes[3] = (data & 0xFF);
+	
+	  break;
+	
+        case 0x27:	// SWP Rd, Rm, [Rn]
+	  ++codes;
+	
+	  bytes[0] = c;
+
+	  bytes[0] |= *codes++;
+	
+	  bytes[1] = regval (&ins->oprs[2],1);
+	  if (has_B_code)
+	    {
+	      bytes[1] |= 0x40;
+	    }
+	  bytes[2] = regval (&ins->oprs[0],1) << 4;
+	  bytes[3] = *codes++;
+	  bytes[3] |= regval (&ins->oprs[1],1);
+	  break;
+	
+        default:
+	  errfunc (ERR_FATAL, "unknown decoding of instruction");
+
+	  bytes[0] = c;
+	  // And a fix nibble
+	  ++codes;
+	  bytes[0] |= *codes++;
+
+	 if ( *codes == 0x01)		// An I bit
+	   {
+
+	   }
+	 if ( *codes == 0x02)		// An I bit
+	   {
+
+	   }
+	 ++codes;
+      }
+    out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG);
+}
+
+
+*)
+{$endif dummy
+}

+ 63 - 0
compiler/arm/armatt.inc

@@ -0,0 +1,63 @@
+{ don't edit, this file is generated from armins.dat }
+(
+'adc',
+'add',
+'and',
+'b',
+'bic',
+'bl',
+'bx',
+'cdp',
+'cmn',
+'cmp',
+'dcb',
+'dcd',
+'dcw',
+'dq',
+'dt',
+'eor',
+'ldc',
+'ldmda',
+'ldmdb',
+'ldmea',
+'ldmed',
+'ldmfa',
+'ldmfd',
+'ldmia',
+'ldmib',
+'ldr',
+'ldrh',
+'ldrsb',
+'ldrsh',
+'mcr',
+'mla',
+'mov',
+'mrc',
+'mrs',
+'msr',
+'mul',
+'mvn',
+'orr',
+'rsb',
+'rsc',
+'sbc',
+'smlal',
+'smull',
+'stmda',
+'stmdb',
+'stmea',
+'stmed',
+'stmfa',
+'stmfd',
+'stmia',
+'stmib',
+'str',
+'strh',
+'sub',
+'swi',
+'swp',
+'teq',
+'tst',
+'umlal',
+'umull'
+);

+ 63 - 0
compiler/arm/armatts.inc

@@ -0,0 +1,63 @@
+{ don't edit, this file is generated from armins.dat }
+(
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE
+);

+ 295 - 0
compiler/arm/armins.dat

@@ -0,0 +1,295 @@
+;
+; Table of assembler instructions for Free Pascal
+; adapted from Netwide Assembler by Florian Klaempfl
+;
+;
+; The Netwide Assembler is copyright (C) 1996 Simon Tatham and
+; Julian Hall. All rights reserved. The software is
+; redistributable under the licence given in the file "Licence"
+; distributed in the NASM archive.
+;
+; Format of file: all four fields must be present on every functional
+; line. Hence `void' for no-operand instructions, and `\0' for such
+; as EQU. If the last three fields are all `ignore', no action is
+; taken except to register the opcode as being present.
+;
+;
+; 'ignore' means no instruc
+; 'void'   means instruc with zero operands
+;
+; Third field has a first byte indicating how to
+; put together the bits, and then some codes
+; that may be used at will (see assemble.c)
+;
+; \1   - 24 bit pc-rel offset		[B, BL]
+; \2   - 24 bit imm value		[SWI]
+; \3   -  3 byte code			[BX]
+;
+; \4   - reg,reg,reg			[AND,EOR,SUB,RSB,ADD,ADC,SBC,RSC,ORR,BIC]
+; \5   - reg,reg,reg,<shift>reg		[-"-]
+; \6   - reg,reg,reg,<shift>#imm	[-"-]
+; \7   - reg,reg,#imm			[-"-]
+;
+; \x8  - reg,reg			[MOV,MVN]
+; \x9  - reg,reg,<shift>reg		[-"-]
+; \xA  - reg,reg,<shift>#imm		[-"-]
+; \xB  - reg,#imm			[-"-]
+;
+; \xC  - reg,reg			[CMP,CMN,TEQ,TST]
+; \xD  - reg,reg,<shift>reg		[-"-]
+; \xE  - reg,reg,<shift>#imm		[-"-]
+; \xF  - reg,#imm			[-"-]
+;
+
+[ADCcc]
+reg32,reg32,reg32        \4\x0\xA0                     ARM7
+reg32,reg32,reg32,reg32  \5\x0\xA0                     ARM7
+reg32,reg32,reg32,imm    \6\x0\xA0                     ARM7
+reg32,reg32,imm          \7\x2\xA0                     ARM7
+
+[ADDcc]
+reg32,reg32,reg32        \4\x0\x80                     ARM7
+reg32,reg32,reg32,reg32  \5\x0\x80                     ARM7
+reg32,reg32,reg32,imm    \6\x0\x80                     ARM7
+reg32,reg32,imm          \7\x2\x80                     ARM7
+
+[ANDcc]
+reg32,reg32,reg32        \4\x0\x00                     ARM7
+reg32,reg32,reg32,reg32  \5\x0\x00                     ARM7
+reg32,reg32,reg32,imm    \6\x0\x00                     ARM7
+reg32,reg32,imm          \7\x2\x00                     ARM7
+
+[Bcc]
+mem32                    \1\x0A                        ARM7
+imm32                    \1\x0A                        ARM7
+
+[BICcc]
+reg32,reg32,reg32        \4\x1\xC0                     ARM7
+reg32,reg32,reg32,reg32  \5\x1\xC0                     ARM7
+reg32,reg32,reg32,imm    \6\x1\xC0                     ARM7
+reg32,reg32,imm          \7\x3\xC0                     ARM7
+
+[BLcc]
+mem32                    \1\x0B                        ARM7
+imm32                    \1\x0B                        ARM7
+
+
+[BXcc]
+reg32                    \3\x01\x2F\xFF\x10            ARM7
+
+[CDP]
+reg8,reg8           \300\1\x10\101                8086
+
+[CMNcc]
+reg32,reg32              \xC\x1\x60                     ARM7
+reg32,reg32,reg32        \xD\x1\x60                     ARM7
+reg32,reg32,imm          \xE\x1\x60                     ARM7
+reg32,imm                \xF\x3\x60                     ARM7
+
+[CMPcc]
+reg32,reg32              \xC\x1\x40                     ARM7
+reg32,reg32,reg32        \xD\x1\x40                     ARM7
+reg32,reg32,imm          \xE\x1\x40                     ARM7
+reg32,imm                \xF\x3\x40                     ARM7
+
+[DCB]
+ignore                   ignore                        ignore
+
+[DCD]
+ignore                   ignore                        ignore
+
+[DCW]
+ignore                   ignore                        ignore
+
+[DQ]
+ignore                   ignore                        ignore
+
+[DT]
+ignore                   ignore                        ignore
+
+[EORcc]
+reg32,reg32,reg32        \4\x0\x20                     ARM7
+reg32,reg32,reg32,reg32  \5\x0\x20                     ARM7
+reg32,reg32,reg32,imm    \6\x0\x20                     ARM7
+reg32,reg32,imm          \7\x2\x20                     ARM7
+
+[LDC]
+reg32,reg32         \321\300\1\x11\101            ARM7
+
+[LDMDAcc]
+reg32,reglist		   \x26\x81			ARM7
+
+[LDMDBcc]
+reg32,reglist		   \x26\x91			ARM7
+
+[LDMEAcc]
+reg32,reglist		   \x26\x91			ARM7
+
+[LDMEDcc]
+reg32,reglist		   \x26\x99			ARM7
+
+[LDMFAcc]
+reg32,reglist		   \x26\x81			ARM7
+
+[LDMFDcc]
+reg32,reglist		   \x26\x89			ARM7
+
+[LDMIAcc]
+reg32,reglist		   \x26\x89			ARM7
+
+[LDMIBcc]
+reg32,reglist		   \x26\x99			ARM7
+
+[LDRcc]
+reg32,imm32              \x17\x05\x10                   ARM7
+reg32,reg32              \x18\x04\x10                   ARM7
+reg32,reg32,imm32        \x19\x04\x10                   ARM7
+reg32,reg32,reg32        \x20\x06\x10                   ARM7
+reg32,reg32,reg32,imm32  \x21\x06\x10                   ARM7
+
+[LDRHcc]
+reg32,imm32              \x22\x50\xB0               ARM7
+reg32,reg32              \x23\x50\xB0               ARM7
+reg32,reg32,imm32        \x24\x50\xB0                   ARM7
+reg32,reg32,reg32        \x25\x10\xB0                   ARM7
+
+[LDRSBcc]
+reg32,imm32              \x22\x50\xD0               ARM7
+reg32,reg32              \x23\x50\xD0               ARM7
+reg32,reg32,imm32        \x24\x50\xD0                   ARM7
+reg32,reg32,reg32        \x25\x10\xD0                   ARM7
+
+[LDRSHcc]
+reg32,imm32              \x22\x50\xF0               ARM7
+reg32,reg32              \x23\x50\xF0               ARM7
+reg32,reg32,imm32        \x24\x50\xF0                   ARM7
+reg32,reg32,reg32        \x25\x10\xF0                   ARM7
+
+[MCR]
+reg32,mem32         \320\301\1\x13\110            8086
+
+[MLAcc]
+reg32,reg32,reg32,reg32  \x15\x00\x20\x90               ARM7
+
+[MOVcc]
+reg32,reg32              \x8\x1\xA0                     ARM7
+reg32,reg32,reg32        \x9\x1\xA0                     ARM7
+reg32,reg32,imm          \xA\x1\xA0                     ARM7
+reg32,imm                \xB\x3\xA0                     ARM7
+
+[MRC]
+reg32,reg32         \321\301\1\x13\110                  ARM7
+
+[MRScc]
+reg32,reg32         \x10\x01\x0F                        ARM7
+
+[MSRcc]
+reg32,reg32         \x11\x01\x29\xF0                    ARM7
+regf,reg32          \x12\x01\x28\xF0                    ARM7
+regf,imm            \x13\x03\x28\xF0                    ARM7
+
+[MULcc]
+reg32,reg32,reg32        \x14\x00\x00\x90          ARM7
+
+[MVNcc]
+reg32,reg32         \x8\x1\xE0                     ARM7
+reg32,reg32,reg32   \x9\x1\xE0                     ARM7
+reg32,reg32,imm     \xA\x1\xE0                     ARM7
+reg32,imm           \xB\x3\xE0                     ARM7
+
+[ORRcc]
+reg32,reg32,reg32        \4\x1\x80                     ARM7
+reg32,reg32,reg32,reg32  \5\x1\x80                     ARM7
+reg32,reg32,reg32,imm    \6\x1\x80                     ARM7
+reg32,reg32,imm          \7\x3\x80                     ARM7
+
+[RSBcc]
+reg32,reg32,reg32        \4\x0\x60                     ARM7
+reg32,reg32,reg32,reg32  \5\x0\x60                     ARM7
+reg32,reg32,reg32,imm    \6\x0\x60                     ARM7
+reg32,reg32,imm          \7\x2\x60                     ARM7
+
+[RSCcc]
+reg32,reg32,reg32        \4\x0\xE0                     ARM7
+reg32,reg32,reg32,reg32  \5\x0\xE0                     ARM7
+reg32,reg32,reg32,imm    \6\x0\xE0                     ARM7
+reg32,reg32,imm          \7\x2\xE0                     ARM7
+
+[SBCcc]
+reg32,reg32,reg32        \4\x0\xC0                     ARM7
+reg32,reg32,reg32,reg32  \5\x0\xC0                     ARM7
+reg32,reg32,reg32,imm    \6\x0\xC0                     ARM7
+reg32,reg32,imm          \7\x2\xC0                     ARM7
+
+[SMLALcc]
+reg32,reg32,reg32,reg32  \x16\x00\xE0\x90		 ARM7
+
+[SMULLcc]
+reg32,reg32,reg32,reg32  \x16\x00\xC0\x90		 ARM7
+
+[STMDAcc]
+reg32,reglist		   \x26\x80			ARM7
+
+[STMDBcc]
+reg32,reglist		   \x26\x90			ARM7
+
+[STMEAcc]
+reg32,reglist		   \x26\x88			ARM7
+
+[STMEDcc]	  
+reg32,reglist		   \x26\x80			ARM7
+
+[STMFAcc]
+reg32,reglist		   \x26\x98			ARM7
+
+[STMFDcc]
+reg32,reglist		   \x26\x90			ARM7
+
+[STMIAcc]
+reg32,reglist		   \x26\x88			ARM7
+
+[STMIBcc]
+reg32,reglist		   \x26\x98			ARM7
+
+[STRcc]
+reg32,imm32              \x17\x05\x00                   ARM7
+reg32,reg32              \x18\x04\x00                   ARM7
+reg32,reg32,imm32        \x19\x04\x00                   ARM7
+reg32,reg32,reg32        \x20\x06\x00                   ARM7
+reg32,reg32,reg32,imm32  \x21\x06\x00                   ARM7
+
+; A dummy since it is parsed as STR{cond}H
+[STRHcc]
+reg32,imm32              \x22\x40\xB0              ARM7
+reg32,reg32              \x23\x40\xB0               ARM7
+reg32,reg32,imm32        \x24\x40\xB0                   ARM7
+reg32,reg32,reg32        \x25\x00\xB0                   ARM7
+
+[SUBcc]
+reg32,reg32,reg32        \4\x0\x40                     ARM7
+reg32,reg32,reg32,reg32  \5\x0\x40                     ARM7
+reg32,reg32,reg32,imm    \6\x0\x40                     ARM7
+reg32,reg32,imm          \7\x2\x40                     ARM7
+
+[SWIcc]
+imm                 \2\x0F                        8086
+
+[SWPcc]
+reg32,reg32,reg32   \x27\x01\x90                   ARM7
+
+[TEQcc]
+reg32,reg32         \xC\x1\x20                     ARM7
+reg32,reg32,reg32   \xD\x1\x20                     ARM7
+reg32,reg32,imm     \xE\x1\x20                     ARM7
+reg32,imm           \xF\x3\x20                     ARM7
+
+[TSTcc]
+reg32,reg32         \xC\x1\x00                     ARM7
+reg32,reg32,reg32   \xD\x1\x00                     ARM7
+reg32,reg32,imm     \xE\x1\x00                     ARM7
+reg32,imm           \xF\x3\x00                     ARM7
+
+[UMLALcc]
+reg32,reg32,reg32,reg32  \x16\x00\xA0\x90		 ARM7
+[UMULLcc]
+reg32,reg32,reg32,reg32  \x16\x00\x80\x90		 ARM7

+ 2 - 0
compiler/arm/armnop.inc

@@ -0,0 +1,2 @@
+{ don't edit, this file is generated from armins.dat }
+132;

+ 63 - 0
compiler/arm/armop.inc

@@ -0,0 +1,63 @@
+{ don't edit, this file is generated from armins.dat }
+(
+A_ADC,
+A_ADD,
+A_AND,
+A_B,
+A_BIC,
+A_BL,
+A_BX,
+A_CDP,
+A_CMN,
+A_CMP,
+A_DCB,
+A_DCD,
+A_DCW,
+A_DQ,
+A_DT,
+A_EOR,
+A_LDC,
+A_LDMDA,
+A_LDMDB,
+A_LDMEA,
+A_LDMED,
+A_LDMFA,
+A_LDMFD,
+A_LDMIA,
+A_LDMIB,
+A_LDR,
+A_LDRH,
+A_LDRSB,
+A_LDRSH,
+A_MCR,
+A_MLA,
+A_MOV,
+A_MRC,
+A_MRS,
+A_MSR,
+A_MUL,
+A_MVN,
+A_ORR,
+A_RSB,
+A_RSC,
+A_SBC,
+A_SMLAL,
+A_SMULL,
+A_STMDA,
+A_STMDB,
+A_STMEA,
+A_STMED,
+A_STMFA,
+A_STMFD,
+A_STMIA,
+A_STMIB,
+A_STR,
+A_STRH,
+A_SUB,
+A_SWI,
+A_SWP,
+A_TEQ,
+A_TST,
+A_UMLAL,
+A_UMULL
+);

+ 927 - 0
compiler/arm/armtab.inc

@@ -0,0 +1,927 @@
+{ don't edit, this file is generated from armins.dat }
+(
+  (
+    opcode  : A_ADC;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #4#0#160;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_ADC;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
+    code    : #5#0#160;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_ADC;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate);
+    code    : #6#0#160;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_ADC;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate,);
+    code    : #7#2#160;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_ADD;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #4#0#128;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_ADD;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
+    code    : #5#0#128;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_ADD;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate);
+    code    : #6#0#128;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_ADD;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate,);
+    code    : #7#2#128;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_AND;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #4#0#0;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_AND;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
+    code    : #5#0#0;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_AND;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate);
+    code    : #6#0#0;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_AND;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate,);
+    code    : #7#2#0;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_B;
+    ops     : 1;
+    optypes : (ot_memory or ot_bits32,ot_none,ot_none,);
+    code    : #1#10;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_B;
+    ops     : 1;
+    optypes : (ot_immediate or ot_bits32,ot_none,ot_none,);
+    code    : #1#10;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_BIC;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #4#1#192;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_BIC;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
+    code    : #5#1#192;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_BIC;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate);
+    code    : #6#1#192;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_BIC;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate,);
+    code    : #7#3#192;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_BL;
+    ops     : 1;
+    optypes : (ot_memory or ot_bits32,ot_none,ot_none,);
+    code    : #1#11;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_BL;
+    ops     : 1;
+    optypes : (ot_immediate or ot_bits32,ot_none,ot_none,);
+    code    : #1#11;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_BX;
+    ops     : 1;
+    optypes : (ot_reg32,ot_none,ot_none,);
+    code    : #3#1#47#255#16;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_CDP;
+    ops     : 2;
+    optypes : (ot_reg8,ot_reg8,ot_none,);
+    code    : #192#1#16#65;
+    flags   : if_8086
+  ),
+  (
+    opcode  : A_CMN;
+    ops     : 2;
+    optypes : (ot_reg32 or ot_signed,ot_reg32,ot_none,);
+    code    : #12#1#96;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_CMN;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32 or ot_signed,ot_reg32,);
+    code    : #13#1#96;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_CMN;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate or ot_signed,);
+    code    : #14#1#96;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_CMN;
+    ops     : 2;
+    optypes : (ot_reg32,ot_immediate,ot_none,);
+    code    : #15#3#96;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_CMP;
+    ops     : 2;
+    optypes : (ot_reg32 or ot_signed,ot_reg32,ot_none,);
+    code    : #12#1#64;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_CMP;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32 or ot_signed,ot_reg32,);
+    code    : #13#1#64;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_CMP;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate or ot_signed,);
+    code    : #14#1#64;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_CMP;
+    ops     : 2;
+    optypes : (ot_reg32,ot_immediate,ot_none,);
+    code    : #15#3#64;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_DCB;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,);
+    code    : #0;
+    flags   : if_ignore
+  ),
+  (
+    opcode  : A_DCD;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,);
+    code    : #0;
+    flags   : if_ignore
+  ),
+  (
+    opcode  : A_DCW;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,);
+    code    : #0;
+    flags   : if_ignore
+  ),
+  (
+    opcode  : A_DQ;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,);
+    code    : #0;
+    flags   : if_ignore
+  ),
+  (
+    opcode  : A_DT;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,);
+    code    : #0;
+    flags   : if_ignore
+  ),
+  (
+    opcode  : A_EOR;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #4#0#32;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_EOR;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
+    code    : #5#0#32;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_EOR;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate);
+    code    : #6#0#32;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_EOR;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate,);
+    code    : #7#2#32;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDC;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reg32,ot_none,);
+    code    : #209#192#1#17#65;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDMDA;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#129;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDMDB;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#145;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDMEA;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#145;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDMED;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#153;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDMFA;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#129;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDMFD;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#137;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDMIA;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#137;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDMIB;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#153;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDR;
+    ops     : 2;
+    optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,);
+    code    : #23#5#16;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDR;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reg32,ot_none,);
+    code    : #24#4#16;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDR;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate or ot_bits32,);
+    code    : #25#4#16;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDR;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #32#6#16;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDR;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate or ot_bits32);
+    code    : #33#6#16;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDRH;
+    ops     : 2;
+    optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,);
+    code    : #34#80#176;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDRH;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reg32,ot_none,);
+    code    : #35#80#176;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDRH;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate or ot_bits32,);
+    code    : #36#80#176;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDRH;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #37#16#176;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDRSB;
+    ops     : 2;
+    optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,);
+    code    : #34#80#208;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDRSB;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reg32,ot_none,);
+    code    : #35#80#208;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDRSB;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate or ot_bits32,);
+    code    : #36#80#208;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDRSB;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #37#16#208;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDRSH;
+    ops     : 2;
+    optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,);
+    code    : #34#80#240;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDRSH;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reg32,ot_none,);
+    code    : #35#80#240;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDRSH;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate or ot_bits32,);
+    code    : #36#80#240;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_LDRSH;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #37#16#240;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_MCR;
+    ops     : 2;
+    optypes : (ot_reg32,ot_memory or ot_bits32,ot_none,);
+    code    : #208#193#1#19#72;
+    flags   : if_8086
+  ),
+  (
+    opcode  : A_MLA;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
+    code    : #21#0#32#144;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_MOV;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reg32,ot_none,);
+    code    : #8#1#160;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_MOV;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #9#1#160;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_MOV;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate,);
+    code    : #10#1#160;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_MOV;
+    ops     : 2;
+    optypes : (ot_reg32,ot_immediate,ot_none,);
+    code    : #11#3#160;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_MRC;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reg32,ot_none,);
+    code    : #209#193#1#19#72;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_MRS;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reg32,ot_none,);
+    code    : #16#1#15;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_MSR;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reg32,ot_none,);
+    code    : #17#1#41#240;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_MSR;
+    ops     : 2;
+    optypes : (ot_regf,ot_reg32,ot_none,);
+    code    : #18#1#40#240;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_MSR;
+    ops     : 2;
+    optypes : (ot_regf,ot_immediate,ot_none,);
+    code    : #19#3#40#240;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_MUL;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #20#0#0#144;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_MVN;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reg32,ot_none,);
+    code    : #8#1#224;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_MVN;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #9#1#224;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_MVN;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate,);
+    code    : #10#1#224;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_MVN;
+    ops     : 2;
+    optypes : (ot_reg32,ot_immediate,ot_none,);
+    code    : #11#3#224;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_ORR;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #4#1#128;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_ORR;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
+    code    : #5#1#128;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_ORR;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate);
+    code    : #6#1#128;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_ORR;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate,);
+    code    : #7#3#128;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_RSB;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #4#0#96;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_RSB;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
+    code    : #5#0#96;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_RSB;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate);
+    code    : #6#0#96;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_RSB;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate,);
+    code    : #7#2#96;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_RSC;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #4#0#224;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_RSC;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
+    code    : #5#0#224;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_RSC;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate);
+    code    : #6#0#224;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_RSC;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate,);
+    code    : #7#2#224;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_SBC;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #4#0#192;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_SBC;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
+    code    : #5#0#192;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_SBC;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate);
+    code    : #6#0#192;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_SBC;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate,);
+    code    : #7#2#192;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_SMLAL;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
+    code    : #22#0#224#144;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_SMULL;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
+    code    : #22#0#192#144;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STMDA;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#128;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STMDB;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#144;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STMEA;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#136;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STMED;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#128;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STMFA;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#152;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STMFD;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#144;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STMIA;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#136;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STMIB;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reglist,ot_none,);
+    code    : #38#152;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STR;
+    ops     : 2;
+    optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,);
+    code    : #23#5#0;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STR;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reg32,ot_none,);
+    code    : #24#4#0;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STR;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate or ot_bits32,);
+    code    : #25#4#0;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STR;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #32#6#0;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STR;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate or ot_bits32);
+    code    : #33#6#0;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STRH;
+    ops     : 2;
+    optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,);
+    code    : #34#64#176;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STRH;
+    ops     : 2;
+    optypes : (ot_reg32,ot_reg32,ot_none,);
+    code    : #35#64#176;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STRH;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate or ot_bits32,);
+    code    : #36#64#176;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_STRH;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #37#0#176;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_SUB;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #4#0#64;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_SUB;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
+    code    : #5#0#64;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_SUB;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate);
+    code    : #6#0#64;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_SUB;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate,);
+    code    : #7#2#64;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_SWI;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,);
+    code    : #2#15;
+    flags   : if_8086
+  ),
+  (
+    opcode  : A_SWP;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,);
+    code    : #39#1#144;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_TEQ;
+    ops     : 2;
+    optypes : (ot_reg32 or ot_signed,ot_reg32,ot_none,);
+    code    : #12#1#32;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_TEQ;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32 or ot_signed,ot_reg32,);
+    code    : #13#1#32;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_TEQ;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate or ot_signed,);
+    code    : #14#1#32;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_TEQ;
+    ops     : 2;
+    optypes : (ot_reg32,ot_immediate,ot_none,);
+    code    : #15#3#32;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_TST;
+    ops     : 2;
+    optypes : (ot_reg32 or ot_signed,ot_reg32,ot_none,);
+    code    : #12#1#0;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_TST;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32 or ot_signed,ot_reg32,);
+    code    : #13#1#0;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_TST;
+    ops     : 3;
+    optypes : (ot_reg32,ot_reg32,ot_immediate or ot_signed,);
+    code    : #14#1#0;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_TST;
+    ops     : 2;
+    optypes : (ot_reg32,ot_immediate,ot_none,);
+    code    : #15#3#0;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_UMLAL;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
+    code    : #22#0#160#144;
+    flags   : if_arm7
+  ),
+  (
+    opcode  : A_UMULL;
+    ops     : 4;
+    optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
+    code    : #22#0#128#144;
+    flags   : if_arm7
+  )
+);

+ 2 - 0
compiler/arm/cputarg.pas

@@ -52,6 +52,8 @@ implementation
     {$ifndef NOAGARMGAS}
     {$ifndef NOAGARMGAS}
       ,agarmgas
       ,agarmgas
     {$endif}
     {$endif}
+
+      ,ogcoff
       ;
       ;
 
 
 end.
 end.

+ 27 - 1
compiler/ogcoff.pas

@@ -1101,7 +1101,12 @@ const go32v2stub : array[0..2047] of byte=(
            sympos:=datapos;
            sympos:=datapos;
          { COFF header }
          { COFF header }
            fillchar(header,sizeof(coffheader),0);
            fillchar(header,sizeof(coffheader),0);
+{$ifdef i386}
            header.mach:=$14c;
            header.mach:=$14c;
+{$endif i386}
+{$ifdef arm}
+           header.mach:=$1c0;
+{$endif arm}
            header.nsects:=nsects;
            header.nsects:=nsects;
            header.sympos:=sympos;
            header.sympos:=sympos;
            header.syms:=symbols.count+initsym;
            header.syms:=symbols.count+initsym;
@@ -1614,7 +1619,12 @@ const go32v2stub : array[0..2047] of byte=(
               Comment(V_Error,'Error reading coff file');
               Comment(V_Error,'Error reading coff file');
               exit;
               exit;
             end;
             end;
+{$ifdef i386}
            if header.mach<>$14c then
            if header.mach<>$14c then
+{$endif i386}
+{$ifdef arm}
+           if header.mach<>$1c0 then
+{$endif arm}
             begin
             begin
               Comment(V_Error,'Not a coff file');
               Comment(V_Error,'Not a coff file');
               exit;
               exit;
@@ -1756,7 +1766,6 @@ const go32v2stub : array[0..2047] of byte=(
             comment : '';
             comment : '';
           );
           );
 
 
-    const
        as_i386_pecoff_info : tasminfo =
        as_i386_pecoff_info : tasminfo =
           (
           (
             id     : as_i386_pecoff;
             id     : as_i386_pecoff;
@@ -1794,9 +1803,26 @@ const go32v2stub : array[0..2047] of byte=(
           );
           );
 
 
 
 
+       as_arm_pecoffwince_info : tasminfo =
+          (
+            id     : as_arm_pecoffwince;
+            idtxt  : 'PECOFFWINCE';
+            asmbin : '';
+            asmcmd : '';
+            supported_target : system_arm_wince;
+            flags : [af_outputbinary];
+            labelprefix : '.L';
+            comment : '';
+          );
+
 initialization
 initialization
+{$ifdef i386}
   RegisterAssembler(as_i386_coff_info,TCoffAssembler);
   RegisterAssembler(as_i386_coff_info,TCoffAssembler);
   RegisterAssembler(as_i386_pecoff_info,TPECoffAssembler);
   RegisterAssembler(as_i386_pecoff_info,TPECoffAssembler);
   RegisterAssembler(as_i386_pecoffwdosx_info,TPECoffAssembler);
   RegisterAssembler(as_i386_pecoffwdosx_info,TPECoffAssembler);
   RegisterAssembler(as_i386_pecoffwince_info,TPECoffAssembler);
   RegisterAssembler(as_i386_pecoffwince_info,TPECoffAssembler);
+{$endif i386}
+{$ifdef arm}
+  RegisterAssembler(as_arm_pecoffwince_info,TPECoffAssembler);
+{$endif arm}
 end.
 end.

+ 1 - 1
compiler/rabase.pas

@@ -40,7 +40,7 @@ unit rabase;
        pasmmodeinfo = ^tasmmodeinfo;
        pasmmodeinfo = ^tasmmodeinfo;
        tasmmodeinfo = record
        tasmmodeinfo = record
           id    : tasmmode;
           id    : tasmmode;
-          idtxt : string[8];
+          idtxt : string[12];
           casmreader : tcbaseasmreader;
           casmreader : tcbaseasmreader;
        end;
        end;
 
 

+ 2 - 1
compiler/systems.pas

@@ -143,6 +143,7 @@ interface
              ,as_x86_64_masm
              ,as_x86_64_masm
              ,as_x86_64_pecoff
              ,as_x86_64_pecoff
              ,as_i386_pecoffwince
              ,as_i386_pecoffwince
+             ,as_arm_pecoffwince
        );
        );
 
 
        tar = (ar_none
        tar = (ar_none
@@ -210,7 +211,7 @@ interface
        pasminfo = ^tasminfo;
        pasminfo = ^tasminfo;
        tasminfo = record
        tasminfo = record
           id          : tasm;
           id          : tasm;
-          idtxt       : string[9];
+          idtxt       : string[12];
           asmbin      : string[8];
           asmbin      : string[8];
           asmcmd      : string[50];
           asmcmd      : string[50];
           supported_target : tsystem;
           supported_target : tsystem;

+ 430 - 0
compiler/utils/mkarmins.pp

@@ -0,0 +1,430 @@
+{
+    Copyright (c) 1998-2005 by Peter Vreman and Florian Klaempfl
+
+    Convert i386ins.dat from Nasm to a .inc file for usage with
+    the Free pascal compiler
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    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.
+
+ **********************************************************************}
+program mkarmins;
+
+const
+  Version = '0.9';
+
+var
+   s : string;
+   i : longint;
+   x86_64 : boolean;
+
+{$ifndef FPC}
+  procedure readln(var t:text;var s:string);
+  var
+    c : char;
+    i : longint;
+  begin
+    c:=#0;
+    i:=0;
+    while (not eof(t)) and (c<>#10) do
+     begin
+       read(t,c);
+       if c<>#10 then
+        begin
+          inc(i);
+          s[i]:=c;
+        end;
+     end;
+    if (i>0) and (s[i]=#13) then
+     dec(i);
+    s[0]:=chr(i);
+  end;
+{$endif}
+
+    function lower(const s : string) : string;
+    {
+      return lowercased string of s
+    }
+      var
+         i : longint;
+      begin
+         for i:=1 to length(s) do
+          if s[i] in ['A'..'Z'] then
+           lower[i]:=char(byte(s[i])+32)
+          else
+           lower[i]:=s[i];
+         lower[0]:=s[0];
+      end;
+
+      function Replace(var s:string;const s1,s2:string):boolean;
+      var
+        i  : longint;
+      begin
+        i:=pos(s1,s);
+        if i>0 then
+         begin
+           Delete(s,i,length(s1));
+           Insert(s2,s,i);
+           Replace:=true;
+         end
+        else
+         Replace:=false;
+      end;
+
+
+function formatop(s:string):string;
+   const
+     replaces=19;
+     replacetab : array[1..replaces,1..2] of string[32]=(
+       (':',' or ot_colon'),
+       ('mem8','mem or ot_bits8'),
+       ('mem16','mem or ot_bits16'),
+       ('mem32','mem or ot_bits32'),
+       ('mem64','mem or ot_bits64'),
+       ('mem80','mem or ot_bits80'),
+       ('mem','memory'),
+       ('memory_offs','mem_offs'),
+       ('imm8','imm or ot_bits8'),
+       ('imm16','imm or ot_bits16'),
+       ('imm32','imm or ot_bits32'),
+       ('imm64','imm or ot_bits64'),
+       ('imm80','imm or ot_bits80'),
+       ('imm','immediate'),
+       ('rm8','regmem or ot_bits8'),
+       ('rm16','regmem or ot_bits16'),
+       ('rm32','regmem or ot_bits32'),
+       ('rm64','regmem or ot_bits64'),
+       ('rm80','regmem or ot_bits80')
+     );
+  var
+    i : longint;
+  begin
+    for i:=1to replaces do
+     replace(s,replacetab[i,1],replacetab[i,2]);
+    formatop:=s;
+  end;
+
+
+function readnumber : longint;
+
+  var
+     base : longint;
+     result : longint;
+
+  begin
+     result:=0;
+     if s[i]='\' then
+       begin
+          base:=8;
+          inc(i);
+          if s[i]='x' then
+            begin
+               base:=16;
+               inc(i);
+            end;
+       end
+     else
+       base:=10;
+     s[i]:=upcase(s[i]);
+     while s[i] in ['0'..'9','A'..'F'] do
+       begin
+          case s[i] of
+             '0'..'9':
+               result:=result*base+ord(s[i])-ord('0');
+
+             'A'..'F':
+               result:=result*base+ord(s[i])-ord('A')+10;
+          end;
+          inc(i);
+       end;
+     readnumber:=result;
+  end;
+
+function tostr(l : longint) : string;
+
+  var
+     hs : string;
+
+  begin
+     str(l,hs);
+     tostr:=hs;
+  end;
+
+function readstr : string;
+
+  var
+     result : string;
+
+  begin
+     result:='';
+     while (s[i] in ['0'..'9','A'..'Z','a'..'z','_']) and (i<=length(s)) do
+       begin
+          result:=result+s[i];
+          inc(i);
+       end;
+     readstr:=result;
+  end;
+
+procedure skipspace;
+
+  begin
+     while (s[i] in [' ',#9]) do
+       inc(i);
+  end;
+
+procedure openinc(var f:text;const fn:string);
+begin
+  writeln('creating ',fn);
+  assign(f,fn);
+  rewrite(f);
+  writeln(f,'{ don''t edit, this file is generated from armins.dat }');
+  writeln(f,'(');
+end;
+
+
+procedure closeinc(var f:text);
+begin
+  writeln(f);
+  writeln(f,');');
+  close(f);
+end;
+
+
+var
+   attsuffix,
+   hs : string;
+   j : longint;
+   firstopcode,
+   first : boolean;
+   maxinfolen,
+   code : byte;
+   insns : longint;
+   attsuffile,propfile,opfile,
+   nopfile,attfile,
+   infile,insfile : text;
+   { instruction fields }
+   skip : boolean;
+   last,
+   ops    : longint;
+   attopcode,
+   opcode,
+   codes,
+   flags   : string;
+   optypes : array[1..4] of string;
+begin
+   writeln('Narm Instruction Table Converter Version ',Version);
+   insns:=0;
+   maxinfolen:=0;
+   { open dat file }
+   assign(infile,'../arm/armins.dat');
+   { create inc files }
+   openinc(insfile,'armtab.inc');
+   openinc(opfile,'armop.inc');
+   assign(nopfile,'armnop.inc');
+   openinc(attfile,'armatt.inc');
+   openinc(attsuffile,'armatts.inc');
+   {
+   openinc(intfile,'i386int.inc');
+   openinc(propfile,'i386prop.inc');
+   }
+   rewrite(nopfile);
+   writeln(nopfile,'{ don''t edit, this file is generated from armins.dat }');
+   reset(infile);
+   first:=true;
+   opcode:='';
+   firstopcode:=true;
+   while not(eof(infile)) do
+     begin
+        { handle comment }
+        readln(infile,s);
+        while (s[1]=' ') do
+         delete(s,1,1);
+        if (s='') or (s[1]=';') then
+          continue;
+        if (s[1]='[') then
+         begin
+           i:=pos(',',s);
+           j:=pos(']',s);
+           if i=0 then
+            begin
+              opcode:='A_'+Copy(s,2,j-2);
+              attopcode:=Copy(s,2,j-2);
+              { Conditional }
+              if (attopcode[length(attopcode)]='c') and
+                 (attopcode[length(attopcode)-1]='c') then
+                begin
+                  dec(byte(attopcode[0]),2);
+                  dec(byte(opcode[0]),2);
+                end;
+              attsuffix:='attsufNONE';
+            end
+           else
+            begin
+              opcode:='A_'+Copy(s,2,i-2);
+              { intel conditional }
+              if (opcode[length(attopcode)]='c') and
+                 (opcode[length(attopcode)-1]='c') then
+                dec(byte(opcode[0]),2);
+              attopcode:=Copy(s,i+1,j-i-1);
+              { att Suffix }
+              case attopcode[length(attopcode)] of
+                'X' :
+                  begin
+                    dec(attopcode[0]);
+                    attsuffix:='attsufINT';
+                  end;
+                'F' :
+                  begin
+                    dec(attopcode[0]);
+                    attsuffix:='attsufFPU';
+                  end;
+                'R' :
+                  begin
+                    dec(attopcode[0]);
+                    attsuffix:='attsufFPUint';
+                  end;
+                else
+                  attsuffix:='attsufNONE';
+              end;
+              { att Conditional }
+              if (attopcode[length(attopcode)]='C') and
+                 (attopcode[length(attopcode)-1]='C') then
+                dec(byte(attopcode[0]),2);
+            end;
+           attopcode:=Lower(attopcode);
+           if firstopcode then
+            firstopcode:=false
+           else
+            begin
+              writeln(opfile,',');
+              writeln(attfile,',');
+              writeln(attsuffile,',');
+{              writeln(propfile,','); }
+            end;
+           write(opfile,opcode);
+           write(attfile,'''',attopcode,'''');
+           write(attsuffile,attsuffix);
+           { read the next line which contains the Change options }
+           {
+           repeat
+             readln(infile,s);
+           until eof(infile) or ((s<>'') and (s[1]<>';'));
+           write(propfile,'(Ch: ',s,')');
+           }
+           continue;
+         end;
+        { we must have an opcode }
+        if opcode='' then
+         runerror(234);
+        { clear }
+        ops:=0;
+        optypes[1]:='';
+        optypes[2]:='';
+        optypes[3]:='';
+        optypes[4]:='';
+        codes:='';
+        flags:='';
+        skip:=false;
+        { ops and optypes }
+        i:=1;
+        repeat
+          hs:=readstr;
+          if (hs='void') or (hs='ignore') then
+            break;
+          inc(ops);
+          optypes[ops]:=optypes[ops]+'ot_'+formatop(hs);
+{          if s[i]=':' then
+            begin
+               inc(i);
+               optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
+            end;}
+          while s[i]='|' do
+            begin
+               inc(i);
+               optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
+            end;
+          if s[i] in [',',':'] then
+            inc(i)
+          else
+            break;
+        until false;
+        for j:=1 to 3-ops do
+          optypes[3-j+1]:='ot_none';
+        { codes }
+        skipspace;
+        j:=0;
+        last:=0;
+        if s[i] in ['\','0'..'9'] then
+          begin
+             while not(s[i] in [' ',#9]) do
+               begin
+                 code:=readnumber;
+                 { for some codes we want also to change the optypes, but not
+                   if the last byte was a 1 then this byte belongs to a direct
+                   copy }
+                 if last<>1 then
+                  begin
+                    case code of
+                      12,13,14 :
+                        optypes[code-11]:=optypes[code-11]+' or ot_signed';
+                    end;
+                  end;
+                 codes:=codes+'#'+tostr(code);
+                 last:=code;
+                 inc(j);
+               end;
+          end
+        else
+          begin
+            readstr;
+            codes:='#0';
+          end;
+        if j>maxinfolen then
+         maxinfolen:=j;
+        { flags }
+        skipspace;
+        while not(s[i] in [' ',#9,#13,#10]) and (i<=length(s)) do
+          begin
+             hs:=readstr;
+             if hs<>'ND' then
+              begin
+                if flags<>'' then
+                 flags:=flags+' or ';
+                flags:=flags+'if_'+lower(hs);
+              end;
+             if (s[i]=',') and (i<=length(s)) then
+              inc(i)
+             else
+              break;
+          end;
+        { write instruction }
+        if not skip then
+          begin
+            if not(first) then
+              writeln(insfile,',')
+            else
+              first:=false;
+            writeln(insfile,'  (');
+            writeln(insfile,'    opcode  : ',opcode,';');
+            writeln(insfile,'    ops     : ',ops,';');
+            writeln(insfile,'    optypes : (',optypes[1],',',optypes[2],',',optypes[3],',',optypes[4],');');
+            writeln(insfile,'    code    : ',codes,';');
+            writeln(insfile,'    flags   : ',flags);
+            write(insfile,'  )');
+            inc(insns);
+          end;
+     end;
+   close(infile);
+   closeinc(insfile);
+   closeinc(attfile);
+   closeinc(attsuffile);
+   closeinc(opfile);
+   writeln(nopfile,insns,';');
+   close(nopfile);
+{   closeinc(propfile); }
+   writeln(insns,' nodes procesed (maxinfolen=',maxinfolen,')');
+end.