Merge pull request #2695 from kugelfuhr/kugelfuhr/fix-2363
Add macros to check for CPU type and supported instruction set.
This commit is contained in:
@@ -1154,6 +1154,96 @@ The compiler defines several macros at startup:
|
||||
<item><tt/__CC65_STD_CC65__/
|
||||
</itemize>
|
||||
|
||||
<label id="macro-CPU">
|
||||
<tag><tt>__CPU__</tt></tag>
|
||||
|
||||
This macro contains a bitset that allows to check if a specific instruction
|
||||
set is supported. For example, the 65C02 CPU supports all instructions of the
|
||||
65SC02. So testing for the instruction set of the 65SC02 using the following
|
||||
check will succeed for both CPUs (and also for the 65816 and HUC6280).
|
||||
|
||||
<tscreen><verb>
|
||||
#if (__CPU__ & __CPU_ISET_65SC02__)
|
||||
</verb></tscreen>
|
||||
|
||||
This is much simpler and more future proof than checking for specific CPUs.
|
||||
|
||||
The compiler defines a set of constants named <tt/__CPU_ISET_xxx/ to do the
|
||||
checks. The <tt/__CPU__/ variable is usually derived from the target system
|
||||
given, but can be changed using the <tt/<ref id="option--cpu" name="--cpu">/
|
||||
command line option.
|
||||
|
||||
<tag><tt>__CPU_6502__</tt></tag>
|
||||
|
||||
This macro is defined if the code is compiled for a 6502 CPU.
|
||||
|
||||
<tag><tt>__CPU_6502X__</tt></tag>
|
||||
|
||||
This macro is defined if the code is compiled for a 6502 CPU with invalid
|
||||
opcodes.
|
||||
|
||||
<tag><tt>__CPU_6502DTV__</tt></tag>
|
||||
|
||||
This macro is defined if the code is compiled for a DTV CPU.
|
||||
|
||||
<tag><tt>__CPU_65SC02__</tt></tag>
|
||||
|
||||
This macro is defined if the code is compiled for a 65SC02 CPU.
|
||||
|
||||
<tag><tt>__CPU_65C02__</tt></tag>
|
||||
|
||||
This macro is defined if the code is compiled for a 65C02 CPU.
|
||||
|
||||
<tag><tt>__CPU_65816__</tt></tag>
|
||||
|
||||
This macro is defined if the code is compiled for a 65816 CPU.
|
||||
|
||||
<tag><tt>__CPU_HUC6280__</tt></tag>
|
||||
|
||||
This macro is defined if the code is compiled for a HUC6280 CPU.
|
||||
|
||||
<tag><tt>__CPU_ISET_6502__</tt></tag>
|
||||
|
||||
This macro expands to a numeric constant that can be used to check the
|
||||
<tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set
|
||||
of the 6502 CPU.
|
||||
|
||||
<tag><tt>__CPU_ISET_6502X__</tt></tag>
|
||||
|
||||
This macro expands to a numeric constant that can be used to check the
|
||||
<tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set
|
||||
of the 6502X CPU.
|
||||
|
||||
<tag><tt>__CPU_ISET_6502DTV__</tt></tag>
|
||||
|
||||
This macro expands to a numeric constant that can be used to check the
|
||||
<tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set
|
||||
of the 6502DTV CPU.
|
||||
|
||||
<tag><tt>__CPU_ISET_65SC02__</tt></tag>
|
||||
|
||||
This macro expands to a numeric constant that can be used to check the
|
||||
<tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set
|
||||
of the 65SC02 CPU.
|
||||
|
||||
<tag><tt>__CPU_ISET_65C02__</tt></tag>
|
||||
|
||||
This macro expands to a numeric constant that can be used to check the
|
||||
<tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set
|
||||
of the 65C02 CPU.
|
||||
|
||||
<tag><tt>__CPU_ISET_65816__</tt></tag>
|
||||
|
||||
This macro expands to a numeric constant that can be used to check the
|
||||
<tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set
|
||||
of the 65816 CPU.
|
||||
|
||||
<tag><tt>__CPU_ISET_HUC6280__</tt></tag>
|
||||
|
||||
This macro expands to a numeric constant that can be used to check the
|
||||
<tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set
|
||||
of the HUC6280 CPU.
|
||||
|
||||
<tag><tt>__CX16__</tt></tag>
|
||||
|
||||
This macro is defined if the target is the Commander X16 (-t cx16).
|
||||
|
||||
@@ -317,6 +317,81 @@ static void SetSys (const char* Sys)
|
||||
|
||||
|
||||
|
||||
static void DefineCpuMacros (void)
|
||||
/* Define macros for the target CPU */
|
||||
{
|
||||
const char* CPUName;
|
||||
|
||||
/* Note: The list of CPUs handled here must match the one checked in
|
||||
** OptCPU().
|
||||
*/
|
||||
switch (CPU) {
|
||||
|
||||
/* The following ones are legal CPUs as far as the assembler is
|
||||
** concerned but are ruled out earlier in the compiler, so this
|
||||
** function should never see them.
|
||||
*/
|
||||
case CPU_NONE:
|
||||
case CPU_SWEET16:
|
||||
case CPU_M740:
|
||||
case CPU_4510:
|
||||
case CPU_UNKNOWN:
|
||||
CPUName = (CPU == CPU_UNKNOWN)? "unknown" : CPUNames[CPU];
|
||||
Internal ("Invalid CPU \"%s\"", CPUName);
|
||||
break;
|
||||
|
||||
case CPU_6502:
|
||||
DefineNumericMacro ("__CPU_6502__", 1);
|
||||
break;
|
||||
|
||||
case CPU_6502X:
|
||||
DefineNumericMacro ("__CPU_6502X__", 1);
|
||||
break;
|
||||
|
||||
case CPU_6502DTV:
|
||||
DefineNumericMacro ("__CPU_6502DTV__", 1);
|
||||
break;
|
||||
|
||||
case CPU_65SC02:
|
||||
DefineNumericMacro ("__CPU_65SC02__", 1);
|
||||
break;
|
||||
|
||||
case CPU_65C02:
|
||||
DefineNumericMacro ("__CPU_65C02__", 1);
|
||||
break;
|
||||
|
||||
case CPU_65816:
|
||||
DefineNumericMacro ("__CPU_65816__", 1);
|
||||
break;
|
||||
|
||||
case CPU_HUC6280:
|
||||
DefineNumericMacro ("__CPU_HUC6280__", 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
FAIL ("Unexpected value in switch");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Define the macros for instruction sets. We only include the ones for
|
||||
** the available CPUs.
|
||||
*/
|
||||
DefineNumericMacro ("__CPU_ISET_6502__", CPU_ISET_6502);
|
||||
DefineNumericMacro ("__CPU_ISET_6502X__", CPU_ISET_6502X);
|
||||
DefineNumericMacro ("__CPU_ISET_6502DTV__", CPU_ISET_6502DTV);
|
||||
DefineNumericMacro ("__CPU_ISET_65SC02__", CPU_ISET_65SC02);
|
||||
DefineNumericMacro ("__CPU_ISET_65C02__", CPU_ISET_65C02);
|
||||
DefineNumericMacro ("__CPU_ISET_65816__", CPU_ISET_65816);
|
||||
DefineNumericMacro ("__CPU_ISET_HUC6280__", CPU_ISET_HUC6280);
|
||||
|
||||
/* Now define the macro that contains the bit set with the available
|
||||
** cpu instructions.
|
||||
*/
|
||||
DefineNumericMacro ("__CPU__", CPUIsets[CPU]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void FileNameOption (const char* Opt, const char* Arg, StrBuf* Name)
|
||||
/* Handle an option that remembers a file name for later */
|
||||
{
|
||||
@@ -477,7 +552,9 @@ static void OptCreateFullDep (const char* Opt attribute ((unused)),
|
||||
static void OptCPU (const char* Opt, const char* Arg)
|
||||
/* Handle the --cpu option */
|
||||
{
|
||||
/* Find the CPU from the given name */
|
||||
/* Find the CPU from the given name. We do only accept a certain number
|
||||
** of CPUs. If the list is changed, be sure to adjust SetCpuMacros().
|
||||
*/
|
||||
CPU = FindCPU (Arg);
|
||||
if (CPU != CPU_6502 && CPU != CPU_6502X && CPU != CPU_65SC02 &&
|
||||
CPU != CPU_65C02 && CPU != CPU_65816 && CPU != CPU_HUC6280 &&
|
||||
@@ -1063,7 +1140,9 @@ int main (int argc, char* argv[])
|
||||
/* Create the output file name if it was not explicitly given */
|
||||
MakeDefaultOutputName (InputFile);
|
||||
|
||||
/* If no CPU given, use the default CPU for the target */
|
||||
/* If no CPU given, use the default CPU for the target. Define macros that
|
||||
** allow to query the CPU.
|
||||
*/
|
||||
if (CPU == CPU_UNKNOWN) {
|
||||
if (Target != TGT_UNKNOWN) {
|
||||
CPU = GetTargetProperties (Target)->DefaultCPU;
|
||||
@@ -1071,6 +1150,7 @@ int main (int argc, char* argv[])
|
||||
CPU = CPU_6502;
|
||||
}
|
||||
}
|
||||
DefineCpuMacros ();
|
||||
|
||||
/* If no memory model was given, use the default */
|
||||
if (MemoryModel == MMODEL_UNKNOWN) {
|
||||
|
||||
Reference in New Issue
Block a user