From 3cea1706e9208fb739b0482519fe48420ca520ea Mon Sep 17 00:00:00 2001 From: Karoly Balogh Date: Mon, 9 Jan 2023 12:00:39 +0100 Subject: [PATCH] m68k: more work on instruction validation for the internal assembler --- compiler/m68k/aasmcpu.pas | 71 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/compiler/m68k/aasmcpu.pas b/compiler/m68k/aasmcpu.pas index 1f391b4645..d25e73c403 100644 --- a/compiler/m68k/aasmcpu.pas +++ b/compiler/m68k/aasmcpu.pas @@ -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