diff --git a/compiler/arm/aasmcpu.pas b/compiler/arm/aasmcpu.pas index 1086f17867..565b9dca41 100644 --- a/compiler/arm/aasmcpu.pas +++ b/compiler/arm/aasmcpu.pas @@ -1596,6 +1596,12 @@ implementation s:=s+' am2 '; end else + if (ot and OT_SHIFTEROP)=OT_SHIFTEROP then + begin + s:=s+'shifterop'; + addsize:=false; + end + else s:=s+'???'; { size } if addsize then @@ -1867,6 +1873,8 @@ implementation begin ot:=OT_SHIFTEROP; end; + top_conditioncode: + ot:=OT_CONDITION; else internalerror(2004022623); end; @@ -1900,7 +1908,6 @@ implementation {siz : array[0..3] of longint;} begin Matches:=100; - writeln(getstring,'---'); { Check the opcode and operands } if (p^.opcode<>opcode) or (p^.ops<>ops) then @@ -1942,7 +1949,7 @@ implementation { update condition flags or floating point single } if (oppostfix=PF_S) and - not(p^.code[0] in [#$04]) then + not(p^.code[0] in [#$04..#$0B]) then begin Matches:=0; exit; @@ -2113,61 +2120,317 @@ implementation procedure taicpu.gencode(objdata:TObjData); + const + CondVal : array[TAsmCond] of byte=( + $E, $0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $A, + $B, $C, $D, $E, 0); var bytes : dword; i_field : byte; + currsym : TObjSymbol; + offset : longint; procedure setshifterop(op : byte); + var + r : byte; + imm : dword; begin case oper[op]^.typ of top_const: begin i_field:=1; - bytes:=bytes or dword(oper[op]^.val and $fff); + if oper[op]^.val and $ff=oper[op]^.val then + bytes:=bytes or dword(oper[op]^.val) + else + begin + { calc rotate and adjust imm } + r:=0; + imm:=dword(oper[op]^.val); + repeat + imm:=RolDWord(imm, 2); + inc(r) + until imm and $ff=imm; + bytes:=bytes or (r shl 8) or imm; + end; end; top_reg: begin i_field:=0; - bytes:=bytes or (getsupreg(oper[op]^.reg) shl 16); + bytes:=bytes or getsupreg(oper[op]^.reg); { does a real shifter op follow? } - if (op+1<=op) and (oper[op+1]^.typ=top_shifterop) then - begin - end; + if (op+1SM_RRX then + bytes:=bytes or (ord(shiftmode) - ord(SM_LSL)) shl 5 + else + bytes:=bytes or (3 shl 5); + if getregtype(rs) <> R_INVALIDREGISTER then + begin + bytes:=bytes or (1 shl 4); + bytes:=bytes or (getsupreg(rs) shl 8); + end + end; end; else internalerror(2005091103); end; end; + function MakeRegList(reglist: tcpuregisterset): word; + var + i, w: word; + begin + result:=0; + w:=1; + for i:=RS_R0 to RS_R15 do + begin + if i in reglist then + result:=result or w; + w:=w shl 1 + end; + end; + begin bytes:=$0; i_field:=0; { evaluate and set condition code } + bytes:=bytes or (CondVal[condition] shl 28); { condition code allowed? } { setup rest of the instruction } case insentry^.code[0] of - #$08: + #$01: // B/BL begin { set instruction code } - bytes:=bytes or (ord(insentry^.code[1]) shl 26); - bytes:=bytes or (ord(insentry^.code[2]) shl 21); - + bytes:=bytes or (ord(insentry^.code[1]) shl 24); + { set offset } + currsym:=objdata.symbolref(oper[0]^.ref^.symbol); + if (currsym.bind<>AB_LOCAL) and (currsym.objsection<>objdata.CurrObjSec) then + objdata.writereloc(oper[0]^.ref^.offset,0,currsym,RELOC_RELATIVE_24) + else + bytes:=bytes or (((currsym.offset-insoffset-8) shr 2) and $ffffff); + end; + #$04..#$07: // SUB + begin + { set instruction code } + bytes:=bytes or (ord(insentry^.code[1]) shl 24); + bytes:=bytes or (ord(insentry^.code[2]) shl 16); { set destination } bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); - + { set Rn } + bytes:=bytes or (getsupreg(oper[1]^.reg) shl 16); { create shifter op } - setshifterop(1); - - { set i field } + setshifterop(2); + { set I field } bytes:=bytes or (i_field shl 25); - - { set s if necessary } + { set S if necessary } if oppostfix=PF_S then bytes:=bytes or (1 shl 20); end; + #$08,#$0A,#$0B: // MOV + begin + { set instruction code } + bytes:=bytes or (ord(insentry^.code[1]) shl 24); + bytes:=bytes or (ord(insentry^.code[2]) shl 16); + { set destination } + bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); + { create shifter op } + setshifterop(1); + { set I field } + bytes:=bytes or (i_field shl 25); + { set S if necessary } + if oppostfix=PF_S then + bytes:=bytes or (1 shl 20); + end; + #$0C,#$0E,#$0F: // CMP + begin + { set instruction code } + bytes:=bytes or (ord(insentry^.code[1]) shl 24); + bytes:=bytes or (ord(insentry^.code[2]) shl 16); + { set destination } + bytes:=bytes or (getsupreg(oper[0]^.reg) shl 16); + { create shifter op } + setshifterop(1); + { set I field } + bytes:=bytes or (i_field shl 25); + { always set S bit } + bytes:=bytes or (1 shl 20); + end; + #$14: // MUL/MLA r1,r2,r3 + begin + { set instruction code } + bytes:=bytes or ord(insentry^.code[1]) shl 24; + bytes:=bytes or ord(insentry^.code[2]) shl 16; + bytes:=bytes or ord(insentry^.code[3]); + { set regs } + bytes:=bytes or getsupreg(oper[0]^.reg) shl 16; + bytes:=bytes or getsupreg(oper[1]^.reg); + bytes:=bytes or getsupreg(oper[2]^.reg) shl 8; + end; + #$15: // MUL/MLA r1,r2,r3,r4 + begin + { set instruction code } + bytes:=bytes or ord(insentry^.code[1]) shl 24; + bytes:=bytes or ord(insentry^.code[2]) shl 16; + bytes:=bytes or ord(insentry^.code[3]); + { set regs } + bytes:=bytes or getsupreg(oper[0]^.reg) shl 16; + bytes:=bytes or getsupreg(oper[1]^.reg); + bytes:=bytes or getsupreg(oper[2]^.reg) shl 8; + bytes:=bytes or getsupreg(oper[3]^.reg) shl 12; + end; + #$16: // MULL r1,r2,r3,r4 + begin + { set instruction code } + bytes:=bytes or ord(insentry^.code[1]) shl 24; + bytes:=bytes or ord(insentry^.code[2]) shl 16; + bytes:=bytes or ord(insentry^.code[3]); + { set regs } + bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; + bytes:=bytes or getsupreg(oper[1]^.reg) shl 16; + bytes:=bytes or getsupreg(oper[2]^.reg); + bytes:=bytes or getsupreg(oper[3]^.reg) shl 8; + end; + #$17: // LDR/STR + begin + { set instruction code } + bytes:=bytes or (ord(insentry^.code[1]) shl 24); + bytes:=bytes or (ord(insentry^.code[2]) shl 16); + { set Rn and Rd } + bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; + bytes:=bytes or getsupreg(oper[1]^.ref^.base) shl 16; + if getregtype(oper[1]^.ref^.index)=R_INVALIDREGISTER then + begin + { set offset } + offset:=0; + currsym:=objdata.symbolref(oper[1]^.ref^.symbol); + if assigned(currsym) then + offset:=currsym.offset-insoffset-8; + offset:=offset+oper[1]^.ref^.offset; + if offset>=0 then + begin + { set U flag } + bytes:=bytes or (1 shl 23); + bytes:=bytes or offset + end + else + begin + offset:=-offset; + bytes:=bytes or offset + end; + end + else + begin + { set U flag } + if oper[1]^.ref^.signindex>0 then + bytes:=bytes or (1 shl 23); + { set I flag } + bytes:=bytes or (1 shl 25); + bytes:=bytes or getsupreg(oper[1]^.ref^.index); + { set shift } + with oper[1]^.ref^ do + if shiftmode<>SM_None then + begin + bytes:=bytes or (shiftimm shl 7); + if shiftmode<>SM_RRX then + bytes:=bytes or (ord(shiftmode) - ord(SM_LSL)) shl 5 + else + bytes:=bytes or (3 shl 5); + end + end; + { set W bit } + if oper[1]^.ref^.addressmode=AM_PREINDEXED then + bytes:=bytes or (1 shl 21); + { set P bit if necessary } + if oper[1]^.ref^.addressmode<>AM_POSTINDEXED then + bytes:=bytes or (1 shl 24); + end; + #$22: // LDRH/STRH + begin + { set instruction code } + bytes:=bytes or (ord(insentry^.code[1]) shl 16); + bytes:=bytes or ord(insentry^.code[2]); + { src/dest register (Rd) } + bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; + { base register (Rn) } + bytes:=bytes or getsupreg(oper[1]^.ref^.base) shl 16; + if getregtype(oper[1]^.ref^.index)=R_INVALIDREGISTER then + begin + bytes:=bytes or (1 shl 22); // with immediate offset + if oper[1]^.ref^.offset < 0 then + begin + bytes:=bytes or ((-oper[1]^.ref^.offset) and $f0 shl 4); + bytes:=bytes or ((-oper[1]^.ref^.offset) and $f); + end + else + begin + { set U bit } + bytes:=bytes or (1 shl 23); + bytes:=bytes or (oper[1]^.ref^.offset and $f0 shl 4); + bytes:=bytes or (oper[1]^.ref^.offset and $f); + end; + end + else + begin + { set U flag } + bytes:=bytes or (1 shl 23); + bytes:=bytes or getsupreg(oper[1]^.ref^.index); + end; + { set W bit } + if oper[1]^.ref^.addressmode=AM_PREINDEXED then + bytes:=bytes or (1 shl 21); + { set P bit if necessary } + if oper[1]^.ref^.addressmode<>AM_POSTINDEXED then + bytes:=bytes or (1 shl 24); + end; + #$26: // LDM/STM + begin + { set instruction code } + bytes:=bytes or (ord(insentry^.code[1]) shl 20); + if oper[0]^.typ=top_ref then + begin + { set W bit } + if oper[0]^.ref^.addressmode=AM_PREINDEXED then + bytes:=bytes or (1 shl 21); + { set Rn } + bytes:=bytes or (getsupreg(oper[0]^.ref^.index) shl 16); + end + else { typ=top_reg } + begin + { set Rn } + bytes:=bytes or (getsupreg(oper[0]^.reg) shl 16); + end; + { reglist } + bytes:=bytes or MakeRegList(oper[1]^.regset^); + { set P bit } + if (opcode=A_LDM) and (oppostfix in [PF_ED,PF_EA,PF_IB,PF_DB]) + or (opcode=A_STM) and (oppostfix in [PF_FA,PF_FD,PF_IB,PF_DB]) then + bytes:=bytes or (1 shl 24); + { set U bit } + if (opcode=A_LDM) and (oppostfix in [PF_ED,PF_FD,PF_IB,PF_IA]) + or (opcode=A_STM) and (oppostfix in [PF_FA,PF_EA,PF_IB,PF_IA]) then + bytes:=bytes or (1 shl 23); + end; + #$27: // SWP/SWPB + begin + { set instruction code } + bytes:=bytes or (ord(insentry^.code[1]) shl 20); + bytes:=bytes or (ord(insentry^.code[2]) shl 4); + { set regs } + bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); + bytes:=bytes or getsupreg(oper[1]^.reg); + bytes:=bytes or (getsupreg(oper[2]^.ref^.base) shl 16); + end; + #$03: // BX + begin + writeln(objdata.CurrObjSec.fullname); + Comment(v_warning,'BX instruction'); + // TBD + end; #$ff: internalerror(2005091101); else diff --git a/compiler/arm/armins.dat b/compiler/arm/armins.dat index 411983bb93..15fc82fc1f 100644 --- a/compiler/arm/armins.dat +++ b/compiler/arm/armins.dat @@ -97,33 +97,34 @@ void void none 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 +reg32,reg32,immshifter \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 +reg32,reg32,reg32 \4\x0\x80 ARM7 +reg32,reg32,reg32,reg32 \5\x0\x80 ARM7 +reg32,reg32,reg32,shifterop \6\x0\x80 ARM7 +reg32,reg32,immshifter \7\x2\x80 ARM7 [ADFcc] [ADRcc] [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 +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,reg32,shifterop \6\x0\x00 ARM7 +reg32,reg32,immshifter \7\x2\x00 ARM7 [Bcc] mem32 \1\x0A ARM7 imm24 \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 +;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,immshifter \7\x3\xC0 ARM7 [BLcc] mem32 \1\x0B ARM7 @@ -149,13 +150,13 @@ reg8,reg8 \300\1\x10\101 ARM7 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 +reg32,immshifter \xF\x1\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 +reg32,reg32,shifterop \xE\x1\x40 ARM7 +reg32,immshifter \xF\x3\x40 ARM7 [CLZcc] reg32,reg32 \x27\x01\x01 ARM7 @@ -171,10 +172,11 @@ reg32,reg32 \x27\x01\x01 ARM7 [DVFcc] [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 +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,reg32,shifterop \6\x0\x20 ARM7 +reg32,reg32,immshifter \7\x2\x20 ARM7 [EXPcc] @@ -193,14 +195,15 @@ reg32,reg32 \321\300\1\x11\101 ARM7 [LDMcc] memam4,reglist \x26\x81 ARM7 +reg32,reglist \x26\x81 ARM7 [LDRBTcc] [LDRBcc] -reg32,memam2 \x17\x07\x10 ARM7 +reg32,memam2 \x17\x04\x50 ARM7 [LDRcc] -reg32,memam2 \x17\x05\x10 ARM7 +reg32,memam2 \x17\x04\x10 ARM7 ; reg32,imm32 \x17\x05\x10 ARM7 ; reg32,reg32 \x18\x04\x10 ARM7 ; reg32,reg32,imm32 \x19\x04\x10 ARM7 @@ -208,22 +211,24 @@ reg32,memam2 \x17\x05\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 +reg32,memam2 \x22\x10\xB0 ARM7 +;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,memam2 \x22\x10\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 +reg32,memam2 \x22\x10\xF0 ARM7 +;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 [LDRTcc] @@ -243,11 +248,10 @@ reg32,imm8,fpureg \xF0\x02\x01 FPA reg32,reg32,reg32,reg32 \x15\x00\x20\x90 ARM7 [MOVcc] -; reg32,shifterop \x8\x0\0xd ARM7 -; reg32,immshifter \x8\x0\0xd ARM7 -; reg32,reg32,reg32 \x9\x1\xA0 ARM7 -; reg32,reg32,imm \xA\x1\xA0 ARM7 -; reg32,imm \xB\x3\xA0 ARM7 +reg32,shifterop \x8\x1\xA0 ARM7 +; reg32,reg32,reg32 \x9\x1\xA0 ARM7 +reg32,reg32,shifterop \xA\x1\xA0 ARM7 +reg32,immshifter \xB\x1\xA0 ARM7 [MRC] ; reg32,reg32 \321\301\1\x13\110 ARM7 @@ -272,18 +276,18 @@ fpureg,fpureg \xF2 FPA fpureg,immfpu \xF2 FPA [MVNcc] -; reg32,reg32 \x8\x0\0xf ARM7 -; reg32,reg32,reg32 \x9\x1\xE0 ARM7 -; reg32,reg32,imm \xA\x1\xE0 ARM7 -; reg32,imm \xB\x3\xE0 ARM7 +reg32,reg32 \x8\x1\xE0 ARM7 +; reg32,reg32,reg32 \x9\x1\xE0 ARM7 +reg32,reg32,shifterop \xA\x1\xE0 ARM7 +reg32,immshifter \xB\x1\xE0 ARM7 [NOP] [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 +reg32,reg32,reg32 \4\x1\x80 ARM7 +reg32,reg32,reg32,reg32 \5\x1\x80 ARM7 +reg32,reg32,reg32,shifterop \6\x1\x80 ARM7 +reg32,reg32,immshifter \7\x3\x80 ARM7 [RDFcc] @@ -296,16 +300,16 @@ reg32,reg32,imm \7\x3\x80 ARM7 [RPWcc] [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 +;reg32,reg32,reg32 \4\x0\x60 ARM7 +;reg32,reg32,reg32,reg32 \5\x0\x60 ARM7 +reg32,reg32,reg32,shifterop \6\x0\x60 ARM7 +reg32,reg32,immshifter \7\x0\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 +reg32,reg32,immshifter \7\x2\xE0 ARM7 [RSFcc] @@ -317,7 +321,7 @@ reg32,reg32,imm \7\x2\xE0 ARM7 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 +reg32,reg32,immshifter \7\x2\xC0 ARM7 [SFMcc] reg32,imm8,fpureg \xF0\x02\x00 FPA @@ -338,6 +342,7 @@ reg32,reg32,reg32,reg32 \x16\x00\xC0\x90 ARM7 [STMcc] memam4,reglist \x26\x80 ARM7 +reg32,reglist \x26\x80 ARM7 [STRcc] reg32,memam2 \x17\x04\x00 ARM7 @@ -348,35 +353,36 @@ reg32,memam2 \x17\x04\x00 ARM7 ; reg32,reg32,reg32,imm32 \x21\x06\x00 ARM7 [STRBcc] -reg32,memam2 \x17\x06\x00 ARM7 +reg32,memam2 \x17\x04\x40 ARM7 [STRBTcc] ; 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 +reg32,memam2 \x22\x00\xB0 ARM7 +;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 [STRTcc] [SUBcc] -reg32,reg32,shifterop \4\x0\x40 ARM7 -reg32,reg32,immshifter \4\x0\x40 ARM7 -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 +reg32,reg32,shifterop \4\x0\x40 ARM7 +reg32,reg32,immshifter \4\x0\x40 ARM7 +reg32,reg32,reg32 \4\x0\x40 ARM7 +; reg32,reg32,reg32,reg32 \5\x0\x40 ARM7 +reg32,reg32,reg32,shifterop \6\x0\x40 ARM7 +; reg32,reg32,imm \7\x2\x40 ARM7 [SWIcc] imm \2\x0F ARM7 [SWPcc] -reg32,reg32,reg32 \x27\x01\x90 ARM7 +reg32,reg32,memam2 \x27\x10\x09 ARM7 [SWPBcc] -reg32,reg32,reg32 \x27\x01\x90 ARM7 +reg32,reg32,reg32 \x27\x14\x09 ARM7 [TANcc] @@ -387,10 +393,10 @@ 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 +reg32,reg32 \xC\x1\x00 ARM7 +reg32,reg32,reg32 \xD\x1\x00 ARM7 +reg32,reg32,shifterop \xE\x1\x00 ARM7 +reg32,immshifter \xF\x3\x00 ARM7 [UMLALcc] reg32,reg32,reg32,reg32 \x16\x00\xA0\x90 ARM7 diff --git a/compiler/arm/armnop.inc b/compiler/arm/armnop.inc index 75c5263999..2a476f44d4 100644 --- a/compiler/arm/armnop.inc +++ b/compiler/arm/armnop.inc @@ -1,2 +1,2 @@ { don't edit, this file is generated from armins.dat } -105; +98; diff --git a/compiler/arm/armtab.inc b/compiler/arm/armtab.inc index f0e43f6832..bc273e4e37 100644 --- a/compiler/arm/armtab.inc +++ b/compiler/arm/armtab.inc @@ -31,7 +31,7 @@ ( opcode : A_ADC; ops : 3; - optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); + optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none); code : #7#2#160; flags : if_arm7 ), @@ -52,14 +52,14 @@ ( opcode : A_ADD; ops : 4; - optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate); + optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop); code : #6#0#128; flags : if_arm7 ), ( opcode : A_ADD; ops : 3; - optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); + optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none); code : #7#2#128; flags : if_arm7 ), @@ -73,21 +73,14 @@ ( 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); + optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop); code : #6#0#0; flags : if_arm7 ), ( opcode : A_AND; ops : 3; - optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); + optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none); code : #7#2#0; flags : if_arm7 ), @@ -108,28 +101,7 @@ ( opcode : A_BIC; ops : 3; - optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); - 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,ot_none); + optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none); code : #7#3#192; flags : if_arm7 ), @@ -199,8 +171,8 @@ ( opcode : A_CMN; ops : 2; - optypes : (ot_reg32,ot_immediate,ot_none,ot_none); - code : #15#3#96; + optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none); + code : #15#1#96; flags : if_arm7 ), ( @@ -220,14 +192,14 @@ ( opcode : A_CMP; ops : 3; - optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); + optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none); code : #14#1#64; flags : if_arm7 ), ( opcode : A_CMP; ops : 2; - optypes : (ot_reg32,ot_immediate,ot_none,ot_none); + optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none); code : #15#3#64; flags : if_arm7 ), @@ -248,21 +220,14 @@ ( 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); + optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop); code : #6#0#32; flags : if_arm7 ), ( opcode : A_EOR; ops : 3; - optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); + optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none); code : #7#2#32; flags : if_arm7 ), @@ -280,53 +245,39 @@ code : #38#129; flags : if_arm7 ), + ( + opcode : A_LDM; + ops : 2; + optypes : (ot_reg32,ot_reglist,ot_none,ot_none); + code : #38#129; + flags : if_arm7 + ), ( opcode : A_LDRB; ops : 2; optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none); - code : #23#7#16; + code : #23#4#80; flags : if_arm7 ), ( opcode : A_LDR; ops : 2; optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none); - code : #23#5#16; + code : #23#4#16; flags : if_arm7 ), ( opcode : A_LDRH; ops : 2; - optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,ot_none); - code : #34#80#176; - flags : if_arm7 - ), - ( - opcode : A_LDRH; - ops : 2; - optypes : (ot_reg32,ot_reg32,ot_none,ot_none); - code : #35#80#176; - flags : if_arm7 - ), - ( - opcode : A_LDRH; - ops : 3; - optypes : (ot_reg32,ot_reg32,ot_immediate or ot_bits32,ot_none); - code : #36#80#176; - flags : if_arm7 - ), - ( - opcode : A_LDRH; - ops : 3; - optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); - code : #37#16#176; + optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none); + code : #34#16#176; flags : if_arm7 ), ( opcode : A_LDRSB; ops : 2; - optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,ot_none); - code : #34#80#208; + optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none); + code : #34#16#208; flags : if_arm7 ), ( @@ -353,29 +304,8 @@ ( opcode : A_LDRSH; ops : 2; - optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,ot_none); - code : #34#80#240; - flags : if_arm7 - ), - ( - opcode : A_LDRSH; - ops : 2; - optypes : (ot_reg32,ot_reg32,ot_none,ot_none); - code : #35#80#240; - flags : if_arm7 - ), - ( - opcode : A_LDRSH; - ops : 3; - optypes : (ot_reg32,ot_reg32,ot_immediate or ot_bits32,ot_none); - code : #36#80#240; - flags : if_arm7 - ), - ( - opcode : A_LDRSH; - ops : 3; - optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); - code : #37#16#240; + optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none); + code : #34#16#240; flags : if_arm7 ), ( @@ -392,6 +322,27 @@ code : #21#0#32#144; flags : if_arm7 ), + ( + opcode : A_MOV; + ops : 2; + optypes : (ot_reg32,ot_shifterop,ot_none,ot_none); + code : #8#1#160; + flags : if_arm7 + ), + ( + opcode : A_MOV; + ops : 3; + optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none); + code : #10#1#160; + flags : if_arm7 + ), + ( + opcode : A_MOV; + ops : 2; + optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none); + code : #11#1#160; + flags : if_arm7 + ), ( opcode : A_MRS; ops : 2; @@ -441,6 +392,27 @@ code : #242; flags : if_fpa ), + ( + opcode : A_MVN; + ops : 2; + optypes : (ot_reg32,ot_reg32,ot_none,ot_none); + code : #8#1#224; + flags : if_arm7 + ), + ( + opcode : A_MVN; + ops : 3; + optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none); + code : #10#1#224; + flags : if_arm7 + ), + ( + opcode : A_MVN; + ops : 2; + optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none); + code : #11#1#224; + flags : if_arm7 + ), ( opcode : A_ORR; ops : 3; @@ -458,43 +430,29 @@ ( opcode : A_ORR; ops : 4; - optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate); + optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop); code : #6#1#128; flags : if_arm7 ), ( opcode : A_ORR; ops : 3; - optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); + optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none); code : #7#3#128; flags : if_arm7 ), - ( - opcode : A_RSB; - ops : 3; - optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); - 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); + optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop); code : #6#0#96; flags : if_arm7 ), ( opcode : A_RSB; ops : 3; - optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); - code : #7#2#96; + optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none); + code : #7#0#96; flags : if_arm7 ), ( @@ -521,7 +479,7 @@ ( opcode : A_RSC; ops : 3; - optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); + optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none); code : #7#2#224; flags : if_arm7 ), @@ -549,7 +507,7 @@ ( opcode : A_SBC; ops : 3; - optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); + optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none); code : #7#2#192; flags : if_arm7 ), @@ -581,6 +539,13 @@ code : #38#128; flags : if_arm7 ), + ( + opcode : A_STM; + ops : 2; + optypes : (ot_reg32,ot_reglist,ot_none,ot_none); + code : #38#128; + flags : if_arm7 + ), ( opcode : A_STR; ops : 2; @@ -592,35 +557,14 @@ opcode : A_STRB; ops : 2; optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none); - code : #23#6#0; + code : #23#4#64; flags : if_arm7 ), ( opcode : A_STRH; ops : 2; - optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,ot_none); - code : #34#64#176; - flags : if_arm7 - ), - ( - opcode : A_STRH; - ops : 2; - optypes : (ot_reg32,ot_reg32,ot_none,ot_none); - code : #35#64#176; - flags : if_arm7 - ), - ( - opcode : A_STRH; - ops : 3; - optypes : (ot_reg32,ot_reg32,ot_immediate or ot_bits32,ot_none); - code : #36#64#176; - flags : if_arm7 - ), - ( - opcode : A_STRH; - ops : 3; - optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); - code : #37#0#176; + optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none); + code : #34#0#176; flags : if_arm7 ), ( @@ -644,6 +588,13 @@ code : #4#0#64; flags : if_arm7 ), + ( + opcode : A_SUB; + ops : 4; + optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop); + code : #6#0#64; + flags : if_arm7 + ), ( opcode : A_SWI; ops : 1; @@ -654,15 +605,15 @@ ( opcode : A_SWP; ops : 3; - optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); - code : #39#1#144; + optypes : (ot_reg32,ot_reg32,ot_memoryam2,ot_none); + code : #39#16#9; flags : if_arm7 ), ( opcode : A_SWPB; ops : 3; optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); - code : #39#1#144; + code : #39#20#9; flags : if_arm7 ), ( @@ -710,14 +661,14 @@ ( opcode : A_TST; ops : 3; - optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); + optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none); code : #14#1#0; flags : if_arm7 ), ( opcode : A_TST; ops : 2; - optypes : (ot_reg32,ot_immediate,ot_none,ot_none); + optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none); code : #15#3#0; flags : if_arm7 ), diff --git a/compiler/ogcoff.pas b/compiler/ogcoff.pas index e17d776394..252b05539b 100644 --- a/compiler/ogcoff.pas +++ b/compiler/ogcoff.pas @@ -1009,10 +1009,9 @@ const pemagic : array[0..3] of byte = ( result:=aname else begin - { non-PECOFF targets lack rodata support. - TODO: WinCE likely supports it, but needs testing. } + { non-PECOFF targets lack rodata support } if (atype in [sec_rodata,sec_rodata_norel]) and - not (target_info.system in systems_windows) then + not (target_info.system in systems_all_windows) then atype:=sec_data; secname:=coffsecnames[atype]; if create_smartlink_sections and @@ -1038,8 +1037,7 @@ const pemagic : array[0..3] of byte = ( begin if (aType in [sec_rodata,sec_rodata_norel]) then begin - { TODO: WinCE needs testing } - if (target_info.system in systems_windows) then + if (target_info.system in systems_all_windows) then aType:=sec_rodata_norel else aType:=sec_data; @@ -1279,6 +1277,8 @@ const pemagic : array[0..3] of byte = ( rel.reloctype:=IMAGE_REL_ARM_ADDR32NB; RELOC_SECREL32 : rel.reloctype:=IMAGE_REL_ARM_SECREL; + RELOC_RELATIVE_24 : + rel.reloctype:=IMAGE_REL_ARM_BRANCH24; {$endif arm} {$ifdef i386} RELOC_RELATIVE : @@ -3045,7 +3045,7 @@ const pemagic : array[0..3] of byte = ( asmbin : ''; asmcmd : ''; supported_targets : [system_arm_wince]; - flags : [af_outputbinary]; + flags : [af_outputbinary,af_smartlink_sections]; labelprefix : '.L'; comment : ''; dollarsign: '$';