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

Legal
=====

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

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:

CPU selections
--------------

-m68000
     Generate code for the MC68000 CPU.

-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 of -gas to enable the FPU.

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, 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 may modify the V-flag, which might not be intended.

-opt-movem
     Enables optimization from MOVEM <ea>,Rn into MOVE <ea>,Rn (or the other way around). 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). 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-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-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-st
     Enables optimization from MOVE.B #-1,<ea> into ST <ea>. This optimization will leave the flags unmodified, which might not be intended.

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

-sd
     References to absolute symbols in a small data section (named "__MERGED") are optimized into a 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+).

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

  - Absolute to PC-relative.

  - Branches without explicit size.

  - Displacements (32 to 16 bit, (0,An) to (An), etc).

  - Optimize floating point constants to the lowest possible precision.

  - Many instruction optimizations which are safe.

Other options
-------------

-conv-brackets
     Brackets ('[' and ']') in an operand are automatically converted into 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 generated. Which is 0 for TOS executables, 4 for Amiga executables and 3 for Amiga object files. 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 are preceded 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
     Values which are out of range usually produce an error. With this option the errors 2026, 2030, 2033 and 2037 will be displayed as a warning, allowing the user to create an object file.

-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.

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 target address type is 32bit. 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.

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

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.

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.

     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
          Convert bra.b to nop, when branching to the next instruction.

     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 each relocation 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:

     l<n>
          Sets the output format (Devpac Atari only). Currently without effect.

     p=<type>[/<type>]
          Sets the CPU type to any model vasm supports (original Devpac only allowed 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.

     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 (-). 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 (-). Examples for valid register lists are: d0-d7/a0-a6, d3-6/a0/a1/a4-5.

Optimizations
=============

Operand optimizations
---------------------

This backend performs the following operand optimizations:

  - (0,An) optimized to (An).

  - (d16,An) translated to (bd32,An,ZDn.w), when d16 is not between -32768 and 32767 and the selected CPU allows it (68020 up or CPU32).

  - (d16,PC) translated to (bd32,PC,ZDn.w), when d16 is not between -32768 and 32767 and the selected CPU allows it (68020 up or CPU32).

  - (d8,An,Rn) translated to (bd,An,Rn), when d8 is not between -128 and 127 and the selected CPU allows it (68020 up or CPU32).

  - (d8,PC,Rn) translated to (bd,PC,Rn), when d8 is not between -128 and 127 and the selected CPU allows it (68020 up or CPU32).

  - <exp>.l optimized to <exp>.w, when <exp> is absolute and between -32768 and 32767.

  - <exp>.w translated to <exp>.l, when <exp> is a program label or absolute and not between -32768 and 32767.

  - (0,An,...) optimized to (An,...) (which means the base displacement will be suppressed). This allows further optimization to (An), when the index is suppressed.

  - (bd16,An,...) translated to (bd32,An,...), when bd16 is not between -32768 and 32767.

  - (bd32,An,...) optimized to (bd16,An,...), when bd16 is between -32768 and 32767.

  - (bd32,An,ZRn) optimized to (d16,An), when bd32 is between -32768 and 32767, and the index is suppressed (zero-Rn).

  - (An,ZRn) optimized to (An), when the index is suppressed.

  - (0,PC,...) optimized to (PC,...) (which means the base displacement will be suppressed).

  - (bd16,PC,...) translated to (bd32,PC,...), when bd16 is not between -32768 and 32767.

  - (bd32,PC,...) optimized to (bd16,PC,...), when bd16 is between -32768 and 32767.

  - (bd32,PC,ZRn) optimized to (d16,PC), when bd32 is between -32768 and 32767, and the index is suppressed (zero-Rn).

  - ([0,Rn,...],...) optimized to ([An,...],...) (which means the base displacement will be suppressed).

  - ([bd16,Rn,...],...) translated to ([bd32,An,...],...), when bd16 is not between -32768 and 32768.

  - ([bd32,Rn,...],...) optimized to ([bd16,An,...],...), when bd32 is between -32768 and 32768.

  - ([...],0) optimized to ([...]) (which means the outer displacement will be suppressed).

  - ([...],od16) translated to ([...],od32), when od16 is not between -32768 and 32767.

  - ([...],od32) translated to ([...],od16), when od32 is between -32768 and 32767.

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))!

Instruction optimizations
-------------------------

This backend performs the following instruction optimizations and translations:

  - <op>.L #x,An optimized to <op>.W #x,An, when x is between -32768 and 32767.

  - ADD.? #x,<ea> optimized to ADDQ.? #x,<ea>, when x is between 1 and 8.

  - ADD.? #x,<ea> optimized to SUBQ.? #x,<ea>, when x is between -1 and -8.

  - ADDA.? #0,An and SUBA.? #0,An will be deleted.

  - ADDA.? #x,An translated to LEA (x,An),An, when x is between -32768 and 32767.

  - ANDI.L #$ff,Dn optimized to MVZ.B Dn,Dn, for ColdFire ISA_B/C.

  - ANDI.L #$ffff,Dn optimized to MVZ.W Dn,Dn, for ColdFire ISA_B/C.

  - ANDI.? #0,<ea> optimized to CLR.? <ea>, when allowed by the option -opt-clr or a different CPU than the MC68000 was selected.

  - ANDI.? #-1,<ea> optimized to TST.? <ea>.

  - ASL.? #1,Dn optimized to ADD.? Dn,Dn for 68000 and 68010.

  - ASL.? #2,Dn optimized into a sequence of two ADD.? Dn,Dn for 68000 and 68010, when the operation size is either byte or word and the options -opt-speed and -opt-lsl are given.

  - B<cc> <label> translated into a combination of B!<cc> *+8 and JMP <label>, when <label> is not defined in the same section (and option -opt-brajmp is given), or outside the range of -32768 to 32767 bytes from the current address when the selected CPU is not 68020 up, CPU32 or ColdFire ISA_B/C.

  - B<cc> <label> is automatically optimized to 8-bit, 16-bit or 32-bit (68020 up, CPU32, MCF5407 only), whatever fits best. When the selected CPU doesn't support 32-bit branches it will try to change the conditional branch into a B<!cc> *+8 and JMP <label> sequence.

  - BRA <label> translated to JMP <label>, when <label> is not defined in the same section (and option -opt-brajmp is given), or outside the range of -32768 to 32767 bytes from the current address when the selected CPU is not 68020 up, CPU32 or ColdFire ISA_B/C.

  - BSR <label> translated to JSR <label>, when <label> is not defined in the same section (and option -opt-brajmp is given), or outside the range of -32768 to 32767 bytes from the current address when the selected CPU is not 68020 up, CPU32 or ColdFire ISA_B/C.

  - <cp>B<cc> <label> is automatically optimized to 16-bit or 32-bit, whatever fits best. <cp> means coprocessor and is P for the PMMU and F for the FPU.

  - CLR.L Dn optimized to MOVEQ #0,Dn.

  - CMP.? #0,<ea> optimized to TST.? <ea>. The selected CPU type must be MC68020 up, ColdFire or CPU32 to support address register direct as effective address (<ea>).

  - DIVS.W/DIVU.W #1,Dn optimized to MVZ.W Dn,Dn, for ColdFire ISA_B/C (-opt-div).

  - DIVS.W #-1,Dn optimized to the sequence of NEG.W Dn and MVZ.W Dn,Dn (-opt-div and -opt-speed).

  - DIVS.L/DIVU.L #1,Dn optimized to TST.L Dn (-opt-div).

  - DIVS.L #-1,Dn optimized to NEG.L Dn (-opt-div).

  - DIVU.L #2..256,Dn optimized to LSR.L #x,Dn (-opt-div).

  - EORI.? #-1,<ea> optimized to NOT.? <ea>.

  - EORI.? #0,<ea> optimized to TST.? <ea>.

  - FMOVEM.? <reglist> is deleted when the register list was empty.

  - FxDIV.? #m,FPn optimized to FxMUL.? #1/m,FPn when m is a power of 2 and option -opt-fconst is given.

  - JMP <label> optimized to BRA.? <label>, when <label> is defined in the same section and in the range of -32768 to 32767 bytes from the current address. Note that JMP (<lab>,PC) is never optimized, with the intention to preserve jump-tables.

  - JSR <label> optimized to BSR.? <label>, when <label> is defined in the same section and in the range of -32768 to 32767 bytes from the current address. Note that JSR (<lab>,PC) is never optimized, with the intention to preserve jump-tables.

  - LEA 0,An optimized to SUBA.L An,An.

  - LEA (0,An),An and LEA (An),An will be deleted.

  - LEA (d,An),An is optimized to ADDQ.L #d,An when d is between 1 and 8 and to SUBQ.L #-d,An when d is between -1 and -8.

  - LEA (d,Am),An will be translated into a combination of MOVEA and ADDA.L for 68000 and 68010, when d is lower than -32768 or higher than 32767. The MOVEA will be omitted when Am and An are identical. Otherwise -opt-speed is required.

  - LINK.L An,#x optimized to LINK.W An,#x, when x is between -32768 and 32767.

  - LINK.W An,#x translated to LINK.L An,#x, when x is not between -32768 and 32767 and selected CPU supports this instruction.

  - LSL.? #1,Dn optimized to ADD.? Dn,Dn for 68000 and 68010, when option -opt-lsl is given.

  - LSL.? #2,Dn optimized into a sequence of two ADD.? Dn,Dn for 68000 and 68010, when the operation size is either byte or word and the options -opt-speed and -opt-lsl are given.

  - MOVE.? #0,<ea> optimized to CLR.? <ea>, when allowed by the option -opt-clr or a different CPU than the MC68000 was selected.

  - MOVE.? #x,-(SP) optimized to PEA x, when allowed by the option -opt-pea. The move-size must not be byte (.b).

  - MOVE.B #-1,<ea> optimized to ST <ea>, when allowed by the option -opt-st.

  - MOVE.L #x,Dn optimized to MOVEQ #x,Dn, when x is between -128 and 127.

  - MOVE.L #x,Dn optimized to the sequence of MOVEQ #x>>1,Dn and ADD.W Dn,Dn, when 128<=x<=254 and x is even.

  - MOVE.L #x,Dn optimized to the sequence of MOVEQ #x^$ff,Dn and NOT.B Dn, when 128<=x<=255 and the option -opt-nmoveq was set.

  - MOVE.L #x,Dn optimized to the sequence of MOVEQ #x>>16,Dn and SWAP Dn, when $10000<=x<=$7f0000 or $ff80ffff<=x<=$fffeffff.

  - MOVE.L #x,Dn optimized to the sequence of MOVEQ #y,Dn and NEG.W Dn, when $ff81<=x<=$ffff or $ffff0001<=x<=$ffff0080 and the option -opt-nmoveq was set.

  - MOVE.L #x,Dn optimized to the sequence of MOVEQ #x>>n,Dn and LSL.W #n,Dn, when $0100<=x<=$7f00 and the LSB is zero and -opt-size was set together with standard optimizations.

  - MOVE.L #x,<ea> optimized to MOV3Q #x,<ea>, for ColdFire ISA_B and ISA_C, when x is -1 or between 1 and 7.

  - MOVEA.? #0,An optimized to SUBA.L An,An.

  - MOVEA.L #x,An optimized to MOVEA.W #x,An, when x is between -32768 and 32767.

  - MOVEA.L #label,An optimized to LEA label,An, which could allow further optimization to LEA label(PC),An.

  - MOVEM.? <reglist> is deleted, when the register list was empty.

  - MOVEM.? <ea>,An optimized to MOVE.? <ea>,An, when the register list only contains a single address register.

  - MOVEM.? <ea>,Rn optimized to MOVE.? <ea>,Rn and MOVEM.? Rn,<ea> optimized to MOVE.? Rn,<ea>, when allowed by the option -opt-movem or when just loading an address register.

  - MOVEM.? <ea>,Rm/Rn and MOVEM.? Rm/Rn,<ea> are optimized into a sequence of two MOVE for all cpus except 68000 and 68010. Complex addressing modes with displacements or addresses are optimized for 68040 only. Has to be enabled by the options -opt-movem and -opt-speed.

  - MULS.?/MULU.? #0,Dn optimized to MOVEQ #0,Dn (-opt-mul).

  - MULS.?/MULU.? #1,Dn is deleted (-opt-mul).

  - MULS.W #-1,Dn optimized to the sequence EXT.L Dn and NEG.L Dn (-opt-mul and -opt-speed).

  - MULS.L #-1,Dn optimized to NEG.L Dn (-opt-mul).

  - MULS.W #2..256,Dn optimized to the sequence EXT.L Dn and ASL.L #x,Dn (-opt-mul and -opt-speed).

  - MULS.W #-2..-256,Dn optimized to the sequence EXT.L Dn, ASL.L #x,Dn and NEG.L Dn (-opt-mul and -opt-speed).

  - MULS.L #2..256,Dn optimized to ASL.L #x,Dn (-opt-mul).

  - MULS.L #-2..-256,Dn optimized to the sequence ASL.L #x,Dn and NEG.L Dn (-opt-mul and -opt-speed).

  - MULU.W #2..256,Dn optimized to the sequence MVZ.W Dn,Dn and ASL.L #x,Dn for ColdFire ISA_B/C (-opt-mul and -opt-speed).

  - MULU.L #2..256,Dn optimized to LSL.L #x,Dn (-opt-mul).

  - MVZ.? #x,Dn and MVS.? #x,Dn are optimized to MOVEQ #x,Dn.

  - ORI.? #0,<ea> optimized to TST.? <ea>.

  - SUB.? #x,<ea> optimized to SUBQ.? #x,<ea>, when x is between 1 and 8.

  - SUB.? #x,<ea> optimized to ADDQ.? #x,<ea>, when x is between -1 and -8.

  - SUBA.? #x,An translated to LEA (-x,An),An, when x is between -32767 and 32768.

Known Problems
==============

Some known problems of this module at the moment:

  - In some rare cases, mainly by stupid input sources, the optimizer might oscillate forever between two states. When this happens, assembly will be terminated automatically after some time.

  - When using FMOVE immediate addressing modes, but without specifying a size extension, constants between $80000000 and $ffffffff are stored with 32 bits, which leads to sign-extension problems when the instruction is really 64 or 96 bits.

Error Messages
==============

This module has the following error messages:

  - 2001: instruction not supported on selected architecture

  - 2002: illegal addressing mode

  - 2003: invalid register list

  - 2004: missing ) in register indirect addressing mode

  - 2005: address register required

  - 2006: bad size extension

  - 2007: displacement at bad position

  - 2008: base or index register expected

  - 2009: missing ] in memory indirect addressing mode

  - 2010: no extension allowed here

  - 2011: illegal scale factor

  - 2012: can't scale PC register

  - 2013: index register expected

  - 2014: too many ] in memory indirect addressing mode

  - 2015: missing outer displacement

  - 2016: %c expected

  - 2017: can't use PC register as index

  - 2018: double registers in list

  - 2019: data register required

  - 2020: illegal bitfield width/offset

  - 2021: constant integer expression required

  - 2022: value from -64 to 63 required for k-factor

  - 2023: need 32 bits to reference a program label

  - 2024: option expected

  - 2025: absolute value expected

  - 2026: operand value out of range: %ld (valid: %ld..%ld)

  - 2027: label in operand required

  - 2028: using signed operand as unsigned: %ld (valid: %ld..%ld), %ld to fix

  - 2029: branch destination out of range

  - 2030: displacement out of range

  - 2031: absolute displacement expected

  - 2032: unknown option %c%c ignored

  - 2033: absolute short address out of range

  - 2034: 8-bit branch with zero displacement was converted to 16-bit

  - 2035: illegal opcode extension

  - 2036: extension for unsized instruction ignored

  - 2037: immediate operand out of range

  - 2038: immediate operand has illegal type or size

  - 2039: data objects with %d bits size are not supported

  - 2040: data out of range

  - 2041: data has illegal type

  - 2042: illegal combination of ColdFire addressing modes

  - 2043: FP register required

  - 2044: unknown cpu type

  - 2045: register expected

  - 2046: link.w changed to link.l

  - 2047: branch out of range changed to jmp

  - 2048: lea-displacement out of range, changed into move/add

  - 2049: translated (A%d) into (0,A%d) for movep

  - 2050: operand optimized: %s

  - 2051: operand translated: %s

  - 2051: instruction optimized: %s

  - 2053: instruction translated: %s

  - 2054: branch optimized into: b<cc>.%c

  - 2055: branch translated into: b<cc>.%c

  - 2056: basereg A%d already in use

  - 2057: basereg A%d is already free

  - 2058: short-branch to following instruction turned into a nop

  - 2059: not a valid small data register

  - 2060: small data mode is not enabled

  - 2061: division by zero

  - 2062: can't use B%d register as index

  - 2063: register list on both sides

  - 2064: "%s" directive was replaced by an instruction with the same name

  - 2065: Addr.reg. operand at level #0 causes F-line exception

  - 2066: Dr and Dq are identical, transforming DIVxL.L effectively into DIVx.L

  - 2067: not a valid register list symbol

  - 2068: trailing garbage in operand

  - 2069: encoding absolute displacement directly

  - 2070: internal symbol %s has been modified

  - 2071: instruction too large for bank prefix

  - 2072: bad FPU id %d for selected cpu type