FASMARM v1.44 This package is an ARM assembler add-on for FASM. FASMARM currently supports the full range of instructions for 32-bit and 64-bit ARM processors and coprocessors up to and including v8. Contents: 1. ARM assembly compatibility 2. UAL and pre-UAL syntaxes 3. IT block handling 4. Alternate encodings 5. Output formats 6. Control directives 7. Data definitions 8. Defining registers lists inside macros 9. Half-precision number formatting 10. Variants supported 11. Further information 12. Version history _______________________________________________________________________________ 1. ARM assembly compatibility There are a few restrictions how the ARM instruction set is implemented. The changes are minor and mostly have a minor impact. For the most part the basic instruction outline is the same. Where possible the original style is used but there are some differences: Not everything matches the ARM ADS assembly style, where possible the original style is used but there are some differences 1) label names cannot begin with a digit 2) CPSIE and CPSID formats are changed, use "iflags_aif" form instead of "aif" (eg. "CPSIE iflags_i" instead of "CPSID i") 3) SRS with writeback must have a separating space after the mode number and before "!" (eg. "SRSDB 16 !" instead of "SRSDB 16!") 4) macro, rept, irp, format, if, virtual etc. are all significant changes from the ARM ADS, so you will need to re-write those sections of existing code Original ARM Syntax | fasmarm Syntax ----------------------+---------------------- cpsie a | cpsie iflags_a | srsdb #29! | srsdb #29 ! ;or, | srsdb 29 ! _______________________________________________________________________________ 2. UAL and pre-UAL syntaxes fasmarm supports the original pre-UAL syntax and the newer UAL syntax. These two syntaxes only affect THUMB encodings. UAL stands for: Universal Assembly Language. pre-UAL syntax is selected with the directive CODE16. UAL syntax is selected with the directive THUMB. pre-UAL syntax does not specify the "s" (flag update) in the opcodes for arithmetic operations involving the low set of registers (r0-r7). For example: pre-UAL Syntax | UAL Syntax ;Note ----------------+------------------------------------------------------ add r0,r1 | adds r0,r1 ;"s" was implicit with all registers <=r7 adds r0,r1 | adds r0,r1 | add r0,r1 ;only available inside an IT block, or | ;as 32-bit T2 instruction add r8,r1 | add r8,r1 ;high register used, does not update PSR adds r8,r1 | adds r8,r1 ;only available as 32-bit T2 instruction | mov r0,r1 | movs r0,r1 ;"s" was implicit with all registers <=r7 mov r8,r1 | mov r8,r1 ;high register used, does not update PSR movs r0,r1 | movs r0,r1 movs r8,r1 | movs r8,r1 ;only available as 32-bit T2 instruction | cpy r0,r1 | cpy r0,r1 ;also: mov r0,r1 in UAL Code written in UAL syntax can generally be assembled without modification in both ARM and THUMB modes. It is recommended to use UAL syntax for all new code. UAL syntax is get-what-you-write, whereas pre-UAL syntax has an implicit "s" flag which can potentially be unclear about what you will get. This is especially important in macros and structures where register numbers may be unknown until instantiated. Both syntaxes support triple and double register operands: "add r0,r0,r1" can be shortened to "add r0,r1" _______________________________________________________________________________ 3. IT block handling In THUMB mode fasmarm can insert IT blocks automatically: thumb ;use UAL syntax ;itet eq ;fasmarm inserts an automatic "IT EQ" block subeq r0,r1 ;T(rue) = eq subsne r2,r3 ;E(lse) = ne subseq r4,r5 ;T(rue) = eq fasmarm will check that manually placed IT blocks are consistent with subsequent code: thumb ;use UAL syntax itet eq ;manually placed IT block subeq r0,r1 ;T(rue) = eq, fasmarm checks the conditions are matched subsne r2,r3 ;E(lse) = ne, fasmarm checks the conditions are matched subseq r4,r5 ;T(rue) = eq, fasmarm checks the conditions are matched IT blocks cannot span across labels: thumb ;use UAL syntax ;it eq ;fasmarm inserts an automatic "IT EQ" block subeq r0,r1 ;T(rue) = eq lab1: ;ite ne ;fasmarm inserts a new "IT NE" block subsne r2,r3 ;T(rue) = ne subseq r4,r5 ;E(lse) = eq fasmarm will check that manually placed IT blocks do not span labels: ite mi ;manually placed IT block submi r0,r1 ;T(rue) = mi, fasmarm checks the conditions are matched lab2: subspl r2,r3 ;Error: IT block would span across the label IT blocks cannot span across changes to PC: thumb ;use UAL syntax ;ite eq ;fasmarm inserts an automatic "IT EQ" block subeq r0,r1 ;T(rue) = eq bne lab2 ;E(lse) = ne, branch will finish the IT block ;it eq ;fasmarm inserts a new "IT EQ" block subseq r4,r5 ;T(rue) = eq _______________________________________________________________________________ 4. Alternate encodings fasmarm follows this principle: Find a way to encode it, the smaller the better What this means is that even though you may write a particular opcocde, fasmarm may assemble another as a replacement. This can only happen where the functionality is exactly the same. The reason for doing this is to increase the likelihood of a successful assembly. This will only affect you if you want to look at a disassembly listing and match it to the original source. Example: What you coded | What is assembled ;reason -------------------+--------------------------------------------------- ARM and r0,0xfffffff0 | bic r0,0x0000000f ;immediate could not be encoded add r1,-4 | sub r1,4 ;immediate could not be encoded cmp r2,0xffffe500 | cmn r2,0x00001b00 ;immediate could not be encoded lsr r1,r2,r3 | mov r1,r2,lsr r3 ;ARM mode does not have LSR pop {r0-r3} | ldmfd r13!,{r0-r3} ;ARM mode does not have POP mul r4,r4,r11 | mul r4,r11,r4 ;encoding restriction for | ;CPU versions before v6 THUMB ldmfd r13!,{r0-r3} | pop {r0-r3} ;THUMB mode uses pop ldmfd r10!,{r8} | ldr r8,[r10],4 ;forbidden single register LDMs pop {r8} | ldr r8,[r13],4 ;forbidden single register POP add r2,0x89a | addw r2,0x89a ;immediate could not be encoded BOTH mov r1,0x4567 | movw r1,0x4567 ;immediate could not be encoded Other instructions than just what is shown above are also affected. The last part of the principles, the smaller the better, may impact THUMB code where a particular alignment is required. If you need to ensure that a particular instruction is always 32-bit, or always 16-bit, then you can use the qualifiers ".W" and ".N" after the opcodes and conditions to force either wide (32-bit) or narrow (16-bit) encodings. If the instruction cannot be encoded in the desired width fasmarm will give an error. If the instruction does not have both wide an narrow forms then the .W and .N suffixes are undefined. If you give no width suffix fasmarm will select the narrow form if it is available and encodable, and the wide form otherwise. To see how this impacts code using IT blocks examine the following example: thumb ;use UAL syntax sub r0,r1 ;only encodable as 32-bit outside an IT block subs r2,r3 ;fasmarm chooses the 16-bit form subs.w r4,r5 ;32-bit "wide" encoding forced b .next1 ;... .next1: ;ittt al ;fasmarm inserts an automatic "IT AL" block sub r0,r1 ;fasmarm chooses the 16-bit form inside an IT block sub r2,r3 ;fasmarm chooses the 16-bit form inside an IT block b .next2 ;IT block extends to here ;... .next2: ;itttt al ;fasmarm inserts an automatic "IT AL" block sub r0,r1 ;fasmarm chooses the 16-bit form inside an IT block sub r2,r3 ;fasmarm chooses the 16-bit form inside an IT block sub r9,r5 ;high register used, only encodable as 32-bit sub r6,r7 ;fasmarm chooses the 16-bit form inside an IT block The insertion of automatic "IT AL" blocks is only done when a reduction in code size is possible. To inhibit automatic "IT AL" block insertion you can force affected instructions to use the wide encoding with a .W suffix, or use the directive ITNOAUTO. To enable automatic insertion of IT AL blocks use the ITAUTO directive. ITAUTO is the default mode at startup. ITNOAUTO and ITAUTO directives only affect IT blocks using AL. Other condition codes will still be inserted automatically if not included explicitly. itauto ;enable automatic IT AL insertion from now onwards thumb ;use UAL syntax sub.w r0,r1 ;32-bit "wide" encoding forced sub.w r2,r3 ;32-bit "wide" encoding forced b .next2 ;... .next2: itnoauto ;inhibit automatic IT AL insertion from now onwards sub r0,r1 ;32-bit "wide" encoding used sub r2,r3 ;32-bit "wide" encoding used _______________________________________________________________________________ 5. Output formats The "format" directive will produce ARM code in all the same formats as the X86 version plus one additional format: ELF DWARF. The ELF DWARF is compatible with the ARM AXD debugger. The DWARF format produced includes all program labels, line numbers and module names for full symbolic debugging. The ELF format has been changed to set the FLAGS, code base and machine type compatible for ARM-LINUX. The PE format has been changed to set the machine type, subsystem and code base compatible with WinCE. PE64 format is available without relocations. ELF64 format has not yet been updated. Use format like this to get the dwarf output: format elf dwarf executable [at ?] Line number and the symbol table generation are automatically enabled with this format. Using "at" is optional and defaults to 0. The "section" directive for DWARF output is like this: section "name" [executable | readable | writeable | at ?] align ? The "name" is required. Align is required and must be a power of 2. All other attributes are optional except that at least one of executable, readable or writeable must be specified. Using "at" is optional and defaults to the next aligned address. Attributes can be specified in any order except "name" which must be first. The "org" directive is not allowed in DWARF output mode, otherwise everything is the same as for normal ELF output. Relocations for ELF and PE are not supported at this time. _______________________________________________________________________________ 6. Control directives There are five directives to control the code generation state: CODE64 - Switches to ARM64 (64bit instructions) code generation (alias USE64) CODE32 - Switches to ARM (32bit instructions) code generation (alias USE32) CODE16 - Switches to THUMB pre-UAL (16bit instructions) code generation (alias USE16) THUMB - Switches to THUMB UAL (16bit instructions) code generation THUMBEE - Switches to ThumbEE UAL (16bit instructions) code generation At startup the default is CODE32. There are two directives to control the instruction set classes enabled: PROCESSOR COPROCESSOR Where is a list instruction classes to enable or disable. Use a plus symbol (+) to enable, and a minus symbol (-) to disable. By default only the CPU32_* and COPRO_* instructions are enabled. To enable or disable one or more instruction classes without changing other classes use a leading plus (+) or minus (-) to incrementally update the settings. For example: processor cpu64_v8 ;enable only 64-bit version 8 base instructions ;all other instruction classes are disabled processor +cpu64_fp ;additionally enable the 64-bit floating point. ;If they were already enabled then they remain ;enabled. Other classes are unaffected. processor cpu64_v8 +cpu64_fp ;Both combined has the same effect as ;above two examples. coprocessor -copro_vfp_v4 ;disable only the VFP V4 instructions. ;If they were already disabled then ;they remain disabled. Other classes ;are unaffected. To query the selected instruction classes you can use the 'if' directive to do logical tests. For example: if processor cpu32_v7 | processor cpu32_7m ;do something end if if coprocessor copro_vfp_v4 ;do something else ;do something else end if The following is a list of processor instruction classes supported: CPU32_26BIT, CPU32_V1, CPU32_V2, CPU32_A, CPU32_V3, CPU32_M, CPU32_V4, CPU32_V4T, CPU32_V5, CPU32_V5T, CPU32_E, CPU32_P, CPU32_J, CPU32_X, CPU32_V6, CPU32_V6T, CPU32_ALIGN, CPU32_K, CPU32_Z, CPU32_6M, CPU32_7M, CPU32_T2, CPU32_V7, CPU32_SYNC, CPU32_DIV, CPU32_T2EE, CPU32_MP, CPU32_VE, CPU32_V8, CPU32_CRC, CPU64_V8, CPU64_FP, CPU64_SIMD, CPU64_CRC, CPU64_CRYPTO The following is a list of coprocessor instruction classes supported: COPRO_FPA_V1, COPRO_FPA_V2, COPRO_MAVERICK, COPRO_VFP_V1XD, COPRO_VFP_V1, COPRO_VFP_V2, COPRO_VFP_V3, COPRO_VFP_D32, COPRO_VFP_HP, COPRO_XSCALE, COPRO_IWMMXT_V1, COPRO_IWMMXT_V2, COPRO_SIMD_INT, COPRO_SIMD_FLOAT, COPRO_SIMD_HP, COPRO_VFP_V4, COPRO_SIMD_V2, COPRO_SIMD_V8, COPRO_SIMD_CRYPTO There are three combination instruction classes that will either enable or disable all instructions within the class: CPU32_ALL, CPU64_ALL, COPRO_ALL For backward compatibility with previous versions a single numeric constant can be specified instead of a list of classes. This is only supported for the following values: PROCESSOR supported immediate values: CPU32_CAPABILITY_26BIT = 1 shl 00 CPU32_CAPABILITY_V1 = 1 shl 01 CPU32_CAPABILITY_V2 = 1 shl 02 CPU32_CAPABILITY_A = 1 shl 03 CPU32_CAPABILITY_V3 = 1 shl 04 CPU32_CAPABILITY_M = 1 shl 05 CPU32_CAPABILITY_V4 = 1 shl 06 CPU32_CAPABILITY_V4T = 1 shl 07 CPU32_CAPABILITY_V5 = 1 shl 08 CPU32_CAPABILITY_V5T = 1 shl 09 CPU32_CAPABILITY_E = 1 shl 10 CPU32_CAPABILITY_P = 1 shl 11 CPU32_CAPABILITY_J = 1 shl 12 CPU32_CAPABILITY_X = 1 shl 13 CPU32_CAPABILITY_V6 = 1 shl 14 CPU32_CAPABILITY_V6T = 1 shl 15 CPU32_CAPABILITY_ALIGN = 1 shl 16 CPU32_CAPABILITY_K = 1 shl 17 CPU32_CAPABILITY_Z = 1 shl 18 CPU32_CAPABILITY_6M = 1 shl 19 CPU32_CAPABILITY_7M = 1 shl 20 CPU32_CAPABILITY_T2 = 1 shl 21 CPU32_CAPABILITY_V7 = 1 shl 22 CPU32_CAPABILITY_SYNC = 1 shl 23 CPU32_CAPABILITY_DIV = 1 shl 24 CPU32_CAPABILITY_T2EE = 1 shl 25 CPU32_CAPABILITY_MP = 1 shl 26 CPU32_CAPABILITY_VE = 1 shl 27 CPU32_CAPABILITY_V8 = 1 shl 28 CPU32_CAPABILITY_CRC = 1 shl 29 COPROCESSOR supported immediate values: COPRO_CAPABILITY_FPA_V1 = 1 shl 00 COPRO_CAPABILITY_FPA_V2 = 1 shl 01 COPRO_CAPABILITY_MAVERICK = 1 shl 02 COPRO_CAPABILITY_VFP_V1xD = 1 shl 03 COPRO_CAPABILITY_VFP_V1 = 1 shl 04 COPRO_CAPABILITY_VFP_V2 = 1 shl 05 COPRO_CAPABILITY_VFP_V3 = 1 shl 06 COPRO_CAPABILITY_VFP_D32 = 1 shl 07 COPRO_CAPABILITY_VFP_HP = 1 shl 08 COPRO_CAPABILITY_XSCALE = 1 shl 09 COPRO_CAPABILITY_IWMMXT_V1 = 1 shl 10 COPRO_CAPABILITY_IWMMXT_V2 = 1 shl 11 COPRO_CAPABILITY_SIMD_INT = 1 shl 12 COPRO_CAPABILITY_SIMD_FLOAT = 1 shl 13 COPRO_CAPABILITY_SIMD_HP = 1 shl 14 COPRO_CAPABILITY_VFP_V4 = 1 shl 15 COPRO_CAPABILITY_SIMD_V2 = 1 shl 16 COPRO_CAPABILITY_SIMD_V8 = 1 shl 17 COPRO_CAPABILITY_SIMD_CRYPTO = 1 shl 18 The above symbol names and values are not defined by fasmarm. You can add them to your source file to use them, or you can use just the raw numbers. There are two associated predefined symbols: %c and %p. %c is the bitmap value of the current coprocessor set enabled. %p is the bitmap value of the current processor set enabled. These predefined symbols only return values in the range as shown above. That means you can't the %p value to determine if any of the CPU64* instruction classes have been enabled. Instead use the 'if' form as shown earlier. Examples using a numeric constant: For ARM7TDMI CPUs: processor 0xfe coprocessor 0x0 For PXA25x CPUs: processor 0x2ffe coprocessor 0x0200 For PXA27x CPUs: processor 0x2ffe coprocessor 0x0600 For Cortex-A8 CPUs: processor 0x2fffffe coprocessor 0x30f8 For Cortex-A9 CPUs: processor 0x6fffffe coprocessor 0x30f8 At start-up the default is to enable the CPU32* instructions and all coprocessors. It you want to use later instruction classes and any 64-bit instructions these need to be specified with PROCESSOR before use. See the files in the ARMDOC folder for details about which instructions are enabled by each setting. _______________________________________________________________________________ 7. Data definitions Data definitions are different between ARM and X86. A "word" in ARM is 32 bits. X86 ARM comment ---+----+--------- DB | DB | byte: 8 bits DW | DH | half word: 16 bits DU | DU | half word strings: 16 bits DD | DW | word: 32 bits DQ | DD | double word: 64 bits RB | RB | byte: 8 bits RW | RH | half word: 16 bits RD | RW | word: 32 bits RQ | RD | double word: 64 bits DF | -- | not valid DP | -- | not valid DT | -- | not valid RF | -- | not valid RP | -- | not valid RT | -- | not valid Address sizes are always 64 bits in ARM64 state and 32 bits in ARM and THUMB states, you can't use any address overrides. Data sizes are different between ARM and X86. A "word" in ARM is 32 bits. X86 ARM comment --------+--------+--------------------- BYTE | BYTE | same: 8 bits WORD | HWORD | half word: 16 bits DWORD | WORD | word: 32 bits QWORD | DWORD | double word: 64 bits DQWORD | QWORD | quad word: 128 bits QQWORD | DQWORD | double quad word: 256 bits You can still use all the pre-processor and assembly features of FASM including macros, structures, repeats etc. _______________________________________________________________________________ 8. Defining registers lists inside macros The standard ARM syntax uses curly brackets, {}, to enclose registers lists. The standard fasm syntax uses curly brackets to enclose macros. Both standards are supported in fasmarm and you can mix them together. The way to state registers lists within macros is to escape the closing curly bracket with a leading backslash. macro block_copy destination, source, length { local .loop mov r0,source mov r1,destination add r2,r0,length .loop: ldmia r0!,{r3-r10\} ;we have to escape the closing bracket stmia r1!,{r3-r10\} ;we have to escape the closing bracket cmp r0,r2 blo .loop } _______________________________________________________________________________ 9. Half-precision number formatting The ARM specification allows extended range half-precision numbers. Care must be taken when defining numbers that fall within the extended range. Numbers in the range 65520.0 to 131039.0 inclusive can be defined using the DH directive and do not give any error. Values within this range place the exponent field at 0x1f. If the CPU is not placed into alternative half-precision (AHP) mode then these numbers fall within the NaN and infinity encoding space. _______________________________________________________________________________ 10. Variants supported Five standard variants of FASM binaries can been produced for FASMARM: FASMARM.EXE - WIN32 console FASMWARM.EXE - WIN32 IDE FASMARM - LINUX FASMARM.X64 - LINUX64 console FASMARM.O - LIBC _______________________________________________________________________________ 11. Further information Visit http://www.arm.com for information on the ARM instruction sets and processors. Visit http://flatassembler.net for the FASM x86 assembler package and tools. If you want to recompile the FASMARM code you will need the flatassembler package from the above URL. To see what others have said and to participate in the development of fasmarm see the active thread on the fasm message board: http://board.flatassembler.net/topic.php?t=4191 If you have a problem, question, suggestion, comment etc. you can contact me at http://board.flatassembler.net - my handle is revolution. _______________________________________________________________________________ 12. Version history v1.44 2023-Jul-01 - Update for compatibility with fasm v1.73.30 - MOVN/MOVZ with zero immediate now encodes any given shift - Add Linux 64-bit version: fasmarm.x64 - Add PE64 support for PIE code without relocations - Fix PE header bug in SizeOf(Un)InitializedData values - Fix errant check for thumb STRD duplicated source registers - Add allowance for DSB, DMB and ISB to accept numeric values - Honour two reg encoding for small immediates in thumb code - Add missing {VPUSH|VPOP}{.32|.64} aliases - Fix bug with 'IT LE' condition mis-tracking - Add alias of APSR_NZCV to R15 for VMRS/FMRX - Encode ROR by 0 to use LSL 0 - Fix bug using LDMIA/STMDB for LDRB/STRB and LDRH/STRH - Reduce aggressiveness of register swapping in thumb mode - Fix detection of invalid values, this improves the minimisation in thumb mode - Fix STMDB/LDMIA conversion to PUsH/POP in thumb mode - Encode single reg LDM as LDM, not as LDR, in thumb mode - Fix bug with LDRD literal load permitting writeback - Delay triggering of using wide instructions until 6 passes before the last - Add ITAUTO and ITNOAUTO directives - Add support for '-' as input/output file in Linux, enabling FASMARM to be used in pipeline - Add Windows armpe64.asm example - Add swapping of ADD(S) X?,X?,SP & W?,W?,WSP in 64-bit code - Fix bug with ADRP erroneously giving unaligned error - Fix ELF format flags for Version5 EABI - Fix bug with undefined symbol used as an implicit address giving unexpected invalid R15 usage error - Fix crash bug in square and curly expression parsers - Set machine type for ELF64 to AARCH64 - Fix bug with explicit register expressions creating bad immediate offsets v1.43 2017-Dec-26 - Fix a code minimisation logic regression v1.42 2017-Jul-23 - Fix a bug with unclosed curly and square bracket parsing v1.41 2016-Nov-09 - Fix a bug with forward referencing of labels in thumb mode v1.40 2016-May-14 - Fix a bug with unexpected size checks in 64-bit code for immediate values not used for addressing - Fix a bug with MOVK not respecting the shift amount when the immediate is zero - Change the IDE error summary dialog to show the full error message v1.39 2016-May-01 - Add 64-bit v8 instructions - Add simple expression evaluation inside address fields, e.g. "ldr x1,[x2-4]" and/or "ldr x1,[x2,-4]" - Add processing for lists of instruction classes to PROCESSOR and COPROCESSOR directives - Add 64-bit SemiHosting example program v1.38 2016-Apr-11 - Fixed more bugs with elf dwarf format file corruption - Fixed a bug with "section ... at 0" not updating PC to 0 - Fixed an encoding bug with VMULL.P8 - Add 32-bit v8 instructions v1.37 2015-Nov-16 - Added code and data generation from macro lines to the line number information table - Fixed a bug with elf dwarf format symbol table corruption - Fixed a bug where post-update instructions with a positive sign (eg. ldr r0,[r1],+r2) would always be forced negative v1.36 2015-Oct-05 - Fixed another bug with elf dwarf format file corruption v1.35 2015-Oct-01 - Fixed a bug with elf dwarf format file corruption v1.34 2015-Jun-18 - Fixed a bug with elf section offsets using "at" v1.33 2015-May-28 - Added on demand memory allocation for WIN32 - Fixed MRC bug with R15 as the destination v1.32 2014-Dec-21 - Update with all fasm changes as at 1.71.31 - Change the format of the undocumented CRC32 directive v1.31 2014-Jan-29 - Fixed long file names error during line number processing v1.30 2013-Sep-12 - Fixed THUMB encoding of LDRB and LDRH. Updated for fasm v1.71.13 v1.29 2012-Dec-24 - Added missing assert directive. Updated for fasm v1.71.07, address space additions v1.28 2012-Jul-11 - Fixed a bug with 65-bit values in section origins v1.27 2012-Jun-09 - Updated for compatibility with fasm v1.70.02, 65-bit values v1.26 2012-Feb-24 - Added support for ARM/THUMB mode v7VE instructions - Added support for ARM/THUMB mode VFPv4 instructions - Added support for ARM/THUMB mode SIMDv2 instructions - Added alternate two operand forms for absolute difference - Removed alternate two operand forms for multiply-accumulate v1.25 2011-Oct-31 - Fixed a bug with BKPT handling in IT blocks in ARM mode v1.24 2011-Oct-29 - Fixed a bug with crashes during expression parsing v1.23 2011-Jul-31 - Fixed a bug with relocations corrupting patch code v1.22 2010-Nov-24 - Fixed a bug with handling nameless sections in dwarf format v1.21 2010-Oct-17 - Minimising the "code cannot be generated" problem. If the assembler gets to a third repetition at the same state then it takes action and uses wide instructions in situations where the narrow instructions are causing problems v1.20 2010-Sep-17 - Fixed a bug with handling of files names in dwarf format v1.19 2010-Sep-16 - Add support for half-precision and extended half-precision number formatting. Compatible with fasm v1.69.24 v1.18 2010-Sep-09 - Update for compatibility with fasm v1.69.22 v1.17 2010-Sep-08 - Added support to separate byte and rotation values for immediate values in shifter encoding v1.16 2010-Apr-26 - Added experimental instruction CRC32 - Added experimental operator FIT - Added alternate encoding logic for VMOV/VMVN 16-bit and 32-bit forms - Generate an error with more than 16 double registers in FLDMD/FSTMD/VLDM/VSTM/VPOP/VPUSH - Fixed erroneous generation of conditional instructions when mixing VIRTUAL with IT blocks - Fixed encoding for THUMB mode PC relative immediate addressing when placed inside auto IT block - Fixed encoding for WLDRx/WSTRx with PC relative addressing v1.15 2010-Apr-21 - Added support for ARM/THUMB mode v6T2 instructions - Added support for ARM/THUMB mode v7 instructions - Added support for ThumbEE instructions - Added support for FPA coprocessors up to v2 - Added support for VFP coprocessors up to v3 - Added support for MAVERICK coprocessors - Added support for Intel WMMXT coprocessors up to v2 - Added support for Advanced SIMD coprocessors - Added support for alternate two register data processing operands. Implicit destination is the first operand - Added support for expressions in addresses to access PC relative variables and locations - Added support for automatic efficient IT block generation in THUMB mode - Added support for UAL assembly syntax - Added support for an optional hash (#) before literal values - Added predefined variables %c and %p - Added ARMDOC folder with example instruction formats for each opcode supported - Extended the alternate encoding logic - Changed numeric separation character from single quote (') to underscore (_) - Changed non-UAL SRS syntax to use a space, instead of a comma, between the mode number and writeback operator - Removed directives CODEFP, CODENOFP, CODEV5, CODEV6, CODEVFP1, CODEVFP2, ARM5, ARM6, VFP1 and VFP2. Use PROCESSOR and COPROCESSOR instead v1.14 2010-Feb-02 - Updated for compatibility with FASM 1.69.11 - Changed "LDRx reg,[reg,0]!" to generate "LDRx reg,[reg,0]" - Changed "LDRx reg,[reg],0" to generate "LDRx reg,[reg,0]" - Changed "LDC Px,Cx,[reg,0]!" to generate "LDC Px,Cx,[reg,0]" - Changed "LDC Px,Cx,[reg],0" to generate "LDC Px,Cx,[reg,0]" - Fixed encoding for thumb mode BLX - Fixed encoding for PKHTB without shift - Fixed encoding for SSAT, SSAT16 - Fixed encoding for UMAAL - Allowed rotation parameter for SXTB, SXTH, UXTB, UXTH v1.13 2008-Nov-04 - Updated register restrictions for STREX, SMLALD, SMLSLD, UMAAL, SMLALxy - Relaxed restriction of rotation count=0 (or omitted) for PKHTB - Enabled THUMB mode aliases for SXTB, SXTH, UXTB, UXTH v1.12 2008-Jul-13 - Updated for compatibility with FASM 1.67.27 - Fixed "error: undefined symbol" displaying the wrong line v1.11 2008-Mar-20 - Updated for compatibility with FASM 1.67.26 (note: no version change) v1.11 2007-Aug-31 - Updated for compatibility with FASM 1.67.22 - Fixed an address parser bug allowing "ldr rx,[constant]" without a register base v1.10 2007-Mar-04 - Updated for compatibility with FASM 1.67.21 expression calculation - Allowed forward referencing of register based structure addressing - Fixed a bug in the ARMLITRL.INC when generating PC relative offsets v1.09 2006-Aug-30 - Updated ARMTABLE.INC for compatibility with FASM 1.67 binary searches - Updated PE format to initialise several accounting fields and also to reset the "relocs stripped" flag if relocs are included v1.08 2006-Jun-09 - Fixed erroneous error with implicit r0 based addressing - Fixed priority of unary minus to match FASM v1.66 priority - Relaxed restrictions with register structure addresses when using zero offset - Enhanced MOV/MOVS to use ADD/SUB encoding when loading a register structure member - Generation of special encoding to allow user code to detect unencodable immediate values and then select an alternate coding without causing assembly errors - Alignment bytes changed to 0xff to facilitate faster FLASH ROM updates - Added proc, apscall, import and literals macros to package, see each individual file for usage and special notes - STRUCT and RESOURCE converted from x86 to ARM format - COREDLL.INC converted to an imports definition file v1.07 2006-May-26 - Patch for basic "format PE" support for WinCE - Added ARMPE example for WinCE (2006-06-02) - COREDLL.DLL import ordinal equates added in "COREDLL.INC" (2006-06-02) v1.06 2006-Mar-03 - Updated to work within FASM version 1.66 v1.05 2006-Feb-14 - Patch for basic "format ELF executable" support - Added ARMELF example v1.04 2005-Nov-09 - Fixed incorrect classification of data/code when using TIMES - Improved line number embedding generation for more efficient tables v1.03 2005-Oct-20 - Fixed IF/ELSE/END IF skip bug with commas v1.02 2005-Oct-03 - Fixed CPS mode change code generation - Fixed THUMB ASR and LSR shift range check v1.01 2005-Oct-01 - Fixed STMIA THUMB instruction checking for base register validity - Fixed error deferring for some expressions - Fixed shift count of 32 - Added ARMv6 instructions - Added VFPv2 instructions - Added register aliases a1-a4, v1-v8, sb, sl, fp, ip - Added CODE16, CODE32, CODEFP, CODENOFP, CODEV5, CODEV6, CODEVFP1, CODEVFP2 directives - Added ARM5, ARM6, VFP1, VFP2 combination directives - Enforced code typing (generates an error if new instructions are used but not enabled) - Enforced VFP to be explicitly enabled before use - Removed condition code "NV" v1 2005-Sep-29 - First public release (C) 01-Jul-2023 revolution