mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-17 12:59:24 +02:00
+ Support for ARM CPS/CPSIE/CPSID instructions and mode flag bitfield
operand (patch by Jeppe Johansen, mantis #18334) git-svn-id: trunk@16750 -
This commit is contained in:
parent
d76ddcabe6
commit
bbf0e35a51
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -10946,6 +10946,7 @@ tests/webtbs/tw1820.pp svneol=native#text/plain
|
||||
tests/webtbs/tw18222.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw1825.pp svneol=native#text/plain
|
||||
tests/webtbs/tw18266.pp svneol=native#text/plain
|
||||
tests/webtbs/tw18334.pp svneol=native#text/plain
|
||||
tests/webtbs/tw18443.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw1850.pp svneol=native#text/plain
|
||||
tests/webtbs/tw1851.pp svneol=native#text/plain
|
||||
|
@ -179,6 +179,7 @@ interface
|
||||
,top_regset
|
||||
,top_shifterop
|
||||
,top_conditioncode
|
||||
,top_modeflags
|
||||
{$endif arm}
|
||||
{$ifdef m68k}
|
||||
{ m68k only }
|
||||
@ -214,7 +215,8 @@ interface
|
||||
{$ifdef arm}
|
||||
top_regset : (regset:^tcpuregisterset; regtyp: tregistertype; subreg: tsubregister);
|
||||
top_shifterop : (shifterop : pshifterop);
|
||||
top_conditioncode: (cc: TAsmCond);
|
||||
top_conditioncode : (cc : TAsmCond);
|
||||
top_modeflags : (modeflags : tcpumodeflags);
|
||||
{$endif arm}
|
||||
{$ifdef m68k}
|
||||
top_regset : (regset:^tcpuregisterset);
|
||||
|
@ -163,6 +163,7 @@ uses
|
||||
procedure loadshifterop(opidx:longint;const so:tshifterop);
|
||||
procedure loadregset(opidx:longint; regsetregtype: tregistertype; regsetsubregtype: tsubregister; const s:tcpuregisterset);
|
||||
procedure loadconditioncode(opidx:longint;const cond:tasmcond);
|
||||
procedure loadmodeflags(opidx:longint;const flags:tcpumodeflags);
|
||||
constructor op_none(op : tasmop);
|
||||
|
||||
constructor op_reg(op : tasmop;_op1 : tregister);
|
||||
@ -187,6 +188,10 @@ uses
|
||||
{ ITxxx }
|
||||
constructor op_cond(op: tasmop; cond: tasmcond);
|
||||
|
||||
{ CPSxx }
|
||||
constructor op_modeflags(op: tasmop; flags: tcpumodeflags);
|
||||
constructor op_modeflags_const(op: tasmop; flags: tcpumodeflags; a: aint);
|
||||
|
||||
{ *M*LL }
|
||||
constructor op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
|
||||
|
||||
@ -328,6 +333,17 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure taicpu.loadmodeflags(opidx: longint; const flags: tcpumodeflags);
|
||||
begin
|
||||
allocate_oper(opidx+1);
|
||||
with oper[opidx]^ do
|
||||
begin
|
||||
if typ<>top_modeflags then
|
||||
clearop(opidx);
|
||||
modeflags:=flags;
|
||||
typ:=top_modeflags;
|
||||
end;
|
||||
end;
|
||||
|
||||
{*****************************************************************************
|
||||
taicpu Constructors
|
||||
@ -448,6 +464,21 @@ implementation
|
||||
condition := cond;
|
||||
end;
|
||||
|
||||
constructor taicpu.op_modeflags(op: tasmop; flags: tcpumodeflags);
|
||||
begin
|
||||
inherited create(op);
|
||||
ops := 1;
|
||||
loadmodeflags(0,flags);
|
||||
end;
|
||||
|
||||
constructor taicpu.op_modeflags_const(op: tasmop; flags: tcpumodeflags; a: aint);
|
||||
begin
|
||||
inherited create(op);
|
||||
ops := 2;
|
||||
loadmodeflags(0,flags);
|
||||
loadconst(1,a);
|
||||
end;
|
||||
|
||||
|
||||
constructor taicpu.op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
|
||||
begin
|
||||
|
@ -204,6 +204,13 @@ unit agarmgas;
|
||||
end;
|
||||
top_conditioncode:
|
||||
getopstr:=cond2str[o.cc];
|
||||
top_modeflags:
|
||||
begin
|
||||
getopstr:='';
|
||||
if mfA in o.modeflags then getopstr:=getopstr+'a';
|
||||
if mfI in o.modeflags then getopstr:=getopstr+'i';
|
||||
if mfF in o.modeflags then getopstr:=getopstr+'f';
|
||||
end;
|
||||
top_ref:
|
||||
if o.ref^.refaddr=addr_full then
|
||||
begin
|
||||
|
@ -23,6 +23,9 @@
|
||||
'clz',
|
||||
'cnf',
|
||||
'cos',
|
||||
'cps',
|
||||
'cpsid',
|
||||
'cpsie',
|
||||
'dvf',
|
||||
'eor',
|
||||
'exp',
|
||||
|
@ -199,5 +199,8 @@ attsufNONE,
|
||||
attsufNONE,
|
||||
attsufNONE,
|
||||
attsufNONE,
|
||||
attsufNONE,
|
||||
attsufNONE,
|
||||
attsufNONE,
|
||||
attsufNONE
|
||||
);
|
||||
|
@ -162,6 +162,10 @@ reg32,reg32 \x27\x01\x01 ARM7
|
||||
|
||||
[COScc]
|
||||
|
||||
[CPS]
|
||||
[CPSID]
|
||||
[CPSIE]
|
||||
|
||||
[DVFcc]
|
||||
|
||||
[EORcc]
|
||||
|
@ -23,6 +23,9 @@ A_CMP,
|
||||
A_CLZ,
|
||||
A_CNF,
|
||||
A_COS,
|
||||
A_CPS,
|
||||
A_CPSID,
|
||||
A_CPSIE,
|
||||
A_DVF,
|
||||
A_EOR,
|
||||
A_EXP,
|
||||
|
@ -203,6 +203,9 @@ unit cpubase;
|
||||
shiftimm : byte;
|
||||
end;
|
||||
|
||||
tcpumodeflag = (mfA, mfI, mfF);
|
||||
tcpumodeflags = set of tcpumodeflag;
|
||||
|
||||
{*****************************************************************************
|
||||
Constants
|
||||
*****************************************************************************}
|
||||
|
@ -672,6 +672,38 @@ Unit raarmgas;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function is_modeflag(hs : string): boolean;
|
||||
var
|
||||
i: longint;
|
||||
flags: tcpumodeflags;
|
||||
begin
|
||||
is_modeflag := false;
|
||||
|
||||
flags:=[];
|
||||
hs:=lower(hs);
|
||||
|
||||
if (actopcode in [A_CPSID,A_CPSIE]) and (length(hs) >= 1) then
|
||||
begin
|
||||
for i:=1 to length(hs) do
|
||||
begin
|
||||
case hs[i] of
|
||||
'a':
|
||||
Include(flags,mfA);
|
||||
'f':
|
||||
Include(flags,mfF);
|
||||
'i':
|
||||
Include(flags,mfI);
|
||||
else
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
oper.opr.typ := OPR_MODEFLAGS;
|
||||
oper.opr.flags := flags;
|
||||
exit(true);
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
tempreg : tregister;
|
||||
ireg : tsuperregister;
|
||||
@ -716,11 +748,16 @@ Unit raarmgas;
|
||||
*)
|
||||
AS_ID: { A constant expression, or a Variable ref. }
|
||||
Begin
|
||||
if is_modeflag(actasmpattern) then
|
||||
begin
|
||||
consume(AS_ID);
|
||||
end
|
||||
else
|
||||
{ Condition code? }
|
||||
if is_conditioncode(actasmpattern) then
|
||||
begin
|
||||
consume(AS_ID);
|
||||
end
|
||||
begin
|
||||
consume(AS_ID);
|
||||
end
|
||||
else
|
||||
{ Local Label ? }
|
||||
if is_locallabel(actasmpattern) then
|
||||
|
@ -65,7 +65,7 @@ Function SearchLabel(const s: string; var hl: tasmlabel;emit:boolean): boolean;
|
||||
|
||||
type
|
||||
TOprType=(OPR_NONE,OPR_CONSTANT,OPR_SYMBOL,OPR_LOCAL,
|
||||
OPR_REFERENCE,OPR_REGISTER,OPR_REGLIST,OPR_COND,OPR_REGSET,OPR_SHIFTEROP);
|
||||
OPR_REFERENCE,OPR_REGISTER,OPR_REGLIST,OPR_COND,OPR_REGSET,OPR_SHIFTEROP,OPR_MODEFLAGS);
|
||||
|
||||
TOprRec = record
|
||||
case typ:TOprType of
|
||||
@ -88,6 +88,7 @@ type
|
||||
OPR_REGSET : (regset : tcpuregisterset; regtype: tregistertype; subreg: tsubregister);
|
||||
OPR_SHIFTEROP : (shifterop : tshifterop);
|
||||
OPR_COND : (cc : tasmcond);
|
||||
OPR_MODEFLAGS : (flags : tcpumodeflags);
|
||||
{$endif arm}
|
||||
end;
|
||||
|
||||
@ -1067,6 +1068,8 @@ end;
|
||||
ai.loadshifterop(i-1,shifterop);
|
||||
OPR_COND:
|
||||
ai.loadconditioncode(i-1,cc);
|
||||
OPR_MODEFLAGS:
|
||||
ai.loadmodeflags(i-1,flags);
|
||||
{$endif ARM}
|
||||
{ ignore wrong operand }
|
||||
OPR_NONE:
|
||||
|
14
tests/webtbs/tw18334.pp
Normal file
14
tests/webtbs/tw18334.pp
Normal file
@ -0,0 +1,14 @@
|
||||
{ %cpu=arm }
|
||||
{ %norun }
|
||||
|
||||
procedure test; assembler;
|
||||
asm
|
||||
cps #0
|
||||
cpsie aif, #0
|
||||
cpsid aif, #0
|
||||
cpsie aif
|
||||
cpsid aif
|
||||
end;
|
||||
|
||||
begin
|
||||
end.
|
Loading…
Reference in New Issue
Block a user