* continued to work on arm binary writer, started to fix operand matching

git-svn-id: trunk@1073 -
This commit is contained in:
florian 2005-09-11 10:01:54 +00:00
parent eb26e1aa39
commit d280ed6e8b
6 changed files with 186 additions and 101 deletions

View File

@ -49,8 +49,10 @@ uses
OT_NEAR = $00000040;
OT_SHORT = $00000080;
OT_BITSTINY = $00000100; { fpu constant }
OT_BITSSHIFTER =
$00000200;
OT_SIZE_MASK = $000000FF; { all the size attributes }
OT_SIZE_MASK = $000003FF; { all the size attributes }
OT_NON_SIZE = longint(not OT_SIZE_MASK);
OT_SIGNED = $00000100; { the operand need to be signed -128-127 }
@ -59,15 +61,21 @@ uses
{ reverse effect in FADD, FSUB &c }
OT_COLON = $00000400;
OT_SHIFTEROP = $00000800;
OT_REGISTER = $00001000;
OT_IMMEDIATE = $00002000;
OT_REGLIST = $00008000;
OT_IMM8 = $00002001;
OT_IMM16 = $00002002;
OT_IMM24 = $00002002;
OT_IMM32 = $00002004;
OT_IMM64 = $00002008;
OT_IMM80 = $00002010;
OT_IMMTINY = $00002100;
OT_IMMSHIFTER= $00002200;
OT_IMMEDIATE24 = OT_IMM24;
OT_SHIFTIMM = OT_SHIFTEROP or OT_IMMSHIFTER;
OT_SHIFTIMMEDIATE = OT_SHIFTIMM;
OT_IMMEDIATEFPU = OT_IMMTINY;
OT_REGMEM = $00200000; { for r/m, ie EA, operands }
@ -83,6 +91,19 @@ uses
OT_MEM32 = $00204004;
OT_MEM64 = $00204008;
OT_MEM80 = $00204010;
{ word/byte load/store }
OT_AM2 = $00010000;
{ misc ld/st operations }
OT_AM3 = $00020000;
{ multiple ld/st operations }
OT_AM4 = $00040000;
{ co proc. ld/st operations }
OT_AM5 = $00080000;
OT_AMMASK = $000f0000;
OT_MEMORYAM4 = OT_MEMORY or OT_AM4;
OT_MEMORYAM5 = OT_MEMORY or OT_AM5;
OT_FPUREG = $01000000; { floating point stack registers }
OT_REG_SMASK = $00070000; { special register operands: these may be treated differently }
{ a mask for the following }
@ -853,6 +874,8 @@ implementation
begin
s:=s+'mem';
addsize:=true;
if (ot and OT_AM2)<>0 then
s:=s+' am2';
end
else
s:=s+'???';
@ -867,6 +890,9 @@ implementation
else
if (ot and OT_BITS32)<>0 then
s:=s+'32'
else
if (ot and OT_BITSSHIFTER)<>0 then
s:=s+'shifter'
else
s:=s+'??';
{ signed }
@ -909,6 +935,11 @@ implementation
function taicpu.Pass1(offset:longint):longint;
var
ldr2op : array[PF_B..PF_T] of tasmop = (
A_LDRB,A_LDRSB,A_LDRBT,A_LDRH,A_LDRSH,A_LDRT);
str2op : array[PF_B..PF_T] of tasmop = (
A_STRB,A_None,A_STRBT,A_STRH,A_None,A_STRT);
begin
Pass1:=0;
{ Save the old offset and set the new offset }
@ -918,6 +949,27 @@ implementation
exit;
{ set the file postion }
aktfilepos:=fileinfo;
{ tranlate LDR+postfix to complete opcode }
if (opcode=A_LDR) and (oppostfix<>PF_None) then
begin
if (oppostfix in [low(ldr2op)..high(ldr2op)]) then
opcode:=ldr2op[oppostfix]
else
internalerror(2005091001);
if opcode=A_None then
internalerror(2005091004);
end
else if (opcode=A_STR) and (oppostfix<>PF_None) then
begin
if (oppostfix in [low(str2op)..high(str2op)]) then
opcode:=str2op[oppostfix]
else
internalerror(2005091002);
if opcode=A_None then
internalerror(2005091003);
end;
{ Get InsEntry }
if FindInsEntry then
begin
@ -963,6 +1015,7 @@ implementation
procedure taicpu.create_ot;
var
i,l,relsize : longint;
dummy : byte;
begin
if ops=0 then
exit;
@ -979,7 +1032,7 @@ implementation
begin
case getregtype(reg) of
R_INTREGISTER:
ot:=OT_REG32;
ot:=OT_REG32 or OT_SHIFTEROP;
R_FPUREGISTER:
ot:=OT_FPUREG;
else
@ -1000,6 +1053,38 @@ implementation
if (ref^.base=NR_NO) and (ref^.index=NR_NO) then
ot:=ot or OT_MEM_OFFS;
{ if we need to fix a reference, we do it here }
{ determine possible address modes }
if (ref^.base<>NR_NO) and
(
(
(ref^.index=NR_NO) and
(ref^.shiftmode=SM_None) and
(ref^.offset>=-4097) and
(ref^.offset<=4097)
) or
(
(ref^.shiftmode=SM_None) and
(ref^.offset=0)
) or
(
(ref^.index<>NR_NO) and
(ref^.shiftmode<>SM_None) and
(ref^.shiftimm<=31) and
(ref^.offset=0)
)
) then
ot:=ot or OT_AM2;
if (ref^.index<>NR_NO) and
(oppostfix in [PF_IA,PF_IB,PF_DA,PF_DB,PF_FD,PF_FA,PF_ED,PF_EA]) and
(
(ref^.base=NR_NO) and
(ref^.shiftmode=SM_None) and
(ref^.offset=0)
) then
ot:=ot or OT_AM4;
end
else
begin
@ -1008,8 +1093,8 @@ implementation
inc(l,ref^.symbol.address);
if (not assigned(ref^.symbol) or
((ref^.symbol.currbind<>AB_EXTERNAL) and (ref^.symbol.address<>0))) and
(relsize>=-128) and (relsize<=127) then
ot:=OT_IMM32 or OT_SHORT
(relsize>=-33554428) and (relsize<=33554428) and (relsize mod 4=0) then
ot:=OT_IMM24
else
ot:=OT_IMM32 or OT_NEAR;
end;
@ -1026,14 +1111,10 @@ implementation
top_const :
begin
ot:=OT_IMMEDIATE;
{ fixme !!!!
if opsize=S_NO then
message(asmr_e_invalid_opcode_and_operand);
if (opsize<>S_W) and (longint(val)>=-128) and (val<=127) then
ot:=OT_IMM8 or OT_SIGNED
if is_shifter_const(val,dummy) then
ot:=OT_IMMSHIFTER
else
ot:=OT_IMMEDIATE or opsize_2_type[i,opsize];
}
ot:=OT_IMM32
end;
top_none :
begin
@ -1043,6 +1124,7 @@ implementation
end;
top_shifterop:
begin
ot:=OT_SHIFTEROP;
end;
else
internalerror(200402261);
@ -1077,6 +1159,7 @@ 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
@ -1111,6 +1194,51 @@ implementation
end;
end;
{ check postfixes:
the existance of a certain postfix requires a
particular code }
{ update condition flags
or floating point single }
if (oppostfix=PF_S) and
not(p^.code[0] in []) then
begin
Matches:=0;
exit;
end;
{ floating point size }
if (oppostfix in [PF_D,PF_E,PF_P,PF_EP]) and
not(p^.code[0] in []) then
begin
Matches:=0;
exit;
end;
{ multiple load/store address modes }
if (oppostfix in [PF_IA,PF_IB,PF_DA,PF_DB,PF_FD,PF_FA,PF_ED,PF_EA]) and
not(p^.code[0] in [
// stm,ldm
#$26
]) then
begin
Matches:=0;
exit;
end;
{ we shouldn't see any opsize prefixes here }
if (oppostfix in [PF_B,PF_SB,PF_BT,PF_H,PF_SH,PF_T]) then
begin
Matches:=0;
exit;
end;
if (roundingmode<>RM_None) and not(p^.code[0] in []) then
begin
Matches:=0;
exit;
end;
{ Check operand sizes }
{ as default an untyped size can get all the sizes, this is different
from nasm, but else we need to do a lot checking which opcodes want
@ -1559,7 +1687,7 @@ static char *CC[] =
out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG);
return;
case 0xC: // CMP Rn,Rm
case 0xD: // CMP Rn,Rm,<shift>Rs
@ -1735,7 +1863,7 @@ static char *CC[] =
case 0x14: // MUL Rd,Rm,Rs
case 0x15: // MULA Rd,Rm,Rs,Rn
++codes;
bytes[0] = c | *codes++;
bytes[1] = *codes++;
@ -2027,7 +2155,7 @@ static char *CC[] =
data = -8;
else
data = 0;
if (data < 0)
{
data = -data;

View File

@ -125,11 +125,11 @@ reg32,reg32,imm \7\x3\xC0 ARM7
[BLcc]
mem32 \1\x0B ARM7
imm32 \1\x0B ARM7
imm24 \1\x0B ARM7
[BLX]
mem32 \xff ARM7
imm32 \xff ARM7
imm24 \xff ARM7
[BKPTcc]
@ -186,7 +186,7 @@ reg32,reg32,imm \7\x2\x20 ARM7
reg32,reg32 \321\300\1\x11\101 ARM7
[LDMcc]
reg32,reglist \x26\x81 ARM7
memam4,reglist \x26\x81 ARM7
[LDRBTcc]
@ -235,10 +235,10 @@ reg32,mem32 \320\301\1\x13\110 ARM7
reg32,reg32,reg32,reg32 \x15\x00\x20\x90 ARM7
[MOVcc]
reg32,reg32 \x8\x1\xA0 ARM7
reg32,reg32,reg32 \x9\x1\xA0 ARM7
reg32,reg32,imm \xA\x1\xA0 ARM7
reg32,imm \xB\x3\xA0 ARM7
reg32,shifterop \x8\x1\xA0 ARM7
; reg32,reg32,reg32 \x9\x1\xA0 ARM7
; reg32,reg32,imm \xA\x1\xA0 ARM7
; reg32,imm \xB\x3\xA0 ARM7
; [MRC]
; reg32,reg32 \321\301\1\x13\110 ARM7
@ -326,7 +326,7 @@ reg32,reg32,reg32,reg32 \x16\x00\xC0\x90 ARM7
[STFcc]
[STMcc]
reg32,reglist \x26\x80 ARM7
memam4,reglist \x26\x80 ARM7
[STRcc]
reg32,imm32 \x17\x05\x00 ARM7
@ -349,10 +349,10 @@ reg32,reg32,reg32 \x25\x00\xB0 ARM7
[STRTcc]
[SUBcc]
reg32,reg32,reg32 \4\x0\x40 ARM7
reg32,reg32,reg32,reg32 \5\x0\x40 ARM7
reg32,reg32,reg32,imm \6\x0\x40 ARM7
reg32,reg32,imm \7\x2\x40 ARM7
reg32,reg32,shiftimm \4\x0\x40 ARM7
; reg32,reg32,reg32,reg32 \5\x0\x40 ARM7
; reg32,reg32,reg32,imm \6\x0\x40 ARM7
; reg32,reg32,imm \7\x2\x40 ARM7
[SWIcc]
imm \2\x0F ARM7

View File

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

View File

@ -143,7 +143,7 @@
(
opcode : A_BL;
ops : 1;
optypes : (ot_immediate or ot_bits32,ot_none,ot_none,ot_none);
optypes : (ot_immediate24,ot_none,ot_none,ot_none);
code : #1#11;
flags : if_arm7
),
@ -157,7 +157,7 @@
(
opcode : A_BLX;
ops : 1;
optypes : (ot_immediate or ot_bits32,ot_none,ot_none,ot_none);
optypes : (ot_immediate24,ot_none,ot_none,ot_none);
code : #15#15;
flags : if_arm7
),
@ -276,7 +276,7 @@
(
opcode : A_LDM;
ops : 2;
optypes : (ot_reg32,ot_reglist,ot_none,ot_none);
optypes : (ot_memoryam5,ot_reglist,ot_none,ot_none);
code : #38#129;
flags : if_arm7
),
@ -423,31 +423,10 @@
(
opcode : A_MOV;
ops : 2;
optypes : (ot_reg32,ot_reg32,ot_none,ot_none);
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_reg32,ot_none);
code : #9#1#160;
flags : if_arm7
),
(
opcode : A_MOV;
ops : 3;
optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none);
code : #10#1#160;
flags : if_arm7
),
(
opcode : A_MOV;
ops : 2;
optypes : (ot_reg32,ot_immediate,ot_none,ot_none);
code : #11#3#160;
flags : if_arm7
),
(
opcode : A_MUL;
ops : 3;
@ -633,7 +612,7 @@
(
opcode : A_STM;
ops : 2;
optypes : (ot_reg32,ot_reglist,ot_none,ot_none);
optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none);
code : #38#128;
flags : if_arm7
),
@ -703,31 +682,10 @@
(
opcode : A_SUB;
ops : 3;
optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none);
optypes : (ot_reg32,ot_reg32,ot_shiftimmediate,ot_none);
code : #4#0#64;
flags : if_arm7
),
(
opcode : A_SUB;
ops : 4;
optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32);
code : #5#0#64;
flags : if_arm7
),
(
opcode : A_SUB;
ops : 4;
optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate);
code : #6#0#64;
flags : if_arm7
),
(
opcode : A_SUB;
ops : 3;
optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none);
code : #7#2#64;
flags : if_arm7
),
(
opcode : A_SWI;
ops : 1;

View File

@ -118,8 +118,6 @@ unit cgcpu;
OpCmp2AsmCond : Array[topcmp] of TAsmCond = (C_NONE,C_EQ,C_GT,
C_LT,C_GE,C_LE,C_NE,C_LS,C_CC,C_CS,C_HI);
function is_shifter_const(d : aint;var imm_shift : byte) : boolean;
function get_fpu_postfix(def : tdef) : toppostfix;
implementation
@ -546,29 +544,6 @@ unit cgcpu;
end;
function rotl(d : dword;b : byte) : dword;
begin
result:=(d shr (32-b)) or (d shl b);
end;
function is_shifter_const(d : aint;var imm_shift : byte) : boolean;
var
i : longint;
begin
for i:=0 to 15 do
begin
if (dword(d) and not(rotl($ff,i*2)))=0 then
begin
imm_shift:=i*2;
result:=true;
exit;
end;
end;
result:=false;
end;
procedure tcgarm.a_load_const_reg(list : taasmoutput; size: tcgsize; a : aint;reg : tregister);
var
imm_shift : byte;

View File

@ -369,6 +369,8 @@ unit cpubase;
procedure shifterop_reset(var so : tshifterop);
function is_pc(const r : tregister) : boolean;
function is_shifter_const(d : aint;var imm_shift : byte) : boolean;
implementation
uses
@ -493,4 +495,26 @@ unit cpubase;
end;
function rotl(d : dword;b : byte) : dword;
begin
result:=(d shr (32-b)) or (d shl b);
end;
function is_shifter_const(d : aint;var imm_shift : byte) : boolean;
var
i : longint;
begin
for i:=0 to 15 do
begin
if (dword(d) and not(rotl($ff,i*2)))=0 then
begin
imm_shift:=i*2;
result:=true;
exit;
end;
end;
result:=false;
end;
end.