ソースを参照

Add initial support for table generated ARM intrinsics functions

git-svn-id: branches/laksen/intrinsics@31130 -
Jeppe Johansen 10 年 前
コミット
caacc0bb5a

+ 8 - 0
.gitattributes

@@ -65,11 +65,16 @@ compiler/arm/aoptcpuc.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/armfirst.inc svneol=native#text/plain
+compiler/arm/arminnr.inc svneol=native#text/plain
 compiler/arm/armins.dat svneol=native#text/plain
+compiler/arm/armintr.dat svneol=native#text/plain
 compiler/arm/armnop.inc svneol=native#text/plain
 compiler/arm/armop.inc svneol=native#text/plain
 compiler/arm/armreg.dat svneol=native#text/plain
+compiler/arm/armsecond.inc svneol=native#text/plain
 compiler/arm/armtab.inc svneol=native#text/plain
+compiler/arm/armtype.inc svneol=native#text/plain
 compiler/arm/cgcpu.pas svneol=native#text/plain
 compiler/arm/cpubase.pas svneol=native#text/plain
 compiler/arm/cpuelf.pas svneol=native#text/plain
@@ -768,6 +773,7 @@ compiler/utils/gppc386.pp svneol=native#text/plain
 compiler/utils/mk68kreg.pp svneol=native#text/plain
 compiler/utils/mka64ins.pp svneol=native#text/plain
 compiler/utils/mka64reg.pp svneol=native#text/plain
+compiler/utils/mkarminl.pp svneol=native#text/plain
 compiler/utils/mkarmins.pp svneol=native#text/plain
 compiler/utils/mkarmreg.pp svneol=native#text/plain
 compiler/utils/mkavrreg.pp svneol=native#text/plain
@@ -8083,6 +8089,8 @@ rtl/android/mipsel/dllprt0.as svneol=native#text/plain
 rtl/android/mipsel/prt0.as svneol=native#text/plain
 rtl/arm/arm.inc svneol=native#text/plain
 rtl/arm/armdefines.inc svneol=native#text/plain
+rtl/arm/arminnr.inc svneol=native#text/plain
+rtl/arm/armprocs.inc svneol=native#text/plain
 rtl/arm/divide.inc svneol=native#text/plain
 rtl/arm/int64p.inc svneol=native#text/plain
 rtl/arm/makefile.cpu svneol=native#text/plain

+ 23 - 0
compiler/arm/aasmcpu.pas

@@ -221,6 +221,8 @@ uses
          constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
          constructor op_reg_reg_shifterop(op : tasmop;_op1,_op2 : tregister;_op3 : tshifterop);
          constructor op_reg_reg_reg_shifterop(op : tasmop;_op1,_op2,_op3 : tregister;_op4 : tshifterop);
+         constructor op_reg_const_reg(op:tasmop; _op1: tregister; _op2: aint; _op3: tregister);
+         constructor op_reg_reg_reg_const(op : tasmop;_op1,_op2,_op3 : tregister; _op4: aint);
          { SFM/LFM }
          constructor op_reg_const_ref(op : tasmop;_op1 : tregister;_op2 : aint;_op3 : treference);
 
@@ -616,6 +618,27 @@ implementation
       end;
 
 
+     constructor taicpu.op_reg_const_reg(op : tasmop;_op1 : tregister;_op2 : aint; _op3 : tregister);
+      begin
+         inherited create(op);
+         ops:=3;
+         loadreg(0,_op1);
+         loadconst(1,_op2);
+         loadreg(2,_op3);
+      end;
+
+
+    constructor taicpu.op_reg_reg_reg_const(op : tasmop;_op1,_op2,_op3 : tregister; _op4: aint);
+      begin
+         inherited create(op);
+         ops:=4;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+         loadreg(2,_op3);
+         loadconst(3,_op4);
+      end;
+
+
     constructor taicpu.op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
       begin
          inherited create(op);

+ 235 - 0
compiler/arm/armfirst.inc

@@ -0,0 +1,235 @@
+in_arm_nop
+,in_arm_yield
+,in_arm_wfi
+,in_arm_wfe
+,in_arm_sev
+,in_arm_clrex
+: //
+  begin
+    expectloc:=LOC_VOID;
+    result:=nil;
+  end;
+in_arm_setend
+: //endian:i32;
+  begin
+    expectloc:=LOC_VOID;
+    result:=nil;
+  end;
+in_arm_ldrex
+,in_arm_ldrexb
+,in_arm_ldrexh
+: //out rt:r32;ref:ptr32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_strex
+,in_arm_strexb
+,in_arm_strexh
+: //out rd:r32;rt:r32;ref:ptr32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_bfi
+: //var rd:r32;rn:r32;lsb:i32;msb:i32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_bfc
+: //var rd:r32;lsb:i32;msb:i32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_smmul
+,in_arm_smuad
+,in_arm_smuadx
+,in_arm_smulbb
+,in_arm_smulbt
+,in_arm_smultb
+,in_arm_smultt
+,in_arm_smulwb
+,in_arm_smulwt
+,in_arm_smusd
+,in_arm_smusdx
+,in_arm_pkhbt
+,in_arm_pkhtb
+: //out rd:r32;rn:r32;rm:r32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_mla
+,in_arm_mls
+,in_arm_smlabb
+,in_arm_smlabt
+,in_arm_smlatb
+,in_arm_smlatt
+,in_arm_smlad
+,in_arm_smladx
+,in_arm_smlawb
+,in_arm_smlawt
+,in_arm_smlsd
+,in_arm_smlsdx
+,in_arm_smmla
+,in_arm_smmlar
+,in_arm_smmls
+,in_arm_smmlsr
+,in_arm_usada8
+: //out rd:r32;rn:r32;rm:r32;ra:r32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_smull
+: //out ro:rs64;rn:r32;rm:r32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_umull
+: //out ro:r64;rn:r32;rm:r32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_smlal
+,in_arm_smlalbb
+,in_arm_smlalbt
+,in_arm_smlaltb
+,in_arm_smlaltt
+,in_arm_smlald
+,in_arm_smlaldx
+,in_arm_smlsldx
+,in_arm_umlal
+: //var rd:r64;rn:r32;rm:r32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_umaal
+: //out rl-rh:r64;rl:r32;rh:r32;rn:r32;rm:r32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_pkhbt_shift
+: //out rd:r32;rn:r32;rm:r32;ls:i32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_pkhtb_shift
+: //out rd:r32;rn:r32;rm:r32;rs:i32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_qadd
+,in_arm_qadd16
+,in_arm_qadd8
+,in_arm_qasx
+,in_arm_qdadd
+,in_arm_qdsub
+,in_arm_qsax
+,in_arm_qsub
+,in_arm_qsub16
+,in_arm_qsub8
+,in_arm_sadd16
+,in_arm_sadd8
+,in_arm_sasx
+,in_arm_shadd16
+,in_arm_shadd8
+,in_arm_shasx
+,in_arm_shsax
+,in_arm_shsub16
+,in_arm_shsub8
+,in_arm_ssax
+,in_arm_ssub16
+,in_arm_ssub8
+,in_arm_uadd16
+,in_arm_uadd8
+,in_arm_uasx
+,in_arm_uhadd16
+,in_arm_uhadd8
+,in_arm_uhasx
+,in_arm_uhsax
+,in_arm_uhsub16
+,in_arm_uhsub8
+,in_arm_uqadd16
+,in_arm_uqadd8
+,in_arm_uqasx
+,in_arm_uqsax
+,in_arm_uqsub16
+,in_arm_uqsub8
+,in_arm_usax
+,in_arm_usub16
+,in_arm_usub8
+,in_arm_usad8
+,in_arm_sxtab
+,in_arm_sxtab16
+,in_arm_sxtah
+,in_arm_uxtab
+,in_arm_uxtab16
+,in_arm_uxtah
+: //out rd:r32;rm:r32;rn:r32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_sxtab_ror
+,in_arm_sxtab16_ror
+,in_arm_sxtah_ror
+,in_arm_uxtab_ror
+,in_arm_uxtab16_ror
+,in_arm_uxtah_ror
+: //out rd:r32;rm:r32;rn:r32;ror:i32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_sxtb
+,in_arm_sxtb16
+,in_arm_sxth
+,in_arm_uxtb
+,in_arm_uxtb16
+,in_arm_uxth
+,in_arm_clz
+,in_arm_rbit
+,in_arm_rev
+,in_arm_rev16
+,in_arm_revsh
+: //out rd:r32;rm:r32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_sxtb_ror
+,in_arm_sxtb16_ror
+,in_arm_sxth_ror
+,in_arm_uxtb_ror
+,in_arm_uxtb16_ror
+,in_arm_uxth_ror
+: //out rd:r32;rm:r32;ror:i32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_sbfx
+,in_arm_ubfx
+: //out rd:r32;rn:r32;lsb:i32;width:i32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;
+in_arm_ssat
+,in_arm_usat
+,in_arm_ssat16
+,in_arm_usat16
+: //out rd:r32;sat:i32;rn:r32;
+  begin
+    expectloc:=LOC_REGISTER;
+    result:=nil;
+  end;

+ 138 - 0
compiler/arm/arminnr.inc

@@ -0,0 +1,138 @@
+const
+  in_arm_first = in_arm_base;
+  in_arm_nop = in_arm_base+0;
+  in_arm_yield = in_arm_base+1;
+  in_arm_wfi = in_arm_base+2;
+  in_arm_wfe = in_arm_base+3;
+  in_arm_sev = in_arm_base+4;
+  in_arm_clrex = in_arm_base+5;
+  in_arm_setend = in_arm_base+6;
+  in_arm_ldrex = in_arm_base+7;
+  in_arm_ldrexb = in_arm_base+8;
+  in_arm_ldrexh = in_arm_base+9;
+  in_arm_strex = in_arm_base+10;
+  in_arm_strexb = in_arm_base+11;
+  in_arm_strexh = in_arm_base+12;
+  in_arm_bfi = in_arm_base+13;
+  in_arm_bfc = in_arm_base+14;
+  in_arm_smmul = in_arm_base+15;
+  in_arm_smuad = in_arm_base+16;
+  in_arm_smuadx = in_arm_base+17;
+  in_arm_smulbb = in_arm_base+18;
+  in_arm_smulbt = in_arm_base+19;
+  in_arm_smultb = in_arm_base+20;
+  in_arm_smultt = in_arm_base+21;
+  in_arm_smulwb = in_arm_base+22;
+  in_arm_smulwt = in_arm_base+23;
+  in_arm_smusd = in_arm_base+24;
+  in_arm_smusdx = in_arm_base+25;
+  in_arm_mla = in_arm_base+26;
+  in_arm_mls = in_arm_base+27;
+  in_arm_smlabb = in_arm_base+28;
+  in_arm_smlabt = in_arm_base+29;
+  in_arm_smlatb = in_arm_base+30;
+  in_arm_smlatt = in_arm_base+31;
+  in_arm_smlad = in_arm_base+32;
+  in_arm_smladx = in_arm_base+33;
+  in_arm_smlawb = in_arm_base+34;
+  in_arm_smlawt = in_arm_base+35;
+  in_arm_smlsd = in_arm_base+36;
+  in_arm_smlsdx = in_arm_base+37;
+  in_arm_smmla = in_arm_base+38;
+  in_arm_smmlar = in_arm_base+39;
+  in_arm_smmls = in_arm_base+40;
+  in_arm_smmlsr = in_arm_base+41;
+  in_arm_usada8 = in_arm_base+42;
+  in_arm_smull = in_arm_base+43;
+  in_arm_umull = in_arm_base+44;
+  in_arm_smlal = in_arm_base+45;
+  in_arm_smlalbb = in_arm_base+46;
+  in_arm_smlalbt = in_arm_base+47;
+  in_arm_smlaltb = in_arm_base+48;
+  in_arm_smlaltt = in_arm_base+49;
+  in_arm_smlald = in_arm_base+50;
+  in_arm_smlaldx = in_arm_base+51;
+  in_arm_smlsldx = in_arm_base+52;
+  in_arm_umlal = in_arm_base+53;
+  in_arm_umaal = in_arm_base+54;
+  in_arm_pkhbt = in_arm_base+55;
+  in_arm_pkhtb = in_arm_base+56;
+  in_arm_pkhbt_shift = in_arm_base+57;
+  in_arm_pkhtb_shift = in_arm_base+58;
+  in_arm_qadd = in_arm_base+59;
+  in_arm_qadd16 = in_arm_base+60;
+  in_arm_qadd8 = in_arm_base+61;
+  in_arm_qasx = in_arm_base+62;
+  in_arm_qdadd = in_arm_base+63;
+  in_arm_qdsub = in_arm_base+64;
+  in_arm_qsax = in_arm_base+65;
+  in_arm_qsub = in_arm_base+66;
+  in_arm_qsub16 = in_arm_base+67;
+  in_arm_qsub8 = in_arm_base+68;
+  in_arm_sadd16 = in_arm_base+69;
+  in_arm_sadd8 = in_arm_base+70;
+  in_arm_sasx = in_arm_base+71;
+  in_arm_shadd16 = in_arm_base+72;
+  in_arm_shadd8 = in_arm_base+73;
+  in_arm_shasx = in_arm_base+74;
+  in_arm_shsax = in_arm_base+75;
+  in_arm_shsub16 = in_arm_base+76;
+  in_arm_shsub8 = in_arm_base+77;
+  in_arm_ssax = in_arm_base+78;
+  in_arm_ssub16 = in_arm_base+79;
+  in_arm_ssub8 = in_arm_base+80;
+  in_arm_uadd16 = in_arm_base+81;
+  in_arm_uadd8 = in_arm_base+82;
+  in_arm_uasx = in_arm_base+83;
+  in_arm_uhadd16 = in_arm_base+84;
+  in_arm_uhadd8 = in_arm_base+85;
+  in_arm_uhasx = in_arm_base+86;
+  in_arm_uhsax = in_arm_base+87;
+  in_arm_uhsub16 = in_arm_base+88;
+  in_arm_uhsub8 = in_arm_base+89;
+  in_arm_uqadd16 = in_arm_base+90;
+  in_arm_uqadd8 = in_arm_base+91;
+  in_arm_uqasx = in_arm_base+92;
+  in_arm_uqsax = in_arm_base+93;
+  in_arm_uqsub16 = in_arm_base+94;
+  in_arm_uqsub8 = in_arm_base+95;
+  in_arm_usax = in_arm_base+96;
+  in_arm_usub16 = in_arm_base+97;
+  in_arm_usub8 = in_arm_base+98;
+  in_arm_usad8 = in_arm_base+99;
+  in_arm_sxtab = in_arm_base+100;
+  in_arm_sxtab16 = in_arm_base+101;
+  in_arm_sxtah = in_arm_base+102;
+  in_arm_uxtab = in_arm_base+103;
+  in_arm_uxtab16 = in_arm_base+104;
+  in_arm_uxtah = in_arm_base+105;
+  in_arm_sxtab_ror = in_arm_base+106;
+  in_arm_sxtab16_ror = in_arm_base+107;
+  in_arm_sxtah_ror = in_arm_base+108;
+  in_arm_uxtab_ror = in_arm_base+109;
+  in_arm_uxtab16_ror = in_arm_base+110;
+  in_arm_uxtah_ror = in_arm_base+111;
+  in_arm_sxtb = in_arm_base+112;
+  in_arm_sxtb16 = in_arm_base+113;
+  in_arm_sxth = in_arm_base+114;
+  in_arm_uxtb = in_arm_base+115;
+  in_arm_uxtb16 = in_arm_base+116;
+  in_arm_uxth = in_arm_base+117;
+  in_arm_sxtb_ror = in_arm_base+118;
+  in_arm_sxtb16_ror = in_arm_base+119;
+  in_arm_sxth_ror = in_arm_base+120;
+  in_arm_uxtb_ror = in_arm_base+121;
+  in_arm_uxtb16_ror = in_arm_base+122;
+  in_arm_uxth_ror = in_arm_base+123;
+  in_arm_clz = in_arm_base+124;
+  in_arm_rbit = in_arm_base+125;
+  in_arm_rev = in_arm_base+126;
+  in_arm_rev16 = in_arm_base+127;
+  in_arm_revsh = in_arm_base+128;
+  in_arm_sbfx = in_arm_base+129;
+  in_arm_ubfx = in_arm_base+130;
+  in_arm_ssat = in_arm_base+131;
+  in_arm_usat = in_arm_base+132;
+  in_arm_ssat16 = in_arm_base+133;
+  in_arm_usat16 = in_arm_base+134;
+  in_arm_last = in_arm_base+134;

+ 154 - 0
compiler/arm/armintr.dat

@@ -0,0 +1,154 @@
+nop()
+yield()
+wfi()
+wfe()
+sev()
+;rfe()
+clrex()
+setend(endian: i32)                                       (endian in [0..1])
+
+ldrex(out rt: r32; ref: ptr32)
+ldrexb(out rt: r32; ref: ptr32)
+ldrexh(out rt: r32; ref: ptr32)
+
+strex(out rd: r32; rt: r32; ref: ptr32)
+strexb(out rd: r32; rt: r32; ref: ptr32)
+strexh(out rd: r32; rt: r32; ref: ptr32)
+
+bfi(var rd: r32; rn: r32; lsb, msb: i32)                  (lsb in [0..31]) and (msb in [0..31]) and (msb >= lsb)
+bfc(var rd: r32; lsb, msb: i32)                           (lsb in [0..31]) and (msb in [0..31]) and (msb >= lsb)
+
+smmul(out rd: r32; rn, rm: r32)
+smuad(out rd: r32; rn, rm: r32)
+smuad{x}(out rd: r32; rn, rm: r32)
+smulbb(out rd: r32; rn, rm: r32)
+smulbt(out rd: r32; rn, rm: r32)
+smultb(out rd: r32; rn, rm: r32)
+smultt(out rd: r32; rn, rm: r32)
+smulwb(out rd: r32; rn, rm: r32)
+smulwt(out rd: r32; rn, rm: r32)
+smusd(out rd: r32; rn, rm: r32)
+smusd{x}(out rd: r32; rn, rm: r32)
+
+mla(out rd: r32; rn, rm, ra: r32)
+mls(out rd: r32; rn, rm, ra: r32)
+smlabb(out rd: r32; rn, rm, ra: r32)
+smlabt(out rd: r32; rn, rm, ra: r32)
+smlatb(out rd: r32; rn, rm, ra: r32)
+smlatt(out rd: r32; rn, rm, ra: r32)
+smlad(out rd: r32; rn, rm, ra: r32)
+smlad{x}(out rd: r32; rn, rm, ra: r32)
+smlawb(out rd: r32; rn, rm, ra: r32)
+smlawt(out rd: r32; rn, rm, ra: r32)
+smlsd(out rd: r32; rn, rm, ra: r32)
+smlsd{x}(out rd: r32; rn, rm, ra: r32)
+smmla(out rd: r32; rn, rm, ra: r32)
+smmla{r}(out rd: r32; rn, rm, ra: r32)
+smmls(out rd: r32; rn, rm, ra: r32)
+smmls{r}(out rd: r32; rn, rm, ra: r32)
+usada8(out rd: r32; rn, rm, ra: r32)
+
+smull(out ro: rs64; rn,rm: r32)
+umull(out ro: r64; rn,rm: r32)
+
+smlal(var rd: r64; rn,rm: r32)
+smlalbb(var rd: r64; rn,rm: r32)
+smlalbt(var rd: r64; rn,rm: r32)
+smlaltb(var rd: r64; rn,rm: r32)
+smlaltt(var rd: r64; rn,rm: r32)
+smlald(var rd: r64; rn,rm: r32)
+smlald{x}(var rd: r64; rn,rm: r32)
+smlsld{x}(var rd: r64; rn,rm: r32)
+umlal(var rd: r64; rn,rm: r32)
+
+umaal(out [rl,rh]: r64; rl, rh, rn,rm: r32)
+
+pkhbt(out rd: r32; rn,rm: r32)
+pkhtb(out rd: r32; rn,rm: r32)
+pkhbt[shift](out rd: r32; rn,rm: r32; ls: i32)                     (ls in [0..31])
+pkhtb[shift](out rd: r32; rn,rm: r32; rs: i32)                     (ls in [0..31])
+
+qadd(out rd: r32; rm,rn: r32)
+qadd16(out rd: r32; rm,rn: r32)
+qadd8(out rd: r32; rm,rn: r32)
+qasx(out rd: r32; rm,rn: r32)
+qdadd(out rd: r32; rm,rn: r32)
+qdsub(out rd: r32; rm,rn: r32)
+qsax(out rd: r32; rm,rn: r32)
+qsub(out rd: r32; rm,rn: r32)
+qsub16(out rd: r32; rm,rn: r32)
+qsub8(out rd: r32; rm,rn: r32)
+sadd16(out rd: r32; rm,rn: r32)
+sadd8(out rd: r32; rm,rn: r32)
+sasx(out rd: r32; rm,rn: r32)
+shadd16(out rd: r32; rm,rn: r32)
+shadd8(out rd: r32; rm,rn: r32)
+shasx(out rd: r32; rm,rn: r32)
+shsax(out rd: r32; rm,rn: r32)
+shsub16(out rd: r32; rm,rn: r32)
+shsub8(out rd: r32; rm,rn: r32)
+ssax(out rd: r32; rm,rn: r32)
+ssub16(out rd: r32; rm,rn: r32)
+ssub8(out rd: r32; rm,rn: r32)
+uadd16(out rd: r32; rm,rn: r32)
+uadd8(out rd: r32; rm,rn: r32)
+uasx(out rd: r32; rm,rn: r32)
+uhadd16(out rd: r32; rm,rn: r32)
+uhadd8(out rd: r32; rm,rn: r32)
+uhasx(out rd: r32; rm,rn: r32)
+uhsax(out rd: r32; rm,rn: r32)
+uhsub16(out rd: r32; rm,rn: r32)
+uhsub8(out rd: r32; rm,rn: r32)
+uqadd16(out rd: r32; rm,rn: r32)
+uqadd8(out rd: r32; rm,rn: r32)
+uqasx(out rd: r32; rm,rn: r32)
+uqsax(out rd: r32; rm,rn: r32)
+uqsub16(out rd: r32; rm,rn: r32)
+uqsub8(out rd: r32; rm,rn: r32)
+usax(out rd: r32; rm,rn: r32)
+usub16(out rd: r32; rm,rn: r32)
+usub8(out rd: r32; rm,rn: r32)
+usad8(out rd: r32; rm,rn: r32)
+
+sxtab(out rd: r32; rm,rn: r32)
+sxtab16(out rd: r32; rm,rn: r32)
+sxtah(out rd: r32; rm,rn: r32)
+uxtab(out rd: r32; rm,rn: r32)
+uxtab16(out rd: r32; rm,rn: r32)
+uxtah(out rd: r32; rm,rn: r32)
+
+sxtab[ror](out rd: r32; rm,rn: r32; ror: i32)                    (ls in [0,8,16,24])
+sxtab16[ror](out rd: r32; rm,rn: r32; ror: i32)                  (ls in [0,8,16,24])
+sxtah[ror](out rd: r32; rm,rn: r32; ror: i32)                    (ls in [0,8,16,24])
+uxtab[ror](out rd: r32; rm,rn: r32; ror: i32)                    (ls in [0,8,16,24])
+uxtab16[ror](out rd: r32; rm,rn: r32; ror: i32)                  (ls in [0,8,16,24])
+uxtah[ror](out rd: r32; rm,rn: r32; ror: i32)                    (ls in [0,8,16,24])
+
+sxtb(out rd: r32; rm: r32)
+sxtb16(out rd: r32; rm: r32)
+sxth(out rd: r32; rm: r32)
+uxtb(out rd: r32; rm: r32)
+uxtb16(out rd: r32; rm: r32)
+uxth(out rd: r32; rm: r32)
+
+sxtb[ror](out rd: r32; rm: r32; ror: i32)                        (ls in [0,8,16,24])
+sxtb16[ror](out rd: r32; rm: r32; ror: i32)                      (ls in [0,8,16,24])
+sxth[ror](out rd: r32; rm: r32; ror: i32)                        (ls in [0,8,16,24])
+uxtb[ror](out rd: r32; rm: r32; ror: i32)                        (ls in [0,8,16,24])
+uxtb16[ror](out rd: r32; rm: r32; ror: i32)                      (ls in [0,8,16,24])
+uxth[ror](out rd: r32; rm: r32; ror: i32)                        (ls in [0,8,16,24])
+
+clz(out rd: r32; rm: r32)
+rbit(out rd: r32; rm: r32)
+rev(out rd: r32; rm: r32)
+rev16(out rd: r32; rm: r32)
+revsh(out rd: r32; rm: r32)
+
+sbfx(out rd: r32; rn: r32; lsb, width: i32)                 (lsb in [0..31]) and ((width+lsb-1) <= 31)
+ubfx(out rd: r32; rn: r32; lsb, width: i32)                 (lsb in [0..31]) and ((width+lsb-1) <= 31)
+
+ssat(out rd: r32; sat: i32; rn: r32)                        (sat in [1..32])
+usat(out rd: r32; sat: i32; rn: r32)                        (sat in [1..32])
+
+ssat16(out rd: r32; sat: i32; rn: r32)                      (sat in [1..32])
+usat16(out rd: r32; sat: i32; rn: r32)                      (sat in [1..32])          

+ 558 - 0
compiler/arm/armsecond.inc

@@ -0,0 +1,558 @@
+in_arm_nop
+,in_arm_yield
+,in_arm_wfi
+,in_arm_wfe
+,in_arm_sev
+,in_arm_clrex
+: //
+  begin
+    case inlinenumber of
+      in_arm_clrex: begin op:=A_clrex; pf:=PF_None; end;
+      in_arm_sev: begin op:=A_sev; pf:=PF_None; end;
+      in_arm_wfe: begin op:=A_wfe; pf:=PF_None; end;
+      in_arm_wfi: begin op:=A_wfi; pf:=PF_None; end;
+      in_arm_yield: begin op:=A_yield; pf:=PF_None; end;
+      in_arm_nop: begin op:=A_nop; pf:=PF_None; end;
+    end;
+
+    GetParameters(0);
+
+    for i := 1 to 0 do secondpass(paraarray[i]);
+
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_none(op),pf));
+  end;
+in_arm_setend
+: //endian:i32;
+  begin
+    case inlinenumber of
+      in_arm_setend: begin op:=A_setend; pf:=PF_None; end;
+    end;
+
+    GetParameters(1);
+
+    for i := 1 to 1 do secondpass(paraarray[i]);
+
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_const(op,GetConstInt(paraarray[1])),pf));
+  end;
+in_arm_ldrex
+,in_arm_ldrexb
+,in_arm_ldrexh
+: //out rt:r32;ref:ptr32;
+  begin
+    case inlinenumber of
+      in_arm_ldrexh: begin op:=A_ldrexh; pf:=PF_None; end;
+      in_arm_ldrexb: begin op:=A_ldrexb; pf:=PF_None; end;
+      in_arm_ldrex: begin op:=A_ldrex; pf:=PF_None; end;
+    end;
+
+    GetParameters(1);
+
+    for i := 1 to 1 do secondpass(paraarray[i]);
+
+    location_make_ref(paraarray[1].location);
+    location_reset(location,LOC_REGISTER,OS_32);
+    location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_ref(op,location.register,paraarray[1].location.reference),pf));
+  end;
+in_arm_strex
+,in_arm_strexb
+,in_arm_strexh
+: //out rd:r32;rt:r32;ref:ptr32;
+  begin
+    case inlinenumber of
+      in_arm_strexh: begin op:=A_strexh; pf:=PF_None; end;
+      in_arm_strexb: begin op:=A_strexb; pf:=PF_None; end;
+      in_arm_strex: begin op:=A_strex; pf:=PF_None; end;
+    end;
+
+    GetParameters(2);
+
+    for i := 1 to 2 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u32inttype,true);
+    location_make_ref(paraarray[2].location);
+    location_reset(location,LOC_REGISTER,OS_32);
+    location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_ref(op,location.register,paraarray[1].location.register,paraarray[2].location.reference),pf));
+  end;
+in_arm_bfi
+: //var rd:r32;rn:r32;lsb:i32;msb:i32;
+  begin
+    case inlinenumber of
+      in_arm_bfi: begin op:=A_bfi; pf:=PF_None; end;
+    end;
+
+    GetParameters(4);
+
+    for i := 1 to 4 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u32inttype,false);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[2].location, paraarray[2].resultdef,u32inttype,true);
+    location:=paraarray[1].location;
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_const_const(op,paraarray[1].location.register,paraarray[2].location.register,GetConstInt(paraarray[3]),GetConstInt(paraarray[4])),pf));
+  end;
+in_arm_bfc
+: //var rd:r32;lsb:i32;msb:i32;
+  begin
+    case inlinenumber of
+      in_arm_bfc: begin op:=A_bfc; pf:=PF_None; end;
+    end;
+
+    GetParameters(3);
+
+    for i := 1 to 3 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u32inttype,false);
+    location:=paraarray[1].location;
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_const_const(op,paraarray[1].location.register,GetConstInt(paraarray[2]),GetConstInt(paraarray[3])),pf));
+  end;
+in_arm_smmul
+,in_arm_smuad
+,in_arm_smuadx
+,in_arm_smulbb
+,in_arm_smulbt
+,in_arm_smultb
+,in_arm_smultt
+,in_arm_smulwb
+,in_arm_smulwt
+,in_arm_smusd
+,in_arm_smusdx
+,in_arm_pkhbt
+,in_arm_pkhtb
+: //out rd:r32;rn:r32;rm:r32;
+  begin
+    case inlinenumber of
+      in_arm_pkhtb: begin op:=A_pkhtb; pf:=PF_None; end;
+      in_arm_pkhbt: begin op:=A_pkhbt; pf:=PF_None; end;
+      in_arm_smusdx: begin op:=A_smusd; pf:=PF_x; end;
+      in_arm_smusd: begin op:=A_smusd; pf:=PF_None; end;
+      in_arm_smulwt: begin op:=A_smulwt; pf:=PF_None; end;
+      in_arm_smulwb: begin op:=A_smulwb; pf:=PF_None; end;
+      in_arm_smultt: begin op:=A_smultt; pf:=PF_None; end;
+      in_arm_smultb: begin op:=A_smultb; pf:=PF_None; end;
+      in_arm_smulbt: begin op:=A_smulbt; pf:=PF_None; end;
+      in_arm_smulbb: begin op:=A_smulbb; pf:=PF_None; end;
+      in_arm_smuadx: begin op:=A_smuad; pf:=PF_x; end;
+      in_arm_smuad: begin op:=A_smuad; pf:=PF_None; end;
+      in_arm_smmul: begin op:=A_smmul; pf:=PF_None; end;
+    end;
+
+    GetParameters(2);
+
+    for i := 1 to 2 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u32inttype,true);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[2].location, paraarray[2].resultdef,u32inttype,true);
+    location_reset(location,LOC_REGISTER,OS_32);
+    location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(op,location.register,paraarray[1].location.register,paraarray[2].location.register),pf));
+  end;
+in_arm_mla
+,in_arm_mls
+,in_arm_smlabb
+,in_arm_smlabt
+,in_arm_smlatb
+,in_arm_smlatt
+,in_arm_smlad
+,in_arm_smladx
+,in_arm_smlawb
+,in_arm_smlawt
+,in_arm_smlsd
+,in_arm_smlsdx
+,in_arm_smmla
+,in_arm_smmlar
+,in_arm_smmls
+,in_arm_smmlsr
+,in_arm_usada8
+: //out rd:r32;rn:r32;rm:r32;ra:r32;
+  begin
+    case inlinenumber of
+      in_arm_usada8: begin op:=A_usada8; pf:=PF_None; end;
+      in_arm_smmlsr: begin op:=A_smmls; pf:=PF_r; end;
+      in_arm_smmls: begin op:=A_smmls; pf:=PF_None; end;
+      in_arm_smmlar: begin op:=A_smmla; pf:=PF_r; end;
+      in_arm_smmla: begin op:=A_smmla; pf:=PF_None; end;
+      in_arm_smlsdx: begin op:=A_smlsd; pf:=PF_x; end;
+      in_arm_smlsd: begin op:=A_smlsd; pf:=PF_None; end;
+      in_arm_smlawt: begin op:=A_smlawt; pf:=PF_None; end;
+      in_arm_smlawb: begin op:=A_smlawb; pf:=PF_None; end;
+      in_arm_smladx: begin op:=A_smlad; pf:=PF_x; end;
+      in_arm_smlad: begin op:=A_smlad; pf:=PF_None; end;
+      in_arm_smlatt: begin op:=A_smlatt; pf:=PF_None; end;
+      in_arm_smlatb: begin op:=A_smlatb; pf:=PF_None; end;
+      in_arm_smlabt: begin op:=A_smlabt; pf:=PF_None; end;
+      in_arm_smlabb: begin op:=A_smlabb; pf:=PF_None; end;
+      in_arm_mls: begin op:=A_mls; pf:=PF_None; end;
+      in_arm_mla: begin op:=A_mla; pf:=PF_None; end;
+    end;
+
+    GetParameters(3);
+
+    for i := 1 to 3 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u32inttype,true);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[2].location, paraarray[2].resultdef,u32inttype,true);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[3].location, paraarray[3].resultdef,u32inttype,true);
+    location_reset(location,LOC_REGISTER,OS_32);
+    location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg_reg(op,location.register,paraarray[1].location.register,paraarray[2].location.register,paraarray[3].location.register),pf));
+  end;
+in_arm_smull
+: //out ro:rs64;rn:r32;rm:r32;
+  begin
+    case inlinenumber of
+      in_arm_smull: begin op:=A_smull; pf:=PF_None; end;
+    end;
+
+    GetParameters(2);
+
+    for i := 1 to 2 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u32inttype,true);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[2].location, paraarray[2].resultdef,u32inttype,true);
+    location_reset(location,LOC_REGISTER,OS_S64);
+    location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList, OS_32); location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg_reg(op,location.register64.reglo,location.register64.reghi,paraarray[1].location.register,paraarray[2].location.register),pf));
+  end;
+in_arm_umull
+: //out ro:r64;rn:r32;rm:r32;
+  begin
+    case inlinenumber of
+      in_arm_umull: begin op:=A_umull; pf:=PF_None; end;
+    end;
+
+    GetParameters(2);
+
+    for i := 1 to 2 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u32inttype,true);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[2].location, paraarray[2].resultdef,u32inttype,true);
+    location_reset(location,LOC_REGISTER,OS_64);
+    location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList, OS_32); location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg_reg(op,location.register64.reglo,location.register64.reghi,paraarray[1].location.register,paraarray[2].location.register),pf));
+  end;
+in_arm_smlal
+,in_arm_smlalbb
+,in_arm_smlalbt
+,in_arm_smlaltb
+,in_arm_smlaltt
+,in_arm_smlald
+,in_arm_smlaldx
+,in_arm_smlsldx
+,in_arm_umlal
+: //var rd:r64;rn:r32;rm:r32;
+  begin
+    case inlinenumber of
+      in_arm_umlal: begin op:=A_umlal; pf:=PF_None; end;
+      in_arm_smlsldx: begin op:=A_smlsld; pf:=PF_x; end;
+      in_arm_smlaldx: begin op:=A_smlald; pf:=PF_x; end;
+      in_arm_smlald: begin op:=A_smlald; pf:=PF_None; end;
+      in_arm_smlaltt: begin op:=A_smlaltt; pf:=PF_None; end;
+      in_arm_smlaltb: begin op:=A_smlaltb; pf:=PF_None; end;
+      in_arm_smlalbt: begin op:=A_smlalbt; pf:=PF_None; end;
+      in_arm_smlalbb: begin op:=A_smlalbb; pf:=PF_None; end;
+      in_arm_smlal: begin op:=A_smlal; pf:=PF_None; end;
+    end;
+
+    GetParameters(3);
+
+    for i := 1 to 3 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u64inttype,false);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[2].location, paraarray[2].resultdef,u32inttype,true);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[3].location, paraarray[3].resultdef,u32inttype,true);
+    location:=paraarray[1].location;
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg_reg(op,paraarray[1].location.register64.reglo,paraarray[1].location.register64.reghi,paraarray[2].location.register,paraarray[3].location.register),pf));
+  end;
+in_arm_umaal
+: //out rl-rh:r64;rl:r32;rh:r32;rn:r32;rm:r32;
+  begin
+    case inlinenumber of
+      in_arm_umaal: begin op:=A_umaal; pf:=PF_None; end;
+    end;
+
+    GetParameters(4);
+
+    for i := 1 to 4 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u32inttype,true);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[2].location, paraarray[2].resultdef,u32inttype,true);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[3].location, paraarray[3].resultdef,u32inttype,true);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[4].location, paraarray[4].resultdef,u32inttype,true);
+    location_reset(location,LOC_REGISTER,OS_64);
+    location.register64.reglo:=paraarray[1].location.register;
+    location.register64.reghi:=paraarray[2].location.register;
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg_reg(op,paraarray[1].location.register,paraarray[2].location.register,paraarray[3].location.register,paraarray[4].location.register),pf));
+  end;
+in_arm_pkhbt_shift
+: //out rd:r32;rn:r32;rm:r32;ls:i32;
+  begin
+    case inlinenumber of
+      in_arm_pkhbt_shift: begin op:=A_pkhbt; pf:=PF_None; end;
+    end;
+
+    GetParameters(3);
+
+    for i := 1 to 3 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u32inttype,true);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[2].location, paraarray[2].resultdef,u32inttype,true);
+    location_reset(location,LOC_REGISTER,OS_32);
+    location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg_const(op,location.register,paraarray[1].location.register,paraarray[2].location.register,GetConstInt(paraarray[3])),pf));
+  end;
+in_arm_pkhtb_shift
+: //out rd:r32;rn:r32;rm:r32;rs:i32;
+  begin
+    case inlinenumber of
+      in_arm_pkhtb_shift: begin op:=A_pkhtb; pf:=PF_None; end;
+    end;
+
+    GetParameters(3);
+
+    for i := 1 to 3 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u32inttype,true);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[2].location, paraarray[2].resultdef,u32inttype,true);
+    location_reset(location,LOC_REGISTER,OS_32);
+    location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg_const(op,location.register,paraarray[1].location.register,paraarray[2].location.register,GetConstInt(paraarray[3])),pf));
+  end;
+in_arm_qadd
+,in_arm_qadd16
+,in_arm_qadd8
+,in_arm_qasx
+,in_arm_qdadd
+,in_arm_qdsub
+,in_arm_qsax
+,in_arm_qsub
+,in_arm_qsub16
+,in_arm_qsub8
+,in_arm_sadd16
+,in_arm_sadd8
+,in_arm_sasx
+,in_arm_shadd16
+,in_arm_shadd8
+,in_arm_shasx
+,in_arm_shsax
+,in_arm_shsub16
+,in_arm_shsub8
+,in_arm_ssax
+,in_arm_ssub16
+,in_arm_ssub8
+,in_arm_uadd16
+,in_arm_uadd8
+,in_arm_uasx
+,in_arm_uhadd16
+,in_arm_uhadd8
+,in_arm_uhasx
+,in_arm_uhsax
+,in_arm_uhsub16
+,in_arm_uhsub8
+,in_arm_uqadd16
+,in_arm_uqadd8
+,in_arm_uqasx
+,in_arm_uqsax
+,in_arm_uqsub16
+,in_arm_uqsub8
+,in_arm_usax
+,in_arm_usub16
+,in_arm_usub8
+,in_arm_usad8
+,in_arm_sxtab
+,in_arm_sxtab16
+,in_arm_sxtah
+,in_arm_uxtab
+,in_arm_uxtab16
+,in_arm_uxtah
+: //out rd:r32;rm:r32;rn:r32;
+  begin
+    case inlinenumber of
+      in_arm_uxtah: begin op:=A_uxtah; pf:=PF_None; end;
+      in_arm_uxtab16: begin op:=A_uxtab16; pf:=PF_None; end;
+      in_arm_uxtab: begin op:=A_uxtab; pf:=PF_None; end;
+      in_arm_sxtah: begin op:=A_sxtah; pf:=PF_None; end;
+      in_arm_sxtab16: begin op:=A_sxtab16; pf:=PF_None; end;
+      in_arm_sxtab: begin op:=A_sxtab; pf:=PF_None; end;
+      in_arm_usad8: begin op:=A_usad8; pf:=PF_None; end;
+      in_arm_usub8: begin op:=A_usub8; pf:=PF_None; end;
+      in_arm_usub16: begin op:=A_usub16; pf:=PF_None; end;
+      in_arm_usax: begin op:=A_usax; pf:=PF_None; end;
+      in_arm_uqsub8: begin op:=A_uqsub8; pf:=PF_None; end;
+      in_arm_uqsub16: begin op:=A_uqsub16; pf:=PF_None; end;
+      in_arm_uqsax: begin op:=A_uqsax; pf:=PF_None; end;
+      in_arm_uqasx: begin op:=A_uqasx; pf:=PF_None; end;
+      in_arm_uqadd8: begin op:=A_uqadd8; pf:=PF_None; end;
+      in_arm_uqadd16: begin op:=A_uqadd16; pf:=PF_None; end;
+      in_arm_uhsub8: begin op:=A_uhsub8; pf:=PF_None; end;
+      in_arm_uhsub16: begin op:=A_uhsub16; pf:=PF_None; end;
+      in_arm_uhsax: begin op:=A_uhsax; pf:=PF_None; end;
+      in_arm_uhasx: begin op:=A_uhasx; pf:=PF_None; end;
+      in_arm_uhadd8: begin op:=A_uhadd8; pf:=PF_None; end;
+      in_arm_uhadd16: begin op:=A_uhadd16; pf:=PF_None; end;
+      in_arm_uasx: begin op:=A_uasx; pf:=PF_None; end;
+      in_arm_uadd8: begin op:=A_uadd8; pf:=PF_None; end;
+      in_arm_uadd16: begin op:=A_uadd16; pf:=PF_None; end;
+      in_arm_ssub8: begin op:=A_ssub8; pf:=PF_None; end;
+      in_arm_ssub16: begin op:=A_ssub16; pf:=PF_None; end;
+      in_arm_ssax: begin op:=A_ssax; pf:=PF_None; end;
+      in_arm_shsub8: begin op:=A_shsub8; pf:=PF_None; end;
+      in_arm_shsub16: begin op:=A_shsub16; pf:=PF_None; end;
+      in_arm_shsax: begin op:=A_shsax; pf:=PF_None; end;
+      in_arm_shasx: begin op:=A_shasx; pf:=PF_None; end;
+      in_arm_shadd8: begin op:=A_shadd8; pf:=PF_None; end;
+      in_arm_shadd16: begin op:=A_shadd16; pf:=PF_None; end;
+      in_arm_sasx: begin op:=A_sasx; pf:=PF_None; end;
+      in_arm_sadd8: begin op:=A_sadd8; pf:=PF_None; end;
+      in_arm_sadd16: begin op:=A_sadd16; pf:=PF_None; end;
+      in_arm_qsub8: begin op:=A_qsub8; pf:=PF_None; end;
+      in_arm_qsub16: begin op:=A_qsub16; pf:=PF_None; end;
+      in_arm_qsub: begin op:=A_qsub; pf:=PF_None; end;
+      in_arm_qsax: begin op:=A_qsax; pf:=PF_None; end;
+      in_arm_qdsub: begin op:=A_qdsub; pf:=PF_None; end;
+      in_arm_qdadd: begin op:=A_qdadd; pf:=PF_None; end;
+      in_arm_qasx: begin op:=A_qasx; pf:=PF_None; end;
+      in_arm_qadd8: begin op:=A_qadd8; pf:=PF_None; end;
+      in_arm_qadd16: begin op:=A_qadd16; pf:=PF_None; end;
+      in_arm_qadd: begin op:=A_qadd; pf:=PF_None; end;
+    end;
+
+    GetParameters(2);
+
+    for i := 1 to 2 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u32inttype,true);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[2].location, paraarray[2].resultdef,u32inttype,true);
+    location_reset(location,LOC_REGISTER,OS_32);
+    location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(op,location.register,paraarray[1].location.register,paraarray[2].location.register),pf));
+  end;
+in_arm_sxtab_ror
+,in_arm_sxtab16_ror
+,in_arm_sxtah_ror
+,in_arm_uxtab_ror
+,in_arm_uxtab16_ror
+,in_arm_uxtah_ror
+: //out rd:r32;rm:r32;rn:r32;ror:i32;
+  begin
+    case inlinenumber of
+      in_arm_uxtah_ror: begin op:=A_uxtah; pf:=PF_None; end;
+      in_arm_uxtab16_ror: begin op:=A_uxtab16; pf:=PF_None; end;
+      in_arm_uxtab_ror: begin op:=A_uxtab; pf:=PF_None; end;
+      in_arm_sxtah_ror: begin op:=A_sxtah; pf:=PF_None; end;
+      in_arm_sxtab16_ror: begin op:=A_sxtab16; pf:=PF_None; end;
+      in_arm_sxtab_ror: begin op:=A_sxtab; pf:=PF_None; end;
+    end;
+
+    GetParameters(3);
+
+    for i := 1 to 3 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u32inttype,true);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[2].location, paraarray[2].resultdef,u32inttype,true);
+    location_reset(location,LOC_REGISTER,OS_32);
+    location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg_const(op,location.register,paraarray[1].location.register,paraarray[2].location.register,GetConstInt(paraarray[3])),pf));
+  end;
+in_arm_sxtb
+,in_arm_sxtb16
+,in_arm_sxth
+,in_arm_uxtb
+,in_arm_uxtb16
+,in_arm_uxth
+,in_arm_clz
+,in_arm_rbit
+,in_arm_rev
+,in_arm_rev16
+,in_arm_revsh
+: //out rd:r32;rm:r32;
+  begin
+    case inlinenumber of
+      in_arm_revsh: begin op:=A_revsh; pf:=PF_None; end;
+      in_arm_rev16: begin op:=A_rev16; pf:=PF_None; end;
+      in_arm_rev: begin op:=A_rev; pf:=PF_None; end;
+      in_arm_rbit: begin op:=A_rbit; pf:=PF_None; end;
+      in_arm_clz: begin op:=A_clz; pf:=PF_None; end;
+      in_arm_uxth: begin op:=A_uxth; pf:=PF_None; end;
+      in_arm_uxtb16: begin op:=A_uxtb16; pf:=PF_None; end;
+      in_arm_uxtb: begin op:=A_uxtb; pf:=PF_None; end;
+      in_arm_sxth: begin op:=A_sxth; pf:=PF_None; end;
+      in_arm_sxtb16: begin op:=A_sxtb16; pf:=PF_None; end;
+      in_arm_sxtb: begin op:=A_sxtb; pf:=PF_None; end;
+    end;
+
+    GetParameters(1);
+
+    for i := 1 to 1 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u32inttype,true);
+    location_reset(location,LOC_REGISTER,OS_32);
+    location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(op,location.register,paraarray[1].location.register),pf));
+  end;
+in_arm_sxtb_ror
+,in_arm_sxtb16_ror
+,in_arm_sxth_ror
+,in_arm_uxtb_ror
+,in_arm_uxtb16_ror
+,in_arm_uxth_ror
+: //out rd:r32;rm:r32;ror:i32;
+  begin
+    case inlinenumber of
+      in_arm_uxth_ror: begin op:=A_uxth; pf:=PF_None; end;
+      in_arm_uxtb16_ror: begin op:=A_uxtb16; pf:=PF_None; end;
+      in_arm_uxtb_ror: begin op:=A_uxtb; pf:=PF_None; end;
+      in_arm_sxth_ror: begin op:=A_sxth; pf:=PF_None; end;
+      in_arm_sxtb16_ror: begin op:=A_sxtb16; pf:=PF_None; end;
+      in_arm_sxtb_ror: begin op:=A_sxtb; pf:=PF_None; end;
+    end;
+
+    GetParameters(2);
+
+    for i := 1 to 2 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u32inttype,true);
+    location_reset(location,LOC_REGISTER,OS_32);
+    location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_const(op,location.register,paraarray[1].location.register,GetConstInt(paraarray[2])),pf));
+  end;
+in_arm_sbfx
+,in_arm_ubfx
+: //out rd:r32;rn:r32;lsb:i32;width:i32;
+  begin
+    case inlinenumber of
+      in_arm_ubfx: begin op:=A_ubfx; pf:=PF_None; end;
+      in_arm_sbfx: begin op:=A_sbfx; pf:=PF_None; end;
+    end;
+
+    GetParameters(3);
+
+    for i := 1 to 3 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[1].location, paraarray[1].resultdef,u32inttype,true);
+    location_reset(location,LOC_REGISTER,OS_32);
+    location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_const_const(op,location.register,paraarray[1].location.register,GetConstInt(paraarray[2]),GetConstInt(paraarray[3])),pf));
+  end;
+in_arm_ssat
+,in_arm_usat
+,in_arm_ssat16
+,in_arm_usat16
+: //out rd:r32;sat:i32;rn:r32;
+  begin
+    case inlinenumber of
+      in_arm_usat16: begin op:=A_usat16; pf:=PF_None; end;
+      in_arm_ssat16: begin op:=A_ssat16; pf:=PF_None; end;
+      in_arm_usat: begin op:=A_usat; pf:=PF_None; end;
+      in_arm_ssat: begin op:=A_ssat; pf:=PF_None; end;
+    end;
+
+    GetParameters(2);
+
+    for i := 1 to 2 do secondpass(paraarray[i]);
+
+    hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[2].location, paraarray[2].resultdef,u32inttype,true);
+    location_reset(location,LOC_REGISTER,OS_32);
+    location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);
+    current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_const_reg(op,location.register,GetConstInt(paraarray[1]),paraarray[2].location.register),pf));
+  end;

+ 235 - 0
compiler/arm/armtype.inc

@@ -0,0 +1,235 @@
+in_arm_nop
+,in_arm_yield
+,in_arm_wfi
+,in_arm_wfe
+,in_arm_sev
+,in_arm_clrex
+: //
+  begin
+    CheckParameters(0);
+    resultdef:=voidtype;
+  end;
+in_arm_setend
+: //endian:i32;
+  begin
+    CheckParameters(1);
+    resultdef:=voidtype;
+  end;
+in_arm_ldrex
+,in_arm_ldrexb
+,in_arm_ldrexh
+: //out rt:r32;ref:ptr32;
+  begin
+    CheckParameters(1);
+    resultdef:=u32inttype;
+  end;
+in_arm_strex
+,in_arm_strexb
+,in_arm_strexh
+: //out rd:r32;rt:r32;ref:ptr32;
+  begin
+    CheckParameters(2);
+    resultdef:=u32inttype;
+  end;
+in_arm_bfi
+: //var rd:r32;rn:r32;lsb:i32;msb:i32;
+  begin
+    CheckParameters(4);
+    resultdef:=u32inttype;
+  end;
+in_arm_bfc
+: //var rd:r32;lsb:i32;msb:i32;
+  begin
+    CheckParameters(3);
+    resultdef:=u32inttype;
+  end;
+in_arm_smmul
+,in_arm_smuad
+,in_arm_smuadx
+,in_arm_smulbb
+,in_arm_smulbt
+,in_arm_smultb
+,in_arm_smultt
+,in_arm_smulwb
+,in_arm_smulwt
+,in_arm_smusd
+,in_arm_smusdx
+,in_arm_pkhbt
+,in_arm_pkhtb
+: //out rd:r32;rn:r32;rm:r32;
+  begin
+    CheckParameters(2);
+    resultdef:=u32inttype;
+  end;
+in_arm_mla
+,in_arm_mls
+,in_arm_smlabb
+,in_arm_smlabt
+,in_arm_smlatb
+,in_arm_smlatt
+,in_arm_smlad
+,in_arm_smladx
+,in_arm_smlawb
+,in_arm_smlawt
+,in_arm_smlsd
+,in_arm_smlsdx
+,in_arm_smmla
+,in_arm_smmlar
+,in_arm_smmls
+,in_arm_smmlsr
+,in_arm_usada8
+: //out rd:r32;rn:r32;rm:r32;ra:r32;
+  begin
+    CheckParameters(3);
+    resultdef:=u32inttype;
+  end;
+in_arm_smull
+: //out ro:rs64;rn:r32;rm:r32;
+  begin
+    CheckParameters(2);
+    resultdef:=s64inttype;
+  end;
+in_arm_umull
+: //out ro:r64;rn:r32;rm:r32;
+  begin
+    CheckParameters(2);
+    resultdef:=u64inttype;
+  end;
+in_arm_smlal
+,in_arm_smlalbb
+,in_arm_smlalbt
+,in_arm_smlaltb
+,in_arm_smlaltt
+,in_arm_smlald
+,in_arm_smlaldx
+,in_arm_smlsldx
+,in_arm_umlal
+: //var rd:r64;rn:r32;rm:r32;
+  begin
+    CheckParameters(3);
+    resultdef:=u64inttype;
+  end;
+in_arm_umaal
+: //out rl-rh:r64;rl:r32;rh:r32;rn:r32;rm:r32;
+  begin
+    CheckParameters(4);
+    resultdef:=u64inttype;
+  end;
+in_arm_pkhbt_shift
+: //out rd:r32;rn:r32;rm:r32;ls:i32;
+  begin
+    CheckParameters(3);
+    resultdef:=u32inttype;
+  end;
+in_arm_pkhtb_shift
+: //out rd:r32;rn:r32;rm:r32;rs:i32;
+  begin
+    CheckParameters(3);
+    resultdef:=u32inttype;
+  end;
+in_arm_qadd
+,in_arm_qadd16
+,in_arm_qadd8
+,in_arm_qasx
+,in_arm_qdadd
+,in_arm_qdsub
+,in_arm_qsax
+,in_arm_qsub
+,in_arm_qsub16
+,in_arm_qsub8
+,in_arm_sadd16
+,in_arm_sadd8
+,in_arm_sasx
+,in_arm_shadd16
+,in_arm_shadd8
+,in_arm_shasx
+,in_arm_shsax
+,in_arm_shsub16
+,in_arm_shsub8
+,in_arm_ssax
+,in_arm_ssub16
+,in_arm_ssub8
+,in_arm_uadd16
+,in_arm_uadd8
+,in_arm_uasx
+,in_arm_uhadd16
+,in_arm_uhadd8
+,in_arm_uhasx
+,in_arm_uhsax
+,in_arm_uhsub16
+,in_arm_uhsub8
+,in_arm_uqadd16
+,in_arm_uqadd8
+,in_arm_uqasx
+,in_arm_uqsax
+,in_arm_uqsub16
+,in_arm_uqsub8
+,in_arm_usax
+,in_arm_usub16
+,in_arm_usub8
+,in_arm_usad8
+,in_arm_sxtab
+,in_arm_sxtab16
+,in_arm_sxtah
+,in_arm_uxtab
+,in_arm_uxtab16
+,in_arm_uxtah
+: //out rd:r32;rm:r32;rn:r32;
+  begin
+    CheckParameters(2);
+    resultdef:=u32inttype;
+  end;
+in_arm_sxtab_ror
+,in_arm_sxtab16_ror
+,in_arm_sxtah_ror
+,in_arm_uxtab_ror
+,in_arm_uxtab16_ror
+,in_arm_uxtah_ror
+: //out rd:r32;rm:r32;rn:r32;ror:i32;
+  begin
+    CheckParameters(3);
+    resultdef:=u32inttype;
+  end;
+in_arm_sxtb
+,in_arm_sxtb16
+,in_arm_sxth
+,in_arm_uxtb
+,in_arm_uxtb16
+,in_arm_uxth
+,in_arm_clz
+,in_arm_rbit
+,in_arm_rev
+,in_arm_rev16
+,in_arm_revsh
+: //out rd:r32;rm:r32;
+  begin
+    CheckParameters(1);
+    resultdef:=u32inttype;
+  end;
+in_arm_sxtb_ror
+,in_arm_sxtb16_ror
+,in_arm_sxth_ror
+,in_arm_uxtb_ror
+,in_arm_uxtb16_ror
+,in_arm_uxth_ror
+: //out rd:r32;rm:r32;ror:i32;
+  begin
+    CheckParameters(2);
+    resultdef:=u32inttype;
+  end;
+in_arm_sbfx
+,in_arm_ubfx
+: //out rd:r32;rn:r32;lsb:i32;width:i32;
+  begin
+    CheckParameters(3);
+    resultdef:=u32inttype;
+  end;
+in_arm_ssat
+,in_arm_usat
+,in_arm_ssat16
+,in_arm_usat16
+: //out rd:r32;sat:i32;rn:r32;
+  begin
+    CheckParameters(2);
+    resultdef:=u32inttype;
+  end;

+ 81 - 1
compiler/arm/narminl.pas

@@ -26,13 +26,14 @@ unit narminl;
 interface
 
     uses
-      node,ninl,ncginl;
+      node,ninl,ncginl,ncal,ncon;
 
     type
       tarminlinenode = class(tcgInlineNode)
         function first_abs_real: tnode; override;
         function first_sqr_real: tnode; override;
         function first_sqrt_real: tnode; override;
+        function first_arm: tnode; override;
         { atn,sin,cos,lgn isn't supported by the linux fpe
         function first_arctan_real: tnode; override;
         function first_ln_real: tnode; override;
@@ -50,6 +51,8 @@ interface
         }
         procedure second_prefetch; override;
         procedure second_abs_long; override;
+
+        procedure second_arm; override;
       private
         procedure load_fpu_location(out singleprec: boolean);
       end;
@@ -202,6 +205,13 @@ implementation
       end;
 
 
+    function tarminlinenode.first_arm : tnode;
+      begin
+        case inlinenumber of
+          {$i armfirst.inc}
+        end;
+      end;
+
     { atn,sin,cos,lgn isn't supported by the linux fpe
     function tarminlinenode.first_arctan_real: tnode;
       begin
@@ -405,6 +415,76 @@ implementation
         cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
       end;
 
+
+    procedure tarminlinenode.second_arm;
+
+      var
+        paraarray : array[1..4] of tnode;
+        i : integer;
+        op: TAsmOp;
+        pf: TOpPostfix;
+
+      function GetConstInt(n: tnode): longint;
+        begin
+          if is_constintnode(n) then
+            result:=tordconstnode(n).value.svalue
+          else
+            Message(type_e_constant_expr_expected);
+        end;
+
+      procedure GetParameters(count: longint);
+        var
+          i: longint;
+          p: tnode;
+        begin
+          if count=1 then
+            paraarray[1]:=left
+          else
+            begin
+              p:=left;
+              for i := count downto 1 do
+                begin
+                  paraarray[i]:=tcallparanode(p).paravalue;
+                  p:=tcallparanode(p).nextpara;
+                end;
+            end;
+        end;
+
+      procedure location_make_ref(var loc: tlocation);
+        var
+          hloc: tlocation;
+        begin
+          case loc.loc of
+            LOC_CREGISTER,
+            LOC_REGISTER:
+              begin
+                location_reset_ref(hloc, LOC_REFERENCE, OS_32, 1);
+                hloc.reference.base:=loc.register;
+
+                loc:=hloc;
+              end;
+            LOC_CREFERENCE,
+            LOC_REFERENCE:
+              begin
+              end;
+          else
+            begin
+              hlcg.location_force_reg(current_asmdata.CurrAsmList,loc,u32inttype,u32inttype,false);
+
+              location_reset_ref(hloc, LOC_REFERENCE, OS_32, 1);
+              hloc.reference.base:=loc.register;
+
+              loc:=hloc;
+            end;
+          end;
+        end;
+
+      begin
+        case inlinenumber of
+          {$i armsecond.inc}
+        end;
+      end;
+
 begin
   cinlinenode:=tarminlinenode;
 end.

+ 2 - 0
compiler/compinnr.inc

@@ -136,3 +136,5 @@ const
 
    { SSE }
 
+{ ARM }
+   in_arm_base         = 300;

+ 8 - 0
compiler/ncginl.pas

@@ -61,6 +61,7 @@ interface
           procedure second_popcnt; virtual;
           procedure second_seg; virtual; abstract;
           procedure second_fma; virtual;
+          procedure second_arm; virtual;
        end;
 
 implementation
@@ -196,6 +197,9 @@ implementation
             in_fma_extended,
             in_fma_float128:
                second_fma;
+
+            in_arm_first..in_arm_last:
+               second_arm;
             else internalerror(9);
          end;
       end;
@@ -780,6 +784,10 @@ implementation
         internalerror(2014032701);
       end;
 
+    procedure tcginlinenode.second_arm;
+      begin
+        internalerror(2015061701);
+      end;
 
 begin
    cinlinenode:=tcginlinenode;

+ 41 - 7
compiler/ninl.pas

@@ -29,11 +29,12 @@ interface
        node,htypechk,cpuinfo,symtype;
 
     {$i compinnr.inc}
+    {$i arm/arminnr.inc}
 
     type
        tinlinenode = class(tunarynode)
-          inlinenumber : byte;
-          constructor create(number : byte;is_const:boolean;l : tnode);virtual;
+          inlinenumber : word;
+          constructor create(number : word;is_const:boolean;l : tnode);virtual;
           constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           function dogetcopy : tnode;override;
@@ -86,6 +87,7 @@ interface
           function first_seg: tnode; virtual;
           function first_sar: tnode; virtual;
           function first_fma : tnode; virtual;
+          function first_arm : tnode; virtual;
         private
           function handle_str: tnode;
           function handle_reset_rewrite_typed: tnode;
@@ -104,7 +106,7 @@ interface
     var
        cinlinenode : tinlinenodeclass = tinlinenode;
 
-   function geninlinenode(number : byte;is_const:boolean;l : tnode) : tinlinenode;
+   function geninlinenode(number : word;is_const:boolean;l : tnode) : tinlinenode;
 
 implementation
 
@@ -118,7 +120,7 @@ implementation
       cgbase,procinfo
       ;
 
-   function geninlinenode(number : byte;is_const:boolean;l : tnode) : tinlinenode;
+   function geninlinenode(number : word;is_const:boolean;l : tnode) : tinlinenode;
 
      begin
         geninlinenode:=cinlinenode.create(number,is_const,l);
@@ -128,7 +130,7 @@ implementation
                            TINLINENODE
 *****************************************************************************}
 
-    constructor tinlinenode.create(number : byte;is_const:boolean;l : tnode);
+    constructor tinlinenode.create(number : word;is_const:boolean;l : tnode);
 
       begin
          inherited create(inlinen,l);
@@ -141,14 +143,14 @@ implementation
     constructor tinlinenode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
       begin
         inherited ppuload(t,ppufile);
-        inlinenumber:=ppufile.getbyte;
+        inlinenumber:=ppufile.getword;
       end;
 
 
     procedure tinlinenode.ppuwrite(ppufile:tcompilerppufile);
       begin
         inherited ppuwrite(ppufile);
-        ppufile.putbyte(inlinenumber);
+        ppufile.putword(inlinenumber);
       end;
 
 
@@ -2578,6 +2580,25 @@ implementation
         end;
 
 
+      procedure CheckParameters(count: integer);
+        var
+          p: tnode;
+        begin
+          if count=1 then
+            set_varstate(left,vs_read,[vsf_must_be_valid])
+          else
+            begin
+              p:=left;
+              while count>0 do
+                begin
+                  set_varstate(tcallparanode(p).left,vs_read,[vsf_must_be_valid]);
+
+                  p:=tcallparanode(p).right;
+                  dec(count);
+                end;
+            end;
+        end;
+
       var
          hightree,
          hp        : tnode;
@@ -3272,6 +3293,10 @@ implementation
                   set_varstate(tcallparanode(tcallparanode(tcallparanode(left).right).right).left,vs_read,[vsf_must_be_valid]);
                   resultdef:=tcallparanode(left).left.resultdef;
                 end;
+
+{$ifdef ARM}
+              {$i armtype.inc}
+{$endif ARM}
               else
                 internalerror(8);
             end;
@@ -3596,6 +3621,8 @@ implementation
          in_fma_extended,
          in_fma_float128:
            result:=first_fma;
+         in_arm_first..in_arm_last:
+           result:=first_arm;
          else
            internalerror(89);
           end;
@@ -4307,5 +4334,12 @@ implementation
          result:=nil;
        end;
 
+
+     function tinlinenode.first_arm: tnode;
+       begin
+         CGMessage1(cg_e_function_not_support_by_selected_instruction_set,'ARM');
+         result:=nil;
+       end;
+
 end.
 

+ 1 - 0
compiler/optcse.pas

@@ -72,6 +72,7 @@ unit optcse;
                with more than one parameter }
              in_fma_single,in_fma_double,in_fma_extended,in_fma_float128])
           ) or
+          (tinlinenode(n).inlinenumber >= 200) or
           ((n.nodetype=callparan) and not(assigned(tcallparanode(n).right))) or
           ((n.nodetype=loadn) and
             not((tloadnode(n).symtableentry.typ in [staticvarsym,localvarsym,paravarsym]) and

+ 543 - 0
compiler/utils/mkarminl.pp

@@ -0,0 +1,543 @@
+program mkarminl;
+
+{$mode objfpc}
+{$H+}
+
+uses
+  sysutils, classes,
+  strutils;
+
+type
+  TOperDirection = (operIn, operVar, operOut);
+
+  TOperand = record
+    name,
+    namehi, // If this is not empty the operand is a virtual register pair operand
+    typ: string;
+    direction: TOperDirection;
+  end;
+
+const
+  DirLUT: array[TOperDirection] of string = ('','var ','out ');
+
+function GetPascalType(const ATyp: string): string;
+  begin
+    case ATyp of
+      'r32':   exit('longword');
+      'rs32':  exit('longint');
+      'r64':   exit('qword');
+      'rs64':  exit('int64');
+      'i32':   exit('longint');
+      'ptr32': exit('pointer');
+    else
+      exit(ATyp);
+    end;
+  end;
+
+function GetTypeDef(const ATyp: string): string;
+  begin
+    case ATyp of
+      'r32':   exit('u32inttype');
+      'rs32':  exit('s32inttype');
+      'r64':   exit('u64inttype');
+      'rs64':  exit('s64inttype');
+      'i32':   exit('s32inttype');
+      'ptr32': exit('voidpointertype');
+    else
+      exit(ATyp);
+    end;
+  end;
+
+function GetOper(const ATyp: string): string;
+  begin
+    case ATyp of
+      'r32':   exit('_reg');
+      'rs32':  exit('_reg');
+      'r64':   exit('_reg_reg');
+      'rs64':  exit('_reg_reg');
+      'i32':   exit('_const');
+      'ptr32': exit('_ref');
+    else
+      exit('');
+    end;
+  end;
+
+function GetOperand(const ATyp: string; AIndex: longint): string;
+  begin
+    case ATyp of
+      'r32':   exit(format(',paraarray[%d].location.register', [AIndex]));
+      'rs32':  exit(format(',paraarray[%d].location.register', [AIndex]));
+      'r64':   exit(format(',paraarray[%d].location.register64.reglo,paraarray[%d].location.register64.reghi', [AIndex,AIndex]));
+      'rs64':  exit(format(',paraarray[%d].location.register64.reglo,paraarray[%d].location.register64.reghi', [AIndex,AIndex]));
+      'i32':   exit(format(',GetConstInt(paraarray[%d])',[AIndex]));
+      'ptr32': exit(format(',paraarray[%d].location.reference', [AIndex]));
+    else
+      exit(ATyp);
+    end;
+  end;
+
+function GetOperandLoc(const ATyp: string): string;
+  begin
+    result:='';
+    case ATyp of
+      'r32':  exit(',location.register');
+      'rs32': exit(',location.register');
+      'r64':  exit(',location.register64.reglo,location.register64.reghi');
+      'rs64': exit(',location.register64.reglo,location.register64.reghi');
+    end;
+  end;
+
+function GetLocStatement(AIndex: longint; const ATyp: string; AConst: boolean): string;
+  begin
+    result:='';
+    case ATyp of
+      'r32':   exit(format('hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[%d].location, paraarray[%d].resultdef,u32inttype,%s);', [AIndex+1, AIndex+1, BoolToStr(aconst,'true','false')]));
+      'rs32':  exit(format('hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[%d].location, paraarray[%d].resultdef,u32inttype,%s);', [AIndex+1, AIndex+1, BoolToStr(aconst,'true','false')]));
+      'r64':   exit(format('hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[%d].location, paraarray[%d].resultdef,u64inttype,%s);', [AIndex+1, AIndex+1, BoolToStr(aconst,'true','false')]));
+      'rs64':  exit(format('hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[%d].location, paraarray[%d].resultdef,u64inttype,%s);', [AIndex+1, AIndex+1, BoolToStr(aconst,'true','false')]));
+      'ptr32': exit(format('location_make_ref(paraarray[%d].location);', [AIndex+1]));
+    end;
+  end;
+
+function GetLoc(const ATyp: string): string;
+  begin
+    result:='';
+    case ATyp of
+      'r32':   exit('LOC_REGISTER,OS_32');
+      'rs32':  exit('LOC_REGISTER,OS_S32');
+      'r64':   exit('LOC_REGISTER,OS_64');
+      'rs64':  exit('LOC_REGISTER,OS_S64');
+      'ptr32': exit('LOC_MEM,OS_32');
+    end;
+  end;
+
+function GetLocAllocation(const ATyp: string): string;
+  begin
+    result:='';
+    case ATyp of
+      'r32':  exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);');
+      'rs32': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);');
+      'r64':  exit('location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList, OS_32); location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);');
+      'rs64': exit('location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList, OS_32); location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);');
+    end;
+  end;
+
+function GetPostFix(const APF: string): string;
+  begin
+    if APF<>'' then
+      result:='PF_'+APF
+    else
+      result:='PF_None';
+  end;
+
+procedure ParseList(const APrefix, AFilename: string);
+  var
+    f: TextFile;
+
+    fprocs,
+    finnr: TextFile;
+    ftypechk, ffirst, fsecond: TStringList;
+
+    str,
+    instrPart,postfix,_alias,
+    params, operline: String;
+
+    opers: array[0..7] of TOperand;
+    opercnt: longint;
+
+    hasOutput: boolean;
+    outputType: string;
+    cnt,
+    i, intrnum: longint;
+    tmp: String;
+
+  function ParseOperands(AIndex: longint = -1): string;
+    var
+      idx: LongInt;
+      pt: Integer;
+      c: Char;
+    begin
+      idx:=opercnt;
+
+      params:=trim(params);
+      if params='' then
+        exit('');
+
+      inc(opercnt);
+
+      if pos('var ', params)=1 then
+        begin
+          opers[idx].direction:=operVar;
+          Delete(params,1,4);
+          params:=trim(params);
+          hasOutput:=true;
+        end
+      else if pos('out ', params)=1 then
+        begin
+          opers[idx].direction:=operOut;
+          Delete(params,1,4);
+          params:=trim(params);
+          hasOutput:=true;
+        end
+      else
+        begin
+          if AIndex<>-1 then
+            opers[idx].direction:=opers[AIndex].direction
+          else
+            opers[idx].direction:=operIn;
+        end;
+
+      if pos('[',params)=1 then
+        begin
+          delete(params,1,1);
+          opers[idx].name:=Copy2SymbDel(params, ',');
+          opers[idx].namehi:=Copy2SymbDel(params, ']');
+
+          pt:=PosSet([',',':'], params);
+          c:=params[pt];
+
+          Copy2SymbDel(params,c);
+
+          params:=trim(params);
+        end
+      else
+        begin
+          pt:=PosSet([',',':'], params);
+
+          c:=params[pt];
+          opers[idx].name:=Copy2SymbDel(params, c);
+          opers[idx].namehi:='';
+          params:=trim(params);
+        end;
+
+      if c = ':' then
+        begin
+          opers[idx].typ:=Copy2SymbDel(params, ';');
+          result:=opers[idx].typ;
+        end
+      else
+        begin
+          opers[idx].typ:=ParseOperands(idx);
+          result:=opers[idx].typ;
+        end;
+
+      if opers[idx].direction<>operIn then
+        outputType:=opers[idx].typ;
+    end;
+
+  function GetOperLine: string;
+    var
+      i: longint;
+    begin
+      result:='';
+      for i := 0 to opercnt-1 do
+        if opers[i].namehi<>'' then
+          result:=result+DirLUT[opers[i].direction]+opers[i].name+'-'+opers[i].namehi+':'+opers[i].typ+';'
+        else
+          result:=result+DirLUT[opers[i].direction]+opers[i].name+':'+opers[i].typ+';';
+    end;
+
+  function GetParams: longint;
+    var
+      i: longint;
+    begin
+      result:=0;
+      for i := 0 to opercnt-1 do
+        if opers[i].direction in [operIn,operVar] then
+          inc(result);
+    end;
+
+  function FindOperIdx(const AOper: string): longint;
+    var
+      i,cnt: longint;
+    begin
+      cnt:=0;
+      result:=0;
+      for i := 0 to opercnt-1 do
+        if (opers[i].direction in [operIn,operVar]) then
+          begin
+            if opers[i].name=AOper then
+              exit(cnt);
+            inc(cnt);
+          end;
+    end;
+
+  begin
+    intrnum:=0;
+
+    assignfile(f, AFilename);
+    reset(f);
+
+    assignfile(fprocs, APrefix+'procs.inc'); rewrite(fprocs);
+    assignfile(finnr, APrefix+'innr.inc'); rewrite(finnr);
+
+    writeln(finnr,'const');
+
+    ftypechk:=TStringList.Create;
+    ffirst:=TStringList.Create;
+    fsecond:=TStringList.Create;
+
+    writeln(finnr, '  in_', APrefix,'_first = in_',APrefix,'_base;');
+
+    while not EOF(f) do
+      begin
+        readln(f, str);
+
+        str:=trim(str);
+
+        if (str='') or (Pos(';',str)=1) then
+          continue;
+
+        instrPart:=Copy2SymbDel(str, '(');
+
+        // Check for postfix
+        if pos('{',instrPart)>0 then
+          begin
+            postfix:=instrPart;
+            instrPart:=Copy2SymbDel(postfix, '{');
+            postfix:=TrimRightSet(postfix,['}']);
+          end
+        else
+          postfix:='';
+
+        // Check for alias
+        if pos('[',instrPart)>0 then
+          begin
+            _alias:=instrPart;
+            instrPart:=Copy2SymbDel(_alias, '[');
+            _alias:='_'+TrimRightSet(_alias,[']']);
+          end
+        else
+          _alias:='';
+
+        // Get parameters
+        params:=trim(Copy2SymbDel(str,')'));
+        str:=trim(str);
+
+        hasOutput:=false;
+        opercnt:=0;
+        outputType:='';
+
+        while params<>'' do
+          ParseOperands;
+
+        operline:=GetOperLine;
+        // Write typecheck code
+        i:=ftypechk.IndexOf(': //'+operline);
+        if i>=0 then
+          ftypechk.Insert(i,',in_'+APrefix+'_'+instrPart+postfix+_alias)
+        else
+          begin
+            ftypechk.Add('in_'+APrefix+'_'+instrPart+postfix+_alias);
+            ftypechk.Add(': //'+operline);
+            ftypechk.Add('  begin');
+            ftypechk.Add('    CheckParameters('+inttostr(GetParams())+');');
+            if hasOutput then
+              ftypechk.Add('    resultdef:='+GetTypeDef(outputType)+';')
+            else
+              ftypechk.Add('    resultdef:=voidtype;');
+            ftypechk.Add('  end;')
+          end;
+
+        // Write firstpass code
+        i:=ffirst.IndexOf(': //'+operline);
+        if i>=0 then
+          ffirst.Insert(i,',in_'+APrefix+'_'+instrPart+postfix+_alias)
+        else
+          begin
+            ffirst.Add('in_'+APrefix+'_'+instrPart+postfix+_alias);
+            ffirst.Add(': //'+operline);
+            ffirst.Add('  begin');
+            if hasOutput then
+              ffirst.Add('    expectloc:=LOC_REGISTER;')
+            else
+              ffirst.Add('    expectloc:=LOC_VOID;');
+            ffirst.Add('    result:=nil;');
+            ffirst.Add('  end;')
+          end;
+
+        // Write secondpass code
+        i:=fsecond.IndexOf(': //'+operline);
+        if i>=0 then
+          begin
+            fsecond.Insert(i+3,'      in_'+APrefix+'_'+instrPart+postfix+_alias+': begin op:=A_'+instrPart+'; pf:='+GetPostFix(postfix)+'; end;');
+            fsecond.Insert(i,',in_'+APrefix+'_'+instrPart+postfix+_alias);
+          end
+        else
+          begin
+            fsecond.Add('in_'+APrefix+'_'+instrPart+postfix+_alias);
+            fsecond.Add(': //'+operline);
+            fsecond.Add('  begin');
+            fsecond.add('    case inlinenumber of');
+            fsecond.Add('      in_'+APrefix+'_'+instrPart+postfix+_alias+': begin op:=A_'+instrPart+'; pf:='+GetPostFix(postfix)+'; end;');
+            fsecond.add('    end;');
+            fsecond.Add('');
+
+            i:=GetParams;
+            fsecond.Add('    GetParameters('+inttostr(i)+');');
+            fsecond.Add('');
+
+            fsecond.add('    for i := 1 to '+inttostr(i)+' do secondpass(paraarray[i]);');
+            fsecond.Add('');
+
+            // Force inputs
+            cnt:=0;
+            for i := 0 to opercnt-1 do
+              begin
+                case opers[i].direction of
+                  operIn:
+                    begin
+                      tmp:=GetLocStatement(cnt, opers[i].typ, true);
+                      if tmp<>'' then
+                        fsecond.add('    '+tmp);
+                      inc(cnt);
+                    end;
+                  operVar:
+                    begin
+                      tmp:=GetLocStatement(cnt, opers[i].typ, false);
+                      if tmp<>'' then
+                        fsecond.add('    '+tmp);
+                      inc(cnt);
+                    end;
+                end;
+              end;
+
+            // Allocate output
+            cnt:=0;
+            for i := 0 to opercnt-1 do
+              begin
+                case opers[i].direction of
+                  operOut:
+                    begin
+                      if opers[i].namehi<>'' then
+                        begin
+                          fsecond.add('    location_reset(location,'+GetLoc(opers[i].typ)+');');
+                          fsecond.Add('    location.register64.reglo:=paraarray['+inttostr(FindOperIdx(opers[i].name)+1)+'].location.register;');
+                          fsecond.Add('    location.register64.reghi:=paraarray['+inttostr(FindOperIdx(opers[i].namehi)+1)+'].location.register;');
+                        end
+                      else
+                        begin
+                          fsecond.add('    location_reset(location,'+GetLoc(opers[i].typ)+');');
+                          fsecond.Add('    '+GetLocAllocation(opers[i].typ));
+                        end;
+                    end;
+                  operVar:
+                    begin
+                      if opers[i].namehi<>'' then
+                        begin
+                          fsecond.add('    location_reset(location,'+GetLoc(opers[i].typ)+');');
+                          fsecond.Add('    location.register64:=paraarray['+inttostr(cnt+1)+'].location.register64;');
+                        end
+                      else
+                        begin
+                          //fsecond.add('    location_reset(location,'+GetLoc(opers[i].typ)+');');
+                          //fsecond.Add('    location.register:=paraarray['+inttostr(cnt+1)+'].location.register;');
+                          fsecond.Add('    location:=paraarray['+inttostr(cnt+1)+'].location;');
+                        end;
+                      inc(cnt);
+                    end;
+                  operIn:
+                    inc(cnt);
+                end;
+              end;
+
+            operline:='taicpu.op';
+            for i := 0 to opercnt-1 do
+              begin
+                case opers[i].direction of
+                  operOut:
+                    if opers[i].namehi='' then
+                      operline:=operline+GetOper(opers[i].typ);
+                  operVar:
+                    operline:=operline+GetOper(opers[i].typ);
+                  operIn:
+                    operline:=operline+GetOper(opers[i].typ);
+                end;
+              end;
+
+            if operline='taicpu.op' then
+              operline:='taicpu.op_none(op'
+            else
+              operline:=operline+'(op';
+
+            cnt:=0;
+            for i := 0 to opercnt-1 do
+              begin
+                case opers[i].direction of
+                  operOut:
+                    if opers[i].namehi='' then
+                      operline:=operline+GetOperandLoc(opers[i].typ);
+                  operIn,
+                  operVar:
+                    begin
+                      operline:=operline+GetOperand(opers[i].typ, cnt+1);
+                      inc(cnt);
+                    end;
+                end;
+              end;
+
+            operline:=operline+')';
+
+            fsecond.Add('    current_asmdata.CurrAsmList.concat(setoppostfix('+operline+',pf));');
+
+            fsecond.Add('  end;')
+          end;
+
+        // Write innr
+        writeln(finnr, '  in_', APrefix,'_',instrPart,postfix+_alias,' = in_',APrefix,'_base+',intrnum,';');
+
+        // Write function
+        if hasOutput then write(fprocs,'function ') else write(fprocs,'procedure ');
+        write(fprocs,APrefix,'_',instrPart,postfix,'(');
+
+        cnt:=0;
+        for i:=0 to opercnt-1 do
+          begin
+            if opers[i].direction=operOut then
+              Continue;
+
+            if cnt>0 then
+              begin
+                if opers[i].typ<>opers[i-1].typ then
+                  write(fprocs,': ',GetPascalType(opers[i-1].typ),'; ')
+                else
+                  write(fprocs,', ');
+              end;
+
+            write(fprocs,opers[i].name);
+            if i=opercnt-1 then
+              write(fprocs,': ',GetPascalType(opers[i].typ));
+
+            inc(cnt);
+          end;
+
+        write(fprocs,')');
+
+        if hasOutput then write(fprocs,': ',GetPascalType(outputType));
+        writeln(fprocs,'; [INTERNPROC: in_',APrefix,'_',instrPart,postfix+_alias,'];');
+
+        // Str now contains conditionals
+
+        inc(intrnum);
+      end;
+
+    writeln(finnr, '  in_', APrefix,'_last = in_',APrefix,'_base+',intrnum-1,';');
+
+    ftypechk.SaveToFile(APrefix+'type.inc');
+    ffirst.SaveToFile(APrefix+'first.inc');
+    fsecond.SaveToFile(APrefix+'second.inc');
+
+    ftypechk.Free;
+    ffirst.Free;
+    fsecond.Free;
+
+    CloseFile(fprocs);
+    CloseFile(finnr);
+
+    closefile(f);
+  end;
+
+begin
+  ParseList('arm', 'armintr.dat');
+end.
+

+ 138 - 0
rtl/arm/arminnr.inc

@@ -0,0 +1,138 @@
+const
+  in_arm_first = in_arm_base;
+  in_arm_nop = in_arm_base+0;
+  in_arm_yield = in_arm_base+1;
+  in_arm_wfi = in_arm_base+2;
+  in_arm_wfe = in_arm_base+3;
+  in_arm_sev = in_arm_base+4;
+  in_arm_clrex = in_arm_base+5;
+  in_arm_setend = in_arm_base+6;
+  in_arm_ldrex = in_arm_base+7;
+  in_arm_ldrexb = in_arm_base+8;
+  in_arm_ldrexh = in_arm_base+9;
+  in_arm_strex = in_arm_base+10;
+  in_arm_strexb = in_arm_base+11;
+  in_arm_strexh = in_arm_base+12;
+  in_arm_bfi = in_arm_base+13;
+  in_arm_bfc = in_arm_base+14;
+  in_arm_smmul = in_arm_base+15;
+  in_arm_smuad = in_arm_base+16;
+  in_arm_smuadx = in_arm_base+17;
+  in_arm_smulbb = in_arm_base+18;
+  in_arm_smulbt = in_arm_base+19;
+  in_arm_smultb = in_arm_base+20;
+  in_arm_smultt = in_arm_base+21;
+  in_arm_smulwb = in_arm_base+22;
+  in_arm_smulwt = in_arm_base+23;
+  in_arm_smusd = in_arm_base+24;
+  in_arm_smusdx = in_arm_base+25;
+  in_arm_mla = in_arm_base+26;
+  in_arm_mls = in_arm_base+27;
+  in_arm_smlabb = in_arm_base+28;
+  in_arm_smlabt = in_arm_base+29;
+  in_arm_smlatb = in_arm_base+30;
+  in_arm_smlatt = in_arm_base+31;
+  in_arm_smlad = in_arm_base+32;
+  in_arm_smladx = in_arm_base+33;
+  in_arm_smlawb = in_arm_base+34;
+  in_arm_smlawt = in_arm_base+35;
+  in_arm_smlsd = in_arm_base+36;
+  in_arm_smlsdx = in_arm_base+37;
+  in_arm_smmla = in_arm_base+38;
+  in_arm_smmlar = in_arm_base+39;
+  in_arm_smmls = in_arm_base+40;
+  in_arm_smmlsr = in_arm_base+41;
+  in_arm_usada8 = in_arm_base+42;
+  in_arm_smull = in_arm_base+43;
+  in_arm_umull = in_arm_base+44;
+  in_arm_smlal = in_arm_base+45;
+  in_arm_smlalbb = in_arm_base+46;
+  in_arm_smlalbt = in_arm_base+47;
+  in_arm_smlaltb = in_arm_base+48;
+  in_arm_smlaltt = in_arm_base+49;
+  in_arm_smlald = in_arm_base+50;
+  in_arm_smlaldx = in_arm_base+51;
+  in_arm_smlsldx = in_arm_base+52;
+  in_arm_umlal = in_arm_base+53;
+  in_arm_umaal = in_arm_base+54;
+  in_arm_pkhbt = in_arm_base+55;
+  in_arm_pkhtb = in_arm_base+56;
+  in_arm_pkhbt_shift = in_arm_base+57;
+  in_arm_pkhtb_shift = in_arm_base+58;
+  in_arm_qadd = in_arm_base+59;
+  in_arm_qadd16 = in_arm_base+60;
+  in_arm_qadd8 = in_arm_base+61;
+  in_arm_qasx = in_arm_base+62;
+  in_arm_qdadd = in_arm_base+63;
+  in_arm_qdsub = in_arm_base+64;
+  in_arm_qsax = in_arm_base+65;
+  in_arm_qsub = in_arm_base+66;
+  in_arm_qsub16 = in_arm_base+67;
+  in_arm_qsub8 = in_arm_base+68;
+  in_arm_sadd16 = in_arm_base+69;
+  in_arm_sadd8 = in_arm_base+70;
+  in_arm_sasx = in_arm_base+71;
+  in_arm_shadd16 = in_arm_base+72;
+  in_arm_shadd8 = in_arm_base+73;
+  in_arm_shasx = in_arm_base+74;
+  in_arm_shsax = in_arm_base+75;
+  in_arm_shsub16 = in_arm_base+76;
+  in_arm_shsub8 = in_arm_base+77;
+  in_arm_ssax = in_arm_base+78;
+  in_arm_ssub16 = in_arm_base+79;
+  in_arm_ssub8 = in_arm_base+80;
+  in_arm_uadd16 = in_arm_base+81;
+  in_arm_uadd8 = in_arm_base+82;
+  in_arm_uasx = in_arm_base+83;
+  in_arm_uhadd16 = in_arm_base+84;
+  in_arm_uhadd8 = in_arm_base+85;
+  in_arm_uhasx = in_arm_base+86;
+  in_arm_uhsax = in_arm_base+87;
+  in_arm_uhsub16 = in_arm_base+88;
+  in_arm_uhsub8 = in_arm_base+89;
+  in_arm_uqadd16 = in_arm_base+90;
+  in_arm_uqadd8 = in_arm_base+91;
+  in_arm_uqasx = in_arm_base+92;
+  in_arm_uqsax = in_arm_base+93;
+  in_arm_uqsub16 = in_arm_base+94;
+  in_arm_uqsub8 = in_arm_base+95;
+  in_arm_usax = in_arm_base+96;
+  in_arm_usub16 = in_arm_base+97;
+  in_arm_usub8 = in_arm_base+98;
+  in_arm_usad8 = in_arm_base+99;
+  in_arm_sxtab = in_arm_base+100;
+  in_arm_sxtab16 = in_arm_base+101;
+  in_arm_sxtah = in_arm_base+102;
+  in_arm_uxtab = in_arm_base+103;
+  in_arm_uxtab16 = in_arm_base+104;
+  in_arm_uxtah = in_arm_base+105;
+  in_arm_sxtab_ror = in_arm_base+106;
+  in_arm_sxtab16_ror = in_arm_base+107;
+  in_arm_sxtah_ror = in_arm_base+108;
+  in_arm_uxtab_ror = in_arm_base+109;
+  in_arm_uxtab16_ror = in_arm_base+110;
+  in_arm_uxtah_ror = in_arm_base+111;
+  in_arm_sxtb = in_arm_base+112;
+  in_arm_sxtb16 = in_arm_base+113;
+  in_arm_sxth = in_arm_base+114;
+  in_arm_uxtb = in_arm_base+115;
+  in_arm_uxtb16 = in_arm_base+116;
+  in_arm_uxth = in_arm_base+117;
+  in_arm_sxtb_ror = in_arm_base+118;
+  in_arm_sxtb16_ror = in_arm_base+119;
+  in_arm_sxth_ror = in_arm_base+120;
+  in_arm_uxtb_ror = in_arm_base+121;
+  in_arm_uxtb16_ror = in_arm_base+122;
+  in_arm_uxth_ror = in_arm_base+123;
+  in_arm_clz = in_arm_base+124;
+  in_arm_rbit = in_arm_base+125;
+  in_arm_rev = in_arm_base+126;
+  in_arm_rev16 = in_arm_base+127;
+  in_arm_revsh = in_arm_base+128;
+  in_arm_sbfx = in_arm_base+129;
+  in_arm_ubfx = in_arm_base+130;
+  in_arm_ssat = in_arm_base+131;
+  in_arm_usat = in_arm_base+132;
+  in_arm_ssat16 = in_arm_base+133;
+  in_arm_usat16 = in_arm_base+134;
+  in_arm_last = in_arm_base+134;

+ 135 - 0
rtl/arm/armprocs.inc

@@ -0,0 +1,135 @@
+procedure arm_nop(); [INTERNPROC: in_arm_nop];
+procedure arm_yield(); [INTERNPROC: in_arm_yield];
+procedure arm_wfi(); [INTERNPROC: in_arm_wfi];
+procedure arm_wfe(); [INTERNPROC: in_arm_wfe];
+procedure arm_sev(); [INTERNPROC: in_arm_sev];
+procedure arm_clrex(); [INTERNPROC: in_arm_clrex];
+procedure arm_setend(endian: longint); [INTERNPROC: in_arm_setend];
+function arm_ldrex(ref: pointer): longword; [INTERNPROC: in_arm_ldrex];
+function arm_ldrexb(ref: pointer): longword; [INTERNPROC: in_arm_ldrexb];
+function arm_ldrexh(ref: pointer): longword; [INTERNPROC: in_arm_ldrexh];
+function arm_strex(rt: longword; ref: pointer): longword; [INTERNPROC: in_arm_strex];
+function arm_strexb(rt: longword; ref: pointer): longword; [INTERNPROC: in_arm_strexb];
+function arm_strexh(rt: longword; ref: pointer): longword; [INTERNPROC: in_arm_strexh];
+function arm_bfi(rd, rn: longword; lsb, msb: longint): longword; [INTERNPROC: in_arm_bfi];
+function arm_bfc(rd: longword; lsb, msb: longint): longword; [INTERNPROC: in_arm_bfc];
+function arm_smmul(rn, rm: longword): longword; [INTERNPROC: in_arm_smmul];
+function arm_smuad(rn, rm: longword): longword; [INTERNPROC: in_arm_smuad];
+function arm_smuadx(rn, rm: longword): longword; [INTERNPROC: in_arm_smuadx];
+function arm_smulbb(rn, rm: longword): longword; [INTERNPROC: in_arm_smulbb];
+function arm_smulbt(rn, rm: longword): longword; [INTERNPROC: in_arm_smulbt];
+function arm_smultb(rn, rm: longword): longword; [INTERNPROC: in_arm_smultb];
+function arm_smultt(rn, rm: longword): longword; [INTERNPROC: in_arm_smultt];
+function arm_smulwb(rn, rm: longword): longword; [INTERNPROC: in_arm_smulwb];
+function arm_smulwt(rn, rm: longword): longword; [INTERNPROC: in_arm_smulwt];
+function arm_smusd(rn, rm: longword): longword; [INTERNPROC: in_arm_smusd];
+function arm_smusdx(rn, rm: longword): longword; [INTERNPROC: in_arm_smusdx];
+function arm_mla(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_mla];
+function arm_mls(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_mls];
+function arm_smlabb(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_smlabb];
+function arm_smlabt(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_smlabt];
+function arm_smlatb(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_smlatb];
+function arm_smlatt(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_smlatt];
+function arm_smlad(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_smlad];
+function arm_smladx(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_smladx];
+function arm_smlawb(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_smlawb];
+function arm_smlawt(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_smlawt];
+function arm_smlsd(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_smlsd];
+function arm_smlsdx(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_smlsdx];
+function arm_smmla(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_smmla];
+function arm_smmlar(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_smmlar];
+function arm_smmls(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_smmls];
+function arm_smmlsr(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_smmlsr];
+function arm_usada8(rn, rm, ra: longword): longword; [INTERNPROC: in_arm_usada8];
+function arm_smull(rn, rm: longword): int64; [INTERNPROC: in_arm_smull];
+function arm_umull(rn, rm: longword): qword; [INTERNPROC: in_arm_umull];
+function arm_smlal(rd: qword; rn, rm: longword): qword; [INTERNPROC: in_arm_smlal];
+function arm_smlalbb(rd: qword; rn, rm: longword): qword; [INTERNPROC: in_arm_smlalbb];
+function arm_smlalbt(rd: qword; rn, rm: longword): qword; [INTERNPROC: in_arm_smlalbt];
+function arm_smlaltb(rd: qword; rn, rm: longword): qword; [INTERNPROC: in_arm_smlaltb];
+function arm_smlaltt(rd: qword; rn, rm: longword): qword; [INTERNPROC: in_arm_smlaltt];
+function arm_smlald(rd: qword; rn, rm: longword): qword; [INTERNPROC: in_arm_smlald];
+function arm_smlaldx(rd: qword; rn, rm: longword): qword; [INTERNPROC: in_arm_smlaldx];
+function arm_smlsldx(rd: qword; rn, rm: longword): qword; [INTERNPROC: in_arm_smlsldx];
+function arm_umlal(rd: qword; rn, rm: longword): qword; [INTERNPROC: in_arm_umlal];
+function arm_umaal(rl, rh, rn, rm: longword): qword; [INTERNPROC: in_arm_umaal];
+function arm_pkhbt(rn, rm: longword): longword; [INTERNPROC: in_arm_pkhbt];
+function arm_pkhtb(rn, rm: longword): longword; [INTERNPROC: in_arm_pkhtb];
+function arm_pkhbt(rn, rm: longword; ls: longint): longword; [INTERNPROC: in_arm_pkhbt_shift];
+function arm_pkhtb(rn, rm: longword; rs: longint): longword; [INTERNPROC: in_arm_pkhtb_shift];
+function arm_qadd(rm, rn: longword): longword; [INTERNPROC: in_arm_qadd];
+function arm_qadd16(rm, rn: longword): longword; [INTERNPROC: in_arm_qadd16];
+function arm_qadd8(rm, rn: longword): longword; [INTERNPROC: in_arm_qadd8];
+function arm_qasx(rm, rn: longword): longword; [INTERNPROC: in_arm_qasx];
+function arm_qdadd(rm, rn: longword): longword; [INTERNPROC: in_arm_qdadd];
+function arm_qdsub(rm, rn: longword): longword; [INTERNPROC: in_arm_qdsub];
+function arm_qsax(rm, rn: longword): longword; [INTERNPROC: in_arm_qsax];
+function arm_qsub(rm, rn: longword): longword; [INTERNPROC: in_arm_qsub];
+function arm_qsub16(rm, rn: longword): longword; [INTERNPROC: in_arm_qsub16];
+function arm_qsub8(rm, rn: longword): longword; [INTERNPROC: in_arm_qsub8];
+function arm_sadd16(rm, rn: longword): longword; [INTERNPROC: in_arm_sadd16];
+function arm_sadd8(rm, rn: longword): longword; [INTERNPROC: in_arm_sadd8];
+function arm_sasx(rm, rn: longword): longword; [INTERNPROC: in_arm_sasx];
+function arm_shadd16(rm, rn: longword): longword; [INTERNPROC: in_arm_shadd16];
+function arm_shadd8(rm, rn: longword): longword; [INTERNPROC: in_arm_shadd8];
+function arm_shasx(rm, rn: longword): longword; [INTERNPROC: in_arm_shasx];
+function arm_shsax(rm, rn: longword): longword; [INTERNPROC: in_arm_shsax];
+function arm_shsub16(rm, rn: longword): longword; [INTERNPROC: in_arm_shsub16];
+function arm_shsub8(rm, rn: longword): longword; [INTERNPROC: in_arm_shsub8];
+function arm_ssax(rm, rn: longword): longword; [INTERNPROC: in_arm_ssax];
+function arm_ssub16(rm, rn: longword): longword; [INTERNPROC: in_arm_ssub16];
+function arm_ssub8(rm, rn: longword): longword; [INTERNPROC: in_arm_ssub8];
+function arm_uadd16(rm, rn: longword): longword; [INTERNPROC: in_arm_uadd16];
+function arm_uadd8(rm, rn: longword): longword; [INTERNPROC: in_arm_uadd8];
+function arm_uasx(rm, rn: longword): longword; [INTERNPROC: in_arm_uasx];
+function arm_uhadd16(rm, rn: longword): longword; [INTERNPROC: in_arm_uhadd16];
+function arm_uhadd8(rm, rn: longword): longword; [INTERNPROC: in_arm_uhadd8];
+function arm_uhasx(rm, rn: longword): longword; [INTERNPROC: in_arm_uhasx];
+function arm_uhsax(rm, rn: longword): longword; [INTERNPROC: in_arm_uhsax];
+function arm_uhsub16(rm, rn: longword): longword; [INTERNPROC: in_arm_uhsub16];
+function arm_uhsub8(rm, rn: longword): longword; [INTERNPROC: in_arm_uhsub8];
+function arm_uqadd16(rm, rn: longword): longword; [INTERNPROC: in_arm_uqadd16];
+function arm_uqadd8(rm, rn: longword): longword; [INTERNPROC: in_arm_uqadd8];
+function arm_uqasx(rm, rn: longword): longword; [INTERNPROC: in_arm_uqasx];
+function arm_uqsax(rm, rn: longword): longword; [INTERNPROC: in_arm_uqsax];
+function arm_uqsub16(rm, rn: longword): longword; [INTERNPROC: in_arm_uqsub16];
+function arm_uqsub8(rm, rn: longword): longword; [INTERNPROC: in_arm_uqsub8];
+function arm_usax(rm, rn: longword): longword; [INTERNPROC: in_arm_usax];
+function arm_usub16(rm, rn: longword): longword; [INTERNPROC: in_arm_usub16];
+function arm_usub8(rm, rn: longword): longword; [INTERNPROC: in_arm_usub8];
+function arm_usad8(rm, rn: longword): longword; [INTERNPROC: in_arm_usad8];
+function arm_sxtab(rm, rn: longword): longword; [INTERNPROC: in_arm_sxtab];
+function arm_sxtab16(rm, rn: longword): longword; [INTERNPROC: in_arm_sxtab16];
+function arm_sxtah(rm, rn: longword): longword; [INTERNPROC: in_arm_sxtah];
+function arm_uxtab(rm, rn: longword): longword; [INTERNPROC: in_arm_uxtab];
+function arm_uxtab16(rm, rn: longword): longword; [INTERNPROC: in_arm_uxtab16];
+function arm_uxtah(rm, rn: longword): longword; [INTERNPROC: in_arm_uxtah];
+function arm_sxtab(rm, rn: longword; ror: longint): longword; [INTERNPROC: in_arm_sxtab_ror];
+function arm_sxtab16(rm, rn: longword; ror: longint): longword; [INTERNPROC: in_arm_sxtab16_ror];
+function arm_sxtah(rm, rn: longword; ror: longint): longword; [INTERNPROC: in_arm_sxtah_ror];
+function arm_uxtab(rm, rn: longword; ror: longint): longword; [INTERNPROC: in_arm_uxtab_ror];
+function arm_uxtab16(rm, rn: longword; ror: longint): longword; [INTERNPROC: in_arm_uxtab16_ror];
+function arm_uxtah(rm, rn: longword; ror: longint): longword; [INTERNPROC: in_arm_uxtah_ror];
+function arm_sxtb(rm: longword): longword; [INTERNPROC: in_arm_sxtb];
+function arm_sxtb16(rm: longword): longword; [INTERNPROC: in_arm_sxtb16];
+function arm_sxth(rm: longword): longword; [INTERNPROC: in_arm_sxth];
+function arm_uxtb(rm: longword): longword; [INTERNPROC: in_arm_uxtb];
+function arm_uxtb16(rm: longword): longword; [INTERNPROC: in_arm_uxtb16];
+function arm_uxth(rm: longword): longword; [INTERNPROC: in_arm_uxth];
+function arm_sxtb(rm: longword; ror: longint): longword; [INTERNPROC: in_arm_sxtb_ror];
+function arm_sxtb16(rm: longword; ror: longint): longword; [INTERNPROC: in_arm_sxtb16_ror];
+function arm_sxth(rm: longword; ror: longint): longword; [INTERNPROC: in_arm_sxth_ror];
+function arm_uxtb(rm: longword; ror: longint): longword; [INTERNPROC: in_arm_uxtb_ror];
+function arm_uxtb16(rm: longword; ror: longint): longword; [INTERNPROC: in_arm_uxtb16_ror];
+function arm_uxth(rm: longword; ror: longint): longword; [INTERNPROC: in_arm_uxth_ror];
+function arm_clz(rm: longword): longword; [INTERNPROC: in_arm_clz];
+function arm_rbit(rm: longword): longword; [INTERNPROC: in_arm_rbit];
+function arm_rev(rm: longword): longword; [INTERNPROC: in_arm_rev];
+function arm_rev16(rm: longword): longword; [INTERNPROC: in_arm_rev16];
+function arm_revsh(rm: longword): longword; [INTERNPROC: in_arm_revsh];
+function arm_sbfx(rn: longword; lsb, width: longint): longword; [INTERNPROC: in_arm_sbfx];
+function arm_ubfx(rn: longword; lsb, width: longint): longword; [INTERNPROC: in_arm_ubfx];
+function arm_ssat(sat: longint; rn: longword): longword; [INTERNPROC: in_arm_ssat];
+function arm_usat(sat: longint; rn: longword): longword; [INTERNPROC: in_arm_usat];
+function arm_ssat16(sat: longint; rn: longword): longword; [INTERNPROC: in_arm_ssat16];
+function arm_usat16(sat: longint; rn: longword): longword; [INTERNPROC: in_arm_usat16];

+ 6 - 0
rtl/inc/innr.inc

@@ -137,3 +137,9 @@ const
 
    { SSE }
 
+{ ARM }
+   in_arm_base             = 300;
+   
+{$ifdef ARM}
+  {$i arminnr.inc}
+{$endif ARM}

+ 4 - 0
rtl/inc/systemh.inc

@@ -798,6 +798,10 @@ procedure ReadDependencyBarrier;
 procedure ReadWriteBarrier;
 procedure WriteBarrier;
 
+{$ifdef ARM}
+  {$i armprocs.inc}
+{$endif ARM}
+
 
 {****************************************************************************
                           Math Routines