mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-06 20:58:25 +02:00
* continued to work on arm binary writer, started to fix operand matching
git-svn-id: trunk@1073 -
This commit is contained in:
parent
eb26e1aa39
commit
d280ed6e8b
@ -49,8 +49,10 @@ uses
|
|||||||
OT_NEAR = $00000040;
|
OT_NEAR = $00000040;
|
||||||
OT_SHORT = $00000080;
|
OT_SHORT = $00000080;
|
||||||
OT_BITSTINY = $00000100; { fpu constant }
|
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_NON_SIZE = longint(not OT_SIZE_MASK);
|
||||||
|
|
||||||
OT_SIGNED = $00000100; { the operand need to be signed -128-127 }
|
OT_SIGNED = $00000100; { the operand need to be signed -128-127 }
|
||||||
@ -59,15 +61,21 @@ uses
|
|||||||
{ reverse effect in FADD, FSUB &c }
|
{ reverse effect in FADD, FSUB &c }
|
||||||
OT_COLON = $00000400;
|
OT_COLON = $00000400;
|
||||||
|
|
||||||
|
OT_SHIFTEROP = $00000800;
|
||||||
OT_REGISTER = $00001000;
|
OT_REGISTER = $00001000;
|
||||||
OT_IMMEDIATE = $00002000;
|
OT_IMMEDIATE = $00002000;
|
||||||
OT_REGLIST = $00008000;
|
OT_REGLIST = $00008000;
|
||||||
OT_IMM8 = $00002001;
|
OT_IMM8 = $00002001;
|
||||||
OT_IMM16 = $00002002;
|
OT_IMM24 = $00002002;
|
||||||
OT_IMM32 = $00002004;
|
OT_IMM32 = $00002004;
|
||||||
OT_IMM64 = $00002008;
|
OT_IMM64 = $00002008;
|
||||||
OT_IMM80 = $00002010;
|
OT_IMM80 = $00002010;
|
||||||
OT_IMMTINY = $00002100;
|
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_IMMEDIATEFPU = OT_IMMTINY;
|
||||||
|
|
||||||
OT_REGMEM = $00200000; { for r/m, ie EA, operands }
|
OT_REGMEM = $00200000; { for r/m, ie EA, operands }
|
||||||
@ -83,6 +91,19 @@ uses
|
|||||||
OT_MEM32 = $00204004;
|
OT_MEM32 = $00204004;
|
||||||
OT_MEM64 = $00204008;
|
OT_MEM64 = $00204008;
|
||||||
OT_MEM80 = $00204010;
|
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_FPUREG = $01000000; { floating point stack registers }
|
||||||
OT_REG_SMASK = $00070000; { special register operands: these may be treated differently }
|
OT_REG_SMASK = $00070000; { special register operands: these may be treated differently }
|
||||||
{ a mask for the following }
|
{ a mask for the following }
|
||||||
@ -853,6 +874,8 @@ implementation
|
|||||||
begin
|
begin
|
||||||
s:=s+'mem';
|
s:=s+'mem';
|
||||||
addsize:=true;
|
addsize:=true;
|
||||||
|
if (ot and OT_AM2)<>0 then
|
||||||
|
s:=s+' am2';
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
s:=s+'???';
|
s:=s+'???';
|
||||||
@ -867,6 +890,9 @@ implementation
|
|||||||
else
|
else
|
||||||
if (ot and OT_BITS32)<>0 then
|
if (ot and OT_BITS32)<>0 then
|
||||||
s:=s+'32'
|
s:=s+'32'
|
||||||
|
else
|
||||||
|
if (ot and OT_BITSSHIFTER)<>0 then
|
||||||
|
s:=s+'shifter'
|
||||||
else
|
else
|
||||||
s:=s+'??';
|
s:=s+'??';
|
||||||
{ signed }
|
{ signed }
|
||||||
@ -909,6 +935,11 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
function taicpu.Pass1(offset:longint):longint;
|
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
|
begin
|
||||||
Pass1:=0;
|
Pass1:=0;
|
||||||
{ Save the old offset and set the new offset }
|
{ Save the old offset and set the new offset }
|
||||||
@ -918,6 +949,27 @@ implementation
|
|||||||
exit;
|
exit;
|
||||||
{ set the file postion }
|
{ set the file postion }
|
||||||
aktfilepos:=fileinfo;
|
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 }
|
{ Get InsEntry }
|
||||||
if FindInsEntry then
|
if FindInsEntry then
|
||||||
begin
|
begin
|
||||||
@ -963,6 +1015,7 @@ implementation
|
|||||||
procedure taicpu.create_ot;
|
procedure taicpu.create_ot;
|
||||||
var
|
var
|
||||||
i,l,relsize : longint;
|
i,l,relsize : longint;
|
||||||
|
dummy : byte;
|
||||||
begin
|
begin
|
||||||
if ops=0 then
|
if ops=0 then
|
||||||
exit;
|
exit;
|
||||||
@ -979,7 +1032,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
case getregtype(reg) of
|
case getregtype(reg) of
|
||||||
R_INTREGISTER:
|
R_INTREGISTER:
|
||||||
ot:=OT_REG32;
|
ot:=OT_REG32 or OT_SHIFTEROP;
|
||||||
R_FPUREGISTER:
|
R_FPUREGISTER:
|
||||||
ot:=OT_FPUREG;
|
ot:=OT_FPUREG;
|
||||||
else
|
else
|
||||||
@ -1000,6 +1053,38 @@ implementation
|
|||||||
if (ref^.base=NR_NO) and (ref^.index=NR_NO) then
|
if (ref^.base=NR_NO) and (ref^.index=NR_NO) then
|
||||||
ot:=ot or OT_MEM_OFFS;
|
ot:=ot or OT_MEM_OFFS;
|
||||||
{ if we need to fix a reference, we do it here }
|
{ 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
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -1008,8 +1093,8 @@ implementation
|
|||||||
inc(l,ref^.symbol.address);
|
inc(l,ref^.symbol.address);
|
||||||
if (not assigned(ref^.symbol) or
|
if (not assigned(ref^.symbol) or
|
||||||
((ref^.symbol.currbind<>AB_EXTERNAL) and (ref^.symbol.address<>0))) and
|
((ref^.symbol.currbind<>AB_EXTERNAL) and (ref^.symbol.address<>0))) and
|
||||||
(relsize>=-128) and (relsize<=127) then
|
(relsize>=-33554428) and (relsize<=33554428) and (relsize mod 4=0) then
|
||||||
ot:=OT_IMM32 or OT_SHORT
|
ot:=OT_IMM24
|
||||||
else
|
else
|
||||||
ot:=OT_IMM32 or OT_NEAR;
|
ot:=OT_IMM32 or OT_NEAR;
|
||||||
end;
|
end;
|
||||||
@ -1026,14 +1111,10 @@ implementation
|
|||||||
top_const :
|
top_const :
|
||||||
begin
|
begin
|
||||||
ot:=OT_IMMEDIATE;
|
ot:=OT_IMMEDIATE;
|
||||||
{ fixme !!!!
|
if is_shifter_const(val,dummy) then
|
||||||
if opsize=S_NO then
|
ot:=OT_IMMSHIFTER
|
||||||
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
|
|
||||||
else
|
else
|
||||||
ot:=OT_IMMEDIATE or opsize_2_type[i,opsize];
|
ot:=OT_IMM32
|
||||||
}
|
|
||||||
end;
|
end;
|
||||||
top_none :
|
top_none :
|
||||||
begin
|
begin
|
||||||
@ -1043,6 +1124,7 @@ implementation
|
|||||||
end;
|
end;
|
||||||
top_shifterop:
|
top_shifterop:
|
||||||
begin
|
begin
|
||||||
|
ot:=OT_SHIFTEROP;
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
internalerror(200402261);
|
internalerror(200402261);
|
||||||
@ -1077,6 +1159,7 @@ implementation
|
|||||||
siz : array[0..3] of longint;
|
siz : array[0..3] of longint;
|
||||||
begin
|
begin
|
||||||
Matches:=100;
|
Matches:=100;
|
||||||
|
writeln(getstring,'---');
|
||||||
|
|
||||||
{ Check the opcode and operands }
|
{ Check the opcode and operands }
|
||||||
if (p^.opcode<>opcode) or (p^.ops<>ops) then
|
if (p^.opcode<>opcode) or (p^.ops<>ops) then
|
||||||
@ -1111,6 +1194,51 @@ implementation
|
|||||||
end;
|
end;
|
||||||
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 }
|
{ Check operand sizes }
|
||||||
{ as default an untyped size can get all the sizes, this is different
|
{ 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
|
from nasm, but else we need to do a lot checking which opcodes want
|
||||||
|
@ -125,11 +125,11 @@ reg32,reg32,imm \7\x3\xC0 ARM7
|
|||||||
|
|
||||||
[BLcc]
|
[BLcc]
|
||||||
mem32 \1\x0B ARM7
|
mem32 \1\x0B ARM7
|
||||||
imm32 \1\x0B ARM7
|
imm24 \1\x0B ARM7
|
||||||
|
|
||||||
[BLX]
|
[BLX]
|
||||||
mem32 \xff ARM7
|
mem32 \xff ARM7
|
||||||
imm32 \xff ARM7
|
imm24 \xff ARM7
|
||||||
|
|
||||||
[BKPTcc]
|
[BKPTcc]
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ reg32,reg32,imm \7\x2\x20 ARM7
|
|||||||
reg32,reg32 \321\300\1\x11\101 ARM7
|
reg32,reg32 \321\300\1\x11\101 ARM7
|
||||||
|
|
||||||
[LDMcc]
|
[LDMcc]
|
||||||
reg32,reglist \x26\x81 ARM7
|
memam4,reglist \x26\x81 ARM7
|
||||||
|
|
||||||
[LDRBTcc]
|
[LDRBTcc]
|
||||||
|
|
||||||
@ -235,10 +235,10 @@ reg32,mem32 \320\301\1\x13\110 ARM7
|
|||||||
reg32,reg32,reg32,reg32 \x15\x00\x20\x90 ARM7
|
reg32,reg32,reg32,reg32 \x15\x00\x20\x90 ARM7
|
||||||
|
|
||||||
[MOVcc]
|
[MOVcc]
|
||||||
reg32,reg32 \x8\x1\xA0 ARM7
|
reg32,shifterop \x8\x1\xA0 ARM7
|
||||||
reg32,reg32,reg32 \x9\x1\xA0 ARM7
|
; reg32,reg32,reg32 \x9\x1\xA0 ARM7
|
||||||
reg32,reg32,imm \xA\x1\xA0 ARM7
|
; reg32,reg32,imm \xA\x1\xA0 ARM7
|
||||||
reg32,imm \xB\x3\xA0 ARM7
|
; reg32,imm \xB\x3\xA0 ARM7
|
||||||
|
|
||||||
; [MRC]
|
; [MRC]
|
||||||
; reg32,reg32 \321\301\1\x13\110 ARM7
|
; reg32,reg32 \321\301\1\x13\110 ARM7
|
||||||
@ -326,7 +326,7 @@ reg32,reg32,reg32,reg32 \x16\x00\xC0\x90 ARM7
|
|||||||
[STFcc]
|
[STFcc]
|
||||||
|
|
||||||
[STMcc]
|
[STMcc]
|
||||||
reg32,reglist \x26\x80 ARM7
|
memam4,reglist \x26\x80 ARM7
|
||||||
|
|
||||||
[STRcc]
|
[STRcc]
|
||||||
reg32,imm32 \x17\x05\x00 ARM7
|
reg32,imm32 \x17\x05\x00 ARM7
|
||||||
@ -349,10 +349,10 @@ reg32,reg32,reg32 \x25\x00\xB0 ARM7
|
|||||||
[STRTcc]
|
[STRTcc]
|
||||||
|
|
||||||
[SUBcc]
|
[SUBcc]
|
||||||
reg32,reg32,reg32 \4\x0\x40 ARM7
|
reg32,reg32,shiftimm \4\x0\x40 ARM7
|
||||||
reg32,reg32,reg32,reg32 \5\x0\x40 ARM7
|
; reg32,reg32,reg32,reg32 \5\x0\x40 ARM7
|
||||||
reg32,reg32,reg32,imm \6\x0\x40 ARM7
|
; reg32,reg32,reg32,imm \6\x0\x40 ARM7
|
||||||
reg32,reg32,imm \7\x2\x40 ARM7
|
; reg32,reg32,imm \7\x2\x40 ARM7
|
||||||
|
|
||||||
[SWIcc]
|
[SWIcc]
|
||||||
imm \2\x0F ARM7
|
imm \2\x0F ARM7
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
{ don't edit, this file is generated from armins.dat }
|
{ don't edit, this file is generated from armins.dat }
|
||||||
117;
|
111;
|
||||||
|
@ -143,7 +143,7 @@
|
|||||||
(
|
(
|
||||||
opcode : A_BL;
|
opcode : A_BL;
|
||||||
ops : 1;
|
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;
|
code : #1#11;
|
||||||
flags : if_arm7
|
flags : if_arm7
|
||||||
),
|
),
|
||||||
@ -157,7 +157,7 @@
|
|||||||
(
|
(
|
||||||
opcode : A_BLX;
|
opcode : A_BLX;
|
||||||
ops : 1;
|
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;
|
code : #15#15;
|
||||||
flags : if_arm7
|
flags : if_arm7
|
||||||
),
|
),
|
||||||
@ -276,7 +276,7 @@
|
|||||||
(
|
(
|
||||||
opcode : A_LDM;
|
opcode : A_LDM;
|
||||||
ops : 2;
|
ops : 2;
|
||||||
optypes : (ot_reg32,ot_reglist,ot_none,ot_none);
|
optypes : (ot_memoryam5,ot_reglist,ot_none,ot_none);
|
||||||
code : #38#129;
|
code : #38#129;
|
||||||
flags : if_arm7
|
flags : if_arm7
|
||||||
),
|
),
|
||||||
@ -423,31 +423,10 @@
|
|||||||
(
|
(
|
||||||
opcode : A_MOV;
|
opcode : A_MOV;
|
||||||
ops : 2;
|
ops : 2;
|
||||||
optypes : (ot_reg32,ot_reg32,ot_none,ot_none);
|
optypes : (ot_reg32,ot_shifterop,ot_none,ot_none);
|
||||||
code : #8#1#160;
|
code : #8#1#160;
|
||||||
flags : if_arm7
|
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;
|
opcode : A_MUL;
|
||||||
ops : 3;
|
ops : 3;
|
||||||
@ -633,7 +612,7 @@
|
|||||||
(
|
(
|
||||||
opcode : A_STM;
|
opcode : A_STM;
|
||||||
ops : 2;
|
ops : 2;
|
||||||
optypes : (ot_reg32,ot_reglist,ot_none,ot_none);
|
optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none);
|
||||||
code : #38#128;
|
code : #38#128;
|
||||||
flags : if_arm7
|
flags : if_arm7
|
||||||
),
|
),
|
||||||
@ -703,31 +682,10 @@
|
|||||||
(
|
(
|
||||||
opcode : A_SUB;
|
opcode : A_SUB;
|
||||||
ops : 3;
|
ops : 3;
|
||||||
optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none);
|
optypes : (ot_reg32,ot_reg32,ot_shiftimmediate,ot_none);
|
||||||
code : #4#0#64;
|
code : #4#0#64;
|
||||||
flags : if_arm7
|
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;
|
opcode : A_SWI;
|
||||||
ops : 1;
|
ops : 1;
|
||||||
|
@ -118,8 +118,6 @@ unit cgcpu;
|
|||||||
OpCmp2AsmCond : Array[topcmp] of TAsmCond = (C_NONE,C_EQ,C_GT,
|
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);
|
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;
|
function get_fpu_postfix(def : tdef) : toppostfix;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -546,29 +544,6 @@ unit cgcpu;
|
|||||||
end;
|
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);
|
procedure tcgarm.a_load_const_reg(list : taasmoutput; size: tcgsize; a : aint;reg : tregister);
|
||||||
var
|
var
|
||||||
imm_shift : byte;
|
imm_shift : byte;
|
||||||
|
@ -369,6 +369,8 @@ unit cpubase;
|
|||||||
procedure shifterop_reset(var so : tshifterop);
|
procedure shifterop_reset(var so : tshifterop);
|
||||||
function is_pc(const r : tregister) : boolean;
|
function is_pc(const r : tregister) : boolean;
|
||||||
|
|
||||||
|
function is_shifter_const(d : aint;var imm_shift : byte) : boolean;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
@ -493,4 +495,26 @@ unit cpubase;
|
|||||||
end;
|
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.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user