Difference between revisions of "m68k"

From Lazarus wiki
Jump to navigationJump to search
(test68000 and friends)
Line 78: Line 78:
 
==Runtime detection of CPU type==
 
==Runtime detection of CPU type==
  
The RTL provides two m68k specific variables, to allow the user code to detect the CPU easily, in case it is necessary. These are
+
The RTL provides two m68k specific variables, to allow the user code to detect the CPU easily, in case it is necessary. These are:
  
 
* '''Test68000''', which is similar to '''Test8086''' on x86. It returns values from 0-6, excluding 5, representing CPU types from 68000 to 68060.
 
* '''Test68000''', which is similar to '''Test8086''' on x86. It returns values from 0-6, excluding 5, representing CPU types from 68000 to 68060.

Revision as of 21:45, 24 December 2016

The contents of this article reflect the status in FPC SVN trunk. Some features listed here might not be available in the latest stable version.

Introduction

Historically, the Motorola 680x0 (abbreviated as "m68k") port was the first Free Pascal port to CPU architectures other than i386. During the big refactoring for FPC 2.0, the code left without maintenance and the support broke and was partly removed. The Motorola 680x0 code generator got revived more than 10 years later, before FPC 3.0. It still shares some components with the old 1.x source code, like parts of the inline assembler reader, but most of the code is new.

Supported CPU types

The current Motorola 680x0 backend supports the following CPU and FPU types:

  • Motorola 68000-68010 (including code generation for unaligned accesses)
  • Motorola 68020-68060
  • Motorola 68881 FPU and compatibles (optional)
  • ColdFire ISA A to ISA C
  • ColdFire v4e FPU (optional)

Notes:

  • FPU support is optional, the code generator also supports using the RTL's SoftFPU.
  • Most of the ColdFire support was never tested on a real hardware, only in QEMU

Supported Targets

Free Pascal currently supports the following operating systems as target platforms on m68k:

Support is planned for the following targets:

Performance

Most members of the old Motorola 680x0 CPU family are not fast enough to run the compiler natively, although high-end 68060 systems and various fast JIT-based m68k emulators with enough memory are capable to do so. Therefore it is recommended to use a cross-compiler when targeting most m68k systems. Apart from the performance issues the code generator is mature enough to compile the compiler itself, make cycle works. Only Amiga and Linux are supported as compilation hosts.

Registers

When compiling for the Motorola 68k, Free Pascal uses the following conventions with registers. This matches, or closely matches most C compilers and most operating systems on this platform.

  • d0-d1 : scratch data registers
  • d2-d7 : non-volatile data registers
  • a0-a1 : scratch address registers
  • a2-a4 : non-volatile address registers
  • a5 : frame pointer on Amiga, non-volatile address register otherwise
  • a6 : frame pointer on other systems, non-volatile address register on Amiga
  • a7 : stack pointer
  • fp0-fp1 : scratch floating point registers
  • fp2-fp7 : non-volatile floating point registers

Inline assembler

The inline assembler follows the Motorola syntax. The register alias fp points to a5 or a6 register, respectively. The register alias sp points to a7.

Calling Conventions

The Motorola 68k CPU target supports several different calling conventions.

  • stdcall: this calling convention is entirely stack based. It passes all parameters on the stack from right to left.
  • register: this calling convention uses the scratch registers to pass arguments. Registers d0 and d1 are used to pass up to two ordinal values, a0 and a1 are used to pass up to two pointers, addresses, or references. When compiling with FPU enabled, fp0 and fp1 are used to pass up to two floating point values. The values on the registers are passed from left to right. The remaining arguments are passed on the stack from right to left, like with the stdcall convention.
  • syscall: the syscall convention is operating system specific. It's supported on Amiga and Atari, and it's documented at their respective pages.

The current default calling convention is register.

Unaligned access support

Some members of the m68k CPU family doesn't support larger than byte accesses of odd addresses. Most notably this includes the original 68000, the 68010 and some members of the CPU32 subfamily. The compiler supports generating special unaligned access code for these scenarios, when targeting these CPU. However, this unaligned access code is slow, as it involves several individual byte accesses plus shifts and masks, so it should be avoided whenever possible. Unaligned access code will be generated at:

  • all locations marked as unaligned (with the unaligned keyword)
  • all code accessing fields of packed records

Because of the second point, it's advised against to use packed records on these CPU in performance critical code.

Runtime detection of CPU type

The RTL provides two m68k specific variables, to allow the user code to detect the CPU easily, in case it is necessary. These are:

  • Test68000, which is similar to Test8086 on x86. It returns values from 0-6, excluding 5, representing CPU types from 68000 to 68060.
  • Test68881, which is similar to Test8087 on x86. It returns values from 0-6. excluding 5. 0 represents no FPU. 1 and 2 are 6888x FPU. 4 and 6 are 68040 and 68060 internal FPU.

Example:

program hello68k;

begin
  writeln('Hello World!');
  write('Running on 680',Test68000,' CPU');
  case Test68881 of
    0: writeln(' without FPU');
    1,2: writeln(' with 6888',Test68881,' FPU');
  else
    writeln(' with internal FPU');
  end;
end.

Notes:

  • this feature is currently only available on Amiga
  • this feature is not available on ColdFire CPUs