+ 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:
Jonas Maebe 2011-01-11 16:02:51 +00:00
parent d76ddcabe6
commit bbf0e35a51
12 changed files with 116 additions and 5 deletions

1
.gitattributes vendored
View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -23,6 +23,9 @@
'clz',
'cnf',
'cos',
'cps',
'cpsid',
'cpsie',
'dvf',
'eor',
'exp',

View File

@ -199,5 +199,8 @@ attsufNONE,
attsufNONE,
attsufNONE,
attsufNONE,
attsufNONE,
attsufNONE,
attsufNONE,
attsufNONE
);

View File

@ -162,6 +162,10 @@ reg32,reg32 \x27\x01\x01 ARM7
[COScc]
[CPS]
[CPSID]
[CPSIE]
[DVFcc]
[EORcc]

View File

@ -23,6 +23,9 @@ A_CMP,
A_CLZ,
A_CNF,
A_COS,
A_CPS,
A_CPSID,
A_CPSIE,
A_DVF,
A_EOR,
A_EXP,

View File

@ -203,6 +203,9 @@ unit cpubase;
shiftimm : byte;
end;
tcpumodeflag = (mfA, mfI, mfF);
tcpumodeflags = set of tcpumodeflag;
{*****************************************************************************
Constants
*****************************************************************************}

View File

@ -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

View File

@ -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
View 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.