mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-01 08:29:50 +01: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/tw18222.pp svneol=native#text/pascal
|
||||||
tests/webtbs/tw1825.pp svneol=native#text/plain
|
tests/webtbs/tw1825.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw18266.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/tw18443.pp svneol=native#text/pascal
|
||||||
tests/webtbs/tw1850.pp svneol=native#text/plain
|
tests/webtbs/tw1850.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw1851.pp svneol=native#text/plain
|
tests/webtbs/tw1851.pp svneol=native#text/plain
|
||||||
|
|||||||
@ -179,6 +179,7 @@ interface
|
|||||||
,top_regset
|
,top_regset
|
||||||
,top_shifterop
|
,top_shifterop
|
||||||
,top_conditioncode
|
,top_conditioncode
|
||||||
|
,top_modeflags
|
||||||
{$endif arm}
|
{$endif arm}
|
||||||
{$ifdef m68k}
|
{$ifdef m68k}
|
||||||
{ m68k only }
|
{ m68k only }
|
||||||
@ -215,6 +216,7 @@ interface
|
|||||||
top_regset : (regset:^tcpuregisterset; regtyp: tregistertype; subreg: tsubregister);
|
top_regset : (regset:^tcpuregisterset; regtyp: tregistertype; subreg: tsubregister);
|
||||||
top_shifterop : (shifterop : pshifterop);
|
top_shifterop : (shifterop : pshifterop);
|
||||||
top_conditioncode : (cc : TAsmCond);
|
top_conditioncode : (cc : TAsmCond);
|
||||||
|
top_modeflags : (modeflags : tcpumodeflags);
|
||||||
{$endif arm}
|
{$endif arm}
|
||||||
{$ifdef m68k}
|
{$ifdef m68k}
|
||||||
top_regset : (regset:^tcpuregisterset);
|
top_regset : (regset:^tcpuregisterset);
|
||||||
|
|||||||
@ -163,6 +163,7 @@ uses
|
|||||||
procedure loadshifterop(opidx:longint;const so:tshifterop);
|
procedure loadshifterop(opidx:longint;const so:tshifterop);
|
||||||
procedure loadregset(opidx:longint; regsetregtype: tregistertype; regsetsubregtype: tsubregister; const s:tcpuregisterset);
|
procedure loadregset(opidx:longint; regsetregtype: tregistertype; regsetsubregtype: tsubregister; const s:tcpuregisterset);
|
||||||
procedure loadconditioncode(opidx:longint;const cond:tasmcond);
|
procedure loadconditioncode(opidx:longint;const cond:tasmcond);
|
||||||
|
procedure loadmodeflags(opidx:longint;const flags:tcpumodeflags);
|
||||||
constructor op_none(op : tasmop);
|
constructor op_none(op : tasmop);
|
||||||
|
|
||||||
constructor op_reg(op : tasmop;_op1 : tregister);
|
constructor op_reg(op : tasmop;_op1 : tregister);
|
||||||
@ -187,6 +188,10 @@ uses
|
|||||||
{ ITxxx }
|
{ ITxxx }
|
||||||
constructor op_cond(op: tasmop; cond: tasmcond);
|
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 }
|
{ *M*LL }
|
||||||
constructor op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
|
constructor op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
|
||||||
|
|
||||||
@ -328,6 +333,17 @@ implementation
|
|||||||
end;
|
end;
|
||||||
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
|
taicpu Constructors
|
||||||
@ -448,6 +464,21 @@ implementation
|
|||||||
condition := cond;
|
condition := cond;
|
||||||
end;
|
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);
|
constructor taicpu.op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
|
||||||
begin
|
begin
|
||||||
|
|||||||
@ -204,6 +204,13 @@ unit agarmgas;
|
|||||||
end;
|
end;
|
||||||
top_conditioncode:
|
top_conditioncode:
|
||||||
getopstr:=cond2str[o.cc];
|
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:
|
top_ref:
|
||||||
if o.ref^.refaddr=addr_full then
|
if o.ref^.refaddr=addr_full then
|
||||||
begin
|
begin
|
||||||
|
|||||||
@ -23,6 +23,9 @@
|
|||||||
'clz',
|
'clz',
|
||||||
'cnf',
|
'cnf',
|
||||||
'cos',
|
'cos',
|
||||||
|
'cps',
|
||||||
|
'cpsid',
|
||||||
|
'cpsie',
|
||||||
'dvf',
|
'dvf',
|
||||||
'eor',
|
'eor',
|
||||||
'exp',
|
'exp',
|
||||||
|
|||||||
@ -199,5 +199,8 @@ attsufNONE,
|
|||||||
attsufNONE,
|
attsufNONE,
|
||||||
attsufNONE,
|
attsufNONE,
|
||||||
attsufNONE,
|
attsufNONE,
|
||||||
|
attsufNONE,
|
||||||
|
attsufNONE,
|
||||||
|
attsufNONE,
|
||||||
attsufNONE
|
attsufNONE
|
||||||
);
|
);
|
||||||
|
|||||||
@ -162,6 +162,10 @@ reg32,reg32 \x27\x01\x01 ARM7
|
|||||||
|
|
||||||
[COScc]
|
[COScc]
|
||||||
|
|
||||||
|
[CPS]
|
||||||
|
[CPSID]
|
||||||
|
[CPSIE]
|
||||||
|
|
||||||
[DVFcc]
|
[DVFcc]
|
||||||
|
|
||||||
[EORcc]
|
[EORcc]
|
||||||
|
|||||||
@ -23,6 +23,9 @@ A_CMP,
|
|||||||
A_CLZ,
|
A_CLZ,
|
||||||
A_CNF,
|
A_CNF,
|
||||||
A_COS,
|
A_COS,
|
||||||
|
A_CPS,
|
||||||
|
A_CPSID,
|
||||||
|
A_CPSIE,
|
||||||
A_DVF,
|
A_DVF,
|
||||||
A_EOR,
|
A_EOR,
|
||||||
A_EXP,
|
A_EXP,
|
||||||
|
|||||||
@ -203,6 +203,9 @@ unit cpubase;
|
|||||||
shiftimm : byte;
|
shiftimm : byte;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
tcpumodeflag = (mfA, mfI, mfF);
|
||||||
|
tcpumodeflags = set of tcpumodeflag;
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
Constants
|
Constants
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|||||||
@ -672,6 +672,38 @@ Unit raarmgas;
|
|||||||
end;
|
end;
|
||||||
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
|
var
|
||||||
tempreg : tregister;
|
tempreg : tregister;
|
||||||
ireg : tsuperregister;
|
ireg : tsuperregister;
|
||||||
@ -716,6 +748,11 @@ Unit raarmgas;
|
|||||||
*)
|
*)
|
||||||
AS_ID: { A constant expression, or a Variable ref. }
|
AS_ID: { A constant expression, or a Variable ref. }
|
||||||
Begin
|
Begin
|
||||||
|
if is_modeflag(actasmpattern) then
|
||||||
|
begin
|
||||||
|
consume(AS_ID);
|
||||||
|
end
|
||||||
|
else
|
||||||
{ Condition code? }
|
{ Condition code? }
|
||||||
if is_conditioncode(actasmpattern) then
|
if is_conditioncode(actasmpattern) then
|
||||||
begin
|
begin
|
||||||
|
|||||||
@ -65,7 +65,7 @@ Function SearchLabel(const s: string; var hl: tasmlabel;emit:boolean): boolean;
|
|||||||
|
|
||||||
type
|
type
|
||||||
TOprType=(OPR_NONE,OPR_CONSTANT,OPR_SYMBOL,OPR_LOCAL,
|
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
|
TOprRec = record
|
||||||
case typ:TOprType of
|
case typ:TOprType of
|
||||||
@ -88,6 +88,7 @@ type
|
|||||||
OPR_REGSET : (regset : tcpuregisterset; regtype: tregistertype; subreg: tsubregister);
|
OPR_REGSET : (regset : tcpuregisterset; regtype: tregistertype; subreg: tsubregister);
|
||||||
OPR_SHIFTEROP : (shifterop : tshifterop);
|
OPR_SHIFTEROP : (shifterop : tshifterop);
|
||||||
OPR_COND : (cc : tasmcond);
|
OPR_COND : (cc : tasmcond);
|
||||||
|
OPR_MODEFLAGS : (flags : tcpumodeflags);
|
||||||
{$endif arm}
|
{$endif arm}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1067,6 +1068,8 @@ end;
|
|||||||
ai.loadshifterop(i-1,shifterop);
|
ai.loadshifterop(i-1,shifterop);
|
||||||
OPR_COND:
|
OPR_COND:
|
||||||
ai.loadconditioncode(i-1,cc);
|
ai.loadconditioncode(i-1,cc);
|
||||||
|
OPR_MODEFLAGS:
|
||||||
|
ai.loadmodeflags(i-1,flags);
|
||||||
{$endif ARM}
|
{$endif ARM}
|
||||||
{ ignore wrong operand }
|
{ ignore wrong operand }
|
||||||
OPR_NONE:
|
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