mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-06 00:30:34 +02:00
m68k: more work on instruction validation for the internal assembler
This commit is contained in:
parent
69761839c0
commit
3cea1706e9
@ -138,6 +138,8 @@ const
|
||||
type
|
||||
toperandtypeset = set of toperandtype;
|
||||
toperandflagset = set of toperandflags;
|
||||
topsupportedset = set of topsupported;
|
||||
topsizeflagset = set of topsizeflag;
|
||||
|
||||
type
|
||||
tinsentry = record
|
||||
@ -147,8 +149,8 @@ type
|
||||
opflags : array[0..max_operands-1] of toperandflagset;
|
||||
codelen : byte;
|
||||
code : array[0..1] of word;
|
||||
support : set of topsupported;
|
||||
sizes : set of topsizeflag;
|
||||
support : topsupportedset;
|
||||
sizes : topsizeflagset;
|
||||
end;
|
||||
pinsentry = ^tinsentry;
|
||||
|
||||
@ -701,6 +703,63 @@ type
|
||||
|
||||
function taicpu.Matches(p: PInsEntry; objdata:TObjData): boolean;
|
||||
|
||||
function TargetMatch: boolean;
|
||||
const
|
||||
CPUTypeToOpSupported: array[TCPUtype] of topsupportedset = (
|
||||
{* cpu_none *} [],
|
||||
{* cpu_MC68000 *} [OS_M68000,OS_M68000UP],
|
||||
{* cpu_MC68020 *} [OS_M68020,OS_M68000UP,OS_M68010UP,OS_M68020UP,OS_M68851],
|
||||
{* cpu_MC68040 *} [OS_M68040,OS_M68000UP,OS_M68010UP,OS_M68020UP,OS_M68040UP],
|
||||
{* cpu_MC68060 *} [OS_M68060,OS_M68000UP,OS_M68010UP,OS_M68020UP,OS_M68040UP],
|
||||
{* cpu_isa_a *} [OS_CF,OS_CF_ISA_A],
|
||||
{* cpu_isa_a_p *} [OS_CF,OS_CF_ISA_APL],
|
||||
{* cpu_isa_b *} [OS_CF,OS_CF_ISA_B],
|
||||
{* cpu_isa_c *} [OS_CF,OS_CF_ISA_C],
|
||||
{* cpu_cfv4e *} [OS_CF,OS_CF_ISA_B]
|
||||
);
|
||||
FPUTypeToOpSupported: array[TFPUtype] of topsupportedset = (
|
||||
{* fpu_none *} [],
|
||||
{* fpu_soft *} [],
|
||||
{* fpu_libgcc *} [],
|
||||
{* fpu_68881 *} [OS_M68881],
|
||||
{* fpu_68040 *} [OS_M68881,OS_M68040,OS_M68040UP],
|
||||
{* fpu_68060 *} [OS_M68881,OS_M68040,OS_M68040UP,OS_M68060],
|
||||
{* fpu_coldfire *} [OS_CF_FPU]
|
||||
);
|
||||
begin
|
||||
result:=((CPUTypeToOpSupported[current_settings.cputype] * p^.support) <> []) or
|
||||
((FPUTypeToOpSupported[current_settings.fputype] * p^.support) <> []);
|
||||
end;
|
||||
|
||||
function OpsizeMatch: boolean;
|
||||
const
|
||||
TOpSizeToOpSizeFlag: array[TOpSize] of TOpSizeFlagSet = (
|
||||
{ S_NO } [ OPS_UNSIZED],
|
||||
{ S_B } [ OPS_SHORT, OPS_BYTE ],
|
||||
{ S_W } [ OPS_WORD ],
|
||||
{ S_L } [ OPS_LONG ],
|
||||
{ S_FS } [ OPS_SINGLE ],
|
||||
{ S_FD } [ OPS_DOUBLE ],
|
||||
{ S_FX } [ OPS_EXTENDED ]
|
||||
);
|
||||
begin
|
||||
result:=(TOpSizeToOpSizeFlag[opsize] * p^.sizes) <> [];
|
||||
|
||||
{ Special handling for instructions where the size can be
|
||||
implicitly determined, because only one size is possible. }
|
||||
if not result and (opsize in [S_NO]) then
|
||||
begin
|
||||
result:=(p^.sizes <> []) and (
|
||||
{ if OPS_SHORT is in sizes, it means we have a branch
|
||||
instruction, so let unsized pass. }
|
||||
(OPS_SHORT in p^.sizes) or
|
||||
{ Or only one size is possible. }
|
||||
((p^.sizes - [ OPS_BYTE ]) = []) or
|
||||
((p^.sizes - [ OPS_WORD ]) = []) or
|
||||
((p^.sizes - [ OPS_LONG ]) = []));
|
||||
end;
|
||||
end;
|
||||
|
||||
function OperandsMatch(const oper: toper; const ots: toperandtypeset): boolean;
|
||||
var
|
||||
ot: toperandtype;
|
||||
@ -786,6 +845,14 @@ type
|
||||
if (p^.opcode<>opcode) or (p^.ops<>ops) then
|
||||
exit;
|
||||
|
||||
{ Check if opcode is valid for this target }
|
||||
if not TargetMatch then
|
||||
exit;
|
||||
|
||||
{ Check if opcode size is valid }
|
||||
if not OpsizeMatch then
|
||||
exit;
|
||||
|
||||
{ Check the operands }
|
||||
for i:=0 to p^.ops-1 do
|
||||
if not OperandsMatch(oper[i]^,p^.optypes[i]) then
|
||||
|
Loading…
Reference in New Issue
Block a user