[ << ] [ >> ]           [] [] [] [ ? ]

23 m68k cpu module

This chapter documents the backend for the Motorola M68k/CPU32/ColdFire microprocessor family.


23.1 Legal

This module is written in 2002-2024 by Frank Wille and is covered by the vasm copyright without modifications.


23.2 Additional options for this module

Note, that the order on the command line may be important when specifying options. For example, if you specify ‘-devpac’ compatibility mode behind enabling some optimization options, the Devpac-mode might disable these optimizations again.

This module provides the following additional options:


23.2.1 CPU selections

-m68000

Generate code for the MC68000 CPU (default).

-m68008

Generate code for the MC68008 CPU.

-m68010

Generate code for the MC68010 CPU.

-m68020

Generate code for the MC68020 CPU.

-m68030

Generate code for the MC68030 CPU.

-m68040

Generate code for the MC68040 CPU.

-m68060

Generate code for the MC68060 CPU.

-m68020up

Generate code for the MC68020-68060 CPU. Be careful with instructions like PFLUSHA, which exist on 68030 and 68040/060 with a different opcode (vasm will use the 040/060 version).

-m68080

Generate code for the Apollo Core AC68080 CPU.

-mcpu32

Generate code for the CPU32 family (MC6833x, MC6834x, etc.).

-mcf5...
-m5...

Generate code for a ColdFire family CPU. The following types are recognized: 5202, 5204, 5206, 520x, 5206e, 5207, 5208, 5210a, 5211a, 5212, 5213, 5214, 5216, 5224, 5225, 5232, 5233, 5234, 5235, 523x, 5249, 5250, 5253, 5270, 5271, 5272, 5274, 5275, 5280, 5281, 528x, 52221, 52553, 52230, 52231, 52232, 52233, 52234, 52235, 52252, 52254, 52255, 52256, 52258, 52259, 52274, 52277, 5307, 5327, 5328, 5329, 532x, 5372, 5373, 537x, 53011, 53012, 53013, 53014, 53015, 53016, 53017, 5301x, 5407, 5470, 5471, 5472, 5473, 5474, 5475, 547x, 5480, 5481, 5482, 5483, 5484, 5485, 548x, 54450, 54451, 54452, 54453, 5445x.

-mcfv2

Generate code for the V2 ColdFire core. This option selects ISA_A (no hardware division or MAC), which is the most limited ISA supported by 5202, 5204 and 5206. All other ColdFire chips are backwards compatible to V2.

-mcfv3

Generate code for the V3 ColdFire core. This option selects ISA_A+, hardware division MAC and EMAC instructions, which are supported by nearly all V3 CPUs, except the 5307.

-mcfv4

Generate code for the V4 ColdFire core. This option selects ISA_B and MAC as supported by the 5407.

-mcfv4e

Generate code for the V4e ColdFire core. This option selects ISA_B, USP-, FPU-, MAC- and EMAC-instructions (no hardware division) as supported by all 547x and 548x CPUs.

-m68851

Generate code for the MC68851 MMU. May be used in combination with another ‘-m’ option.

-m68881

Generate code for the MC68881 FPU. May be used in combination with another ‘-m’ option.

-m68882

Generate code for the MC68882 FPU. May be used in combination with another ‘-m’ option.

-no-fpu

Ignore any FPU options or directives, which has the effect that no 68881/2 FPU instructions will be accepted. This option can override the default behaviour of ‘-gas’ enabling the FPU.


23.2.2 Optimization options

-no-opt

Disable all optimizations. Can be seen as a main switch to ignore all other optimization options on the command line and in the source.

-opt-allbra

When specified the assembler will also try to optimize branch instructions which already have a valid size extension. This option is automatically enabled in ‘-phxass’ mode.

-opt-brajmp

Translate relative branch instructions, whose destination is in a different section, into absolute jump instructions.

-opt-clr

Enables optimization from MOVE #0,<ea> into CLR <ea> for the MC68000. Note that CLR will execute a read-modify-write cycle on the 68000, so it is disabled by default. With 68010 and higher this is a generic standard optimization.

-opt-div

Unsigned immediate divisors, which are a power of two (from 2 to 256), are optimized to shifts. Divisions by 1 are replaced by TST.L Dn (32-bit) or MVZ.W Dn,Dn (16-bit, ColdFire only). Divisions by -1 are replaced by NEG.L Dn (32-bit) or by a combination of NEG.W Dn and MVZ.W Dn,Dn (16-bit, ColdFire only). This optimization will leave the flags in a different state as can normally be expected after a division instruction.

-opt-fconst

Floating point constants are loaded with the lowest precision possible. This means that FMOVE.D #1.0,FP0 would be optimized to FMOVE.S #1.0,FP0, or even FMOVE.W #1,FP0, because it is faster and shorter at the same precision. The optimization will be performed on all FPU instructions with immediate addressing mode. When an FDIV-family instruction (FSDIV, FDDIV, FSGLDIV) is detected it will additionally be checked if the immediate constant is a power of 2 and then converted into FMUL #1/c,FPn.

-opt-jbra

JMP and JSR instructions to external labels will be converted into BRA.L and BSR.L, when the selected CPU is 68020 or higher (or CPU32).

-opt-lsl

Allows optimization of LSL #1 into ADD. It is also needed to optimize ASL #2 and LSL #2 into two ADD instructions (together with ‘-opt-speed’). These optimizations can modify the V-flag, which may not be intended.

-opt-movem

Enables optimization from MOVEM <ea>,Rn into MOVE <ea>,Rn (or the other way around). May also optimize MOVEM with two registers into two separate MOVE insructions, when advantageous for the currently selected CPU. This optimization will modify the flags when the destination is no address register.

-opt-mul

Immediate multplication factors, which are a power of two (from 2 to 256), are optimized to shifts. Multiplications with zero are replaced by a MOVEQ #0,Dn, with -1 are replaced by a NEG.L Dn and with 1 by EXT.L Dn or TST.L Dn (long-form). Not all optimizations are available for all cpu types (e.g. MULU.W can only be optimized on ColdFire by using the MVZ.W instruction). This optimization will leave the flags in a different state as can normally be expected after a multiplication instruction, and the size of the optimized code may be bigger than before in some situations (e.g. MULS.W #4,Dn). So the latter will additionally require the ‘-opt-speed’ flag.

-opt-nmoveq

Optimizes MOVE.L #x,Dn into a combination of MOVEQ and NEG.W, which works for ranges from $ff81<=x<=$ffff and $ffff0001<=x<=$ffff0080. Note that this optimization flips the N-flag!

-opt-pea

Enables optimization from MOVE #x,-(SP) into PEA x. This optimization will leave the flags unmodified, which might not be intended.

-opt-size

Optimize for size, even if this would make the code slower. This enables for example optimization of MOVE.L #x,Dn into MOVEQ #x>>n,Dn + LSL.W #n,Dn. It is mostly used together with other optimization flags.

-opt-speed

Optimize for speed, even if this would increase code size. For example it enables optimization of ASL.W #2,Dn into two ADD.W Dn,Dn instructions. Or MULS.W #-4,Dn into EXT.L Dn + ASL.L #2,Dn + NEG.L Dn.

-opt-st

Enables optimization from MOVE.B #-1,<ea> into ST <ea>. This optimization will leave the flags unmodified, which might not be intended.

-opt-<option>

Alternatively, you can use ‘-opt-’ followed by a Devpac-compatible option, as described under the OPT directive. Example: ‘-opt-o1-’ disables branch optimization in the same way as an OPT o1- directive would do at the top of the source text.

-sc

Small code model. All JMP and JSR instructions to external labels will be converted into 16-bit PC-relative jumps.

-sd

References to labels in a small data section (named "__MERGED") are optimized into base-relative addressing mode, using the current base register set by an active NEAR directive. This option is automatically enabled in ‘-phxass’ mode.

-showcrit

Print all critical optimizations which have side effects. Among those are ‘-opt-lsl’, ‘-opt-mul’, ‘-opt-st’, ‘-opt-pea’, ‘-opt-movem’ and ‘-opt-clr’.

-showopt

Print all optimizations and translations vasm is doing (same as opt ow+).

-warnabs16

Show a warning for every access to an absolute 16-bit address.

-warnabs32

Show a warning for every access to an absolute 32-bit address. This doesn’t include section labels.

In its default setting (no ‘-devpac’ or ‘-phxass’ option) vasm performs the following optimizations:


23.2.3 Other options

-conv-brackets

Brackets ('[' and ']') in an operand are automatically treated like parentheses ('(' and ')') as long as the CPU is 68000 or 68010. This is a compatibility option for some old assemblers.

-devpac

All options are initially set to be Devpac compatible. Which means that all optimizations are disabled, no debugging symbols will be written and vasm will warn about any optimization being done. When symbol output is enabled by opt d+, then the TOS symbol table defaults to standard DRI format (limited to 8 characters). Shift-right operations are performed using an unsigned 32-bit value. Other options are the same as vasm’s defaults. The symbol __G2 is defined, which contains information about the selected cpu type. The symbol __LK reflects the type of output file to generate. Which is 0 for TOS executables, 1 for DRI objects, 2 for GST objects, 3 for AmigaDOS objects and 4 for AmigaDOS executables. All other formats are represented by 99, as they are unknown to Devpac. It will also automatically enable ‘-guess-ext’ and ‘-nodpc’.

-elfregs

Register names have to be prefixed by a ’%’ to prevent confusion with symbol names.

-extsd

Recognize small data references in all 020+ extended addressing modes using 16-bit displacements on the base register. By default only the 16-bit address register displacement addressing mode can be used with small data (for compatibility reasons).

-gas

Enable additional GNU-as compatibility mnemonics, like mov, movm and jra. Also accepts | instead of ; for comments. GNU-as compatibility mode selects the 68020 CPU and 68881/2 FPU by default and enables ‘-opt-jbra’.

-guess-ext

Accept illegal size extensions for an instruction, as long as the instruction is unsized or there is just a single size possible. This is the default setting in PhxAss and Devpac compatibility mode.

-kick1hunks

Prevents optimization of JMP/JSR to 32-bit PC-relative (BRA/BSR).

-nodpc

Do not attempt to encode absolute PC-displacements directly. Example: 10(PC)

-no-typechk

Do not check the size and type of expressions (OPT t-). Example: dc.b 300

-phxass

PhxAss-compatibilty mode. The "current PC symbol" (e.g. * in mot-syntax module) is set to the instruction’s address + 2 whenever an instruction is parsed. According to the current cpu setting the symbols __CPU, __FPU and __MMU are defined. JMP/JSR (label,PC) will never be optimized (into a branch, for example). It will also automatically enable ‘-opt-allbra’, ‘-sd’ and ‘-guess-ext’.

-rangewarnings

Recognized for backwards-compatibility only. No longer needed since V2.0.

-regsymredef

Allow redefining register symbols with EQUR. This should only be used for compatibility with old sources. Not many assemblers support that.

-sdreg=<n>

Set the small data base register to An. <n> is valid between 0 and 6.

-sgs

Additionally allow immediate operands to be prefixed by & instead of just by #. This syntax was used by the SGS assembler.


23.3 General

This backend accepts M68k and CPU32 instructions as described in Mototola’s M68000 family Programmer’s Reference Manual. Additionally it supports ColdFire instructions as described in Motorola’s ColdFire Microprocessor Family Programmer’s Reference Manual.

The syntax for the scale factor in ColdFire MAC instructions is << for left- and >> for right-shift. The scale factor may be appended as an optional operand, when needed. Example: mac d0.l,d1.u,<<.

The mask flag in MAC instructions is written as & and is appended directly to the effective address operand. Example: mac d0,d1,(a0)&,d2.

The register list in MOVEM, FMOVEM, etc. instructions may optionally be specified by an immediate addressing mode, using a 16 or 8 (FMOVEM) bit register mask constant. Example (push no registers): movem.l #0,-(sp).

The target address type is 32 bit. Floating point constants in instructions and data are supported and encoded in IEEE format.

Default alignment for instructions is 2 bytes. The default alignment for data is 2 bytes, when the data size is larger than 8 bits. Note, that data is not auto-aligned unless you specify the ‘-align’ option (or use Devpac-compatibility mode: ‘-devpac’).


23.4 Internal symbols

Depending on the selected cpu type the __VASM symbol will have a value defined by the following bits:

bit 0

MC68000 instruction set. Also used by MC6830x, MC68322, MC68356.

bit 1

MC68010 instruction set.

bit 2

MC68020 instruction set.

bit 3

MC68030 instruction set.

bit 4

MC68040 instruction set.

bit 5

MC68060 instruction set.

bit 6

MC68881 or MC68882 FPU.

bit 7

MC68851 PMMU.

bit 8

CPU32. Any MC6833x or MC6834x CPU.

bit 9

ColdFire ISA_A.

bit 10

ColdFire ISA_A+.

bit 11

ColdFire ISA_B.

bit 12

ColdFire ISA_C.

bit 13

ColdFire hardware division support.

bit 14

ColdFire MAC instructions.

bit 15

ColdFire enhanced MAC instructions.

bit 16

ColdFire USP register.

bit 17

ColdFire FPU instructions.

bit 18

ColdFire MMU instructions.

bit 20

Apollo Core AC68080 instruction set.

The following symbols are defined for compatibility with other assemblers, so their function is not described here.

Devpac

__G2, __LK

PhxAss

__CPU, __FPU, __MMU, __OPTC

BAsm

_MOVEMBYTES, __MOVEMREGS


23.5 Extensions

This backend extends the selected syntax module by the following directives:

.sdreg <An>

Equivalent to near <An>.

basereg <expression>,<An>

Starts a block of base-relative addressing through register An (remember that A7 is not allowed as a base register). The developer has to make sure that <expression> is placed into An first, while the assembler automatically subtracts <expression>, which is usually a program label with an optional offset, from each displacement in a (d,An) addressing mode. basereg has priority over the near directive. Its effect can be suspended with the endb directive. It is allowed to use several base registers in parallel.

cpu32

Generate code for the CPU32 family.

endb <An>

Ends a basereg block and suspends its effect onto the specified base register An. It may be reused with a different base expression thereafter (refer to basereg).

far

Disables small data (base-relative) mode. All data references will be absolute.

fpu <cpID>

Enables 68881/68882 FPU code generation. The <cpID> is inserted into the FPU instructions to select the correct coprocessor. Note that <cpID> is always 1 for the on-chip FPUs in the 68040 and 68060. A <cpID> of zero will disable FPU code generation.

initnear

Initializes the selected small data base register. In contrast to PhxAss, where this directive comes from, just a reference to _LinkerDB is generated, which has to be resolved by a linker: lea _LinkerDB,An

machine <cpu_type>

Makes the assembler generate code for <cpu_type>, which can be the following: 68000, 68010, 68020, 68030, 68040, 68060, 68080, 68851, 68881, 68882, cpu32. And various ColdFire CPUs, starting with 5....

mc68000

Generate code for the MC68000 CPU.

mc68010

Generate code for the MC68010 CPU.

mc68020

Generate code for the MC68020 CPU.

mc68030

Generate code for the MC68030 CPU.

mc68040

Generate code for the MC68040 CPU.

mc68060

Generate code for the MC68060 CPU.

ac68080

Generate code for the Apollo Core AC68080 FPGA CPU.

mcf5...

Generate code for a ColdFire CPU. The recognized models are listed in the assembler-options section.

near [<An>]

Enables small data (base-relative) mode and sets the base register to An. near without an argument will reactivate a previously defined small data mode, which might have been switched off by a far directive.

near code

All JMP and JSR instructions to external labels will be converted into 16-bit PC-relative jumps. The small code mode can be switched off by a far directive.

opt <option>[,<option>...]

Sets Devpac-compatible options. When option ‘-phxass’ is given, then it will parse PhxAss options instead (which is discouraged for new code, so there is no detailed description here). Most supported Devpac2-style options are always suffixed by a + or - to enable or disable the option:

a

Automatically optimize absolute to PC-relative references. Default is off in Devpac-comptability mode, otherwise on.

c

Case-sensitivity for all symbols, instructions and macros. Default is on.

d

Include all symbols for debugging in the output file. May also generate line debugging information in some output formats. Default is off in Devpac-comptability mode, otherwise on.

l

Generate a linkable object file. The default is defined by the selected output format via the assembler’s ‘-F’ option. This option was supported by Devpac-Amiga only.

l0
l1
l2

Nonzero selects object file, zero selects executable file format, when Atari-TOS (‘-Ftos’) or Amiga-hunk output format (‘-Fhunk’) was set on the command line. This option was supported by Devpac-Atari only and its original function was to select TOS-executable (0), DRI-object (1) or GST-object (2) output. For GST objects use (‘-Fgst’) instead.

o

Enable all optimizations (o1 to o12), or disable all optimizations. The default is that all are disabled in Devpac-compatibility mode and enabled otherwise. When running in native vasm mode this option will also enable PC-relative (opt a) and the following safe vasm-specific optimizations (see below): og, of.

o1

Optimize branches without an explicit size extension.

o2

Standard displacement optimizations (e.g. (0,An) -> (An)).

o3

Optimize absolute addresses to short words.

o4

Optimize move.l to moveq.

o5

Optimize add #x and sub #x into their quick forms.

o6

No effect in vasm.

o7

Replace bra.b by a 2-byte no-operation instruction, like lea (a6),a6, when branching to the next instruction. Note: nop is not really a no-operation instruction on 68040 and higher.

o8

Optimize 68020+ base displacements to 16 bit.

o9

Optimize 68020+ outer displacements to 16 bit.

o10

Optimize add/sub #x,An to lea.

o11

Optimize lea (d,An),An to addq/subq.

o12

Optimize <op>.l #x,An to <op>.w #x,An.

ow

Show all optimizations being performed. Default is on in Devpac-compatibility mode, otherwise off.

p

Check if code is position independent. This will cause an error on every relocation entry being required. Default is off.

s

Include symbols in listing file. Default is on.

t

Check size and type of all expressions. Default is on.

w

Show assembler warnings. Default is on.

x

For Amiga hunk format objects x+ strips local symbols from the symbol table (symbols without xdef). For Atari TOS executables this will enable the extended (HiSoft) DRI symbol table format, which allows symbols with up to 22 characters. DRI standard only supports 8 characters.

Devpac options without +/- suffix:

l0
l1
l2

Nonzero selects object file, zero selects executable file format, when Atari-TOS (‘-Ftos’) or Amiga-hunk output format (‘-Fhunk’) was set on the command line. This option was supported by Devpac-Atari only and its original function was to select TOS-executable (0), DRI-object (1) or GST-object (2) output. For GST objects use (‘-Fgst’) instead.

p=<type>[/<type>]

Sets the CPU type to any model vasm supports (Devpac only allows 68000-68040, 68332, 68881, 68882 and 68851).

Also the following Devpac3-style options are supported:

autopc

Corresponds to a+.

case

Corresponds to c+.

chkpc

Corresponds to p+.

debug

Corresponds to d+.

symtab

Corresponds to s+.

type

Corresponds to t+.

warn

Corresponds to w+.

xdebug

Corresponds to x+.

noautopc

Corresponds to a-.

nocase

Corresponds to c-.

nochkpc

Corresponds to p-.

nodebug

Corresponds to d-.

nosymtab

Corresponds to s-.

notype

Corresponds to t-.

nowarn

Corresponds to w-.

noxdebug

Corresponds to x-.

The following options are vasm specific and should not be used when writing portable source. Using opt o+ or opt o- in Devpac mode only toggles og and of.

oa

Automatically optimize absolute Apollo destination operands to PC-relative references (requires 68080 code-generation enabled).

ob

Convert absolute jumps to external labels into long-branches (refer to ‘-opt-jbra’).

oc

Enable optimizations to CLR (refer to ‘-opt-clr’).

od

Enable optimization of divisions into shifts (refer to ‘-opt-div’).

of

Enable immediate float constant optimizations (refer to ‘-opt-fconst’).

og

Enable generic vasm optimizations. This includes all safe optimizations which cannot be controlled by another option.

oj

Enable branch to jump translations (refer to ‘-opt-brajmp’).

ol

Enable shift optimizations to ADD (refer to ‘-opt-lsl’).

om

Enable MOVEM optimizations (refer to ‘-opt-movem’).

on

Enable small data optimizations. References to absolute symbols in a small data section (named "__MERGED") are optimized into a base-relative addressing mode (refer to ‘-sd’).

op

Enable optimizations to PEA (refer to ‘-opt-pea’).

oq

Optimizes MOVE.L into a combination of MOVEQ and NEG.W (refer to ‘-opt-nmoveq’).

os

Optimize for speed before optimizing for size (refer to ‘-opt-speed’).

ot

Enable optimizations to ST (refer to ‘-opt-st’).

ox

Enable optimization of multiplications into shifts (refer to ‘-opt-mul’).

oz

Enable optimization for size, even if the code becomes slower (refer to ‘-opt-size’).

The default state is ’off’ for all these vasm specific options, except for of and og, which are ’on’.

The following directives are only available for the Motorola syntax module:

<symbol> equr <Rn>

Define a new symbol named <symbol> and assign the data or address register Rn, which can be used from now on in operands. When 68080 code generation is enabled, also Bn base address registers and En vector registers are allowed to be assigned. Note that a register symbol must be defined before it can be used!

<symbol> equrl <reglist>

Equivalent to <symbol> reg <reglist>.

<symbol> fequr <FPn>

Define a new symbol named <symbol> and assign the FPU register FPn, which can be used from now on in operands. Note that a register symbol must be defined before it can be used!

<symbol> fequrl <reglist>

Equivalent to <symbol> freg <reglist>.

<symbol> freg <reglist>

Defines a new symbol named <symbol> and assign the FPU register list <reglist> to it. Registers in a list must be separated by a slash (/) and ranges or registers can be defined by using a hyphen (-). No character at all represents an empty regiser list. Optionally you may specify the <reglist> as an 8-bit register mask constant (fp0 is bit 0, fp7 is bit 7). Examples for valid FPU register lists are: fp0-fp7, fp1-3/fp5/fp7, fpiar/fpcr.

<symbol> reg <reglist>

Defines a new symbol named <symbol> and assign the register list <reglist> to it. Registers in a list must be separated by a slash (/) and ranges or registers can be defined by using a hyphen (-). No character at all represents an empty regiser list. Optionally you may specify the <reglist> as a 16-bit register mask constant (d0 is bit 0, a7 is bit 15). Examples for valid register lists are: d0-d7/a0-a6, d3-6/a0/a1/a4-5.


23.6 Optimizations


23.6.1 Operand optimizations

This backend performs the following operand optimizations:

Note that an operand optimization will only take place when a displacement’s size was not enforced by the developer through an explicit size extension (e.g. (4.l,a0))!


23.6.2 Instruction optimizations

This backend performs the following instruction optimizations and translations:


23.7 Known Problems

Some known problems of this module at the moment:


23.8 Error Messages

This module has the following error messages:


[ << ] [ >> ]           [] [] [] [ ? ]