aboutsummaryrefslogtreecommitdiff
path: root/misc
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-09-17 18:18:44 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-09-17 18:18:44 +0000
commit57623d42ebb04f0a0b9e6eb7c0847a3ece2aa0ff (patch)
tree25d07d14e920d31c0b1947c9ca586f2a01fc32d8 /misc
downloadpx4-firmware-57623d42ebb04f0a0b9e6eb7c0847a3ece2aa0ff.tar.gz
px4-firmware-57623d42ebb04f0a0b9e6eb7c0847a3ece2aa0ff.tar.bz2
px4-firmware-57623d42ebb04f0a0b9e6eb7c0847a3ece2aa0ff.zip
Resync new repository with old repo r5166
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5153 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'misc')
-rw-r--r--misc/LICENSING.txt46
-rw-r--r--misc/buildroot/.defconfig64
-rw-r--r--misc/buildroot/ChangeLog119
-rw-r--r--misc/buildroot/Config.in371
-rw-r--r--misc/buildroot/Makefile224
-rw-r--r--misc/buildroot/ReleaseNotes89
-rw-r--r--misc/buildroot/configs/README.txt340
-rw-r--r--misc/buildroot/configs/arm-defconfig112
-rw-r--r--misc/buildroot/configs/arm7tdmi-defconfig-4.2.4115
-rw-r--r--misc/buildroot/configs/arm7tdmi-defconfig-4.3.3116
-rw-r--r--misc/buildroot/configs/arm920t-defconfig-4.2.4115
-rw-r--r--misc/buildroot/configs/arm920t-defconfig-4.3.3119
-rw-r--r--misc/buildroot/configs/arm920t-eabi-defconfig-4.5.2121
-rw-r--r--misc/buildroot/configs/arm926t-defconfig-4.2.4116
-rw-r--r--misc/buildroot/configs/arm926t-defconfig-4.3.3117
-rw-r--r--misc/buildroot/configs/arm926t-defconfig-nxflat110
-rw-r--r--misc/buildroot/configs/avr-defconfig-4.3.399
-rw-r--r--misc/buildroot/configs/avr-defconfig-4.5.299
-rw-r--r--misc/buildroot/configs/bfin-defconfig-4.2.492
-rw-r--r--misc/buildroot/configs/cortexm3-defconfig-4.3.3116
-rw-r--r--misc/buildroot/configs/cortexm3-defconfig-nxflat106
-rw-r--r--misc/buildroot/configs/gdb-6_8-cygwin-1_7.patch19
-rw-r--r--misc/buildroot/configs/h8300_defconfig92
-rw-r--r--misc/buildroot/configs/i486-defconfig-4.3.3103
-rw-r--r--misc/buildroot/configs/m32c-defconfig-4.2.493
-rw-r--r--misc/buildroot/configs/m32c-defconfig-4.3.393
-rw-r--r--misc/buildroot/configs/m68hc11-config92
-rw-r--r--misc/buildroot/configs/m68hc12-config-3.4.693
-rw-r--r--misc/buildroot/configs/m68hc12-config-4.3.394
-rw-r--r--misc/buildroot/configs/m68k-defconfig92
-rw-r--r--misc/buildroot/configs/m9s12x-config-3.3.696
-rw-r--r--misc/buildroot/configs/sh-defconfig99
-rw-r--r--misc/buildroot/package/Makefile.in111
-rw-r--r--misc/buildroot/package/config/Kconfig-language.txt282
-rw-r--r--misc/buildroot/package/config/Makefile134
-rw-r--r--misc/buildroot/package/config/conf.c583
-rw-r--r--misc/buildroot/package/config/confdata.c397
-rw-r--r--misc/buildroot/package/config/expr.c1099
-rw-r--r--misc/buildroot/package/config/expr.h195
-rw-r--r--misc/buildroot/package/config/lex.zconf.c_shipped3688
-rw-r--r--misc/buildroot/package/config/lkc.h123
-rw-r--r--misc/buildroot/package/config/lkc_proto.h40
-rw-r--r--misc/buildroot/package/config/lxdialog/BIG.FAT.WARNING4
-rw-r--r--misc/buildroot/package/config/lxdialog/checklist.c372
-rw-r--r--misc/buildroot/package/config/lxdialog/colors.h161
-rw-r--r--misc/buildroot/package/config/lxdialog/dialog.h199
-rw-r--r--misc/buildroot/package/config/lxdialog/inputbox.c240
-rw-r--r--misc/buildroot/package/config/lxdialog/menubox.c438
-rw-r--r--misc/buildroot/package/config/lxdialog/msgbox.c85
-rw-r--r--misc/buildroot/package/config/lxdialog/textbox.c556
-rw-r--r--misc/buildroot/package/config/lxdialog/util.c375
-rw-r--r--misc/buildroot/package/config/lxdialog/yesno.c118
-rw-r--r--misc/buildroot/package/config/mconf.c973
-rw-r--r--misc/buildroot/package/config/menu.c390
-rw-r--r--misc/buildroot/package/config/symbol.c809
-rw-r--r--misc/buildroot/package/config/util.c108
-rw-r--r--misc/buildroot/package/config/zconf.l366
-rw-r--r--misc/buildroot/package/config/zconf.tab.c_shipped2130
-rw-r--r--misc/buildroot/package/config/zconf.tab.h_shipped125
-rw-r--r--misc/buildroot/package/config/zconf.y690
-rw-r--r--misc/buildroot/package/gnuconfig/ChangeLog1813
-rw-r--r--misc/buildroot/package/gnuconfig/Makefile15
-rw-r--r--misc/buildroot/package/gnuconfig/README.buildroot16
-rwxr-xr-xmisc/buildroot/package/gnuconfig/config.guess1517
-rwxr-xr-xmisc/buildroot/package/gnuconfig/config.sub1627
-rw-r--r--misc/buildroot/package/gnuconfig/gnuconfig.mk3
-rw-r--r--misc/buildroot/package/gnuconfig/patches/config.sub.ps2.patch50
-rw-r--r--misc/buildroot/package/gnuconfig/patches/config.sub.sh.patch39
-rw-r--r--misc/buildroot/package/gnuconfig/testsuite/config-guess.data23
-rw-r--r--misc/buildroot/package/gnuconfig/testsuite/config-guess.sh47
-rw-r--r--misc/buildroot/package/gnuconfig/testsuite/config-sub.data92
-rw-r--r--misc/buildroot/package/gnuconfig/testsuite/config-sub.sh35
-rwxr-xr-xmisc/buildroot/package/gnuconfig/testsuite/uname.in9
-rwxr-xr-xmisc/buildroot/package/gnuconfig/uname9
-rw-r--r--misc/buildroot/toolchain/Config.in46
-rw-r--r--misc/buildroot/toolchain/Makefile.in21
-rw-r--r--misc/buildroot/toolchain/binutils/2.17/110-arm-eabi-conf.patch24
-rw-r--r--misc/buildroot/toolchain/binutils/2.17/300-001_ld_makefile_patch.patch50
-rw-r--r--misc/buildroot/toolchain/binutils/2.17/300-006_better_file_error.patch43
-rw-r--r--misc/buildroot/toolchain/binutils/2.17/300-012_check_ldrunpath_length.patch47
-rw-r--r--misc/buildroot/toolchain/binutils/2.17/400-makeinfo-version-check.patch12
-rw-r--r--misc/buildroot/toolchain/binutils/2.17/400-mips-ELF_MAXPAGESIZE-4K.patch26
-rw-r--r--misc/buildroot/toolchain/binutils/2.18/100-s12x-20100504.patch8646
-rw-r--r--misc/buildroot/toolchain/binutils/2.19.1/110-arm-eabi-conf.patch24
-rw-r--r--misc/buildroot/toolchain/binutils/2.19.1/120-sh-conf.patch42
-rw-r--r--misc/buildroot/toolchain/binutils/2.19.1/300-001_ld_makefile_patch.patch24
-rw-r--r--misc/buildroot/toolchain/binutils/2.19.1/300-012_check_ldrunpath_length.patch21
-rw-r--r--misc/buildroot/toolchain/binutils/2.19.1/400-thumb-cputype.patch16
-rw-r--r--misc/buildroot/toolchain/binutils/2.19/110-arm-eabi-conf.patch24
-rw-r--r--misc/buildroot/toolchain/binutils/2.19/120-sh-conf.patch42
-rw-r--r--misc/buildroot/toolchain/binutils/2.19/300-001_ld_makefile_patch.patch24
-rw-r--r--misc/buildroot/toolchain/binutils/2.19/300-012_check_ldrunpath_length.patch21
-rw-r--r--misc/buildroot/toolchain/binutils/2.21.1/110-arm-eabi-conf.patch24
-rw-r--r--misc/buildroot/toolchain/binutils/2.21.1/120-sh-conf.patch42
-rw-r--r--misc/buildroot/toolchain/binutils/2.21.1/300-001_ld_makefile_patch.patch24
-rw-r--r--misc/buildroot/toolchain/binutils/2.21.1/300-012_check_ldrunpath_length.patch21
-rw-r--r--misc/buildroot/toolchain/binutils/2.21.1/900-bug12296-cortexm3-svc.patch48
-rw-r--r--misc/buildroot/toolchain/binutils/Config.in47
-rw-r--r--misc/buildroot/toolchain/binutils/binutils.mk125
-rw-r--r--misc/buildroot/toolchain/dependencies/dependencies.mk25
-rwxr-xr-xmisc/buildroot/toolchain/dependencies/dependencies.sh316
-rw-r--r--misc/buildroot/toolchain/gcc/3.3.6/120-softfloat.patch14
-rw-r--r--misc/buildroot/toolchain/gcc/3.3.6/500-loop.patch10
-rw-r--r--misc/buildroot/toolchain/gcc/3.3.6/800-arm-bigendian.patch68
-rw-r--r--misc/buildroot/toolchain/gcc/3.3.6/810-mips-xgot.patch6
-rw-r--r--misc/buildroot/toolchain/gcc/3.3.6/820-no-mips-empic-relocs.patch59
-rw-r--r--misc/buildroot/toolchain/gcc/3.3.6/830-gcc-bug-num-22167.patch16
-rw-r--r--misc/buildroot/toolchain/gcc/3.3.6/900-sx12-20101109.patch17940
-rw-r--r--misc/buildroot/toolchain/gcc/3.3.6/910-create-mode.patch11
-rw-r--r--misc/buildroot/toolchain/gcc/3.4.6/300-libstdc++-pic.patch47
-rw-r--r--misc/buildroot/toolchain/gcc/3.4.6/304-index_macro.patch24
-rw-r--r--misc/buildroot/toolchain/gcc/3.4.6/600-gcc34-arm-ldm-peephole.patch65
-rw-r--r--misc/buildroot/toolchain/gcc/3.4.6/601-gcc34-arm-ldm-peephole2.patch42
-rw-r--r--misc/buildroot/toolchain/gcc/3.4.6/601-gcc34-arm-ldm.patch119
-rw-r--r--misc/buildroot/toolchain/gcc/3.4.6/602-sdk-libstdc++-includes.patch22
-rw-r--r--misc/buildroot/toolchain/gcc/3.4.6/700-pr15068-fix.patch44
-rw-r--r--misc/buildroot/toolchain/gcc/3.4.6/71_all_sh-pr16665-fix.patch43
-rw-r--r--misc/buildroot/toolchain/gcc/3.4.6/72_all_sh-no-reorder-blocks.patch13
-rw-r--r--misc/buildroot/toolchain/gcc/3.4.6/73_all_sh-pr20617.patch28
-rw-r--r--misc/buildroot/toolchain/gcc/3.4.6/800-arm-bigendian.patch68
-rw-r--r--misc/buildroot/toolchain/gcc/3.4.6/810-mips-xgot.patch6
-rw-r--r--misc/buildroot/toolchain/gcc/3.4.6/900-nios2.patch10211
-rw-r--r--misc/buildroot/toolchain/gcc/3.4.6/910-gcc-3.4.6-ocreatmode.patch12
-rw-r--r--misc/buildroot/toolchain/gcc/3.4.6/arm-softfloat.patch.conditional270
-rw-r--r--misc/buildroot/toolchain/gcc/4.2.4/300-libstdc++-pic.patch50
-rw-r--r--misc/buildroot/toolchain/gcc/4.2.4/304-index_macro.patch24
-rw-r--r--misc/buildroot/toolchain/gcc/4.2.4/305-libmudflap-susv3-legacy.patch49
-rw-r--r--misc/buildroot/toolchain/gcc/4.2.4/307-locale_facets.patch26
-rw-r--r--misc/buildroot/toolchain/gcc/4.2.4/402-libbackend_dep_gcov-iov.h.patch13
-rw-r--r--misc/buildroot/toolchain/gcc/4.2.4/800-arm-bigendian.patch67
-rw-r--r--misc/buildroot/toolchain/gcc/4.2.4/904-flatten-switch-stmt-00.patch153
-rw-r--r--misc/buildroot/toolchain/gcc/4.2.4/910-soft-float.patch26
-rw-r--r--misc/buildroot/toolchain/gcc/4.2.4/920-soft-float.patch21
-rw-r--r--misc/buildroot/toolchain/gcc/4.2.4/930-nuttx-nolibc.patch30
-rw-r--r--misc/buildroot/toolchain/gcc/4.2.4/940-nuttx-nolibstdc.patch13
-rw-r--r--misc/buildroot/toolchain/gcc/4.3.3/300-libmudflap-susv3-legacy.patch49
-rw-r--r--misc/buildroot/toolchain/gcc/4.3.3/310-arm-softfloat-libgcc.patch29
-rw-r--r--misc/buildroot/toolchain/gcc/4.3.3/500-backport-fix-for-bug-39076.patch11
-rw-r--r--misc/buildroot/toolchain/gcc/4.3.3/510-backport-fix-for-bug-32044.patch188
-rw-r--r--misc/buildroot/toolchain/gcc/4.3.3/600-arm_insn-opinit-RTX_CODE-fixup.patch41
-rw-r--r--misc/buildroot/toolchain/gcc/4.3.3/610-gcc-4.3.0-fix-header.00.patch15
-rw-r--r--misc/buildroot/toolchain/gcc/4.3.3/620-gcc-4.3.2-armeabi-aapcs-linux.patch18
-rw-r--r--misc/buildroot/toolchain/gcc/4.3.3/630-gcc-4.3.0-cris-pragma-pack-warning-remove.patch13
-rw-r--r--misc/buildroot/toolchain/gcc/4.3.3/700-gcc-4.3.3-arm7arch.patch16
-rwxr-xr-xmisc/buildroot/toolchain/gcc/4.3.3/900-nuttx-nolibc.patch30
-rw-r--r--misc/buildroot/toolchain/gcc/4.3.3/910-nuttx-nolibstdc.patch13
-rw-r--r--misc/buildroot/toolchain/gcc/4.3.3/920-gcc-4.3.3-objext.patch22
-rw-r--r--misc/buildroot/toolchain/gcc/4.5.2/305-libmudflap-susv3-legacy.patch49
-rw-r--r--misc/buildroot/toolchain/gcc/4.5.2/810-arm-softfloat-libgcc.patch38
-rw-r--r--misc/buildroot/toolchain/gcc/4.5.2/820-arm-unbreak-armv4t.patch14
-rw-r--r--misc/buildroot/toolchain/gcc/4.5.2/830-arm-pr43440.patch345
-rw-r--r--misc/buildroot/toolchain/gcc/4.5.2/850-arm-pr44392.patch70
-rw-r--r--misc/buildroot/toolchain/gcc/4.5.2/900-nuttx-nolibstdc.patch13
-rw-r--r--misc/buildroot/toolchain/gcc/4.5.2/901-bug43999-fix-mismatch-between-conditions-of-an-IT-block.patch13
-rw-r--r--misc/buildroot/toolchain/gcc/Config.in106
-rw-r--r--misc/buildroot/toolchain/gcc/Makefile.in62
-rw-r--r--misc/buildroot/toolchain/gcc/gcc-nuttx-3.x.mk226
-rw-r--r--misc/buildroot/toolchain/gcc/gcc-nuttx-4.x.mk208
-rw-r--r--misc/buildroot/toolchain/gcc/i386-gcc-soft-float.patch61
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/400-mips-coredump.patch-2.4.23-2928
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/500-thread-timeout.patch34
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/600-debian_10.selected-frame.patch552
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/620-debian_static-thread-db.patch156
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/630-debian_24.tracepoint-segv.patch15
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/640-debian_dwarf2-frame-signal-unwinder.patch120
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/650-debian_vsyscall-gdb-support.patch245
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/660-debian_dwarf-cfa-restore.patch23
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/680-debian_sim-destdir.patch53
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/690-debian_member-field-symtab.patch35
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/700-debian_cp-pass-by-reference.patch464
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/710-debian_thread-db-multiple-libraries.patch593
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/720-debian_static-threads-test.patch36
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/730-debian_gdb-fix-tracefork-check.patch225
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/740-debian_make-cv-type-crash.patch132
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/750-debian_sparc-singlestep.patch37
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/760-debian_vsyscall-bfd-close-result.patch20
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/770-debian_vfork-done-spelling.patch31
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/780-debian_gdbserver-rdynamic.patch675
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/790-debian_dwarf2-cfi-warning.patch39
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/800-debian_linux-use-underscore-exit.patch22
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/810-debian_bfd-no-kylix-crash.patch47
-rw-r--r--misc/buildroot/toolchain/gdb/6.3/820-debian_disable-linux-fork-messages.patch46
-rw-r--r--misc/buildroot/toolchain/gdb/6.4/400-mips-coredump.patch-2.4.23-2928
-rw-r--r--misc/buildroot/toolchain/gdb/6.4/500-thread-timeout.patch34
-rw-r--r--misc/buildroot/toolchain/gdb/6.4/600-fix-compile-flag-mismatch.patch87
-rw-r--r--misc/buildroot/toolchain/gdb/6.4/700-m68hc1x-20060122.patch5682
-rw-r--r--misc/buildroot/toolchain/gdb/6.8/600-fix-compile-flag-mismatch.patch31
-rw-r--r--misc/buildroot/toolchain/gdb/Config.in48
-rw-r--r--misc/buildroot/toolchain/gdb/gdb.mk224
-rw-r--r--misc/buildroot/toolchain/gdb/snapshot/400-mips-coredump.patch-2.4.23-2930
-rw-r--r--misc/buildroot/toolchain/gdb/snapshot/400-mips-nptl-support.patch143
-rw-r--r--misc/buildroot/toolchain/gdb/snapshot/500-thread-timeout.patch34
-rw-r--r--misc/buildroot/toolchain/gdb/snapshot/680-debian_sim-destdir.patch14
-rw-r--r--misc/buildroot/toolchain/gdb/snapshot/690-debian_member-field-symtab.patch20
-rw-r--r--misc/buildroot/toolchain/genromfs/Config.in8
-rwxr-xr-xmisc/buildroot/toolchain/genromfs/genromfs-0.5.2.tar.gzbin0 -> 21069 bytes
-rw-r--r--misc/buildroot/toolchain/genromfs/genromfs.mk38
-rw-r--r--misc/buildroot/toolchain/nxflat/Config.in9
-rw-r--r--misc/buildroot/toolchain/nxflat/Makefile74
-rw-r--r--misc/buildroot/toolchain/nxflat/arm/Makefile50
-rw-r--r--misc/buildroot/toolchain/nxflat/arm/arch.h303
-rw-r--r--misc/buildroot/toolchain/nxflat/arm/disarm.c1004
-rw-r--r--misc/buildroot/toolchain/nxflat/arm/dyncall_skeleton.def216
-rw-r--r--misc/buildroot/toolchain/nxflat/ldnxflat.c2336
-rw-r--r--misc/buildroot/toolchain/nxflat/mknxflat.c769
-rw-r--r--misc/buildroot/toolchain/nxflat/nxflat.h202
-rw-r--r--misc/buildroot/toolchain/nxflat/nxflat.mk69
-rw-r--r--misc/buildroot/toolchain/nxflat/readnxflat.c717
-rw-r--r--misc/buildroot/toolchain/nxflat/reloc-macros.h140
-rw-r--r--misc/buildroot/toolchain/nxflat/thumb2/Makefile50
-rw-r--r--misc/buildroot/toolchain/nxflat/thumb2/arch.h303
-rw-r--r--misc/buildroot/toolchain/nxflat/thumb2/disthumb2.c16
-rw-r--r--misc/buildroot/toolchain/nxflat/thumb2/dyncall_skeleton.def222
-rwxr-xr-xmisc/buildroot/toolchain/patch-kernel.sh54
-rw-r--r--misc/buildroot/toolchain/sstrip/Config.in11
-rw-r--r--misc/buildroot/toolchain/sstrip/sstrip.c468
-rw-r--r--misc/buildroot/toolchain/sstrip/sstrip.mk69
-rwxr-xr-xmisc/buildroot/zipme.sh80
-rwxr-xr-xmisc/drivers/INSTALL.sh101
-rwxr-xr-xmisc/drivers/rtl8187x/INSTALL.sh134
-rw-r--r--misc/drivers/rtl8187x/rtl8187x.c4213
-rw-r--r--misc/drivers/rtl8187x/rtl8187x.h475
-rw-r--r--misc/pascal/ChangeLog37
-rwxr-xr-xmisc/pascal/Configure188
-rw-r--r--misc/pascal/Make.config.h78
-rw-r--r--misc/pascal/Make.defs50
-rw-r--r--misc/pascal/Makefile115
-rw-r--r--misc/pascal/README25
-rwxr-xr-xmisc/pascal/Reconfigure89
-rw-r--r--misc/pascal/ReleaseNotes40
-rwxr-xr-xmisc/pascal/config.info64
-rw-r--r--misc/pascal/doc/PascalGrammar.txt455
-rw-r--r--misc/pascal/doc/PascalNotes.txt135
-rw-r--r--misc/pascal/include/keywords.h82
-rw-r--r--misc/pascal/include/paslib.h90
-rw-r--r--misc/pascal/include/pdefs.h115
-rw-r--r--misc/pascal/include/pedefs.h280
-rw-r--r--misc/pascal/include/perr.h56
-rw-r--r--misc/pascal/include/pfdefs.h93
-rw-r--r--misc/pascal/include/pinsn.h82
-rw-r--r--misc/pascal/include/podefs.h204
-rw-r--r--misc/pascal/include/poff.h429
-rw-r--r--misc/pascal/include/pofflib.h313
-rw-r--r--misc/pascal/include/pxdefs.h232
-rw-r--r--misc/pascal/insn16/Makefile82
-rw-r--r--misc/pascal/insn16/doc/PascalOptimizations.txt239
-rw-r--r--misc/pascal/insn16/doc/PascalTestStatus.txt208
-rw-r--r--misc/pascal/insn16/include/pdbg.h52
-rw-r--r--misc/pascal/insn16/include/pexec.h156
-rw-r--r--misc/pascal/insn16/include/pinsn16.h408
-rw-r--r--misc/pascal/insn16/libinsn/Makefile76
-rw-r--r--misc/pascal/insn16/libinsn/paddopcode.c100
-rw-r--r--misc/pascal/insn16/libinsn/paddtmpopcode.c100
-rw-r--r--misc/pascal/insn16/libinsn/pdasm.c569
-rw-r--r--misc/pascal/insn16/libinsn/pgen.c312
-rw-r--r--misc/pascal/insn16/libinsn/pgetopcode.c140
-rw-r--r--misc/pascal/insn16/libinsn/preloc.c149
-rw-r--r--misc/pascal/insn16/plist/Makefile90
-rw-r--r--misc/pascal/insn16/plist/plist.c360
-rw-r--r--misc/pascal/insn16/popt/Makefile92
-rw-r--r--misc/pascal/insn16/popt/pcopt.c906
-rw-r--r--misc/pascal/insn16/popt/pcopt.h53
-rw-r--r--misc/pascal/insn16/popt/pfopt.c473
-rw-r--r--misc/pascal/insn16/popt/pfopt.h54
-rw-r--r--misc/pascal/insn16/popt/pjopt.c450
-rw-r--r--misc/pascal/insn16/popt/pjopt.h52
-rw-r--r--misc/pascal/insn16/popt/plopt.c250
-rw-r--r--misc/pascal/insn16/popt/plopt.h54
-rw-r--r--misc/pascal/insn16/popt/polocal.c301
-rw-r--r--misc/pascal/insn16/popt/polocal.h74
-rw-r--r--misc/pascal/insn16/popt/popt.c289
-rw-r--r--misc/pascal/insn16/popt/popt.h52
-rw-r--r--misc/pascal/insn16/popt/psopt.c387
-rw-r--r--misc/pascal/insn16/popt/psopt.h54
-rw-r--r--misc/pascal/insn16/prun/Make.defs38
-rw-r--r--misc/pascal/insn16/prun/Makefile87
-rw-r--r--misc/pascal/insn16/prun/pdbg.c748
-rw-r--r--misc/pascal/insn16/prun/pexec.c2375
-rw-r--r--misc/pascal/insn16/prun/pload.c176
-rw-r--r--misc/pascal/insn16/prun/prun.c278
-rw-r--r--misc/pascal/insn32/Makefile92
-rw-r--r--misc/pascal/insn32/doc/insn32.txt119
-rw-r--r--misc/pascal/insn32/include/builtins.h450
-rw-r--r--misc/pascal/insn32/include/pexec.h160
-rw-r--r--misc/pascal/insn32/include/pinsn32.h426
-rw-r--r--misc/pascal/insn32/include/rinsn32.h226
-rw-r--r--misc/pascal/insn32/libinsn/Makefile76
-rw-r--r--misc/pascal/insn32/libinsn/paddopcode.c99
-rw-r--r--misc/pascal/insn32/libinsn/paddtmpopcode.c99
-rw-r--r--misc/pascal/insn32/libinsn/pdasm.c436
-rw-r--r--misc/pascal/insn32/libinsn/pgen.c383
-rw-r--r--misc/pascal/insn32/libinsn/pgetopcode.c128
-rw-r--r--misc/pascal/insn32/libinsn/preloc.c149
-rw-r--r--misc/pascal/insn32/libinsn/presettmpopcodewrite.c99
-rw-r--r--misc/pascal/insn32/plist/Makefile90
-rw-r--r--misc/pascal/insn32/plist/plist.c388
-rw-r--r--misc/pascal/insn32/popt/Makefile93
-rw-r--r--misc/pascal/insn32/popt/pcopt.c840
-rw-r--r--misc/pascal/insn32/popt/pcopt.h47
-rw-r--r--misc/pascal/insn32/popt/pfopt.c544
-rw-r--r--misc/pascal/insn32/popt/pfopt.h54
-rw-r--r--misc/pascal/insn32/popt/pjopt.c449
-rw-r--r--misc/pascal/insn32/popt/pjopt.h44
-rw-r--r--misc/pascal/insn32/popt/plopt.c215
-rw-r--r--misc/pascal/insn32/popt/plopt.h43
-rw-r--r--misc/pascal/insn32/popt/polocal.c271
-rw-r--r--misc/pascal/insn32/popt/polocal.h73
-rw-r--r--misc/pascal/insn32/popt/popt.c327
-rw-r--r--misc/pascal/insn32/popt/popt.h52
-rw-r--r--misc/pascal/insn32/popt/psopt.c385
-rw-r--r--misc/pascal/insn32/popt/psopt.h54
-rw-r--r--misc/pascal/insn32/regm/Makefile94
-rw-r--r--misc/pascal/insn32/regm/regm.c342
-rw-r--r--misc/pascal/insn32/regm/regm.h67
-rw-r--r--misc/pascal/insn32/regm/regm_pass1.c281
-rw-r--r--misc/pascal/insn32/regm/regm_pass1.h58
-rw-r--r--misc/pascal/insn32/regm/regm_pass2.c1526
-rw-r--r--misc/pascal/insn32/regm/regm_pass2.h68
-rw-r--r--misc/pascal/insn32/regm/regm_registers2.c542
-rw-r--r--misc/pascal/insn32/regm/regm_registers2.h319
-rw-r--r--misc/pascal/insn32/regm/regm_tree.c338
-rw-r--r--misc/pascal/insn32/regm/regm_tree.h122
-rw-r--r--misc/pascal/libpas/Make.defs38
-rw-r--r--misc/pascal/libpas/Makefile67
-rw-r--r--misc/pascal/libpas/pextension.c133
-rw-r--r--misc/pascal/libpas/psignextend16.c58
-rw-r--r--misc/pascal/libpas/pswap.c60
-rw-r--r--misc/pascal/libpoff/Make.defs48
-rw-r--r--misc/pascal/libpoff/Makefile47
-rw-r--r--misc/pascal/libpoff/pfdbgcontainer.c106
-rw-r--r--misc/pascal/libpoff/pfdbgdiscard.c94
-rw-r--r--misc/pascal/libpoff/pfdbginfo.c158
-rw-r--r--misc/pascal/libpoff/pfdhdr.c182
-rw-r--r--misc/pascal/libpoff/pfdreloc.c108
-rw-r--r--misc/pascal/libpoff/pfdsymbol.c117
-rw-r--r--misc/pascal/libpoff/pfhandle.c195
-rw-r--r--misc/pascal/libpoff/pfiprog.c93
-rw-r--r--misc/pascal/libpoff/pfirodata.c103
-rw-r--r--misc/pascal/libpoff/pflabel.c285
-rw-r--r--misc/pascal/libpoff/pflineno.c334
-rw-r--r--misc/pascal/libpoff/pfprivate.h190
-rw-r--r--misc/pascal/libpoff/pfproghandle.c127
-rw-r--r--misc/pascal/libpoff/pfrdbgfunc.c131
-rw-r--r--misc/pascal/libpoff/pfread.c361
-rw-r--r--misc/pascal/libpoff/pfrelease.c94
-rw-r--r--misc/pascal/libpoff/pfrfname.c117
-rw-r--r--misc/pascal/libpoff/pfrhdr.c118
-rw-r--r--misc/pascal/libpoff/pfrlineno.c128
-rw-r--r--misc/pascal/libpoff/pfrprog.c91
-rw-r--r--misc/pascal/libpoff/pfrrawlineno.c111
-rw-r--r--misc/pascal/libpoff/pfrrawreloc.c108
-rw-r--r--misc/pascal/libpoff/pfrseek.c116
-rw-r--r--misc/pascal/libpoff/pfrstring.c91
-rw-r--r--misc/pascal/libpoff/pfrsymbol.c108
-rw-r--r--misc/pascal/libpoff/pfswap.c252
-rw-r--r--misc/pascal/libpoff/pfsymhandle.c127
-rw-r--r--misc/pascal/libpoff/pftprog.c225
-rw-r--r--misc/pascal/libpoff/pftsymbol.c189
-rw-r--r--misc/pascal/libpoff/pfwdbgfunc.c174
-rw-r--r--misc/pascal/libpoff/pfwfname.c146
-rw-r--r--misc/pascal/libpoff/pfwhdr.c116
-rw-r--r--misc/pascal/libpoff/pfwlineno.c165
-rw-r--r--misc/pascal/libpoff/pfwprog.c128
-rw-r--r--misc/pascal/libpoff/pfwreloc.c162
-rw-r--r--misc/pascal/libpoff/pfwrite.c541
-rw-r--r--misc/pascal/libpoff/pfwrodata.c193
-rw-r--r--misc/pascal/libpoff/pfwstring.c218
-rw-r--r--misc/pascal/libpoff/pfwsymbol.c152
-rw-r--r--misc/pascal/libpoff/pfxprog.c96
-rw-r--r--misc/pascal/libpoff/pfxrodata.c95
-rw-r--r--misc/pascal/libpoff/pofferr.c94
-rwxr-xr-xmisc/pascal/nuttx/INSTALL.sh166
-rw-r--r--misc/pascal/nuttx/Makefile138
-rw-r--r--misc/pascal/nuttx/README.txt43
-rw-r--r--misc/pascal/nuttx/keywords.h67
-rw-r--r--misc/pascal/pascal/Makefile85
-rw-r--r--misc/pascal/pascal/pas.c538
-rw-r--r--misc/pascal/pascal/pas.h116
-rw-r--r--misc/pascal/pascal/pasdefs.h284
-rw-r--r--misc/pascal/pascal/pblck.c2263
-rw-r--r--misc/pascal/pascal/pblck.h57
-rw-r--r--misc/pascal/pascal/pcexpr.c576
-rw-r--r--misc/pascal/pascal/pcfunc.c341
-rw-r--r--misc/pascal/pascal/perr.c191
-rw-r--r--misc/pascal/pascal/pexpr.c2737
-rw-r--r--misc/pascal/pascal/pexpr.h98
-rw-r--r--misc/pascal/pascal/pffunc.c452
-rw-r--r--misc/pascal/pascal/pfunc.h57
-rw-r--r--misc/pascal/pascal/pgen.c641
-rw-r--r--misc/pascal/pascal/pgen.h89
-rw-r--r--misc/pascal/pascal/pprgm.c265
-rw-r--r--misc/pascal/pascal/pprgm.h47
-rw-r--r--misc/pascal/pascal/pproc.c736
-rw-r--r--misc/pascal/pascal/pproc.h49
-rw-r--r--misc/pascal/pascal/pstm.c1683
-rw-r--r--misc/pascal/pascal/pstm.h47
-rw-r--r--misc/pascal/pascal/ptbl.c692
-rw-r--r--misc/pascal/pascal/ptbl.h79
-rw-r--r--misc/pascal/pascal/ptdefs.h209
-rw-r--r--misc/pascal/pascal/ptkn.c899
-rw-r--r--misc/pascal/pascal/ptkn.h65
-rw-r--r--misc/pascal/pascal/punit.c599
-rw-r--r--misc/pascal/pascal/punit.h51
-rw-r--r--misc/pascal/plink/Makefile83
-rw-r--r--misc/pascal/plink/plink.c551
-rw-r--r--misc/pascal/plink/plink.h52
-rw-r--r--misc/pascal/plink/plreloc.c255
-rw-r--r--misc/pascal/plink/plreloc.h60
-rw-r--r--misc/pascal/plink/plsym.c469
-rw-r--r--misc/pascal/plink/plsym.h62
-rwxr-xr-xmisc/pascal/tests/501-uses.sh84
-rwxr-xr-xmisc/pascal/tests/debug.sh104
-rwxr-xr-xmisc/pascal/tests/list.sh73
-rw-r--r--misc/pascal/tests/src/001-beginend.pas11
-rw-r--r--misc/pascal/tests/src/002-writeln.pas17
-rw-r--r--misc/pascal/tests/src/003-for.inp2
-rw-r--r--misc/pascal/tests/src/003-for.pas16
-rw-r--r--misc/pascal/tests/src/004-repeat.inp2
-rw-r--r--misc/pascal/tests/src/004-repeat.pas18
-rw-r--r--misc/pascal/tests/src/005-while.inp2
-rw-r--r--misc/pascal/tests/src/005-while.pas19
-rw-r--r--misc/pascal/tests/src/006-optconst.pas43
-rw-r--r--misc/pascal/tests/src/007-function.pas16
-rw-r--r--misc/pascal/tests/src/101-cosine.inp2
-rw-r--r--misc/pascal/tests/src/101-cosine.pas29
-rw-r--r--misc/pascal/tests/src/102-cen2fahr.pas22
-rw-r--r--misc/pascal/tests/src/103-sumharm.inp2
-rw-r--r--misc/pascal/tests/src/103-sumharm.pas46
-rw-r--r--misc/pascal/tests/src/104-primes.pas43
-rw-r--r--misc/pascal/tests/src/105-inflation.pas27
-rw-r--r--misc/pascal/tests/src/201-strcat.pas36
-rw-r--r--misc/pascal/tests/src/202-strcmp.pas47
-rw-r--r--misc/pascal/tests/src/501-unit-cosine.pas36
-rw-r--r--misc/pascal/tests/src/501-unit-data.pas21
-rw-r--r--misc/pascal/tests/src/501-unit-sine.pas24
-rw-r--r--misc/pascal/tests/src/501-uses.inp1
-rw-r--r--misc/pascal/tests/src/501-uses.pas20
-rw-r--r--misc/pascal/tests/src/801-cgihello.pas20
-rw-r--r--misc/pascal/tests/src/802-cgiinfo.pas67
-rw-r--r--misc/pascal/tests/src/803-redirect.pas137
-rw-r--r--misc/pascal/tests/src/804-cgiform.pas322
-rw-r--r--misc/pascal/tests/src/805-cgimail.pas553
-rw-r--r--misc/pascal/tests/src/806-cgicook.pas771
-rw-r--r--misc/pascal/tests/src/901-pageutils.pas5651
-rw-r--r--misc/pascal/tests/src/README38
-rwxr-xr-xmisc/pascal/tests/testall.sh124
-rwxr-xr-xmisc/pascal/tests/testone.sh166
-rwxr-xr-xmisc/pascal/zipme71
-rw-r--r--misc/sims/README.txt35
-rw-r--r--misc/sims/z80sim/README.txt24
-rw-r--r--misc/sims/z80sim/example/Makefile44
-rw-r--r--misc/sims/z80sim/example/example.asm84
-rw-r--r--misc/sims/z80sim/src/Makefile39
-rw-r--r--misc/sims/z80sim/src/main.c485
-rw-r--r--misc/tools/README.txt46
-rw-r--r--misc/tools/genromfs-0.5.2.tar.gzbin0 -> 21069 bytes
-rw-r--r--misc/tools/kconfig-frontends-3.3.0-1-libintl.patch72
-rw-r--r--misc/tools/kconfig-frontends-3.3.0-1.tar.gzbin0 -> 504640 bytes
-rw-r--r--misc/tools/kconfig-language.txt413
-rwxr-xr-xmisc/tools/kconfig-macos.diff22
460 files changed, 144310 insertions, 0 deletions
diff --git a/misc/LICENSING.txt b/misc/LICENSING.txt
new file mode 100644
index 000000000..05e96d4a2
--- /dev/null
+++ b/misc/LICENSING.txt
@@ -0,0 +1,46 @@
+Licensing
+^^^^^^^^^
+
+This directory contains miscellaneous NuttX add-ons and utilities.
+NuttX is retained separately for maintenance and licensing reasons.
+NuttX has a BSD-style license. However, the contents of this
+directory have have other license restrictions.
+
+The licensing of the components of this directory are summarized
+below:
+
+ buildroot:
+ Description: GNU toolchain build environment. Derived from
+ http://buildroot.uclibc.org/
+ License: GPLv2
+
+ pascal:
+ Description: Pascal compiler with NuttX runtime add-on.
+ License: BSD
+
+ sims:
+ Description: This is a repository of instruction set simulators
+ that were used to verify NuttX. The licensing of the
+ instruction set simulators vary
+
+ sims/z80sim:
+ You are well comecom to use the source files provided in
+ this directory for any purpose. However, the core of the Z80
+ emulation is based on a proprietary-but-free-to-use
+ instruction set emulator. That emulation is not included
+ in this directory, but is automatically downloaded when
+ z80sim is built.
+
+ drivers:
+ Descriptions: This is a folder of drivers that are not included
+ in the main NuttX source tree due to licensing or other concerns.
+ Compatibly licensed drivers (BSD or MIT) are included in the main
+ source tree. These drivers have incompatible licesnes. They
+ may, as an example, have been leveraged from Linux and, hence,
+ inherit a GPL license. By installing this driver package you
+ agree to the licensing terms of the individual drivers.
+
+ rtl8187x
+ This is a USB host driver for the RTL8187x wireless LAN. Some
+ of the critical logic in this driver derives from Linux and,
+ hence, is GPLv2.
diff --git a/misc/buildroot/.defconfig b/misc/buildroot/.defconfig
new file mode 100644
index 000000000..12bce6183
--- /dev/null
+++ b/misc/buildroot/.defconfig
@@ -0,0 +1,64 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_arm is not set
+# BR2_armeb is not set
+# BR2_cris is not set
+BR2_i386=y
+# BR2_m68k is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sparc is not set
+BR2_ARCH="i386"
+BR2_WGET="wget --passive-ftp"
+
+#
+# Toolchain Options
+#
+BR2_KERNEL_HEADERS_2_6_19_2=y
+BR2_DEFAULT_KERNEL_HEADERS="2.6.19.2"
+# BR2_UCLIBC_VERSION_SNAPSHOT is not set
+BR2_UCLIBC_VERSION_0_9_28_1=y
+# BR2_ENABLE_LOCALE is not set
+# BR2_BINUTILS_VERSION_2_14_90_0_8 is not set
+# BR2_BINUTILS_VERSION_2_15 is not set
+# BR2_BINUTILS_VERSION_2_15_94_0_2_2 is not set
+# BR2_BINUTILS_VERSION_2_16_1 is not set
+# BR2_BINUTILS_VERSION_2_16_90_0_3 is not set
+# BR2_BINUTILS_VERSION_2_16_91_0_5 is not set
+# BR2_BINUTILS_VERSION_2_16_91_0_6 is not set
+# BR2_BINUTILS_VERSION_2_16_91_0_7 is not set
+BR2_BINUTILS_VERSION_2_17=y
+# BR2_BINUTILS_VERSION_2_17_50_0_2 is not set
+# BR2_BINUTILS_VERSION_2_17_50_0_3 is not set
+# BR2_BINUTILS_VERSION_2_17_50_0_4 is not set
+# BR2_BINUTILS_VERSION_2_17_50_0_5 is not set
+# BR2_BINUTILS_VERSION_2_17_50_0_6 is not set
+# BR2_BINUTILS_VERSION_2_17_50_0_7 is not set
+# BR2_BINUTILS_VERSION_2_17_50_0_8 is not set
+# BR2_BINUTILS_VERSION_2_17_50_0_9 is not set
+# BR2_BINUTILS_VERSION is not set
+# BR2_GCC_VERSION_3_3_5 is not set
+# BR2_GCC_VERSION_3_3_6 is not set
+# BR2_GCC_VERSION_3_4_2 is not set
+# BR2_GCC_VERSION_3_4_3 is not set
+# BR2_GCC_VERSION_3_4_4 is not set
+# BR2_GCC_VERSION_3_4_5 is not set
+# BR2_GCC_VERSION_3_4_6 is not set
+# BR2_GCC_VERSION_4_0_0 is not set
+# BR2_GCC_VERSION_4_0_1 is not set
+# BR2_GCC_VERSION_4_0_2 is not set
+# BR2_GCC_VERSION_4_0_3 is not set
+# BR2_GCC_VERSION_4_1_0 is not set
+BR2_GCC_VERSION_4_1_1=y
+BR2_GCC_USE_SJLJ_EXCEPTIONS="--enable-sjlj-exceptions"
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+# BR2_INSTALL_LIBSTDCPP is not set
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/ChangeLog b/misc/buildroot/ChangeLog
new file mode 100644
index 000000000..9c22edf03
--- /dev/null
+++ b/misc/buildroot/ChangeLog
@@ -0,0 +1,119 @@
+buildroot-0.1.0 2007-03-09 <gnutt@nuttx.org>
+
+ Support for arm-elf toolchain
+
+buildroot-0.1.1 (revision number not used)
+
+buildroot-0.1.2 2008-11-06 <gnutt@nuttx.org>
+
+ * Add support for m68k-elf and m68hc11 toolchain
+ * Add patch to build older binutils with newer Texinfo version
+ * Add support for SH-1 toolchain
+
+buildroot-0.1.3 2009-02-28 <gnutt@nuttx.org>
+
+ * Add support for H8/300 toolchain
+ * Add support for GCC 4.2.4 and binutils 2.19
+ * Various fixes for newer Linux environments
+ * New ARM configuration using GCC 4.2.4 and binutils 2.19
+ * Add Renesas R8C/M16C/M32C configuration using GCC 4.2.4 and binutils 2.19
+
+buildroot-0.1.4 2009-04-19 <gnutt@nuttx.org>
+
+ * Add support for a blackfin toolchain using GCC 4.2.4 and binutils 2.19
+ * GCC 4.2.4 no longer attempts to build libstdc++. Now we can build g++!
+ * The ARM GCC-4.2.4 configuration was changed so that it now builds g++.
+ * Removed building of initial and final GCC. that is not necessary because
+ we do not build a libc. Now it builds almost twice as fast.
+ * Removed logic to build the target GCC. That is never used.
+
+buildroot-0.1.5 2009-04-25 <gnutt@nuttx.org>
+
+ * Replaced config/arm-defconfig-4.2.4 with config/arm920t-defconfig-4.2.4
+ and config/arm926t-defconfig-4.2.4 because of differences in the
+ way that soft floating point is handled between these two
+ architectures.
+ * Add support for gcc-4.3.3 and the ARM Cortex-M3 processor (thumb2)
+ * Add support for binutils 2.19.1
+
+buildroot-0.1.6 2009-05-19 <gnutt@nuttx.org>
+
+ * Added config/arm7tdmi-defconfig-4.2.4
+ * Added config/arm920t-defconfig-4.3.3
+ * Correct error in arm-defconfig gcc-3.4.6 build. The gcc-3.4.6 configuration
+ does not not take --with-abi
+ * Correct error in gcc-3.4.6/gcc/collect.c. Calls open with O_CREAT but
+ does not specify mode. Newer host compilers can error out on this.
+
+buildroot-0.1.7 2009-06-26 <gnutt@nuttx.org>
+
+ * configs/avr-defconfig-4.3.3: Added support for AVR to support a NuttX
+ port of the ATmega128.
+ * toolchain/nxflat: Added logic to build NuttX NXFLAT binding support tools
+ * toolchain/genromfs: Added support for the genromfs tool
+
+buildroot-1.8 2009-12-21 <gnutt@nuttx.org>
+
+ * configs/cortexm3-defconfig-4.3.3: Added support for NuttX NXFLAT
+ tools.
+ * configs/arm7tdmi-defconfig-4.3.3: Update to arm7tdmi-defconfig-4.2.4.
+ Also builds NuttX NXFLAT tools.
+ * configs/m68hc12-defconfig-4.3.3: Update to m68ch11-defconfig.
+ * configs/m68hc12-defconfig-3.4.6: There are problems building GCC
+ 4.3.3 for the hc12.
+ * configs/m32c-defconfig-4.2.4: Added genromfs
+ * configs/m32c-defconfig-4.3.3: Update to m32c-defconfig-4.2.4
+
+buildroot-1.9 2011-02-10 <gnutt@nuttx.org>
+
+ * configs/arm926t-defconfig-4.3.3: update arm926t-defconfig-4.2.4
+ * configs/arm926t-defconfig-nxflat: NXFLAT-only configuration for
+ arm926
+ * toolchain/gdb/gdb.mk - Remove ncurses dependency from gdb_target target.
+ * toolchain/gdb/gdb.mk - Added --disable-werror to GDB configuration line.
+ GDB 6.8 won't build because the tarbal was released with -Werror enabled and
+ the build stops on the first warning.
+ * Add support for Freescale m9s12x using binutils 2.18 and gcc 3.3.6 and
+ patches available from http://www.msextra.com/tools courtesy of James
+ Cortina. Add configs/m9x12x-defconfig-3.3.6.
+
+buildroot-1.10 2011-05-06 <gnutt@nuttx.org>
+
+ * Add patch submitted by Dimiter Georgiev to work around problems in building
+ GDB 6.8 with versions of Cygwin > 1.7.
+ * configs/i486-defconfig-4.3.3 - Builds an i486 cross development toolchain
+ using gcc 4.3.3. Why would you want such a thing? On Linux, of course,
+ such a thing is not needed because you can use the installed GCC to build
+ i486 ELF binaries. But that will not work under Cygwin! The Cygwin
+ toolchain (and probably MinGW), build DOS MZ format executables (i.e.,
+ .exe files). That is probably not usable for most NuttX targets.
+ Instead, you should use this i486-elf-gcc to generate true ELF binaries
+ under Cygwin.
+ * Makefile - Alter copy arguments to avoid permissions problems when
+ copying NuttX header files.
+ * toolchain/nxflat/nxflat.mk and Makefile - Fix include paths.
+ * toolchain/gcc/3.3.6 - Added a patch to fixed compilation error on Ubuntu
+ 9.10.
+ * toolchain/nxflat/Makefile - Correct static library link order.
+ * configs/arm920t-defconfig-4.3.3 - Enable support for NXFLAT tools.
+ * toolchain/binutils/2.21 and toolchain/gcc/4.5.2 - Add support for GCC
+ 4.5.2 with binutils 2.21.
+ * configs/arm920t-eabi-defconfig-4.5.2 - Add a configuration to build a
+ GCC 4.5.2 EABI ARM toolchain for the ARM920t.
+
+buildroot-1.11 2011-xx-xx <gnutt@nuttx.org>
+
+ * configs/avr-defconfig-4.3.3 - Added --enable-long-long as a GCC
+ option.
+ * configs/avr-defconfig-4.5.2 - New configuration.
+ * Config.in and almost all configurations in configs/ - Changed the
+ default nuttx path to $(TOPDIR)/../../nuttx
+ * Misc files. Patch provided by Gerd v. Egidy that solves the following
+ problems
+ - binutils 2.21 is not available on the gnu servers anymore, they replaced
+ it with 2.21.1
+ - there is some assembler error when compiling gcc for arm, gcc bugzilla
+ 43999
+ - you can't build nuttx for cortex m3/m4 because of a missing instruction
+ in ethe assembler, binutils bugzilla 12296
+
diff --git a/misc/buildroot/Config.in b/misc/buildroot/Config.in
new file mode 100644
index 000000000..d5c5fbfe7
--- /dev/null
+++ b/misc/buildroot/Config.in
@@ -0,0 +1,371 @@
+#
+
+mainmenu "Buildroot2 Configuration"
+
+config BR2_HAVE_DOT_CONFIG
+ bool
+ default y
+
+choice
+ prompt "Target Architecture"
+ default BR2_i386
+ help
+ Select the target architecture family to build for.
+
+config BR2_alpha
+ bool "alpha"
+config BR2_arm
+ bool "arm"
+config BR2_armeb
+ bool "armeb"
+config BR2_avr
+ bool "avr"
+config BR2_avr32
+ bool "avr32"
+config BR2_bfin
+ bool "blackfin"
+config BR2_cris
+ bool "cris"
+config BR2_i386
+ bool "i386"
+config BR2_m32c
+ bool "r8c/m16c/m32c"
+config BR2_m68k
+ bool "m68k"
+config BR2_m68hc11
+ bool "m68hc11"
+config BR2_m68hc12
+ bool "m68hc12"
+config BR2_m9s12x
+ bool "m9s12x"
+config BR2_mips
+ bool "mips"
+config BR2_mipsel
+ bool "mipsel"
+config BR2_nios2
+ bool "nios2"
+config BR2_powerpc
+ bool "powerpc"
+config BR2_sh
+ bool "superh"
+config BR2_sh64
+ bool "superh64"
+config BR2_h8300
+ bool "H8/300"
+config BR2_sparc
+ bool "sparc"
+config BR2_x86_64
+ bool "x86_64"
+endchoice
+
+#
+# Keep the variants separate, there's no need to clutter everything else.
+# sh is fairly "special" in this regard, as virtually everyone else has
+# things kept down to a _sensible_ number of target variants. No such
+# luck for sh..
+#
+choice
+ prompt "Target Architecture Variant"
+ depends BR2_arm || BR2_armeb
+ default BR2_generic_arm
+ help
+ Specific CPU variant to use
+
+config BR2_generic_arm
+ bool "generic ARM"
+config BR2_arm610
+ bool "ARM610"
+config BR2_arm7tdmi
+ bool "ARM7TDMI"
+config BR2_arm710
+ bool "ARM710"
+config BR2_arm720t
+ bool "ARM720T"
+config BR2_arm740t
+ bool "ARM740T"
+config BR2_arm920t
+ bool "ARM920T"
+config BR2_arm922t
+ bool "ARM922T"
+config BR2_arm926t
+ bool "ARM926T"
+config BR2_arm1136jf_s
+ bool "ARM1136JF-S"
+config BR2_cortex_m3
+ bool "Cortex-M3"
+config BR2_sa110
+ bool "SA110"
+config BR2_sa1100
+ bool "SA1100"
+config BR2_xscale
+ bool "X-Scale"
+config BR2_iwmmxt
+ bool "iwmmxt"
+endchoice
+
+choice
+ prompt "Target ABI"
+ depends BR2_arm || BR2_armeb
+ default BR2_ARM_OABI
+ help
+ Application Binary Interface to use
+
+config BR2_ARM_OABI
+ bool "OABI"
+config BR2_ARM_EABI
+ bool "EABI"
+endchoice
+
+choice
+ prompt "Target Architecture Variant"
+ depends BR2_avr32
+config BR2_ap7000
+ bool "AP7000"
+config BR2_ap7010
+ bool "AP7010"
+config BR2_ap7020
+ bool "AP7020"
+endchoice
+
+choice
+ prompt "Target Architecture Variant"
+ depends BR2_sh
+ default BR2_sh4
+ help
+ Specific CPU variant to use
+
+config BR2_sh1
+ bool "sh1"
+config BR2_sh2a_nofpueb
+ bool "sh2a_nofpueb"
+config BR2_sh2eb
+ bool "sh2eb"
+config BR2_sh3
+ bool "sh3"
+config BR2_sh3eb
+ bool "sh3eb"
+config BR2_sh4
+ bool "sh4"
+config BR2_sh4eb
+ bool "sh4eb"
+endchoice
+
+#
+# gcc builds libstdc++ differently depending on the
+# host tuplet given to it, so let people choose
+#
+choice
+ prompt "Target Architecture Variant"
+ depends BR2_i386
+ default BR2_x86_i686
+ help
+ Specific CPU variant to use
+
+config BR2_x86_i386
+ bool "i386"
+config BR2_x86_i486
+ bool "i486"
+config BR2_x86_i586
+ bool "i586"
+config BR2_x86_i686
+ bool "i686"
+endchoice
+
+config BR2_ARCH
+ string
+ default "alpha" if BR2_alpha
+ default "arm" if BR2_arm
+ default "armeb" if BR2_armeb
+ default "avr" if BR2_avr
+ default "avr32" if BR2_avr32
+ default "bfin" if BR2_bfin
+ default "cris" if BR2_cris
+ default "i386" if BR2_x86_i386
+ default "i486" if BR2_x86_i486
+ default "i586" if BR2_x86_i586
+ default "i686" if BR2_x86_i686
+ default "m32c" if BR2_m32c
+ default "m68k" if BR2_m68k
+ default "m68hc11" if BR2_m68hc11
+ default "m68hc12" if BR2_m68hc12
+ default "m9s12x" if BR2_m9s12x
+ default "mips" if BR2_mips
+ default "mipsel" if BR2_mipsel
+ default "nios2" if BR2_nios2
+ default "powerpc" if BR2_powerpc
+ default "sh" if BR2_sh1
+ default "sh2a_nofpueb" if BR2_sh2a_nofpueb
+ default "sh2eb" if BR2_sh2eb
+ default "sh3" if BR2_sh3
+ default "sh3eb" if BR2_sh3eb
+ default "sh4" if BR2_sh4
+ default "sh4eb" if BR2_sh4eb
+ default "sh64" if BR2_sh64
+ default "h8300" if BR2_h8300
+ default "sparc" if BR2_sparc
+
+config BR2_GCC_TARGET_TUNE
+ string
+ default i386 if BR2_x86_i386
+ default i486 if BR2_x86_i486
+ default i586 if BR2_x86_i586
+ default i686 if BR2_x86_i686
+ default arm610 if BR2_arm610
+ default arm7tdmi if BR2_arm7tdmi || BR2_arm720t || BR2_arm740t
+ default arm920t if BR2_arm920t
+ default arm922t if BR2_arm922t
+ default arm9tdmi if BR2_arm926t
+ default arm1136jf-s if BR2_arm1136jf_s
+ default cortex-m3 if BR2_cortex_m3
+ default strongarm110 if BR2_sa110
+ default strongarm1100 if BR2_sa1100
+ default xscale if BR2_xscale
+ default iwmmxt if BR2_iwmmxt
+
+config BR2_GCC_TARGET_ARCH
+ string
+ default i386 if BR2_x86_i386
+ default i486 if BR2_x86_i486
+ default i586 if BR2_x86_i586
+ default i686 if BR2_x86_i686
+ default armv3 if BR2_arm610 || BR2_arm710
+ default armv4 if BR2_sa110 || BR2_sa1100
+ default armv4t if BR2_arm7tdmi
+ default armv4t if BR2_arm720t || BR2_arm920t || BR2_arm922t
+ default armv5te if BR2_arm926t || BR2_arm10t || BR2_xscale
+ default armv6j if BR2_arm1136jf_s
+ default armv7-m if BR2_cortex_m3
+ default iwmmxt if BR2_iwmmxt
+
+config BR2_GCC_TARGET_ABI
+ string
+ default apcs-gnu if BR2_ARM_OABI
+ default aapcs-linux if BR2_ARM_EABI
+
+config BR2_ENDIAN
+ string
+ default "LITTLE" if BR2_arm || BR2_avr || BR2_bfin || BR2_cris || BR2_i386 || BR2_m32c || \
+ BR2_mipsel || BR2_sh3 || BR2_sh4 || BR2_x86_64 || \
+ BR2_nios2 || BR2_sh64 || BR2_h8300
+ default "BIG" if BR2_alpha || BR2_armeb || BR2_avr32 || BR2_m68k || \
+ BR2_m68hc11 || BR2_m68hc12 || BR2_m9s12x || BR2_mips || \
+ BR2_powerpc || BR2_sh1 || BR2_sh2a_nofpueb || BR2_sh2eb || \
+ BR2_sh3eb || BR2_sh4eb || BR2_sparc
+
+menu "Build options"
+
+config BR2_WGET
+ string "Wget command"
+ default "wget --passive-ftp -nd"
+
+config BR2_SVN
+ string "Subversion (svn) checkout command"
+ default "svn co"
+
+config BR2_ZCAT
+ string "zcat command"
+ default "zcat"
+ help
+ Command to be used to extract a gzip'ed file to stdout.
+ zcat is identical to gunzip -c except that the former may
+ not be available on your system.
+ Default is "zcat"
+ Other possible values include "gunzip -c" or "gzip -d -c".
+
+config BR2_BZCAT
+ string "bzcat command"
+ default "bzcat"
+ help
+ Command to be used to extract a bzip2'ed file to stdout.
+ bzcat is identical to bunzip2 -c except that the former may
+ not be available on your system.
+ Default is "bzcat"
+ Other possible values include "bunzip2 -c" or "bzip2 -d -c".
+
+config BR2_TAR_OPTIONS
+ string "Tar options"
+ default ""
+ help
+ Options to pass to tar when extracting the sources.
+ E.g. " -v --exclude='*.svn*'" to exclude all .svn internal files
+ and to be verbose.
+
+config BR2_DL_DIR
+ string "Download dir"
+ default "$(BASE_DIR)/dl"
+ help
+ Directory to store all the source files that we need to fetch.
+
+config BR2_STAGING_DIR
+ string "Toolchain and header file location?"
+ default "$(BUILD_DIR)/staging_dir"
+ help
+ This is the location where the toolchain will be installed. The
+ toolchain will not work if it is moved from this location.
+ Therefore, if you wish to package up a uClibc toolchain, it is
+ important that is is set to the final location where the toolchain
+ will be used.
+
+ Most people will leave this set to the default value of
+ "$(BUILD_DIR)/staging_dir".
+
+config BR2_NUTTX_DIR
+ string "Path to the NuttX root directory"
+ default "$(TOPDIR)/../../nuttx"
+ help
+ This is the location where the NuttX source tree is located.
+
+config BR2_TOPDIR_PREFIX
+ string "Custom build dir prefix"
+ default ""
+ help
+ Add a custom string to the beginning of the build directories.
+
+ build_ARCH -> [PREFIX]_build_ARCH
+ toolchain_build_ARCH -> [PREFIX]_toolchain_build_ARCH
+
+config BR2_TOPDIR_SUFFIX
+ string "Custom build dir suffix"
+ default ""
+ help
+ Add a custom string to the end of the build directories.
+
+ build_ARCH -> build_ARCH_[SUFFIX]
+ toolchain_build_ARCH -> toolchain_build_ARCH_[SUFFIX]
+
+config BR2_GNU_BUILD_SUFFIX
+ string "GNU build hostname suffix"
+ default "pc-elf"
+ help
+ The string used to pass to configure scripts via the
+ --build= option. Just specify the suffix here, the leading
+ arch will be filled in automatically.
+
+config BR2_GNU_TARGET_SUFFIX
+ string "GNU target suffix"
+ default "elf"
+ help
+ The string used to pass to configure scripts via the
+ --target= option. Just specify the suffix here, the leading
+ arch will be filled in automatically.
+
+ Most users will want to stick with the default setting, though
+ other users (most notably ARM EABI) like to add on to this in
+ order to stay in line with gcc conventions.
+
+config BR2_PREFER_IMA
+ bool "prefer IMA compiles"
+ default n
+ help
+ Where possible, compile package with Inter Module Analysis.
+ This potentially uses alot of system resources on your compile
+ host with the benefit of creating smaller binaries for the target.
+
+ If unsure, say No.
+
+ WARNING: This is highly experimental at the moment.
+
+
+endmenu
+
+source "toolchain/Config.in"
diff --git a/misc/buildroot/Makefile b/misc/buildroot/Makefile
new file mode 100644
index 000000000..166b13c04
--- /dev/null
+++ b/misc/buildroot/Makefile
@@ -0,0 +1,224 @@
+# Makefile for buildroot2
+#
+# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+#--------------------------------------------------------------
+# Just run 'make menuconfig', configure stuff, then run 'make'.
+# You shouldn't need to mess with anything beyond this point...
+#--------------------------------------------------------------
+TOPDIR=./
+CONFIG_CONFIG_IN = Config.in
+CONFIG_DEFCONFIG = .defconfig
+CONFIG = package/config
+
+noconfig_targets := menuconfig config oldconfig randconfig \
+ defconfig allyesconfig allnoconfig release tags \
+
+# $(shell find . -name *_defconfig |sed 's/.*\///')
+
+# Pull in the user's configuration file
+ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),)
+-include $(TOPDIR).config
+endif
+
+ifeq ($(strip $(BR2_HAVE_DOT_CONFIG)),y)
+
+# cc-option
+# Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586)
+# sets -march=winchip-c6 if supported else falls back to -march=i586
+# without checking the latter.
+cc-option = $(shell if $(TARGET_CC) $(TARGET_CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
+ > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
+
+#############################################################
+#
+# The list of stuff to build for the target toolchain
+# along with the packages to build for the target.
+#
+##############################################################
+TARGETS:=binutils
+include toolchain/Makefile.in
+include package/Makefile.in
+
+#############################################################
+#
+# You should probably leave this stuff alone unless you know
+# what you are doing.
+#
+#############################################################
+
+all: world
+
+# In this section, we need .config
+include .config.cmd
+include package/gnuconfig/gnuconfig.mk
+include toolchain/*/*.mk
+
+TARGETS_CLEAN:=$(patsubst %,%-clean,$(TARGETS))
+TARGETS_SOURCE:=$(patsubst %,%-source,$(TARGETS))
+TARGETS_DIRCLEAN:=$(patsubst %,%-dirclean,$(TARGETS))
+
+world: $(DL_DIR) $(BUILD_DIR) $(STAGING_DIR) $(TARGET_DIR) nuttx_setup $(NUTTX_HDRS) $(TARGETS)
+dirs: $(DL_DIR) $(BUILD_DIR) $(STAGING_DIR) $(NUTTX_DIR)
+
+.PHONY: all world dirs clean dirclean distclean source $(TARGETS) \
+ $(TARGETS_CLEAN) $(TARGETS_DIRCLEAN) $(TARGETS_SOURCE) \
+ $(DL_DIR) $(BUILD_DIR) $(TOOL_BUILD_DIR) $(STAGING_DIR)
+
+#############################################################
+#
+# staging and target directories do NOT list these as
+# dependencies anywhere else
+#
+#############################################################
+$(DL_DIR) $(BUILD_DIR) $(TOOL_BUILD_DIR):
+ @mkdir -p $@
+
+$(STAGING_DIR):
+ @mkdir -p $(STAGING_DIR)/lib
+ @mkdir -p $(STAGING_DIR)/include
+ @mkdir -p $(STAGING_DIR)/usr
+ @mkdir -p $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)
+ @ln -snf ../lib $(STAGING_DIR)/usr/lib
+ @ln -snf ../lib $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/lib
+
+$(TARGET_DIR):
+ mkdir -p $(TARGET_DIR)
+ if [ -d "$(TARGET_SKELETON)" ] ; then \
+ cp -fa $(TARGET_SKELETON)/* $(TARGET_DIR)/; \
+ fi;
+ touch $(STAGING_DIR)/.fakeroot.00000
+ -find $(TARGET_DIR) -type d -name CVS | xargs rm -rf
+ -find $(TARGET_DIR) -type d -name .svn | xargs rm -rf
+
+$(NUTTX_DIR):
+ @if [ ! -d $(NUTTX_DIR) ]; then \
+ echo "NuttX directory $(NUTTX_DIR) does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -e $(NUTTX_DIR)/.config ]; then \
+ echo "NuttX directory $(NUTTX_DIR) has not been configured" ; \
+ exit 1 ; \
+ fi
+
+$(NUTTX_DIR)/include/arch: $(NUTTX_DIR)
+ $(MAKE) -C $(NUTTX_DIR) include/arch
+
+$(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/include : $(STAGING_DIR) $(NUTTX_DIR)/include/arch
+ @mkdir -p $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/include || \
+ { echo "Failed to create $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/include" ; exit 1 ; }
+ @cp -aLf $(NUTTX_DIR)/include/* $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/include/. || \
+ { echo "Failed to copy Nuttx header files" ; exit 1 ; }
+
+$(TOOL_BUILD_DIR):
+ mkdir -p $(TOOL_BUILD_DIR)
+
+nuttx_setup: $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/include
+
+source: $(TARGETS_SOURCE)
+
+#############################################################
+#
+# Cleanup and misc junk
+#
+#############################################################
+clean: $(TARGETS_CLEAN)
+ rm -rf $(STAGING_DIR) $(TARGET_DIR)
+
+dirclean: $(TARGETS_DIRCLEAN)
+ rm -rf $(STAGING_DIR) $(TARGET_DIR)
+
+distclean:
+ifeq ($(DL_DIR),$(BASE_DIR)/dl)
+ rm -rf $(DL_DIR)
+endif
+ rm -rf $(BUILD_DIR)
+ $(MAKE) -C $(CONFIG) clean
+
+sourceball:
+ rm -rf $(BUILD_DIR)
+ set -e; \
+ cd ..; \
+ rm -f buildroot.tar.bz2; \
+ tar -cvf buildroot.tar buildroot; \
+ bzip2 -9 buildroot.tar; \
+
+
+else # ifeq ($(strip $(BR2_HAVE_DOT_CONFIG)),y)
+
+all: menuconfig
+
+# configuration
+# ---------------------------------------------------------------------------
+
+$(CONFIG)/conf:
+ $(MAKE) -C $(CONFIG) conf
+ -@if [ ! -f .config ] ; then \
+ cp $(CONFIG_DEFCONFIG) .config; \
+ fi
+$(CONFIG)/mconf:
+ $(MAKE) -C $(CONFIG) ncurses conf mconf
+ -@if [ ! -f .config ] ; then \
+ cp $(CONFIG_DEFCONFIG) .config; \
+ fi
+
+menuconfig: $(CONFIG)/mconf
+ @$(CONFIG)/mconf $(CONFIG_CONFIG_IN)
+
+config: $(CONFIG)/conf
+ @$(CONFIG)/conf $(CONFIG_CONFIG_IN)
+
+oldconfig: $(CONFIG)/conf
+ @$(CONFIG)/conf -o $(CONFIG_CONFIG_IN)
+
+randconfig: $(CONFIG)/conf
+ @$(CONFIG)/conf -r $(CONFIG_CONFIG_IN)
+
+allyesconfig: $(CONFIG)/conf
+ #@$(CONFIG)/conf -y $(CONFIG_CONFIG_IN)
+ #sed -i -e "s/^CONFIG_DEBUG.*/# CONFIG_DEBUG is not set/" .config
+ @$(CONFIG)/conf -o $(CONFIG_CONFIG_IN)
+
+allnoconfig: $(CONFIG)/conf
+ @$(CONFIG)/conf -n $(CONFIG_CONFIG_IN)
+
+defconfig: $(CONFIG)/conf
+ @$(CONFIG)/conf -d $(CONFIG_CONFIG_IN)
+
+%_defconfig: $(CONFIG)/conf
+ cp $(shell find . -name $@) .config
+ @$(CONFIG)/conf -o $(CONFIG_CONFIG_IN)
+
+#############################################################
+#
+# Cleanup and misc junk
+#
+#############################################################
+clean:
+ rm -f .config .config.old .config.cmd .tmpconfig.h
+ - $(MAKE) -C $(CONFIG) clean
+
+distclean: clean
+ rm -rf sources/*
+
+endif # ifeq ($(strip $(BR2_HAVE_DOT_CONFIG)),y)
+
+.PHONY: dummy subdirs release distclean clean config oldconfig \
+ menuconfig tags check test depend defconfig
+
+
diff --git a/misc/buildroot/ReleaseNotes b/misc/buildroot/ReleaseNotes
new file mode 100644
index 000000000..889b97073
--- /dev/null
+++ b/misc/buildroot/ReleaseNotes
@@ -0,0 +1,89 @@
+ReleaseNotes v0.1.10:
+^^^^^^^^^^^^^^^^^^^^^
+
+This is a highly hacked up version of the buildroot (see
+http://buildroot.uclibc.org/). It has been hacked so that it
+can be used to build the following NuttX-compatible toolchains:
+
+ o arm-elf toolchain needed for use with the TI C5471 (ARM7TDMI),
+ NXP LPC214x (ARM7TMDI), STMicro STR71x (ARM7TDMI), Freescale
+ i.MX1 (ARM920T), and TI DM320 (ARM926EJ-S) provided with the
+ NuttX releases.
+
+ NXFLAT toolchain for use with the ARM7 and ARM9.
+
+ o arm-elf ARM Cortex-M3 (thumb2) toolchain needed for use with
+ the Luminary LM3Sxxx, NXP 17xxxx, Atmel SAM3u, and STMicor
+ STM32 ports provided with the NuttX releases.
+
+ NXFLAT toolchain for use with the ARM Cortex-M3.
+
+ o avr-elf toolchain needed for use with the ATmega128 ports
+ provided with the NuttX releases.
+
+ o H8/300 toolchain (not currently used in any NuttX
+ configuration).
+
+ o i486-elf toochain. Why would you want such a thing? On Linux, of
+ course, such a thing is not needed because you can use the installed GCC
+ to build i486 ELF binaries. But that will not work under Cygwin! The
+ Cygwin toolchain (and probably MinGW), build DOS MZ format executables
+ (i.e., .exe files). That is probably not usable for most NuttX targets.
+ Instead, you should use this i486-elf-gcc to generate true ELF binaries
+ under Cygwin.
+
+ o bfin-elf toolchain not currently used in any NuttX
+ configuration).
+
+ o m68k-elf toolchain (not currently used in any NuttX
+ configuration).
+
+ o m68hc11-elf toolchain (not currently used in any NuttX
+ configuration).
+
+ o m68hc12-elf toolchain. (NOT RECOMMENDED for hcs12;
+ Use m9s12x-elf toolchain)
+
+ o m9s12x-elf toolchain Supports Freescale m9s12x using
+ binutils 2.18 and gcc 3.3.6 and patches available from
+ http://www.msextra.com/tools courtesy of James Cortina.
+
+ o m32c-elf toolchain needed for the Renesas M16C NuttX port.
+
+ o sh-elf toolchain needed for the SH-1 NuttX port.
+
+Supported tool versions include:
+
+ o gcc-3.3.6 + binuils-2.18 (for m9s12x).
+ o gcc-3.4.6 + binutils-2.17
+ o gcc-4.2.4 + binutils-2.19
+ o gcc-4.3.3 + binutils-2.19.1
+ o gcc-4.5.2 + binutils-2.21
+
+See the ChangeLog of features/architectures added in v0.1.9.
+
+Installation instructions:
+
+ - You must have already configured Nuttx in <some-dir>/nuttx
+ - download the buildroot package into <some-dir>
+ - unpack -cd <some-dir>/buildroot
+ - cp configs/arm-defconfig .config
+ - make oldconfig
+ - make
+
+See configs/README.txt for other configurations and for more detailed
+instructions. If your NuttX installation resides at a different location
+then:
+
+ - make menuconfig
+
+And set the "Path to the NuttX root directory" appropriately.
+
+NXFLAT Toolchain Build
+
+You can select to build the NXFLAT toolchain with GCC by selecting
+the NXFLAT toolchin during the configuration process(you can also
+select omit building GCC with and only build the NXFLAT toolchain
+for use with your own GCC toolchain.
+
+NFFLAT is only available for ARM and Cortex-M3 architectures.
diff --git a/misc/buildroot/configs/README.txt b/misc/buildroot/configs/README.txt
new file mode 100644
index 000000000..f37bcf178
--- /dev/null
+++ b/misc/buildroot/configs/README.txt
@@ -0,0 +1,340 @@
+README
+^^^^^^
+
+CONTENTS
+^^^^^^^^
+
+ o AVAILABLE CONFIGURATIONS
+ o GENERAL BUILD STEPS
+ o FAQ
+ o Cygwin GCC BUILD NOTES
+ o Building GDB Under Cygwin
+
+AVAILABLE CONFIGURATIONS
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+arm-defconfig
+ Builds an ARM toolchain using gcc 3.4.6
+
+arm7tdmi-defconfig-4.2.4
+arm920t-defconfig-4.2.4
+arm926t-defconfig-4.2.4
+ Builds an ARM toolchain using gcc 4.2.4. This configuration
+ builds both gcc and g++. There are three versions: one for
+ arm7tdmi (armv4t), arm920t (armv4t) and arm926t (arv5t) because
+ of differences in the way that soft floating is handled in between
+ the armv4t and arm5t architectures.
+
+ NOTE: The newer versions of GCC generate new sections and can
+ cause some problems for NuttX configurations developed under older
+ toolchains. In particular, arm-elf-objcopy may fail with strange
+ errors. If this occurs, try adding the following arguments to the
+ arm-elf-objcopy command "-R .note -R .note.gnu.build-id -R .comment"
+
+ This logic is several configuration Make.defs files:
+
+ HOSTOS = ${shell uname -o}
+
+ ARCHCCVERSION = ${shell $(CC) -v 2>&1 | sed -n '/^gcc version/p' | sed -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q'}
+ ARCHCCMAJOR = ${shell echo $(ARCHCCVERSION) | cut -d'.' -f1}
+
+ ifeq ($(ARCHCCMAJOR),4)
+ ifneq ($(HOSTOS),Cygwin)
+ OBJCOPYARGS = -R .note -R .note.gnu.build-id -R .comment
+ endif
+ endif
+
+ This change probably applies to other architectures as well (?)
+
+arm920t-defconfig-4.3.3
+arm7tdmi-defconfig-4.3.3
+ Builds an ARM toolchain using gcc 4.3.3. These configurations
+ builds both gcc and g++ for the arm7tdmi (armv4t) or the arm920t
+ (armv4t). These are udates to *-defconfig-4.2.4 (see notes above).
+
+avr-defconfig-4.3.3
+avr-defconfig-5.4.2
+ Builds an AVR toolchain using gcc 4.3.3 or 4.5.2. This configuration
+ builds both gcc and g++ for the AVR (armv4t). This toolchain
+ is intended to support the NuttX ATmega128 port.
+
+cortexm3-defconfig-4.3.3
+ Builds an OABI ARM toolchain for the Cortex-M3 using gcc 4.3.3.
+ This configuration builds gcc, g++ and the NXFLAT toolchain.
+
+cortexm3-defconfig-nxflat
+arm926t-defconfig-nxflat
+ This configuration build an NXFLAT toolchain (only) for
+ use with the Cortex-M3 or ARM9 (untested on ARM9 as of this
+ writing).
+
+cortexm3-eabi-defconfig-4.5.2
+ Builds an EABI ARM toolchain for the Cortex-M3 using gcc 4.5.2.
+ This configuration builds gcc, g++ and the NXFLAT toolchain.
+
+bfin-defconfig-4.2.4
+ Builds an Blackfin toolchain using gcc 4.2.4
+
+h8300_config
+ Builds an H8/300 toolchain using gcc 3.4.6
+
+i486-defconfig-4.3.3
+ Builds an i486 cross development toolchain using gcc 4.3.3. Why would
+ you want such a thing? On Linux, of course, such a thing is not needed
+ because you can use the installed GCC to build i486 ELF binaries. But
+ that will not work under Cygwin! The Cygwin toolchain (and probably
+ MinGW), build DOS MZ format executables (i.e., .exe files). That is
+ probably not usable for most NuttX targets. Instead, you should use this
+ i486-elf-gcc to generate true ELF binaries under Cygwin.
+
+m32c_defconfig_4.2.4
+m32c_defconfig_4.3.3
+ Build a toolchain for use with the M16C port using eith gcc 4.2.4 or 4.3.3
+
+m68hc11-config
+m68hc12-config-3.4.6
+ Builds an hc11/hc12 toolchain using gcc 3.4.6 . NOT RECOMMENDED for hcs12;
+ Use m9s12x_config_3.3.6
+
+m68hc12-config-4.3.3
+ Builds an hc11/hc12 toolchain using gcc 4.3.3.NOT RECOMMENDED for hcs12;
+ Use m9s12x_config_3.3.6
+
+ This configuration fails to build with the following error:
+
+ make[3]: Entering directory `blabla/buildroot/toolchain_build_m68hc12/gcc-4.3.3-build/m68hc12-elf/libgcc'
+ ...
+ blabla/buildroot/toolchain_build_m68hc12/gcc-4.3.3/libgcc/../gcc/libgcc2.c:566: internal compiler error: in init_move_cost, at regclass.c:323
+ Please submit a full bug report,
+ with preprocessed source if appropriate.
+ See <http://gcc.gnu.org/bugs.html> for instructions.
+ make[3]: *** [_muldi3.o] Error 1
+ make[3]: Leaving directory `blabla/buildroot/toolchain_build_m68hc12/gcc-4.3.3-build/m68hc12-elf/libgcc'
+
+ Use m68hc12-config-3.4.6
+
+m9s12x_config_3.3.6
+ Builds a hcs12 toolchain using gcc 3.3.6 and extensive m9x12x-specific patches.
+
+m68k-config
+ Builds an M68K toolchain using gcc 3.4.6
+
+sh-defconfig
+ Builds an SH-1/2 toolchain using gcc 3.4.6
+
+GENERAL BUILD STEPS
+^^^^^^^^^^^^^^^^^^^
+
+1. Configure your host machine. You host PC should have a relatively complete
+ C development environment. I don't have a full list of the package requirements.
+ The later tool chains also require GMP and MPRF development packages or the
+ build will fail with errors like:
+
+ "configure: error: Building GCC requires GMP 4.1+ and MPFR 2.3.0+. ...
+ Copies of these libraries' source code can be found at their respective
+ hosting sites as well as at ftp://gcc.gnu.org/pub/gcc/infrastructure/.
+ See also http://gcc.gnu.org/install/prerequisites.html for additional info.
+ If you obtained GMP and/or MPFR from a vendor distribution package, make
+ sure that you have installed both the libraries and the header files.
+ They may be located in separate packages."
+
+ Version 4.5.x and beyond also require the MPC package.
+
+ You should try your package manager for whatever Linux version you are using
+ first. The header files are normally included in versions of the packages that
+ have "-devel" in the package name.
+
+2. CD to the correct directory.
+
+ Change to the directory just above the NuttX installation. If <nuttx-dir> is
+ where NuttX is installed, then cd to <nuttx-dir>/..
+
+3. Get and Install the buildroot Module
+
+ a. Using a release tarball:
+
+ cd <nuttx-dir>/..
+ Download the appropriate buildroot package.
+ unpack the buildroot package
+ rename the directory to buildroot
+
+ b. Using SVN
+
+ Check out the misc/buildroot module. SVN checkout instructions:
+
+ svn co https://nuttx.svn.sourceforge.net/svnroot/nuttx nuttx/trunk/misc/buildroot
+
+ Move the buildroot Source Tree and create the archive directory
+
+ mv misc/buildroot .
+
+ Make the archive directory:
+
+ mkdir archive
+
+ The <nuttx-dir>/../buildroot is where the toolchain is built;
+ The <nuttx-dir>/../archive directory is where toolchain sources will be downloaded.
+
+4. Make sure that NuttX is configured
+
+ cd <nuttx-dir>/tools
+ ./configure.sh <nuttx-configuration>
+
+5. Configure and Make the buildroot
+
+ cd buildroot
+ cp configs/<config-file> .config
+ make oldconfig
+ make
+
+ This will download the large source packages for the toolchain and build the toolchain.
+ The resulting binaries will be under buildroot/build_<arch>. There will also be a
+ large build directory called something like toolchain_build_<arch>; this directory
+ can be removed once the build completes successfully.
+
+ Where <config-file> is one of the configuration files listed above and <arch> is an
+ archtecture name. Examples: build_m32c, build_arm_nofpu, etc.
+
+FAQ
+^^^
+
+Q: What is up with errors like this:
+
+ fatal error: ansidecl.h: No such file or directory
+
+A: This was reported on Fedora F14. The cause of the problem is that some host
+ binutils header files were moved from the binutils RPM to the binutils-dev
+ RPM. The fix is to install the binutils-dev RPM.
+
+Q: How do I build the NuttX toolchain under Cygwin?
+
+A: See below...
+
+Q: NuttX directory ../../nuttx does not exist
+
+A: The default path to the nuttx directory is $(TOPDIR)/../../nuttx where
+ TOPDIR holds the path to the buildroot directory. If you checkout the
+ entire SVN tree then that will be the correct location of the nuttx
+ directory.
+
+ If you see this error, it just means that nuttx is not in that expected,
+ default location. In that case, use 'make config' or 'make menuconfig'
+ to edit the configuration. Find the option to set the path to NuttX
+ and set it to the correct location for your build environment.
+
+Q: Some of my libraries like GMP and MPFR are in non-standard locations the
+ GCC build can't file them:
+
+ checking for correct version of mpfr.h... no
+ configure: error: Building GCC requires GMP 4.1+ and MPFR 2.3.0+.
+
+A: http://tech.groups.yahoo.com/group/nuttx/message/1160
+
+ "I think that you can specify the path to GMP and MPFR. I think that GCC
+ has some special configuration command line options to support this. I
+ can't remember exactly and I don't have an unpacked version of GCC at
+ hand.
+
+ "Try this: Go to the buildroot/toolchain_build_nofpu_arm/gcc-x.x directory
+ and type:
+
+ ./configure --help
+
+ "That should list all of the GCC configuration options. I bet you will see
+ (near the bottom) some options to set the path to these tools.
+
+ "What you will have to do then is to modify the script at:
+
+ buildroot/toolchain/gcc/gcc-nuttx-4.x.mk
+
+ "You will see that there are several places where $(GCC_DIR)/configure is
+ invoked. I think you would have to hard code those path options into those
+ configure commands."
+
+Cygwin GCC BUILD NOTES
+^^^^^^^^^^^^^^^^^^^^^^
+
+ o Cygwin normally creates a /home directory with your Windows user name. Unfortunately,
+ that could very likely include spaces. In that case, the Cygwin build will have
+ lots of problems. Here is how I worked around that:
+
+ - I created a /home/buildroot directory and copied buildroot to that location
+ (/home/build/buildroot/buildroot)
+ - I have the archives directory at /home/buildroot/archives
+ - And a symbolic link to the nuttx build directory at /home/buildroot/nuttx
+
+ With those workarounds, the buildroot will build. However, you will also need
+ to either edit the setenv.sh file to reference this new location, or else move
+ resulting build diectory.
+
+ o On Cygwin, the buildroot 'make' command will fail with an error like:
+
+ "...
+ build/genchecksum cc1-dummy > cc1-checksum.c
+ opening cc1-dummy: No such file or directory
+ ..."
+
+ This is caused because on Cygwin, host executables will be generated with the extension .exe
+ and, apparently, the make variable "exeext" is set incorrectly. A work around after the
+ above occurs is:
+
+ cd toolchain_build_<arch>/gcc-4.2.4-build/gcc # Go to the directory where error occurred
+ mv cc1-dummy.exe cc1-dummy # Rename the executable without .exe
+ rm cc1-checksum.c # Get rid of the bad generated file
+
+ Then resume the buildroot make:
+
+ cd - # Back to the buildroot make directory
+ make # Restart the build
+
+ If you build g++, you will see another similar error:
+
+ ...
+ build/genchecksum cc1plus-dummy > cc1plus-checksum.c
+ opening cc1plus-dummy: No such file or directory
+ ...
+
+ The fix is similar:
+
+ cd toolchain_build_<arch>/gcc-4.2.4-build/gcc # Go to the directory where error occurred
+ mv cc1plus-dummy.exe cc1plus-dummy # Rename the executable without .exe
+ rm cc1plus-checksum.c # Get rid of the bad generated file
+
+ Then resume the buildroot make:
+
+ cd - # Back to the buildroot make directory
+ make # Restart the build
+
+ o Once I had problems building the toolchain on Cygwin. In this case, I
+ would occasioinally get "Permission denied" errors will trying to configure
+ the toolchain. My hunch is that this error was caused because of failures
+ to remove some temporary files (like conftest.c). Perhaps there errors
+ occurred because some other application opened those files too??? Perhaps
+ a virus scanner.
+
+ Sometimes when this occurs, the build continues to execute. If that is
+ the case, it could end-up making a bad toolchain??? In this case, you need
+ to hit Control-C to stop the build. Normally, however, the "Permission
+ denied" error causes the configure script to stop. In either case, if you
+ just restart the make, the build will continue past the failure point.
+
+ This has happened to me only while doing other intensive activities in
+ windows during the toolchain build. I suspect if you leave your PC
+ mostly idle while the toolchain builds, this will not likely be a problem
+ for you.
+
+Building GDB Under Cygwin
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ This can be tricking, but it has been done. See this message sequence for
+ http://tech.groups.yahoo.com/group/nuttx/message/726 . Apparently there
+ are some incompatibilities with Cygwin 1.7 that require an additional
+ patch. See http://old.nabble.com/-RFA--windows-nat.c%3A-Cygwin%3A-Port-to-Cygwin-1.7-td27735619.html
+
+ A version of this patch for GDB-6.8 and Cywgin 1.7 (and above) is provided
+ in this directory (Thanks to Dimiter Georgiev). That file is called
+ gdb-1_8-cygwin-1_7.patch. This should be copied into the GDB 6.8 toolchain
+ directory if it is needed:
+
+ cp configs/gdb-1_8-cygwin-1_7.patch toolchain/gdb/6.8/.
+
diff --git a/misc/buildroot/configs/arm-defconfig b/misc/buildroot/configs/arm-defconfig
new file mode 100644
index 000000000..bcdab8c89
--- /dev/null
+++ b/misc/buildroot/configs/arm-defconfig
@@ -0,0 +1,112 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+BR2_arm=y
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+BR2_generic_arm=y
+# BR2_arm610 is not set
+# BR2_arm7tdmi is not set
+# BR2_arm710 is not set
+# BR2_arm720t is not set
+# BR2_arm740t is not set
+# BR2_arm920t is not set
+# BR2_arm922t is not set
+# BR2_arm926t is not set
+# BR2_arm1136jf_s is not set
+# BR2_cortex_m3 is not set
+# BR2_sa110 is not set
+# BR2_sa1100 is not set
+# BR2_xscale is not set
+# BR2_iwmmxt is not set
+BR2_ARM_OABI=y
+# BR2_ARM_EABI is not set
+BR2_ARCH="arm"
+BR2_GCC_TARGET_ABI="apcs-gnu"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+BR2_BINUTILS_VERSION_2_17=y
+# BR2_BINUTILS_VERSION_2_19 is not set
+# BR2_BINUTILS_VERSION_2_19_1 is not set
+BR2_BINUTILS_VERSION="2.17"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+BR2_GCC_VERSION_3_4_6=y
+# BR2_GCC_VERSION_4_2_4 is not set
+# BR2_GCC_VERSION_4_3_3 is not set
+# BR2_GCC_SUPPORTS_SYSROOT is not set
+BR2_GCC_VERSION="3.4.6"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+# BR2_INSTALL_LIBSTDCPP is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+# BR2_PACKAGE_NXFLAT is not set
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_SOFT_FLOAT=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/arm7tdmi-defconfig-4.2.4 b/misc/buildroot/configs/arm7tdmi-defconfig-4.2.4
new file mode 100644
index 000000000..00f05bc9c
--- /dev/null
+++ b/misc/buildroot/configs/arm7tdmi-defconfig-4.2.4
@@ -0,0 +1,115 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+BR2_arm=y
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+# BR2_generic_arm is not set
+# BR2_arm610 is not set
+BR2_arm7tdmi=y
+# BR2_arm710 is not set
+# BR2_arm720t is not set
+# BR2_arm740t is not set
+# BR2_arm920t is not set
+# BR2_arm922t is not set
+# BR2_arm926t is not set
+# BR2_arm1136jf_s is not set
+# BR2_cortex_m3 is not set
+# BR2_sa110 is not set
+# BR2_sa1100 is not set
+# BR2_xscale is not set
+# BR2_iwmmxt is not set
+BR2_ARM_OABI=y
+# BR2_ARM_EABI is not set
+BR2_ARCH="arm"
+BR2_GCC_TARGET_TUNE="arm7tdmi"
+BR2_GCC_TARGET_ARCH="armv4t"
+BR2_GCC_TARGET_ABI="apcs-gnu"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+BR2_BINUTILS_VERSION_2_19=y
+# BR2_BINUTILS_VERSION_2_19_1 is not set
+BR2_BINUTILS_VERSION="2.19"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+# BR2_GCC_VERSION_3_4_6 is not set
+BR2_GCC_VERSION_4_2_4=y
+# BR2_GCC_VERSION_4_3_3 is not set
+BR2_GCC_SUPPORTS_SYSROOT=y
+BR2_GCC_VERSION="4.2.4"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+BR2_INSTALL_LIBSTDCPP=y
+# BR2_INSTALL_LIBGCJ is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+# BR2_PACKAGE_NXFLAT is not set
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_SOFT_FLOAT=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/arm7tdmi-defconfig-4.3.3 b/misc/buildroot/configs/arm7tdmi-defconfig-4.3.3
new file mode 100644
index 000000000..9207ad3e2
--- /dev/null
+++ b/misc/buildroot/configs/arm7tdmi-defconfig-4.3.3
@@ -0,0 +1,116 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+BR2_arm=y
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+# BR2_generic_arm is not set
+# BR2_arm610 is not set
+BR2_arm7tdmi=y
+# BR2_arm710 is not set
+# BR2_arm720t is not set
+# BR2_arm740t is not set
+# BR2_arm920t is not set
+# BR2_arm922t is not set
+# BR2_arm926t is not set
+# BR2_arm1136jf_s is not set
+# BR2_cortex_m3 is not set
+# BR2_sa110 is not set
+# BR2_sa1100 is not set
+# BR2_xscale is not set
+# BR2_iwmmxt is not set
+BR2_ARM_OABI=y
+# BR2_ARM_EABI is not set
+BR2_ARCH="arm"
+BR2_GCC_TARGET_TUNE="arm7tdmi"
+BR2_GCC_TARGET_ARCH="armv4t"
+BR2_GCC_TARGET_ABI="apcs-gnu"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+# BR2_BINUTILS_VERSION_2_19 is not set
+BR2_BINUTILS_VERSION_2_19_1=y
+BR2_BINUTILS_VERSION="2.19.1"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+# BR2_GCC_VERSION_3_4_6 is not set
+# BR2_GCC_VERSION_4_2_4 is not set
+BR2_GCC_VERSION_4_3_3=y
+BR2_GCC_SUPPORTS_SYSROOT=y
+BR2_GCC_VERSION="4.3.3"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+BR2_INSTALL_LIBSTDCPP=y
+# BR2_INSTALL_LIBGCJ is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+BR2_PACKAGE_NXFLAT=y
+BR2_PACKAGE_GENROMFS=y
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_SOFT_FLOAT=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/arm920t-defconfig-4.2.4 b/misc/buildroot/configs/arm920t-defconfig-4.2.4
new file mode 100644
index 000000000..4abf36813
--- /dev/null
+++ b/misc/buildroot/configs/arm920t-defconfig-4.2.4
@@ -0,0 +1,115 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+BR2_arm=y
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+# BR2_generic_arm is not set
+# BR2_arm610 is not set
+# BR2_arm7tdmi is not set
+# BR2_arm710 is not set
+# BR2_arm720t is not set
+# BR2_arm740t is not set
+BR2_arm920t=y
+# BR2_arm922t is not set
+# BR2_arm926t is not set
+# BR2_arm1136jf_s is not set
+# BR2_cortex_m3 is not set
+# BR2_sa110 is not set
+# BR2_sa1100 is not set
+# BR2_xscale is not set
+# BR2_iwmmxt is not set
+BR2_ARM_OABI=y
+# BR2_ARM_EABI is not set
+BR2_ARCH="arm"
+BR2_GCC_TARGET_TUNE="arm920t"
+BR2_GCC_TARGET_ARCH="armv4t"
+BR2_GCC_TARGET_ABI="apcs-gnu"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+BR2_BINUTILS_VERSION_2_19=y
+# BR2_BINUTILS_VERSION_2_19_1 is not set
+BR2_BINUTILS_VERSION="2.19"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+# BR2_GCC_VERSION_3_4_6 is not set
+BR2_GCC_VERSION_4_2_4=y
+# BR2_GCC_VERSION_4_3_3 is not set
+BR2_GCC_SUPPORTS_SYSROOT=y
+BR2_GCC_VERSION="4.2.4"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+BR2_INSTALL_LIBSTDCPP=y
+# BR2_INSTALL_LIBGCJ is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+# BR2_PACKAGE_NXFLAT is not set
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_SOFT_FLOAT=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/arm920t-defconfig-4.3.3 b/misc/buildroot/configs/arm920t-defconfig-4.3.3
new file mode 100644
index 000000000..f6080a03c
--- /dev/null
+++ b/misc/buildroot/configs/arm920t-defconfig-4.3.3
@@ -0,0 +1,119 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+BR2_arm=y
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_m9s12x is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+# BR2_generic_arm is not set
+# BR2_arm610 is not set
+# BR2_arm7tdmi is not set
+# BR2_arm710 is not set
+# BR2_arm720t is not set
+# BR2_arm740t is not set
+BR2_arm920t=y
+# BR2_arm922t is not set
+# BR2_arm926t is not set
+# BR2_arm1136jf_s is not set
+# BR2_cortex_m3 is not set
+# BR2_sa110 is not set
+# BR2_sa1100 is not set
+# BR2_xscale is not set
+# BR2_iwmmxt is not set
+BR2_ARM_OABI=y
+# BR2_ARM_EABI is not set
+BR2_ARCH="arm"
+BR2_GCC_TARGET_TUNE="arm920t"
+BR2_GCC_TARGET_ARCH="armv4t"
+BR2_GCC_TARGET_ABI="apcs-gnu"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+# BR2_BINUTILS_VERSION_2_18 is not set
+# BR2_BINUTILS_VERSION_2_19 is not set
+BR2_BINUTILS_VERSION_2_19_1=y
+BR2_BINUTILS_VERSION="2.19.1"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+# BR2_GCC_VERSION_3_3_6 is not set
+# BR2_GCC_VERSION_3_4_6 is not set
+# BR2_GCC_VERSION_4_2_4 is not set
+BR2_GCC_VERSION_4_3_3=y
+BR2_GCC_SUPPORTS_SYSROOT=y
+BR2_GCC_VERSION="4.3.3"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+BR2_INSTALL_LIBSTDCPP=y
+# BR2_INSTALL_LIBGCJ is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+BR2_PACKAGE_NXFLAT=y
+BR2_PACKAGE_GENROMFS=y
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_SOFT_FLOAT=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/arm920t-eabi-defconfig-4.5.2 b/misc/buildroot/configs/arm920t-eabi-defconfig-4.5.2
new file mode 100644
index 000000000..3586e4f33
--- /dev/null
+++ b/misc/buildroot/configs/arm920t-eabi-defconfig-4.5.2
@@ -0,0 +1,121 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+BR2_arm=y
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_m9s12x is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+# BR2_generic_arm is not set
+# BR2_arm610 is not set
+# BR2_arm7tdmi is not set
+# BR2_arm710 is not set
+# BR2_arm720t is not set
+# BR2_arm740t is not set
+BR2_arm920t=y
+# BR2_arm922t is not set
+# BR2_arm926t is not set
+# BR2_arm1136jf_s is not set
+# BR2_cortex_m3 is not set
+# BR2_sa110 is not set
+# BR2_sa1100 is not set
+# BR2_xscale is not set
+# BR2_iwmmxt is not set
+# BR2_ARM_OABI is not set
+BR2_ARM_EABI=y
+BR2_ARCH="arm"
+BR2_GCC_TARGET_TUNE="arm920t"
+BR2_GCC_TARGET_ARCH="armv4t"
+BR2_GCC_TARGET_ABI="aapcs-linux"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="eabi"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+# BR2_BINUTILS_VERSION_2_18 is not set
+# BR2_BINUTILS_VERSION_2_19 is not set
+# BR2_BINUTILS_VERSION_2_19_1 is not set
+BR2_BINUTILS_VERSION_2_21_1=y
+BR2_BINUTILS_VERSION="2.21"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+# BR2_GCC_VERSION_3_3_6 is not set
+# BR2_GCC_VERSION_3_4_6 is not set
+# BR2_GCC_VERSION_4_2_4 is not set
+# BR2_GCC_VERSION_4_3_3 is not set
+BR2_GCC_VERSION_4_5_2=y
+BR2_GCC_SUPPORTS_SYSROOT=y
+BR2_GCC_VERSION="4.5.2"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+BR2_INSTALL_LIBSTDCPP=y
+# BR2_INSTALL_LIBGCJ is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+BR2_PACKAGE_NXFLAT=y
+BR2_PACKAGE_GENROMFS=y
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_SOFT_FLOAT=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/arm926t-defconfig-4.2.4 b/misc/buildroot/configs/arm926t-defconfig-4.2.4
new file mode 100644
index 000000000..1c5ae784d
--- /dev/null
+++ b/misc/buildroot/configs/arm926t-defconfig-4.2.4
@@ -0,0 +1,116 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+BR2_arm=y
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+# BR2_generic_arm is not set
+# BR2_arm610 is not set
+# BR2_arm7tdmi is not set
+# BR2_arm710 is not set
+# BR2_arm720t is not set
+# BR2_arm740t is not set
+# BR2_arm920t is not set
+# BR2_arm922t is not set
+BR2_arm926t=y
+# BR2_arm1136jf_s is not set
+# BR2_cortex_m3 is not set
+# BR2_sa110 is not set
+# BR2_sa1100 is not set
+# BR2_xscale is not set
+# BR2_iwmmxt is not set
+BR2_ARM_OABI=y
+# BR2_ARM_EABI is not set
+BR2_ARCH="arm"
+BR2_GCC_TARGET_TUNE="arm9tdmi"
+BR2_GCC_TARGET_ARCH="armv5te"
+BR2_GCC_TARGET_ABI="apcs-gnu"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+BR2_BINUTILS_VERSION_2_19=y
+# BR2_BINUTILS_VERSION_2_19_1 is not set
+BR2_BINUTILS_VERSION="2.19"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+# BR2_GCC_VERSION_3_4_6 is not set
+BR2_GCC_VERSION_4_2_4=y
+# BR2_GCC_VERSION_4_3_3 is not set
+BR2_GCC_SUPPORTS_SYSROOT=y
+BR2_GCC_VERSION="4.2.4"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+BR2_INSTALL_LIBSTDCPP=y
+# BR2_INSTALL_LIBGCJ is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+BR2_PACKAGE_NXFLAT=y
+BR2_PACKAGE_GENROMFS=y
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_SOFT_FLOAT=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/arm926t-defconfig-4.3.3 b/misc/buildroot/configs/arm926t-defconfig-4.3.3
new file mode 100644
index 000000000..3d3d7d9f7
--- /dev/null
+++ b/misc/buildroot/configs/arm926t-defconfig-4.3.3
@@ -0,0 +1,117 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+BR2_arm=y
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+# BR2_generic_arm is not set
+# BR2_arm610 is not set
+# BR2_arm7tdmi is not set
+# BR2_arm710 is not set
+# BR2_arm720t is not set
+# BR2_arm740t is not set
+# BR2_arm920t is not set
+# BR2_arm922t is not set
+BR2_arm926t=y
+# BR2_arm1136jf_s is not set
+# BR2_cortex_m3 is not set
+# BR2_sa110 is not set
+# BR2_sa1100 is not set
+# BR2_xscale is not set
+# BR2_iwmmxt is not set
+BR2_ARM_OABI=y
+# BR2_ARM_EABI is not set
+BR2_ARCH="arm"
+BR2_GCC_TARGET_TUNE="arm9tdmi"
+BR2_GCC_TARGET_ARCH="armv5te"
+BR2_GCC_TARGET_ABI="apcs-gnu"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="arm-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+# BR2_DEPRECATED is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+# BR2_BINUTILS_VERSION_2_19 is not set
+BR2_BINUTILS_VERSION_2_19_1=y
+BR2_BINUTILS_VERSION="2.19.1"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+# BR2_GCC_VERSION_3_4_6 is not set
+# BR2_GCC_VERSION_4_2_4 is not set
+BR2_GCC_VERSION_4_3_3=y
+BR2_GCC_SUPPORTS_SYSROOT=y
+BR2_GCC_VERSION="4.3.3"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+BR2_INSTALL_LIBSTDCPP=y
+# BR2_INSTALL_LIBGCJ is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+BR2_PACKAGE_NXFLAT=y
+BR2_PACKAGE_GENROMFS=y
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_SOFT_FLOAT=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/arm926t-defconfig-nxflat b/misc/buildroot/configs/arm926t-defconfig-nxflat
new file mode 100644
index 000000000..f0ddd17bc
--- /dev/null
+++ b/misc/buildroot/configs/arm926t-defconfig-nxflat
@@ -0,0 +1,110 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+BR2_arm=y
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+# BR2_generic_arm is not set
+# BR2_arm610 is not set
+# BR2_arm7tdmi is not set
+# BR2_arm710 is not set
+# BR2_arm720t is not set
+# BR2_arm740t is not set
+# BR2_arm920t is not set
+# BR2_arm922t is not set
+BR2_arm926t=y
+# BR2_arm1136jf_s is not set
+# BR2_cortex_m3 is not set
+# BR2_sa110 is not set
+# BR2_sa1100 is not set
+# BR2_xscale is not set
+# BR2_iwmmxt is not set
+BR2_ARM_OABI=y
+# BR2_ARM_EABI is not set
+BR2_ARCH="arm"
+BR2_GCC_TARGET_TUNE="arm9tdmi"
+BR2_GCC_TARGET_ARCH="armv5te"
+BR2_GCC_TARGET_ABI="apcs-gnu"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="arm-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+# BR2_DEPRECATED is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+# BR2_BINUTILS_VERSION_2_19 is not set
+BR2_BINUTILS_VERSION_2_19_1=y
+BR2_BINUTILS_VERSION="2.19.1"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+# BR2_PACKAGE_GCC is not set
+# BR2_GCC_VERSION_3_4_6 is not set
+# BR2_GCC_VERSION_4_2_4 is not set
+# BR2_GCC_VERSION_4_3_3 is not set
+# BR2_GCC_SUPPORTS_SYSROOT is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+BR2_PACKAGE_NXFLAT=y
+BR2_PACKAGE_GENROMFS=y
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_SOFT_FLOAT=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/avr-defconfig-4.3.3 b/misc/buildroot/configs/avr-defconfig-4.3.3
new file mode 100644
index 000000000..a597e5e3b
--- /dev/null
+++ b/misc/buildroot/configs/avr-defconfig-4.3.3
@@ -0,0 +1,99 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+# BR2_arm is not set
+# BR2_armeb is not set
+BR2_avr=y
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_m9s12x is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+BR2_ARCH="avr"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+# BR2_BINUTILS_VERSION_2_18 is not set
+# BR2_BINUTILS_VERSION_2_19 is not set
+BR2_BINUTILS_VERSION_2_19_1=y
+# BR2_BINUTILS_VERSION_2_21_1 is not set
+BR2_BINUTILS_VERSION="2.19.1"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+# BR2_GCC_VERSION_3_3_6 is not set
+# BR2_GCC_VERSION_3_4_6 is not set
+# BR2_GCC_VERSION_4_2_4 is not set
+BR2_GCC_VERSION_4_3_3=y
+# BR2_GCC_VERSION_4_5_2 is not set
+BR2_GCC_SUPPORTS_SYSROOT=y
+BR2_GCC_VERSION="4.3.3"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS="--enable-long-long"
+BR2_INSTALL_LIBSTDCPP=y
+# BR2_INSTALL_LIBGCJ is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+BR2_PACKAGE_GENROMFS=y
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/avr-defconfig-4.5.2 b/misc/buildroot/configs/avr-defconfig-4.5.2
new file mode 100644
index 000000000..e0ebe0559
--- /dev/null
+++ b/misc/buildroot/configs/avr-defconfig-4.5.2
@@ -0,0 +1,99 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+# BR2_arm is not set
+# BR2_armeb is not set
+BR2_avr=y
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_m9s12x is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+BR2_ARCH="avr"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+# BR2_BINUTILS_VERSION_2_18 is not set
+# BR2_BINUTILS_VERSION_2_19 is not set
+# BR2_BINUTILS_VERSION_2_19_1 is not set
+BR2_BINUTILS_VERSION_2_21_1=y
+BR2_BINUTILS_VERSION="2.21"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+# BR2_GCC_VERSION_3_3_6 is not set
+# BR2_GCC_VERSION_3_4_6 is not set
+# BR2_GCC_VERSION_4_2_4 is not set
+# BR2_GCC_VERSION_4_3_3 is not set
+BR2_GCC_VERSION_4_5_2=y
+BR2_GCC_SUPPORTS_SYSROOT=y
+BR2_GCC_VERSION="4.5.2"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS="--enable-long-long"
+BR2_INSTALL_LIBSTDCPP=y
+# BR2_INSTALL_LIBGCJ is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+BR2_PACKAGE_GENROMFS=y
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/bfin-defconfig-4.2.4 b/misc/buildroot/configs/bfin-defconfig-4.2.4
new file mode 100644
index 000000000..a88b9f269
--- /dev/null
+++ b/misc/buildroot/configs/bfin-defconfig-4.2.4
@@ -0,0 +1,92 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+# BR2_arm is not set
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+BR2_bfin=y
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+BR2_ARCH="bfin"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+BR2_BINUTILS_VERSION_2_19=y
+# BR2_BINUTILS_VERSION_2_19_1 is not set
+BR2_BINUTILS_VERSION="2.19"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+# BR2_GCC_VERSION_3_4_6 is not set
+BR2_GCC_VERSION_4_2_4=y
+# BR2_GCC_VERSION_4_3_3 is not set
+BR2_GCC_SUPPORTS_SYSROOT=y
+BR2_GCC_VERSION="4.2.4"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+# BR2_INSTALL_LIBSTDCPP is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/cortexm3-defconfig-4.3.3 b/misc/buildroot/configs/cortexm3-defconfig-4.3.3
new file mode 100644
index 000000000..36a441c69
--- /dev/null
+++ b/misc/buildroot/configs/cortexm3-defconfig-4.3.3
@@ -0,0 +1,116 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+BR2_arm=y
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+# BR2_generic_arm is not set
+# BR2_arm610 is not set
+# BR2_arm7tdmi is not set
+# BR2_arm710 is not set
+# BR2_arm720t is not set
+# BR2_arm740t is not set
+# BR2_arm920t is not set
+# BR2_arm922t is not set
+# BR2_arm926t is not set
+# BR2_arm1136jf_s is not set
+BR2_cortex_m3=y
+# BR2_sa110 is not set
+# BR2_sa1100 is not set
+# BR2_xscale is not set
+# BR2_iwmmxt is not set
+BR2_ARM_OABI=y
+# BR2_ARM_EABI is not set
+BR2_ARCH="arm"
+BR2_GCC_TARGET_TUNE="cortex-m3"
+BR2_GCC_TARGET_ARCH="armv7-m"
+BR2_GCC_TARGET_ABI="apcs-gnu"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+# BR2_BINUTILS_VERSION_2_19 is not set
+BR2_BINUTILS_VERSION_2_19_1=y
+BR2_BINUTILS_VERSION="2.19.1"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+# BR2_GCC_VERSION_3_4_6 is not set
+# BR2_GCC_VERSION_4_2_4 is not set
+BR2_GCC_VERSION_4_3_3=y
+BR2_GCC_SUPPORTS_SYSROOT=y
+BR2_GCC_VERSION="4.3.3"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+BR2_INSTALL_LIBSTDCPP=y
+# BR2_INSTALL_LIBGCJ is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+BR2_PACKAGE_NXFLAT=y
+BR2_PACKAGE_GENROMFS=y
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_SOFT_FLOAT=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/cortexm3-defconfig-nxflat b/misc/buildroot/configs/cortexm3-defconfig-nxflat
new file mode 100644
index 000000000..ac247703a
--- /dev/null
+++ b/misc/buildroot/configs/cortexm3-defconfig-nxflat
@@ -0,0 +1,106 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+BR2_arm=y
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+# BR2_generic_arm is not set
+# BR2_arm610 is not set
+# BR2_arm7tdmi is not set
+# BR2_arm710 is not set
+# BR2_arm720t is not set
+# BR2_arm740t is not set
+# BR2_arm920t is not set
+# BR2_arm922t is not set
+# BR2_arm926t is not set
+# BR2_arm1136jf_s is not set
+BR2_cortex_m3=y
+# BR2_sa110 is not set
+# BR2_sa1100 is not set
+# BR2_xscale is not set
+# BR2_iwmmxt is not set
+BR2_ARM_OABI=y
+# BR2_ARM_EABI is not set
+BR2_ARCH="arm"
+BR2_GCC_TARGET_TUNE="cortex-m3"
+BR2_GCC_TARGET_ARCH="armv7-m"
+BR2_GCC_TARGET_ABI="apcs-gnu"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+# BR2_BINUTILS_VERSION_2_19 is not set
+BR2_BINUTILS_VERSION_2_19_1=y
+BR2_BINUTILS_VERSION="2.19.1"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+# BR2_PACKAGE_GCC is not set
+# BR2_GCC_SUPPORTS_SYSROOT is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+BR2_PACKAGE_NXFLAT=y
+BR2_PACKAGE_GENROMFS=y
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_SOFT_FLOAT=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/gdb-6_8-cygwin-1_7.patch b/misc/buildroot/configs/gdb-6_8-cygwin-1_7.patch
new file mode 100644
index 000000000..93fa15b31
--- /dev/null
+++ b/misc/buildroot/configs/gdb-6_8-cygwin-1_7.patch
@@ -0,0 +1,19 @@
+--- gdb-6.8/gdb/remote-fileio.c.orig 2008-01-01 16:53:12.000000000 -0600
++++ gdb-6.8/gdb/remote-fileio.c 2011-02-12 18:00:07.390625000 -0600
+@@ -1000,12 +1000,12 @@
+ errno = EISDIR;
+ else
+ {
+- char oldfullpath[PATH_MAX + 1];
+- char newfullpath[PATH_MAX + 1];
++ char oldfullpath[PATH_MAX];
++ char newfullpath[PATH_MAX];
+ int len;
+
+- cygwin_conv_to_full_posix_path (oldpath, oldfullpath);
+- cygwin_conv_to_full_posix_path (newpath, newfullpath);
++ cygwin_conv_path (CCP_WIN_A_TO_POSIX, oldpath, oldfullpath, PATH_MAX);
++ cygwin_conv_path (CCP_WIN_A_TO_POSIX, newpath, newfullpath, PATH_MAX);
+ len = strlen (oldfullpath);
+ if (newfullpath[len] == '/'
+ && !strncmp (oldfullpath, newfullpath, len))
diff --git a/misc/buildroot/configs/h8300_defconfig b/misc/buildroot/configs/h8300_defconfig
new file mode 100644
index 000000000..127b04de3
--- /dev/null
+++ b/misc/buildroot/configs/h8300_defconfig
@@ -0,0 +1,92 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+# BR2_arm is not set
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+BR2_h8300=y
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+BR2_ARCH="h8300"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+BR2_BINUTILS_VERSION_2_17=y
+# BR2_BINUTILS_VERSION_2_19 is not set
+# BR2_BINUTILS_VERSION_2_19_1 is not set
+BR2_BINUTILS_VERSION="2.17"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+BR2_GCC_VERSION_3_4_6=y
+# BR2_GCC_VERSION_4_2_4 is not set
+# BR2_GCC_VERSION_4_3_3 is not set
+# BR2_GCC_SUPPORTS_SYSROOT is not set
+BR2_GCC_VERSION="3.4.6"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+# BR2_INSTALL_LIBSTDCPP is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/i486-defconfig-4.3.3 b/misc/buildroot/configs/i486-defconfig-4.3.3
new file mode 100644
index 000000000..c99130521
--- /dev/null
+++ b/misc/buildroot/configs/i486-defconfig-4.3.3
@@ -0,0 +1,103 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+# BR2_arm is not set
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+BR2_i386=y
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_m9s12x is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+# BR2_x86_i386 is not set
+BR2_x86_i486=y
+# BR2_x86_i586 is not set
+# BR2_x86_i686 is not set
+BR2_ARCH="i486"
+BR2_GCC_TARGET_TUNE="i486"
+BR2_GCC_TARGET_ARCH="i486"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+# BR2_BINUTILS_VERSION_2_18 is not set
+# BR2_BINUTILS_VERSION_2_19 is not set
+BR2_BINUTILS_VERSION_2_19_1=y
+BR2_BINUTILS_VERSION="2.19.1"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+# BR2_GCC_VERSION_3_3_6 is not set
+# BR2_GCC_VERSION_3_4_6 is not set
+# BR2_GCC_VERSION_4_2_4 is not set
+BR2_GCC_VERSION_4_3_3=y
+BR2_GCC_SUPPORTS_SYSROOT=y
+BR2_GCC_VERSION="4.3.3"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+BR2_INSTALL_LIBSTDCPP=y
+# BR2_INSTALL_LIBGCJ is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+BR2_PACKAGE_GENROMFS=y
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/m32c-defconfig-4.2.4 b/misc/buildroot/configs/m32c-defconfig-4.2.4
new file mode 100644
index 000000000..cf6b51bde
--- /dev/null
+++ b/misc/buildroot/configs/m32c-defconfig-4.2.4
@@ -0,0 +1,93 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+# BR2_arm is not set
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+BR2_m32c=y
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+BR2_ARCH="m32c"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+BR2_BINUTILS_VERSION_2_19=y
+# BR2_BINUTILS_VERSION_2_19_1 is not set
+BR2_BINUTILS_VERSION="2.19"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+# BR2_GCC_VERSION_3_4_6 is not set
+BR2_GCC_VERSION_4_2_4=y
+# BR2_GCC_VERSION_4_3_3 is not set
+BR2_GCC_SUPPORTS_SYSROOT=y
+BR2_GCC_VERSION="4.2.4"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+# BR2_INSTALL_LIBSTDCPP is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+BR2_PACKAGE_GENROMFS=y
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/m32c-defconfig-4.3.3 b/misc/buildroot/configs/m32c-defconfig-4.3.3
new file mode 100644
index 000000000..ef7fa4d00
--- /dev/null
+++ b/misc/buildroot/configs/m32c-defconfig-4.3.3
@@ -0,0 +1,93 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+# BR2_arm is not set
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+BR2_m32c=y
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+BR2_ARCH="m32c"
+BR2_ENDIAN="LITTLE"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+# BR2_BINUTILS_VERSION_2_19 is not set
+BR2_BINUTILS_VERSION_2_19_1=y
+BR2_BINUTILS_VERSION="2.19.1"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+# BR2_GCC_VERSION_3_4_6 is not set
+# BR2_GCC_VERSION_4_2_4 is not set
+BR2_GCC_VERSION_4_3_3=y
+BR2_GCC_SUPPORTS_SYSROOT=y
+BR2_GCC_VERSION="4.3.3"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+# BR2_INSTALL_LIBSTDCPP is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+BR2_PACKAGE_GENROMFS=y
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/m68hc11-config b/misc/buildroot/configs/m68hc11-config
new file mode 100644
index 000000000..9496beb66
--- /dev/null
+++ b/misc/buildroot/configs/m68hc11-config
@@ -0,0 +1,92 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+# BR2_arm is not set
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+BR2_m68hc11=y
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+BR2_ARCH="m68hc11"
+BR2_ENDIAN="BIG"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+BR2_BINUTILS_VERSION_2_17=y
+# BR2_BINUTILS_VERSION_2_19 is not set
+# BR2_BINUTILS_VERSION_2_19_1 is not set
+BR2_BINUTILS_VERSION="2.17"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+BR2_GCC_VERSION_3_4_6=y
+# BR2_GCC_VERSION_4_2_4 is not set
+# BR2_GCC_VERSION_4_3_3 is not set
+# BR2_GCC_SUPPORTS_SYSROOT is not set
+BR2_GCC_VERSION="3.4.6"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+# BR2_INSTALL_LIBSTDCPP is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/m68hc12-config-3.4.6 b/misc/buildroot/configs/m68hc12-config-3.4.6
new file mode 100644
index 000000000..3277e0989
--- /dev/null
+++ b/misc/buildroot/configs/m68hc12-config-3.4.6
@@ -0,0 +1,93 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+# BR2_arm is not set
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+BR2_m68hc12=y
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+BR2_ARCH="m68hc12"
+BR2_ENDIAN="BIG"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+BR2_BINUTILS_VERSION_2_17=y
+# BR2_BINUTILS_VERSION_2_19 is not set
+# BR2_BINUTILS_VERSION_2_19_1 is not set
+BR2_BINUTILS_VERSION="2.17"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+BR2_GCC_VERSION_3_4_6=y
+# BR2_GCC_VERSION_4_2_4 is not set
+# BR2_GCC_VERSION_4_3_3 is not set
+# BR2_GCC_SUPPORTS_SYSROOT is not set
+BR2_GCC_VERSION="3.4.6"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+# BR2_INSTALL_LIBSTDCPP is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+# BR2_PACKAGE_GENROMFS is not set
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/m68hc12-config-4.3.3 b/misc/buildroot/configs/m68hc12-config-4.3.3
new file mode 100644
index 000000000..e889e273d
--- /dev/null
+++ b/misc/buildroot/configs/m68hc12-config-4.3.3
@@ -0,0 +1,94 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+# BR2_arm is not set
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+BR2_m68hc12=y
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+BR2_ARCH="m68hc12"
+BR2_ENDIAN="BIG"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+# BR2_BINUTILS_VERSION_2_19 is not set
+BR2_BINUTILS_VERSION_2_19_1=y
+BR2_BINUTILS_VERSION="2.19.1"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+# BR2_GCC_VERSION_3_4_6 is not set
+# BR2_GCC_VERSION_4_2_4 is not set
+BR2_GCC_VERSION_4_3_3=y
+BR2_GCC_SUPPORTS_SYSROOT=y
+BR2_GCC_VERSION="4.3.3"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+BR2_INSTALL_LIBSTDCPP=y
+# BR2_INSTALL_LIBGCJ is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+BR2_PACKAGE_GENROMFS=y
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/m68k-defconfig b/misc/buildroot/configs/m68k-defconfig
new file mode 100644
index 000000000..2de720755
--- /dev/null
+++ b/misc/buildroot/configs/m68k-defconfig
@@ -0,0 +1,92 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+# BR2_arm is not set
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+BR2_m68k=y
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+BR2_ARCH="m68k"
+BR2_ENDIAN="BIG"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+BR2_BINUTILS_VERSION_2_17=y
+# BR2_BINUTILS_VERSION_2_19 is not set
+# BR2_BINUTILS_VERSION_2_19_1 is not set
+BR2_BINUTILS_VERSION="2.17"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+BR2_GCC_VERSION_3_4_6=y
+# BR2_GCC_VERSION_4_2_4 is not set
+# BR2_GCC_VERSION_4_3_3 is not set
+# BR2_GCC_SUPPORTS_SYSROOT is not set
+BR2_GCC_VERSION="3.4.6"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+# BR2_INSTALL_LIBSTDCPP is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/m9s12x-config-3.3.6 b/misc/buildroot/configs/m9s12x-config-3.3.6
new file mode 100644
index 000000000..ab75d010d
--- /dev/null
+++ b/misc/buildroot/configs/m9s12x-config-3.3.6
@@ -0,0 +1,96 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+# BR2_arm is not set
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+BR2_m9s12x=y
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+# BR2_sh is not set
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+BR2_ARCH="m9s12x"
+BR2_ENDIAN="BIG"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+# BR2_BINUTILS_VERSION_2_17 is not set
+BR2_BINUTILS_VERSION_2_18=y
+# BR2_BINUTILS_VERSION_2_19 is not set
+# BR2_BINUTILS_VERSION_2_19_1 is not set
+BR2_BINUTILS_VERSION="2.18"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+BR2_GCC_VERSION_3_3_6=y
+# BR2_GCC_VERSION_3_4_6 is not set
+# BR2_GCC_VERSION_4_2_4 is not set
+# BR2_GCC_VERSION_4_3_3 is not set
+# BR2_GCC_SUPPORTS_SYSROOT is not set
+BR2_GCC_VERSION="3.3.6"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+# BR2_INSTALL_LIBSTDCPP is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+# BR2_PACKAGE_GENROMFS is not set
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/configs/sh-defconfig b/misc/buildroot/configs/sh-defconfig
new file mode 100644
index 000000000..5fc95a5ff
--- /dev/null
+++ b/misc/buildroot/configs/sh-defconfig
@@ -0,0 +1,99 @@
+#
+# Automatically generated make config: don't edit
+#
+BR2_HAVE_DOT_CONFIG=y
+# BR2_alpha is not set
+# BR2_arm is not set
+# BR2_armeb is not set
+# BR2_avr is not set
+# BR2_avr32 is not set
+# BR2_bfin is not set
+# BR2_cris is not set
+# BR2_i386 is not set
+# BR2_m32c is not set
+# BR2_m68k is not set
+# BR2_m68hc11 is not set
+# BR2_m68hc12 is not set
+# BR2_mips is not set
+# BR2_mipsel is not set
+# BR2_nios2 is not set
+# BR2_powerpc is not set
+BR2_sh=y
+# BR2_sh64 is not set
+# BR2_h8300 is not set
+# BR2_sparc is not set
+# BR2_x86_64 is not set
+BR2_sh1=y
+# BR2_sh2a_nofpueb is not set
+# BR2_sh2eb is not set
+# BR2_sh3 is not set
+# BR2_sh3eb is not set
+# BR2_sh4 is not set
+# BR2_sh4eb is not set
+BR2_ARCH="sh"
+BR2_ENDIAN="BIG"
+
+#
+# Build options
+#
+BR2_WGET="wget --passive-ftp"
+BR2_SVN="svn co"
+BR2_ZCAT="zcat"
+BR2_BZCAT="bzcat"
+BR2_TAR_OPTIONS=""
+BR2_DL_DIR="$(BASE_DIR)/../archives"
+BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir"
+BR2_NUTTX_DIR="$(TOPDIR)/../../nuttx"
+BR2_TOPDIR_PREFIX=""
+BR2_TOPDIR_SUFFIX=""
+BR2_GNU_BUILD_SUFFIX="pc-elf"
+BR2_GNU_TARGET_SUFFIX="elf"
+# BR2_PREFER_IMA is not set
+
+#
+# Toolchain Options
+#
+
+#
+# Binutils Options
+#
+BR2_BINUTILS_VERSION_2_17=y
+# BR2_BINUTILS_VERSION_2_19 is not set
+# BR2_BINUTILS_VERSION_2_19_1 is not set
+BR2_BINUTILS_VERSION="2.17"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""
+
+#
+# GCC Options
+#
+BR2_PACKAGE_GCC=y
+BR2_GCC_VERSION_3_4_6=y
+# BR2_GCC_VERSION_4_2_4 is not set
+# BR2_GCC_VERSION_4_3_3 is not set
+# BR2_GCC_SUPPORTS_SYSROOT is not set
+BR2_GCC_VERSION="3.4.6"
+# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
+BR2_EXTRA_GCC_CONFIG_OPTIONS=""
+# BR2_INSTALL_LIBSTDCPP is not set
+# BR2_INSTALL_OBJC is not set
+# BR2_INSTALL_FORTRAN is not set
+
+#
+# Gdb Options
+#
+# BR2_PACKAGE_GDB is not set
+# BR2_PACKAGE_GDB_SERVER is not set
+# BR2_PACKAGE_GDB_HOST is not set
+
+#
+# NuttX Binary Support
+#
+
+#
+# Common Toolchain Options
+#
+# BR2_PACKAGE_SSTRIP_TARGET is not set
+# BR2_PACKAGE_SSTRIP_HOST is not set
+# BR2_ENABLE_MULTILIB is not set
+BR2_LARGEFILE=y
+BR2_TARGET_OPTIMIZATION="-Os -pipe"
diff --git a/misc/buildroot/package/Makefile.in b/misc/buildroot/package/Makefile.in
new file mode 100644
index 000000000..d79783343
--- /dev/null
+++ b/misc/buildroot/package/Makefile.in
@@ -0,0 +1,111 @@
+ifndef MAKE
+MAKE=make
+endif
+MAKE1:=$(MAKE) MAKE="$(firstword $(MAKE)) -j1"
+
+# Strip off the annoying quoting
+ARCH:=$(strip $(subst ",, $(BR2_ARCH)))
+#"))
+WGET:=$(strip $(subst ",, $(BR2_WGET)))
+#"))
+SVN:=$(strip $(subst ",, $(BR2_SVN)))
+#"))
+ZCAT:=$(strip $(subst ",, $(BR2_ZCAT)))
+#"))
+BZCAT:=$(strip $(subst ",, $(BR2_BZCAT)))
+#"))
+TAR_OPTIONS=$(subst ",, $(BR2_TAR_OPTIONS)) -xf
+#")
+
+TARGET_CFLAGS=$(TARGET_OPTIMIZATION) $(TARGET_DEBUGGING)
+HOSTCC:=gcc
+HOSTCXX:=g++
+
+BASE_DIR:=${shell pwd}
+
+TOPDIR_PREFIX:=$(strip $(subst ",, $(BR2_TOPDIR_PREFIX)))_
+#"))
+TOPDIR_SUFFIX:=_$(strip $(subst ",, $(BR2_TOPDIR_SUFFIX)))
+#"))
+ifeq ($(TOPDIR_PREFIX),_)
+TOPDIR_PREFIX:=
+endif
+ifeq ($(TOPDIR_SUFFIX),_)
+TOPDIR_SUFFIX:=
+endif
+
+DL_DIR=$(strip $(subst ",, $(BR2_DL_DIR)))
+#"))
+ifeq ($(DL_DIR),)
+DL_DIR:=$(BASE_DIR)/dl
+endif
+#PATCH_DIR=$(BASE_DIR)/sources/patches
+BUILD_DIR:=$(BASE_DIR)/$(TOPDIR_PREFIX)build_$(ARCH)$(ARCH_FPU_SUFFIX)$(TOPDIR_SUFFIX)
+TARGET_DIR:=$(BUILD_DIR)/root
+
+GNU_TARGET_SUFFIX:=-$(strip $(subst ",, $(BR2_GNU_TARGET_SUFFIX)))
+#"))
+
+STAGING_DIR:=$(strip $(subst ",, $(BR2_STAGING_DIR)))
+NUTTX_DIR:=$(strip $(subst ",, $(BR2_NUTTX_DIR)))
+#"))
+TOOL_BUILD_DIR=$(BASE_DIR)/$(TOPDIR_PREFIX)toolchain_build_$(ARCH)$(ARCH_FPU_SUFFIX)$(TOPDIR_SUFFIX)
+
+# Quotes are needed for spaces et al in path components.
+TARGET_PATH="$(STAGING_DIR)/bin:$(TOOL_BUILD_DIR)/bin:$(PATH)"
+REAL_GNU_TARGET_NAME=$(OPTIMIZE_FOR_CPU)$(GNU_TARGET_SUFFIX)
+GNU_TARGET_NAME=$(OPTIMIZE_FOR_CPU)-elf
+KERNEL_CROSS=$(STAGING_DIR)/bin/$(OPTIMIZE_FOR_CPU)$(GNU_TARGET_SUFFIX)-
+TARGET_CROSS=$(STAGING_DIR)/bin/$(OPTIMIZE_FOR_CPU)$(GNU_TARGET_SUFFIX)-
+TARGET_CC=$(TARGET_CROSS)gcc
+TARGET_CXX=$(TARGET_CROSS)g++
+TARGET_RANLIB=$(TARGET_CROSS)ranlib
+STRIP=$(TARGET_CROSS)strip --remove-section=.comment --remove-section=.note
+INSTALL=/usr/bin/install
+
+
+HOST_ARCH:=$(shell $(HOSTCC) -dumpmachine | sed -e s'/-.*//' \
+ -e 's/sparc.*/sparc/' \
+ -e 's/arm.*/arm/g' \
+ -e 's/m68k.*/m68k/' \
+ -e 's/ppc/powerpc/g' \
+ -e 's/v850.*/v850/g' \
+ -e 's/sh[234]/sh/' \
+ -e 's/mips-.*/mips/' \
+ -e 's/mipsel-.*/mipsel/' \
+ -e 's/cris.*/cris/' \
+ -e 's/i[3-9]86/i386/' \
+ )
+GNU_HOST_NAME:=$(HOST_ARCH)-$(subst ",,$(BR2_GNU_BUILD_SUFFIX))
+#")
+TARGET_CONFIGURE_OPTS=PATH=$(TARGET_PATH) \
+ AR=$(TARGET_CROSS)ar \
+ AS=$(TARGET_CROSS)as \
+ LD=$(TARGET_CROSS)ld \
+ NM=$(TARGET_CROSS)nm \
+ CC=$(TARGET_CROSS)gcc \
+ GCC=$(TARGET_CROSS)gcc \
+ CXX=$(TARGET_CROSS)g++ \
+ CPP=$(TARGET_CROSS)cpp \
+ RANLIB=$(TARGET_CROSS)ranlib \
+ STRIP=$(TARGET_CROSS)strip \
+ OBJCOPY=$(TARGET_CROSS)objcopy \
+ CC_FOR_BUILD="$(HOSTCC)" \
+ PKG_CONFIG_SYSROOT=$(STAGING_DIR) \
+ PKG_CONFIG=$(STAGING_DIR)/usr/bin/pkg-config
+
+
+ifeq ($(BR2_ENABLE_LOCALE),y)
+DISABLE_NLS:=
+else
+DISABLE_NLS:=--disable-nls
+endif
+
+ifneq ($(BR2_LARGEFILE),y)
+DISABLE_LARGEFILE= --disable-largefile
+endif
+
+ifeq ($(BR2_INSTALL_LIBSTDCPP),)
+TARGET_CONFIGURE_OPTS+=CXX=""
+endif
+
diff --git a/misc/buildroot/package/config/Kconfig-language.txt b/misc/buildroot/package/config/Kconfig-language.txt
new file mode 100644
index 000000000..d78969e32
--- /dev/null
+++ b/misc/buildroot/package/config/Kconfig-language.txt
@@ -0,0 +1,282 @@
+Introduction
+------------
+
+The configuration database is collection of configuration options
+organized in a tree structure:
+
+ +- Code maturity level options
+ | +- Prompt for development and/or incomplete code/drivers
+ +- General setup
+ | +- Networking support
+ | +- System V IPC
+ | +- BSD Process Accounting
+ | +- Sysctl support
+ +- Loadable module support
+ | +- Enable loadable module support
+ | +- Set version information on all module symbols
+ | +- Kernel module loader
+ +- ...
+
+Every entry has its own dependencies. These dependencies are used
+to determine the visibility of an entry. Any child entry is only
+visible if its parent entry is also visible.
+
+Menu entries
+------------
+
+Most entries define a config option, all other entries help to organize
+them. A single configuration option is defined like this:
+
+config MODVERSIONS
+ bool "Set version information on all module symbols"
+ depends MODULES
+ help
+ Usually, modules have to be recompiled whenever you switch to a new
+ kernel. ...
+
+Every line starts with a key word and can be followed by multiple
+arguments. "config" starts a new config entry. The following lines
+define attributes for this config option. Attributes can be the type of
+the config option, input prompt, dependencies, help text and default
+values. A config option can be defined multiple times with the same
+name, but every definition can have only a single input prompt and the
+type must not conflict.
+
+Menu attributes
+---------------
+
+A menu entry can have a number of attributes. Not all of them are
+applicable everywhere (see syntax).
+
+- type definition: "bool"/"tristate"/"string"/"hex"/"integer"
+ Every config option must have a type. There are only two basic types:
+ tristate and string, the other types are based on these two. The type
+ definition optionally accepts an input prompt, so these two examples
+ are equivalent:
+
+ bool "Networking support"
+ and
+ bool
+ prompt "Networking support"
+
+- input prompt: "prompt" <prompt> ["if" <expr>]
+ Every menu entry can have at most one prompt, which is used to display
+ to the user. Optionally dependencies only for this prompt can be added
+ with "if".
+
+- default value: "default" <expr> ["if" <expr>]
+ A config option can have any number of default values. If multiple
+ default values are visible, only the first defined one is active.
+ Default values are not limited to the menu entry, where they are
+ defined, this means the default can be defined somewhere else or be
+ overridden by an earlier definition.
+ The default value is only assigned to the config symbol if no other
+ value was set by the user (via the input prompt above). If an input
+ prompt is visible the default value is presented to the user and can
+ be overridden by him.
+ Optionally dependencies only for this default value can be added with
+ "if".
+
+- dependencies: "depends on"/"requires" <expr>
+ This defines a dependency for this menu entry. If multiple
+ dependencies are defined they are connected with '&&'. Dependencies
+ are applied to all other options within this menu entry (which also
+ accept an "if" expression), so these two examples are equivalent:
+
+ bool "foo" if BAR
+ default y if BAR
+ and
+ depends on BAR
+ bool "foo"
+ default y
+
+- reverse dependencies: "select" <symbol> ["if" <expr>]
+ While normal dependencies reduce the upper limit of a symbol (see
+ below), reverse dependencies can be used to force a lower limit of
+ another symbol. The value of the current menu symbol is used as the
+ minimal value <symbol> can be set to. If <symbol> is selected multiple
+ times, the limit is set to the largest selection.
+ Reverse dependencies can only be used with boolean or tristate
+ symbols.
+
+- numerical ranges: "range" <symbol> <symbol> ["if" <expr>]
+ This allows to limit the range of possible input values for integer
+ and hex symbols. The user can only input a value which is larger than
+ or equal to the first symbol and smaller than or equal to the second
+ symbol.
+
+- help text: "help" or "---help---"
+ This defines a help text. The end of the help text is determined by
+ the indentation level, this means it ends at the first line which has
+ a smaller indentation than the first line of the help text.
+ "---help---" and "help" do not differ in behaviour, "---help---" is
+ used to help visually separate configuration logic from help within
+ the file as an aid to developers.
+
+
+Menu dependencies
+-----------------
+
+Dependencies define the visibility of a menu entry and can also reduce
+the input range of tristate symbols. The tristate logic used in the
+expressions uses one more state than normal boolean logic to express the
+module state. Dependency expressions have the following syntax:
+
+<expr> ::= <symbol> (1)
+ <symbol> '=' <symbol> (2)
+ <symbol> '!=' <symbol> (3)
+ '(' <expr> ')' (4)
+ '!' <expr> (5)
+ <expr> '&&' <expr> (6)
+ <expr> '||' <expr> (7)
+
+Expressions are listed in decreasing order of precedence.
+
+(1) Convert the symbol into an expression. Boolean and tristate symbols
+ are simply converted into the respective expression values. All
+ other symbol types result in 'n'.
+(2) If the values of both symbols are equal, it returns 'y',
+ otherwise 'n'.
+(3) If the values of both symbols are equal, it returns 'n',
+ otherwise 'y'.
+(4) Returns the value of the expression. Used to override precedence.
+(5) Returns the result of (2-/expr/).
+(6) Returns the result of min(/expr/, /expr/).
+(7) Returns the result of max(/expr/, /expr/).
+
+An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2
+respectively for calculations). A menu entry becomes visible when it's
+expression evaluates to 'm' or 'y'.
+
+There are two types of symbols: constant and nonconstant symbols.
+Nonconstant symbols are the most common ones and are defined with the
+'config' statement. Nonconstant symbols consist entirely of alphanumeric
+characters or underscores.
+Constant symbols are only part of expressions. Constant symbols are
+always surrounded by single or double quotes. Within the quote any
+other character is allowed and the quotes can be escaped using '\'.
+
+Menu structure
+--------------
+
+The position of a menu entry in the tree is determined in two ways. First
+it can be specified explicitly:
+
+menu "Network device support"
+ depends NET
+
+config NETDEVICES
+ ...
+
+endmenu
+
+All entries within the "menu" ... "endmenu" block become a submenu of
+"Network device support". All subentries inherit the dependencies from
+the menu entry, e.g. this means the dependency "NET" is added to the
+dependency list of the config option NETDEVICES.
+
+The other way to generate the menu structure is done by analyzing the
+dependencies. If a menu entry somehow depends on the previous entry, it
+can be made a submenu of it. First, the previous (parent) symbol must
+be part of the dependency list and then one of these two conditions
+must be true:
+- the child entry must become invisible, if the parent is set to 'n'
+- the child entry must only be visible, if the parent is visible
+
+config MODULES
+ bool "Enable loadable module support"
+
+config MODVERSIONS
+ bool "Set version information on all module symbols"
+ depends MODULES
+
+comment "module support disabled"
+ depends !MODULES
+
+MODVERSIONS directly depends on MODULES, this means it's only visible if
+MODULES is different from 'n'. The comment on the other hand is always
+visible when MODULES is visible (the (empty) dependency of MODULES is
+also part of the comment dependencies).
+
+
+Kconfig syntax
+--------------
+
+The configuration file describes a series of menu entries, where every
+line starts with a keyword (except help texts). The following keywords
+end a menu entry:
+- config
+- menuconfig
+- choice/endchoice
+- comment
+- menu/endmenu
+- if/endif
+- source
+The first five also start the definition of a menu entry.
+
+config:
+
+ "config" <symbol>
+ <config options>
+
+This defines a config symbol <symbol> and accepts any of above
+attributes as options.
+
+menuconfig:
+ "menuconfig" <symbol>
+ <config options>
+
+This is similiar to the simple config entry above, but it also gives a
+hint to front ends, that all suboptions should be displayed as a
+separate list of options.
+
+choices:
+
+ "choice"
+ <choice options>
+ <choice block>
+ "endchoice"
+
+This defines a choice group and accepts any of above attributes as
+options. A choice can only be of type bool or tristate, while a boolean
+choice only allows a single config entry to be selected, a tristate
+choice also allows any number of config entries to be set to 'm'. This
+can be used if multiple drivers for a single hardware exists and only a
+single driver can be compiled/loaded into the kernel, but all drivers
+can be compiled as modules.
+A choice accepts another option "optional", which allows to set the
+choice to 'n' and no entry needs to be selected.
+
+comment:
+
+ "comment" <prompt>
+ <comment options>
+
+This defines a comment which is displayed to the user during the
+configuration process and is also echoed to the output files. The only
+possible options are dependencies.
+
+menu:
+
+ "menu" <prompt>
+ <menu options>
+ <menu block>
+ "endmenu"
+
+This defines a menu block, see "Menu structure" above for more
+information. The only possible options are dependencies.
+
+if:
+
+ "if" <expr>
+ <if block>
+ "endif"
+
+This defines an if block. The dependency expression <expr> is appended
+to all enclosed menu entries.
+
+source:
+
+ "source" <prompt>
+
+This reads the specified configuration file. This file is always parsed.
diff --git a/misc/buildroot/package/config/Makefile b/misc/buildroot/package/config/Makefile
new file mode 100644
index 000000000..430138f77
--- /dev/null
+++ b/misc/buildroot/package/config/Makefile
@@ -0,0 +1,134 @@
+# Makefile for buildroot2
+#
+# Copyright (C) 2002-2005 Erik Andersen <andersen@codepoet.org>
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Library General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# Select the compiler needed to build binaries for your development system
+HOSTCC = gcc
+HOSTCFLAGS= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
+# Ensure consistent sort order, 'gcc -print-search-dirs' behavior, etc.
+LC_ALL:= C
+
+all: ncurses conf mconf
+
+ifeq ($(shell uname),SunOS)
+LIBS = -lcurses
+else
+LIBS = -lncurses
+endif
+ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h))
+ HOSTNCURSES += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"
+else
+ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h))
+ HOSTNCURSES += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"
+else
+ifeq (/usr/local/include/ncurses/ncurses.h, $(wildcard /usr/local/include/ncurses/ncurses.h))
+ HOSTCFLAGS += -I/usr/local/include/ncurses -DCURSES_LOC="<ncurses.h>"
+else
+ifeq (/usr/local/include/ncurses/curses.h, $(wildcard /usr/local/include/ncurses/curses.h))
+ HOSTCFLAGS += -I/usr/local/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"
+else
+ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h))
+ HOSTNCURSES += -DCURSES_LOC="<ncurses.h>"
+else
+ HOSTNCURSES += -DCURSES_LOC="<curses.h>"
+endif
+endif
+endif
+endif
+endif
+
+CONF_SRC = conf.c
+MCONF_SRC = mconf.c
+LXD_SRC = lxdialog/checklist.c lxdialog/menubox.c lxdialog/textbox.c \
+ lxdialog/yesno.c lxdialog/inputbox.c lxdialog/util.c \
+ lxdialog/msgbox.c
+SHARED_SRC = zconf.tab.c
+SHARED_DEPS := lkc.h lkc_proto.h lkc_defs.h expr.h zconf.tab.h
+CONF_OBJS = $(patsubst %.c,%.o, $(CONF_SRC))
+MCONF_OBJS = $(patsubst %.c,%.o, $(MCONF_SRC) $(LXD_SRC))
+SHARED_OBJS = $(patsubst %.c,%.o, $(SHARED_SRC))
+
+conf: $(CONF_OBJS) $(SHARED_OBJS)
+ $(HOSTCC) $(NATIVE_LDFLAGS) $^ -o $@
+
+mconf: $(MCONF_OBJS) $(SHARED_OBJS)
+ $(HOSTCC) $(NATIVE_LDFLAGS) $^ -o $@ $(LIBS)
+
+$(CONF_OBJS): %.o : %.c $(SHARED_DEPS)
+ $(HOSTCC) $(HOSTCFLAGS) -I. -c $< -o $@
+
+$(MCONF_OBJS): %.o : %.c $(SHARED_DEPS)
+ $(HOSTCC) $(HOSTCFLAGS) $(HOSTNCURSES) -I. -c $< -o $@
+
+lkc_defs.h: lkc_proto.h
+ @sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
+
+###
+# The following requires flex/bison
+# By default we use the _shipped versions, uncomment the
+# following line if you are modifying the flex/bison src.
+#LKC_GENPARSER := 1
+
+ifdef LKC_GENPARSER
+
+%.tab.c %.tab.h: %.y
+ bison -t -d -v -b $* -p $(notdir $*) $<
+
+lex.%.c: %.l
+ flex -P$(notdir $*) -o$@ $<
+else
+
+lex.zconf.o: lex.zconf.c $(SHARED_DEPS)
+ $(HOSTCC) $(HOSTCFLAGS) -I. -c $< -o $@
+
+lex.zconf.c: lex.zconf.c_shipped
+ cp lex.zconf.c_shipped lex.zconf.c
+
+zconf.tab.o: zconf.tab.c lex.zconf.c confdata.c expr.c symbol.c menu.c $(SHARED_DEPS)
+ $(HOSTCC) $(HOSTCFLAGS) -I. -c $< -o $@
+
+zconf.tab.c: zconf.tab.c_shipped
+ cp zconf.tab.c_shipped zconf.tab.c
+
+zconf.tab.h: zconf.tab.h_shipped
+ cp zconf.tab.h_shipped zconf.tab.h
+endif
+
+.PHONY: ncurses
+
+ncurses:
+ @echo "main() {}" > lxtemp.c
+ @if $(HOSTCC) lxtemp.c $(LIBS) ; then \
+ $(RM) lxtemp.c a.out; \
+ else \
+ $(RM) lxtemp.c; \
+ /bin/echo -e "\007" ;\
+ echo ">> Unable to find the Ncurses libraries." ;\
+ echo ">>" ;\
+ echo ">> You must have Ncurses installed in order" ;\
+ echo ">> to use 'make menuconfig'" ;\
+ echo ">>" ;\
+ echo ">> Maybe you want to try 'make config', which" ;\
+ echo ">> doesn't depend on the Ncurses libraries." ;\
+ echo ;\
+ exit 1 ;\
+ fi
+
+clean:
+ $(RM) *.o *~ core $(TARGETS) $(MCONF_OBJS) $(CONF_OBJS) \
+ conf mconf zconf.tab.c zconf.tab.h lex.zconf.c lkc_defs.h
+
diff --git a/misc/buildroot/package/config/conf.c b/misc/buildroot/package/config/conf.c
new file mode 100644
index 000000000..8ca430b0b
--- /dev/null
+++ b/misc/buildroot/package/config/conf.c
@@ -0,0 +1,583 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/stat.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+static void conf(struct menu *menu);
+static void check_conf(struct menu *menu);
+
+enum {
+ ask_all,
+ ask_new,
+ ask_silent,
+ set_default,
+ set_yes,
+ set_mod,
+ set_no,
+ set_random
+} input_mode = ask_all;
+char *defconfig_file;
+
+static int indent = 1;
+static int valid_stdin = 1;
+static int conf_cnt;
+static signed char line[128];
+static struct menu *rootEntry;
+
+static char nohelp_text[] = "Sorry, no help available for this option yet.\n";
+
+static void strip(signed char *str)
+{
+ signed char *p = str;
+ int l;
+
+ while ((isspace(*p)))
+ p++;
+ l = strlen(p);
+ if (p != str)
+ memmove(str, p, l + 1);
+ if (!l)
+ return;
+ p = str + l - 1;
+ while ((isspace(*p)))
+ *p-- = 0;
+}
+
+static void check_stdin(void)
+{
+ if (!valid_stdin && input_mode == ask_silent) {
+ printf("aborted!\n\n");
+ printf("Console input/output is redirected. ");
+ printf("Run 'make oldconfig' to update configuration.\n\n");
+ exit(1);
+ }
+}
+
+static void conf_askvalue(struct symbol *sym, const char *def)
+{
+ enum symbol_type type = sym_get_type(sym);
+ tristate val;
+
+ if (!sym_has_value(sym))
+ printf("(NEW) ");
+
+ line[0] = '\n';
+ line[1] = 0;
+
+ if (!sym_is_changable(sym)) {
+ printf("%s\n", def);
+ line[0] = '\n';
+ line[1] = 0;
+ return;
+ }
+
+ switch (input_mode) {
+ case ask_new:
+ case ask_silent:
+ if (sym_has_value(sym)) {
+ printf("%s\n", def);
+ return;
+ }
+ check_stdin();
+ case ask_all:
+ fflush(stdout);
+ fgets(line, 128, stdin);
+ return;
+ case set_default:
+ printf("%s\n", def);
+ return;
+ default:
+ break;
+ }
+
+ switch (type) {
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ printf("%s\n", def);
+ return;
+ default:
+ ;
+ }
+ switch (input_mode) {
+ case set_yes:
+ if (sym_tristate_within_range(sym, yes)) {
+ line[0] = 'y';
+ line[1] = '\n';
+ line[2] = 0;
+ break;
+ }
+ case set_mod:
+ if (type == S_TRISTATE) {
+ if (sym_tristate_within_range(sym, mod)) {
+ line[0] = 'm';
+ line[1] = '\n';
+ line[2] = 0;
+ break;
+ }
+ } else {
+ if (sym_tristate_within_range(sym, yes)) {
+ line[0] = 'y';
+ line[1] = '\n';
+ line[2] = 0;
+ break;
+ }
+ }
+ case set_no:
+ if (sym_tristate_within_range(sym, no)) {
+ line[0] = 'n';
+ line[1] = '\n';
+ line[2] = 0;
+ break;
+ }
+ case set_random:
+ do {
+ val = (tristate)(random() % 3);
+ } while (!sym_tristate_within_range(sym, val));
+ switch (val) {
+ case no: line[0] = 'n'; break;
+ case mod: line[0] = 'm'; break;
+ case yes: line[0] = 'y'; break;
+ }
+ line[1] = '\n';
+ line[2] = 0;
+ break;
+ default:
+ break;
+ }
+ printf("%s", line);
+}
+
+int conf_string(struct menu *menu)
+{
+ struct symbol *sym = menu->sym;
+ const char *def, *help;
+
+ while (1) {
+ printf("%*s%s ", indent - 1, "", menu->prompt->text);
+ printf("(%s) ", sym->name);
+ def = sym_get_string_value(sym);
+ if (sym_get_string_value(sym))
+ printf("[%s] ", def);
+ conf_askvalue(sym, def);
+ switch (line[0]) {
+ case '\n':
+ break;
+ case '?':
+ /* print help */
+ if (line[1] == '\n') {
+ help = nohelp_text;
+ if (menu->sym->help)
+ help = menu->sym->help;
+ printf("\n%s\n", menu->sym->help);
+ def = NULL;
+ break;
+ }
+ default:
+ line[strlen(line)-1] = 0;
+ def = line;
+ }
+ if (def && sym_set_string_value(sym, def))
+ return 0;
+ }
+}
+
+static int conf_sym(struct menu *menu)
+{
+ struct symbol *sym = menu->sym;
+ int type;
+ tristate oldval, newval;
+ const char *help;
+
+ while (1) {
+ printf("%*s%s ", indent - 1, "", menu->prompt->text);
+ if (sym->name)
+ printf("(%s) ", sym->name);
+ type = sym_get_type(sym);
+ putchar('[');
+ oldval = sym_get_tristate_value(sym);
+ switch (oldval) {
+ case no:
+ putchar('N');
+ break;
+ case mod:
+ putchar('M');
+ break;
+ case yes:
+ putchar('Y');
+ break;
+ }
+ if (oldval != no && sym_tristate_within_range(sym, no))
+ printf("/n");
+ if (oldval != mod && sym_tristate_within_range(sym, mod))
+ printf("/m");
+ if (oldval != yes && sym_tristate_within_range(sym, yes))
+ printf("/y");
+ if (sym->help)
+ printf("/?");
+ printf("] ");
+ conf_askvalue(sym, sym_get_string_value(sym));
+ strip(line);
+
+ switch (line[0]) {
+ case 'n':
+ case 'N':
+ newval = no;
+ if (!line[1] || !strcmp(&line[1], "o"))
+ break;
+ continue;
+ case 'm':
+ case 'M':
+ newval = mod;
+ if (!line[1])
+ break;
+ continue;
+ case 'y':
+ case 'Y':
+ newval = yes;
+ if (!line[1] || !strcmp(&line[1], "es"))
+ break;
+ continue;
+ case 0:
+ newval = oldval;
+ break;
+ case '?':
+ goto help;
+ default:
+ continue;
+ }
+ if (sym_set_tristate_value(sym, newval))
+ return 0;
+help:
+ help = nohelp_text;
+ if (sym->help)
+ help = sym->help;
+ printf("\n%s\n", help);
+ }
+}
+
+static int conf_choice(struct menu *menu)
+{
+ struct symbol *sym, *def_sym;
+ struct menu *child;
+ int type;
+ bool is_new;
+
+ sym = menu->sym;
+ type = sym_get_type(sym);
+ is_new = !sym_has_value(sym);
+ if (sym_is_changable(sym)) {
+ conf_sym(menu);
+ sym_calc_value(sym);
+ switch (sym_get_tristate_value(sym)) {
+ case no:
+ return 1;
+ case mod:
+ return 0;
+ case yes:
+ break;
+ }
+ } else {
+ switch (sym_get_tristate_value(sym)) {
+ case no:
+ return 1;
+ case mod:
+ printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
+ return 0;
+ case yes:
+ break;
+ }
+ }
+
+ while (1) {
+ int cnt, def;
+
+ printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
+ def_sym = sym_get_choice_value(sym);
+ cnt = def = 0;
+ line[0] = '0';
+ line[1] = 0;
+ for (child = menu->list; child; child = child->next) {
+ if (!menu_is_visible(child))
+ continue;
+ if (!child->sym) {
+ printf("%*c %s\n", indent, '*', menu_get_prompt(child));
+ continue;
+ }
+ cnt++;
+ if (child->sym == def_sym) {
+ def = cnt;
+ printf("%*c", indent, '>');
+ } else
+ printf("%*c", indent, ' ');
+ printf(" %d. %s", cnt, menu_get_prompt(child));
+ if (child->sym->name)
+ printf(" (%s)", child->sym->name);
+ if (!sym_has_value(child->sym))
+ printf(" (NEW)");
+ printf("\n");
+ }
+ printf("%*schoice", indent - 1, "");
+ if (cnt == 1) {
+ printf("[1]: 1\n");
+ goto conf_childs;
+ }
+ printf("[1-%d", cnt);
+ if (sym->help)
+ printf("?");
+ printf("]: ");
+ switch (input_mode) {
+ case ask_new:
+ case ask_silent:
+ if (!is_new) {
+ cnt = def;
+ printf("%d\n", cnt);
+ break;
+ }
+ check_stdin();
+ case ask_all:
+ fflush(stdout);
+ fgets(line, 128, stdin);
+ strip(line);
+ if (line[0] == '?') {
+ printf("\n%s\n", menu->sym->help ?
+ menu->sym->help : nohelp_text);
+ continue;
+ }
+ if (!line[0])
+ cnt = def;
+ else if (isdigit(line[0]))
+ cnt = atoi(line);
+ else
+ continue;
+ break;
+ case set_random:
+ def = (random() % cnt) + 1;
+ case set_default:
+ case set_yes:
+ case set_mod:
+ case set_no:
+ cnt = def;
+ printf("%d\n", cnt);
+ break;
+ }
+
+ conf_childs:
+ for (child = menu->list; child; child = child->next) {
+ if (!child->sym || !menu_is_visible(child))
+ continue;
+ if (!--cnt)
+ break;
+ }
+ if (!child)
+ continue;
+ if (line[strlen(line) - 1] == '?') {
+ printf("\n%s\n", child->sym->help ?
+ child->sym->help : nohelp_text);
+ continue;
+ }
+ sym_set_choice_value(sym, child->sym);
+ if (child->list) {
+ indent += 2;
+ conf(child->list);
+ indent -= 2;
+ }
+ return 1;
+ }
+}
+
+static void conf(struct menu *menu)
+{
+ struct symbol *sym;
+ struct property *prop;
+ struct menu *child;
+
+ if (!menu_is_visible(menu))
+ return;
+
+ sym = menu->sym;
+ prop = menu->prompt;
+ if (prop) {
+ const char *prompt;
+
+ switch (prop->type) {
+ case P_MENU:
+ if (input_mode == ask_silent && rootEntry != menu) {
+ check_conf(menu);
+ return;
+ }
+ case P_COMMENT:
+ prompt = menu_get_prompt(menu);
+ if (prompt)
+ printf("%*c\n%*c %s\n%*c\n",
+ indent, '*',
+ indent, '*', prompt,
+ indent, '*');
+ default:
+ ;
+ }
+ }
+
+ if (!sym)
+ goto conf_childs;
+
+ if (sym_is_choice(sym)) {
+ conf_choice(menu);
+ if (sym->curr.tri != mod)
+ return;
+ goto conf_childs;
+ }
+
+ switch (sym->type) {
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ conf_string(menu);
+ break;
+ default:
+ conf_sym(menu);
+ break;
+ }
+
+conf_childs:
+ if (sym)
+ indent += 2;
+ for (child = menu->list; child; child = child->next)
+ conf(child);
+ if (sym)
+ indent -= 2;
+}
+
+static void check_conf(struct menu *menu)
+{
+ struct symbol *sym;
+ struct menu *child;
+
+ if (!menu_is_visible(menu))
+ return;
+
+ sym = menu->sym;
+ if (sym) {
+ if (sym_is_changable(sym) && !sym_has_value(sym)) {
+ if (!conf_cnt++)
+ printf("*\n* Restart config...\n*\n");
+ rootEntry = menu_get_parent_menu(menu);
+ conf(rootEntry);
+ }
+ if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod)
+ return;
+ }
+
+ for (child = menu->list; child; child = child->next)
+ check_conf(child);
+}
+
+int main(int ac, char **av)
+{
+ int i = 1;
+ const char *name;
+ struct stat tmpstat;
+
+ if (ac > i && av[i][0] == '-') {
+ switch (av[i++][1]) {
+ case 'o':
+ input_mode = ask_new;
+ break;
+ case 's':
+ input_mode = ask_silent;
+ valid_stdin = isatty(0) && isatty(1) && isatty(2);
+ break;
+ case 'd':
+ input_mode = set_default;
+ break;
+ case 'D':
+ input_mode = set_default;
+ defconfig_file = av[i++];
+ if (!defconfig_file) {
+ printf("%s: No default config file specified\n",
+ av[0]);
+ exit(1);
+ }
+ break;
+ case 'n':
+ input_mode = set_no;
+ break;
+ case 'm':
+ input_mode = set_mod;
+ break;
+ case 'y':
+ input_mode = set_yes;
+ break;
+ case 'r':
+ input_mode = set_random;
+ srandom(time(NULL));
+ break;
+ case 'h':
+ case '?':
+ printf("%s [-o|-s] config\n", av[0]);
+ exit(0);
+ }
+ }
+ name = av[i];
+ if (!name) {
+ printf("%s: configuration file missing\n", av[0]);
+ }
+ conf_parse(name);
+ //zconfdump(stdout);
+ switch (input_mode) {
+ case set_default:
+ if (!defconfig_file)
+ defconfig_file = conf_get_default_confname();
+ if (conf_read(defconfig_file)) {
+ printf("***\n"
+ "*** Can't find default configuration \"%s\"!\n"
+ "***\n", defconfig_file);
+ exit(1);
+ }
+ break;
+ case ask_silent:
+ if (stat(".config", &tmpstat)) {
+ printf("***\n"
+ "*** You have not yet configured Buildroot!\n"
+ "***\n"
+ "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
+ "*** \"make menuconfig\" or \"make config\").\n"
+ "***\n");
+ exit(1);
+ }
+ case ask_all:
+ case ask_new:
+ conf_read(NULL);
+ break;
+ default:
+ break;
+ }
+
+ if (input_mode != ask_silent) {
+ rootEntry = &rootmenu;
+ conf(&rootmenu);
+ if (input_mode == ask_all) {
+ input_mode = ask_silent;
+ valid_stdin = 1;
+ }
+ }
+ do {
+ conf_cnt = 0;
+ check_conf(&rootmenu);
+ } while (conf_cnt);
+ if (conf_write(NULL)) {
+ fprintf(stderr, "\n*** Error during writing of the Buildroot configuration.\n\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/misc/buildroot/package/config/confdata.c b/misc/buildroot/package/config/confdata.c
new file mode 100644
index 000000000..144b15c04
--- /dev/null
+++ b/misc/buildroot/package/config/confdata.c
@@ -0,0 +1,397 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <sys/stat.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+const char conf_def_filename[] = ".config";
+
+const char conf_defname[] = ".defconfig";
+
+const char *conf_confnames[] = {
+ ".config",
+ conf_defname,
+ NULL,
+};
+
+static char *conf_expand_value(const signed char *in)
+{
+ struct symbol *sym;
+ const signed char *src;
+ static char res_value[SYMBOL_MAXLENGTH];
+ char *dst, name[SYMBOL_MAXLENGTH];
+
+ res_value[0] = 0;
+ dst = name;
+ while ((src = strchr(in, '$'))) {
+ strncat(res_value, in, src - in);
+ src++;
+ dst = name;
+ while (isalnum(*src) || *src == '_')
+ *dst++ = *src++;
+ *dst = 0;
+ sym = sym_lookup(name, 0);
+ sym_calc_value(sym);
+ strcat(res_value, sym_get_string_value(sym));
+ in = src;
+ }
+ strcat(res_value, in);
+
+ return res_value;
+}
+
+char *conf_get_default_confname(void)
+{
+ struct stat buf;
+ static char fullname[PATH_MAX+1];
+ char *env, *name;
+
+ name = conf_expand_value(conf_defname);
+ env = getenv(SRCTREE);
+ if (env) {
+ sprintf(fullname, "%s/%s", env, name);
+ if (!stat(fullname, &buf))
+ return fullname;
+ }
+ return name;
+}
+
+int conf_read(const char *name)
+{
+ FILE *in = NULL;
+ char line[1024];
+ char *p, *p2;
+ int lineno = 0;
+ struct symbol *sym;
+ struct property *prop;
+ struct expr *e;
+ int i;
+
+ if (name) {
+ in = zconf_fopen(name);
+ } else {
+ const char **names = conf_confnames;
+ while ((name = *names++)) {
+ name = conf_expand_value(name);
+ in = zconf_fopen(name);
+ if (in) {
+ printf("#\n"
+ "# using defaults found in %s\n"
+ "#\n", name);
+ break;
+ }
+ }
+ }
+
+ if (!in)
+ return 1;
+
+ for_all_symbols(i, sym) {
+ sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
+ sym->flags &= ~SYMBOL_VALID;
+ switch (sym->type) {
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ if (sym->user.val)
+ free(sym->user.val);
+ default:
+ sym->user.val = NULL;
+ sym->user.tri = no;
+ }
+ }
+
+ while (fgets(line, sizeof(line), in)) {
+ lineno++;
+ sym = NULL;
+ switch (line[0]) {
+ case '#':
+ if (line[1]!=' ')
+ continue;
+ p = strchr(line + 2, ' ');
+ if (!p)
+ continue;
+ *p++ = 0;
+ if (strncmp(p, "is not set", 10))
+ continue;
+ sym = sym_find(line + 2);
+ if (!sym) {
+ fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 2);
+ break;
+ }
+ switch (sym->type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ sym->user.tri = no;
+ sym->flags &= ~SYMBOL_NEW;
+ break;
+ default:
+ ;
+ }
+ break;
+
+ case 'A' ... 'Z':
+ p = strchr(line, '=');
+ if (!p)
+ continue;
+ *p++ = 0;
+ p2 = strchr(p, '\n');
+ if (p2)
+ *p2 = 0;
+ sym = sym_find(line);
+ if (!sym) {
+ fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line);
+ break;
+ }
+ switch (sym->type) {
+ case S_TRISTATE:
+ if (p[0] == 'm') {
+ sym->user.tri = mod;
+ sym->flags &= ~SYMBOL_NEW;
+ break;
+ }
+ case S_BOOLEAN:
+ if (p[0] == 'y') {
+ sym->user.tri = yes;
+ sym->flags &= ~SYMBOL_NEW;
+ break;
+ }
+ if (p[0] == 'n') {
+ sym->user.tri = no;
+ sym->flags &= ~SYMBOL_NEW;
+ break;
+ }
+ break;
+ case S_STRING:
+ if (*p++ != '"')
+ break;
+ for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
+ if (*p2 == '"') {
+ *p2 = 0;
+ break;
+ }
+ memmove(p2, p2 + 1, strlen(p2));
+ }
+ if (!p2) {
+ fprintf(stderr, "%s:%d: invalid string found\n", name, lineno);
+ exit(1);
+ }
+ case S_INT:
+ case S_HEX:
+ if (sym_string_valid(sym, p)) {
+ sym->user.val = strdup(p);
+ sym->flags &= ~SYMBOL_NEW;
+ } else {
+ fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name);
+ exit(1);
+ }
+ break;
+ default:
+ ;
+ }
+ break;
+ case '\n':
+ break;
+ default:
+ continue;
+ }
+ if (sym && sym_is_choice_value(sym)) {
+ struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
+ switch (sym->user.tri) {
+ case no:
+ break;
+ case mod:
+ if (cs->user.tri == yes)
+ /* warn? */;
+ break;
+ case yes:
+ if (cs->user.tri != no)
+ /* warn? */;
+ cs->user.val = sym;
+ break;
+ }
+ cs->user.tri = E_OR(cs->user.tri, sym->user.tri);
+ cs->flags &= ~SYMBOL_NEW;
+ }
+ }
+ fclose(in);
+
+ if (modules_sym)
+ sym_calc_value(modules_sym);
+ for_all_symbols(i, sym) {
+ sym_calc_value(sym);
+ if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
+ if (sym->visible == no)
+ sym->flags |= SYMBOL_NEW;
+ switch (sym->type) {
+ case S_STRING:
+ case S_INT:
+ case S_HEX:
+ if (!sym_string_within_range(sym, sym->user.val))
+ sym->flags |= SYMBOL_NEW;
+ default:
+ break;
+ }
+ }
+ if (!sym_is_choice(sym))
+ continue;
+ prop = sym_get_choice_prop(sym);
+ for (e = prop->expr; e; e = e->left.expr)
+ if (e->right.sym->visible != no)
+ sym->flags |= e->right.sym->flags & SYMBOL_NEW;
+ }
+
+ sym_change_count = 1;
+
+ return 0;
+}
+
+int conf_write(const char *name)
+{
+ FILE *out;
+ struct symbol *sym;
+ struct menu *menu;
+ const char *basename;
+ char dirname[128], tmpname[128], newname[128];
+ int type, l;
+ const char *str;
+
+ dirname[0] = 0;
+ if (name && name[0]) {
+ struct stat st;
+ char *slash;
+
+ if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
+ strcpy(dirname, name);
+ strcat(dirname, "/");
+ basename = conf_def_filename;
+ } else if ((slash = strrchr(name, '/'))) {
+ int size = slash - name + 1;
+ memcpy(dirname, name, size);
+ dirname[size] = 0;
+ if (slash[1])
+ basename = slash + 1;
+ else
+ basename = conf_def_filename;
+ } else
+ basename = name;
+ } else
+ basename = conf_def_filename;
+
+ sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid());
+ out = fopen(newname, "w");
+ if (!out)
+ return 1;
+ fprintf(out, "#\n"
+ "# Automatically generated make config: don't edit\n"
+ "#\n");
+
+ if (!sym_change_count)
+ sym_clear_all_valid();
+
+ menu = rootmenu.list;
+ while (menu) {
+ sym = menu->sym;
+ if (!sym) {
+ if (!menu_is_visible(menu))
+ goto next;
+ str = menu_get_prompt(menu);
+ fprintf(out, "\n"
+ "#\n"
+ "# %s\n"
+ "#\n", str);
+ } else if (!(sym->flags & SYMBOL_CHOICE)) {
+ sym_calc_value(sym);
+ if (!(sym->flags & SYMBOL_WRITE))
+ goto next;
+ sym->flags &= ~SYMBOL_WRITE;
+ type = sym->type;
+ if (type == S_TRISTATE) {
+ sym_calc_value(modules_sym);
+ if (modules_sym->curr.tri == no)
+ type = S_BOOLEAN;
+ }
+ switch (type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ switch (sym_get_tristate_value(sym)) {
+ case no:
+ fprintf(out, "# %s is not set\n", sym->name);
+ break;
+ case mod:
+ fprintf(out, "%s=m\n", sym->name);
+ break;
+ case yes:
+ fprintf(out, "%s=y\n", sym->name);
+ break;
+ }
+ break;
+ case S_STRING:
+ // fix me
+ str = sym_get_string_value(sym);
+ fprintf(out, "%s=\"", sym->name);
+ do {
+ l = strcspn(str, "\"\\");
+ if (l) {
+ fwrite(str, l, 1, out);
+ }
+ str += l;
+ while (*str == '\\' || *str == '"') {
+ fprintf(out, "\\%c", *str);
+ str++;
+ }
+ } while (*str);
+ fputs("\"\n", out);
+ break;
+ case S_HEX:
+ str = sym_get_string_value(sym);
+ if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
+ fprintf(out, "%s=%s\n", sym->name, str);
+ break;
+ }
+ case S_INT:
+ str = sym_get_string_value(sym);
+ fprintf(out, "%s=%s\n", sym->name, str);
+ break;
+ }
+ }
+
+ next:
+ if (menu->list) {
+ menu = menu->list;
+ continue;
+ }
+ if (menu->next)
+ menu = menu->next;
+ else while ((menu = menu->parent)) {
+ if (menu->next) {
+ menu = menu->next;
+ break;
+ }
+ }
+ }
+ fclose(out);
+ file_write_dep(NULL);
+ if (!name || basename != conf_def_filename) {
+ if (!name)
+ name = conf_def_filename;
+ sprintf(tmpname, "%s.old", name);
+ rename(name, tmpname);
+ }
+ sprintf(tmpname, "%s%s", dirname, basename);
+ if (rename(newname, tmpname))
+ return 1;
+
+ sym_change_count = 0;
+
+ return 0;
+}
diff --git a/misc/buildroot/package/config/expr.c b/misc/buildroot/package/config/expr.c
new file mode 100644
index 000000000..30e4f9d69
--- /dev/null
+++ b/misc/buildroot/package/config/expr.c
@@ -0,0 +1,1099 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+#define DEBUG_EXPR 0
+
+struct expr *expr_alloc_symbol(struct symbol *sym)
+{
+ struct expr *e = malloc(sizeof(*e));
+ memset(e, 0, sizeof(*e));
+ e->type = E_SYMBOL;
+ e->left.sym = sym;
+ return e;
+}
+
+struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
+{
+ struct expr *e = malloc(sizeof(*e));
+ memset(e, 0, sizeof(*e));
+ e->type = type;
+ e->left.expr = ce;
+ return e;
+}
+
+struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
+{
+ struct expr *e = malloc(sizeof(*e));
+ memset(e, 0, sizeof(*e));
+ e->type = type;
+ e->left.expr = e1;
+ e->right.expr = e2;
+ return e;
+}
+
+struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
+{
+ struct expr *e = malloc(sizeof(*e));
+ memset(e, 0, sizeof(*e));
+ e->type = type;
+ e->left.sym = s1;
+ e->right.sym = s2;
+ return e;
+}
+
+struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
+{
+ if (!e1)
+ return e2;
+ return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
+}
+
+struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
+{
+ if (!e1)
+ return e2;
+ return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
+}
+
+struct expr *expr_copy(struct expr *org)
+{
+ struct expr *e;
+
+ if (!org)
+ return NULL;
+
+ e = malloc(sizeof(*org));
+ memcpy(e, org, sizeof(*org));
+ switch (org->type) {
+ case E_SYMBOL:
+ e->left = org->left;
+ break;
+ case E_NOT:
+ e->left.expr = expr_copy(org->left.expr);
+ break;
+ case E_EQUAL:
+ case E_UNEQUAL:
+ e->left.sym = org->left.sym;
+ e->right.sym = org->right.sym;
+ break;
+ case E_AND:
+ case E_OR:
+ case E_CHOICE:
+ e->left.expr = expr_copy(org->left.expr);
+ e->right.expr = expr_copy(org->right.expr);
+ break;
+ default:
+ printf("can't copy type %d\n", e->type);
+ free(e);
+ e = NULL;
+ break;
+ }
+
+ return e;
+}
+
+void expr_free(struct expr *e)
+{
+ if (!e)
+ return;
+
+ switch (e->type) {
+ case E_SYMBOL:
+ break;
+ case E_NOT:
+ expr_free(e->left.expr);
+ return;
+ case E_EQUAL:
+ case E_UNEQUAL:
+ break;
+ case E_OR:
+ case E_AND:
+ expr_free(e->left.expr);
+ expr_free(e->right.expr);
+ break;
+ default:
+ printf("how to free type %d?\n", e->type);
+ break;
+ }
+ free(e);
+}
+
+static int trans_count;
+
+#define e1 (*ep1)
+#define e2 (*ep2)
+
+static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
+{
+ if (e1->type == type) {
+ __expr_eliminate_eq(type, &e1->left.expr, &e2);
+ __expr_eliminate_eq(type, &e1->right.expr, &e2);
+ return;
+ }
+ if (e2->type == type) {
+ __expr_eliminate_eq(type, &e1, &e2->left.expr);
+ __expr_eliminate_eq(type, &e1, &e2->right.expr);
+ return;
+ }
+ if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
+ e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO)))
+ return;
+ if (!expr_eq(e1, e2))
+ return;
+ trans_count++;
+ expr_free(e1); expr_free(e2);
+ switch (type) {
+ case E_OR:
+ e1 = expr_alloc_symbol(&symbol_no);
+ e2 = expr_alloc_symbol(&symbol_no);
+ break;
+ case E_AND:
+ e1 = expr_alloc_symbol(&symbol_yes);
+ e2 = expr_alloc_symbol(&symbol_yes);
+ break;
+ default:
+ ;
+ }
+}
+
+void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
+{
+ if (!e1 || !e2)
+ return;
+ switch (e1->type) {
+ case E_OR:
+ case E_AND:
+ __expr_eliminate_eq(e1->type, ep1, ep2);
+ default:
+ ;
+ }
+ if (e1->type != e2->type) switch (e2->type) {
+ case E_OR:
+ case E_AND:
+ __expr_eliminate_eq(e2->type, ep1, ep2);
+ default:
+ ;
+ }
+ e1 = expr_eliminate_yn(e1);
+ e2 = expr_eliminate_yn(e2);
+}
+
+#undef e1
+#undef e2
+
+int expr_eq(struct expr *e1, struct expr *e2)
+{
+ int res, old_count;
+
+ if (e1->type != e2->type)
+ return 0;
+ switch (e1->type) {
+ case E_EQUAL:
+ case E_UNEQUAL:
+ return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
+ case E_SYMBOL:
+ return e1->left.sym == e2->left.sym;
+ case E_NOT:
+ return expr_eq(e1->left.expr, e2->left.expr);
+ case E_AND:
+ case E_OR:
+ e1 = expr_copy(e1);
+ e2 = expr_copy(e2);
+ old_count = trans_count;
+ expr_eliminate_eq(&e1, &e2);
+ res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
+ e1->left.sym == e2->left.sym);
+ expr_free(e1);
+ expr_free(e2);
+ trans_count = old_count;
+ return res;
+ case E_CHOICE:
+ case E_RANGE:
+ case E_NONE:
+ /* panic */;
+ }
+
+ if (DEBUG_EXPR) {
+ expr_fprint(e1, stdout);
+ printf(" = ");
+ expr_fprint(e2, stdout);
+ printf(" ?\n");
+ }
+
+ return 0;
+}
+
+struct expr *expr_eliminate_yn(struct expr *e)
+{
+ struct expr *tmp;
+
+ if (e) switch (e->type) {
+ case E_AND:
+ e->left.expr = expr_eliminate_yn(e->left.expr);
+ e->right.expr = expr_eliminate_yn(e->right.expr);
+ if (e->left.expr->type == E_SYMBOL) {
+ if (e->left.expr->left.sym == &symbol_no) {
+ expr_free(e->left.expr);
+ expr_free(e->right.expr);
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_no;
+ e->right.expr = NULL;
+ return e;
+ } else if (e->left.expr->left.sym == &symbol_yes) {
+ free(e->left.expr);
+ tmp = e->right.expr;
+ *e = *(e->right.expr);
+ free(tmp);
+ return e;
+ }
+ }
+ if (e->right.expr->type == E_SYMBOL) {
+ if (e->right.expr->left.sym == &symbol_no) {
+ expr_free(e->left.expr);
+ expr_free(e->right.expr);
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_no;
+ e->right.expr = NULL;
+ return e;
+ } else if (e->right.expr->left.sym == &symbol_yes) {
+ free(e->right.expr);
+ tmp = e->left.expr;
+ *e = *(e->left.expr);
+ free(tmp);
+ return e;
+ }
+ }
+ break;
+ case E_OR:
+ e->left.expr = expr_eliminate_yn(e->left.expr);
+ e->right.expr = expr_eliminate_yn(e->right.expr);
+ if (e->left.expr->type == E_SYMBOL) {
+ if (e->left.expr->left.sym == &symbol_no) {
+ free(e->left.expr);
+ tmp = e->right.expr;
+ *e = *(e->right.expr);
+ free(tmp);
+ return e;
+ } else if (e->left.expr->left.sym == &symbol_yes) {
+ expr_free(e->left.expr);
+ expr_free(e->right.expr);
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_yes;
+ e->right.expr = NULL;
+ return e;
+ }
+ }
+ if (e->right.expr->type == E_SYMBOL) {
+ if (e->right.expr->left.sym == &symbol_no) {
+ free(e->right.expr);
+ tmp = e->left.expr;
+ *e = *(e->left.expr);
+ free(tmp);
+ return e;
+ } else if (e->right.expr->left.sym == &symbol_yes) {
+ expr_free(e->left.expr);
+ expr_free(e->right.expr);
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_yes;
+ e->right.expr = NULL;
+ return e;
+ }
+ }
+ break;
+ default:
+ ;
+ }
+ return e;
+}
+
+/*
+ * bool FOO!=n => FOO
+ */
+struct expr *expr_trans_bool(struct expr *e)
+{
+ if (!e)
+ return NULL;
+ switch (e->type) {
+ case E_AND:
+ case E_OR:
+ case E_NOT:
+ e->left.expr = expr_trans_bool(e->left.expr);
+ e->right.expr = expr_trans_bool(e->right.expr);
+ break;
+ case E_UNEQUAL:
+ // FOO!=n -> FOO
+ if (e->left.sym->type == S_TRISTATE) {
+ if (e->right.sym == &symbol_no) {
+ e->type = E_SYMBOL;
+ e->right.sym = NULL;
+ }
+ }
+ break;
+ default:
+ ;
+ }
+ return e;
+}
+
+/*
+ * e1 || e2 -> ?
+ */
+struct expr *expr_join_or(struct expr *e1, struct expr *e2)
+{
+ struct expr *tmp;
+ struct symbol *sym1, *sym2;
+
+ if (expr_eq(e1, e2))
+ return expr_copy(e1);
+ if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
+ return NULL;
+ if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
+ return NULL;
+ if (e1->type == E_NOT) {
+ tmp = e1->left.expr;
+ if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
+ return NULL;
+ sym1 = tmp->left.sym;
+ } else
+ sym1 = e1->left.sym;
+ if (e2->type == E_NOT) {
+ if (e2->left.expr->type != E_SYMBOL)
+ return NULL;
+ sym2 = e2->left.expr->left.sym;
+ } else
+ sym2 = e2->left.sym;
+ if (sym1 != sym2)
+ return NULL;
+ if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
+ return NULL;
+ if (sym1->type == S_TRISTATE) {
+ if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
+ ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
+ (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) {
+ // (a='y') || (a='m') -> (a!='n')
+ return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no);
+ }
+ if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
+ ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
+ (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) {
+ // (a='y') || (a='n') -> (a!='m')
+ return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod);
+ }
+ if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
+ ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
+ (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) {
+ // (a='m') || (a='n') -> (a!='y')
+ return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes);
+ }
+ }
+ if (sym1->type == S_BOOLEAN && sym1 == sym2) {
+ if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) ||
+ (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL))
+ return expr_alloc_symbol(&symbol_yes);
+ }
+
+ if (DEBUG_EXPR) {
+ printf("optimize (");
+ expr_fprint(e1, stdout);
+ printf(") || (");
+ expr_fprint(e2, stdout);
+ printf(")?\n");
+ }
+ return NULL;
+}
+
+struct expr *expr_join_and(struct expr *e1, struct expr *e2)
+{
+ struct expr *tmp;
+ struct symbol *sym1, *sym2;
+
+ if (expr_eq(e1, e2))
+ return expr_copy(e1);
+ if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
+ return NULL;
+ if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
+ return NULL;
+ if (e1->type == E_NOT) {
+ tmp = e1->left.expr;
+ if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
+ return NULL;
+ sym1 = tmp->left.sym;
+ } else
+ sym1 = e1->left.sym;
+ if (e2->type == E_NOT) {
+ if (e2->left.expr->type != E_SYMBOL)
+ return NULL;
+ sym2 = e2->left.expr->left.sym;
+ } else
+ sym2 = e2->left.sym;
+ if (sym1 != sym2)
+ return NULL;
+ if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
+ return NULL;
+
+ if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
+ (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
+ // (a) && (a='y') -> (a='y')
+ return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
+
+ if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
+ (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
+ // (a) && (a!='n') -> (a)
+ return expr_alloc_symbol(sym1);
+
+ if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) ||
+ (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod))
+ // (a) && (a!='m') -> (a='y')
+ return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
+
+ if (sym1->type == S_TRISTATE) {
+ if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
+ // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
+ sym2 = e1->right.sym;
+ if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
+ return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
+ : expr_alloc_symbol(&symbol_no);
+ }
+ if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
+ // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
+ sym2 = e2->right.sym;
+ if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
+ return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
+ : expr_alloc_symbol(&symbol_no);
+ }
+ if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
+ ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
+ (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
+ // (a!='y') && (a!='n') -> (a='m')
+ return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
+
+ if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
+ ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
+ (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
+ // (a!='y') && (a!='m') -> (a='n')
+ return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
+
+ if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
+ ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
+ (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
+ // (a!='m') && (a!='n') -> (a='m')
+ return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
+
+ if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
+ (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
+ (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
+ (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
+ return NULL;
+ }
+
+ if (DEBUG_EXPR) {
+ printf("optimize (");
+ expr_fprint(e1, stdout);
+ printf(") && (");
+ expr_fprint(e2, stdout);
+ printf(")?\n");
+ }
+ return NULL;
+}
+
+static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
+{
+#define e1 (*ep1)
+#define e2 (*ep2)
+ struct expr *tmp;
+
+ if (e1->type == type) {
+ expr_eliminate_dups1(type, &e1->left.expr, &e2);
+ expr_eliminate_dups1(type, &e1->right.expr, &e2);
+ return;
+ }
+ if (e2->type == type) {
+ expr_eliminate_dups1(type, &e1, &e2->left.expr);
+ expr_eliminate_dups1(type, &e1, &e2->right.expr);
+ return;
+ }
+ if (e1 == e2)
+ return;
+
+ switch (e1->type) {
+ case E_OR: case E_AND:
+ expr_eliminate_dups1(e1->type, &e1, &e1);
+ default:
+ ;
+ }
+
+ switch (type) {
+ case E_OR:
+ tmp = expr_join_or(e1, e2);
+ if (tmp) {
+ expr_free(e1); expr_free(e2);
+ e1 = expr_alloc_symbol(&symbol_no);
+ e2 = tmp;
+ trans_count++;
+ }
+ break;
+ case E_AND:
+ tmp = expr_join_and(e1, e2);
+ if (tmp) {
+ expr_free(e1); expr_free(e2);
+ e1 = expr_alloc_symbol(&symbol_yes);
+ e2 = tmp;
+ trans_count++;
+ }
+ break;
+ default:
+ ;
+ }
+#undef e1
+#undef e2
+}
+
+static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2)
+{
+#define e1 (*ep1)
+#define e2 (*ep2)
+ struct expr *tmp, *tmp1, *tmp2;
+
+ if (e1->type == type) {
+ expr_eliminate_dups2(type, &e1->left.expr, &e2);
+ expr_eliminate_dups2(type, &e1->right.expr, &e2);
+ return;
+ }
+ if (e2->type == type) {
+ expr_eliminate_dups2(type, &e1, &e2->left.expr);
+ expr_eliminate_dups2(type, &e1, &e2->right.expr);
+ }
+ if (e1 == e2)
+ return;
+
+ switch (e1->type) {
+ case E_OR:
+ expr_eliminate_dups2(e1->type, &e1, &e1);
+ // (FOO || BAR) && (!FOO && !BAR) -> n
+ tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
+ tmp2 = expr_copy(e2);
+ tmp = expr_extract_eq_and(&tmp1, &tmp2);
+ if (expr_is_yes(tmp1)) {
+ expr_free(e1);
+ e1 = expr_alloc_symbol(&symbol_no);
+ trans_count++;
+ }
+ expr_free(tmp2);
+ expr_free(tmp1);
+ expr_free(tmp);
+ break;
+ case E_AND:
+ expr_eliminate_dups2(e1->type, &e1, &e1);
+ // (FOO && BAR) || (!FOO || !BAR) -> y
+ tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
+ tmp2 = expr_copy(e2);
+ tmp = expr_extract_eq_or(&tmp1, &tmp2);
+ if (expr_is_no(tmp1)) {
+ expr_free(e1);
+ e1 = expr_alloc_symbol(&symbol_yes);
+ trans_count++;
+ }
+ expr_free(tmp2);
+ expr_free(tmp1);
+ expr_free(tmp);
+ break;
+ default:
+ ;
+ }
+#undef e1
+#undef e2
+}
+
+struct expr *expr_eliminate_dups(struct expr *e)
+{
+ int oldcount;
+ if (!e)
+ return e;
+
+ oldcount = trans_count;
+ while (1) {
+ trans_count = 0;
+ switch (e->type) {
+ case E_OR: case E_AND:
+ expr_eliminate_dups1(e->type, &e, &e);
+ expr_eliminate_dups2(e->type, &e, &e);
+ default:
+ ;
+ }
+ if (!trans_count)
+ break;
+ e = expr_eliminate_yn(e);
+ }
+ trans_count = oldcount;
+ return e;
+}
+
+struct expr *expr_transform(struct expr *e)
+{
+ struct expr *tmp;
+
+ if (!e)
+ return NULL;
+ switch (e->type) {
+ case E_EQUAL:
+ case E_UNEQUAL:
+ case E_SYMBOL:
+ case E_CHOICE:
+ break;
+ default:
+ e->left.expr = expr_transform(e->left.expr);
+ e->right.expr = expr_transform(e->right.expr);
+ }
+
+ switch (e->type) {
+ case E_EQUAL:
+ if (e->left.sym->type != S_BOOLEAN)
+ break;
+ if (e->right.sym == &symbol_no) {
+ e->type = E_NOT;
+ e->left.expr = expr_alloc_symbol(e->left.sym);
+ e->right.sym = NULL;
+ break;
+ }
+ if (e->right.sym == &symbol_mod) {
+ printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_no;
+ e->right.sym = NULL;
+ break;
+ }
+ if (e->right.sym == &symbol_yes) {
+ e->type = E_SYMBOL;
+ e->right.sym = NULL;
+ break;
+ }
+ break;
+ case E_UNEQUAL:
+ if (e->left.sym->type != S_BOOLEAN)
+ break;
+ if (e->right.sym == &symbol_no) {
+ e->type = E_SYMBOL;
+ e->right.sym = NULL;
+ break;
+ }
+ if (e->right.sym == &symbol_mod) {
+ printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_yes;
+ e->right.sym = NULL;
+ break;
+ }
+ if (e->right.sym == &symbol_yes) {
+ e->type = E_NOT;
+ e->left.expr = expr_alloc_symbol(e->left.sym);
+ e->right.sym = NULL;
+ break;
+ }
+ break;
+ case E_NOT:
+ switch (e->left.expr->type) {
+ case E_NOT:
+ // !!a -> a
+ tmp = e->left.expr->left.expr;
+ free(e->left.expr);
+ free(e);
+ e = tmp;
+ e = expr_transform(e);
+ break;
+ case E_EQUAL:
+ case E_UNEQUAL:
+ // !a='x' -> a!='x'
+ tmp = e->left.expr;
+ free(e);
+ e = tmp;
+ e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
+ break;
+ case E_OR:
+ // !(a || b) -> !a && !b
+ tmp = e->left.expr;
+ e->type = E_AND;
+ e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
+ tmp->type = E_NOT;
+ tmp->right.expr = NULL;
+ e = expr_transform(e);
+ break;
+ case E_AND:
+ // !(a && b) -> !a || !b
+ tmp = e->left.expr;
+ e->type = E_OR;
+ e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
+ tmp->type = E_NOT;
+ tmp->right.expr = NULL;
+ e = expr_transform(e);
+ break;
+ case E_SYMBOL:
+ if (e->left.expr->left.sym == &symbol_yes) {
+ // !'y' -> 'n'
+ tmp = e->left.expr;
+ free(e);
+ e = tmp;
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_no;
+ break;
+ }
+ if (e->left.expr->left.sym == &symbol_mod) {
+ // !'m' -> 'm'
+ tmp = e->left.expr;
+ free(e);
+ e = tmp;
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_mod;
+ break;
+ }
+ if (e->left.expr->left.sym == &symbol_no) {
+ // !'n' -> 'y'
+ tmp = e->left.expr;
+ free(e);
+ e = tmp;
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_yes;
+ break;
+ }
+ break;
+ default:
+ ;
+ }
+ break;
+ default:
+ ;
+ }
+ return e;
+}
+
+int expr_contains_symbol(struct expr *dep, struct symbol *sym)
+{
+ if (!dep)
+ return 0;
+
+ switch (dep->type) {
+ case E_AND:
+ case E_OR:
+ return expr_contains_symbol(dep->left.expr, sym) ||
+ expr_contains_symbol(dep->right.expr, sym);
+ case E_SYMBOL:
+ return dep->left.sym == sym;
+ case E_EQUAL:
+ case E_UNEQUAL:
+ return dep->left.sym == sym ||
+ dep->right.sym == sym;
+ case E_NOT:
+ return expr_contains_symbol(dep->left.expr, sym);
+ default:
+ ;
+ }
+ return 0;
+}
+
+bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
+{
+ if (!dep)
+ return false;
+
+ switch (dep->type) {
+ case E_AND:
+ return expr_depends_symbol(dep->left.expr, sym) ||
+ expr_depends_symbol(dep->right.expr, sym);
+ case E_SYMBOL:
+ return dep->left.sym == sym;
+ case E_EQUAL:
+ if (dep->left.sym == sym) {
+ if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
+ return true;
+ }
+ break;
+ case E_UNEQUAL:
+ if (dep->left.sym == sym) {
+ if (dep->right.sym == &symbol_no)
+ return true;
+ }
+ break;
+ default:
+ ;
+ }
+ return false;
+}
+
+struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
+{
+ struct expr *tmp = NULL;
+ expr_extract_eq(E_AND, &tmp, ep1, ep2);
+ if (tmp) {
+ *ep1 = expr_eliminate_yn(*ep1);
+ *ep2 = expr_eliminate_yn(*ep2);
+ }
+ return tmp;
+}
+
+struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
+{
+ struct expr *tmp = NULL;
+ expr_extract_eq(E_OR, &tmp, ep1, ep2);
+ if (tmp) {
+ *ep1 = expr_eliminate_yn(*ep1);
+ *ep2 = expr_eliminate_yn(*ep2);
+ }
+ return tmp;
+}
+
+void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
+{
+#define e1 (*ep1)
+#define e2 (*ep2)
+ if (e1->type == type) {
+ expr_extract_eq(type, ep, &e1->left.expr, &e2);
+ expr_extract_eq(type, ep, &e1->right.expr, &e2);
+ return;
+ }
+ if (e2->type == type) {
+ expr_extract_eq(type, ep, ep1, &e2->left.expr);
+ expr_extract_eq(type, ep, ep1, &e2->right.expr);
+ return;
+ }
+ if (expr_eq(e1, e2)) {
+ *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
+ expr_free(e2);
+ if (type == E_AND) {
+ e1 = expr_alloc_symbol(&symbol_yes);
+ e2 = expr_alloc_symbol(&symbol_yes);
+ } else if (type == E_OR) {
+ e1 = expr_alloc_symbol(&symbol_no);
+ e2 = expr_alloc_symbol(&symbol_no);
+ }
+ }
+#undef e1
+#undef e2
+}
+
+struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
+{
+ struct expr *e1, *e2;
+
+ if (!e) {
+ e = expr_alloc_symbol(sym);
+ if (type == E_UNEQUAL)
+ e = expr_alloc_one(E_NOT, e);
+ return e;
+ }
+ switch (e->type) {
+ case E_AND:
+ e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
+ e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
+ if (sym == &symbol_yes)
+ e = expr_alloc_two(E_AND, e1, e2);
+ if (sym == &symbol_no)
+ e = expr_alloc_two(E_OR, e1, e2);
+ if (type == E_UNEQUAL)
+ e = expr_alloc_one(E_NOT, e);
+ return e;
+ case E_OR:
+ e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
+ e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
+ if (sym == &symbol_yes)
+ e = expr_alloc_two(E_OR, e1, e2);
+ if (sym == &symbol_no)
+ e = expr_alloc_two(E_AND, e1, e2);
+ if (type == E_UNEQUAL)
+ e = expr_alloc_one(E_NOT, e);
+ return e;
+ case E_NOT:
+ return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
+ case E_UNEQUAL:
+ case E_EQUAL:
+ if (type == E_EQUAL) {
+ if (sym == &symbol_yes)
+ return expr_copy(e);
+ if (sym == &symbol_mod)
+ return expr_alloc_symbol(&symbol_no);
+ if (sym == &symbol_no)
+ return expr_alloc_one(E_NOT, expr_copy(e));
+ } else {
+ if (sym == &symbol_yes)
+ return expr_alloc_one(E_NOT, expr_copy(e));
+ if (sym == &symbol_mod)
+ return expr_alloc_symbol(&symbol_yes);
+ if (sym == &symbol_no)
+ return expr_copy(e);
+ }
+ break;
+ case E_SYMBOL:
+ return expr_alloc_comp(type, e->left.sym, sym);
+ case E_CHOICE:
+ case E_RANGE:
+ case E_NONE:
+ /* panic */;
+ }
+ return NULL;
+}
+
+tristate expr_calc_value(struct expr *e)
+{
+ tristate val1, val2;
+ const char *str1, *str2;
+
+ if (!e)
+ return yes;
+
+ switch (e->type) {
+ case E_SYMBOL:
+ sym_calc_value(e->left.sym);
+ return e->left.sym->curr.tri;
+ case E_AND:
+ val1 = expr_calc_value(e->left.expr);
+ val2 = expr_calc_value(e->right.expr);
+ return E_AND(val1, val2);
+ case E_OR:
+ val1 = expr_calc_value(e->left.expr);
+ val2 = expr_calc_value(e->right.expr);
+ return E_OR(val1, val2);
+ case E_NOT:
+ val1 = expr_calc_value(e->left.expr);
+ return E_NOT(val1);
+ case E_EQUAL:
+ sym_calc_value(e->left.sym);
+ sym_calc_value(e->right.sym);
+ str1 = sym_get_string_value(e->left.sym);
+ str2 = sym_get_string_value(e->right.sym);
+ return !strcmp(str1, str2) ? yes : no;
+ case E_UNEQUAL:
+ sym_calc_value(e->left.sym);
+ sym_calc_value(e->right.sym);
+ str1 = sym_get_string_value(e->left.sym);
+ str2 = sym_get_string_value(e->right.sym);
+ return !strcmp(str1, str2) ? no : yes;
+ default:
+ printf("expr_calc_value: %d?\n", e->type);
+ return no;
+ }
+}
+
+int expr_compare_type(enum expr_type t1, enum expr_type t2)
+{
+#if 0
+ return 1;
+#else
+ if (t1 == t2)
+ return 0;
+ switch (t1) {
+ case E_EQUAL:
+ case E_UNEQUAL:
+ if (t2 == E_NOT)
+ return 1;
+ case E_NOT:
+ if (t2 == E_AND)
+ return 1;
+ case E_AND:
+ if (t2 == E_OR)
+ return 1;
+ case E_OR:
+ if (t2 == E_CHOICE)
+ return 1;
+ case E_CHOICE:
+ if (t2 == 0)
+ return 1;
+ default:
+ return -1;
+ }
+ printf("[%dgt%d?]", t1, t2);
+ return 0;
+#endif
+}
+
+void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken)
+{
+ if (!e) {
+ fn(data, "y");
+ return;
+ }
+
+ if (expr_compare_type(prevtoken, e->type) > 0)
+ fn(data, "(");
+ switch (e->type) {
+ case E_SYMBOL:
+ if (e->left.sym->name)
+ fn(data, e->left.sym->name);
+ else
+ fn(data, "<choice>");
+ break;
+ case E_NOT:
+ fn(data, "!");
+ expr_print(e->left.expr, fn, data, E_NOT);
+ break;
+ case E_EQUAL:
+ fn(data, e->left.sym->name);
+ fn(data, "=");
+ fn(data, e->right.sym->name);
+ break;
+ case E_UNEQUAL:
+ fn(data, e->left.sym->name);
+ fn(data, "!=");
+ fn(data, e->right.sym->name);
+ break;
+ case E_OR:
+ expr_print(e->left.expr, fn, data, E_OR);
+ fn(data, " || ");
+ expr_print(e->right.expr, fn, data, E_OR);
+ break;
+ case E_AND:
+ expr_print(e->left.expr, fn, data, E_AND);
+ fn(data, " && ");
+ expr_print(e->right.expr, fn, data, E_AND);
+ break;
+ case E_CHOICE:
+ fn(data, e->right.sym->name);
+ if (e->left.expr) {
+ fn(data, " ^ ");
+ expr_print(e->left.expr, fn, data, E_CHOICE);
+ }
+ break;
+ case E_RANGE:
+ fn(data, "[");
+ fn(data, e->left.sym->name);
+ fn(data, " ");
+ fn(data, e->right.sym->name);
+ fn(data, "]");
+ break;
+ default:
+ {
+ char buf[32];
+ sprintf(buf, "<unknown type %d>", e->type);
+ fn(data, buf);
+ break;
+ }
+ }
+ if (expr_compare_type(prevtoken, e->type) > 0)
+ fn(data, ")");
+}
+
+static void expr_print_file_helper(void *data, const char *str)
+{
+ fwrite(str, strlen(str), 1, data);
+}
+
+void expr_fprint(struct expr *e, FILE *out)
+{
+ expr_print(e, expr_print_file_helper, out, E_NONE);
+}
+
+static void expr_print_gstr_helper(void *data, const char *str)
+{
+ str_append((struct gstr*)data, str);
+}
+
+void expr_gstr_print(struct expr *e, struct gstr *gs)
+{
+ expr_print(e, expr_print_gstr_helper, gs, E_NONE);
+}
diff --git a/misc/buildroot/package/config/expr.h b/misc/buildroot/package/config/expr.h
new file mode 100644
index 000000000..7d39ff43e
--- /dev/null
+++ b/misc/buildroot/package/config/expr.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#ifndef EXPR_H
+#define EXPR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif
+
+struct file {
+ struct file *next;
+ struct file *parent;
+ char *name;
+ int lineno;
+ int flags;
+};
+
+#define FILE_BUSY 0x0001
+#define FILE_SCANNED 0x0002
+#define FILE_PRINTED 0x0004
+
+typedef enum tristate {
+ no, mod, yes
+} tristate;
+
+enum expr_type {
+ E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE
+};
+
+union expr_data {
+ struct expr *expr;
+ struct symbol *sym;
+};
+
+struct expr {
+ enum expr_type type;
+ union expr_data left, right;
+};
+
+#define E_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2))
+#define E_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2))
+#define E_NOT(dep) (2-(dep))
+
+struct expr_value {
+ struct expr *expr;
+ tristate tri;
+};
+
+struct symbol_value {
+ void *val;
+ tristate tri;
+};
+
+enum symbol_type {
+ S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
+};
+
+struct symbol {
+ struct symbol *next;
+ char *name;
+ char *help;
+ enum symbol_type type;
+ struct symbol_value curr, user;
+ tristate visible;
+ int flags;
+ struct property *prop;
+ struct expr *dep, *dep2;
+ struct expr_value rev_dep;
+};
+
+#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
+
+#define SYMBOL_YES 0x0001
+#define SYMBOL_MOD 0x0002
+#define SYMBOL_NO 0x0004
+#define SYMBOL_CONST 0x0007
+#define SYMBOL_CHECK 0x0008
+#define SYMBOL_CHOICE 0x0010
+#define SYMBOL_CHOICEVAL 0x0020
+#define SYMBOL_PRINTED 0x0040
+#define SYMBOL_VALID 0x0080
+#define SYMBOL_OPTIONAL 0x0100
+#define SYMBOL_WRITE 0x0200
+#define SYMBOL_CHANGED 0x0400
+#define SYMBOL_NEW 0x0800
+#define SYMBOL_AUTO 0x1000
+#define SYMBOL_CHECKED 0x2000
+#define SYMBOL_CHECK_DONE 0x4000
+#define SYMBOL_WARNED 0x8000
+
+#define SYMBOL_MAXLENGTH 256
+#define SYMBOL_HASHSIZE 257
+#define SYMBOL_HASHMASK 0xff
+
+enum prop_type {
+ P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE
+};
+
+struct property {
+ struct property *next;
+ struct symbol *sym;
+ enum prop_type type;
+ const char *text;
+ struct expr_value visible;
+ struct expr *expr;
+ struct menu *menu;
+ struct file *file;
+ int lineno;
+};
+
+#define for_all_properties(sym, st, tok) \
+ for (st = sym->prop; st; st = st->next) \
+ if (st->type == (tok))
+#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT)
+#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE)
+#define for_all_prompts(sym, st) \
+ for (st = sym->prop; st; st = st->next) \
+ if (st->text)
+
+struct menu {
+ struct menu *next;
+ struct menu *parent;
+ struct menu *list;
+ struct symbol *sym;
+ struct property *prompt;
+ struct expr *dep;
+ unsigned int flags;
+ //char *help;
+ struct file *file;
+ int lineno;
+ void *data;
+};
+
+#define MENU_CHANGED 0x0001
+#define MENU_ROOT 0x0002
+
+#ifndef SWIG
+
+extern struct file *file_list;
+extern struct file *current_file;
+struct file *lookup_file(const char *name);
+
+extern struct symbol symbol_yes, symbol_no, symbol_mod;
+extern struct symbol *modules_sym;
+extern int cdebug;
+struct expr *expr_alloc_symbol(struct symbol *sym);
+struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
+struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2);
+struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
+struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
+struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
+struct expr *expr_copy(struct expr *org);
+void expr_free(struct expr *e);
+int expr_eq(struct expr *e1, struct expr *e2);
+void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
+tristate expr_calc_value(struct expr *e);
+struct expr *expr_eliminate_yn(struct expr *e);
+struct expr *expr_trans_bool(struct expr *e);
+struct expr *expr_eliminate_dups(struct expr *e);
+struct expr *expr_transform(struct expr *e);
+int expr_contains_symbol(struct expr *dep, struct symbol *sym);
+bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
+struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
+struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
+void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
+struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
+
+void expr_fprint(struct expr *e, FILE *out);
+struct gstr; /* forward */
+void expr_gstr_print(struct expr *e, struct gstr *gs);
+
+static inline int expr_is_yes(struct expr *e)
+{
+ return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes);
+}
+
+static inline int expr_is_no(struct expr *e)
+{
+ return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no);
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EXPR_H */
diff --git a/misc/buildroot/package/config/lex.zconf.c_shipped b/misc/buildroot/package/config/lex.zconf.c_shipped
new file mode 100644
index 000000000..22dda11f7
--- /dev/null
+++ b/misc/buildroot/package/config/lex.zconf.c_shipped
@@ -0,0 +1,3688 @@
+
+#line 3 "lex.zconf.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 31
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE zconfrestart(zconfin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int zconfleng;
+
+extern FILE *zconfin, *zconfout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up zconftext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up zconftext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via zconfrestart()), so that the user can continue scanning by
+ * just pointing zconfin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when zconftext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int zconfleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow zconfwrap()'s to do buffer switches
+ * instead of setting up a fresh zconfin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void zconfrestart (FILE *input_file );
+void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE zconf_create_buffer (FILE *file,int size );
+void zconf_delete_buffer (YY_BUFFER_STATE b );
+void zconf_flush_buffer (YY_BUFFER_STATE b );
+void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer );
+void zconfpop_buffer_state (void );
+
+static void zconfensure_buffer_stack (void );
+static void zconf_load_buffer_state (void );
+static void zconf_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER zconf_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE zconf_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE zconf_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE zconf_scan_bytes (yyconst char *bytes,int len );
+
+void *zconfalloc (yy_size_t );
+void *zconfrealloc (void *,yy_size_t );
+void zconffree (void * );
+
+#define yy_new_buffer zconf_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ zconfensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ zconfensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define zconfwrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *zconfin = (FILE *) 0, *zconfout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int zconflineno;
+
+int zconflineno = 1;
+
+extern char *zconftext;
+#define yytext_ptr zconftext
+static yyconst flex_int16_t yy_nxt[][38] =
+ {
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+ },
+
+ {
+ 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12
+ },
+
+ {
+ 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12
+ },
+
+ {
+ 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 18, 16, 16, 18, 18, 19, 20,
+ 21, 22, 18, 18, 23, 24, 18, 25, 18, 26,
+ 27, 18, 28, 29, 30, 18, 18, 16
+ },
+
+ {
+ 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 18, 16, 16, 18, 18, 19, 20,
+ 21, 22, 18, 18, 23, 24, 18, 25, 18, 26,
+ 27, 18, 28, 29, 30, 18, 18, 16
+
+ },
+
+ {
+ 11, 31, 32, 33, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31
+ },
+
+ {
+ 11, 31, 32, 33, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31
+ },
+
+ {
+ 11, 34, 34, 35, 34, 36, 34, 34, 36, 34,
+ 34, 34, 34, 34, 34, 37, 34, 34, 34, 34,
+
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34
+ },
+
+ {
+ 11, 34, 34, 35, 34, 36, 34, 34, 36, 34,
+ 34, 34, 34, 34, 34, 37, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34
+ },
+
+ {
+ 11, 38, 38, 39, 40, 41, 42, 43, 41, 44,
+ 45, 46, 47, 47, 48, 49, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 50, 47, 47, 47, 51,
+ 47, 47, 47, 47, 47, 47, 47, 52
+
+ },
+
+ {
+ 11, 38, 38, 39, 40, 41, 42, 43, 41, 44,
+ 45, 46, 47, 47, 48, 49, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 50, 47, 47, 47, 51,
+ 47, 47, 47, 47, 47, 47, 47, 52
+ },
+
+ {
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11
+ },
+
+ {
+ 11, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12
+ },
+
+ {
+ 11, -13, 53, 54, -13, -13, 55, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13
+ },
+
+ {
+ 11, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14
+
+ },
+
+ {
+ 11, 56, 56, 57, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56
+ },
+
+ {
+ 11, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16, -16
+ },
+
+ {
+ 11, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, -17, -17, -17, -17, -17, -17, -17
+ },
+
+ {
+ 11, -18, -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, 58, -18, -18, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -18
+ },
+
+ {
+ 11, -19, -19, -19, -19, -19, -19, -19, -19, -19,
+ -19, -19, -19, 58, -19, -19, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 59,
+ 58, 58, 58, 58, 58, 58, 58, -19
+
+ },
+
+ {
+ 11, -20, -20, -20, -20, -20, -20, -20, -20, -20,
+ -20, -20, -20, 58, -20, -20, 58, 58, 58, 58,
+ 58, 58, 58, 58, 60, 58, 58, 58, 58, 61,
+ 58, 58, 58, 58, 58, 58, 58, -20
+ },
+
+ {
+ 11, -21, -21, -21, -21, -21, -21, -21, -21, -21,
+ -21, -21, -21, 58, -21, -21, 58, 58, 58, 58,
+ 58, 62, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -21
+ },
+
+ {
+ 11, -22, -22, -22, -22, -22, -22, -22, -22, -22,
+ -22, -22, -22, 58, -22, -22, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 63, 58,
+ 58, 58, 58, 58, 58, 58, 58, -22
+ },
+
+ {
+ 11, -23, -23, -23, -23, -23, -23, -23, -23, -23,
+ -23, -23, -23, 58, -23, -23, 58, 58, 58, 58,
+ 58, 64, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -23
+ },
+
+ {
+ 11, -24, -24, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, 58, -24, -24, 58, 58, 58, 58,
+ 58, 58, 65, 58, 58, 58, 58, 58, 66, 58,
+ 58, 58, 58, 58, 58, 58, 58, -24
+
+ },
+
+ {
+ 11, -25, -25, -25, -25, -25, -25, -25, -25, -25,
+ -25, -25, -25, 58, -25, -25, 58, 67, 58, 58,
+ 58, 68, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -25
+ },
+
+ {
+ 11, -26, -26, -26, -26, -26, -26, -26, -26, -26,
+ -26, -26, -26, 58, -26, -26, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 69, 58, 58, 58, 58, 58, 58, -26
+ },
+
+ {
+ 11, -27, -27, -27, -27, -27, -27, -27, -27, -27,
+ -27, -27, -27, 58, -27, -27, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 70, 58, 58, 58, 58, -27
+ },
+
+ {
+ 11, -28, -28, -28, -28, -28, -28, -28, -28, -28,
+ -28, -28, -28, 58, -28, -28, 58, 71, 58, 58,
+ 58, 72, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -28
+ },
+
+ {
+ 11, -29, -29, -29, -29, -29, -29, -29, -29, -29,
+ -29, -29, -29, 58, -29, -29, 58, 58, 58, 58,
+ 58, 73, 58, 58, 58, 58, 58, 58, 58, 74,
+ 58, 58, 58, 58, 75, 58, 58, -29
+
+ },
+
+ {
+ 11, -30, -30, -30, -30, -30, -30, -30, -30, -30,
+ -30, -30, -30, 58, -30, -30, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 76, 58, 58, 58, 58, -30
+ },
+
+ {
+ 11, 77, 77, -31, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77
+ },
+
+ {
+ 11, -32, 78, 79, -32, -32, -32, -32, -32, -32,
+ -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+
+ -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+ -32, -32, -32, -32, -32, -32, -32, -32
+ },
+
+ {
+ 11, 80, -33, -33, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80
+ },
+
+ {
+ 11, 81, 81, 82, 81, -34, 81, 81, -34, 81,
+ 81, 81, 81, 81, 81, -34, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81
+
+ },
+
+ {
+ 11, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, -35, -35, -35, -35, -35, -35, -35
+ },
+
+ {
+ 11, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36
+ },
+
+ {
+ 11, 83, 83, 84, 83, 83, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83
+ },
+
+ {
+ 11, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38
+ },
+
+ {
+ 11, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39
+
+ },
+
+ {
+ 11, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, 85, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40, -40
+ },
+
+ {
+ 11, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+ -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+ -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+ -41, -41, -41, -41, -41, -41, -41, -41
+ },
+
+ {
+ 11, 86, 86, -42, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86
+ },
+
+ {
+ 11, -43, -43, -43, -43, -43, -43, 87, -43, -43,
+ -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
+ -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
+ -43, -43, -43, -43, -43, -43, -43, -43
+ },
+
+ {
+ 11, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, -44
+
+ },
+
+ {
+ 11, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45
+ },
+
+ {
+ 11, -46, -46, -46, -46, -46, -46, -46, -46, -46,
+ -46, 88, 89, 89, -46, -46, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -46
+ },
+
+ {
+ 11, -47, -47, -47, -47, -47, -47, -47, -47, -47,
+ -47, 89, 89, 89, -47, -47, 89, 89, 89, 89,
+
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -47
+ },
+
+ {
+ 11, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, -48
+ },
+
+ {
+ 11, -49, -49, 90, -49, -49, -49, -49, -49, -49,
+ -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
+ -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
+ -49, -49, -49, -49, -49, -49, -49, -49
+
+ },
+
+ {
+ 11, -50, -50, -50, -50, -50, -50, -50, -50, -50,
+ -50, 89, 89, 89, -50, -50, 89, 89, 89, 89,
+ 89, 89, 91, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -50
+ },
+
+ {
+ 11, -51, -51, -51, -51, -51, -51, -51, -51, -51,
+ -51, 89, 89, 89, -51, -51, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 92, 89,
+ 89, 89, 89, 89, 89, 89, 89, -51
+ },
+
+ {
+ 11, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+ -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+
+ -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+ -52, -52, -52, -52, -52, -52, -52, 93
+ },
+
+ {
+ 11, -53, 53, 54, -53, -53, 55, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53, -53
+ },
+
+ {
+ 11, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+ -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+ -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+ -54, -54, -54, -54, -54, -54, -54, -54
+
+ },
+
+ {
+ 11, 56, 56, 57, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56
+ },
+
+ {
+ 11, 56, 56, 57, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56
+ },
+
+ {
+ 11, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57
+ },
+
+ {
+ 11, -58, -58, -58, -58, -58, -58, -58, -58, -58,
+ -58, -58, -58, 58, -58, -58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -58
+ },
+
+ {
+ 11, -59, -59, -59, -59, -59, -59, -59, -59, -59,
+ -59, -59, -59, 58, -59, -59, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 94,
+ 58, 58, 58, 58, 58, 58, 58, -59
+
+ },
+
+ {
+ 11, -60, -60, -60, -60, -60, -60, -60, -60, -60,
+ -60, -60, -60, 58, -60, -60, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 95,
+ 58, 58, 58, 58, 58, 58, 58, -60
+ },
+
+ {
+ 11, -61, -61, -61, -61, -61, -61, -61, -61, -61,
+ -61, -61, -61, 58, -61, -61, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 96, 97, 58,
+ 58, 58, 58, 58, 58, 58, 58, -61
+ },
+
+ {
+ 11, -62, -62, -62, -62, -62, -62, -62, -62, -62,
+ -62, -62, -62, 58, -62, -62, 58, 58, 58, 58,
+
+ 58, 58, 98, 58, 58, 58, 58, 58, 58, 58,
+ 99, 58, 58, 58, 58, 58, 58, -62
+ },
+
+ {
+ 11, -63, -63, -63, -63, -63, -63, -63, -63, -63,
+ -63, -63, -63, 58, -63, -63, 58, 100, 58, 58,
+ 101, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -63
+ },
+
+ {
+ 11, -64, -64, -64, -64, -64, -64, -64, -64, -64,
+ -64, -64, -64, 58, -64, -64, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 102, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 103, -64
+
+ },
+
+ {
+ 11, -65, -65, -65, -65, -65, -65, -65, -65, -65,
+ -65, -65, -65, 58, -65, -65, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -65
+ },
+
+ {
+ 11, -66, -66, -66, -66, -66, -66, -66, -66, -66,
+ -66, -66, -66, 58, -66, -66, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 104, 58, 58, -66
+ },
+
+ {
+ 11, -67, -67, -67, -67, -67, -67, -67, -67, -67,
+ -67, -67, -67, 58, -67, -67, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 105, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -67
+ },
+
+ {
+ 11, -68, -68, -68, -68, -68, -68, -68, -68, -68,
+ -68, -68, -68, 58, -68, -68, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 106, 58,
+ 58, 58, 58, 58, 58, 58, 58, -68
+ },
+
+ {
+ 11, -69, -69, -69, -69, -69, -69, -69, -69, -69,
+ -69, -69, -69, 58, -69, -69, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 107, 58, 58, -69
+
+ },
+
+ {
+ 11, -70, -70, -70, -70, -70, -70, -70, -70, -70,
+ -70, -70, -70, 58, -70, -70, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 108,
+ 58, 58, 58, 58, 58, 58, 58, -70
+ },
+
+ {
+ 11, -71, -71, -71, -71, -71, -71, -71, -71, -71,
+ -71, -71, -71, 58, -71, -71, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 109, 58,
+ 58, 58, 58, 58, 58, 58, 58, -71
+ },
+
+ {
+ 11, -72, -72, -72, -72, -72, -72, -72, -72, -72,
+ -72, -72, -72, 58, -72, -72, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 110, 58, 58, 58, 58, 58, -72
+ },
+
+ {
+ 11, -73, -73, -73, -73, -73, -73, -73, -73, -73,
+ -73, -73, -73, 58, -73, -73, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 111, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -73
+ },
+
+ {
+ 11, -74, -74, -74, -74, -74, -74, -74, -74, -74,
+ -74, -74, -74, 58, -74, -74, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 112, 58, -74
+
+ },
+
+ {
+ 11, -75, -75, -75, -75, -75, -75, -75, -75, -75,
+ -75, -75, -75, 58, -75, -75, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 113, 58, 58, 58, 58, -75
+ },
+
+ {
+ 11, -76, -76, -76, -76, -76, -76, -76, -76, -76,
+ -76, -76, -76, 58, -76, -76, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 114, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -76
+ },
+
+ {
+ 11, 77, 77, -77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77
+ },
+
+ {
+ 11, -78, 78, 79, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78
+ },
+
+ {
+ 11, 80, -79, -79, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80
+
+ },
+
+ {
+ 11, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80
+ },
+
+ {
+ 11, 81, 81, 82, 81, -81, 81, 81, -81, 81,
+ 81, 81, 81, 81, 81, -81, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81
+ },
+
+ {
+ 11, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+ -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+
+ -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+ -82, -82, -82, -82, -82, -82, -82, -82
+ },
+
+ {
+ 11, -83, -83, 84, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83
+ },
+
+ {
+ 11, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84
+
+ },
+
+ {
+ 11, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, -85, -85, -85
+ },
+
+ {
+ 11, 86, 86, -86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86
+ },
+
+ {
+ 11, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+ -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+
+ -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+ -87, -87, -87, -87, -87, -87, -87, -87
+ },
+
+ {
+ 11, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, 115, 89, 89, -88, -88, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -88
+ },
+
+ {
+ 11, -89, -89, -89, -89, -89, -89, -89, -89, -89,
+ -89, 89, 89, 89, -89, -89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -89
+
+ },
+
+ {
+ 11, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90
+ },
+
+ {
+ 11, -91, -91, -91, -91, -91, -91, -91, -91, -91,
+ -91, 89, 89, 89, -91, -91, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -91
+ },
+
+ {
+ 11, -92, -92, -92, -92, -92, -92, -92, -92, -92,
+ -92, 89, 89, 89, -92, -92, 89, 89, 89, 89,
+
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -92
+ },
+
+ {
+ 11, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+ -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+ -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+ -93, -93, -93, -93, -93, -93, -93, -93
+ },
+
+ {
+ 11, -94, -94, -94, -94, -94, -94, -94, -94, -94,
+ -94, -94, -94, 58, -94, -94, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 116, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -94
+
+ },
+
+ {
+ 11, -95, -95, -95, -95, -95, -95, -95, -95, -95,
+ -95, -95, -95, 58, -95, -95, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 117, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -95
+ },
+
+ {
+ 11, -96, -96, -96, -96, -96, -96, -96, -96, -96,
+ -96, -96, -96, 58, -96, -96, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 118, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -96
+ },
+
+ {
+ 11, -97, -97, -97, -97, -97, -97, -97, -97, -97,
+ -97, -97, -97, 58, -97, -97, 58, 58, 58, 58,
+
+ 58, 58, 119, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -97
+ },
+
+ {
+ 11, -98, -98, -98, -98, -98, -98, -98, -98, -98,
+ -98, -98, -98, 58, -98, -98, 120, 121, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -98
+ },
+
+ {
+ 11, -99, -99, -99, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, 58, -99, -99, 58, 58, 58, 58,
+ 58, 122, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -99
+
+ },
+
+ {
+ 11, -100, -100, -100, -100, -100, -100, -100, -100, -100,
+ -100, -100, -100, 58, -100, -100, 58, 58, 123, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -100
+ },
+
+ {
+ 11, -101, -101, -101, -101, -101, -101, -101, -101, -101,
+ -101, -101, -101, 58, -101, -101, 58, 58, 58, 124,
+ 58, 58, 58, 58, 58, 125, 58, 126, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -101
+ },
+
+ {
+ 11, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ -102, -102, -102, 58, -102, -102, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 127, 58, 58, 58, 58, 58, 58, -102
+ },
+
+ {
+ 11, -103, -103, -103, -103, -103, -103, -103, -103, -103,
+ -103, -103, -103, 58, -103, -103, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -103
+ },
+
+ {
+ 11, -104, -104, -104, -104, -104, -104, -104, -104, -104,
+ -104, -104, -104, 58, -104, -104, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -104
+
+ },
+
+ {
+ 11, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -105, 58, -105, -105, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 128, 58,
+ 58, 58, 58, 58, 58, 58, 58, -105
+ },
+
+ {
+ 11, -106, -106, -106, -106, -106, -106, -106, -106, -106,
+ -106, -106, -106, 58, -106, -106, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 129, 58, -106
+ },
+
+ {
+ 11, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, 58, -107, -107, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 130, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -107
+ },
+
+ {
+ 11, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, 58, -108, -108, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 131, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -108
+ },
+
+ {
+ 11, -109, -109, -109, -109, -109, -109, -109, -109, -109,
+ -109, -109, -109, 58, -109, -109, 58, 58, 58, 58,
+ 58, 58, 58, 132, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -109
+
+ },
+
+ {
+ 11, -110, -110, -110, -110, -110, -110, -110, -110, -110,
+ -110, -110, -110, 58, -110, -110, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 133, 58, -110
+ },
+
+ {
+ 11, -111, -111, -111, -111, -111, -111, -111, -111, -111,
+ -111, -111, -111, 58, -111, -111, 58, 58, 58, 58,
+ 58, 134, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -111
+ },
+
+ {
+ 11, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, 58, -112, -112, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 135, 58, 58, 58, 58, -112
+ },
+
+ {
+ 11, -113, -113, -113, -113, -113, -113, -113, -113, -113,
+ -113, -113, -113, 58, -113, -113, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 136, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -113
+ },
+
+ {
+ 11, -114, -114, -114, -114, -114, -114, -114, -114, -114,
+ -114, -114, -114, 58, -114, -114, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 137, 58, 58, 58, -114
+
+ },
+
+ {
+ 11, -115, -115, -115, -115, -115, -115, -115, -115, -115,
+ -115, 89, 89, 89, -115, -115, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -115
+ },
+
+ {
+ 11, -116, -116, -116, -116, -116, -116, -116, -116, -116,
+ -116, -116, -116, 58, -116, -116, 58, 58, 58, 58,
+ 58, 138, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -116
+ },
+
+ {
+ 11, -117, -117, -117, -117, -117, -117, -117, -117, -117,
+ -117, -117, -117, 58, -117, -117, 58, 58, 58, 139,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -117
+ },
+
+ {
+ 11, -118, -118, -118, -118, -118, -118, -118, -118, -118,
+ -118, -118, -118, 58, -118, -118, 58, 58, 58, 58,
+ 58, 140, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -118
+ },
+
+ {
+ 11, -119, -119, -119, -119, -119, -119, -119, -119, -119,
+ -119, -119, -119, 58, -119, -119, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 141, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -119
+
+ },
+
+ {
+ 11, -120, -120, -120, -120, -120, -120, -120, -120, -120,
+ -120, -120, -120, 58, -120, -120, 58, 58, 142, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 143, 58, 58, -120
+ },
+
+ {
+ 11, -121, -121, -121, -121, -121, -121, -121, -121, -121,
+ -121, -121, -121, 58, -121, -121, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 144, 58, -121
+ },
+
+ {
+ 11, -122, -122, -122, -122, -122, -122, -122, -122, -122,
+ -122, -122, -122, 58, -122, -122, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 145, 58,
+ 58, 58, 58, 58, 58, 58, 58, -122
+ },
+
+ {
+ 11, -123, -123, -123, -123, -123, -123, -123, -123, -123,
+ -123, -123, -123, 58, -123, -123, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 146, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -123
+ },
+
+ {
+ 11, -124, -124, -124, -124, -124, -124, -124, -124, -124,
+ -124, -124, -124, 58, -124, -124, 58, 58, 58, 58,
+ 58, 58, 58, 58, 147, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -124
+
+ },
+
+ {
+ 11, -125, -125, -125, -125, -125, -125, -125, -125, -125,
+ -125, -125, -125, 58, -125, -125, 58, 58, 58, 58,
+ 58, 58, 148, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -125
+ },
+
+ {
+ 11, -126, -126, -126, -126, -126, -126, -126, -126, -126,
+ -126, -126, -126, 58, -126, -126, 58, 58, 58, 58,
+ 58, 149, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -126
+ },
+
+ {
+ 11, -127, -127, -127, -127, -127, -127, -127, -127, -127,
+ -127, -127, -127, 58, -127, -127, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -127
+ },
+
+ {
+ 11, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+ -128, -128, -128, 58, -128, -128, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 150, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -128
+ },
+
+ {
+ 11, -129, -129, -129, -129, -129, -129, -129, -129, -129,
+ -129, -129, -129, 58, -129, -129, 58, 58, 58, 151,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -129
+
+ },
+
+ {
+ 11, -130, -130, -130, -130, -130, -130, -130, -130, -130,
+ -130, -130, -130, 58, -130, -130, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 152,
+ 58, 58, 58, 58, 58, 58, 58, -130
+ },
+
+ {
+ 11, -131, -131, -131, -131, -131, -131, -131, -131, -131,
+ -131, -131, -131, 58, -131, -131, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 153, 58, 58, 58, 58, 58, 58, -131
+ },
+
+ {
+ 11, -132, -132, -132, -132, -132, -132, -132, -132, -132,
+ -132, -132, -132, 58, -132, -132, 58, 58, 58, 58,
+
+ 58, 154, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -132
+ },
+
+ {
+ 11, -133, -133, -133, -133, -133, -133, -133, -133, -133,
+ -133, -133, -133, 58, -133, -133, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 155, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -133
+ },
+
+ {
+ 11, -134, -134, -134, -134, -134, -134, -134, -134, -134,
+ -134, -134, -134, 58, -134, -134, 58, 58, 58, 156,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -134
+
+ },
+
+ {
+ 11, -135, -135, -135, -135, -135, -135, -135, -135, -135,
+ -135, -135, -135, 58, -135, -135, 58, 58, 58, 157,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -135
+ },
+
+ {
+ 11, -136, -136, -136, -136, -136, -136, -136, -136, -136,
+ -136, -136, -136, 58, -136, -136, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 158, 58,
+ 58, 58, 58, 58, 58, 58, 58, -136
+ },
+
+ {
+ 11, -137, -137, -137, -137, -137, -137, -137, -137, -137,
+ -137, -137, -137, 58, -137, -137, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 159, 58, 58, -137
+ },
+
+ {
+ 11, -138, -138, -138, -138, -138, -138, -138, -138, -138,
+ -138, -138, -138, 58, -138, -138, 58, 160, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -138
+ },
+
+ {
+ 11, -139, -139, -139, -139, -139, -139, -139, -139, -139,
+ -139, -139, -139, 58, -139, -139, 58, 58, 58, 58,
+ 58, 161, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -139
+
+ },
+
+ {
+ 11, -140, -140, -140, -140, -140, -140, -140, -140, -140,
+ -140, -140, -140, 58, -140, -140, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 162, 58,
+ 58, 58, 58, 58, 58, 58, 58, -140
+ },
+
+ {
+ 11, -141, -141, -141, -141, -141, -141, -141, -141, -141,
+ -141, -141, -141, 58, -141, -141, 58, 58, 58, 58,
+ 58, 58, 58, 163, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -141
+ },
+
+ {
+ 11, -142, -142, -142, -142, -142, -142, -142, -142, -142,
+ -142, -142, -142, 58, -142, -142, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 164,
+ 58, 58, 58, 58, 58, 58, 58, -142
+ },
+
+ {
+ 11, -143, -143, -143, -143, -143, -143, -143, -143, -143,
+ -143, -143, -143, 58, -143, -143, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 165, 58, 58, 58, 58, -143
+ },
+
+ {
+ 11, -144, -144, -144, -144, -144, -144, -144, -144, -144,
+ -144, -144, -144, 58, -144, -144, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 166, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -144
+
+ },
+
+ {
+ 11, -145, -145, -145, -145, -145, -145, -145, -145, -145,
+ -145, -145, -145, 58, -145, -145, 58, 58, 58, 58,
+ 167, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -145
+ },
+
+ {
+ 11, -146, -146, -146, -146, -146, -146, -146, -146, -146,
+ -146, -146, -146, 58, -146, -146, 58, 58, 58, 58,
+ 58, 168, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -146
+ },
+
+ {
+ 11, -147, -147, -147, -147, -147, -147, -147, -147, -147,
+ -147, -147, -147, 58, -147, -147, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 169,
+ 58, 58, 58, 58, 58, 58, 58, -147
+ },
+
+ {
+ 11, -148, -148, -148, -148, -148, -148, -148, -148, -148,
+ -148, -148, -148, 58, -148, -148, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -148
+ },
+
+ {
+ 11, -149, -149, -149, -149, -149, -149, -149, -149, -149,
+ -149, -149, -149, 58, -149, -149, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 170, 58,
+ 58, 58, 58, 58, 58, 58, 58, -149
+
+ },
+
+ {
+ 11, -150, -150, -150, -150, -150, -150, -150, -150, -150,
+ -150, -150, -150, 58, -150, -150, 58, 58, 58, 58,
+ 58, 171, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -150
+ },
+
+ {
+ 11, -151, -151, -151, -151, -151, -151, -151, -151, -151,
+ -151, -151, -151, 58, -151, -151, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 172,
+ 58, 58, 58, 58, 58, 58, 58, -151
+ },
+
+ {
+ 11, -152, -152, -152, -152, -152, -152, -152, -152, -152,
+ -152, -152, -152, 58, -152, -152, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 173, 58,
+ 58, 58, 58, 58, 58, 58, 58, -152
+ },
+
+ {
+ 11, -153, -153, -153, -153, -153, -153, -153, -153, -153,
+ -153, -153, -153, 58, -153, -153, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 174, 58, 58, -153
+ },
+
+ {
+ 11, -154, -154, -154, -154, -154, -154, -154, -154, -154,
+ -154, -154, -154, 58, -154, -154, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -154
+
+ },
+
+ {
+ 11, -155, -155, -155, -155, -155, -155, -155, -155, -155,
+ -155, -155, -155, 58, -155, -155, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 175, 58, 58, 58, 58, -155
+ },
+
+ {
+ 11, -156, -156, -156, -156, -156, -156, -156, -156, -156,
+ -156, -156, -156, 58, -156, -156, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 176, 58, 58, -156
+ },
+
+ {
+ 11, -157, -157, -157, -157, -157, -157, -157, -157, -157,
+ -157, -157, -157, 58, -157, -157, 58, 58, 58, 58,
+
+ 58, 177, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -157
+ },
+
+ {
+ 11, -158, -158, -158, -158, -158, -158, -158, -158, -158,
+ -158, -158, -158, 58, -158, -158, 58, 58, 58, 58,
+ 58, 58, 58, 178, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -158
+ },
+
+ {
+ 11, -159, -159, -159, -159, -159, -159, -159, -159, -159,
+ -159, -159, -159, 58, -159, -159, 58, 179, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -159
+
+ },
+
+ {
+ 11, -160, -160, -160, -160, -160, -160, -160, -160, -160,
+ -160, -160, -160, 58, -160, -160, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 180, 58,
+ 58, 58, 58, 58, 58, 58, 58, -160
+ },
+
+ {
+ 11, -161, -161, -161, -161, -161, -161, -161, -161, -161,
+ -161, -161, -161, 58, -161, -161, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -161
+ },
+
+ {
+ 11, -162, -162, -162, -162, -162, -162, -162, -162, -162,
+ -162, -162, -162, 58, -162, -162, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 181, 58, 58, -162
+ },
+
+ {
+ 11, -163, -163, -163, -163, -163, -163, -163, -163, -163,
+ -163, -163, -163, 58, -163, -163, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -163
+ },
+
+ {
+ 11, -164, -164, -164, -164, -164, -164, -164, -164, -164,
+ -164, -164, -164, 58, -164, -164, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 182,
+ 58, 58, 58, 58, 58, 58, 58, -164
+
+ },
+
+ {
+ 11, -165, -165, -165, -165, -165, -165, -165, -165, -165,
+ -165, -165, -165, 58, -165, -165, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 183, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -165
+ },
+
+ {
+ 11, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ -166, -166, -166, 58, -166, -166, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 184, 58, 58, -166
+ },
+
+ {
+ 11, -167, -167, -167, -167, -167, -167, -167, -167, -167,
+ -167, -167, -167, 58, -167, -167, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 185, 58, 58, 58, -167
+ },
+
+ {
+ 11, -168, -168, -168, -168, -168, -168, -168, -168, -168,
+ -168, -168, -168, 58, -168, -168, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -168
+ },
+
+ {
+ 11, -169, -169, -169, -169, -169, -169, -169, -169, -169,
+ -169, -169, -169, 58, -169, -169, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 186, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -169
+
+ },
+
+ {
+ 11, -170, -170, -170, -170, -170, -170, -170, -170, -170,
+ -170, -170, -170, 58, -170, -170, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 187, 58, -170
+ },
+
+ {
+ 11, -171, -171, -171, -171, -171, -171, -171, -171, -171,
+ -171, -171, -171, 58, -171, -171, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 188, 58,
+ 58, 58, 58, 58, 58, 58, 58, -171
+ },
+
+ {
+ 11, -172, -172, -172, -172, -172, -172, -172, -172, -172,
+ -172, -172, -172, 58, -172, -172, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 189, 58,
+ 58, 58, 58, 58, 58, 58, 58, -172
+ },
+
+ {
+ 11, -173, -173, -173, -173, -173, -173, -173, -173, -173,
+ -173, -173, -173, 58, -173, -173, 58, 190, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -173
+ },
+
+ {
+ 11, -174, -174, -174, -174, -174, -174, -174, -174, -174,
+ -174, -174, -174, 58, -174, -174, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -174
+
+ },
+
+ {
+ 11, -175, -175, -175, -175, -175, -175, -175, -175, -175,
+ -175, -175, -175, 58, -175, -175, 58, 58, 58, 58,
+ 58, 191, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -175
+ },
+
+ {
+ 11, -176, -176, -176, -176, -176, -176, -176, -176, -176,
+ -176, -176, -176, 58, -176, -176, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -176
+ },
+
+ {
+ 11, -177, -177, -177, -177, -177, -177, -177, -177, -177,
+ -177, -177, -177, 58, -177, -177, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -177
+ },
+
+ {
+ 11, -178, -178, -178, -178, -178, -178, -178, -178, -178,
+ -178, -178, -178, 58, -178, -178, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -178
+ },
+
+ {
+ 11, -179, -179, -179, -179, -179, -179, -179, -179, -179,
+ -179, -179, -179, 58, -179, -179, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 192, 58, 58, -179
+
+ },
+
+ {
+ 11, -180, -180, -180, -180, -180, -180, -180, -180, -180,
+ -180, -180, -180, 58, -180, -180, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -180
+ },
+
+ {
+ 11, -181, -181, -181, -181, -181, -181, -181, -181, -181,
+ -181, -181, -181, 58, -181, -181, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -181
+ },
+
+ {
+ 11, -182, -182, -182, -182, -182, -182, -182, -182, -182,
+ -182, -182, -182, 58, -182, -182, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 193, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -182
+ },
+
+ {
+ 11, -183, -183, -183, -183, -183, -183, -183, -183, -183,
+ -183, -183, -183, 58, -183, -183, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 194, 58, 58, 58, -183
+ },
+
+ {
+ 11, -184, -184, -184, -184, -184, -184, -184, -184, -184,
+ -184, -184, -184, 58, -184, -184, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -184
+
+ },
+
+ {
+ 11, -185, -185, -185, -185, -185, -185, -185, -185, -185,
+ -185, -185, -185, 58, -185, -185, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -185
+ },
+
+ {
+ 11, -186, -186, -186, -186, -186, -186, -186, -186, -186,
+ -186, -186, -186, 58, -186, -186, 58, 58, 58, 195,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -186
+ },
+
+ {
+ 11, -187, -187, -187, -187, -187, -187, -187, -187, -187,
+ -187, -187, -187, 58, -187, -187, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -187
+ },
+
+ {
+ 11, -188, -188, -188, -188, -188, -188, -188, -188, -188,
+ -188, -188, -188, 58, -188, -188, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 196, 58, -188
+ },
+
+ {
+ 11, -189, -189, -189, -189, -189, -189, -189, -189, -189,
+ -189, -189, -189, 58, -189, -189, 58, 58, 58, 58,
+ 58, 58, 197, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -189
+
+ },
+
+ {
+ 11, -190, -190, -190, -190, -190, -190, -190, -190, -190,
+ -190, -190, -190, 58, -190, -190, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 198, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -190
+ },
+
+ {
+ 11, -191, -191, -191, -191, -191, -191, -191, -191, -191,
+ -191, -191, -191, 58, -191, -191, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 199, 58, 58, 58, -191
+ },
+
+ {
+ 11, -192, -192, -192, -192, -192, -192, -192, -192, -192,
+ -192, -192, -192, 58, -192, -192, 58, 58, 58, 58,
+
+ 58, 200, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -192
+ },
+
+ {
+ 11, -193, -193, -193, -193, -193, -193, -193, -193, -193,
+ -193, -193, -193, 58, -193, -193, 58, 58, 58, 58,
+ 58, 201, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -193
+ },
+
+ {
+ 11, -194, -194, -194, -194, -194, -194, -194, -194, -194,
+ -194, -194, -194, 58, -194, -194, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 202, 58, 58, -194
+
+ },
+
+ {
+ 11, -195, -195, -195, -195, -195, -195, -195, -195, -195,
+ -195, -195, -195, 58, -195, -195, 58, 58, 58, 58,
+ 58, 203, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -195
+ },
+
+ {
+ 11, -196, -196, -196, -196, -196, -196, -196, -196, -196,
+ -196, -196, -196, 58, -196, -196, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -196
+ },
+
+ {
+ 11, -197, -197, -197, -197, -197, -197, -197, -197, -197,
+ -197, -197, -197, 58, -197, -197, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 204, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -197
+ },
+
+ {
+ 11, -198, -198, -198, -198, -198, -198, -198, -198, -198,
+ -198, -198, -198, 58, -198, -198, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -198
+ },
+
+ {
+ 11, -199, -199, -199, -199, -199, -199, -199, -199, -199,
+ -199, -199, -199, 58, -199, -199, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -199
+
+ },
+
+ {
+ 11, -200, -200, -200, -200, -200, -200, -200, -200, -200,
+ -200, -200, -200, 58, -200, -200, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -200
+ },
+
+ {
+ 11, -201, -201, -201, -201, -201, -201, -201, -201, -201,
+ -201, -201, -201, 58, -201, -201, 58, 205, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -201
+ },
+
+ {
+ 11, -202, -202, -202, -202, -202, -202, -202, -202, -202,
+ -202, -202, -202, 58, -202, -202, 58, 206, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -202
+ },
+
+ {
+ 11, -203, -203, -203, -203, -203, -203, -203, -203, -203,
+ -203, -203, -203, 58, -203, -203, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -203
+ },
+
+ {
+ 11, -204, -204, -204, -204, -204, -204, -204, -204, -204,
+ -204, -204, -204, 58, -204, -204, 58, 58, 58, 58,
+ 58, 58, 58, 207, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -204
+
+ },
+
+ {
+ 11, -205, -205, -205, -205, -205, -205, -205, -205, -205,
+ -205, -205, -205, 58, -205, -205, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 208, 58,
+ 58, 58, 58, 58, 58, 58, 58, -205
+ },
+
+ {
+ 11, -206, -206, -206, -206, -206, -206, -206, -206, -206,
+ -206, -206, -206, 58, -206, -206, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 209, 58, 58, -206
+ },
+
+ {
+ 11, -207, -207, -207, -207, -207, -207, -207, -207, -207,
+ -207, -207, -207, 58, -207, -207, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -207
+ },
+
+ {
+ 11, -208, -208, -208, -208, -208, -208, -208, -208, -208,
+ -208, -208, -208, 58, -208, -208, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -208
+ },
+
+ {
+ 11, -209, -209, -209, -209, -209, -209, -209, -209, -209,
+ -209, -209, -209, 58, -209, -209, 58, 58, 58, 58,
+ 58, 210, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -209
+
+ },
+
+ {
+ 11, -210, -210, -210, -210, -210, -210, -210, -210, -210,
+ -210, -210, -210, 58, -210, -210, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -210
+ },
+
+ } ;
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up zconftext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ zconfleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 64
+#define YY_END_OF_BUFFER 65
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[211] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 65, 5, 4, 3, 2, 36, 37, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 63, 60, 62, 55, 59, 58, 57, 53, 48, 42,
+ 47, 51, 53, 40, 41, 50, 50, 43, 53, 50,
+ 50, 53, 4, 3, 2, 2, 1, 35, 35, 35,
+ 35, 35, 35, 35, 16, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 63, 60, 62, 61,
+ 55, 54, 57, 56, 44, 51, 38, 50, 50, 52,
+ 45, 46, 39, 35, 35, 35, 35, 35, 35, 35,
+
+ 35, 35, 30, 29, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 49, 25, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 15, 35, 7, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 17, 35, 35,
+ 35, 35, 35, 34, 35, 35, 35, 35, 35, 35,
+ 10, 35, 13, 35, 35, 35, 35, 33, 35, 35,
+ 35, 35, 35, 22, 35, 32, 9, 31, 35, 26,
+ 12, 35, 35, 21, 18, 35, 8, 35, 35, 35,
+ 35, 35, 27, 35, 35, 6, 35, 20, 19, 23,
+
+ 35, 35, 11, 35, 35, 35, 14, 28, 35, 24
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 4, 5, 6, 1, 1, 7, 8, 9,
+ 10, 1, 1, 1, 11, 12, 12, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 1, 1, 1,
+ 14, 1, 1, 1, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 1, 15, 1, 1, 16, 1, 17, 18, 19, 20,
+
+ 21, 22, 23, 24, 25, 13, 13, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 13, 13, 36,
+ 13, 13, 1, 37, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+extern int zconf_flex_debug;
+int zconf_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *zconftext;
+
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+#define START_STRSIZE 16
+
+char *text;
+static char *text_ptr;
+static int text_size, text_asize;
+
+struct buffer {
+ struct buffer *parent;
+ YY_BUFFER_STATE state;
+};
+
+struct buffer *current_buf;
+
+static int last_ts, first_ts;
+
+static void zconf_endhelp(void);
+static struct buffer *zconf_endfile(void);
+
+void new_string(void)
+{
+ text = malloc(START_STRSIZE);
+ text_asize = START_STRSIZE;
+ text_ptr = text;
+ text_size = 0;
+ *text_ptr = 0;
+}
+
+void append_string(const char *str, int size)
+{
+ int new_size = text_size + size + 1;
+ if (new_size > text_asize) {
+ text = realloc(text, new_size);
+ text_asize = new_size;
+ text_ptr = text + text_size;
+ }
+ memcpy(text_ptr, str, size);
+ text_ptr += size;
+ text_size += size;
+ *text_ptr = 0;
+}
+
+void alloc_string(const char *str, int size)
+{
+ text = malloc(size + 1);
+ memcpy(text, str, size);
+ text[size] = 0;
+}
+
+#define INITIAL 0
+#define COMMAND 1
+#define HELP 2
+#define STRING 3
+#define PARAM 4
+
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int zconfwrap (void );
+#else
+extern int zconfwrap (void );
+#endif
+#endif
+
+ static void yyunput (int c,char *buf_ptr );
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( zconftext, zconfleng, 1, zconfout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ errno=0; \
+ while ( (result = read( fileno(zconfin), (char *) buf, max_size )) < 0 ) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(zconfin); \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int zconflex (void);
+
+#define YY_DECL int zconflex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after zconftext and zconfleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+ int str = 0;
+ int ts, i;
+
+ if ( (yy_init) )
+ {
+ (yy_init) = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! zconfin )
+ zconfin = stdin;
+
+ if ( ! zconfout )
+ zconfout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ zconfensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ zconf_create_buffer(zconfin,YY_BUF_SIZE );
+ }
+
+ zconf_load_buffer_state( );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of zconftext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+yy_match:
+ while ( (yy_current_state = yy_nxt[yy_current_state][ yy_ec[YY_SC_TO_UI(*yy_cp)] ]) > 0 )
+ ++yy_cp;
+
+ yy_current_state = -yy_current_state;
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+case 1:
+/* rule 1 can match eol */
+YY_RULE_SETUP
+current_file->lineno++;
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+
+ YY_BREAK
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+current_file->lineno++; return T_EOL;
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+{
+ BEGIN(COMMAND);
+}
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+{
+ unput(zconftext[0]);
+ BEGIN(COMMAND);
+}
+ YY_BREAK
+
+case 6:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_MAINMENU;
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_MENU;
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_ENDMENU;
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_SOURCE;
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_CHOICE;
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_ENDCHOICE;
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_COMMENT;
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_CONFIG;
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_MENUCONFIG;
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_HELP;
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_IF;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_ENDIF;
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_DEPENDS;
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_REQUIRES;
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_OPTIONAL;
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_DEFAULT;
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_PROMPT;
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_TRISTATE;
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_DEF_TRISTATE;
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_BOOLEAN;
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_BOOLEAN;
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_DEF_BOOLEAN;
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_DEF_BOOLEAN;
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_INT;
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_HEX;
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_STRING;
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_SELECT;
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_SELECT;
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_RANGE;
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+{
+ alloc_string(zconftext, zconfleng);
+ zconflval.string = text;
+ return T_WORD;
+ }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+
+ YY_BREAK
+case 37:
+/* rule 37 can match eol */
+YY_RULE_SETUP
+current_file->lineno++; BEGIN(INITIAL);
+ YY_BREAK
+
+case 38:
+YY_RULE_SETUP
+return T_AND;
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+return T_OR;
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+return T_OPEN_PAREN;
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+return T_CLOSE_PAREN;
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+return T_NOT;
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+return T_EQUAL;
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+return T_UNEQUAL;
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+return T_IF;
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+return T_ON;
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+{
+ str = zconftext[0];
+ new_string();
+ BEGIN(STRING);
+ }
+ YY_BREAK
+case 48:
+/* rule 48 can match eol */
+YY_RULE_SETUP
+BEGIN(INITIAL); current_file->lineno++; return T_EOL;
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+/* ignore */
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+{
+ alloc_string(zconftext, zconfleng);
+ zconflval.string = text;
+ return T_WORD;
+ }
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+/* comment */
+ YY_BREAK
+case 52:
+/* rule 52 can match eol */
+YY_RULE_SETUP
+current_file->lineno++;
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+
+ YY_BREAK
+case YY_STATE_EOF(PARAM):
+{
+ BEGIN(INITIAL);
+ }
+ YY_BREAK
+
+case 54:
+/* rule 54 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
+(yy_c_buf_p) = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up zconftext again */
+YY_RULE_SETUP
+{
+ append_string(zconftext, zconfleng);
+ zconflval.string = text;
+ return T_WORD_QUOTE;
+ }
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+{
+ append_string(zconftext, zconfleng);
+ }
+ YY_BREAK
+case 56:
+/* rule 56 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
+(yy_c_buf_p) = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up zconftext again */
+YY_RULE_SETUP
+{
+ append_string(zconftext + 1, zconfleng - 1);
+ zconflval.string = text;
+ return T_WORD_QUOTE;
+ }
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+{
+ append_string(zconftext + 1, zconfleng - 1);
+ }
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+{
+ if (str == zconftext[0]) {
+ BEGIN(PARAM);
+ zconflval.string = text;
+ return T_WORD_QUOTE;
+ } else
+ append_string(zconftext, 1);
+ }
+ YY_BREAK
+case 59:
+/* rule 59 can match eol */
+YY_RULE_SETUP
+{
+ printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
+ current_file->lineno++;
+ BEGIN(INITIAL);
+ return T_EOL;
+ }
+ YY_BREAK
+case YY_STATE_EOF(STRING):
+{
+ BEGIN(INITIAL);
+ }
+ YY_BREAK
+
+case 60:
+YY_RULE_SETUP
+{
+ ts = 0;
+ for (i = 0; i < zconfleng; i++) {
+ if (zconftext[i] == '\t')
+ ts = (ts & ~7) + 8;
+ else
+ ts++;
+ }
+ last_ts = ts;
+ if (first_ts) {
+ if (ts < first_ts) {
+ zconf_endhelp();
+ return T_HELPTEXT;
+ }
+ ts -= first_ts;
+ while (ts > 8) {
+ append_string(" ", 8);
+ ts -= 8;
+ }
+ append_string(" ", ts);
+ }
+ }
+ YY_BREAK
+case 61:
+/* rule 61 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
+(yy_c_buf_p) = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up zconftext again */
+YY_RULE_SETUP
+{
+ current_file->lineno++;
+ zconf_endhelp();
+ return T_HELPTEXT;
+ }
+ YY_BREAK
+case 62:
+/* rule 62 can match eol */
+YY_RULE_SETUP
+{
+ current_file->lineno++;
+ append_string("\n", 1);
+ }
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+{
+ append_string(zconftext, zconfleng);
+ if (!first_ts)
+ first_ts = last_ts;
+ }
+ YY_BREAK
+case YY_STATE_EOF(HELP):
+{
+ zconf_endhelp();
+ return T_HELPTEXT;
+ }
+ YY_BREAK
+
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(COMMAND):
+{
+ if (current_buf) {
+ zconf_endfile();
+ return T_EOF;
+ }
+ fclose(zconfin);
+ yyterminate();
+}
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+YY_FATAL_ERROR( "flex scanner jammed" );
+ YY_BREAK
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed zconfin at a new source and called
+ * zconflex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = zconfin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( zconfwrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * zconftext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of zconflex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = (yytext_ptr);
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ size_t num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ zconfrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ zconfrestart(zconfin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ register int yy_is_jam;
+
+ yy_current_state = yy_nxt[yy_current_state][1];
+ yy_is_jam = (yy_current_state <= 0);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+ static void yyunput (int c, register char * yy_bp )
+{
+ register char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up zconftext */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = (yy_n_chars) + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ zconfrestart(zconfin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( zconfwrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve zconftext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void zconfrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ zconfensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ zconf_create_buffer(zconfin,YY_BUF_SIZE );
+ }
+
+ zconf_init_buffer(YY_CURRENT_BUFFER,input_file );
+ zconf_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * zconfpop_buffer_state();
+ * zconfpush_buffer_state(new_buffer);
+ */
+ zconfensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ zconf_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (zconfwrap()) processing, but the only time this flag
+ * is looked at is after zconfwrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void zconf_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ zconfin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE zconf_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) zconfalloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ zconf_init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with zconf_create_buffer()
+ *
+ */
+ void zconf_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ zconffree((void *) b->yy_ch_buf );
+
+ zconffree((void *) b );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a zconfrestart() or at EOF.
+ */
+ static void zconf_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ zconf_flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then zconf_init_buffer was _probably_
+ * called from zconfrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void zconf_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ zconf_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ zconfensure_buffer_stack();
+
+ /* This block is copied from zconf_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from zconf_switch_to_buffer. */
+ zconf_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void zconfpop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ zconf_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ zconf_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void zconfensure_buffer_stack (void)
+{
+ int num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)zconfalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)zconfrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ zconf_switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to zconflex() will
+ * scan from a @e copy of @a str.
+ * @param str a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * zconf_scan_bytes() instead.
+ */
+YY_BUFFER_STATE zconf_scan_string (yyconst char * str )
+{
+
+ return zconf_scan_bytes(str,strlen(str) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE zconf_scan_bytes (yyconst char * bytes, int len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) zconfalloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = zconf_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in zconf_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up zconftext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ zconftext[zconfleng] = (yy_hold_char); \
+ (yy_c_buf_p) = zconftext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ zconfleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int zconfget_lineno (void)
+{
+
+ return zconflineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *zconfget_in (void)
+{
+ return zconfin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *zconfget_out (void)
+{
+ return zconfout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int zconfget_leng (void)
+{
+ return zconfleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *zconfget_text (void)
+{
+ return zconftext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void zconfset_lineno (int line_number )
+{
+
+ zconflineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see zconf_switch_to_buffer
+ */
+void zconfset_in (FILE * in_str )
+{
+ zconfin = in_str ;
+}
+
+void zconfset_out (FILE * out_str )
+{
+ zconfout = out_str ;
+}
+
+int zconfget_debug (void)
+{
+ return zconf_flex_debug;
+}
+
+void zconfset_debug (int bdebug )
+{
+ zconf_flex_debug = bdebug ;
+}
+
+/* zconflex_destroy is for both reentrant and non-reentrant scanners. */
+int zconflex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ zconf_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ zconfpop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ zconffree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *zconfalloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *zconfrealloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void zconffree (void * ptr )
+{
+ free( (char *) ptr ); /* see zconfrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#undef YY_NEW_FILE
+#undef YY_FLUSH_BUFFER
+#undef yy_set_bol
+#undef yy_new_buffer
+#undef yy_set_interactive
+#undef yytext_ptr
+#undef YY_DO_BEFORE_ACTION
+
+#ifdef YY_DECL_IS_OURS
+#undef YY_DECL_IS_OURS
+#undef YY_DECL
+#endif
+
+void zconf_starthelp(void)
+{
+ new_string();
+ last_ts = first_ts = 0;
+ BEGIN(HELP);
+}
+
+static void zconf_endhelp(void)
+{
+ zconflval.string = text;
+ BEGIN(INITIAL);
+}
+
+/*
+ * Try to open specified file with following names:
+ * ./name
+ * $(srctree)/name
+ * The latter is used when srctree is separate from objtree
+ * when compiling the kernel.
+ * Return NULL if file is not found.
+ */
+FILE *zconf_fopen(const char *name)
+{
+ char *env, fullname[PATH_MAX+1];
+ FILE *f;
+
+ f = fopen(name, "r");
+ if (!f && name[0] != '/') {
+ env = getenv(SRCTREE);
+ if (env) {
+ sprintf(fullname, "%s/%s", env, name);
+ f = fopen(fullname, "r");
+ }
+ }
+ return f;
+}
+
+void zconf_initscan(const char *name)
+{
+ zconfin = zconf_fopen(name);
+ if (!zconfin) {
+ printf("can't find file %s\n", name);
+ exit(1);
+ }
+
+ current_buf = malloc(sizeof(*current_buf));
+ memset(current_buf, 0, sizeof(*current_buf));
+
+ current_file = file_lookup(name);
+ current_file->lineno = 1;
+ current_file->flags = FILE_BUSY;
+}
+
+void zconf_nextfile(const char *name)
+{
+ struct file *file = file_lookup(name);
+ struct buffer *buf = malloc(sizeof(*buf));
+ memset(buf, 0, sizeof(*buf));
+
+ current_buf->state = YY_CURRENT_BUFFER;
+ zconfin = zconf_fopen(name);
+ if (!zconfin) {
+ printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
+ exit(1);
+ }
+ zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE));
+ buf->parent = current_buf;
+ current_buf = buf;
+
+ if (file->flags & FILE_BUSY) {
+ printf("recursive scan (%s)?\n", name);
+ exit(1);
+ }
+ if (file->flags & FILE_SCANNED) {
+ printf("file %s already scanned?\n", name);
+ exit(1);
+ }
+ file->flags |= FILE_BUSY;
+ file->lineno = 1;
+ file->parent = current_file;
+ current_file = file;
+}
+
+static struct buffer *zconf_endfile(void)
+{
+ struct buffer *parent;
+
+ current_file->flags |= FILE_SCANNED;
+ current_file->flags &= ~FILE_BUSY;
+ current_file = current_file->parent;
+
+ parent = current_buf->parent;
+ if (parent) {
+ fclose(zconfin);
+ zconf_delete_buffer(YY_CURRENT_BUFFER);
+ zconf_switch_to_buffer(parent->state);
+ }
+ free(current_buf);
+ current_buf = parent;
+
+ return parent;
+}
+
+int zconf_lineno(void)
+{
+ if (current_buf)
+ return current_file->lineno - 1;
+ else
+ return 0;
+}
+
+char *zconf_curname(void)
+{
+ if (current_buf)
+ return current_file->name;
+ else
+ return "<none>";
+}
+
diff --git a/misc/buildroot/package/config/lkc.h b/misc/buildroot/package/config/lkc.h
new file mode 100644
index 000000000..b8a67fc9d
--- /dev/null
+++ b/misc/buildroot/package/config/lkc.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#ifndef LKC_H
+#define LKC_H
+
+#include "expr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef LKC_DIRECT_LINK
+#define P(name,type,arg) extern type name arg
+#else
+#include "lkc_defs.h"
+#define P(name,type,arg) extern type (*name ## _p) arg
+#endif
+#include "lkc_proto.h"
+#undef P
+
+#define SRCTREE "srctree"
+
+int zconfparse(void);
+void zconfdump(FILE *out);
+
+extern int zconfdebug;
+void zconf_starthelp(void);
+FILE *zconf_fopen(const char *name);
+void zconf_initscan(const char *name);
+void zconf_nextfile(const char *name);
+int zconf_lineno(void);
+char *zconf_curname(void);
+
+/* confdata.c */
+extern const char conf_def_filename[];
+extern char conf_filename[];
+
+char *conf_get_default_confname(void);
+
+/* kconfig_load.c */
+void kconfig_load(void);
+
+/* menu.c */
+void menu_init(void);
+void menu_add_menu(void);
+void menu_end_menu(void);
+void menu_add_entry(struct symbol *sym);
+void menu_end_entry(void);
+void menu_add_dep(struct expr *dep);
+struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
+void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
+void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
+void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
+void menu_finalize(struct menu *parent);
+void menu_set_type(int type);
+
+/* util.c */
+struct file *file_lookup(const char *name);
+int file_write_dep(const char *name);
+
+struct gstr {
+ size_t len;
+ char *s;
+};
+struct gstr str_new(void);
+struct gstr str_assign(const char *s);
+void str_free(struct gstr *gs);
+void str_append(struct gstr *gs, const char *s);
+void str_printf(struct gstr *gs, const char *fmt, ...);
+const char *str_get(struct gstr *gs);
+
+/* symbol.c */
+void sym_init(void);
+void sym_clear_all_valid(void);
+void sym_set_changed(struct symbol *sym);
+struct symbol *sym_check_deps(struct symbol *sym);
+struct property *prop_alloc(enum prop_type type, struct symbol *sym);
+struct symbol *prop_get_symbol(struct property *prop);
+
+static inline tristate sym_get_tristate_value(struct symbol *sym)
+{
+ return sym->curr.tri;
+}
+
+
+static inline struct symbol *sym_get_choice_value(struct symbol *sym)
+{
+ return (struct symbol *)sym->curr.val;
+}
+
+static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval)
+{
+ return sym_set_tristate_value(chval, yes);
+}
+
+static inline bool sym_is_choice(struct symbol *sym)
+{
+ return sym->flags & SYMBOL_CHOICE ? true : false;
+}
+
+static inline bool sym_is_choice_value(struct symbol *sym)
+{
+ return sym->flags & SYMBOL_CHOICEVAL ? true : false;
+}
+
+static inline bool sym_is_optional(struct symbol *sym)
+{
+ return sym->flags & SYMBOL_OPTIONAL ? true : false;
+}
+
+static inline bool sym_has_value(struct symbol *sym)
+{
+ return sym->flags & SYMBOL_NEW ? false : true;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LKC_H */
diff --git a/misc/buildroot/package/config/lkc_proto.h b/misc/buildroot/package/config/lkc_proto.h
new file mode 100644
index 000000000..6dc6d0c48
--- /dev/null
+++ b/misc/buildroot/package/config/lkc_proto.h
@@ -0,0 +1,40 @@
+
+/* confdata.c */
+P(conf_parse,void,(const char *name));
+P(conf_read,int,(const char *name));
+P(conf_write,int,(const char *name));
+
+/* menu.c */
+P(rootmenu,struct menu,);
+
+P(menu_is_visible,bool,(struct menu *menu));
+P(menu_get_prompt,const char *,(struct menu *menu));
+P(menu_get_root_menu,struct menu *,(struct menu *menu));
+P(menu_get_parent_menu,struct menu *,(struct menu *menu));
+
+/* symbol.c */
+P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
+P(sym_change_count,int,);
+
+P(sym_lookup,struct symbol *,(const char *name, int isconst));
+P(sym_find,struct symbol *,(const char *name));
+P(sym_re_search,struct symbol **,(const char *pattern));
+P(sym_type_name,const char *,(enum symbol_type type));
+P(sym_calc_value,void,(struct symbol *sym));
+P(sym_get_type,enum symbol_type,(struct symbol *sym));
+P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri));
+P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri));
+P(sym_toggle_tristate_value,tristate,(struct symbol *sym));
+P(sym_string_valid,bool,(struct symbol *sym, const char *newval));
+P(sym_string_within_range,bool,(struct symbol *sym, const char *str));
+P(sym_set_string_value,bool,(struct symbol *sym, const char *newval));
+P(sym_is_changable,bool,(struct symbol *sym));
+P(sym_get_choice_prop,struct property *,(struct symbol *sym));
+P(sym_get_default_prop,struct property *,(struct symbol *sym));
+P(sym_get_string_value,const char *,(struct symbol *sym));
+
+P(prop_get_type_name,const char *,(enum prop_type type));
+
+/* expr.c */
+P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2));
+P(expr_print,void,(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken));
diff --git a/misc/buildroot/package/config/lxdialog/BIG.FAT.WARNING b/misc/buildroot/package/config/lxdialog/BIG.FAT.WARNING
new file mode 100644
index 000000000..a8999d82b
--- /dev/null
+++ b/misc/buildroot/package/config/lxdialog/BIG.FAT.WARNING
@@ -0,0 +1,4 @@
+This is NOT the official version of dialog. This version has been
+significantly modified from the original. It is for use by the Linux
+kernel configuration script. Please do not bother Savio Lam with
+questions about this program.
diff --git a/misc/buildroot/package/config/lxdialog/checklist.c b/misc/buildroot/package/config/lxdialog/checklist.c
new file mode 100644
index 000000000..71de4a191
--- /dev/null
+++ b/misc/buildroot/package/config/lxdialog/checklist.c
@@ -0,0 +1,372 @@
+/*
+ * checklist.c -- implements the checklist box
+ *
+ * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
+ * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
+ * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+static int list_width, check_x, item_x, checkflag;
+
+/*
+ * Print list item
+ */
+static void
+print_item (WINDOW * win, const char *item, int status,
+ int choice, int selected)
+{
+ int i;
+
+ /* Clear 'residue' of last item */
+ wattrset (win, menubox_attr);
+ wmove (win, choice, 0);
+ for (i = 0; i < list_width; i++)
+ waddch (win, ' ');
+
+ wmove (win, choice, check_x);
+ wattrset (win, selected ? check_selected_attr : check_attr);
+ if (checkflag == FLAG_CHECK)
+ wprintw (win, "[%c]", status ? 'X' : ' ');
+ else
+ wprintw (win, "(%c)", status ? 'X' : ' ');
+
+ wattrset (win, selected ? tag_selected_attr : tag_attr);
+ mvwaddch(win, choice, item_x, item[0]);
+ wattrset (win, selected ? item_selected_attr : item_attr);
+ waddstr (win, (char *)item+1);
+ if (selected) {
+ wmove (win, choice, check_x+1);
+ wrefresh (win);
+ }
+}
+
+/*
+ * Print the scroll indicators.
+ */
+static void
+print_arrows (WINDOW * win, int choice, int item_no, int scroll,
+ int y, int x, int height)
+{
+ wmove(win, y, x);
+
+ if (scroll > 0) {
+ wattrset (win, uarrow_attr);
+ waddch (win, ACS_UARROW);
+ waddstr (win, "(-)");
+ }
+ else {
+ wattrset (win, menubox_attr);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ }
+
+ y = y + height + 1;
+ wmove(win, y, x);
+
+ if ((height < item_no) && (scroll + choice < item_no - 1)) {
+ wattrset (win, darrow_attr);
+ waddch (win, ACS_DARROW);
+ waddstr (win, "(+)");
+ }
+ else {
+ wattrset (win, menubox_border_attr);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ }
+}
+
+/*
+ * Display the termination buttons
+ */
+static void
+print_buttons( WINDOW *dialog, int height, int width, int selected)
+{
+ int x = width / 2 - 11;
+ int y = height - 2;
+
+ print_button (dialog, "Select", y, x, selected == 0);
+ print_button (dialog, " Help ", y, x + 14, selected == 1);
+
+ wmove(dialog, y, x+1 + 14*selected);
+ wrefresh (dialog);
+}
+
+/*
+ * Display a dialog box with a list of options that can be turned on or off
+ * The `flag' parameter is used to select between radiolist and checklist.
+ */
+int
+dialog_checklist (const char *title, const char *prompt, int height, int width,
+ int list_height, int item_no, struct dialog_list_item ** items,
+ int flag)
+
+{
+ int i, x, y, box_x, box_y;
+ int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
+ WINDOW *dialog, *list;
+
+ checkflag = flag;
+
+ /* Allocate space for storing item on/off status */
+ if ((status = malloc (sizeof (int) * item_no)) == NULL) {
+ endwin ();
+ fprintf (stderr,
+ "\nCan't allocate memory in dialog_checklist().\n");
+ exit (-1);
+ }
+
+ /* Initializes status */
+ for (i = 0; i < item_no; i++) {
+ status[i] = (items[i]->selected == 1); /* ON */
+ if ((!choice && status[i]) || items[i]->selected == 2) /* SELECTED */
+ choice = i + 1;
+ }
+ if (choice)
+ choice--;
+
+ max_choice = MIN (list_height, item_no);
+
+ /* center dialog box on screen */
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+ draw_shadow (stdscr, y, x, height, width);
+
+ dialog = newwin (height, width, y, x);
+ keypad (dialog, TRUE);
+
+ draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset (dialog, border_attr);
+ mvwaddch (dialog, height-3, 0, ACS_LTEE);
+ for (i = 0; i < width - 2; i++)
+ waddch (dialog, ACS_HLINE);
+ wattrset (dialog, dialog_attr);
+ waddch (dialog, ACS_RTEE);
+
+ if (title != NULL && strlen(title) >= width-2 ) {
+ /* truncate long title -- mec */
+ char * title2 = malloc(width-2+1);
+ memcpy( title2, title, width-2 );
+ title2[width-2] = '\0';
+ title = title2;
+ }
+
+ if (title != NULL) {
+ wattrset (dialog, title_attr);
+ mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+ waddstr (dialog, (char *)title);
+ waddch (dialog, ' ');
+ }
+
+ wattrset (dialog, dialog_attr);
+ print_autowrap (dialog, prompt, width - 2, 1, 3);
+
+ list_width = width - 6;
+ box_y = height - list_height - 5;
+ box_x = (width - list_width) / 2 - 1;
+
+ /* create new window for the list */
+ list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1);
+
+ keypad (list, TRUE);
+
+ /* draw a box around the list items */
+ draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2,
+ menubox_border_attr, menubox_attr);
+
+ /* Find length of longest item in order to center checklist */
+ check_x = 0;
+ for (i = 0; i < item_no; i++)
+ check_x = MAX (check_x, + strlen (items[i]->name) + 4);
+
+ check_x = (list_width - check_x) / 2;
+ item_x = check_x + 4;
+
+ if (choice >= list_height) {
+ scroll = choice - list_height + 1;
+ choice -= scroll;
+ }
+
+ /* Print the list */
+ for (i = 0; i < max_choice; i++) {
+ print_item (list, items[scroll + i]->name,
+ status[i+scroll], i, i == choice);
+ }
+
+ print_arrows(dialog, choice, item_no, scroll,
+ box_y, box_x + check_x + 5, list_height);
+
+ print_buttons(dialog, height, width, 0);
+
+ wnoutrefresh (list);
+ wnoutrefresh (dialog);
+ doupdate ();
+
+ while (key != ESC) {
+ key = wgetch (dialog);
+
+ for (i = 0; i < max_choice; i++)
+ if (toupper(key) == toupper(items[scroll + i]->name[0]))
+ break;
+
+
+ if ( i < max_choice || key == KEY_UP || key == KEY_DOWN ||
+ key == '+' || key == '-' ) {
+ if (key == KEY_UP || key == '-') {
+ if (!choice) {
+ if (!scroll)
+ continue;
+ /* Scroll list down */
+ if (list_height > 1) {
+ /* De-highlight current first item */
+ print_item (list, items[scroll]->name,
+ status[scroll], 0, FALSE);
+ scrollok (list, TRUE);
+ wscrl (list, -1);
+ scrollok (list, FALSE);
+ }
+ scroll--;
+ print_item (list, items[scroll]->name,
+ status[scroll], 0, TRUE);
+ wnoutrefresh (list);
+
+ print_arrows(dialog, choice, item_no, scroll,
+ box_y, box_x + check_x + 5, list_height);
+
+ wrefresh (dialog);
+
+ continue; /* wait for another key press */
+ } else
+ i = choice - 1;
+ } else if (key == KEY_DOWN || key == '+') {
+ if (choice == max_choice - 1) {
+ if (scroll + choice >= item_no - 1)
+ continue;
+ /* Scroll list up */
+ if (list_height > 1) {
+ /* De-highlight current last item before scrolling up */
+ print_item (list, items[scroll + max_choice - 1]->name,
+ status[scroll + max_choice - 1],
+ max_choice - 1, FALSE);
+ scrollok (list, TRUE);
+ scroll (list);
+ scrollok (list, FALSE);
+ }
+ scroll++;
+ print_item (list, items[scroll + max_choice - 1]->name,
+ status[scroll + max_choice - 1],
+ max_choice - 1, TRUE);
+ wnoutrefresh (list);
+
+ print_arrows(dialog, choice, item_no, scroll,
+ box_y, box_x + check_x + 5, list_height);
+
+ wrefresh (dialog);
+
+ continue; /* wait for another key press */
+ } else
+ i = choice + 1;
+ }
+ if (i != choice) {
+ /* De-highlight current item */
+ print_item (list, items[scroll + choice]->name,
+ status[scroll + choice], choice, FALSE);
+ /* Highlight new item */
+ choice = i;
+ print_item (list, items[scroll + choice]->name,
+ status[scroll + choice], choice, TRUE);
+ wnoutrefresh (list);
+ wrefresh (dialog);
+ }
+ continue; /* wait for another key press */
+ }
+ switch (key) {
+ case 'H':
+ case 'h':
+ case '?':
+ for (i = 0; i < item_no; i++)
+ items[i]->selected = 0;
+ items[scroll + choice]->selected = 1;
+ delwin (dialog);
+ free (status);
+ return 1;
+ case TAB:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ button = ((key == KEY_LEFT ? --button : ++button) < 0)
+ ? 1 : (button > 1 ? 0 : button);
+
+ print_buttons(dialog, height, width, button);
+ wrefresh (dialog);
+ break;
+ case 'S':
+ case 's':
+ case ' ':
+ case '\n':
+ if (!button) {
+ if (flag == FLAG_CHECK) {
+ status[scroll + choice] = !status[scroll + choice];
+ wmove (list, choice, check_x);
+ wattrset (list, check_selected_attr);
+ wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' ');
+ } else {
+ if (!status[scroll + choice]) {
+ for (i = 0; i < item_no; i++)
+ status[i] = 0;
+ status[scroll + choice] = 1;
+ for (i = 0; i < max_choice; i++)
+ print_item (list, items[scroll + i]->name,
+ status[scroll + i], i, i == choice);
+ }
+ }
+ wnoutrefresh (list);
+ wrefresh (dialog);
+
+ for (i = 0; i < item_no; i++) {
+ items[i]->selected = status[i];
+ }
+ } else {
+ for (i = 0; i < item_no; i++)
+ items[i]->selected = 0;
+ items[scroll + choice]->selected = 1;
+ }
+ delwin (dialog);
+ free (status);
+ return button;
+ case 'X':
+ case 'x':
+ key = ESC;
+ case ESC:
+ break;
+ }
+
+ /* Now, update everything... */
+ doupdate ();
+ }
+
+
+ delwin (dialog);
+ free (status);
+ return -1; /* ESC pressed */
+}
diff --git a/misc/buildroot/package/config/lxdialog/colors.h b/misc/buildroot/package/config/lxdialog/colors.h
new file mode 100644
index 000000000..d34dd37c6
--- /dev/null
+++ b/misc/buildroot/package/config/lxdialog/colors.h
@@ -0,0 +1,161 @@
+/*
+ * colors.h -- color attribute definitions
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * Default color definitions
+ *
+ * *_FG = foreground
+ * *_BG = background
+ * *_HL = highlight?
+ */
+#define SCREEN_FG COLOR_CYAN
+#define SCREEN_BG COLOR_BLUE
+#define SCREEN_HL TRUE
+
+#define SHADOW_FG COLOR_BLACK
+#define SHADOW_BG COLOR_BLACK
+#define SHADOW_HL TRUE
+
+#define DIALOG_FG COLOR_BLACK
+#define DIALOG_BG COLOR_WHITE
+#define DIALOG_HL FALSE
+
+#define TITLE_FG COLOR_YELLOW
+#define TITLE_BG COLOR_WHITE
+#define TITLE_HL TRUE
+
+#define BORDER_FG COLOR_WHITE
+#define BORDER_BG COLOR_WHITE
+#define BORDER_HL TRUE
+
+#define BUTTON_ACTIVE_FG COLOR_WHITE
+#define BUTTON_ACTIVE_BG COLOR_BLUE
+#define BUTTON_ACTIVE_HL TRUE
+
+#define BUTTON_INACTIVE_FG COLOR_BLACK
+#define BUTTON_INACTIVE_BG COLOR_WHITE
+#define BUTTON_INACTIVE_HL FALSE
+
+#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE
+#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE
+#define BUTTON_KEY_ACTIVE_HL TRUE
+
+#define BUTTON_KEY_INACTIVE_FG COLOR_RED
+#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE
+#define BUTTON_KEY_INACTIVE_HL FALSE
+
+#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW
+#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE
+#define BUTTON_LABEL_ACTIVE_HL TRUE
+
+#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK
+#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE
+#define BUTTON_LABEL_INACTIVE_HL TRUE
+
+#define INPUTBOX_FG COLOR_BLACK
+#define INPUTBOX_BG COLOR_WHITE
+#define INPUTBOX_HL FALSE
+
+#define INPUTBOX_BORDER_FG COLOR_BLACK
+#define INPUTBOX_BORDER_BG COLOR_WHITE
+#define INPUTBOX_BORDER_HL FALSE
+
+#define SEARCHBOX_FG COLOR_BLACK
+#define SEARCHBOX_BG COLOR_WHITE
+#define SEARCHBOX_HL FALSE
+
+#define SEARCHBOX_TITLE_FG COLOR_YELLOW
+#define SEARCHBOX_TITLE_BG COLOR_WHITE
+#define SEARCHBOX_TITLE_HL TRUE
+
+#define SEARCHBOX_BORDER_FG COLOR_WHITE
+#define SEARCHBOX_BORDER_BG COLOR_WHITE
+#define SEARCHBOX_BORDER_HL TRUE
+
+#define POSITION_INDICATOR_FG COLOR_YELLOW
+#define POSITION_INDICATOR_BG COLOR_WHITE
+#define POSITION_INDICATOR_HL TRUE
+
+#define MENUBOX_FG COLOR_BLACK
+#define MENUBOX_BG COLOR_WHITE
+#define MENUBOX_HL FALSE
+
+#define MENUBOX_BORDER_FG COLOR_WHITE
+#define MENUBOX_BORDER_BG COLOR_WHITE
+#define MENUBOX_BORDER_HL TRUE
+
+#define ITEM_FG COLOR_BLACK
+#define ITEM_BG COLOR_WHITE
+#define ITEM_HL FALSE
+
+#define ITEM_SELECTED_FG COLOR_WHITE
+#define ITEM_SELECTED_BG COLOR_BLUE
+#define ITEM_SELECTED_HL TRUE
+
+#define TAG_FG COLOR_YELLOW
+#define TAG_BG COLOR_WHITE
+#define TAG_HL TRUE
+
+#define TAG_SELECTED_FG COLOR_YELLOW
+#define TAG_SELECTED_BG COLOR_BLUE
+#define TAG_SELECTED_HL TRUE
+
+#define TAG_KEY_FG COLOR_YELLOW
+#define TAG_KEY_BG COLOR_WHITE
+#define TAG_KEY_HL TRUE
+
+#define TAG_KEY_SELECTED_FG COLOR_YELLOW
+#define TAG_KEY_SELECTED_BG COLOR_BLUE
+#define TAG_KEY_SELECTED_HL TRUE
+
+#define CHECK_FG COLOR_BLACK
+#define CHECK_BG COLOR_WHITE
+#define CHECK_HL FALSE
+
+#define CHECK_SELECTED_FG COLOR_WHITE
+#define CHECK_SELECTED_BG COLOR_BLUE
+#define CHECK_SELECTED_HL TRUE
+
+#define UARROW_FG COLOR_GREEN
+#define UARROW_BG COLOR_WHITE
+#define UARROW_HL TRUE
+
+#define DARROW_FG COLOR_GREEN
+#define DARROW_BG COLOR_WHITE
+#define DARROW_HL TRUE
+
+/* End of default color definitions */
+
+#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
+#define COLOR_NAME_LEN 10
+#define COLOR_COUNT 8
+
+/*
+ * Global variables
+ */
+
+typedef struct {
+ char name[COLOR_NAME_LEN];
+ int value;
+} color_names_st;
+
+extern color_names_st color_names[];
+extern int color_table[][3];
diff --git a/misc/buildroot/package/config/lxdialog/dialog.h b/misc/buildroot/package/config/lxdialog/dialog.h
new file mode 100644
index 000000000..7bab3ad0e
--- /dev/null
+++ b/misc/buildroot/package/config/lxdialog/dialog.h
@@ -0,0 +1,199 @@
+
+/*
+ * dialog.h -- common declarations for all dialog modules
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef CURSES_LOC
+#ifdef __sun__
+#define CURS_MACROS
+#endif
+#include CURSES_LOC
+
+/*
+ * Colors in ncurses 1.9.9e do not work properly since foreground and
+ * background colors are OR'd rather than separately masked. This version
+ * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible
+ * with standard curses. The simplest fix (to make this work with standard
+ * curses) uses the wbkgdset() function, not used in the original hack.
+ * Turn it off if we're building with 1.9.9e, since it just confuses things.
+ */
+#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
+#define OLD_NCURSES 1
+#undef wbkgdset
+#define wbkgdset(w,p) /*nothing*/
+#else
+#define OLD_NCURSES 0
+#endif
+
+#define TR(params) _tracef params
+
+#define ESC 27
+#define TAB 9
+#define MAX_LEN 2048
+#define BUF_SIZE (10*1024)
+#define MIN(x,y) (x < y ? x : y)
+#define MAX(x,y) (x > y ? x : y)
+
+
+#ifndef ACS_ULCORNER
+#define ACS_ULCORNER '+'
+#endif
+#ifndef ACS_LLCORNER
+#define ACS_LLCORNER '+'
+#endif
+#ifndef ACS_URCORNER
+#define ACS_URCORNER '+'
+#endif
+#ifndef ACS_LRCORNER
+#define ACS_LRCORNER '+'
+#endif
+#ifndef ACS_HLINE
+#define ACS_HLINE '-'
+#endif
+#ifndef ACS_VLINE
+#define ACS_VLINE '|'
+#endif
+#ifndef ACS_LTEE
+#define ACS_LTEE '+'
+#endif
+#ifndef ACS_RTEE
+#define ACS_RTEE '+'
+#endif
+#ifndef ACS_UARROW
+#define ACS_UARROW '^'
+#endif
+#ifndef ACS_DARROW
+#define ACS_DARROW 'v'
+#endif
+
+/*
+ * Attribute names
+ */
+#define screen_attr attributes[0]
+#define shadow_attr attributes[1]
+#define dialog_attr attributes[2]
+#define title_attr attributes[3]
+#define border_attr attributes[4]
+#define button_active_attr attributes[5]
+#define button_inactive_attr attributes[6]
+#define button_key_active_attr attributes[7]
+#define button_key_inactive_attr attributes[8]
+#define button_label_active_attr attributes[9]
+#define button_label_inactive_attr attributes[10]
+#define inputbox_attr attributes[11]
+#define inputbox_border_attr attributes[12]
+#define searchbox_attr attributes[13]
+#define searchbox_title_attr attributes[14]
+#define searchbox_border_attr attributes[15]
+#define position_indicator_attr attributes[16]
+#define menubox_attr attributes[17]
+#define menubox_border_attr attributes[18]
+#define item_attr attributes[19]
+#define item_selected_attr attributes[20]
+#define tag_attr attributes[21]
+#define tag_selected_attr attributes[22]
+#define tag_key_attr attributes[23]
+#define tag_key_selected_attr attributes[24]
+#define check_attr attributes[25]
+#define check_selected_attr attributes[26]
+#define uarrow_attr attributes[27]
+#define darrow_attr attributes[28]
+
+/* number of attributes */
+#define ATTRIBUTE_COUNT 29
+
+/*
+ * Global variables
+ */
+extern bool use_colors;
+
+extern chtype attributes[];
+#endif
+
+extern const char *backtitle;
+
+struct dialog_list_item {
+ char *name;
+ int namelen;
+ char *tag;
+ int selected; /* Set to 1 by dialog_*() function. */
+};
+
+/*
+ * Function prototypes
+ */
+
+void init_dialog (void);
+void end_dialog (void);
+void dialog_clear (void);
+#ifdef CURSES_LOC
+void attr_clear (WINDOW * win, int height, int width, chtype attr);
+void color_setup (void);
+void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x);
+void print_button (WINDOW * win, const char *label, int y, int x, int selected);
+void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box,
+ chtype border);
+void draw_shadow (WINDOW * win, int y, int x, int height, int width);
+#endif
+
+int first_alpha (const char *string, const char *exempt);
+int dialog_yesno (const char *title, const char *prompt, int height, int width);
+int dialog_msgbox (const char *title, const char *prompt, int height,
+ int width, int pause);
+int dialog_textbox (const char *title, const char *file, int height, int width);
+int dialog_menu (const char *title, const char *prompt, int height, int width,
+ int menu_height, const char *choice, int item_no,
+ struct dialog_list_item ** items);
+int dialog_checklist (const char *title, const char *prompt, int height,
+ int width, int list_height, int item_no,
+ struct dialog_list_item ** items, int flag);
+extern unsigned char dialog_input_result[];
+int dialog_inputbox (const char *title, const char *prompt, int height,
+ int width, const char *init);
+
+struct dialog_list_item *first_sel_item(int item_no,
+ struct dialog_list_item ** items);
+
+/*
+ * This is the base for fictitious keys, which activate
+ * the buttons.
+ *
+ * Mouse-generated keys are the following:
+ * -- the first 32 are used as numbers, in addition to '0'-'9'
+ * -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o')
+ * -- uppercase chars are used to invoke the button (M_EVENT + 'O')
+ */
+#ifdef CURSES_LOC
+#define M_EVENT (KEY_MAX+1)
+#endif
+
+
+/*
+ * The `flag' parameter in checklist is used to select between
+ * radiolist and checklist
+ */
+#define FLAG_CHECK 1
+#define FLAG_RADIO 0
diff --git a/misc/buildroot/package/config/lxdialog/inputbox.c b/misc/buildroot/package/config/lxdialog/inputbox.c
new file mode 100644
index 000000000..fa7bebc69
--- /dev/null
+++ b/misc/buildroot/package/config/lxdialog/inputbox.c
@@ -0,0 +1,240 @@
+/*
+ * inputbox.c -- implements the input box
+ *
+ * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+unsigned char dialog_input_result[MAX_LEN + 1];
+
+/*
+ * Print the termination buttons
+ */
+static void
+print_buttons(WINDOW *dialog, int height, int width, int selected)
+{
+ int x = width / 2 - 11;
+ int y = height - 2;
+
+ print_button (dialog, " Ok ", y, x, selected==0);
+ print_button (dialog, " Help ", y, x + 14, selected==1);
+
+ wmove(dialog, y, x+1+14*selected);
+ wrefresh(dialog);
+}
+
+/*
+ * Display a dialog box for inputing a string
+ */
+int
+dialog_inputbox (const char *title, const char *prompt, int height, int width,
+ const char *init)
+{
+ int i, x, y, box_y, box_x, box_width;
+ int input_x = 0, scroll = 0, key = 0, button = -1;
+ unsigned char *instr = dialog_input_result;
+ WINDOW *dialog;
+
+ /* center dialog box on screen */
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+
+ draw_shadow (stdscr, y, x, height, width);
+
+ dialog = newwin (height, width, y, x);
+ keypad (dialog, TRUE);
+
+ draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset (dialog, border_attr);
+ mvwaddch (dialog, height-3, 0, ACS_LTEE);
+ for (i = 0; i < width - 2; i++)
+ waddch (dialog, ACS_HLINE);
+ wattrset (dialog, dialog_attr);
+ waddch (dialog, ACS_RTEE);
+
+ if (title != NULL && strlen(title) >= width-2 ) {
+ /* truncate long title -- mec */
+ char * title2 = malloc(width-2+1);
+ memcpy( title2, title, width-2 );
+ title2[width-2] = '\0';
+ title = title2;
+ }
+
+ if (title != NULL) {
+ wattrset (dialog, title_attr);
+ mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+ waddstr (dialog, (char *)title);
+ waddch (dialog, ' ');
+ }
+
+ wattrset (dialog, dialog_attr);
+ print_autowrap (dialog, prompt, width - 2, 1, 3);
+
+ /* Draw the input field box */
+ box_width = width - 6;
+ getyx (dialog, y, x);
+ box_y = y + 2;
+ box_x = (width - box_width) / 2;
+ draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2,
+ border_attr, dialog_attr);
+
+ print_buttons(dialog, height, width, 0);
+
+ /* Set up the initial value */
+ wmove (dialog, box_y, box_x);
+ wattrset (dialog, inputbox_attr);
+
+ if (!init)
+ instr[0] = '\0';
+ else
+ strcpy (instr, init);
+
+ input_x = strlen (instr);
+
+ if (input_x >= box_width) {
+ scroll = input_x - box_width + 1;
+ input_x = box_width - 1;
+ for (i = 0; i < box_width - 1; i++)
+ waddch (dialog, instr[scroll + i]);
+ } else
+ waddstr (dialog, instr);
+
+ wmove (dialog, box_y, box_x + input_x);
+
+ wrefresh (dialog);
+
+ while (key != ESC) {
+ key = wgetch (dialog);
+
+ if (button == -1) { /* Input box selected */
+ switch (key) {
+ case TAB:
+ case KEY_UP:
+ case KEY_DOWN:
+ break;
+ case KEY_LEFT:
+ continue;
+ case KEY_RIGHT:
+ continue;
+ case KEY_BACKSPACE:
+ case 127:
+ if (input_x || scroll) {
+ wattrset (dialog, inputbox_attr);
+ if (!input_x) {
+ scroll = scroll < box_width - 1 ?
+ 0 : scroll - (box_width - 1);
+ wmove (dialog, box_y, box_x);
+ for (i = 0; i < box_width; i++)
+ waddch (dialog, instr[scroll + input_x + i] ?
+ instr[scroll + input_x + i] : ' ');
+ input_x = strlen (instr) - scroll;
+ } else
+ input_x--;
+ instr[scroll + input_x] = '\0';
+ mvwaddch (dialog, box_y, input_x + box_x, ' ');
+ wmove (dialog, box_y, input_x + box_x);
+ wrefresh (dialog);
+ }
+ continue;
+ default:
+ if (key < 0x100 && isprint (key)) {
+ if (scroll + input_x < MAX_LEN) {
+ wattrset (dialog, inputbox_attr);
+ instr[scroll + input_x] = key;
+ instr[scroll + input_x + 1] = '\0';
+ if (input_x == box_width - 1) {
+ scroll++;
+ wmove (dialog, box_y, box_x);
+ for (i = 0; i < box_width - 1; i++)
+ waddch (dialog, instr[scroll + i]);
+ } else {
+ wmove (dialog, box_y, input_x++ + box_x);
+ waddch (dialog, key);
+ }
+ wrefresh (dialog);
+ } else
+ flash (); /* Alarm user about overflow */
+ continue;
+ }
+ }
+ }
+ switch (key) {
+ case 'O':
+ case 'o':
+ delwin (dialog);
+ return 0;
+ case 'H':
+ case 'h':
+ delwin (dialog);
+ return 1;
+ case KEY_UP:
+ case KEY_LEFT:
+ switch (button) {
+ case -1:
+ button = 1; /* Indicates "Cancel" button is selected */
+ print_buttons(dialog, height, width, 1);
+ break;
+ case 0:
+ button = -1; /* Indicates input box is selected */
+ print_buttons(dialog, height, width, 0);
+ wmove (dialog, box_y, box_x + input_x);
+ wrefresh (dialog);
+ break;
+ case 1:
+ button = 0; /* Indicates "OK" button is selected */
+ print_buttons(dialog, height, width, 0);
+ break;
+ }
+ break;
+ case TAB:
+ case KEY_DOWN:
+ case KEY_RIGHT:
+ switch (button) {
+ case -1:
+ button = 0; /* Indicates "OK" button is selected */
+ print_buttons(dialog, height, width, 0);
+ break;
+ case 0:
+ button = 1; /* Indicates "Cancel" button is selected */
+ print_buttons(dialog, height, width, 1);
+ break;
+ case 1:
+ button = -1; /* Indicates input box is selected */
+ print_buttons(dialog, height, width, 0);
+ wmove (dialog, box_y, box_x + input_x);
+ wrefresh (dialog);
+ break;
+ }
+ break;
+ case ' ':
+ case '\n':
+ delwin (dialog);
+ return (button == -1 ? 0 : button);
+ case 'X':
+ case 'x':
+ key = ESC;
+ case ESC:
+ break;
+ }
+ }
+
+ delwin (dialog);
+ return -1; /* ESC pressed */
+}
diff --git a/misc/buildroot/package/config/lxdialog/menubox.c b/misc/buildroot/package/config/lxdialog/menubox.c
new file mode 100644
index 000000000..873dc587b
--- /dev/null
+++ b/misc/buildroot/package/config/lxdialog/menubox.c
@@ -0,0 +1,438 @@
+/*
+ * menubox.c -- implements the menu box
+ *
+ * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Changes by Clifford Wolf (god@clifford.at)
+ *
+ * [ 1998-06-13 ]
+ *
+ * *) A bugfix for the Page-Down problem
+ *
+ * *) Formerly when I used Page Down and Page Up, the cursor would be set
+ * to the first position in the menu box. Now lxdialog is a bit
+ * smarter and works more like other menu systems (just have a look at
+ * it).
+ *
+ * *) Formerly if I selected something my scrolling would be broken because
+ * lxdialog is re-invoked by the Menuconfig shell script, can't
+ * remember the last scrolling position, and just sets it so that the
+ * cursor is at the bottom of the box. Now it writes the temporary file
+ * lxdialog.scrltmp which contains this information. The file is
+ * deleted by lxdialog if the user leaves a submenu or enters a new
+ * one, but it would be nice if Menuconfig could make another "rm -f"
+ * just to be sure. Just try it out - you will recognise a difference!
+ *
+ * [ 1998-06-14 ]
+ *
+ * *) Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
+ * and menus change their size on the fly.
+ *
+ * *) If for some reason the last scrolling position is not saved by
+ * lxdialog, it sets the scrolling so that the selected item is in the
+ * middle of the menu box, not at the bottom.
+ *
+ * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
+ * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
+ * This fixes a bug in Menuconfig where using ' ' to descend into menus
+ * would leave mis-synchronized lxdialog.scrltmp files lying around,
+ * fscanf would read in 'scroll', and eventually that value would get used.
+ */
+
+#include "dialog.h"
+
+static int menu_width, item_x;
+
+/*
+ * Print menu item
+ */
+static void
+print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey)
+{
+ int j;
+ char menu_item[menu_width+1];
+
+ strncpy(menu_item, item, menu_width);
+ menu_item[menu_width] = 0;
+ j = first_alpha(menu_item, "YyNnMmHh");
+
+ /* Clear 'residue' of last item */
+ wattrset (win, menubox_attr);
+ wmove (win, choice, 0);
+#if OLD_NCURSES
+ {
+ int i;
+ for (i = 0; i < menu_width; i++)
+ waddch (win, ' ');
+ }
+#else
+ wclrtoeol(win);
+#endif
+ wattrset (win, selected ? item_selected_attr : item_attr);
+ mvwaddstr (win, choice, item_x, menu_item);
+ if (hotkey) {
+ wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
+ mvwaddch(win, choice, item_x+j, menu_item[j]);
+ }
+ if (selected) {
+ wmove (win, choice, item_x+1);
+ wrefresh (win);
+ }
+}
+
+/*
+ * Print the scroll indicators.
+ */
+static void
+print_arrows (WINDOW * win, int item_no, int scroll,
+ int y, int x, int height)
+{
+ int cur_y, cur_x;
+
+ getyx(win, cur_y, cur_x);
+
+ wmove(win, y, x);
+
+ if (scroll > 0) {
+ wattrset (win, uarrow_attr);
+ waddch (win, ACS_UARROW);
+ waddstr (win, "(-)");
+ }
+ else {
+ wattrset (win, menubox_attr);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ }
+
+ y = y + height + 1;
+ wmove(win, y, x);
+
+ if ((height < item_no) && (scroll + height < item_no)) {
+ wattrset (win, darrow_attr);
+ waddch (win, ACS_DARROW);
+ waddstr (win, "(+)");
+ }
+ else {
+ wattrset (win, menubox_border_attr);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ }
+
+ wmove(win, cur_y, cur_x);
+}
+
+/*
+ * Display the termination buttons.
+ */
+static void
+print_buttons (WINDOW *win, int height, int width, int selected)
+{
+ int x = width / 2 - 16;
+ int y = height - 2;
+
+ print_button (win, "Select", y, x, selected == 0);
+ print_button (win, " Exit ", y, x + 12, selected == 1);
+ print_button (win, " Help ", y, x + 24, selected == 2);
+
+ wmove(win, y, x+1+12*selected);
+ wrefresh (win);
+}
+
+/*
+ * Display a menu for choosing among a number of options
+ */
+int
+dialog_menu (const char *title, const char *prompt, int height, int width,
+ int menu_height, const char *current, int item_no,
+ struct dialog_list_item ** items)
+{
+ int i, j, x, y, box_x, box_y;
+ int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice;
+ WINDOW *dialog, *menu;
+ FILE *f;
+
+ max_choice = MIN (menu_height, item_no);
+
+ /* center dialog box on screen */
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+ draw_shadow (stdscr, y, x, height, width);
+
+ dialog = newwin (height, width, y, x);
+ keypad (dialog, TRUE);
+
+ draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset (dialog, border_attr);
+ mvwaddch (dialog, height - 3, 0, ACS_LTEE);
+ for (i = 0; i < width - 2; i++)
+ waddch (dialog, ACS_HLINE);
+ wattrset (dialog, dialog_attr);
+ wbkgdset (dialog, dialog_attr & A_COLOR);
+ waddch (dialog, ACS_RTEE);
+
+ if (title != NULL && strlen(title) >= width-2 ) {
+ /* truncate long title -- mec */
+ char * title2 = malloc(width-2+1);
+ memcpy( title2, title, width-2 );
+ title2[width-2] = '\0';
+ title = title2;
+ }
+
+ if (title != NULL) {
+ wattrset (dialog, title_attr);
+ mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+ waddstr (dialog, (char *)title);
+ waddch (dialog, ' ');
+ }
+
+ wattrset (dialog, dialog_attr);
+ print_autowrap (dialog, prompt, width - 2, 1, 3);
+
+ menu_width = width - 6;
+ box_y = height - menu_height - 5;
+ box_x = (width - menu_width) / 2 - 1;
+
+ /* create new window for the menu */
+ menu = subwin (dialog, menu_height, menu_width,
+ y + box_y + 1, x + box_x + 1);
+ keypad (menu, TRUE);
+
+ /* draw a box around the menu items */
+ draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2,
+ menubox_border_attr, menubox_attr);
+
+ /*
+ * Find length of longest item in order to center menu.
+ * Set 'choice' to default item.
+ */
+ item_x = 0;
+ for (i = 0; i < item_no; i++) {
+ item_x = MAX (item_x, MIN(menu_width, strlen (items[i]->name) + 2));
+ if (strcmp(current, items[i]->tag) == 0) choice = i;
+ }
+
+ item_x = (menu_width - item_x) / 2;
+
+ /* get the scroll info from the temp file */
+ if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) {
+ if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) &&
+ (scroll+max_choice > choice) && (scroll >= 0) &&
+ (scroll+max_choice <= item_no) ) {
+ first_item = scroll;
+ choice = choice - scroll;
+ fclose(f);
+ } else {
+ scroll=0;
+ remove("lxdialog.scrltmp");
+ fclose(f);
+ f=NULL;
+ }
+ }
+ if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) {
+ if (choice >= item_no-max_choice/2)
+ scroll = first_item = item_no-max_choice;
+ else
+ scroll = first_item = choice - max_choice/2;
+ choice = choice - scroll;
+ }
+
+ /* Print the menu */
+ for (i=0; i < max_choice; i++) {
+ print_item (menu, items[first_item + i]->name, i, i == choice,
+ (items[first_item + i]->tag[0] != ':'));
+ }
+
+ wnoutrefresh (menu);
+
+ print_arrows(dialog, item_no, scroll,
+ box_y, box_x+item_x+1, menu_height);
+
+ print_buttons (dialog, height, width, 0);
+ wmove (menu, choice, item_x+1);
+ wrefresh (menu);
+
+ while (key != ESC) {
+ key = wgetch(menu);
+
+ if (key < 256 && isalpha(key)) key = tolower(key);
+
+ if (strchr("ynmh", key))
+ i = max_choice;
+ else {
+ for (i = choice+1; i < max_choice; i++) {
+ j = first_alpha(items[scroll + i]->name, "YyNnMmHh");
+ if (key == tolower(items[scroll + i]->name[j]))
+ break;
+ }
+ if (i == max_choice)
+ for (i = 0; i < max_choice; i++) {
+ j = first_alpha(items[scroll + i]->name, "YyNnMmHh");
+ if (key == tolower(items[scroll + i]->name[j]))
+ break;
+ }
+ }
+
+ if (i < max_choice ||
+ key == KEY_UP || key == KEY_DOWN ||
+ key == '-' || key == '+' ||
+ key == KEY_PPAGE || key == KEY_NPAGE) {
+
+ print_item (menu, items[scroll + choice]->name, choice, FALSE,
+ (items[scroll + choice]->tag[0] != ':'));
+
+ if (key == KEY_UP || key == '-') {
+ if (choice < 2 && scroll) {
+ /* Scroll menu down */
+ scrollok (menu, TRUE);
+ wscrl (menu, -1);
+ scrollok (menu, FALSE);
+
+ scroll--;
+
+ print_item (menu, items[scroll]->name, 0, FALSE,
+ (items[scroll]->tag[0] != ':'));
+ } else
+ choice = MAX(choice - 1, 0);
+
+ } else if (key == KEY_DOWN || key == '+') {
+
+ print_item (menu, items[scroll + choice]->name, choice, FALSE,
+ (items[scroll + choice]->tag[0] != ':'));
+
+ if ((choice > max_choice-3) &&
+ (scroll + max_choice < item_no)
+ ) {
+ /* Scroll menu up */
+ scrollok (menu, TRUE);
+ scroll (menu);
+ scrollok (menu, FALSE);
+
+ scroll++;
+
+ print_item (menu, items[scroll + max_choice - 1]->name,
+ max_choice-1, FALSE,
+ (items[scroll + max_choice - 1]->tag[0] != ':'));
+ } else
+ choice = MIN(choice+1, max_choice-1);
+
+ } else if (key == KEY_PPAGE) {
+ scrollok (menu, TRUE);
+ for (i=0; (i < max_choice); i++) {
+ if (scroll > 0) {
+ wscrl (menu, -1);
+ scroll--;
+ print_item (menu, items[scroll]->name, 0, FALSE,
+ (items[scroll]->tag[0] != ':'));
+ } else {
+ if (choice > 0)
+ choice--;
+ }
+ }
+ scrollok (menu, FALSE);
+
+ } else if (key == KEY_NPAGE) {
+ for (i=0; (i < max_choice); i++) {
+ if (scroll+max_choice < item_no) {
+ scrollok (menu, TRUE);
+ scroll(menu);
+ scrollok (menu, FALSE);
+ scroll++;
+ print_item (menu, items[scroll + max_choice - 1]->name,
+ max_choice-1, FALSE,
+ (items[scroll + max_choice - 1]->tag[0] != ':'));
+ } else {
+ if (choice+1 < max_choice)
+ choice++;
+ }
+ }
+
+ } else
+ choice = i;
+
+ print_item (menu, items[scroll + choice]->name, choice, TRUE,
+ (items[scroll + choice]->tag[0] != ':'));
+
+ print_arrows(dialog, item_no, scroll,
+ box_y, box_x+item_x+1, menu_height);
+
+ wnoutrefresh (dialog);
+ wrefresh (menu);
+
+ continue; /* wait for another key press */
+ }
+
+ switch (key) {
+ case KEY_LEFT:
+ case TAB:
+ case KEY_RIGHT:
+ button = ((key == KEY_LEFT ? --button : ++button) < 0)
+ ? 2 : (button > 2 ? 0 : button);
+
+ print_buttons(dialog, height, width, button);
+ wrefresh (menu);
+ break;
+ case ' ':
+ case 's':
+ case 'y':
+ case 'n':
+ case 'm':
+ case '/':
+ /* save scroll info */
+ if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) {
+ fprintf(f,"%d\n",scroll);
+ fclose(f);
+ }
+ delwin (dialog);
+ items[scroll + choice]->selected = 1;
+ switch (key) {
+ case 's': return 3;
+ case 'y': return 3;
+ case 'n': return 4;
+ case 'm': return 5;
+ case ' ': return 6;
+ case '/': return 7;
+ }
+ return 0;
+ case 'h':
+ case '?':
+ button = 2;
+ case '\n':
+ delwin (dialog);
+ items[scroll + choice]->selected = 1;
+
+ remove("lxdialog.scrltmp");
+ return button;
+ case 'e':
+ case 'x':
+ key = ESC;
+ case ESC:
+ break;
+ }
+ }
+
+ delwin (dialog);
+ remove("lxdialog.scrltmp");
+ return -1; /* ESC pressed */
+}
diff --git a/misc/buildroot/package/config/lxdialog/msgbox.c b/misc/buildroot/package/config/lxdialog/msgbox.c
new file mode 100644
index 000000000..93692e1fb
--- /dev/null
+++ b/misc/buildroot/package/config/lxdialog/msgbox.c
@@ -0,0 +1,85 @@
+/*
+ * msgbox.c -- implements the message box and info box
+ *
+ * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+/*
+ * Display a message box. Program will pause and display an "OK" button
+ * if the parameter 'pause' is non-zero.
+ */
+int
+dialog_msgbox (const char *title, const char *prompt, int height, int width,
+ int pause)
+{
+ int i, x, y, key = 0;
+ WINDOW *dialog;
+
+ /* center dialog box on screen */
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+ draw_shadow (stdscr, y, x, height, width);
+
+ dialog = newwin (height, width, y, x);
+ keypad (dialog, TRUE);
+
+ draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+ if (title != NULL && strlen(title) >= width-2 ) {
+ /* truncate long title -- mec */
+ char * title2 = malloc(width-2+1);
+ memcpy( title2, title, width-2 );
+ title2[width-2] = '\0';
+ title = title2;
+ }
+
+ if (title != NULL) {
+ wattrset (dialog, title_attr);
+ mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+ waddstr (dialog, (char *)title);
+ waddch (dialog, ' ');
+ }
+ wattrset (dialog, dialog_attr);
+ print_autowrap (dialog, prompt, width - 2, 1, 2);
+
+ if (pause) {
+ wattrset (dialog, border_attr);
+ mvwaddch (dialog, height - 3, 0, ACS_LTEE);
+ for (i = 0; i < width - 2; i++)
+ waddch (dialog, ACS_HLINE);
+ wattrset (dialog, dialog_attr);
+ waddch (dialog, ACS_RTEE);
+
+ print_button (dialog, " Ok ",
+ height - 2, width / 2 - 4, TRUE);
+
+ wrefresh (dialog);
+ while (key != ESC && key != '\n' && key != ' ' &&
+ key != 'O' && key != 'o' && key != 'X' && key != 'x')
+ key = wgetch (dialog);
+ } else {
+ key = '\n';
+ wrefresh (dialog);
+ }
+
+ delwin (dialog);
+ return key == ESC ? -1 : 0;
+}
diff --git a/misc/buildroot/package/config/lxdialog/textbox.c b/misc/buildroot/package/config/lxdialog/textbox.c
new file mode 100644
index 000000000..a5a460b5c
--- /dev/null
+++ b/misc/buildroot/package/config/lxdialog/textbox.c
@@ -0,0 +1,556 @@
+/*
+ * textbox.c -- implements the text box
+ *
+ * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+static void back_lines (int n);
+static void print_page (WINDOW * win, int height, int width);
+static void print_line (WINDOW * win, int row, int width);
+static char *get_line (void);
+static void print_position (WINDOW * win, int height, int width);
+
+static int hscroll, fd, file_size, bytes_read;
+static int begin_reached = 1, end_reached, page_length;
+static char *buf, *page;
+
+/*
+ * Display text from a file in a dialog box.
+ */
+int
+dialog_textbox (const char *title, const char *file, int height, int width)
+{
+ int i, x, y, cur_x, cur_y, fpos, key = 0;
+ int passed_end;
+ char search_term[MAX_LEN + 1];
+ WINDOW *dialog, *text;
+
+ search_term[0] = '\0'; /* no search term entered yet */
+
+ /* Open input file for reading */
+ if ((fd = open (file, O_RDONLY)) == -1) {
+ endwin ();
+ fprintf (stderr,
+ "\nCan't open input file in dialog_textbox().\n");
+ exit (-1);
+ }
+ /* Get file size. Actually, 'file_size' is the real file size - 1,
+ since it's only the last byte offset from the beginning */
+ if ((file_size = lseek (fd, 0, SEEK_END)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError getting file size in dialog_textbox().\n");
+ exit (-1);
+ }
+ /* Restore file pointer to beginning of file after getting file size */
+ if (lseek (fd, 0, SEEK_SET) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n");
+ exit (-1);
+ }
+ /* Allocate space for read buffer */
+ if ((buf = malloc (BUF_SIZE + 1)) == NULL) {
+ endwin ();
+ fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n");
+ exit (-1);
+ }
+ if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError reading file in dialog_textbox().\n");
+ exit (-1);
+ }
+ buf[bytes_read] = '\0'; /* mark end of valid data */
+ page = buf; /* page is pointer to start of page to be displayed */
+
+ /* center dialog box on screen */
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+
+ draw_shadow (stdscr, y, x, height, width);
+
+ dialog = newwin (height, width, y, x);
+ keypad (dialog, TRUE);
+
+ /* Create window for text region, used for scrolling text */
+ text = subwin (dialog, height - 4, width - 2, y + 1, x + 1);
+ wattrset (text, dialog_attr);
+ wbkgdset (text, dialog_attr & A_COLOR);
+
+ keypad (text, TRUE);
+
+ /* register the new window, along with its borders */
+ draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+ wattrset (dialog, border_attr);
+ mvwaddch (dialog, height-3, 0, ACS_LTEE);
+ for (i = 0; i < width - 2; i++)
+ waddch (dialog, ACS_HLINE);
+ wattrset (dialog, dialog_attr);
+ wbkgdset (dialog, dialog_attr & A_COLOR);
+ waddch (dialog, ACS_RTEE);
+
+ if (title != NULL && strlen(title) >= width-2 ) {
+ /* truncate long title -- mec */
+ char * title2 = malloc(width-2+1);
+ memcpy( title2, title, width-2 );
+ title2[width-2] = '\0';
+ title = title2;
+ }
+
+ if (title != NULL) {
+ wattrset (dialog, title_attr);
+ mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+ waddstr (dialog, (char *)title);
+ waddch (dialog, ' ');
+ }
+ print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
+ wnoutrefresh (dialog);
+ getyx (dialog, cur_y, cur_x); /* Save cursor position */
+
+ /* Print first page of text */
+ attr_clear (text, height - 4, width - 2, dialog_attr);
+ print_page (text, height - 4, width - 2);
+ print_position (dialog, height, width);
+ wmove (dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh (dialog);
+
+ while ((key != ESC) && (key != '\n')) {
+ key = wgetch (dialog);
+ switch (key) {
+ case 'E': /* Exit */
+ case 'e':
+ case 'X':
+ case 'x':
+ delwin (dialog);
+ free (buf);
+ close (fd);
+ return 0;
+ case 'g': /* First page */
+ case KEY_HOME:
+ if (!begin_reached) {
+ begin_reached = 1;
+ /* First page not in buffer? */
+ if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+ endwin ();
+ fprintf (stderr,
+ "\nError moving file pointer in dialog_textbox().\n");
+ exit (-1);
+ }
+ if (fpos > bytes_read) { /* Yes, we have to read it in */
+ if (lseek (fd, 0, SEEK_SET) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer in "
+ "dialog_textbox().\n");
+ exit (-1);
+ }
+ if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+ endwin ();
+ fprintf (stderr,
+ "\nError reading file in dialog_textbox().\n");
+ exit (-1);
+ }
+ buf[bytes_read] = '\0';
+ }
+ page = buf;
+ print_page (text, height - 4, width - 2);
+ print_position (dialog, height, width);
+ wmove (dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh (dialog);
+ }
+ break;
+ case 'G': /* Last page */
+ case KEY_END:
+
+ end_reached = 1;
+ /* Last page not in buffer? */
+ if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+ endwin ();
+ fprintf (stderr,
+ "\nError moving file pointer in dialog_textbox().\n");
+ exit (-1);
+ }
+ if (fpos < file_size) { /* Yes, we have to read it in */
+ if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) {
+ endwin ();
+ fprintf (stderr,
+ "\nError moving file pointer in dialog_textbox().\n");
+ exit (-1);
+ }
+ if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+ endwin ();
+ fprintf (stderr,
+ "\nError reading file in dialog_textbox().\n");
+ exit (-1);
+ }
+ buf[bytes_read] = '\0';
+ }
+ page = buf + bytes_read;
+ back_lines (height - 4);
+ print_page (text, height - 4, width - 2);
+ print_position (dialog, height, width);
+ wmove (dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh (dialog);
+ break;
+ case 'K': /* Previous line */
+ case 'k':
+ case KEY_UP:
+ if (!begin_reached) {
+ back_lines (page_length + 1);
+
+ /* We don't call print_page() here but use scrolling to ensure
+ faster screen update. However, 'end_reached' and
+ 'page_length' should still be updated, and 'page' should
+ point to start of next page. This is done by calling
+ get_line() in the following 'for' loop. */
+ scrollok (text, TRUE);
+ wscrl (text, -1); /* Scroll text region down one line */
+ scrollok (text, FALSE);
+ page_length = 0;
+ passed_end = 0;
+ for (i = 0; i < height - 4; i++) {
+ if (!i) {
+ /* print first line of page */
+ print_line (text, 0, width - 2);
+ wnoutrefresh (text);
+ } else
+ /* Called to update 'end_reached' and 'page' */
+ get_line ();
+ if (!passed_end)
+ page_length++;
+ if (end_reached && !passed_end)
+ passed_end = 1;
+ }
+
+ print_position (dialog, height, width);
+ wmove (dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh (dialog);
+ }
+ break;
+ case 'B': /* Previous page */
+ case 'b':
+ case KEY_PPAGE:
+ if (begin_reached)
+ break;
+ back_lines (page_length + height - 4);
+ print_page (text, height - 4, width - 2);
+ print_position (dialog, height, width);
+ wmove (dialog, cur_y, cur_x);
+ wrefresh (dialog);
+ break;
+ case 'J': /* Next line */
+ case 'j':
+ case KEY_DOWN:
+ if (!end_reached) {
+ begin_reached = 0;
+ scrollok (text, TRUE);
+ scroll (text); /* Scroll text region up one line */
+ scrollok (text, FALSE);
+ print_line (text, height - 5, width - 2);
+ wnoutrefresh (text);
+ print_position (dialog, height, width);
+ wmove (dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh (dialog);
+ }
+ break;
+ case KEY_NPAGE: /* Next page */
+ case ' ':
+ if (end_reached)
+ break;
+
+ begin_reached = 0;
+ print_page (text, height - 4, width - 2);
+ print_position (dialog, height, width);
+ wmove (dialog, cur_y, cur_x);
+ wrefresh (dialog);
+ break;
+ case '0': /* Beginning of line */
+ case 'H': /* Scroll left */
+ case 'h':
+ case KEY_LEFT:
+ if (hscroll <= 0)
+ break;
+
+ if (key == '0')
+ hscroll = 0;
+ else
+ hscroll--;
+ /* Reprint current page to scroll horizontally */
+ back_lines (page_length);
+ print_page (text, height - 4, width - 2);
+ wmove (dialog, cur_y, cur_x);
+ wrefresh (dialog);
+ break;
+ case 'L': /* Scroll right */
+ case 'l':
+ case KEY_RIGHT:
+ if (hscroll >= MAX_LEN)
+ break;
+ hscroll++;
+ /* Reprint current page to scroll horizontally */
+ back_lines (page_length);
+ print_page (text, height - 4, width - 2);
+ wmove (dialog, cur_y, cur_x);
+ wrefresh (dialog);
+ break;
+ case ESC:
+ break;
+ }
+ }
+
+ delwin (dialog);
+ free (buf);
+ close (fd);
+ return 1; /* ESC pressed */
+}
+
+/*
+ * Go back 'n' lines in text file. Called by dialog_textbox().
+ * 'page' will be updated to point to the desired line in 'buf'.
+ */
+static void
+back_lines (int n)
+{
+ int i, fpos;
+
+ begin_reached = 0;
+ /* We have to distinguish between end_reached and !end_reached
+ since at end of file, the line is not ended by a '\n'.
+ The code inside 'if' basically does a '--page' to move one
+ character backward so as to skip '\n' of the previous line */
+ if (!end_reached) {
+ /* Either beginning of buffer or beginning of file reached? */
+ if (page == buf) {
+ if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer in "
+ "back_lines().\n");
+ exit (-1);
+ }
+ if (fpos > bytes_read) { /* Not beginning of file yet */
+ /* We've reached beginning of buffer, but not beginning of
+ file yet, so read previous part of file into buffer.
+ Note that we only move backward for BUF_SIZE/2 bytes,
+ but not BUF_SIZE bytes to avoid re-reading again in
+ print_page() later */
+ /* Really possible to move backward BUF_SIZE/2 bytes? */
+ if (fpos < BUF_SIZE / 2 + bytes_read) {
+ /* No, move less then */
+ if (lseek (fd, 0, SEEK_SET) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer in "
+ "back_lines().\n");
+ exit (-1);
+ }
+ page = buf + fpos - bytes_read;
+ } else { /* Move backward BUF_SIZE/2 bytes */
+ if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR)
+ == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer "
+ "in back_lines().\n");
+ exit (-1);
+ }
+ page = buf + BUF_SIZE / 2;
+ }
+ if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError reading file in back_lines().\n");
+ exit (-1);
+ }
+ buf[bytes_read] = '\0';
+ } else { /* Beginning of file reached */
+ begin_reached = 1;
+ return;
+ }
+ }
+ if (*(--page) != '\n') { /* '--page' here */
+ /* Something's wrong... */
+ endwin ();
+ fprintf (stderr, "\nInternal error in back_lines().\n");
+ exit (-1);
+ }
+ }
+ /* Go back 'n' lines */
+ for (i = 0; i < n; i++)
+ do {
+ if (page == buf) {
+ if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+ endwin ();
+ fprintf (stderr,
+ "\nError moving file pointer in back_lines().\n");
+ exit (-1);
+ }
+ if (fpos > bytes_read) {
+ /* Really possible to move backward BUF_SIZE/2 bytes? */
+ if (fpos < BUF_SIZE / 2 + bytes_read) {
+ /* No, move less then */
+ if (lseek (fd, 0, SEEK_SET) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer "
+ "in back_lines().\n");
+ exit (-1);
+ }
+ page = buf + fpos - bytes_read;
+ } else { /* Move backward BUF_SIZE/2 bytes */
+ if (lseek (fd, -(BUF_SIZE / 2 + bytes_read),
+ SEEK_CUR) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer"
+ " in back_lines().\n");
+ exit (-1);
+ }
+ page = buf + BUF_SIZE / 2;
+ }
+ if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError reading file in "
+ "back_lines().\n");
+ exit (-1);
+ }
+ buf[bytes_read] = '\0';
+ } else { /* Beginning of file reached */
+ begin_reached = 1;
+ return;
+ }
+ }
+ } while (*(--page) != '\n');
+ page++;
+}
+
+/*
+ * Print a new page of text. Called by dialog_textbox().
+ */
+static void
+print_page (WINDOW * win, int height, int width)
+{
+ int i, passed_end = 0;
+
+ page_length = 0;
+ for (i = 0; i < height; i++) {
+ print_line (win, i, width);
+ if (!passed_end)
+ page_length++;
+ if (end_reached && !passed_end)
+ passed_end = 1;
+ }
+ wnoutrefresh (win);
+}
+
+/*
+ * Print a new line of text. Called by dialog_textbox() and print_page().
+ */
+static void
+print_line (WINDOW * win, int row, int width)
+{
+ int y, x;
+ char *line;
+
+ line = get_line ();
+ line += MIN (strlen (line), hscroll); /* Scroll horizontally */
+ wmove (win, row, 0); /* move cursor to correct line */
+ waddch (win, ' ');
+ waddnstr (win, line, MIN (strlen (line), width - 2));
+
+ getyx (win, y, x);
+ /* Clear 'residue' of previous line */
+#if OLD_NCURSES
+ {
+ int i;
+ for (i = 0; i < width - x; i++)
+ waddch (win, ' ');
+ }
+#else
+ wclrtoeol(win);
+#endif
+}
+
+/*
+ * Return current line of text. Called by dialog_textbox() and print_line().
+ * 'page' should point to start of current line before calling, and will be
+ * updated to point to start of next line.
+ */
+static char *
+get_line (void)
+{
+ int i = 0, fpos;
+ static char line[MAX_LEN + 1];
+
+ end_reached = 0;
+ while (*page != '\n') {
+ if (*page == '\0') {
+ /* Either end of file or end of buffer reached */
+ if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer in "
+ "get_line().\n");
+ exit (-1);
+ }
+ if (fpos < file_size) { /* Not end of file yet */
+ /* We've reached end of buffer, but not end of file yet,
+ so read next part of file into buffer */
+ if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError reading file in get_line().\n");
+ exit (-1);
+ }
+ buf[bytes_read] = '\0';
+ page = buf;
+ } else {
+ if (!end_reached)
+ end_reached = 1;
+ break;
+ }
+ } else if (i < MAX_LEN)
+ line[i++] = *(page++);
+ else {
+ /* Truncate lines longer than MAX_LEN characters */
+ if (i == MAX_LEN)
+ line[i++] = '\0';
+ page++;
+ }
+ }
+ if (i <= MAX_LEN)
+ line[i] = '\0';
+ if (!end_reached)
+ page++; /* move pass '\n' */
+
+ return line;
+}
+
+/*
+ * Print current position
+ */
+static void
+print_position (WINDOW * win, int height, int width)
+{
+ int fpos, percent;
+
+ if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer in print_position().\n");
+ exit (-1);
+ }
+ wattrset (win, position_indicator_attr);
+ wbkgdset (win, position_indicator_attr & A_COLOR);
+ percent = !file_size ?
+ 100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
+ wmove (win, height - 3, width - 9);
+ wprintw (win, "(%3d%%)", percent);
+}
diff --git a/misc/buildroot/package/config/lxdialog/util.c b/misc/buildroot/package/config/lxdialog/util.c
new file mode 100644
index 000000000..6f83951b9
--- /dev/null
+++ b/misc/buildroot/package/config/lxdialog/util.c
@@ -0,0 +1,375 @@
+/*
+ * util.c
+ *
+ * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+
+/* use colors by default? */
+bool use_colors = 1;
+
+const char *backtitle = NULL;
+
+const char *dialog_result;
+
+/*
+ * Attribute values, default is for mono display
+ */
+chtype attributes[] =
+{
+ A_NORMAL, /* screen_attr */
+ A_NORMAL, /* shadow_attr */
+ A_NORMAL, /* dialog_attr */
+ A_BOLD, /* title_attr */
+ A_NORMAL, /* border_attr */
+ A_REVERSE, /* button_active_attr */
+ A_DIM, /* button_inactive_attr */
+ A_REVERSE, /* button_key_active_attr */
+ A_BOLD, /* button_key_inactive_attr */
+ A_REVERSE, /* button_label_active_attr */
+ A_NORMAL, /* button_label_inactive_attr */
+ A_NORMAL, /* inputbox_attr */
+ A_NORMAL, /* inputbox_border_attr */
+ A_NORMAL, /* searchbox_attr */
+ A_BOLD, /* searchbox_title_attr */
+ A_NORMAL, /* searchbox_border_attr */
+ A_BOLD, /* position_indicator_attr */
+ A_NORMAL, /* menubox_attr */
+ A_NORMAL, /* menubox_border_attr */
+ A_NORMAL, /* item_attr */
+ A_REVERSE, /* item_selected_attr */
+ A_BOLD, /* tag_attr */
+ A_REVERSE, /* tag_selected_attr */
+ A_BOLD, /* tag_key_attr */
+ A_REVERSE, /* tag_key_selected_attr */
+ A_BOLD, /* check_attr */
+ A_REVERSE, /* check_selected_attr */
+ A_BOLD, /* uarrow_attr */
+ A_BOLD /* darrow_attr */
+};
+
+
+#include "colors.h"
+
+/*
+ * Table of color values
+ */
+int color_table[][3] =
+{
+ {SCREEN_FG, SCREEN_BG, SCREEN_HL},
+ {SHADOW_FG, SHADOW_BG, SHADOW_HL},
+ {DIALOG_FG, DIALOG_BG, DIALOG_HL},
+ {TITLE_FG, TITLE_BG, TITLE_HL},
+ {BORDER_FG, BORDER_BG, BORDER_HL},
+ {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
+ {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
+ {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
+ {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL},
+ {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL},
+ {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
+ BUTTON_LABEL_INACTIVE_HL},
+ {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
+ {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
+ {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
+ {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
+ {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
+ {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
+ {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
+ {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
+ {ITEM_FG, ITEM_BG, ITEM_HL},
+ {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
+ {TAG_FG, TAG_BG, TAG_HL},
+ {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
+ {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
+ {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
+ {CHECK_FG, CHECK_BG, CHECK_HL},
+ {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
+ {UARROW_FG, UARROW_BG, UARROW_HL},
+ {DARROW_FG, DARROW_BG, DARROW_HL},
+}; /* color_table */
+
+/*
+ * Set window to attribute 'attr'
+ */
+void
+attr_clear (WINDOW * win, int height, int width, chtype attr)
+{
+ int i, j;
+
+ wattrset (win, attr);
+ for (i = 0; i < height; i++) {
+ wmove (win, i, 0);
+ for (j = 0; j < width; j++)
+ waddch (win, ' ');
+ }
+ touchwin (win);
+}
+
+void dialog_clear (void)
+{
+ attr_clear (stdscr, LINES, COLS, screen_attr);
+ /* Display background title if it exists ... - SLH */
+ if (backtitle != NULL) {
+ int i;
+
+ wattrset (stdscr, screen_attr);
+ mvwaddstr (stdscr, 0, 1, (char *)backtitle);
+ wmove (stdscr, 1, 1);
+ for (i = 1; i < COLS - 1; i++)
+ waddch (stdscr, ACS_HLINE);
+ }
+ wnoutrefresh (stdscr);
+}
+
+/*
+ * Do some initialization for dialog
+ */
+void
+init_dialog (void)
+{
+ initscr (); /* Init curses */
+ keypad (stdscr, TRUE);
+ cbreak ();
+ noecho ();
+
+
+ if (use_colors) /* Set up colors */
+ color_setup ();
+
+
+ dialog_clear ();
+}
+
+/*
+ * Setup for color display
+ */
+void
+color_setup (void)
+{
+ int i;
+
+ if (has_colors ()) { /* Terminal supports color? */
+ start_color ();
+
+ /* Initialize color pairs */
+ for (i = 0; i < ATTRIBUTE_COUNT; i++)
+ init_pair (i + 1, color_table[i][0], color_table[i][1]);
+
+ /* Setup color attributes */
+ for (i = 0; i < ATTRIBUTE_COUNT; i++)
+ attributes[i] = C_ATTR (color_table[i][2], i + 1);
+ }
+}
+
+/*
+ * End using dialog functions.
+ */
+void
+end_dialog (void)
+{
+ endwin ();
+}
+
+
+/*
+ * Print a string of text in a window, automatically wrap around to the
+ * next line if the string is too long to fit on one line. Newline
+ * characters '\n' are replaced by spaces. We start on a new line
+ * if there is no room for at least 4 nonblanks following a double-space.
+ */
+void
+print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x)
+{
+ int newl, cur_x, cur_y;
+ int i, prompt_len, room, wlen;
+ char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
+
+ strcpy (tempstr, prompt);
+
+ prompt_len = strlen(tempstr);
+
+ /*
+ * Remove newlines
+ */
+ for(i=0; i<prompt_len; i++) {
+ if(tempstr[i] == '\n') tempstr[i] = ' ';
+ }
+
+ if (prompt_len <= width - x * 2) { /* If prompt is short */
+ wmove (win, y, (width - prompt_len) / 2);
+ waddstr (win, tempstr);
+ } else {
+ cur_x = x;
+ cur_y = y;
+ newl = 1;
+ word = tempstr;
+ while (word && *word) {
+ sp = index(word, ' ');
+ if (sp)
+ *sp++ = 0;
+
+ /* Wrap to next line if either the word does not fit,
+ or it is the first word of a new sentence, and it is
+ short, and the next word does not fit. */
+ room = width - cur_x;
+ wlen = strlen(word);
+ if (wlen > room ||
+ (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room
+ && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) {
+ cur_y++;
+ cur_x = x;
+ }
+ wmove (win, cur_y, cur_x);
+ waddstr (win, word);
+ getyx (win, cur_y, cur_x);
+ cur_x++;
+ if (sp && *sp == ' ') {
+ cur_x++; /* double space */
+ while (*++sp == ' ');
+ newl = 1;
+ } else
+ newl = 0;
+ word = sp;
+ }
+ }
+}
+
+/*
+ * Print a button
+ */
+void
+print_button (WINDOW * win, const char *label, int y, int x, int selected)
+{
+ int i, temp;
+
+ wmove (win, y, x);
+ wattrset (win, selected ? button_active_attr : button_inactive_attr);
+ waddstr (win, "<");
+ temp = strspn (label, " ");
+ label += temp;
+ wattrset (win, selected ? button_label_active_attr
+ : button_label_inactive_attr);
+ for (i = 0; i < temp; i++)
+ waddch (win, ' ');
+ wattrset (win, selected ? button_key_active_attr
+ : button_key_inactive_attr);
+ waddch (win, label[0]);
+ wattrset (win, selected ? button_label_active_attr
+ : button_label_inactive_attr);
+ waddstr (win, (char *)label + 1);
+ wattrset (win, selected ? button_active_attr : button_inactive_attr);
+ waddstr (win, ">");
+ wmove (win, y, x + temp + 1);
+}
+
+/*
+ * Draw a rectangular box with line drawing characters
+ */
+void
+draw_box (WINDOW * win, int y, int x, int height, int width,
+ chtype box, chtype border)
+{
+ int i, j;
+
+ wattrset (win, 0);
+ for (i = 0; i < height; i++) {
+ wmove (win, y + i, x);
+ for (j = 0; j < width; j++)
+ if (!i && !j)
+ waddch (win, border | ACS_ULCORNER);
+ else if (i == height - 1 && !j)
+ waddch (win, border | ACS_LLCORNER);
+ else if (!i && j == width - 1)
+ waddch (win, box | ACS_URCORNER);
+ else if (i == height - 1 && j == width - 1)
+ waddch (win, box | ACS_LRCORNER);
+ else if (!i)
+ waddch (win, border | ACS_HLINE);
+ else if (i == height - 1)
+ waddch (win, box | ACS_HLINE);
+ else if (!j)
+ waddch (win, border | ACS_VLINE);
+ else if (j == width - 1)
+ waddch (win, box | ACS_VLINE);
+ else
+ waddch (win, box | ' ');
+ }
+}
+
+/*
+ * Draw shadows along the right and bottom edge to give a more 3D look
+ * to the boxes
+ */
+void
+draw_shadow (WINDOW * win, int y, int x, int height, int width)
+{
+ int i;
+
+ if (has_colors ()) { /* Whether terminal supports color? */
+ wattrset (win, shadow_attr);
+ wmove (win, y + height, x + 2);
+ for (i = 0; i < width; i++)
+ waddch (win, winch (win) & A_CHARTEXT);
+ for (i = y + 1; i < y + height + 1; i++) {
+ wmove (win, i, x + width);
+ waddch (win, winch (win) & A_CHARTEXT);
+ waddch (win, winch (win) & A_CHARTEXT);
+ }
+ wnoutrefresh (win);
+ }
+}
+
+/*
+ * Return the position of the first alphabetic character in a string.
+ */
+int
+first_alpha(const char *string, const char *exempt)
+{
+ int i, in_paren=0, c;
+
+ for (i = 0; i < strlen(string); i++) {
+ c = tolower(string[i]);
+
+ if (strchr("<[(", c)) ++in_paren;
+ if (strchr(">])", c) && in_paren > 0) --in_paren;
+
+ if ((! in_paren) && isalpha(c) &&
+ strchr(exempt, c) == 0)
+ return i;
+ }
+
+ return 0;
+}
+
+/*
+ * Get the first selected item in the dialog_list_item list.
+ */
+struct dialog_list_item *
+first_sel_item(int item_no, struct dialog_list_item ** items)
+{
+ int i;
+
+ for (i = 0; i < item_no; i++) {
+ if (items[i]->selected)
+ return items[i];
+ }
+
+ return NULL;
+}
diff --git a/misc/buildroot/package/config/lxdialog/yesno.c b/misc/buildroot/package/config/lxdialog/yesno.c
new file mode 100644
index 000000000..11fcc25f5
--- /dev/null
+++ b/misc/buildroot/package/config/lxdialog/yesno.c
@@ -0,0 +1,118 @@
+/*
+ * yesno.c -- implements the yes/no box
+ *
+ * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+/*
+ * Display termination buttons
+ */
+static void
+print_buttons(WINDOW *dialog, int height, int width, int selected)
+{
+ int x = width / 2 - 10;
+ int y = height - 2;
+
+ print_button (dialog, " Yes ", y, x, selected == 0);
+ print_button (dialog, " No ", y, x + 13, selected == 1);
+
+ wmove(dialog, y, x+1 + 13*selected );
+ wrefresh (dialog);
+}
+
+/*
+ * Display a dialog box with two buttons - Yes and No
+ */
+int
+dialog_yesno (const char *title, const char *prompt, int height, int width)
+{
+ int i, x, y, key = 0, button = 0;
+ WINDOW *dialog;
+
+ /* center dialog box on screen */
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+ draw_shadow (stdscr, y, x, height, width);
+
+ dialog = newwin (height, width, y, x);
+ keypad (dialog, TRUE);
+
+ draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset (dialog, border_attr);
+ mvwaddch (dialog, height-3, 0, ACS_LTEE);
+ for (i = 0; i < width - 2; i++)
+ waddch (dialog, ACS_HLINE);
+ wattrset (dialog, dialog_attr);
+ waddch (dialog, ACS_RTEE);
+
+ if (title != NULL && strlen(title) >= width-2 ) {
+ /* truncate long title -- mec */
+ char * title2 = malloc(width-2+1);
+ memcpy( title2, title, width-2 );
+ title2[width-2] = '\0';
+ title = title2;
+ }
+
+ if (title != NULL) {
+ wattrset (dialog, title_attr);
+ mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+ waddstr (dialog, (char *)title);
+ waddch (dialog, ' ');
+ }
+
+ wattrset (dialog, dialog_attr);
+ print_autowrap (dialog, prompt, width - 2, 1, 3);
+
+ print_buttons(dialog, height, width, 0);
+
+ while (key != ESC) {
+ key = wgetch (dialog);
+ switch (key) {
+ case 'Y':
+ case 'y':
+ delwin (dialog);
+ return 0;
+ case 'N':
+ case 'n':
+ delwin (dialog);
+ return 1;
+
+ case TAB:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ button = ((key == KEY_LEFT ? --button : ++button) < 0)
+ ? 1 : (button > 1 ? 0 : button);
+
+ print_buttons(dialog, height, width, button);
+ wrefresh (dialog);
+ break;
+ case ' ':
+ case '\n':
+ delwin (dialog);
+ return button;
+ case ESC:
+ break;
+ }
+ }
+
+ delwin (dialog);
+ return -1; /* ESC pressed */
+}
diff --git a/misc/buildroot/package/config/mconf.c b/misc/buildroot/package/config/mconf.c
new file mode 100644
index 000000000..3f645d44a
--- /dev/null
+++ b/misc/buildroot/package/config/mconf.c
@@ -0,0 +1,973 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ *
+ * Introduced single menu mode (show all sub-menus in one large tree).
+ * 2002-11-06 Petr Baudis <pasky@ucw.cz>
+ *
+ * Directly use liblxdialog library routines.
+ * 2002-11-14 Petr Baudis <pasky@ucw.cz>
+ */
+
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <sys/termios.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "lxdialog/dialog.h"
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+static char menu_backtitle[128];
+static const char mconf_readme[] =
+"Overview\n"
+"--------\n"
+"Some features may be built directly into Buildroot. Some features\n"
+"may be completely removed altogether. There are also certain\n"
+"parameters which are not really features, but must be\n"
+"entered in as decimal or hexadecimal numbers or possibly text.\n"
+"\n"
+"Menu items beginning with [*] or [ ] represent features\n"
+"configured to be built in or removed respectively.\n"
+"\n"
+"To change any of these features, highlight it with the cursor\n"
+"keys and press <Y> to build it in or <N> to removed it.\n"
+"You may also press the <Space Bar> to cycle\n"
+"through the available options (ie. Y->N->Y).\n"
+"\n"
+"Some additional keyboard hints:\n"
+"\n"
+"Menus\n"
+"----------\n"
+"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
+" you wish to change or submenu wish to select and press <Enter>.\n"
+" Submenus are designated by \"--->\".\n"
+"\n"
+" Shortcut: Press the option's highlighted letter (hotkey).\n"
+" Pressing a hotkey more than once will sequence\n"
+" through all visible items which use that hotkey.\n"
+"\n"
+" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
+" unseen options into view.\n"
+"\n"
+"o To exit a menu use the cursor keys to highlight the <Exit> button\n"
+" and press <ENTER>.\n"
+"\n"
+" Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n"
+" using those letters. You may press a single <ESC>, but\n"
+" there is a delayed response which you may find annoying.\n"
+"\n"
+" Also, the <TAB> and cursor keys will cycle between <Select>,\n"
+" <Exit> and <Help>\n"
+"\n"
+"o To get help with an item, use the cursor keys to highlight <Help>\n"
+" and Press <ENTER>.\n"
+"\n"
+" Shortcut: Press <H> or <?>.\n"
+"\n"
+"\n"
+"Radiolists (Choice lists)\n"
+"-----------\n"
+"o Use the cursor keys to select the option you wish to set and press\n"
+" <S> or the <SPACE BAR>.\n"
+"\n"
+" Shortcut: Press the first letter of the option you wish to set then\n"
+" press <S> or <SPACE BAR>.\n"
+"\n"
+"o To see available help for the item, use the cursor keys to highlight\n"
+" <Help> and Press <ENTER>.\n"
+"\n"
+" Shortcut: Press <H> or <?>.\n"
+"\n"
+" Also, the <TAB> and cursor keys will cycle between <Select> and\n"
+" <Help>\n"
+"\n"
+"\n"
+"Data Entry\n"
+"-----------\n"
+"o Enter the requested information and press <ENTER>\n"
+" If you are entering hexadecimal values, it is not necessary to\n"
+" add the '0x' prefix to the entry.\n"
+"\n"
+"o For help, use the <TAB> or cursor keys to highlight the help option\n"
+" and press <ENTER>. You can try <TAB><H> as well.\n"
+"\n"
+"\n"
+"Text Box (Help Window)\n"
+"--------\n"
+"o Use the cursor keys to scroll up/down/left/right. The VI editor\n"
+" keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n"
+" who are familiar with less and lynx.\n"
+"\n"
+"o Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n"
+"\n"
+"\n"
+"Alternate Configuration Files\n"
+"-----------------------------\n"
+"Menuconfig supports the use of alternate configuration files for\n"
+"those who, for various reasons, find it necessary to switch\n"
+"between different configurations.\n"
+"\n"
+"At the end of the main menu you will find two options. One is\n"
+"for saving the current configuration to a file of your choosing.\n"
+"The other option is for loading a previously saved alternate\n"
+"configuration.\n"
+"\n"
+"Even if you don't use alternate configuration files, but you\n"
+"find during a Menuconfig session that you have completely messed\n"
+"up your settings, you may use the \"Load Alternate...\" option to\n"
+"restore your previously saved settings from \".config\" without\n"
+"restarting Menuconfig.\n"
+"\n"
+"Other information\n"
+"-----------------\n"
+"If you use Menuconfig in an XTERM window make sure you have your\n"
+"$TERM variable set to point to a xterm definition which supports color.\n"
+"Otherwise, Menuconfig will look rather bad. Menuconfig will not\n"
+"display correctly in a RXVT window because rxvt displays only one\n"
+"intensity of color, bright.\n"
+"\n"
+"Menuconfig will display larger menus on screens or xterms which are\n"
+"set to display more than the standard 25 row by 80 column geometry.\n"
+"In order for this to work, the \"stty size\" command must be able to\n"
+"display the screen's current row and column geometry. I STRONGLY\n"
+"RECOMMEND that you make sure you do NOT have the shell variables\n"
+"LINES and COLUMNS exported into your environment. Some distributions\n"
+"export those variables via /etc/profile. Some ncurses programs can\n"
+"become confused when those variables (LINES & COLUMNS) don't reflect\n"
+"the true screen size.\n"
+"\n"
+"Optional personality available\n"
+"------------------------------\n"
+"If you prefer to have all of the options listed in a single\n"
+"menu, rather than the default multimenu hierarchy, run the menuconfig\n"
+"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
+"\n"
+"make MENUCONFIG_MODE=single_menu menuconfig\n"
+"\n"
+"<Enter> will then unroll the appropriate category, or enfold it if it\n"
+"is already unrolled.\n"
+"\n"
+"Note that this mode can eventually be a little more CPU expensive\n"
+"(especially with a larger number of unrolled categories) than the\n"
+"default mode.\n",
+menu_instructions[] =
+ "Arrow keys navigate the menu. "
+ "<Enter> selects submenus --->. "
+ "Highlighted letters are hotkeys. "
+ "Pressing <Y> selectes a feature, while <N> will exclude a feature. "
+ "Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
+ "Legend: [*] feature is selected [ ] feature is excluded",
+radiolist_instructions[] =
+ "Use the arrow keys to navigate this window or "
+ "press the hotkey of the item you wish to select "
+ "followed by the <SPACE BAR>. "
+ "Press <?> for additional information about this option.",
+inputbox_instructions_int[] =
+ "Please enter a decimal value. "
+ "Fractions will not be accepted. "
+ "Use the <TAB> key to move from the input field to the buttons below it.",
+inputbox_instructions_hex[] =
+ "Please enter a hexadecimal value. "
+ "Use the <TAB> key to move from the input field to the buttons below it.",
+inputbox_instructions_string[] =
+ "Please enter a string value. "
+ "Use the <TAB> key to move from the input field to the buttons below it.",
+setmod_text[] =
+ "This feature depends on another which has been configured as a module.\n"
+ "As a result, this feature will be built as a module.",
+nohelp_text[] =
+ "There is no help available for this option.\n",
+load_config_text[] =
+ "Enter the name of the configuration file you wish to load. "
+ "Accept the name shown to restore the configuration you "
+ "last retrieved. Leave blank to abort.",
+load_config_help[] =
+ "\n"
+ "For various reasons, one may wish to keep several different Buildroot\n"
+ "configurations available on a single machine.\n"
+ "\n"
+ "If you have saved a previous configuration in a file other than the\n"
+ "Buildroot's default, entering the name of the file here will allow you\n"
+ "to modify that configuration.\n"
+ "\n"
+ "If you are uncertain, then you have probably never used alternate\n"
+ "configuration files. You should therefor leave this blank to abort.\n",
+save_config_text[] =
+ "Enter a filename to which this configuration should be saved "
+ "as an alternate. Leave blank to abort.",
+save_config_help[] =
+ "\n"
+ "For various reasons, one may wish to keep different Buildroot\n"
+ "configurations available on a single machine.\n"
+ "\n"
+ "Entering a file name here will allow you to later retrieve, modify\n"
+ "and use the current configuration as an alternate to whatever\n"
+ "configuration options you have selected at that time.\n"
+ "\n"
+ "If you are uncertain what all this means then you should probably\n"
+ "leave this blank.\n",
+search_help[] =
+ "\n"
+ "Search for CONFIG_ symbols and display their relations.\n"
+ "Example: search for \"^FOO\"\n"
+ "Result:\n"
+ "-----------------------------------------------------------------\n"
+ "Symbol: FOO [=m]\n"
+ "Prompt: Foo bus is used to drive the bar HW\n"
+ "Defined at drivers/pci/Kconfig:47\n"
+ "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
+ "Location:\n"
+ " -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
+ " -> PCI support (PCI [=y])\n"
+ " -> PCI access mode (<choice> [=y])\n"
+ "Selects: LIBCRC32\n"
+ "Selected by: BAR\n"
+ "-----------------------------------------------------------------\n"
+ "o The line 'Prompt:' shows the text used in the menu structure for\n"
+ " this CONFIG_ symbol\n"
+ "o The 'Defined at' line tell at what file / line number the symbol\n"
+ " is defined\n"
+ "o The 'Depends on:' line tell what symbols needs to be defined for\n"
+ " this symbol to be visible in the menu (selectable)\n"
+ "o The 'Location:' lines tell where in the menu structure this symbol\n"
+ " is located\n"
+ " A location followed by a [=y] indicate that this is a selectable\n"
+ " menu item - and current value is displayed inside brackets.\n"
+ "o The 'Selects:' line tell what symbol will be automatically\n"
+ " selected if this symbol is selected (y or m)\n"
+ "o The 'Selected by' line tell what symbol has selected this symbol\n"
+ "\n"
+ "Only relevant lines are shown.\n"
+ "\n\n"
+ "Search examples:\n"
+ "Examples: USB => find all CONFIG_ symbols containing USB\n"
+ " ^USB => find all CONFIG_ symbols starting with USB\n"
+ " USB$ => find all CONFIG_ symbols ending with USB\n"
+ "\n";
+
+static char filename[PATH_MAX+1] = ".config";
+static int indent;
+static struct termios ios_org;
+static int rows = 0, cols = 0;
+static struct menu *current_menu;
+static int child_count;
+static int single_menu_mode;
+
+static struct dialog_list_item *items[16384]; /* FIXME: This ought to be dynamic. */
+static int item_no;
+
+static void conf(struct menu *menu);
+static void conf_choice(struct menu *menu);
+static void conf_string(struct menu *menu);
+static void conf_load(void);
+static void conf_save(void);
+static void show_textbox(const char *title, const char *text, int r, int c);
+static void show_helptext(const char *title, const char *text);
+static void show_help(struct menu *menu);
+static void show_file(const char *filename, const char *title, int r, int c);
+
+static void init_wsize(void)
+{
+ struct winsize ws;
+ char *env;
+
+ if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)) {
+ rows = ws.ws_row;
+ cols = ws.ws_col;
+ }
+
+ if (!rows) {
+ env = getenv("LINES");
+ if (env)
+ rows = atoi(env);
+ if (!rows)
+ rows = 24;
+ }
+ if (!cols) {
+ env = getenv("COLUMNS");
+ if (env)
+ cols = atoi(env);
+ if (!cols)
+ cols = 80;
+ }
+
+ if (rows < 19 || cols < 80) {
+ fprintf(stderr, "Your display is too small to run Menuconfig!\n");
+ fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
+ exit(1);
+ }
+
+ rows -= 4;
+ cols -= 5;
+}
+
+static void cinit(void)
+{
+ item_no = 0;
+}
+
+static void cmake(void)
+{
+ items[item_no] = malloc(sizeof(struct dialog_list_item));
+ memset(items[item_no], 0, sizeof(struct dialog_list_item));
+ items[item_no]->tag = malloc(32); items[item_no]->tag[0] = 0;
+ items[item_no]->name = malloc(512); items[item_no]->name[0] = 0;
+ items[item_no]->namelen = 0;
+ item_no++;
+}
+
+static int cprint_name(const char *fmt, ...)
+{
+ va_list ap;
+ int res;
+
+ if (!item_no)
+ cmake();
+ va_start(ap, fmt);
+ res = vsnprintf(items[item_no - 1]->name + items[item_no - 1]->namelen,
+ 512 - items[item_no - 1]->namelen, fmt, ap);
+ if (res > 0)
+ items[item_no - 1]->namelen += res;
+ va_end(ap);
+
+ return res;
+}
+
+static int cprint_tag(const char *fmt, ...)
+{
+ va_list ap;
+ int res;
+
+ if (!item_no)
+ cmake();
+ va_start(ap, fmt);
+ res = vsnprintf(items[item_no - 1]->tag, 32, fmt, ap);
+ va_end(ap);
+
+ return res;
+}
+
+static void cdone(void)
+{
+ int i;
+
+ for (i = 0; i < item_no; i++) {
+ free(items[i]->tag);
+ free(items[i]->name);
+ free(items[i]);
+ }
+
+ item_no = 0;
+}
+
+static void get_prompt_str(struct gstr *r, struct property *prop)
+{
+ int i, j;
+ struct menu *submenu[8], *menu;
+
+ str_printf(r, "Prompt: %s\n", prop->text);
+ str_printf(r, " Defined at %s:%d\n", prop->menu->file->name,
+ prop->menu->lineno);
+ if (!expr_is_yes(prop->visible.expr)) {
+ str_append(r, " Depends on: ");
+ expr_gstr_print(prop->visible.expr, r);
+ str_append(r, "\n");
+ }
+ menu = prop->menu->parent;
+ for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
+ submenu[i++] = menu;
+ if (i > 0) {
+ str_printf(r, " Location:\n");
+ for (j = 4; --i >= 0; j += 2) {
+ menu = submenu[i];
+ str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu));
+ if (menu->sym) {
+ str_printf(r, " (%s [=%s])", menu->sym->name ?
+ menu->sym->name : "<choice>",
+ sym_get_string_value(menu->sym));
+ }
+ str_append(r, "\n");
+ }
+ }
+}
+
+static void get_symbol_str(struct gstr *r, struct symbol *sym)
+{
+ bool hit;
+ struct property *prop;
+
+ str_printf(r, "Symbol: %s [=%s]\n", sym->name,
+ sym_get_string_value(sym));
+ for_all_prompts(sym, prop)
+ get_prompt_str(r, prop);
+ hit = false;
+ for_all_properties(sym, prop, P_SELECT) {
+ if (!hit) {
+ str_append(r, " Selects: ");
+ hit = true;
+ } else
+ str_printf(r, " && ");
+ expr_gstr_print(prop->expr, r);
+ }
+ if (hit)
+ str_append(r, "\n");
+ if (sym->rev_dep.expr) {
+ str_append(r, " Selected by: ");
+ expr_gstr_print(sym->rev_dep.expr, r);
+ str_append(r, "\n");
+ }
+ str_append(r, "\n\n");
+}
+
+static struct gstr get_relations_str(struct symbol **sym_arr)
+{
+ struct symbol *sym;
+ struct gstr res = str_new();
+ int i;
+
+ for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
+ get_symbol_str(&res, sym);
+ if (!i)
+ str_append(&res, "No matches found.\n");
+ return res;
+}
+
+static void search_conf(void)
+{
+ struct symbol **sym_arr;
+ struct gstr res;
+
+again:
+ switch (dialog_inputbox("Search Configuration Parameter",
+ "Enter Keyword", 10, 75,
+ NULL)) {
+ case 0:
+ break;
+ case 1:
+ show_helptext("Search Configuration", search_help);
+ goto again;
+ default:
+ return;
+ }
+
+ sym_arr = sym_re_search(dialog_input_result);
+ res = get_relations_str(sym_arr);
+ free(sym_arr);
+ show_textbox("Search Results", str_get(&res), 0, 0);
+ str_free(&res);
+}
+
+static void build_conf(struct menu *menu)
+{
+ struct symbol *sym;
+ struct property *prop;
+ struct menu *child;
+ int type, tmp, doint = 2;
+ tristate val;
+ char ch;
+
+ if (!menu_is_visible(menu))
+ return;
+
+ sym = menu->sym;
+ prop = menu->prompt;
+ if (!sym) {
+ if (prop && menu != current_menu) {
+ const char *prompt = menu_get_prompt(menu);
+ switch (prop->type) {
+ case P_MENU:
+ child_count++;
+ cmake();
+ cprint_tag("m%p", menu);
+
+ if (single_menu_mode) {
+ cprint_name("%s%*c%s",
+ menu->data ? "-->" : "++>",
+ indent + 1, ' ', prompt);
+ } else {
+ cprint_name(" %*c%s --->", indent + 1, ' ', prompt);
+ }
+
+ if (single_menu_mode && menu->data)
+ goto conf_childs;
+ return;
+ default:
+ if (prompt) {
+ child_count++;
+ cmake();
+ cprint_tag(":%p", menu);
+ cprint_name("---%*c%s", indent + 1, ' ', prompt);
+ }
+ }
+ } else
+ doint = 0;
+ goto conf_childs;
+ }
+
+ cmake();
+ type = sym_get_type(sym);
+ if (sym_is_choice(sym)) {
+ struct symbol *def_sym = sym_get_choice_value(sym);
+ struct menu *def_menu = NULL;
+
+ child_count++;
+ for (child = menu->list; child; child = child->next) {
+ if (menu_is_visible(child) && child->sym == def_sym)
+ def_menu = child;
+ }
+
+ val = sym_get_tristate_value(sym);
+ if (sym_is_changable(sym)) {
+ cprint_tag("t%p", menu);
+ switch (type) {
+ case S_BOOLEAN:
+ cprint_name("[%c]", val == no ? ' ' : '*');
+ break;
+ case S_TRISTATE:
+ switch (val) {
+ case yes: ch = '*'; break;
+ case mod: ch = 'M'; break;
+ default: ch = ' '; break;
+ }
+ cprint_name("<%c>", ch);
+ break;
+ }
+ } else {
+ cprint_tag("%c%p", def_menu ? 't' : ':', menu);
+ cprint_name(" ");
+ }
+
+ cprint_name("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+ if (val == yes) {
+ if (def_menu) {
+ cprint_name(" (%s)", menu_get_prompt(def_menu));
+ cprint_name(" --->");
+ if (def_menu->list) {
+ indent += 2;
+ build_conf(def_menu);
+ indent -= 2;
+ }
+ }
+ return;
+ }
+ } else {
+ if (menu == current_menu) {
+ cprint_tag(":%p", menu);
+ cprint_name("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+ goto conf_childs;
+ }
+ child_count++;
+ val = sym_get_tristate_value(sym);
+ if (sym_is_choice_value(sym) && val == yes) {
+ cprint_tag(":%p", menu);
+ cprint_name(" ");
+ } else {
+ switch (type) {
+ case S_BOOLEAN:
+ cprint_tag("t%p", menu);
+ if (sym_is_changable(sym))
+ cprint_name("[%c]", val == no ? ' ' : '*');
+ else
+ cprint_name("---");
+ break;
+ case S_TRISTATE:
+ cprint_tag("t%p", menu);
+ switch (val) {
+ case yes: ch = '*'; break;
+ case mod: ch = 'M'; break;
+ default: ch = ' '; break;
+ }
+ if (sym_is_changable(sym))
+ cprint_name("<%c>", ch);
+ else
+ cprint_name("---");
+ break;
+ default:
+ cprint_tag("s%p", menu);
+ tmp = cprint_name("(%s)", sym_get_string_value(sym));
+ tmp = indent - tmp + 4;
+ if (tmp < 0)
+ tmp = 0;
+ cprint_name("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
+ (sym_has_value(sym) || !sym_is_changable(sym)) ?
+ "" : " (NEW)");
+ goto conf_childs;
+ }
+ }
+ cprint_name("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
+ (sym_has_value(sym) || !sym_is_changable(sym)) ?
+ "" : " (NEW)");
+ if (menu->prompt->type == P_MENU) {
+ cprint_name(" --->");
+ return;
+ }
+ }
+
+conf_childs:
+ indent += doint;
+ for (child = menu->list; child; child = child->next)
+ build_conf(child);
+ indent -= doint;
+}
+
+static void conf(struct menu *menu)
+{
+ struct dialog_list_item *active_item = NULL;
+ struct menu *submenu;
+ const char *prompt = menu_get_prompt(menu);
+ struct symbol *sym;
+ char active_entry[40];
+ int stat, type;
+
+ unlink("lxdialog.scrltmp");
+ active_entry[0] = 0;
+ while (1) {
+ indent = 0;
+ child_count = 0;
+ current_menu = menu;
+ cdone(); cinit();
+ build_conf(menu);
+ if (!child_count)
+ break;
+ if (menu == &rootmenu) {
+ cmake(); cprint_tag(":"); cprint_name("--- ");
+ cmake(); cprint_tag("L"); cprint_name("Load an Alternate Configuration File");
+ cmake(); cprint_tag("S"); cprint_name("Save Configuration to an Alternate File");
+ }
+ dialog_clear();
+ stat = dialog_menu(prompt ? prompt : "Main Menu",
+ menu_instructions, rows, cols, rows - 10,
+ active_entry, item_no, items);
+ if (stat < 0)
+ return;
+
+ if (stat == 1 || stat == 255)
+ break;
+
+ active_item = first_sel_item(item_no, items);
+ if (!active_item)
+ continue;
+ active_item->selected = 0;
+ strncpy(active_entry, active_item->tag, sizeof(active_entry));
+ active_entry[sizeof(active_entry)-1] = 0;
+ type = active_entry[0];
+ if (!type)
+ continue;
+
+ sym = NULL;
+ submenu = NULL;
+ if (sscanf(active_entry + 1, "%p", &submenu) == 1)
+ sym = submenu->sym;
+
+ switch (stat) {
+ case 0:
+ switch (type) {
+ case 'm':
+ if (single_menu_mode)
+ submenu->data = (void *) (long) !submenu->data;
+ else
+ conf(submenu);
+ break;
+ case 't':
+ if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
+ conf_choice(submenu);
+ else if (submenu->prompt->type == P_MENU)
+ conf(submenu);
+ break;
+ case 's':
+ conf_string(submenu);
+ break;
+ case 'L':
+ conf_load();
+ break;
+ case 'S':
+ conf_save();
+ break;
+ }
+ break;
+ case 2:
+ if (sym)
+ show_help(submenu);
+ else
+ show_helptext("README", mconf_readme);
+ break;
+ case 3:
+ if (type == 't') {
+ if (sym_set_tristate_value(sym, yes))
+ break;
+ if (sym_set_tristate_value(sym, mod))
+ show_textbox(NULL, setmod_text, 6, 74);
+ }
+ break;
+ case 4:
+ if (type == 't')
+ sym_set_tristate_value(sym, no);
+ break;
+ case 5:
+ if (type == 't')
+ sym_set_tristate_value(sym, mod);
+ break;
+ case 6:
+ if (type == 't')
+ sym_toggle_tristate_value(sym);
+ else if (type == 'm')
+ conf(submenu);
+ break;
+ case 7:
+ search_conf();
+ break;
+ }
+ }
+}
+
+static void show_textbox(const char *title, const char *text, int r, int c)
+{
+ int fd;
+
+ fd = creat(".help.tmp", 0777);
+ write(fd, text, strlen(text));
+ close(fd);
+ show_file(".help.tmp", title, r, c);
+ unlink(".help.tmp");
+}
+
+static void show_helptext(const char *title, const char *text)
+{
+ show_textbox(title, text, 0, 0);
+}
+
+static void show_help(struct menu *menu)
+{
+ struct gstr help = str_new();
+ struct symbol *sym = menu->sym;
+
+ if (sym->help)
+ {
+ if (sym->name) {
+ str_printf(&help, "%s:\n\n", sym->name);
+ str_append(&help, sym->help);
+ str_append(&help, "\n");
+ }
+ } else {
+ str_append(&help, nohelp_text);
+ }
+ get_symbol_str(&help, sym);
+ show_helptext(menu_get_prompt(menu), str_get(&help));
+ str_free(&help);
+}
+
+static void show_file(const char *filename, const char *title, int r, int c)
+{
+ while (dialog_textbox(title, filename, r ? r : rows, c ? c : cols) < 0)
+ ;
+}
+
+static void conf_choice(struct menu *menu)
+{
+ const char *prompt = menu_get_prompt(menu);
+ struct menu *child;
+ struct symbol *active;
+
+ active = sym_get_choice_value(menu->sym);
+ while (1) {
+ current_menu = menu;
+ cdone(); cinit();
+ for (child = menu->list; child; child = child->next) {
+ if (!menu_is_visible(child))
+ continue;
+ cmake();
+ cprint_tag("%p", child);
+ cprint_name("%s", menu_get_prompt(child));
+ if (child->sym == sym_get_choice_value(menu->sym))
+ items[item_no - 1]->selected = 1; /* ON */
+ else if (child->sym == active)
+ items[item_no - 1]->selected = 2; /* SELECTED */
+ else
+ items[item_no - 1]->selected = 0; /* OFF */
+ }
+
+ switch (dialog_checklist(prompt ? prompt : "Main Menu",
+ radiolist_instructions, 15, 70, 6,
+ item_no, items, FLAG_RADIO)) {
+ case 0:
+ if (sscanf(first_sel_item(item_no, items)->tag, "%p", &child) != 1)
+ break;
+ sym_set_tristate_value(child->sym, yes);
+ return;
+ case 1:
+ if (sscanf(first_sel_item(item_no, items)->tag, "%p", &child) == 1) {
+ show_help(child);
+ active = child->sym;
+ } else
+ show_help(menu);
+ break;
+ case 255:
+ return;
+ }
+ }
+}
+
+static void conf_string(struct menu *menu)
+{
+ const char *prompt = menu_get_prompt(menu);
+
+ while (1) {
+ char *heading;
+
+ switch (sym_get_type(menu->sym)) {
+ case S_INT:
+ heading = (char *) inputbox_instructions_int;
+ break;
+ case S_HEX:
+ heading = (char *) inputbox_instructions_hex;
+ break;
+ case S_STRING:
+ heading = (char *) inputbox_instructions_string;
+ break;
+ default:
+ heading = "Internal mconf error!";
+ /* panic? */;
+ }
+
+ switch (dialog_inputbox(prompt ? prompt : "Main Menu",
+ heading, 10, 75,
+ sym_get_string_value(menu->sym))) {
+ case 0:
+ if (sym_set_string_value(menu->sym, dialog_input_result))
+ return;
+ show_textbox(NULL, "You have made an invalid entry.", 5, 43);
+ break;
+ case 1:
+ show_help(menu);
+ break;
+ case 255:
+ return;
+ }
+ }
+}
+
+static void conf_load(void)
+{
+ while (1) {
+ switch (dialog_inputbox(NULL, load_config_text, 11, 55,
+ filename)) {
+ case 0:
+ if (!dialog_input_result[0])
+ return;
+ if (!conf_read(dialog_input_result))
+ return;
+ show_textbox(NULL, "File does not exist!", 5, 38);
+ break;
+ case 1:
+ show_helptext("Load Alternate Configuration", load_config_help);
+ break;
+ case 255:
+ return;
+ }
+ }
+}
+
+static void conf_save(void)
+{
+ while (1) {
+ switch (dialog_inputbox(NULL, save_config_text, 11, 55,
+ filename)) {
+ case 0:
+ if (!dialog_input_result[0])
+ return;
+ if (!conf_write(dialog_input_result))
+ return;
+ show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60);
+ break;
+ case 1:
+ show_helptext("Save Alternate Configuration", save_config_help);
+ break;
+ case 255:
+ return;
+ }
+ }
+}
+
+static void conf_cleanup(void)
+{
+ tcsetattr(1, TCSAFLUSH, &ios_org);
+ unlink(".help.tmp");
+}
+
+static void winch_handler(int sig)
+{
+ struct winsize ws;
+
+ if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
+ rows = 24;
+ cols = 80;
+ } else {
+ rows = ws.ws_row;
+ cols = ws.ws_col;
+ }
+
+ if (rows < 19 || cols < 80) {
+ end_dialog();
+ fprintf(stderr, "Your display is too small to run Menuconfig!\n");
+ fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
+ exit(1);
+ }
+
+ rows -= 4;
+ cols -= 5;
+
+}
+
+int main(int ac, char **av)
+{
+ char *mode;
+ int stat;
+
+ conf_parse(av[1]);
+ conf_read(NULL);
+
+ snprintf(menu_backtitle, 128, "Buildroot Configuration");
+
+ mode = getenv("MENUCONFIG_MODE");
+ if (mode) {
+ if (!strcasecmp(mode, "single_menu"))
+ single_menu_mode = 1;
+ }
+
+ tcgetattr(1, &ios_org);
+ atexit(conf_cleanup);
+ init_wsize();
+ init_dialog();
+ signal(SIGWINCH, winch_handler);
+ conf(&rootmenu);
+ end_dialog();
+
+ /* Restart dialog to act more like when lxdialog was still separate */
+ init_dialog();
+ do {
+ stat = dialog_yesno(NULL,
+ "Do you wish to save your new Buildroot configuration?", 5, 60);
+ } while (stat < 0);
+ end_dialog();
+
+ if (stat == 0) {
+ conf_write(NULL);
+ printf("\n\n"
+ "*** End of Buildroot configuration.\n"
+ "*** Check the top-level Makefile for additional configuration options.\n\n");
+ } else
+ printf("\n\nYour Buildroot configuration changes were NOT saved.\n\n");
+
+ return 0;
+}
diff --git a/misc/buildroot/package/config/menu.c b/misc/buildroot/package/config/menu.c
new file mode 100644
index 000000000..0c13156f3
--- /dev/null
+++ b/misc/buildroot/package/config/menu.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+struct menu rootmenu;
+static struct menu **last_entry_ptr;
+
+struct file *file_list;
+struct file *current_file;
+
+static void menu_warn(struct menu *menu, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+}
+
+static void prop_warn(struct property *prop, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+}
+
+void menu_init(void)
+{
+ current_entry = current_menu = &rootmenu;
+ last_entry_ptr = &rootmenu.list;
+}
+
+void menu_add_entry(struct symbol *sym)
+{
+ struct menu *menu;
+
+ menu = malloc(sizeof(*menu));
+ memset(menu, 0, sizeof(*menu));
+ menu->sym = sym;
+ menu->parent = current_menu;
+ menu->file = current_file;
+ menu->lineno = zconf_lineno();
+
+ *last_entry_ptr = menu;
+ last_entry_ptr = &menu->next;
+ current_entry = menu;
+}
+
+void menu_end_entry(void)
+{
+}
+
+void menu_add_menu(void)
+{
+ current_menu = current_entry;
+ last_entry_ptr = &current_entry->list;
+}
+
+void menu_end_menu(void)
+{
+ last_entry_ptr = &current_menu->next;
+ current_menu = current_menu->parent;
+}
+
+struct expr *menu_check_dep(struct expr *e)
+{
+ if (!e)
+ return e;
+
+ switch (e->type) {
+ case E_NOT:
+ e->left.expr = menu_check_dep(e->left.expr);
+ break;
+ case E_OR:
+ case E_AND:
+ e->left.expr = menu_check_dep(e->left.expr);
+ e->right.expr = menu_check_dep(e->right.expr);
+ break;
+ case E_SYMBOL:
+ /* change 'm' into 'm' && MODULES */
+ if (e->left.sym == &symbol_mod)
+ return expr_alloc_and(e, expr_alloc_symbol(modules_sym));
+ break;
+ default:
+ break;
+ }
+ return e;
+}
+
+void menu_add_dep(struct expr *dep)
+{
+ current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
+}
+
+void menu_set_type(int type)
+{
+ struct symbol *sym = current_entry->sym;
+
+ if (sym->type == type)
+ return;
+ if (sym->type == S_UNKNOWN) {
+ sym->type = type;
+ return;
+ }
+ menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'\n",
+ sym->name ? sym->name : "<choice>",
+ sym_type_name(sym->type), sym_type_name(type));
+}
+
+struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
+{
+ struct property *prop = prop_alloc(type, current_entry->sym);
+
+ prop->menu = current_entry;
+ prop->text = prompt;
+ prop->expr = expr;
+ prop->visible.expr = menu_check_dep(dep);
+
+ if (prompt) {
+ if (current_entry->prompt)
+ menu_warn(current_entry, "prompt redefined\n");
+ current_entry->prompt = prop;
+ }
+
+ return prop;
+}
+
+void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep)
+{
+ menu_add_prop(type, prompt, NULL, dep);
+}
+
+void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
+{
+ menu_add_prop(type, NULL, expr, dep);
+}
+
+void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
+{
+ menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
+}
+
+void sym_check_prop(struct symbol *sym)
+{
+ struct property *prop;
+ struct symbol *sym2;
+ for (prop = sym->prop; prop; prop = prop->next) {
+ switch (prop->type) {
+ case P_DEFAULT:
+ if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
+ prop->expr->type != E_SYMBOL)
+ prop_warn(prop,
+ "default for config symbol '%'"
+ " must be a single symbol", sym->name);
+ break;
+ case P_SELECT:
+ sym2 = prop_get_symbol(prop);
+ if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
+ prop_warn(prop,
+ "config symbol '%s' uses select, but is "
+ "not boolean or tristate", sym->name);
+ else if (sym2->type == S_UNKNOWN)
+ prop_warn(prop,
+ "'select' used by config symbol '%s' "
+ "refer to undefined symbol '%s'",
+ sym->name, sym2->name);
+ else if (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE)
+ prop_warn(prop,
+ "'%s' has wrong type. 'select' only "
+ "accept arguments of boolean and "
+ "tristate type", sym2->name);
+ break;
+ case P_RANGE:
+ if (sym->type != S_INT && sym->type != S_HEX)
+ prop_warn(prop, "range is only allowed "
+ "for int or hex symbols");
+ if (!sym_string_valid(sym, prop->expr->left.sym->name) ||
+ !sym_string_valid(sym, prop->expr->right.sym->name))
+ prop_warn(prop, "range is invalid");
+ break;
+ default:
+ ;
+ }
+ }
+}
+
+void menu_finalize(struct menu *parent)
+{
+ struct menu *menu, *last_menu;
+ struct symbol *sym;
+ struct property *prop;
+ struct expr *parentdep, *basedep, *dep, *dep2, **ep;
+
+ sym = parent->sym;
+ if (parent->list) {
+ if (sym && sym_is_choice(sym)) {
+ /* find the first choice value and find out choice type */
+ for (menu = parent->list; menu; menu = menu->next) {
+ if (menu->sym) {
+ current_entry = parent;
+ menu_set_type(menu->sym->type);
+ current_entry = menu;
+ menu_set_type(sym->type);
+ break;
+ }
+ }
+ parentdep = expr_alloc_symbol(sym);
+ } else if (parent->prompt)
+ parentdep = parent->prompt->visible.expr;
+ else
+ parentdep = parent->dep;
+
+ for (menu = parent->list; menu; menu = menu->next) {
+ basedep = expr_transform(menu->dep);
+ basedep = expr_alloc_and(expr_copy(parentdep), basedep);
+ basedep = expr_eliminate_dups(basedep);
+ menu->dep = basedep;
+ if (menu->sym)
+ prop = menu->sym->prop;
+ else
+ prop = menu->prompt;
+ for (; prop; prop = prop->next) {
+ if (prop->menu != menu)
+ continue;
+ dep = expr_transform(prop->visible.expr);
+ dep = expr_alloc_and(expr_copy(basedep), dep);
+ dep = expr_eliminate_dups(dep);
+ if (menu->sym && menu->sym->type != S_TRISTATE)
+ dep = expr_trans_bool(dep);
+ prop->visible.expr = dep;
+ if (prop->type == P_SELECT) {
+ struct symbol *es = prop_get_symbol(prop);
+ es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
+ expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
+ }
+ }
+ }
+ for (menu = parent->list; menu; menu = menu->next)
+ menu_finalize(menu);
+ } else if (sym) {
+ basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
+ basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
+ basedep = expr_eliminate_dups(expr_transform(basedep));
+ last_menu = NULL;
+ for (menu = parent->next; menu; menu = menu->next) {
+ dep = menu->prompt ? menu->prompt->visible.expr : menu->dep;
+ if (!expr_contains_symbol(dep, sym))
+ break;
+ if (expr_depends_symbol(dep, sym))
+ goto next;
+ dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no);
+ dep = expr_eliminate_dups(expr_transform(dep));
+ dep2 = expr_copy(basedep);
+ expr_eliminate_eq(&dep, &dep2);
+ expr_free(dep);
+ if (!expr_is_yes(dep2)) {
+ expr_free(dep2);
+ break;
+ }
+ expr_free(dep2);
+ next:
+ menu_finalize(menu);
+ menu->parent = parent;
+ last_menu = menu;
+ }
+ if (last_menu) {
+ parent->list = parent->next;
+ parent->next = last_menu->next;
+ last_menu->next = NULL;
+ }
+ }
+ for (menu = parent->list; menu; menu = menu->next) {
+ if (sym && sym_is_choice(sym) && menu->sym) {
+ menu->sym->flags |= SYMBOL_CHOICEVAL;
+ if (!menu->prompt)
+ menu_warn(menu, "choice value must have a prompt");
+ for (prop = menu->sym->prop; prop; prop = prop->next) {
+ if (prop->type == P_PROMPT && prop->menu != menu) {
+ prop_warn(prop, "choice values "
+ "currently only support a "
+ "single prompt");
+ }
+ if (prop->type == P_DEFAULT)
+ prop_warn(prop, "defaults for choice "
+ "values not supported");
+ }
+ current_entry = menu;
+ menu_set_type(sym->type);
+ menu_add_symbol(P_CHOICE, sym, NULL);
+ prop = sym_get_choice_prop(sym);
+ for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
+ ;
+ *ep = expr_alloc_one(E_CHOICE, NULL);
+ (*ep)->right.sym = menu->sym;
+ }
+ if (menu->list && (!menu->prompt || !menu->prompt->text)) {
+ for (last_menu = menu->list; ; last_menu = last_menu->next) {
+ last_menu->parent = parent;
+ if (!last_menu->next)
+ break;
+ }
+ last_menu->next = menu->next;
+ menu->next = menu->list;
+ menu->list = NULL;
+ }
+ }
+
+ if (sym && !(sym->flags & SYMBOL_WARNED)) {
+ if (sym->type == S_UNKNOWN)
+ menu_warn(parent, "config symbol defined "
+ "without type\n");
+
+ if (sym_is_choice(sym) && !parent->prompt)
+ menu_warn(parent, "choice must have a prompt\n");
+
+ /* Check properties connected to this symbol */
+ sym_check_prop(sym);
+ sym->flags |= SYMBOL_WARNED;
+ }
+
+ if (sym && !sym_is_optional(sym) && parent->prompt) {
+ sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
+ expr_alloc_and(parent->prompt->visible.expr,
+ expr_alloc_symbol(&symbol_mod)));
+ }
+}
+
+bool menu_is_visible(struct menu *menu)
+{
+ struct menu *child;
+ struct symbol *sym;
+ tristate visible;
+
+ if (!menu->prompt)
+ return false;
+ sym = menu->sym;
+ if (sym) {
+ sym_calc_value(sym);
+ visible = menu->prompt->visible.tri;
+ } else
+ visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr);
+
+ if (visible != no)
+ return true;
+ if (!sym || sym_get_tristate_value(menu->sym) == no)
+ return false;
+
+ for (child = menu->list; child; child = child->next)
+ if (menu_is_visible(child))
+ return true;
+ return false;
+}
+
+const char *menu_get_prompt(struct menu *menu)
+{
+ if (menu->prompt)
+ return menu->prompt->text;
+ else if (menu->sym)
+ return menu->sym->name;
+ return NULL;
+}
+
+struct menu *menu_get_root_menu(struct menu *menu)
+{
+ return &rootmenu;
+}
+
+struct menu *menu_get_parent_menu(struct menu *menu)
+{
+ enum prop_type type;
+
+ for (; menu != &rootmenu; menu = menu->parent) {
+ type = menu->prompt ? menu->prompt->type : 0;
+ if (type == P_MENU)
+ break;
+ }
+ return menu;
+}
+
diff --git a/misc/buildroot/package/config/symbol.c b/misc/buildroot/package/config/symbol.c
new file mode 100644
index 000000000..ea629728a
--- /dev/null
+++ b/misc/buildroot/package/config/symbol.c
@@ -0,0 +1,809 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <regex.h>
+#include <sys/utsname.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+struct symbol symbol_yes = {
+ .name = "y",
+ .curr = { "y", yes },
+ .flags = SYMBOL_YES|SYMBOL_VALID,
+}, symbol_mod = {
+ .name = "m",
+ .curr = { "m", mod },
+ .flags = SYMBOL_MOD|SYMBOL_VALID,
+}, symbol_no = {
+ .name = "n",
+ .curr = { "n", no },
+ .flags = SYMBOL_NO|SYMBOL_VALID,
+}, symbol_empty = {
+ .name = "",
+ .curr = { "", no },
+ .flags = SYMBOL_VALID,
+};
+
+int sym_change_count;
+struct symbol *modules_sym;
+tristate modules_val;
+
+void sym_add_default(struct symbol *sym, const char *def)
+{
+ struct property *prop = prop_alloc(P_DEFAULT, sym);
+
+ prop->expr = expr_alloc_symbol(sym_lookup(def, 1));
+}
+
+void sym_init(void)
+{
+ struct symbol *sym;
+ char *p;
+ static bool inited = false;
+
+ if (inited)
+ return;
+ inited = true;
+
+ sym = sym_lookup("VERSION", 0);
+ sym->type = S_STRING;
+ sym->flags |= SYMBOL_AUTO;
+ p = getenv("VERSION");
+ if (p)
+ sym_add_default(sym, p);
+
+ sym = sym_lookup("TARGET_ARCH", 0);
+ sym->type = S_STRING;
+ sym->flags |= SYMBOL_AUTO;
+ p = getenv("TARGET_ARCH");
+ if (p)
+ sym_add_default(sym, p);
+
+}
+
+enum symbol_type sym_get_type(struct symbol *sym)
+{
+ enum symbol_type type = sym->type;
+
+ if (type == S_TRISTATE) {
+ if (sym_is_choice_value(sym) && sym->visible == yes)
+ type = S_BOOLEAN;
+ else if (modules_val == no)
+ type = S_BOOLEAN;
+ }
+ return type;
+}
+
+const char *sym_type_name(enum symbol_type type)
+{
+ switch (type) {
+ case S_BOOLEAN:
+ return "boolean";
+ case S_TRISTATE:
+ return "tristate";
+ case S_INT:
+ return "integer";
+ case S_HEX:
+ return "hex";
+ case S_STRING:
+ return "string";
+ case S_UNKNOWN:
+ return "unknown";
+ case S_OTHER:
+ break;
+ }
+ return "???";
+}
+
+struct property *sym_get_choice_prop(struct symbol *sym)
+{
+ struct property *prop;
+
+ for_all_choices(sym, prop)
+ return prop;
+ return NULL;
+}
+
+struct property *sym_get_default_prop(struct symbol *sym)
+{
+ struct property *prop;
+
+ for_all_defaults(sym, prop) {
+ prop->visible.tri = expr_calc_value(prop->visible.expr);
+ if (prop->visible.tri != no)
+ return prop;
+ }
+ return NULL;
+}
+
+struct property *sym_get_range_prop(struct symbol *sym)
+{
+ struct property *prop;
+
+ for_all_properties(sym, prop, P_RANGE) {
+ prop->visible.tri = expr_calc_value(prop->visible.expr);
+ if (prop->visible.tri != no)
+ return prop;
+ }
+ return NULL;
+}
+
+static void sym_calc_visibility(struct symbol *sym)
+{
+ struct property *prop;
+ tristate tri;
+
+ /* any prompt visible? */
+ tri = no;
+ for_all_prompts(sym, prop) {
+ prop->visible.tri = expr_calc_value(prop->visible.expr);
+ tri = E_OR(tri, prop->visible.tri);
+ }
+ if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
+ tri = yes;
+ if (sym->visible != tri) {
+ sym->visible = tri;
+ sym_set_changed(sym);
+ }
+ if (sym_is_choice_value(sym))
+ return;
+ tri = no;
+ if (sym->rev_dep.expr)
+ tri = expr_calc_value(sym->rev_dep.expr);
+ if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
+ tri = yes;
+ if (sym->rev_dep.tri != tri) {
+ sym->rev_dep.tri = tri;
+ sym_set_changed(sym);
+ }
+}
+
+static struct symbol *sym_calc_choice(struct symbol *sym)
+{
+ struct symbol *def_sym;
+ struct property *prop;
+ struct expr *e;
+
+ /* is the user choice visible? */
+ def_sym = sym->user.val;
+ if (def_sym) {
+ sym_calc_visibility(def_sym);
+ if (def_sym->visible != no)
+ return def_sym;
+ }
+
+ /* any of the defaults visible? */
+ for_all_defaults(sym, prop) {
+ prop->visible.tri = expr_calc_value(prop->visible.expr);
+ if (prop->visible.tri == no)
+ continue;
+ def_sym = prop_get_symbol(prop);
+ sym_calc_visibility(def_sym);
+ if (def_sym->visible != no)
+ return def_sym;
+ }
+
+ /* just get the first visible value */
+ prop = sym_get_choice_prop(sym);
+ for (e = prop->expr; e; e = e->left.expr) {
+ def_sym = e->right.sym;
+ sym_calc_visibility(def_sym);
+ if (def_sym->visible != no)
+ return def_sym;
+ }
+
+ /* no choice? reset tristate value */
+ sym->curr.tri = no;
+ return NULL;
+}
+
+void sym_calc_value(struct symbol *sym)
+{
+ struct symbol_value newval, oldval;
+ struct property *prop;
+ struct expr *e;
+
+ if (!sym)
+ return;
+
+ if (sym->flags & SYMBOL_VALID)
+ return;
+ sym->flags |= SYMBOL_VALID;
+
+ oldval = sym->curr;
+
+ switch (sym->type) {
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ newval = symbol_empty.curr;
+ break;
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ newval = symbol_no.curr;
+ break;
+ default:
+ sym->curr.val = sym->name;
+ sym->curr.tri = no;
+ return;
+ }
+ if (!sym_is_choice_value(sym))
+ sym->flags &= ~SYMBOL_WRITE;
+
+ sym_calc_visibility(sym);
+
+ /* set default if recursively called */
+ sym->curr = newval;
+
+ switch (sym_get_type(sym)) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ if (sym_is_choice_value(sym) && sym->visible == yes) {
+ prop = sym_get_choice_prop(sym);
+ newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
+ } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
+ sym->flags |= SYMBOL_WRITE;
+ if (sym_has_value(sym))
+ newval.tri = sym->user.tri;
+ else if (!sym_is_choice(sym)) {
+ prop = sym_get_default_prop(sym);
+ if (prop)
+ newval.tri = expr_calc_value(prop->expr);
+ }
+ newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri);
+ } else if (!sym_is_choice(sym)) {
+ prop = sym_get_default_prop(sym);
+ if (prop) {
+ sym->flags |= SYMBOL_WRITE;
+ newval.tri = expr_calc_value(prop->expr);
+ }
+ }
+ if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
+ newval.tri = yes;
+ break;
+ case S_STRING:
+ case S_HEX:
+ case S_INT:
+ if (sym->visible != no) {
+ sym->flags |= SYMBOL_WRITE;
+ if (sym_has_value(sym)) {
+ newval.val = sym->user.val;
+ break;
+ }
+ }
+ prop = sym_get_default_prop(sym);
+ if (prop) {
+ struct symbol *ds = prop_get_symbol(prop);
+ if (ds) {
+ sym->flags |= SYMBOL_WRITE;
+ sym_calc_value(ds);
+ newval.val = ds->curr.val;
+ }
+ }
+ break;
+ default:
+ ;
+ }
+
+ sym->curr = newval;
+ if (sym_is_choice(sym) && newval.tri == yes)
+ sym->curr.val = sym_calc_choice(sym);
+
+ if (memcmp(&oldval, &sym->curr, sizeof(oldval)))
+ sym_set_changed(sym);
+ if (modules_sym == sym)
+ modules_val = modules_sym->curr.tri;
+
+ if (sym_is_choice(sym)) {
+ int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
+ prop = sym_get_choice_prop(sym);
+ for (e = prop->expr; e; e = e->left.expr) {
+ e->right.sym->flags |= flags;
+ if (flags & SYMBOL_CHANGED)
+ sym_set_changed(e->right.sym);
+ }
+ }
+}
+
+void sym_clear_all_valid(void)
+{
+ struct symbol *sym;
+ int i;
+
+ for_all_symbols(i, sym)
+ sym->flags &= ~SYMBOL_VALID;
+ sym_change_count++;
+ if (modules_sym)
+ sym_calc_value(modules_sym);
+}
+
+void sym_set_changed(struct symbol *sym)
+{
+ struct property *prop;
+
+ sym->flags |= SYMBOL_CHANGED;
+ for (prop = sym->prop; prop; prop = prop->next) {
+ if (prop->menu)
+ prop->menu->flags |= MENU_CHANGED;
+ }
+}
+
+void sym_set_all_changed(void)
+{
+ struct symbol *sym;
+ int i;
+
+ for_all_symbols(i, sym)
+ sym_set_changed(sym);
+}
+
+bool sym_tristate_within_range(struct symbol *sym, tristate val)
+{
+ int type = sym_get_type(sym);
+
+ if (sym->visible == no)
+ return false;
+
+ if (type != S_BOOLEAN && type != S_TRISTATE)
+ return false;
+
+ if (type == S_BOOLEAN && val == mod)
+ return false;
+ if (sym->visible <= sym->rev_dep.tri)
+ return false;
+ if (sym_is_choice_value(sym) && sym->visible == yes)
+ return val == yes;
+ return val >= sym->rev_dep.tri && val <= sym->visible;
+}
+
+bool sym_set_tristate_value(struct symbol *sym, tristate val)
+{
+ tristate oldval = sym_get_tristate_value(sym);
+
+ if (oldval != val && !sym_tristate_within_range(sym, val))
+ return false;
+
+ if (sym->flags & SYMBOL_NEW) {
+ sym->flags &= ~SYMBOL_NEW;
+ sym_set_changed(sym);
+ }
+ if (sym_is_choice_value(sym) && val == yes) {
+ struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
+
+ cs->user.val = sym;
+ cs->flags &= ~SYMBOL_NEW;
+ }
+
+ sym->user.tri = val;
+ if (oldval != val) {
+ sym_clear_all_valid();
+ if (sym == modules_sym)
+ sym_set_all_changed();
+ }
+
+ return true;
+}
+
+tristate sym_toggle_tristate_value(struct symbol *sym)
+{
+ tristate oldval, newval;
+
+ oldval = newval = sym_get_tristate_value(sym);
+ do {
+ switch (newval) {
+ case no:
+ newval = mod;
+ break;
+ case mod:
+ newval = yes;
+ break;
+ case yes:
+ newval = no;
+ break;
+ }
+ if (sym_set_tristate_value(sym, newval))
+ break;
+ } while (oldval != newval);
+ return newval;
+}
+
+bool sym_string_valid(struct symbol *sym, const char *str)
+{
+ signed char ch;
+
+ switch (sym->type) {
+ case S_STRING:
+ return true;
+ case S_INT:
+ ch = *str++;
+ if (ch == '-')
+ ch = *str++;
+ if (!isdigit(ch))
+ return false;
+ if (ch == '0' && *str != 0)
+ return false;
+ while ((ch = *str++)) {
+ if (!isdigit(ch))
+ return false;
+ }
+ return true;
+ case S_HEX:
+ if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
+ str += 2;
+ ch = *str++;
+ do {
+ if (!isxdigit(ch))
+ return false;
+ } while ((ch = *str++));
+ return true;
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ switch (str[0]) {
+ case 'y': case 'Y':
+ case 'm': case 'M':
+ case 'n': case 'N':
+ return true;
+ }
+ return false;
+ default:
+ return false;
+ }
+}
+
+bool sym_string_within_range(struct symbol *sym, const char *str)
+{
+ struct property *prop;
+ int val;
+
+ switch (sym->type) {
+ case S_STRING:
+ return sym_string_valid(sym, str);
+ case S_INT:
+ if (!sym_string_valid(sym, str))
+ return false;
+ prop = sym_get_range_prop(sym);
+ if (!prop)
+ return true;
+ val = strtol(str, NULL, 10);
+ return val >= strtol(prop->expr->left.sym->name, NULL, 10) &&
+ val <= strtol(prop->expr->right.sym->name, NULL, 10);
+ case S_HEX:
+ if (!sym_string_valid(sym, str))
+ return false;
+ prop = sym_get_range_prop(sym);
+ if (!prop)
+ return true;
+ val = strtol(str, NULL, 16);
+ return val >= strtol(prop->expr->left.sym->name, NULL, 16) &&
+ val <= strtol(prop->expr->right.sym->name, NULL, 16);
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ switch (str[0]) {
+ case 'y': case 'Y':
+ return sym_tristate_within_range(sym, yes);
+ case 'm': case 'M':
+ return sym_tristate_within_range(sym, mod);
+ case 'n': case 'N':
+ return sym_tristate_within_range(sym, no);
+ }
+ return false;
+ default:
+ return false;
+ }
+}
+
+bool sym_set_string_value(struct symbol *sym, const char *newval)
+{
+ const char *oldval;
+ char *val;
+ int size;
+
+ switch (sym->type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ switch (newval[0]) {
+ case 'y': case 'Y':
+ return sym_set_tristate_value(sym, yes);
+ case 'm': case 'M':
+ return sym_set_tristate_value(sym, mod);
+ case 'n': case 'N':
+ return sym_set_tristate_value(sym, no);
+ }
+ return false;
+ default:
+ ;
+ }
+
+ if (!sym_string_within_range(sym, newval))
+ return false;
+
+ if (sym->flags & SYMBOL_NEW) {
+ sym->flags &= ~SYMBOL_NEW;
+ sym_set_changed(sym);
+ }
+
+ oldval = sym->user.val;
+ size = strlen(newval) + 1;
+ if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
+ size += 2;
+ sym->user.val = val = malloc(size);
+ *val++ = '0';
+ *val++ = 'x';
+ } else if (!oldval || strcmp(oldval, newval))
+ sym->user.val = val = malloc(size);
+ else
+ return true;
+
+ strcpy(val, newval);
+ free((void *)oldval);
+ sym_clear_all_valid();
+
+ return true;
+}
+
+const char *sym_get_string_value(struct symbol *sym)
+{
+ tristate val;
+
+ switch (sym->type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ val = sym_get_tristate_value(sym);
+ switch (val) {
+ case no:
+ return "n";
+ case mod:
+ return "m";
+ case yes:
+ return "y";
+ }
+ break;
+ default:
+ ;
+ }
+ return (const char *)sym->curr.val;
+}
+
+bool sym_is_changable(struct symbol *sym)
+{
+ return sym->visible > sym->rev_dep.tri;
+}
+
+struct symbol *sym_lookup(const char *name, int isconst)
+{
+ struct symbol *symbol;
+ const char *ptr;
+ char *new_name;
+ int hash = 0;
+
+ if (name) {
+ if (name[0] && !name[1]) {
+ switch (name[0]) {
+ case 'y': return &symbol_yes;
+ case 'm': return &symbol_mod;
+ case 'n': return &symbol_no;
+ }
+ }
+ for (ptr = name; *ptr; ptr++)
+ hash += *ptr;
+ hash &= 0xff;
+
+ for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
+ if (!strcmp(symbol->name, name)) {
+ if ((isconst && symbol->flags & SYMBOL_CONST) ||
+ (!isconst && !(symbol->flags & SYMBOL_CONST)))
+ return symbol;
+ }
+ }
+ new_name = strdup(name);
+ } else {
+ new_name = NULL;
+ hash = 256;
+ }
+
+ symbol = malloc(sizeof(*symbol));
+ memset(symbol, 0, sizeof(*symbol));
+ symbol->name = new_name;
+ symbol->type = S_UNKNOWN;
+ symbol->flags = SYMBOL_NEW;
+ if (isconst)
+ symbol->flags |= SYMBOL_CONST;
+
+ symbol->next = symbol_hash[hash];
+ symbol_hash[hash] = symbol;
+
+ return symbol;
+}
+
+struct symbol *sym_find(const char *name)
+{
+ struct symbol *symbol = NULL;
+ const char *ptr;
+ int hash = 0;
+
+ if (!name)
+ return NULL;
+
+ if (name[0] && !name[1]) {
+ switch (name[0]) {
+ case 'y': return &symbol_yes;
+ case 'm': return &symbol_mod;
+ case 'n': return &symbol_no;
+ }
+ }
+ for (ptr = name; *ptr; ptr++)
+ hash += *ptr;
+ hash &= 0xff;
+
+ for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
+ if (!strcmp(symbol->name, name) &&
+ !(symbol->flags & SYMBOL_CONST))
+ break;
+ }
+
+ return symbol;
+}
+
+struct symbol **sym_re_search(const char *pattern)
+{
+ struct symbol *sym, **sym_arr = NULL;
+ int i, cnt, size;
+ regex_t re;
+
+ cnt = size = 0;
+ /* Skip if empty */
+ if (strlen(pattern) == 0)
+ return NULL;
+ if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
+ return NULL;
+
+ for_all_symbols(i, sym) {
+ if (sym->flags & SYMBOL_CONST || !sym->name)
+ continue;
+ if (regexec(&re, sym->name, 0, NULL, 0))
+ continue;
+ if (cnt + 1 >= size) {
+ void *tmp = sym_arr;
+ size += 16;
+ sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
+ if (!sym_arr) {
+ free(tmp);
+ return NULL;
+ }
+ }
+ sym_arr[cnt++] = sym;
+ }
+ if (sym_arr)
+ sym_arr[cnt] = NULL;
+ regfree(&re);
+
+ return sym_arr;
+}
+
+
+struct symbol *sym_check_deps(struct symbol *sym);
+
+static struct symbol *sym_check_expr_deps(struct expr *e)
+{
+ struct symbol *sym;
+
+ if (!e)
+ return NULL;
+ switch (e->type) {
+ case E_OR:
+ case E_AND:
+ sym = sym_check_expr_deps(e->left.expr);
+ if (sym)
+ return sym;
+ return sym_check_expr_deps(e->right.expr);
+ case E_NOT:
+ return sym_check_expr_deps(e->left.expr);
+ case E_EQUAL:
+ case E_UNEQUAL:
+ sym = sym_check_deps(e->left.sym);
+ if (sym)
+ return sym;
+ return sym_check_deps(e->right.sym);
+ case E_SYMBOL:
+ return sym_check_deps(e->left.sym);
+ default:
+ break;
+ }
+ printf("Oops! How to check %d?\n", e->type);
+ return NULL;
+}
+
+struct symbol *sym_check_deps(struct symbol *sym)
+{
+ struct symbol *sym2;
+ struct property *prop;
+
+ if (sym->flags & SYMBOL_CHECK_DONE)
+ return NULL;
+ if (sym->flags & SYMBOL_CHECK) {
+ printf("Warning! Found recursive dependency: %s", sym->name);
+ return sym;
+ }
+
+ sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
+ sym2 = sym_check_expr_deps(sym->rev_dep.expr);
+ if (sym2)
+ goto out;
+
+ for (prop = sym->prop; prop; prop = prop->next) {
+ if (prop->type == P_CHOICE || prop->type == P_SELECT)
+ continue;
+ sym2 = sym_check_expr_deps(prop->visible.expr);
+ if (sym2)
+ goto out;
+ if (prop->type != P_DEFAULT || sym_is_choice(sym))
+ continue;
+ sym2 = sym_check_expr_deps(prop->expr);
+ if (sym2)
+ goto out;
+ }
+out:
+ if (sym2)
+ printf(" %s", sym->name);
+ sym->flags &= ~SYMBOL_CHECK;
+ return sym2;
+}
+
+struct property *prop_alloc(enum prop_type type, struct symbol *sym)
+{
+ struct property *prop;
+ struct property **propp;
+
+ prop = malloc(sizeof(*prop));
+ memset(prop, 0, sizeof(*prop));
+ prop->type = type;
+ prop->sym = sym;
+ prop->file = current_file;
+ prop->lineno = zconf_lineno();
+
+ /* append property to the prop list of symbol */
+ if (sym) {
+ for (propp = &sym->prop; *propp; propp = &(*propp)->next)
+ ;
+ *propp = prop;
+ }
+
+ return prop;
+}
+
+struct symbol *prop_get_symbol(struct property *prop)
+{
+ if (prop->expr && (prop->expr->type == E_SYMBOL ||
+ prop->expr->type == E_CHOICE))
+ return prop->expr->left.sym;
+ return NULL;
+}
+
+const char *prop_get_type_name(enum prop_type type)
+{
+ switch (type) {
+ case P_PROMPT:
+ return "prompt";
+ case P_COMMENT:
+ return "comment";
+ case P_MENU:
+ return "menu";
+ case P_DEFAULT:
+ return "default";
+ case P_CHOICE:
+ return "choice";
+ case P_SELECT:
+ return "select";
+ case P_RANGE:
+ return "range";
+ case P_UNKNOWN:
+ break;
+ }
+ return "unknown";
+}
diff --git a/misc/buildroot/package/config/util.c b/misc/buildroot/package/config/util.c
new file mode 100644
index 000000000..8f65ccac5
--- /dev/null
+++ b/misc/buildroot/package/config/util.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org>
+ * Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org>
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <string.h>
+#include "lkc.h"
+
+/* file already present in list? If not add it */
+struct file *file_lookup(const char *name)
+{
+ struct file *file;
+
+ for (file = file_list; file; file = file->next) {
+ if (!strcmp(name, file->name))
+ return file;
+ }
+
+ file = malloc(sizeof(*file));
+ memset(file, 0, sizeof(*file));
+ file->name = strdup(name);
+ file->next = file_list;
+ file_list = file;
+ return file;
+}
+
+/* write a dependency file as used by kbuild to track dependencies */
+int file_write_dep(const char *name)
+{
+ struct file *file;
+ FILE *out;
+
+ if (!name)
+ name = ".config.cmd";
+ out = fopen(".config.tmp", "w");
+ if (!out)
+ return 1;
+ fprintf(out, "deps_config := \\\n");
+ for (file = file_list; file; file = file->next) {
+ if (file->next)
+ fprintf(out, "\t%s \\\n", file->name);
+ else
+ fprintf(out, "\t%s\n", file->name);
+ }
+ fprintf(out, "\n.config include/config.h: $(deps_config)\n\n$(deps_config):\n");
+ fclose(out);
+ rename(".config.tmp", name);
+ return 0;
+}
+
+/* Allocate initial growable sting */
+struct gstr str_new(void)
+{
+ struct gstr gs;
+ gs.s = malloc(sizeof(char) * 64);
+ gs.len = 16;
+ strcpy(gs.s, "\0");
+ return gs;
+}
+
+/* Allocate and assign growable string */
+struct gstr str_assign(const char *s)
+{
+ struct gstr gs;
+ gs.s = strdup(s);
+ gs.len = strlen(s) + 1;
+ return gs;
+}
+
+/* Free storage for growable string */
+void str_free(struct gstr *gs)
+{
+ if (gs->s)
+ free(gs->s);
+ gs->s = NULL;
+ gs->len = 0;
+}
+
+/* Append to growable string */
+void str_append(struct gstr *gs, const char *s)
+{
+ size_t l = strlen(gs->s) + strlen(s) + 1;
+ if (l > gs->len) {
+ gs->s = realloc(gs->s, l);
+ gs->len = l;
+ }
+ strcat(gs->s, s);
+}
+
+/* Append printf formatted string to growable string */
+void str_printf(struct gstr *gs, const char *fmt, ...)
+{
+ va_list ap;
+ char s[10000]; /* big enough... */
+ va_start(ap, fmt);
+ vsnprintf(s, sizeof(s), fmt, ap);
+ str_append(gs, s);
+ va_end(ap);
+}
+
+/* Retreive value of growable string */
+const char *str_get(struct gstr *gs)
+{
+ return gs->s;
+}
+
diff --git a/misc/buildroot/package/config/zconf.l b/misc/buildroot/package/config/zconf.l
new file mode 100644
index 000000000..55517b287
--- /dev/null
+++ b/misc/buildroot/package/config/zconf.l
@@ -0,0 +1,366 @@
+%option backup nostdinit noyywrap never-interactive full ecs
+%option 8bit backup nodefault perf-report perf-report
+%x COMMAND HELP STRING PARAM
+%{
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+#define START_STRSIZE 16
+
+char *text;
+static char *text_ptr;
+static int text_size, text_asize;
+
+struct buffer {
+ struct buffer *parent;
+ YY_BUFFER_STATE state;
+};
+
+struct buffer *current_buf;
+
+static int last_ts, first_ts;
+
+static void zconf_endhelp(void);
+static struct buffer *zconf_endfile(void);
+
+void new_string(void)
+{
+ text = malloc(START_STRSIZE);
+ text_asize = START_STRSIZE;
+ text_ptr = text;
+ text_size = 0;
+ *text_ptr = 0;
+}
+
+void append_string(const char *str, int size)
+{
+ int new_size = text_size + size + 1;
+ if (new_size > text_asize) {
+ text = realloc(text, new_size);
+ text_asize = new_size;
+ text_ptr = text + text_size;
+ }
+ memcpy(text_ptr, str, size);
+ text_ptr += size;
+ text_size += size;
+ *text_ptr = 0;
+}
+
+void alloc_string(const char *str, int size)
+{
+ text = malloc(size + 1);
+ memcpy(text, str, size);
+ text[size] = 0;
+}
+%}
+
+ws [ \n\t]
+n [A-Za-z0-9_]
+
+%%
+ int str = 0;
+ int ts, i;
+
+[ \t]*#.*\n current_file->lineno++;
+[ \t]*#.*
+
+[ \t]*\n current_file->lineno++; return T_EOL;
+
+[ \t]+ {
+ BEGIN(COMMAND);
+}
+
+. {
+ unput(yytext[0]);
+ BEGIN(COMMAND);
+}
+
+
+<COMMAND>{
+ "mainmenu" BEGIN(PARAM); return T_MAINMENU;
+ "menu" BEGIN(PARAM); return T_MENU;
+ "endmenu" BEGIN(PARAM); return T_ENDMENU;
+ "source" BEGIN(PARAM); return T_SOURCE;
+ "choice" BEGIN(PARAM); return T_CHOICE;
+ "endchoice" BEGIN(PARAM); return T_ENDCHOICE;
+ "comment" BEGIN(PARAM); return T_COMMENT;
+ "config" BEGIN(PARAM); return T_CONFIG;
+ "menuconfig" BEGIN(PARAM); return T_MENUCONFIG;
+ "help" BEGIN(PARAM); return T_HELP;
+ "if" BEGIN(PARAM); return T_IF;
+ "endif" BEGIN(PARAM); return T_ENDIF;
+ "depends" BEGIN(PARAM); return T_DEPENDS;
+ "requires" BEGIN(PARAM); return T_REQUIRES;
+ "optional" BEGIN(PARAM); return T_OPTIONAL;
+ "default" BEGIN(PARAM); return T_DEFAULT;
+ "prompt" BEGIN(PARAM); return T_PROMPT;
+ "tristate" BEGIN(PARAM); return T_TRISTATE;
+ "def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE;
+ "bool" BEGIN(PARAM); return T_BOOLEAN;
+ "boolean" BEGIN(PARAM); return T_BOOLEAN;
+ "def_bool" BEGIN(PARAM); return T_DEF_BOOLEAN;
+ "def_boolean" BEGIN(PARAM); return T_DEF_BOOLEAN;
+ "int" BEGIN(PARAM); return T_INT;
+ "hex" BEGIN(PARAM); return T_HEX;
+ "string" BEGIN(PARAM); return T_STRING;
+ "select" BEGIN(PARAM); return T_SELECT;
+ "enable" BEGIN(PARAM); return T_SELECT;
+ "range" BEGIN(PARAM); return T_RANGE;
+ {n}+ {
+ alloc_string(yytext, yyleng);
+ zconflval.string = text;
+ return T_WORD;
+ }
+ .
+ \n current_file->lineno++; BEGIN(INITIAL);
+}
+
+<PARAM>{
+ "&&" return T_AND;
+ "||" return T_OR;
+ "(" return T_OPEN_PAREN;
+ ")" return T_CLOSE_PAREN;
+ "!" return T_NOT;
+ "=" return T_EQUAL;
+ "!=" return T_UNEQUAL;
+ "if" return T_IF;
+ "on" return T_ON;
+ \"|\' {
+ str = yytext[0];
+ new_string();
+ BEGIN(STRING);
+ }
+ \n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
+ --- /* ignore */
+ ({n}|[-/.])+ {
+ alloc_string(yytext, yyleng);
+ zconflval.string = text;
+ return T_WORD;
+ }
+ #.* /* comment */
+ \\\n current_file->lineno++;
+ .
+ <<EOF>> {
+ BEGIN(INITIAL);
+ }
+}
+
+<STRING>{
+ [^'"\\\n]+/\n {
+ append_string(yytext, yyleng);
+ zconflval.string = text;
+ return T_WORD_QUOTE;
+ }
+ [^'"\\\n]+ {
+ append_string(yytext, yyleng);
+ }
+ \\.?/\n {
+ append_string(yytext + 1, yyleng - 1);
+ zconflval.string = text;
+ return T_WORD_QUOTE;
+ }
+ \\.? {
+ append_string(yytext + 1, yyleng - 1);
+ }
+ \'|\" {
+ if (str == yytext[0]) {
+ BEGIN(PARAM);
+ zconflval.string = text;
+ return T_WORD_QUOTE;
+ } else
+ append_string(yytext, 1);
+ }
+ \n {
+ printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
+ current_file->lineno++;
+ BEGIN(INITIAL);
+ return T_EOL;
+ }
+ <<EOF>> {
+ BEGIN(INITIAL);
+ }
+}
+
+<HELP>{
+ [ \t]+ {
+ ts = 0;
+ for (i = 0; i < yyleng; i++) {
+ if (yytext[i] == '\t')
+ ts = (ts & ~7) + 8;
+ else
+ ts++;
+ }
+ last_ts = ts;
+ if (first_ts) {
+ if (ts < first_ts) {
+ zconf_endhelp();
+ return T_HELPTEXT;
+ }
+ ts -= first_ts;
+ while (ts > 8) {
+ append_string(" ", 8);
+ ts -= 8;
+ }
+ append_string(" ", ts);
+ }
+ }
+ [ \t]*\n/[^ \t\n] {
+ current_file->lineno++;
+ zconf_endhelp();
+ return T_HELPTEXT;
+ }
+ [ \t]*\n {
+ current_file->lineno++;
+ append_string("\n", 1);
+ }
+ [^ \t\n].* {
+ append_string(yytext, yyleng);
+ if (!first_ts)
+ first_ts = last_ts;
+ }
+ <<EOF>> {
+ zconf_endhelp();
+ return T_HELPTEXT;
+ }
+}
+
+<<EOF>> {
+ if (current_buf) {
+ zconf_endfile();
+ return T_EOF;
+ }
+ fclose(yyin);
+ yyterminate();
+}
+
+%%
+void zconf_starthelp(void)
+{
+ new_string();
+ last_ts = first_ts = 0;
+ BEGIN(HELP);
+}
+
+static void zconf_endhelp(void)
+{
+ zconflval.string = text;
+ BEGIN(INITIAL);
+}
+
+
+/*
+ * Try to open specified file with following names:
+ * ./name
+ * $(srctree)/name
+ * The latter is used when srctree is separate from objtree
+ * when compiling the kernel.
+ * Return NULL if file is not found.
+ */
+FILE *zconf_fopen(const char *name)
+{
+ char *env, fullname[PATH_MAX+1];
+ FILE *f;
+
+ f = fopen(name, "r");
+ if (!f && name[0] != '/') {
+ env = getenv(SRCTREE);
+ if (env) {
+ sprintf(fullname, "%s/%s", env, name);
+ f = fopen(fullname, "r");
+ }
+ }
+ return f;
+}
+
+void zconf_initscan(const char *name)
+{
+ yyin = zconf_fopen(name);
+ if (!yyin) {
+ printf("can't find file %s\n", name);
+ exit(1);
+ }
+
+ current_buf = malloc(sizeof(*current_buf));
+ memset(current_buf, 0, sizeof(*current_buf));
+
+ current_file = file_lookup(name);
+ current_file->lineno = 1;
+ current_file->flags = FILE_BUSY;
+}
+
+void zconf_nextfile(const char *name)
+{
+ struct file *file = file_lookup(name);
+ struct buffer *buf = malloc(sizeof(*buf));
+ memset(buf, 0, sizeof(*buf));
+
+ current_buf->state = YY_CURRENT_BUFFER;
+ yyin = zconf_fopen(name);
+ if (!yyin) {
+ printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
+ exit(1);
+ }
+ yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
+ buf->parent = current_buf;
+ current_buf = buf;
+
+ if (file->flags & FILE_BUSY) {
+ printf("recursive scan (%s)?\n", name);
+ exit(1);
+ }
+ if (file->flags & FILE_SCANNED) {
+ printf("file %s already scanned?\n", name);
+ exit(1);
+ }
+ file->flags |= FILE_BUSY;
+ file->lineno = 1;
+ file->parent = current_file;
+ current_file = file;
+}
+
+static struct buffer *zconf_endfile(void)
+{
+ struct buffer *parent;
+
+ current_file->flags |= FILE_SCANNED;
+ current_file->flags &= ~FILE_BUSY;
+ current_file = current_file->parent;
+
+ parent = current_buf->parent;
+ if (parent) {
+ fclose(yyin);
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ yy_switch_to_buffer(parent->state);
+ }
+ free(current_buf);
+ current_buf = parent;
+
+ return parent;
+}
+
+int zconf_lineno(void)
+{
+ if (current_buf)
+ return current_file->lineno - 1;
+ else
+ return 0;
+}
+
+char *zconf_curname(void)
+{
+ if (current_buf)
+ return current_file->name;
+ else
+ return "<none>";
+}
diff --git a/misc/buildroot/package/config/zconf.tab.c_shipped b/misc/buildroot/package/config/zconf.tab.c_shipped
new file mode 100644
index 000000000..ed612a058
--- /dev/null
+++ b/misc/buildroot/package/config/zconf.tab.c_shipped
@@ -0,0 +1,2130 @@
+/* A Bison parser, made by GNU Bison 1.875a. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* Written by Richard Stallman by simplifying the original so called
+ ``semantic'' parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+/* If NAME_PREFIX is specified substitute the variables and functions
+ names. */
+#define yyparse zconfparse
+#define yylex zconflex
+#define yyerror zconferror
+#define yylval zconflval
+#define yychar zconfchar
+#define yydebug zconfdebug
+#define yynerrs zconfnerrs
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ T_MAINMENU = 258,
+ T_MENU = 259,
+ T_ENDMENU = 260,
+ T_SOURCE = 261,
+ T_CHOICE = 262,
+ T_ENDCHOICE = 263,
+ T_COMMENT = 264,
+ T_CONFIG = 265,
+ T_MENUCONFIG = 266,
+ T_HELP = 267,
+ T_HELPTEXT = 268,
+ T_IF = 269,
+ T_ENDIF = 270,
+ T_DEPENDS = 271,
+ T_REQUIRES = 272,
+ T_OPTIONAL = 273,
+ T_PROMPT = 274,
+ T_DEFAULT = 275,
+ T_TRISTATE = 276,
+ T_DEF_TRISTATE = 277,
+ T_BOOLEAN = 278,
+ T_DEF_BOOLEAN = 279,
+ T_STRING = 280,
+ T_INT = 281,
+ T_HEX = 282,
+ T_WORD = 283,
+ T_WORD_QUOTE = 284,
+ T_UNEQUAL = 285,
+ T_EOF = 286,
+ T_EOL = 287,
+ T_CLOSE_PAREN = 288,
+ T_OPEN_PAREN = 289,
+ T_ON = 290,
+ T_SELECT = 291,
+ T_RANGE = 292,
+ T_OR = 293,
+ T_AND = 294,
+ T_EQUAL = 295,
+ T_NOT = 296
+ };
+#endif
+#define T_MAINMENU 258
+#define T_MENU 259
+#define T_ENDMENU 260
+#define T_SOURCE 261
+#define T_CHOICE 262
+#define T_ENDCHOICE 263
+#define T_COMMENT 264
+#define T_CONFIG 265
+#define T_MENUCONFIG 266
+#define T_HELP 267
+#define T_HELPTEXT 268
+#define T_IF 269
+#define T_ENDIF 270
+#define T_DEPENDS 271
+#define T_REQUIRES 272
+#define T_OPTIONAL 273
+#define T_PROMPT 274
+#define T_DEFAULT 275
+#define T_TRISTATE 276
+#define T_DEF_TRISTATE 277
+#define T_BOOLEAN 278
+#define T_DEF_BOOLEAN 279
+#define T_STRING 280
+#define T_INT 281
+#define T_HEX 282
+#define T_WORD 283
+#define T_WORD_QUOTE 284
+#define T_UNEQUAL 285
+#define T_EOF 286
+#define T_EOL 287
+#define T_CLOSE_PAREN 288
+#define T_OPEN_PAREN 289
+#define T_ON 290
+#define T_SELECT 291
+#define T_RANGE 292
+#define T_OR 293
+#define T_AND 294
+#define T_EQUAL 295
+#define T_NOT 296
+
+
+
+
+/* Copy the first part of user declarations. */
+
+
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
+
+#define PRINTD 0x0001
+#define DEBUG_PARSE 0x0002
+
+int cdebug = PRINTD;
+
+extern int zconflex(void);
+static void zconfprint(const char *err, ...);
+static void zconferror(const char *err);
+static bool zconf_endtoken(int token, int starttoken, int endtoken);
+
+struct symbol *symbol_hash[257];
+
+static struct menu *current_menu, *current_entry;
+
+#define YYERROR_VERBOSE
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+
+typedef union YYSTYPE {
+ int token;
+ char *string;
+ struct symbol *symbol;
+ struct expr *expr;
+ struct menu *menu;
+} YYSTYPE;
+/* Line 191 of yacc.c. */
+
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations. */
+
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+
+/* Line 214 of yacc.c. */
+
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# else
+# ifndef YYSTACK_USE_ALLOCA
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+# define YYSTACK_ALLOC malloc
+# define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+ && (! defined (__cplusplus) \
+ || (YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ short yyss;
+ YYSTYPE yyvs;
+ };
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ register YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+ typedef signed char yysigned_char;
+#else
+ typedef short yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 2
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 201
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 42
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 41
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 104
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 182
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 296
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned short yyprhs[] =
+{
+ 0, 0, 3, 4, 7, 9, 11, 13, 17, 19,
+ 21, 23, 26, 28, 30, 32, 34, 36, 38, 42,
+ 45, 49, 52, 53, 56, 59, 62, 65, 69, 74,
+ 78, 83, 87, 91, 95, 100, 105, 110, 116, 119,
+ 122, 124, 128, 131, 132, 135, 138, 141, 144, 149,
+ 153, 157, 160, 165, 166, 169, 173, 175, 179, 182,
+ 183, 186, 189, 192, 196, 199, 201, 205, 208, 209,
+ 212, 215, 218, 222, 226, 228, 232, 235, 238, 241,
+ 242, 245, 248, 253, 257, 261, 262, 265, 267, 269,
+ 272, 275, 278, 280, 282, 283, 286, 288, 292, 296,
+ 300, 303, 307, 311, 313
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+ 43, 0, -1, -1, 43, 44, -1, 45, -1, 55,
+ -1, 66, -1, 3, 77, 79, -1, 5, -1, 15,
+ -1, 8, -1, 1, 79, -1, 61, -1, 71, -1,
+ 47, -1, 49, -1, 69, -1, 79, -1, 10, 28,
+ 32, -1, 46, 50, -1, 11, 28, 32, -1, 48,
+ 50, -1, -1, 50, 51, -1, 50, 75, -1, 50,
+ 73, -1, 50, 32, -1, 21, 76, 32, -1, 22,
+ 81, 80, 32, -1, 23, 76, 32, -1, 24, 81,
+ 80, 32, -1, 26, 76, 32, -1, 27, 76, 32,
+ -1, 25, 76, 32, -1, 19, 77, 80, 32, -1,
+ 20, 81, 80, 32, -1, 36, 28, 80, 32, -1,
+ 37, 82, 82, 80, 32, -1, 7, 32, -1, 52,
+ 56, -1, 78, -1, 53, 58, 54, -1, 53, 58,
+ -1, -1, 56, 57, -1, 56, 75, -1, 56, 73,
+ -1, 56, 32, -1, 19, 77, 80, 32, -1, 21,
+ 76, 32, -1, 23, 76, 32, -1, 18, 32, -1,
+ 20, 28, 80, 32, -1, -1, 58, 45, -1, 14,
+ 81, 32, -1, 78, -1, 59, 62, 60, -1, 59,
+ 62, -1, -1, 62, 45, -1, 62, 66, -1, 62,
+ 55, -1, 4, 77, 32, -1, 63, 74, -1, 78,
+ -1, 64, 67, 65, -1, 64, 67, -1, -1, 67,
+ 45, -1, 67, 66, -1, 67, 55, -1, 67, 1,
+ 32, -1, 6, 77, 32, -1, 68, -1, 9, 77,
+ 32, -1, 70, 74, -1, 12, 32, -1, 72, 13,
+ -1, -1, 74, 75, -1, 74, 32, -1, 16, 35,
+ 81, 32, -1, 16, 81, 32, -1, 17, 81, 32,
+ -1, -1, 77, 80, -1, 28, -1, 29, -1, 5,
+ 79, -1, 8, 79, -1, 15, 79, -1, 32, -1,
+ 31, -1, -1, 14, 81, -1, 82, -1, 82, 40,
+ 82, -1, 82, 30, 82, -1, 34, 81, 33, -1,
+ 41, 81, -1, 81, 38, 81, -1, 81, 39, 81,
+ -1, 28, -1, 29, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned short yyrline[] =
+{
+ 0, 94, 94, 95, 98, 99, 100, 101, 102, 103,
+ 104, 105, 109, 110, 111, 112, 113, 114, 120, 128,
+ 134, 142, 152, 154, 155, 156, 157, 160, 166, 173,
+ 179, 186, 192, 198, 204, 210, 216, 222, 230, 239,
+ 245, 254, 255, 261, 263, 264, 265, 266, 269, 275,
+ 281, 287, 293, 299, 301, 306, 315, 324, 325, 331,
+ 333, 334, 335, 340, 347, 353, 362, 363, 369, 371,
+ 372, 373, 374, 377, 383, 390, 397, 404, 410, 417,
+ 418, 419, 422, 427, 432, 440, 442, 447, 448, 451,
+ 452, 453, 457, 457, 459, 460, 463, 464, 465, 466,
+ 467, 468, 469, 472, 473
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU",
+ "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
+ "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
+ "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_DEFAULT", "T_TRISTATE",
+ "T_DEF_TRISTATE", "T_BOOLEAN", "T_DEF_BOOLEAN", "T_STRING", "T_INT",
+ "T_HEX", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", "T_EOF", "T_EOL",
+ "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_ON", "T_SELECT", "T_RANGE", "T_OR",
+ "T_AND", "T_EQUAL", "T_NOT", "$accept", "input", "block",
+ "common_block", "config_entry_start", "config_stmt",
+ "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
+ "config_option", "choice", "choice_entry", "choice_end", "choice_stmt",
+ "choice_option_list", "choice_option", "choice_block", "if", "if_end",
+ "if_stmt", "if_block", "menu", "menu_entry", "menu_end", "menu_stmt",
+ "menu_block", "source", "source_stmt", "comment", "comment_stmt",
+ "help_start", "help", "depends_list", "depends", "prompt_stmt_opt",
+ "prompt", "end", "nl_or_eof", "if_expr", "expr", "symbol", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const unsigned short yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned char yyr1[] =
+{
+ 0, 42, 43, 43, 44, 44, 44, 44, 44, 44,
+ 44, 44, 45, 45, 45, 45, 45, 45, 46, 47,
+ 48, 49, 50, 50, 50, 50, 50, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 52, 53,
+ 54, 55, 55, 56, 56, 56, 56, 56, 57, 57,
+ 57, 57, 57, 58, 58, 59, 60, 61, 61, 62,
+ 62, 62, 62, 63, 64, 65, 66, 66, 67, 67,
+ 67, 67, 67, 68, 69, 70, 71, 72, 73, 74,
+ 74, 74, 75, 75, 75, 76, 76, 77, 77, 78,
+ 78, 78, 79, 79, 80, 80, 81, 81, 81, 81,
+ 81, 81, 81, 82, 82
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 0, 2, 1, 1, 1, 3, 1, 1,
+ 1, 2, 1, 1, 1, 1, 1, 1, 3, 2,
+ 3, 2, 0, 2, 2, 2, 2, 3, 4, 3,
+ 4, 3, 3, 3, 4, 4, 4, 5, 2, 2,
+ 1, 3, 2, 0, 2, 2, 2, 2, 4, 3,
+ 3, 2, 4, 0, 2, 3, 1, 3, 2, 0,
+ 2, 2, 2, 3, 2, 1, 3, 2, 0, 2,
+ 2, 2, 3, 3, 1, 3, 2, 2, 2, 0,
+ 2, 2, 4, 3, 3, 0, 2, 1, 1, 2,
+ 2, 2, 1, 1, 0, 2, 1, 3, 3, 3,
+ 2, 3, 3, 1, 1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const unsigned char yydefact[] =
+{
+ 2, 0, 1, 0, 0, 0, 8, 0, 0, 10,
+ 0, 0, 0, 0, 9, 93, 92, 3, 4, 22,
+ 14, 22, 15, 43, 53, 5, 59, 12, 79, 68,
+ 6, 74, 16, 79, 13, 17, 11, 87, 88, 0,
+ 0, 0, 38, 0, 0, 0, 103, 104, 0, 0,
+ 0, 96, 19, 21, 39, 42, 58, 64, 0, 76,
+ 7, 63, 73, 75, 18, 20, 0, 100, 55, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 85, 0,
+ 85, 0, 85, 85, 85, 26, 0, 0, 23, 0,
+ 25, 24, 0, 0, 0, 85, 85, 47, 44, 46,
+ 45, 0, 0, 0, 54, 41, 40, 60, 62, 57,
+ 61, 56, 81, 80, 0, 69, 71, 66, 70, 65,
+ 99, 101, 102, 98, 97, 77, 0, 0, 0, 94,
+ 94, 0, 94, 94, 0, 94, 0, 0, 0, 94,
+ 0, 78, 51, 94, 94, 0, 0, 89, 90, 91,
+ 72, 0, 83, 84, 0, 0, 0, 27, 86, 0,
+ 29, 0, 33, 31, 32, 0, 94, 0, 0, 49,
+ 50, 82, 95, 34, 35, 28, 30, 36, 0, 48,
+ 52, 37
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const short yydefgoto[] =
+{
+ -1, 1, 17, 18, 19, 20, 21, 22, 52, 88,
+ 23, 24, 105, 25, 54, 98, 55, 26, 109, 27,
+ 56, 28, 29, 117, 30, 58, 31, 32, 33, 34,
+ 89, 90, 57, 91, 131, 132, 106, 35, 155, 50,
+ 51
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -99
+static const short yypact[] =
+{
+ -99, 48, -99, 38, 46, 46, -99, 46, -29, -99,
+ 46, -17, -3, -11, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, -99, -99, -99, -99, -99, 38,
+ 12, 15, -99, 18, 51, 62, -99, -99, -11, -11,
+ 4, -24, 138, 138, 160, 121, 110, -4, 81, -4,
+ -99, -99, -99, -99, -99, -99, -19, -99, -99, -11,
+ -11, 70, 70, 73, 32, -11, 46, -11, 46, -11,
+ 46, -11, 46, 46, 46, -99, 36, 70, -99, 95,
+ -99, -99, 96, 46, 106, 46, 46, -99, -99, -99,
+ -99, 38, 38, 38, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, 112, -99, -99, -99, -99, -99,
+ -99, 117, -99, -99, -99, -99, -11, 33, 65, 131,
+ 1, 119, 131, 1, 136, 1, 153, 154, 155, 131,
+ 70, -99, -99, 131, 131, 156, 157, -99, -99, -99,
+ -99, 101, -99, -99, -11, 158, 159, -99, -99, 161,
+ -99, 162, -99, -99, -99, 163, 131, 164, 165, -99,
+ -99, -99, 99, -99, -99, -99, -99, -99, 166, -99,
+ -99, -99
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const short yypgoto[] =
+{
+ -99, -99, -99, 111, -99, -99, -99, -99, 178, -99,
+ -99, -99, -99, 91, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, 115, -99, -99, -99, -99, -99,
+ -99, 146, 168, 89, 27, 0, 126, -1, -98, -48,
+ -63
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -68
+static const short yytable[] =
+{
+ 66, 67, 36, 42, 39, 40, 71, 41, 123, 124,
+ 43, 44, 74, 75, 120, 154, 72, 46, 47, 69,
+ 70, 121, 122, 48, 140, 45, 127, 128, 112, 130,
+ 49, 133, 156, 135, 158, 159, 68, 161, 60, 69,
+ 70, 165, 69, 70, 61, 167, 168, 62, 2, 3,
+ 63, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 46, 47, 13, 14, 139, 152, 48, 126, 178, 15,
+ 16, 69, 70, 49, 37, 38, 129, 166, 151, 15,
+ 16, -67, 114, 64, -67, 5, 101, 7, 8, 102,
+ 10, 11, 12, 143, 65, 13, 103, 153, 46, 47,
+ 147, 148, 149, 69, 70, 125, 172, 134, 141, 136,
+ 137, 138, 15, 16, 5, 101, 7, 8, 102, 10,
+ 11, 12, 145, 146, 13, 103, 101, 7, 142, 102,
+ 10, 11, 12, 171, 144, 13, 103, 69, 70, 69,
+ 70, 15, 16, 100, 150, 154, 113, 108, 113, 116,
+ 73, 157, 15, 16, 74, 75, 70, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 104, 107, 160, 115,
+ 85, 110, 73, 118, 86, 87, 74, 75, 92, 93,
+ 94, 95, 111, 96, 119, 162, 163, 164, 169, 170,
+ 173, 174, 97, 175, 176, 177, 179, 180, 181, 53,
+ 99, 59
+};
+
+static const unsigned char yycheck[] =
+{
+ 48, 49, 3, 32, 4, 5, 30, 7, 71, 72,
+ 10, 28, 16, 17, 33, 14, 40, 28, 29, 38,
+ 39, 69, 70, 34, 87, 28, 74, 75, 32, 77,
+ 41, 79, 130, 81, 132, 133, 32, 135, 39, 38,
+ 39, 139, 38, 39, 32, 143, 144, 32, 0, 1,
+ 32, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 28, 29, 14, 15, 28, 32, 34, 35, 166, 31,
+ 32, 38, 39, 41, 28, 29, 76, 140, 126, 31,
+ 32, 0, 1, 32, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 93, 32, 14, 15, 32, 28, 29,
+ 101, 102, 103, 38, 39, 32, 154, 80, 13, 82,
+ 83, 84, 31, 32, 4, 5, 6, 7, 8, 9,
+ 10, 11, 95, 96, 14, 15, 5, 6, 32, 8,
+ 9, 10, 11, 32, 28, 14, 15, 38, 39, 38,
+ 39, 31, 32, 54, 32, 14, 57, 56, 59, 58,
+ 12, 32, 31, 32, 16, 17, 39, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 55, 56, 32, 58,
+ 32, 56, 12, 58, 36, 37, 16, 17, 18, 19,
+ 20, 21, 56, 23, 58, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 21,
+ 54, 33
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned char yystos[] =
+{
+ 0, 43, 0, 1, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 14, 15, 31, 32, 44, 45, 46,
+ 47, 48, 49, 52, 53, 55, 59, 61, 63, 64,
+ 66, 68, 69, 70, 71, 79, 79, 28, 29, 77,
+ 77, 77, 32, 77, 28, 28, 28, 29, 34, 41,
+ 81, 82, 50, 50, 56, 58, 62, 74, 67, 74,
+ 79, 32, 32, 32, 32, 32, 81, 81, 32, 38,
+ 39, 30, 40, 12, 16, 17, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 32, 36, 37, 51, 72,
+ 73, 75, 18, 19, 20, 21, 23, 32, 57, 73,
+ 75, 5, 8, 15, 45, 54, 78, 45, 55, 60,
+ 66, 78, 32, 75, 1, 45, 55, 65, 66, 78,
+ 33, 81, 81, 82, 82, 32, 35, 81, 81, 77,
+ 81, 76, 77, 81, 76, 81, 76, 76, 76, 28,
+ 82, 13, 32, 77, 28, 76, 76, 79, 79, 79,
+ 32, 81, 32, 32, 14, 80, 80, 32, 80, 80,
+ 32, 80, 32, 32, 32, 80, 82, 80, 80, 32,
+ 32, 32, 81, 32, 32, 32, 32, 32, 80, 32,
+ 32, 32
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrlab1
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror ("syntax error: cannot back up");\
+ YYERROR; \
+ } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+ are run). */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ Current.first_line = Rhs[1].first_line; \
+ Current.first_column = Rhs[1].first_column; \
+ Current.last_line = Rhs[N].last_line; \
+ Current.last_column = Rhs[N].last_column;
+#endif
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+# define YYDSYMPRINT(Args) \
+do { \
+ if (yydebug) \
+ yysymprint Args; \
+} while (0)
+
+# define YYDSYMPRINTF(Title, Token, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yysymprint (stderr, \
+ Token, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (cinluded). |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short *bottom, short *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ short *bottom;
+ short *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (/* Nothing. */; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+ int yyrule;
+#endif
+{
+ int yyi;
+ unsigned int yylineno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+ yyrule - 1, yylineno);
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
+ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YYDSYMPRINT(Args)
+# define YYDSYMPRINTF(Title, Token, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined (__GLIBC__) && defined (_STRING_H)
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ register const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ register char *yyd = yydest;
+ register const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ if (yytype < YYNTOKENS)
+ {
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ }
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+ YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yytype, yyvaluep)
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes. */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+ register int yystate;
+ register int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short yyssa[YYINITDEPTH];
+ short *yyss = yyssa;
+ register short *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK (yyvsp--, yyssp--)
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks.
+ */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyoverflowlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyoverflowlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyoverflowlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 8:
+
+ { zconfprint("unexpected 'endmenu' statement"); ;}
+ break;
+
+ case 9:
+
+ { zconfprint("unexpected 'endif' statement"); ;}
+ break;
+
+ case 10:
+
+ { zconfprint("unexpected 'endchoice' statement"); ;}
+ break;
+
+ case 11:
+
+ { zconfprint("syntax error"); yyerrok; ;}
+ break;
+
+ case 18:
+
+ {
+ struct symbol *sym = sym_lookup(yyvsp[-1].string, 0);
+ sym->flags |= SYMBOL_OPTIONAL;
+ menu_add_entry(sym);
+ printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
+;}
+ break;
+
+ case 19:
+
+ {
+ menu_end_entry();
+ printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 20:
+
+ {
+ struct symbol *sym = sym_lookup(yyvsp[-1].string, 0);
+ sym->flags |= SYMBOL_OPTIONAL;
+ menu_add_entry(sym);
+ printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
+;}
+ break;
+
+ case 21:
+
+ {
+ if (current_entry->prompt)
+ current_entry->prompt->type = P_MENU;
+ else
+ zconfprint("warning: menuconfig statement without prompt");
+ menu_end_entry();
+ printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 27:
+
+ {
+ menu_set_type(S_TRISTATE);
+ printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 28:
+
+ {
+ menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
+ menu_set_type(S_TRISTATE);
+ printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 29:
+
+ {
+ menu_set_type(S_BOOLEAN);
+ printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 30:
+
+ {
+ menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
+ menu_set_type(S_BOOLEAN);
+ printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 31:
+
+ {
+ menu_set_type(S_INT);
+ printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 32:
+
+ {
+ menu_set_type(S_HEX);
+ printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 33:
+
+ {
+ menu_set_type(S_STRING);
+ printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 34:
+
+ {
+ menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 35:
+
+ {
+ menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 36:
+
+ {
+ menu_add_symbol(P_SELECT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 37:
+
+ {
+ menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,yyvsp[-3].symbol, yyvsp[-2].symbol), yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 38:
+
+ {
+ struct symbol *sym = sym_lookup(NULL, 0);
+ sym->flags |= SYMBOL_CHOICE;
+ menu_add_entry(sym);
+ menu_add_expr(P_CHOICE, NULL, NULL);
+ printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 39:
+
+ {
+ menu_end_entry();
+ menu_add_menu();
+;}
+ break;
+
+ case 40:
+
+ {
+ if (zconf_endtoken(yyvsp[0].token, T_CHOICE, T_ENDCHOICE)) {
+ menu_end_menu();
+ printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
+ }
+;}
+ break;
+
+ case 42:
+
+ {
+ printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
+ zconfnerrs++;
+;}
+ break;
+
+ case 48:
+
+ {
+ menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 49:
+
+ {
+ menu_set_type(S_TRISTATE);
+ printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 50:
+
+ {
+ menu_set_type(S_BOOLEAN);
+ printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 51:
+
+ {
+ current_entry->sym->flags |= SYMBOL_OPTIONAL;
+ printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 52:
+
+ {
+ menu_add_symbol(P_DEFAULT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 55:
+
+ {
+ printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
+ menu_add_entry(NULL);
+ menu_add_dep(yyvsp[-1].expr);
+ menu_end_entry();
+ menu_add_menu();
+;}
+ break;
+
+ case 56:
+
+ {
+ if (zconf_endtoken(yyvsp[0].token, T_IF, T_ENDIF)) {
+ menu_end_menu();
+ printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
+ }
+;}
+ break;
+
+ case 58:
+
+ {
+ printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
+ zconfnerrs++;
+;}
+ break;
+
+ case 63:
+
+ {
+ menu_add_entry(NULL);
+ menu_add_prop(P_MENU, yyvsp[-1].string, NULL, NULL);
+ printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 64:
+
+ {
+ menu_end_entry();
+ menu_add_menu();
+;}
+ break;
+
+ case 65:
+
+ {
+ if (zconf_endtoken(yyvsp[0].token, T_MENU, T_ENDMENU)) {
+ menu_end_menu();
+ printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
+ }
+;}
+ break;
+
+ case 67:
+
+ {
+ printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
+ zconfnerrs++;
+;}
+ break;
+
+ case 72:
+
+ { zconfprint("invalid menu option"); yyerrok; ;}
+ break;
+
+ case 73:
+
+ {
+ yyval.string = yyvsp[-1].string;
+ printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
+;}
+ break;
+
+ case 74:
+
+ {
+ zconf_nextfile(yyvsp[0].string);
+;}
+ break;
+
+ case 75:
+
+ {
+ menu_add_entry(NULL);
+ menu_add_prop(P_COMMENT, yyvsp[-1].string, NULL, NULL);
+ printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 76:
+
+ {
+ menu_end_entry();
+;}
+ break;
+
+ case 77:
+
+ {
+ printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
+ zconf_starthelp();
+;}
+ break;
+
+ case 78:
+
+ {
+ current_entry->sym->help = yyvsp[0].string;
+;}
+ break;
+
+ case 82:
+
+ {
+ menu_add_dep(yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 83:
+
+ {
+ menu_add_dep(yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 84:
+
+ {
+ menu_add_dep(yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 86:
+
+ {
+ menu_add_prop(P_PROMPT, yyvsp[-1].string, NULL, yyvsp[0].expr);
+;}
+ break;
+
+ case 89:
+
+ { yyval.token = T_ENDMENU; ;}
+ break;
+
+ case 90:
+
+ { yyval.token = T_ENDCHOICE; ;}
+ break;
+
+ case 91:
+
+ { yyval.token = T_ENDIF; ;}
+ break;
+
+ case 94:
+
+ { yyval.expr = NULL; ;}
+ break;
+
+ case 95:
+
+ { yyval.expr = yyvsp[0].expr; ;}
+ break;
+
+ case 96:
+
+ { yyval.expr = expr_alloc_symbol(yyvsp[0].symbol); ;}
+ break;
+
+ case 97:
+
+ { yyval.expr = expr_alloc_comp(E_EQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;}
+ break;
+
+ case 98:
+
+ { yyval.expr = expr_alloc_comp(E_UNEQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;}
+ break;
+
+ case 99:
+
+ { yyval.expr = yyvsp[-1].expr; ;}
+ break;
+
+ case 100:
+
+ { yyval.expr = expr_alloc_one(E_NOT, yyvsp[0].expr); ;}
+ break;
+
+ case 101:
+
+ { yyval.expr = expr_alloc_two(E_OR, yyvsp[-2].expr, yyvsp[0].expr); ;}
+ break;
+
+ case 102:
+
+ { yyval.expr = expr_alloc_two(E_AND, yyvsp[-2].expr, yyvsp[0].expr); ;}
+ break;
+
+ case 103:
+
+ { yyval.symbol = sym_lookup(yyvsp[0].string, 0); free(yyvsp[0].string); ;}
+ break;
+
+ case 104:
+
+ { yyval.symbol = sym_lookup(yyvsp[0].string, 1); free(yyvsp[0].string); ;}
+ break;
+
+
+ }
+
+/* Line 999 of yacc.c. */
+
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+
+
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (YYPACT_NINF < yyn && yyn < YYLAST)
+ {
+ YYSIZE_T yysize = 0;
+ int yytype = YYTRANSLATE (yychar);
+ char *yymsg;
+ int yyx, yycount;
+
+ yycount = 0;
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ yysize += yystrlen (yytname[yyx]) + 15, yycount++;
+ yysize += yystrlen ("syntax error, unexpected ") + 1;
+ yysize += yystrlen (yytname[yytype]);
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg != 0)
+ {
+ char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
+ yyp = yystpcpy (yyp, yytname[yytype]);
+
+ if (yycount < 5)
+ {
+ yycount = 0;
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *));
+ yyx++)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ const char *yyq = ! yycount ? ", expecting " : " or ";
+ yyp = yystpcpy (yyp, yyq);
+ yyp = yystpcpy (yyp, yytname[yyx]);
+ yycount++;
+ }
+ }
+ yyerror (yymsg);
+ YYSTACK_FREE (yymsg);
+ }
+ else
+ yyerror ("syntax error; also virtual memory exhausted");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror ("syntax error");
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ {
+ /* Pop the error token. */
+ YYPOPSTACK;
+ /* Pop the rest of the stack. */
+ while (yyss < yyssp)
+ {
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[*yyssp], yyvsp);
+ YYPOPSTACK;
+ }
+ YYABORT;
+ }
+
+ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
+ yydestruct (yytoken, &yylval);
+ yychar = YYEMPTY;
+
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*----------------------------------------------------.
+| yyerrlab1 -- error raised explicitly by an action. |
+`----------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[yystate], yyvsp);
+ yyvsp--;
+ yystate = *--yyssp;
+
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ YYDPRINTF ((stderr, "Shifting error token, "));
+
+ *++yyvsp = yylval;
+
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here. |
+`----------------------------------------------*/
+yyoverflowlab:
+ yyerror ("parser stack overflow");
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ return yyresult;
+}
+
+
+
+
+
+void conf_parse(const char *name)
+{
+ struct symbol *sym;
+ int i;
+
+ zconf_initscan(name);
+
+ sym_init();
+ menu_init();
+ modules_sym = sym_lookup("MODULES", 0);
+ rootmenu.prompt = menu_add_prop(P_MENU, "Buildroot Configuration", NULL, NULL);
+
+ //zconfdebug = 1;
+ zconfparse();
+ if (zconfnerrs)
+ exit(1);
+ menu_finalize(&rootmenu);
+ for_all_symbols(i, sym) {
+ if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
+ printf("\n");
+ else
+ sym->flags |= SYMBOL_CHECK_DONE;
+ }
+
+ sym_change_count = 1;
+}
+
+const char *zconf_tokenname(int token)
+{
+ switch (token) {
+ case T_MENU: return "menu";
+ case T_ENDMENU: return "endmenu";
+ case T_CHOICE: return "choice";
+ case T_ENDCHOICE: return "endchoice";
+ case T_IF: return "if";
+ case T_ENDIF: return "endif";
+ }
+ return "<token>";
+}
+
+static bool zconf_endtoken(int token, int starttoken, int endtoken)
+{
+ if (token != endtoken) {
+ zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
+ zconfnerrs++;
+ return false;
+ }
+ if (current_menu->file != current_file) {
+ zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
+ zconfprint("location of the '%s'", zconf_tokenname(starttoken));
+ zconfnerrs++;
+ return false;
+ }
+ return true;
+}
+
+static void zconfprint(const char *err, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
+ va_start(ap, err);
+ vfprintf(stderr, err, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+}
+
+static void zconferror(const char *err)
+{
+ fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
+}
+
+void print_quoted_string(FILE *out, const char *str)
+{
+ const char *p;
+ int len;
+
+ putc('"', out);
+ while ((p = strchr(str, '"'))) {
+ len = p - str;
+ if (len)
+ fprintf(out, "%.*s", len, str);
+ fputs("\\\"", out);
+ str = p + 1;
+ }
+ fputs(str, out);
+ putc('"', out);
+}
+
+void print_symbol(FILE *out, struct menu *menu)
+{
+ struct symbol *sym = menu->sym;
+ struct property *prop;
+
+ if (sym_is_choice(sym))
+ fprintf(out, "choice\n");
+ else
+ fprintf(out, "config %s\n", sym->name);
+ switch (sym->type) {
+ case S_BOOLEAN:
+ fputs(" boolean\n", out);
+ break;
+ case S_TRISTATE:
+ fputs(" tristate\n", out);
+ break;
+ case S_STRING:
+ fputs(" string\n", out);
+ break;
+ case S_INT:
+ fputs(" integer\n", out);
+ break;
+ case S_HEX:
+ fputs(" hex\n", out);
+ break;
+ default:
+ fputs(" ???\n", out);
+ break;
+ }
+ for (prop = sym->prop; prop; prop = prop->next) {
+ if (prop->menu != menu)
+ continue;
+ switch (prop->type) {
+ case P_PROMPT:
+ fputs(" prompt ", out);
+ print_quoted_string(out, prop->text);
+ if (!expr_is_yes(prop->visible.expr)) {
+ fputs(" if ", out);
+ expr_fprint(prop->visible.expr, out);
+ }
+ fputc('\n', out);
+ break;
+ case P_DEFAULT:
+ fputs( " default ", out);
+ expr_fprint(prop->expr, out);
+ if (!expr_is_yes(prop->visible.expr)) {
+ fputs(" if ", out);
+ expr_fprint(prop->visible.expr, out);
+ }
+ fputc('\n', out);
+ break;
+ case P_CHOICE:
+ fputs(" #choice value\n", out);
+ break;
+ default:
+ fprintf(out, " unknown prop %d!\n", prop->type);
+ break;
+ }
+ }
+ if (sym->help) {
+ int len = strlen(sym->help);
+ while (sym->help[--len] == '\n')
+ sym->help[len] = 0;
+ fprintf(out, " help\n%s\n", sym->help);
+ }
+ fputc('\n', out);
+}
+
+void zconfdump(FILE *out)
+{
+ struct property *prop;
+ struct symbol *sym;
+ struct menu *menu;
+
+ menu = rootmenu.list;
+ while (menu) {
+ if ((sym = menu->sym))
+ print_symbol(out, menu);
+ else if ((prop = menu->prompt)) {
+ switch (prop->type) {
+ case P_COMMENT:
+ fputs("\ncomment ", out);
+ print_quoted_string(out, prop->text);
+ fputs("\n", out);
+ break;
+ case P_MENU:
+ fputs("\nmenu ", out);
+ print_quoted_string(out, prop->text);
+ fputs("\n", out);
+ break;
+ default:
+ ;
+ }
+ if (!expr_is_yes(prop->visible.expr)) {
+ fputs(" depends ", out);
+ expr_fprint(prop->visible.expr, out);
+ fputc('\n', out);
+ }
+ fputs("\n", out);
+ }
+
+ if (menu->list)
+ menu = menu->list;
+ else if (menu->next)
+ menu = menu->next;
+ else while ((menu = menu->parent)) {
+ if (menu->prompt && menu->prompt->type == P_MENU)
+ fputs("\nendmenu\n", out);
+ if (menu->next) {
+ menu = menu->next;
+ break;
+ }
+ }
+ }
+}
+
+#include "lex.zconf.c"
+#include "util.c"
+#include "confdata.c"
+#include "expr.c"
+#include "symbol.c"
+#include "menu.c"
+
+
diff --git a/misc/buildroot/package/config/zconf.tab.h_shipped b/misc/buildroot/package/config/zconf.tab.h_shipped
new file mode 100644
index 000000000..3b191ef59
--- /dev/null
+++ b/misc/buildroot/package/config/zconf.tab.h_shipped
@@ -0,0 +1,125 @@
+/* A Bison parser, made from zconf.y, by GNU bison 1.75. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+#ifndef BISON_ZCONF_TAB_H
+# define BISON_ZCONF_TAB_H
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ T_MAINMENU = 258,
+ T_MENU = 259,
+ T_ENDMENU = 260,
+ T_SOURCE = 261,
+ T_CHOICE = 262,
+ T_ENDCHOICE = 263,
+ T_COMMENT = 264,
+ T_CONFIG = 265,
+ T_HELP = 266,
+ T_HELPTEXT = 267,
+ T_IF = 268,
+ T_ENDIF = 269,
+ T_DEPENDS = 270,
+ T_REQUIRES = 271,
+ T_OPTIONAL = 272,
+ T_PROMPT = 273,
+ T_DEFAULT = 274,
+ T_TRISTATE = 275,
+ T_BOOLEAN = 276,
+ T_INT = 277,
+ T_HEX = 278,
+ T_WORD = 279,
+ T_STRING = 280,
+ T_UNEQUAL = 281,
+ T_EOF = 282,
+ T_EOL = 283,
+ T_CLOSE_PAREN = 284,
+ T_OPEN_PAREN = 285,
+ T_ON = 286,
+ T_OR = 287,
+ T_AND = 288,
+ T_EQUAL = 289,
+ T_NOT = 290
+ };
+#endif
+#define T_MAINMENU 258
+#define T_MENU 259
+#define T_ENDMENU 260
+#define T_SOURCE 261
+#define T_CHOICE 262
+#define T_ENDCHOICE 263
+#define T_COMMENT 264
+#define T_CONFIG 265
+#define T_HELP 266
+#define T_HELPTEXT 267
+#define T_IF 268
+#define T_ENDIF 269
+#define T_DEPENDS 270
+#define T_REQUIRES 271
+#define T_OPTIONAL 272
+#define T_PROMPT 273
+#define T_DEFAULT 274
+#define T_TRISTATE 275
+#define T_BOOLEAN 276
+#define T_INT 277
+#define T_HEX 278
+#define T_WORD 279
+#define T_STRING 280
+#define T_UNEQUAL 281
+#define T_EOF 282
+#define T_EOL 283
+#define T_CLOSE_PAREN 284
+#define T_OPEN_PAREN 285
+#define T_ON 286
+#define T_OR 287
+#define T_AND 288
+#define T_EQUAL 289
+#define T_NOT 290
+
+
+
+
+#ifndef YYSTYPE
+#line 33 "zconf.y"
+typedef union {
+ int token;
+ char *string;
+ struct symbol *symbol;
+ struct expr *expr;
+ struct menu *menu;
+} yystype;
+/* Line 1281 of /usr/share/bison/yacc.c. */
+#line 118 "zconf.tab.h"
+# define YYSTYPE yystype
+#endif
+
+extern YYSTYPE zconflval;
+
+
+#endif /* not BISON_ZCONF_TAB_H */
+
diff --git a/misc/buildroot/package/config/zconf.y b/misc/buildroot/package/config/zconf.y
new file mode 100644
index 000000000..bc9431831
--- /dev/null
+++ b/misc/buildroot/package/config/zconf.y
@@ -0,0 +1,690 @@
+%{
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
+
+#define PRINTD 0x0001
+#define DEBUG_PARSE 0x0002
+
+int cdebug = PRINTD;
+
+extern int zconflex(void);
+static void zconfprint(const char *err, ...);
+static void zconferror(const char *err);
+static bool zconf_endtoken(int token, int starttoken, int endtoken);
+
+struct symbol *symbol_hash[257];
+
+static struct menu *current_menu, *current_entry;
+
+#define YYERROR_VERBOSE
+%}
+%expect 40
+
+%union
+{
+ int token;
+ char *string;
+ struct symbol *symbol;
+ struct expr *expr;
+ struct menu *menu;
+}
+
+%token T_MAINMENU
+%token T_MENU
+%token T_ENDMENU
+%token T_SOURCE
+%token T_CHOICE
+%token T_ENDCHOICE
+%token T_COMMENT
+%token T_CONFIG
+%token T_MENUCONFIG
+%token T_HELP
+%token <string> T_HELPTEXT
+%token T_IF
+%token T_ENDIF
+%token T_DEPENDS
+%token T_REQUIRES
+%token T_OPTIONAL
+%token T_PROMPT
+%token T_DEFAULT
+%token T_TRISTATE
+%token T_DEF_TRISTATE
+%token T_BOOLEAN
+%token T_DEF_BOOLEAN
+%token T_STRING
+%token T_INT
+%token T_HEX
+%token <string> T_WORD
+%token <string> T_WORD_QUOTE
+%token T_UNEQUAL
+%token T_EOF
+%token T_EOL
+%token T_CLOSE_PAREN
+%token T_OPEN_PAREN
+%token T_ON
+%token T_SELECT
+%token T_RANGE
+
+%left T_OR
+%left T_AND
+%left T_EQUAL T_UNEQUAL
+%nonassoc T_NOT
+
+%type <string> prompt
+%type <string> source
+%type <symbol> symbol
+%type <expr> expr
+%type <expr> if_expr
+%type <token> end
+
+%{
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+%}
+%%
+input: /* empty */
+ | input block
+;
+
+block: common_block
+ | choice_stmt
+ | menu_stmt
+ | T_MAINMENU prompt nl_or_eof
+ | T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); }
+ | T_ENDIF { zconfprint("unexpected 'endif' statement"); }
+ | T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); }
+ | error nl_or_eof { zconfprint("syntax error"); yyerrok; }
+;
+
+common_block:
+ if_stmt
+ | comment_stmt
+ | config_stmt
+ | menuconfig_stmt
+ | source_stmt
+ | nl_or_eof
+;
+
+
+/* config/menuconfig entry */
+
+config_entry_start: T_CONFIG T_WORD T_EOL
+{
+ struct symbol *sym = sym_lookup($2, 0);
+ sym->flags |= SYMBOL_OPTIONAL;
+ menu_add_entry(sym);
+ printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
+};
+
+config_stmt: config_entry_start config_option_list
+{
+ menu_end_entry();
+ printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
+};
+
+menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
+{
+ struct symbol *sym = sym_lookup($2, 0);
+ sym->flags |= SYMBOL_OPTIONAL;
+ menu_add_entry(sym);
+ printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
+};
+
+menuconfig_stmt: menuconfig_entry_start config_option_list
+{
+ if (current_entry->prompt)
+ current_entry->prompt->type = P_MENU;
+ else
+ zconfprint("warning: menuconfig statement without prompt");
+ menu_end_entry();
+ printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
+};
+
+config_option_list:
+ /* empty */
+ | config_option_list config_option
+ | config_option_list depends
+ | config_option_list help
+ | config_option_list T_EOL
+;
+
+config_option: T_TRISTATE prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_TRISTATE);
+ printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_DEF_TRISTATE expr if_expr T_EOL
+{
+ menu_add_expr(P_DEFAULT, $2, $3);
+ menu_set_type(S_TRISTATE);
+ printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_BOOLEAN prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_BOOLEAN);
+ printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_DEF_BOOLEAN expr if_expr T_EOL
+{
+ menu_add_expr(P_DEFAULT, $2, $3);
+ menu_set_type(S_BOOLEAN);
+ printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_INT prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_INT);
+ printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_HEX prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_HEX);
+ printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_STRING prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_STRING);
+ printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_PROMPT prompt if_expr T_EOL
+{
+ menu_add_prompt(P_PROMPT, $2, $3);
+ printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_DEFAULT expr if_expr T_EOL
+{
+ menu_add_expr(P_DEFAULT, $2, $3);
+ printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_SELECT T_WORD if_expr T_EOL
+{
+ menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
+ printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_RANGE symbol symbol if_expr T_EOL
+{
+ menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
+ printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
+};
+
+/* choice entry */
+
+choice: T_CHOICE T_EOL
+{
+ struct symbol *sym = sym_lookup(NULL, 0);
+ sym->flags |= SYMBOL_CHOICE;
+ menu_add_entry(sym);
+ menu_add_expr(P_CHOICE, NULL, NULL);
+ printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
+};
+
+choice_entry: choice choice_option_list
+{
+ menu_end_entry();
+ menu_add_menu();
+};
+
+choice_end: end
+{
+ if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
+ menu_end_menu();
+ printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
+ }
+};
+
+choice_stmt:
+ choice_entry choice_block choice_end
+ | choice_entry choice_block
+{
+ printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
+ zconfnerrs++;
+};
+
+choice_option_list:
+ /* empty */
+ | choice_option_list choice_option
+ | choice_option_list depends
+ | choice_option_list help
+ | choice_option_list T_EOL
+;
+
+choice_option: T_PROMPT prompt if_expr T_EOL
+{
+ menu_add_prompt(P_PROMPT, $2, $3);
+ printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
+};
+
+choice_option: T_TRISTATE prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_TRISTATE);
+ printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
+};
+
+choice_option: T_BOOLEAN prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_BOOLEAN);
+ printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
+};
+
+choice_option: T_OPTIONAL T_EOL
+{
+ current_entry->sym->flags |= SYMBOL_OPTIONAL;
+ printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
+};
+
+choice_option: T_DEFAULT T_WORD if_expr T_EOL
+{
+ menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
+ printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
+};
+
+choice_block:
+ /* empty */
+ | choice_block common_block
+;
+
+/* if entry */
+
+if: T_IF expr T_EOL
+{
+ printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
+ menu_add_entry(NULL);
+ menu_add_dep($2);
+ menu_end_entry();
+ menu_add_menu();
+};
+
+if_end: end
+{
+ if (zconf_endtoken($1, T_IF, T_ENDIF)) {
+ menu_end_menu();
+ printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
+ }
+};
+
+if_stmt:
+ if if_block if_end
+ | if if_block
+{
+ printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
+ zconfnerrs++;
+};
+
+if_block:
+ /* empty */
+ | if_block common_block
+ | if_block menu_stmt
+ | if_block choice_stmt
+;
+
+/* menu entry */
+
+menu: T_MENU prompt T_EOL
+{
+ menu_add_entry(NULL);
+ menu_add_prop(P_MENU, $2, NULL, NULL);
+ printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
+};
+
+menu_entry: menu depends_list
+{
+ menu_end_entry();
+ menu_add_menu();
+};
+
+menu_end: end
+{
+ if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
+ menu_end_menu();
+ printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
+ }
+};
+
+menu_stmt:
+ menu_entry menu_block menu_end
+ | menu_entry menu_block
+{
+ printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
+ zconfnerrs++;
+};
+
+menu_block:
+ /* empty */
+ | menu_block common_block
+ | menu_block menu_stmt
+ | menu_block choice_stmt
+ | menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
+;
+
+source: T_SOURCE prompt T_EOL
+{
+ $$ = $2;
+ printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
+};
+
+source_stmt: source
+{
+ zconf_nextfile($1);
+};
+
+/* comment entry */
+
+comment: T_COMMENT prompt T_EOL
+{
+ menu_add_entry(NULL);
+ menu_add_prop(P_COMMENT, $2, NULL, NULL);
+ printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
+};
+
+comment_stmt: comment depends_list
+{
+ menu_end_entry();
+};
+
+/* help option */
+
+help_start: T_HELP T_EOL
+{
+ printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
+ zconf_starthelp();
+};
+
+help: help_start T_HELPTEXT
+{
+ current_entry->sym->help = $2;
+};
+
+/* depends option */
+
+depends_list: /* empty */
+ | depends_list depends
+ | depends_list T_EOL
+;
+
+depends: T_DEPENDS T_ON expr T_EOL
+{
+ menu_add_dep($3);
+ printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
+}
+ | T_DEPENDS expr T_EOL
+{
+ menu_add_dep($2);
+ printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
+}
+ | T_REQUIRES expr T_EOL
+{
+ menu_add_dep($2);
+ printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
+};
+
+/* prompt statement */
+
+prompt_stmt_opt:
+ /* empty */
+ | prompt if_expr
+{
+ menu_add_prop(P_PROMPT, $1, NULL, $2);
+};
+
+prompt: T_WORD
+ | T_WORD_QUOTE
+;
+
+end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; }
+ | T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; }
+ | T_ENDIF nl_or_eof { $$ = T_ENDIF; }
+;
+
+nl_or_eof:
+ T_EOL | T_EOF;
+
+if_expr: /* empty */ { $$ = NULL; }
+ | T_IF expr { $$ = $2; }
+;
+
+expr: symbol { $$ = expr_alloc_symbol($1); }
+ | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
+ | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
+ | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; }
+ | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); }
+ | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); }
+ | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
+;
+
+symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }
+ | T_WORD_QUOTE { $$ = sym_lookup($1, 1); free($1); }
+;
+
+%%
+
+void conf_parse(const char *name)
+{
+ struct symbol *sym;
+ int i;
+
+ zconf_initscan(name);
+
+ sym_init();
+ menu_init();
+ modules_sym = sym_lookup("MODULES", 0);
+ rootmenu.prompt = menu_add_prop(P_MENU, "Buildroot Configuration", NULL, NULL);
+
+ //zconfdebug = 1;
+ zconfparse();
+ if (zconfnerrs)
+ exit(1);
+ menu_finalize(&rootmenu);
+ for_all_symbols(i, sym) {
+ if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
+ printf("\n");
+ else
+ sym->flags |= SYMBOL_CHECK_DONE;
+ }
+
+ sym_change_count = 1;
+}
+
+const char *zconf_tokenname(int token)
+{
+ switch (token) {
+ case T_MENU: return "menu";
+ case T_ENDMENU: return "endmenu";
+ case T_CHOICE: return "choice";
+ case T_ENDCHOICE: return "endchoice";
+ case T_IF: return "if";
+ case T_ENDIF: return "endif";
+ }
+ return "<token>";
+}
+
+static bool zconf_endtoken(int token, int starttoken, int endtoken)
+{
+ if (token != endtoken) {
+ zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
+ zconfnerrs++;
+ return false;
+ }
+ if (current_menu->file != current_file) {
+ zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
+ zconfprint("location of the '%s'", zconf_tokenname(starttoken));
+ zconfnerrs++;
+ return false;
+ }
+ return true;
+}
+
+static void zconfprint(const char *err, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
+ va_start(ap, err);
+ vfprintf(stderr, err, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+}
+
+static void zconferror(const char *err)
+{
+ fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
+}
+
+void print_quoted_string(FILE *out, const char *str)
+{
+ const char *p;
+ int len;
+
+ putc('"', out);
+ while ((p = strchr(str, '"'))) {
+ len = p - str;
+ if (len)
+ fprintf(out, "%.*s", len, str);
+ fputs("\\\"", out);
+ str = p + 1;
+ }
+ fputs(str, out);
+ putc('"', out);
+}
+
+void print_symbol(FILE *out, struct menu *menu)
+{
+ struct symbol *sym = menu->sym;
+ struct property *prop;
+
+ if (sym_is_choice(sym))
+ fprintf(out, "choice\n");
+ else
+ fprintf(out, "config %s\n", sym->name);
+ switch (sym->type) {
+ case S_BOOLEAN:
+ fputs(" boolean\n", out);
+ break;
+ case S_TRISTATE:
+ fputs(" tristate\n", out);
+ break;
+ case S_STRING:
+ fputs(" string\n", out);
+ break;
+ case S_INT:
+ fputs(" integer\n", out);
+ break;
+ case S_HEX:
+ fputs(" hex\n", out);
+ break;
+ default:
+ fputs(" ???\n", out);
+ break;
+ }
+ for (prop = sym->prop; prop; prop = prop->next) {
+ if (prop->menu != menu)
+ continue;
+ switch (prop->type) {
+ case P_PROMPT:
+ fputs(" prompt ", out);
+ print_quoted_string(out, prop->text);
+ if (!expr_is_yes(prop->visible.expr)) {
+ fputs(" if ", out);
+ expr_fprint(prop->visible.expr, out);
+ }
+ fputc('\n', out);
+ break;
+ case P_DEFAULT:
+ fputs( " default ", out);
+ expr_fprint(prop->expr, out);
+ if (!expr_is_yes(prop->visible.expr)) {
+ fputs(" if ", out);
+ expr_fprint(prop->visible.expr, out);
+ }
+ fputc('\n', out);
+ break;
+ case P_CHOICE:
+ fputs(" #choice value\n", out);
+ break;
+ default:
+ fprintf(out, " unknown prop %d!\n", prop->type);
+ break;
+ }
+ }
+ if (sym->help) {
+ int len = strlen(sym->help);
+ while (sym->help[--len] == '\n')
+ sym->help[len] = 0;
+ fprintf(out, " help\n%s\n", sym->help);
+ }
+ fputc('\n', out);
+}
+
+void zconfdump(FILE *out)
+{
+ struct property *prop;
+ struct symbol *sym;
+ struct menu *menu;
+
+ menu = rootmenu.list;
+ while (menu) {
+ if ((sym = menu->sym))
+ print_symbol(out, menu);
+ else if ((prop = menu->prompt)) {
+ switch (prop->type) {
+ case P_COMMENT:
+ fputs("\ncomment ", out);
+ print_quoted_string(out, prop->text);
+ fputs("\n", out);
+ break;
+ case P_MENU:
+ fputs("\nmenu ", out);
+ print_quoted_string(out, prop->text);
+ fputs("\n", out);
+ break;
+ default:
+ ;
+ }
+ if (!expr_is_yes(prop->visible.expr)) {
+ fputs(" depends ", out);
+ expr_fprint(prop->visible.expr, out);
+ fputc('\n', out);
+ }
+ fputs("\n", out);
+ }
+
+ if (menu->list)
+ menu = menu->list;
+ else if (menu->next)
+ menu = menu->next;
+ else while ((menu = menu->parent)) {
+ if (menu->prompt && menu->prompt->type == P_MENU)
+ fputs("\nendmenu\n", out);
+ if (menu->next) {
+ menu = menu->next;
+ break;
+ }
+ }
+ }
+}
+
+#include "lex.zconf.c"
+#include "util.c"
+#include "confdata.c"
+#include "expr.c"
+#include "symbol.c"
+#include "menu.c"
diff --git a/misc/buildroot/package/gnuconfig/ChangeLog b/misc/buildroot/package/gnuconfig/ChangeLog
new file mode 100644
index 000000000..b615b748b
--- /dev/null
+++ b/misc/buildroot/package/gnuconfig/ChangeLog
@@ -0,0 +1,1813 @@
+2006-02-27 David S. Miller <davem@sunset.davemloft.net>
+ Ben Elliston <bje@gnu.org>
+
+ * config.sub (sparcv9v, sparc64v): Recognise SUN4V-based SPARCs.
+ * testsuite/config-sub.data: Add test cases.
+
+2006-02-27 Ben Elliston <bje@gnu.org>
+
+ * config.guess, config.sub: Add 2006 to copyright years.
+
+2006-02-23 Ben Elliston <bje@gnu.org>
+
+ * config.guess (EM64T:Interix:*:*): New case.
+ * testsuite/config-guess.data: Add test case.
+
+2006-02-23 Mike Frysinger <vapier@gentoo.org>
+
+ * config.sub (nios, nios2): New.
+ * testsuite/config-sub.data: Add test cases.
+
+2006-02-23 Ben Elliston <bje@gnu.org>
+
+ * config.guess (x86:Interix*:[345]*): Retain full Interix version.
+ * testsuite/config-guess.data: Update Interix test(s).
+
+2006-02-23 Ben Elliston <bje@gnu.org>
+
+ * testsuite/config-guess.data: Tweak MSYS_NT-5.1 test.
+
+2006-02-23 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * config.guess (i*86:Linux:*:*): Recognise the Sun Studio compiler
+ by handling #if defined(__sun).
+
+2006-02-23 Ben Elliston <bje@gnu.org>
+
+ * config.guess: Handle i*:MSYS_NT-*:*:* for MSYS/Mingw.
+ * testsuite/config-guess.data: Add test case.
+
+2006-01-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * config.guess: Don't use semicolons to separate sed commands, as
+ POSIX says it's not portable.
+ Noted by Paul Eggert <eggert@cs.ucla.edu>.
+
+2006-01-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * config.guess (set_cc_for_build): Do not pass `-q' to mktemp.
+ Reported by Bruce Korb <bkorb@gnu.org>.
+
+2006-01-19 Robert Millan <robertmh@gnu.org>
+
+ * testsuite/config-guess.data: Add test case for GNU/kFreeBSD.
+ * testsuite/config-sub.data: Add test case for amd64-kfreebsd5.4-gnu.
+
+2006-01-02 Ben Elliston <bje@gnu.org>
+
+ * config.guess (*:SolidBSD:*:*): New.
+ * config.sub (-solidbsd*): New.
+ * testsuite/config-guess.data: Add test case.
+ * testsuite/config-sub.data: Ditto.
+
+2005-12-23 Ben Elliston <bje@gnu.org>
+
+ From Takahashi Yoshihiro <nyan@jp.FreeBSD.org>:
+ * config.guess (pc98:FreeBSD:*:*) Add special case.
+ * config.sub (pc98, pc98-*): New.
+ * testsuite/config-guess.data: Add test case.
+ * testsuite/config-sub.data: Ditto.
+
+2005-12-22 Ben Elliston <bje@gnu.org>
+
+ From John Williams <jwilliams@itee.uq.edu.au>:
+ * config.sub (mb, microblaze): New basic_machine.
+ * testsuite/config-sub.data: New tests.
+
+2005-12-13 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * config.guess (mips:Linux:*:*, mips64:Linux:*:*, i*86:Linux:*:*):
+ Fix quoting of eval command line, allow for preprocessor to insert
+ white space between C tokens.
+ (i*86:Linux:*:*): Handle Portland Group pgcc like Intel icc; it
+ doesn't define __ELF__ either.
+
+2005-12-11 Ben Elliston <bje@gnu.org>
+
+ From Shaun Jackman <sjackman@gmail.com>:
+ * config.sub: Add the KERNEL-OS combination linux-newlib*.
+ * testsuite/config-sub.data: Add a test for i386-linux-newlib.
+
+2005-12-11 Ben Elliston <bje@gnu.org>
+
+ Reported by Leif Ekblad <leif@rdos.net>:
+ * config.guess (i*86:rdos:*:*): New.
+ * config.sub: Handle rdos.
+ * testsuite/config-guess.data: Add test case for RDOS.
+ * testsuite/config-sub.data: Likewise.
+
+2005-12-09 Ben Elliston <bje@gnu.org>
+
+ Reported by Jan-Benedict Glaw <jbglaw@lug-owl.de>:
+ * config.guess (vax:Linux:*:): Detect as vax-dec-linux-gnu.
+ * testsuite/config-guess.data: Add test.
+
+2005-12-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * config.sub (mt): Rename from ms1.
+ (ms1): Alias it to mt for backward compatibility.
+ * testsuite/config-sub.data: Update testsuite.
+
+2005-11-13 Kean Johnston <jkj@sco.com>
+
+ * config.sub: Allow -sco6 and -sco5v6 to be aliases for SCO
+ OpenServer 6.
+ * testsuite/config-sub.data: New tests.
+
+2005-11-11 Ben Elliston <bje@gnu.org>
+
+ * testsuite/config-guess.data: Add test case for Linux PPC64.
+
+2005-11-11 Ben Elliston <bje@gnu.org>
+
+ * config.guess (x86:Interix*:[345]*): Handle Interix version 5.
+ * testsuite/config-guess.data: Add test case.
+
+2005-09-19 Gerben Wierda <Gerben.Wierda@rna.nl>
+
+ * config.guess (*:Darwin:*:*): Don't treat *86 specifically.
+
+2005-08-03 Ben Elliston <bje@gnu.org>
+
+ Reported by Kulkin Alexey <kulkin@yandex.ru>:
+ * config.guess (x86_64:CYGWIN*:*:*): New case.
+ * testsuite/config-guess.data: Add test case.
+
+2005-07-14 Robert Millan <robertmh@gnu.org>
+
+ * config.guess (or32:Linux:*:*): Detect.
+ * testsuite/config-guess.data: Add test case.
+
+2005-07-08 Michael Haubenwallner <michael.haubenwallner@salomon.at>
+
+ * config.guess: Let set_cc_for_build evaluate only once to avoid
+ creation of more than one tmpdir without removing the old one.
+
+2005-07-08 Ben Elliston <bje@gnu.org>
+
+ * config.sub: Add support for Haiku.
+ * testsuite/config-sub.data: Add test cases for i386, SPARC and
+ PowerPC Haiku.
+
+2005-07-08 Ben Elliston <bje@gnu.org>
+
+ * Makefile (SHELL): Remove override.
+
+2005-07-04 Ben Elliston <bje@gnu.org>
+ Paul Mundt <lethal@linux-sh.org>
+
+ * config.sub: Handle sh2a/sh4a.
+ * testsuite/config-sub.data: Add test cases.
+
+2005-07-01 Robert Millan <robertmh@gnu.org>
+
+ * config.sub: Deprecate "openrisc" in favour of "or32".
+ Do not default the OS field to "coff".
+ * testsuite/config-sub.data: Add a test case.
+
+2005-06-30 Ben Elliston <bje@gnu.org>
+
+ * config.sub (sh64): Remove duplicate entry.
+ * testsuite/config-sub.data: Add test case for sh64.
+
+2005-06-30 Mike Frysinger <vapier@gentoo.org>
+
+ * config.sub (mips64vr5900, mips64vr5900el): New machines.
+ * testsuite/config-sub.data: Add test cases.
+
+2005-06-30 Brad Smith <brad@comstyle.com>
+
+ * config.guess: Simplify OpenBSD support.
+
+2005-06-02 Aldy Hernandez <aldyh@redhat.com>
+
+ * config.sub (ms1, ms1-*): New.
+ * testsuite/config-sub.data: Add test cases.
+
+2005-06-02 Jim Blandy <jimb@redhat.com>
+
+ * config.sub (m32c, m32c-*): New.
+ * testsuite/config-sub.data: Add test cases.
+
+2005-05-27 Ben Elliston <bje@gnu.org>
+
+ * config.guess (i*:windows32*:*): uname -m includes "-pc", so no
+ need to emit it additionally.
+ * testsuite/config-guess.data: Update test case.
+
+2005-05-15 Ben Elliston <bje@gnu.org>
+
+ Reported by Sam Steingold <sds@gnu.org>:
+ * config.guess (i*:windows32*:*): New.
+ * testsuite/config-guess.data: Add a corresponding test case.
+
+2005-05-15 Paul Eggert <eggert@cs.ucla.edu>
+
+ * config.guess: Fix remaining problematic uses of "exit 0" (and
+ one problematic use of "&& exit").
+
+2005-05-12 Ben Elliston <bje@gnu.org>
+
+ * config.guess: Update Free Software Foundation address.
+ * config.sub: Likewise.
+
+2005-05-12 Ben Elliston <bje@gnu.org>
+
+ * uname: Similar to the last change, remove all exit commands and
+ let the script exit with the exit code of the last command.
+
+2005-05-12 Paul Eggert <eggert@CS.UCLA.EDU>
+
+ Explanation for this subtle change:
+
+ From: Paul Eggert <eggert@CS.UCLA.EDU>
+ To: config-patches@gnu.org
+ Subject: config.guess, config.sub misdiagnose write errors
+
+ config.guess and config.sub sometimes mishandle write errors to
+ stdout: they either ignore the errors, or output invalid
+ diagnostics when they occur. For a simple (albeit unrealistic)
+ example, on my Solaris 8 (sparc) host, the command "config.guess
+ >&-" exits with status 0; it should exit with status 1, due to the
+ write failure.
+
+ * config.guess: Don't exit with an explicit exit code of 0.
+ * config.sub: Likewise.
+
+2005-05-12 Ben Elliston <bje@gnu.org>
+
+ * config.guess (i*86:skyos:*:*): New.
+ * config.sub (case $os): Handle "-skyos*" as a valid OS.
+ * testsuite/config-guess.data: Add a test case.
+ * testsuite/config-sub.data: Likewise.
+
+2005-05-12 Tim Rice <tim@multitalents.net>
+
+ * config.guess: Add support for SCO OpenServer 6.
+
+2005-05-12 Noah Misch <noah@cs.caltech.edu>
+
+ * config.guess (9000/[34678]??:HP-UX:*:*): Discard stderr of `cc
+ -E -'; HP `cc' emits an error for it but still preprocesses
+ standard input as expected. Add comment.
+
+2005-05-12 Nick Burrett <nick@sqrt.co.uk>
+ Ben Elliston <bje@gnu.org>
+
+ * config.guess (arm:riscos:*:*): New configuration.
+ * testsuite/config-sub.data: New tests.
+ * testsuite/config-guess.data: Likewise.
+
+2005-05-12 Nick Burrett <nick@sqrt.co.uk>
+
+ * config.guess: Add a missing newline to arm-acorn-riscix string.
+
+2005-04-22 Paul Green <Paul.Green@stratus.com>
+ Ben Elliston <bje@gnu.org>
+
+ * config.guess: Add Stratus VOS IA32 systems.
+ * testsuite/config-guess.data: Add a testcase.
+
+2005-04-22 Ben Elliston <bje@gnu.org>
+ Bernd Schmidt <bernds_cb1@t-online.de>
+
+ * config.sub (bfin): New target.
+ * testsuite/config-sub.data: Test bfin-elf.
+
+2005-04-22 Ben Elliston <bje@gnu.org>
+ Dave Miller <davem@davemloft.net>
+
+ * config.sub (sparc64b): Handle.
+ * testsuite/config-sub.data: Test sparc64-linux, sparc64b-linux.
+
+2005-03-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ * config.guess: Update URL for script location.
+ Problem reported by Bruno Haible.
+
+2005-02-10 Ben Elliston <bje@gnu.org>
+ J Shepherd <jashepherd@usa.net>
+
+ * config.guess (NSE-?:NONSTOP_KERNEL:*:*): New.
+ * testsuite/config-guess.data: Test for nse-tandem-nsk.
+
+2005-02-10 Ben Elliston <bje@gnu.org>
+
+ * testsuite/config-guess.data: Add craynv-cray-unicosmp2.5.X case.
+
+2005-02-10 Ben Elliston <bje@gnu.org>
+
+ * testsuite/config-sub.sh (run_config_sub): New function. Compute
+ $rc within the function and return it.
+ * testsuite/config-guess.sh (run_config_guess): Likewise.
+
+2005-02-10 Ben Elliston <bje@gnu.org>
+
+ * config.guess (amd64:CYGWIN*:*:*): New.
+ * testsuite/config-sub.data: Add amd64-cygwin, x86_64-cygwin.
+ * testsuite/config-guess.data: Add x86_64-unknown-cygwin test.
+
+2005-02-10 Ben Elliston <bje@gnu.org>
+
+ * config.guess: Update copyright years.
+ * config.sub: Likewise.
+
+2005-01-11 Inderpreet Singh <inderpreetb@noida.hcltech.com>
+ Ben Elliston <bje@gnu.org>
+
+ * config.sub: Handle maxq target.
+ * testsuite/config-sub.data: Add maxq and maxq-elf tests.
+
+2004-11-30 Melissa Mears <asterisk@graces.dricas.com>
+
+ * config.sub: Handle xbox alias.
+ * testsuite/config-sub.data: Add xbox case.
+
+2004-11-17 Ian Lance Taylor <ian@wasabisystems.com>
+ Ben Elliston <bje@gnu.org>
+
+ * config.sub: Recognize xscalee[bl].
+ * testsuite/config-sub.data: Add xscale, xscalee[bl] cases.
+
+2004-11-12 Ben Elliston <bje@gnu.org>
+
+ * config.guess (*:z/VM:*:*): Add new case.
+ * config.sub (os): Add case for -zvmoe.
+ * testsuite/config-guess.data: Add a test case.
+ * testsuite/config-sub.data: Likewise.
+
+2004-11-12 Ben Elliston <bje@gnu.org>
+
+ * testsuite/config-guess.sh: Use , and not / as the sed delimiter.
+
+2004-11-12 Andris Pavenis <pavenis@latnet.lv>
+
+ * config.sub (djgpp): Alias to i586-pc-msdosdjgpp.
+ * testsuite/config-sub.data: Add a test case.
+
+2004-10-25 Ben Elliston <bje@gnu.org>
+
+ * testsuite/config-guess.sh: Reduce recurring tabs into a single
+ tab, to allow the test data to be better aligned in columns.
+
+2004-10-25 Ben Elliston <bje@gnu.org>
+
+ Reported by Monty Solomon <monty@roscom.com>:
+ * config.guess (*:XENIX:*:SysV): New.
+ * testsuite/config-guess.data: Add a test case.
+
+2004-10-25 Ben Elliston <bje@gnu.org>
+
+ Reported by Martin Hammer <martin.hammer@siemens.com>:
+ * config.guess (DRS?6000:isis:4.2*:7*): New pattern.
+
+2004-09-07 Ben Elliston <bje@gnu.org>
+
+ * config.guess (frv:Linux:*:*): New.
+ * testsuite/config-sub.data: Add cris-linux, frv-linux.
+ * testsuite/config-guess.data: Add frv-linux-unknown-gnu case.
+
+2004-08-27 Hans-Peter Nilsson <hp@axis.com>
+
+ * config.sub: Handle crisv32, alias etraxfs.
+ * config.guess (crisv32:Linux:*:*): Handle.
+ * testsuite/config-sub.data: Add test case.
+ * testsuite/config-guess.data: Likewise.
+
+2004-08-22 Ben Elliston <bje@gnu.org>
+
+ * Makefile (check): Run config-guess.sh tests as well.
+ * testsuite/config-guess.sh: New test.
+ * testsuite/config-guess.data: New file.
+ * testsuite/uname.in: Likewise.
+ * testsuite/config-sub.data (amd64-unknown-freebsd5.2): New case.
+
+2004-08-13 Brad Smith <brad@comstyle.com>
+
+ * config.guess (*:OpenBSD:*:*): Remove defunct MIPS machines.
+ (sgi:OpenBSD:*:*): Emit mips64, not mipseb.
+
+2004-08-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ * config.guess (*:Darwin:*:*): If uname -p reports "unknown",
+ assume the processor is a powerpc. This is because coreutils
+ uname (at least versions 4.5.7 through 5.2.1) outputs "unknown"
+ in this case, due to a MacOS X bug that causes
+ sysctl ((int[]) {CTL_HW, HW_MACHINE_ARCH}, 2, buffer, &bufsize, 0, 0)
+ to return a negative number.
+ Problem reported by Petter Reinholdtsen in:
+ http://lists.gnu.org/archive/html/bug-gnu-utils/2003-02/msg00201.html
+
+2004-07-19 Ben Elliston <bje@gnu.org>
+
+ * config.guess (S7501:*:4.0:3.0): Handle NCR System V UNIX machine.
+
+2004-07-02 Ben Elliston <bje@gnu.org>
+
+ * testsuite/config-sub.data: Add i386-elf to i786-elf.
+
+2004-06-30 Ben Elliston <bje@gnu.org>
+
+ * testsuite/config-sub.data: Add more new tests.
+
+2004-06-25 Ben Elliston <bje@gnu.org>
+
+ * Makefile (check): New target.
+ * testsuite/config-sub.sh: New test.
+ * testsuite/config-sub.data: New file.
+
+2004-06-24 Ben Elliston <bje@gnu.org>
+
+ * config.guess: Update copyright years.
+ * config.sub: Likewise.
+
+2004-06-22 Robert Millan <robertmh@gnu.org>
+
+ * config.guess (*:FreeBSD:*:*): Remove check for glibc (unneeded
+ since GNU/kFreeBSD systems match *:GNU/*:*:* instead).
+
+2004-06-22 Stanley F. Quayle <stan@stanq.com>
+
+ * config.guess (*:*VMS:*:*): New entry. Replaces
+ Alpha:OpenVMS:*. Recognize and advertise all VMS flavors as dec
+ manufacturer.
+
+2004-06-22 Ben Elliston <bje@gnu.org>
+
+ * config.guess: Cray fixes from Wendy Palm <wendyp@cray.com>.
+ * config.sub: Likewise.
+
+2004-06-22 Ben Elliston <bje@gnu.org>
+
+ Reported by Hans-Peter Nilsson <hp@bitrange.com>:
+ * config.sub: Correctly handle mmix-knuth and mmix-knuth-mmixware.
+
+2004-06-21 Ben Elliston <bje@gnu.org>
+
+ * Makefile: New file.
+
+2004-06-11 Ben Elliston <bje@gnu.org>
+
+ * config.guess (pegasos:OpenBSD:*:*): Remove.
+
+2004-06-11 Ben Elliston <bje@gnu.org>
+
+ From Wouter Verhelst <wouter@grep.be>:
+ * config.guess (M68*:*:R3V[5678]:*): Detect R3V8.
+
+2004-06-11 Ben Elliston <bje@gnu.org>
+
+ * config.guess (luna88k:OpenBSD:*:*): New.
+
+2004-03-12 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config.guess (m32r*:Linux:*:*): New case.
+ * config.sub: Handle m32rle.
+
+2004-03-12 Ben Elliston <bje@wasabisystems.com>
+
+ From Jens Petersen <petersen@redhat.com>:
+ * config.sub: Handle sparcv8.
+
+2004-03-03 Ben Elliston <bje@wasabisystems.com>
+
+ From Tom Smith <smith@cag.lkg.hp.com>:
+ * config.guess: Version suffixes are equally significant on Tru64
+ V4.* and V5.*, so do not ignore them on V5.*. Handle a version
+ prefix of "P" (patched kernel).
+
+2004-02-23 Tal Agmon <Tal.Agmon@nsc.com>
+
+ * config.sub: Add support for National Semiconductor CRX target.
+
+2004-02-16 Thorsten Glaser <x86@ePost.de>
+
+ * config.guess (*:MirBSD:*:*, macppc:MirBSD:*:*): Handle.
+ * config.sub: Handle -mirbsd*.
+
+2004-02-16 Brad Smith <brad@comstyle.com>
+
+ * config.guess: Recognize OpenBSD on AMD64 and CATS hardware.
+
+2004-02-11 Ben Elliston <bje@wasabisystems.com>
+
+ * config.sub (abacus): Add.
+
+2004-02-11 Galit Heller <Galit.Heller@nsc.com>
+
+ * config.sub: Add support for National Semiconductor CR16C target.
+
+2004-02-02 Ben Elliston <bje@wasabisystems.com>
+
+ * config.guess (*:ekkoBSD:*:*): Handle.
+ * config.guess: Handle -ekkobsd*.
+
+2004-01-30 Ben Elliston <bje@wasabisystems.com>
+
+ * NEWS: Remove.
+
+2004-01-24 Ben Elliston <bje@wasabisystems.com>
+
+ From Brett E. Wynkoop <wynkoop@wynn.com>:
+ * config.guess (m68k:machten:*:*): Handle.
+
+2004-01-20 Jeroen Ruigrok van der Werven <asmodai@dragonflybsd.org>
+
+ * config.guess: Fix DragonFly entry to really work.
+
+2004-01-05 Ben Elliston <bje@wasabisystems.com>
+ Joachim Schmitz <schmitz@hp.com>
+
+ * config.guess: Handle NSR-? to accept any CPU type.
+
+2004-01-05 Ben Elliston <bje@wasabisystems.com>
+
+ * config.sub: Handle amd64-*.
+
+2003-11-20 Kristian Van Der Vliet <vanders@liqwyd.com>
+
+ * config.guess (i*86:syllable:*:*): New.
+ * config.sub (-syllable*): Likewise.
+
+2003-11-18 Jeroen Ruigrok van der Werven <asmodai@dragonflybsd.org>
+
+ * config.guess (*:DRAGONFLY:*:*): New.
+ * config.sub (-dragonfly*): Likewise.
+
+2003-11-03 Ben Elliston <bje@wasabisystems.com>
+
+ * config.guess: Detect OpenBSD on Pegasos I hardware.
+
+2003-11-03 Jim Tison <jtison@us.ibm.com>
+ Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config.sub (tpf, -tpf*): Recognize.
+
+2003-10-16 Ben Elliston <bje@wasabisystems.com>
+
+ * config.guess (5000:UNIX_System_V:4.*:*): Detect the Fujitsu
+ VPP5000. Reported by Naoki Yoshida <naoki@th.nao.ac.jp>.
+
+2003-10-16 Bernardo Innocenti <bernie@develer.com>
+
+ * config.sub (linux-uclibc, uclinux-uclibc): Handle.
+
+2003-10-16 Ben Elliston <bje@wasabisystems.com>
+
+ Reported by Todd Humphrey <thump@isl.net>:
+ * config.guess (*:OS400:*:*): Detect OS/400 on AS/400 machines.
+ * config.sub (os400, -os400*): Recognise.
+
+2003-10-07 Robert Millan <robertmh@gnu.org>
+ Ben Elliston <bje@wasabisystems.com>
+
+ * config.guess (*:GNU/*:*:*): New. Generic check for systems with
+ GNU libc and userland (matches GNU/KFreeBSD and GNU/KNetBSD).
+ (*:GNU/FreeBSD:*:*): Remove, superceeded by GNU/*.
+ * config.sub: Handle -knetbsd*.
+
+2003-10-07 Ben Elliston <bje@wasabisystems.com>
+
+ * config.guess (3[345]??:*:4.0:3.0): Expand pattern to match 3526.
+
+2003-10-03 Chris Demetriou <cgd@broadcom.com>
+
+ * config.sub (mipsisa64r2*): Add.
+
+2003-10-03 Ben Elliston <bje@wasabisystems.com>
+ Joachim Schmitz <schmitz@hp.com>
+
+ * config.guess (NSR-*:NONSTOP_KERNEL:*:*): Recognise NSR-Y.
+
+2003-08-18 Andreas Krennmair <krennmair@lizenzfrei.at>
+
+ * config.guess: Add detection for diet libc.
+ * config.sub: Handle linux-dietlibc.
+
+2003-07-29 Ben Elliston <bje@wasabisystems.com>
+
+ * NEWS: New draft file.
+
+2003-07-17 Ben Elliston <bje@wasabisystems.com>
+
+ Reported as missing by Doug Evans:
+ * config.sub: Handle iq2000 and iq2000-*.
+
+2003-07-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * config.sub: Add am33_2.0 machine.
+
+2003-07-04 Ben Elliston <bje@wasabisystems.com>
+
+ * config.sub: Handle -kfreebsd*. From Robert Millan.
+
+2003-07-02 Robert Millan <rmh@debian.org>
+
+ * config.guess (*:GNU/FreeBSD:*:*): Prefix GNU/FreeBSD triplet
+ with a "k" to indicate the system is based on FreeBSD's kernel and
+ not the whole OS.
+
+2003-06-17 Ben Elliston <bje@wasabisystems.com>
+
+ From by Stephen Thomas <stephen.thomas@superh.com>:
+ * config.guess (sh64*:*:*:Linux): New case.
+ * config.sub (sh64): Map to sh64-unknown.
+
+2003-06-17 Ben Elliston <bje@wasabisystems.com>
+
+ Reported by Dennis Grevenstein <dennis@pcde.inka.de>:
+ * config.guess (sei:*:*:seiux): Detect SEIUX running on MIPS-based
+ workstations manufactured by Sumitomo Electric Industries.
+ * config.sub (sei, -sei*): Handle.
+
+2003-06-13 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * config.sub (c4x, tic4x): Re-arrange and fix.
+
+2003-06-12 Bernard Giroud <bernard.giroud@creditlyonnais.ch>
+
+ * config.guess (Alpha*:OpenVMS:*:*): New entry.
+
+2003-06-06 Ben Elliston <bje@wasabisystems.com>
+
+ * config.sub: Recognise pentium3 and pentium4. From Kelley Cook
+ <kcook34@ford.com>.
+
+2003-06-06 Douglas B Rupp <rupp@gnat.com>
+
+ * config.guess: Recognize Interix 4.
+
+2003-06-04 Ben Elliston <bje@wasabisystems.com>
+
+ * config.guess (set_cc_for_build): Allow insecure temporary
+ filenames to be generated on systems without mktemp(1) or $RANDOM,
+ but issue a warning to standard error. Suggested by Hans-Peter
+ Nilsson.
+
+2003-05-24 Ben Elliston <bje@wasabisystems.com>
+
+ * config.sub: Handle $os values of -nx6 and -nx7.
+
+2003-05-22 Ben Elliston <bje@wasabisystems.com>
+
+ * config.guess: Detect ICL NX version 6 running on ICL/Fujitsu DRS
+ 6000 machines. Reported by <alpha1@alpha1teclabs.com>.
+
+2003-05-19 Hans-Peter Nilsson <hp@axis.com>
+
+ * config.guess (cris:Linux:*:*): New case.
+
+2003-05-09 Ben Elliston <bje@wasabisystems.com>
+
+ * config.guess (SHG2:*:4.0:3.0): Handle NCR System V UNIX machine.
+ Reported by Raj Mannar <rajman@ureach.com>.
+
+2003-05-09 Andreas Jaeger <aj@suse.de>
+
+ * config.sub (maybe_os): Add alias amd64 for x86_64.
+
+2003-05-09 Ben Elliston <bje@wasabisystems.com>
+
+ From Robert Millan <zeratul2@wanadoo.es>
+ * config.guess (*:GNU/FreeBSD:*:*): Handle.
+
+2003-02-22 Ben Elliston <bje@redhat.com>
+
+ Revert the following due to the demise of MicroBSD:
+
+ 2003-01-03 Scott Kamp <dingo@microbsd.net>
+ * config.guess: Detect MicroBSD operating system on i386 CPUs.
+ * config.sub: Handle aliases for such.
+
+2003-02-03 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Handle -kaos*.
+
+2003-02-03 Charles Lepple <clepple@ghz.cc>
+
+ * config.sub: Handle TI tic55x-* and tic6x-* targets.
+
+2003-01-30 Ben Elliston <bje@redhat.com>
+
+ * config.guess (alpha:OSF1:*:*): Use /usr/sbin/psrinfo -v to
+ detect the Alpha CPU type, not an assembled program requiring
+ $CC_FOR_BUILD.
+
+2003-01-28 Nick Clifton <nickc@redhat.com>
+
+ * config.sub: Add sh2e support.
+
+2003-01-22 Fabio Alemagna <falemagn@aros.org>
+
+ * config.sub: Handle -aros*.
+
+2003-01-10 Stuart Hastings <stuart@apple.com>
+
+ * config.guess: Make i686 the default for Darwin/x86.
+
+2003-01-03 Scott Kamp <dingo@microbsd.net>
+
+ * config.guess: Detect MicroBSD operating system on i386 CPUs.
+ * config.sub: Handle aliases for such.
+
+2003-01-02 Ben Elliston <bje@redhat.com>
+
+ From Wendy Palm <wendyp@cray.com>:
+ * config.guess (CRAY*T3D:*:*:*): Remove.
+ (*:UNICOS/mp:*:*): New system.
+ * config.sub (t3d): Remove.
+ (nv1): Add.
+
+2003-01-02 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Fix mipstx39-* and mipstx39el-* handling (typo).
+
+2003-01-02 Ben Elliston <bje@redhat.com>
+
+ From Dmitry Diky <diwil@mail.ru>:
+ * config.sub (basic_machine): Add msp430 and msp430-*.
+
+2003-01-02 Chris Demetriou <cgd@broadcom.com>
+
+ * config.sub (mipsisa32r2*): Add.
+
+2002-12-23 Ben Elliston <bje@redhat.com>
+
+ * config.guess (set_cc_for_build): Rework to do more secure tmp
+ directory creation. Remove temporary files and tmp directory on
+ exit; remove redundant rm(1) and rmdir(1) commands throughout.
+
+2002-12-17 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * config.guess (hppa*): Remove tmpdir when CC_FOR_BUILD is set.
+
+2002-12-11 Ben Elliston <bje@redhat.com>
+ Dave Anglin <dave.anglin@nrc.ca>
+ Ross Alexander <ross.alexander@uk.neceur.com>
+
+ * config.guess (*:HP-UX:*:*): Detect 64-bit compiler.
+
+2002-11-30 J.T. Conklin <jtc@acorntoolworks.com>
+
+ * config.sub (-nto-qnx*): New $os pattern.
+ (-nto*): Preserve OS version when converting to -nto-qnx*.
+
+2002-11-30 Ben Elliston <bje@redhat.com>
+
+ From Stefan Neis <neis@kobil.de>:
+ * config.guess: Reorder entries so that hosts with a different
+ operating system won't be misdetected as System V simply because
+ their version number happens to be 3.2, 4.* or 5. This is needed
+ for OS/2, at least, which is currently at version 4.52.
+
+2002-11-30 Ben Elliston <bje@redhat.com>
+
+ From Joel Baker <lucifer@lightbearer.com>:
+ * config.guess: Append "-gnu" to triplet on Debian/NetBSD systems.
+ * config.sub: Recognise netbsd*-gnu*.
+
+2002-11-30 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * config.guess (mips64:Linux:*:*): Recognize.
+ (mips:Linux:*:*): Recognize as mips-unknown-linux-gnu instead of
+ mips-pc-linux-gnu.
+
+2002-11-30 Douglas B Rupp <rupp@gnat.com>
+
+ * config.guess: Make default Interix arch "i586".
+
+2002-11-30 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Add "SDS2" to machines that run NCR System V UNIX.
+ Reported by <agustinsanchez@prodigy.net.mx>.
+
+2002-11-13 Ben Elliston <bje@redhat.com>
+
+ * config.sub (windows32): Remove bad idea.
+
+2002-11-13 Werner Lemberg <wl@gnu.org>
+
+ * config.sub: Add -mks*.
+
+2002-11-13 Jeff Conrad <jeff_conrad@msn.com>
+
+ * config.guess: Detect MKS running on Windows {95,98,NT}.
+
+2002-11-13 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect PowerMAX OS on Concurrent Synergy machines.
+ Reported by Sam Williams <sam.williams@hs.utc.com>.
+
+2002-11-08 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect m68k-diab-dnix.
+ * config.sub: Handle -dnix*.
+
+2002-10-21 Paul Eggert <eggert@twinsun.com>
+
+ * config.guess (CC_FOR_BUILD): Put "-o outputfile" before any
+ operands. POSIX 1003.1-2001 says that "c99 file.c -o file" is not
+ supported; you must put all options before all operands, e.g. "c99
+ -o file file.c".
+
+2002-09-05 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * config.sub: Add tic4x target.
+
+2002-09-03 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect NSR-D machines for nsr-tandem-nsk.
+ Reported by <Duncan_Stodart@insession.com>.
+
+2002-08-23 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect Concurrent PowerMaxion.
+ Reported by Lloyd Goldston <lloyd.goldston@sed.redstone.army.mil>.
+
+ * config.guess: Detect Convergent 3B1 machines (running AT&T UNIX).
+ Reported by Bruce Lilly <blilly@erols.com>.
+
+2002-08-22 Urs Janßen <urs@akk.org>
+
+ * config.sub: Cosmetic whitespace fixes.
+
+2002-08-20 Phil Edwards <pme@gcc.gnu.org>
+
+ * config.sub: Accept athlon_* patterns as synonyms for i686-pc.
+
+2002-08-20 Ben Elliston <bje@redhat.com>
+
+ From Chris Demetriou <cgd@broadcom.com>:
+ * config.sub (sb1, sb1el): Treat these machines as
+ mipsisa64sb1-unknown and mipsisa64sb1el-unknown, respectively.
+
+2002-08-19 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect Super-UX on NEC SX-6.
+ Reported by Joachim Worringen <joachim@ccrl-nece.de>.
+
+2002-08-16 Eric Christopher <echristo@redhat.com>
+
+ * config.sub (mipsisa64sr71k*, mips64vr*): Add.
+
+2002-07-23 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect alphaev7. Reported by urs@akk.org.
+
+2002-07-03 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Use umask to create temporary directly safely.
+ Using mkdir and chmod introduces a race.
+
+2002-07-03 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect ICL NX version 7 running on ICL/Fujitsu DRS
+ 6000 machines. Reported by Henrik N. Spuur Hansen <hnsh@mera.dk>.
+
+2002-07-03 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Execute $dummy, not ./$dummy, throughout.
+
+ * config.guess (set_cc_for_build): Create a chmod 700 directory in
+ /tmp (or $TMPDIR, if set) to store temporary files generated for
+ use by the C compiler. This should resist the /tmp symbolic link
+ race vulnerability reported by Lawrence Teo.
+
+2002-07-03 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Handle freebsd*. From Bruno Haible.
+
+2002-07-01 Bruno Haible <bruno@clisp.org>
+
+ * config.guess: For FreeBSD systems using glibc, add suffix "-gnu".
+ * config.sub: Accept freebsd-gnu system name.
+
+2002-06-21 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config.sub: Add support for sh[12], sh3e, sh[1234]le, sh3ele,
+ shle, sh[1234]le, sh3ele.
+
+2002-06-21 Dave Brolley <brolley@redhat.com>
+
+ * config.sub: Add support for frv.
+
+2002-06-20 Chris Demetriou <cgd@broadcom.com>
+
+ * config.sub: Add Broadcom SiByte SB-1 processor support
+ (mipsisa64sb1, mipsisa64sb1el). Add little-endian variants of
+ mipsisa32 and mipsisa64 (mipsisa32el and mipsisa64el,
+ respectively). Sort MIPS entries and split their lines a bit more
+ logically. Make sure that all of the MIPS entries in the "without
+ company name" target list are echoed in the "with company name"
+ list.
+
+2002-06-19 Denis Chertykov <denisc@overta.ru>
+
+ * (config.sub): Add ip2k support.
+
+2002-06-19 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config.sub: Accept sh64le and sh64le-*.
+
+2002-05-29 Paul Eggert <eggert@twinsun.com>
+
+ * config.guess: Don't use egrep, as POSIX 1003.1-2001 no longer
+ requires egrep. Use grep instead.
+
+2002-05-28 Kuang Hwa Lin <kuang@sbcglobal.net>
+
+ * config.sub: Add DLX support.
+
+2002-05-22 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.guess: Add case for "armeb" in NetBSD section.
+ * config.sub: Allow "armeb" as a valid CPU type.
+
+2002-05-16 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect PowerMAX OS on Concurrent Night Hawk.
+ * config.sub: Handle -powermax*.
+
+2002-05-02 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Add "4400" to machines that run NCR System V UNIX.
+
+2002-04-25 Mark Mitchell <mark@codesourcery.com>
+
+ * config.sub (*-wrs-windiss): New targets.
+
+2002-03-20 Keith Thompson <kst@sdsc.edu>
+
+ * config.guess (ia64:Linux:*:*): Output "ia64-unknown-linux-gnu".
+
+2002-03-20 Ben Elliston <bje@redhat.com>
+
+ * config.guess (set_cc_for_build): Add c99 to list of candidates.
+
+2002-03-12 J.T. Conklin <jtc@acorntoolworks.com>
+
+ * config.guess: Add OS release to QNX config strings.
+
+2002-03-06 Chris Demetriou <cgd@broadcom.com>
+
+ * config.sub: Add support for mipsisa64.
+
+2002-03-04 Ben Elliston <bje@redhat.com>
+
+ From Kevin Ryde <user42@zip.com.au>:
+ * config.sub (sparclet-*-*): Accept any vendor.
+ (sparc86x): Expand to sparc86x-unknown-none.
+
+2002-03-04 Adrian Bunk <bunk@fs.tum.de>
+
+ * config.guess (*:NetBSD:*:*): Use "sysctl -n hw.machine_arch"
+ instead of "uname -p" to get UNAME_MACHINE_ARCH.
+
+2002-02-22 Ben Elliston <bje@redhat.com>
+ Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config.sub (case $basic_machine): Add mips and clean up other
+ Linux specific cases. Now `config.sub mips` yields mips-unknown-elf.
+
+2002-02-22 Ben Elliston <bje@redhat.com>
+
+ From Kevin Ryde <user42@zip.com.au>:
+ * config.sub (sv1-*, ymp-*, c90-*): Preserve CPU type in output.
+ (t3d-*, t3e-*): Canonicalize to alpha and alphaev5.
+
+2002-02-18 Jim Meyering <meyering@lucent.com>
+
+ * config.guess: Don't use `head -1'; it's no longer portable.
+ Use `sed 1q' instead.
+
+2002-02-15 Ben Elliston <bje@redhat.com>
+
+ * config.sub (rtmk*, rtmk-nova*): Recognise.
+ From Johan Rydberg <jrydberg@rtmk.org>.
+
+2002-02-15 Wendy Palm <wendyp@cray.com>
+
+ * config.guess (CRAY*X-MP:*:*:*, CRAY-2:*:*:*): Remove, as we know
+ they no longer exist in the field.
+ * config.sub (cray2, xmp): Likewise.
+ (cray, ymp, [cj]90-cray): basic_machine is now j90-cray.
+ (sv1-cray, cray-t3e, cray-t3d, cray-t90): New basic machine patterns.
+
+2002-02-15 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Accept m68060.
+
+2002-02-12 Ben Elliston <bje@redhat.com>
+
+ * config.sub (sx?-*, superux*): New basic_machine and os.
+ From Len Makin <Len.Makin@csiro.au>.
+
+2002-02-12 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Set LC_ALL, not LANG, when running ld --help.
+ From Nicola Pero <nicola@brainstorm.co.uk>.
+
+2002-02-01 Ben Elliston <bje@redhat.com>
+
+ * config.sub (sh64, sh64-*): Add new machine.
+
+2002-01-31 Ivan Guzvinec <ivang@opencores.org>
+
+ * config.sub: Add support for or32.
+
+2002-01-26 Andy Olson <andrew.olson@lmco.com>
+
+ * config.guess (*:QNX:*:*): Report i386-* rather than x86pc-*.
+ Discussed with and approved by <peterv@qnx.com>.
+
+2002-01-23 Ben Elliston <bje@redhat.com>
+
+ * config.guess (i*86:Linux:*:*): Specifically handle the Intel icc
+ compiler, which doesn't define __ELF__. Submitted by Erik Lindahl
+ <lindahl@stanford.edu>.
+
+2002-01-22 Nicola Pero <nicola@brainstorm.co.uk>
+
+ * config.guess (i*86:Linux:*:*): Fixed: export LANG=C before
+ running ld so that linker output can be assumed to be in English,
+ and it works with non-default locales.
+
+2002-01-10 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Update Per Bothner's mail address.
+
+2002-01-02 Douglas B. Rupp <rupp@gnat.com>
+
+ * config.sub (alpha64*): New basic_machine.
+
+2002-01-02 Ben Elliston <bje@redhat.com>
+
+ From Sigbjorn Skjaeret <cisc@c2i.net>.
+ * config.guess: Add detection for MorphOS.
+ * config.sub: Handle morphos*.
+
+2002-01-02 H.J. Lu <hjl@gnu.org>
+
+ * config.guess (mips:Linux:*:*): Undef CPU, mips and mipsel first.
+
+2001-12-13 Douglas B. Rupp <rupp@gnat.com>
+
+ * config.guess: Recognize x86 Interix version 3.
+
+2001-12-12 Ben Elliston <bje@redhat.com>
+
+ * config.guess (i*86:Linux:*:*): Minor simplification: have the
+ preprocessor emit shell assignments and just eval the output.
+
+2001-12-12 H.J. Lu <hjl@gnu.org>
+
+ * config.guess (mips:Linux:*:*): Re-work.
+
+2001-12-12 Ben Elliston <bje@redhat.com>
+
+ * config.guess (i*86:Linux:*:*): Speed up detection of x86 Linux
+ systems by using just the C preprocessor rather than assembling
+ and linking a final executable.
+
+2001-12-12 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.guess: Simplify assignment of machine for NetBSD targets,
+ and make it match the convention that NetBSD uses. List all
+ NetBSD architectures that require "elf" at the end of the OS name.
+
+2001-12-10 Lars Brinkhoff <lars@nocrew.org>
+
+ * config.sub: Recognize a few PDP-10 aliases.
+
+2001-12-03 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Recognise the Nucleus family of operating systems.
+ From <Takahiko_Kawasaki@cii.csk.co.jp>.
+
+2001-12-03 Bob Wilson <bwilson@tensilica.com>
+
+ * config.sub: Add support for Xtensa targets.
+
+2001-11-30 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Recognise NEC v850e. From Miles Bader
+ <miles@lsi.nec.co.jp>.
+
+2001-11-26 Ben Elliston <bje@redhat.com>
+
+ * config.guess (nsr-tandem-nsk): Detect all known NSR processor
+ types. Contributed by Kjetil Barvik <kjetil.barvik@bbs.no>.
+
+2001-11-16 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Accept "-atheos*" as a valid OS.
+ From Taco Witte <T.C.Witte@phys.uu.nl>.
+
+2001-11-08 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Handle 3487/3488 machines for NCR SysV UNIX.
+ Contributed by Melvin M. Bagaforo <mbagaforo@makro.com.ph>.
+
+2001-11-07 Adrian von Bidder <avbidder@acter.ch>
+
+ * config.sub: Accept "-uclinux*" as a valid OS.
+
+2001-11-07 D.J. Barrow <djbarrow@de.ibm.com>
+
+ * config.sub: Added S/390 31 and 64 bit target.
+
+2001-11-06 John Marshall <jmarshall@acm.org>
+
+ * config.sub: Accept "-palmos*" as a valid OS.
+
+2001-11-07 Geoffrey Keating <geoffk@redhat.com>
+
+ * config.sub: Change 'stormy16' to 'xstormy16' in the two places
+ it appears.
+
+2001-10-05 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Add "SKA40" as a machine type for NCR SysV UNIX.
+ From Rudi Heitbaum <rheitbaum@tattersalls.com.au>.
+
+2001-10-05 Rodney Brown <rbrown64@csc.com.au>
+
+ * config.guess (9000/[34678]??:HP-UX:*:*): Unconditionally try
+ /usr/bin/getconf which is available on HP-UX 10.20. Reindent.
+
+2001-10-04 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Handle viac3 as an i586-class CPU.
+
+ * config.sub: Handle simso-wrs (Wind River's VxWorks Solaris
+ simulator target). From dpovey@dstc.qut.edu.au.
+
+2001-09-14 H.J. Lu <hjl@gnu.org>
+
+ * config.sub: Support avr-vendor-*.
+
+2001-09-13 Ben Elliston <bje@redhat.com>
+
+ * config.guess (*-*-openbsd): Reorganise and clean up.
+ Contributed by brad@openbsd.org.
+
+2001-09-12 Ben Elliston <bje@redhat.com>
+
+ * config.guess (sparc*-*-netbsd): Properly match 32-bit NetBSD/sparc64
+ as sparc-unknown-netbsd. From Matthew Green <mrg@eterna.com.au>.
+
+2001-09-07 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Add mipseb-* alias (whoops).
+
+2001-09-04 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Add mipseb alias.
+
+2001-09-04 Eric Christopher <echristo@redhat.com>
+ Jason Eckhardt <jle@redhat.com>
+
+ * config.sub: Add support for mipsisa32.
+
+2001-09-04 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Move eval $set_cc_for_build in most cases, to
+ prevent this script fragment from cloberring a previously
+ constructed C program in $dummy.c.
+
+2001-08-23 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect AtheOS on x86 systems.
+ Based on info provided by Taco Witte <tcwitte@wish.net>.
+
+2001-08-23 Geoffrey Keating <geoffk@redhat.com>
+
+ * config.sub: Add stormy16-elf.
+
+2001-08-21 matthew green <mrg@eterna.com.au>
+
+ * config.guess (sparc*:NetBSD:*): Use $MACHINE_ARCH, not $MACHINE.
+
+2001-08-13 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Handle complete system name for elxsi.
+ From Zack Weinberg <zackw@panix.com>.
+
+2001-08-09 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect Alpha ev68 on OSF/1 and Linux.
+ From Ken Whaley <ken@believe.com>.
+
+2001-08-04 Darrell Hamilton <Darrell_Hamilton@labcorp.com>
+
+ * config.guess: Unisys places the host id in ${UNAME_SYSTEM}
+ which is too unique to flag this system. Detect it with *
+ instead.
+
+2001-08-02 Alan Modra <amodra@bigpond.net.au>
+
+ * config.sub: Sort basic cpu patterns. Combine hppa patterns.
+
+2001-08-01 Alan Modra <amodra@bigpond.net.au>
+
+ * config.sub: Recognise powerpc64, powerpc64le, ppc64 variations.
+
+2001-07-31 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect Stratus VOS operating system.
+ * config.sub: Handle aliases for such.
+
+2001-07-30 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect STOP operating system on x86 CPUs.
+ From Hans Edwards <Hans.Edwards@getronicsgov.com>.
+
+2001-07-27 Niibe Yutaka <gniibe@m17n.org>
+
+ * config.sub: Recognize sh3eb and sh4eb (big endian) aliases.
+
+2001-07-19 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect Linux on the PPC64 architecture.
+
+2001-07-12 Keith Thompson <kst@sdsc.edu>
+
+ * config.guess: Strip trailing sub-version number from
+ $UNAME_RELEASE on Cray YMP or Cray [A-Z]90 models.
+
+2001-07-09 Mark Klein <mklein@dis.com>
+
+ * config.guess: Update MPE/iX to handle A and N class HPe3000.
+
+2001-07-02 Graham Stott <grahams@redhat.com>
+
+ * config.sub (basic_machine): Fix typo for mips64vr5000el.
+
+2001-06-29 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Remove stale libc1 tests on PowerPC Linux.
+
+2001-06-29 John Wolfe <jlw@sco.com>
+
+ * config.guess: Correct UnixWare 7 and Open UNIX 8.0 change;
+ test for i586 must be a string that ends with "Pentium".
+
+2001-06-28 Ben Elliston <bje@redhat.com>
+
+ * config.guess: On Alpha Linux, use /proc/cpuinfo to determine
+ the CPU model, rather than assembling a small test program.
+
+2001-06-27 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Do not unconditionally run the script fragment
+ to set $CC_FOR_BUILD. Put the script in the shell variable
+ $set_cc_for_build and only evaluate it before $CC_FOR_BUILD is
+ referenced. (Poor man's function inlining!)
+
+ In future, the goal will be to reduce the dependence on a C
+ compiler to detect system types by utilising other means.
+
+2001-06-26 Ben Elliston <bje@redhat.com>
+
+ * config.guess: On MIPS Linux, use /proc/cpuinfo to determine
+ the endian mode of the CPU, rather than compiling and running
+ a small C program.
+
+2001-06-12 John Wolfe <jlw@sco.com>
+
+ * config.guess: Standardize triplet for UnixWare 7 and Open
+ UNIX 8.0, improve processor detection and maintain "sysv5"
+ prefix on third segment.
+
+2001-06-08 Christopher Faylor <cgf@redhat.com>
+
+ * config.sub: Add support for Sun Chorus.
+
+2001-06-05 Tomislav Greguric <greguric@stud.uni-frankfurt.de>
+
+ * config.guess: Add 2001 to copyright notice issued for -v.
+
+2001-06-01 Ben Elliston <bje@redhat.com>
+
+ * config.guess (i*86:Linux:*:*): Examine the list of supported
+ targets, not the list of supported emulations when capturing
+ the output of "ld --help". This causes problems on systems
+ where GNU ld is built with support for all targets. Adjust
+ cases in the switch accordingly.
+
+ * config.guess: Other small Linux cleanups. Remove unnecessary
+ logic for setting $VENDOR, since UNAME_MACHINE will always be
+ i*86 in this case.
+
+2001-05-30 Mo DeJong <mdejong@redhat.com>
+
+ * config.sub: Handle windows32 and runtimes.
+
+2001-05-24 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Remove duplicate z8k entry.
+
+2001-05-11 Yaegashi Takeshi <t@keshi.org>
+
+ * config.sub: Handle sh[34]-* and sh[34]eb-*.
+
+2001-05-09 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Handle z8k-coff.
+ From Christian Groessler <cpg@aladdin.de>.
+
+2001-04-20 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Handle sparcv9b.
+ From Dave Miller <davem@redhat.com>.
+
+ * config.guess: Detect PowerMAX OS on PowerPC.
+
+2001-04-20 Tyson Dowd <trd@cs.mu.oz.au>
+ Fergus Henderson <fjh@cs.mu.oz.au>
+
+ * config.guess: Replace i?86 with i*86 to match newer Pentiums.
+ * config.sub: Likewise.
+
+2001-03-30 Peter Buckingham <pbuckingham@lnxw.com>
+
+ * config.guess: Update LynxOS version numbers.
+
+2001-03-30 Alexandre Oliva <aoliva@redhat.com>
+
+ * config.sub: Make sure to match an already-canonicalized
+ machine name (eg. mn10300-unknown-elf).
+
+2001-03-19 Philip Blundell <philb@gnu.org>
+
+ * config.sub: Allow tic80 as machine type. Allow company name for
+ h8500 and pj targets; add `unknown' component when canonicalising
+ h8500-*, pj-* and pjl-*.
+
+2001-03-16 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect Linux on SPARC64.
+
+2001-03-14 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect ELF-based m68k Linux systems. Reported by
+ Michael Fedrowitz <michael.fedrowitz@informatik.uni-ulm.de>.
+
+2001-03-09 H.J. Lu <hjl@gnu.org>
+
+ * config.sub: Recognize s390/s390x as valid $basic_machine.
+
+2001-03-05 Pavel Roskin <proski@gnu.org>
+
+ * config.guess: Never use `rm' without `-f' since it may be
+ interactive.
+
+2001-02-24 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Match Linux x86 systems explicitly. Allow unknown
+ architectures to fall through to the default case.
+
+2001-02-23 Ben Elliston <bje@redhat.com>
+
+ * config.guess: More Linux cleanup. Match more in the top-level
+ case statement and less by groking the output of ld.
+
+2001-02-16 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Recognise [cjt]90-*. From Kevin Ryde.
+
+2001-02-13 David Edelsohn <edelsohn@gnu.org>
+
+ * config.guess (ia64:AIX): New case.
+ (*:AIX): Expand AIX V4 case to include V5. Remove unnecessary `H'
+ option from lsattr. Check for string "POWER" with prepended space
+ to distinguish from PowerPC_POWER3. Use ${UNAME_VERSION} instead
+ of assuming "4" to match the expanded case.
+
+2001-02-13 Kevin Ryde <user42@zip.com.au>
+
+ * config.sub: Recognise t90, c90, j90 without -cray. Preserve t90
+ and j90--don't transform to c90.
+
+2001-02-13 Ben Elliston <bje@redhat.com>
+
+ * config.guess: More Linux cleanup.
+
+2001-02-13 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config.guess: Add Linux target for S/390x.
+ * config.sub: Likewise.
+
+2001-02-13 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Rework detection of many Linux platforms, where
+ detection is straightforward.
+
+2001-01-31 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Handle hppa64-linux systems. From Alan Modra
+ <alan@linuxcare.com.au>.
+
+2001-01-29 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * config.guess: Specifically identify 4.3BSD and 4.3BSD-Reno in
+ the original VAX UNIX detection logic based on the BSD define in
+ <sys/param.h>.
+
+2001-01-17 Pavel Roskin <proski@gnu.org>
+
+ * config.sub: Removed cases that cannot match. Vendor changed
+ from "unknown" to "pc" for "mingw", "msdos" and "go32".
+
+2001-01-17 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect HI-UX on Hitachi SR8000 machines. It has
+ been difficult to discover what type of CPU is in this machine,
+ so we'll punt on hppa1.1 for now.
+
+2001-01-14 Pavel Roskin <proski@gnu.org>
+
+ * config.guess: Don't use $version in the error message. Use
+ $timestamp instead. Minor changes in the error text.
+
+2001-01-12 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Delete $dummy.rel after compiling test programs on
+ PDP-10 systems whose compilers produce this output file. From Lars
+ Brinkhoff <lars@nocrew.org>.
+
+ * config.sub: Handle EMX on OS/2. From Pavel Roskin.
+
+2001-01-12 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect common kernels running on various PDP-10
+ architectures. Contributed by Lars Brinkhoff <lars@nocrew.org>.
+ * config.sub: Handle PDP-10.
+
+2001-01-10 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect LynxOS 3.x on PowerPC architectures.
+
+2001-01-07 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Recognise openrisc-*-*.
+
+2000-12-21 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect HP-UX on IA-64 hosts. From Jonathan
+ Thackray <jon@thackray.org>.
+
+2000-12-20 Pavel Roskin <proski@gnu.org>
+
+ * config.sub: Handle mint with version number as recognized OS.
+ Contributed by Tomas Berndtsson <tomas@nocrew.org>.
+
+2000-12-20 Pavel Roskin <proski@gnu.org>
+
+ * config.guess: Detect Fujitsu f700 machines.
+ * config.sub: Handle f700 and f700-fujitsu.
+
+2000-12-15 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect AIX version 5. Contributed by
+ Dan McNichol <mcnichol@austin.ibm.com>.
+
+ * config.sub: Accept f301 for Fujitsu machines.
+ Reported by Pavel Roskin <proski@gnu.org>.
+
+2000-12-07 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Add more detail to version information.
+ * config.guess: Likewise.
+
+2000-12-06 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Add --version option.
+ * config.guess: Likewise.
+
+2000-12-02 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Only append "elf" to "netbsd" for platforms that
+ have switched to the ELF object file format in recent history.
+ From Matthew Green <mrg@eterna.com.au>.
+
+2000-11-24 Nick Clifton <nickc@redhat.com>
+
+ * config.sub: Add xscale as a recognised CPU name.
+
+2000-11-23 Ben Elliston <bje@redhat.com>
+
+ Patches from Akim Demaille <akim@epita.fr>.
+ * config.sub (version): Rename from this ..
+ (timestamp): .. to this.
+ (usage): Replace --version with --time-stamp. Add additional help
+ and copyleft notice.
+ (time-stamp-start): Replace with "timestamp=".
+ * config.guess (version): Rename from this ..
+ (timestamp): .. to this.
+ (usage): Replace --version with --time-stamp. Add additional help
+ and copyleft notice.
+ (CC_FOR_BUILD): Rework this logic.
+ (time-stamp-start): Replace with "timestamp=".
+
+2000-11-21 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect EMX on OS/2. Reported by Ilya Zakharevich
+ <ilya@math.ohio-state.edu>.
+
+2000-11-16 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Use getconf(1) on HP-UX 11.x systems (when
+ available) to eliminate the need for compiling a small test
+ program. From Neil Schellenberger <nschelle@crosskeys.com>.
+
+2000-11-15 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Expand `power' to `power-ibm-aix' for consistency.
+ From Kevin Ryde.
+
+ * config.guess: Differentiate Cray T3D and T3E. From Kevin Ryde
+ <user42@zip.com.au>.
+
+2000-11-10 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Map pentiumpro and pentiumii aliases onto i686-pc.
+ From Kevin Ryde <user42@zip.com.au>.
+
+ * config.guess: Search for a working C compiler if CC_FOR_BUILD is
+ not specified. From Kevin Ryde.
+
+ * config.guess: Set CPU architecture to "hppa" by default, in case
+ tests fail to produce a result. From Kevin Ryde.
+
+2000-11-08 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect sparc-unknown-linux-gnu. Reported by Peter
+ Storkey <pstorkey@primex.com>.
+
+2000-11-02 Per Lundberg <plundis@chaosdev.org>
+
+ * config.sub: Add support for the *-storm-chaos OS.
+
+2000-10-25 Ed Satterthwaite <ehs@sibyte.com>
+
+ * config.sub: NexGen, not nexen, is the x86 CPU clone
+ manufacturer.
+
+2000-10-23 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect NonStop-UX on Compaq MIPS machines.
+ * config.sub: Handle aliases for mips-compaq-nonstopux.
+ From Tom Bates <tom.bates@compaq.com>.
+
+2000-10-12 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect GNU/Linux on HP PA-RISC systems.
+ From David Huggins-Daines <dhd@linuxcare.com>.
+
+2000-10-09 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Typo fix for sh{3,4} case.
+
+2000-10-08 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Handle 8-way NCR 4300s -- uname(1) returns 3446A.
+ From Ken Cormack <kcormack@acs.roadway.com>.
+
+2000-10-03 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Do not hold ld's output in a shell variable; feed
+ the output directly into the command pipline to avoid a limitation
+ in variable lengths in ash(1). From Pavel Roskin <proski@gnu.org>.
+
+2000-09-11 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Handle nsk*.
+
+2000-09-11 Philip Blundell <philb@gnu.org>
+
+ * config.sub: Fix mistake in change of 2000-08-06.
+
+2000-09-05 Andreas Jaeger <aj@suse.de>
+
+ * config.sub (maybe_os): Recognise AMD x86-64 as x86_64.
+ * config.guess: Detect x86_64-unknown-linux-gnu.
+
+2000-09-05 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Handle Tandem NSR-K machines.
+ Reported by Andres Junge <ajunge@adexus.cl>.
+
+2000-09-05 Paul Sokolovsky <Paul.Sokolovsky@technologist.com>
+
+ * config.guess: Detect the PW32 POSIX-on-Win32 environment.
+ * config.sub: Handle pw32 aliases.
+
+2000-08-31 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Correctly detect Sony NEWS-OS 6.x.
+ From Kimio Ishii <ishii@sm.sony.co.jp>.
+
+2000-08-06 Philip Blundell <philb@gnu.org>
+
+ * config.sub: Accept `-conix*' as a valid OS. Accept `armv*' as a
+ valid CPU without a company name.
+
+2000-07-31 Mark Kettenis <kettenis@gnu.org>
+
+ * config.guess: Restore detection of libc version for x86
+ Linux/GNU ELF systems, but fall back on tentative name based on ld
+ emulation. Use i?86-pc-linux-gnu as tentative name since that's
+ the canonical name.
+
+2000-07-27 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Use "unknown" for the manufacturer field of Amiga
+ systems, not "cbm". Contributed by Ruediger Kuhlmann
+ <ruediger.kuhlmann@stud.uni-karlsruhe.de>.
+ * config.sub: Likewise.
+
+2000-07-24 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect Plan 9.
+
+2000-07-06 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config.sub: Recognise d30v as a valid basic_machine.
+
+2000-06-28 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Recognise Motorola 68HC11/12 targets. From Stephane
+ Carrez <Stephane.Carrez@worldnet.fr>.
+
+2000-06-20 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Recognise tic54x (Texas Instruments TMS320C54x) and
+ c54x (IBM C54XDSP). From Tim Wall <twall@cygnus.com>.
+
+2000-06-13 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect Minix on x86 machines.
+ * config.sub: Recognise i286. From <michael@moria.de>.
+
+ * config.sub: Recognise sh3 and sh4 aliases. From Kazumoto Kojima
+ <kkojima@rr.iij4u.or.jp>.
+
+ * config.sub: Per Bothner is not the author.
+
+2000-06-10 Hans-Peter Nilsson <hp@axis.com>
+
+ * config.sub (os): Recognize axis as manufacturer.
+ (basic_machine): Recognize cris and etrax* as cris-axis.
+
+2000-05-31 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Accept athlon as an i686 variant. From Philipp
+ Thomas <pthomas@suse.de>.
+
+2000-05-30 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Re-word some output.
+ * config.sub: Fix a syntax error introduced by yesterday's
+ changes. Correct a spelling mistake. From Steven G. Johnson
+ <stevenj@alum.mit.edu>.
+
+2000-05-02 Akim Demaille <akim@epita.fr>
+
+ * config.guess: Add --help and --version options. Add Emacs hooks.
+ * config.sub: Likewise.
+
+2000-05-27 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Handle GNU/Linux on Hitachi SuperH. From Niibe
+ Yutaka <gniibe@chroot.org>.
+
+2000-05-19 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Recognise hppa64 as a valid cpu type. From Jeff Law.
+
+2000-05-10 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Recognise bs2000-siemens as a basic_machine type.
+ From Jean-Frederic Clere <jfrederic.clere@fujitsu.siemens.se>.
+
+2000-05-07 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Mac OS X will never return "Mac OS" as a uname
+ value, so remove these cases and punt to the "Darwin" case.
+ From Wilfredo Sanchez <wsanchez@apple.com>.
+
+2000-04-30 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Handle Fujitsu UXP/DS. From Fu-Chuan Tsai
+ <fchtsai@ms23.hinet.net>.
+
+2000-04-26 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Handle an ld emulation of elf_i?86. From Bruce
+ Korb <bkorb@sco.com>.
+
+2000-04-22 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Do not differentiate FreeBSD systems that use the
+ ELF object file format. From David O'Brien <obrien@freebsd.org>.
+
+2000-04-22 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect Siemens BS2000 machines. From Jean-Frederic
+ Clere <jfrederic.clere@fujitsu.siemens.se>.
+
+2000-04-22 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Fix a syntax error in the DG/UX test.
+
+2000-04-06 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Define _HPUX_SOURCE for the HP-UX test program.
+ From Bruno Haible <haible@ilog.fr>.
+
+2000-04-06 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect Apple's Darwin operating system.
+ * config.sub: Handle an appropriate alias. From Assar Westerlund.
+
+2000-03-27 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect Ascend Embedded/OS, which is really BSDI.
+ From Assar Westerlund <assar@sics.se>.
+
+2000-03-20 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Detect the NonStop Kernel on Tandem
+ machines. Suggested by Kelly F. Hickel <kfh@mqsoftware.com>.
+ * config.sub: Handle nsr-tandem and -nsk aliases.
+
+2000-02-29 Peter van der Veen <peterv@qnx.com>
+
+ * config.guess: Add support for QNX Neutrino.
+ * config.sub: Improve support for QNX Neutrino.
+
+2000-02-29 Ossama Othman <ossama@ece.uci.edu>
+
+ * config.sub: Add support for QNX Neutrino.
+
+2000-02-24 Nick Clifton <nickc@cygnus.com>
+
+ * config.sub: Support an OS of "wince".
+
+2000-02-15 Andrew Cagney <cagney@cygnus.com>
+
+ * config.guess: Rewrite NetBSD code. Return *-*-netbsdelf* for
+ ELF systems and *-*-netbsd* for all others. Provide a guideline
+ for how to match a NetBSD tuple.
+
+2000-02-15 Richard Henderson <rth@cygnus.com>
+
+ * config.guess (alpha-osf, alpha-linux): Detect ev67.
+ * config.sub: Accept alphaev6[78], alphaev8.
+
+2000-02-15 Philip Blundell <philb@gnu.org>
+
+ * config.guess: Distinguish arm-*-linux-gnuoldld from
+ arm*-linux-gnu.
+
+2000-02-15 Ben Elliston <bje@redhat.com>
+
+ * config.sub: Handle avr. From Denis Chertykov <denisc@overta.ru>.
+
+ * config.guess: Detect GNU/Linux on IBM S/390 machines.
+ * config.sub: Handle s390-*. From Adam J. Thornton
+ <adam@phoenix.princeton.edu>.
+
+ * config.guess: Detect MacOS X on PowerPC and other machines.
+ From Stephen G. Johnson <stephenj@gil-galad.mit.edu>.
+
+2000-02-08 John W. Eaton <jwe@bevo.che.wisc.edu>
+
+ * config.sub: Recognize sv1-cray as a basic_machine type.
+
+2000-02-07 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Replace sub-minor system version number with an
+ `X' on certain Cray platforms. From Keith Thompson <kst@sdsc.edu>.
+
+ * config.sub: Add support for mmix and mmixware. From Hans-Peter
+ Nilsson <hp@bitrange.com>.
+
+2000-02-06 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Include <stdio.h> when compiling test programs
+ with a C++ compiler. Function prototypes are mandatory in C++.
+ From Ossama Othman <othman@cs.wustl.edu>.
+
+ * config.guess: Fix a regression in PowerPC Linux detection.
+ From Franz Sirl.
+
+2000-02-03 Ben Elliston <bje@redhat.com>
+
+ * config.guess: Handle versions of DJGPP's uname(1) command which
+ return the exact machine type and not just `pc'. From Laurynas
+ Biveinis <lauras@softhome.net>.
+
+ * config.guess: Import from autoconf source tree.
+ * config.sub: Likewise.
diff --git a/misc/buildroot/package/gnuconfig/Makefile b/misc/buildroot/package/gnuconfig/Makefile
new file mode 100644
index 000000000..f99ebce83
--- /dev/null
+++ b/misc/buildroot/package/gnuconfig/Makefile
@@ -0,0 +1,15 @@
+UPLOAD=ftp://ftp-upload.gnu.org/incoming/ftp/
+
+all:
+ @echo "Type 'make upload' to upload to the GNU FTP server."
+
+upload:
+ gpg --detach-sign config.guess
+ gpg --detach-sign config.sub
+ echo "directory: config" | gpg --clearsign > config.guess.directive.asc
+ cp config.guess.directive.asc config.sub.directive.asc
+ ftp -a -u $(UPLOAD) config.{guess,sub}{,.sig,.directive.asc}
+ rm config.{guess,sub}{.sig,.directive.asc}
+
+check:
+ cd testsuite && (sh config-sub.sh; sh config-guess.sh) && rm uname
diff --git a/misc/buildroot/package/gnuconfig/README.buildroot b/misc/buildroot/package/gnuconfig/README.buildroot
new file mode 100644
index 000000000..521f120b9
--- /dev/null
+++ b/misc/buildroot/package/gnuconfig/README.buildroot
@@ -0,0 +1,16 @@
+--- ABOUT ---
+This isnt a real package, it just exists to easily update the
+config.sub / config.guess files in packages to the latest version
+(since many bundled ones don't support the latest possible targets)
+
+--- HOWTO ---
+To use, just add this to your unpack rule in the package.mk:
+$(CONFIG_UPDATE) $(PACKAGE_DIR)/
+
+--- UPDATE ---
+This is a CVS checkout of the config project, so just run `cvs up`
+to get the latest config.sub / config.guess files.
+
+A few local customizations are used to support uClibc so you may
+have to make sure they're still needed. The patches are broken
+out in the patches/ dir to keep things simple.
diff --git a/misc/buildroot/package/gnuconfig/config.guess b/misc/buildroot/package/gnuconfig/config.guess
new file mode 100755
index 000000000..d870848e0
--- /dev/null
+++ b/misc/buildroot/package/gnuconfig/config.guess
@@ -0,0 +1,1517 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
+# Inc.
+
+timestamp='2006-02-27'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+if [ "${UNAME_SYSTEM}" = "Linux" ] ; then
+ eval $set_cc_for_build
+ cat << EOF > $dummy.c
+ #include <features.h>
+ #ifdef __UCLIBC__
+ # ifdef __UCLIBC_CONFIG_VERSION__
+ LIBC=uclibc __UCLIBC_CONFIG_VERSION__
+ # else
+ LIBC=uclibc
+ # endif
+ #else
+ LIBC=gnu
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep LIBC= | sed -e 's: ::g'`
+fi
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep __ELF__ >/dev/null
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm:riscos:*:*|arm:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[45])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep __LP64__ >/dev/null
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ case ${UNAME_MACHINE} in
+ pc98)
+ echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:MSYS_NT-*:*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ x86:Interix*:[345]*)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ EM64T:Interix*:[345]*)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ arm*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+ echo crisv32-axis-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+ echo frv-unknown-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips
+ #undef mipsel
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mipsel
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^CPU/{
+ s: ::g
+ p
+ }'`"
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+ mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips64
+ #undef mips64el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mips64el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips64
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^CPU/{
+ s: ::g
+ p
+ }'`"
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+ or32:Linux:*:*)
+ echo or32-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ # Set LC_ALL=C to ensure ld outputs messages in English.
+ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+ | sed -ne '/supported targets:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported targets: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_targets" in
+ elf32-i386)
+ TENTATIVE="${UNAME_MACHINE}-pc-linux-${LIBC}"
+ ;;
+ a.out-i386-linux)
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}aout"
+ exit ;;
+ coff-i386)
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}coff"
+ exit ;;
+ "")
+ # Either a pre-BFD a.out linker (linux-gnuoldld) or
+ # one that does not give us useful --help.
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}oldld"
+ exit ;;
+ esac
+ # This should get integrated into the C code below, but now we hack
+ if [ "$LIBC" != "gnu" ] ; then echo "$TENTATIVE" && exit 0 ; fi
+ # Determine whether the default compiler is a.out or elf
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #ifdef __ELF__
+ # ifdef __GLIBC__
+ # if __GLIBC__ >= 2
+ LIBC=gnu
+ # else
+ LIBC=gnulibc1
+ # endif
+ # else
+ LIBC=gnulibc1
+ # endif
+ #else
+ #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun)
+ LIBC=gnu
+ #else
+ LIBC=gnuaout
+ #endif
+ #endif
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^LIBC/{
+ s: ::g
+ p
+ }'`"
+ test x"${LIBC}" != x && {
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ exit
+ }
+ test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+ ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NSE-?:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ c34*)
+ echo c34-convex-bsd
+ exit ;;
+ c38*)
+ echo c38-convex-bsd
+ exit ;;
+ c4*)
+ echo c4-convex-bsd
+ exit ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+ http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/misc/buildroot/package/gnuconfig/config.sub b/misc/buildroot/package/gnuconfig/config.sub
new file mode 100755
index 000000000..e66bd561f
--- /dev/null
+++ b/misc/buildroot/package/gnuconfig/config.sub
@@ -0,0 +1,1627 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
+# Inc.
+
+timestamp='2006-02-27'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+ | bfin \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx | dvp \
+ | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64vr | mips64vrel \
+ | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | mt \
+ | msp430 \
+ | nios | nios2 \
+ | ns16k | ns32k \
+ | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+ | sh | sh[1234] | sh[24]a | sh[24]a*eb | sh[23]e | sh[34]eb | shbe | sheb | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | strongarm \
+ | tahoe | thumb | tic4x | tic80 | tron \
+ | v850 | v850e \
+ | we32k \
+ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+ | z8k)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m32c)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nios-* | nios2-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tron-* \
+ | v850-* | v850e-* | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+ | xstormy16-* | xtensa-* \
+ | ymp-* \
+ | z8k-*)
+ ;;
+ m32c-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16c)
+ basic_machine=cr16c-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mipsEE* | ee | ps2)
+ basic_machine=mips64r5900el-scei
+ case $os in
+ -linux*)
+ ;;
+ *)
+ os=-elf
+ ;;
+ esac
+ ;;
+ iop)
+ basic_machine=mipsel-scei
+ os=-irx
+ ;;
+ dvp)
+ basic_machine=dvp-scei
+ os=-elf
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tic54x | c54x*)
+ basic_machine=tic54x-unknown
+ os=-coff
+ ;;
+ tic55x | c55x*)
+ basic_machine=tic55x-unknown
+ os=-coff
+ ;;
+ tic6x | c6x*)
+ basic_machine=tic6x-unknown
+ os=-coff
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -irx*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/misc/buildroot/package/gnuconfig/gnuconfig.mk b/misc/buildroot/package/gnuconfig/gnuconfig.mk
new file mode 100644
index 000000000..e6cd2dedb
--- /dev/null
+++ b/misc/buildroot/package/gnuconfig/gnuconfig.mk
@@ -0,0 +1,3 @@
+# See README.buildroot
+
+CONFIG_UPDATE = cp -f package/gnuconfig/config.sub package/gnuconfig/config.guess
diff --git a/misc/buildroot/package/gnuconfig/patches/config.sub.ps2.patch b/misc/buildroot/package/gnuconfig/patches/config.sub.ps2.patch
new file mode 100644
index 000000000..619a96e21
--- /dev/null
+++ b/misc/buildroot/package/gnuconfig/patches/config.sub.ps2.patch
@@ -0,0 +1,50 @@
+Index: config.sub
+===================================================================
+RCS file: /cvsroot/config/config/config.sub,v
+retrieving revision 1.340
+diff -u -p -r1.340 config.sub
+--- config.sub
++++ config.sub
+@@ -244,7 +244,7 @@ case $basic_machine in
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+ | bfin \
+ | c4x | clipper \
+- | d10v | d30v | dlx | dsp16xx \
++ | d10v | d30v | dlx | dsp16xx | dvp \
+ | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+@@ -693,6 +693,24 @@ case $basic_machine in
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
++ mipsEE* | ee | ps2)
++ basic_machine=mips64r5900el-scei
++ case $os in
++ -linux*)
++ ;;
++ *)
++ os=-elf
++ ;;
++ esac
++ ;;
++ iop)
++ basic_machine=mipsel-scei
++ os=-irx
++ ;;
++ dvp)
++ basic_machine=dvp-scei
++ os=-elf
++ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+@@ -1218,7 +1236,7 @@ case $os in
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+- | -skyos* | -haiku* | -rdos*)
++ | -skyos* | -haiku* | -rdos* | -irx*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
diff --git a/misc/buildroot/package/gnuconfig/patches/config.sub.sh.patch b/misc/buildroot/package/gnuconfig/patches/config.sub.sh.patch
new file mode 100644
index 000000000..edbc41910
--- /dev/null
+++ b/misc/buildroot/package/gnuconfig/patches/config.sub.sh.patch
@@ -0,0 +1,39 @@
+gnuconfig seems intent on only supporting superfluous targets that don't
+represent any real hardware (such as sh2a LE). GCC in its infinite wisdom is
+also incapable of supporting tuning for other variants in a sensible fashion.
+
+As such, we still need to be able to support such useful targets as
+sh2a_nofpueb in order to not only get the byte order right, but also to
+support -m2a-nofpu tuning from the kernel (though we tend to do this through
+-Wa,-isa= instead, as the binutils people do a much better job of not screwing
+up their config code every other day. Way to go config.gcc..).
+
+The fact that the sh variant matching is the ugliest out of any of the other
+architectures doesn't seem to deter GCC folk from their well thought out and
+brilliantly managed config target list.
+
+Index: config.sub
+===================================================================
+RCS file: /cvsroot/config/config/config.sub,v
+retrieving revision 1.340
+diff -u -p -r1.340 config.sub
+--- config.sub 26 Feb 2006 23:33:46 -0000 1.340
++++ config.sub 2 Mar 2006 06:22:01 -0000
+@@ -275,7 +275,7 @@ case $basic_machine in
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+- | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
++ | sh | sh[1234] | sh[24]a | sh[24]a*eb | sh[23]e | sh[34]eb | shbe | sheb | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+@@ -359,7 +359,7 @@ case $basic_machine in
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* \
+- | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
++ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]a*eb-* | sh[23]e-* | sh[34]eb-* | shbe-* | sheb-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
diff --git a/misc/buildroot/package/gnuconfig/testsuite/config-guess.data b/misc/buildroot/package/gnuconfig/testsuite/config-guess.data
new file mode 100644
index 000000000..156685d73
--- /dev/null
+++ b/misc/buildroot/package/gnuconfig/testsuite/config-guess.data
@@ -0,0 +1,23 @@
+crisv32 2.6.6 Linux ignored crisv32-axis-linux-gnu
+frv 2.4.24 Linux ignored frv-unknown-linux-gnu
+3 2.3.3 XENIX SysV i386-pc-xenix
+2064 ignored z/VM ignored s390-ibm-zvmoe
+amd64 1.5.12(0.116/4/2) CYGWIN_NT-5.2 ignored x86_64-unknown-cygwin
+crayx1 2.5.20 UNICOS/mp ignored craynv-cray-unicosmp2.5.X
+NSE-N 1.0 NONSTOP_KERNEL ignored nse-tandem-nsk1.0
+i386 ignored VOS ignored i386-stratus-vos
+arm ignored RISCOS ignored arm-unknown-riscos
+arm ignored riscos ignored arm-unknown-riscos
+i586 5.0.0 skyos ignored i586-pc-skyos5.0.0
+i786-pc ignored windows32 ignored i786-pc-mingw32
+or32 ignored Linux ignored or32-unknown-linux-gnu
+x86_64 1.5.18(0.132/4/2) CYGWIN_NT-5.2 ignored x86_64-unknown-cygwin
+x86 5.2 Interix ignored i586-pc-interix5.2
+ppc64 2.6.9-22 Linux ignored powerpc64-unknown-linux-gnu
+vax 2.6.15 Linux ignored vax-dec-linux-gnu
+i586 ignored rdos ignored i586-pc-rdos
+pc98 7.0 FreeBSD ignored i386-unknown-freebsd7.0
+i586 1.0 SolidBSD ignored i586-unknown-solidbsd1.0
+i686 5.4-1-686 GNU/kFreeBSD ignored i686-unknown-kfreebsd5.4-gnu
+i686 1.0.10(0.46/3/2) MSYS_NT-5.1 ignored i686-pc-mingw32
+EM64T 5.2 Interix ignored x86_64-unknown-interix5.2
diff --git a/misc/buildroot/package/gnuconfig/testsuite/config-guess.sh b/misc/buildroot/package/gnuconfig/testsuite/config-guess.sh
new file mode 100644
index 000000000..3f5103080
--- /dev/null
+++ b/misc/buildroot/package/gnuconfig/testsuite/config-guess.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+#
+# Copyright 2004, 2005 Free Software Foundation, Inc.
+# Contributed by Ben Elliston <bje@gnu.org>.
+#
+# This test reads 5-tuples from config-guess.data: the components of
+# the simulated uname(1) output and the expected GNU system triplet.
+
+verbose=false
+export PATH=`pwd`:$PATH
+IFS=" " # tab
+
+function run_config_guess ()
+{
+ rc=0
+ while read machine release system version triplet ; do
+ sed \
+ -e "s,@MACHINE@,$machine," \
+ -e "s,@RELEASE@,$release," \
+ -e "s,@SYSTEM@,$system," \
+ -e "s,@VERSION@,$version," < uname.in > uname
+ chmod +x uname
+ output=`sh ../config.guess 2>/dev/null`
+ if test $? != 0 ; then
+ echo "FAIL: unable to guess $machine:$release:$system:$version"
+ rc=1
+ continue
+ fi
+ if test $output != $triplet ; then
+ echo "FAIL: $output (expected $triplet)"
+ rc=1
+ continue
+ fi
+ $verbose && echo "PASS: $triplet"
+ done
+ return $rc
+}
+
+sed 's/ */ /g' < config-guess.data | run_config_guess
+rc=$?
+if test $rc -eq 0 ; then
+ $verbose || echo "PASS: config.guess checks"
+else
+ test $rc -eq 1 && echo "Unexpected failures."
+fi
+
+exit $rc
diff --git a/misc/buildroot/package/gnuconfig/testsuite/config-sub.data b/misc/buildroot/package/gnuconfig/testsuite/config-sub.data
new file mode 100644
index 000000000..9b4cd1933
--- /dev/null
+++ b/misc/buildroot/package/gnuconfig/testsuite/config-sub.data
@@ -0,0 +1,92 @@
+arm-coff arm-unknown-coff
+arm-elf arm-unknown-elf
+sun3 m68k-sun-sunos4.1.1
+sun4 sparc-sun-sunos4.1.1
+ibm i370-ibm-aix
+i386-os2 i386-pc-os2
+os400 powerpc-ibm-os400
+mmix mmix-knuth-mmixware
+mmix-elf mmix-knuth-elf
+i386-linux i386-pc-linux-gnu
+i386-netbsd i386-pc-netbsd
+i386-openbsd i386-pc-openbsd
+i386-freebsd i386-pc-freebsd
+pc98-freebsd i386-pc-freebsd
+i386-elf i386-pc-elf
+i486-elf i486-pc-elf
+i586-elf i586-pc-elf
+i686-elf i686-pc-elf
+i786-elf i786-pc-elf
+amd64-unknown-freebsd5.2 x86_64-unknown-freebsd5.2
+cris-linux cris-axis-linux-gnu
+crisv32-linux crisv32-axis-linux-gnu
+frv-linux frv-unknown-linux-gnu
+djgpp i586-pc-msdosdjgpp
+s390-ibm-zvmoe s390-ibm-zvmoe
+xscale xscale-unknown-none
+xscaleeb xscaleeb-unknown-none
+xscaleel xscaleel-unknown-none
+xbox i686-pc-mingw32
+maxq maxq-unknown-none
+maxq-elf maxq-unknown-elf
+amd64-cygwin x86_64-pc-cygwin
+x86_64-cygwin x86_64-pc-cygwin
+sparc64-linux sparc64-unknown-linux-gnu
+sparc64b-linux sparc64b-unknown-linux-gnu
+bfin-elf bfin-unknown-elf
+bfin bfin-unknown-none
+arm-riscos arm-unknown-riscos
+arm-unknown-riscos arm-unknown-riscos
+i586-skyos i586-pc-skyos
+m32c m32c-unknown-none
+m32c-elf m32c-unknown-elf
+ms1 mt-unknown-none
+ms1-elf mt-unknown-elf
+mips64vr5900-elf mips64vr5900-unknown-elf
+mips64vr5900el-elf mips64vr5900el-unknown-elf
+mips64vr5900 mips64vr5900-unknown-elf
+mips64vr5900el mips64vr5900el-unknown-elf
+sh64 sh64-unknown-none
+sh64-elf sh64-unknown-elf
+openrisc-linux or32-unknown-linux-gnu
+or32-linux or32-unknown-linux-gnu
+sh-elf sh-unknown-elf
+sh1-elf sh1-unknown-elf
+sh2-elf sh2-unknown-elf
+sh3-elf sh3-unknown-elf
+sh4-elf sh4-unknown-elf
+sh2a-elf sh2a-unknown-elf
+sh4a-elf sh4a-unknown-elf
+sh2e-elf sh2e-unknown-elf
+sh3e-elf sh3e-unknown-elf
+sh3eb-elf sh3eb-unknown-elf
+sh4eb-elf sh4eb-unknown-elf
+shbe-elf shbe-unknown-elf
+shle-elf shle-unknown-elf
+sh1le-elf sh1le-unknown-elf
+sh2le-elf sh2le-unknown-elf
+sh3le-elf sh3le-unknown-elf
+sh4le-elf sh4le-unknown-elf
+sh3ele-elf sh3ele-unknown-elf
+i386-haiku i386-pc-haiku
+sparc-haiku sparc-unknown-haiku
+powerpc-haiku powerpc-unknown-haiku
+i386-pc-sco6 i386-pc-sco5v6
+i386-pc-sco5v6 i386-pc-sco5v6
+mt mt-unknown-none
+mt-elf mt-unknown-elf
+rdos i386-pc-rdos
+i586-rdos i586-pc-rdos
+i386-linux-newlib i386-pc-linux-newlib
+mb-elf mb-unknown-elf
+microblaze-elf microblaze-unknown-elf
+i386-solidbsd i386-pc-solidbsd
+amd64-kfreebsd5.4-gnu x86_64-pc-kfreebsd5.4-gnu
+nios nios-unknown-none
+nios2 nios2-unknown-none
+nios-elf nios-unknown-elf
+nios2-elf nios2-unknown-elf
+sparcv9v-elf sparcv9v-unknown-elf
+sparc64v-elf sparc64v-unknown-elf
+sparcv9v-solaris2.9 sparcv9v-unknown-solaris2.9
+sparc64v-solaris2.9 sparc64v-unknown-solaris2.9
diff --git a/misc/buildroot/package/gnuconfig/testsuite/config-sub.sh b/misc/buildroot/package/gnuconfig/testsuite/config-sub.sh
new file mode 100644
index 000000000..03b642010
--- /dev/null
+++ b/misc/buildroot/package/gnuconfig/testsuite/config-sub.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# Copyright 2004, 2005 Free Software Foundation, Inc.
+# Contributed by Ben Elliston <bje@gnu.org>.
+#
+# This test reads pairs from config-sub.data: an alias and its
+# canonical triplet. The config.sub scripts is invoked and the test
+# checks that the alias expands to the expected canonical triplet.
+
+verbose=false
+
+function run_config_sub ()
+{
+ rc=0
+ while read alias canonical ; do
+ output=`sh ../config.sub $alias`
+ if test $output != $canonical ; then
+ echo "FAIL: $alias -> $output, but expected $canonical"
+ rc=1
+ else
+ $verbose && echo "PASS: $alias"
+ fi
+ done < config-sub.data
+ return $rc
+}
+
+run_config_sub
+rc=$?
+if test $rc -eq 0 ; then
+ $verbose || echo "PASS: config.sub checks"
+else
+ test $rc -eq 1 && echo "Unexpected failures."
+fi
+
+exit $rc
diff --git a/misc/buildroot/package/gnuconfig/testsuite/uname.in b/misc/buildroot/package/gnuconfig/testsuite/uname.in
new file mode 100755
index 000000000..d44d15f04
--- /dev/null
+++ b/misc/buildroot/package/gnuconfig/testsuite/uname.in
@@ -0,0 +1,9 @@
+#!/bin/sh
+# uname(1) simulator, inspired by Pavel Roskin.
+
+[ $# -ne 1 ] && exec sh $0 -s
+[ $1 = -m ] && echo "@MACHINE@" && exit 0
+[ $1 = -r ] && echo "@RELEASE@" && exit 0
+[ $1 = -s ] && echo "@SYSTEM@" && exit 0
+[ $1 = -v ] && echo "@VERSION@" && exit 0
+[ $1 = -p ] && echo "Pentium III(TM)-ISA/PCI"
diff --git a/misc/buildroot/package/gnuconfig/uname b/misc/buildroot/package/gnuconfig/uname
new file mode 100755
index 000000000..4d2b55d52
--- /dev/null
+++ b/misc/buildroot/package/gnuconfig/uname
@@ -0,0 +1,9 @@
+#!/bin/sh
+# uname(1) simulator, inspired by Pavel Roskin.
+
+[ $# -ne 1 ] && exec sh $0 -s
+[ $1 = -m ] && echo 4400
+[ $1 = -r ] && echo 4.0
+[ $1 = -s ] && echo iainfo2
+[ $1 = -v ] && echo 3.0
+[ $1 = -p ] && echo "Pentium III(TM)-ISA/PCI"
diff --git a/misc/buildroot/toolchain/Config.in b/misc/buildroot/toolchain/Config.in
new file mode 100644
index 000000000..7824dba35
--- /dev/null
+++ b/misc/buildroot/toolchain/Config.in
@@ -0,0 +1,46 @@
+#
+
+menu "Toolchain Options"
+
+source "toolchain/binutils/Config.in"
+source "toolchain/gcc/Config.in"
+source "toolchain/gdb/Config.in"
+source "toolchain/nxflat/Config.in"
+source "toolchain/genromfs/Config.in"
+
+comment "Common Toolchain Options"
+
+source "toolchain/sstrip/Config.in"
+
+config BR2_ENABLE_MULTILIB
+ bool "Enable multilib support?"
+ default n
+ help
+ If you want multilib enabled, enable this...
+
+config BR2_LARGEFILE
+ bool "Enable large file (files > 2 GB) support?"
+ depends on !BR2_cris
+ default y
+ help
+ Enable large file (files > 2 GB) support
+
+config BR2_SOFT_FLOAT
+ bool "Use software floating point by default"
+ default n
+ depends on BR2_arm || BR2_armeb || BR2_mips || BR2_mipsel || BR2_powerpc
+ help
+ If your target CPU does not have a Floating Point Unit (FPU) or a
+ kernel FPU emulator, but you still wish to support floating point
+ functions, then everything will need to be compiled with soft
+ floating point support (-msoft-float).
+
+ Most people will answer N.
+
+config BR2_TARGET_OPTIMIZATION
+ string "Target Optimizations"
+ default "-Os -pipe"
+ help
+ Optimizations to use when building for the target host.
+
+endmenu
diff --git a/misc/buildroot/toolchain/Makefile.in b/misc/buildroot/toolchain/Makefile.in
new file mode 100644
index 000000000..84e2ae42f
--- /dev/null
+++ b/misc/buildroot/toolchain/Makefile.in
@@ -0,0 +1,21 @@
+ifeq ($(BR2_PTHREADS_NONE),y)
+THREADS:=--disable-threads
+else
+THREADS:=--enable-threads
+endif
+
+ifeq ($(BR2_ENABLE_MULTILIB),y)
+MULTILIB:=--enable-multilib
+else
+MULTILIB:=--disable-multilib
+endif
+
+
+# FIXME -- this is temporary
+OPTIMIZE_FOR_CPU=$(ARCH)
+
+# late binding check to see if the target cc supports -fwhole-program
+CFLAGS_WHOLE_PROGRAM = $(call cc-option,-fwhole-program,)
+
+# gcc has a bunch of needed stuff....
+include toolchain/gcc/Makefile.in
diff --git a/misc/buildroot/toolchain/binutils/2.17/110-arm-eabi-conf.patch b/misc/buildroot/toolchain/binutils/2.17/110-arm-eabi-conf.patch
new file mode 100644
index 000000000..be85ceb10
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.17/110-arm-eabi-conf.patch
@@ -0,0 +1,24 @@
+diff -urN binutils-2.16.91.0.7.orig/configure binutils-2.16.91.0.7/configure
+--- binutils-2.16.91.0.7.orig/configure 2006-05-31 14:54:24.000000000 +0300
++++ binutils-2.16.91.0.7/configure 2006-05-31 14:55:53.000000000 +0300
+@@ -1299,7 +1299,7 @@
+ arm-*-elf* | strongarm-*-elf* | xscale-*-elf* | arm*-*-eabi* )
+ noconfigdirs="$noconfigdirs target-libffi target-qthreads"
+ ;;
+- arm*-*-linux-gnueabi)
++ arm*-*-linux-gnueabi | arm*-*-linux-uclibcgnueabi)
+ noconfigdirs="$noconfigdirs target-libffi target-qthreads"
+ noconfigdirs="$noconfigdirs target-libjava target-libobjc"
+ ;;
+diff -urN binutils-2.16.91.0.7.orig/configure.in binutils-2.16.91.0.7/configure.in
+--- binutils-2.16.91.0.7.orig/configure.in 2006-05-31 14:54:24.000000000 +0300
++++ binutils-2.16.91.0.7/configure.in 2006-05-31 14:55:53.000000000 +0300
+@@ -497,7 +497,7 @@
+ arm-*-elf* | strongarm-*-elf* | xscale-*-elf* | arm*-*-eabi* )
+ noconfigdirs="$noconfigdirs target-libffi target-qthreads"
+ ;;
+- arm*-*-linux-gnueabi)
++ arm*-*-linux-gnueabi | arm*-*-linux-uclibcgnueabi)
+ noconfigdirs="$noconfigdirs target-libffi target-qthreads"
+ noconfigdirs="$noconfigdirs target-libjava target-libobjc"
+ ;;
diff --git a/misc/buildroot/toolchain/binutils/2.17/300-001_ld_makefile_patch.patch b/misc/buildroot/toolchain/binutils/2.17/300-001_ld_makefile_patch.patch
new file mode 100644
index 000000000..04a7e61e2
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.17/300-001_ld_makefile_patch.patch
@@ -0,0 +1,50 @@
+#!/bin/sh -e
+## 001_ld_makefile_patch.dpatch
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Description: correct where ld scripts are installed
+## DP: Author: Chris Chimelis <chris@debian.org>
+## DP: Upstream status: N/A
+## DP: Date: ??
+
+if [ $# -ne 1 ]; then
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
+
+case "$1" in
+ -patch) patch $patch_opts -p1 < $0;;
+ -unpatch) patch $patch_opts -p1 -R < $0;;
+ *)
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1;;
+esac
+
+exit 0
+
+@DPATCH@
+--- binutils-2.16.91.0.1/ld/Makefile.am
++++ binutils-2.16.91.0.1/ld/Makefile.am
+@@ -20,7 +20,7 @@
+ # We put the scripts in the directory $(scriptdir)/ldscripts.
+ # We can't put the scripts in $(datadir) because the SEARCH_DIR
+ # directives need to be different for native and cross linkers.
+-scriptdir = $(tooldir)/lib
++scriptdir = $(libdir)
+
+ EMUL = @EMUL@
+ EMULATION_OFILES = @EMULATION_OFILES@
+--- binutils-2.16.91.0.1/ld/Makefile.in
++++ binutils-2.16.91.0.1/ld/Makefile.in
+@@ -268,7 +268,7 @@
+ # We put the scripts in the directory $(scriptdir)/ldscripts.
+ # We can't put the scripts in $(datadir) because the SEARCH_DIR
+ # directives need to be different for native and cross linkers.
+-scriptdir = $(tooldir)/lib
++scriptdir = $(libdir)
+ BASEDIR = $(srcdir)/..
+ BFDDIR = $(BASEDIR)/bfd
+ INCDIR = $(BASEDIR)/include
diff --git a/misc/buildroot/toolchain/binutils/2.17/300-006_better_file_error.patch b/misc/buildroot/toolchain/binutils/2.17/300-006_better_file_error.patch
new file mode 100644
index 000000000..f337611ed
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.17/300-006_better_file_error.patch
@@ -0,0 +1,43 @@
+#!/bin/sh -e
+## 006_better_file_error.dpatch by David Kimdon <dwhedon@gordian.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Specify which filename is causing an error if the filename is a
+## DP: directory. (#45832)
+
+if [ $# -ne 1 ]; then
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
+
+case "$1" in
+ -patch) patch $patch_opts -p1 < $0;;
+ -unpatch) patch $patch_opts -p1 -R < $0;;
+ *)
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1;;
+esac
+
+exit 0
+
+@DPATCH@
+diff -urNad /home/james/debian/packages/binutils/binutils-2.14.90.0.6/bfd/opncls.c binutils-2.14.90.0.6/bfd/opncls.c
+--- /home/james/debian/packages/binutils/binutils-2.14.90.0.6/bfd/opncls.c 2003-07-23 16:08:09.000000000 +0100
++++ binutils-2.14.90.0.6/bfd/opncls.c 2003-09-10 22:35:00.000000000 +0100
+@@ -150,6 +150,13 @@
+ {
+ bfd *nbfd;
+ const bfd_target *target_vec;
++ struct stat s;
++
++ if (stat (filename, &s) == 0)
++ if (S_ISDIR(s.st_mode)) {
++ bfd_set_error (bfd_error_file_not_recognized);
++ return NULL;
++ }
+
+ nbfd = _bfd_new_bfd ();
+ if (nbfd == NULL)
diff --git a/misc/buildroot/toolchain/binutils/2.17/300-012_check_ldrunpath_length.patch b/misc/buildroot/toolchain/binutils/2.17/300-012_check_ldrunpath_length.patch
new file mode 100644
index 000000000..498651a90
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.17/300-012_check_ldrunpath_length.patch
@@ -0,0 +1,47 @@
+#!/bin/sh -e
+## 012_check_ldrunpath_length.dpatch by Chris Chimelis <chris@debian.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Only generate an RPATH entry if LD_RUN_PATH is not empty, for
+## DP: cases where -rpath isn't specified. (#151024)
+
+if [ $# -ne 1 ]; then
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
+
+case "$1" in
+ -patch) patch $patch_opts -p1 < $0;;
+ -unpatch) patch $patch_opts -p1 -R < $0;;
+ *)
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1;;
+esac
+
+exit 0
+
+@DPATCH@
+diff -urNad /home/james/debian/packages/binutils/new/binutils-2.15/ld/emultempl/elf32.em binutils-2.15/ld/emultempl/elf32.em
+--- /home/james/debian/packages/binutils/new/binutils-2.15/ld/emultempl/elf32.em 2004-05-21 23:12:58.000000000 +0100
++++ binutils-2.15/ld/emultempl/elf32.em 2004-05-21 23:12:59.000000000 +0100
+@@ -692,6 +692,8 @@
+ && command_line.rpath == NULL)
+ {
+ lib_path = (const char *) getenv ("LD_RUN_PATH");
++ if ((lib_path) && (strlen (lib_path) == 0))
++ lib_path = NULL;
+ if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
+ force))
+ break;
+@@ -871,6 +873,8 @@
+ rpath = command_line.rpath;
+ if (rpath == NULL)
+ rpath = (const char *) getenv ("LD_RUN_PATH");
++ if ((rpath) && (strlen (rpath) == 0))
++ rpath = NULL;
+ if (! (bfd_elf_size_dynamic_sections
+ (output_bfd, command_line.soname, rpath,
+ command_line.filter_shlib,
diff --git a/misc/buildroot/toolchain/binutils/2.17/400-makeinfo-version-check.patch b/misc/buildroot/toolchain/binutils/2.17/400-makeinfo-version-check.patch
new file mode 100644
index 000000000..8445b608a
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.17/400-makeinfo-version-check.patch
@@ -0,0 +1,12 @@
+diff -up binutils-2.17/configure~ binutils-2.17/configure
+--- binutils-2.17/configure~ 2007-12-02 16:56:59.000000000 +0100
++++ binutils-2.17/configure 2007-12-02 16:56:59.000000000 +0100
+@@ -3637,7 +3637,7 @@ case " $build_configdirs " in
+ # For an installed makeinfo, we require it to be from texinfo 4.4 or
+ # higher, else we use the "missing" dummy.
+ if ${MAKEINFO} --version \
+- | egrep 'texinfo[^0-9]*([1-3][0-9]|4\.[4-9]|[5-9])' >/dev/null 2>&1; then
++ | egrep 'texinfo[^0-9]*([1-3][0-9]|4\.[4-9]|4\.[1-3][0-9]|[5-9])' >/dev/null 2>&1; then
+ :
+ else
+ MAKEINFO="$MISSING makeinfo"
diff --git a/misc/buildroot/toolchain/binutils/2.17/400-mips-ELF_MAXPAGESIZE-4K.patch b/misc/buildroot/toolchain/binutils/2.17/400-mips-ELF_MAXPAGESIZE-4K.patch
new file mode 100644
index 000000000..5959c718d
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.17/400-mips-ELF_MAXPAGESIZE-4K.patch
@@ -0,0 +1,26 @@
+--- binutils/bfd/elf32-mips.c~
++++ binutils/bfd/elf32-mips.c
+@@ -1613,7 +1613,9 @@
+
+ /* The SVR4 MIPS ABI says that this should be 0x10000, and Linux uses
+ page sizes of up to that limit, so we need to respect it. */
+-#define ELF_MAXPAGESIZE 0x10000
++/*#define ELF_MAXPAGESIZE 0x10000*/
++/* Use 4K to shrink the elf header. NOT for general use! */
++#define ELF_MAXPAGESIZE 0x1000
+ #define elf32_bed elf32_tradbed
+
+ /* Include the target file again for this target. */
+--- binutils/bfd/elfn32-mips.c~
++++ binutils/bfd/elfn32-mips.c
+@@ -2399,7 +2399,9 @@
+
+ /* The SVR4 MIPS ABI says that this should be 0x10000, and Linux uses
+ page sizes of up to that limit, so we need to respect it. */
+-#define ELF_MAXPAGESIZE 0x10000
++/*#define ELF_MAXPAGESIZE 0x10000*/
++/* Use 4K to shrink the elf header. NOT for general use! */
++#define ELF_MAXPAGESIZE 0x1000
+ #define elf32_bed elf32_tradbed
+
+ /* Include the target file again for this target. */
diff --git a/misc/buildroot/toolchain/binutils/2.18/100-s12x-20100504.patch b/misc/buildroot/toolchain/binutils/2.18/100-s12x-20100504.patch
new file mode 100644
index 000000000..9c8ff408c
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.18/100-s12x-20100504.patch
@@ -0,0 +1,8646 @@
+diff -u -r -N binutils-2.18/bfd/archures.c binutils-2.18-s12x/bfd/archures.c
+--- binutils-2.18/bfd/archures.c 2007-08-06 20:59:14.000000000 +0100
++++ binutils-2.18-s12x/bfd/archures.c 2008-03-21 13:28:47.000000000 +0000
+@@ -236,6 +236,8 @@
+ .#define bfd_mach_m6812_default 0
+ .#define bfd_mach_m6812 1
+ .#define bfd_mach_m6812s 2
++. bfd_arch_m9s12x, {* Freescale S12X *}
++. bfd_arch_m9s12xg, {* Freescale XGATE *}
+ . bfd_arch_z8k, {* Zilog Z8000 *}
+ .#define bfd_mach_z8001 1
+ .#define bfd_mach_z8002 2
+@@ -462,6 +464,8 @@
+ extern const bfd_arch_info_type bfd_m32r_arch;
+ extern const bfd_arch_info_type bfd_m68hc11_arch;
+ extern const bfd_arch_info_type bfd_m68hc12_arch;
++extern const bfd_arch_info_type bfd_m9s12x_arch;
++extern const bfd_arch_info_type bfd_m9s12xg_arch;
+ extern const bfd_arch_info_type bfd_m68k_arch;
+ extern const bfd_arch_info_type bfd_m88k_arch;
+ extern const bfd_arch_info_type bfd_maxq_arch;
+@@ -533,6 +537,8 @@
+ &bfd_m32r_arch,
+ &bfd_m68hc11_arch,
+ &bfd_m68hc12_arch,
++ &bfd_m9s12x_arch,
++ &bfd_m9s12xg_arch,
+ &bfd_m68k_arch,
+ &bfd_m88k_arch,
+ &bfd_maxq_arch,
+diff -u -r -N binutils-2.18/bfd/bfd-in2.h binutils-2.18-s12x/bfd/bfd-in2.h
+--- binutils-2.18/bfd/bfd-in2.h 2007-08-06 20:59:15.000000000 +0100
++++ binutils-2.18-s12x/bfd/bfd-in2.h 2009-10-08 18:02:09.000000000 +0100
+@@ -1907,6 +1907,8 @@
+ #define bfd_mach_m6812_default 0
+ #define bfd_mach_m6812 1
+ #define bfd_mach_m6812s 2
++ bfd_arch_m9s12x, /* Freescale 9S12X */
++ bfd_arch_m9s12xg, /* Freescale XGATE */
+ bfd_arch_z8k, /* Zilog Z8000 */
+ #define bfd_mach_z8001 1
+ #define bfd_mach_z8002 2
+@@ -2361,6 +2363,8 @@
+ BFD_RELOC_24_PCREL,
+ BFD_RELOC_16_PCREL,
+ BFD_RELOC_12_PCREL,
++ BFD_RELOC_10_PCREL,
++ BFD_RELOC_9_PCREL,
+ BFD_RELOC_8_PCREL,
+
+ /* Section relative relocations. Some targets need this for DWARF2. */
+@@ -4025,6 +4029,10 @@
+ BFD_RELOC_IA64_LTOFF_DTPREL22,
+
+ /* Motorola 68HC11 reloc.
++This is the 8 bit high part of a linktime address */
++ BFD_RELOC_M68HC11_HI8_16,
++
++/* Motorola 68HC11 reloc.
+ This is the 8 bit high part of an absolute address. */
+ BFD_RELOC_M68HC11_HI8,
+
+diff -u -r -N binutils-2.18/bfd/config.bfd binutils-2.18-s12x/bfd/config.bfd
+--- binutils-2.18/bfd/config.bfd 2007-08-28 18:19:33.000000000 +0100
++++ binutils-2.18-s12x/bfd/config.bfd 2008-03-24 22:32:33.000000000 +0000
+@@ -86,6 +86,7 @@
+ i370) targ_archs=bfd_i370_arch ;;
+ m6811*|m68hc11*) targ_archs="bfd_m68hc11_arch bfd_m68hc12_arch" ;;
+ m6812*|m68hc12*) targ_archs="bfd_m68hc12_arch bfd_m68hc11_arch" ;;
++m9s12x*) targ_archs="bfd_m9s12x_arch bfd_m9s12xg_arch bfd_m68hc12_arch bfd_m68hc11_arch" ;;
+ m68*) targ_archs=bfd_m68k_arch ;;
+ m88*) targ_archs=bfd_m88k_arch ;;
+ maxq*) targ_archs=bfd_maxq_arch ;;
+@@ -732,6 +733,11 @@
+ targ_selvecs="bfd_elf32_m68hc11_vec bfd_elf32_m68hc12_vec"
+ ;;
+
++ m9s12x-*-* | m9s12xg-*-*)
++ targ_defvec=bfd_elf32_m68hc12_vec
++ targ_selvecs="bfd_elf32_m9s12xg_vec bfd_elf32_m68hc11_vec bfd_elf32_m68hc12_vec"
++ ;;
++
+ m68*-motorola-sysv*)
+ targ_defvec=m68ksysvcoff_vec
+ ;;
+diff -u -r -N binutils-2.18/bfd/configure binutils-2.18-s12x/bfd/configure
+--- binutils-2.18/bfd/configure 2007-08-28 21:19:51.000000000 +0100
++++ binutils-2.18-s12x/bfd/configure 2008-03-20 19:58:27.000000000 +0000
+@@ -19097,6 +19097,7 @@
+ bfd_elf32_m32rlelin_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
+ bfd_elf32_m68hc11_vec) tb="$tb elf32-m68hc11.lo elf32-m68hc1x.lo elf32.lo $elf" ;;
+ bfd_elf32_m68hc12_vec) tb="$tb elf32-m68hc12.lo elf32-m68hc1x.lo elf32.lo $elf" ;;
++ bfd_elf32_m9s12xg_vec) tb="$tb elf32-m9s12xg.lo elf32-m9s12xg.lo elf32.lo $elf" ;;
+ bfd_elf32_m68k_vec) tb="$tb elf32-m68k.lo elf32.lo $elf" ;;
+ bfd_elf32_m88k_vec) tb="$tb elf32-m88k.lo elf32.lo $elf" ;;
+ bfd_elf32_mcore_big_vec) tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
+diff -u -r -N binutils-2.18/bfd/configure.in binutils-2.18-s12x/bfd/configure.in
+--- binutils-2.18/bfd/configure.in 2007-08-28 21:19:56.000000000 +0100
++++ binutils-2.18-s12x/bfd/configure.in 2008-03-20 19:56:40.000000000 +0000
+@@ -675,6 +675,8 @@
+ bfd_elf32_m32rlelin_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
+ bfd_elf32_m68hc11_vec) tb="$tb elf32-m68hc11.lo elf32-m68hc1x.lo elf32.lo $elf" ;;
+ bfd_elf32_m68hc12_vec) tb="$tb elf32-m68hc12.lo elf32-m68hc1x.lo elf32.lo $elf" ;;
++ bfd_elf32_m9s12x_vec) tb="$tb elf32-m68hc12.lo elf32-m68hc1x.lo elf32.lo $elf" ;;
++ bfd_elf32_m9s12xg_vec) tb="$tb elf32-m9s12xg.lo elf32-m9s12xg.lo elf32.lo $elf" ;;
+ bfd_elf32_m68k_vec) tb="$tb elf32-m68k.lo elf32.lo $elf" ;;
+ bfd_elf32_m88k_vec) tb="$tb elf32-m88k.lo elf32.lo $elf" ;;
+ bfd_elf32_mcore_big_vec) tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
+diff -u -r -N binutils-2.18/bfd/cpu-m9s12x.c binutils-2.18-s12x/bfd/cpu-m9s12x.c
+--- binutils-2.18/bfd/cpu-m9s12x.c 1970-01-01 01:00:00.000000000 +0100
++++ binutils-2.18-s12x/bfd/cpu-m9s12x.c 2008-03-21 13:54:17.000000000 +0000
+@@ -0,0 +1,40 @@
++/* BFD support for the Motorola 9S12X processor
++ Copyright 1999, 2000, 2002, 2003, 2007 Free Software Foundation, Inc.
++
++ This file is part of BFD, the Binary File Descriptor library.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 3 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
++ MA 02110-1301, USA. */
++
++#include "sysdep.h"
++#include "bfd.h"
++#include "libbfd.h"
++
++const bfd_arch_info_type bfd_m9s12x_arch =
++{
++ 16, /* 16 bits in a word */
++ 32, /* 16 bits in an address */
++ 8, /* 8 bits in a byte */
++ bfd_arch_m9s12x,
++ 0,
++ "m9s12x",
++ "m9s12x",
++ 4, /* section alignment power */
++ TRUE,
++ bfd_default_compatible,
++ bfd_default_scan,
++ 0,
++};
++
+diff -u -r -N binutils-2.18/bfd/cpu-m9s12xg.c binutils-2.18-s12x/bfd/cpu-m9s12xg.c
+--- binutils-2.18/bfd/cpu-m9s12xg.c 1970-01-01 01:00:00.000000000 +0100
++++ binutils-2.18-s12x/bfd/cpu-m9s12xg.c 2008-03-24 22:44:17.000000000 +0000
+@@ -0,0 +1,40 @@
++/* BFD support for the Motorola 9S12-XGATE processor
++ Copyright 1999, 2000, 2002, 2003, 2007 Free Software Foundation, Inc.
++
++ This file is part of BFD, the Binary File Descriptor library.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 3 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
++ MA 02110-1301, USA. */
++
++#include "sysdep.h"
++#include "bfd.h"
++#include "libbfd.h"
++
++const bfd_arch_info_type bfd_m9s12xg_arch =
++{
++ 16, /* 16 bits in a word */
++ 32, /* 16 bits in an address */
++ 8, /* 8 bits in a byte */
++ bfd_arch_m9s12xg,
++ 0,
++ "m9s12xg",
++ "m9s12xg",
++ 4, /* section alignment power */
++ TRUE,
++ bfd_default_compatible,
++ bfd_default_scan,
++ 0,
++};
++
+diff -u -r -N binutils-2.18/bfd/elf32-m68hc11.c binutils-2.18-s12x/bfd/elf32-m68hc11.c
+--- binutils-2.18/bfd/elf32-m68hc11.c 2007-08-06 20:59:27.000000000 +0100
++++ binutils-2.18-s12x/bfd/elf32-m68hc11.c 2009-10-08 18:06:37.000000000 +0100
+@@ -274,7 +274,22 @@
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+- EMPTY_HOWTO (14),
++
++ /* A 8 bit absolute relocation (upper address) */
++ HOWTO (R_M68HC11_HI8_16, /* type */
++ 0, /* rightshift */
++ 1, /* size (0 = byte, 1 = short, 2 = long) */ // was 0
++ 16, /* bitsize */ // was 8
++ FALSE, /* pc_relative */
++ 0, /* bitpos */ // was 0
++ complain_overflow_dont, /* complain_on_overflow */
++ bfd_elf_generic_reloc, /* special_function */
++ "R_M68HC11_HI8_16", /* name */
++ FALSE, /* partial_inplace */
++ 0xffff, /* src_mask */
++ 0xffff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
+ EMPTY_HOWTO (15),
+ EMPTY_HOWTO (16),
+ EMPTY_HOWTO (17),
+@@ -340,6 +355,7 @@
+
+ {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
+ {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
++ {BFD_RELOC_M68HC11_HI8_16, R_M68HC11_HI8_16},
+ };
+
+ static reloc_howto_type *
+diff -u -r -N binutils-2.18/bfd/elf32-m68hc12.c binutils-2.18-s12x/bfd/elf32-m68hc12.c
+--- binutils-2.18/bfd/elf32-m68hc12.c 2007-08-06 20:59:27.000000000 +0100
++++ binutils-2.18-s12x/bfd/elf32-m68hc12.c 2009-10-08 18:06:45.000000000 +0100
+@@ -151,7 +151,7 @@
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+- "R_M68HC12_HI8", /* name */
++ "R_M68HC11_HI8", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+@@ -323,7 +323,21 @@
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+- EMPTY_HOWTO (14),
++ /* A 8 bit absolute relocation (upper address) */
++ HOWTO (R_M68HC11_HI8_16, /* type */
++ 0, /* rightshift */
++ 1, /* size (0 = byte, 1 = short, 2 = long) */ // was 0
++ 16, /* bitsize */ // was 8
++ FALSE, /* pc_relative */
++ 0, /* bitpos */ // was 0
++ complain_overflow_dont, /* complain_on_overflow */
++ bfd_elf_generic_reloc, /* special_function */
++ "R_M68HC11_HI8_16", /* name */
++ FALSE, /* partial_inplace */
++ 0xffff, /* src_mask */
++ 0xffff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
+ EMPTY_HOWTO (15),
+ EMPTY_HOWTO (16),
+ EMPTY_HOWTO (17),
+@@ -389,6 +403,7 @@
+
+ {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
+ {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
++ {BFD_RELOC_M68HC11_HI8_16, R_M68HC11_HI8_16},
+ };
+
+ static reloc_howto_type *
+diff -u -r -N binutils-2.18/bfd/elf32-m68hc1x.c binutils-2.18-s12x/bfd/elf32-m68hc1x.c
+--- binutils-2.18/bfd/elf32-m68hc1x.c 2007-08-06 20:59:27.000000000 +0100
++++ binutils-2.18-s12x/bfd/elf32-m68hc1x.c 2009-10-09 14:15:13.000000000 +0100
+@@ -1010,6 +1010,18 @@
+ phys_page = m68hc11_phys_page (pinfo, relocation + rel->r_addend);
+ switch (r_type)
+ {
++ case R_M68HC11_HI8_16:
++ relocation = phys_addr;
++ break;
++ case R_M68HC11_HI8:
++ relocation = phys_addr;
++ break;
++ case R_M68HC11_LO8:
++ /* Reloc generated by %hi(expr) %lo(expr) assembler
++ or XGATE instructions like ld */
++ relocation = phys_addr;
++ break;
++
+ case R_M68HC11_24:
+ /* Reloc used by 68HC12 call instruction. */
+ bfd_put_16 (input_bfd, phys_addr,
+@@ -1104,11 +1116,16 @@
+ relocation = phys_addr;
+ break;
+ }
+- if (r_type != R_M68HC11_NONE)
++ if (r_type != R_M68HC11_NONE) {
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+-
++ }
++ if (r_type == R_M68HC11_HI8_16) {
++ /* now drop a NOP to obscure our 16 bit data */
++ *(unsigned char*)(contents + rel->r_offset +1) = 1; // } NOP
++ *(unsigned char*)(contents + rel->r_offset +2) = 0; // }
++ }
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = (const char *) 0;
+diff -u -r -N binutils-2.18/bfd/elf32-m9s12xg.c binutils-2.18-s12x/bfd/elf32-m9s12xg.c
+--- binutils-2.18/bfd/elf32-m9s12xg.c 1970-01-01 01:00:00.000000000 +0100
++++ binutils-2.18-s12x/bfd/elf32-m9s12xg.c 2009-10-08 18:18:50.000000000 +0100
+@@ -0,0 +1,2597 @@
++/* Motorola 68HCS12XGATE-specific support for 32-bit ELF
++ Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
++ Free Software Foundation, Inc.
++
++James Murray 2008.
++Status: search and replace hc11 -> hcs12xgate
++
++
++ Contributed by Stephane Carrez (stcarrez@nerim.fr)
++ (Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
++
++ This file is part of BFD, the Binary File Descriptor library.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 3 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
++ MA 02110-1301, USA. */
++
++#include "sysdep.h"
++#include "bfd.h"
++#include "bfdlink.h"
++#include "libbfd.h"
++#include "elf-bfd.h"
++#include "elf32-m9s12xg.h"
++#include "elf/m9s12xg.h"
++#include "opcode/m9s12xg.h"
++#include "elf/reloc-macros.h"
++
++// this seems bogus
++#define m9s12xg_stub_hash_lookup(table, string, create, copy) \
++ ((struct elf32_m9s12xg_stub_hash_entry *) \
++ bfd_hash_lookup ((table), (string), (create), (copy)))
++
++static struct bfd_hash_entry *stub_hash_newfunc
++ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
++
++struct m9s12xg_scan_param
++{
++ struct m9s12xg_page_info* pinfo;
++ bfd_boolean use_memory_banks;
++};
++
++static struct elf32_m9s12xg_stub_hash_entry* m9s12xg_add_stub
++ (const char *stub_name,
++ asection *section,
++ struct m9s12xg_elf_link_hash_table *htab);
++
++static bfd_boolean m9s12xg_elf_export_one_stub
++ (struct bfd_hash_entry *gen_entry, void *in_arg);
++
++static void scan_sections_for_abi (bfd*, asection*, PTR);
++
++static void m9s12xg_elf_set_symbol (bfd* abfd, struct bfd_link_info *info,
++ const char* name, bfd_vma value,
++ asection* sec);
++
++/* Relocation functions. */
++static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
++ (bfd *, bfd_reloc_code_real_type);
++static void m9s12xg_info_to_howto_rel
++ (bfd *, arelent *, Elf_Internal_Rela *);
++
++/* Trampoline generation. */
++static bfd_boolean m9s12xg_elf_size_one_stub
++ (struct bfd_hash_entry *gen_entry, void *in_arg);
++static bfd_boolean m9s12xg_elf_build_one_stub
++ (struct bfd_hash_entry *gen_entry, void *in_arg);
++static struct bfd_link_hash_table* m9s12xg_elf_bfd_link_hash_table_create
++ (bfd* abfd);
++
++/* Linker relaxation. */
++static bfd_boolean m9s12xg_elf_relax_section
++ (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
++static void m9s12xg_elf_relax_delete_bytes
++ (bfd *, asection *, bfd_vma, int);
++static void m9s12xg_relax_group
++ (bfd *, asection *, bfd_byte *, unsigned, unsigned long, unsigned long);
++static int compare_reloc (const void *, const void *);
++
++/* Use REL instead of RELA to save space */
++#define USE_REL 1
++
++/* The xgate core addresses 64Kb and does not use banking.
++ Lots of old code remains in this file from hc12 that ought to
++ be deleted.
++ We must handle 8 and 16-bit relocations. The 32-bit relocation
++ are used for debugging sections (DWARF2) to represent a virtual
++ address.
++ The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */
++static reloc_howto_type elf_m9s12xg_howto_table[] = {
++ /* This reloc does nothing. */
++ HOWTO (R_M68HC11_NONE, /* type */
++ 0, /* rightshift */
++ 2, /* size (0 = byte, 1 = short, 2 = long) */
++ 32, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_dont,/* complain_on_overflow */
++ bfd_elf_generic_reloc, /* special_function */
++ "R_M68HC11_NONE", /* name */
++ FALSE, /* partial_inplace */
++ 0, /* src_mask */
++ 0, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* A 8 bit absolute relocation */
++ HOWTO (R_M68HC11_8, /* type */
++ 0, /* rightshift */
++ 0, /* size (0 = byte, 1 = short, 2 = long) */
++ 8, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_bitfield, /* complain_on_overflow */
++ bfd_elf_generic_reloc, /* special_function */
++ "R_M68HC11_8", /* name */
++ FALSE, /* partial_inplace */
++ 0x00ff, /* src_mask */
++ 0x00ff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* A 8 bit absolute relocation (upper address) */
++ HOWTO (R_M68HC11_HI8, /* type */
++ 0, /* rightshift */
++ 1, /* size (0 = byte, 1 = short, 2 = long) */
++ 16, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_dont, /* complain_on_overflow */
++ bfd_elf_generic_reloc, /* special_function */
++ "R_M68HC11_HI8", /* name */
++ FALSE, /* partial_inplace */
++ 0xffff, /* src_mask */
++ 0xffff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* A 8 bit absolute relocation (lower address) */
++ HOWTO (R_M68HC11_LO8, /* type */
++ 0, /* rightshift */
++ 0, /* size (0 = byte, 1 = short, 2 = long) */
++ 8, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_dont, /* complain_on_overflow */
++ bfd_elf_generic_reloc, /* special_function */
++ "R_M68HC11_LO8", /* name */
++ FALSE, /* partial_inplace */
++ 0x00ff, /* src_mask */
++ 0x00ff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* A 8 bit PC-rel relocation */
++ HOWTO (R_M68HC11_PCREL_8, /* type */
++ 0, /* rightshift */
++ 0, /* size (0 = byte, 1 = short, 2 = long) */
++ 8, /* bitsize */
++ TRUE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_bitfield, /* complain_on_overflow */
++ bfd_elf_generic_reloc, /* special_function */
++ "R_M68HC11_PCREL_8", /* name */
++ FALSE, /* partial_inplace */
++ 0x00ff, /* src_mask */
++ 0x00ff, /* dst_mask */
++ TRUE), /* pcrel_offset */
++
++ /* A 16 bit absolute relocation */
++ HOWTO (R_M68HC11_16, /* type */
++ 0, /* rightshift */
++ 1, /* size (0 = byte, 1 = short, 2 = long) */
++ 16, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
++ bfd_elf_generic_reloc, /* special_function */
++ "R_M68HC11_16", /* name */
++ FALSE, /* partial_inplace */
++ 0xffff, /* src_mask */
++ 0xffff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* A 32 bit absolute relocation. This one is never used for the
++ code relocation. It's used by gas for -gstabs generation. */
++ HOWTO (R_M68HC11_32, /* type */
++ 0, /* rightshift */
++ 2, /* size (0 = byte, 1 = short, 2 = long) */
++ 32, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_bitfield, /* complain_on_overflow */
++ bfd_elf_generic_reloc, /* special_function */
++ "R_M68HC11_32", /* name */
++ FALSE, /* partial_inplace */
++ 0xffffffff, /* src_mask */
++ 0xffffffff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* A 3 bit absolute relocation */
++ HOWTO (R_M68HC11_3B, /* type */
++ 0, /* rightshift */
++ 0, /* size (0 = byte, 1 = short, 2 = long) */
++ 3, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_bitfield, /* complain_on_overflow */
++ bfd_elf_generic_reloc, /* special_function */
++ "R_M68HC11_4B", /* name */
++ FALSE, /* partial_inplace */
++ 0x007, /* src_mask */
++ 0x007, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* A 16 bit PC-rel relocation */
++ HOWTO (R_M68HC11_PCREL_16, /* type */
++ 0, /* rightshift */
++ 1, /* size (0 = byte, 1 = short, 2 = long) */
++ 16, /* bitsize */
++ TRUE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_dont, /* complain_on_overflow */
++ bfd_elf_generic_reloc, /* special_function */
++ "R_M68HC11_PCREL_16", /* name */
++ FALSE, /* partial_inplace */
++ 0xffff, /* src_mask */
++ 0xffff, /* dst_mask */
++ TRUE), /* pcrel_offset */
++
++ /* GNU extension to record C++ vtable hierarchy */
++ HOWTO (R_M68HC11_GNU_VTINHERIT, /* type */
++ 0, /* rightshift */
++ 1, /* size (0 = byte, 1 = short, 2 = long) */
++ 0, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_dont, /* complain_on_overflow */
++ NULL, /* special_function */
++ "R_M68HC11_GNU_VTINHERIT", /* name */
++ FALSE, /* partial_inplace */
++ 0, /* src_mask */
++ 0, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* GNU extension to record C++ vtable member usage */
++ HOWTO (R_M68HC11_GNU_VTENTRY, /* type */
++ 0, /* rightshift */
++ 1, /* size (0 = byte, 1 = short, 2 = long) */
++ 0, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_dont, /* complain_on_overflow */
++ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
++ "R_M68HC11_GNU_VTENTRY", /* name */
++ FALSE, /* partial_inplace */
++ 0, /* src_mask */
++ 0, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* A 24 bit relocation */
++ HOWTO (R_M68HC11_24, /* type */
++ 0, /* rightshift */
++ 1, /* size (0 = byte, 1 = short, 2 = long) */
++ 24, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_bitfield, /* complain_on_overflow */
++ bfd_elf_generic_reloc, /* special_function */
++ "R_M68HC11_24", /* name */
++ FALSE, /* partial_inplace */
++ 0xffffff, /* src_mask */
++ 0xffffff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* A 16-bit low relocation */
++ HOWTO (R_M68HC11_LO16, /* type */
++ 0, /* rightshift */
++ 1, /* size (0 = byte, 1 = short, 2 = long) */
++ 16, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_bitfield, /* complain_on_overflow */
++ bfd_elf_generic_reloc, /* special_function */
++ "R_M68HC11_LO16", /* name */
++ FALSE, /* partial_inplace */
++ 0xffff, /* src_mask */
++ 0xffff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* A page relocation */
++ HOWTO (R_M68HC11_PAGE, /* type */
++ 0, /* rightshift */
++ 0, /* size (0 = byte, 1 = short, 2 = long) */
++ 8, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_bitfield, /* complain_on_overflow */
++ bfd_elf_generic_reloc, /* special_function */
++ "R_M68HC11_PAGE", /* name */
++ FALSE, /* partial_inplace */
++ 0x00ff, /* src_mask */
++ 0x00ff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* A 8 bit absolute relocation (upper address) */
++ HOWTO (R_M68HC11_HI8_16, /* type */
++ 0, /* rightshift */
++ 1, /* size (0 = byte, 1 = short, 2 = long) */
++ 16, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_dont, /* complain_on_overflow */
++ bfd_elf_generic_reloc, /* special_function */
++ "R_M68HC11_HI8_16", /* name */
++ FALSE, /* partial_inplace */
++ 0xffff, /* src_mask */
++ 0xffff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ EMPTY_HOWTO (15),
++ EMPTY_HOWTO (16),
++ EMPTY_HOWTO (17),
++ EMPTY_HOWTO (18),
++ EMPTY_HOWTO (19),
++
++ /* Mark beginning of a jump instruction (any form). */
++ HOWTO (R_M68HC11_RL_JUMP, /* type */
++ 0, /* rightshift */
++ 1, /* size (0 = byte, 1 = short, 2 = long) */
++ 0, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_dont, /* complain_on_overflow */
++ m9s12xg_elf_ignore_reloc, /* special_function */
++ "R_M68HC11_RL_JUMP", /* name */
++ TRUE, /* partial_inplace */
++ 0, /* src_mask */
++ 0, /* dst_mask */
++ TRUE), /* pcrel_offset */
++
++ /* Mark beginning of Gcc relaxation group instruction. */
++ HOWTO (R_M68HC11_RL_GROUP, /* type */
++ 0, /* rightshift */
++ 1, /* size (0 = byte, 1 = short, 2 = long) */
++ 0, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_dont, /* complain_on_overflow */
++ m9s12xg_elf_ignore_reloc, /* special_function */
++ "R_M68HC11_RL_GROUP", /* name */
++ TRUE, /* partial_inplace */
++ 0, /* src_mask */
++ 0, /* dst_mask */
++ TRUE), /* pcrel_offset */
++};
++
++/* Map BFD reloc types to m9s12xg ELF reloc types. */
++
++
++struct m9s12xg_reloc_map
++{
++ bfd_reloc_code_real_type bfd_reloc_val;
++ unsigned char elf_reloc_val;
++};
++
++static const struct m9s12xg_reloc_map m9s12xg_reloc_map[] = {
++ {BFD_RELOC_NONE, R_M68HC11_NONE,},
++ {BFD_RELOC_8, R_M68HC11_8},
++ {BFD_RELOC_M68HC11_HI8, R_M68HC11_HI8},
++ {BFD_RELOC_M68HC11_LO8, R_M68HC11_LO8},
++ {BFD_RELOC_8_PCREL, R_M68HC11_PCREL_8},
++ {BFD_RELOC_16_PCREL, R_M68HC11_PCREL_16},
++ {BFD_RELOC_16, R_M68HC11_16},
++ {BFD_RELOC_32, R_M68HC11_32},
++ {BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
++
++ {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
++ {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
++
++ {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
++ {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
++ {BFD_RELOC_M68HC11_24, R_M68HC11_24},
++
++ {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
++ {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
++ {BFD_RELOC_M68HC11_HI8_16, R_M68HC11_HI8_16}
++};
++
++static reloc_howto_type *
++bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
++ bfd_reloc_code_real_type code)
++{
++ unsigned int i;
++
++ for (i = 0;
++ i < sizeof (m9s12xg_reloc_map) / sizeof (struct m9s12xg_reloc_map);
++ i++)
++ {
++ if (m9s12xg_reloc_map[i].bfd_reloc_val == code)
++ return &elf_m9s12xg_howto_table[m9s12xg_reloc_map[i].elf_reloc_val];
++ }
++
++ return NULL;
++}
++
++static reloc_howto_type *
++bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
++ const char *r_name)
++{
++ unsigned int i;
++
++ for (i = 0;
++ i < (sizeof (elf_m9s12xg_howto_table)
++ / sizeof (elf_m9s12xg_howto_table[0]));
++ i++)
++ if (elf_m9s12xg_howto_table[i].name != NULL
++ && strcasecmp (elf_m9s12xg_howto_table[i].name, r_name) == 0)
++ return &elf_m9s12xg_howto_table[i];
++
++ return NULL;
++}
++
++/* Set the howto pointer for an m9s12xg ELF reloc. */
++
++static void
++m9s12xg_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
++ arelent *cache_ptr, Elf_Internal_Rela *dst)
++{
++ unsigned int r_type;
++
++ r_type = ELF32_R_TYPE (dst->r_info);
++ BFD_ASSERT (r_type < (unsigned int) R_M68HC11_max);
++ cache_ptr->howto = &elf_m9s12xg_howto_table[r_type];
++}
++
++
++/* Far trampoline generation. */
++
++/* Build a 68HCS12XGATE trampoline stub. */
++static bfd_boolean
++m9s12xg_elf_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
++{
++ struct elf32_m9s12xg_stub_hash_entry *stub_entry;
++ struct bfd_link_info *info;
++ struct m9s12xg_elf_link_hash_table *htab;
++ asection *stub_sec;
++ bfd *stub_bfd;
++ bfd_byte *loc;
++ bfd_vma sym_value, phys_page, phys_addr;
++
++ /* Massage our args to the form they really have. */
++ stub_entry = (struct elf32_m9s12xg_stub_hash_entry *) gen_entry;
++ info = (struct bfd_link_info *) in_arg;
++
++ htab = m9s12xg_elf_hash_table (info);
++
++ stub_sec = stub_entry->stub_sec;
++
++ /* Make a note of the offset within the stubs for this entry. */
++ stub_entry->stub_offset = stub_sec->size;
++ stub_sec->size += 10;
++ loc = stub_sec->contents + stub_entry->stub_offset;
++
++ stub_bfd = stub_sec->owner;
++
++ /* Create the trampoline call stub:
++
++ pshb
++ ldab #%page(symbol)
++ ldy #%addr(symbol)
++ jmp __trampoline
++
++ */
++ sym_value = (stub_entry->target_value
++ + stub_entry->target_section->output_offset
++ + stub_entry->target_section->output_section->vma);
++ phys_addr = m9s12xg_phys_addr (&htab->pinfo, sym_value);
++ phys_page = m9s12xg_phys_page (&htab->pinfo, sym_value);
++
++ /* pshb; ldab #%page(sym) */
++ bfd_put_8 (stub_bfd, 0x37, loc);
++ bfd_put_8 (stub_bfd, 0xC6, loc + 1);
++ bfd_put_8 (stub_bfd, phys_page, loc + 2);
++ loc += 3;
++
++ /* ldy #%addr(sym) */
++ bfd_put_8 (stub_bfd, 0x18, loc);
++ bfd_put_8 (stub_bfd, 0xCE, loc + 1);
++ bfd_put_16 (stub_bfd, phys_addr, loc + 2);
++ loc += 4;
++
++ /* jmp __trampoline */
++ bfd_put_8 (stub_bfd, 0x7E, loc);
++ bfd_put_16 (stub_bfd, htab->pinfo.trampoline_addr, loc + 1);
++
++ return TRUE;
++}
++
++/* As above, but don't actually build the stub. Just bump offset so
++ we know stub section sizes. */
++
++static bfd_boolean
++m9s12xg_elf_size_one_stub (struct bfd_hash_entry *gen_entry,
++ void *in_arg ATTRIBUTE_UNUSED)
++{
++ struct elf32_m9s12xg_stub_hash_entry *stub_entry;
++
++ /* Massage our args to the form they really have. */
++ stub_entry = (struct elf32_m9s12xg_stub_hash_entry *) gen_entry;
++
++ stub_entry->stub_sec->size += 10;
++ return TRUE;
++}
++
++/* Create a 68HCS12XGATE ELF linker hash table. */
++
++static struct bfd_link_hash_table *
++m9s12xg_elf_bfd_link_hash_table_create (bfd *abfd)
++{
++ struct m9s12xg_elf_link_hash_table *ret;
++
++ ret = m9s12xg_elf_hash_table_create (abfd);
++ if (ret == (struct m9s12xg_elf_link_hash_table *) NULL)
++ return NULL;
++
++ ret->size_one_stub = m9s12xg_elf_size_one_stub;
++ ret->build_one_stub = m9s12xg_elf_build_one_stub;
++
++ return &ret->root.root;
++}
++
++
++/* 68HCS12XGATE Linker Relaxation. */
++/* this probably doesn't make any sense at all with XGATE, but don't even know what it means ! */
++struct m9s12xg_direct_relax
++{
++ const char *name;
++ unsigned char code;
++ unsigned char direct_code;
++} m9s12xg_direct_relax_table[] = {
++ { "adca", 0xB9, 0x99 },
++ { "adcb", 0xF9, 0xD9 },
++ { "adda", 0xBB, 0x9B },
++ { "addb", 0xFB, 0xDB },
++ { "addd", 0xF3, 0xD3 },
++ { "anda", 0xB4, 0x94 },
++ { "andb", 0xF4, 0xD4 },
++ { "cmpa", 0xB1, 0x91 },
++ { "cmpb", 0xF1, 0xD1 },
++ { "cpd", 0xB3, 0x93 },
++ { "cpxy", 0xBC, 0x9C },
++/* { "cpy", 0xBC, 0x9C }, */
++ { "eora", 0xB8, 0x98 },
++ { "eorb", 0xF8, 0xD8 },
++ { "jsr", 0xBD, 0x9D },
++ { "ldaa", 0xB6, 0x96 },
++ { "ldab", 0xF6, 0xD6 },
++ { "ldd", 0xFC, 0xDC },
++ { "lds", 0xBE, 0x9E },
++ { "ldxy", 0xFE, 0xDE },
++ /* { "ldy", 0xFE, 0xDE },*/
++ { "oraa", 0xBA, 0x9A },
++ { "orab", 0xFA, 0xDA },
++ { "sbca", 0xB2, 0x92 },
++ { "sbcb", 0xF2, 0xD2 },
++ { "staa", 0xB7, 0x97 },
++ { "stab", 0xF7, 0xD7 },
++ { "std", 0xFD, 0xDD },
++ { "sts", 0xBF, 0x9F },
++ { "stxy", 0xFF, 0xDF },
++ /* { "sty", 0xFF, 0xDF },*/
++ { "suba", 0xB0, 0x90 },
++ { "subb", 0xF0, 0xD0 },
++ { "subd", 0xB3, 0x93 },
++ { 0, 0, 0 }
++};
++
++static struct m9s12xg_direct_relax *
++find_relaxable_insn (unsigned char code)
++{
++ int i;
++
++ for (i = 0; m9s12xg_direct_relax_table[i].name; i++)
++ if (m9s12xg_direct_relax_table[i].code == code)
++ return &m9s12xg_direct_relax_table[i];
++
++ return 0;
++}
++
++static int
++compare_reloc (const void *e1, const void *e2)
++{
++ const Elf_Internal_Rela *i1 = (const Elf_Internal_Rela *) e1;
++ const Elf_Internal_Rela *i2 = (const Elf_Internal_Rela *) e2;
++
++ if (i1->r_offset == i2->r_offset)
++ return 0;
++ else
++ return i1->r_offset < i2->r_offset ? -1 : 1;
++}
++
++#define M6811_OP_LDX_IMMEDIATE (0xCE)
++
++static void
++m9s12xg_relax_group (bfd *abfd, asection *sec, bfd_byte *contents,
++ unsigned value, unsigned long offset,
++ unsigned long end_group)
++{
++ unsigned char code;
++ unsigned long start_offset;
++ unsigned long ldx_offset = offset;
++ unsigned long ldx_size;
++ int can_delete_ldx;
++ int relax_ldy = 0;
++
++ /* First instruction of the relax group must be a
++ LDX #value or LDY #value. If this is not the case,
++ ignore the relax group. */
++ code = bfd_get_8 (abfd, contents + offset);
++ if (code == 0x18)
++ {
++ relax_ldy++;
++ offset++;
++ code = bfd_get_8 (abfd, contents + offset);
++ }
++ ldx_size = offset - ldx_offset + 3;
++ offset += 3;
++ if (code != M6811_OP_LDX_IMMEDIATE || offset >= end_group)
++ return;
++
++
++ /* We can remove the LDX/LDY only when all bset/brclr instructions
++ of the relax group have been converted to use direct addressing
++ mode. */
++ can_delete_ldx = 1;
++ while (offset < end_group)
++ {
++ unsigned isize;
++ unsigned new_value;
++ int bset_use_y;
++
++ bset_use_y = 0;
++ start_offset = offset;
++ code = bfd_get_8 (abfd, contents + offset);
++ if (code == 0x18)
++ {
++ bset_use_y++;
++ offset++;
++ code = bfd_get_8 (abfd, contents + offset);
++ }
++
++ /* Check the instruction and translate to use direct addressing mode. */
++ switch (code)
++ {
++ /* bset */
++ case 0x1C:
++ code = 0x14;
++ isize = 3;
++ break;
++
++ /* brclr */
++ case 0x1F:
++ code = 0x13;
++ isize = 4;
++ break;
++
++ /* brset */
++ case 0x1E:
++ code = 0x12;
++ isize = 4;
++ break;
++
++ /* bclr */
++ case 0x1D:
++ code = 0x15;
++ isize = 3;
++ break;
++
++ /* This instruction is not recognized and we are not
++ at end of the relax group. Ignore and don't remove
++ the first LDX (we don't know what it is used for...). */
++ default:
++ return;
++ }
++ new_value = (unsigned) bfd_get_8 (abfd, contents + offset + 1);
++ new_value += value;
++ if ((new_value & 0xff00) == 0 && bset_use_y == relax_ldy)
++ {
++ bfd_put_8 (abfd, code, contents + offset);
++ bfd_put_8 (abfd, new_value, contents + offset + 1);
++ if (start_offset != offset)
++ {
++ m9s12xg_elf_relax_delete_bytes (abfd, sec, start_offset,
++ offset - start_offset);
++ end_group--;
++ }
++ }
++ else
++ {
++ can_delete_ldx = 0;
++ }
++ offset = start_offset + isize;
++ }
++ if (can_delete_ldx)
++ {
++ /* Remove the move instruction (3 or 4 bytes win). */
++ m9s12xg_elf_relax_delete_bytes (abfd, sec, ldx_offset, ldx_size);
++ }
++}
++
++/* This function handles relaxing for the 68HCS12XGATE.
++ Not reviewed for XGATE at all, may need removing totally
++
++ and somewhat more difficult to support. */
++
++static bfd_boolean
++m9s12xg_elf_relax_section (bfd *abfd, asection *sec,
++ struct bfd_link_info *link_info, bfd_boolean *again)
++{
++ Elf_Internal_Shdr *symtab_hdr;
++ Elf_Internal_Shdr *shndx_hdr;
++ Elf_Internal_Rela *internal_relocs;
++ Elf_Internal_Rela *free_relocs = NULL;
++ Elf_Internal_Rela *irel, *irelend;
++ bfd_byte *contents = NULL;
++ bfd_byte *free_contents = NULL;
++ Elf32_External_Sym *free_extsyms = NULL;
++ Elf_Internal_Rela *prev_insn_branch = NULL;
++ Elf_Internal_Rela *prev_insn_group = NULL;
++ unsigned insn_group_value = 0;
++ Elf_Internal_Sym *isymbuf = NULL;
++
++ /* Assume nothing changes. */
++ *again = FALSE;
++
++ /* We don't have to do anything for a relocatable link, if
++ this section does not have relocs, or if this is not a
++ code section. */
++ if (link_info->relocatable
++ || (sec->flags & SEC_RELOC) == 0
++ || sec->reloc_count == 0
++ || (sec->flags & SEC_CODE) == 0)
++ return TRUE;
++
++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
++ shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
++
++ /* Get a copy of the native relocations. */
++ internal_relocs = (_bfd_elf_link_read_relocs
++ (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
++ link_info->keep_memory));
++ if (internal_relocs == NULL)
++ goto error_return;
++ if (! link_info->keep_memory)
++ free_relocs = internal_relocs;
++
++ /* Checking for branch relaxation relies on the relocations to
++ be sorted on 'r_offset'. This is not guaranteed so we must sort. */
++ qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
++ compare_reloc);
++
++ /* Walk through them looking for relaxing opportunities. */
++ irelend = internal_relocs + sec->reloc_count;
++ for (irel = internal_relocs; irel < irelend; irel++)
++ {
++ bfd_vma symval;
++ bfd_vma value;
++ Elf_Internal_Sym *isym;
++ asection *sym_sec;
++ int is_far = 0;
++
++ /* If this isn't something that can be relaxed, then ignore
++ this reloc. */
++ if (ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_16
++ && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_JUMP
++ && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_GROUP)
++ {
++ prev_insn_branch = 0;
++ prev_insn_group = 0;
++ continue;
++ }
++
++ /* Get the section contents if we haven't done so already. */
++ if (contents == NULL)
++ {
++ /* Get cached copy if it exists. */
++ if (elf_section_data (sec)->this_hdr.contents != NULL)
++ contents = elf_section_data (sec)->this_hdr.contents;
++ else
++ {
++ /* Go get them off disk. */
++ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
++ goto error_return;
++ }
++ }
++
++ /* Try to eliminate an unconditional 8 bit pc-relative branch
++ which immediately follows a conditional 8 bit pc-relative
++ branch around the unconditional branch.
++
++ original: new:
++ bCC lab1 bCC' lab2
++ bra lab2
++ lab1: lab1:
++
++ This happens when the bCC can't reach lab2 at assembly time,
++ but due to other relaxations it can reach at link time. */
++ if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_JUMP)
++ {
++ Elf_Internal_Rela *nrel;
++ unsigned char code;
++ unsigned char roffset;
++
++ prev_insn_branch = 0;
++ prev_insn_group = 0;
++
++ /* Do nothing if this reloc is the last byte in the section. */
++ if (irel->r_offset + 2 >= sec->size)
++ continue;
++
++ /* See if the next instruction is an unconditional pc-relative
++ branch, more often than not this test will fail, so we
++ test it first to speed things up. */
++ code = bfd_get_8 (abfd, contents + irel->r_offset + 2);
++ if (code != 0x7e)
++ continue;
++
++ /* Also make sure the next relocation applies to the next
++ instruction and that it's a pc-relative 8 bit branch. */
++ nrel = irel + 1;
++ if (nrel == irelend
++ || irel->r_offset + 3 != nrel->r_offset
++ || ELF32_R_TYPE (nrel->r_info) != (int) R_M68HC11_16)
++ continue;
++
++ /* Make sure our destination immediately follows the
++ unconditional branch. */
++ roffset = bfd_get_8 (abfd, contents + irel->r_offset + 1);
++ if (roffset != 3)
++ continue;
++
++ prev_insn_branch = irel;
++ prev_insn_group = 0;
++ continue;
++ }
++
++ /* Read this BFD's symbols if we haven't done so already. */
++ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
++ {
++ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
++ if (isymbuf == NULL)
++ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
++ symtab_hdr->sh_info, 0,
++ NULL, NULL, NULL);
++ if (isymbuf == NULL)
++ goto error_return;
++ }
++
++ /* Get the value of the symbol referred to by the reloc. */
++ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
++ {
++ /* A local symbol. */
++ isym = isymbuf + ELF32_R_SYM (irel->r_info);
++ is_far = isym->st_other & STO_M68HC12_FAR;
++ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
++ symval = (isym->st_value
++ + sym_sec->output_section->vma
++ + sym_sec->output_offset);
++ }
++ else
++ {
++ unsigned long indx;
++ struct elf_link_hash_entry *h;
++
++ /* An external symbol. */
++ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
++ h = elf_sym_hashes (abfd)[indx];
++ BFD_ASSERT (h != NULL);
++ if (h->root.type != bfd_link_hash_defined
++ && h->root.type != bfd_link_hash_defweak)
++ {
++ /* This appears to be a reference to an undefined
++ symbol. Just ignore it--it will be caught by the
++ regular reloc processing. */
++ prev_insn_branch = 0;
++ prev_insn_group = 0;
++ continue;
++ }
++
++ is_far = h->other & STO_M68HC12_FAR;
++ isym = 0;
++ sym_sec = h->root.u.def.section;
++ symval = (h->root.u.def.value
++ + sym_sec->output_section->vma
++ + sym_sec->output_offset);
++ }
++
++ if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_GROUP)
++ {
++ prev_insn_branch = 0;
++ prev_insn_group = 0;
++
++ /* Do nothing if this reloc is the last byte in the section. */
++ if (irel->r_offset == sec->size)
++ continue;
++
++ prev_insn_group = irel;
++ insn_group_value = isym->st_value;
++ continue;
++ }
++
++ /* When we relax some bytes, the size of our section changes.
++ This affects the layout of next input sections that go in our
++ output section. When the symbol is part of another section that
++ will go in the same output section as the current one, it's
++ final address may now be incorrect (too far). We must let the
++ linker re-compute all section offsets before processing this
++ reloc. Code example:
++
++ Initial Final
++ .sect .text section size = 6 section size = 4
++ jmp foo
++ jmp bar
++ .sect .text.foo_bar output_offset = 6 output_offset = 4
++ foo: rts
++ bar: rts
++
++ If we process the reloc now, the jmp bar is replaced by a
++ relative branch to the initial bar address (output_offset 6). */
++ if (*again && sym_sec != sec
++ && sym_sec->output_section == sec->output_section)
++ {
++ prev_insn_group = 0;
++ prev_insn_branch = 0;
++ continue;
++ }
++
++ value = symval;
++ /* Try to turn a far branch to a near branch. */
++ if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
++ && prev_insn_branch)
++ {
++ bfd_vma offset;
++ unsigned char code;
++
++ offset = value - (prev_insn_branch->r_offset
++ + sec->output_section->vma
++ + sec->output_offset + 2);
++
++ /* If the offset is still out of -128..+127 range,
++ leave that far branch unchanged. */
++ if ((offset & 0xff80) != 0 && (offset & 0xff80) != 0xff80)
++ {
++ prev_insn_branch = 0;
++ continue;
++ }
++
++ /* Shrink the branch. */
++ code = bfd_get_8 (abfd, contents + prev_insn_branch->r_offset);
++ if (code == 0x7e)
++ {
++ code = 0x20;
++ bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
++ bfd_put_8 (abfd, 0xff,
++ contents + prev_insn_branch->r_offset + 1);
++ irel->r_offset = prev_insn_branch->r_offset + 1;
++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
++ R_M68XG_PCREL_9);
++ m9s12xg_elf_relax_delete_bytes (abfd, sec,
++ irel->r_offset + 1, 1);
++ }
++ else
++ {
++ code ^= 0x1;
++ bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
++ bfd_put_8 (abfd, 0xff,
++ contents + prev_insn_branch->r_offset + 1);
++ irel->r_offset = prev_insn_branch->r_offset + 1;
++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
++ R_M68XG_PCREL_9);
++ m9s12xg_elf_relax_delete_bytes (abfd, sec,
++ irel->r_offset + 1, 3);
++ }
++ prev_insn_branch = 0;
++ *again = TRUE;
++ }
++
++ /* Try to turn a 16 bit address into a 8 bit page0 address. */
++ else if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
++ && (value & 0xff00) == 0)
++ {
++ unsigned char code;
++ unsigned short offset;
++ struct m9s12xg_direct_relax *rinfo;
++
++ prev_insn_branch = 0;
++ offset = bfd_get_16 (abfd, contents + irel->r_offset);
++ offset += value;
++ if ((offset & 0xff00) != 0)
++ {
++ prev_insn_group = 0;
++ continue;
++ }
++
++ if (prev_insn_group)
++ {
++ unsigned long old_sec_size = sec->size;
++
++ /* Note that we've changed the relocation contents, etc. */
++ elf_section_data (sec)->relocs = internal_relocs;
++ free_relocs = NULL;
++
++ elf_section_data (sec)->this_hdr.contents = contents;
++ free_contents = NULL;
++
++ symtab_hdr->contents = (bfd_byte *) isymbuf;
++ free_extsyms = NULL;
++
++ m9s12xg_relax_group (abfd, sec, contents, offset,
++ prev_insn_group->r_offset,
++ insn_group_value);
++ irel = prev_insn_group;
++ prev_insn_group = 0;
++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
++ R_M68HC11_NONE);
++ if (sec->size != old_sec_size)
++ *again = TRUE;
++ continue;
++ }
++
++ /* Get the opcode. */
++ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
++ rinfo = find_relaxable_insn (code);
++ if (rinfo == 0)
++ {
++ prev_insn_group = 0;
++ continue;
++ }
++
++ /* Note that we've changed the relocation contents, etc. */
++ elf_section_data (sec)->relocs = internal_relocs;
++ free_relocs = NULL;
++
++ elf_section_data (sec)->this_hdr.contents = contents;
++ free_contents = NULL;
++
++ symtab_hdr->contents = (bfd_byte *) isymbuf;
++ free_extsyms = NULL;
++
++ /* Fix the opcode. */
++ /* printf ("A relaxable case : 0x%02x (%s)\n",
++ code, rinfo->name); */
++ bfd_put_8 (abfd, rinfo->direct_code,
++ contents + irel->r_offset - 1);
++
++ /* Delete one byte of data (upper byte of address). */
++ m9s12xg_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 1);
++
++ /* Fix the relocation's type. */
++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
++ R_M68HC11_8);
++
++ /* That will change things, so, we should relax again. */
++ *again = TRUE;
++ }
++ else if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_16 && !is_far)
++ {
++ unsigned char code;
++ bfd_vma offset;
++
++ prev_insn_branch = 0;
++ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
++ if (code == 0x7e || code == 0xbd)
++ {
++ offset = value - (irel->r_offset
++ + sec->output_section->vma
++ + sec->output_offset + 1);
++ offset += bfd_get_16 (abfd, contents + irel->r_offset);
++
++ /* If the offset is still out of -128..+127 range,
++ leave that far branch unchanged. */
++ if ((offset & 0xff80) == 0 || (offset & 0xff80) == 0xff80)
++ {
++
++ /* Note that we've changed the relocation contents, etc. */
++ elf_section_data (sec)->relocs = internal_relocs;
++ free_relocs = NULL;
++
++ elf_section_data (sec)->this_hdr.contents = contents;
++ free_contents = NULL;
++
++ symtab_hdr->contents = (bfd_byte *) isymbuf;
++ free_extsyms = NULL;
++
++ /* Shrink the branch. */
++ code = (code == 0x7e) ? 0x20 : 0x8d;
++ bfd_put_8 (abfd, code,
++ contents + irel->r_offset - 1);
++ bfd_put_8 (abfd, 0xff,
++ contents + irel->r_offset);
++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
++ R_M68XG_PCREL_9);
++ m9s12xg_elf_relax_delete_bytes (abfd, sec,
++ irel->r_offset + 1, 1);
++ /* That will change things, so, we should relax again. */
++ *again = TRUE;
++ }
++ }
++ }
++ prev_insn_branch = 0;
++ prev_insn_group = 0;
++ }
++
++ if (free_relocs != NULL)
++ {
++ free (free_relocs);
++ free_relocs = NULL;
++ }
++
++ if (free_contents != NULL)
++ {
++ if (! link_info->keep_memory)
++ free (free_contents);
++ else
++ {
++ /* Cache the section contents for elf_link_input_bfd. */
++ elf_section_data (sec)->this_hdr.contents = contents;
++ }
++ free_contents = NULL;
++ }
++
++ if (free_extsyms != NULL)
++ {
++ if (! link_info->keep_memory)
++ free (free_extsyms);
++ else
++ {
++ /* Cache the symbols for elf_link_input_bfd. */
++ symtab_hdr->contents = (unsigned char *) isymbuf;
++ }
++ free_extsyms = NULL;
++ }
++
++ return TRUE;
++
++ error_return:
++ if (free_relocs != NULL)
++ free (free_relocs);
++ if (free_contents != NULL)
++ free (free_contents);
++ if (free_extsyms != NULL)
++ free (free_extsyms);
++ return FALSE;
++}
++
++/* Delete some bytes from a section while relaxing. */
++
++static void
++m9s12xg_elf_relax_delete_bytes (bfd *abfd, asection *sec,
++ bfd_vma addr, int count)
++{
++ Elf_Internal_Shdr *symtab_hdr;
++ unsigned int sec_shndx;
++ bfd_byte *contents;
++ Elf_Internal_Rela *irel, *irelend;
++ bfd_vma toaddr;
++ Elf_Internal_Sym *isymbuf, *isym, *isymend;
++ struct elf_link_hash_entry **sym_hashes;
++ struct elf_link_hash_entry **end_hashes;
++ unsigned int symcount;
++
++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
++ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
++
++ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
++
++ contents = elf_section_data (sec)->this_hdr.contents;
++
++ toaddr = sec->size;
++
++ irel = elf_section_data (sec)->relocs;
++ irelend = irel + sec->reloc_count;
++
++ /* Actually delete the bytes. */
++ memmove (contents + addr, contents + addr + count,
++ (size_t) (toaddr - addr - count));
++
++ sec->size -= count;
++
++ /* Adjust all the relocs. */
++ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
++ {
++ unsigned char code;
++ unsigned char offset;
++ unsigned short raddr;
++ unsigned long old_offset;
++ int branch_pos;
++
++ old_offset = irel->r_offset;
++
++ /* See if this reloc was for the bytes we have deleted, in which
++ case we no longer care about it. Don't delete relocs which
++ represent addresses, though. */
++ if (ELF32_R_TYPE (irel->r_info) != R_M68HC11_RL_JUMP
++ && irel->r_offset >= addr && irel->r_offset < addr + count)
++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
++ R_M68HC11_NONE);
++
++ if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_NONE)
++ continue;
++
++ /* Get the new reloc address. */
++ if ((irel->r_offset > addr
++ && irel->r_offset < toaddr))
++ irel->r_offset -= count;
++
++ /* If this is a PC relative reloc, see if the range it covers
++ includes the bytes we have deleted. */
++ switch (ELF32_R_TYPE (irel->r_info))
++ {
++ default:
++ break;
++
++ case R_M68HC11_RL_JUMP:
++ code = bfd_get_8 (abfd, contents + irel->r_offset);
++ switch (code)
++ {
++ /* jsr and jmp instruction are also marked with RL_JUMP
++ relocs but no adjustment must be made. */
++ case 0x7e:
++ case 0x9d:
++ case 0xbd:
++ continue;
++
++ case 0x12:
++ case 0x13:
++ branch_pos = 3;
++ raddr = 4;
++
++ /* Special case when we translate a brclr N,y into brclr *<addr>
++ In this case, the 0x18 page2 prefix is removed.
++ The reloc offset is not modified but the instruction
++ size is reduced by 1. */
++ if (old_offset == addr)
++ raddr++;
++ break;
++
++ case 0x1e:
++ case 0x1f:
++ branch_pos = 3;
++ raddr = 4;
++ break;
++
++ case 0x18:
++ branch_pos = 4;
++ raddr = 5;
++ break;
++
++ default:
++ branch_pos = 1;
++ raddr = 2;
++ break;
++ }
++ offset = bfd_get_8 (abfd, contents + irel->r_offset + branch_pos);
++ raddr += old_offset;
++ raddr += ((unsigned short) offset | ((offset & 0x80) ? 0xff00 : 0));
++ if (irel->r_offset < addr && raddr > addr)
++ {
++ offset -= count;
++ bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
++ }
++ else if (irel->r_offset >= addr && raddr <= addr)
++ {
++ offset += count;
++ bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
++ }
++ else
++ {
++ /*printf ("Not adjusted 0x%04x [0x%4x 0x%4x]\n", raddr,
++ irel->r_offset, addr);*/
++ }
++
++ break;
++ }
++ }
++
++ /* Adjust the local symbols defined in this section. */
++ isymend = isymbuf + symtab_hdr->sh_info;
++ for (isym = isymbuf; isym < isymend; isym++)
++ {
++ if (isym->st_shndx == sec_shndx
++ && isym->st_value > addr
++ && isym->st_value <= toaddr)
++ isym->st_value -= count;
++ }
++
++ /* Now adjust the global symbols defined in this section. */
++ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
++ - symtab_hdr->sh_info);
++ sym_hashes = elf_sym_hashes (abfd);
++ end_hashes = sym_hashes + symcount;
++ for (; sym_hashes < end_hashes; sym_hashes++)
++ {
++ struct elf_link_hash_entry *sym_hash = *sym_hashes;
++ if ((sym_hash->root.type == bfd_link_hash_defined
++ || sym_hash->root.type == bfd_link_hash_defweak)
++ && sym_hash->root.u.def.section == sec
++ && sym_hash->root.u.def.value > addr
++ && sym_hash->root.u.def.value <= toaddr)
++ {
++ sym_hash->root.u.def.value -= count;
++ }
++ }
++}
++
++/* Specific sections:
++ - The .page0 is a data section that is mapped in [0x0000..0x00FF].
++ Page0 accesses are faster on the M68HC11. Soft registers used by GCC-m6811
++ are located in .page0.
++ - The .vectors is the section that represents the interrupt
++ vectors. */
++static const struct bfd_elf_special_section elf32_m9s12xg_special_sections[] =
++{
++ { STRING_COMMA_LEN (".eeprom"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
++ { STRING_COMMA_LEN (".page0"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
++ { STRING_COMMA_LEN (".softregs"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
++ { STRING_COMMA_LEN (".vectors"), 0, SHT_PROGBITS, SHF_ALLOC },
++ { NULL, 0, 0, 0, 0 }
++};
++
++/* sections of code taken from elf32-m68hc1x.c */
++/* Return the physical address seen by the processor, taking
++ into account banked memory. */
++bfd_vma
++m9s12xg_phys_addr (struct m9s12xg_page_info *pinfo, bfd_vma addr)
++{
++ if (addr < pinfo->bank_virtual)
++ return addr;
++
++ /* Map the address to the memory bank. */
++ addr -= pinfo->bank_virtual;
++ addr &= pinfo->bank_mask;
++ addr += pinfo->bank_physical;
++ return addr;
++}
++
++/* Return the page number corresponding to an address in banked memory. */
++bfd_vma
++m9s12xg_phys_page (struct m9s12xg_page_info *pinfo, bfd_vma addr)
++{
++ if (addr < pinfo->bank_virtual)
++ return 0;
++
++ /* Map the address to the memory bank. */
++ addr -= pinfo->bank_virtual;
++ addr >>= pinfo->bank_shift;
++ addr &= 0x0ff;
++ return addr;
++}
++
++/* Hook called by the linker routine which adds symbols from an object
++ file. We use it for identify far symbols and force a loading of
++ the trampoline handler. */
++
++bfd_boolean
++elf32_m9s12xg_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
++ Elf_Internal_Sym *sym,
++ const char **namep ATTRIBUTE_UNUSED,
++ flagword *flagsp ATTRIBUTE_UNUSED,
++ asection **secp ATTRIBUTE_UNUSED,
++ bfd_vma *valp ATTRIBUTE_UNUSED)
++{
++ if (sym->st_other & STO_M68HC12_FAR)
++ {
++ struct elf_link_hash_entry *h;
++
++ h = (struct elf_link_hash_entry *)
++ bfd_link_hash_lookup (info->hash, "__far_trampoline",
++ FALSE, FALSE, FALSE);
++ if (h == NULL)
++ {
++ struct bfd_link_hash_entry* entry = NULL;
++
++ _bfd_generic_link_add_one_symbol (info, abfd,
++ "__far_trampoline",
++ BSF_GLOBAL,
++ bfd_und_section_ptr,
++ (bfd_vma) 0, (const char*) NULL,
++ FALSE, FALSE, &entry);
++ }
++
++ }
++ return TRUE;
++}
++
++/* Look through the relocs for a section during the first phase.
++ Since we don't do .gots or .plts, we just need to consider the
++ virtual table relocs for gc. */
++
++bfd_boolean
++elf32_m9s12xg_check_relocs (bfd *abfd, struct bfd_link_info *info,
++ asection *sec, const Elf_Internal_Rela *relocs)
++{
++ Elf_Internal_Shdr * symtab_hdr;
++ struct elf_link_hash_entry ** sym_hashes;
++ struct elf_link_hash_entry ** sym_hashes_end;
++ const Elf_Internal_Rela * rel;
++ const Elf_Internal_Rela * rel_end;
++
++ if (info->relocatable)
++ return TRUE;
++
++ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
++ sym_hashes = elf_sym_hashes (abfd);
++ sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
++ if (!elf_bad_symtab (abfd))
++ sym_hashes_end -= symtab_hdr->sh_info;
++
++ rel_end = relocs + sec->reloc_count;
++
++ for (rel = relocs; rel < rel_end; rel++)
++ {
++ struct elf_link_hash_entry * h;
++ unsigned long r_symndx;
++
++ r_symndx = ELF32_R_SYM (rel->r_info);
++
++ if (r_symndx < symtab_hdr->sh_info)
++ h = NULL;
++ else
++ {
++ h = sym_hashes [r_symndx - symtab_hdr->sh_info];
++ while (h->root.type == bfd_link_hash_indirect
++ || h->root.type == bfd_link_hash_warning)
++ h = (struct elf_link_hash_entry *) h->root.u.i.link;
++ }
++
++ switch (ELF32_R_TYPE (rel->r_info))
++ {
++ /* This relocation describes the C++ object vtable hierarchy.
++ Reconstruct it for later use during GC. */
++ case R_M68HC11_GNU_VTINHERIT:
++ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
++ return FALSE;
++ break;
++
++ /* This relocation describes which C++ vtable entries are actually
++ used. Record for later use during GC. */
++ case R_M68HC11_GNU_VTENTRY:
++ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
++ return FALSE;
++ break;
++ }
++ }
++
++ return TRUE;
++}
++
++/* Relocate a 68hc11/68hc12 ELF section. */
++/* I don't believe this function is actually used.. uses the one in elf32-m68hc1x.c instead */
++bfd_boolean
++elf32_m9s12xg_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
++ struct bfd_link_info *info,
++ bfd *input_bfd, asection *input_section,
++ bfd_byte *contents, Elf_Internal_Rela *relocs,
++ Elf_Internal_Sym *local_syms,
++ asection **local_sections)
++{
++ Elf_Internal_Shdr *symtab_hdr;
++ struct elf_link_hash_entry **sym_hashes;
++ Elf_Internal_Rela *rel, *relend;
++ const char *name = NULL;
++ struct m9s12xg_page_info *pinfo;
++ const struct elf_backend_data * const ebd = get_elf_backend_data (input_bfd);
++
++ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
++ sym_hashes = elf_sym_hashes (input_bfd);
++
++ /* Get memory bank parameters. */
++ m9s12xg_elf_get_bank_parameters (info);
++ pinfo = &m9s12xg_elf_hash_table (info)->pinfo;
++
++ rel = relocs;
++ relend = relocs + input_section->reloc_count;
++ for (; rel < relend; rel++)
++ {
++ int r_type;
++ arelent arel;
++ reloc_howto_type *howto;
++ unsigned long r_symndx;
++ Elf_Internal_Sym *sym;
++ asection *sec;
++ bfd_vma relocation = 0;
++ bfd_reloc_status_type r = bfd_reloc_undefined;
++ bfd_vma phys_page;
++ bfd_vma phys_addr;
++ bfd_vma insn_addr;
++ bfd_vma insn_page;
++ bfd_boolean is_far = FALSE;
++ struct elf_link_hash_entry *h;
++ const char* stub_name = 0;
++
++ r_symndx = ELF32_R_SYM (rel->r_info);
++ r_type = ELF32_R_TYPE (rel->r_info);
++
++ if (r_type == R_M68HC11_GNU_VTENTRY
++ || r_type == R_M68HC11_GNU_VTINHERIT )
++ continue;
++
++ (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel);
++ howto = arel.howto;
++
++ h = NULL;
++ sym = NULL;
++ sec = NULL;
++ if (r_symndx < symtab_hdr->sh_info)
++ {
++ sym = local_syms + r_symndx;
++ sec = local_sections[r_symndx];
++ relocation = (sec->output_section->vma
++ + sec->output_offset
++ + sym->st_value);
++ is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
++ if (is_far)
++ stub_name = (bfd_elf_string_from_elf_section
++ (input_bfd, symtab_hdr->sh_link,
++ sym->st_name));
++ }
++ else
++ {
++ bfd_boolean unresolved_reloc, warned;
++
++ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
++ r_symndx, symtab_hdr, sym_hashes,
++ h, sec, relocation, unresolved_reloc,
++ warned);
++
++ is_far = (h && (h->other & STO_M68HC12_FAR));
++ stub_name = h->root.root.string;
++ }
++
++ if (sec != NULL && elf_discarded_section (sec))
++ {
++ /* For relocs against symbols from removed linkonce sections,
++ or sections discarded by a linker script, we just want the
++ section contents zeroed. Avoid any special processing. */
++ _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
++ rel->r_info = 0;
++ rel->r_addend = 0;
++ continue;
++ }
++
++ if (info->relocatable)
++ {
++ /* This is a relocatable link. We don't have to change
++ anything, unless the reloc is against a section symbol,
++ in which case we have to adjust according to where the
++ section symbol winds up in the output section. */
++ if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
++ rel->r_addend += sec->output_offset;
++ continue;
++ }
++
++ if (h != NULL)
++ name = h->root.root.string;
++ else
++ {
++ name = (bfd_elf_string_from_elf_section
++ (input_bfd, symtab_hdr->sh_link, sym->st_name));
++ if (name == NULL || *name == '\0')
++ name = bfd_section_name (input_bfd, sec);
++ }
++
++ if (is_far && ELF32_R_TYPE (rel->r_info) == R_M68HC11_16)
++ {
++ struct elf32_m9s12xg_stub_hash_entry* stub;
++ struct m9s12xg_elf_link_hash_table *htab;
++
++ htab = m9s12xg_elf_hash_table (info);
++ stub = m9s12xg_stub_hash_lookup (htab->stub_hash_table,
++ name, FALSE, FALSE);
++ if (stub)
++ {
++ relocation = stub->stub_offset
++ + stub->stub_sec->output_section->vma
++ + stub->stub_sec->output_offset;
++ is_far = FALSE;
++ }
++ }
++
++ /* Do the memory bank mapping. */
++ phys_addr = m9s12xg_phys_addr (pinfo, relocation + rel->r_addend);
++ phys_page = m9s12xg_phys_page (pinfo, relocation + rel->r_addend);
++ switch (r_type)
++ {
++ case R_M68HC11_24:
++ /* Reloc used by 68HC12 call instruction. */
++ bfd_put_16 (input_bfd, phys_addr,
++ (bfd_byte*) contents + rel->r_offset);
++ bfd_put_8 (input_bfd, phys_page,
++ (bfd_byte*) contents + rel->r_offset + 2);
++ r = bfd_reloc_ok;
++ r_type = R_M68HC11_NONE;
++ break;
++
++ case R_M68HC11_NONE:
++ r = bfd_reloc_ok;
++ break;
++
++ case R_M68HC11_LO16:
++ /* Reloc generated by %addr(expr) gas to obtain the
++ address as mapped in the memory bank window. */
++ relocation = phys_addr;
++ break;
++
++ case R_M68HC11_PAGE:
++ /* Reloc generated by %page(expr) gas to obtain the
++ page number associated with the address. */
++ relocation = phys_page;
++ break;
++
++ case R_M68HC11_16:
++ /* Get virtual address of instruction having the relocation. */
++ if (is_far)
++ {
++ const char* msg;
++ char* buf;
++ msg = _("Reference to the far symbol `%s' using a wrong "
++ "relocation may result in incorrect execution");
++ buf = alloca (strlen (msg) + strlen (name) + 10);
++ sprintf (buf, msg, name);
++
++ (* info->callbacks->warning)
++ (info, buf, name, input_bfd, NULL, rel->r_offset);
++ }
++
++ /* Get virtual address of instruction having the relocation. */
++ insn_addr = input_section->output_section->vma
++ + input_section->output_offset
++ + rel->r_offset;
++
++ insn_page = m9s12xg_phys_page (pinfo, insn_addr);
++
++ if (m9s12xg_addr_is_banked (pinfo, relocation + rel->r_addend)
++ && m9s12xg_addr_is_banked (pinfo, insn_addr)
++ && phys_page != insn_page)
++ {
++ const char* msg;
++ char* buf;
++
++ msg = _("banked address [%lx:%04lx] (%lx) is not in the same bank "
++ "as current banked address [%lx:%04lx] (%lx)");
++
++ buf = alloca (strlen (msg) + 128);
++ sprintf (buf, msg, phys_page, phys_addr,
++ (long) (relocation + rel->r_addend),
++ insn_page, m9s12xg_phys_addr (pinfo, insn_addr),
++ (long) (insn_addr));
++ if (!((*info->callbacks->warning)
++ (info, buf, name, input_bfd, input_section,
++ rel->r_offset)))
++ return FALSE;
++ break;
++ }
++ if (phys_page != 0 && insn_page == 0)
++ {
++ const char* msg;
++ char* buf;
++
++ msg = _("reference to a banked address [%lx:%04lx] in the "
++ "normal address space at %04lx");
++
++ buf = alloca (strlen (msg) + 128);
++ sprintf (buf, msg, phys_page, phys_addr, insn_addr);
++ if (!((*info->callbacks->warning)
++ (info, buf, name, input_bfd, input_section,
++ insn_addr)))
++ return FALSE;
++
++ relocation = phys_addr;
++ break;
++ }
++
++ /* If this is a banked address use the phys_addr so that
++ we stay in the banked window. */
++ if (m9s12xg_addr_is_banked (pinfo, relocation + rel->r_addend))
++ relocation = phys_addr;
++ break;
++ }
++ if (r_type != R_M68HC11_NONE)
++ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
++ contents, rel->r_offset,
++ relocation, rel->r_addend);
++
++ if (r != bfd_reloc_ok)
++ {
++ const char * msg = (const char *) 0;
++
++ switch (r)
++ {
++ case bfd_reloc_overflow:
++ if (!((*info->callbacks->reloc_overflow)
++ (info, NULL, name, howto->name, (bfd_vma) 0,
++ input_bfd, input_section, rel->r_offset)))
++ return FALSE;
++ break;
++
++ case bfd_reloc_undefined:
++ if (!((*info->callbacks->undefined_symbol)
++ (info, name, input_bfd, input_section,
++ rel->r_offset, TRUE)))
++ return FALSE;
++ break;
++
++ case bfd_reloc_outofrange:
++ msg = _ ("internal error: out of range error");
++ goto common_error;
++
++ case bfd_reloc_notsupported:
++ msg = _ ("internal error: unsupported relocation error");
++ goto common_error;
++
++ case bfd_reloc_dangerous:
++ msg = _ ("internal error: dangerous error");
++ goto common_error;
++
++ default:
++ msg = _ ("internal error: unknown error");
++ /* fall through */
++
++ common_error:
++ if (!((*info->callbacks->warning)
++ (info, msg, name, input_bfd, input_section,
++ rel->r_offset)))
++ return FALSE;
++ break;
++ }
++ }
++ }
++
++ return TRUE;
++}
++
++/* Merge backend specific data from an object file to the output
++ object file when linking. */
++
++bfd_boolean
++_bfd_m9s12xg_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
++{
++ flagword old_flags;
++ flagword new_flags;
++ bfd_boolean ok = TRUE;
++
++ /* Check if we have the same endianess */
++ if (!_bfd_generic_verify_endian_match (ibfd, obfd))
++ return FALSE;
++
++ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
++ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
++ return TRUE;
++
++ new_flags = elf_elfheader (ibfd)->e_flags;
++ elf_elfheader (obfd)->e_flags |= new_flags & EF_M9S12XG_ABI;
++ old_flags = elf_elfheader (obfd)->e_flags;
++
++ if (! elf_flags_init (obfd))
++ {
++ elf_flags_init (obfd) = TRUE;
++ elf_elfheader (obfd)->e_flags = new_flags;
++ elf_elfheader (obfd)->e_ident[EI_CLASS]
++ = elf_elfheader (ibfd)->e_ident[EI_CLASS];
++
++ if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
++ && bfd_get_arch_info (obfd)->the_default)
++ {
++ if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
++ bfd_get_mach (ibfd)))
++ return FALSE;
++ }
++
++ return TRUE;
++ }
++
++ /* Check ABI compatibility. */
++ if ((new_flags & E_M9S12XG_I32) != (old_flags & E_M9S12XG_I32))
++ {
++ (*_bfd_error_handler)
++ (_("%B: linking files compiled for 16-bit integers (-mshort) "
++ "and others for 32-bit integers"), ibfd);
++ ok = FALSE;
++ }
++ if ((new_flags & E_M9S12XG_F64) != (old_flags & E_M9S12XG_F64))
++ {
++ (*_bfd_error_handler)
++ (_("%B: linking files compiled for 32-bit double (-fshort-double) "
++ "and others for 64-bit double"), ibfd);
++ ok = FALSE;
++ }
++
++ /* Processor compatibility. */
++ if (!EF_M9S12XG_CAN_MERGE_MACH (new_flags, old_flags))
++ {
++ (*_bfd_error_handler)
++ (_("%B: linking files compiled for HCS12 with "
++ "others compiled for HC12"), ibfd);
++ ok = FALSE;
++ }
++ new_flags = ((new_flags & ~EF_M9S12XG_MACH_MASK)
++ | (EF_M9S12XG_MERGE_MACH (new_flags, old_flags)));
++
++ elf_elfheader (obfd)->e_flags = new_flags;
++
++ new_flags &= ~(EF_M9S12XG_ABI | EF_M9S12XG_MACH_MASK);
++ old_flags &= ~(EF_M9S12XG_ABI | EF_M9S12XG_MACH_MASK);
++
++ /* Warn about any other mismatches */
++ if (new_flags != old_flags)
++ {
++ (*_bfd_error_handler)
++ (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
++ ibfd, (unsigned long) new_flags, (unsigned long) old_flags);
++ ok = FALSE;
++ }
++
++ if (! ok)
++ {
++ bfd_set_error (bfd_error_bad_value);
++ return FALSE;
++ }
++
++ return TRUE;
++}
++
++bfd_boolean
++_bfd_m9s12xg_elf_print_private_bfd_data (bfd *abfd, void *ptr)
++{
++ FILE *file = (FILE *) ptr;
++
++ BFD_ASSERT (abfd != NULL && ptr != NULL);
++
++ /* Print normal ELF private data. */
++ _bfd_elf_print_private_bfd_data (abfd, ptr);
++
++ /* xgettext:c-format */
++ fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
++
++ if (elf_elfheader (abfd)->e_flags & E_M9S12XG_I32)
++ fprintf (file, _("[abi=32-bit int, "));
++ else
++ fprintf (file, _("[abi=16-bit int, "));
++
++ if (elf_elfheader (abfd)->e_flags & E_M9S12XG_F64)
++ fprintf (file, _("64-bit double, "));
++ else
++ fprintf (file, _("32-bit double, "));
++
++ if (strcmp (bfd_get_target (abfd), "elf32-m68hc11") == 0)
++ fprintf (file, _("cpu=HC11]"));
++ else if (strcmp (bfd_get_target (abfd), "elf32-m9s12xg") == 0)
++ fprintf (file, _("cpu=M9S12XG]"));
++ else if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH)
++ fprintf (file, _("cpu=HCS12]"));
++ else
++ fprintf (file, _("cpu=HC12]"));
++
++ if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
++ fprintf (file, _(" [memory=bank-model]"));
++ else
++ fprintf (file, _(" [memory=flat]"));
++
++ fputc ('\n', file);
++
++ return TRUE;
++}
++
++/* Set and control ELF flags in ELF header. */
++
++bfd_boolean
++_bfd_m9s12xg_elf_set_private_flags (bfd *abfd, flagword flags)
++{
++ BFD_ASSERT (!elf_flags_init (abfd)
++ || elf_elfheader (abfd)->e_flags == flags);
++
++ elf_elfheader (abfd)->e_flags = flags;
++ elf_flags_init (abfd) = TRUE;
++ return TRUE;
++}
++
++/* This function is used for relocs which are only used for relaxing,
++ which the linker should otherwise ignore. */
++
++bfd_reloc_status_type
++m9s12xg_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
++ arelent *reloc_entry,
++ asymbol *symbol ATTRIBUTE_UNUSED,
++ void *data ATTRIBUTE_UNUSED,
++ asection *input_section,
++ bfd *output_bfd,
++ char **error_message ATTRIBUTE_UNUSED)
++{
++ if (output_bfd != NULL)
++ reloc_entry->address += input_section->output_offset;
++ return bfd_reloc_ok;
++}
++
++/* Return 1 if the address is in banked memory.
++ This can be applied to a virtual address and to a physical address. */
++int
++m9s12xg_addr_is_banked (struct m9s12xg_page_info *pinfo, bfd_vma addr)
++{
++ if (addr >= pinfo->bank_virtual)
++ return 1;
++
++ if (addr >= pinfo->bank_physical && addr <= pinfo->bank_physical_end)
++ return 1;
++
++ return 0;
++}
++
++void
++m9s12xg_elf_get_bank_parameters (struct bfd_link_info *info)
++{
++ unsigned i;
++ struct m9s12xg_page_info *pinfo;
++ struct bfd_link_hash_entry *h;
++
++ pinfo = &m9s12xg_elf_hash_table (info)->pinfo;
++ if (pinfo->bank_param_initialized)
++ return;
++
++ pinfo->bank_virtual = M68HC12_BANK_VIRT;
++ pinfo->bank_mask = M68HC12_BANK_MASK;
++ pinfo->bank_physical = M68HC12_BANK_BASE;
++ pinfo->bank_shift = M68HC12_BANK_SHIFT;
++ pinfo->bank_size = 1 << M68HC12_BANK_SHIFT;
++
++ h = bfd_link_hash_lookup (info->hash, BFD_M9S12XG_BANK_START_NAME,
++ FALSE, FALSE, TRUE);
++ if (h != (struct bfd_link_hash_entry*) NULL
++ && h->type == bfd_link_hash_defined)
++ pinfo->bank_physical = (h->u.def.value
++ + h->u.def.section->output_section->vma
++ + h->u.def.section->output_offset);
++
++ h = bfd_link_hash_lookup (info->hash, BFD_M9S12XG_BANK_VIRTUAL_NAME,
++ FALSE, FALSE, TRUE);
++ if (h != (struct bfd_link_hash_entry*) NULL
++ && h->type == bfd_link_hash_defined)
++ pinfo->bank_virtual = (h->u.def.value
++ + h->u.def.section->output_section->vma
++ + h->u.def.section->output_offset);
++
++ h = bfd_link_hash_lookup (info->hash, BFD_M9S12XG_BANK_SIZE_NAME,
++ FALSE, FALSE, TRUE);
++ if (h != (struct bfd_link_hash_entry*) NULL
++ && h->type == bfd_link_hash_defined)
++ pinfo->bank_size = (h->u.def.value
++ + h->u.def.section->output_section->vma
++ + h->u.def.section->output_offset);
++
++ pinfo->bank_shift = 0;
++ for (i = pinfo->bank_size; i != 0; i >>= 1)
++ pinfo->bank_shift++;
++ pinfo->bank_shift--;
++ pinfo->bank_mask = (1 << pinfo->bank_shift) - 1;
++ pinfo->bank_physical_end = pinfo->bank_physical + pinfo->bank_size;
++ pinfo->bank_param_initialized = 1;
++
++ h = bfd_link_hash_lookup (info->hash, "__far_trampoline", FALSE,
++ FALSE, TRUE);
++ if (h != (struct bfd_link_hash_entry*) NULL
++ && h->type == bfd_link_hash_defined)
++ pinfo->trampoline_addr = (h->u.def.value
++ + h->u.def.section->output_section->vma
++ + h->u.def.section->output_offset);
++}
++
++/* Free the derived linker hash table. */
++
++void
++m9s12xg_elf_bfd_link_hash_table_free (struct bfd_link_hash_table *hash)
++{
++ struct m9s12xg_elf_link_hash_table *ret
++ = (struct m9s12xg_elf_link_hash_table *) hash;
++
++ bfd_hash_table_free (ret->stub_hash_table);
++ free (ret->stub_hash_table);
++ _bfd_generic_link_hash_table_free (hash);
++}
++
++/* Create a 68HC11/68HC12 ELF linker hash table. */
++
++struct m9s12xg_elf_link_hash_table*
++m9s12xg_elf_hash_table_create (bfd *abfd)
++{
++ struct m9s12xg_elf_link_hash_table *ret;
++ bfd_size_type amt = sizeof (struct m9s12xg_elf_link_hash_table);
++
++ ret = (struct m9s12xg_elf_link_hash_table *) bfd_malloc (amt);
++ if (ret == (struct m9s12xg_elf_link_hash_table *) NULL)
++ return NULL;
++
++ memset (ret, 0, amt);
++ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
++ _bfd_elf_link_hash_newfunc,
++ sizeof (struct elf_link_hash_entry)))
++ {
++ free (ret);
++ return NULL;
++ }
++
++ /* Init the stub hash table too. */
++ amt = sizeof (struct bfd_hash_table);
++ ret->stub_hash_table = (struct bfd_hash_table*) bfd_malloc (amt);
++ if (ret->stub_hash_table == NULL)
++ {
++ free (ret);
++ return NULL;
++ }
++ if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc,
++ sizeof (struct elf32_m9s12xg_stub_hash_entry)))
++ return NULL;
++
++ ret->stub_bfd = NULL;
++ ret->stub_section = 0;
++ ret->add_stub_section = NULL;
++ ret->sym_sec.abfd = NULL;
++
++ return ret;
++}
++
++/* Assorted hash table functions. */
++
++/* Initialize an entry in the stub hash table. */
++
++static struct bfd_hash_entry *
++stub_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
++ const char *string)
++{
++ /* Allocate the structure if it has not already been allocated by a
++ subclass. */
++ if (entry == NULL)
++ {
++ entry = bfd_hash_allocate (table,
++ sizeof (struct elf32_m9s12xg_stub_hash_entry));
++ if (entry == NULL)
++ return entry;
++ }
++
++ /* Call the allocation method of the superclass. */
++ entry = bfd_hash_newfunc (entry, table, string);
++ if (entry != NULL)
++ {
++ struct elf32_m9s12xg_stub_hash_entry *eh;
++
++ /* Initialize the local fields. */
++ eh = (struct elf32_m9s12xg_stub_hash_entry *) entry;
++ eh->stub_sec = NULL;
++ eh->stub_offset = 0;
++ eh->target_value = 0;
++ eh->target_section = NULL;
++ }
++
++ return entry;
++}
++
++/* Determine and set the size of the stub section for a final link.
++
++ The basic idea here is to examine all the relocations looking for
++ PC-relative calls to a target that is unreachable with a "bl"
++ instruction. */
++
++bfd_boolean
++elf32_m9s12xg_size_stubs (bfd *output_bfd, bfd *stub_bfd,
++ struct bfd_link_info *info,
++ asection * (*add_stub_section) (const char*, asection*))
++{
++ bfd *input_bfd;
++ asection *section;
++ Elf_Internal_Sym *local_syms, **all_local_syms;
++ unsigned int bfd_indx, bfd_count;
++ bfd_size_type amt;
++ asection *stub_sec;
++
++ struct m9s12xg_elf_link_hash_table *htab = m9s12xg_elf_hash_table (info);
++
++ /* Stash our params away. */
++ htab->stub_bfd = stub_bfd;
++ htab->add_stub_section = add_stub_section;
++
++ /* Count the number of input BFDs and find the top input section id. */
++ for (input_bfd = info->input_bfds, bfd_count = 0;
++ input_bfd != NULL;
++ input_bfd = input_bfd->link_next)
++ {
++ bfd_count += 1;
++ }
++
++ /* We want to read in symbol extension records only once. To do this
++ we need to read in the local symbols in parallel and save them for
++ later use; so hold pointers to the local symbols in an array. */
++ amt = sizeof (Elf_Internal_Sym *) * bfd_count;
++ all_local_syms = (Elf_Internal_Sym **) bfd_zmalloc (amt);
++ if (all_local_syms == NULL)
++ return FALSE;
++
++ /* Walk over all the input BFDs, swapping in local symbols. */
++ for (input_bfd = info->input_bfds, bfd_indx = 0;
++ input_bfd != NULL;
++ input_bfd = input_bfd->link_next, bfd_indx++)
++ {
++ Elf_Internal_Shdr *symtab_hdr;
++
++ /* We'll need the symbol table in a second. */
++ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
++ if (symtab_hdr->sh_info == 0)
++ continue;
++
++ /* We need an array of the local symbols attached to the input bfd. */
++ local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
++ if (local_syms == NULL)
++ {
++ local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
++ symtab_hdr->sh_info, 0,
++ NULL, NULL, NULL);
++ /* Cache them for elf_link_input_bfd. */
++ symtab_hdr->contents = (unsigned char *) local_syms;
++ }
++ if (local_syms == NULL)
++ {
++ free (all_local_syms);
++ return FALSE;
++ }
++
++ all_local_syms[bfd_indx] = local_syms;
++ }
++
++ for (input_bfd = info->input_bfds, bfd_indx = 0;
++ input_bfd != NULL;
++ input_bfd = input_bfd->link_next, bfd_indx++)
++ {
++ Elf_Internal_Shdr *symtab_hdr;
++ Elf_Internal_Sym *local_syms;
++ struct elf_link_hash_entry ** sym_hashes;
++
++ sym_hashes = elf_sym_hashes (input_bfd);
++
++ /* We'll need the symbol table in a second. */
++ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
++ if (symtab_hdr->sh_info == 0)
++ continue;
++
++ local_syms = all_local_syms[bfd_indx];
++
++ /* Walk over each section attached to the input bfd. */
++ for (section = input_bfd->sections;
++ section != NULL;
++ section = section->next)
++ {
++ Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
++
++ /* If there aren't any relocs, then there's nothing more
++ to do. */
++ if ((section->flags & SEC_RELOC) == 0
++ || section->reloc_count == 0)
++ continue;
++
++ /* If this section is a link-once section that will be
++ discarded, then don't create any stubs. */
++ if (section->output_section == NULL
++ || section->output_section->owner != output_bfd)
++ continue;
++
++ /* Get the relocs. */
++ internal_relocs
++ = _bfd_elf_link_read_relocs (input_bfd, section, NULL,
++ (Elf_Internal_Rela *) NULL,
++ info->keep_memory);
++ if (internal_relocs == NULL)
++ goto error_ret_free_local;
++
++ /* Now examine each relocation. */
++ irela = internal_relocs;
++ irelaend = irela + section->reloc_count;
++ for (; irela < irelaend; irela++)
++ {
++ unsigned int r_type, r_indx;
++ struct elf32_m9s12xg_stub_hash_entry *stub_entry;
++ asection *sym_sec;
++ bfd_vma sym_value;
++ struct elf_link_hash_entry *hash;
++ const char *stub_name;
++ Elf_Internal_Sym *sym;
++
++ r_type = ELF32_R_TYPE (irela->r_info);
++
++// /* Only look at 16-bit relocs. */
++// if (r_type != (unsigned int) R_M68HC11_16)
++// continue;
++
++ /* Now determine the call target, its name, value,
++ section. */
++ r_indx = ELF32_R_SYM (irela->r_info);
++ if (r_indx < symtab_hdr->sh_info)
++ {
++ /* It's a local symbol. */
++ Elf_Internal_Shdr *hdr;
++ bfd_boolean is_far;
++
++ sym = local_syms + r_indx;
++ is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
++ if (!is_far)
++ continue;
++
++ hdr = elf_elfsections (input_bfd)[sym->st_shndx];
++ sym_sec = hdr->bfd_section;
++ stub_name = (bfd_elf_string_from_elf_section
++ (input_bfd, symtab_hdr->sh_link,
++ sym->st_name));
++ sym_value = sym->st_value;
++ hash = NULL;
++ }
++ else
++ {
++ /* It's an external symbol. */
++ int e_indx;
++
++ e_indx = r_indx - symtab_hdr->sh_info;
++ hash = (struct elf_link_hash_entry *)
++ (sym_hashes[e_indx]);
++
++ while (hash->root.type == bfd_link_hash_indirect
++ || hash->root.type == bfd_link_hash_warning)
++ hash = ((struct elf_link_hash_entry *)
++ hash->root.u.i.link);
++
++ if (hash->root.type == bfd_link_hash_defined
++ || hash->root.type == bfd_link_hash_defweak
++ || hash->root.type == bfd_link_hash_new)
++ {
++ if (!(hash->other & STO_M68HC12_FAR))
++ continue;
++ }
++ else if (hash->root.type == bfd_link_hash_undefweak)
++ {
++ continue;
++ }
++ else if (hash->root.type == bfd_link_hash_undefined)
++ {
++ continue;
++ }
++ else
++ {
++ bfd_set_error (bfd_error_bad_value);
++ goto error_ret_free_internal;
++ }
++ sym_sec = hash->root.u.def.section;
++ sym_value = hash->root.u.def.value;
++ stub_name = hash->root.root.string;
++ }
++
++ if (!stub_name)
++ goto error_ret_free_internal;
++
++ stub_entry = m9s12xg_stub_hash_lookup
++ (htab->stub_hash_table,
++ stub_name,
++ FALSE, FALSE);
++ if (stub_entry == NULL)
++ {
++ if (add_stub_section == 0)
++ continue;
++
++ stub_entry = m9s12xg_add_stub (stub_name, section, htab);
++ if (stub_entry == NULL)
++ {
++ error_ret_free_internal:
++ if (elf_section_data (section)->relocs == NULL)
++ free (internal_relocs);
++ goto error_ret_free_local;
++ }
++ }
++
++ stub_entry->target_value = sym_value;
++ stub_entry->target_section = sym_sec;
++ }
++
++ /* We're done with the internal relocs, free them. */
++ if (elf_section_data (section)->relocs == NULL)
++ free (internal_relocs);
++ }
++ }
++
++ if (add_stub_section)
++ {
++ /* OK, we've added some stubs. Find out the new size of the
++ stub sections. */
++ for (stub_sec = htab->stub_bfd->sections;
++ stub_sec != NULL;
++ stub_sec = stub_sec->next)
++ {
++ stub_sec->size = 0;
++ }
++
++ bfd_hash_traverse (htab->stub_hash_table, htab->size_one_stub, htab);
++ }
++ free (all_local_syms);
++ return TRUE;
++
++ error_ret_free_local:
++ free (all_local_syms);
++ return FALSE;
++}
++
++/* Build all the stubs associated with the current output file. The
++ stubs are kept in a hash table attached to the main linker hash
++ table. This function is called via m68hc12elf_finish in the
++ linker. */
++
++bfd_boolean
++elf32_m9s12xg_build_stubs (bfd *abfd, struct bfd_link_info *info)
++{
++ asection *stub_sec;
++ struct bfd_hash_table *table;
++ struct m9s12xg_elf_link_hash_table *htab;
++ struct m9s12xg_scan_param param;
++
++ m9s12xg_elf_get_bank_parameters (info);
++ htab = m9s12xg_elf_hash_table (info);
++
++ for (stub_sec = htab->stub_bfd->sections;
++ stub_sec != NULL;
++ stub_sec = stub_sec->next)
++ {
++ bfd_size_type size;
++
++ /* Allocate memory to hold the linker stubs. */
++ size = stub_sec->size;
++ stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size);
++ if (stub_sec->contents == NULL && size != 0)
++ return FALSE;
++ stub_sec->size = 0;
++ }
++
++ /* Build the stubs as directed by the stub hash table. */
++ table = htab->stub_hash_table;
++ bfd_hash_traverse (table, m9s12xg_elf_export_one_stub, info);
++
++ /* Scan the output sections to see if we use the memory banks.
++ If so, export the symbols that define how the memory banks
++ are mapped. This is used by gdb and the simulator to obtain
++ the information. It can be used by programs to burn the eprom
++ at the good addresses. */
++ param.use_memory_banks = FALSE;
++ param.pinfo = &htab->pinfo;
++ bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
++ if (param.use_memory_banks)
++ {
++ m9s12xg_elf_set_symbol (abfd, info, BFD_M9S12XG_BANK_START_NAME,
++ htab->pinfo.bank_physical,
++ bfd_abs_section_ptr);
++ m9s12xg_elf_set_symbol (abfd, info, BFD_M9S12XG_BANK_VIRTUAL_NAME,
++ htab->pinfo.bank_virtual,
++ bfd_abs_section_ptr);
++ m9s12xg_elf_set_symbol (abfd, info, BFD_M9S12XG_BANK_SIZE_NAME,
++ htab->pinfo.bank_size,
++ bfd_abs_section_ptr);
++ }
++
++ return TRUE;
++}
++
++/* External entry points for sizing and building linker stubs. */
++
++/* Set up various things so that we can make a list of input sections
++ for each output section included in the link. Returns -1 on error,
++ 0 when no stubs will be needed, and 1 on success. */
++
++int
++elf32_m9s12xg_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
++{
++ bfd *input_bfd;
++ unsigned int bfd_count;
++ int top_id, top_index;
++ asection *section;
++ asection **input_list, **list;
++ bfd_size_type amt;
++ asection *text_section;
++ struct m9s12xg_elf_link_hash_table *htab;
++
++ htab = m9s12xg_elf_hash_table (info);
++
++ if (htab->root.root.creator->flavour != bfd_target_elf_flavour)
++ return 0;
++
++ /* Count the number of input BFDs and find the top input section id.
++ Also search for an existing ".tramp" section so that we know
++ where generated trampolines must go. Default to ".text" if we
++ can't find it. */
++ htab->tramp_section = 0;
++ text_section = 0;
++ for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
++ input_bfd != NULL;
++ input_bfd = input_bfd->link_next)
++ {
++ bfd_count += 1;
++ for (section = input_bfd->sections;
++ section != NULL;
++ section = section->next)
++ {
++ const char* name = bfd_get_section_name (input_bfd, section);
++
++ if (!strcmp (name, ".tramp"))
++ htab->tramp_section = section;
++
++ if (!strcmp (name, ".text"))
++ text_section = section;
++
++ if (top_id < section->id)
++ top_id = section->id;
++ }
++ }
++ htab->bfd_count = bfd_count;
++ if (htab->tramp_section == 0)
++ htab->tramp_section = text_section;
++
++ /* We can't use output_bfd->section_count here to find the top output
++ section index as some sections may have been removed, and
++ strip_excluded_output_sections doesn't renumber the indices. */
++ for (section = output_bfd->sections, top_index = 0;
++ section != NULL;
++ section = section->next)
++ {
++ if (top_index < section->index)
++ top_index = section->index;
++ }
++
++ htab->top_index = top_index;
++ amt = sizeof (asection *) * (top_index + 1);
++ input_list = (asection **) bfd_malloc (amt);
++ htab->input_list = input_list;
++ if (input_list == NULL)
++ return -1;
++
++ /* For sections we aren't interested in, mark their entries with a
++ value we can check later. */
++ list = input_list + top_index;
++ do
++ *list = bfd_abs_section_ptr;
++ while (list-- != input_list);
++
++ for (section = output_bfd->sections;
++ section != NULL;
++ section = section->next)
++ {
++ if ((section->flags & SEC_CODE) != 0)
++ input_list[section->index] = NULL;
++ }
++
++ return 1;
++}
++
++/* Export the trampoline addresses in the symbol table. */
++static bfd_boolean
++m9s12xg_elf_export_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
++{
++ struct bfd_link_info *info;
++ struct m9s12xg_elf_link_hash_table *htab;
++ struct elf32_m9s12xg_stub_hash_entry *stub_entry;
++ char* name;
++ bfd_boolean result;
++
++ info = (struct bfd_link_info *) in_arg;
++ htab = m9s12xg_elf_hash_table (info);
++
++ /* Massage our args to the form they really have. */
++ stub_entry = (struct elf32_m9s12xg_stub_hash_entry *) gen_entry;
++
++ /* Generate the trampoline according to HC11 or HC12. */
++ result = (* htab->build_one_stub) (gen_entry, in_arg);
++
++ /* Make a printable name that does not conflict with the real function. */
++ name = alloca (strlen (stub_entry->root.string) + 16);
++ sprintf (name, "tramp.%s", stub_entry->root.string);
++
++ /* Export the symbol for debugging/disassembling. */
++ m9s12xg_elf_set_symbol (htab->stub_bfd, info, name,
++ stub_entry->stub_offset,
++ stub_entry->stub_sec);
++ return result;
++}
++
++static void scan_sections_for_abi (bfd *abfd ATTRIBUTE_UNUSED,
++ asection *asect, void *arg)
++{
++ struct m9s12xg_scan_param* p = (struct m9s12xg_scan_param*) arg;
++
++ if (asect->vma >= p->pinfo->bank_virtual)
++ p->use_memory_banks = TRUE;
++}
++
++/* Export a symbol or set its value and section. */
++static void
++m9s12xg_elf_set_symbol (bfd *abfd, struct bfd_link_info *info,
++ const char *name, bfd_vma value, asection *sec)
++{
++ struct elf_link_hash_entry *h;
++
++ h = (struct elf_link_hash_entry *)
++ bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, FALSE);
++ if (h == NULL)
++ {
++ _bfd_generic_link_add_one_symbol (info, abfd,
++ name,
++ BSF_GLOBAL,
++ sec,
++ value,
++ (const char*) NULL,
++ TRUE, FALSE, NULL);
++ }
++ else
++ {
++ h->root.type = bfd_link_hash_defined;
++ h->root.u.def.value = value;
++ h->root.u.def.section = sec;
++ }
++}
++
++/* Add a new stub entry to the stub hash. Not all fields of the new
++ stub entry are initialised. */
++
++static struct elf32_m9s12xg_stub_hash_entry *
++m9s12xg_add_stub (const char *stub_name, asection *section,
++ struct m9s12xg_elf_link_hash_table *htab)
++{
++ struct elf32_m9s12xg_stub_hash_entry *stub_entry;
++
++ /* Enter this entry into the linker stub hash table. */
++ stub_entry = m9s12xg_stub_hash_lookup (htab->stub_hash_table, stub_name,
++ TRUE, FALSE);
++ if (stub_entry == NULL)
++ {
++ (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
++ section->owner, stub_name);
++ return NULL;
++ }
++
++ if (htab->stub_section == 0)
++ {
++ htab->stub_section = (*htab->add_stub_section) (".tramp",
++ htab->tramp_section);
++ }
++
++ stub_entry->stub_sec = htab->stub_section;
++ stub_entry->stub_offset = 0;
++ return stub_entry;
++}
++
++
++/* end sections of code taken from elf32-m68hc1x.c */
++
++#define ELF_ARCH bfd_arch_m9s12xg
++#define ELF_MACHINE_CODE EM_M9S12XG
++#define ELF_MAXPAGESIZE 0x1000
++
++#define TARGET_BIG_SYM bfd_elf32_m9s12xg_vec
++#define TARGET_BIG_NAME "elf32-m9s12xg"
++
++#define elf_info_to_howto 0
++#define elf_info_to_howto_rel m9s12xg_info_to_howto_rel
++#define bfd_elf32_bfd_relax_section m9s12xg_elf_relax_section
++#define elf_backend_check_relocs elf32_m9s12xg_check_relocs
++#define elf_backend_relocate_section elf32_m9s12xg_relocate_section
++#define elf_backend_add_symbol_hook elf32_m9s12xg_add_symbol_hook
++#define elf_backend_object_p 0
++#define elf_backend_final_write_processing 0
++#define elf_backend_can_gc_sections 1
++#define elf_backend_special_sections elf32_m9s12xg_special_sections
++
++#define bfd_elf32_bfd_link_hash_table_create \
++ m9s12xg_elf_bfd_link_hash_table_create
++#define bfd_elf32_bfd_link_hash_table_free \
++ m9s12xg_elf_bfd_link_hash_table_free
++#define bfd_elf32_bfd_merge_private_bfd_data \
++ _bfd_m9s12xg_elf_merge_private_bfd_data
++#define bfd_elf32_bfd_set_private_flags _bfd_m9s12xg_elf_set_private_flags
++#define bfd_elf32_bfd_print_private_bfd_data \
++ _bfd_m9s12xg_elf_print_private_bfd_data
++
++#include "elf32-target.h"
+diff -u -r -N binutils-2.18/bfd/elf32-m9s12xg.h binutils-2.18-s12x/bfd/elf32-m9s12xg.h
+--- binutils-2.18/bfd/elf32-m9s12xg.h 1970-01-01 01:00:00.000000000 +0100
++++ binutils-2.18-s12x/bfd/elf32-m9s12xg.h 2008-03-20 19:57:49.000000000 +0000
+@@ -0,0 +1,188 @@
++/* Motorola 68HCS12XGATE/68HC12-specific support for 32-bit ELF
++ Copyright 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
++ Contributed by Stephane Carrez (stcarrez@nerim.fr)
++
++ This file is part of BFD, the Binary File Descriptor library.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 3 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
++ MA 02110-1301, USA. */
++
++#ifndef _ELF32_M9S12XG_H
++#define _ELF32_M9S12XG_H
++
++#include "elf-bfd.h"
++#include "bfdlink.h"
++#include "elf/m9s12xg.h"
++
++/* Name of symbols exported by HCS12XGATE/HC12 linker when there is a memory
++ bank window. */
++#define BFD_M9S12XG_BANK_START_NAME "__bank_start"
++#define BFD_M9S12XG_BANK_SIZE_NAME "__bank_size"
++#define BFD_M9S12XG_BANK_VIRTUAL_NAME "__bank_virtual"
++
++/* Set and control ELF flags in ELF header. */
++extern bfd_boolean _bfd_m9s12xg_elf_merge_private_bfd_data (bfd*,bfd*);
++extern bfd_boolean _bfd_m9s12xg_elf_set_private_flags (bfd*,flagword);
++extern bfd_boolean _bfd_m9s12xg_elf_print_private_bfd_data (bfd*, void*);
++
++/* This hash entry is used to record a trampoline that must be generated
++ to call a far function using a normal calling convention ('jsr').
++ The trampoline is used when a pointer to a far function is used.
++ It takes care of installing the proper memory bank as well as creating
++ the 'call/rtc' calling convention. */
++struct elf32_m9s12xg_stub_hash_entry {
++
++ /* Base hash table entry structure. */
++ struct bfd_hash_entry root;
++
++ /* The stub section. */
++ asection *stub_sec;
++
++ /* Offset within stub_sec of the beginning of this stub. */
++ bfd_vma stub_offset;
++
++ /* Given the symbol's value and its section we can determine its final
++ value when building the stubs (so the stub knows where to jump. */
++ bfd_vma target_value;
++ asection *target_section;
++};
++
++/* Placeholder for the parameters to compute memory page and physical address.
++ The following formulas are used:
++
++ sym > bank_virtual =>
++ %addr(sym) = (((sym - bank_virtual) & bank_mask) + bank_physical
++ %page(sym) = (((sym - bank_virtual) >> bank_shift) % 256
++
++ sym < bank_virtual =>
++ %addr(sym) = sym
++ %page(sym) = 0
++
++
++ These parameters are obtained from the symbol table by looking
++ at the following:
++
++ __bank_start Symbol marking the start of memory bank window
++ (bank_physical)
++ __bank_virtual Logical address of symbols for which the transformation
++ must be computed
++ __bank_page_size Size in bytes of page size (this is *NOT* the memory
++ bank window size and the window size is always
++ less or equal to the page size)
++
++ For 68HCS12, the window is at 0x8000 and the page size is 16K (full window).
++
++*/
++struct m9s12xg_page_info
++{
++ bfd_vma bank_virtual;
++ bfd_vma bank_physical;
++ bfd_vma bank_physical_end;
++ bfd_vma bank_mask;
++ bfd_vma bank_size;
++ int bank_shift;
++ int bank_param_initialized;
++ bfd_vma trampoline_addr;
++};
++
++struct m9s12xg_elf_link_hash_table
++{
++ struct elf_link_hash_table root;
++ struct m9s12xg_page_info pinfo;
++
++ /* The stub hash table. */
++ struct bfd_hash_table* stub_hash_table;
++
++ /* Linker stub bfd. */
++ bfd *stub_bfd;
++
++ asection* stub_section;
++ asection* tramp_section;
++
++ /* Linker call-backs. */
++ asection * (*add_stub_section) PARAMS ((const char *, asection *));
++
++ /* Assorted information used by elf32_hppa_size_stubs. */
++ unsigned int bfd_count;
++ int top_index;
++ asection **input_list;
++
++ /* Small local sym to section mapping cache. */
++ struct sym_sec_cache sym_sec;
++
++ bfd_boolean (* size_one_stub) PARAMS((struct bfd_hash_entry*, void*));
++ bfd_boolean (* build_one_stub) PARAMS((struct bfd_hash_entry*, void*));
++};
++
++/* Get the Sparc64 ELF linker hash table from a link_info structure. */
++
++#define m9s12xg_elf_hash_table(p) \
++ ((struct m9s12xg_elf_link_hash_table *) ((p)->hash))
++
++/* Create a 68HCS12XGATE ELF linker hash table. */
++
++extern struct m9s12xg_elf_link_hash_table* m9s12xg_elf_hash_table_create
++ (bfd*);
++extern void m9s12xg_elf_bfd_link_hash_table_free (struct bfd_link_hash_table*);
++
++extern void m9s12xg_elf_get_bank_parameters (struct bfd_link_info*);
++
++/* Return 1 if the address is in banked memory.
++ This can be applied to a virtual address and to a physical address. */
++extern int m9s12xg_addr_is_banked (struct m9s12xg_page_info*, bfd_vma);
++
++/* Return the physical address seen by the processor, taking
++ into account banked memory. */
++extern bfd_vma m9s12xg_phys_addr (struct m9s12xg_page_info*, bfd_vma);
++
++/* Return the page number corresponding to an address in banked memory. */
++extern bfd_vma m9s12xg_phys_page (struct m9s12xg_page_info*, bfd_vma);
++
++bfd_reloc_status_type m9s12xg_elf_ignore_reloc
++ (bfd *abfd, arelent *reloc_entry,
++ asymbol *symbol, void *data, asection *input_section,
++ bfd *output_bfd, char **error_message);
++bfd_reloc_status_type m9s12xg_elf_special_reloc
++ (bfd *abfd, arelent *reloc_entry,
++ asymbol *symbol, void *data, asection *input_section,
++ bfd *output_bfd, char **error_message);
++
++bfd_boolean elf32_m9s12xg_check_relocs
++ (bfd * abfd, struct bfd_link_info * info,
++ asection * sec, const Elf_Internal_Rela * relocs);
++bfd_boolean elf32_m9s12xg_relocate_section
++ (bfd *output_bfd, struct bfd_link_info *info,
++ bfd *input_bfd, asection *input_section,
++ bfd_byte *contents, Elf_Internal_Rela *relocs,
++ Elf_Internal_Sym *local_syms, asection **local_sections);
++
++bfd_boolean elf32_m9s12xg_add_symbol_hook
++ (bfd *abfd, struct bfd_link_info *info,
++ Elf_Internal_Sym *sym, const char **namep,
++ flagword *flagsp, asection **secp,
++ bfd_vma *valp);
++
++/* Tweak the OSABI field of the elf header. */
++
++extern void elf32_m9s12xg_post_process_headers (bfd*, struct bfd_link_info*);
++
++int elf32_m9s12xg_setup_section_lists (bfd *, struct bfd_link_info *);
++
++bfd_boolean elf32_m9s12xg_size_stubs
++ (bfd *, bfd *, struct bfd_link_info *,
++ asection * (*) (const char *, asection *));
++
++bfd_boolean elf32_m9s12xg_build_stubs (bfd* abfd, struct bfd_link_info *);
++#endif
+diff -u -r -N binutils-2.18/bfd/libbfd.h binutils-2.18-s12x/bfd/libbfd.h
+--- binutils-2.18/bfd/libbfd.h 2007-08-06 20:59:37.000000000 +0100
++++ binutils-2.18-s12x/bfd/libbfd.h 2008-02-26 22:14:32.000000000 +0000
+@@ -800,6 +800,8 @@
+ "BFD_RELOC_24_PCREL",
+ "BFD_RELOC_16_PCREL",
+ "BFD_RELOC_12_PCREL",
++ "BFD_RELOC_10_PCREL",
++ "BFD_RELOC_9_PCREL",
+ "BFD_RELOC_8_PCREL",
+ "BFD_RELOC_32_SECREL",
+ "BFD_RELOC_32_GOT_PCREL",
+diff -u -r -N binutils-2.18/bfd/Makefile.in binutils-2.18-s12x/bfd/Makefile.in
+--- binutils-2.18/bfd/Makefile.in 2007-08-28 21:20:12.000000000 +0100
++++ binutils-2.18-s12x/bfd/Makefile.in 2008-03-20 19:55:49.000000000 +0000
+@@ -336,6 +336,8 @@
+ cpu-m32r.lo \
+ cpu-m68hc11.lo \
+ cpu-m68hc12.lo \
++ cpu-m9s12x.lo \
++ cpu-m9s12xg.lo \
+ cpu-m68k.lo \
+ cpu-m88k.lo \
+ cpu-m10200.lo \
+@@ -402,6 +404,8 @@
+ cpu-m32r.c \
+ cpu-m68hc11.c \
+ cpu-m68hc12.c \
++ cpu-m9s12x.c \
++ cpu-m9s12xg.c \
+ cpu-m68k.c \
+ cpu-m88k.c \
+ cpu-m10200.c \
+@@ -517,6 +521,7 @@
+ elf32-m68hc11.lo \
+ elf32-m68hc12.lo \
+ elf32-m68hc1x.lo \
++ elf32-m9s12xg.lo \
+ elf32-m68k.lo \
+ elf32-m88k.lo \
+ elf-m10200.lo \
+@@ -697,6 +702,7 @@
+ elf32-m68hc11.c \
+ elf32-m68hc12.c \
+ elf32-m68hc1x.c \
++ elf32-m9s12xg.c \
+ elf32-m88k.c \
+ elf-m10200.c \
+ elf-m10300.c \
+@@ -1666,6 +1672,10 @@
+ $(INCDIR)/hashtab.h
+ cpu-m68hc12.lo: cpu-m68hc12.c $(INCDIR)/filenames.h \
+ $(INCDIR)/hashtab.h
++cpu-m9s12x.lo: cpu-m9s12x.c $(INCDIR)/filenames.h \
++ $(INCDIR)/hashtab.h
++cpu-m9s12xg.lo: cpu-m9s12xg.c $(INCDIR)/filenames.h \
++ $(INCDIR)/hashtab.h
+ cpu-m68k.lo: cpu-m68k.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
+ $(INCDIR)/opcode/m68k.h
+ cpu-m88k.lo: cpu-m88k.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
+@@ -2007,6 +2017,11 @@
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h elf32-m68hc1x.h \
+ $(INCDIR)/elf/m68hc11.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/opcode/m68hc11.h
++elf32-m9s12xg.lo: elf32-m9s12xg.c $(INCDIR)/filenames.h \
++ $(INCDIR)/bfdlink.h $(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
++ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h elf32-m9s12xg.h \
++ $(INCDIR)/elf/m9s12xg.h $(INCDIR)/elf/reloc-macros.h \
++ $(INCDIR)/opcode/m9s12xg.h elf32-target.h
+ elf32-m88k.lo: elf32-m88k.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
+ elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h elf32-target.h
+diff -u -r -N binutils-2.18/bfd/targets.c binutils-2.18-s12x/bfd/targets.c
+--- binutils-2.18/bfd/targets.c 2007-08-06 20:59:42.000000000 +0100
++++ binutils-2.18-s12x/bfd/targets.c 2008-03-20 19:58:10.000000000 +0000
+@@ -612,6 +612,7 @@
+ extern const bfd_target bfd_elf32_m32rlelin_vec;
+ extern const bfd_target bfd_elf32_m68hc11_vec;
+ extern const bfd_target bfd_elf32_m68hc12_vec;
++extern const bfd_target bfd_elf32_m9s12xg_vec;
+ extern const bfd_target bfd_elf32_m68k_vec;
+ extern const bfd_target bfd_elf32_m88k_vec;
+ extern const bfd_target bfd_elf32_mcore_big_vec;
+@@ -941,6 +942,7 @@
+ &bfd_elf32_m32rlelin_vec,
+ &bfd_elf32_m68hc11_vec,
+ &bfd_elf32_m68hc12_vec,
++ &bfd_elf32_m9s12xg_vec,
+ &bfd_elf32_m68k_vec,
+ &bfd_elf32_m88k_vec,
+ &bfd_elf32_mcore_big_vec,
+diff -u -r -N binutils-2.18/bfd/version.h binutils-2.18-s12x/bfd/version.h
+--- binutils-2.18/bfd/version.h 2007-08-28 18:19:33.000000000 +0100
++++ binutils-2.18-s12x/bfd/version.h 2010-05-04 11:52:37.000000000 +0100
+@@ -1,4 +1,4 @@
+-#define BFD_VERSION_DATE 20070828
++#define BFD_VERSION_DATE 20100504
+ #define BFD_VERSION @bfd_version@
+ #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@
+ #define REPORT_BUGS_TO @report_bugs_to@
+diff -u -r -N binutils-2.18/binutils/readelf.c binutils-2.18-s12x/binutils/readelf.c
+--- binutils-2.18/binutils/readelf.c 2007-08-28 18:19:34.000000000 +0100
++++ binutils-2.18-s12x/binutils/readelf.c 2008-03-21 13:58:35.000000000 +0000
+@@ -665,6 +665,7 @@
+ case EM_68HC05:
+ case EM_68HC08:
+ case EM_68HC11:
++ case EM_M9S12XG:
+ case EM_68HC16:
+ case EM_FX66:
+ case EM_ME16:
+@@ -990,6 +991,7 @@
+
+ case EM_68HC11:
+ case EM_68HC12:
++ case EM_M9S12XG:
+ rtype = elf_m68hc11_reloc_type (type);
+ break;
+
+@@ -1724,7 +1726,7 @@
+ case EM_IA_64: return "Intel IA-64";
+ case EM_MIPS_X: return "Stanford MIPS-X";
+ case EM_COLDFIRE: return "Motorola Coldfire";
+- case EM_68HC12: return "Motorola M68HC12";
++
+ case EM_ALPHA: return "Alpha";
+ case EM_CYGNUS_D10V:
+ case EM_D10V: return "d10v";
+@@ -1755,6 +1757,8 @@
+ case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
+ case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
+ case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
++ case EM_M9S12XG: return "Freescale 9S12X-XGATE";
++ case EM_68HC12: return "Motorola M68HC12";
+ case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
+ case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
+ case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
+diff -u -r -N binutils-2.18/binutils/version.c binutils-2.18-s12x/binutils/version.c
+--- binutils-2.18/binutils/version.c 2007-08-06 20:56:15.000000000 +0100
++++ binutils-2.18-s12x/binutils/version.c 2010-05-04 11:53:24.000000000 +0100
+@@ -37,5 +37,6 @@
+ This program is free software; you may redistribute it under the terms of\n\
+ the GNU General Public License version 3 or (at your option) any later version.\n\
+ This program has absolutely no warranty.\n"));
++ printf (_("9S12X patch 20100504\n"));
+ exit (0);
+ }
+diff -u -r -N binutils-2.18/config.sub binutils-2.18-s12x/config.sub
+--- binutils-2.18/config.sub 2007-08-06 21:00:30.000000000 +0100
++++ binutils-2.18-s12x/config.sub 2008-03-21 14:08:52.000000000 +0000
+@@ -250,6 +250,7 @@
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \
++ | m9s12x \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+diff -u -r -N binutils-2.18/configure binutils-2.18-s12x/configure
+--- binutils-2.18/configure 2007-08-06 21:29:40.000000000 +0100
++++ binutils-2.18-s12x/configure 2008-03-21 14:08:08.000000000 +0000
+@@ -2418,7 +2418,7 @@
+ m32r-*-*)
+ noconfigdirs="$noconfigdirs ${libgcj}"
+ ;;
+- m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
++ m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*|m9s12x-*-*)
+ noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj}"
+ ;;
+ m68k-*-elf*)
+@@ -6128,7 +6128,7 @@
+ # For an installed makeinfo, we require it to be from texinfo 4.4 or
+ # higher, else we use the "missing" dummy.
+ if ${MAKEINFO} --version \
+- | egrep 'texinfo[^0-9]*([1-3][0-9]|4\.[4-9]|[5-9])' >/dev/null 2>&1; then
++ | egrep 'texinfo[^0-9]*(4\.([6-9]|[1-9][0-9])|[5-9]|[1-9][0-9])' >/dev/null 2>&1; then
+ :
+ else
+ MAKEINFO="$MISSING makeinfo"
+diff -u -r -N binutils-2.18/configure.ac binutils-2.18-s12x/configure.ac
+--- binutils-2.18/configure.ac 2007-08-28 21:24:26.000000000 +0100
++++ binutils-2.18-s12x/configure.ac 2008-03-08 13:44:14.000000000 +0000
+@@ -2403,7 +2403,7 @@
+ # For an installed makeinfo, we require it to be from texinfo 4.4 or
+ # higher, else we use the "missing" dummy.
+ if ${MAKEINFO} --version \
+- | egrep 'texinfo[^0-9]*([1-3][0-9]|4\.[4-9]|[5-9])' >/dev/null 2>&1; then
++ | egrep 'texinfo[^0-9]*(4\.([6-9]|[1-9][0-9])|[5-9]|[1-9][0-9])' >/dev/null 2>&1; then
+ :
+ else
+ MAKEINFO="$MISSING makeinfo"
+diff -u -r -N binutils-2.18/gas/config/tc-m68hc11.c binutils-2.18-s12x/gas/config/tc-m68hc11.c
+--- binutils-2.18/gas/config/tc-m68hc11.c 2007-08-06 20:59:59.000000000 +0100
++++ binutils-2.18-s12x/gas/config/tc-m68hc11.c 2010-05-04 11:51:42.000000000 +0100
+@@ -2,6 +2,7 @@
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
+ Written by Stephane Carrez (stcarrez@nerim.fr)
++ XGATE and S12X added by James Murray (jsm@jsm-net.demon.co.uk)
+
+ This file is part of GAS, the GNU Assembler.
+
+@@ -125,7 +126,18 @@
+ REG_X = 5,
+ REG_Y = 6,
+ REG_SP = 7,
+- REG_PC = 8
++ REG_PC = 8,
++ REG_R0 = 0,
++ REG_R1 = 1,
++ REG_R2 = 2,
++ REG_R3 = 3,
++ REG_R4 = 4,
++ REG_R5 = 5,
++ REG_R6 = 6,
++ REG_R7 = 7,
++ REG_SP_XG = 8,
++ REG_PC_XG = 9,
++ REG_CCR_XG = 10
+ } register_id;
+
+ typedef struct operand {
+@@ -159,6 +171,15 @@
+ {0, 0}
+ };
+
++struct m9s12xg_opcode_def {
++ long format;
++ int min_operands;
++ int max_operands;
++ int nb_modes;
++ int used;
++ struct m9s12xg_opcode *opcode;
++};
++
+ /* Local functions. */
+ static register_id reg_name_search (char *);
+ static register_id register_name (void);
+@@ -173,6 +194,8 @@
+ static void fixup8 (expressionS *, int, int);
+ static void fixup16 (expressionS *, int, int);
+ static void fixup24 (expressionS *, int, int);
++static void fixup8_xg (expressionS *, int, int);
++static void fixup16_xg (expressionS *, int, int);
+ static unsigned char convert_branch (unsigned char);
+ static char *m68hc11_new_insn (int);
+ static void build_dbranch_insn (struct m68hc11_opcode *,
+@@ -263,6 +286,7 @@
+ /* The following pseudo-ops are supported for MRI compatibility. */
+ {"fcb", cons, 1},
+ {"fdb", cons, 2},
++ {"fqb", cons, 4},
+ {"fcc", stringer, 1},
+ {"rmb", s_space, 0},
+
+@@ -334,6 +358,8 @@
+ get_default_target ();
+ if (current_architecture & cpu6811)
+ return "elf32-m68hc11";
++ else if (current_architecture & cpuxgate)
++ return "elf32-m9s12xg";
+ else
+ return "elf32-m68hc12";
+ }
+@@ -344,6 +370,8 @@
+ get_default_target ();
+ if (current_architecture & cpu6811)
+ return bfd_arch_m68hc11;
++ else if (current_architecture & cpuxgate)
++ return bfd_arch_m9s12xg;
+ else
+ return bfd_arch_m68hc12;
+ }
+@@ -360,6 +388,10 @@
+ {
+ if (current_architecture & cpu6811)
+ return "M68HC11 GAS ";
++ else if (current_architecture & cpuxgate)
++ return "XGATE GAS ";
++ else if (current_architecture & cpu9s12x)
++ return "S12X GAS ";
+ else
+ return "M68HC12 GAS ";
+ }
+@@ -371,7 +403,8 @@
+ fprintf (stream, _("\
+ Motorola 68HC11/68HC12/68HCS12 options:\n\
+ -m68hc11 | -m68hc12 |\n\
+- -m68hcs12 specify the processor [default %s]\n\
++ -m68hcs12 | -m9s12x |\n\
++ -mxgate specify the processor [default %s]\n\
+ -mshort use 16-bit int ABI (default)\n\
+ -mlong use 32-bit int ABI\n\
+ -mshort-double use 32-bit double ABI\n\
+@@ -412,6 +445,11 @@
+ current_architecture = cpu6811;
+ default_cpu = "m68hc11";
+ }
++ else if (strcmp (target->name, "elf32-m9s12xg") == 0)
++ {
++ current_architecture = cpuxgate;
++ default_cpu = "mxgate";
++ }
+ else
+ {
+ as_bad (_("Default target `%s' is not supported."), target->name);
+@@ -491,14 +529,19 @@
+ break;
+
+ case 'm':
+- if (strcasecmp (arg, "68hc11") == 0)
++ if (strcasecmp (arg, "68hc11") == 0) {
+ current_architecture = cpu6811;
+- else if (strcasecmp (arg, "68hc12") == 0)
++ } else if (strcasecmp (arg, "68hc12") == 0) {
+ current_architecture = cpu6812;
+- else if (strcasecmp (arg, "68hcs12") == 0)
++ } else if (strcasecmp (arg, "68hcs12") == 0) {
+ current_architecture = cpu6812 | cpu6812s;
+- else
++ } else if (strcasecmp (arg, "m9s12x") == 0) {
++ current_architecture = cpu6812 | cpu6812s | cpu9s12x;
++ } else if (strcasecmp (arg, "xgate") == 0) {
++ current_architecture = cpuxgate;
++ } else {
+ as_bad (_("Option `%s' is not recognized."), arg);
++ }
+ break;
+
+ default:
+@@ -666,6 +709,15 @@
+
+ /* See how many operands this opcode needs. */
+ expect = 0;
++ if (opcodes->arch == cpuxgate) {
++ if (opcodes->format & (M68XG_OP_IMM3 | M68XG_OP_R | M68XG_OP_REL9 | M68XG_OP_REL10 )) {
++ expect = 1;
++ } else if (opcodes->format & (M68XG_OP_R_R | M68XG_OP_R_IMM4 | M68XG_OP_R_IMM8 | M68XG_OP_R_IMM8)) {
++ expect = 2;
++ } else if (opcodes->format & (M68XG_OP_R_R_R | M68XG_OP_R_R_OFFS5 | M68XG_OP_RD_RB_RI | M68XG_OP_RD_RB_RIp | M68XG_OP_RD_RB_mRI)) {
++ expect = 3;
++ }
++ } else {
+ if (opcodes->format & M6811_OP_MASK)
+ expect++;
+ if (opcodes->format & M6811_OP_BITMASK)
+@@ -678,6 +730,7 @@
+ if ((opcodes->format & M6812_OP_PAGE)
+ && !(opcodes->format & M6811_OP_IND16))
+ expect++;
++ }
+
+ if (expect < opc->min_operands)
+ opc->min_operands = expect;
+@@ -715,6 +768,90 @@
+
+ p = buf;
+ buf[0] = 0;
++
++ if (current_architecture == cpuxgate) {
++ if (format & M68XG_OP_IMM3) {
++ if (example)
++ sprintf (p, "#%d", rand () & 0x007);
++ else
++ strcpy (p, _("imm3"));
++ p = &p[strlen (p)];
++ } else if (format & M68XG_OP_R) {
++ if (example)
++ sprintf (p, "R%d", rand () & 0x07);
++ else
++ strcpy (p, _("Rx"));
++ p = &p[strlen (p)];
++ } else if (format & M68XG_OP_R_R) {
++ if (example)
++ sprintf (p, "R%d,R%d", rand () & 0x07, rand () & 0x07);
++ else
++ strcpy (p, _("Rx,Ry"));
++ p = &p[strlen (p)];
++ } else if (format & M68XG_OP_R_IMM4) {
++ if (example)
++ sprintf (p, "R%d,#%d", rand () & 0x07, rand () & 0x0f);
++ else
++ strcpy (p, _("Rx, #imm4"));
++ p = &p[strlen (p)];
++ } else if (format & M68XG_OP_R_R_R) {
++ if (example)
++ sprintf (p, "R%d,R%d,R%d", rand () & 0x07, rand () & 0x07, rand () & 0x07);
++ else
++ strcpy (p, "Rx,Ry,Rz");
++ p = &p[strlen (p)];
++ } else if (format & M68XG_OP_REL9) {
++ if (example)
++ sprintf (p, "%d", rand () & 0x1FF);
++ else
++ strcpy (p, "<rel9>");
++ p = &p[strlen (p)];
++ } else if (format & M68XG_OP_REL10) {
++ if (example)
++ sprintf (p, "%d", rand () & 0x3FF);
++ else
++ strcpy (p, "<rel10>");
++ p = &p[strlen (p)];
++ } else if (format & M68XG_OP_R_R_OFFS5) {
++ if (example)
++ sprintf (p, "R%d, (R%d, #0x%x)", rand () & 0x07, rand () & 0x07, rand () & 0x1f);
++ else
++ strcpy (p, _("Rx, (Ry,#offs5)"));
++ p = &p[strlen (p)];
++ } else if (format & M68XG_OP_RD_RB_RI) {
++ if (example)
++ sprintf (p, "R%d, (R%d, R%d)", rand () & 0x07, rand () & 0x07, rand () & 0x07);
++ else
++ strcpy (p, "RD, (RB, RI)");
++ p = &p[strlen (p)];
++ } else if (format & M68XG_OP_RD_RB_RIp) {
++ if (example)
++ sprintf (p, "R%d, (R%d, R%d+)", rand () & 0x07, rand () & 0x07, rand () & 0x07);
++ else
++ strcpy (p, "RD, (RB, RI+)");
++ p = &p[strlen (p)];
++ } else if (format & M68XG_OP_RD_RB_mRI) {
++ if (example)
++ sprintf (p, "R%d, (R%d, -R%d)", rand () & 0x07, rand () & 0x07, rand () & 0x07);
++ else
++ strcpy (p, "RD, (RB, -RI)");
++ p = &p[strlen (p)];
++ } else if (format & M68XG_OP_R_IMM8) {
++ if (example)
++ sprintf (p, "R%d, #0x%x", rand () & 0x07, rand () & 0xff);
++ else
++ strcpy (p, "RD, #imm8");
++ p = &p[strlen (p)];
++ } else if (format & M68XG_OP_R_IMM16) {
++ if (example)
++ sprintf (p, "R%d, #0x%x", rand () & 0x07, rand () & 0xffff);
++ else
++ strcpy (p, "RD, #imm16");
++ p = &p[strlen (p)];
++ }
++
++ } else {
++
+ if (format & M6811_OP_IMM8)
+ {
+ if (example)
+@@ -819,7 +956,7 @@
+ else
+ strcpy (p, _("<label>"));
+ }
+-
++ }
+ return buf;
+ }
+
+@@ -834,7 +971,7 @@
+
+ if (example)
+ printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
+- default_cpu);
++ default_cpu); /* reports incorrect name, need to use current_architecture instead */
+
+ opcodes = m68hc11_sorted_opcodes;
+
+@@ -922,7 +1059,29 @@
+ return REG_PC;
+ if (strcasecmp (name, "ccr") == 0)
+ return REG_CCR;
+-
++/* XGATE */
++ if (strcasecmp (name, "r0") == 0)
++ return REG_R0;
++ if (strcasecmp (name, "r1") == 0)
++ return REG_R1;
++ if (strcasecmp (name, "r2") == 0)
++ return REG_R2;
++ if (strcasecmp (name, "r3") == 0)
++ return REG_R3;
++ if (strcasecmp (name, "r4") == 0)
++ return REG_R4;
++ if (strcasecmp (name, "r5") == 0)
++ return REG_R5;
++ if (strcasecmp (name, "r6") == 0)
++ return REG_R6;
++ if (strcasecmp (name, "r7") == 0)
++ return REG_R7;
++ if (strcasecmp (name, "sp") == 0)
++ return REG_SP_XG;
++ if (strcasecmp (name, "pc") == 0)
++ return REG_PC_XG;
++ if (strcasecmp (name, "ccr") == 0)
++ return REG_CCR_XG;
+ return REG_NONE;
+ }
+
+@@ -1323,6 +1482,35 @@
+ static int
+ check_range (long num, int mode)
+ {
++ if (current_architecture == cpuxgate) {
++
++ switch (mode)
++ {
++ case M68XG_OP_IMM3:
++ return (num >= 0 && num <= 7) ? 1 : 0;
++
++ case M68XG_OP_R_IMM4:
++ return (num >= 0 && num <= 31) ? 1 : 0;
++
++ case M68XG_OP_R_R_OFFS5:
++ return (num >= 0 && num <= 63) ? 1 : 0;
++
++ case M68XG_OP_R_IMM8:
++ return (num >= 0 && num <= 255) ? 1 : 0;
++
++ case M68XG_OP_R_IMM16:
++ return (num >= 0 && num <= 65535) ? 1 : 0;
++
++ case M68XG_OP_B_MARKER:
++ return (num >= -512 && num <= 511) ? 1 : 0;
++
++ case M68XG_OP_BRA_MARKER:
++ return (num >= -1024 && num <= 1023) ? 1 : 0;
++
++ default:
++ return 0;
++ }
++ } else {
+ /* Auto increment and decrement are ok for [-8..8] without 0. */
+ if (mode & M6812_AUTO_INC_DEC)
+ return (num != 0 && num <= 8 && num >= -8);
+@@ -1369,6 +1557,7 @@
+ default:
+ return 0;
+ }
++ }
+ }
+
+ /* Gas fixup generation. */
+@@ -1527,6 +1716,137 @@
+ as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
+ }
+ }
++
++/* XGATE Put a 1 byte expression described by 'oper'. If this expression contains
++ unresolved symbols, generate an 8-bit fixup. */
++static void
++fixup8_xg (expressionS *oper, int mode, int opmode)
++{
++ char *f;
++
++ f = frag_more (1);
++
++ if (oper->X_op == O_constant) {
++ fixS *fixp;
++ int reloc;
++ if ((opmode & M6811_OP_HIGH_ADDR) || (opmode & M6811_OP_LOW_ADDR)) {
++ if (opmode & M6811_OP_HIGH_ADDR) {
++ reloc = BFD_RELOC_M68HC11_HI8;
++ } else {
++ reloc = BFD_RELOC_M68HC11_LO8;
++ }
++
++ fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
++ oper, FALSE, reloc);
++ fixp->fx_no_overflow = 1;
++ number_to_chars_bigendian (f, 0, 1);
++ } else {
++ if (!(check_range (oper->X_add_number, mode))) {
++ as_bad (_("Operand out of 8-bit range: `%ld'."), oper->X_add_number);
++ }
++ number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
++ }
++
++ } else if (oper->X_op != O_register) {
++ if (mode == M68XG_OP_REL9) {
++ fixS *fixp;
++
++ fixp = fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2,
++ oper, TRUE, BFD_RELOC_9_PCREL);
++ fixp->fx_pcrel_adjust = 1;
++ } else if (mode == M68XG_OP_REL10) {
++ fixS *fixp;
++
++ fixp = fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2,
++ oper, TRUE, BFD_RELOC_10_PCREL);
++ fixp->fx_pcrel_adjust = 1;
++ } else {
++ fixS *fixp;
++ int reloc;
++ /* Now create an 8-bit fixup. If there was some %hi, %lo
++ or %page modifier, generate the reloc accordingly. */
++ if (opmode & M6811_OP_HIGH_ADDR) {
++ reloc = BFD_RELOC_M68HC11_HI8;
++ } else if (opmode & M6811_OP_LOW_ADDR) {
++ reloc = BFD_RELOC_M68HC11_LO8;
++ } else if (opmode & M6811_OP_PAGE_ADDR) {
++ reloc = BFD_RELOC_M68HC11_PAGE;
++ } else {
++ reloc = BFD_RELOC_8;
++ }
++
++ fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
++ oper, FALSE, reloc);
++ if (reloc != BFD_RELOC_8) {
++ fixp->fx_no_overflow = 1;
++ }
++ }
++ number_to_chars_bigendian (f, 0, 1);
++ } else {
++ as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
++ }
++}
++
++/* XGATE Put a 2 byte expression described by 'oper'. If this expression contains
++ unresolved symbols, generate an 16-bit fixup. */
++static void
++fixup16_xg (expressionS *oper, int mode, int opmode)
++{
++ char *f;
++
++ f = frag_more (3); // preserve alignment
++
++ if (oper->X_op == O_constant) {
++ fixS *fixp;
++ int reloc;
++ if (opmode & M6811_OP_HIGH_ADDR) {
++ reloc = BFD_RELOC_M68HC11_HI8;
++
++ fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
++ oper, FALSE, reloc);
++ fixp->fx_no_overflow = 1;
++ number_to_chars_bigendian (f, 0, 2);
++ } else {
++ if (!(check_range (oper->X_add_number, mode))) {
++ as_bad (_("Operand out of 16-bit range: `%ld'."), oper->X_add_number);
++ }
++ number_to_chars_bigendian (f, oper->X_add_number, 2);
++ }
++
++ } else if (oper->X_op != O_register) {
++ if (mode == M68XG_OP_REL9) {
++ fixS *fixp;
++
++ fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
++ oper, TRUE, BFD_RELOC_9_PCREL);
++ fixp->fx_pcrel_adjust = 1;
++ } else if (mode == M68XG_OP_REL10) {
++ fixS *fixp;
++
++ fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
++ oper, TRUE, BFD_RELOC_10_PCREL);
++ fixp->fx_pcrel_adjust = 1;
++ } else {
++ fixS *fixp;
++ int reloc;
++ /* Now create an 16-bit fixup. If there was some %hi, %lo
++ or %page modifier, generate the reloc accordingly. */
++ if (opmode & M6811_OP_HIGH_ADDR) {
++ reloc = BFD_RELOC_M68HC11_HI8_16;
++ } else {
++ reloc = BFD_RELOC_16;
++ }
++ fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
++ oper, FALSE, reloc);
++ if (reloc != BFD_RELOC_16) {
++ fixp->fx_no_overflow = 1; // not sure what this is doing
++ }
++ }
++ number_to_chars_bigendian (f, 0, 3);
++ } else {
++ as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
++ }
++}
+
+ /* 68HC11 and 68HC12 code generation. */
+
+@@ -2052,7 +2372,9 @@
+ return 1;
+ }
+
++
+ as_fatal (_("Addressing mode not implemented yet."));
++ fprintf(stderr, "mode = 0x%x\nop->reg1 = 0x%x\nop->reg2 = 0x%x\n", mode, op->reg1, op->reg2);
+ return 0;
+ }
+
+@@ -2101,6 +2423,45 @@
+ /* Put the page code instruction if there is one. */
+ format = opcode->format;
+
++ if (current_architecture == cpuxgate) {
++ operands[0].mode = 0;
++ if (format & M68XG_OP_R_IMM8) {
++ // these opcodes are byte followed by imm8
++ f = m68hc11_new_insn (1);
++ number_to_chars_bigendian (f, opcode->opcode >> 8, 1);
++ fixup8_xg (&operands[0].exp, format, operands[0].mode);
++ } else if (format & M68XG_OP_R_IMM16) {
++ // these opcodes expand into two imm8 instructions
++ f = m68hc11_new_insn (1);
++ number_to_chars_bigendian (f, opcode->opcode >> 8, 1);
++ operands[0].mode = M6811_OP_LOW_ADDR;
++ fixup8_xg (&operands[0].exp, format, operands[0].mode); /* low byte */
++
++ f = m68hc11_new_insn (1);
++ number_to_chars_bigendian (f, (opcode->opcode >> 8) | 0x08, 1);
++ /* just writing the high byte doesn't work due to low byte overflow,
++ so write high and low and figure it out in reloc code */
++ operands[0].mode = M6811_OP_HIGH_ADDR;
++ if (operands[0].exp.X_op == O_constant) {
++ fixup8_xg (&operands[0].exp, format, operands[0].mode); /* a constant so high only is ok */
++ } else {
++ fixup16_xg (&operands[0].exp, format, operands[0].mode); /* high and low bytes */
++ }
++ } else if (format & M68XG_OP_REL9) {
++ f = m68hc11_new_insn (1);
++ number_to_chars_bigendian (f, opcode->opcode >> 8, 1); /* high byte */
++ fixup8_xg (&operands[0].exp, format, M68XG_OP_REL9);
++ } else if (format & M68XG_OP_REL10) {
++ f = m68hc11_new_insn (1);
++ number_to_chars_bigendian (f, opcode->opcode >> 8, 1); /* high byte */
++ fixup8_xg (&operands[0].exp, format, M68XG_OP_REL10);
++ } else {
++ f = m68hc11_new_insn (2);
++ number_to_chars_bigendian (f, opcode->opcode, 2);
++ }
++ return;
++ }
++
+ if (format & M6811_OP_BRANCH)
+ fix_new (frag_now, frag_now_fix (), 0,
+ &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
+@@ -2223,9 +2584,26 @@
+ op_indirect = 0;
+ opcode = opc->opcode;
+
++
++ if (current_architecture & cpuxgate) {
++
++ /* Now search the opcode table table for one with operands
++ that matches what we've got.
++ XGATE simple enough that we should get an exact match */
++ for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++) {
++ if (opcode->format == operands[nb_operands-1].mode ) {
++ return opcode;
++ }
++ }
++
++ return 0;
++
++ } else { /* non XGATE */
++
+ /* Now search the opcode table table for one with operands
+ that matches what we've got. We're only done if the operands matched so
+ far AND there are no more to check. */
++
+ for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
+ {
+ int poss_indirect = 0;
+@@ -2233,6 +2611,7 @@
+ int expect;
+
+ expect = 0;
++
+ if (opcode->format & M6811_OP_MASK)
+ expect++;
+ if (opcode->format & M6811_OP_BITMASK)
+@@ -2244,7 +2623,7 @@
+ if ((opcode->format & M6812_OP_PAGE)
+ && (!IS_CALL_SYMBOL (opcode->format) || nb_operands == 2))
+ expect++;
+-
++
+ for (i = 0; expect == nb_operands && i < nb_operands; i++)
+ {
+ int mode = operands[i].mode;
+@@ -2370,7 +2749,7 @@
+ {
+ return (0);
+ }
+-
++}
+ return opcode;
+ }
+
+@@ -2452,6 +2831,7 @@
+ struct m68hc11_opcode_def *opc;
+ struct m68hc11_opcode *opcode;
+
++ struct m68hc11_opcode opcode_local;
+ unsigned char *op_start, *op_end;
+ char *save;
+ char name[20];
+@@ -2482,6 +2862,450 @@
+ return;
+ }
+
++
++ if (current_architecture == cpuxgate) { /* XGATE */
++
++ /* Find the opcode definition given its name. */
++ opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
++ if (opc == NULL) {
++ as_bad (_("Opcode `%s' is not recognized."), name);
++ return;
++ }
++
++ /* grab to local copy */
++ opcode_local.name = opc->opcode->name;
++ /* these will be incorrect where multiple variants exist */
++ opcode_local.opcode = opc->opcode->opcode;
++ opcode_local.format = opc->opcode->format;
++
++ save = input_line_pointer;
++ input_line_pointer = (char *) op_end;
++
++ if (opc->format == M68XG_OP_NONE) {
++ opcode_local.format = M68XG_OP_NONE; // no special handling required
++ build_insn (opc->opcode, operands, 0);
++ return;
++ }
++
++ // special handling of TFR
++ if (strncmp(opc->opcode->name, "tfr",3) == 0) {
++ // There must be two operands with a comma
++ input_line_pointer = skip_whites (input_line_pointer);
++ operands[0].reg1 = register_name ();
++ if (operands[0].reg1 == REG_NONE) {
++ as_bad("Invalid register\n");
++ return;
++ }
++ input_line_pointer = skip_whites (input_line_pointer);
++ if (*input_line_pointer != ',') {
++ as_bad ("Missing comma.\n"); // FIXME translate
++ return;
++ }
++ input_line_pointer++;
++ input_line_pointer = skip_whites (input_line_pointer);
++ operands[1].reg1 = register_name ();
++ if (operands[1].reg1 == REG_NONE) {
++ as_bad("Invalid register\n");
++ return;
++ }
++ input_line_pointer = skip_whites (input_line_pointer);
++ if (*input_line_pointer != '\n' && *input_line_pointer) {
++ as_bad (_("Garbage at end of instruction: `%s'."), input_line_pointer);
++ return;
++ }
++ if (operands[1].reg1 == REG_CCR) { // ,CCR
++ opc->opcode->opcode = 0x00f8 | ( operands[0].reg1 << 8);
++ } else if (operands[0].reg1 == REG_CCR) { // CCR,
++ opc->opcode->opcode = 0x00f9 | ( operands[1].reg1 << 8);
++ } else if (operands[1].reg1 == REG_PC) { // ,PC
++ opc->opcode->opcode = 0x00fa | ( operands[0].reg1 << 8);
++ } else {
++ as_bad("Invalid operand to TFR\n");
++ return;
++ }
++ opcode_local.format = M68XG_OP_NONE; // no special handling required
++ build_insn (&opcode_local, operands, 0);
++ return;
++ }
++
++//CSEM, SSEM
++ if (opc->format & M68XG_OP_IMM3) {
++ // either imm3 or R
++ input_line_pointer = skip_whites (input_line_pointer);
++ if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r')) {
++ operands[0].reg1 = register_name ();
++ if (operands[0].reg1 == REG_NONE) {
++ as_bad("Invalid register\n");
++ return;
++ }
++ operands[0].mode = M68XG_OP_R;
++ // same opcodes have multiple modes, so find right one
++ opcode = find (opc, operands, 1);
++ if (opcode) {
++ opcode_local.opcode = opcode->opcode | (operands[0].reg1 << 8);
++ opcode_local.format = M68XG_OP_NONE;
++ build_insn (&opcode_local, operands, 1);
++ } else {
++ as_bad("No opcode found\n");
++ }
++ return;
++ } else {
++ if (*input_line_pointer == '#') {
++ input_line_pointer++;
++ }
++ expression (&operands[0].exp);
++ if (operands[0].exp.X_op == O_illegal) {
++ as_bad (_("Illegal operand."));
++ return;
++ } else if (operands[0].exp.X_op == O_absent) {
++ as_bad (_("Missing operand."));
++ return;
++ }
++
++ if (check_range(operands[0].exp.X_add_number,M68XG_OP_IMM3)) {
++ opcode_local.opcode |= (operands[0].exp.X_add_number);
++ operands[0].mode = M68XG_OP_IMM3;
++ // same opcodes have multiple modes, so find right one
++ opcode = find (opc, operands, 1);
++ if (opcode) {
++ opcode_local.opcode = opcode->opcode;
++ opcode_local.opcode |= (operands[0].exp.X_add_number) << 8;
++ opcode_local.format = M68XG_OP_NONE;
++ build_insn (&opcode_local, operands, 1);
++ } else {
++ as_bad("No opcode found\n");
++ }
++ return;
++ } else {
++ as_bad("Number out of range for IMM3\n");
++ return;
++ }
++ }
++ }
++
++ // special handling of SIF
++ if (strncmp(opc->opcode->name, "sif",3) == 0) {
++ // Either OP_NONE or OP_RS
++ if (*input_line_pointer != '\n') {
++ input_line_pointer = skip_whites (input_line_pointer);
++ }
++ if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r') || (*input_line_pointer == '\0')) {
++ opc->opcode->opcode = 0x0300;
++ } else {
++ operands[0].reg1 = register_name ();
++ if (operands[0].reg1 == REG_NONE) {
++ as_bad("Invalid register\n");
++ return;
++ }
++ opcode_local.opcode = 0x00f7 | (operands[0].reg1 << 8);
++ }
++ opcode_local.format = M68XG_OP_NONE; // no special handling required
++ build_insn (&opcode_local, operands, 0);
++ return;
++ }
++
++ // SEX, PAR, JAL only
++ if (opc->format & M68XG_OP_R) {
++ input_line_pointer = skip_whites (input_line_pointer);
++ operands[0].reg1 = register_name ();
++ if (operands[0].reg1 == REG_NONE) {
++ as_bad("Invalid register\n");
++ return;
++ }
++ opcode_local.opcode |= (operands[0].reg1 << 8);
++ build_insn (&opcode_local, operands, 0);
++ return;
++ }
++
++ if (opc->format & (M68XG_OP_REL9 | M68XG_OP_REL10)) {
++ opcode_local.format = opc->format;
++ input_line_pointer = skip_whites (input_line_pointer);
++ expression (&operands[0].exp);
++ if (operands[0].exp.X_op == O_illegal) {
++ as_bad (_("Illegal operand."));
++ return;
++ } else if (operands[0].exp.X_op == O_absent) {
++ as_bad (_("Missing operand."));
++ return;
++ }
++ opcode_local.opcode = opc->opcode->opcode;
++ build_insn (&opcode_local, operands, 1);
++ return;
++ }
++
++
++ /* For other command formats, parse input line and determine the mode we are using as we go */
++ /* the above special cases work, but may not be necessary */
++
++ input_line_pointer = skip_whites (input_line_pointer);
++ if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r') || (*input_line_pointer == '\0')) {
++ return; // nothing left
++ }
++
++ if (*input_line_pointer == '#') {
++ as_bad("No register specified before hash\n");
++ return;
++ }
++
++ /* first operand is expected to be a register */
++ if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r')) {
++ operands[0].reg1 = register_name ();
++ if (operands[0].reg1 == REG_NONE) {
++ as_bad("Invalid register\n");
++ return;
++ }
++ }
++
++ input_line_pointer = skip_whites (input_line_pointer);
++ if (*input_line_pointer != ',') {
++ as_bad ("1Missing operand\n"); // FIXME translate
++ return;
++ }
++ input_line_pointer++;
++ input_line_pointer = skip_whites (input_line_pointer);
++
++ if (*input_line_pointer == '#') {
++ // some kind of immediate mode. Check if this is possible
++ if (!(opc->format & (M68XG_OP_R_IMM8 | M68XG_OP_R_IMM16 | M68XG_OP_R_IMM4))) {
++ as_bad("Invalid immediate mode\n");
++ return;
++ }
++ input_line_pointer++;
++ input_line_pointer = skip_whites (input_line_pointer);
++ if (strncmp (input_line_pointer, "%hi", 3) == 0) {
++ input_line_pointer += 3;
++ operands[0].mode = M6811_OP_HIGH_ADDR;
++ } else if (strncmp (input_line_pointer, "%lo", 3) == 0) {
++ input_line_pointer += 3;
++ operands[0].mode = M6811_OP_LOW_ADDR;
++ }
++ expression (&operands[0].exp);
++ if (operands[0].exp.X_op == O_illegal) {
++ as_bad (_("Illegal operand."));
++ return;
++ } else if (operands[0].exp.X_op == O_absent) {
++ as_bad (_("Missing operand."));
++ return;
++ }
++ /* ok so far, can only be one mode */
++ opcode_local.format = opc->format & (M68XG_OP_R_IMM8 | M68XG_OP_R_IMM16 | M68XG_OP_R_IMM4);
++ if (opcode_local.format & M68XG_OP_R_IMM4) {
++ operands[0].mode = M68XG_OP_R_IMM4;
++ // same opcodes have multiple modes, so find right one
++ opcode = find (opc, operands, 1);
++ if (opcode) {
++ opcode_local.opcode = opcode->opcode | (operands[0].reg1 << 8);
++ }
++ if (operands[0].exp.X_op != O_constant) {
++ as_bad("Only constants supported at for IMM4 mode\n");
++ } else {
++ if (check_range(operands[0].exp.X_add_number,M68XG_OP_R_IMM4)) {
++ opcode_local.opcode |= (operands[0].exp.X_add_number << 4);
++ } else {
++ as_bad("Number out of range for IMM4\n");
++ }
++ }
++ opcode_local.format = M68XG_OP_NONE;
++ } else if (opcode_local.format & M68XG_OP_R_IMM16) {
++ operands[0].mode = M68XG_OP_R_IMM16;
++ // same opcodes have multiple modes, so find right one
++ opcode = find (opc, operands, 1);
++ if (opcode) {
++ opcode_local.opcode = opcode->opcode | (operands[0].reg1 << 8);
++ }
++ } else {
++ opcode_local.opcode = opc->opcode->opcode | (operands[0].reg1 << 8);
++ }
++ build_insn (&opcode_local, operands, 1);
++ } else if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r')) {
++ /* we've got as far as OP R, R */
++ operands[1].reg1 = register_name ();
++ if (operands[1].reg1 == REG_NONE) {
++ as_bad("Invalid register\n");
++ return;
++ }
++ if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r') || (*input_line_pointer == '\0')) {
++ /* looks like OP_R_R */
++ if (opc->format & M68XG_OP_R_R) {
++ operands[0].mode = M68XG_OP_R_R;
++ // same opcodes have multiple modes, so find right one
++ opcode = find (opc, operands, 1);
++ if (opcode) {
++ if (opcode->opcode == 0x1800) {
++ //special case for cmp RS1, RS2 alias for sub R0, RS1, RS2
++ opcode_local.opcode = opcode->opcode | (operands[0].reg1 << 5) | (operands[1].reg1 << 2);
++ } else {
++ opcode_local.opcode = opcode->opcode | (operands[0].reg1 << 8) | (operands[1].reg1 << 5);
++ }
++ opcode_local.format = M68XG_OP_NONE;
++ build_insn (&opcode_local, operands, 1);
++ }
++ } else {
++ as_bad("No valid mode found\n");
++ }
++ } else {
++ /* more data */
++ if (*input_line_pointer != ',') {
++ as_bad (_("Missing operand."));
++ return;
++ }
++ input_line_pointer++;
++ input_line_pointer = skip_whites (input_line_pointer);
++ if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r')) {
++ operands[2].reg1 = register_name ();
++ if (operands[2].reg1 == REG_NONE) {
++ as_bad("Invalid register\n");
++ return;
++ }
++ if (opc->format & M68XG_OP_R_R_R) {
++ operands[0].mode = M68XG_OP_R_R_R;
++ // same opcodes have multiple modes, so find right one
++ opcode = find (opc, operands, 1);
++ if (opcode) {
++ opcode_local.opcode = opcode->opcode | (operands[0].reg1 << 8) | (operands[1].reg1 << 5) | (operands[2].reg1 << 2);
++ opcode_local.format = M68XG_OP_NONE;
++ build_insn (&opcode_local, operands, 1);
++ }
++ } else {
++ as_bad("No valid mode found\n");
++ }
++ }
++ }
++ } else if (*input_line_pointer == '(') { /* indexed modes */
++ input_line_pointer++;
++ input_line_pointer = skip_whites (input_line_pointer);
++ if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r')) {
++ /* we've got as far as OP R, (R */
++ operands[1].reg1 = register_name ();
++ if (operands[1].reg1 == REG_NONE) {
++ as_bad("Invalid register\n");
++ return;
++ }
++//? input_line_pointer = skip_whites (input_line_pointer);
++ if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r') || (*input_line_pointer == '\0')) {
++ /* looks like OP_R_R */
++ as_bad (_("Missing operand."));
++ return;
++ }
++
++ input_line_pointer = skip_whites (input_line_pointer);
++
++ if (*input_line_pointer != ',') {
++ as_bad (_("Missing operand."));
++ return;
++ }
++ input_line_pointer++;
++ input_line_pointer = skip_whites (input_line_pointer);
++
++ if (*input_line_pointer == '#') {
++
++ input_line_pointer++;
++ input_line_pointer = skip_whites (input_line_pointer);
++ expression (&operands[0].exp);
++ if (operands[0].exp.X_op == O_illegal) {
++ as_bad (_("Illegal operand."));
++ return;
++ } else if (operands[0].exp.X_op == O_absent) {
++ as_bad (_("Missing operand."));
++ return;
++ }
++
++ input_line_pointer = skip_whites (input_line_pointer);
++ if (*input_line_pointer != ')') {
++ as_bad ("Missing `)' to close register indirect operand.");
++ return;
++ } else {
++ input_line_pointer++;
++ }
++
++ /* ok so far, can only be one mode */
++ opcode_local.format = M68XG_OP_R_R_OFFS5;
++ operands[0].mode = M68XG_OP_R_R_OFFS5;
++ // same opcodes have multiple modes, so find right one
++ opcode = find (opc, operands, 1);
++ if (opcode) {
++ opcode_local.opcode = opcode->opcode | (operands[0].reg1 << 8) | (operands[1].reg1 << 5);
++ if (operands[0].exp.X_op != O_constant) {
++ as_bad("Only constants supported at for indexed OFFS5 mode\n");
++ } else {
++ if (check_range(operands[0].exp.X_add_number,M68XG_OP_R_R_OFFS5)) {
++ opcode_local.opcode |= (operands[0].exp.X_add_number);
++ opcode_local.format = M68XG_OP_NONE;
++ build_insn (&opcode_local, operands, 1);
++ } else {
++ as_bad("Number out of range for OFFS5\n");
++ }
++ }
++ }
++ } else {
++ operands[0].mode = M68XG_OP_RD_RB_RI;
++
++ if (*input_line_pointer == '-') {
++ operands[0].mode = M68XG_OP_RD_RB_mRI;
++ input_line_pointer++;
++ }
++ operands[2].reg1 = register_name ();
++ if (operands[2].reg1 == REG_NONE) {
++ as_bad("Invalid register\n");
++ return;
++ }
++
++ if (*input_line_pointer == '+') {
++ if (opcode_local.format == M68XG_OP_RD_RB_mRI) {
++ as_bad (_("Illegal operand."));
++ return;
++ }
++ operands[0].mode = M68XG_OP_RD_RB_RIp;
++ input_line_pointer++;
++ }
++
++ input_line_pointer = skip_whites (input_line_pointer);
++ if (*input_line_pointer != ')') {
++ as_bad ("Missing `)' to close register indirect operand.");
++ return;
++ } else {
++ input_line_pointer++;
++ }
++
++ opcode = find (opc, operands, 1);
++ if (opcode) {
++ opcode_local.opcode = opcode->opcode | (operands[0].reg1 << 8) | (operands[1].reg1 << 5) | (operands[2].reg1 << 2);
++ opcode_local.format = M68XG_OP_NONE;
++ build_insn (&opcode_local, operands, 1);
++ } else {
++ as_bad("Failed to find opcode for %s %s\n", opc->opcode->name, (char *)op_end);
++ }
++ }
++ }
++ }
++
++// needed?
++ if (opc->opcode && !flag_mri)
++ {
++ char *p = input_line_pointer;
++
++ while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
++ p++;
++
++ if (*p != '\n' && *p)
++ as_bad (_("Garbage at end of instruction: `%s'."), p);
++ }
++
++ input_line_pointer = save;
++
++ /* Opcode is known but does not have valid operands. Print out the
++ syntax for this opcode. */
++ if (opc->opcode == 0)
++ {
++ if (flag_print_insn_syntax)
++ print_insn_format (name);
++
++ as_bad (_("Invalid operand for `%s'"), name);
++ return;
++ }
++
++ } else { /* *********** non XGATE *********** */
++
+ /* Find the opcode definition given its name. */
+ opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
+
+@@ -2500,7 +3324,7 @@
+ branch_optimize = 1;
+ }
+
+- /* The following test should probably be removed. This is not conform
++ /* The following test should probably be removed. This does not conform
+ to Motorola assembler specs. */
+ if (opc == NULL && flag_mri)
+ {
+@@ -2554,8 +3378,9 @@
+ opc->used++;
+ opcode = find_opcode (opc, operands, &nb_operands);
+ }
+- else
++ else {
+ opcode = 0;
++ }
+
+ if ((opcode || alias_id >= 0) && !flag_mri)
+ {
+@@ -2594,19 +3419,22 @@
+
+ /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
+ relative and must be in the range -256..255 (9-bits). */
+- if ((opcode->format & M6812_XBCC_MARKER)
+- && (opcode->format & M6811_OP_JUMP_REL))
++
++ if ((opcode->format & M6812_XBCC_MARKER)
++ && (opcode->format & M6811_OP_JUMP_REL)) {
+ build_dbranch_insn (opcode, operands, nb_operands, branch_optimize);
+
+ /* Relative jumps instructions are taken care of separately. We have to make
+ sure that the relative branch is within the range -128..127. If it's out
+ of range, the instructions are changed into absolute instructions.
+ This is not supported for the brset and brclr instructions. */
+- else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
+- && !(opcode->format & M6811_OP_BITMASK))
++ } else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
++ && !(opcode->format & M6811_OP_BITMASK)) {
+ build_jump_insn (opcode, operands, nb_operands, branch_optimize);
+- else
++ } else {
+ build_insn (opcode, operands, nb_operands);
++ }
++}
+ }
+
+
+@@ -2997,6 +3825,7 @@
+ int
+ md_estimate_size_before_relax (fragS *fragP, asection *segment)
+ {
++
+ if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
+ {
+ if (S_GET_SEGMENT (fragP->fr_symbol) != segment
+@@ -3268,6 +4097,7 @@
+ ((bfd_byte*) where)[2] = ((value >> 16) & 0x0ff);
+ break;
+
++ case BFD_RELOC_M68HC11_HI8_16:
+ case BFD_RELOC_16:
+ case BFD_RELOC_16_PCREL:
+ case BFD_RELOC_M68HC11_LO16:
+@@ -3278,9 +4108,7 @@
+ break;
+
+ case BFD_RELOC_M68HC11_HI8:
+- value = value >> 8;
+- /* Fall through. */
+-
++ value = value >>8;
+ case BFD_RELOC_M68HC11_LO8:
+ case BFD_RELOC_8:
+ case BFD_RELOC_M68HC11_PAGE:
+@@ -3296,6 +4124,25 @@
+ value);
+ break;
+
++/* these next two are dubious */
++ case BFD_RELOC_9_PCREL:
++ ((bfd_byte *) where)[0] |= (bfd_byte) ((value >>9) & 0x01);
++ ((bfd_byte *) where)[1] = (bfd_byte) ((value>>1) & 0xff);
++ if (value < -512 || value > 511)
++ as_bad_where (fixP->fx_file, fixP->fx_line,
++ _("Value %ld too large for 8-bit PC-relative branch."),
++ value);
++ break;
++
++ case BFD_RELOC_10_PCREL:
++ ((bfd_byte *) where)[0] |= (bfd_byte) ((value >>9) & 0x03);
++ ((bfd_byte *) where)[1] = (bfd_byte) ((value>>1) & 0xff);
++ if (value < -1024 || value > 1023)
++ as_bad_where (fixP->fx_file, fixP->fx_line,
++ _("Value %ld too large for 8-bit PC-relative branch."),
++ value);
++ break;
++
+ case BFD_RELOC_M68HC11_3B:
+ if (value <= 0 || value > 8)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+diff -u -r -N binutils-2.18/gas/config/tc-m68hc11.h binutils-2.18-s12x/gas/config/tc-m68hc11.h
+--- binutils-2.18/gas/config/tc-m68hc11.h 2007-08-06 20:59:59.000000000 +0100
++++ binutils-2.18-s12x/gas/config/tc-m68hc11.h 2008-03-20 19:53:33.000000000 +0000
+@@ -21,6 +21,7 @@
+
+ #define TC_M68HC11
+ #define TC_M68HC12
++#define TC_M9S12XG
+
+ struct fix;
+
+@@ -32,6 +33,10 @@
+ /* Motorola assembler specs does not require '.' before pseudo-ops. */
+ #define NO_PSEUDO_DOT 1
+
++#define m9s12xg_arch_format m68hc11_arch_format
++#define m9s12xg_arch m68hc11_arch
++#define m9s12xg_listing_header m68hc11_listing_header
++
+ /* The target BFD architecture. */
+ #define TARGET_ARCH (m68hc11_arch ())
+ extern enum bfd_architecture m68hc11_arch (void);
+diff -u -r -N binutils-2.18/gas/configure.tgt binutils-2.18-s12x/gas/configure.tgt
+--- binutils-2.18/gas/configure.tgt 2007-08-28 18:19:36.000000000 +0100
++++ binutils-2.18-s12x/gas/configure.tgt 2008-03-20 19:59:41.000000000 +0000
+@@ -50,7 +50,7 @@
+ m5200) cpu_type=m68k ;;
+ m68008) cpu_type=m68k ;;
+ m680[012346]0) cpu_type=m68k ;;
+- m6811|m6812|m68hc12) cpu_type=m68hc11 ;;
++ m6811|m6812|m68hc12|m9s12x|m9s12xg) cpu_type=m68hc11 ;;
+ m683??) cpu_type=m68k ;;
+ maxq) cpu_type=maxq ;;
+ mep-*-elf) cpu_type=mep endian=big ;;
+@@ -247,6 +247,8 @@
+
+ m68hc11-*-* | m6811-*-*) fmt=elf ;;
+ m68hc12-*-* | m6812-*-*) fmt=elf ;;
++ m9s12x-*-*) fmt=elf ;;
++ m9s12xg-*-*) fmt=elf ;;
+
+ m68k-*-elf*) fmt=elf ;;
+ m68k-*-sysv4*) fmt=elf em=svr4 ;;
+diff -u -r -N binutils-2.18/gas/Makefile.am binutils-2.18-s12x/gas/Makefile.am
+--- binutils-2.18/gas/Makefile.am 2007-08-28 18:19:35.000000000 +0100
++++ binutils-2.18-s12x/gas/Makefile.am 2008-02-26 21:50:41.000000000 +0000
+@@ -67,7 +67,7 @@
+ m32c \
+ m32r \
+ m68hc11 \
+- m68k \
++ m68k \
+ maxq \
+ mcore \
+ mep \
+diff -u -r -N binutils-2.18/gas/Makefile.in binutils-2.18-s12x/gas/Makefile.in
+--- binutils-2.18/gas/Makefile.in 2007-08-28 18:19:35.000000000 +0100
++++ binutils-2.18-s12x/gas/Makefile.in 2008-02-25 21:20:27.000000000 +0000
+@@ -312,7 +312,7 @@
+ m32c \
+ m32r \
+ m68hc11 \
+- m68k \
++ m68k \
+ maxq \
+ mcore \
+ mep \
+diff -u -r -N binutils-2.18/include/dis-asm.h binutils-2.18-s12x/include/dis-asm.h
+--- binutils-2.18/include/dis-asm.h 2007-08-06 20:59:46.000000000 +0100
++++ binutils-2.18-s12x/include/dis-asm.h 2008-03-20 20:45:54.000000000 +0000
+@@ -247,6 +247,8 @@
+ extern int print_insn_m32r (bfd_vma, disassemble_info *);
+ extern int print_insn_m68hc11 (bfd_vma, disassemble_info *);
+ extern int print_insn_m68hc12 (bfd_vma, disassemble_info *);
++extern int print_insn_m9s12x (bfd_vma, disassemble_info *);
++extern int print_insn_m9s12xg (bfd_vma, disassemble_info *);
+ extern int print_insn_m68k (bfd_vma, disassemble_info *);
+ extern int print_insn_m88k (bfd_vma, disassemble_info *);
+ extern int print_insn_maxq_big (bfd_vma, disassemble_info *);
+diff -u -r -N binutils-2.18/include/elf/common.h binutils-2.18-s12x/include/elf/common.h
+--- binutils-2.18/include/elf/common.h 2007-08-28 18:19:40.000000000 +0100
++++ binutils-2.18-s12x/include/elf/common.h 2008-03-21 13:53:22.000000000 +0000
+@@ -189,6 +189,8 @@
+ #define EM_CR16 115 /* National Semiconductor CompactRISC - CR16 */
+ #define EM_SCORE 135 /* Sunplus Score */
+
++#define EM_M9S12XG 0xb001 /* "random" number for Freescale 9S12X-XGATE */
++
+ /* If it is necessary to assign new unofficial EM_* values, please pick large
+ random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
+ with official or non-GNU unofficial values.
+diff -u -r -N binutils-2.18/include/elf/m68hc11.h binutils-2.18-s12x/include/elf/m68hc11.h
+--- binutils-2.18/include/elf/m68hc11.h 2005-05-10 11:21:10.000000000 +0100
++++ binutils-2.18-s12x/include/elf/m68hc11.h 2009-10-08 18:09:32.000000000 +0100
+@@ -41,6 +41,7 @@
+ RELOC_NUMBER (R_M68HC11_24, 11)
+ RELOC_NUMBER (R_M68HC11_LO16, 12)
+ RELOC_NUMBER (R_M68HC11_PAGE, 13)
++ RELOC_NUMBER (R_M68HC11_HI8_16, 14)
+
+ /* GNU extension for linker relaxation.
+ Mark beginning of a jump instruction (any form). */
+diff -u -r -N binutils-2.18/include/elf/m9s12xg.h binutils-2.18-s12x/include/elf/m9s12xg.h
+--- binutils-2.18/include/elf/m9s12xg.h 1970-01-01 01:00:00.000000000 +0100
++++ binutils-2.18-s12x/include/elf/m9s12xg.h 2009-10-08 18:12:05.000000000 +0100
+@@ -0,0 +1,98 @@
++/* m68hcs12xgate & m68hc12 ELF support for BFD.
++ Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
++
++ This file is part of BFD, the Binary File Descriptor library.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software Foundation,
++ Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
++
++#ifndef _ELF_M9S12XG_H
++#define _ELF_M9S12XG_H
++
++#include "elf/reloc-macros.h"
++
++/* Relocation types. */
++START_RELOC_NUMBERS (elf_m9s12xg_reloc_type)
++ RELOC_NUMBER (R_M68HC11_NONE, 0)
++ RELOC_NUMBER (R_M68HC11_8, 1)
++ RELOC_NUMBER (R_M68HC11_HI8, 2)
++ RELOC_NUMBER (R_M68HC11_LO8, 3)
++ RELOC_NUMBER (R_M68HC11_PCREL_8, 4)
++ RELOC_NUMBER (R_M68HC11_16, 5)
++ RELOC_NUMBER (R_M68HC11_32, 6)
++ RELOC_NUMBER (R_M68HC11_3B, 7)
++ RELOC_NUMBER (R_M68HC11_PCREL_16, 8)
++
++ /* These are GNU extensions to enable C++ vtable garbage collection. */
++ RELOC_NUMBER (R_M68HC11_GNU_VTINHERIT, 9)
++ RELOC_NUMBER (R_M68HC11_GNU_VTENTRY, 10)
++
++ RELOC_NUMBER (R_M68HC11_24, 11)
++ RELOC_NUMBER (R_M68HC11_LO16, 12)
++ RELOC_NUMBER (R_M68HC11_PAGE, 13)
++ RELOC_NUMBER (R_M68HC11_HI8_16, 14)
++ RELOC_NUMBER (R_M68XG_PCREL_9, 15)
++ RELOC_NUMBER (R_M68XG_PCREL_10, 16)
++
++ /* GNU extension for linker relaxation.
++ Mark beginning of a jump instruction (any form). */
++ RELOC_NUMBER (R_M68HC11_RL_JUMP, 20)
++
++ /* Mark beginning of Gcc relaxation group instruction. */
++ RELOC_NUMBER (R_M68HC11_RL_GROUP, 21)
++END_RELOC_NUMBERS (R_M68HC11_max)
++
++/* Processor specific flags for the ELF header e_flags field. */
++
++/* ABI identification. */
++#define EF_M9S12XG_ABI 0x00000000F
++
++/* Integers are 32-bit long. */
++#define E_M9S12XG_I32 0x000000001
++
++/* Doubles are 64-bit long. */
++#define E_M9S12XG_F64 0x000000002
++
++/* Uses 68HC12 memory banks. */
++#define E_M68HC12_BANKS 0x000000004
++
++#define EF_M9S12XG_MACH_MASK 0xF0
++#define EF_M9S12XG_GENERIC 0x00 /* Generic 68HC12/backward compatibility. */
++#define EF_M68HC12_MACH 0x10 /* 68HC12 microcontroller. */
++#define EF_M68HCS12_MACH 0x20 /* 68HCS12 microcontroller. */
++#define EF_M9S12XG_MACH(mach) ((mach) & EF_M9S12XG_MACH_MASK)
++
++/* True if we can merge machines. A generic HC12 can work on any proc
++ but once we have specific code, merge is not possible. */
++#define EF_M9S12XG_CAN_MERGE_MACH(mach1, mach2) \
++ ((EF_M9S12XG_MACH (mach1) == EF_M9S12XG_MACH (mach2)) \
++ || (EF_M9S12XG_MACH (mach1) == EF_M9S12XG_GENERIC) \
++ || (EF_M9S12XG_MACH (mach2) == EF_M9S12XG_GENERIC))
++
++#define EF_M9S12XG_MERGE_MACH(mach1, mach2) \
++ (((EF_M9S12XG_MACH (mach1) == EF_M9S12XG_MACH (mach2)) \
++ || (EF_M9S12XG_MACH (mach1) == EF_M9S12XG_GENERIC)) ? \
++ EF_M9S12XG_MACH (mach2) : EF_M9S12XG_MACH (mach1))
++
++
++/* Special values for the st_other field in the symbol table. These
++ are used for 68HC12 to identify far functions (must be called with
++ 'call' and returns with 'rtc'). */
++#define STO_M68HC12_FAR 0x80
++
++/* Identify interrupt handlers. This is used by the debugger to
++ correctly compute the stack frame. */
++#define STO_M68HC12_INTERRUPT 0x40
++
++#endif
+diff -u -r -N binutils-2.18/include/opcode/m68hc11.h binutils-2.18-s12x/include/opcode/m68hc11.h
+--- binutils-2.18/include/opcode/m68hc11.h 2005-05-10 11:21:12.000000000 +0100
++++ binutils-2.18-s12x/include/opcode/m68hc11.h 2008-03-02 14:30:42.000000000 +0000
+@@ -362,6 +362,32 @@
+ #define M6812_INDEXED_IND 0x10000000 /* [n,r] n = 16-bits */
+ #define M6812_INDEXED 0x20000000 /* n,r n = 5, 9 or 16-bits */
+ #define M6812_OP_IDX_P2 0x40000000
++#define M6812_OP_IDX1_P2 0x80000000
++/* these won't work - need new method */
++#define M6812_OP_IDX1_P2 0x80000000
++#define M6812_OP_IDX2_P2 0x80000000
++#define M6812_OP_D_IDX_P2 0x80000000
++#define M6812_OP_D_IDX2_P2 0x80000000
++
++/* XGATE defines
++ * these overlap with HC11/12 as above but not used at the same time */
++#define M68XG_OP_NONE 0x0001
++#define M68XG_OP_IMM3 0x0002
++#define M68XG_OP_R 0x0004
++#define M68XG_OP_R_R 0x0008
++#define M68XG_OP_R_IMM4 0x0010
++#define M68XG_OP_R_R_R 0x0020
++#define M68XG_OP_REL9 0x0040
++#define M68XG_OP_REL10 0x0080
++#define M68XG_OP_R_R_OFFS5 0x0100
++#define M68XG_OP_RD_RB_RI 0x0200
++#define M68XG_OP_RD_RB_RIp 0x0400
++#define M68XG_OP_RD_RB_mRI 0x0800
++#define M68XG_OP_R_IMM8 0x1000
++#define M68XG_OP_R_IMM16 0x2000
++#define M68XG_OP_REG 0x4000 /* Register operand 1 */
++#define M68XG_OP_REG_2 0x8000 /* Register operand 2 */
++#define M68XG_MAX_OPERANDS 3 /* Max operands of triadic r1, r2, r3 */
+
+ /* Markers to identify some instructions. */
+ #define M6812_OP_EXG_MARKER 0x01000000 /* exg r1,r2 */
+@@ -373,6 +399,10 @@
+ #define M6812_OP_IBCC_MARKER 0x02000000 /* ibeq/ibne */
+ #define M6812_OP_TBCC_MARKER 0x01000000
+
++/* XGATE markers */
++#define M68XG_OP_B_MARKER 0x04000000 /* bXX rel9 */
++#define M68XG_OP_BRA_MARKER 0x02000000 /* bra rel10 */
++
+ #define M6812_OP_TRAP_ID 0x80000000 /* trap #N */
+
+ #define M6811_OP_HIGH_ADDR 0x01000000 /* Used internally by gas. */
+@@ -389,19 +419,22 @@
+ #define cpu6811 0x01
+ #define cpu6812 0x02
+ #define cpu6812s 0x04
++#define cpu9s12x 0x08 /* 9S12X main cpu*/
++#define cpuxgate 0x10 /* The XGATE module itself */
+
+ /* The opcode table is an array of struct m68hc11_opcode. */
+ struct m68hc11_opcode {
+ const char* name; /* Op-code name */
+ long format;
+ unsigned char size;
+- unsigned char opcode;
++ unsigned int opcode;
+ unsigned char cycles_low;
+ unsigned char cycles_high;
+ unsigned char set_flags_mask;
+ unsigned char clr_flags_mask;
+ unsigned char chg_flags_mask;
+ unsigned char arch;
++ unsigned int xg_mask; /* mask with zero in register place for xgate*/
+ };
+
+ /* Alias definition for 68HC12. */
+diff -u -r -N binutils-2.18/include/opcode/m9s12xg.h binutils-2.18-s12x/include/opcode/m9s12xg.h
+--- binutils-2.18/include/opcode/m9s12xg.h 1970-01-01 01:00:00.000000000 +0100
++++ binutils-2.18-s12x/include/opcode/m9s12xg.h 2008-03-20 20:46:14.000000000 +0000
+@@ -0,0 +1,121 @@
++/* m68hcs12xgate.h -- Header file for Motorola 68HCS12XGATE & 68HC12 opcode table
++ Copyright 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
++ Written by Stephane Carrez (stcarrez@nerim.fr)
++
++This file is part of GDB, GAS, and the GNU binutils.
++
++GDB, GAS, and the GNU binutils are free software; you can redistribute
++them and/or modify them under the terms of the GNU General Public
++License as published by the Free Software Foundation; either version
++1, or (at your option) any later version.
++
++GDB, GAS, and the GNU binutils are distributed in the hope that they
++will be useful, but WITHOUT ANY WARRANTY; without even the implied
++warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
++the GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with this file; see the file COPYING. If not, write to the Free
++Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
++
++#ifndef _OPCODE_M9S12XG_H
++#define _OPCODE_M9S12XG_H
++
++/* Flags for the definition of the 68HCS12XGATE & 68HC12 CCR. */
++#define M6811_S_BIT 0x80 /* Stop disable */
++#define M6811_X_BIT 0x40 /* X-interrupt mask */
++#define M6811_H_BIT 0x20 /* Half carry flag */
++#define M6811_I_BIT 0x10 /* I-interrupt mask */
++#define M6811_N_BIT 0x08 /* Negative */
++#define M6811_Z_BIT 0x04 /* Zero */
++#define M6811_V_BIT 0x02 /* Overflow */
++#define M6811_C_BIT 0x01 /* Carry */
++
++/* Removed register definitions
++*/
++
++
++/* Some insns used by gas to turn relative branches into absolute ones. */
++#define M6811_BRA 0x20
++#define M6811_JMP 0x7e
++#define M6811_BSR 0x8d
++#define M6811_JSR 0xbd
++#define M6812_JMP 0x06
++#define M6812_BSR 0x07
++#define M6812_JSR 0x16
++
++/* Instruction code pages. Code page 1 is the default. */
++/*#define M6811_OPCODE_PAGE1 0x00*/
++#define M6811_OPCODE_PAGE2 0x18
++#define M6811_OPCODE_PAGE3 0x1A
++#define M6811_OPCODE_PAGE4 0xCD
++
++
++/* 68HCS12XGATE operands formats as stored in the m6811_opcode table. These
++ flags do not correspond to anything in the 68HCS12XGATE or 68HC12.
++ They are only used by GAS to recognize operands. */
++
++#define M68XG_OP_NONE 0x0001
++#define M68XG_OP_IMM3 0x0002
++#define M68XG_OP_R 0x0004
++#define M68XG_OP_R_R 0x0008
++#define M68XG_OP_R_IMM4 0x0010
++#define M68XG_OP_R_R_R 0x0020
++#define M68XG_OP_REL9 0x0040
++#define M68XG_OP_REL10 0x0080
++#define M68XG_OP_R_R_OFFS5 0x0100
++#define M68XG_OP_RD_RB_RI 0x0200
++#define M68XG_OP_RD_RB_RIp 0x0400
++#define M68XG_OP_RD_RB_mRI 0x0800
++#define M68XG_OP_R_IMM8 0x1000
++#define M68XG_OP_R_IMM16 0x2000
++#define M68XG_OP_REG 0x10000 /* Register operand 1 */
++#define M68XG_OP_REG_2 0x20000 /* Register operand 2 */
++#define M68XG_MAX_OPERANDS 3 /* Max operands of triadic r1, r2, r3 */
++
++
++// probably want to scrub all of these
++#define M6811_OP_BRANCH 0x00008000 /* Branch, jsr, call */
++#define M6811_OP_BITMASK 0x00010000 /* Bitmask: #<val-8> */
++
++/* Markers to identify some instructions. */
++#define M6812_OP_EXG_MARKER 0x01000000 /* exg r1,r2 */
++#define M6812_OP_TFR_MARKER 0x02000000 /* tfr r1,r2 */
++#define M6812_OP_SEX_MARKER 0x04000000 /* sex r1,r2 */
++
++#define M68XG_OP_B_MARKER 0x04000000 /* bXX rel9 */
++#define M68XG_OP_BRA_MARKER 0x02000000 /* bra rel10 */
++
++#define M6812_OP_TRAP_ID 0x80000000 /* trap #N */
++
++#define M6811_OP_HIGH_ADDR 0x01000000 /* Used internally by gas. */
++#define M6811_OP_LOW_ADDR 0x02000000
++
++#define M68HC12_BANK_VIRT 0x010000
++#define M68HC12_BANK_MASK 0x00003fff
++#define M68HC12_BANK_BASE 0x00008000
++#define M68HC12_BANK_SHIFT 14
++#define M68HC12_BANK_PAGE_MASK 0x0ff
++
++
++/* CPU identification. */
++#define cpu6811 0x01
++#define cpu6812 0x02
++#define cpu6812s 0x04
++#define cpu9s12xe 0x08
++#define cpu9s12xgate 0x10
++
++/* The opcode table is an array of struct m68hcs12xgate_opcode. */
++struct m68hcs12xgate_opcode {
++ const char* name; /* Op-code name */
++ long format;
++ unsigned int opcode; // base opcode with zero in register place
++ unsigned int opcode_mask; // mask with zero in register place
++};
++
++/* The opcode table. The table contains all the opcodes (all pages).
++ You can't rely on the order. */
++extern const struct m68hcs12xgate_opcode m68hcs12xgate_opcodes[];
++extern const int m68hcs12xgate_num_opcodes;
++
++#endif /* _OPCODE_M9S12XG_H */
+diff -u -r -N binutils-2.18/ld/configure.tgt binutils-2.18-s12x/ld/configure.tgt
+--- binutils-2.18/ld/configure.tgt 2007-08-28 18:19:42.000000000 +0100
++++ binutils-2.18-s12x/ld/configure.tgt 2008-03-21 14:14:05.000000000 +0000
+@@ -307,6 +307,8 @@
+ targ_extra_emuls="m68hc11elfb m68hc12elf m68hc12elfb" ;;
+ m68hc12-*-*|m6812-*-*) targ_emul=m68hc12elf
+ targ_extra_emuls="m68hc12elfb m68hc11elf m68hc11elfb" ;;
++m9s12x-*-*) targ_emul=m68hc12elf
++ targ_extra_emuls="m9s12xgelf m9s12xgelfb m68hc12elf m68hc12elfb m68hc11elf m68hc11elfb" ;;
+ m68*-sun-sunos[34]*) targ_emul=sun3 ;;
+ m68*-wrs-vxworks*) targ_emul=sun3 ;;
+ m68*-ericsson-ose) targ_emul=sun3 ;;
+diff -u -r -N binutils-2.18/ld/emulparams/m9s12xgelfb.sh binutils-2.18-s12x/ld/emulparams/m9s12xgelfb.sh
+--- binutils-2.18/ld/emulparams/m9s12xgelfb.sh 1970-01-01 01:00:00.000000000 +0100
++++ binutils-2.18-s12x/ld/emulparams/m9s12xgelfb.sh 2008-03-20 20:47:12.000000000 +0000
+@@ -0,0 +1,12 @@
++MACHINE=
++SCRIPT_NAME=elfm9s12xg
++OUTPUT_FORMAT="elf32-m68hc12"
++TEXT_MEMORY=text
++DATA_MEMORY=data
++EEPROM_MEMORY=eeprom
++ARCH=m9s12xg
++MAXPAGESIZE=32
++GENERIC_BOARD=yes
++TEMPLATE_NAME=elf32
++EXTRA_EM_FILE=m9s12xgelf
++
+diff -u -r -N binutils-2.18/ld/emulparams/m9s12xgelf.sh binutils-2.18-s12x/ld/emulparams/m9s12xgelf.sh
+--- binutils-2.18/ld/emulparams/m9s12xgelf.sh 1970-01-01 01:00:00.000000000 +0100
++++ binutils-2.18-s12x/ld/emulparams/m9s12xgelf.sh 2008-03-20 20:47:26.000000000 +0000
+@@ -0,0 +1,18 @@
++MACHINE=
++SCRIPT_NAME=elfm9s12xg
++OUTPUT_FORMAT="elf32-m68hc12"
++ROM_START_ADDR=0x08000
++ROM_SIZE=0x8000
++RAM_START_ADDR=0x01100
++RAM_SIZE=0x6F00
++EEPROM_START_ADDR=0xb600
++EEPROM_SIZE=512
++TEXT_MEMORY=text
++DATA_MEMORY=data
++EEPROM_MEMORY=eeprom
++ARCH=m9s12xg
++MAXPAGESIZE=32
++EMBEDDED=yes
++GENERIC_BOARD=no
++TEMPLATE_NAME=elf32
++EXTRA_EM_FILE=m9s12xgelf
+diff -u -r -N binutils-2.18/ld/emultempl/m9s12xgelf.em binutils-2.18-s12x/ld/emultempl/m9s12xgelf.em
+--- binutils-2.18/ld/emultempl/m9s12xgelf.em 1970-01-01 01:00:00.000000000 +0100
++++ binutils-2.18-s12x/ld/emultempl/m9s12xgelf.em 2008-03-20 20:48:12.000000000 +0000
+@@ -0,0 +1,376 @@
++# This shell script emits a C file. -*- C -*-
++# Copyright 1991, 1993, 1994, 1997, 1999, 2000, 2001, 2002, 2003, 2007
++# Free Software Foundation, Inc.
++#
++# This file is part of the GNU Binutils.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
++# MA 02110-1301, USA.
++#
++
++# This file is sourced from elf32.em, and defines extra m68hc12-elf
++# and m68hc11-elf specific routines. It is used to generate the
++# HC11/HC12 trampolines to call a far function by using a normal 'jsr/bsr'.
++#
++# - The HC11/HC12 relocations are checked to see if there is a
++# R_M68HC11_16 relocation to a symbol marked with STO_M68HC12_FAR.
++# This relocation cannot be made on the symbol but must be made on
++# its trampoline
++# The trampolines to generate are collected during this pass
++# (See elf32_m68hc11_size_stubs)
++#
++# - The trampolines are generated in a ".tramp" section. The generation
++# takes care of HC11 and HC12 specificities.
++# (See elf32_m68hc11_build_stubs)
++#
++# - During relocation the R_M68HC11_16 relocation to the far symbols
++# are redirected to the trampoline that was generated.
++#
++# Copied from hppaelf and adapted for M68HC11/M68HC12 specific needs.
++#
++fragment <<EOF
++
++#include "ldctor.h"
++#include "elf32-m9s12xg.h"
++
++static asection *m9s12xgelf_add_stub_section (const char *, asection *);
++
++/* Fake input file for stubs. */
++static lang_input_statement_type *stub_file;
++
++/* By default the HC11/HC12 trampolines to call a far function using
++ a normal 'bsr' and 'jsr' convention are generated during the link.
++ The --no-trampoline option prevents that. */
++static int no_trampoline = 0;
++
++/* Name of memory bank window in the MEMORY description.
++ This is set by --bank-window option. */
++static const char* bank_window_name = 0;
++
++static void
++m9s12xg_elf_${EMULATION_NAME}_before_allocation (void)
++{
++ lang_memory_region_type* region;
++ int ret;
++
++ gld${EMULATION_NAME}_before_allocation ();
++
++ /* If generating a relocatable output file, then we don't
++ have to generate the trampolines. */
++ if (link_info.relocatable)
++ return;
++
++ ret = elf32_m9s12xg_setup_section_lists (output_bfd, &link_info);
++ if (ret != 0 && no_trampoline == 0)
++ {
++ if (ret < 0)
++ {
++ einfo ("%X%P: can not size stub section: %E\n");
++ return;
++ }
++
++ /* Call into the BFD backend to do the real work. */
++ if (!elf32_m9s12xg_size_stubs (output_bfd,
++ stub_file->the_bfd,
++ &link_info,
++ &m9s12xgelf_add_stub_section))
++ {
++ einfo ("%X%P: can not size stub section: %E\n");
++ return;
++ }
++ }
++
++ if (bank_window_name == 0)
++ return;
++
++ /* The 'bank_window_name' memory region is a special region that describes
++ the memory bank window to access to paged memory. For 68HC12
++ this is fixed and should be:
++
++ window (rx) : ORIGIN = 0x8000, LENGTH = 16K
++
++ But for 68HC11 this is board specific. The definition of such
++ memory region allows to control how this paged memory is accessed. */
++ region = lang_memory_region_lookup (bank_window_name, FALSE);
++
++ /* Check the length to see if it was defined in the script. */
++ if (region->length != 0)
++ {
++ struct m9s12xg_page_info *pinfo;
++ unsigned i;
++
++ /* Get default values */
++ m9s12xg_elf_get_bank_parameters (&link_info);
++ pinfo = &m9s12xg_elf_hash_table (&link_info)->pinfo;
++
++ /* And override them with the region definition. */
++ pinfo->bank_size = region->length;
++ pinfo->bank_shift = 0;
++ for (i = pinfo->bank_size; i != 0; i >>= 1)
++ pinfo->bank_shift++;
++ pinfo->bank_shift--;
++ pinfo->bank_size = 1L << pinfo->bank_shift;
++ pinfo->bank_mask = (1 << pinfo->bank_shift) - 1;
++ pinfo->bank_physical = region->origin;
++ pinfo->bank_physical_end = region->origin + pinfo->bank_size;
++
++ if (pinfo->bank_size != region->length)
++ {
++ einfo (_("warning: the size of the 'window' memory region "
++ "is not a power of 2\n"));
++ einfo (_("warning: its size %d is truncated to %d\n"),
++ region->length, pinfo->bank_size);
++ }
++ }
++}
++
++/* This is called before the input files are opened. We create a new
++ fake input file to hold the stub sections. */
++
++static void
++m9s12xgelf_create_output_section_statements (void)
++{
++ stub_file = lang_add_input_file ("linker stubs",
++ lang_input_file_is_fake_enum,
++ NULL);
++ stub_file->the_bfd = bfd_create ("linker stubs", output_bfd);
++ if (stub_file->the_bfd == NULL
++ || !bfd_set_arch_mach (stub_file->the_bfd,
++ bfd_get_arch (output_bfd),
++ bfd_get_mach (output_bfd)))
++ {
++ einfo ("%X%P: can not create BFD %E\n");
++ return;
++ }
++
++ ldlang_add_file (stub_file);
++}
++
++
++struct hook_stub_info
++{
++ lang_statement_list_type add;
++ asection *input_section;
++};
++
++/* Traverse the linker tree to find the spot where the stub goes. */
++
++static bfd_boolean
++hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp)
++{
++ lang_statement_union_type *l;
++ bfd_boolean ret;
++
++ for (; (l = *lp) != NULL; lp = &l->header.next)
++ {
++ switch (l->header.type)
++ {
++ case lang_constructors_statement_enum:
++ ret = hook_in_stub (info, &constructor_list.head);
++ if (ret)
++ return ret;
++ break;
++
++ case lang_output_section_statement_enum:
++ ret = hook_in_stub (info,
++ &l->output_section_statement.children.head);
++ if (ret)
++ return ret;
++ break;
++
++ case lang_wild_statement_enum:
++ ret = hook_in_stub (info, &l->wild_statement.children.head);
++ if (ret)
++ return ret;
++ break;
++
++ case lang_group_statement_enum:
++ ret = hook_in_stub (info, &l->group_statement.children.head);
++ if (ret)
++ return ret;
++ break;
++
++ case lang_input_section_enum:
++ if (l->input_section.section == info->input_section
++ || strcmp (bfd_get_section_name (output_section,
++ l->input_section.section),
++ bfd_get_section_name (output_section,
++ info->input_section)) == 0)
++ {
++ /* We've found our section. Insert the stub immediately
++ before its associated input section. */
++ *lp = info->add.head;
++ *(info->add.tail) = l;
++ return TRUE;
++ }
++ break;
++
++ case lang_data_statement_enum:
++ case lang_reloc_statement_enum:
++ case lang_object_symbols_statement_enum:
++ case lang_output_statement_enum:
++ case lang_target_statement_enum:
++ case lang_input_statement_enum:
++ case lang_assignment_statement_enum:
++ case lang_padding_statement_enum:
++ case lang_address_statement_enum:
++ case lang_fill_statement_enum:
++ break;
++
++ default:
++ FAIL ();
++ break;
++ }
++ }
++ return FALSE;
++}
++
++
++/* Call-back for elf32_m68hc11_size_stubs. */
++
++/* Create a new stub section, and arrange for it to be linked
++ immediately before INPUT_SECTION. */
++
++static asection *
++m9s12xgelf_add_stub_section (const char *stub_sec_name,
++ asection *tramp_section)
++{
++ asection *stub_sec;
++ flagword flags;
++ asection *output_section;
++ const char *secname;
++ lang_output_section_statement_type *os;
++ struct hook_stub_info info;
++
++ stub_sec = bfd_make_section_anyway (stub_file->the_bfd, stub_sec_name);
++ if (stub_sec == NULL)
++ goto err_ret;
++
++ flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
++ | SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP);
++ if (!bfd_set_section_flags (stub_file->the_bfd, stub_sec, flags))
++ goto err_ret;
++
++ output_section = tramp_section->output_section;
++ secname = bfd_get_section_name (output_section->owner, output_section);
++ os = lang_output_section_find (secname);
++
++ /* Try to put the new section at the same place as an existing
++ .tramp section. Such .tramp section exists in most cases and
++ contains the trampoline code. This way we put the generated trampoline
++ at the correct place. */
++ info.input_section = tramp_section;
++ lang_list_init (&info.add);
++ lang_add_section (&info.add, stub_sec, os);
++
++ if (info.add.head == NULL)
++ goto err_ret;
++
++ if (hook_in_stub (&info, &os->children.head))
++ return stub_sec;
++
++ err_ret:
++ einfo ("%X%P: can not make stub section: %E\n");
++ return NULL;
++}
++
++/* Final emulation specific call. For the 68HC12 we use this opportunity
++ to build linker stubs. */
++
++static void
++m9s12xgelf_finish (void)
++{
++ /* Now build the linker stubs. */
++ if (stub_file->the_bfd->sections != NULL)
++ {
++ /* Call again the trampoline analyzer to initialize the trampoline
++ stubs with the correct symbol addresses. Since there could have
++ been relaxation, the symbol addresses that were found during
++ first call may no longer be correct. */
++ if (!elf32_m9s12xg_size_stubs (output_bfd,
++ stub_file->the_bfd,
++ &link_info, 0))
++ {
++ einfo ("%X%P: can not size stub section: %E\n");
++ return;
++ }
++ if (!elf32_m9s12xg_build_stubs (output_bfd, &link_info))
++ einfo ("%X%P: can not build stubs: %E\n");
++ }
++
++ gld${EMULATION_NAME}_finish ();
++}
++
++
++/* Avoid processing the fake stub_file in vercheck, stat_needed and
++ check_needed routines. */
++
++static void (*real_func) (lang_input_statement_type *);
++
++static void m9s12xg_for_each_input_file_wrapper (lang_input_statement_type *l)
++{
++ if (l != stub_file)
++ (*real_func) (l);
++}
++
++static void
++m9s12xg_lang_for_each_input_file (void (*func) (lang_input_statement_type *))
++{
++ real_func = func;
++ lang_for_each_input_file (&m9s12xg_for_each_input_file_wrapper);
++}
++
++#define lang_for_each_input_file m9s12xg_lang_for_each_input_file
++
++EOF
++
++# Define some shell vars to insert bits of code into the standard elf
++# parse_args and list_options functions.
++#
++PARSE_AND_LIST_PROLOGUE='
++#define OPTION_NO_TRAMPOLINE 300
++#define OPTION_BANK_WINDOW 301
++'
++
++# The options are repeated below so that no abbreviations are allowed.
++# Otherwise -s matches stub-group-size
++PARSE_AND_LIST_LONGOPTS='
++ { "no-trampoline", no_argument, NULL, OPTION_NO_TRAMPOLINE },
++ { "bank-window", required_argument, NULL, OPTION_BANK_WINDOW },
++'
++
++PARSE_AND_LIST_OPTIONS='
++ fprintf (file, _(""
++" --no-trampoline Do not generate the far trampolines used to call\n"
++" a far function using 'jsr' or 'bsr'.\n"
++" --bank-window NAME Specify the name of the memory region describing\n"
++" the layout of the memory bank window.\n"
++ ));
++'
++
++PARSE_AND_LIST_ARGS_CASES='
++ case OPTION_NO_TRAMPOLINE:
++ no_trampoline = 1;
++ break;
++ case OPTION_BANK_WINDOW:
++ bank_window_name = optarg;
++ break;
++'
++
++# Put these extra m9s12xgelf routines in ld_${EMULATION_NAME}_emulation
++#
++LDEMUL_BEFORE_ALLOCATION=m9s12xg_elf_${EMULATION_NAME}_before_allocation
++LDEMUL_FINISH=m9s12xgelf_finish
++LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=m9s12xgelf_create_output_section_statements
+diff -u -r -N binutils-2.18/ld/Makefile.am binutils-2.18-s12x/ld/Makefile.am
+--- binutils-2.18/ld/Makefile.am 2007-08-06 21:00:17.000000000 +0100
++++ binutils-2.18-s12x/ld/Makefile.am 2008-03-20 20:47:00.000000000 +0000
+@@ -259,6 +259,8 @@
+ em68hc11elfb.o \
+ em68hc12elf.o \
+ em68hc12elfb.o \
++ em9s12xgelf.o \
++ em9s12xgelfb.o \
+ em68k4knbsd.o \
+ em68kaout.o \
+ em68kaux.o \
+@@ -1170,6 +1172,14 @@
+ $(srcdir)/emultempl/m68hc1xelf.em $(ELF_DEPS) \
+ $(srcdir)/scripttempl/elfm68hc12.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68hc12elfb "$(tdir_m68hc12b)"
++em9s12xgelf.c: $(srcdir)/emulparams/m9s12xgelf.sh \
++ $(srcdir)/emultempl/m9s12xgateelf.em $(ELF_DEPS) \
++ $(srcdir)/scripttempl/elfm9s12xg.sc ${GEN_DEPENDS}
++ ${GENSCRIPTS} m9s12xgelf "$(tdir_m9s12xg)"
++em68hc12elfb.c: $(srcdir)/emulparams/m9s12xgelfb.sh \
++ $(srcdir)/emultempl/m9s12xgelf.em $(ELF_DEPS) \
++ $(srcdir)/scripttempl/elfm9s12xg.sc ${GEN_DEPENDS}
++ ${GENSCRIPTS} m9s12xgelfb "$(tdir_m68hcx12xgateb)"
+ em68k4knbsd.c: $(srcdir)/emulparams/m68k4knbsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68k4knbsd "$(tdir_m68k4knbsd)"
+diff -u -r -N binutils-2.18/ld/Makefile.in binutils-2.18-s12x/ld/Makefile.in
+--- binutils-2.18/ld/Makefile.in 2007-08-06 21:29:54.000000000 +0100
++++ binutils-2.18-s12x/ld/Makefile.in 2008-03-20 20:48:26.000000000 +0000
+@@ -506,6 +506,8 @@
+ em68hc11elfb.o \
+ em68hc12elf.o \
+ em68hc12elfb.o \
++ em9s12xgelf.o \
++ em9s12xgelfb.o \
+ em68k4knbsd.o \
+ em68kaout.o \
+ em68kaux.o \
+@@ -1996,6 +1998,14 @@
+ $(srcdir)/emultempl/m68hc1xelf.em $(ELF_DEPS) \
+ $(srcdir)/scripttempl/elfm68hc12.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68hc12elfb "$(tdir_m68hc12b)"
++em9s12xgelf.c: $(srcdir)/emulparams/m9s12xgelf.sh \
++ $(srcdir)/emultempl/m68hc1xelf.em $(ELF_DEPS) \
++ $(srcdir)/scripttempl/elfm9s12xg.sc ${GEN_DEPENDS}
++ ${GENSCRIPTS} m9s12xgelf "$(tdir_m9s12xg)"
++em9s12xgelfb.c: $(srcdir)/emulparams/m9s12xgelfb.sh \
++ $(srcdir)/emultempl/m68hc1xelf.em $(ELF_DEPS) \
++ $(srcdir)/scripttempl/elfm9s12xg.sc ${GEN_DEPENDS}
++ ${GENSCRIPTS} m9s12xgelfb "$(tdir_m9s12xgb)"
+ em68k4knbsd.c: $(srcdir)/emulparams/m68k4knbsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68k4knbsd "$(tdir_m68k4knbsd)"
+diff -u -r -N binutils-2.18/ld/scripttempl/elfm9s12xg.sc binutils-2.18-s12x/ld/scripttempl/elfm9s12xg.sc
+--- binutils-2.18/ld/scripttempl/elfm9s12xg.sc 1970-01-01 01:00:00.000000000 +0100
++++ binutils-2.18-s12x/ld/scripttempl/elfm9s12xg.sc 2008-02-08 23:23:59.000000000 +0000
+@@ -0,0 +1,460 @@
++#
++# Unusual variables checked by this code:
++# NOP - four byte opcode for no-op (defaults to 0)
++# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start
++# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ...
++# (e.g., .PARISC.global)
++# OTHER_SECTIONS - at the end
++# EXECUTABLE_SYMBOLS - symbols that must be defined for an
++# executable (e.g., _DYNAMIC_LINK)
++# TEXT_START_SYMBOLS - symbols that appear at the start of the
++# .text section.
++# DATA_START_SYMBOLS - symbols that appear at the start of the
++# .data section.
++# OTHER_BSS_SYMBOLS - symbols that appear at the start of the
++# .bss section besides __bss_start.
++# EMBEDDED - whether this is for an embedded system.
++#
++# When adding sections, do note that the names of some sections are used
++# when specifying the start address of the next.
++#
++test -z "$ENTRY" && ENTRY=_start
++test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT}
++test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
++if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi
++test "$LD_FLAG" = "N" && DATA_ADDR=.
++
++CTOR=".ctors ${CONSTRUCTING-0} :
++ {
++ ${CONSTRUCTING+ PROVIDE (__CTOR_LIST__ = .); }
++ ${CONSTRUCTING+${CTOR_START}}
++ KEEP (*(.ctors))
++
++ ${CONSTRUCTING+${CTOR_END}}
++ ${CONSTRUCTING+ PROVIDE(__CTOR_END__ = .); }
++ } ${RELOCATING+ > ${TEXT_MEMORY}}"
++
++DTOR=" .dtors ${CONSTRUCTING-0} :
++ {
++ ${CONSTRUCTING+ PROVIDE(__DTOR_LIST__ = .); }
++ KEEP (*(.dtors))
++ ${CONSTRUCTING+ PROVIDE(__DTOR_END__ = .); }
++ } ${RELOCATING+ > ${TEXT_MEMORY}}"
++
++
++VECTORS="
++ /* If the 'vectors_addr' symbol is defined, it indicates the start address
++ of interrupt vectors. This depends on the 68HC11 operating mode:
++
++ Addr
++ Single chip 0xffc0
++ Extended mode 0xffc0
++ Bootstrap 0x00c0
++ Test 0xbfc0
++
++ In general, the vectors address is 0xffc0. This can be overriden
++ with the '-defsym vectors_addr=0xbfc0' ld option.
++
++ Note: for the bootstrap mode, the interrupt vectors are at 0xbfc0 but
++ they are redirected to 0x00c0 by the internal PROM. Application's vectors
++ must also consist of jump instructions (see Motorola's manual). */
++
++ PROVIDE (_vectors_addr = DEFINED (vectors_addr) ? vectors_addr : 0xffc0);
++ .vectors DEFINED (vectors_addr) ? vectors_addr : 0xffc0 :
++ {
++ KEEP (*(.vectors))
++ }"
++
++#
++# We provide two emulations: a fixed on that defines some memory banks
++# and a configurable one that includes a user provided memory definition.
++#
++case $GENERIC_BOARD in
++ yes|1|YES)
++ MEMORY_DEF="
++/* Get memory banks definition from some user configuration file.
++ This file must be located in some linker directory (search path
++ with -L<dir>). See fixed memory banks emulation script. */
++INCLUDE memory.x;
++"
++ ;;
++ *)
++MEMORY_DEF="
++/* Fixed definition of the available memory banks.
++ See generic emulation script for a user defined configuration. */
++MEMORY
++{
++ page0 (rwx) : ORIGIN = 0x0, LENGTH = 256
++ text (rx) : ORIGIN = ${ROM_START_ADDR}, LENGTH = ${ROM_SIZE}
++ data : ORIGIN = ${RAM_START_ADDR}, LENGTH = ${RAM_SIZE}
++ eeprom : ORIGIN = ${EEPROM_START_ADDR}, LENGTH = ${EEPROM_SIZE}
++}
++
++/* Setup the stack on the top of the data memory bank. */
++PROVIDE (_stack = ${RAM_START_ADDR} + ${RAM_SIZE} - 1);
++"
++ ;;
++esac
++
++STARTUP_CODE="
++ /* Startup code. */
++ KEEP (*(.install0)) /* Section should setup the stack pointer. */
++ KEEP (*(.install1)) /* Place holder for applications. */
++ KEEP (*(.install2)) /* Optional installation of data sections in RAM. */
++ KEEP (*(.install3)) /* Place holder for applications. */
++ KEEP (*(.install4)) /* Section that calls the main. */
++"
++
++FINISH_CODE="
++ /* Finish code. */
++ KEEP (*(.fini0)) /* Beginning of finish code (_exit symbol). */
++ KEEP (*(.fini1)) /* Place holder for applications. */
++ KEEP (*(.fini2)) /* C++ destructors. */
++ KEEP (*(.fini3)) /* Place holder for applications. */
++ KEEP (*(.fini4)) /* Runtime exit. */
++"
++
++PRE_COMPUTE_DATA_SIZE="
++/* SCz: this does not work yet... This is supposed to force the loading
++ of _map_data.o (from libgcc.a) when the .data section is not empty.
++ By doing so, this should bring the code that copies the .data section
++ from ROM to RAM at init time.
++
++ ___pre_comp_data_size = SIZEOF(.data);
++ __install_data_sections = ___pre_comp_data_size > 0 ?
++ __map_data_sections : 0;
++*/
++"
++
++INSTALL_RELOC="
++ .install0 0 : { *(.install0) }
++ .install1 0 : { *(.install1) }
++ .install2 0 : { *(.install2) }
++ .install3 0 : { *(.install3) }
++ .install4 0 : { *(.install4) }
++"
++
++FINISH_RELOC="
++ .fini0 0 : { *(.fini0) }
++ .fini1 0 : { *(.fini1) }
++ .fini2 0 : { *(.fini2) }
++ .fini3 0 : { *(.fini3) }
++ .fini4 0 : { *(.fini4) }
++"
++
++BSS_DATA_RELOC="
++ .data1 0 : { *(.data1) }
++
++ /* We want the small data sections together, so single-instruction offsets
++ can access them all, and initialized data all before uninitialized, so
++ we can shorten the on-disk segment size. */
++ .sdata 0 : { *(.sdata) }
++ .sbss 0 : { *(.sbss) }
++ .scommon 0 : { *(.scommon) }
++"
++
++SOFT_REGS_RELOC="
++ .softregs 0 : { *(.softregs) }
++"
++
++cat <<EOF
++${RELOCATING+/* Linker script for 68HCS12XGATE executable (PROM). */}
++${RELOCATING-/* Linker script for 68HCS12XGATE object file (ld -r). */}
++
++OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}",
++ "${LITTLE_OUTPUT_FORMAT}")
++OUTPUT_ARCH(${OUTPUT_ARCH})
++ENTRY(${ENTRY})
++
++${RELOCATING+${LIB_SEARCH_DIRS}}
++${RELOCATING+${EXECUTABLE_SYMBOLS}}
++${RELOCATING+${MEMORY_DEF}}
++
++SECTIONS
++{
++ .hash ${RELOCATING-0} : { *(.hash) }
++ .dynsym ${RELOCATING-0} : { *(.dynsym) }
++ .dynstr ${RELOCATING-0} : { *(.dynstr) }
++ .gnu.version ${RELOCATING-0} : { *(.gnu.version) }
++ .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) }
++ .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) }
++
++ .rel.text ${RELOCATING-0} :
++ {
++ *(.rel.text)
++ ${RELOCATING+*(.rel.text.*)}
++ ${RELOCATING+*(.rel.gnu.linkonce.t.*)}
++ }
++ .rela.text ${RELOCATING-0} :
++ {
++ *(.rela.text)
++ ${RELOCATING+*(.rela.text.*)}
++ ${RELOCATING+*(.rela.gnu.linkonce.t.*)}
++ }
++ .rel.data ${RELOCATING-0} :
++ {
++ *(.rel.data)
++ ${RELOCATING+*(.rel.data.*)}
++ ${RELOCATING+*(.rel.gnu.linkonce.d.*)}
++ }
++ .rela.data ${RELOCATING-0} :
++ {
++ *(.rela.data)
++ ${RELOCATING+*(.rela.data.*)}
++ ${RELOCATING+*(.rela.gnu.linkonce.d.*)}
++ }
++ .rel.rodata ${RELOCATING-0} :
++ {
++ *(.rel.rodata)
++ ${RELOCATING+*(.rel.rodata.*)}
++ ${RELOCATING+*(.rel.gnu.linkonce.r.*)}
++ }
++ .rela.rodata ${RELOCATING-0} :
++ {
++ *(.rela.rodata)
++ ${RELOCATING+*(.rela.rodata.*)}
++ ${RELOCATING+*(.rela.gnu.linkonce.r.*)}
++ }
++ .rel.sdata ${RELOCATING-0} :
++ {
++ *(.rel.sdata)
++ ${RELOCATING+*(.rel.sdata.*)}
++ ${RELOCATING+*(.rel.gnu.linkonce.s.*)}
++ }
++ .rela.sdata ${RELOCATING-0} :
++ {
++ *(.rela.sdata)
++ ${RELOCATING+*(.rela.sdata.*)}
++ ${RELOCATING+*(.rela.gnu.linkonce.s.*)}
++ }
++ .rel.sbss ${RELOCATING-0} :
++ {
++ *(.rel.sbss)
++ ${RELOCATING+*(.rel.sbss.*)}
++ ${RELOCATING+*(.rel.gnu.linkonce.sb.*)}
++ }
++ .rela.sbss ${RELOCATING-0} :
++ {
++ *(.rela.sbss)
++ ${RELOCATING+*(.rela.sbss.*)}
++ ${RELOCATING+*(.rel.gnu.linkonce.sb.*)}
++ }
++ .rel.bss ${RELOCATING-0} :
++ {
++ *(.rel.bss)
++ ${RELOCATING+*(.rel.bss.*)}
++ ${RELOCATING+*(.rel.gnu.linkonce.b.*)}
++ }
++ .rela.bss ${RELOCATING-0} :
++ {
++ *(.rela.bss)
++ ${RELOCATING+*(.rela.bss.*)}
++ ${RELOCATING+*(.rela.gnu.linkonce.b.*)}
++ }
++ .rel.stext ${RELOCATING-0} : { *(.rel.stest) }
++ .rela.stext ${RELOCATING-0} : { *(.rela.stest) }
++ .rel.etext ${RELOCATING-0} : { *(.rel.etest) }
++ .rela.etext ${RELOCATING-0} : { *(.rela.etest) }
++ .rel.sdata ${RELOCATING-0} : { *(.rel.sdata) }
++ .rela.sdata ${RELOCATING-0} : { *(.rela.sdata) }
++ .rel.edata ${RELOCATING-0} : { *(.rel.edata) }
++ .rela.edata ${RELOCATING-0} : { *(.rela.edata) }
++ .rel.eit_v ${RELOCATING-0} : { *(.rel.eit_v) }
++ .rela.eit_v ${RELOCATING-0} : { *(.rela.eit_v) }
++ .rel.ebss ${RELOCATING-0} : { *(.rel.ebss) }
++ .rela.ebss ${RELOCATING-0} : { *(.rela.ebss) }
++ .rel.srodata ${RELOCATING-0} : { *(.rel.srodata) }
++ .rela.srodata ${RELOCATING-0} : { *(.rela.srodata) }
++ .rel.erodata ${RELOCATING-0} : { *(.rel.erodata) }
++ .rela.erodata ${RELOCATING-0} : { *(.rela.erodata) }
++ .rel.got ${RELOCATING-0} : { *(.rel.got) }
++ .rela.got ${RELOCATING-0} : { *(.rela.got) }
++ .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) }
++ .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) }
++ .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) }
++ .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) }
++ .rel.init ${RELOCATING-0} : { *(.rel.init) }
++ .rela.init ${RELOCATING-0} : { *(.rela.init) }
++ .rel.fini ${RELOCATING-0} : { *(.rel.fini) }
++ .rela.fini ${RELOCATING-0} : { *(.rela.fini) }
++ .rel.plt ${RELOCATING-0} : { *(.rel.plt) }
++ .rela.plt ${RELOCATING-0} : { *(.rela.plt) }
++
++ /* Concatenate .page0 sections. Put them in the page0 memory bank
++ unless we are creating a relocatable file. */
++ .page0 :
++ {
++ *(.page0)
++ ${RELOCATING+*(.softregs)}
++ } ${RELOCATING+ > page0}
++
++ /* Start of text section. */
++ .stext ${RELOCATING-0} :
++ {
++ *(.stext)
++ } ${RELOCATING+ > ${TEXT_MEMORY}}
++
++ .init ${RELOCATING-0} :
++ {
++ *(.init)
++ } ${RELOCATING+=${NOP-0}}
++
++ ${RELOCATING-${INSTALL_RELOC}}
++ ${RELOCATING-${FINISH_RELOC}}
++
++ .text ${RELOCATING-0}:
++ {
++ /* Put startup code at beginning so that _start keeps same address. */
++ ${RELOCATING+${STARTUP_CODE}}
++
++ ${RELOCATING+*(.init)}
++ *(.text)
++ ${RELOCATING+*(.text.*)}
++ /* .gnu.warning sections are handled specially by elf32.em. */
++ *(.gnu.warning)
++ ${RELOCATING+*(.gnu.linkonce.t.*)}
++ ${RELOCATING+*(.tramp)}
++ ${RELOCATING+*(.tramp.*)}
++
++ ${RELOCATING+${FINISH_CODE}}
++
++ ${RELOCATING+_etext = .;}
++ ${RELOCATING+PROVIDE (etext = .);}
++
++ } ${RELOCATING+ > ${TEXT_MEMORY}}
++
++ .eh_frame ${RELOCATING-0} :
++ {
++ KEEP (*(.eh_frame))
++ } ${RELOCATING+ > ${TEXT_MEMORY}}
++
++ .gcc_except_table ${RELOCATING-0} :
++ {
++ *(.gcc_except_table)
++ } ${RELOCATING+ > ${TEXT_MEMORY}}
++
++ .rodata ${RELOCATING-0} :
++ {
++ *(.rodata)
++ ${RELOCATING+*(.rodata.*)}
++ ${RELOCATING+*(.gnu.linkonce.r*)}
++ } ${RELOCATING+ > ${TEXT_MEMORY}}
++
++ .rodata1 ${RELOCATING-0} :
++ {
++ *(.rodata1)
++ } ${RELOCATING+ > ${TEXT_MEMORY}}
++
++ /* Constructor and destructor tables are in ROM. */
++ ${RELOCATING+${CTOR}}
++ ${RELOCATING+${DTOR}}
++
++ .jcr ${RELOCATING-0} :
++ {
++ KEEP (*(.jcr))
++ } ${RELOCATING+ > ${TEXT_MEMORY}}
++
++ /* Start of the data section image in ROM. */
++ ${RELOCATING+__data_image = .;}
++ ${RELOCATING+PROVIDE (__data_image = .);}
++
++ /* All read-only sections that normally go in PROM must be above.
++ We construct the DATA image section in PROM at end of all these
++ read-only sections. The data image must be copied at init time.
++ Refer to GNU ld, Section 3.6.8.2 Output Section LMA. */
++ .data ${RELOCATING-0} : ${RELOCATING+AT (__data_image)}
++ {
++ ${RELOCATING+__data_section_start = .;}
++ ${RELOCATING+PROVIDE (__data_section_start = .);}
++
++ ${RELOCATING+${DATA_START_SYMBOLS}}
++ ${RELOCATING+*(.sdata)}
++ *(.data)
++ ${RELOCATING+*(.data.*)}
++ ${RELOCATING+*(.data1)}
++ ${RELOCATING+*(.gnu.linkonce.d.*)}
++ ${CONSTRUCTING+CONSTRUCTORS}
++
++ ${RELOCATING+_edata = .;}
++ ${RELOCATING+PROVIDE (edata = .);}
++ } ${RELOCATING+ > ${DATA_MEMORY}}
++
++ ${RELOCATING+__data_section_size = SIZEOF(.data);}
++ ${RELOCATING+PROVIDE (__data_section_size = SIZEOF(.data));}
++ ${RELOCATING+__data_image_end = __data_image + __data_section_size;}
++
++ ${RELOCATING+${PRE_COMPUTE_DATA_SIZE}}
++
++ /* .install ${RELOCATING-0}:
++ {
++ . = _data_image_end;
++ } ${RELOCATING+ > ${TEXT_MEMORY}} */
++
++ /* Relocation for some bss and data sections. */
++ ${RELOCATING-${BSS_DATA_RELOC}}
++ ${RELOCATING-${SOFT_REGS_RELOC}}
++
++ .bss ${RELOCATING-0} :
++ {
++ ${RELOCATING+__bss_start = .;}
++ ${RELOCATING+*(.sbss)}
++ ${RELOCATING+*(.scommon)}
++
++ *(.dynbss)
++ *(.bss)
++ ${RELOCATING+*(.bss.*)}
++ ${RELOCATING+*(.gnu.linkonce.b.*)}
++ *(COMMON)
++ ${RELOCATING+PROVIDE (_end = .);}
++ } ${RELOCATING+ > ${DATA_MEMORY}}
++ ${RELOCATING+__bss_size = SIZEOF(.bss);}
++ ${RELOCATING+PROVIDE (__bss_size = SIZEOF(.bss));}
++
++ .eeprom ${RELOCATING-0} :
++ {
++ *(.eeprom)
++ *(.eeprom.*)
++ } ${RELOCATING+ > ${EEPROM_MEMORY}}
++
++ ${RELOCATING+${VECTORS}}
++
++ /* Stabs debugging sections. */
++ .stab 0 : { *(.stab) }
++ .stabstr 0 : { *(.stabstr) }
++ .stab.excl 0 : { *(.stab.excl) }
++ .stab.exclstr 0 : { *(.stab.exclstr) }
++ .stab.index 0 : { *(.stab.index) }
++ .stab.indexstr 0 : { *(.stab.indexstr) }
++
++ .comment 0 : { *(.comment) }
++
++ /* DWARF debug sections.
++ Symbols in the DWARF debugging sections are relative to the beginning
++ of the section so we begin them at 0.
++ Treatment of DWARF debug section must be at end of the linker
++ script to avoid problems when there are undefined symbols. It's necessary
++ to avoid that the DWARF section is relocated before such undefined
++ symbols are found. */
++
++ /* DWARF 1 */
++ .debug 0 : { *(.debug) }
++ .line 0 : { *(.line) }
++
++ /* GNU DWARF 1 extensions */
++ .debug_srcinfo 0 : { *(.debug_srcinfo) }
++ .debug_sfnames 0 : { *(.debug_sfnames) }
++
++ /* DWARF 1.1 and DWARF 2 */
++ .debug_aranges 0 : { *(.debug_aranges) }
++ .debug_pubnames 0 : { *(.debug_pubnames) }
++
++ /* DWARF 2 */
++ .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
++ .debug_abbrev 0 : { *(.debug_abbrev) }
++ .debug_line 0 : { *(.debug_line) }
++ .debug_frame 0 : { *(.debug_frame) }
++ .debug_str 0 : { *(.debug_str) }
++ .debug_loc 0 : { *(.debug_loc) }
++ .debug_macinfo 0 : { *(.debug_macinfo) }
++}
++EOF
+diff -u -r -N binutils-2.18/opcodes/configure binutils-2.18-s12x/opcodes/configure
+--- binutils-2.18/opcodes/configure 2007-08-06 21:29:45.000000000 +0100
++++ binutils-2.18-s12x/opcodes/configure 2008-03-21 13:55:45.000000000 +0000
+@@ -11441,6 +11441,8 @@
+ bfd_m32r_arch) ta="$ta m32r-asm.lo m32r-desc.lo m32r-dis.lo m32r-ibld.lo m32r-opc.lo m32r-opinst.lo" using_cgen=yes ;;
+ bfd_m68hc11_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;
+ bfd_m68hc12_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;
++ bfd_m9s12x_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;
++ bfd_m9s12xg_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;
+ bfd_m68k_arch) ta="$ta m68k-dis.lo m68k-opc.lo" ;;
+ bfd_m88k_arch) ta="$ta m88k-dis.lo" ;;
+ bfd_maxq_arch) ta="$ta maxq-dis.lo" ;;
+diff -u -r -N binutils-2.18/opcodes/configure.in binutils-2.18-s12x/opcodes/configure.in
+--- binutils-2.18/opcodes/configure.in 2007-08-06 20:58:39.000000000 +0100
++++ binutils-2.18-s12x/opcodes/configure.in 2008-03-20 20:48:57.000000000 +0000
+@@ -181,6 +181,8 @@
+ bfd_m32r_arch) ta="$ta m32r-asm.lo m32r-desc.lo m32r-dis.lo m32r-ibld.lo m32r-opc.lo m32r-opinst.lo" using_cgen=yes ;;
+ bfd_m68hc11_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;
+ bfd_m68hc12_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;
++ bfd_m9s12x_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;
++ bfd_m9s12xg_arch) ta="$ta m68hc11-dis.lo m68hc11-opc.lo" ;;
+ bfd_m68k_arch) ta="$ta m68k-dis.lo m68k-opc.lo" ;;
+ bfd_m88k_arch) ta="$ta m88k-dis.lo" ;;
+ bfd_maxq_arch) ta="$ta maxq-dis.lo" ;;
+diff -u -r -N binutils-2.18/opcodes/disassemble.c binutils-2.18-s12x/opcodes/disassemble.c
+--- binutils-2.18/opcodes/disassemble.c 2007-08-06 20:58:40.000000000 +0100
++++ binutils-2.18-s12x/opcodes/disassemble.c 2008-03-21 13:10:15.000000000 +0000
+@@ -50,6 +50,7 @@
+ #define ARCH_m32r
+ #define ARCH_m68hc11
+ #define ARCH_m68hc12
++#define ARCH_m9s12xg
+ #define ARCH_m68k
+ #define ARCH_m88k
+ #define ARCH_maxq
+@@ -228,13 +229,19 @@
+ disassemble = print_insn_m32r;
+ break;
+ #endif
+-#if defined(ARCH_m68hc11) || defined(ARCH_m68hc12)
++#if defined(ARCH_m68hc11) || defined(ARCH_m68hc12) || defined(ARCH_9s12x) || defined(ARCH_m9s12xg)
+ case bfd_arch_m68hc11:
+ disassemble = print_insn_m68hc11;
+ break;
+ case bfd_arch_m68hc12:
+ disassemble = print_insn_m68hc12;
+ break;
++ case bfd_arch_m9s12x:
++ disassemble = print_insn_m9s12x;
++ break;
++ case bfd_arch_m9s12xg:
++ disassemble = print_insn_m9s12xg;
++ break;
+ #endif
+ #ifdef ARCH_m68k
+ case bfd_arch_m68k:
+diff -u -r -N binutils-2.18/opcodes/m68hc11-dis.c binutils-2.18-s12x/opcodes/m68hc11-dis.c
+--- binutils-2.18/opcodes/m68hc11-dis.c 2007-08-06 20:59:06.000000000 +0100
++++ binutils-2.18-s12x/opcodes/m68hc11-dis.c 2009-10-09 00:48:35.000000000 +0100
+@@ -2,6 +2,7 @@
+ Copyright 1999, 2000, 2001, 2002, 2003, 2006, 2007
+ Free Software Foundation, Inc.
+ Written by Stephane Carrez (stcarrez@nerim.fr)
++ XGATE and S12X added by James Murray (jsm@jsm-net.demon.co.uk)
+
+ This file is part of the GNU opcodes library.
+
+@@ -98,8 +99,8 @@
+ /* 68HC12 requires an adjustment for movb/movw pc relative modes. */
+ if (reg == PC_REGNUM && info->mach == bfd_mach_m6812 && mov_insn)
+ sval += pc_offset;
+- (*info->fprintf_func) (info->stream, "%d,%s",
+- (int) sval, reg_name[reg]);
++ (*info->fprintf_func) (info->stream, "0x%x,%s",
++ (unsigned short) sval, reg_name[reg]);
+
+ if (reg == PC_REGNUM)
+ {
+@@ -127,8 +128,8 @@
+ sval = sval + 1;
+ mode = "+";
+ }
+- (*info->fprintf_func) (info->stream, "%d,%s%s%s",
+- (int) sval,
++ (*info->fprintf_func) (info->stream, "0x%x,%s%s%s",
++ (unsigned short) sval,
+ (buffer[0] & 0x10 ? "" : mode),
+ reg_name[reg], (buffer[0] & 0x10 ? mode : ""));
+ }
+@@ -151,7 +152,7 @@
+
+ pos += 2;
+ sval = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
+- (*info->fprintf_func) (info->stream, "[%u,%s]",
++ (*info->fprintf_func) (info->stream, "[0x%x,%s]",
+ sval & 0x0ffff, reg_name[reg]);
+ if (indirect)
+ *indirect = 1;
+@@ -188,8 +189,8 @@
+ pos++;
+ endaddr++;
+ }
+- (*info->fprintf_func) (info->stream, "%d,%s",
+- (int) sval, reg_name[reg]);
++ (*info->fprintf_func) (info->stream, "0x%x,%s",
++ (unsigned short) sval, reg_name[reg]);
+ if (reg == PC_REGNUM)
+ {
+ (* info->fprintf_func) (info->stream, " {");
+@@ -230,11 +231,89 @@
+ {
+ int status;
+ bfd_byte buffer[4];
+- unsigned char code;
++ unsigned int code;
+ long format, pos, i;
+ short sval;
+ const struct m68hc11_opcode *opcode;
+
++ if (arch & cpuxgate)
++ {
++ int val;
++ /* Get two bytes as all XGATE instructions are 16bit. */
++ status = read_memory (memaddr, buffer, 2, info);
++ if (status != 0)
++ {
++ return status;
++ }
++
++ format = 0;
++ code = (buffer[0]<<8) + buffer[1];
++
++ /* Scan the opcode table until we find the opcode
++ with the corresponding page. */
++ opcode = m68hc11_opcodes;
++ for (i = 0; i < m68hc11_num_opcodes; i++, opcode++)
++ {
++ if ((opcode->opcode != (code & opcode->xg_mask)) || (opcode->arch != cpuxgate)) {
++ continue;
++ }
++ /* We have found the opcode. Extract the operand and print it. */
++ (*info->fprintf_func) (info->stream, "%s", opcode->name);
++ format = opcode->format;
++ if (format & (M68XG_OP_NONE)) {
++ // ok
++ } else if (format & M68XG_OP_IMM3) {
++ (*info->fprintf_func) (info->stream, " #0x%x", (code >> 8) & 0x7 );
++ } else if (format & M68XG_OP_R_R) {
++ (*info->fprintf_func) (info->stream, " R%x, R%x", (code >> 8) & 0x7, (code >> 5) & 0x7 );
++ } else if (format & M68XG_OP_R_R_R) {
++ (*info->fprintf_func) (info->stream, " R%x, R%x, R%x", (code >> 8) & 0x7, (code >> 5) & 0x7, (code >> 2) & 0x7 );
++ } else if (format & M68XG_OP_RD_RB_RI) {
++ (*info->fprintf_func) (info->stream, " R%x, (R%x, R%x)", (code >> 8) & 0x7, (code >> 5) & 0x7, (code >> 2) & 0x7 );
++ } else if (format & M68XG_OP_RD_RB_RIp) {
++ (*info->fprintf_func) (info->stream, " R%x, (R%x, R%x+)", (code >> 8) & 0x7, (code >> 5) & 0x7, (code >> 2) & 0x7 );
++ } else if (format & M68XG_OP_RD_RB_mRI) {
++ (*info->fprintf_func) (info->stream, " R%x, (R%x, -R%x)", (code >> 8) & 0x7, (code >> 5) & 0x7, (code >> 2) & 0x7 );
++ } else if (format & M68XG_OP_R_R_OFFS5) {
++ (*info->fprintf_func) (info->stream, " R%x, (R%x, #0x%x)", (code >> 8) & 0x7, (code >> 5) & 0x7, code & 0x1f );
++ } else if (format & M68XG_OP_R_IMM8) {
++ (*info->fprintf_func) (info->stream, " R%x, #0x%02x", (code >> 8) & 0x7, code & 0xff);
++ } else if (format & M68XG_OP_R_IMM4) {
++ (*info->fprintf_func) (info->stream, " R%x, #0x%x", (code >> 8) & 0x7, (code & 0xf0)>>4);
++ } else if (format & M68XG_OP_REL9) {
++ (*info->fprintf_func) (info->stream, " 0x");
++ val = (buffer[0] & 0x1) ? buffer[1] | 0xFFFFFF00 : buffer[1];
++ (*info->print_address_func) (memaddr + (val<<1) + 2, info);
++
++ } else if (format & M68XG_OP_REL10) {
++ (*info->fprintf_func) (info->stream, " 0x");
++ val = (buffer[0]<<8) | (unsigned int)buffer[1];
++ if (val & 0x200) {
++ val |= 0xfffffc00;
++ } else {
++ val &= 0x000001ff;
++ }
++ (*info->print_address_func) (memaddr + (val<<1) +2 , info);
++ } else if ((code & 0x00ff) == 0x00f8) {
++ (*info->fprintf_func) (info->stream, " R%x, CCR", (code >> 8) & 0x7);
++ } else if ((code & 0x00ff) == 0x00f9) {
++ (*info->fprintf_func) (info->stream, " CCR, R%x", (code >> 8) & 0x7);
++ } else if ((code & 0x00ff) == 0x0) {
++ (*info->fprintf_func) (info->stream, " R%x, PC", (code >> 8) & 0x7);
++ } else if (format & M68XG_OP_R) {
++ (*info->fprintf_func) (info->stream, " R%x", (code >> 8) & 0x7 );
++ } else {
++ /* Opcode not recognized. */
++ (*info->fprintf_func) (info->stream, "Not yet handled .byte\t0x%04x", code);
++ }
++ return 2;
++ }
++ /* Opcode not recognized. */
++ (*info->fprintf_func) (info->stream, ".byte\t0x%04x", code);
++ return 2; // everything is two bytes
++ }
++ else /* HC11 and HC12 */
++ {
+ /* Get first byte. Only one at a time because we don't know the
+ size of the insn. */
+ status = read_memory (memaddr, buffer, 1, info);
+@@ -441,7 +520,7 @@
+ pc_dst_offset = 2;
+ if (format & M6811_OP_IMM8)
+ {
+- (*info->fprintf_func) (info->stream, "#%d", (int) buffer[0]);
++ (*info->fprintf_func) (info->stream, "#0x%x", (int) buffer[0]);
+ format &= ~M6811_OP_IMM8;
+ /* Set PC destination offset. */
+ pc_dst_offset = 1;
+@@ -449,17 +528,17 @@
+ else if (format & M6811_OP_IX)
+ {
+ /* Offsets are in range 0..255, print them unsigned. */
+- (*info->fprintf_func) (info->stream, "%u,x", buffer[0] & 0x0FF);
++ (*info->fprintf_func) (info->stream, "0x%x,x", buffer[0] & 0x0FF);
+ format &= ~M6811_OP_IX;
+ }
+ else if (format & M6811_OP_IY)
+ {
+- (*info->fprintf_func) (info->stream, "%u,y", buffer[0] & 0x0FF);
++ (*info->fprintf_func) (info->stream, "0x%x,y", buffer[0] & 0x0FF);
+ format &= ~M6811_OP_IY;
+ }
+ else if (format & M6811_OP_DIRECT)
+ {
+- (*info->fprintf_func) (info->stream, "*");
++ (*info->fprintf_func) (info->stream, "*0x");
+ (*info->print_address_func) (buffer[0] & 0x0FF, info);
+ format &= ~M6811_OP_DIRECT;
+ }
+@@ -508,6 +587,7 @@
+ sval |= 0xff00;
+
+ pos += 2;
++ (*info->fprintf_func) (info->stream, " 0x");
+ (*info->print_address_func) (memaddr + pos + sval, info);
+ format &= ~(M6812_OP_REG | M6811_OP_JUMP_REL);
+ }
+@@ -585,12 +665,13 @@
+ else
+ format &= ~M6811_OP_IND16;
+
++ (*info->fprintf_func) (info->stream, "0x");
+ (*info->print_address_func) (addr, info);
+ if (format & M6812_OP_PAGE)
+ {
+ (* info->fprintf_func) (info->stream, " {");
+ (* info->print_address_func) (val, info);
+- (* info->fprintf_func) (info->stream, ", %d}", page);
++ (* info->fprintf_func) (info->stream, ", 0x%x}", page);
+ format &= ~M6812_OP_PAGE;
+ pos += 1;
+ }
+@@ -622,6 +703,7 @@
+
+ val = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
+ val &= 0x0FFFF;
++ (*info->fprintf_func) (info->stream, " 0x");
+ (*info->print_address_func) (val, info);
+ }
+
+@@ -636,7 +718,7 @@
+ return status;
+ }
+ pos++;
+- (*info->fprintf_func) (info->stream, " #$%02x%s",
++ (*info->fprintf_func) (info->stream, ", #0x%02x%s",
+ buffer[0] & 0x0FF,
+ (format & M6811_OP_JUMP_REL ? " " : ""));
+ format &= ~M6811_OP_BITMASK;
+@@ -651,6 +733,7 @@
+ return status;
+ }
+
++ (*info->fprintf_func) (info->stream, " 0x");
+ pos++;
+ val = (buffer[0] & 0x80) ? buffer[0] | 0xFFFFFF00 : buffer[0];
+ (*info->print_address_func) (memaddr + pos + val, info);
+@@ -671,6 +754,7 @@
+ if (val & 0x8000)
+ val |= 0xffff0000;
+
++ (*info->fprintf_func) (info->stream, " 0x");
+ (*info->print_address_func) (memaddr + pos + val, info);
+ format &= ~M6812_OP_JUMP_REL16;
+ }
+@@ -687,7 +771,7 @@
+ pos += 1;
+
+ val = buffer[0] & 0x0ff;
+- (*info->fprintf_func) (info->stream, ", %d", val);
++ (*info->fprintf_func) (info->stream, ", 0x%x", val);
+ }
+
+ #ifdef DEBUG
+@@ -710,7 +794,7 @@
+ /* Opcode not recognized. */
+ if (format == M6811_OP_PAGE2 && arch & cpu6812
+ && ((code >= 0x30 && code <= 0x39) || (code >= 0x40)))
+- (*info->fprintf_func) (info->stream, "trap\t#%d", code & 0x0ff);
++ (*info->fprintf_func) (info->stream, "trap\t#0x%02x", code & 0x0ff);
+
+ else if (format == M6811_OP_PAGE2)
+ (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x",
+@@ -725,6 +809,7 @@
+ (*info->fprintf_func) (info->stream, ".byte\t0x%02x", code);
+
+ return pos;
++ }
+ }
+
+ /* Disassemble one instruction at address 'memaddr'. Returns the number
+@@ -740,3 +825,18 @@
+ {
+ return print_insn (memaddr, info, cpu6812);
+ }
++
++int
++print_insn_m9s12x (bfd_vma memaddr, struct disassemble_info* info)
++{
++ return print_insn (memaddr, info, cpu6812|cpu9s12x);
++}
++
++int
++print_insn_m9s12xg (bfd_vma memaddr, struct disassemble_info* info)
++{
++ return print_insn (memaddr, info, cpuxgate);
++}
++
++
++
+diff -u -r -N binutils-2.18/opcodes/m68hc11-opc.c binutils-2.18-s12x/opcodes/m68hc11-opc.c
+--- binutils-2.18/opcodes/m68hc11-opc.c 2007-08-06 20:59:06.000000000 +0100
++++ binutils-2.18-s12x/opcodes/m68hc11-opc.c 2010-05-04 11:36:22.000000000 +0100
+@@ -1,6 +1,9 @@
+-/* m68hc11-opc.c -- Motorola 68HC11 & 68HC12 opcode list
+- Copyright 1999, 2000, 2002, 2007 Free Software Foundation, Inc.
++/* m68hc11-opc.c -- Motorola/Freescale 68HC11, 68HC12, S12X and XGATE
++ opcode list.
++ Copyright 1999, 2000, 2002, 2007, 2008 Free Software Foundation, Inc.
+ Written by Stephane Carrez (stcarrez@nerim.fr)
++ XGATE and S12X added by James Murray (jsm@jsm-net.demon.co.uk)
++ Note: min/max cycles not updated for S12X opcodes.
+
+ This file is part of the GNU opcodes library.
+
+@@ -91,6 +94,10 @@
+ #define OP_REG_1 M6812_OP_REG
+ #define OP_REG_2 M6812_OP_REG_2
+ #define OP_IDX_p2 M6812_OP_IDX_P2
++#define OP_IDX1_p2 M6812_OP_IDX1_P2
++#define OP_IDX2_p2 M6812_OP_IDX2_P2
++#define OP_D_IDX_p2 M6812_OP_D_IDX_P2
++#define OP_D_IDX2_p2 M6812_OP_D_IDX2_P2
+ #define OP_IND16_p2 M6812_OP_IND16_P2
+ #define OP_TRAP_ID M6812_OP_TRAP_ID
+ #define OP_EXG_MARKER M6812_OP_EXG_MARKER
+@@ -103,956 +110,1603 @@
+ #define OP_IBNE_MARKER (M6812_OP_IBCC_MARKER)
+
+ /*
+- { "test", OP_NONE, 1, 0x00, 5, _M, CHG_NONE, cpu6811 },
+- +-- cpu
++ { "test", OP_NONE, 1, 0x00, 5, _M, CHG_NONE, cpu6811, 0 },
++ +-- cpu +-- XGATE opcode mask
+ Name -+ +------- Insn CCR changes
+ Format ------+ +----------- Max # cycles
+ Size --------------------+ +--------------- Min # cycles
+ +--------------------- Opcode
+ */
+ const struct m68hc11_opcode m68hc11_opcodes[] = {
+- { "aba", OP_NONE, 1, 0x1b, 2, 2, CHG_HNZVC, cpu6811 },
+- { "aba", OP_NONE | OP_PAGE2,2, 0x06, 2, 2, CHG_HNZVC, cpu6812 },
+- { "abx", OP_NONE, 1, 0x3a, 3, 3, CHG_NONE, cpu6811 },
+- { "aby", OP_NONE | OP_PAGE2,2, 0x3a, 4, 4, CHG_NONE, cpu6811 },
+-
+- { "adca", OP_IMM8, 2, 0x89, 1, 1, CHG_HNZVC, cpu6811|cpu6812 },
+- { "adca", OP_DIRECT, 2, 0x99, 3, 3, CHG_HNZVC, cpu6811|cpu6812 },
+- { "adca", OP_IND16, 3, 0xb9, 3, 3, CHG_HNZVC, cpu6811|cpu6812 },
+- { "adca", OP_IX, 2, 0xa9, 4, 4, CHG_HNZVC, cpu6811 },
+- { "adca", OP_IY | OP_PAGE2, 3, 0xa9, 5, 5, CHG_HNZVC, cpu6811 },
+- { "adca", OP_IDX, 2, 0xa9, 3, 3, CHG_HNZVC, cpu6812 },
+- { "adca", OP_IDX_1, 3, 0xa9, 3, 3, CHG_HNZVC, cpu6812 },
+- { "adca", OP_IDX_2, 4, 0xa9, 4, 4, CHG_HNZVC, cpu6812 },
+- { "adca", OP_D_IDX, 2, 0xa9, 6, 6, CHG_HNZVC, cpu6812 },
+- { "adca", OP_D_IDX_2, 4, 0xa9, 6, 6, CHG_HNZVC, cpu6812 },
+-
+- { "adcb", OP_IMM8, 2, 0xc9, 1, 1, CHG_HNZVC, cpu6811|cpu6812 },
+- { "adcb", OP_DIRECT, 2, 0xd9, 3, 3, CHG_HNZVC, cpu6811|cpu6812 },
+- { "adcb", OP_IND16, 3, 0xf9, 3, 3, CHG_HNZVC, cpu6811|cpu6812 },
+- { "adcb", OP_IX, 2, 0xe9, 4, 4, CHG_HNZVC, cpu6811 },
+- { "adcb", OP_IY | OP_PAGE2, 3, 0xe9, 5, 5, CHG_HNZVC, cpu6811 },
+- { "adcb", OP_IDX, 2, 0xe9, 3, 3, CHG_HNZVC, cpu6812 },
+- { "adcb", OP_IDX_1, 3, 0xe9, 3, 3, CHG_HNZVC, cpu6812 },
+- { "adcb", OP_IDX_2, 4, 0xe9, 4, 4, CHG_HNZVC, cpu6812 },
+- { "adcb", OP_D_IDX, 2, 0xe9, 6, 6, CHG_HNZVC, cpu6812 },
+- { "adcb", OP_D_IDX_2, 4, 0xe9, 6, 6, CHG_HNZVC, cpu6812 },
+-
+- { "adda", OP_IMM8, 2, 0x8b, 1, 1, CHG_HNZVC, cpu6811|cpu6812 },
+- { "adda", OP_DIRECT, 2, 0x9b, 3, 3, CHG_HNZVC, cpu6811|cpu6812 },
+- { "adda", OP_IND16, 3, 0xbb, 3, 3, CHG_HNZVC, cpu6811|cpu6812 },
+- { "adda", OP_IX, 2, 0xab, 4, 4, CHG_HNZVC, cpu6811 },
+- { "adda", OP_IY | OP_PAGE2, 3, 0xab, 5, 5, CHG_HNZVC, cpu6811 },
+- { "adda", OP_IDX, 2, 0xab, 3, 3, CHG_HNZVC, cpu6812 },
+- { "adda", OP_IDX_1, 3, 0xab, 3, 3, CHG_HNZVC, cpu6812 },
+- { "adda", OP_IDX_2, 4, 0xab, 4, 4, CHG_HNZVC, cpu6812 },
+- { "adda", OP_D_IDX, 2, 0xab, 6, 6, CHG_HNZVC, cpu6812 },
+- { "adda", OP_D_IDX_2, 4, 0xab, 6, 6, CHG_HNZVC, cpu6812 },
+-
+- { "addb", OP_IMM8, 2, 0xcb, 1, 1, CHG_HNZVC, cpu6811|cpu6812 },
+- { "addb", OP_DIRECT, 2, 0xdb, 3, 3, CHG_HNZVC, cpu6811|cpu6812 },
+- { "addb", OP_IND16, 3, 0xfb, 3, 3, CHG_HNZVC, cpu6811|cpu6812 },
+- { "addb", OP_IX, 2, 0xeb, 4, 4, CHG_HNZVC, cpu6811 },
+- { "addb", OP_IY | OP_PAGE2, 3, 0xeb, 5, 5, CHG_HNZVC, cpu6811 },
+- { "addb", OP_IDX, 2, 0xeb, 3, 3, CHG_HNZVC, cpu6812 },
+- { "addb", OP_IDX_1, 3, 0xeb, 3, 3, CHG_HNZVC, cpu6812 },
+- { "addb", OP_IDX_2, 4, 0xeb, 4, 4, CHG_HNZVC, cpu6812 },
+- { "addb", OP_D_IDX, 2, 0xeb, 6, 6, CHG_HNZVC, cpu6812 },
+- { "addb", OP_D_IDX_2, 4, 0xeb, 6, 6, CHG_HNZVC, cpu6812 },
+-
+- { "addd", OP_IMM16, 3, 0xc3, 2, 2, CHG_NZVC, cpu6811|cpu6812 },
+- { "addd", OP_DIRECT, 2, 0xd3, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "addd", OP_IND16, 3, 0xf3, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "addd", OP_IX, 2, 0xe3, 6, 6, CHG_NZVC, cpu6811 },
+- { "addd", OP_IY | OP_PAGE2, 3, 0xe3, 7, 7, CHG_NZVC, cpu6811 },
+- { "addd", OP_IDX, 2, 0xe3, 3, 3, CHG_NZVC, cpu6812 },
+- { "addd", OP_IDX_1, 3, 0xe3, 3, 3, CHG_NZVC, cpu6812 },
+- { "addd", OP_IDX_2, 4, 0xe3, 4, 4, CHG_NZVC, cpu6812 },
+- { "addd", OP_D_IDX, 2, 0xe3, 6, 6, CHG_NZVC, cpu6812 },
+- { "addd", OP_D_IDX_2, 4, 0xe3, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "anda", OP_IMM8, 2, 0x84, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "anda", OP_DIRECT, 2, 0x94, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "anda", OP_IND16, 3, 0xb4, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "anda", OP_IX, 2, 0xa4, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "anda", OP_IY | OP_PAGE2, 3, 0xa4, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "anda", OP_IDX, 2, 0xa4, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "anda", OP_IDX_1, 3, 0xa4, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "anda", OP_IDX_2, 4, 0xa4, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "anda", OP_D_IDX, 2, 0xa4, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+- { "anda", OP_D_IDX_2, 4, 0xa4, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "andb", OP_IMM8, 2, 0xc4, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "andb", OP_DIRECT, 2, 0xd4, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "andb", OP_IND16, 3, 0xf4, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "andb", OP_IX, 2, 0xe4, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "andb", OP_IY | OP_PAGE2, 3, 0xe4, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "andb", OP_IDX, 2, 0xe4, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "andb", OP_IDX_1, 3, 0xe4, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "andb", OP_IDX_2, 4, 0xe4, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "andb", OP_D_IDX, 2, 0xe4, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+- { "andb", OP_D_IDX_2, 4, 0xe4, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "andcc", OP_IMM8, 2, 0x10, 1, 1, CHG_ALL, cpu6812 },
+-
+- { "asl", OP_IND16, 3, 0x78, 4, 4, CHG_NZVC, cpu6811|cpu6812 },
+- { "asl", OP_IX, 2, 0x68, 6, 6, CHG_NZVC, cpu6811 },
+- { "asl", OP_IY | OP_PAGE2, 3, 0x68, 7, 7, CHG_NZVC, cpu6811 },
+- { "asl", OP_IDX, 2, 0x68, 3, 3, CHG_NZVC, cpu6812 },
+- { "asl", OP_IDX_1, 3, 0x68, 4, 4, CHG_NZVC, cpu6812 },
+- { "asl", OP_IDX_2, 4, 0x68, 5, 5, CHG_NZVC, cpu6812 },
+- { "asl", OP_D_IDX, 2, 0x68, 6, 6, CHG_NZVC, cpu6812 },
+- { "asl", OP_D_IDX_2, 4, 0x68, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "asla", OP_NONE, 1, 0x48, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+- { "aslb", OP_NONE, 1, 0x58, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+- { "asld", OP_NONE, 1, 0x05, 3, 3, CHG_NZVC, cpu6811 },
+- { "asld", OP_NONE, 1, 0x59, 1, 1, CHG_NZVC, cpu6812 },
+-
+- { "asr", OP_IND16, 3, 0x77, 4, 4, CHG_NZVC, cpu6811|cpu6812 },
+- { "asr", OP_IX, 2, 0x67, 6, 6, CHG_NZVC, cpu6811 },
+- { "asr", OP_IY | OP_PAGE2, 3, 0x67, 7, 7, CHG_NZVC, cpu6811 },
+- { "asr", OP_IDX, 2, 0x67, 3, 3, CHG_NZVC, cpu6812 },
+- { "asr", OP_IDX_1, 3, 0x67, 4, 4, CHG_NZVC, cpu6812 },
+- { "asr", OP_IDX_2, 4, 0x67, 5, 5, CHG_NZVC, cpu6812 },
+- { "asr", OP_D_IDX, 2, 0x67, 6, 6, CHG_NZVC, cpu6812 },
+- { "asr", OP_D_IDX_2, 4, 0x67, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "asra", OP_NONE, 1, 0x47, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+- { "asrb", OP_NONE, 1, 0x57, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+-
+- { "bcc", OP_JUMP_REL, 2, 0x24, 1, 3, CHG_NONE, cpu6811|cpu6812 },
+-
+- { "bclr", OP_BITMASK|OP_DIRECT, 3, 0x15, 6, 6, CLR_V_CHG_NZ, cpu6811 },
+- { "bclr", OP_BITMASK|OP_IX, 3, 0x1d, 7, 7, CLR_V_CHG_NZ, cpu6811 },
+- { "bclr", OP_BITMASK|OP_IY|OP_PAGE2, 4, 0x1d, 8, 8, CLR_V_CHG_NZ, cpu6811},
+- { "bclr", OP_BITMASK|OP_DIRECT, 3, 0x4d, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "bclr", OP_BITMASK|OP_IND16, 4, 0x1d, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "bclr", OP_BITMASK|OP_IDX, 3, 0x0d, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "bclr", OP_BITMASK|OP_IDX_1, 4, 0x0d, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "bclr", OP_BITMASK|OP_IDX_2, 5, 0x0d, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "bcs", OP_JUMP_REL, 2, 0x25, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
+- { "beq", OP_JUMP_REL, 2, 0x27, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
+- { "bge", OP_JUMP_REL, 2, 0x2c, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
+-
+- { "bgnd", OP_NONE, 1, 0x00, 5, 5, CHG_NONE, cpu6811 | cpu6812 },
+-
+- { "bgt", OP_JUMP_REL, 2, 0x2e, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
+- { "bhi", OP_JUMP_REL, 2, 0x22, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
+- { "bhs", OP_JUMP_REL, 2, 0x24, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
++ { "aba", OP_NONE, 1, 0x1b, 2, 2, CHG_HNZVC, cpu6811, 0 },
++ { "aba", OP_NONE | OP_PAGE2,2, 0x06, 2, 2, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "abx", OP_NONE, 1, 0x3a, 3, 3, CHG_NONE, cpu6811, 0 },
++ { "aby", OP_NONE | OP_PAGE2,2, 0x3a, 4, 4, CHG_NONE, cpu6811, 0 },
++
++ { "adca", OP_IMM8, 2, 0x89, 1, 1, CHG_HNZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "adca", OP_DIRECT, 2, 0x99, 3, 3, CHG_HNZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "adca", OP_IND16, 3, 0xb9, 3, 3, CHG_HNZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "adca", OP_IX, 2, 0xa9, 4, 4, CHG_HNZVC, cpu6811, 0 },
++ { "adca", OP_IY | OP_PAGE2, 3, 0xa9, 5, 5, CHG_HNZVC, cpu6811, 0 },
++ { "adca", OP_IDX, 2, 0xa9, 3, 3, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "adca", OP_IDX_1, 3, 0xa9, 3, 3, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "adca", OP_IDX_2, 4, 0xa9, 4, 4, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "adca", OP_D_IDX, 2, 0xa9, 6, 6, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "adca", OP_D_IDX_2, 4, 0xa9, 6, 6, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++
++ { "adcb", OP_IMM8, 2, 0xc9, 1, 1, CHG_HNZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "adcb", OP_DIRECT, 2, 0xd9, 3, 3, CHG_HNZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "adcb", OP_IND16, 3, 0xf9, 3, 3, CHG_HNZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "adcb", OP_IX, 2, 0xe9, 4, 4, CHG_HNZVC, cpu6811, 0 },
++ { "adcb", OP_IY | OP_PAGE2, 3, 0xe9, 5, 5, CHG_HNZVC, cpu6811, 0 },
++ { "adcb", OP_IDX, 2, 0xe9, 3, 3, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "adcb", OP_IDX_1, 3, 0xe9, 3, 3, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "adcb", OP_IDX_2, 4, 0xe9, 4, 4, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "adcb", OP_D_IDX, 2, 0xe9, 6, 6, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "adcb", OP_D_IDX_2, 4, 0xe9, 6, 6, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++
++ { "adda", OP_IMM8, 2, 0x8b, 1, 1, CHG_HNZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "adda", OP_DIRECT, 2, 0x9b, 3, 3, CHG_HNZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "adda", OP_IND16, 3, 0xbb, 3, 3, CHG_HNZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "adda", OP_IX, 2, 0xab, 4, 4, CHG_HNZVC, cpu6811, 0 },
++ { "adda", OP_IY | OP_PAGE2, 3, 0xab, 5, 5, CHG_HNZVC, cpu6811, 0 },
++ { "adda", OP_IDX, 2, 0xab, 3, 3, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "adda", OP_IDX_1, 3, 0xab, 3, 3, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "adda", OP_IDX_2, 4, 0xab, 4, 4, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "adda", OP_D_IDX, 2, 0xab, 6, 6, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "adda", OP_D_IDX_2, 4, 0xab, 6, 6, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++
++ { "addb", OP_IMM8, 2, 0xcb, 1, 1, CHG_HNZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "addb", OP_DIRECT, 2, 0xdb, 3, 3, CHG_HNZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "addb", OP_IND16, 3, 0xfb, 3, 3, CHG_HNZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "addb", OP_IX, 2, 0xeb, 4, 4, CHG_HNZVC, cpu6811, 0 },
++ { "addb", OP_IY | OP_PAGE2, 3, 0xeb, 5, 5, CHG_HNZVC, cpu6811, 0 },
++ { "addb", OP_IDX, 2, 0xeb, 3, 3, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "addb", OP_IDX_1, 3, 0xeb, 3, 3, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "addb", OP_IDX_2, 4, 0xeb, 4, 4, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "addb", OP_D_IDX, 2, 0xeb, 6, 6, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "addb", OP_D_IDX_2, 4, 0xeb, 6, 6, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++
++ { "addd", OP_IMM16, 3, 0xc3, 2, 2, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "addd", OP_DIRECT, 2, 0xd3, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "addd", OP_IND16, 3, 0xf3, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "addd", OP_IX, 2, 0xe3, 6, 6, CHG_NZVC, cpu6811, 0 },
++ { "addd", OP_IY | OP_PAGE2, 3, 0xe3, 7, 7, CHG_NZVC, cpu6811, 0 },
++ { "addd", OP_IDX, 2, 0xe3, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "addd", OP_IDX_1, 3, 0xe3, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "addd", OP_IDX_2, 4, 0xe3, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "addd", OP_D_IDX, 2, 0xe3, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "addd", OP_D_IDX_2, 4, 0xe3, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "addx", OP_IMM16 | OP_PAGE2, 3, 0x8b, 2, 2, CHG_NZVC, cpu9s12x, 0 },
++ { "addx", OP_DIRECT | OP_PAGE2, 2, 0x9b, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "addx", OP_IND16 | OP_PAGE2, 3, 0xbb, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "addx", OP_IDX | OP_PAGE2, 2, 0xab, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "addx", OP_IDX_1 | OP_PAGE2, 3, 0xab, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "addx", OP_IDX_2 | OP_PAGE2, 4, 0xab, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "addx", OP_D_IDX | OP_PAGE2, 2, 0xab, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "addx", OP_D_IDX_2 | OP_PAGE2, 4, 0xab, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "addy", OP_IMM16 | OP_PAGE2, 3, 0xcb, 2, 2, CHG_NZVC, cpu9s12x, 0 },
++ { "addy", OP_DIRECT | OP_PAGE2, 2, 0xdb, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "addy", OP_IND16 | OP_PAGE2, 3, 0xfb, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "addy", OP_IDX | OP_PAGE2, 2, 0xeb, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "addy", OP_IDX_1 | OP_PAGE2, 3, 0xeb, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "addy", OP_IDX_2 | OP_PAGE2, 4, 0xeb, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "addy", OP_D_IDX | OP_PAGE2, 2, 0xeb, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "addy", OP_D_IDX_2 | OP_PAGE2, 4, 0xeb, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "aded", OP_IMM16 | OP_PAGE2, 3, 0xc3, 2, 2, CHG_NZVC, cpu9s12x, 0 },
++ { "aded", OP_DIRECT | OP_PAGE2, 2, 0xd3, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "aded", OP_IND16 | OP_PAGE2, 3, 0xf3, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "aded", OP_IDX | OP_PAGE2, 2, 0xe3, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "aded", OP_IDX_1 | OP_PAGE2, 3, 0xe3, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "aded", OP_IDX_2 | OP_PAGE2, 4, 0xe3, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "aded", OP_D_IDX | OP_PAGE2, 2, 0xe3, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "aded", OP_D_IDX_2 | OP_PAGE2, 4, 0xe3, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "adex", OP_IMM16 | OP_PAGE2, 3, 0x89, 2, 2, CHG_NZVC, cpu9s12x, 0 },
++ { "adex", OP_DIRECT | OP_PAGE2, 2, 0x99, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "adex", OP_IND16 | OP_PAGE2, 3, 0xb9, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "adex", OP_IDX | OP_PAGE2, 2, 0xa9, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "adex", OP_IDX_1 | OP_PAGE2, 3, 0xa9, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "adex", OP_IDX_2 | OP_PAGE2, 4, 0xa9, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "adex", OP_D_IDX | OP_PAGE2, 2, 0xa9, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "adex", OP_D_IDX_2 | OP_PAGE2, 4, 0xa9, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "adey", OP_IMM16 | OP_PAGE2, 3, 0xc9, 2, 2, CHG_NZVC, cpu9s12x, 0 },
++ { "adey", OP_DIRECT | OP_PAGE2, 2, 0xd9, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "adey", OP_IND16 | OP_PAGE2, 3, 0xf9, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "adey", OP_IDX | OP_PAGE2, 2, 0xe9, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "adey", OP_IDX_1 | OP_PAGE2, 3, 0xe9, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "adey", OP_IDX_2 | OP_PAGE2, 4, 0xe9, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "adey", OP_D_IDX | OP_PAGE2, 2, 0xe9, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "adey", OP_D_IDX_2 | OP_PAGE2, 4, 0xe9, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "anda", OP_IMM8, 2, 0x84, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "anda", OP_DIRECT, 2, 0x94, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "anda", OP_IND16, 3, 0xb4, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "anda", OP_IX, 2, 0xa4, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "anda", OP_IY | OP_PAGE2, 3, 0xa4, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "anda", OP_IDX, 2, 0xa4, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "anda", OP_IDX_1, 3, 0xa4, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "anda", OP_IDX_2, 4, 0xa4, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "anda", OP_D_IDX, 2, 0xa4, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "anda", OP_D_IDX_2, 4, 0xa4, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "andb", OP_IMM8, 2, 0xc4, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "andb", OP_DIRECT, 2, 0xd4, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "andb", OP_IND16, 3, 0xf4, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "andb", OP_IX, 2, 0xe4, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "andb", OP_IY | OP_PAGE2, 3, 0xe4, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "andb", OP_IDX, 2, 0xe4, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "andb", OP_IDX_1, 3, 0xe4, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "andb", OP_IDX_2, 4, 0xe4, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "andb", OP_D_IDX, 2, 0xe4, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "andb", OP_D_IDX_2, 4, 0xe4, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "andcc", OP_IMM8, 2, 0x10, 1, 1, CHG_ALL, cpu6812|cpu9s12x, 0 },
++
++ { "andx", OP_IMM16 | OP_PAGE2, 2, 0x84, 1, 1, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "andx", OP_DIRECT | OP_PAGE2, 2, 0x94, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "andx", OP_IND16 | OP_PAGE2, 3, 0xb4, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "andx", OP_IDX | OP_PAGE2, 2, 0xa4, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "andx", OP_IDX_1 | OP_PAGE2, 3, 0xa4, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "andx", OP_IDX_2 | OP_PAGE2, 4, 0xa4, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "andx", OP_D_IDX | OP_PAGE2, 2, 0xa4, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "andx", OP_D_IDX_2 | OP_PAGE2, 4, 0xa4, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "andy", OP_IMM16 | OP_PAGE2, 2, 0xc4, 1, 1, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "andy", OP_DIRECT | OP_PAGE2, 2, 0xd4, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "andy", OP_IND16 | OP_PAGE2, 3, 0xf4, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "andy", OP_IDX | OP_PAGE2, 2, 0xe4, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "andy", OP_IDX_1 | OP_PAGE2, 3, 0xe4, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "andy", OP_IDX_2 | OP_PAGE2, 4, 0xe4, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "andy", OP_D_IDX | OP_PAGE2, 2, 0xe4, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "andy", OP_D_IDX_2 | OP_PAGE2, 4, 0xe4, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "asl", OP_IND16, 3, 0x78, 4, 4, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "asl", OP_IX, 2, 0x68, 6, 6, CHG_NZVC, cpu6811, 0 },
++ { "asl", OP_IY | OP_PAGE2, 3, 0x68, 7, 7, CHG_NZVC, cpu6811, 0 },
++ { "asl", OP_IDX, 2, 0x68, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "asl", OP_IDX_1, 3, 0x68, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "asl", OP_IDX_2, 4, 0x68, 5, 5, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "asl", OP_D_IDX, 2, 0x68, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "asl", OP_D_IDX_2, 4, 0x68, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "asla", OP_NONE, 1, 0x48, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "aslb", OP_NONE, 1, 0x58, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "asld", OP_NONE, 1, 0x05, 3, 3, CHG_NZVC, cpu6811, 0 },
++ { "asld", OP_NONE, 1, 0x59, 1, 1, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "aslw", OP_IND16 | OP_PAGE2, 3, 0x78, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "aslw", OP_IDX | OP_PAGE2, 2, 0x68, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "aslw", OP_IDX_1 | OP_PAGE2, 3, 0x68, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "aslw", OP_IDX_2 | OP_PAGE2, 4, 0x68, 5, 5, CHG_NZVC, cpu9s12x, 0 },
++ { "aslw", OP_D_IDX | OP_PAGE2, 2, 0x68, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "aslw", OP_D_IDX_2 | OP_PAGE2, 4, 0x68, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "aslx", OP_NONE | OP_PAGE2, 1, 0x48, 1, 1, CHG_NZVC, cpu9s12x, 0 },
++
++ { "asly", OP_NONE | OP_PAGE2, 1, 0x58, 1, 1, CHG_NZVC, cpu9s12x, 0 },
++
++ { "asr", OP_IND16, 3, 0x77, 4, 4, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "asr", OP_IX, 2, 0x67, 6, 6, CHG_NZVC, cpu6811, 0 },
++ { "asr", OP_IY | OP_PAGE2, 3, 0x67, 7, 7, CHG_NZVC, cpu6811, 0 },
++ { "asr", OP_IDX, 2, 0x67, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "asr", OP_IDX_1, 3, 0x67, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "asr", OP_IDX_2, 4, 0x67, 5, 5, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "asr", OP_D_IDX, 2, 0x67, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "asr", OP_D_IDX_2, 4, 0x67, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "asra", OP_NONE, 1, 0x47, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "asrb", OP_NONE, 1, 0x57, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++
++ { "asrw", OP_IND16 | OP_PAGE2, 3, 0x77, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "asrw", OP_IDX | OP_PAGE2, 2, 0x67, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "asrw", OP_IDX_1 | OP_PAGE2, 3, 0x67, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "asrw", OP_IDX_2 | OP_PAGE2, 4, 0x67, 5, 5, CHG_NZVC, cpu9s12x, 0 },
++ { "asrw", OP_D_IDX | OP_PAGE2, 2, 0x67, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "asrw", OP_D_IDX_2 | OP_PAGE2, 4, 0x67, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "asrx", OP_NONE | OP_PAGE2, 1, 0x47, 1, 1, CHG_NZVC, cpu9s12x, 0 },
++
++ { "asry", OP_NONE | OP_PAGE2, 1, 0x57, 1, 1, CHG_NZVC, cpu9s12x, 0 },
++
++ { "bcc", OP_JUMP_REL, 2, 0x24, 1, 3, CHG_NONE, cpu6811|cpu6812|cpu9s12x, 0 },
++
++ { "bclr", OP_BITMASK|OP_DIRECT, 3, 0x15, 6, 6, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "bclr", OP_BITMASK|OP_IX, 3, 0x1d, 7, 7, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "bclr", OP_BITMASK|OP_IY|OP_PAGE2, 4, 0x1d, 8, 8, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "bclr", OP_BITMASK|OP_DIRECT, 3, 0x4d, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bclr", OP_BITMASK|OP_IND16, 4, 0x1d, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bclr", OP_BITMASK|OP_IDX, 3, 0x0d, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bclr", OP_BITMASK|OP_IDX_1, 4, 0x0d, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bclr", OP_BITMASK|OP_IDX_2, 5, 0x0d, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "bcs", OP_JUMP_REL, 2, 0x25, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
++ { "beq", OP_JUMP_REL, 2, 0x27, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
++ { "bge", OP_JUMP_REL, 2, 0x2c, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
++
++ { "bgnd", OP_NONE, 1, 0x00, 5, 5, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
++
++ { "bgt", OP_JUMP_REL, 2, 0x2e, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
++ { "bhi", OP_JUMP_REL, 2, 0x22, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
++ { "bhs", OP_JUMP_REL, 2, 0x24, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
+
+- { "bita", OP_IMM8, 2, 0x85, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "bita", OP_DIRECT, 2, 0x95, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "bita", OP_IND16, 3, 0xb5, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "bita", OP_IX, 2, 0xa5, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "bita", OP_IY | OP_PAGE2, 3, 0xa5, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "bita", OP_IDX, 2, 0xa5, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "bita", OP_IDX_1, 3, 0xa5, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "bita", OP_IDX_2, 4, 0xa5, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "bita", OP_D_IDX, 2, 0xa5, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+- { "bita", OP_D_IDX_2, 4, 0xa5, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "bitb", OP_IMM8, 2, 0xc5, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "bitb", OP_DIRECT, 2, 0xd5, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "bitb", OP_IND16, 3, 0xf5, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "bitb", OP_IX, 2, 0xe5, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "bitb", OP_IY | OP_PAGE2, 3, 0xe5, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "bitb", OP_IDX, 2, 0xe5, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "bitb", OP_IDX_1, 3, 0xe5, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "bitb", OP_IDX_2, 4, 0xe5, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "bitb", OP_D_IDX, 2, 0xe5, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+- { "bitb", OP_D_IDX_2, 4, 0xe5, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "ble", OP_JUMP_REL, 2, 0x2f, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
+- { "blo", OP_JUMP_REL, 2, 0x25, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
+- { "bls", OP_JUMP_REL, 2, 0x23, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
+- { "blt", OP_JUMP_REL, 2, 0x2d, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
+- { "bmi", OP_JUMP_REL, 2, 0x2b, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
+- { "bne", OP_JUMP_REL, 2, 0x26, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
+- { "bpl", OP_JUMP_REL, 2, 0x2a, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
+- { "bra", OP_JUMP_REL, 2, 0x20, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
++ { "bita", OP_IMM8, 2, 0x85, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "bita", OP_DIRECT, 2, 0x95, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "bita", OP_IND16, 3, 0xb5, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "bita", OP_IX, 2, 0xa5, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "bita", OP_IY | OP_PAGE2, 3, 0xa5, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "bita", OP_IDX, 2, 0xa5, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bita", OP_IDX_1, 3, 0xa5, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bita", OP_IDX_2, 4, 0xa5, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bita", OP_D_IDX, 2, 0xa5, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bita", OP_D_IDX_2, 4, 0xa5, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "bitb", OP_IMM8, 2, 0xc5, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "bitb", OP_DIRECT, 2, 0xd5, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "bitb", OP_IND16, 3, 0xf5, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "bitb", OP_IX, 2, 0xe5, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "bitb", OP_IY | OP_PAGE2, 3, 0xe5, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "bitb", OP_IDX, 2, 0xe5, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bitb", OP_IDX_1, 3, 0xe5, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bitb", OP_IDX_2, 4, 0xe5, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bitb", OP_D_IDX, 2, 0xe5, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bitb", OP_D_IDX_2, 4, 0xe5, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "bitx", OP_IMM16 | OP_PAGE2, 2, 0x85, 1, 1, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "bitx", OP_DIRECT | OP_PAGE2, 2, 0x95, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "bitx", OP_IND16 | OP_PAGE2, 3, 0xb5, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "bitx", OP_IDX | OP_PAGE2, 2, 0xa5, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "bitx", OP_IDX_1 | OP_PAGE2, 3, 0xa5, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "bitx", OP_IDX_2 | OP_PAGE2, 4, 0xa5, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "bitx", OP_D_IDX | OP_PAGE2, 2, 0xa5, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "bitx", OP_D_IDX_2 | OP_PAGE2, 4, 0xa5, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "bity", OP_IMM16 | OP_PAGE2, 2, 0xc5, 1, 1, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "bity", OP_DIRECT | OP_PAGE2, 2, 0xd5, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "bity", OP_IND16 | OP_PAGE2, 3, 0xf5, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "bity", OP_IDX | OP_PAGE2, 2, 0xe5, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "bity", OP_IDX_1 | OP_PAGE2, 3, 0xe5, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "bity", OP_IDX_2 | OP_PAGE2, 4, 0xe5, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "bity", OP_D_IDX | OP_PAGE2, 2, 0xe5, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "bity", OP_D_IDX_2 | OP_PAGE2, 4, 0xe5, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "ble", OP_JUMP_REL, 2, 0x2f, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
++ { "blo", OP_JUMP_REL, 2, 0x25, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
++ { "bls", OP_JUMP_REL, 2, 0x23, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
++ { "blt", OP_JUMP_REL, 2, 0x2d, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
++ { "bmi", OP_JUMP_REL, 2, 0x2b, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
++ { "bne", OP_JUMP_REL, 2, 0x26, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
++ { "bpl", OP_JUMP_REL, 2, 0x2a, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
++ { "bra", OP_JUMP_REL, 2, 0x20, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
+
+ { "brclr", OP_BITMASK | OP_JUMP_REL
+- | OP_DIRECT, 4, 0x13, 6, 6, CHG_NONE, cpu6811 },
++ | OP_DIRECT, 4, 0x13, 6, 6, CHG_NONE, cpu6811, 0 },
+ { "brclr", OP_BITMASK | OP_JUMP_REL
+- | OP_IX, 4, 0x1f, 7, 7, CHG_NONE, cpu6811 },
++ | OP_IX, 4, 0x1f, 7, 7, CHG_NONE, cpu6811, 0 },
+ { "brclr", OP_BITMASK | OP_JUMP_REL
+- | OP_IY | OP_PAGE2, 5, 0x1f, 8, 8, CHG_NONE, cpu6811 },
++ | OP_IY | OP_PAGE2, 5, 0x1f, 8, 8, CHG_NONE, cpu6811, 0 },
+ { "brclr", OP_BITMASK | OP_JUMP_REL
+- | OP_DIRECT, 4, 0x4f, 4, 4, CHG_NONE, cpu6812 },
++ | OP_DIRECT, 4, 0x4f, 4, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
+ { "brclr", OP_BITMASK | OP_JUMP_REL
+- | OP_IND16, 5, 0x1f, 5, 5, CHG_NONE, cpu6812 },
++ | OP_IND16, 5, 0x1f, 5, 5, CHG_NONE, cpu6812|cpu9s12x, 0 },
+ { "brclr", OP_BITMASK | OP_JUMP_REL
+- | OP_IDX, 4, 0x0f, 4, 4, CHG_NONE, cpu6812 },
++ | OP_IDX, 4, 0x0f, 4, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
+ { "brclr", OP_BITMASK | OP_JUMP_REL
+- | OP_IDX_1, 5, 0x0f, 6, 6, CHG_NONE, cpu6812 },
++ | OP_IDX_1, 5, 0x0f, 6, 6, CHG_NONE, cpu6812|cpu9s12x, 0 },
+ { "brclr", OP_BITMASK
+ | OP_JUMP_REL
+- | OP_IDX_2, 6, 0x0f, 8, 8, CHG_NONE, cpu6812 },
++ | OP_IDX_2, 6, 0x0f, 8, 8, CHG_NONE, cpu6812|cpu9s12x, 0 },
+
+- { "brn", OP_JUMP_REL, 2, 0x21, 1, 3, CHG_NONE, cpu6811|cpu6812 },
++ { "brn", OP_JUMP_REL, 2, 0x21, 1, 3, CHG_NONE, cpu6811|cpu6812|cpu9s12x, 0 },
+
+ { "brset", OP_BITMASK | OP_JUMP_REL
+- | OP_DIRECT, 4, 0x12, 6, 6, CHG_NONE, cpu6811 },
++ | OP_DIRECT, 4, 0x12, 6, 6, CHG_NONE, cpu6811, 0 },
+ { "brset", OP_BITMASK
+ | OP_JUMP_REL
+- | OP_IX, 4, 0x1e, 7, 7, CHG_NONE, cpu6811 },
++ | OP_IX, 4, 0x1e, 7, 7, CHG_NONE, cpu6811, 0 },
+ { "brset", OP_BITMASK | OP_JUMP_REL
+- | OP_IY | OP_PAGE2, 5, 0x1e, 8, 8, CHG_NONE, cpu6811 },
++ | OP_IY | OP_PAGE2, 5, 0x1e, 8, 8, CHG_NONE, cpu6811, 0 },
+ { "brset", OP_BITMASK | OP_JUMP_REL
+- | OP_DIRECT, 4, 0x4e, 4, 4, CHG_NONE, cpu6812 },
++ | OP_DIRECT, 4, 0x4e, 4, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
+ { "brset", OP_BITMASK | OP_JUMP_REL
+- | OP_IND16, 5, 0x1e, 5, 5, CHG_NONE, cpu6812 },
++ | OP_IND16, 5, 0x1e, 5, 5, CHG_NONE, cpu6812|cpu9s12x, 0 },
+ { "brset", OP_BITMASK | OP_JUMP_REL
+- | OP_IDX, 4, 0x0e, 4, 4, CHG_NONE, cpu6812 },
++ | OP_IDX, 4, 0x0e, 4, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
+ { "brset", OP_BITMASK | OP_JUMP_REL
+- | OP_IDX_1, 5, 0x0e, 6, 6, CHG_NONE, cpu6812 },
++ | OP_IDX_1, 5, 0x0e, 6, 6, CHG_NONE, cpu6812|cpu9s12x, 0 },
+ { "brset", OP_BITMASK | OP_JUMP_REL
+- | OP_IDX_2, 6, 0x0e, 8, 8, CHG_NONE, cpu6812 },
++ | OP_IDX_2, 6, 0x0e, 8, 8, CHG_NONE, cpu6812|cpu9s12x, 0 },
+
+
+- { "bset", OP_BITMASK | OP_DIRECT, 3, 0x14, 6, 6, CLR_V_CHG_NZ, cpu6811 },
+- { "bset", OP_BITMASK | OP_IX, 3, 0x1c, 7, 7, CLR_V_CHG_NZ, cpu6811 },
+- { "bset", OP_BITMASK|OP_IY|OP_PAGE2, 4, 0x1c, 8, 8, CLR_V_CHG_NZ, cpu6811 },
+- { "bset", OP_BITMASK|OP_DIRECT, 3, 0x4c, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "bset", OP_BITMASK|OP_IND16, 4, 0x1c, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "bset", OP_BITMASK|OP_IDX, 3, 0x0c, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "bset", OP_BITMASK|OP_IDX_1, 4, 0x0c, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "bset", OP_BITMASK|OP_IDX_2, 5, 0x0c, 6, 6, CLR_V_CHG_NZ, cpu6812 },
++ { "bset", OP_BITMASK | OP_DIRECT, 3, 0x14, 6, 6, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "bset", OP_BITMASK | OP_IX, 3, 0x1c, 7, 7, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "bset", OP_BITMASK|OP_IY|OP_PAGE2, 4, 0x1c, 8, 8, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "bset", OP_BITMASK|OP_DIRECT, 3, 0x4c, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bset", OP_BITMASK|OP_IND16, 4, 0x1c, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bset", OP_BITMASK|OP_IDX, 3, 0x0c, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bset", OP_BITMASK|OP_IDX_1, 4, 0x0c, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "bset", OP_BITMASK|OP_IDX_2, 5, 0x0c, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "bsr", OP_JUMP_REL, 2, 0x8d, 6, 6, CHG_NONE, cpu6811, 0 },
++ { "bsr", OP_JUMP_REL, 2, 0x07, 4, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++
++ { "btas", OP_BITMASK|OP_DIRECT | OP_PAGE2, 3, 0x35, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "btas", OP_BITMASK|OP_IND16 | OP_PAGE2, 4, 0x36, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "btas", OP_BITMASK|OP_IDX | OP_PAGE2, 3, 0x37, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "btas", OP_BITMASK|OP_IDX_1 | OP_PAGE2, 4, 0x37, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "btas", OP_BITMASK|OP_IDX_2 | OP_PAGE2, 5, 0x37, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
+
+- { "bsr", OP_JUMP_REL, 2, 0x8d, 6, 6, CHG_NONE, cpu6811 },
+- { "bsr", OP_JUMP_REL, 2, 0x07, 4, 4, CHG_NONE, cpu6812 },
+-
+- { "bvc", OP_JUMP_REL, 2, 0x28, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
+- { "bvs", OP_JUMP_REL, 2, 0x29, 1, 3, CHG_NONE, cpu6811 | cpu6812 },
++ { "bvc", OP_JUMP_REL, 2, 0x28, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
++ { "bvs", OP_JUMP_REL, 2, 0x29, 1, 3, CHG_NONE, cpu6811 | cpu6812|cpu9s12x, 0 },
+
+ { "call", OP_IND16 | OP_PAGE
+- | OP_BRANCH, 4, 0x4a, 8, 8, CHG_NONE, cpu6812 },
++ | OP_BRANCH, 4, 0x4a, 8, 8, CHG_NONE, cpu6812|cpu9s12x, 0 },
+ { "call", OP_IDX | OP_PAGE
+- | OP_BRANCH, 3, 0x4b, 8, 8, CHG_NONE, cpu6812 },
++ | OP_BRANCH, 3, 0x4b, 8, 8, CHG_NONE, cpu6812|cpu9s12x, 0 },
+ { "call", OP_IDX_1 | OP_PAGE
+- | OP_BRANCH, 4, 0x4b, 8, 8, CHG_NONE, cpu6812 },
++ | OP_BRANCH, 4, 0x4b, 8, 8, CHG_NONE, cpu6812|cpu9s12x, 0 },
+ { "call", OP_IDX_2 | OP_PAGE
+- | OP_BRANCH, 5, 0x4b, 9, 9, CHG_NONE, cpu6812 },
++ | OP_BRANCH, 5, 0x4b, 9, 9, CHG_NONE, cpu6812|cpu9s12x, 0 },
+ { "call", OP_D_IDX
+- | OP_BRANCH, 2, 0x4b, 10, 10, CHG_NONE, cpu6812 },
++ | OP_BRANCH, 2, 0x4b, 10, 10, CHG_NONE, cpu6812|cpu9s12x, 0 },
+ { "call", OP_D_IDX_2
+- | OP_BRANCH, 4, 0x4b, 10, 10, CHG_NONE, cpu6812 },
++ | OP_BRANCH, 4, 0x4b, 10, 10, CHG_NONE, cpu6812|cpu9s12x, 0 },
+
+- { "cba", OP_NONE, 1, 0x11, 2, 2, CHG_NZVC, cpu6811 },
+- { "cba", OP_NONE | OP_PAGE2,2, 0x17, 2, 2, CHG_NZVC, cpu6812 },
++ { "cba", OP_NONE, 1, 0x11, 2, 2, CHG_NZVC, cpu6811, 0 },
++ { "cba", OP_NONE | OP_PAGE2,2, 0x17, 2, 2, CHG_NZVC, cpu6812|cpu9s12x, 0 },
+
+- { "clc", OP_NONE, 1, 0x0c, 2, 2, CLR_C, cpu6811 },
+- { "cli", OP_NONE, 1, 0x0e, 2, 2, CLR_I, cpu6811 },
++ { "clc", OP_NONE, 1, 0x0c, 2, 2, CLR_C, cpu6811, 0 },
++ { "cli", OP_NONE, 1, 0x0e, 2, 2, CLR_I, cpu6811, 0 },
+
+- { "clr", OP_IND16, 3, 0x7f, 6, 6, SET_Z_CLR_NVC, cpu6811 },
+- { "clr", OP_IX, 2, 0x6f, 6, 6, SET_Z_CLR_NVC, cpu6811 },
+- { "clr", OP_IY | OP_PAGE2, 3, 0x6f, 7, 7, SET_Z_CLR_NVC, cpu6811 },
+- { "clr", OP_IND16, 3, 0x79, 3, 3, SET_Z_CLR_NVC, cpu6812 },
+- { "clr", OP_IDX, 2, 0x69, 2, 2, SET_Z_CLR_NVC, cpu6812 },
+- { "clr", OP_IDX_1, 3, 0x69, 3, 3, SET_Z_CLR_NVC, cpu6812 },
+- { "clr", OP_IDX_2, 4, 0x69, 4, 4, SET_Z_CLR_NVC, cpu6812 },
+- { "clr", OP_D_IDX, 2, 0x69, 5, 5, SET_Z_CLR_NVC, cpu6812 },
+- { "clr", OP_D_IDX_2, 4, 0x69, 5, 5, SET_Z_CLR_NVC, cpu6812 },
+-
+- { "clra", OP_NONE, 1, 0x4f, 2, 2, SET_Z_CLR_NVC, cpu6811 },
+- { "clrb", OP_NONE, 1, 0x5f, 2, 2, SET_Z_CLR_NVC, cpu6811 },
+- { "clra", OP_NONE, 1, 0x87, 1, 1, SET_Z_CLR_NVC, cpu6812 },
+- { "clrb", OP_NONE, 1, 0xc7, 1, 1, SET_Z_CLR_NVC, cpu6812 },
+-
+- { "clv", OP_NONE, 1, 0x0a, 2, 2, CLR_V, cpu6811 },
+-
+- { "cmpa", OP_IMM8, 2, 0x81, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+- { "cmpa", OP_DIRECT, 2, 0x91, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "cmpa", OP_IND16, 3, 0xb1, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "cmpa", OP_IX, 2, 0xa1, 4, 4, CHG_NZVC, cpu6811 },
+- { "cmpa", OP_IY | OP_PAGE2, 3, 0xa1, 5, 5, CHG_NZVC, cpu6811 },
+- { "cmpa", OP_IDX, 2, 0xa1, 3, 3, CHG_NZVC, cpu6812 },
+- { "cmpa", OP_IDX_1, 3, 0xa1, 3, 3, CHG_NZVC, cpu6812 },
+- { "cmpa", OP_IDX_2, 4, 0xa1, 4, 4, CHG_NZVC, cpu6812 },
+- { "cmpa", OP_D_IDX, 2, 0xa1, 6, 6, CHG_NZVC, cpu6812 },
+- { "cmpa", OP_D_IDX_2, 4, 0xa1, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "cmpb", OP_IMM8, 2, 0xc1, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+- { "cmpb", OP_DIRECT, 2, 0xd1, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "cmpb", OP_IND16, 3, 0xf1, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "cmpb", OP_IX, 2, 0xe1, 4, 4, CHG_NZVC, cpu6811 },
+- { "cmpb", OP_IY | OP_PAGE2, 3, 0xe1, 5, 5, CHG_NZVC, cpu6811 },
+- { "cmpb", OP_IDX, 2, 0xe1, 3, 3, CHG_NZVC, cpu6812 },
+- { "cmpb", OP_IDX_1, 3, 0xe1, 3, 3, CHG_NZVC, cpu6812 },
+- { "cmpb", OP_IDX_2, 4, 0xe1, 4, 4, CHG_NZVC, cpu6812 },
+- { "cmpb", OP_D_IDX, 2, 0xe1, 6, 6, CHG_NZVC, cpu6812 },
+- { "cmpb", OP_D_IDX_2, 4, 0xe1, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "com", OP_IND16, 3, 0x73, 6, 6, SET_C_CLR_V_CHG_NZ, cpu6811 },
+- { "com", OP_IX, 2, 0x63, 6, 6, SET_C_CLR_V_CHG_NZ, cpu6811 },
+- { "com", OP_IY | OP_PAGE2, 3, 0x63, 7, 7, SET_C_CLR_V_CHG_NZ, cpu6811 },
+- { "com", OP_IND16, 3, 0x71, 4, 4, SET_C_CLR_V_CHG_NZ, cpu6812 },
+- { "com", OP_IDX, 2, 0x61, 3, 3, SET_C_CLR_V_CHG_NZ, cpu6812 },
+- { "com", OP_IDX_1, 3, 0x61, 4, 4, SET_C_CLR_V_CHG_NZ, cpu6812 },
+- { "com", OP_IDX_2, 4, 0x61, 5, 5, SET_C_CLR_V_CHG_NZ, cpu6812 },
+- { "com", OP_D_IDX, 2, 0x61, 6, 6, SET_C_CLR_V_CHG_NZ, cpu6812 },
+- { "com", OP_D_IDX_2, 4, 0x61, 6, 6, SET_C_CLR_V_CHG_NZ, cpu6812 },
+-
+- { "coma", OP_NONE, 1, 0x43, 2, 2, SET_C_CLR_V_CHG_NZ, cpu6811 },
+- { "coma", OP_NONE, 1, 0x41, 1, 1, SET_C_CLR_V_CHG_NZ, cpu6812 },
+- { "comb", OP_NONE, 1, 0x53, 2, 2, SET_C_CLR_V_CHG_NZ, cpu6811 },
+- { "comb", OP_NONE, 1, 0x51, 1, 1, SET_C_CLR_V_CHG_NZ, cpu6812 },
+-
+- { "cpd", OP_IMM16 | OP_PAGE3, 4, 0x83, 5, 5, CHG_NZVC, cpu6811 },
+- { "cpd", OP_DIRECT | OP_PAGE3, 3, 0x93, 6, 6, CHG_NZVC, cpu6811 },
+- { "cpd", OP_IND16 | OP_PAGE3, 4, 0xb3, 7, 7, CHG_NZVC, cpu6811 },
+- { "cpd", OP_IX | OP_PAGE3, 3, 0xa3, 7, 7, CHG_NZVC, cpu6811 },
+- { "cpd", OP_IY | OP_PAGE4, 3, 0xa3, 7, 7, CHG_NZVC, cpu6811 },
+- { "cpd", OP_IMM16, 3, 0x8c, 2, 2, CHG_NZVC, cpu6812 },
+- { "cpd", OP_DIRECT, 2, 0x9c, 3, 3, CHG_NZVC, cpu6812 },
+- { "cpd", OP_IND16, 3, 0xbc, 3, 3, CHG_NZVC, cpu6812 },
+- { "cpd", OP_IDX, 2, 0xac, 3, 3, CHG_NZVC, cpu6812 },
+- { "cpd", OP_IDX_1, 3, 0xac, 3, 3, CHG_NZVC, cpu6812 },
+- { "cpd", OP_IDX_2, 4, 0xac, 4, 4, CHG_NZVC, cpu6812 },
+- { "cpd", OP_D_IDX, 2, 0xac, 6, 6, CHG_NZVC, cpu6812 },
+- { "cpd", OP_D_IDX_2, 4, 0xac, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "cps", OP_IMM16, 3, 0x8f, 2, 2, CHG_NZVC, cpu6812 },
+- { "cps", OP_DIRECT, 2, 0x9f, 3, 3, CHG_NZVC, cpu6812 },
+- { "cps", OP_IND16, 3, 0xbf, 3, 3, CHG_NZVC, cpu6812 },
+- { "cps", OP_IDX, 2, 0xaf, 3, 3, CHG_NZVC, cpu6812 },
+- { "cps", OP_IDX_1, 3, 0xaf, 3, 3, CHG_NZVC, cpu6812 },
+- { "cps", OP_IDX_2, 4, 0xaf, 4, 4, CHG_NZVC, cpu6812 },
+- { "cps", OP_D_IDX, 2, 0xaf, 6, 6, CHG_NZVC, cpu6812 },
+- { "cps", OP_D_IDX_2, 4, 0xaf, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "cpx", OP_IMM16, 3, 0x8c, 4, 4, CHG_NZVC, cpu6811 },
+- { "cpx", OP_DIRECT, 2, 0x9c, 5, 5, CHG_NZVC, cpu6811 },
+- { "cpx", OP_IND16, 3, 0xbc, 5, 5, CHG_NZVC, cpu6811 },
+- { "cpx", OP_IX, 2, 0xac, 6, 6, CHG_NZVC, cpu6811 },
+- { "cpx", OP_IY | OP_PAGE4, 3, 0xac, 7, 7, CHG_NZVC, cpu6811 },
+- { "cpx", OP_IMM16, 3, 0x8e, 2, 2, CHG_NZVC, cpu6812 },
+- { "cpx", OP_DIRECT, 2, 0x9e, 3, 3, CHG_NZVC, cpu6812 },
+- { "cpx", OP_IND16, 3, 0xbe, 3, 3, CHG_NZVC, cpu6812 },
+- { "cpx", OP_IDX, 2, 0xae, 3, 3, CHG_NZVC, cpu6812 },
+- { "cpx", OP_IDX_1, 3, 0xae, 3, 3, CHG_NZVC, cpu6812 },
+- { "cpx", OP_IDX_2, 4, 0xae, 4, 4, CHG_NZVC, cpu6812 },
+- { "cpx", OP_D_IDX, 2, 0xae, 6, 6, CHG_NZVC, cpu6812 },
+- { "cpx", OP_D_IDX_2, 4, 0xae, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "cpy", OP_PAGE2 | OP_IMM16, 4, 0x8c, 5, 5, CHG_NZVC, cpu6811 },
+- { "cpy", OP_PAGE2 | OP_DIRECT, 3, 0x9c, 6, 6, CHG_NZVC, cpu6811 },
+- { "cpy", OP_PAGE2 | OP_IY, 3, 0xac, 7, 7, CHG_NZVC, cpu6811 },
+- { "cpy", OP_PAGE2 | OP_IND16, 4, 0xbc, 7, 7, CHG_NZVC, cpu6811 },
+- { "cpy", OP_PAGE3 | OP_IX, 3, 0xac, 7, 7, CHG_NZVC, cpu6811 },
+- { "cpy", OP_IMM16, 3, 0x8d, 2, 2, CHG_NZVC, cpu6812 },
+- { "cpy", OP_DIRECT, 2, 0x9d, 3, 3, CHG_NZVC, cpu6812 },
+- { "cpy", OP_IND16, 3, 0xbd, 3, 3, CHG_NZVC, cpu6812 },
+- { "cpy", OP_IDX, 2, 0xad, 3, 3, CHG_NZVC, cpu6812 },
+- { "cpy", OP_IDX_1, 3, 0xad, 3, 3, CHG_NZVC, cpu6812 },
+- { "cpy", OP_IDX_2, 4, 0xad, 4, 4, CHG_NZVC, cpu6812 },
+- { "cpy", OP_D_IDX, 2, 0xad, 6, 6, CHG_NZVC, cpu6812 },
+- { "cpy", OP_D_IDX_2, 4, 0xad, 6, 6, CHG_NZVC, cpu6812 },
++ { "clr", OP_IND16, 3, 0x7f, 6, 6, SET_Z_CLR_NVC, cpu6811, 0 },
++ { "clr", OP_IX, 2, 0x6f, 6, 6, SET_Z_CLR_NVC, cpu6811, 0 },
++ { "clr", OP_IY | OP_PAGE2, 3, 0x6f, 7, 7, SET_Z_CLR_NVC, cpu6811, 0 },
++ { "clr", OP_IND16, 3, 0x79, 3, 3, SET_Z_CLR_NVC, cpu6812|cpu9s12x, 0 },
++ { "clr", OP_IDX, 2, 0x69, 2, 2, SET_Z_CLR_NVC, cpu6812|cpu9s12x, 0 },
++ { "clr", OP_IDX_1, 3, 0x69, 3, 3, SET_Z_CLR_NVC, cpu6812|cpu9s12x, 0 },
++ { "clr", OP_IDX_2, 4, 0x69, 4, 4, SET_Z_CLR_NVC, cpu6812|cpu9s12x, 0 },
++ { "clr", OP_D_IDX, 2, 0x69, 5, 5, SET_Z_CLR_NVC, cpu6812|cpu9s12x, 0 },
++ { "clr", OP_D_IDX_2, 4, 0x69, 5, 5, SET_Z_CLR_NVC, cpu6812|cpu9s12x, 0 },
++
++ { "clra", OP_NONE, 1, 0x4f, 2, 2, SET_Z_CLR_NVC, cpu6811, 0 },
++ { "clrb", OP_NONE, 1, 0x5f, 2, 2, SET_Z_CLR_NVC, cpu6811, 0 },
++ { "clra", OP_NONE, 1, 0x87, 1, 1, SET_Z_CLR_NVC, cpu6812|cpu9s12x, 0 },
++ { "clrb", OP_NONE, 1, 0xc7, 1, 1, SET_Z_CLR_NVC, cpu6812|cpu9s12x, 0 },
++
++ { "clrw", OP_IND16 | OP_PAGE2, 3, 0x79, 4, 4, SET_Z_CLR_NVC, cpu9s12x, 0 },
++ { "clrw", OP_IDX | OP_PAGE2, 2, 0x69, 3, 3, SET_Z_CLR_NVC, cpu9s12x, 0 },
++ { "clrw", OP_IDX_1 | OP_PAGE2, 3, 0x69, 4, 4, SET_Z_CLR_NVC, cpu9s12x, 0 },
++ { "clrw", OP_IDX_2 | OP_PAGE2, 4, 0x69, 5, 5, SET_Z_CLR_NVC, cpu9s12x, 0 },
++ { "clrw", OP_D_IDX | OP_PAGE2, 2, 0x69, 6, 6, SET_Z_CLR_NVC, cpu9s12x, 0 },
++ { "clrw", OP_D_IDX_2 | OP_PAGE2, 4, 0x69, 6, 6, SET_Z_CLR_NVC, cpu9s12x, 0 },
++
++ { "clrx", OP_NONE | OP_PAGE2, 3, 0x87, 4, 4, SET_Z_CLR_NVC, cpu9s12x, 0 },
++
++ { "clry", OP_NONE | OP_PAGE2, 3, 0xc7, 4, 4, SET_Z_CLR_NVC, cpu9s12x, 0 },
++
++ { "clv", OP_NONE, 1, 0x0a, 2, 2, CLR_V, cpu6811, 0 },
++
++ { "cmpa", OP_IMM8, 2, 0x81, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "cmpa", OP_DIRECT, 2, 0x91, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "cmpa", OP_IND16, 3, 0xb1, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "cmpa", OP_IX, 2, 0xa1, 4, 4, CHG_NZVC, cpu6811, 0 },
++ { "cmpa", OP_IY | OP_PAGE2, 3, 0xa1, 5, 5, CHG_NZVC, cpu6811, 0 },
++ { "cmpa", OP_IDX, 2, 0xa1, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cmpa", OP_IDX_1, 3, 0xa1, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cmpa", OP_IDX_2, 4, 0xa1, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cmpa", OP_D_IDX, 2, 0xa1, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cmpa", OP_D_IDX_2, 4, 0xa1, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "cmpb", OP_IMM8, 2, 0xc1, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "cmpb", OP_DIRECT, 2, 0xd1, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "cmpb", OP_IND16, 3, 0xf1, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "cmpb", OP_IX, 2, 0xe1, 4, 4, CHG_NZVC, cpu6811, 0 },
++ { "cmpb", OP_IY | OP_PAGE2, 3, 0xe1, 5, 5, CHG_NZVC, cpu6811, 0 },
++ { "cmpb", OP_IDX, 2, 0xe1, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cmpb", OP_IDX_1, 3, 0xe1, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cmpb", OP_IDX_2, 4, 0xe1, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cmpb", OP_D_IDX, 2, 0xe1, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cmpb", OP_D_IDX_2, 4, 0xe1, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "com", OP_IND16, 3, 0x73, 6, 6, SET_C_CLR_V_CHG_NZ, cpu6811, 0 },
++ { "com", OP_IX, 2, 0x63, 6, 6, SET_C_CLR_V_CHG_NZ, cpu6811, 0 },
++ { "com", OP_IY | OP_PAGE2, 3, 0x63, 7, 7, SET_C_CLR_V_CHG_NZ, cpu6811, 0 },
++ { "com", OP_IND16, 3, 0x71, 4, 4, SET_C_CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "com", OP_IDX, 2, 0x61, 3, 3, SET_C_CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "com", OP_IDX_1, 3, 0x61, 4, 4, SET_C_CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "com", OP_IDX_2, 4, 0x61, 5, 5, SET_C_CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "com", OP_D_IDX, 2, 0x61, 6, 6, SET_C_CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "com", OP_D_IDX_2, 4, 0x61, 6, 6, SET_C_CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "coma", OP_NONE, 1, 0x43, 2, 2, SET_C_CLR_V_CHG_NZ, cpu6811, 0 },
++ { "coma", OP_NONE, 1, 0x41, 1, 1, SET_C_CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "comb", OP_NONE, 1, 0x53, 2, 2, SET_C_CLR_V_CHG_NZ, cpu6811, 0 },
++ { "comb", OP_NONE, 1, 0x51, 1, 1, SET_C_CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "comw", OP_IND16 | OP_PAGE2, 3, 0x71, 4, 4, SET_C_CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "comw", OP_IDX | OP_PAGE2, 2, 0x61, 3, 3, SET_C_CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "comw", OP_IDX_1 | OP_PAGE2, 3, 0x61, 4, 4, SET_C_CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "comw", OP_IDX_2 | OP_PAGE2, 4, 0x61, 5, 5, SET_C_CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "comw", OP_D_IDX | OP_PAGE2, 2, 0x61, 6, 6, SET_C_CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "comw", OP_D_IDX_2 | OP_PAGE2, 4, 0x61, 6, 6, SET_C_CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "comx", OP_NONE | OP_PAGE2, 1, 0x41, 2, 2, SET_C_CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "comy", OP_NONE | OP_PAGE2, 1, 0x51, 2, 2, SET_C_CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "cpd", OP_IMM16 | OP_PAGE3, 4, 0x83, 5, 5, CHG_NZVC, cpu6811, 0 },
++ { "cpd", OP_DIRECT | OP_PAGE3, 3, 0x93, 6, 6, CHG_NZVC, cpu6811, 0 },
++ { "cpd", OP_IND16 | OP_PAGE3, 4, 0xb3, 7, 7, CHG_NZVC, cpu6811, 0 },
++ { "cpd", OP_IX | OP_PAGE3, 3, 0xa3, 7, 7, CHG_NZVC, cpu6811, 0 },
++ { "cpd", OP_IY | OP_PAGE4, 3, 0xa3, 7, 7, CHG_NZVC, cpu6811, 0 },
++ { "cpd", OP_IMM16, 3, 0x8c, 2, 2, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpd", OP_DIRECT, 2, 0x9c, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpd", OP_IND16, 3, 0xbc, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpd", OP_IDX, 2, 0xac, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpd", OP_IDX_1, 3, 0xac, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpd", OP_IDX_2, 4, 0xac, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpd", OP_D_IDX, 2, 0xac, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpd", OP_D_IDX_2, 4, 0xac, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "cped", OP_IMM16 | OP_PAGE2, 3, 0x8c, 2, 2, CHG_NZVC, cpu9s12x, 0 },
++ { "cped", OP_DIRECT | OP_PAGE2, 2, 0x9c, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cped", OP_IND16 | OP_PAGE2, 3, 0xbc, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cped", OP_IDX | OP_PAGE2, 2, 0xac, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cped", OP_IDX_1 | OP_PAGE2, 3, 0xac, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cped", OP_IDX_2 | OP_PAGE2, 4, 0xac, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "cped", OP_D_IDX | OP_PAGE2, 2, 0xac, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "cped", OP_D_IDX_2 | OP_PAGE2, 4, 0xac, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "cpes", OP_IMM16 | OP_PAGE2, 3, 0x8f, 2, 2, CHG_NZVC, cpu9s12x, 0 },
++ { "cpes", OP_DIRECT | OP_PAGE2, 2, 0x9f, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cpes", OP_IND16 | OP_PAGE2, 3, 0xbf, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cpes", OP_IDX | OP_PAGE2, 2, 0xaf, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cpes", OP_IDX_1 | OP_PAGE2, 3, 0xaf, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cpes", OP_IDX_2 | OP_PAGE2, 4, 0xaf, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "cpes", OP_D_IDX | OP_PAGE2, 2, 0xaf, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "cpes", OP_D_IDX_2 | OP_PAGE2, 4, 0xaf, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "cpex", OP_IMM16 | OP_PAGE2, 3, 0x8e, 2, 2, CHG_NZVC, cpu9s12x, 0 },
++ { "cpex", OP_DIRECT | OP_PAGE2, 2, 0x9e, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cpex", OP_IND16 | OP_PAGE2, 3, 0xbe, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cpex", OP_IDX | OP_PAGE2, 2, 0xae, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cpex", OP_IDX_1 | OP_PAGE2, 3, 0xae, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cpex", OP_IDX_2 | OP_PAGE2, 4, 0xae, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "cpex", OP_D_IDX | OP_PAGE2, 2, 0xae, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "cpex", OP_D_IDX_2 | OP_PAGE2, 4, 0xae, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "cpey", OP_IMM16 | OP_PAGE2, 3, 0x8d, 2, 2, CHG_NZVC, cpu9s12x, 0 },
++ { "cpey", OP_DIRECT | OP_PAGE2, 2, 0x9d, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cpey", OP_IND16 | OP_PAGE2, 3, 0xbd, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cpey", OP_IDX | OP_PAGE2, 2, 0xad, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cpey", OP_IDX_1 | OP_PAGE2, 3, 0xad, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "cpey", OP_IDX_2 | OP_PAGE2, 4, 0xad, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "cpey", OP_D_IDX | OP_PAGE2, 2, 0xad, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "cpey", OP_D_IDX_2 | OP_PAGE2, 4, 0xad, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "cps", OP_IMM16, 3, 0x8f, 2, 2, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cps", OP_DIRECT, 2, 0x9f, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cps", OP_IND16, 3, 0xbf, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cps", OP_IDX, 2, 0xaf, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cps", OP_IDX_1, 3, 0xaf, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cps", OP_IDX_2, 4, 0xaf, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cps", OP_D_IDX, 2, 0xaf, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cps", OP_D_IDX_2, 4, 0xaf, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "cpx", OP_IMM16, 3, 0x8c, 4, 4, CHG_NZVC, cpu6811, 0 },
++ { "cpx", OP_DIRECT, 2, 0x9c, 5, 5, CHG_NZVC, cpu6811, 0 },
++ { "cpx", OP_IND16, 3, 0xbc, 5, 5, CHG_NZVC, cpu6811, 0 },
++ { "cpx", OP_IX, 2, 0xac, 6, 6, CHG_NZVC, cpu6811, 0 },
++ { "cpx", OP_IY | OP_PAGE4, 3, 0xac, 7, 7, CHG_NZVC, cpu6811, 0 },
++ { "cpx", OP_IMM16, 3, 0x8e, 2, 2, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpx", OP_DIRECT, 2, 0x9e, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpx", OP_IND16, 3, 0xbe, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpx", OP_IDX, 2, 0xae, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpx", OP_IDX_1, 3, 0xae, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpx", OP_IDX_2, 4, 0xae, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpx", OP_D_IDX, 2, 0xae, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpx", OP_D_IDX_2, 4, 0xae, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "cpy", OP_PAGE2 | OP_IMM16, 4, 0x8c, 5, 5, CHG_NZVC, cpu6811, 0 },
++ { "cpy", OP_PAGE2 | OP_DIRECT, 3, 0x9c, 6, 6, CHG_NZVC, cpu6811, 0 },
++ { "cpy", OP_PAGE2 | OP_IY, 3, 0xac, 7, 7, CHG_NZVC, cpu6811, 0 },
++ { "cpy", OP_PAGE2 | OP_IND16, 4, 0xbc, 7, 7, CHG_NZVC, cpu6811, 0 },
++ { "cpy", OP_PAGE3 | OP_IX, 3, 0xac, 7, 7, CHG_NZVC, cpu6811, 0 },
++ { "cpy", OP_IMM16, 3, 0x8d, 2, 2, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpy", OP_DIRECT, 2, 0x9d, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpy", OP_IND16, 3, 0xbd, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpy", OP_IDX, 2, 0xad, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpy", OP_IDX_1, 3, 0xad, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpy", OP_IDX_2, 4, 0xad, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpy", OP_D_IDX, 2, 0xad, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "cpy", OP_D_IDX_2, 4, 0xad, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
+
+ /* After 'daa', the Z flag is undefined. Mark it as changed. */
+- { "daa", OP_NONE, 1, 0x19, 2, 2, CHG_NZVC, cpu6811 },
+- { "daa", OP_NONE | OP_PAGE2, 2, 0x07, 3, 3, CHG_NZVC, cpu6812 },
++ { "daa", OP_NONE, 1, 0x19, 2, 2, CHG_NZVC, cpu6811, 0 },
++ { "daa", OP_NONE | OP_PAGE2, 2, 0x07, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
+
+ { "dbeq", OP_DBEQ_MARKER
+- | OP_REG | OP_JUMP_REL,3, 0x04, 3, 3, CHG_NONE, cpu6812 },
++ | OP_REG | OP_JUMP_REL,3, 0x04, 3, 3, CHG_NONE, cpu6812|cpu9s12x, 0 },
+ { "dbne", OP_DBNE_MARKER
+- | OP_REG | OP_JUMP_REL,3, 0x04, 3, 3, CHG_NONE, cpu6812 },
++ | OP_REG | OP_JUMP_REL,3, 0x04, 3, 3, CHG_NONE, cpu6812|cpu9s12x, 0 },
+
+- { "dec", OP_IX, 2, 0x6a, 6, 6, CHG_NZV, cpu6811 },
+- { "dec", OP_IND16, 3, 0x7a, 6, 6, CHG_NZV, cpu6811 },
+- { "dec", OP_IY | OP_PAGE2, 3, 0x6a, 7, 7, CHG_NZV, cpu6811 },
+- { "dec", OP_IND16, 3, 0x73, 4, 4, CHG_NZV, cpu6812 },
+- { "dec", OP_IDX, 2, 0x63, 3, 3, CHG_NZV, cpu6812 },
+- { "dec", OP_IDX_1, 3, 0x63, 4, 4, CHG_NZV, cpu6812 },
+- { "dec", OP_IDX_2, 4, 0x63, 5, 5, CHG_NZV, cpu6812 },
+- { "dec", OP_D_IDX, 2, 0x63, 6, 6, CHG_NZV, cpu6812 },
+- { "dec", OP_D_IDX_2, 4, 0x63, 6, 6, CHG_NZV, cpu6812 },
+-
+- { "des", OP_NONE, 1, 0x34, 3, 3, CHG_NONE, cpu6811 },
+-
+- { "deca", OP_NONE, 1, 0x4a, 2, 2, CHG_NZV, cpu6811 },
+- { "deca", OP_NONE, 1, 0x43, 1, 1, CHG_NZV, cpu6812 },
+- { "decb", OP_NONE, 1, 0x5a, 2, 2, CHG_NZV, cpu6811 },
+- { "decb", OP_NONE, 1, 0x53, 1, 1, CHG_NZV, cpu6812 },
+-
+- { "dex", OP_NONE, 1, 0x09, 1, 1, CHG_Z, cpu6812|cpu6811 },
+- { "dey", OP_NONE | OP_PAGE2, 2, 0x09, 4, 4, CHG_Z, cpu6811 },
+- { "dey", OP_NONE, 1, 0x03, 1, 1, CHG_Z, cpu6812 },
+-
+- { "ediv", OP_NONE, 1, 0x11, 11, 11, CHG_NZVC, cpu6812 },
+- { "edivs", OP_NONE | OP_PAGE2, 2, 0x14, 12, 12, CHG_NZVC, cpu6812 },
+- { "emacs", OP_IND16 | OP_PAGE2, 4, 0x12, 13, 13, CHG_NZVC, cpu6812 },
+-
+- { "emaxd", OP_IDX | OP_PAGE2, 3, 0x1a, 4, 4, CHG_NZVC, cpu6812 },
+- { "emaxd", OP_IDX_1 | OP_PAGE2, 4, 0x1a, 4, 4, CHG_NZVC, cpu6812 },
+- { "emaxd", OP_IDX_2 | OP_PAGE2, 5, 0x1a, 5, 5, CHG_NZVC, cpu6812 },
+- { "emaxd", OP_D_IDX | OP_PAGE2, 3, 0x1a, 7, 7, CHG_NZVC, cpu6812 },
+- { "emaxd", OP_D_IDX_2 | OP_PAGE2, 5, 0x1a, 7, 7, CHG_NZVC, cpu6812 },
+-
+- { "emaxm", OP_IDX | OP_PAGE2, 3, 0x1e, 4, 4, CHG_NZVC, cpu6812 },
+- { "emaxm", OP_IDX_1 | OP_PAGE2, 4, 0x1e, 5, 5, CHG_NZVC, cpu6812 },
+- { "emaxm", OP_IDX_2 | OP_PAGE2, 5, 0x1e, 6, 6, CHG_NZVC, cpu6812 },
+- { "emaxm", OP_D_IDX | OP_PAGE2, 3, 0x1e, 7, 7, CHG_NZVC, cpu6812 },
+- { "emaxm", OP_D_IDX_2 | OP_PAGE2, 5, 0x1e, 7, 7, CHG_NZVC, cpu6812 },
+-
+- { "emind", OP_IDX | OP_PAGE2, 3, 0x1b, 4, 4, CHG_NZVC, cpu6812 },
+- { "emind", OP_IDX_1 | OP_PAGE2, 4, 0x1b, 4, 4, CHG_NZVC, cpu6812 },
+- { "emind", OP_IDX_2 | OP_PAGE2, 5, 0x1b, 5, 5, CHG_NZVC, cpu6812 },
+- { "emind", OP_D_IDX | OP_PAGE2, 3, 0x1b, 7, 7, CHG_NZVC, cpu6812 },
+- { "emind", OP_D_IDX_2 | OP_PAGE2, 5, 0x1b, 7, 7, CHG_NZVC, cpu6812 },
+-
+- { "eminm", OP_IDX | OP_PAGE2, 3, 0x1f, 4, 4, CHG_NZVC, cpu6812 },
+- { "eminm", OP_IDX_1 | OP_PAGE2, 4, 0x1f, 5, 5, CHG_NZVC, cpu6812 },
+- { "eminm", OP_IDX_2 | OP_PAGE2, 5, 0x1f, 6, 6, CHG_NZVC, cpu6812 },
+- { "eminm", OP_D_IDX | OP_PAGE2, 3, 0x1f, 7, 7, CHG_NZVC, cpu6812 },
+- { "eminm", OP_D_IDX_2 | OP_PAGE2, 5, 0x1f, 7, 7, CHG_NZVC, cpu6812 },
+-
+- { "emul", OP_NONE, 1, 0x13, 3, 3, CHG_NZC, cpu6812 },
+- { "emuls", OP_NONE | OP_PAGE2, 2, 0x13, 3, 3, CHG_NZC, cpu6812 },
+-
+- { "eora", OP_IMM8, 2, 0x88, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "eora", OP_DIRECT, 2, 0x98, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "eora", OP_IND16, 3, 0xb8, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "eora", OP_IX, 2, 0xa8, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "eora", OP_IY | OP_PAGE2, 3, 0xa8, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "eora", OP_IDX, 2, 0xa8, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "eora", OP_IDX_1, 3, 0xa8, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "eora", OP_IDX_2, 4, 0xa8, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "eora", OP_D_IDX, 2, 0xa8, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+- { "eora", OP_D_IDX_2, 4, 0xa8, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "eorb", OP_IMM8, 2, 0xc8, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "eorb", OP_DIRECT, 2, 0xd8, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "eorb", OP_IND16, 3, 0xf8, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "eorb", OP_IX, 2, 0xe8, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "eorb", OP_IY | OP_PAGE2, 3, 0xe8, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "eorb", OP_IDX, 2, 0xe8, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "eorb", OP_IDX_1, 3, 0xe8, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "eorb", OP_IDX_2, 4, 0xe8, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "eorb", OP_D_IDX, 2, 0xe8, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+- { "eorb", OP_D_IDX_2, 4, 0xe8, 6, 6, CLR_V_CHG_NZ, cpu6812 },
++ { "dec", OP_IX, 2, 0x6a, 6, 6, CHG_NZV, cpu6811, 0 },
++ { "dec", OP_IND16, 3, 0x7a, 6, 6, CHG_NZV, cpu6811, 0 },
++ { "dec", OP_IY | OP_PAGE2, 3, 0x6a, 7, 7, CHG_NZV, cpu6811, 0 },
++ { "dec", OP_IND16, 3, 0x73, 4, 4, CHG_NZV, cpu6812|cpu9s12x, 0 },
++ { "dec", OP_IDX, 2, 0x63, 3, 3, CHG_NZV, cpu6812|cpu9s12x, 0 },
++ { "dec", OP_IDX_1, 3, 0x63, 4, 4, CHG_NZV, cpu6812|cpu9s12x, 0 },
++ { "dec", OP_IDX_2, 4, 0x63, 5, 5, CHG_NZV, cpu6812|cpu9s12x, 0 },
++ { "dec", OP_D_IDX, 2, 0x63, 6, 6, CHG_NZV, cpu6812|cpu9s12x, 0 },
++ { "dec", OP_D_IDX_2, 4, 0x63, 6, 6, CHG_NZV, cpu6812|cpu9s12x, 0 },
++
++ { "des", OP_NONE, 1, 0x34, 3, 3, CHG_NONE, cpu6811, 0 },
++
++ { "deca", OP_NONE, 1, 0x4a, 2, 2, CHG_NZV, cpu6811, 0 },
++ { "deca", OP_NONE, 1, 0x43, 1, 1, CHG_NZV, cpu6812|cpu9s12x, 0 },
++ { "decb", OP_NONE, 1, 0x5a, 2, 2, CHG_NZV, cpu6811, 0 },
++ { "decb", OP_NONE, 1, 0x53, 1, 1, CHG_NZV, cpu6812|cpu9s12x, 0 },
++
++ { "decw", OP_IND16 | OP_PAGE2, 3, 0x73, 4, 4, CHG_NZV, cpu9s12x, 0 },
++ { "decw", OP_IDX | OP_PAGE2, 2, 0x63, 3, 3, CHG_NZV, cpu9s12x, 0 },
++ { "decw", OP_IDX_1 | OP_PAGE2, 3, 0x63, 4, 4, CHG_NZV, cpu9s12x, 0 },
++ { "decw", OP_IDX_2 | OP_PAGE2, 4, 0x63, 5, 5, CHG_NZV, cpu9s12x, 0 },
++ { "decw", OP_D_IDX | OP_PAGE2, 2, 0x63, 6, 6, CHG_NZV, cpu9s12x, 0 },
++ { "decw", OP_D_IDX_2 | OP_PAGE2, 4, 0x63, 6, 6, CHG_NZV, cpu9s12x, 0 },
++
++ { "decx", OP_NONE | OP_PAGE2, 3, 0x43, 4, 4, CHG_NZV, cpu9s12x, 0 },
++
++ { "decy", OP_NONE | OP_PAGE2, 3, 0x53, 4, 4, CHG_NZV, cpu9s12x, 0 },
++
++ { "dex", OP_NONE, 1, 0x09, 1, 1, CHG_Z, cpu6812|cpu9s12x|cpu6811, 0 },
++ { "dey", OP_NONE | OP_PAGE2, 2, 0x09, 4, 4, CHG_Z, cpu6811, 0 },
++ { "dey", OP_NONE, 1, 0x03, 1, 1, CHG_Z, cpu6812|cpu9s12x, 0 },
++
++ { "ediv", OP_NONE, 1, 0x11, 11, 11, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "edivs", OP_NONE | OP_PAGE2, 2, 0x14, 12, 12, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "emacs", OP_IND16 | OP_PAGE2, 4, 0x12, 13, 13, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "emaxd", OP_IDX | OP_PAGE2, 3, 0x1a, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "emaxd", OP_IDX_1 | OP_PAGE2, 4, 0x1a, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "emaxd", OP_IDX_2 | OP_PAGE2, 5, 0x1a, 5, 5, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "emaxd", OP_D_IDX | OP_PAGE2, 3, 0x1a, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "emaxd", OP_D_IDX_2 | OP_PAGE2, 5, 0x1a, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "emaxm", OP_IDX | OP_PAGE2, 3, 0x1e, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "emaxm", OP_IDX_1 | OP_PAGE2, 4, 0x1e, 5, 5, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "emaxm", OP_IDX_2 | OP_PAGE2, 5, 0x1e, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "emaxm", OP_D_IDX | OP_PAGE2, 3, 0x1e, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "emaxm", OP_D_IDX_2 | OP_PAGE2, 5, 0x1e, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "emind", OP_IDX | OP_PAGE2, 3, 0x1b, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "emind", OP_IDX_1 | OP_PAGE2, 4, 0x1b, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "emind", OP_IDX_2 | OP_PAGE2, 5, 0x1b, 5, 5, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "emind", OP_D_IDX | OP_PAGE2, 3, 0x1b, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "emind", OP_D_IDX_2 | OP_PAGE2, 5, 0x1b, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "eminm", OP_IDX | OP_PAGE2, 3, 0x1f, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "eminm", OP_IDX_1 | OP_PAGE2, 4, 0x1f, 5, 5, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "eminm", OP_IDX_2 | OP_PAGE2, 5, 0x1f, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "eminm", OP_D_IDX | OP_PAGE2, 3, 0x1f, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "eminm", OP_D_IDX_2 | OP_PAGE2, 5, 0x1f, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "emul", OP_NONE, 1, 0x13, 3, 3, CHG_NZC, cpu6812|cpu9s12x, 0 },
++ { "emuls", OP_NONE | OP_PAGE2, 2, 0x13, 3, 3, CHG_NZC, cpu6812|cpu9s12x, 0 },
++
++ { "eora", OP_IMM8, 2, 0x88, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "eora", OP_DIRECT, 2, 0x98, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "eora", OP_IND16, 3, 0xb8, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "eora", OP_IX, 2, 0xa8, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "eora", OP_IY | OP_PAGE2, 3, 0xa8, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "eora", OP_IDX, 2, 0xa8, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "eora", OP_IDX_1, 3, 0xa8, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "eora", OP_IDX_2, 4, 0xa8, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "eora", OP_D_IDX, 2, 0xa8, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "eora", OP_D_IDX_2, 4, 0xa8, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "eorb", OP_IMM8, 2, 0xc8, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "eorb", OP_DIRECT, 2, 0xd8, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "eorb", OP_IND16, 3, 0xf8, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "eorb", OP_IX, 2, 0xe8, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "eorb", OP_IY | OP_PAGE2, 3, 0xe8, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "eorb", OP_IDX, 2, 0xe8, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "eorb", OP_IDX_1, 3, 0xe8, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "eorb", OP_IDX_2, 4, 0xe8, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "eorb", OP_D_IDX, 2, 0xe8, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "eorb", OP_D_IDX_2, 4, 0xe8, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "eorx", OP_IMM16 | OP_PAGE2, 2, 0x88, 1, 1, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "eorx", OP_DIRECT | OP_PAGE2, 2, 0x98, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "eorx", OP_IND16 | OP_PAGE2, 3, 0xb8, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "eorx", OP_IDX | OP_PAGE2, 2, 0xa8, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "eorx", OP_IDX_1 | OP_PAGE2, 3, 0xa8, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "eorx", OP_IDX_2 | OP_PAGE2, 4, 0xa8, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "eorx", OP_D_IDX | OP_PAGE2, 2, 0xa8, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "eorx", OP_D_IDX_2 | OP_PAGE2, 4, 0xa8, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "eory", OP_IMM16 | OP_PAGE2, 2, 0xc8, 1, 1, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "eory", OP_DIRECT | OP_PAGE2, 2, 0xd8, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "eory", OP_IND16 | OP_PAGE2, 3, 0xf8, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "eory", OP_IDX | OP_PAGE2, 2, 0xe8, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "eory", OP_IDX_1 | OP_PAGE2, 3, 0xe8, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "eory", OP_IDX_2 | OP_PAGE2, 4, 0xe8, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "eory", OP_D_IDX | OP_PAGE2, 2, 0xe8, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "eory", OP_D_IDX_2 | OP_PAGE2, 4, 0xe8, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
+
+- { "etbl", OP_IDX | OP_PAGE2,3, 0x3f, 10, 10, CHG_NZC, cpu6812 },
++ { "etbl", OP_IDX | OP_PAGE2,3, 0x3f, 10, 10, CHG_NZC, cpu6812|cpu9s12x, 0 },
+
++/* FIXME S12X support more exg variants */
+ { "exg", OP_EXG_MARKER
+- | OP_REG | OP_REG_2, 2, 0xb7, 1, 1, CHG_NONE, cpu6812 },
++ | OP_REG | OP_REG_2, 2, 0xb7, 1, 1, CHG_NONE, cpu6812|cpu9s12x, 0 },
++
++ { "fdiv", OP_NONE, 1, 0x03, 3, 41, CHG_ZVC, cpu6811, 0 },
++ { "fdiv", OP_NONE | OP_PAGE2, 2, 0x11, 12, 12, CHG_ZVC, cpu6812|cpu9s12x, 0 },
+
+- { "fdiv", OP_NONE, 1, 0x03, 3, 41, CHG_ZVC, cpu6811},
+- { "fdiv", OP_NONE | OP_PAGE2, 2, 0x11, 12, 12, CHG_ZVC, cpu6812 },
++ { "gldaa", OP_DIRECT | OP_PAGE2, 2, 0x96, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldaa", OP_IND16 | OP_PAGE2, 3, 0xb6, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldaa", OP_IDX | OP_PAGE2, 2, 0xa6, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldaa", OP_IDX_1 | OP_PAGE2, 3, 0xa6, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldaa", OP_IDX_2 | OP_PAGE2, 4, 0xa6, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldaa", OP_D_IDX | OP_PAGE2, 2, 0xa6, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldaa", OP_D_IDX_2 | OP_PAGE2, 4, 0xa6, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "gldab", OP_DIRECT | OP_PAGE2, 2, 0xd6, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldab", OP_IND16 | OP_PAGE2, 3, 0xf6, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldab", OP_IDX | OP_PAGE2, 2, 0xe6, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldab", OP_IDX_1 | OP_PAGE2, 3, 0xe6, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldab", OP_IDX_2 | OP_PAGE2, 4, 0xe6, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldab", OP_D_IDX | OP_PAGE2, 2, 0xe6, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldab", OP_D_IDX_2 | OP_PAGE2, 4, 0xe6, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "gldd", OP_DIRECT | OP_PAGE2, 2, 0xdc, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldd", OP_IND16 | OP_PAGE2, 3, 0xfc, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldd", OP_IDX | OP_PAGE2, 2, 0xec, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldd", OP_IDX_1 | OP_PAGE2, 3, 0xec, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldd", OP_IDX_2 | OP_PAGE2, 4, 0xec, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldd", OP_D_IDX | OP_PAGE2, 2, 0xec, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldd", OP_D_IDX_2 | OP_PAGE2, 4, 0xec, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "glds", OP_DIRECT | OP_PAGE2, 2, 0xdf, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "glds", OP_IND16 | OP_PAGE2, 3, 0xff, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "glds", OP_IDX | OP_PAGE2, 2, 0xef, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "glds", OP_IDX_1 | OP_PAGE2, 3, 0xef, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "glds", OP_IDX_2 | OP_PAGE2, 4, 0xef, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "glds", OP_D_IDX | OP_PAGE2, 2, 0xef, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "glds", OP_D_IDX_2 | OP_PAGE2, 4, 0xef, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "gldx", OP_DIRECT | OP_PAGE2, 2, 0xde, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldx", OP_IND16 | OP_PAGE2, 3, 0xfe, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldx", OP_IDX | OP_PAGE2, 2, 0xee, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldx", OP_IDX_1 | OP_PAGE2, 3, 0xee, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldx", OP_IDX_2 | OP_PAGE2, 4, 0xee, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldx", OP_D_IDX | OP_PAGE2, 2, 0xee, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldx", OP_D_IDX_2 | OP_PAGE2, 4, 0xee, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "gldy", OP_DIRECT | OP_PAGE2, 2, 0xdd, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldy", OP_IND16 | OP_PAGE2, 3, 0xfd, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldy", OP_IDX | OP_PAGE2, 2, 0xed, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldy", OP_IDX_1 | OP_PAGE2, 3, 0xed, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldy", OP_IDX_2 | OP_PAGE2, 4, 0xed, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldy", OP_D_IDX | OP_PAGE2, 2, 0xed, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gldy", OP_D_IDX_2 | OP_PAGE2, 4, 0xed, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "gstaa", OP_DIRECT | OP_PAGE2, 2, 0x5a, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstaa", OP_IND16 | OP_PAGE2, 3, 0x7a, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstaa", OP_IDX | OP_PAGE2, 2, 0x6a, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstaa", OP_IDX_1 | OP_PAGE2, 3, 0x6a, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstaa", OP_IDX_2 | OP_PAGE2, 4, 0x6a, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstaa", OP_D_IDX | OP_PAGE2, 2, 0x6a, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstaa", OP_D_IDX_2 | OP_PAGE2, 4, 0x6a, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "gstab", OP_DIRECT | OP_PAGE2, 2, 0x5b, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstab", OP_IND16 | OP_PAGE2, 3, 0x7b, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstab", OP_IDX | OP_PAGE2, 2, 0x6b, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstab", OP_IDX_1 | OP_PAGE2, 3, 0x6b, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstab", OP_IDX_2 | OP_PAGE2, 4, 0x6b, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstab", OP_D_IDX | OP_PAGE2, 2, 0x6b, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstab", OP_D_IDX_2 | OP_PAGE2, 4, 0x6b, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "gstd", OP_DIRECT | OP_PAGE2, 2, 0x5c, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstd", OP_IND16 | OP_PAGE2, 3, 0x7c, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstd", OP_IDX | OP_PAGE2, 2, 0x6c, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstd", OP_IDX_1 | OP_PAGE2, 3, 0x6c, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstd", OP_IDX_2 | OP_PAGE2, 4, 0x6c, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstd", OP_D_IDX | OP_PAGE2, 2, 0x6c, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstd", OP_D_IDX_2 | OP_PAGE2, 4, 0x6c, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "gsts", OP_DIRECT | OP_PAGE2, 2, 0x5f, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gsts", OP_IND16 | OP_PAGE2, 3, 0x6f, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gsts", OP_IDX | OP_PAGE2, 2, 0x6f, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gsts", OP_IDX_1 | OP_PAGE2, 3, 0x6f, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gsts", OP_IDX_2 | OP_PAGE2, 4, 0x6f, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gsts", OP_D_IDX | OP_PAGE2, 2, 0x6f, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gsts", OP_D_IDX_2 | OP_PAGE2, 4, 0x6f, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "gstx", OP_DIRECT | OP_PAGE2, 2, 0x5e, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstx", OP_IND16 | OP_PAGE2, 3, 0x7e, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstx", OP_IDX | OP_PAGE2, 2, 0x6e, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstx", OP_IDX_1 | OP_PAGE2, 3, 0x6e, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstx", OP_IDX_2 | OP_PAGE2, 4, 0x6e, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstx", OP_D_IDX | OP_PAGE2, 2, 0x6e, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gstx", OP_D_IDX_2 | OP_PAGE2, 4, 0x6e, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "gsty", OP_DIRECT | OP_PAGE2, 2, 0x5d, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gsty", OP_IND16 | OP_PAGE2, 3, 0x7d, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gsty", OP_IDX | OP_PAGE2, 2, 0x6d, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gsty", OP_IDX_1 | OP_PAGE2, 3, 0x6d, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gsty", OP_IDX_2 | OP_PAGE2, 4, 0x6d, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gsty", OP_D_IDX | OP_PAGE2, 2, 0x6d, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "gsty", OP_D_IDX_2 | OP_PAGE2, 4, 0x6d, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
+
+ { "ibeq", OP_IBEQ_MARKER
+- | OP_REG | OP_JUMP_REL, 3, 0x04, 3, 3, CHG_NONE, cpu6812 },
++ | OP_REG | OP_JUMP_REL, 3, 0x04, 3, 3, CHG_NONE, cpu6812|cpu9s12x, 0 },
+ { "ibne", OP_IBNE_MARKER
+- | OP_REG | OP_JUMP_REL, 3, 0x04, 3, 3, CHG_NONE, cpu6812 },
++ | OP_REG | OP_JUMP_REL, 3, 0x04, 3, 3, CHG_NONE, cpu6812|cpu9s12x, 0 },
+
+- { "idiv", OP_NONE, 1, 0x02, 3, 41, CLR_V_CHG_ZC, cpu6811},
+- { "idiv", OP_NONE | OP_PAGE2, 2, 0x10, 12, 12, CLR_V_CHG_ZC, cpu6812 },
+- { "idivs", OP_NONE | OP_PAGE2, 2, 0x15, 12, 12, CHG_NZVC, cpu6812 },
+-
+- { "inc", OP_IX, 2, 0x6c, 6, 6, CHG_NZV, cpu6811 },
+- { "inc", OP_IND16, 3, 0x7c, 6, 6, CHG_NZV, cpu6811 },
+- { "inc", OP_IY | OP_PAGE2, 3, 0x6c, 7, 7, CHG_NZV, cpu6811 },
+- { "inc", OP_IND16, 3, 0x72, 4, 4, CHG_NZV, cpu6812 },
+- { "inc", OP_IDX, 2, 0x62, 3, 3, CHG_NZV, cpu6812 },
+- { "inc", OP_IDX_1, 3, 0x62, 4, 4, CHG_NZV, cpu6812 },
+- { "inc", OP_IDX_2, 4, 0x62, 5, 5, CHG_NZV, cpu6812 },
+- { "inc", OP_D_IDX, 2, 0x62, 6, 6, CHG_NZV, cpu6812 },
+- { "inc", OP_D_IDX_2, 4, 0x62, 6, 6, CHG_NZV, cpu6812 },
+-
+- { "inca", OP_NONE, 1, 0x4c, 2, 2, CHG_NZV, cpu6811 },
+- { "inca", OP_NONE, 1, 0x42, 1, 1, CHG_NZV, cpu6812 },
+- { "incb", OP_NONE, 1, 0x5c, 2, 2, CHG_NZV, cpu6811 },
+- { "incb", OP_NONE, 1, 0x52, 1, 1, CHG_NZV, cpu6812 },
+-
+- { "ins", OP_NONE, 1, 0x31, 3, 3, CHG_NONE, cpu6811 },
+-
+- { "inx", OP_NONE, 1, 0x08, 1, 1, CHG_Z, cpu6811|cpu6812 },
+- { "iny", OP_NONE |OP_PAGE2, 2, 0x08, 4, 4, CHG_Z, cpu6811 },
+- { "iny", OP_NONE, 1, 0x02, 1, 1, CHG_Z, cpu6812 },
+-
+- { "jmp", OP_IND16 | OP_BRANCH, 3, 0x7e, 3, 3, CHG_NONE, cpu6811 },
+- { "jmp", OP_IX, 2, 0x6e, 3, 3, CHG_NONE, cpu6811 },
+- { "jmp", OP_IY | OP_PAGE2, 3, 0x6e, 4, 4, CHG_NONE, cpu6811 },
+- { "jmp", OP_IND16 | OP_BRANCH, 3, 0x06, 3, 3, CHG_NONE, cpu6812 },
+- { "jmp", OP_IDX, 2, 0x05, 3, 3, CHG_NONE, cpu6812 },
+- { "jmp", OP_IDX_1, 3, 0x05, 3, 3, CHG_NONE, cpu6812 },
+- { "jmp", OP_IDX_2, 4, 0x05, 4, 4, CHG_NONE, cpu6812 },
+- { "jmp", OP_D_IDX, 2, 0x05, 6, 6, CHG_NONE, cpu6812 },
+- { "jmp", OP_D_IDX_2, 4, 0x05, 6, 6, CHG_NONE, cpu6812 },
+-
+- { "jsr", OP_DIRECT | OP_BRANCH, 2, 0x9d, 5, 5, CHG_NONE, cpu6811 },
+- { "jsr", OP_IND16 | OP_BRANCH, 3, 0xbd, 6, 6, CHG_NONE, cpu6811 },
+- { "jsr", OP_IX, 2, 0xad, 6, 6, CHG_NONE, cpu6811 },
+- { "jsr", OP_IY | OP_PAGE2, 3, 0xad, 6, 6, CHG_NONE, cpu6811 },
+- { "jsr", OP_DIRECT | OP_BRANCH, 2, 0x17, 4, 4, CHG_NONE, cpu6812 },
+- { "jsr", OP_IND16 | OP_BRANCH, 3, 0x16, 4, 3, CHG_NONE, cpu6812 },
+- { "jsr", OP_IDX, 2, 0x15, 4, 4, CHG_NONE, cpu6812 },
+- { "jsr", OP_IDX_1, 3, 0x15, 4, 4, CHG_NONE, cpu6812 },
+- { "jsr", OP_IDX_2, 4, 0x15, 5, 5, CHG_NONE, cpu6812 },
+- { "jsr", OP_D_IDX, 2, 0x15, 7, 7, CHG_NONE, cpu6812 },
+- { "jsr", OP_D_IDX_2, 4, 0x15, 7, 7, CHG_NONE, cpu6812 },
+-
+- { "lbcc", OP_JUMP_REL16 | OP_PAGE2, 4, 0x24, 3, 4, CHG_NONE, cpu6812 },
+- { "lbcs", OP_JUMP_REL16 | OP_PAGE2, 4, 0x25, 3, 4, CHG_NONE, cpu6812 },
+- { "lbeq", OP_JUMP_REL16 | OP_PAGE2, 4, 0x27, 3, 4, CHG_NONE, cpu6812 },
+- { "lbge", OP_JUMP_REL16 | OP_PAGE2, 4, 0x2c, 3, 4, CHG_NONE, cpu6812 },
+- { "lbgt", OP_JUMP_REL16 | OP_PAGE2, 4, 0x2e, 3, 4, CHG_NONE, cpu6812 },
+- { "lbhi", OP_JUMP_REL16 | OP_PAGE2, 4, 0x22, 3, 4, CHG_NONE, cpu6812 },
+- { "lbhs", OP_JUMP_REL16 | OP_PAGE2, 4, 0x24, 3, 4, CHG_NONE, cpu6812 },
+- { "lble", OP_JUMP_REL16 | OP_PAGE2, 4, 0x2f, 3, 4, CHG_NONE, cpu6812 },
+- { "lblo", OP_JUMP_REL16 | OP_PAGE2, 4, 0x25, 3, 4, CHG_NONE, cpu6812 },
+- { "lbls", OP_JUMP_REL16 | OP_PAGE2, 4, 0x23, 3, 4, CHG_NONE, cpu6812 },
+- { "lblt", OP_JUMP_REL16 | OP_PAGE2, 4, 0x2d, 3, 4, CHG_NONE, cpu6812 },
+- { "lbmi", OP_JUMP_REL16 | OP_PAGE2, 4, 0x2b, 3, 4, CHG_NONE, cpu6812 },
+- { "lbne", OP_JUMP_REL16 | OP_PAGE2, 4, 0x26, 3, 4, CHG_NONE, cpu6812 },
+- { "lbpl", OP_JUMP_REL16 | OP_PAGE2, 4, 0x2a, 3, 4, CHG_NONE, cpu6812 },
+- { "lbra", OP_JUMP_REL16 | OP_PAGE2, 4, 0x20, 4, 4, CHG_NONE, cpu6812 },
+- { "lbrn", OP_JUMP_REL16 | OP_PAGE2, 4, 0x21, 3, 3, CHG_NONE, cpu6812 },
+- { "lbvc", OP_JUMP_REL16 | OP_PAGE2, 4, 0x28, 3, 4, CHG_NONE, cpu6812 },
+- { "lbvs", OP_JUMP_REL16 | OP_PAGE2, 4, 0x29, 3, 4, CHG_NONE, cpu6812 },
+-
+- { "ldaa", OP_IMM8, 2, 0x86, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "ldaa", OP_DIRECT, 2, 0x96, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "ldaa", OP_IND16, 3, 0xb6, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "ldaa", OP_IX, 2, 0xa6, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "ldaa", OP_IY | OP_PAGE2, 3, 0xa6, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "ldaa", OP_IDX, 2, 0xa6, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "ldaa", OP_IDX_1, 3, 0xa6, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "ldaa", OP_IDX_2, 4, 0xa6, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "ldaa", OP_D_IDX, 2, 0xa6, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+- { "ldaa", OP_D_IDX_2, 4, 0xa6, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "ldab", OP_IMM8, 2, 0xc6, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "ldab", OP_DIRECT, 2, 0xd6, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "ldab", OP_IND16, 3, 0xf6, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "ldab", OP_IX, 2, 0xe6, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "ldab", OP_IY | OP_PAGE2, 3, 0xe6, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "ldab", OP_IDX, 2, 0xe6, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "ldab", OP_IDX_1, 3, 0xe6, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "ldab", OP_IDX_2, 4, 0xe6, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "ldab", OP_D_IDX, 2, 0xe6, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+- { "ldab", OP_D_IDX_2, 4, 0xe6, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "ldd", OP_IMM16, 3, 0xcc, 2, 2, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "ldd", OP_DIRECT, 2, 0xdc, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "ldd", OP_IND16, 3, 0xfc, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "ldd", OP_IX, 2, 0xec, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "ldd", OP_IY | OP_PAGE2, 3, 0xec, 6, 6, CLR_V_CHG_NZ, cpu6811 },
+- { "ldd", OP_IDX, 2, 0xec, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "ldd", OP_IDX_1, 3, 0xec, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "ldd", OP_IDX_2, 4, 0xec, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "ldd", OP_D_IDX, 2, 0xec, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+- { "ldd", OP_D_IDX_2, 4, 0xec, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "lds", OP_IMM16, 3, 0x8e, 3, 3, CLR_V_CHG_NZ, cpu6811 },
+- { "lds", OP_DIRECT, 2, 0x9e, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "lds", OP_IND16, 3, 0xbe, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "lds", OP_IX, 2, 0xae, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "lds", OP_IY | OP_PAGE2, 3, 0xae, 6, 6, CLR_V_CHG_NZ, cpu6811 },
+- { "lds", OP_IMM16, 3, 0xcf, 2, 2, CLR_V_CHG_NZ, cpu6812 },
+- { "lds", OP_DIRECT, 2, 0xdf, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "lds", OP_IND16, 3, 0xff, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "lds", OP_IDX, 2, 0xef, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "lds", OP_IDX_1, 3, 0xef, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "lds", OP_IDX_2, 4, 0xef, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "lds", OP_D_IDX, 2, 0xef, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+- { "lds", OP_D_IDX_2, 4, 0xef, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "ldx", OP_IMM16, 3, 0xce, 2, 2, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "ldx", OP_DIRECT, 2, 0xde, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "ldx", OP_IND16, 3, 0xfe, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "ldx", OP_IX, 2, 0xee, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "ldx", OP_IY | OP_PAGE4, 3, 0xee, 6, 6, CLR_V_CHG_NZ, cpu6811 },
+- { "ldx", OP_IDX, 2, 0xee, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "ldx", OP_IDX_1, 3, 0xee, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "ldx", OP_IDX_2, 4, 0xee, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "ldx", OP_D_IDX, 2, 0xee, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+- { "ldx", OP_D_IDX_2, 4, 0xee, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "ldy", OP_IMM16 | OP_PAGE2, 4, 0xce, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "ldy", OP_DIRECT | OP_PAGE2, 3, 0xde, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "ldy", OP_IND16 | OP_PAGE2, 4, 0xfe, 6, 6, CLR_V_CHG_NZ, cpu6811 },
+- { "ldy", OP_IX | OP_PAGE3, 3, 0xee, 6, 6, CLR_V_CHG_NZ, cpu6811 },
+- { "ldy", OP_IY | OP_PAGE2, 3, 0xee, 6, 6, CLR_V_CHG_NZ, cpu6811 },
+- { "ldy", OP_IMM16, 3, 0xcd, 2, 2, CLR_V_CHG_NZ, cpu6812 },
+- { "ldy", OP_DIRECT, 2, 0xdd, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "ldy", OP_IND16, 3, 0xfd, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "ldy", OP_IDX, 2, 0xed, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "ldy", OP_IDX_1, 3, 0xed, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "ldy", OP_IDX_2, 4, 0xed, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "ldy", OP_D_IDX, 2, 0xed, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+- { "ldy", OP_D_IDX_2, 4, 0xed, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "leas", OP_IDX, 2, 0x1b, 2, 2, CHG_NONE, cpu6812 },
+- { "leas", OP_IDX_1, 3, 0x1b, 2, 2, CHG_NONE, cpu6812 },
+- { "leas", OP_IDX_2, 4, 0x1b, 2, 2, CHG_NONE, cpu6812 },
+-
+- { "leax", OP_IDX, 2, 0x1a, 2, 2, CHG_NONE, cpu6812 },
+- { "leax", OP_IDX_1, 3, 0x1a, 2, 2, CHG_NONE, cpu6812 },
+- { "leax", OP_IDX_2, 4, 0x1a, 2, 2, CHG_NONE, cpu6812 },
+-
+- { "leay", OP_IDX, 2, 0x19, 2, 2, CHG_NONE, cpu6812 },
+- { "leay", OP_IDX_1, 3, 0x19, 2, 2, CHG_NONE, cpu6812 },
+- { "leay", OP_IDX_2, 4, 0x19, 2, 2, CHG_NONE, cpu6812 },
+-
+- { "lsl", OP_IND16, 3, 0x78, 4, 4, CHG_NZVC, cpu6811|cpu6812 },
+- { "lsl", OP_IX, 2, 0x68, 6, 6, CHG_NZVC, cpu6811 },
+- { "lsl", OP_IY | OP_PAGE2, 3, 0x68, 7, 7, CHG_NZVC, cpu6811 },
+- { "lsl", OP_IDX, 2, 0x68, 3, 3, CHG_NZVC, cpu6812 },
+- { "lsl", OP_IDX_1, 3, 0x68, 4, 4, CHG_NZVC, cpu6812 },
+- { "lsl", OP_IDX_2, 4, 0x68, 5, 5, CHG_NZVC, cpu6812 },
+- { "lsl", OP_D_IDX, 2, 0x68, 6, 6, CHG_NZVC, cpu6812 },
+- { "lsl", OP_D_IDX_2, 4, 0x68, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "lsla", OP_NONE, 1, 0x48, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+- { "lslb", OP_NONE, 1, 0x58, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+- { "lsld", OP_NONE, 1, 0x05, 3, 3, CHG_NZVC, cpu6811 },
+- { "lsld", OP_NONE, 1, 0x59, 1, 1, CHG_NZVC, cpu6812 },
+-
+- { "lsr", OP_IND16, 3, 0x74, 4, 4, CLR_N_CHG_ZVC, cpu6811|cpu6812},
+- { "lsr", OP_IX, 2, 0x64, 6, 6, CLR_N_CHG_ZVC, cpu6811 },
+- { "lsr", OP_IY | OP_PAGE2, 3, 0x64, 7, 7, CLR_V_CHG_ZVC, cpu6811 },
+- { "lsr", OP_IDX, 2, 0x64, 3, 3, CLR_N_CHG_ZVC, cpu6812 },
+- { "lsr", OP_IDX_1, 3, 0x64, 4, 4, CLR_N_CHG_ZVC, cpu6812 },
+- { "lsr", OP_IDX_2, 4, 0x64, 5, 5, CLR_N_CHG_ZVC, cpu6812 },
+- { "lsr", OP_D_IDX, 2, 0x64, 6, 6, CLR_N_CHG_ZVC, cpu6812 },
+- { "lsr", OP_D_IDX_2, 4, 0x64, 6, 6, CLR_N_CHG_ZVC, cpu6812 },
+-
+- { "lsra", OP_NONE, 1, 0x44, 1, 1, CLR_N_CHG_ZVC, cpu6811|cpu6812},
+- { "lsrb", OP_NONE, 1, 0x54, 1, 1, CLR_N_CHG_ZVC, cpu6811|cpu6812},
+- { "lsrd", OP_NONE, 1, 0x04, 3, 3, CLR_N_CHG_ZVC, cpu6811 },
+- { "lsrd", OP_NONE, 1, 0x49, 1, 1, CLR_N_CHG_ZVC, cpu6812 },
+-
+- { "maxa", OP_IDX | OP_PAGE2, 3, 0x18, 4, 4, CHG_NZVC, cpu6812 },
+- { "maxa", OP_IDX_1 | OP_PAGE2, 4, 0x18, 4, 4, CHG_NZVC, cpu6812 },
+- { "maxa", OP_IDX_2 | OP_PAGE2, 5, 0x18, 5, 5, CHG_NZVC, cpu6812 },
+- { "maxa", OP_D_IDX | OP_PAGE2, 3, 0x18, 7, 7, CHG_NZVC, cpu6812 },
+- { "maxa", OP_D_IDX_2 | OP_PAGE2, 5, 0x18, 7, 7, CHG_NZVC, cpu6812 },
+-
+- { "maxm", OP_IDX | OP_PAGE2, 3, 0x1c, 4, 4, CHG_NZVC, cpu6812 },
+- { "maxm", OP_IDX_1 | OP_PAGE2, 4, 0x1c, 5, 5, CHG_NZVC, cpu6812 },
+- { "maxm", OP_IDX_2 | OP_PAGE2, 5, 0x1c, 6, 6, CHG_NZVC, cpu6812 },
+- { "maxm", OP_D_IDX | OP_PAGE2, 3, 0x1c, 7, 7, CHG_NZVC, cpu6812 },
+- { "maxm", OP_D_IDX_2 | OP_PAGE2, 5, 0x1c, 7, 7, CHG_NZVC, cpu6812 },
+-
+- { "mem", OP_NONE, 1, 0x01, 5, 5, CHG_HNZVC, cpu6812 },
+-
+- { "mina", OP_IDX | OP_PAGE2, 3, 0x19, 4, 4, CHG_NZVC, cpu6812 },
+- { "mina", OP_IDX_1 | OP_PAGE2, 4, 0x19, 4, 4, CHG_NZVC, cpu6812 },
+- { "mina", OP_IDX_2 | OP_PAGE2, 5, 0x19, 5, 5, CHG_NZVC, cpu6812 },
+- { "mina", OP_D_IDX | OP_PAGE2, 3, 0x19, 7, 7, CHG_NZVC, cpu6812 },
+- { "mina", OP_D_IDX_2 | OP_PAGE2, 5, 0x19, 7, 7, CHG_NZVC, cpu6812 },
+-
+- { "minm", OP_IDX | OP_PAGE2, 3, 0x1d, 4, 4, CHG_NZVC, cpu6812 },
+- { "minm", OP_IDX_1 | OP_PAGE2, 4, 0x1d, 5, 5, CHG_NZVC, cpu6812 },
+- { "minm", OP_IDX_2 | OP_PAGE2, 5, 0x1d, 6, 6, CHG_NZVC, cpu6812 },
+- { "minm", OP_D_IDX | OP_PAGE2, 3, 0x1d, 7, 7, CHG_NZVC, cpu6812 },
+- { "minm", OP_D_IDX_2 | OP_PAGE2, 5, 0x1d, 7, 7, CHG_NZVC, cpu6812 },
+-
+- { "movb", OP_IMM8|OP_IND16_p2|OP_PAGE2, 5, 0x0b, 4, 4, CHG_NONE, cpu6812 },
+- { "movb", OP_IMM8|OP_IDX_p2|OP_PAGE2, 4, 0x08, 4, 4, CHG_NONE, cpu6812 },
+- { "movb", OP_IND16|OP_IND16_p2|OP_PAGE2, 6, 0x0c, 6, 6, CHG_NONE, cpu6812 },
+- { "movb", OP_IND16 | OP_IDX_p2 | OP_PAGE2, 5, 0x09, 5, 5, CHG_NONE, cpu6812 },
+- { "movb", OP_IDX | OP_IND16_p2 | OP_PAGE2, 5, 0x0d, 5, 5, CHG_NONE, cpu6812 },
+- { "movb", OP_IDX | OP_IDX_p2 | OP_PAGE2, 4, 0x0a, 5, 5, CHG_NONE, cpu6812 },
+-
+- { "movw", OP_IMM16 | OP_IND16_p2 | OP_PAGE2, 6, 0x03, 5, 5, CHG_NONE, cpu6812 },
+- { "movw", OP_IMM16 | OP_IDX_p2 | OP_PAGE2, 5, 0x00, 4, 4, CHG_NONE, cpu6812 },
+- { "movw", OP_IND16 | OP_IND16_p2 | OP_PAGE2, 6, 0x04, 6, 6, CHG_NONE, cpu6812 },
+- { "movw", OP_IND16 | OP_IDX_p2 | OP_PAGE2, 5, 0x01, 5, 5, CHG_NONE, cpu6812 },
+- { "movw", OP_IDX | OP_IND16_p2 | OP_PAGE2, 5, 0x05, 5, 5, CHG_NONE, cpu6812 },
+- { "movw", OP_IDX | OP_IDX_p2 | OP_PAGE2, 4, 0x02, 5, 5, CHG_NONE, cpu6812 },
+-
+- { "mul", OP_NONE, 1, 0x3d, 3, 10, CHG_C, cpu6811 },
+- { "mul", OP_NONE, 1, 0x12, 3, 3, CHG_C, cpu6812 },
+-
+- { "neg", OP_IND16, 3, 0x70, 4, 4, CHG_NZVC, cpu6811|cpu6812 },
+- { "neg", OP_IX, 2, 0x60, 6, 6, CHG_NZVC, cpu6811 },
+- { "neg", OP_IY | OP_PAGE2, 3, 0x60, 7, 7, CHG_NZVC, cpu6811 },
+- { "neg", OP_IDX, 2, 0x60, 3, 3, CHG_NZVC, cpu6812 },
+- { "neg", OP_IDX_1, 3, 0x60, 4, 4, CHG_NZVC, cpu6812 },
+- { "neg", OP_IDX_2, 4, 0x60, 5, 5, CHG_NZVC, cpu6812 },
+- { "neg", OP_D_IDX, 2, 0x60, 6, 6, CHG_NZVC, cpu6812 },
+- { "neg", OP_D_IDX_2, 4, 0x60, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "nega", OP_NONE, 1, 0x40, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+- { "negb", OP_NONE, 1, 0x50, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+- { "nop", OP_NONE, 1, 0x01, 2, 2, CHG_NONE, cpu6811 },
+- { "nop", OP_NONE, 1, 0xa7, 1, 1, CHG_NONE, cpu6812 },
+-
+- { "oraa", OP_IMM8, 2, 0x8a, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "oraa", OP_DIRECT, 2, 0x9a, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "oraa", OP_IND16, 3, 0xba, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "oraa", OP_IX, 2, 0xaa, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "oraa", OP_IY | OP_PAGE2, 3, 0xaa, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "oraa", OP_IDX, 2, 0xaa, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "oraa", OP_IDX_1, 3, 0xaa, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "oraa", OP_IDX_2, 4, 0xaa, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "oraa", OP_D_IDX, 2, 0xaa, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+- { "oraa", OP_D_IDX_2, 4, 0xaa, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "orab", OP_IMM8, 2, 0xca, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "orab", OP_DIRECT, 2, 0xda, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "orab", OP_IND16, 3, 0xfa, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812 },
+- { "orab", OP_IX, 2, 0xea, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "orab", OP_IY | OP_PAGE2, 3, 0xea, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "orab", OP_IDX, 2, 0xea, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "orab", OP_IDX_1, 3, 0xea, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "orab", OP_IDX_2, 4, 0xea, 4, 4, CLR_V_CHG_NZ, cpu6812 },
+- { "orab", OP_D_IDX, 2, 0xea, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+- { "orab", OP_D_IDX_2, 4, 0xea, 6, 6, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "orcc", OP_IMM8, 2, 0x14, 1, 1, CHG_ALL, cpu6812 },
+-
+- { "psha", OP_NONE, 1, 0x36, 2, 2, CHG_NONE, cpu6811|cpu6812 },
+- { "pshb", OP_NONE, 1, 0x37, 2, 2, CHG_NONE, cpu6811|cpu6812 },
+- { "pshc", OP_NONE, 1, 0x39, 2, 2, CHG_NONE, cpu6812 },
+- { "pshd", OP_NONE, 1, 0x3b, 2, 2, CHG_NONE, cpu6812 },
+- { "pshx", OP_NONE, 1, 0x3c, 4, 4, CHG_NONE, cpu6811 },
+- { "pshx", OP_NONE, 1, 0x34, 2, 2, CHG_NONE, cpu6812 },
+- { "pshy", OP_NONE | OP_PAGE2,2, 0x3c, 5, 5, CHG_NONE, cpu6811 },
+- { "pshy", OP_NONE, 1, 0x35, 2, 2, CHG_NONE, cpu6812 },
+-
+- { "pula", OP_NONE, 1, 0x32, 3, 3, CHG_NONE, cpu6811|cpu6812 },
+- { "pulb", OP_NONE, 1, 0x33, 3, 3, CHG_NONE, cpu6811|cpu6812 },
+- { "pulc", OP_NONE, 1, 0x38, 3, 3, CHG_NONE, cpu6812 },
+- { "puld", OP_NONE, 1, 0x3a, 3, 3, CHG_NONE, cpu6812 },
+- { "pulx", OP_NONE, 1, 0x38, 5, 5, CHG_NONE, cpu6811 },
+- { "pulx", OP_NONE, 1, 0x30, 3, 3, CHG_NONE, cpu6812 },
+- { "puly", OP_NONE | OP_PAGE2,2, 0x38, 6, 6, CHG_NONE, cpu6811 },
+- { "puly", OP_NONE, 1, 0x31, 3, 3, CHG_NONE, cpu6812 },
+-
+- { "rev", OP_NONE | OP_PAGE2, 2, 0x3a, _M, _M, CHG_HNZVC, cpu6812 },
+- { "revw", OP_NONE | OP_PAGE2, 2, 0x3b, _M, _M, CHG_HNZVC, cpu6812 },
+-
+- { "rol", OP_IND16, 3, 0x79, 6, 6, CHG_NZVC, cpu6811 },
+- { "rol", OP_IX, 2, 0x69, 6, 6, CHG_NZVC, cpu6811 },
+- { "rol", OP_IY | OP_PAGE2, 3, 0x69, 7, 7, CHG_NZVC, cpu6811 },
+- { "rol", OP_IND16, 3, 0x75, 4, 4, CHG_NZVC, cpu6812 },
+- { "rol", OP_IDX, 2, 0x65, 3, 3, CHG_NZVC, cpu6812 },
+- { "rol", OP_IDX_1, 3, 0x65, 4, 4, CHG_NZVC, cpu6812 },
+- { "rol", OP_IDX_2, 4, 0x65, 5, 5, CHG_NZVC, cpu6812 },
+- { "rol", OP_D_IDX, 2, 0x65, 6, 6, CHG_NZVC, cpu6812 },
+- { "rol", OP_D_IDX_2, 4, 0x65, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "rola", OP_NONE, 1, 0x49, 2, 2, CHG_NZVC, cpu6811 },
+- { "rola", OP_NONE, 1, 0x45, 1, 1, CHG_NZVC, cpu6812 },
+- { "rolb", OP_NONE, 1, 0x59, 2, 2, CHG_NZVC, cpu6811 },
+- { "rolb", OP_NONE, 1, 0x55, 1, 1, CHG_NZVC, cpu6812 },
+-
+- { "ror", OP_IND16, 3, 0x76, 4, 4, CHG_NZVC, cpu6811|cpu6812 },
+- { "ror", OP_IX, 2, 0x66, 6, 6, CHG_NZVC, cpu6811 },
+- { "ror", OP_IY | OP_PAGE2, 3, 0x66, 7, 7, CHG_NZVC, cpu6811 },
+- { "ror", OP_IDX, 2, 0x66, 3, 3, CHG_NZVC, cpu6812 },
+- { "ror", OP_IDX_1, 3, 0x66, 4, 4, CHG_NZVC, cpu6812 },
+- { "ror", OP_IDX_2, 4, 0x66, 5, 5, CHG_NZVC, cpu6812 },
+- { "ror", OP_D_IDX, 2, 0x66, 6, 6, CHG_NZVC, cpu6812 },
+- { "ror", OP_D_IDX_2, 4, 0x66, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "rora", OP_NONE, 1, 0x46, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+- { "rorb", OP_NONE, 1, 0x56, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+-
+- { "rtc", OP_NONE, 1, 0x0a, 6, 6, CHG_NONE, cpu6812 },
+- { "rti", OP_NONE, 1, 0x3b, 12, 12, CHG_ALL, cpu6811},
+- { "rti", OP_NONE, 1, 0x0b, 8, 10, CHG_ALL, cpu6812},
+- { "rts", OP_NONE, 1, 0x39, 5, 5, CHG_NONE, cpu6811 },
+- { "rts", OP_NONE, 1, 0x3d, 5, 5, CHG_NONE, cpu6812 },
+-
+- { "sba", OP_NONE, 1, 0x10, 2, 2, CHG_NZVC, cpu6811 },
+- { "sba", OP_NONE | OP_PAGE2, 2, 0x16, 2, 2, CHG_NZVC, cpu6812 },
+-
+- { "sbca", OP_IMM8, 2, 0x82, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+- { "sbca", OP_DIRECT, 2, 0x92, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "sbca", OP_IND16, 3, 0xb2, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "sbca", OP_IX, 2, 0xa2, 4, 4, CHG_NZVC, cpu6811 },
+- { "sbca", OP_IY | OP_PAGE2, 3, 0xa2, 5, 5, CHG_NZVC, cpu6811 },
+- { "sbca", OP_IDX, 2, 0xa2, 3, 3, CHG_NZVC, cpu6812 },
+- { "sbca", OP_IDX_1, 3, 0xa2, 3, 3, CHG_NZVC, cpu6812 },
+- { "sbca", OP_IDX_2, 4, 0xa2, 4, 4, CHG_NZVC, cpu6812 },
+- { "sbca", OP_D_IDX, 2, 0xa2, 6, 6, CHG_NZVC, cpu6812 },
+- { "sbca", OP_D_IDX_2, 4, 0xa2, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "sbcb", OP_IMM8, 2, 0xc2, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+- { "sbcb", OP_DIRECT, 2, 0xd2, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "sbcb", OP_IND16, 3, 0xf2, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "sbcb", OP_IX, 2, 0xe2, 4, 4, CHG_NZVC, cpu6811 },
+- { "sbcb", OP_IY | OP_PAGE2, 3, 0xe2, 5, 5, CHG_NZVC, cpu6811 },
+- { "sbcb", OP_IDX, 2, 0xe2, 3, 3, CHG_NZVC, cpu6812 },
+- { "sbcb", OP_IDX_1, 3, 0xe2, 3, 3, CHG_NZVC, cpu6812 },
+- { "sbcb", OP_IDX_2, 4, 0xe2, 4, 4, CHG_NZVC, cpu6812 },
+- { "sbcb", OP_D_IDX, 2, 0xe2, 6, 6, CHG_NZVC, cpu6812 },
+- { "sbcb", OP_D_IDX_2, 4, 0xe2, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "sec", OP_NONE, 1, 0x0d, 2, 2, SET_C, cpu6811 },
+- { "sei", OP_NONE, 1, 0x0f, 2, 2, SET_I, cpu6811 },
+- { "sev", OP_NONE, 1, 0x0b, 2, 2, SET_V, cpu6811 },
++ { "idiv", OP_NONE, 1, 0x02, 3, 41, CLR_V_CHG_ZC, cpu6811, 0 },
++ { "idiv", OP_NONE | OP_PAGE2, 2, 0x10, 12, 12, CLR_V_CHG_ZC, cpu6812|cpu9s12x, 0 },
++ { "idivs", OP_NONE | OP_PAGE2, 2, 0x15, 12, 12, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "inc", OP_IX, 2, 0x6c, 6, 6, CHG_NZV, cpu6811, 0 },
++ { "inc", OP_IND16, 3, 0x7c, 6, 6, CHG_NZV, cpu6811, 0 },
++ { "inc", OP_IY | OP_PAGE2, 3, 0x6c, 7, 7, CHG_NZV, cpu6811, 0 },
++ { "inc", OP_IND16, 3, 0x72, 4, 4, CHG_NZV, cpu6812|cpu9s12x, 0 },
++ { "inc", OP_IDX, 2, 0x62, 3, 3, CHG_NZV, cpu6812|cpu9s12x, 0 },
++ { "inc", OP_IDX_1, 3, 0x62, 4, 4, CHG_NZV, cpu6812|cpu9s12x, 0 },
++ { "inc", OP_IDX_2, 4, 0x62, 5, 5, CHG_NZV, cpu6812|cpu9s12x, 0 },
++ { "inc", OP_D_IDX, 2, 0x62, 6, 6, CHG_NZV, cpu6812|cpu9s12x, 0 },
++ { "inc", OP_D_IDX_2, 4, 0x62, 6, 6, CHG_NZV, cpu6812|cpu9s12x, 0 },
++
++ { "inca", OP_NONE, 1, 0x4c, 2, 2, CHG_NZV, cpu6811, 0 },
++ { "inca", OP_NONE, 1, 0x42, 1, 1, CHG_NZV, cpu6812|cpu9s12x, 0 },
++ { "incb", OP_NONE, 1, 0x5c, 2, 2, CHG_NZV, cpu6811, 0 },
++ { "incb", OP_NONE, 1, 0x52, 1, 1, CHG_NZV, cpu6812|cpu9s12x, 0 },
++
++ { "incw", OP_IND16 | OP_PAGE2, 3, 0x72, 4, 4, CHG_NZV, cpu9s12x, 0 },
++ { "incw", OP_IDX | OP_PAGE2, 2, 0x62, 3, 3, CHG_NZV, cpu9s12x, 0 },
++ { "incw", OP_IDX_1 | OP_PAGE2, 3, 0x62, 4, 4, CHG_NZV, cpu9s12x, 0 },
++ { "incw", OP_IDX_2 | OP_PAGE2, 4, 0x62, 5, 5, CHG_NZV, cpu9s12x, 0 },
++ { "incw", OP_D_IDX | OP_PAGE2, 2, 0x62, 6, 6, CHG_NZV, cpu9s12x, 0 },
++ { "incw", OP_D_IDX_2 | OP_PAGE2, 4, 0x62, 6, 6, CHG_NZV, cpu9s12x, 0 },
++
++ { "incx", OP_NONE | OP_PAGE2, 3, 0x42, 4, 4, CHG_NZV, cpu9s12x, 0 },
++
++ { "incy", OP_NONE | OP_PAGE2, 3, 0x52, 4, 4, CHG_NZV, cpu9s12x, 0 },
++
++ { "ins", OP_NONE, 1, 0x31, 3, 3, CHG_NONE, cpu6811, 0 },
++
++ { "inx", OP_NONE, 1, 0x08, 1, 1, CHG_Z, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "iny", OP_NONE |OP_PAGE2, 2, 0x08, 4, 4, CHG_Z, cpu6811, 0 },
++ { "iny", OP_NONE, 1, 0x02, 1, 1, CHG_Z, cpu6812|cpu9s12x, 0 },
++
++ { "jmp", OP_IND16 | OP_BRANCH, 3, 0x7e, 3, 3, CHG_NONE, cpu6811, 0 },
++ { "jmp", OP_IX, 2, 0x6e, 3, 3, CHG_NONE, cpu6811, 0 },
++ { "jmp", OP_IY | OP_PAGE2, 3, 0x6e, 4, 4, CHG_NONE, cpu6811, 0 },
++ { "jmp", OP_IND16 | OP_BRANCH, 3, 0x06, 3, 3, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "jmp", OP_IDX, 2, 0x05, 3, 3, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "jmp", OP_IDX_1, 3, 0x05, 3, 3, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "jmp", OP_IDX_2, 4, 0x05, 4, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "jmp", OP_D_IDX, 2, 0x05, 6, 6, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "jmp", OP_D_IDX_2, 4, 0x05, 6, 6, CHG_NONE, cpu6812|cpu9s12x, 0 },
++
++ { "jsr", OP_DIRECT | OP_BRANCH, 2, 0x9d, 5, 5, CHG_NONE, cpu6811, 0 },
++ { "jsr", OP_IND16 | OP_BRANCH, 3, 0xbd, 6, 6, CHG_NONE, cpu6811, 0 },
++ { "jsr", OP_IX, 2, 0xad, 6, 6, CHG_NONE, cpu6811, 0 },
++ { "jsr", OP_IY | OP_PAGE2, 3, 0xad, 6, 6, CHG_NONE, cpu6811, 0 },
++ { "jsr", OP_DIRECT | OP_BRANCH, 2, 0x17, 4, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "jsr", OP_IND16 | OP_BRANCH, 3, 0x16, 4, 3, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "jsr", OP_IDX, 2, 0x15, 4, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "jsr", OP_IDX_1, 3, 0x15, 4, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "jsr", OP_IDX_2, 4, 0x15, 5, 5, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "jsr", OP_D_IDX, 2, 0x15, 7, 7, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "jsr", OP_D_IDX_2, 4, 0x15, 7, 7, CHG_NONE, cpu6812|cpu9s12x, 0 },
++
++ { "lbcc", OP_JUMP_REL16 | OP_PAGE2, 4, 0x24, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lbcs", OP_JUMP_REL16 | OP_PAGE2, 4, 0x25, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lbeq", OP_JUMP_REL16 | OP_PAGE2, 4, 0x27, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lbge", OP_JUMP_REL16 | OP_PAGE2, 4, 0x2c, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lbgt", OP_JUMP_REL16 | OP_PAGE2, 4, 0x2e, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lbhi", OP_JUMP_REL16 | OP_PAGE2, 4, 0x22, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lbhs", OP_JUMP_REL16 | OP_PAGE2, 4, 0x24, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lble", OP_JUMP_REL16 | OP_PAGE2, 4, 0x2f, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lblo", OP_JUMP_REL16 | OP_PAGE2, 4, 0x25, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lbls", OP_JUMP_REL16 | OP_PAGE2, 4, 0x23, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lblt", OP_JUMP_REL16 | OP_PAGE2, 4, 0x2d, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lbmi", OP_JUMP_REL16 | OP_PAGE2, 4, 0x2b, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lbne", OP_JUMP_REL16 | OP_PAGE2, 4, 0x26, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lbpl", OP_JUMP_REL16 | OP_PAGE2, 4, 0x2a, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lbra", OP_JUMP_REL16 | OP_PAGE2, 4, 0x20, 4, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lbrn", OP_JUMP_REL16 | OP_PAGE2, 4, 0x21, 3, 3, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lbvc", OP_JUMP_REL16 | OP_PAGE2, 4, 0x28, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "lbvs", OP_JUMP_REL16 | OP_PAGE2, 4, 0x29, 3, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++
++ { "ldaa", OP_IMM8, 2, 0x86, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "ldaa", OP_DIRECT, 2, 0x96, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "ldaa", OP_IND16, 3, 0xb6, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "ldaa", OP_IX, 2, 0xa6, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "ldaa", OP_IY | OP_PAGE2, 3, 0xa6, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "ldaa", OP_IDX, 2, 0xa6, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldaa", OP_IDX_1, 3, 0xa6, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldaa", OP_IDX_2, 4, 0xa6, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldaa", OP_D_IDX, 2, 0xa6, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldaa", OP_D_IDX_2, 4, 0xa6, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "ldab", OP_IMM8, 2, 0xc6, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "ldab", OP_DIRECT, 2, 0xd6, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "ldab", OP_IND16, 3, 0xf6, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "ldab", OP_IX, 2, 0xe6, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "ldab", OP_IY | OP_PAGE2, 3, 0xe6, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "ldab", OP_IDX, 2, 0xe6, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldab", OP_IDX_1, 3, 0xe6, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldab", OP_IDX_2, 4, 0xe6, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldab", OP_D_IDX, 2, 0xe6, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldab", OP_D_IDX_2, 4, 0xe6, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "ldd", OP_IMM16, 3, 0xcc, 2, 2, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "ldd", OP_DIRECT, 2, 0xdc, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "ldd", OP_IND16, 3, 0xfc, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "ldd", OP_IX, 2, 0xec, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "ldd", OP_IY | OP_PAGE2, 3, 0xec, 6, 6, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "ldd", OP_IDX, 2, 0xec, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldd", OP_IDX_1, 3, 0xec, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldd", OP_IDX_2, 4, 0xec, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldd", OP_D_IDX, 2, 0xec, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldd", OP_D_IDX_2, 4, 0xec, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "lds", OP_IMM16, 3, 0x8e, 3, 3, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "lds", OP_DIRECT, 2, 0x9e, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "lds", OP_IND16, 3, 0xbe, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "lds", OP_IX, 2, 0xae, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "lds", OP_IY | OP_PAGE2, 3, 0xae, 6, 6, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "lds", OP_IMM16, 3, 0xcf, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "lds", OP_DIRECT, 2, 0xdf, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "lds", OP_IND16, 3, 0xff, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "lds", OP_IDX, 2, 0xef, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "lds", OP_IDX_1, 3, 0xef, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "lds", OP_IDX_2, 4, 0xef, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "lds", OP_D_IDX, 2, 0xef, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "lds", OP_D_IDX_2, 4, 0xef, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "ldx", OP_IMM16, 3, 0xce, 2, 2, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "ldx", OP_DIRECT, 2, 0xde, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "ldx", OP_IND16, 3, 0xfe, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "ldx", OP_IX, 2, 0xee, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "ldx", OP_IY | OP_PAGE4, 3, 0xee, 6, 6, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "ldx", OP_IDX, 2, 0xee, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldx", OP_IDX_1, 3, 0xee, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldx", OP_IDX_2, 4, 0xee, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldx", OP_D_IDX, 2, 0xee, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldx", OP_D_IDX_2, 4, 0xee, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "ldy", OP_IMM16 | OP_PAGE2, 4, 0xce, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "ldy", OP_DIRECT | OP_PAGE2, 3, 0xde, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "ldy", OP_IND16 | OP_PAGE2, 4, 0xfe, 6, 6, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "ldy", OP_IX | OP_PAGE3, 3, 0xee, 6, 6, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "ldy", OP_IY | OP_PAGE2, 3, 0xee, 6, 6, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "ldy", OP_IMM16, 3, 0xcd, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldy", OP_DIRECT, 2, 0xdd, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldy", OP_IND16, 3, 0xfd, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldy", OP_IDX, 2, 0xed, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldy", OP_IDX_1, 3, 0xed, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldy", OP_IDX_2, 4, 0xed, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldy", OP_D_IDX, 2, 0xed, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "ldy", OP_D_IDX_2, 4, 0xed, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "leas", OP_IDX, 2, 0x1b, 2, 2, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "leas", OP_IDX_1, 3, 0x1b, 2, 2, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "leas", OP_IDX_2, 4, 0x1b, 2, 2, CHG_NONE, cpu6812|cpu9s12x, 0 },
++
++ { "leax", OP_IDX, 2, 0x1a, 2, 2, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "leax", OP_IDX_1, 3, 0x1a, 2, 2, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "leax", OP_IDX_2, 4, 0x1a, 2, 2, CHG_NONE, cpu6812|cpu9s12x, 0 },
++
++ { "leay", OP_IDX, 2, 0x19, 2, 2, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "leay", OP_IDX_1, 3, 0x19, 2, 2, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "leay", OP_IDX_2, 4, 0x19, 2, 2, CHG_NONE, cpu6812|cpu9s12x, 0 },
++
++ { "lsl", OP_IND16, 3, 0x78, 4, 4, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "lsl", OP_IX, 2, 0x68, 6, 6, CHG_NZVC, cpu6811, 0 },
++ { "lsl", OP_IY | OP_PAGE2, 3, 0x68, 7, 7, CHG_NZVC, cpu6811, 0 },
++ { "lsl", OP_IDX, 2, 0x68, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "lsl", OP_IDX_1, 3, 0x68, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "lsl", OP_IDX_2, 4, 0x68, 5, 5, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "lsl", OP_D_IDX, 2, 0x68, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "lsl", OP_D_IDX_2, 4, 0x68, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "lsla", OP_NONE, 1, 0x48, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "lslb", OP_NONE, 1, 0x58, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "lsld", OP_NONE, 1, 0x05, 3, 3, CHG_NZVC, cpu6811, 0 },
++ { "lsld", OP_NONE, 1, 0x59, 1, 1, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++/* same as aslw */
++ { "lslw", OP_IND16 | OP_PAGE2, 3, 0x78, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "lslw", OP_IDX | OP_PAGE2, 2, 0x68, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "lslw", OP_IDX_1 | OP_PAGE2, 3, 0x68, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "lslw", OP_IDX_2 | OP_PAGE2, 4, 0x68, 5, 5, CHG_NZVC, cpu9s12x, 0 },
++ { "lslw", OP_D_IDX | OP_PAGE2, 2, 0x68, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "lslw", OP_D_IDX_2 | OP_PAGE2, 4, 0x68, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++/* same as lslw */
++ { "lslx", OP_NONE | OP_PAGE2, 1, 0x48, 1, 1, CHG_NZVC, cpu9s12x, 0 },
++/* same as lslw */
++ { "lsly", OP_NONE | OP_PAGE2, 1, 0x58, 1, 1, CHG_NZVC, cpu9s12x, 0 },
++
++ { "lsr", OP_IND16, 3, 0x74, 4, 4, CLR_N_CHG_ZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "lsr", OP_IX, 2, 0x64, 6, 6, CLR_N_CHG_ZVC, cpu6811, 0 },
++ { "lsr", OP_IY | OP_PAGE2, 3, 0x64, 7, 7, CLR_V_CHG_ZVC, cpu6811, 0 },
++ { "lsr", OP_IDX, 2, 0x64, 3, 3, CLR_N_CHG_ZVC, cpu6812|cpu9s12x, 0 },
++ { "lsr", OP_IDX_1, 3, 0x64, 4, 4, CLR_N_CHG_ZVC, cpu6812|cpu9s12x, 0 },
++ { "lsr", OP_IDX_2, 4, 0x64, 5, 5, CLR_N_CHG_ZVC, cpu6812|cpu9s12x, 0 },
++ { "lsr", OP_D_IDX, 2, 0x64, 6, 6, CLR_N_CHG_ZVC, cpu6812|cpu9s12x, 0 },
++ { "lsr", OP_D_IDX_2, 4, 0x64, 6, 6, CLR_N_CHG_ZVC, cpu6812|cpu9s12x, 0 },
++
++ { "lsra", OP_NONE, 1, 0x44, 1, 1, CLR_N_CHG_ZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "lsrb", OP_NONE, 1, 0x54, 1, 1, CLR_N_CHG_ZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "lsrd", OP_NONE, 1, 0x04, 3, 3, CLR_N_CHG_ZVC, cpu6811, 0 },
++ { "lsrd", OP_NONE, 1, 0x49, 1, 1, CLR_N_CHG_ZVC, cpu6812|cpu9s12x, 0 },
++
++ { "lsrw", OP_IND16 | OP_PAGE2, 3, 0x74, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "lsrw", OP_IDX | OP_PAGE2, 2, 0x64, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "lsrw", OP_IDX_1 | OP_PAGE2, 3, 0x64, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "lsrw", OP_IDX_2 | OP_PAGE2, 4, 0x64, 5, 5, CHG_NZVC, cpu9s12x, 0 },
++ { "lsrw", OP_D_IDX | OP_PAGE2, 2, 0x64, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "lsrw", OP_D_IDX_2 | OP_PAGE2, 4, 0x64, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "lsrx", OP_NONE | OP_PAGE2, 1, 0x44, 1, 1, CHG_NZVC, cpu9s12x, 0 },
++
++ { "lsry", OP_NONE | OP_PAGE2, 1, 0x54, 1, 1, CHG_NZVC, cpu9s12x, 0 },
++
++ { "maxa", OP_IDX | OP_PAGE2, 3, 0x18, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "maxa", OP_IDX_1 | OP_PAGE2, 4, 0x18, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "maxa", OP_IDX_2 | OP_PAGE2, 5, 0x18, 5, 5, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "maxa", OP_D_IDX | OP_PAGE2, 3, 0x18, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "maxa", OP_D_IDX_2 | OP_PAGE2, 5, 0x18, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "maxm", OP_IDX | OP_PAGE2, 3, 0x1c, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "maxm", OP_IDX_1 | OP_PAGE2, 4, 0x1c, 5, 5, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "maxm", OP_IDX_2 | OP_PAGE2, 5, 0x1c, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "maxm", OP_D_IDX | OP_PAGE2, 3, 0x1c, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "maxm", OP_D_IDX_2 | OP_PAGE2, 5, 0x1c, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "mem", OP_NONE, 1, 0x01, 5, 5, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++
++ { "mina", OP_IDX | OP_PAGE2, 3, 0x19, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "mina", OP_IDX_1 | OP_PAGE2, 4, 0x19, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "mina", OP_IDX_2 | OP_PAGE2, 5, 0x19, 5, 5, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "mina", OP_D_IDX | OP_PAGE2, 3, 0x19, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "mina", OP_D_IDX_2 | OP_PAGE2, 5, 0x19, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "minm", OP_IDX | OP_PAGE2, 3, 0x1d, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "minm", OP_IDX_1 | OP_PAGE2, 4, 0x1d, 5, 5, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "minm", OP_IDX_2 | OP_PAGE2, 5, 0x1d, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "minm", OP_D_IDX | OP_PAGE2, 3, 0x1d, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "minm", OP_D_IDX_2 | OP_PAGE2, 5, 0x1d, 7, 7, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++/* FIXME S12X additional modes not implemented */
++ { "movb", OP_IMM8|OP_IND16_p2|OP_PAGE2, 5, 0x0b, 4, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "movb", OP_IMM8|OP_IDX_p2|OP_PAGE2, 4, 0x08, 4, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++// { "movb", OP_IMM8|OP_IDX1_p2|OP_PAGE2, 5, 0x08, 4, 4, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IMM8|OP_IDX2_p2|OP_PAGE2, 4, 0x08, 4, 4, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IMM8|OP_D_IDX_p2|OP_PAGE2, 5, 0x08, 4, 4, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IMM8|OP_D_IDX2_p2|OP_PAGE2, 4, 0x08, 4, 4, CHG_NONE, cpu9s12x, 0 },
++
++ { "movb", OP_IND16|OP_IND16_p2|OP_PAGE2, 6, 0x0c, 6, 6, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "movb", OP_IND16|OP_IDX_p2|OP_PAGE2, 5, 0x09, 5, 5, CHG_NONE, cpu6812|cpu9s12x, 0 },
++// { "movb", OP_IND16|OP_IDX1_p2|OP_PAGE2, 6, 0x09, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IND16|OP_IDX2_p2|OP_PAGE2, 5, 0x09, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IND16|OP_D_IDX_p2|OP_PAGE2, 6, 0x09, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IND16|OP_D_IDX2_p2|OP_PAGE2, 5, 0x09, 5, 5, CHG_NONE, cpu9s12x, 0 },
++
++ { "movb", OP_IDX|OP_IND16_p2|OP_PAGE2, 5, 0x0d, 5, 5, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "movb", OP_IDX|OP_IDX_p2|OP_PAGE2, 4, 0x0a, 5, 5, CHG_NONE, cpu6812|cpu9s12x, 0 },
++// { "movb", OP_IDX|OP_IDX1_p2|OP_PAGE2, 5, 0x0a, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IDX|OP_IDX2_p2|OP_PAGE2, 4, 0x0a, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IDX|OP_D_IDX_p2|OP_PAGE2, 5, 0x0d, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IDX|OP_D_IDX2_p2|OP_PAGE2, 4, 0x0a, 5, 5, CHG_NONE, cpu9s12x, 0 },
++
++// { "movb", OP_IDX_1|OP_IND16_p2|OP_PAGE2, 5, 0x0d, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IDX_1|OP_IDX_p2|OP_PAGE2, 4, 0x0a, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IDX_1|OP_IDX1_p2|OP_PAGE2, 6, 0x0a, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IDX_1|OP_IDX2_p2|OP_PAGE2, 5, 0x0a, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IDX_1|OP_D_IDX_p2|OP_PAGE2, 6, 0x0a, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IDX_1|OP_D_IDX2_p2|OP_PAGE2, 5, 0x0a, 5, 5, CHG_NONE, cpu9s12x, 0 },
++
++// { "movb", OP_IDX_2|OP_IND16_p2|OP_PAGE2, 5, 0x0d, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IDX_2|OP_IDX_p2|OP_PAGE2, 4, 0x0a, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IDX_2|OP_IDX1_p2|OP_PAGE2, 6, 0x0a, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IDX_2|OP_IDX2_p2|OP_PAGE2, 5, 0x0a, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IDX_2|OP_D_IDX_p2|OP_PAGE2, 6, 0x0a, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_IDX_2|OP_D_IDX2_p2|OP_PAGE2, 5, 0x0a, 5, 5, CHG_NONE, cpu9s12x, 0 },
++
++// { "movb", OP_D_IDX|OP_IND16_p2|OP_PAGE2, 5, 0x0d, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_D_IDX|OP_IDX_p2|OP_PAGE2, 4, 0x0a, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_D_IDX|OP_IDX1_p2|OP_PAGE2, 6, 0x0a, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_D_IDX|OP_IDX2_p2|OP_PAGE2, 5, 0x0a, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_D_IDX|OP_D_IDX_p2|OP_PAGE2, 6, 0x0a, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_D_IDX|OP_D_IDX2_p2|OP_PAGE2, 5, 0x0a, 5, 5, CHG_NONE, cpu9s12x, 0 },
++
++// { "movb", OP_D_IDX_2|OP_IND16_p2|OP_PAGE2, 5, 0x0d, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_D_IDX_2|OP_IDX_p2|OP_PAGE2, 4, 0x0a, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_D_IDX_2|OP_IDX1_p2|OP_PAGE2, 6, 0x0a, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_D_IDX_2|OP_IDX2_p2|OP_PAGE2, 5, 0x0a, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_D_IDX_2|OP_D_IDX_p2|OP_PAGE2, 6, 0x0a, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movb", OP_D_IDX_2|OP_D_IDX2_p2|OP_PAGE2, 5, 0x0a, 5, 5, CHG_NONE, cpu9s12x, 0 },
++
++/* FIXME S12X additional modes not implemented */
++ { "movw", OP_IMM16 | OP_IND16_p2 | OP_PAGE2, 6, 0x03, 5, 5, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "movw", OP_IMM16 | OP_IDX_p2 | OP_PAGE2, 5, 0x00, 4, 4, CHG_NONE, cpu6812|cpu9s12x, 0 },
++// { "movw", OP_IMM16|OP_IDX1_p2|OP_PAGE2, 5, 0x00, 4, 4, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IMM16|OP_IDX2_p2|OP_PAGE2, 4, 0x00, 4, 4, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IMM16|OP_D_IDX_p2|OP_PAGE2, 5, 0x00, 4, 4, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IMM16|OP_D_IDX2_p2|OP_PAGE2, 4, 0x00, 4, 4, CHG_NONE, cpu9s12x, 0 },
++
++ { "movw", OP_IND16 | OP_IND16_p2 | OP_PAGE2, 6, 0x04, 6, 6, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "movw", OP_IND16 | OP_IDX_p2 | OP_PAGE2, 5, 0x01, 5, 5, CHG_NONE, cpu6812|cpu9s12x, 0 },
++// { "movw", OP_IND16|OP_IDX1_p2|OP_PAGE2, 6, 0x01, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IND16|OP_IDX2_p2|OP_PAGE2, 5, 0x01, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IND16|OP_D_IDX_p2|OP_PAGE2, 6, 0x01, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IND16|OP_D_IDX2_p2|OP_PAGE2, 5, 0x01, 5, 5, CHG_NONE, cpu9s12x, 0 },
++
++ { "movw", OP_IDX | OP_IND16_p2 | OP_PAGE2, 5, 0x05, 5, 5, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "movw", OP_IDX | OP_IDX_p2 | OP_PAGE2, 4, 0x02, 5, 5, CHG_NONE, cpu6812|cpu9s12x, 0 },
++// { "movw", OP_IDX|OP_IDX1_p2|OP_PAGE2, 5, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IDX|OP_IDX2_p2|OP_PAGE2, 4, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IDX|OP_D_IDX_p2|OP_PAGE2, 5, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IDX|OP_D_IDX2_p2|OP_PAGE2, 4, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++
++// { "movw", OP_IDX_1|OP_IND16_p2|OP_PAGE2, 5, 0x05, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IDX_1|OP_IDX_p2|OP_PAGE2, 4, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IDX_1|OP_IDX1_p2|OP_PAGE2, 6, 0x02, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IDX_1|OP_IDX2_p2|OP_PAGE2, 5, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IDX_1|OP_D_IDX_p2|OP_PAGE2, 6, 0x02, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IDX_1|OP_D_IDX2_p2|OP_PAGE2, 5, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++
++// { "movw", OP_IDX_2|OP_IND16_p2|OP_PAGE2, 5, 0x05, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IDX_2|OP_IDX_p2|OP_PAGE2, 4, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IDX_2|OP_IDX1_p2|OP_PAGE2, 6, 0x02, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IDX_2|OP_IDX2_p2|OP_PAGE2, 5, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IDX_2|OP_D_IDX_p2|OP_PAGE2, 6, 0x02, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_IDX_2|OP_D_IDX2_p2|OP_PAGE2, 5, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++
++// { "movw", OP_D_IDX|OP_IND16_p2|OP_PAGE2, 5, 0x05, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_D_IDX|OP_IDX_p2|OP_PAGE2, 4, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_D_IDX|OP_IDX1_p2|OP_PAGE2, 6, 0x02, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_D_IDX|OP_IDX2_p2|OP_PAGE2, 5, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_D_IDX|OP_D_IDX_p2|OP_PAGE2, 6, 0x02, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_D_IDX|OP_D_IDX2_p2|OP_PAGE2, 5, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++
++// { "movw", OP_D_IDX_2|OP_IND16_p2|OP_PAGE2, 5, 0x05, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_D_IDX_2|OP_IDX_p2|OP_PAGE2, 4, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_D_IDX_2|OP_IDX1_p2|OP_PAGE2, 6, 0x02, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_D_IDX_2|OP_IDX2_p2|OP_PAGE2, 5, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_D_IDX_2|OP_D_IDX_p2|OP_PAGE2, 6, 0x02, 6, 6, CHG_NONE, cpu9s12x, 0 },
++// { "movw", OP_D_IDX_2|OP_D_IDX2_p2|OP_PAGE2, 5, 0x02, 5, 5, CHG_NONE, cpu9s12x, 0 },
++
++ { "mul", OP_NONE, 1, 0x3d, 3, 10, CHG_C, cpu6811, 0 },
++ { "mul", OP_NONE, 1, 0x12, 3, 3, CHG_C, cpu6812|cpu9s12x, 0 },
++
++ { "neg", OP_IND16, 3, 0x70, 4, 4, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "neg", OP_IX, 2, 0x60, 6, 6, CHG_NZVC, cpu6811, 0 },
++ { "neg", OP_IY | OP_PAGE2, 3, 0x60, 7, 7, CHG_NZVC, cpu6811, 0 },
++ { "neg", OP_IDX, 2, 0x60, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "neg", OP_IDX_1, 3, 0x60, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "neg", OP_IDX_2, 4, 0x60, 5, 5, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "neg", OP_D_IDX, 2, 0x60, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "neg", OP_D_IDX_2, 4, 0x60, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "nega", OP_NONE, 1, 0x40, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "negb", OP_NONE, 1, 0x50, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++
++ { "negw", OP_IND16| OP_PAGE2, 3, 0x70, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "negw", OP_IDX| OP_PAGE2, 2, 0x60, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "negw", OP_IDX_1| OP_PAGE2, 3, 0x60, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "negw", OP_IDX_2| OP_PAGE2, 4, 0x60, 5, 5, CHG_NZVC, cpu9s12x, 0 },
++ { "negw", OP_D_IDX| OP_PAGE2, 2, 0x60, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "negw", OP_D_IDX_2| OP_PAGE2, 4, 0x60, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "negx", OP_NONE| OP_PAGE2, 1, 0x40, 1, 1, CHG_NZVC, cpu9s12x, 0 },
++
++ { "negy", OP_NONE| OP_PAGE2, 1, 0x50, 1, 1, CHG_NZVC, cpu9s12x, 0 },
++
++ { "nop", OP_NONE, 1, 0x01, 2, 2, CHG_NONE, cpu6811, 0 },
++ { "nop", OP_NONE, 1, 0xa7, 1, 1, CHG_NONE, cpu6812|cpu9s12x, 0 },
++
++ { "oraa", OP_IMM8, 2, 0x8a, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "oraa", OP_DIRECT, 2, 0x9a, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "oraa", OP_IND16, 3, 0xba, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "oraa", OP_IX, 2, 0xaa, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "oraa", OP_IY | OP_PAGE2, 3, 0xaa, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "oraa", OP_IDX, 2, 0xaa, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "oraa", OP_IDX_1, 3, 0xaa, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "oraa", OP_IDX_2, 4, 0xaa, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "oraa", OP_D_IDX, 2, 0xaa, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "oraa", OP_D_IDX_2, 4, 0xaa, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "orab", OP_IMM8, 2, 0xca, 1, 1, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "orab", OP_DIRECT, 2, 0xda, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "orab", OP_IND16, 3, 0xfa, 3, 3, CLR_V_CHG_NZ, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "orab", OP_IX, 2, 0xea, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "orab", OP_IY | OP_PAGE2, 3, 0xea, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "orab", OP_IDX, 2, 0xea, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "orab", OP_IDX_1, 3, 0xea, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "orab", OP_IDX_2, 4, 0xea, 4, 4, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "orab", OP_D_IDX, 2, 0xea, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "orab", OP_D_IDX_2, 4, 0xea, 6, 6, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "orcc", OP_IMM8, 2, 0x14, 1, 1, CHG_ALL, cpu6812|cpu9s12x, 0 },
++
++ { "orx", OP_IMM16| OP_PAGE2, 2, 0x8a, 1, 1, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "orx", OP_DIRECT| OP_PAGE2, 2, 0x9a, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "orx", OP_IND16| OP_PAGE2, 3, 0xba, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "orx", OP_IDX| OP_PAGE2, 2, 0xaa, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "orx", OP_IDX_1| OP_PAGE2, 3, 0xaa, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "orx", OP_IDX_2| OP_PAGE2, 4, 0xaa, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "orx", OP_D_IDX| OP_PAGE2, 2, 0xaa, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "orx", OP_D_IDX_2| OP_PAGE2,4, 0xaa, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "ory", OP_IMM16| OP_PAGE2, 2, 0xca, 1, 1, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "ory", OP_DIRECT| OP_PAGE2, 2, 0xda, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "ory", OP_IND16| OP_PAGE2, 3, 0xfa, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "ory", OP_IDX| OP_PAGE2, 2, 0xea, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "ory", OP_IDX_1| OP_PAGE2, 3, 0xea, 3, 3, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "ory", OP_IDX_2| OP_PAGE2, 4, 0xea, 4, 4, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "ory", OP_D_IDX| OP_PAGE2, 2, 0xea, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++ { "ory", OP_D_IDX_2| OP_PAGE2,4, 0xea, 6, 6, CLR_V_CHG_NZ, cpu9s12x, 0 },
++
++ { "psha", OP_NONE, 1, 0x36, 2, 2, CHG_NONE, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "pshb", OP_NONE, 1, 0x37, 2, 2, CHG_NONE, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "pshc", OP_NONE, 1, 0x39, 2, 2, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "pshcw", OP_NONE| OP_PAGE2,1, 0x39, 2, 2, CHG_NONE, cpu9s12x, 0 },
++ { "pshd", OP_NONE, 1, 0x3b, 2, 2, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "pshx", OP_NONE, 1, 0x3c, 4, 4, CHG_NONE, cpu6811, 0 },
++ { "pshx", OP_NONE, 1, 0x34, 2, 2, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "pshy", OP_NONE | OP_PAGE2,2, 0x3c, 5, 5, CHG_NONE, cpu6811, 0 },
++ { "pshy", OP_NONE, 1, 0x35, 2, 2, CHG_NONE, cpu6812|cpu9s12x, 0 },
++
++
++ { "pula", OP_NONE, 1, 0x32, 3, 3, CHG_NONE, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "pulb", OP_NONE, 1, 0x33, 3, 3, CHG_NONE, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "pulc", OP_NONE, 1, 0x38, 3, 3, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "pulcw", OP_NONE| OP_PAGE2,1, 0x38, 2, 2, CHG_NONE, cpu9s12x, 0 },
++ { "puld", OP_NONE, 1, 0x3a, 3, 3, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "pulx", OP_NONE, 1, 0x38, 5, 5, CHG_NONE, cpu6811, 0 },
++ { "pulx", OP_NONE, 1, 0x30, 3, 3, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "puly", OP_NONE | OP_PAGE2,2, 0x38, 6, 6, CHG_NONE, cpu6811, 0 },
++ { "puly", OP_NONE, 1, 0x31, 3, 3, CHG_NONE, cpu6812|cpu9s12x, 0 },
++
++ { "rev", OP_NONE | OP_PAGE2, 2, 0x3a, _M, _M, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++ { "revw", OP_NONE | OP_PAGE2, 2, 0x3b, _M, _M, CHG_HNZVC, cpu6812|cpu9s12x, 0 },
++
++ { "rol", OP_IND16, 3, 0x79, 6, 6, CHG_NZVC, cpu6811, 0 },
++ { "rol", OP_IX, 2, 0x69, 6, 6, CHG_NZVC, cpu6811, 0 },
++ { "rol", OP_IY | OP_PAGE2, 3, 0x69, 7, 7, CHG_NZVC, cpu6811, 0 },
++ { "rol", OP_IND16, 3, 0x75, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "rol", OP_IDX, 2, 0x65, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "rol", OP_IDX_1, 3, 0x65, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "rol", OP_IDX_2, 4, 0x65, 5, 5, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "rol", OP_D_IDX, 2, 0x65, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "rol", OP_D_IDX_2, 4, 0x65, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "rola", OP_NONE, 1, 0x49, 2, 2, CHG_NZVC, cpu6811, 0 },
++ { "rola", OP_NONE, 1, 0x45, 1, 1, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "rolb", OP_NONE, 1, 0x59, 2, 2, CHG_NZVC, cpu6811, 0 },
++ { "rolb", OP_NONE, 1, 0x55, 1, 1, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "rolw", OP_IND16 | OP_PAGE2, 3, 0x75, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "rolw", OP_IDX | OP_PAGE2, 2, 0x65, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "rolw", OP_IDX_1 | OP_PAGE2, 3, 0x65, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "rolw", OP_IDX_2 | OP_PAGE2, 4, 0x65, 5, 5, CHG_NZVC, cpu9s12x, 0 },
++ { "rolw", OP_D_IDX | OP_PAGE2, 2, 0x65, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "rolw", OP_D_IDX_2 | OP_PAGE2, 4, 0x65, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "rolx", OP_NONE | OP_PAGE2, 1, 0x45, 1, 1, CHG_NZVC, cpu9s12x, 0 },
++ { "roly", OP_NONE | OP_PAGE2, 1, 0x55, 1, 1, CHG_NZVC, cpu9s12x, 0 },
++
++ { "ror", OP_IND16, 3, 0x76, 4, 4, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "ror", OP_IX, 2, 0x66, 6, 6, CHG_NZVC, cpu6811, 0 },
++ { "ror", OP_IY | OP_PAGE2, 3, 0x66, 7, 7, CHG_NZVC, cpu6811, 0 },
++ { "ror", OP_IDX, 2, 0x66, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "ror", OP_IDX_1, 3, 0x66, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "ror", OP_IDX_2, 4, 0x66, 5, 5, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "ror", OP_D_IDX, 2, 0x66, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "ror", OP_D_IDX_2, 4, 0x66, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "rora", OP_NONE, 1, 0x46, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "rorb", OP_NONE, 1, 0x56, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++
++ { "rorw", OP_IND16 | OP_PAGE2, 3, 0x76, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "rorw", OP_IDX | OP_PAGE2, 2, 0x66, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "rorw", OP_IDX_1 | OP_PAGE2, 3, 0x66, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "rorw", OP_IDX_2 | OP_PAGE2, 4, 0x66, 5, 5, CHG_NZVC, cpu9s12x, 0 },
++ { "rorw", OP_D_IDX | OP_PAGE2, 2, 0x66, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "rorw", OP_D_IDX_2 | OP_PAGE2, 4, 0x66, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "rorx", OP_NONE | OP_PAGE2, 1, 0x46, 1, 1, CHG_NZVC, cpu9s12x, 0 },
++ { "rorx", OP_NONE | OP_PAGE2, 1, 0x56, 1, 1, CHG_NZVC, cpu9s12x, 0 },
++
++ { "rtc", OP_NONE, 1, 0x0a, 6, 6, CHG_NONE, cpu6812|cpu9s12x, 0 },
++ { "rti", OP_NONE, 1, 0x3b, 12, 12, CHG_ALL, cpu6811, 0 },
++ { "rti", OP_NONE, 1, 0x0b, 8, 10, CHG_ALL, cpu6812|cpu9s12x, 0 },
++ { "rts", OP_NONE, 1, 0x39, 5, 5, CHG_NONE, cpu6811, 0 },
++ { "rts", OP_NONE, 1, 0x3d, 5, 5, CHG_NONE, cpu6812|cpu9s12x, 0 },
++
++ { "sba", OP_NONE, 1, 0x10, 2, 2, CHG_NZVC, cpu6811, 0 },
++ { "sba", OP_NONE | OP_PAGE2, 2, 0x16, 2, 2, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "sbca", OP_IMM8, 2, 0x82, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "sbca", OP_DIRECT, 2, 0x92, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "sbca", OP_IND16, 3, 0xb2, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "sbca", OP_IX, 2, 0xa2, 4, 4, CHG_NZVC, cpu6811, 0 },
++ { "sbca", OP_IY | OP_PAGE2, 3, 0xa2, 5, 5, CHG_NZVC, cpu6811, 0 },
++ { "sbca", OP_IDX, 2, 0xa2, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "sbca", OP_IDX_1, 3, 0xa2, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "sbca", OP_IDX_2, 4, 0xa2, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "sbca", OP_D_IDX, 2, 0xa2, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "sbca", OP_D_IDX_2, 4, 0xa2, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "sbcb", OP_IMM8, 2, 0xc2, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "sbcb", OP_DIRECT, 2, 0xd2, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "sbcb", OP_IND16, 3, 0xf2, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "sbcb", OP_IX, 2, 0xe2, 4, 4, CHG_NZVC, cpu6811, 0 },
++ { "sbcb", OP_IY | OP_PAGE2, 3, 0xe2, 5, 5, CHG_NZVC, cpu6811, 0 },
++ { "sbcb", OP_IDX, 2, 0xe2, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "sbcb", OP_IDX_1, 3, 0xe2, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "sbcb", OP_IDX_2, 4, 0xe2, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "sbcb", OP_D_IDX, 2, 0xe2, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "sbcb", OP_D_IDX_2, 4, 0xe2, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "sbed", OP_IMM16 | OP_PAGE2, 3, 0x83, 2, 2, CHG_NZVC, cpu9s12x, 0 },
++ { "sbed", OP_DIRECT | OP_PAGE2, 2, 0x93, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "sbed", OP_IND16 | OP_PAGE2, 3, 0xb3, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "sbed", OP_IDX | OP_PAGE2, 2, 0xa3, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "sbed", OP_IDX_1 | OP_PAGE2, 3, 0xa3, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "sbed", OP_IDX_2 | OP_PAGE2, 4, 0xa3, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "sbed", OP_D_IDX | OP_PAGE2, 2, 0xa3, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "sbed", OP_D_IDX_2 | OP_PAGE2, 4, 0xa3, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "sbex", OP_IMM16 | OP_PAGE2, 3, 0x82, 2, 2, CHG_NZVC, cpu9s12x, 0 },
++ { "sbex", OP_DIRECT | OP_PAGE2, 2, 0x92, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "sbex", OP_IND16 | OP_PAGE2, 3, 0xb2, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "sbex", OP_IDX | OP_PAGE2, 2, 0xa2, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "sbex", OP_IDX_1 | OP_PAGE2, 3, 0xa2, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "sbex", OP_IDX_2 | OP_PAGE2, 4, 0xa2, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "sbex", OP_D_IDX | OP_PAGE2, 2, 0xa2, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "sbex", OP_D_IDX_2 | OP_PAGE2, 4, 0xa2, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "sbey", OP_IMM16 | OP_PAGE2, 3, 0xc2, 2, 2, CHG_NZVC, cpu9s12x, 0 },
++ { "sbey", OP_DIRECT | OP_PAGE2, 2, 0xd2, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "sbey", OP_IND16 | OP_PAGE2, 3, 0xf2, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "sbey", OP_IDX | OP_PAGE2, 2, 0xe2, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "sbey", OP_IDX_1 | OP_PAGE2, 3, 0xe2, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "sbey", OP_IDX_2 | OP_PAGE2, 4, 0xe2, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "sbey", OP_D_IDX | OP_PAGE2, 2, 0xe2, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "sbey", OP_D_IDX_2 | OP_PAGE2, 4, 0xe2, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "sec", OP_NONE, 1, 0x0d, 2, 2, SET_C, cpu6811, 0 },
++ { "sei", OP_NONE, 1, 0x0f, 2, 2, SET_I, cpu6811, 0 },
++ { "sev", OP_NONE, 1, 0x0b, 2, 2, SET_V, cpu6811, 0 },
+
++/* FIXME S12X has more sex */
+ { "sex", M6812_OP_SEX_MARKER
+- | OP_REG | OP_REG_2, 2, 0xb7, 1, 1, CHG_NONE, cpu6812 },
++ | OP_REG | OP_REG_2, 2, 0xb7, 1, 1, CHG_NONE, cpu6812|cpu9s12x, 0 },
+
+- { "staa", OP_IND16, 3, 0xb7, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "staa", OP_DIRECT, 2, 0x97, 3, 3, CLR_V_CHG_NZ, cpu6811 },
+- { "staa", OP_IX, 2, 0xa7, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "staa", OP_IY | OP_PAGE2, 3, 0xa7, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "staa", OP_DIRECT, 2, 0x5a, 2, 2, CLR_V_CHG_NZ, cpu6812 },
+- { "staa", OP_IND16, 3, 0x7a, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "staa", OP_IDX, 2, 0x6a, 2, 2, CLR_V_CHG_NZ, cpu6812 },
+- { "staa", OP_IDX_1, 3, 0x6a, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "staa", OP_IDX_2, 4, 0x6a, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "staa", OP_D_IDX, 2, 0x6a, 5, 5, CLR_V_CHG_NZ, cpu6812 },
+- { "staa", OP_D_IDX_2, 4, 0x6a, 5, 5, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "stab", OP_IND16, 3, 0xf7, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "stab", OP_DIRECT, 2, 0xd7, 3, 3, CLR_V_CHG_NZ, cpu6811 },
+- { "stab", OP_IX, 2, 0xe7, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "stab", OP_IY | OP_PAGE2, 3, 0xe7, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "stab", OP_DIRECT, 2, 0x5b, 2, 2, CLR_V_CHG_NZ, cpu6812 },
+- { "stab", OP_IND16, 3, 0x7b, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "stab", OP_IDX, 2, 0x6b, 2, 2, CLR_V_CHG_NZ, cpu6812 },
+- { "stab", OP_IDX_1, 3, 0x6b, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "stab", OP_IDX_2, 4, 0x6b, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "stab", OP_D_IDX, 2, 0x6b, 5, 5, CLR_V_CHG_NZ, cpu6812 },
+- { "stab", OP_D_IDX_2, 4, 0x6b, 5, 5, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "std", OP_IND16, 3, 0xfd, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "std", OP_DIRECT, 2, 0xdd, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "std", OP_IX, 2, 0xed, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "std", OP_IY | OP_PAGE2, 3, 0xed, 6, 6, CLR_V_CHG_NZ, cpu6811 },
+- { "std", OP_DIRECT, 2, 0x5c, 2, 2, CLR_V_CHG_NZ, cpu6812 },
+- { "std", OP_IND16, 3, 0x7c, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "std", OP_IDX, 2, 0x6c, 2, 2, CLR_V_CHG_NZ, cpu6812 },
+- { "std", OP_IDX_1, 3, 0x6c, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "std", OP_IDX_2, 4, 0x6c, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "std", OP_D_IDX, 2, 0x6c, 5, 5, CLR_V_CHG_NZ, cpu6812 },
+- { "std", OP_D_IDX_2, 4, 0x6c, 5, 5, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "stop", OP_NONE, 1, 0xcf, 2, 2, CHG_NONE, cpu6811 },
+- { "stop", OP_NONE | OP_PAGE2,2, 0x3e, 2, 9, CHG_NONE, cpu6812 },
+-
+- { "sts", OP_IND16, 3, 0xbf, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "sts", OP_DIRECT, 2, 0x9f, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "sts", OP_IX, 2, 0xaf, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "sts", OP_IY | OP_PAGE2, 3, 0xaf, 6, 6, CLR_V_CHG_NZ, cpu6811 },
+- { "sts", OP_DIRECT, 2, 0x5f, 2, 2, CLR_V_CHG_NZ, cpu6812 },
+- { "sts", OP_IND16, 3, 0x7f, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "sts", OP_IDX, 2, 0x6f, 2, 2, CLR_V_CHG_NZ, cpu6812 },
+- { "sts", OP_IDX_1, 3, 0x6f, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "sts", OP_IDX_2, 4, 0x6f, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "sts", OP_D_IDX, 2, 0x6f, 5, 5, CLR_V_CHG_NZ, cpu6812 },
+- { "sts", OP_D_IDX_2, 4, 0x6f, 5, 5, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "stx", OP_IND16, 3, 0xff, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "stx", OP_DIRECT, 2, 0xdf, 4, 4, CLR_V_CHG_NZ, cpu6811 },
+- { "stx", OP_IX, 2, 0xef, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "stx", OP_IY | OP_PAGE4, 3, 0xef, 6, 6, CLR_V_CHG_NZ, cpu6811 },
+- { "stx", OP_DIRECT, 2, 0x5e, 2, 2, CLR_V_CHG_NZ, cpu6812 },
+- { "stx", OP_IND16, 3, 0x7e, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "stx", OP_IDX, 2, 0x6e, 2, 2, CLR_V_CHG_NZ, cpu6812 },
+- { "stx", OP_IDX_1, 3, 0x6e, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "stx", OP_IDX_2, 4, 0x6e, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "stx", OP_D_IDX, 2, 0x6e, 5, 5, CLR_V_CHG_NZ, cpu6812 },
+- { "stx", OP_D_IDX_2, 4, 0x6e, 5, 5, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "sty", OP_IND16 | OP_PAGE2, 4, 0xff, 6, 6, CLR_V_CHG_NZ, cpu6811 },
+- { "sty", OP_DIRECT | OP_PAGE2, 3, 0xdf, 5, 5, CLR_V_CHG_NZ, cpu6811 },
+- { "sty", OP_IY | OP_PAGE2, 3, 0xef, 6, 6, CLR_V_CHG_NZ, cpu6811 },
+- { "sty", OP_IX | OP_PAGE3, 3, 0xef, 6, 6, CLR_V_CHG_NZ, cpu6811 },
+- { "sty", OP_DIRECT, 2, 0x5d, 2, 2, CLR_V_CHG_NZ, cpu6812 },
+- { "sty", OP_IND16, 3, 0x7d, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "sty", OP_IDX, 2, 0x6d, 2, 2, CLR_V_CHG_NZ, cpu6812 },
+- { "sty", OP_IDX_1, 3, 0x6d, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "sty", OP_IDX_2, 4, 0x6d, 3, 3, CLR_V_CHG_NZ, cpu6812 },
+- { "sty", OP_D_IDX, 2, 0x6d, 5, 5, CLR_V_CHG_NZ, cpu6812 },
+- { "sty", OP_D_IDX_2, 4, 0x6d, 5, 5, CLR_V_CHG_NZ, cpu6812 },
+-
+- { "suba", OP_IMM8, 2, 0x80, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+- { "suba", OP_DIRECT, 2, 0x90, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "suba", OP_IND16, 3, 0xb0, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "suba", OP_IX, 2, 0xa0, 4, 4, CHG_NZVC, cpu6811 },
+- { "suba", OP_IY | OP_PAGE2, 3, 0xa0, 5, 5, CHG_NZVC, cpu6811 },
+- { "suba", OP_IDX, 2, 0xa0, 3, 3, CHG_NZVC, cpu6812 },
+- { "suba", OP_IDX_1, 3, 0xa0, 3, 3, CHG_NZVC, cpu6812 },
+- { "suba", OP_IDX_2, 4, 0xa0, 4, 4, CHG_NZVC, cpu6812 },
+- { "suba", OP_D_IDX, 2, 0xa0, 6, 6, CHG_NZVC, cpu6812 },
+- { "suba", OP_D_IDX_2, 4, 0xa0, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "subb", OP_IMM8, 2, 0xc0, 1, 1, CHG_NZVC, cpu6811|cpu6812 },
+- { "subb", OP_DIRECT, 2, 0xd0, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "subb", OP_IND16, 3, 0xf0, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "subb", OP_IX, 2, 0xe0, 4, 4, CHG_NZVC, cpu6811 },
+- { "subb", OP_IY | OP_PAGE2, 3, 0xe0, 5, 5, CHG_NZVC, cpu6811 },
+- { "subb", OP_IDX, 2, 0xe0, 3, 3, CHG_NZVC, cpu6812 },
+- { "subb", OP_IDX_1, 3, 0xe0, 3, 3, CHG_NZVC, cpu6812 },
+- { "subb", OP_IDX_2, 4, 0xe0, 4, 4, CHG_NZVC, cpu6812 },
+- { "subb", OP_D_IDX, 2, 0xe0, 6, 6, CHG_NZVC, cpu6812 },
+- { "subb", OP_D_IDX_2, 4, 0xe0, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "subd", OP_IMM16, 3, 0x83, 2, 2, CHG_NZVC, cpu6811|cpu6812 },
+- { "subd", OP_DIRECT, 2, 0x93, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "subd", OP_IND16, 3, 0xb3, 3, 3, CHG_NZVC, cpu6811|cpu6812 },
+- { "subd", OP_IX, 2, 0xa3, 6, 6, CHG_NZVC, cpu6811 },
+- { "subd", OP_IY | OP_PAGE2, 3, 0xa3, 7, 7, CHG_NZVC, cpu6811 },
+- { "subd", OP_IDX, 2, 0xa3, 3, 3, CHG_NZVC, cpu6812 },
+- { "subd", OP_IDX_1, 3, 0xa3, 3, 3, CHG_NZVC, cpu6812 },
+- { "subd", OP_IDX_2, 4, 0xa3, 4, 4, CHG_NZVC, cpu6812 },
+- { "subd", OP_D_IDX, 2, 0xa3, 6, 6, CHG_NZVC, cpu6812 },
+- { "subd", OP_D_IDX_2, 4, 0xa3, 6, 6, CHG_NZVC, cpu6812 },
+-
+- { "swi", OP_NONE, 1, 0x3f, 9, 9, CHG_NONE, cpu6811|cpu6812 },
+-
+- { "tab", OP_NONE, 1, 0x16, 2, 2, CLR_V_CHG_NZ, cpu6811 },
+- { "tab", OP_NONE | OP_PAGE2,2, 0x0e, 2, 2, CLR_V_CHG_NZ, cpu6812 },
++ { "staa", OP_IND16, 3, 0xb7, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "staa", OP_DIRECT, 2, 0x97, 3, 3, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "staa", OP_IX, 2, 0xa7, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "staa", OP_IY | OP_PAGE2, 3, 0xa7, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "staa", OP_DIRECT, 2, 0x5a, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "staa", OP_IND16, 3, 0x7a, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "staa", OP_IDX, 2, 0x6a, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "staa", OP_IDX_1, 3, 0x6a, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "staa", OP_IDX_2, 4, 0x6a, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "staa", OP_D_IDX, 2, 0x6a, 5, 5, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "staa", OP_D_IDX_2, 4, 0x6a, 5, 5, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "stab", OP_IND16, 3, 0xf7, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "stab", OP_DIRECT, 2, 0xd7, 3, 3, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "stab", OP_IX, 2, 0xe7, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "stab", OP_IY | OP_PAGE2, 3, 0xe7, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "stab", OP_DIRECT, 2, 0x5b, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "stab", OP_IND16, 3, 0x7b, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "stab", OP_IDX, 2, 0x6b, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "stab", OP_IDX_1, 3, 0x6b, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "stab", OP_IDX_2, 4, 0x6b, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "stab", OP_D_IDX, 2, 0x6b, 5, 5, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "stab", OP_D_IDX_2, 4, 0x6b, 5, 5, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "std", OP_IND16, 3, 0xfd, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "std", OP_DIRECT, 2, 0xdd, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "std", OP_IX, 2, 0xed, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "std", OP_IY | OP_PAGE2, 3, 0xed, 6, 6, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "std", OP_DIRECT, 2, 0x5c, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "std", OP_IND16, 3, 0x7c, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "std", OP_IDX, 2, 0x6c, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "std", OP_IDX_1, 3, 0x6c, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "std", OP_IDX_2, 4, 0x6c, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "std", OP_D_IDX, 2, 0x6c, 5, 5, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "std", OP_D_IDX_2, 4, 0x6c, 5, 5, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "stop", OP_NONE, 1, 0xcf, 2, 2, CHG_NONE, cpu6811, 0 },
++ { "stop", OP_NONE | OP_PAGE2,2, 0x3e, 2, 9, CHG_NONE, cpu6812|cpu9s12x, 0 },
++
++ { "sts", OP_IND16, 3, 0xbf, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "sts", OP_DIRECT, 2, 0x9f, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "sts", OP_IX, 2, 0xaf, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "sts", OP_IY | OP_PAGE2, 3, 0xaf, 6, 6, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "sts", OP_DIRECT, 2, 0x5f, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "sts", OP_IND16, 3, 0x7f, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "sts", OP_IDX, 2, 0x6f, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "sts", OP_IDX_1, 3, 0x6f, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "sts", OP_IDX_2, 4, 0x6f, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "sts", OP_D_IDX, 2, 0x6f, 5, 5, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "sts", OP_D_IDX_2, 4, 0x6f, 5, 5, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "stx", OP_IND16, 3, 0xff, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "stx", OP_DIRECT, 2, 0xdf, 4, 4, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "stx", OP_IX, 2, 0xef, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "stx", OP_IY | OP_PAGE4, 3, 0xef, 6, 6, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "stx", OP_DIRECT, 2, 0x5e, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "stx", OP_IND16, 3, 0x7e, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "stx", OP_IDX, 2, 0x6e, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "stx", OP_IDX_1, 3, 0x6e, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "stx", OP_IDX_2, 4, 0x6e, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "stx", OP_D_IDX, 2, 0x6e, 5, 5, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "stx", OP_D_IDX_2, 4, 0x6e, 5, 5, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "sty", OP_IND16 | OP_PAGE2, 4, 0xff, 6, 6, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "sty", OP_DIRECT | OP_PAGE2, 3, 0xdf, 5, 5, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "sty", OP_IY | OP_PAGE2, 3, 0xef, 6, 6, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "sty", OP_IX | OP_PAGE3, 3, 0xef, 6, 6, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "sty", OP_DIRECT, 2, 0x5d, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "sty", OP_IND16, 3, 0x7d, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "sty", OP_IDX, 2, 0x6d, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "sty", OP_IDX_1, 3, 0x6d, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "sty", OP_IDX_2, 4, 0x6d, 3, 3, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "sty", OP_D_IDX, 2, 0x6d, 5, 5, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "sty", OP_D_IDX_2, 4, 0x6d, 5, 5, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "suba", OP_IMM8, 2, 0x80, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "suba", OP_DIRECT, 2, 0x90, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "suba", OP_IND16, 3, 0xb0, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "suba", OP_IX, 2, 0xa0, 4, 4, CHG_NZVC, cpu6811, 0 },
++ { "suba", OP_IY | OP_PAGE2, 3, 0xa0, 5, 5, CHG_NZVC, cpu6811, 0 },
++ { "suba", OP_IDX, 2, 0xa0, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "suba", OP_IDX_1, 3, 0xa0, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "suba", OP_IDX_2, 4, 0xa0, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "suba", OP_D_IDX, 2, 0xa0, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "suba", OP_D_IDX_2, 4, 0xa0, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "subb", OP_IMM8, 2, 0xc0, 1, 1, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "subb", OP_DIRECT, 2, 0xd0, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "subb", OP_IND16, 3, 0xf0, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "subb", OP_IX, 2, 0xe0, 4, 4, CHG_NZVC, cpu6811, 0 },
++ { "subb", OP_IY | OP_PAGE2, 3, 0xe0, 5, 5, CHG_NZVC, cpu6811, 0 },
++ { "subb", OP_IDX, 2, 0xe0, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "subb", OP_IDX_1, 3, 0xe0, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "subb", OP_IDX_2, 4, 0xe0, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "subb", OP_D_IDX, 2, 0xe0, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "subb", OP_D_IDX_2, 4, 0xe0, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "subd", OP_IMM16, 3, 0x83, 2, 2, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "subd", OP_DIRECT, 2, 0x93, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "subd", OP_IND16, 3, 0xb3, 3, 3, CHG_NZVC, cpu6811|cpu6812|cpu9s12x, 0 },
++ { "subd", OP_IX, 2, 0xa3, 6, 6, CHG_NZVC, cpu6811, 0 },
++ { "subd", OP_IY | OP_PAGE2, 3, 0xa3, 7, 7, CHG_NZVC, cpu6811, 0 },
++ { "subd", OP_IDX, 2, 0xa3, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "subd", OP_IDX_1, 3, 0xa3, 3, 3, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "subd", OP_IDX_2, 4, 0xa3, 4, 4, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "subd", OP_D_IDX, 2, 0xa3, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++ { "subd", OP_D_IDX_2, 4, 0xa3, 6, 6, CHG_NZVC, cpu6812|cpu9s12x, 0 },
++
++ { "subx", OP_IMM16 | OP_PAGE2, 3, 0x80, 2, 2, CHG_NZVC, cpu9s12x, 0 },
++ { "subx", OP_DIRECT | OP_PAGE2, 2, 0x90, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "subx", OP_IND16 | OP_PAGE2, 3, 0xb0, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "subx", OP_IDX | OP_PAGE2, 2, 0xa0, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "subx", OP_IDX_1 | OP_PAGE2, 3, 0xa0, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "subx", OP_IDX_2 | OP_PAGE2, 4, 0xa0, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "subx", OP_D_IDX | OP_PAGE2, 2, 0xa0, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "subx", OP_D_IDX_2 | OP_PAGE2, 4, 0xa0, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "suby", OP_IMM16 | OP_PAGE2, 3, 0xc0, 2, 2, CHG_NZVC, cpu9s12x, 0 },
++ { "suby", OP_DIRECT | OP_PAGE2, 2, 0xd0, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "suby", OP_IND16 | OP_PAGE2, 3, 0xf0, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "suby", OP_IDX | OP_PAGE2, 2, 0xe0, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "suby", OP_IDX_1 | OP_PAGE2, 3, 0xe0, 3, 3, CHG_NZVC, cpu9s12x, 0 },
++ { "suby", OP_IDX_2 | OP_PAGE2, 4, 0xe0, 4, 4, CHG_NZVC, cpu9s12x, 0 },
++ { "suby", OP_D_IDX | OP_PAGE2, 2, 0xe0, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++ { "suby", OP_D_IDX_2 | OP_PAGE2, 4, 0xe0, 6, 6, CHG_NZVC, cpu9s12x, 0 },
++
++ { "swi", OP_NONE, 1, 0x3f, 9, 9, CHG_NONE, cpu6811|cpu6812|cpu9s12x, 0 },
++
++ { "tab", OP_NONE, 1, 0x16, 2, 2, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "tab", OP_NONE | OP_PAGE2,2, 0x0e, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
+
+- { "tap", OP_NONE, 1, 0x06, 2, 2, CHG_ALL, cpu6811 },
++ { "tap", OP_NONE, 1, 0x06, 2, 2, CHG_ALL, cpu6811, 0 },
+
+- { "tba", OP_NONE, 1, 0x17, 2, 2, CLR_V_CHG_NZ, cpu6811 },
+- { "tba", OP_NONE | OP_PAGE2,2, 0x0f, 2, 2, CLR_V_CHG_NZ, cpu6812 },
++ { "tba", OP_NONE, 1, 0x17, 2, 2, CLR_V_CHG_NZ, cpu6811, 0 },
++ { "tba", OP_NONE | OP_PAGE2,2, 0x0f, 2, 2, CLR_V_CHG_NZ, cpu6812|cpu9s12x, 0 },
+
+- { "test", OP_NONE, 1, 0x00, 5, _M, CHG_NONE, cpu6811 },
++ { "test", OP_NONE, 1, 0x00, 5, _M, CHG_NONE, cpu6811, 0 },
+
+- { "tpa", OP_NONE, 1, 0x07, 2, 2, CHG_NONE, cpu6811 },
++ { "tpa", OP_NONE, 1, 0x07, 2, 2, CHG_NONE, cpu6811, 0 },
+
+ { "tbeq", OP_TBEQ_MARKER
+- | OP_REG | OP_JUMP_REL, 3, 0x04, 3, 3, CHG_NONE, cpu6812 },
++ | OP_REG | OP_JUMP_REL, 3, 0x04, 3, 3, CHG_NONE, cpu6812|cpu9s12x, 0 },
+
+- { "tbl", OP_IDX | OP_PAGE2, 3, 0x3d, 8, 8, CHG_NZC, cpu6812 },
++ { "tbl", OP_IDX | OP_PAGE2, 3, 0x3d, 8, 8, CHG_NZC, cpu6812|cpu9s12x, 0 },
+
+ { "tbne", OP_TBNE_MARKER
+- | OP_REG | OP_JUMP_REL, 3, 0x04, 3, 3, CHG_NONE, cpu6812 },
++ | OP_REG | OP_JUMP_REL, 3, 0x04, 3, 3, CHG_NONE, cpu6812|cpu9s12x, 0 },
+
++/* FIXME S12X has more options */
+ { "tfr", OP_TFR_MARKER
+- | OP_REG_1 | OP_REG_2, 2, 0xb7, 1, 1, CHG_NONE, cpu6812 },
+-
+- { "trap", OP_IMM8 | OP_TRAP_ID, 2, 0x18, 11, 11, SET_I, cpu6812 },
+-
+- { "tst", OP_IND16, 3, 0x7d, 6, 6, CLR_VC_CHG_NZ, cpu6811 },
+- { "tst", OP_IX, 2, 0x6d, 6, 6, CLR_VC_CHG_NZ, cpu6811 },
+- { "tst", OP_IY | OP_PAGE2, 3, 0x6d, 7, 7, CLR_VC_CHG_NZ, cpu6811 },
+- { "tst", OP_IND16, 3, 0xf7, 3, 3, CLR_VC_CHG_NZ, cpu6812 },
+- { "tst", OP_IDX, 2, 0xe7, 3, 3, CLR_VC_CHG_NZ, cpu6812 },
+- { "tst", OP_IDX_1, 3, 0xe7, 3, 3, CLR_VC_CHG_NZ, cpu6812 },
+- { "tst", OP_IDX_2, 4, 0xe7, 4, 4, CLR_VC_CHG_NZ, cpu6812 },
+- { "tst", OP_D_IDX, 2, 0xe7, 6, 6, CLR_VC_CHG_NZ, cpu6812 },
+- { "tst", OP_D_IDX_2, 4, 0xe7, 6, 6, CLR_VC_CHG_NZ, cpu6812 },
+-
+- { "tsta", OP_NONE, 1, 0x4d, 2, 2, CLR_VC_CHG_NZ, cpu6811 },
+- { "tsta", OP_NONE, 1, 0x97, 1, 1, CLR_VC_CHG_NZ, cpu6812 },
+- { "tstb", OP_NONE, 1, 0x5d, 2, 2, CLR_VC_CHG_NZ, cpu6811 },
+- { "tstb", OP_NONE, 1, 0xd7, 1, 1, CLR_VC_CHG_NZ, cpu6812 },
+-
+- { "tsx", OP_NONE, 1, 0x30, 3, 3, CHG_NONE, cpu6811 },
+- { "tsy", OP_NONE | OP_PAGE2,2, 0x30, 4, 4, CHG_NONE, cpu6811 },
+- { "txs", OP_NONE, 1, 0x35, 3, 3, CHG_NONE, cpu6811 },
+- { "tys", OP_NONE | OP_PAGE2,2, 0x35, 4, 4, CHG_NONE, cpu6811 },
++ | OP_REG_1 | OP_REG_2, 2, 0xb7, 1, 1, CHG_NONE, cpu6812|cpu9s12x, 0 },
+
+- { "wai", OP_NONE, 1, 0x3e, 5, _M, CHG_NONE, cpu6811|cpu6812 },
++ { "trap", OP_IMM8 | OP_TRAP_ID, 2, 0x18, 11, 11, SET_I, cpu6812|cpu9s12x, 0 },
+
+- { "wav", OP_NONE | OP_PAGE2, 2, 0x3c, 8, _M, SET_Z_CHG_HNVC, cpu6812 },
+-
+- { "xgdx", OP_NONE, 1, 0x8f, 3, 3, CHG_NONE, cpu6811 },
+- { "xgdy", OP_NONE | OP_PAGE2,2, 0x8f, 4, 4, CHG_NONE, cpu6811 }
++ { "tst", OP_IND16, 3, 0x7d, 6, 6, CLR_VC_CHG_NZ, cpu6811, 0 },
++ { "tst", OP_IX, 2, 0x6d, 6, 6, CLR_VC_CHG_NZ, cpu6811, 0 },
++ { "tst", OP_IY | OP_PAGE2, 3, 0x6d, 7, 7, CLR_VC_CHG_NZ, cpu6811, 0 },
++ { "tst", OP_IND16, 3, 0xf7, 3, 3, CLR_VC_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "tst", OP_IDX, 2, 0xe7, 3, 3, CLR_VC_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "tst", OP_IDX_1, 3, 0xe7, 3, 3, CLR_VC_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "tst", OP_IDX_2, 4, 0xe7, 4, 4, CLR_VC_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "tst", OP_D_IDX, 2, 0xe7, 6, 6, CLR_VC_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "tst", OP_D_IDX_2, 4, 0xe7, 6, 6, CLR_VC_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "tsta", OP_NONE, 1, 0x4d, 2, 2, CLR_VC_CHG_NZ, cpu6811, 0 },
++ { "tsta", OP_NONE, 1, 0x97, 1, 1, CLR_VC_CHG_NZ, cpu6812|cpu9s12x, 0 },
++ { "tstb", OP_NONE, 1, 0x5d, 2, 2, CLR_VC_CHG_NZ, cpu6811, 0 },
++ { "tstb", OP_NONE, 1, 0xd7, 1, 1, CLR_VC_CHG_NZ, cpu6812|cpu9s12x, 0 },
++
++ { "tstw", OP_IND16| OP_PAGE2, 3, 0xf7, 3, 3, CLR_VC_CHG_NZ, cpu9s12x, 0 },
++ { "tstw", OP_IDX| OP_PAGE2, 2, 0xe7, 3, 3, CLR_VC_CHG_NZ, cpu9s12x, 0 },
++ { "tstw", OP_IDX_1| OP_PAGE2, 3, 0xe7, 3, 3, CLR_VC_CHG_NZ, cpu9s12x, 0 },
++ { "tstw", OP_IDX_2| OP_PAGE2, 4, 0xe7, 4, 4, CLR_VC_CHG_NZ, cpu9s12x, 0 },
++ { "tstw", OP_D_IDX| OP_PAGE2, 2, 0xe7, 6, 6, CLR_VC_CHG_NZ, cpu9s12x, 0 },
++ { "tstw", OP_D_IDX_2| OP_PAGE2, 4, 0xe7, 6, 6, CLR_VC_CHG_NZ, cpu9s12x, 0 },
++
++ { "tstx", OP_NONE| OP_PAGE2, 1, 0x97, 1, 1, CLR_VC_CHG_NZ, cpu9s12x, 0 },
++ { "tsty", OP_NONE| OP_PAGE2, 1, 0xd7, 1, 1, CLR_VC_CHG_NZ, cpu9s12x, 0 },
++
++ { "tsx", OP_NONE, 1, 0x30, 3, 3, CHG_NONE, cpu6811, 0 },
++ { "tsy", OP_NONE | OP_PAGE2,2, 0x30, 4, 4, CHG_NONE, cpu6811, 0 },
++ { "txs", OP_NONE, 1, 0x35, 3, 3, CHG_NONE, cpu6811, 0 },
++ { "tys", OP_NONE | OP_PAGE2,2, 0x35, 4, 4, CHG_NONE, cpu6811, 0 },
++
++ { "wai", OP_NONE, 1, 0x3e, 5, _M, CHG_NONE, cpu6811|cpu6812|cpu9s12x, 0 },
++
++ { "wav", OP_NONE | OP_PAGE2, 2, 0x3c, 8, _M, SET_Z_CHG_HNVC, cpu6812|cpu9s12x, 0 },
++
++ { "xgdx", OP_NONE, 1, 0x8f, 3, 3, CHG_NONE, cpu6811, 0 },
++ { "xgdy", OP_NONE | OP_PAGE2,2, 0x8f, 4, 4, CHG_NONE, cpu6811, 0 },
++
++/* XGATE opcodes */
++//Return to Scheduler and Others
++ { "brk", M68XG_OP_NONE, 2, 0x0000, 0, 0, 0, 0, 0, cpuxgate, 0xffff },
++ { "nop", M68XG_OP_NONE, 2, 0x0100, 0, 0, 0, 0, 0, cpuxgate, 0xffff },
++ { "rts", M68XG_OP_NONE, 2, 0x0200, 0, 0, 0, 0, 0, cpuxgate, 0xffff },
++ { "sif", M68XG_OP_NONE, 2, 0x0300, 0, 0, 0, 0, 0, cpuxgate, 0xffff },
++// Semaphore Instructions
++ { "csem", M68XG_OP_IMM3, 2, 0x00f0, 0, 0, 0, 0, 0, cpuxgate, 0xf8ff },
++ { "csem", M68XG_OP_R, 2, 0x00f1, 0, 0, 0, 0, 0, cpuxgate, 0xf8ff },
++ { "ssem", M68XG_OP_IMM3, 2, 0x00f2, 0, 0, 0, 0, 0, cpuxgate, 0xf8ff },
++ { "ssem", M68XG_OP_R, 2, 0x00f3, 0, 0, 0, 0, 0, cpuxgate, 0xf8ff },
++//Single Register Instructions
++ { "sex", M68XG_OP_R, 2, 0x00f4, 0, 0, 0, 0, 0, cpuxgate, 0xf8ff },
++ { "par", M68XG_OP_R, 2, 0x00f5, 0, 0, 0, 0, 0, cpuxgate, 0xf8ff },
++ { "jal", M68XG_OP_R, 2, 0x00f6, 0, 0, 0, 0, 0, cpuxgate, 0xf8ff },
++ { "sif", M68XG_OP_R, 2, 0x00f7, 0, 0, 0, 0, 0, cpuxgate, 0xf8ff },
++//Special Move instructions
++ { "tfr", M68XG_OP_R, 2, 0x00f8, 0, 0, 0, 0, 0, cpuxgate, 0xf8ff }, // RD,CCR
++ { "tfr", M68XG_OP_R, 2, 0x00f9, 0, 0, 0, 0, 0, cpuxgate, 0xf8ff }, // CCR,RS
++ { "tfr", M68XG_OP_R, 2, 0x00fa, 0, 0, 0, 0, 0, cpuxgate, 0xf8ff }, // RD,PC
++//Shift instructions Dyadic
++ { "bffo", M68XG_OP_R_R, 2, 0x0810, 0, 0, 0, 0, 0, cpuxgate, 0xf81f },
++ { "asr", M68XG_OP_R_R, 2, 0x0811, 0, 0, 0, 0, 0, cpuxgate, 0xf81f },
++ { "csl", M68XG_OP_R_R, 2, 0x0812, 0, 0, 0, 0, 0, cpuxgate, 0xf81f },
++ { "csr", M68XG_OP_R_R, 2, 0x0813, 0, 0, 0, 0, 0, cpuxgate, 0xf81f },
++ { "lsl", M68XG_OP_R_R, 2, 0x0814, 0, 0, 0, 0, 0, cpuxgate, 0xf81f },
++ { "lsr", M68XG_OP_R_R, 2, 0x0815, 0, 0, 0, 0, 0, cpuxgate, 0xf81f },
++ { "rol", M68XG_OP_R_R, 2, 0x0816, 0, 0, 0, 0, 0, cpuxgate, 0xf81f },
++ { "ror", M68XG_OP_R_R, 2, 0x0817, 0, 0, 0, 0, 0, cpuxgate, 0xf81f },
++//Compare dyadic (alias for sub r0,...)
++ { "cmp", M68XG_OP_R_R, 2, 0x1800, 0, 0, 0, 0, 0, cpuxgate, 0x0000 },
++//Shift instructions immediate
++ { "asr", M68XG_OP_R_IMM4, 2, 0x0809, 0, 0, 0, 0, 0, cpuxgate, 0xf81f },
++ { "csl", M68XG_OP_R_IMM4, 2, 0x080a, 0, 0, 0, 0, 0, cpuxgate, 0xf81f },
++ { "csr", M68XG_OP_R_IMM4, 2, 0x080b, 0, 0, 0, 0, 0, cpuxgate, 0xf81f },
++ { "lsl", M68XG_OP_R_IMM4, 2, 0x080c, 0, 0, 0, 0, 0, cpuxgate, 0xf81f },
++ { "lsr", M68XG_OP_R_IMM4, 2, 0x080d, 0, 0, 0, 0, 0, cpuxgate, 0xf81f },
++ { "rol", M68XG_OP_R_IMM4, 2, 0x080e, 0, 0, 0, 0, 0, cpuxgate, 0xf81f },
++ { "ror", M68XG_OP_R_IMM4, 2, 0x080f, 0, 0, 0, 0, 0, cpuxgate, 0xf81f },
++//Logical Triadic
++ { "and", M68XG_OP_R_R_R, 2, 0x1000, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "or", M68XG_OP_R_R_R, 2, 0x1002, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "xnor", M68XG_OP_R_R_R, 2, 0x1003, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++//Arithmetic Triadic For compare use SUB R0,Rs1,Rs2
++ { "sub", M68XG_OP_R_R_R, 2, 0x1800, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "sbc", M68XG_OP_R_R_R, 2, 0x1801, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "add", M68XG_OP_R_R_R, 2, 0x1802, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "adc", M68XG_OP_R_R_R, 2, 0x1803, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++//Branches
++ { "bcc", M68XG_OP_REL9, 2, 0x2000, 0, 0, 0, 0, 0, cpuxgate, 0xfe00 },
++ { "bcs", M68XG_OP_REL9, 2, 0x2200, 0, 0, 0, 0, 0, cpuxgate, 0xfe00 },
++ { "bne", M68XG_OP_REL9, 2, 0x2400, 0, 0, 0, 0, 0, cpuxgate, 0xfe00 },
++ { "beq", M68XG_OP_REL9, 2, 0x2600, 0, 0, 0, 0, 0, cpuxgate, 0xfe00 },
++ { "bpl", M68XG_OP_REL9, 2, 0x2800, 0, 0, 0, 0, 0, cpuxgate, 0xfe00 },
++ { "bmi", M68XG_OP_REL9, 2, 0x2a00, 0, 0, 0, 0, 0, cpuxgate, 0xfe00 },
++ { "bvc", M68XG_OP_REL9, 2, 0x2c00, 0, 0, 0, 0, 0, cpuxgate, 0xfe00 },
++ { "bvs", M68XG_OP_REL9, 2, 0x2e00, 0, 0, 0, 0, 0, cpuxgate, 0xfe00 },
++ { "bhi", M68XG_OP_REL9, 2, 0x3000, 0, 0, 0, 0, 0, cpuxgate, 0xfe00 },
++ { "bls", M68XG_OP_REL9, 2, 0x3200, 0, 0, 0, 0, 0, cpuxgate, 0xfe00 },
++ { "bge", M68XG_OP_REL9, 2, 0x3400, 0, 0, 0, 0, 0, cpuxgate, 0xfe00 },
++ { "blt", M68XG_OP_REL9, 2, 0x3600, 0, 0, 0, 0, 0, cpuxgate, 0xfe00 },
++ { "bgt", M68XG_OP_REL9, 2, 0x3800, 0, 0, 0, 0, 0, cpuxgate, 0xfe00 },
++ { "ble", M68XG_OP_REL9, 2, 0x3a00, 0, 0, 0, 0, 0, cpuxgate, 0xfe00 },
++ { "bra", M68XG_OP_REL10, 2, 0x3c00, 0, 0, 0, 0, 0, cpuxgate, 0xfc00 },
++// Load and Store Instructions
++ { "ldb", M68XG_OP_R_R_OFFS5, 2, 0x4000, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "ldw", M68XG_OP_R_R_OFFS5, 2, 0x4800, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "stb", M68XG_OP_R_R_OFFS5, 2, 0x5000, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "stw", M68XG_OP_R_R_OFFS5, 2, 0x5800, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++
++ { "ldb", M68XG_OP_RD_RB_RI, 2, 0x6000, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "ldw", M68XG_OP_RD_RB_RI, 2, 0x6800, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "stb", M68XG_OP_RD_RB_RI, 2, 0x7000, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "stw", M68XG_OP_RD_RB_RI, 2, 0x7800, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++
++ { "ldb", M68XG_OP_RD_RB_RIp, 2, 0x6001, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "ldw", M68XG_OP_RD_RB_RIp, 2, 0x6801, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "stb", M68XG_OP_RD_RB_RIp, 2, 0x7001, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "stw", M68XG_OP_RD_RB_RIp, 2, 0x7801, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++
++ { "ldb", M68XG_OP_RD_RB_mRI, 2, 0x6002, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "ldw", M68XG_OP_RD_RB_mRI, 2, 0x6802, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "stb", M68XG_OP_RD_RB_mRI, 2, 0x7002, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "stw", M68XG_OP_RD_RB_mRI, 2, 0x7802, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++//Bit Field Instructions
++ { "bfext", M68XG_OP_R_R_R, 2, 0x6003, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "bfins", M68XG_OP_R_R_R, 2, 0x6803, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "bfinsi",M68XG_OP_R_R_R, 2, 0x7003, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++ { "bfinsx",M68XG_OP_R_R_R, 2, 0x7803, 0, 0, 0, 0, 0, cpuxgate, 0xf803 },
++/* these immediate commands need better handling so we can send
++ the assembler a 16bit address and generate the two opcodes */
++//Logic Immediate Instructions
++ { "andl", M68XG_OP_R_IMM8, 2, 0x8000, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "andh", M68XG_OP_R_IMM8, 2, 0x8800, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "bitl", M68XG_OP_R_IMM8, 2, 0x9000, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "bith", M68XG_OP_R_IMM8, 2, 0x9800, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "orl", M68XG_OP_R_IMM8, 2, 0xa000, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "orh", M68XG_OP_R_IMM8, 2, 0xa800, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "xnorl", M68XG_OP_R_IMM8, 2, 0xb000, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "xnorh", M68XG_OP_R_IMM8, 2, 0xb800, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++//Arithmetic Immediate Instructions
++ { "subl", M68XG_OP_R_IMM8, 2, 0xc000, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "subh", M68XG_OP_R_IMM8, 2, 0xc800, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "cmpl", M68XG_OP_R_IMM8, 2, 0xd000, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "cpch", M68XG_OP_R_IMM8, 2, 0xd800, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "addl", M68XG_OP_R_IMM8, 2, 0xe000, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "addh", M68XG_OP_R_IMM8, 2, 0xe800, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "ldl", M68XG_OP_R_IMM8, 2, 0xf000, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ { "ldh", M68XG_OP_R_IMM8, 2, 0xf800, 0, 0, 0, 0, 0, cpuxgate, 0xf800 },
++ /* 16 bit versions.
++ * These are pseudo opcodes to allow 16 bit addresses
++ * to be passed.
++ * Mask ensures we'll never disassemble to these instructions
++*/
++//Logic Immediate Instructions
++ { "and", M68XG_OP_R_IMM16, 2, 0x8000, 0, 0, 0, 0, 0, cpuxgate, 0x0000 },
++ { "bit", M68XG_OP_R_IMM16, 2, 0x9000, 0, 0, 0, 0, 0, cpuxgate, 0x0000 },
++ { "or", M68XG_OP_R_IMM16, 2, 0xa000, 0, 0, 0, 0, 0, cpuxgate, 0x0000 },
++ { "xnor", M68XG_OP_R_IMM16, 2, 0xb000, 0, 0, 0, 0, 0, cpuxgate, 0x0000 },
++//Arithmetic Immediate Instructions
++ { "sub", M68XG_OP_R_IMM16, 2, 0xc000, 0, 0, 0, 0, 0, cpuxgate, 0x0000 },
++ { "cmp", M68XG_OP_R_IMM16, 2, 0xd000, 0, 0, 0, 0, 0, cpuxgate, 0x0000 },
++ { "add", M68XG_OP_R_IMM16, 2, 0xe000, 0, 0, 0, 0, 0, cpuxgate, 0x0000 },
++ { "ld", M68XG_OP_R_IMM16, 2, 0xf000, 0, 0, 0, 0, 0, cpuxgate, 0x0000 }
+ };
+
+ const int m68hc11_num_opcodes = TABLE_SIZE (m68hc11_opcodes);
+@@ -1080,3 +1734,4 @@
+ { "xgdy","exg d,y", 2, 0xb7, 0xc6 }
+ };
+ const int m68hc12_num_alias = TABLE_SIZE (m68hc12_alias);
++
diff --git a/misc/buildroot/toolchain/binutils/2.19.1/110-arm-eabi-conf.patch b/misc/buildroot/toolchain/binutils/2.19.1/110-arm-eabi-conf.patch
new file mode 100644
index 000000000..af26329d9
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.19.1/110-arm-eabi-conf.patch
@@ -0,0 +1,24 @@
+diff -rdup binutils-2.18.50.0.3.orig/configure binutils-2.18.50.0.3/configure
+--- binutils-2.18.50.0.3.orig/configure 2007-11-22 12:41:26.000000000 +0100
++++ binutils-2.18.50.0.3/configure 2007-11-22 12:45:01.000000000 +0100
+@@ -2245,7 +2245,7 @@ case "${target}" in
+ noconfigdirs="$noconfigdirs target-libffi target-qthreads"
+ libgloss_dir=arm
+ ;;
+- arm*-*-linux-gnueabi)
++ arm*-*-linux-*gnueabi)
+ noconfigdirs="$noconfigdirs target-qthreads"
+ noconfigdirs="$noconfigdirs target-libobjc"
+ case ${with_newlib} in
+diff -rdup binutils-2.18.50.0.3.orig/configure.ac binutils-2.18.50.0.3/configure.ac
+--- binutils-2.18.50.0.3.orig/configure.ac 2007-11-22 12:41:26.000000000 +0100
++++ binutils-2.18.50.0.3/configure.ac 2007-11-22 12:44:54.000000000 +0100
+@@ -522,7 +522,7 @@ case "${target}" in
+ noconfigdirs="$noconfigdirs target-libffi target-qthreads"
+ libgloss_dir=arm
+ ;;
+- arm*-*-linux-gnueabi)
++ arm*-*-linux-*gnueabi)
+ noconfigdirs="$noconfigdirs target-qthreads"
+ noconfigdirs="$noconfigdirs target-libobjc"
+ case ${with_newlib} in
diff --git a/misc/buildroot/toolchain/binutils/2.19.1/120-sh-conf.patch b/misc/buildroot/toolchain/binutils/2.19.1/120-sh-conf.patch
new file mode 100644
index 000000000..071d15a41
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.19.1/120-sh-conf.patch
@@ -0,0 +1,42 @@
+diff -rdup binutils-2.18.50.0.9.old/configure binutils-2.18.50.0.9/configure
+--- binutils-2.18.50.0.9.old/configure 2008-08-23 17:36:13.000000000 +0200
++++ binutils-2.18.50.0.9/configure 2008-10-14 14:25:22.000000000 +0200
+@@ -2281,7 +2281,7 @@ case "${target}" in
+ am33_2.0-*-linux*)
+ noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
+ ;;
+- sh-*-linux*)
++ sh*-*-linux*)
+ noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
+ ;;
+ sh*-*-pe|mips*-*-pe|*arm-wince-pe)
+@@ -2606,7 +2606,7 @@ case "${target}" in
+ romp-*-*)
+ noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes target-libgloss ${libgcj}"
+ ;;
+- sh-*-* | sh64-*-*)
++ sh*-*-* | sh64-*-*)
+ case "${host}" in
+ i[3456789]86-*-vsta) ;; # don't add gprof back in
+ i[3456789]86-*-go32*) ;; # don't add gprof back in
+diff -rdup binutils-2.18.50.0.9.old/configure.ac binutils-2.18.50.0.9/configure.ac
+--- binutils-2.18.50.0.9.old/configure.ac 2008-08-23 17:36:13.000000000 +0200
++++ binutils-2.18.50.0.9/configure.ac 2008-10-14 14:25:11.000000000 +0200
+@@ -530,7 +530,7 @@ case "${target}" in
+ am33_2.0-*-linux*)
+ noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
+ ;;
+- sh-*-linux*)
++ sh*-*-linux*)
+ noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
+ ;;
+ sh*-*-pe|mips*-*-pe|*arm-wince-pe)
+@@ -855,7 +855,7 @@ case "${target}" in
+ romp-*-*)
+ noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes target-libgloss ${libgcj}"
+ ;;
+- sh-*-* | sh64-*-*)
++ sh*-*-* | sh64-*-*)
+ case "${host}" in
+ i[[3456789]]86-*-vsta) ;; # don't add gprof back in
+ i[[3456789]]86-*-go32*) ;; # don't add gprof back in
diff --git a/misc/buildroot/toolchain/binutils/2.19.1/300-001_ld_makefile_patch.patch b/misc/buildroot/toolchain/binutils/2.19.1/300-001_ld_makefile_patch.patch
new file mode 100644
index 000000000..5cb0f614d
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.19.1/300-001_ld_makefile_patch.patch
@@ -0,0 +1,24 @@
+diff -u binutils-2.17.50.0.17.oorig/ld/Makefile.am binutils-2.17.50.0.17/ld/Makefile.am
+--- binutils-2.17.50.0.17.oorig/ld/Makefile.am 2007-06-18 19:29:29.000000000 +0200
++++ binutils-2.17.50.0.17/ld/Makefile.am 2007-06-25 10:00:36.000000000 +0200
+@@ -18,7 +18,7 @@
+ # We put the scripts in the directory $(scriptdir)/ldscripts.
+ # We can't put the scripts in $(datadir) because the SEARCH_DIR
+ # directives need to be different for native and cross linkers.
+-scriptdir = $(tooldir)/lib
++scriptdir = $(libdir)
+
+ EMUL = @EMUL@
+ EMULATION_OFILES = @EMULATION_OFILES@
+diff -u binutils-2.17.50.0.17.oorig/ld/Makefile.in binutils-2.17.50.0.17/ld/Makefile.in
+--- binutils-2.17.50.0.17.oorig/ld/Makefile.in 2007-06-18 19:29:29.000000000 +0200
++++ binutils-2.17.50.0.17/ld/Makefile.in 2007-06-25 10:00:36.000000000 +0200
+@@ -287,7 +287,7 @@
+ # We put the scripts in the directory $(scriptdir)/ldscripts.
+ # We can't put the scripts in $(datadir) because the SEARCH_DIR
+ # directives need to be different for native and cross linkers.
+-scriptdir = $(tooldir)/lib
++scriptdir = $(libdir)
+ BASEDIR = $(srcdir)/..
+ BFDDIR = $(BASEDIR)/bfd
+ INCDIR = $(BASEDIR)/include
diff --git a/misc/buildroot/toolchain/binutils/2.19.1/300-012_check_ldrunpath_length.patch b/misc/buildroot/toolchain/binutils/2.19.1/300-012_check_ldrunpath_length.patch
new file mode 100644
index 000000000..6e809213d
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.19.1/300-012_check_ldrunpath_length.patch
@@ -0,0 +1,21 @@
+diff -u binutils-2.17.50.0.17.oorig/ld/emultempl/elf32.em binutils-2.17.50.0.17/ld/emultempl/elf32.em
+--- binutils-2.17.50.0.17.oorig/ld/emultempl/elf32.em 2007-06-18 19:31:40.000000000 +0200
++++ binutils-2.17.50.0.17/ld/emultempl/elf32.em 2007-06-25 10:01:25.000000000 +0200
+@@ -1007,6 +1007,8 @@
+ && command_line.rpath == NULL)
+ {
+ lib_path = (const char *) getenv ("LD_RUN_PATH");
++ if ((lib_path) && (strlen (lib_path) == 0))
++ lib_path = NULL;
+ if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
+ force))
+ break;
+@@ -1191,6 +1193,8 @@
+ rpath = command_line.rpath;
+ if (rpath == NULL)
+ rpath = (const char *) getenv ("LD_RUN_PATH");
++ if ((rpath) && (strlen (rpath) == 0))
++ rpath = NULL;
+ if (! (bfd_elf_size_dynamic_sections
+ (output_bfd, command_line.soname, rpath,
+ command_line.filter_shlib,
diff --git a/misc/buildroot/toolchain/binutils/2.19.1/400-thumb-cputype.patch b/misc/buildroot/toolchain/binutils/2.19.1/400-thumb-cputype.patch
new file mode 100644
index 000000000..c792d2e38
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.19.1/400-thumb-cputype.patch
@@ -0,0 +1,16 @@
+// This patch is bogus. It does let you create a a version of binutils with the cross
+// name of thumb-elf, but it is insufficient to build a whole thumb-elf toolchain because
+// of issues with gcc. Rather, build arm-elf, but configure --with-mode=thumb
+//
+diff -u binutils-2.19.1/gas/configure.tgt.orig binutils-2.19.1/gas/configure.tgt
+--- binutils-2.19.1/gas/configure.tgt.orig 2009-04-25 11:00:15.593750000 -0400
++++ binutils-2.19.1/gas/configure.tgt 2009-04-25 11:00:45.593750000 -0400
+@@ -32,7 +32,7 @@
+ alpha*) cpu_type=alpha ;;
+ am33_2.0) cpu_type=mn10300 endian=little ;;
+ arm*be|arm*b) cpu_type=arm endian=big ;;
+- arm*) cpu_type=arm endian=little ;;
++ arm*|thumb*) cpu_type=arm endian=little ;;
+ bfin*) cpu_type=bfin endian=little ;;
+ c4x*) cpu_type=tic4x ;;
+ cr16*) cpu_type=cr16 endian=little ;;
diff --git a/misc/buildroot/toolchain/binutils/2.19/110-arm-eabi-conf.patch b/misc/buildroot/toolchain/binutils/2.19/110-arm-eabi-conf.patch
new file mode 100644
index 000000000..af26329d9
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.19/110-arm-eabi-conf.patch
@@ -0,0 +1,24 @@
+diff -rdup binutils-2.18.50.0.3.orig/configure binutils-2.18.50.0.3/configure
+--- binutils-2.18.50.0.3.orig/configure 2007-11-22 12:41:26.000000000 +0100
++++ binutils-2.18.50.0.3/configure 2007-11-22 12:45:01.000000000 +0100
+@@ -2245,7 +2245,7 @@ case "${target}" in
+ noconfigdirs="$noconfigdirs target-libffi target-qthreads"
+ libgloss_dir=arm
+ ;;
+- arm*-*-linux-gnueabi)
++ arm*-*-linux-*gnueabi)
+ noconfigdirs="$noconfigdirs target-qthreads"
+ noconfigdirs="$noconfigdirs target-libobjc"
+ case ${with_newlib} in
+diff -rdup binutils-2.18.50.0.3.orig/configure.ac binutils-2.18.50.0.3/configure.ac
+--- binutils-2.18.50.0.3.orig/configure.ac 2007-11-22 12:41:26.000000000 +0100
++++ binutils-2.18.50.0.3/configure.ac 2007-11-22 12:44:54.000000000 +0100
+@@ -522,7 +522,7 @@ case "${target}" in
+ noconfigdirs="$noconfigdirs target-libffi target-qthreads"
+ libgloss_dir=arm
+ ;;
+- arm*-*-linux-gnueabi)
++ arm*-*-linux-*gnueabi)
+ noconfigdirs="$noconfigdirs target-qthreads"
+ noconfigdirs="$noconfigdirs target-libobjc"
+ case ${with_newlib} in
diff --git a/misc/buildroot/toolchain/binutils/2.19/120-sh-conf.patch b/misc/buildroot/toolchain/binutils/2.19/120-sh-conf.patch
new file mode 100644
index 000000000..071d15a41
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.19/120-sh-conf.patch
@@ -0,0 +1,42 @@
+diff -rdup binutils-2.18.50.0.9.old/configure binutils-2.18.50.0.9/configure
+--- binutils-2.18.50.0.9.old/configure 2008-08-23 17:36:13.000000000 +0200
++++ binutils-2.18.50.0.9/configure 2008-10-14 14:25:22.000000000 +0200
+@@ -2281,7 +2281,7 @@ case "${target}" in
+ am33_2.0-*-linux*)
+ noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
+ ;;
+- sh-*-linux*)
++ sh*-*-linux*)
+ noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
+ ;;
+ sh*-*-pe|mips*-*-pe|*arm-wince-pe)
+@@ -2606,7 +2606,7 @@ case "${target}" in
+ romp-*-*)
+ noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes target-libgloss ${libgcj}"
+ ;;
+- sh-*-* | sh64-*-*)
++ sh*-*-* | sh64-*-*)
+ case "${host}" in
+ i[3456789]86-*-vsta) ;; # don't add gprof back in
+ i[3456789]86-*-go32*) ;; # don't add gprof back in
+diff -rdup binutils-2.18.50.0.9.old/configure.ac binutils-2.18.50.0.9/configure.ac
+--- binutils-2.18.50.0.9.old/configure.ac 2008-08-23 17:36:13.000000000 +0200
++++ binutils-2.18.50.0.9/configure.ac 2008-10-14 14:25:11.000000000 +0200
+@@ -530,7 +530,7 @@ case "${target}" in
+ am33_2.0-*-linux*)
+ noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
+ ;;
+- sh-*-linux*)
++ sh*-*-linux*)
+ noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
+ ;;
+ sh*-*-pe|mips*-*-pe|*arm-wince-pe)
+@@ -855,7 +855,7 @@ case "${target}" in
+ romp-*-*)
+ noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes target-libgloss ${libgcj}"
+ ;;
+- sh-*-* | sh64-*-*)
++ sh*-*-* | sh64-*-*)
+ case "${host}" in
+ i[[3456789]]86-*-vsta) ;; # don't add gprof back in
+ i[[3456789]]86-*-go32*) ;; # don't add gprof back in
diff --git a/misc/buildroot/toolchain/binutils/2.19/300-001_ld_makefile_patch.patch b/misc/buildroot/toolchain/binutils/2.19/300-001_ld_makefile_patch.patch
new file mode 100644
index 000000000..5cb0f614d
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.19/300-001_ld_makefile_patch.patch
@@ -0,0 +1,24 @@
+diff -u binutils-2.17.50.0.17.oorig/ld/Makefile.am binutils-2.17.50.0.17/ld/Makefile.am
+--- binutils-2.17.50.0.17.oorig/ld/Makefile.am 2007-06-18 19:29:29.000000000 +0200
++++ binutils-2.17.50.0.17/ld/Makefile.am 2007-06-25 10:00:36.000000000 +0200
+@@ -18,7 +18,7 @@
+ # We put the scripts in the directory $(scriptdir)/ldscripts.
+ # We can't put the scripts in $(datadir) because the SEARCH_DIR
+ # directives need to be different for native and cross linkers.
+-scriptdir = $(tooldir)/lib
++scriptdir = $(libdir)
+
+ EMUL = @EMUL@
+ EMULATION_OFILES = @EMULATION_OFILES@
+diff -u binutils-2.17.50.0.17.oorig/ld/Makefile.in binutils-2.17.50.0.17/ld/Makefile.in
+--- binutils-2.17.50.0.17.oorig/ld/Makefile.in 2007-06-18 19:29:29.000000000 +0200
++++ binutils-2.17.50.0.17/ld/Makefile.in 2007-06-25 10:00:36.000000000 +0200
+@@ -287,7 +287,7 @@
+ # We put the scripts in the directory $(scriptdir)/ldscripts.
+ # We can't put the scripts in $(datadir) because the SEARCH_DIR
+ # directives need to be different for native and cross linkers.
+-scriptdir = $(tooldir)/lib
++scriptdir = $(libdir)
+ BASEDIR = $(srcdir)/..
+ BFDDIR = $(BASEDIR)/bfd
+ INCDIR = $(BASEDIR)/include
diff --git a/misc/buildroot/toolchain/binutils/2.19/300-012_check_ldrunpath_length.patch b/misc/buildroot/toolchain/binutils/2.19/300-012_check_ldrunpath_length.patch
new file mode 100644
index 000000000..6e809213d
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.19/300-012_check_ldrunpath_length.patch
@@ -0,0 +1,21 @@
+diff -u binutils-2.17.50.0.17.oorig/ld/emultempl/elf32.em binutils-2.17.50.0.17/ld/emultempl/elf32.em
+--- binutils-2.17.50.0.17.oorig/ld/emultempl/elf32.em 2007-06-18 19:31:40.000000000 +0200
++++ binutils-2.17.50.0.17/ld/emultempl/elf32.em 2007-06-25 10:01:25.000000000 +0200
+@@ -1007,6 +1007,8 @@
+ && command_line.rpath == NULL)
+ {
+ lib_path = (const char *) getenv ("LD_RUN_PATH");
++ if ((lib_path) && (strlen (lib_path) == 0))
++ lib_path = NULL;
+ if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
+ force))
+ break;
+@@ -1191,6 +1193,8 @@
+ rpath = command_line.rpath;
+ if (rpath == NULL)
+ rpath = (const char *) getenv ("LD_RUN_PATH");
++ if ((rpath) && (strlen (rpath) == 0))
++ rpath = NULL;
+ if (! (bfd_elf_size_dynamic_sections
+ (output_bfd, command_line.soname, rpath,
+ command_line.filter_shlib,
diff --git a/misc/buildroot/toolchain/binutils/2.21.1/110-arm-eabi-conf.patch b/misc/buildroot/toolchain/binutils/2.21.1/110-arm-eabi-conf.patch
new file mode 100644
index 000000000..af26329d9
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.21.1/110-arm-eabi-conf.patch
@@ -0,0 +1,24 @@
+diff -rdup binutils-2.18.50.0.3.orig/configure binutils-2.18.50.0.3/configure
+--- binutils-2.18.50.0.3.orig/configure 2007-11-22 12:41:26.000000000 +0100
++++ binutils-2.18.50.0.3/configure 2007-11-22 12:45:01.000000000 +0100
+@@ -2245,7 +2245,7 @@ case "${target}" in
+ noconfigdirs="$noconfigdirs target-libffi target-qthreads"
+ libgloss_dir=arm
+ ;;
+- arm*-*-linux-gnueabi)
++ arm*-*-linux-*gnueabi)
+ noconfigdirs="$noconfigdirs target-qthreads"
+ noconfigdirs="$noconfigdirs target-libobjc"
+ case ${with_newlib} in
+diff -rdup binutils-2.18.50.0.3.orig/configure.ac binutils-2.18.50.0.3/configure.ac
+--- binutils-2.18.50.0.3.orig/configure.ac 2007-11-22 12:41:26.000000000 +0100
++++ binutils-2.18.50.0.3/configure.ac 2007-11-22 12:44:54.000000000 +0100
+@@ -522,7 +522,7 @@ case "${target}" in
+ noconfigdirs="$noconfigdirs target-libffi target-qthreads"
+ libgloss_dir=arm
+ ;;
+- arm*-*-linux-gnueabi)
++ arm*-*-linux-*gnueabi)
+ noconfigdirs="$noconfigdirs target-qthreads"
+ noconfigdirs="$noconfigdirs target-libobjc"
+ case ${with_newlib} in
diff --git a/misc/buildroot/toolchain/binutils/2.21.1/120-sh-conf.patch b/misc/buildroot/toolchain/binutils/2.21.1/120-sh-conf.patch
new file mode 100644
index 000000000..071d15a41
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.21.1/120-sh-conf.patch
@@ -0,0 +1,42 @@
+diff -rdup binutils-2.18.50.0.9.old/configure binutils-2.18.50.0.9/configure
+--- binutils-2.18.50.0.9.old/configure 2008-08-23 17:36:13.000000000 +0200
++++ binutils-2.18.50.0.9/configure 2008-10-14 14:25:22.000000000 +0200
+@@ -2281,7 +2281,7 @@ case "${target}" in
+ am33_2.0-*-linux*)
+ noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
+ ;;
+- sh-*-linux*)
++ sh*-*-linux*)
+ noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
+ ;;
+ sh*-*-pe|mips*-*-pe|*arm-wince-pe)
+@@ -2606,7 +2606,7 @@ case "${target}" in
+ romp-*-*)
+ noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes target-libgloss ${libgcj}"
+ ;;
+- sh-*-* | sh64-*-*)
++ sh*-*-* | sh64-*-*)
+ case "${host}" in
+ i[3456789]86-*-vsta) ;; # don't add gprof back in
+ i[3456789]86-*-go32*) ;; # don't add gprof back in
+diff -rdup binutils-2.18.50.0.9.old/configure.ac binutils-2.18.50.0.9/configure.ac
+--- binutils-2.18.50.0.9.old/configure.ac 2008-08-23 17:36:13.000000000 +0200
++++ binutils-2.18.50.0.9/configure.ac 2008-10-14 14:25:11.000000000 +0200
+@@ -530,7 +530,7 @@ case "${target}" in
+ am33_2.0-*-linux*)
+ noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
+ ;;
+- sh-*-linux*)
++ sh*-*-linux*)
+ noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
+ ;;
+ sh*-*-pe|mips*-*-pe|*arm-wince-pe)
+@@ -855,7 +855,7 @@ case "${target}" in
+ romp-*-*)
+ noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes target-libgloss ${libgcj}"
+ ;;
+- sh-*-* | sh64-*-*)
++ sh*-*-* | sh64-*-*)
+ case "${host}" in
+ i[[3456789]]86-*-vsta) ;; # don't add gprof back in
+ i[[3456789]]86-*-go32*) ;; # don't add gprof back in
diff --git a/misc/buildroot/toolchain/binutils/2.21.1/300-001_ld_makefile_patch.patch b/misc/buildroot/toolchain/binutils/2.21.1/300-001_ld_makefile_patch.patch
new file mode 100644
index 000000000..5cb0f614d
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.21.1/300-001_ld_makefile_patch.patch
@@ -0,0 +1,24 @@
+diff -u binutils-2.17.50.0.17.oorig/ld/Makefile.am binutils-2.17.50.0.17/ld/Makefile.am
+--- binutils-2.17.50.0.17.oorig/ld/Makefile.am 2007-06-18 19:29:29.000000000 +0200
++++ binutils-2.17.50.0.17/ld/Makefile.am 2007-06-25 10:00:36.000000000 +0200
+@@ -18,7 +18,7 @@
+ # We put the scripts in the directory $(scriptdir)/ldscripts.
+ # We can't put the scripts in $(datadir) because the SEARCH_DIR
+ # directives need to be different for native and cross linkers.
+-scriptdir = $(tooldir)/lib
++scriptdir = $(libdir)
+
+ EMUL = @EMUL@
+ EMULATION_OFILES = @EMULATION_OFILES@
+diff -u binutils-2.17.50.0.17.oorig/ld/Makefile.in binutils-2.17.50.0.17/ld/Makefile.in
+--- binutils-2.17.50.0.17.oorig/ld/Makefile.in 2007-06-18 19:29:29.000000000 +0200
++++ binutils-2.17.50.0.17/ld/Makefile.in 2007-06-25 10:00:36.000000000 +0200
+@@ -287,7 +287,7 @@
+ # We put the scripts in the directory $(scriptdir)/ldscripts.
+ # We can't put the scripts in $(datadir) because the SEARCH_DIR
+ # directives need to be different for native and cross linkers.
+-scriptdir = $(tooldir)/lib
++scriptdir = $(libdir)
+ BASEDIR = $(srcdir)/..
+ BFDDIR = $(BASEDIR)/bfd
+ INCDIR = $(BASEDIR)/include
diff --git a/misc/buildroot/toolchain/binutils/2.21.1/300-012_check_ldrunpath_length.patch b/misc/buildroot/toolchain/binutils/2.21.1/300-012_check_ldrunpath_length.patch
new file mode 100644
index 000000000..df783109b
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.21.1/300-012_check_ldrunpath_length.patch
@@ -0,0 +1,21 @@
+diff -Nura binutils-2.21.orig/ld/emultempl/elf32.em binutils-2.21/ld/emultempl/elf32.em
+--- binutils-2.21.orig/ld/emultempl/elf32.em 2010-10-29 09:10:36.000000000 -0300
++++ binutils-2.21/ld/emultempl/elf32.em 2010-12-10 09:26:56.746102724 -0300
+@@ -1270,6 +1270,8 @@
+ && command_line.rpath == NULL)
+ {
+ lib_path = (const char *) getenv ("LD_RUN_PATH");
++ if ((lib_path) && (strlen (lib_path) == 0))
++ lib_path = NULL;
+ if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
+ force))
+ break;
+@@ -1497,6 +1499,8 @@
+ rpath = command_line.rpath;
+ if (rpath == NULL)
+ rpath = (const char *) getenv ("LD_RUN_PATH");
++ if ((rpath) && (strlen (rpath) == 0))
++ rpath = NULL;
+
+ for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next)
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
diff --git a/misc/buildroot/toolchain/binutils/2.21.1/900-bug12296-cortexm3-svc.patch b/misc/buildroot/toolchain/binutils/2.21.1/900-bug12296-cortexm3-svc.patch
new file mode 100644
index 000000000..df4c9ff1d
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/2.21.1/900-bug12296-cortexm3-svc.patch
@@ -0,0 +1,48 @@
+Index: gas/testsuite/gas/arm/arch7.d
+===================================================================
+RCS file: /cvs/src/src/gas/testsuite/gas/arm/arch7.d,v
+--- a/gas/testsuite/gas/arm/arch7.d 17 Sep 2010 10:42:04 -0000 1.6
++++ b/gas/testsuite/gas/arm/arch7.d 30 Mar 2011 22:44:17 -0000
+@@ -76,3 +76,4 @@
+ 0+10c <[^>]*> f380 8814 msr CONTROL, r0
+ 0+110 <[^>]*> f3ef 8003 mrs r0, PSR
+ 0+114 <[^>]*> f380 8803 msr PSR, r0
++0+118 <[^>]*> df00 svc 0
+Index: gas/testsuite/gas/arm/arch7.s
+===================================================================
+RCS file: /cvs/src/src/gas/testsuite/gas/arm/arch7.s,v
+--- a/gas/testsuite/gas/arm/arch7.s 17 Sep 2010 10:42:04 -0000 1.2
++++ b/gas/testsuite/gas/arm/arch7.s 30 Mar 2011 22:44:17 -0000
+@@ -79,3 +79,5 @@
+ msr control, r0
+ mrs r0, xpsr
+ msr xpsr, r0
++
++ svc 0
+Index: gas/testsuite/gas/arm/attr-march-armv7.d
+===================================================================
+RCS file: /cvs/src/src/gas/testsuite/gas/arm/attr-march-armv7.d,v
+--- a/gas/testsuite/gas/arm/attr-march-armv7.d 11 May 2010 17:36:33 -0000 1.3
++++ b/gas/testsuite/gas/arm/attr-march-armv7.d 30 Mar 2011 22:44:17 -0000
+@@ -9,5 +9,6 @@
+ File Attributes
+ Tag_CPU_name: "7"
+ Tag_CPU_arch: v7
++ Tag_CPU_arch_profile: Microcontroller
+ Tag_THUMB_ISA_use: Thumb-2
+ Tag_DIV_use: Not allowed
+Index: include/opcode/arm.h
+===================================================================
+RCS file: /cvs/src/src/include/opcode/arm.h,v
+--- a/include/opcode/arm.h 15 Nov 2010 10:03:05 -0000 1.24
++++ b/include/opcode/arm.h 30 Mar 2011 22:44:18 -0000
+@@ -109,7 +109,8 @@
+ #define ARM_AEXT_V6KT2 (ARM_AEXT_V6T2 | ARM_EXT_V6K)
+ #define ARM_AEXT_V6ZT2 (ARM_AEXT_V6T2 | ARM_EXT_SEC)
+ #define ARM_AEXT_V6ZKT2 (ARM_AEXT_V6T2 | ARM_EXT_V6K | ARM_EXT_SEC)
+-#define ARM_AEXT_V7_ARM (ARM_AEXT_V6KT2 | ARM_EXT_V7 | ARM_EXT_BARRIER)
++#define ARM_AEXT_V7_ARM (ARM_AEXT_V6KT2 | ARM_EXT_V7 | ARM_EXT_BARRIER \
++ | ARM_EXT_OS)
+ #define ARM_AEXT_V7A (ARM_AEXT_V7_ARM | ARM_EXT_V7A)
+ #define ARM_AEXT_V7R (ARM_AEXT_V7_ARM | ARM_EXT_V7R | ARM_EXT_DIV)
+ #define ARM_AEXT_NOTM \
diff --git a/misc/buildroot/toolchain/binutils/Config.in b/misc/buildroot/toolchain/binutils/Config.in
new file mode 100644
index 000000000..d1e674ba5
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/Config.in
@@ -0,0 +1,47 @@
+# Choose binutils version.
+
+comment "Binutils Options"
+
+choice
+ prompt "Binutils Version"
+ default BR2_BINUTILS_VERSION_2_19_1 if BR2_cortex_m3
+ default BR2_BINUTILS_VERSION_2_19 if !BR2_avr32 && !BR2_cortex_m3 && !BR2_m9s12x
+ default BR2_BINUTILS_VERSION_2_18 if BR2_m9s12x
+ default BR2_BINUTILS_VERSION_2_17 if !BR2_cortex_m3 && !BR2_m9s12x
+ help
+ Select the version of binutils you wish to use.
+
+ config BR2_BINUTILS_VERSION_2_17
+ depends !BR2_nios2 && !BR2_cortex_m3 && !BR2_m9s12x
+ bool "binutils 2.17"
+
+ config BR2_BINUTILS_VERSION_2_18
+ depends !BR2_avr32 && !BR2_nios2 && !BR2_cortex_m3
+ bool "binutils 2.18"
+
+ config BR2_BINUTILS_VERSION_2_19
+ depends !BR2_avr32 && !BR2_nios2 && !BR2_cortex_m3 && !BR2_m9s12x
+ bool "binutils 2.19"
+
+ config BR2_BINUTILS_VERSION_2_19_1
+ depends !BR2_avr32 && !BR2_nios2 && !BR2_m9s12x
+ bool "binutils 2.19.1"
+
+ config BR2_BINUTILS_VERSION_2_21_1
+ depends !BR2_avr32 && !BR2_nios2 && !BR2_m9s12x
+ bool "binutils 2.21.1"
+endchoice
+
+config BR2_BINUTILS_VERSION
+ string
+ default "2.17" if BR2_BINUTILS_VERSION_2_17
+ default "2.18" if BR2_BINUTILS_VERSION_2_18
+ default "2.19" if BR2_BINUTILS_VERSION_2_19
+ default "2.19.1" if BR2_BINUTILS_VERSION_2_19_1
+ default "2.21.1" if BR2_BINUTILS_VERSION_2_21_1
+
+config BR2_EXTRA_BINUTILS_CONFIG_OPTIONS
+ string "Additional binutils options"
+ default ""
+ help
+ Any additional binutils options you may want to include ...
diff --git a/misc/buildroot/toolchain/binutils/binutils.mk b/misc/buildroot/toolchain/binutils/binutils.mk
new file mode 100644
index 000000000..e4f00c899
--- /dev/null
+++ b/misc/buildroot/toolchain/binutils/binutils.mk
@@ -0,0 +1,125 @@
+#############################################################
+#
+# build binutils for use on the host system
+#
+#############################################################
+BINUTILS_VERSION:=$(strip $(subst ",, $(BR2_BINUTILS_VERSION)))
+#"))
+
+EXTRA_BINUTILS_CONFIG_OPTIONS=$(strip $(subst ",, $(BR2_EXTRA_BINUTILS_CONFIG_OPTIONS)))
+#"))
+BINUTILS_SITE:=ftp://ftp.gnu.org/gnu/binutils
+
+# NOTE: Unlike the original buildroot binutils.mk, this version always relies on
+# the system libgmp and libmpfr which must be installed for certain binutils versions.
+
+BINUTILS_SOURCE:=binutils-$(BINUTILS_VERSION).tar.bz2
+BINUTILS_DIR:=$(TOOL_BUILD_DIR)/binutils-$(BINUTILS_VERSION)
+BINUTILS_CAT:=$(BZCAT)
+
+BINUTILS_DIR1:=$(TOOL_BUILD_DIR)/binutils-$(BINUTILS_VERSION)-build
+
+$(DL_DIR)/$(BINUTILS_SOURCE):
+ mkdir -p $(DL_DIR)
+ $(WGET) -P $(DL_DIR) $(BINUTILS_SITE)/$(BINUTILS_SOURCE)
+
+binutils-unpacked: $(BINUTILS_DIR)/.unpacked
+$(BINUTILS_DIR)/.unpacked: $(DL_DIR)/$(BINUTILS_SOURCE)
+ mkdir -p $(TOOL_BUILD_DIR)
+ $(BINUTILS_CAT) $(DL_DIR)/$(BINUTILS_SOURCE) | tar -C $(TOOL_BUILD_DIR) $(TAR_OPTIONS) -
+ $(CONFIG_UPDATE) $(BINUTILS_DIR)
+ touch $@
+
+$(BINUTILS_DIR)/.patched: $(BINUTILS_DIR)/.unpacked
+ # Apply appropriate binutils patches.
+ toolchain/patch-kernel.sh $(BINUTILS_DIR) toolchain/binutils/$(BINUTILS_VERSION) \*.patch
+ touch $@
+
+$(BINUTILS_DIR1)/.configured: $(BINUTILS_DIR)/.patched
+ mkdir -p $(BINUTILS_DIR1)
+ (cd $(BINUTILS_DIR1); \
+ CC="$(HOSTCC)" \
+ $(BINUTILS_DIR)/configure \
+ --prefix=$(STAGING_DIR) \
+ --build=$(GNU_HOST_NAME) \
+ --host=$(GNU_HOST_NAME) \
+ --target=$(REAL_GNU_TARGET_NAME) \
+ $(DISABLE_NLS) \
+ $(MULTILIB) \
+ --disable-werror \
+ $(SOFT_FLOAT_CONFIG_OPTION) \
+ $(EXTRA_BINUTILS_CONFIG_OPTIONS));
+ touch $@
+
+$(BINUTILS_DIR1)/binutils/objdump: $(BINUTILS_DIR1)/.configured
+ $(MAKE) -C $(BINUTILS_DIR1) all
+
+# Make install will put gettext data in staging_dir/share/locale.
+# Unfortunatey, it isn't configureable.
+$(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/bin/ld: $(BINUTILS_DIR1)/binutils/objdump
+ $(MAKE) -C $(BINUTILS_DIR1) install
+
+binutils: dependencies $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/bin/ld
+
+binutils-source: $(DL_DIR)/$(BINUTILS_SOURCE)
+
+binutils-clean:
+ rm -f $(STAGING_DIR)/bin/$(REAL_GNU_TARGET_NAME)*
+ -$(MAKE) -C $(BINUTILS_DIR1) clean
+
+binutils-dirclean:
+ rm -rf $(BINUTILS_DIR1)
+
+
+
+#############################################################
+#
+# build binutils for use on the target system
+#
+#############################################################
+BINUTILS_DIR2:=$(BUILD_DIR)/binutils-$(BINUTILS_VERSION)-target
+$(BINUTILS_DIR2)/.configured: $(BINUTILS_DIR)/.patched
+ mkdir -p $(BINUTILS_DIR2)
+ (cd $(BINUTILS_DIR2); \
+ CC_FOR_BUILD="$(HOSTCC)" \
+ PATH=$(TARGET_PATH) \
+ CFLAGS="$(TARGET_CFLAGS)" \
+ CFLAGS_FOR_BUILD="-O2 -g" \
+ $(BINUTILS_DIR)/configure \
+ --prefix=/usr \
+ --exec-prefix=/usr \
+ --build=$(GNU_HOST_NAME) \
+ --host=$(REAL_GNU_TARGET_NAME) \
+ --target=$(REAL_GNU_TARGET_NAME) \
+ $(DISABLE_NLS) \
+ $(MULTILIB) \
+ $(BINUTILS_TARGET_CONFIG_OPTIONS) \
+ --disable-werror \
+ $(SOFT_FLOAT_CONFIG_OPTION) );
+ touch $@
+
+$(BINUTILS_DIR2)/binutils/objdump: $(BINUTILS_DIR2)/.configured
+ PATH=$(TARGET_PATH) \
+ $(MAKE) -C $(BINUTILS_DIR2) all
+
+$(TARGET_DIR)/usr/bin/ld: $(BINUTILS_DIR2)/binutils/objdump
+ PATH=$(TARGET_PATH) \
+ $(MAKE) DESTDIR=$(TARGET_DIR) \
+ tooldir=/usr build_tooldir=/usr \
+ -C $(BINUTILS_DIR2) install
+ #rm -rf $(TARGET_DIR)/share/locale $(TARGET_DIR)/usr/info \
+ # $(TARGET_DIR)/usr/man $(TARGET_DIR)/usr/share/doc
+ -$(STRIP) $(TARGET_DIR)/usr/$(REAL_GNU_TARGET_NAME)/bin/* > /dev/null 2>&1
+ -$(STRIP) $(TARGET_DIR)/usr/bin/* > /dev/null 2>&1
+
+binutils_target: $(TARGET_DIR)/usr/bin/ld
+
+binutils_target-clean:
+ (cd $(TARGET_DIR)/usr/bin; \
+ rm -f addr2line ar as gprof ld nm objcopy \
+ objdump ranlib readelf size strings strip)
+ rm -f $(TARGET_DIR)/bin/$(REAL_GNU_TARGET_NAME)*
+ -$(MAKE) -C $(BINUTILS_DIR2) clean
+
+binutils_target-dirclean:
+ rm -rf $(BINUTILS_DIR2)
diff --git a/misc/buildroot/toolchain/dependencies/dependencies.mk b/misc/buildroot/toolchain/dependencies/dependencies.mk
new file mode 100644
index 000000000..507132c70
--- /dev/null
+++ b/misc/buildroot/toolchain/dependencies/dependencies.mk
@@ -0,0 +1,25 @@
+######################################################################
+#
+# Check buildroot dependencies and bail out if the user's
+# system is judged to be lacking....
+#
+######################################################################
+
+dependencies:
+ @HOSTCC="$(firstword $(HOSTCC))" MAKE="$(MAKE)" $(TOPDIR)/toolchain/dependencies/dependencies.sh
+
+dependencies-source:
+
+dependencies-clean:
+ rm -f $(SSTRIP_TARGET)
+
+dependencies-dirclean:
+ true
+
+#############################################################
+#
+# Toplevel Makefile options
+#
+#############################################################
+.PHONY: dependencies
+
diff --git a/misc/buildroot/toolchain/dependencies/dependencies.sh b/misc/buildroot/toolchain/dependencies/dependencies.sh
new file mode 100755
index 000000000..de0d187bd
--- /dev/null
+++ b/misc/buildroot/toolchain/dependencies/dependencies.sh
@@ -0,0 +1,316 @@
+#!/bin/sh
+# vi: set sw=4 ts=4:
+# set -x
+
+echo ""
+echo "Checking build system dependencies:"
+
+#############################################################
+#
+# check build system 'environment'
+#
+#############################################################
+
+if test -n "$CC" ; then
+ echo "CC clean: FALSE"
+ echo ""
+ echo ""
+ echo "You must run 'unset CC' so buildroot can run with"
+ echo "a clean environment on your build machine"
+ echo ""
+ exit 1
+fi
+echo "CC clean: Ok"
+
+if test -n "$CXX" ; then
+ echo "CXX clean: FALSE"
+ echo ""
+ echo ""
+ echo "You must run 'unset CXX' so buildroot can run with"
+ echo "a clean environment on your build machine"
+ echo ""
+ exit 1
+fi
+echo "CXX clean: Ok"
+
+if test -n "$CPP" ; then
+ echo "CPP clean: FALSE"
+ echo ""
+ echo ""
+ echo "You must run 'unset CPP' so buildroot can run with"
+ echo "a clean environment on your build machine"
+ echo ""
+ exit 1
+fi
+echo "CPP clean: Ok"
+
+if test -n "$CFLAGS" ; then
+ echo "CFLAGS clean: FALSE"
+ echo ""
+ echo ""
+ echo "You must run 'unset CFLAGS' so buildroot can run with"
+ echo "a clean environment on your build machine"
+ echo ""
+ exit 1
+fi
+echo "CFLAGS clean: Ok"
+
+if test -n "$INCLUDES" ; then
+ echo "INCLUDES clean: FALSE"
+ echo "WARNING: INCLUDES contains:"
+ echo " '$INCLUDES'"
+else
+ echo "INCLUDES clean: Ok"
+fi
+
+if test -n "$CXXFLAGS" ; then
+ echo "CXXFLAGS clean: FALSE"
+ echo ""
+ echo ""
+ echo "You must run 'unset CXXFLAGS' so buildroot can run with"
+ echo "a clean environment on your build machine"
+ echo ""
+ exit 1
+fi
+echo "CXXFLAGS clean: Ok"
+
+echo "WORKS" | grep "WORKS" >/dev/null 2>&1
+if test $? != 0 ; then
+ echo "grep works: FALSE"
+ exit 1
+fi
+
+# sanity check for CWD in LD_LIBRARY_PATH
+# try not to rely on egrep..
+if test -n "$LD_LIBRARY_PATH" ; then
+ echo TRiGGER_start"$LD_LIBRARY_PATH"TRiGGER_end | grep ':.:' >/dev/null 2>&1 ||
+ echo TRiGGER_start"$LD_LIBRARY_PATH"TRiGGER_end | grep 'TRiGGER_start:' >/dev/null 2>&1 ||
+ echo TRiGGER_start"$LD_LIBRARY_PATH"TRiGGER_end | grep ':TRiGGER_end' >/dev/null 2>&1 ||
+ echo TRiGGER_start"$LD_LIBRARY_PATH"TRiGGER_end | grep '::' >/dev/null 2>&1
+ if test $? = 0; then
+ echo "LD_LIBRARY_PATH sane: FALSE"
+ echo "You seem to have the current working directory in your"
+ echo "LD_LIBRARY_PATH environment variable. This doesn't work."
+ exit 1;
+ else
+ echo "LD_LIBRARY_PATH sane: Ok"
+ fi
+fi
+
+#############################################################
+#
+# check build system 'sed'
+#
+#############################################################
+
+if test -x /usr/bin/sed ; then
+ SED="/usr/bin/sed"
+else
+ if test -x /bin/sed ; then
+ SED="/bin/sed"
+ else
+ SED="sed"
+ fi
+fi
+echo "HELLO" > .sedtest
+$SED -i -e "s/HELLO/GOODBYE/" .sedtest >/dev/null 2>&1
+if test $? != 0 ; then
+ echo "sed works: No"
+ exit 1
+else
+ echo "sed works: Ok"
+fi
+rm -f .sedtest
+
+#############################################################
+#
+# check build system 'which'
+#
+#############################################################
+
+if ! which which > /dev/null ; then
+ echo "which installed: FALSE"
+ echo ""
+ echo ""
+ echo "You must install 'which' on your build machine"
+ echo ""
+ exit 1
+fi
+echo "which installed: Ok"
+
+#############################################################
+#
+# check build system 'make'
+#
+#############################################################
+
+MAKE=$(which make)
+if [ -z "$MAKE" ] ; then
+ echo "make installed: FALSE"
+ echo ""
+ echo ""
+ echo "You must install 'make' on your build machine"
+ echo ""
+ exit 1
+fi
+
+MAKE_VERSION=$($MAKE --version 2>&1 | head -n1 | $SED -e 's/^.* \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g')
+if [ -z "$MAKE_VERSION" ] ; then
+ echo "make installed: FALSE"
+ echo ""
+ echo ""
+ echo "You must install 'make' on your build machine"
+ echo ""
+ exit 1
+fi
+
+MAKE_MAJOR=$(echo $MAKE_VERSION | $SED -e "s/\..*//g")
+MAKE_MINOR=$(echo $MAKE_VERSION | $SED -e "s/^$MAKE_MAJOR\.//g" -e "s/\..*//g" -e "s/[a-zA-Z].*//g")
+if [ $MAKE_MAJOR -lt 3 -o $MAKE_MAJOR -eq 3 -a $MAKE_MINOR -lt 8 ] ; then
+ echo "You have make '$MAKE_VERSION' installed. GNU make >=3.80 is required"
+ exit 1;
+fi
+echo "GNU make version '$MAKE_VERSION': Ok"
+
+#############################################################
+#
+# check build system 'gcc'
+#
+#############################################################
+
+COMPILER=$(which $HOSTCC)
+if [ -z "$COMPILER" ] ; then
+ COMPILER=$(which cc)
+fi
+
+if [ -z "$COMPILER" ] ; then
+ echo "C Compiler installed: FALSE"
+ echo ""
+ echo ""
+ echo "You must install 'gcc' on your build machine"
+ echo ""
+ exit 1
+fi
+
+COMPILER_VERSION=$($COMPILER -v 2>&1 | $SED -n '/^gcc version/p' |
+ $SED -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q')
+if [ -z "$COMPILER_VERSION" ] ; then
+ echo "gcc installed: FALSE"
+ echo ""
+ echo ""
+ echo "You must install 'gcc' on your build machine"
+ echo ""
+ exit 1
+fi
+
+COMPILER_MAJOR=$(echo $COMPILER_VERSION | $SED -e "s/\..*//g")
+COMPILER_MINOR=$(echo $COMPILER_VERSION | $SED -e "s/^$COMPILER_MAJOR\.//g" -e "s/\..*//g")
+if [ $COMPILER_MAJOR -lt 3 -o $COMPILER_MAJOR -eq 2 -a $COMPILER_MINOR -lt 95 ] ; then
+ echo "You have gcc '$COMPILER_VERSION' installed. gcc >= 2.95 is required"
+ exit 1;
+fi
+echo "C compiler '$COMPILER'"
+echo "C compiler version '$COMPILER_VERSION': Ok"
+
+# check for host CXX
+CXXCOMPILER=$(which $HOSTCXX 2>/dev/null)
+if [ -z "$CXXCOMPILER" ] ; then
+ CXXCOMPILER=$(which c++ 2>/dev/null)
+fi
+
+if [ -z "$CXXCOMPILER" ] ; then
+ echo "C++ Compiler installed: FALSE"
+ echo ""
+ echo "You may have to install 'g++' on your build machine"
+ echo ""
+ #exit 1
+fi
+
+if [ ! -z "$CXXCOMPILER" ] ; then
+ CXXCOMPILER_VERSION=$($CXXCOMPILER -v 2>&1 | $SED -n '/^gcc version/p' |
+ $SED -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q')
+ if [ -z "$CXXCOMPILER_VERSION" ] ; then
+ echo "c++ installed: FALSE"
+ echo ""
+ echo "You may have to install 'g++' on your build machine"
+ echo ""
+ #exit 1
+ fi
+
+ CXXCOMPILER_MAJOR=$(echo $CXXCOMPILER_VERSION | $SED -e "s/\..*//g")
+ CXXCOMPILER_MINOR=$(echo $CXXCOMPILER_VERSION | $SED -e "s/^$CXXCOMPILER_MAJOR\.//g" -e "s/\..*//g")
+ if [ $CXXCOMPILER_MAJOR -lt 3 -o $CXXCOMPILER_MAJOR -eq 2 -a $CXXCOMPILER_MINOR -lt 95 ] ; then
+ echo "You have g++ '$CXXCOMPILER_VERSION' installed. g++ >= 2.95 is required"
+ exit 1
+ fi
+ echo "C++ compiler '$CXXCOMPILER'"
+ echo "C++ compiler version '$CXXCOMPILER_VERSION': Ok"
+fi
+
+#############################################################
+#
+# check build system 'bison'
+#
+#############################################################
+
+if ! which bison > /dev/null ; then
+ echo "bison installed: FALSE"
+ echo ""
+ echo ""
+ echo "You must install 'bison' on your build machine"
+ echo ""
+ exit 1
+fi
+echo "bison installed: Ok"
+
+#############################################################
+#
+# check build system 'flex'
+#
+#############################################################
+
+if ! which flex > /dev/null ; then
+ echo "flex installed: FALSE"
+ echo ""
+ echo ""
+ echo "You must install 'flex' on your build machine"
+ echo ""
+ exit 1
+fi
+echo "flex installed: Ok"
+
+#############################################################
+#
+# check build system 'gettext'
+#
+#############################################################
+
+if ! which msgfmt > /dev/null ; then
+ echo "gettext installed: FALSE"
+ echo ""
+ echo ""
+ echo "You must install 'gettext' on your build machine"
+ echo ""
+ exit 1
+fi
+echo "gettext installed: Ok"
+
+if ! which makeinfo > /dev/null ; then
+ echo "makeinfo installed: FALSE"
+ echo ""
+ echo ""
+ echo "Most likely some packages will fail to build their documentation"
+ echo "Either install 'makeinfo' on your host or fix the respective packages"
+else
+ echo "makeinfo installed: Ok"
+fi
+
+#############################################################
+#
+# All done
+#
+#############################################################
+
+echo "Build system dependencies: Ok"
+echo ""
+
diff --git a/misc/buildroot/toolchain/gcc/3.3.6/120-softfloat.patch b/misc/buildroot/toolchain/gcc/3.3.6/120-softfloat.patch
new file mode 100644
index 000000000..f2431896c
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.3.6/120-softfloat.patch
@@ -0,0 +1,14 @@
+--- gcc-3.3.2-old/configure.in 2003-08-09 01:57:21.000000000 -0500
++++ gcc-3.3.2/configure.in 2004-01-15 12:46:29.000000000 -0600
+@@ -1418,6 +1418,11 @@
+ fi
+
+ FLAGS_FOR_TARGET=
++case " $targargs " in
++ *" --nfp "* | *" --without-float "*)
++ FLAGS_FOR_TARGET=$FLAGS_FOR_TARGET' -msoft-float'
++ ;;
++esac
+ case " $target_configdirs " in
+ *" newlib "*)
+ case " $targargs " in
diff --git a/misc/buildroot/toolchain/gcc/3.3.6/500-loop.patch b/misc/buildroot/toolchain/gcc/3.3.6/500-loop.patch
new file mode 100644
index 000000000..476f84b37
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.3.6/500-loop.patch
@@ -0,0 +1,10 @@
+--- gcc/gcc/loop.c 14 Feb 2004 14:46:03 -0000 1.488.2.3
++++ gcc/gcc/loop.c 28 Apr 2004 22:02:53 -0000
+@@ -929,6 +929,7 @@
+ || (! (GET_CODE (SET_SRC (set)) == REG
+ && (REGNO (SET_SRC (set))
+ < FIRST_PSEUDO_REGISTER))))
++ && regno >= FIRST_PSEUDO_REGISTER
+ /* This test is not redundant; SET_SRC (set) might be
+ a call-clobbered register and the life of REGNO
+ might span a call. */
diff --git a/misc/buildroot/toolchain/gcc/3.3.6/800-arm-bigendian.patch b/misc/buildroot/toolchain/gcc/3.3.6/800-arm-bigendian.patch
new file mode 100644
index 000000000..79140ddf0
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.3.6/800-arm-bigendian.patch
@@ -0,0 +1,68 @@
+By Lennert Buytenhek <buytenh@wantstofly.org>
+Adds support for arm*b-linux* big-endian ARM targets
+
+See http://gcc.gnu.org/PR16350
+
+--- gcc-3.3.5-dist/gcc/config/arm/linux-elf.h
++++ gcc-3.3.5/gcc/config/arm/linux-elf.h
+@@ -30,17 +30,34 @@
+ /* Do not assume anything about header files. */
+ #define NO_IMPLICIT_EXTERN_C
+
++/*
++ * 'config.gcc' defines TARGET_BIG_ENDIAN_DEFAULT as 1 for arm*b-*
++ * (big endian) configurations.
++ */
++#if TARGET_BIG_ENDIAN_DEFAULT
++#define TARGET_ENDIAN_DEFAULT ARM_FLAG_BIG_END
++#define TARGET_ENDIAN_OPTION "mbig-endian"
++#define TARGET_LINKER_EMULATION "armelfb_linux"
++#else
++#define TARGET_ENDIAN_DEFAULT 0
++#define TARGET_ENDIAN_OPTION "mlittle-endian"
++#define TARGET_LINKER_EMULATION "armelf_linux"
++#endif
++
+ /* Default is to use APCS-32 mode. */
+ #undef TARGET_DEFAULT
+-#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_MMU_TRAPS)
++#define TARGET_DEFAULT \
++ ( ARM_FLAG_APCS_32 | \
++ ARM_FLAG_MMU_TRAPS | \
++ TARGET_ENDIAN_DEFAULT )
+
+ #define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm6
+
+-#define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux -p"
++#define SUBTARGET_EXTRA_LINK_SPEC " -m " TARGET_LINKER_EMULATION " -p"
+
+ #undef MULTILIB_DEFAULTS
+ #define MULTILIB_DEFAULTS \
+- { "marm", "mlittle-endian", "mhard-float", "mapcs-32", "mno-thumb-interwork" }
++ { "marm", TARGET_ENDIAN_OPTION, "mhard-float", "mapcs-32", "mno-thumb-interwork" }
+
+ #define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__"
+
+@@ -100,7 +117,7 @@
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2} \
+ -X \
+- %{mbig-endian:-EB}" \
++ %{mbig-endian:-EB} %{mlittle-endian:-EL}" \
+ SUBTARGET_EXTRA_LINK_SPEC
+ #endif
+
+--- gcc-3.3.5-dist/gcc/config.gcc
++++ gcc-3.3.5/gcc/config.gcc
+@@ -710,6 +710,11 @@
+ ;;
+ arm*-*-linux*) # ARM GNU/Linux with ELF
+ tm_file="dbxelf.h elfos.h arm/elf.h arm/linux-gas.h arm/linux-elf.h arm/aout.h arm/arm.h"
++ case $target in
++ arm*b-*)
++ tm_defines="TARGET_BIG_ENDIAN_DEFAULT=1 $tm_defines"
++ ;;
++ esac
+ tmake_file="t-slibgcc-elf-ver t-linux arm/t-linux"
+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
+ gnu_ld=yes
diff --git a/misc/buildroot/toolchain/gcc/3.3.6/810-mips-xgot.patch b/misc/buildroot/toolchain/gcc/3.3.6/810-mips-xgot.patch
new file mode 100644
index 000000000..d7d6691ef
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.3.6/810-mips-xgot.patch
@@ -0,0 +1,6 @@
+--- gcc.orig/gcc/config/mips/t-linux 1970-01-01 01:00:00.000000000 +0100
++++ gcc/gcc/config/mips/t-linux 2004-08-26 18:28:12.000000000 +0200
+@@ -0,0 +1,3 @@
++# Compile crtbegin/end with xgot so it works for both
++# normal and large GOTs.
++CRTSTUFF_T_CFLAGS = -Wa,-xgot
diff --git a/misc/buildroot/toolchain/gcc/3.3.6/820-no-mips-empic-relocs.patch b/misc/buildroot/toolchain/gcc/3.3.6/820-no-mips-empic-relocs.patch
new file mode 100644
index 000000000..d5c4c9cb5
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.3.6/820-no-mips-empic-relocs.patch
@@ -0,0 +1,59 @@
+From: cgd at broadcom dot com
+To: gcc-patches at gcc dot gnu dot org
+Cc: mark at codesourcery dot com
+Date: 13 Jun 2004 22:51:30 -0700
+Subject: [trunk + 3.4-branch RFA] don't use empic relocs for mips-linuxeh
+
+This patch changes mips-linux to avoid using embedded-pic relocs for
+its eh data. (Support for generating these for new code is removed in
+current binutils srcs.)
+
+Relating to this, previously, mips-linux and mips64-linux would use
+different representations for their EH data (even for mips64-linux o32
+abi), due to the mips64-linux n32/64 BFDs not supporting the
+embedded-pic relocs. This was a bug.
+
+For more explanation, see the thread of the URL quoted in the comment
+in linux.h.
+
+
+Tested the same w/ sources of about a week ago for c/c++ for
+mips-linux (native) before/after. Also verified .o compatibility
+before/after just to be sure.
+
+I'd like this approved for the branch as well, so 3.4.1 will work
+nicely w/ the next major binutils release.
+
+
+thanks,
+
+chris
+
+2004-06-13 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/linux.h (ASM_PREFERRED_EH_DATA_FORMAT): Redefine
+ to return DW_EH_PE_absptr.
+
+Index: config/mips/linux.h
+===================================================================
+RCS file: /cvs/gcc/gcc/gcc/config/mips/linux.h,v
+retrieving revision 1.77
+diff -u -p -r1.77 linux.h
+--- gcc/gcc/config/mips/linux.h 19 Feb 2004 22:07:51 -0000 1.77
++++ gcc/gcc/config/mips/linux.h 14 Jun 2004 05:49:51 -0000
+@@ -170,10 +170,11 @@ Boston, MA 02111-1307, USA. */
+ #undef FUNCTION_NAME_ALREADY_DECLARED
+ #define FUNCTION_NAME_ALREADY_DECLARED 1
+
+-#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
+- (flag_pic \
+- ? ((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4\
+- : DW_EH_PE_absptr)
++/* If possible, we should attempt to use GP-relative relocs for this
++ (see <a href="http://sources.redhat.com/ml/binutils/2004-05/msg00227.html">http://sources.redhat.com/ml/binutils/2004-05/msg00227.html</a>).
++ However, until that is implement, this just uses standard, absolute
++ references. */
++#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) DW_EH_PE_absptr
+
+ /* The glibc _mcount stub will save $v0 for us. Don't mess with saving
+ it, since ASM_OUTPUT_REG_PUSH/ASM_OUTPUT_REG_POP do not work in the
diff --git a/misc/buildroot/toolchain/gcc/3.3.6/830-gcc-bug-num-22167.patch b/misc/buildroot/toolchain/gcc/3.3.6/830-gcc-bug-num-22167.patch
new file mode 100644
index 000000000..c7419af90
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.3.6/830-gcc-bug-num-22167.patch
@@ -0,0 +1,16 @@
+Index: gcc/gcse.c
+===================================================================
+RCS file: /cvs/gcc/gcc/gcc/gcse.c,v
+retrieving revision 1.288.2.9
+diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.288.2.9 gcse.c
+--- gcc/gcc/gcse.c 30 Oct 2004 18:02:53 -0000 1.288.2.9
++++ gcc/gcc/gcse.c 14 Jul 2005 13:19:57 -0000
+@@ -6445,7 +6445,7 @@ hoist_code (void)
+ insn_inserted_p = 0;
+
+ /* These tests should be the same as the tests above. */
+- if (TEST_BIT (hoist_vbeout[bb->index], i))
++ if (TEST_BIT (hoist_exprs[bb->index], i))
+ {
+ /* We've found a potentially hoistable expression, now
+ we look at every block BB dominates to see if it
diff --git a/misc/buildroot/toolchain/gcc/3.3.6/900-sx12-20101109.patch b/misc/buildroot/toolchain/gcc/3.3.6/900-sx12-20101109.patch
new file mode 100644
index 000000000..e0b3e2fb7
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.3.6/900-sx12-20101109.patch
@@ -0,0 +1,17940 @@
+diff -u -r -N gcc-3.3.6-core-orig/ChangeLog.M68HC11 gcc-3.3.6/ChangeLog.M68HC11
+--- gcc-3.3.6-core-orig/ChangeLog.M68HC11 1970-01-01 01:00:00.000000000 +0100
++++ gcc-3.3.6/ChangeLog.M68HC11 2010-11-09 20:47:16.000000000 +0000
+@@ -0,0 +1,4 @@
++2003-05-18 Stephane Carrez <stcarrez@nerim.fr>
++
++ * configure.in (m68hc11): Configure libstdcxx_version.
++
+diff -u -r -N gcc-3.3.6-core-orig/config.sub gcc-3.3.6/config.sub
+--- gcc-3.3.6-core-orig/config.sub 2003-01-30 23:25:36.000000000 +0000
++++ gcc-3.3.6/config.sub 2010-11-09 20:47:16.000000000 +0000
+@@ -268,7 +268,7 @@
+ | z8k)
+ basic_machine=$basic_machine-unknown
+ ;;
+- m6811 | m68hc11 | m6812 | m68hc12)
++ m6811 | m68hc11 | m6812 | m68hc12 | m9s12x)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+diff -u -r -N gcc-3.3.6-core-orig/configure.in gcc-3.3.6/configure.in
+--- gcc-3.3.6-core-orig/configure.in 2004-01-02 14:09:48.000000000 +0000
++++ gcc-3.3.6/configure.in 2010-11-09 20:47:16.000000000 +0000
+@@ -487,7 +487,7 @@
+ i[3456]86-*-beos*)
+ noconfigdirs="$noconfigdirs gdb target-newlib target-libgloss ${libgcj}"
+ ;;
+- m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
++ m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*|m9s12x-*-*)
+ noconfigdirs="$noconfigdirs target-libiberty ${libstdcxx_version} ${libgcj}"
+ ;;
+ m68k-*-elf*)
+diff -u -r -N gcc-3.3.6-core-orig/gcc/ChangeLog.M68HC11 gcc-3.3.6/gcc/ChangeLog.M68HC11
+--- gcc-3.3.6-core-orig/gcc/ChangeLog.M68HC11 1970-01-01 01:00:00.000000000 +0100
++++ gcc-3.3.6/gcc/ChangeLog.M68HC11 2010-11-09 20:47:16.000000000 +0000
+@@ -0,0 +1,384 @@
++2010-10-28 James Murray <jsm@jsm-net.demon.co.uk>
++ More work on 9s12x target building
++ S12X optimisations in larith.asm
++
++2010-10-26 James Murray <jsm@jsm-net.demon.co.uk>
++ Bump version
++ Include A.E.Smith S12X ldivmod.asm assembler long division
++ Port ldivmod.asm to S12
++ (Earlier work)
++ Support building as 9S12X target to match binutils
++
++2006-01-22 Stephane Carrez <stcarrez@nerim.fr>
++
++ * version.c: Bump to 2006-01-22
++
++2006-01-22 Stephane Carrez <stcarrez@nerim.fr>
++
++ PR savannah/13917
++ * config/m68hc11/m68hc11.c (nonimmediate_noinc_operand): New predicate.
++ * config/m68hc11/m68hc11-protos.h (nonimmediate_noinc_operand): Declare.
++ * config/m68hc11/m68hc11.h (PREDICATE_CODES): Register it.
++ * config/m68hc11/m68hc11.md ("addqi3"): Use it for operand 0, 1.
++ ("uminqi3"): Likewise.
++ ("umaxqi3"): Likewise.
++ ("uminhi3"): Likewise.
++ ("umaxhi3"): Likewise.
++ ("negqi2"): Likewise.
++ ("*ashlqi3_const1", "*ashrqi3_const1"): Likewise.
++ ("lshrhi3_const", "*lshrqi3_const1"): Likewise.
++
++2006-01-20 Stephane Carrez <stcarrez@nerim.fr>
++
++ savannah/15493
++ * config/m68hc11/m68hc11.c (m68hc11_gen_movqi): Must save register
++ A and copy X or Y in it for a move when both operands refer to X or Y.
++
++2005-11-05 Stephane Carrez <stcarrez@nerim.fr>
++
++ PR savannah/13879
++ * expmed.c (make_tree): If we have a constant for SIGN_EXTEND or
++ ZERO_EXTEND, use the mode from the extend node; the constant is VOIDmode
++ and it will crash.
++
++2005-11-05 Stephane Carrez <stcarrez@nerim.fr>
++
++ * expmed.c (store_bit_field): Must apply a correction for big-endian
++ target when the bitfield contains less word than the source constant.
++
++2005-05-15 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.h (REG_VALID_P): The macro can be used with
++ signed numbers passed as argument.
++ * version.c: Bump to 20050515
++
++2005-05-08 Stephane Carrez <stcarrez@nerim.fr>
++
++ PR savannah/12572
++ * config/m68hc11/m68hc11.md ("movhi"): Sign extend the constants in
++ the range 32768..65535 so that the generated set is recognized.
++
++2005-05-08 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md ("mulqi3"): Use general_operand for operand
++ 1 and fix constraints.
++ ("mulqihi3")" Use general_operand for operand 2.
++ * config/m68hc11/m68hc11.c (m68hc11_gen_movqi): Use pula and pulb
++ instead of lda and ldb for 68HC12.
++
++2005-05-08 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11-protos.h (m68hc11_hard_regno_rename_ok): Pass
++ the mode.
++ * config/m68hc11/m68hc11.h (HARD_REGNO_RENAME_OK): Likewise.
++ * config/m68hc11/m68hc11.c (m68hc11_hard_regno_rename_ok): Likewise.
++ * regrename.c (regrename_optimize): Pass the mode in which the register
++ is used.
++
++2005-04-03 Stephane Carrez <stcarrez@nerim.fr>
++
++ PR savannah/12297
++ * config/m68hc11/m68hc11.c (m68hc11_z_replacement): Use emit_insn_after
++ when adding the save Z instruction so that it is part of the good BB.
++
++2005-02-13 Stephane Carrez <stcarrez@nerim.fr>
++
++ PR target/17551
++ * gcse.c (handle_avail_expr): Use gen_move_insn() instead of
++ gen_rtx_SET()
++
++2005-02-13 Stephane Carrez <stcarrez@nerim.fr>
++
++ PR target/16925
++ * config/m68hc11/m68hc11.c (m68hc11_gen_highpart): Handle split of
++ 64-bit constants on 64-bit hosts.
++ (m68hc11_split_logical): Simplify.
++ (m68hc11_split_move): Likewise.
++
++2005-02-12 Stephane Carrez <stcarrez@nerim.fr>
++
++ PR savannah/11813
++ * config/m68hc11/m68hc11.c (reg_or_some_mem_operand): Do not allow
++ the 68HC12 address indirect addressing mode as it is not supported
++ by bset and bclr.
++
++2005-01-29 Stephane Carrez <stcarrez@nerim.fr>
++
++ * version.c (version_string): Bump to 2005-01-29.
++ * config/udivmodsi4.c (__udivmodsi4): Rewrite ediv as it didn't
++ passed the gcc validation.
++
++2005-01-28 Stephane Carrez <stcarrez@nerim.fr>
++
++ From philipljohnson@comcast.net:
++
++ Patch savannah/3626
++ * config/udivmodsi4.c (__udivmodsi4): Use 68HC12 ediv instruction to
++ compute division and modulus.
++
++2004-08-30 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.c (m68hc11_gen_movhi): Fix invalid generation
++ of indexed indirect addressing with movw
++
++2004-08-29 Stephane Carrez <stcarrez@nerim.fr>
++
++ * version.c (version_string): Bump to 2004-08-29.
++
++2004-08-29 Stephane Carrez <stcarrez@nerim.fr>
++
++ * final.c (alter_subreg): Adjust the offset of paradoxical subreg
++ so that we load the correct value.
++
++2004-08-06 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md ("movhi_const0"): Use this pattern only
++ for 68HC11.
++
++2004-08-01 Stephane Carrez <stcarrez@nerim.fr>
++
++ * version.c (version_string): Bump to 2004-08-01 and use gcc 3.3.4.
++
++2004-06-06 Stephane Carrez <stcarrez@nerim.fr>
++
++ PR target/14542
++ * config/m68hc11/m68hc11.md (move peephole2): Emit a use note to avoid
++ a live change of a register after peephole replacement.
++
++2004-06-06 Stephane Carrez <stcarrez@nerim.fr>
++
++ PR target/14457
++ * config/m68hc11/m68hc11.c (splitable_operand): New predicate.
++ * config/m68hc11/m68hc11-protos.h (splitable_operand): Declare.
++ * config/m68hc11/m68hc11.h (PREDICATE_CODES): Register it.
++ (inhibit_libc): Must define.
++ * config/m68hc11/m68hc11.md ("movhi_const0"): Use splitable_operand.
++ ("*andhi3_gen", "iorhi3", "*iorhi3_gen"): Likewise.
++ ("xorhi3"): Likewise.
++
++2004-04-25 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md ("iorqi3_gen"): Use general_operand for
++ first operand.
++ ("*andqi3_gen", "xorqi3"): Likewise.
++ ("subqi3", "*subhi3"): Likewise.
++ ("*addhi3_zext"): Likewise.
++
++2004-04-25 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.h (ASM_OUTPUT_LABELREF): Redefine to strip
++ any name encoding.
++
++2004-03-07 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md ("*lshrsi3_const"): Disable for 68HC12.
++ ("*lshrsi3"): Also accept an immediate for 68HC12.
++ ("*ashrsi3_const"): Likewise.
++ ("*ashrsi3"): Likewise.
++ ("*ashlsi3_const"): Likewise.
++ ("*ashlsi3"): Likewise.
++ ("cmphi_1_hc12"): Compare two hard register by pushing them and
++ comparing with a pop; don't use a split for that.
++ ("cmphi split"): Disable compare split for 68HC12.
++
++2004-03-06 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md ("*lshrsi3_const1"): Allow a memory for
++ operand 1 when operand 0 is a soft register.
++ ("*ashlsi3_const1"): Likewise.
++
++2004-03-06 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.c (m68hc11_gen_movhi): Use 2,-sp to push
++ the stack register.
++
++2004-03-06 Stephane Carrez <stcarrez@nerim.fr>
++
++ * doc/extend.texi (Function Attributes): Document page0, trap and
++ update far documentation.
++
++2004-03-06 Stephane Carrez <stcarrez@nerim.fr>
++
++ PR savannah/4987:
++ * doc/invoke.texi (M68hc1x Options): Document -mrelax
++
++2004-03-06 Stephane Carrez <stcarrez@nerim.fr>
++
++ PR savannah/8028:
++ * config/m68hc11/m68hc11.c (expand_prologue): Don't make an interrupt
++ or a trap handler a far symbol.
++ (m68hc11_initial_elimination_offset): Likewise.
++
++2004-03-06 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md ("*lshrsi3_const1"): Tune constraints
++ to optimize more case where we don't need a scratch register.
++ ("*ashlsi3_const1"): Likewise.
++ ("*pushdi_internal"): New insn and split
++ to separate push from moves.
++ ("*pushdf_internal"): Likewise.
++ ("*pushsf_internal"): Likewise.
++ ("*pushsi_internal"): Likewise.
++ ("movdi_internal"): Use define_insn_and_split; non push operand.
++ ("movdf_internal"): Likewise.
++ ("movsf_internal"): Likewise.
++ ("movsi_internal"): Likewise.
++
++2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.c (m68hc11_addr_mode): New variable.
++ (m68hc11_mov_addr_mode): Likewise.
++ (m68hc11_override_options): Initialize them based on target.
++ (register_indirect_p): Allow a MEM for indirect addressing modes and
++ use flags to control what is allowed.
++ (m68hc11_small_indexed_indirect_p): Use m68hc11_mov_addr_mode for
++ supported addressing modes.
++ (m68hc11_register_indirect_p): Use m68hc11_addr_mode.
++ (go_if_legitimate_address_internal): Likewise.
++ (m68hc11_indirect_p): Likewise and check the mode.
++ (print_operand): Allow a (MEM (MEM)) and generate indirect addressing.
++
++2004-02-22 Stephane Carrez <stcarrez@nerim.fr>
++
++ * version.c: Bump to 20040222 and use gcc 3.3.3.
++
++2003-11-16 Stephane Carrez <stcarrez@nerim.fr>
++
++ * version.c: Bump to 200311116.
++
++2003-11-10 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11-protos.h (m68hc11_page0_symbol_p): Declare.
++ * config/m68hc11/m68hc11.c (m68hc11_page0_symbol_p): New predicate.
++ (m68hc11_indirect_p): Use it.
++ (print_operand): Likewise.
++ (m68hc11_handle_page0_attribute): New function to handle page0
++ attribute
++ (m68hc11_attribute_table): New attribute page0
++ (m68hc11_encode_section_info): Check page0 attribute.
++ * config/m68hc11/m68hc11.md: Use define_insn_and_split
++ (peephole2): New peephole to generate bset/bclr.
++ (peephole): New peephole to optimize compare in few cases and
++ setting of 2 registers from memory.
++
++2003-10-04 Stephane Carrez <stcarrez@nerim.fr>
++
++ * version.c: Bump to 20031004.
++
++2003-10-04 Stephane Carrez <stcarrez@nerim.fr>
++
++ PR savannah/3432:
++ * config/m68hc11/t-m68hc11-gas (MULTILIB_MATCHES): m68hcs12 is
++ identical to m68hc12 for libraries.
++
++2003-10-01 Stephane Carrez <stcarrez@nerim.fr>
++
++ * version.c: Bump to 20031001.
++
++2003-09-30 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md ("*ashldi3_const32"): Adjust first operand
++ if it uses stack pointer register.
++
++2003-09-30 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md (peephole2 "remove one load"): Make sure
++ that register operand 3 does not appear in operand 2.
++
++2003-08-08 Stephane Carrez <stcarrez@nerim.fr>
++
++ * version.c: Bump to 20030808
++
++2003-08-02 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md (peephole2 "leas 2,sp"): Enable it
++ and add a use rtx.
++ (peephole2): New peephole to optimize moves on stack.
++
++2003-07-19 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md (peephole2 abx): Use m68hc11_gen_lowpart
++ to make sure the constant has the appropriate QImode.
++
++2003-07-08 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.h (HAVE_AS_DWARF2_DEBUG_LINE): Don't define
++ as .file/.loc directives are incompatible with linker relaxation.
++
++2003-05-19 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md ("*movqi" split): Don't split when source
++ or destination is d, b or a register.
++
++2003-05-18 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md ("*logicalhi3_zexthi_ashift8): Allow
++ address registers for operand 1 and 2.
++
++2003-05-18 Stephane Carrez <stcarrez@nerim.fr>
++
++ * reload.c (find_reloads_toplev): Do not reload the paradoxical
++ subreg with its wider mode but the register itself.
++
++2003-05-18 Stephane Carrez <stcarrez@nerim.fr>
++
++ Merge 3.0.4-20030501 patchs in 3.3
++
++ 2003-03-12 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md
++ ("movdi_internal", "movdf_internal"): Fix constraints.
++ ("movsi_internal", "movsf_internal"): Likewise.
++ (peephole2): New peephole2 to optimize the address computations
++ by using 'abx' and 'aby'.
++ (peephole2): New peephole2 to optimize 32-bit shift and use only
++ one hard register instead of two.
++ (peephole2): New peephole2 to avoid loading the same value in two
++ different registers.
++
++ 2003-03-12 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md (split "logicalsi3_silshl16_zext"): Split
++ after reload but reject the particular case that generates a xgdx
++ pattern, it must be handled after Z register replacement.
++
++ 2003-03-10 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md ("*addhi3_68hc12"): Accept any constant
++ when adding to X and Y since leax/leay are fast.
++ ("*addhi3"): Accept 'I' constraint when adding to address register.
++
++ 2003-02-27 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md ("*logicalsi3_silshr16"): Accept D reg
++ on all operands.
++
++ 2003-01-10 Stephane Carrez <stcarrez@nerim.fr>
++
++ * config/m68hc11/m68hc11.md ("*logicalsi3_silshl16_zext"): New split.
++ ("*logicalsi3_silshr16"): Fix constraints.
++
++ 2002-02-27 Stephane Carrez <Stephane.Carrez@worldnet.fr>
++
++ * reload.c (find_reloads): Change to RELOAD_FOR_OTHER_ADDRESS any
++ RELOAD_FOR_OPERAND_ADDRESS reloads which is used by a RELOAD_FOR_OTHER
++ reload (ensures correct order of reload insns).
++
++ 2001-07-09 Stephane Carrez <Stephane.Carrez@worldnet.fr>
++
++ * reload1.c (merge_assigned_reloads): After a RELOAD_OTHER merge,
++ fix setting of the reloads of that reload to RELOAD_FOR_OTHER_ADDRESS.
++
++ 2001-06-22 Stephane Carrez <Stephane.Carrez@worldnet.fr>
++
++ * config/m68hc11/m68hc11.h (MAX_BITS_PER_WORD): Define to 32.
++
++ 2001-03-01 Stephane Carrez <Stephane.Carrez@worldnet.fr>
++
++ * reload1.c (merge_assigned_reloads): Change the type of the
++ reload to emit it at the good place after the merge.
++
++ 2001-02-24 Stephane Carrez <Stephane.Carrez@worldnet.fr>
++
++ * reload.c (find_reloads_subreg_address): Call find_reloads_address
++ with the same reload type.
+diff -u -r -N gcc-3.3.6-core-orig/gcc/collect2.c gcc-3.3.6/gcc/collect2.c
+--- gcc-3.3.6-core-orig/gcc/collect2.c 2003-12-08 19:02:39.000000000 +0000
++++ gcc-3.3.6/gcc/collect2.c 2010-11-09 20:47:16.000000000 +0000
+@@ -74,6 +74,10 @@
+ #undef REAL_STRIP_FILE_NAME
+ #endif
+
++#ifdef WIN32
++# define USE_POPEN
++#endif
++
+ /* If we cannot use a special method, use the ordinary one:
+ run nm to find what symbols are present.
+ In a cross-compiler, this means you need a cross nm,
+@@ -444,7 +448,11 @@
+ #endif
+
+ signal (signo, SIG_DFL);
++#ifndef WIN32
+ kill (getpid (), signo);
++#else
++ exit(3);
++#endif
+ }
+
+
+@@ -2081,6 +2089,31 @@
+ if (nm_file_name == 0)
+ fatal ("cannot find `nm'");
+
++#ifdef USE_POPEN
++ p = (char*) xmalloc (strlen (nm_file_name)
++ + strlen (NM_FLAGS)
++ + strlen (prog_name)
++ + 10);
++ strcpy (p, nm_file_name);
++ strcat (p, " ");
++ if (NM_FLAGS[0] != '\0')
++ {
++ strcat (p, NM_FLAGS);
++ strcat (p, " ");
++ }
++ strcat (p, prog_name);
++ inf = popen (p, "r");
++ if (inf == NULL)
++ fatal_perror ("can't popen `%s'", p);
++
++ /* Trace if needed. */
++ if (vflag)
++ fprintf (stderr, " %s\n", p);
++
++ free (p);
++ fflush (stdout);
++ fflush (stderr);
++#else
+ nm_argv[argc++] = nm_file_name;
+ if (NM_FLAGS[0] != '\0')
+ nm_argv[argc++] = NM_FLAGS;
+@@ -2142,6 +2175,7 @@
+
+ if (debug)
+ fprintf (stderr, "\nnm output with constructors/destructors.\n");
++#endif
+
+ /* Read each line of nm output. */
+ while (fgets (buf, sizeof buf, inf) != (char *) 0)
+@@ -2215,7 +2249,11 @@
+ if (fclose (inf) != 0)
+ fatal_perror ("fclose");
+
++#ifdef USE_POPEN
++ pclose (inf);
++#else
+ do_wait (nm_file_name);
++#endif
+
+ signal (SIGINT, int_handler);
+ #ifdef SIGQUIT
+diff -u -r -N gcc-3.3.6-core-orig/gcc/combine.c gcc-3.3.6/gcc/combine.c
+--- gcc-3.3.6-core-orig/gcc/combine.c 2005-01-18 08:39:05.000000000 +0000
++++ gcc-3.3.6/gcc/combine.c 2010-11-09 20:47:16.000000000 +0000
+@@ -6553,7 +6553,7 @@
+ address, we stay there. If we have a comparison, set to COMPARE,
+ but once inside, go back to our default of SET. */
+
+- next_code = (code == MEM || code == PLUS || code == MINUS ? MEM
++ next_code = (code == MEM /* SCz: || code == PLUS || code == MINUS */ ? MEM
+ : ((code == COMPARE || GET_RTX_CLASS (code) == '<')
+ && XEXP (x, 1) == const0_rtx) ? COMPARE
+ : in_code == COMPARE ? SET : in_code);
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config/divmod.c gcc-3.3.6/gcc/config/divmod.c
+--- gcc-3.3.6-core-orig/gcc/config/divmod.c 2000-11-30 08:25:58.000000000 +0000
++++ gcc-3.3.6/gcc/config/divmod.c 2010-11-09 20:47:16.000000000 +0000
+@@ -1,4 +1,21 @@
+-long udivmodsi4 ();
++/* cover the root directory case */
++#if !defined(mc68hc11) && !defined(mc68hc12) && !defined(m9s12x)
++#if defined(target11)
++#define mc68hc11
++#endif
++#if defined(target12)
++#define mc68hc12
++#endif
++#if defined(targets12x)
++#define m9s12x
++#define mc68hc12
++#endif
++#endif
++
++#ifndef mc68hc12
++
++extern unsigned long __udivmodsi4 (unsigned long num, unsigned long den,
++ unsigned long *mod);
+
+ long
+ __divsi3 (long a, long b)
+@@ -18,7 +35,7 @@
+ neg = !neg;
+ }
+
+- res = udivmodsi4 (a, b, 0);
++ res = __udivmodsi4 (a, b, 0);
+
+ if (neg)
+ res = -res;
+@@ -41,10 +58,13 @@
+ if (b < 0)
+ b = -b;
+
+- res = udivmodsi4 (a, b, 1);
++ __udivmodsi4 (a, b, (unsigned long*) &res);
+
+ if (neg)
+ res = -res;
+
+ return res;
+ }
++
++
++#endif /* !mc68hc12 */
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config/larith.asm gcc-3.3.6/gcc/config/larith.asm
+--- gcc-3.3.6-core-orig/gcc/config/larith.asm 1970-01-01 01:00:00.000000000 +0100
++++ gcc-3.3.6/gcc/config/larith.asm 2010-11-09 20:47:16.000000000 +0000
+@@ -0,0 +1,1348 @@
++/* libgcc routines for M68HC11 & M68HC12.
++ Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
++
++This file is part of GNU CC.
++
++GNU CC is free software; you can redistribute it and/or modify it
++under the terms of the GNU General Public License as published by the
++Free Software Foundation; either version 2, or (at your option) any
++later version.
++
++In addition to the permissions in the GNU General Public License, the
++Free Software Foundation gives you unlimited permission to link the
++compiled version of this file with other programs, and to distribute
++those programs without any restriction coming from the use of this
++file. (The General Public License restrictions do apply in other
++respects; for example, they cover modification of the file, and
++distribution when not linked into another program.)
++
++This file is distributed in the hope that it will be useful, but
++WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with this program; see the file COPYING. If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA. */
++
++/* As a special exception, if you link this library with other files,
++ some of which are compiled with GCC, to produce an executable,
++ this library does not by itself cause the resulting executable
++ to be covered by the GNU General Public License.
++ This exception does not however invalidate any other reasons why
++ the executable file might be covered by the GNU General Public License. */
++
++ .file "larith.asm"
++
++#ifdef __HAVE_SHORT_INT__
++ .mode mshort
++#else
++ .mode mlong
++#endif
++
++ .macro declare_near name
++ .globl \name
++ .type \name,@function
++ .size \name,.Lend-\name
++\name:
++ .endm
++
++#if defined(__USE_RTC__)
++# define ARG(N) N+1
++
++ .macro ret
++#if defined(mc68hc12)
++ rtc
++#else
++ jmp __return_32
++#endif
++ .endm
++
++ .macro declare name
++ .globl \name
++ .type \name,@function
++ .size \name,.Lend-\name
++ .far \name
++\name:
++ .endm
++
++ .macro farsym name
++ .far NAME
++ .endm
++
++#else
++# define ARG(N) N
++
++ .macro ret
++ rts
++ .endm
++
++ .macro farsym name
++ .endm
++
++ .macro declare name
++ .globl \name
++ .type \name,@function
++ .size \name,.Lend-\name
++\name:
++ .endm
++
++#endif
++
++ .sect .text
++
++
++#define REG(NAME) \
++NAME: .dc.w 1; \
++ .type NAME,@object ; \
++ .size NAME,2
++
++#ifdef L_regs_min
++/* Pseudo hard registers used by gcc.
++ They should be located in page0. */
++
++ .sect .softregs
++ .globl _.tmp
++ .globl _.z,_.xy
++REG(_.tmp)
++REG(_.z)
++REG(_.xy)
++
++#endif
++
++#ifdef L_regs_frame
++ .sect .softregs
++ .globl _.frame
++REG(_.frame)
++#endif
++
++#ifdef L_regs_d1_2
++ .sect .softregs
++ .globl _.d1,_.d2
++REG(_.d1)
++REG(_.d2)
++#endif
++
++#ifdef L_regs_d3_4
++ .sect .softregs
++ .globl _.d3,_.d4
++REG(_.d3)
++REG(_.d4)
++#endif
++
++#ifdef L_regs_d5_6
++ .sect .softregs
++ .globl _.d5,_.d6
++REG(_.d5)
++REG(_.d6)
++#endif
++
++#ifdef L_regs_d7_8
++ .sect .softregs
++ .globl _.d7,_.d8
++REG(_.d7)
++REG(_.d8)
++#endif
++
++#ifdef L_regs_d9_16
++/* Pseudo hard registers used by gcc.
++ They should be located in page0. */
++ .sect .softregs
++ .globl _.d9,_.d10,_.d11,_.d12,_.d13,_.d14
++ .globl _.d15,_.d16
++REG(_.d9)
++REG(_.d10)
++REG(_.d11)
++REG(_.d12)
++REG(_.d13)
++REG(_.d14)
++REG(_.d15)
++REG(_.d16)
++
++#endif
++
++#ifdef L_regs_d17_32
++/* Pseudo hard registers used by gcc.
++ They should be located in page0. */
++ .sect .softregs
++ .globl _.d17,_.d18,_.d19,_.d20,_.d21,_.d22
++ .globl _.d23,_.d24,_.d25,_.d26,_.d27,_.d28
++ .globl _.d29,_.d30,_.d31,_.d32
++REG(_.d17)
++REG(_.d18)
++REG(_.d19)
++REG(_.d20)
++REG(_.d21)
++REG(_.d22)
++REG(_.d23)
++REG(_.d24)
++REG(_.d25)
++REG(_.d26)
++REG(_.d27)
++REG(_.d28)
++REG(_.d29)
++REG(_.d30)
++REG(_.d31)
++REG(_.d32)
++#endif
++
++#ifdef L_premain
++;;
++;; Specific initialization for 68hc11 before the main.
++;; Nothing special for a generic routine; Just enable interrupts.
++;;
++ declare_near __premain
++ clra
++ tap ; Clear both I and X.
++ rts
++#endif
++
++#ifdef L__exit
++;;
++;; Exit operation. Just loop forever and wait for interrupts.
++;; (no other place to go)
++;; This operation is split in several pieces collected together by
++;; the linker script. This allows to support destructors at the
++;; exit stage while not impacting program sizes when there is no
++;; destructors.
++;;
++;; _exit:
++;; *(.fini0) /* Beginning of finish code (_exit symbol). */
++;; *(.fini1) /* Place holder for applications. */
++;; *(.fini2) /* C++ destructors. */
++;; *(.fini3) /* Place holder for applications. */
++;; *(.fini4) /* Runtime exit. */
++;;
++ .sect .fini0,"ax",@progbits
++ .globl _exit
++ .globl exit
++ .weak exit
++ farsym exit
++ farsym _exit
++exit:
++_exit:
++
++ .sect .fini4,"ax",@progbits
++fatal:
++ cli
++ wai
++ bra fatal
++#endif
++
++#ifdef L_abort
++;;
++;; Abort operation. This is defined for the GCC testsuite.
++;;
++ declare abort
++
++ ldd #255 ;
++#ifdef mc68hc12
++ trap #0x30
++#else
++ .byte 0xCD ; Generate an illegal instruction trap
++ .byte 0x03 ; The simulator catches this and stops.
++#endif
++ jmp _exit
++#endif
++
++#ifdef L_cleanup
++;;
++;; Cleanup operation used by exit().
++;;
++ declare _cleanup
++
++ ret
++#endif
++
++;-----------------------------------------
++; required gcclib code
++;-----------------------------------------
++#ifdef L_memcpy
++ declare memcpy
++ declare __memcpy
++
++ .weak memcpy
++;;;
++;;; void* memcpy(void*, const void*, size_t)
++;;;
++;;; D = dst Pmode
++;;; 2,sp = src Pmode
++;;; 4,sp = size HImode (size_t)
++;;;
++#ifdef mc68hc12
++ ldx ARG(2),sp
++ ldy ARG(4),sp
++ pshd
++ xgdy
++ lsrd
++ bcc Start
++ movb 1,x+,1,y+
++Start:
++ beq Done
++Loop:
++ movw 2,x+,2,y+
++ dbne d,Loop
++Done:
++ puld
++ ret
++#else
++ xgdy
++ tsx
++ ldd ARG(4),x
++ ldx ARG(2),x ; SRC = X, DST = Y
++ cpd #0
++ beq End
++ pshy
++ inca ; Correction for the deca below
++L0:
++ psha ; Save high-counter part
++L1:
++ ldaa 0,x ; Copy up to 256 bytes
++ staa 0,y
++ inx
++ iny
++ decb
++ bne L1
++ pula
++ deca
++ bne L0
++ puly ; Restore Y to return the DST
++End:
++ xgdy
++ ret
++#endif
++#endif
++
++#ifdef L_memset
++ declare memset
++ declare __memset
++;;;
++;;; void* memset(void*, int value, size_t)
++;;;
++#ifndef __HAVE_SHORT_INT__
++;;; D = dst Pmode
++;;; 2,sp = src SImode
++;;; 6,sp = size HImode (size_t)
++ val = ARG(5)
++ size = ARG(6)
++#else
++;;; D = dst Pmode
++;;; 2,sp = src SImode
++;;; 6,sp = size HImode (size_t)
++ val = ARG(3)
++ size = ARG(4)
++#endif
++#ifdef mc68hc12
++ xgdx
++ ldab val,sp
++ ldy size,sp
++ pshx
++ beq End
++Loop:
++ stab 1,x+
++ dbne y,Loop
++End:
++ puld
++ ret
++#else
++ xgdx
++ tsy
++ ldab val,y
++ ldy size,y ; DST = X, CNT = Y
++ beq End
++ pshx
++L0:
++ stab 0,x ; Fill up to 256 bytes
++ inx
++ dey
++ bne L0
++ pulx ; Restore X to return the DST
++End:
++ xgdx
++ ret
++#endif
++#endif
++
++#ifdef L_adddi3
++ declare ___adddi3
++
++ tsx
++ xgdy
++ ldd ARG(8),x ; Add LSB
++ addd ARG(16),x
++ std 6,y ; Save (carry preserved)
++
++ ldd ARG(6),x
++ adcb ARG(15),x
++ adca ARG(14),x
++ std 4,y
++
++ ldd ARG(4),x
++ adcb ARG(13),x
++ adca ARG(12),x
++ std 2,y
++
++ ldd ARG(2),x
++ adcb ARG(11),x ; Add MSB
++ adca ARG(10),x
++ std 0,y
++
++ xgdy
++ ret
++#endif
++
++#ifdef L_subdi3
++ declare ___subdi3
++
++ tsx
++ xgdy
++ ldd ARG(8),x ; Subtract LSB
++ subd ARG(16),x
++ std 6,y ; Save, borrow preserved
++
++ ldd ARG(6),x
++ sbcb ARG(15),x
++ sbca ARG(14),x
++ std 4,y
++
++ ldd ARG(4),x
++ sbcb ARG(13),x
++ sbca ARG(12),x
++ std 2,y
++
++ ldd ARG(2),x ; Subtract MSB
++ sbcb ARG(11),x
++ sbca ARG(10),x
++ std 0,y
++
++ xgdy ;
++ ret
++#endif
++
++#ifdef L_notdi2
++ declare ___notdi2
++
++ tsy
++ xgdx
++ ldd ARG(8),y
++ coma
++ comb
++ std 6,x
++
++ ldd ARG(6),y
++ coma
++ comb
++ std 4,x
++
++ ldd ARG(4),y
++ coma
++ comb
++ std 2,x
++
++ ldd ARG(2),y
++ coma
++ comb
++ std 0,x
++ xgdx
++ ret
++#endif
++
++#ifdef L_negsi2
++ declare_near ___negsi2
++
++ comb
++ coma
++ xgdx
++ comb
++ coma
++ inx
++ xgdx
++ bne done
++ inx
++done:
++ rts
++#endif
++
++#ifdef L_one_cmplsi2
++ declare_near ___one_cmplsi2
++
++ comb
++ coma
++ xgdx
++ comb
++ coma
++ xgdx
++ rts
++#endif
++
++#ifdef L_ashlsi3
++ declare_near ___ashlsi3
++
++ xgdy
++ clra
++ andb #0x1f
++ xgdy
++ beq Return
++Loop:
++ lsld
++ xgdx
++ rolb
++ rola
++ xgdx
++ dey
++ bne Loop
++Return:
++ rts
++#endif
++
++#ifdef L_ashrsi3
++ declare_near ___ashrsi3
++
++ xgdy
++ clra
++ andb #0x1f
++ xgdy
++ beq Return
++Loop:
++ xgdx
++ asra
++ rorb
++ xgdx
++ rora
++ rorb
++ dey
++ bne Loop
++Return:
++ rts
++#endif
++
++#ifdef L_lshrsi3
++ declare_near ___lshrsi3
++
++ xgdy
++ clra
++ andb #0x1f
++ xgdy
++ beq Return
++Loop:
++ xgdx
++ lsrd
++ xgdx
++ rora
++ rorb
++ dey
++ bne Loop
++Return:
++ rts
++#endif
++
++#ifdef L_lshrhi3
++ declare_near ___lshrhi3
++
++ cpx #16
++ bge Return_zero
++ cpx #0
++ beq Return
++Loop:
++ lsrd
++ dex
++ bne Loop
++Return:
++ rts
++Return_zero:
++ clra
++ clrb
++ rts
++#endif
++
++#ifdef L_lshlhi3
++ declare_near ___lshlhi3
++
++ cpx #16
++ bge Return_zero
++ cpx #0
++ beq Return
++Loop:
++ lsld
++ dex
++ bne Loop
++Return:
++ rts
++Return_zero:
++ clra
++ clrb
++ rts
++#endif
++
++#ifdef L_rotrhi3
++ declare_near ___rotrhi3
++
++___rotrhi3:
++ xgdx
++ clra
++ andb #0x0f
++ xgdx
++ beq Return
++Loop:
++ tap
++ rorb
++ rora
++ dex
++ bne Loop
++Return:
++ rts
++#endif
++
++#ifdef L_rotlhi3
++ declare_near ___rotlhi3
++
++___rotlhi3:
++ xgdx
++ clra
++ andb #0x0f
++ xgdx
++ beq Return
++Loop:
++ asrb
++ rolb
++ rola
++ rolb
++ dex
++ bne Loop
++Return:
++ rts
++#endif
++
++#ifdef L_ashrhi3
++ declare_near ___ashrhi3
++
++ cpx #16
++ bge Return_minus_1_or_zero
++ cpx #0
++ beq Return
++Loop:
++ asra
++ rorb
++ dex
++ bne Loop
++Return:
++ rts
++Return_minus_1_or_zero:
++ clrb
++ tsta
++ bpl Return_zero
++ comb
++Return_zero:
++ tba
++ rts
++#endif
++
++#ifdef L_ashrqi3
++ declare_near ___ashrqi3
++
++ cmpa #8
++ bge Return_minus_1_or_zero
++ tsta
++ beq Return
++Loop:
++ asrb
++ deca
++ bne Loop
++Return:
++ rts
++Return_minus_1_or_zero:
++ clrb
++ tstb
++ bpl Return_zero
++ coma
++Return_zero:
++ tab
++ rts
++#endif
++
++#ifdef L_lshlqi3
++ declare_near ___lshlqi3
++
++ cmpa #8
++ bge Return_zero
++ tsta
++ beq Return
++Loop:
++ lslb
++ deca
++ bne Loop
++Return:
++ rts
++Return_zero:
++ clrb
++ rts
++#endif
++
++#ifdef L_divmodhi4
++#ifndef mc68hc12
++/* 68HC12 signed divisions are generated inline (idivs). */
++
++ declare_near __divmodhi4
++
++;
++;; D = numerator
++;; X = denominator
++;;
++;; Result: D = D / X
++;; X = D % X
++;;
++ tsta
++ bpl Numerator_pos
++ comb ; D = -D <=> D = (~D) + 1
++ coma
++ xgdx
++ inx
++ tsta
++ bpl Numerator_neg_denominator_pos
++Numerator_neg_denominator_neg:
++ comb ; X = -X
++ coma
++ addd #1
++ xgdx
++ idiv
++ coma
++ comb
++ xgdx ; Remainder <= 0 and result >= 0
++ inx
++ rts
++
++Numerator_pos_denominator_pos:
++ xgdx
++ idiv
++ xgdx ; Both values are >= 0
++ rts
++
++Numerator_pos:
++ xgdx
++ tsta
++ bpl Numerator_pos_denominator_pos
++Numerator_pos_denominator_neg:
++ coma ; X = -X
++ comb
++ xgdx
++ inx
++ idiv
++ xgdx ; Remainder >= 0 but result <= 0
++ coma
++ comb
++ addd #1
++ rts
++
++Numerator_neg_denominator_pos:
++ xgdx
++ idiv
++ coma ; One value is > 0 and the other < 0
++ comb ; Change the sign of result and remainder
++ xgdx
++ inx
++ coma
++ comb
++ addd #1
++ rts
++#endif /* !mc68hc12 */
++#endif
++
++#ifdef L_mulqi3
++ declare_near ___mulqi3
++
++;
++; short __mulqi3(signed char a, signed char b);
++;
++; signed char a -> register A
++; signed char b -> register B
++;
++; returns the signed result of A * B in register D.
++;
++ tsta
++ bmi A_neg
++ tstb
++ bmi B_neg
++ mul
++ rts
++B_neg:
++ negb
++ bra A_or_B_neg
++A_neg:
++ nega
++ tstb
++ bmi AB_neg
++A_or_B_neg:
++ mul
++ coma
++ comb
++ addd #1
++ rts
++AB_neg:
++ negb
++ mul
++ rts
++#endif
++
++#ifdef L_mulhi3
++ declare_near ___mulhi3
++
++;
++;
++; unsigned short ___mulhi3(unsigned short a, unsigned short b)
++;
++; a = register D
++; b = register X
++;
++#ifdef mc68hc12
++ pshx ; Preserve X
++ exg x,y
++ emul
++ exg x,y
++ pulx
++ rts
++#else
++#ifdef NO_TMP
++ ;
++ ; 16 bit multiplication without temp memory location.
++ ; (smaller but slower)
++ ;
++ pshx ; (4)
++ ins ; (3)
++ pshb ; (3)
++ psha ; (3)
++ pshx ; (4)
++ pula ; (4)
++ pulx ; (5)
++ mul ; (10) B.high * A.low
++ xgdx ; (3)
++ mul ; (10) B.low * A.high
++ abx ; (3)
++ pula ; (4)
++ pulb ; (4)
++ mul ; (10) B.low * A.low
++ pshx ; (4)
++ tsx ; (3)
++ adda 1,x ; (4)
++ pulx ; (5)
++ rts ; (5) 20 bytes
++ ; ---
++ ; 91 cycles
++#else
++ stx *_.tmp ; (4)
++ pshb ; (3)
++ ldab *_.tmp+1 ; (3)
++ mul ; (10) A.high * B.low
++ ldaa *_.tmp ; (3)
++ stab *_.tmp ; (3)
++ pulb ; (4)
++ pshb ; (4)
++ mul ; (10) A.low * B.high
++ addb *_.tmp ; (4)
++ stab *_.tmp ; (3)
++ ldaa *_.tmp+1 ; (3)
++ pulb ; (4)
++ mul ; (10) A.low * B.low
++ adda *_.tmp ; (4)
++ rts ; (5) 24/32 bytes
++ ; 77/85 cycles
++#endif
++#endif
++#endif
++
++#ifdef L_mulhi32
++
++;
++;
++; unsigned long __mulhi32(unsigned short a, unsigned short b)
++;
++; a = register D
++; b = value on stack
++;
++; +---------------+
++; | B low | <- 7,x
++; +---------------+
++; | B high | <- 6,x
++; +---------------+
++; | PC low |
++; +---------------+
++; | PC high |
++; +---------------+
++; | Tmp low |
++; +---------------+
++; | Tmp high |
++; +---------------+
++; | A low |
++; +---------------+
++; | A high |
++; +---------------+ <- 0,x
++;
++;
++; <B-low> 5,x
++; <B-high> 4,x
++; <ret> 2,x
++; <A-low> 1,x
++; <A-high> 0,x
++;
++ declare_near __mulhi32
++
++#ifdef mc68hc12
++ ldy 2,sp
++ emul
++ exg x,y
++ rts
++#else
++ pshx ; Room for temp value
++ pshb
++ psha
++ tsx
++ ldab 6,x
++ mul
++ xgdy ; A.high * B.high
++ ldab 7,x
++ pula
++ mul ; A.high * B.low
++ std 2,x
++ ldaa 1,x
++ ldab 6,x
++ mul ; A.low * B.high
++ addd 2,x
++ stab 2,x
++ tab
++ aby
++ bcc N
++ ldab #0xff
++ aby
++ iny
++N:
++ ldab 7,x
++ pula
++ mul ; A.low * B.low
++ adda 2,x
++ pulx ; Drop temp location
++ pshy ; Put high part in X
++ pulx
++ bcc Ret
++ inx
++Ret:
++ rts
++#endif
++#endif
++
++#ifdef L_mulsi3
++
++;
++; <B-low> 8,y
++; <B-high> 6,y
++; <ret> 4,y
++; <tmp> 2,y
++; <A-low> 0,y
++;
++; D,X -> A
++; Stack -> B
++;
++; The result is:
++;
++; (((A.low * B.high) + (A.high * B.low)) << 16) + (A.low * B.low)
++;
++;
++;
++
++ declare __mulsi3
++
++#ifdef mc68hc12
++
++
++
++ pshd ; Save A.low
++ ldy ARG(4),sp
++ emul ; A.low * B.high
++ ldy ARG(6),sp
++ exg x,d
++ emul ; A.high * B.low
++ leax d,x
++ ldy ARG(6),sp
++ puld
++ emul ; A.low * B.low
++ exg d,y
++ leax d,x
++ exg d,y
++ ret
++#else
++B_low = ARG(8)
++B_high = ARG(6)
++A_low = 0
++A_high = 2
++ pshx
++ pshb
++ psha
++ tsy
++;
++; If B.low is 0, optimize into: (A.low * B.high) << 16
++;
++ ldd B_low,y
++ beq B_low_zero
++;
++; If A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low)
++;
++ cpx #0
++ beq A_high_zero
++ bsr ___mulhi3 ; A.high * B.low
++;
++; If A.low is 0, optimize into: (A.high * B.low) << 16
++;
++ ldx A_low,y
++ beq A_low_zero ; X = 0, D = A.high * B.low
++ std 2,y
++;
++; If B.high is 0, we can avoid the (A.low * B.high) << 16 term.
++;
++ ldd B_high,y
++ beq B_high_zero
++ bsr ___mulhi3 ; A.low * B.high
++ addd 2,y
++ std 2,y
++;
++; Here, we know that A.low and B.low are not 0.
++;
++B_high_zero:
++ ldd B_low,y ; A.low is on the stack
++ bsr __mulhi32 ; A.low * B.low
++ xgdx
++ tsy ; Y was clobbered, get it back
++ addd 2,y
++A_low_zero: ; See A_low_zero_non_optimized below
++ xgdx
++Return:
++ ins
++ ins
++ ins
++ ins
++ ret
++;
++;
++; A_low_zero_non_optimized:
++;
++; At this step, X = 0 and D = (A.high * B.low)
++; Optimize into: (A.high * B.low) << 16
++;
++; xgdx
++; clra ; Since X was 0, clearing D is superfuous.
++; clrb
++; bra Return
++; ----------------
++; B.low == 0, the result is: (A.low * B.high) << 16
++;
++; At this step:
++; D = B.low = 0
++; X = A.high ?
++; A.low is at A_low,y ?
++; B.low is at B_low,y ?
++;
++B_low_zero:
++ ldd A_low,y
++ beq Zero1
++ ldx B_high,y
++ beq Zero2
++ bsr ___mulhi3
++Zero1:
++ xgdx
++Zero2:
++ clra
++ clrb
++ bra Return
++; ----------------
++; A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low)
++;
++; At this step:
++; D = B.low != 0
++; X = A.high = 0
++; A.low is at A_low,y ?
++; B.low is at B_low,y ?
++;
++A_high_zero:
++ ldd A_low,y ; A.low
++ beq Zero1
++ ldx B_high,y ; B.high
++ beq A_low_B_low
++ bsr ___mulhi3
++ std 2,y
++ bra B_high_zero ; Do the (A.low * B.low) and the add.
++
++; ----------------
++; A.high and B.high are 0 optimize into: (A.low * B.low)
++;
++; At this step:
++; D = B.high = 0
++; X = A.low != 0
++; A.low is at A_low,y != 0
++; B.high is at B_high,y = 0
++;
++A_low_B_low:
++ ldd B_low,y ; A.low is on the stack
++ bsr __mulhi32
++ bra Return
++#endif
++#endif
++
++#ifdef L_map_data
++
++ .sect .install2,"ax",@progbits
++ .globl __map_data_section
++ .globl __data_image
++#ifdef mc68hc12
++ .globl __data_section_size
++#endif
++__map_data_section:
++#ifdef mc68hc12
++ ldx #__data_image
++ ldy #__data_section_start
++ ldd #__data_section_size
++ beq Done
++Loop:
++ movb 1,x+,1,y+
++ dbne d,Loop
++#else
++ ldx #__data_image
++ ldy #__data_section_start
++ bra Start_map
++Loop:
++ ldaa 0,x
++ staa 0,y
++ inx
++ iny
++Start_map:
++ cpx #__data_image_end
++ blo Loop
++#endif
++Done:
++
++#endif
++
++#ifdef L_init_bss
++
++ .sect .install2,"ax",@progbits
++ .globl __init_bss_section
++
++__init_bss_section:
++ ldd #__bss_size
++ beq Done
++ ldx #__bss_start
++Loop:
++#ifdef mc68hc12
++ clr 1,x+
++ dbne d,Loop
++#else
++ clr 0,x
++ inx
++ subd #1
++ bne Loop
++#endif
++Done:
++
++#endif
++
++#ifdef L_ctor
++
++; End of constructor table
++ .sect .install3,"ax",@progbits
++ .globl __do_global_ctors
++
++__do_global_ctors:
++ ; Start from the end - sizeof(void*)
++ ldx #__CTOR_END__-2
++ctors_loop:
++ cpx #__CTOR_LIST__
++ blo ctors_done
++ pshx
++ ldx 0,x
++ jsr 0,x
++ pulx
++ dex
++ dex
++ bra ctors_loop
++ctors_done:
++
++#endif
++
++#ifdef L_dtor
++
++ .sect .fini3,"ax",@progbits
++ .globl __do_global_dtors
++
++;;
++;; This piece of code is inserted in the _exit() code by the linker.
++;;
++__do_global_dtors:
++ pshb ; Save exit code
++ psha
++ ldx #__DTOR_LIST__
++dtors_loop:
++ cpx #__DTOR_END__
++ bhs dtors_done
++ pshx
++ ldx 0,x
++ jsr 0,x
++ pulx
++ inx
++ inx
++ bra dtors_loop
++dtors_done:
++ pula ; Restore exit code
++ pulb
++
++#endif
++
++#ifdef L_far_tramp
++#ifdef mc68hc12
++ .sect .tramp,"ax",@progbits
++ .globl __far_trampoline
++
++;; This is a trampoline used by the linker to invoke a function
++;; using rtc to return and being called with jsr/bsr.
++;; The trampoline generated is:
++;;
++;; foo_tramp:
++;; ldy #foo
++;; call __far_trampoline,page(foo)
++;;
++;; The linker transforms:
++;;
++;; jsr foo
++;;
++;; into
++;; jsr foo_tramp
++;;
++;; The linker generated trampoline and _far_trampoline must be in
++;; non-banked memory.
++;;
++__far_trampoline:
++ movb 0,sp, 2,sp ; Copy page register below the caller's return
++ leas 2,sp ; address.
++ jmp 0,y ; We have a 'call/rtc' stack layout now
++ ; and can jump to the far handler
++ ; (whose memory bank is mapped due to the
++ ; call to the trampoline).
++#endif
++
++#ifdef mc68hc11
++ .sect .tramp,"ax",@progbits
++ .globl __far_trampoline
++
++;; Trampoline generated by gcc for 68HC11:
++;;
++;; pshb
++;; ldab #%page(func)
++;; ldy #%addr(func)
++;; jmp __far_trampoline
++;;
++__far_trampoline:
++ psha ; (2) Save function parameter (high)
++ ;; <Read current page in A>
++ psha ; (2)
++ ;; <Set currenge page from B>
++ pshx ; (4)
++ tsx ; (3)
++ ldab 4,x ; (4) Restore function parameter (low)
++ ldaa 2,x ; (4) Get saved page number
++ staa 4,x ; (4) Save it below return PC
++ pulx ; (5)
++ pula ; (3)
++ pula ; (3) Restore function parameter (high)
++ jmp 0,y ; (4)
++#endif
++#endif
++
++#ifdef L_call_far
++#ifdef mc68hc11
++ .sect .tramp,"ax",@progbits
++ .globl __call_a16
++ .globl __call_a32
++;;
++;; The call methods are used for 68HC11 to support memory bank switching.
++;; Every far call is redirected to these call methods. Its purpose is to:
++;;
++;; 1/ Save the current page on the stack (1 byte to follow 68HC12 call frame)
++;; 2/ Install the new page
++;; 3/ Jump to the real function
++;;
++;; The page switching (get/save) is board dependent. The default provided
++;; here does nothing (just create the appropriate call frame).
++;;
++;; Call sequence (10 bytes, 13 cycles):
++;;
++;; ldx #page ; (3)
++;; ldy #func ; (4)
++;; jsr __call_a16 ; (6)
++;;
++;; Call trampoline (11 bytes, 19 cycles):
++;;
++__call_a16:
++ ;; xgdx ; (3)
++ ;; <Read current page in A> ; (3) ldaa _current_page
++ psha ; (2)
++ ;; <Set current page from B> ; (4) staa _current_page
++ ;; xgdx ; (3)
++ jmp 0,y ; (4)
++
++;;
++;; Call sequence (10 bytes, 14 cycles):
++;;
++;; pshb ; (2)
++;; ldab #page ; (2)
++;; ldy #func ; (4)
++;; jsr __call_a32 ; (6)
++;;
++;; Call trampoline (87 bytes, 57 cycles):
++;;
++__call_a32:
++ pshx ; (4)
++ psha ; (2)
++ ;; <Read current page in A> ; (3) ldaa _current_page
++ psha ; (2)
++ ;; <Set current page from B> ; (4) staa _current_page
++ tsx ; (3)
++ ldab 6,x ; (4) Restore function parameter
++ ldaa 5,x ; (4) Move PC return at good place
++ staa 6,x ; (4)
++ ldaa 4,x ; (4)
++ staa 5,x ; (4)
++ pula ; (3)
++ staa 4,x ; (4)
++ pula ; (3)
++ pulx ; (5)
++ jmp 0,y ; (4)
++#endif
++#endif
++
++#ifdef L_return_far
++#ifdef mc68hc11
++ .sect .tramp,"ax",@progbits
++ .globl __return_void
++ .globl __return_16
++ .globl __return_32
++
++__return_void:
++ ;; pulb
++ ;; <Set current page from B> (Board specific)
++ ;; rts
++__return_16:
++ ;; xgdx
++ ;; pulb
++ ;; <Set current page from B> (Board specific)
++ ;; xgdx
++ ;; rts
++__return_32:
++ ;; xgdy
++ ;; pulb
++ ;; <Set current page from B> (Board specific)
++ ;; xgdy
++ ;; rts
++ ins
++ rts
++#endif
++#endif
++.Lend:
++;-----------------------------------------
++; end required gcclib code
++;-----------------------------------------
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/larith.asm gcc-3.3.6/gcc/config/m68hc11/larith.asm
+--- gcc-3.3.6-core-orig/gcc/config/m68hc11/larith.asm 2003-04-12 15:53:47.000000000 +0100
++++ gcc-3.3.6/gcc/config/m68hc11/larith.asm 2010-11-09 20:47:16.000000000 +0000
+@@ -35,6 +35,20 @@
+
+ .file "larith.asm"
+
++/* cover the root directory case */
++#if !defined(mc68hc11) && !defined(mc68hc12) && !defined(m9s12x)
++#if defined(target11)
++#define mc68hc11
++#endif
++#if defined(target12)
++#define mc68hc12
++#endif
++#if defined(targets12x)
++#define m9s12x
++#define mc68hc12
++#endif
++#endif
++
+ #ifdef __HAVE_SHORT_INT__
+ .mode mshort
+ #else
+@@ -402,18 +416,30 @@
+ std 6,y ; Save, borrow preserved
+
+ ldd ARG(6),x
++#if defined(m9s12x)
++ sbed ARG(14),x
++#else
+ sbcb ARG(15),x
+ sbca ARG(14),x
++#endif
+ std 4,y
+
+ ldd ARG(4),x
++#if defined(m9s12x)
++ sbed ARG(12),x
++#else
+ sbcb ARG(13),x
+ sbca ARG(12),x
++#endif
+ std 2,y
+
+ ldd ARG(2),x ; Subtract MSB
++#if defined(m9s12x)
++ sbed ARG(10),x
++#else
+ sbcb ARG(11),x
+ sbca ARG(10),x
++#endif
+ std 0,y
+
+ xgdy ;
+@@ -469,10 +495,14 @@
+
+ comb
+ coma
++#if defined(m9s12x)
++ comx
++#else
+ xgdx
+ comb
+ coma
+ xgdx
++#endif
+ rts
+ #endif
+
+@@ -486,10 +516,14 @@
+ beq Return
+ Loop:
+ lsld
++#if defined(m9s12x)
++ rolx
++#else
+ xgdx
+ rolb
+ rola
+ xgdx
++#endif
+ dey
+ bne Loop
+ Return:
+@@ -505,10 +539,14 @@
+ xgdy
+ beq Return
+ Loop:
++#if defined(m9s12x)
++ asrx
++#else
+ xgdx
+ asra
+ rorb
+ xgdx
++#endif
+ rora
+ rorb
+ dey
+@@ -526,9 +564,13 @@
+ xgdy
+ beq Return
+ Loop:
++#if defined(m9s12x)
++ lsrx
++#else
+ xgdx
+ lsrd
+ xgdx
++#endif
+ rora
+ rorb
+ dey
+@@ -579,10 +621,14 @@
+ declare_near ___rotrhi3
+
+ ___rotrhi3:
++#if defined(m9s12x)
++ andx #0x000f
++#else
+ xgdx
+ clra
+ andb #0x0f
+ xgdx
++#endif
+ beq Return
+ Loop:
+ tap
+@@ -598,10 +644,14 @@
+ declare_near ___rotlhi3
+
+ ___rotlhi3:
++#if defined(m9s12x)
++ andx #0x000f
++#else
+ xgdx
+ clra
+ andb #0x0f
+ xgdx
++#endif
+ beq Return
+ Loop:
+ asrb
+@@ -951,6 +1001,9 @@
+ declare __mulsi3
+
+ #ifdef mc68hc12
++
++
++
+ pshd ; Save A.low
+ ldy ARG(4),sp
+ emul ; A.low * B.high
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/ldivmod.asm gcc-3.3.6/gcc/config/m68hc11/ldivmod.asm
+--- gcc-3.3.6-core-orig/gcc/config/m68hc11/ldivmod.asm 1970-01-01 01:00:00.000000000 +0100
++++ gcc-3.3.6/gcc/config/m68hc11/ldivmod.asm 2010-11-09 20:47:16.000000000 +0000
+@@ -0,0 +1,598 @@
++;;;-----------------------------------------
++
++;;; Hand coded div and mod functions.
++;;; AES 2009
++;;; for S12X platform
++;;;-----------------------------------------
++
++; Re-coded for m68hc12 as well - James Murray October 2010
++
++ .file "ldivmod.asm"
++
++
++/* cover the root directory case */
++#if !defined(mc68hc11) && !defined(mc68hc12) && !defined(m9s12x)
++#if defined(target11)
++#define mc68hc11
++#endif
++#if defined(target12)
++#define mc68hc12
++#endif
++#if defined(targets12x)
++#define m9s12x
++#define mc68hc12
++#endif
++#endif
++
++#if !defined(mc68hc11)
++; not for 68hc11
++
++#ifdef __HAVE_SHORT_INT__
++ .mode mshort
++#else
++ .mode mlong
++#endif
++
++ .macro declare_near name
++ .globl \name
++ .type \name,@function
++ .size \name,.Lend-\name
++\name:
++ .endm
++
++#if defined(__USE_RTC__)
++# define ARG(N) N+1
++
++ .macro ret
++#if defined(mc68hc12)
++ rtc
++#else
++ jmp __return_32
++#endif
++ .endm
++
++ .macro declare name
++ .globl \name
++ .type \name,@function
++ .size \name,.Lend-\name
++ .far \name
++\name:
++ .endm
++
++ .macro farsym name
++ .far NAME
++ .endm
++
++#else
++# define ARG(N) N
++
++ .macro ret
++ rts
++ .endm
++
++ .macro farsym name
++ .endm
++
++ .macro declare name
++ .globl \name
++ .type \name,@function
++ .size \name,.Lend-\name
++\name:
++ .endm
++
++#endif
++
++ .sect .text
++
++
++#define REG(NAME) \
++NAME: .dc.w 1; \
++ .type NAME,@object ; \
++ .size NAME,2
++
++#ifdef L_regs_min
++/* Pseudo hard registers used by gcc.
++ They should be located in page0. */
++
++ .sect .softregs
++ .globl _.tmp
++
++REG(_.tmp)
++#endif
++
++
++
++/* ok, guessing that we get called with a in D and X and B on stack */
++
++;;;
++;;; long __divsi3 ( long num, long den )
++;;;
++
++;;; d == num_low
++;;; x == num_high
++
++;;; sp, ARG(4) == den_high
++;;; sp, ARG(6) == den_low
++;;; return result in XD
++
++;;; calling here we have also pushed 4 extra bytes on stack
++;;; and we dont use a frame pointer
++
++
++udivmodsi:
++ pshy ; preserve y
++ pshd ; save numerator in case ediv fails
++ pshx
++#ifndef m9s12x
++ tst ARG(10), sp ; does denominator fit in uint16 ?
++ bne go_soft_udivmodsi
++ tst ARG(11), sp ; does denominator fit in uint16 ?
++ bne go_soft_udivmodsi
++#else
++ tstw ARG(10), sp ; does denominator fit in uint16 ?
++ bne go_soft_udivmodsi
++#endif
++ tfr x,y ; load num_high into y
++ ldx ARG(12), sp ; load denominator into x
++ ediv
++ bvs go_soft_udivmodsi ; overflow ??
++
++ ;; overwrite denominator on stack with modulus
++ ;; this is ok since c copies args onto stack (???CHECKME)
++
++ std ARG(12), sp
++#ifndef m9s12x
++ clr ARG(10), sp
++ clr ARG(11), sp
++#else
++ clrw ARG(10), sp
++#endif
++
++ ;; return division results in X:D
++#ifndef m9s12x
++ ldx #0
++#else
++ clrx
++#endif
++ tfr y,d
++
++ leas 4, sp ; deallocate stack for numerator save
++ puly ; retrieve y
++ rts
++
++go_soft_udivmodsi:
++#ifndef m9s12x
++ ldy #0
++#else
++ clry
++#endif
++ bra soft_udivmodsi
++
++
++divmodsi:
++
++ pshy ; preserve y
++ pshd ; save numerator in case edivs fails
++ pshx
++ ldy ARG(10),sp ; denominator fits in signed int16 ??
++ beq test_pos
++#ifndef m9s12x
++ xgdy
++ coma
++ comb
++ xgdy
++#else
++ comy
++#endif
++ beq test_neg
++ bra soft_divmodsi
++test_pos:
++ ldy ARG(12),sp
++ bpl hard_divmodsi
++ bra soft_divmodsi
++
++test_neg:
++ ldy ARG(12),sp
++ bpl soft_divmodsi
++
++hard_divmodsi:
++
++ exg x,y
++ edivs ; attempt a divide by hardware
++ bvs soft_divmodsi ; an overflow happened ... do soft divide
++
++#ifndef m9s12x
++ clr ARG(10),sp
++ clr ARG(11),sp
++#else
++ clrw ARG(10),sp
++#endif
++ std ARG(12), sp
++ bpl skip_hdsx_mod ; sign extend modulus
++ movw #0xFFFF, ARG(10), sp
++skip_hdsx_mod:
++
++
++ ;; returned division results in X:D
++#ifndef m9s12x
++ ldx #0
++ xgdy
++ tsta
++ xgdy
++#else
++ clrx
++ tsty
++#endif
++ bpl skip_hdsx_div ; sign extend result
++ ldx #0xFFFF
++
++skip_hdsx_div:
++ tfr y,d
++ leas 4,sp ; deallocate stack
++ puly ; retrieve y
++ rts
++
++soft_divmodsi:
++ ;; numerator in sp and sp+1 ; den in ARG(10) and ARG(12)
++#ifndef m9s12x
++ ldy #0
++#else
++ clry ; use y to evaluate sign of result
++#endif
++ tst 0, sp ; was tstw
++ bpl sd_skip_neg_num
++
++#ifndef m9s12x
++ xgdy
++ orab #3
++ xgdy
++ com 3, sp
++ com 2, sp
++ com 1, sp
++ com 0, sp
++ inc 3, sp
++ bne sd_skip_neg_num
++ inc 2, sp
++ bne sd_skip_neg_num
++ inc 1, sp
++ bne sd_skip_neg_num
++ inc 0, sp
++#else
++ ory #3
++ comw 2, sp
++ comw 0, sp
++ incw 2, sp
++ bne sd_skip_neg_num
++ incw 0, sp
++#endif
++
++sd_skip_neg_num:
++
++ tst ARG(10), sp
++ bpl sd_skip_neg_den ; was tstw
++
++#ifndef m9s12x
++ xgdy
++ eorb #1
++ xgdy
++ com ARG(13), sp
++ com ARG(12), sp
++ com ARG(11), sp
++ com ARG(10), sp
++ inc ARG(13), sp
++ bne sd_skip_neg_den
++ inc ARG(12), sp
++ bne sd_skip_neg_den
++ inc ARG(11), sp
++ bne sd_skip_neg_den
++ inc ARG(10), sp
++#else
++ eory #1
++ comw ARG(12), sp
++ comw ARG(10), sp
++ incw ARG(12), sp
++ bne sd_skip_neg_den
++ incw ARG(10), sp
++#endif
++
++sd_skip_neg_den:
++soft_udivmodsi: ; if called from udivmodsi
++ ; make sure y=0
++ leas -8,sp ; allocate for 'bit' and 'res'
++
++ ;; stack should look like this on entry if ARG(N)=N:
++
++ ;;
++ ;;
++ ;;
++ ;; denominator (SI) --- sp+18
++ ;;
++ ;; return address for calling function (HI) sp+16
++ ;;
++ ;; return address for frontend function (HI) sp+14
++ ;;
++ ;; preserve y ---- sp+12
++ ;;
++ ;;
++ ;;
++ ;; numerator (SI) ---- sp+8
++ ;;
++ ;;
++ ;;
++ ;; bit (SI) ---- sp+4
++ ;;
++ ;;
++ ;;
++ ;; res (SI) ---- sp
++
++#ifndef m9s12x
++ clr 0, sp ; res = 0
++ clr 1, sp
++ clr 2, sp
++ clr 3, sp
++ tst ARG(18),sp
++ bne checked_den
++ tst ARG(19),sp
++ bne checked_den
++ tst ARG(20),sp
++ bne checked_den
++ tst ARG(21),sp
++ beq while_end
++#else
++ clrw 0, sp ; res = 0
++ clrw 2, sp
++ tstw ARG(18),sp
++ bne checked_den
++ tstw ARG(20),sp
++ beq while_end
++#endif
++
++checked_den:
++
++ movw #1, 6, sp
++#ifndef m9s12x
++ clr 4,sp ; bit = 1
++ clr 5,sp ; bit = 1
++#else
++ clrw 4,sp ; bit = 1
++#endif
++
++while_den: ; while ((den < num) && !(den.bit31))
++ tst ARG(18), sp ; was tstw
++ bmi while_bit
++ ldd 10,sp
++ ldx 8,sp
++
++ subd ARG(20), sp
++#ifndef m9s12x
++ xgdx
++ sbcb ARG(19), sp
++ sbca ARG(18), sp
++ xgdx
++#else
++ sbex ARG(18), sp
++#endif
++ bcs while_bit
++
++#ifndef m9s12x
++ asl ARG(21), sp ; den <<= 1
++ rol ARG(20), sp
++ rol ARG(19), sp
++ rol ARG(18), sp
++
++ asl 7,sp ; bit <<= 1
++ rol 6,sp
++ rol 5,sp
++ rol 4,sp
++#else
++ aslw ARG(20), sp ; den <<= 1
++ rolw ARG(18), sp
++
++ aslw 6,sp ; bit <<= 1
++ rolw 4,sp
++#endif
++
++ bra while_den
++
++
++while_bit: ; while (bit!=0)
++#ifndef m9s12x
++ tst 4, sp
++ bne while_bit_ok
++ tst 5, sp
++ bne while_bit_ok
++ tst 6, sp
++ bne while_bit_ok
++ tst 7,sp
++ beq while_end
++#else
++ tstw 4, sp
++ bne while_bit_ok
++ tstw 6,sp
++ beq while_end
++#endif
++
++while_bit_ok:
++
++ ldd 10, sp ; if (num >= den)
++ ldx 8, sp
++ subd ARG(20),sp
++#ifndef m9s12x
++ xgdx
++ sbcb ARG(19),sp
++ sbca ARG(18),sp
++ xgdx
++#else
++ sbex ARG(18),sp
++#endif
++ bcs skip_restore ; here was bmi
++
++ std 10,sp ; num-=den
++ stx 8,sp
++
++#ifndef m9s12x
++ ldd 0,sp ; res|= bit
++ oraa 4,sp
++ orab 5,sp
++ std 0,sp
++ ldd 2,sp
++ oraa 6,sp
++ orab 7,sp
++ std 2,sp
++#else
++ ldx 0,sp ; res|= bit
++ orx 4,sp
++ stx 0,sp
++ ldx 2,sp
++ orx 6,sp
++ stx 2,sp
++#endif
++
++skip_restore:
++
++#ifndef m9s12x
++ lsr 4,sp ; bit >>=1
++ ror 5,sp
++ ror 6,sp
++ ror 7,sp
++
++ lsr ARG(18),sp ; den >>=1
++ ror ARG(19),sp
++ ror ARG(20),sp
++ ror ARG(21),sp
++#else
++ lsrw 4,sp ; bit >>=1
++ rorw 6,sp
++
++ lsrw ARG(18),sp ; den >>=1
++ rorw ARG(20),sp
++#endif
++
++ bra while_bit
++
++while_end:
++ ;; numerator contains mod
++ ;; overwrite denominator with it on stack for return
++// movw 8,sp,ARG(18), sp
++// movw 10,sp, ARG(20), sp
++ leax ARG(18), sp
++ movw 8,sp, 0,x
++ movw 10,sp, 2,x
++
++ ldx 0,sp
++ ldd 2,sp
++
++ leas 12,sp ; deallocate locals
++#ifndef m9s12x
++ xgdy ; do we need to negate result ?
++ tsta
++ bne no_end
++ tstb
++ bne no_end
++ xgdy
++ bra end_division
++no_end:
++ xgdy
++#else
++ tsty ; do we need to negate result ?
++ beq end_division
++#endif
++
++ ;; if y&1 then negate result
++ ;; if y&2 then negate modulus
++
++ pshy
++#ifndef m9s12x
++ xgdy
++ andb #1
++ xgdy
++#else
++ andy #1
++#endif
++ puly
++ beq skip_end_res_neg
++
++ coma
++ comb
++#ifndef m9s12x
++ xgdx
++ coma
++ comb
++ xgdx
++#else
++ comx
++#endif
++ incb
++ bne end_division
++ inca
++ bne end_division
++ inx
++
++skip_end_res_neg:
++#ifndef m9s12x
++ xgdy
++ andb #2
++ xgdy
++#else
++ andy #2
++#endif
++ beq end_division
++
++#ifndef m9s12x
++ com ARG(6), sp
++ com ARG(7), sp
++ com ARG(8), sp
++ com ARG(9), sp
++ inc ARG(9), sp
++ bne end_division
++ inc ARG(8), sp
++ bne end_division
++ inc ARG(7), sp
++ bne end_division
++ inc ARG(6), sp
++#else
++ comw ARG(6), sp
++ comw ARG(8), sp
++ incw ARG(8), sp
++ bne end_division
++ incw ARG(6), sp
++#endif
++
++end_division:
++ puly
++ rts
++
++
++
++;;; si3 frontends for divmodsi3
++
++ declare __divsi3
++ bsr divmodsi
++ ret
++
++ declare __modsi3
++
++ bsr divmodsi
++ ldx ARG(2), sp ; stack has two less on it now
++ ldd ARG(4), sp
++ ret
++
++ declare __umodsi3
++ bsr udivmodsi
++ ldx ARG(2), sp
++ ldd ARG(4), sp
++ ret
++
++
++ declare __udivsi3
++ bsr udivmodsi
++ ret
++
++#endif
++ ; defined(m68hc12) || defined(m9s12x)
++
++
++.Lend:
++;-----------------------------------------
++; end required gcclib code
++;-----------------------------------------
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/ldivmod.asm-s12x_only gcc-3.3.6/gcc/config/m68hc11/ldivmod.asm-s12x_only
+--- gcc-3.3.6-core-orig/gcc/config/m68hc11/ldivmod.asm-s12x_only 1970-01-01 01:00:00.000000000 +0100
++++ gcc-3.3.6/gcc/config/m68hc11/ldivmod.asm-s12x_only 2010-11-09 20:47:16.000000000 +0000
+@@ -0,0 +1,380 @@
++;;;-----------------------------------------
++
++;;; Hand coded div and mod functions.
++;;; AES 2009
++
++;;;-----------------------------------------
++
++
++
++
++ .file "ldivmod.asm"
++
++#ifdef __HAVE_SHORT_INT__
++ .mode mshort
++#else
++ .mode mlong
++#endif
++
++ .macro declare_near name
++ .globl \name
++ .type \name,@function
++ .size \name,.Lend-\name
++\name:
++ .endm
++
++#if defined(__USE_RTC__)
++# define ARG(N) N+1
++
++ .macro ret
++#if defined(mc68hc12)
++ rtc
++#else
++ jmp __return_32
++#endif
++ .endm
++
++ .macro declare name
++ .globl \name
++ .type \name,@function
++ .size \name,.Lend-\name
++ .far \name
++\name:
++ .endm
++
++ .macro farsym name
++ .far NAME
++ .endm
++
++#else
++# define ARG(N) N
++
++ .macro ret
++ rts
++ .endm
++
++ .macro farsym name
++ .endm
++
++ .macro declare name
++ .globl \name
++ .type \name,@function
++ .size \name,.Lend-\name
++\name:
++ .endm
++
++#endif
++
++ .sect .text
++
++
++#define REG(NAME) \
++NAME: .dc.w 1; \
++ .type NAME,@object ; \
++ .size NAME,2
++
++#ifdef L_regs_min
++/* Pseudo hard registers used by gcc.
++ They should be located in page0. */
++
++ .sect .softregs
++ .globl _.tmp
++
++REG(_.tmp)
++#endif
++
++
++
++/* ok, guessing that we get called with a in D and X and B on stack */
++
++;;;
++;;; long __divsi3 ( long num, long den )
++;;;
++
++;;; d == num_low
++;;; x == num_high
++
++;;; sp, ARG(4) == den_high
++;;; sp, ARG(6) == den_low
++;;; return result in XD
++
++;;; calling here we have also pushed 4 extra bytes on stack
++;;; and we dont use a frame pointer
++
++
++udivmodsi:
++ pshy ; preserve y
++ pshd ; save numerator in case ediv fails
++ pshx
++ tstw ARG(10), sp ; does denominator fit in uint16 ?
++ bne go_soft_udivmodsi
++ tfr x,y ; load num_high into y
++ ldx ARG(12), sp ; load denominator into x
++ ediv
++ bvs go_soft_udivmodsi ; overflow ??
++
++ ;; overwrite denominator on stack with modulus
++ ;; this is ok since c copies args onto stack (???CHECKME)
++
++ std ARG(12), sp
++ clrw ARG(10), sp
++
++ ;; return division results in X:D
++ clrx
++ tfr y,d
++
++ leas 4, sp ; deallocate stack for numerator save
++ puly ; retrieve y
++ rts
++
++go_soft_udivmodsi:
++ clry
++ bra soft_udivmodsi
++
++
++divmodsi:
++
++ pshy ; preserve y
++ pshd ; save numerator in case edivs fails
++ pshx
++ ldy ARG(10),sp ; denominator fits in signed int16 ??
++ beq test_pos
++ comy
++ beq test_neg
++ bra soft_divmodsi
++test_pos:
++ ldy ARG(12),sp
++ bpl hard_divmodsi
++ bra soft_divmodsi
++
++test_neg:
++ ldy ARG(12),sp
++ bpl soft_divmodsi
++
++hard_divmodsi:
++
++ exg x,y
++ edivs ; attempt a divide by hardware
++ bvs soft_divmodsi ; an overflow happened ... do soft divide
++
++ clrw ARG(10),sp
++ std ARG(12), sp
++ bpl skip_hdsx_mod ; sign extend modulus
++ movw #0xFFFF, ARG(10), sp
++skip_hdsx_mod:
++
++
++ ;; returned division results in X:D
++ clrx
++ tsty
++ bpl skip_hdsx_div ; sign extend result
++ ldx #0xFFFF
++
++skip_hdsx_div:
++ tfr y,d
++ leas 4,sp ; deallocate stack
++ puly ; retrieve y
++ rts
++
++soft_divmodsi:
++ ;; numerator in sp and sp+1 ; den in ARG(10) and ARG(12)
++ clry ; use y to evaluate sign of result
++ tstw 0, sp
++ bpl sd_skip_neg_num
++
++ ory #3
++ comw 2, sp
++ comw 0, sp
++ incw 2, sp
++ bne sd_skip_neg_num
++ incw 0, sp
++
++
++sd_skip_neg_num:
++
++ tstw ARG(10), sp
++ bpl sd_skip_neg_den
++
++ eory #1
++ comw ARG(12), sp
++ comw ARG(10), sp
++ incw ARG(12), sp
++ bne sd_skip_neg_den
++ incw ARG(10), sp
++
++
++sd_skip_neg_den:
++soft_udivmodsi: ; if called from udivmodsi
++ ; make sure y=0
++ leas -8,sp ; allocate for 'bit' and 'res'
++
++ ;; stack should look like this on entry if ARG(N)=N:
++
++ ;;
++ ;;
++ ;;
++ ;; denominator (SI) --- sp+18
++ ;;
++ ;; return address for calling function (HI) sp+16
++ ;;
++ ;; return address for frontend function (HI) sp+14
++ ;;
++ ;; preserve y ---- sp+12
++ ;;
++ ;;
++ ;;
++ ;; numerator (SI) ---- sp+8
++ ;;
++ ;;
++ ;;
++ ;; bit (SI) ---- sp+4
++ ;;
++ ;;
++ ;;
++ ;; res (SI) ---- sp
++
++ clrw 0, sp ; res = 0
++ clrw 2, sp
++
++ tstw ARG(18),sp
++ bne checked_den
++ tstw ARG(20),sp
++ beq while_end
++
++checked_den:
++
++ movw #1, 6, sp
++ clrw 4,sp ; bit = 1
++
++while_den: ; while ((den < num) && !(den.bit31))
++ tstw ARG(18), sp
++ bmi while_bit
++ ldd 10,sp
++ ldx 8,sp
++
++ subd ARG(20), sp
++ sbex ARG(18), sp
++ bcs while_bit
++
++ aslw ARG(20), sp ; den <<= 1
++ rolw ARG(18), sp
++
++ aslw 6,sp ; bit <<= 1
++ rolw 4,sp
++
++ bra while_den
++
++
++while_bit: ; while (bit!=0)
++ tstw 4, sp
++ bne while_bit_ok
++ tstw 6,sp
++ beq while_end
++
++while_bit_ok:
++
++ ldd 10, sp ; if (num >= den)
++ ldx 8, sp
++ subd ARG(20),sp
++ sbex ARG(18),sp
++ bcs skip_restore ; here was bmi
++
++ std 10,sp ; num-=den
++ stx 8,sp
++
++ ldx 0,sp ; res|= bit
++ orx 4,sp
++ stx 0,sp
++ ldx 2,sp
++ orx 6,sp
++ stx 2,sp
++
++skip_restore:
++
++ lsrw 4,sp ; bit >>=1
++ rorw 6,sp
++
++ lsrw ARG(18),sp ; den >>=1
++ rorw ARG(20),sp
++
++ bra while_bit
++
++while_end:
++ ;; numerator contains mod
++ ;; overwrite denominator with it on stack for return
++// movw 8,sp,ARG(18), sp
++// movw 10,sp, ARG(20), sp
++ leax ARG(18), sp
++ movw 8,sp, 0,x
++ movw 10,sp, 2,x
++
++ ldx 0,sp
++ ldd 2,sp
++
++ leas 12,sp ; deallocate locals
++ tsty ; do we need to negate result ?
++ beq end_division
++
++ ;; if y&1 then negate result
++ ;; if y&2 then negate modulus
++
++ pshy
++ andy #1
++ puly
++ beq skip_end_res_neg
++
++ coma
++ comb
++ comx
++ incb
++ bne end_division
++ inca
++ bne end_division
++ incx
++
++skip_end_res_neg:
++ andy #2
++ beq end_division
++
++ comw ARG(6), sp
++ comw ARG(8), sp
++ incw ARG(8), sp
++ bne end_division
++ incw ARG(6), sp
++
++
++end_division:
++ puly
++ rts
++
++
++
++;;; si3 frontends for divmodsi3
++
++ declare __divsi3
++ bsr divmodsi
++ ret
++
++ declare __modsi3
++
++ bsr divmodsi
++ ldx ARG(2), sp ; stack has two less on it now
++ ldd ARG(4), sp
++ ret
++
++ declare __umodsi3
++ bsr udivmodsi
++ ldx ARG(2), sp
++ ldd ARG(4), sp
++ ret
++
++
++ declare __udivsi3
++ bsr udivmodsi
++ ret
++
++
++.Lend:
++;-----------------------------------------
++; end required gcclib code
++;-----------------------------------------
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11.c gcc-3.3.6/gcc/config/m68hc11/m68hc11.c
+--- gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11.c 2003-04-12 22:53:41.000000000 +0100
++++ gcc-3.3.6/gcc/config/m68hc11/m68hc11.c 2010-11-09 20:47:16.000000000 +0000
+@@ -1,21 +1,22 @@
+ /* Subroutines for code generation on Motorola 68HC11 and 68HC12.
+- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
++ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
++ Free Software Foundation, Inc.
+ Contributed by Stephane Carrez (stcarrez@nerim.fr)
+
+-This file is part of GNU CC.
++This file is part of GCC.
+
+-GNU CC is free software; you can redistribute it and/or modify
++GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+-GNU CC is distributed in the hope that it will be useful,
++GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+-along with GNU CC; see the file COPYING. If not, write to
++along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+@@ -70,6 +71,7 @@
+ static int m68hc11_make_autoinc_notes PARAMS ((rtx*, void*));
+ static int m68hc11_auto_inc_p PARAMS ((rtx));
+ static tree m68hc11_handle_fntype_attribute PARAMS ((tree *, tree, tree, int, bool *));
++static tree m68hc11_handle_page0_attribute PARAMS ((tree *, tree, tree, int, bool *));
+ const struct attribute_spec m68hc11_attribute_table[];
+
+ void create_regs_rtx PARAMS ((void));
+@@ -79,6 +81,7 @@
+ static void m68hc11_asm_out_constructor PARAMS ((rtx, int));
+ static void m68hc11_asm_out_destructor PARAMS ((rtx, int));
+ static void m68hc11_encode_section_info PARAMS((tree, int));
++static const char *m68hc11_strip_name_encoding (const char* str);
+
+ /* Must be set to 1 to produce debug messages. */
+ int debug_m6811 = 0;
+@@ -129,6 +132,16 @@
+ This is 1 for 68HC11 and 0 for 68HC12. */
+ int m68hc11_sp_correction;
+
++#define ADDR_STRICT 0x01 /* Accept only registers in class A_REGS */
++#define ADDR_INCDEC 0x02 /* Post/Pre inc/dec */
++#define ADDR_INDEXED 0x04 /* D-reg index */
++#define ADDR_OFFSET 0x08
++#define ADDR_INDIRECT 0x10 /* Accept (mem (mem ...)) for [n,X] */
++#define ADDR_CONST 0x20 /* Accept const and symbol_ref */
++
++int m68hc11_addr_mode;
++int m68hc11_mov_addr_mode;
++
+ /* Comparison operands saved by the "tstxx" and "cmpxx" expand patterns. */
+ rtx m68hc11_compare_op0;
+ rtx m68hc11_compare_op1;
+@@ -227,6 +240,9 @@
+ #undef TARGET_ENCODE_SECTION_INFO
+ #define TARGET_ENCODE_SECTION_INFO m68hc11_encode_section_info
+
++#undef TARGET_STRIP_NAME_ENCODING
++#define TARGET_STRIP_NAME_ENCODING m68hc11_strip_name_encoding
++
+ struct gcc_target targetm = TARGET_INITIALIZER;
+
+ int
+@@ -264,6 +280,8 @@
+ m68hc11_reg_valid_for_base[HARD_Z_REGNUM] = 1;
+ m68hc11_sp_correction = 1;
+ m68hc11_tmp_regs_class = D_REGS;
++ m68hc11_addr_mode = ADDR_OFFSET;
++ m68hc11_mov_addr_mode = 0;
+ if (m68hc11_soft_reg_count == 0 && !TARGET_M6812)
+ m68hc11_soft_reg_count = "4";
+ }
+@@ -283,6 +301,10 @@
+ m68hc11_reg_valid_for_index[HARD_D_REGNUM] = 1;
+ m68hc11_sp_correction = 0;
+ m68hc11_tmp_regs_class = TMP_REGS;
++ m68hc11_addr_mode = ADDR_INDIRECT | ADDR_OFFSET | ADDR_CONST
++ | (TARGET_AUTO_INC_DEC ? ADDR_INCDEC : 0);
++ m68hc11_mov_addr_mode = ADDR_OFFSET | ADDR_CONST
++ | (TARGET_AUTO_INC_DEC ? ADDR_INCDEC : 0);
+ target_flags &= ~MASK_M6811;
+ target_flags |= MASK_NO_DIRECT_MODE;
+ if (m68hc11_soft_reg_count == 0)
+@@ -316,7 +338,7 @@
+ /* For 68HC12, the Z register emulation is not necessary when the
+ frame pointer is not used. The frame pointer is eliminated and
+ replaced by the stack register (which is a BASE_REG_CLASS). */
+- if (TARGET_M6812 && flag_omit_frame_pointer && optimize)
++ if (TARGET_M6812 && flag_omit_frame_pointer && optimize && 0)
+ {
+ fixed_regs[HARD_Z_REGNUM] = 1;
+ }
+@@ -385,8 +407,9 @@
+ }
+
+ int
+-m68hc11_hard_regno_rename_ok (reg1, reg2)
++m68hc11_hard_regno_rename_ok (reg1, reg2, mode)
+ int reg1, reg2;
++ int mode;
+ {
+ /* Don't accept renaming to Z register. We will replace it to
+ X,Y or D during machine reorg pass. */
+@@ -398,6 +421,11 @@
+ && (D_REGNO_P (reg1) || X_REGNO_P (reg1)))
+ return 0;
+
++ /* Don't rename D as if it holds a 8-bit value, the code will be
++ bigger. */
++ if (mode == QImode && D_REGNO_P (reg1))
++ return 0;
++
+ return 1;
+ }
+
+@@ -522,21 +550,25 @@
+ For 68hc11: n,r with n in [0..255] and r in A_REGS class
+ For 68hc12: n,r no constraint on the constant, r in A_REGS class. */
+ static int
+-register_indirect_p (operand, mode, strict)
+- rtx operand;
+- enum machine_mode mode;
+- int strict;
++register_indirect_p (rtx operand, enum machine_mode mode, int addr_mode)
+ {
+ rtx base, offset;
+
+ switch (GET_CODE (operand))
+ {
++ case MEM:
++ if ((addr_mode & ADDR_INDIRECT) && GET_MODE_SIZE (mode) <= 2)
++ return register_indirect_p (XEXP (operand, 0), mode,
++ addr_mode & (ADDR_STRICT | ADDR_OFFSET));
++ return 0;
++
+ case POST_INC:
+ case PRE_INC:
+ case POST_DEC:
+ case PRE_DEC:
+- if (TARGET_M6812 && TARGET_AUTO_INC_DEC)
+- return register_indirect_p (XEXP (operand, 0), mode, strict);
++ if (addr_mode & ADDR_INCDEC)
++ return register_indirect_p (XEXP (operand, 0), mode,
++ addr_mode & ADDR_STRICT);
+ return 0;
+
+ case PLUS:
+@@ -548,36 +580,57 @@
+ if (GET_CODE (offset) == MEM)
+ return 0;
+
++ /* Indexed addressing mode with 2 registers. */
++ if (GET_CODE (base) == REG && GET_CODE (offset) == REG)
++ {
++ if (!(addr_mode & ADDR_INDEXED))
++ return 0;
++
++ addr_mode &= ADDR_STRICT;
++ if (REGNO_OK_FOR_BASE_P2 (REGNO (base), addr_mode)
++ && REGNO_OK_FOR_INDEX_P2 (REGNO (offset), addr_mode))
++ return 1;
++
++ if (REGNO_OK_FOR_BASE_P2 (REGNO (offset), addr_mode)
++ && REGNO_OK_FOR_INDEX_P2 (REGNO (base), addr_mode))
++ return 1;
++
++ return 0;
++ }
++
++ if (!(addr_mode & ADDR_OFFSET))
++ return 0;
++
+ if (GET_CODE (base) == REG)
+ {
+- if (!VALID_CONSTANT_OFFSET_P (offset, mode))
++ if (!VALID_CONSTANT_OFFSET_P (offset, mode))
+ return 0;
+
+- if (strict == 0)
++ if (!(addr_mode & ADDR_STRICT))
+ return 1;
+
+- return REGNO_OK_FOR_BASE_P2 (REGNO (base), strict);
++ return REGNO_OK_FOR_BASE_P2 (REGNO (base), 1);
+ }
++
+ if (GET_CODE (offset) == REG)
+ {
+ if (!VALID_CONSTANT_OFFSET_P (base, mode))
+ return 0;
+
+- if (strict == 0)
++ if (!(addr_mode & ADDR_STRICT))
+ return 1;
+
+- return REGNO_OK_FOR_BASE_P2 (REGNO (offset), strict);
++ return REGNO_OK_FOR_BASE_P2 (REGNO (offset), 1);
+ }
+ return 0;
+
+ case REG:
+- return REGNO_OK_FOR_BASE_P2 (REGNO (operand), strict);
++ return REGNO_OK_FOR_BASE_P2 (REGNO (operand), addr_mode & ADDR_STRICT);
+
+ case CONST_INT:
+- if (TARGET_M6811)
+- return 0;
+-
+- return VALID_CONSTANT_OFFSET_P (operand, mode);
++ if (addr_mode & ADDR_CONST)
++ return VALID_CONSTANT_OFFSET_P (operand, mode);
++ return 0;
+
+ default:
+ return 0;
+@@ -592,6 +645,7 @@
+ enum machine_mode mode;
+ {
+ rtx base, offset;
++ int addr_mode;
+
+ if (GET_CODE (operand) == REG && reload_in_progress
+ && REGNO (operand) >= FIRST_PSEUDO_REGISTER
+@@ -611,7 +665,8 @@
+ if (PUSH_POP_ADDRESS_P (operand))
+ return 1;
+
+- if (!register_indirect_p (operand, mode, reload_completed))
++ addr_mode = m68hc11_mov_addr_mode | (reload_completed ? ADDR_STRICT : 0);
++ if (!register_indirect_p (operand, mode, addr_mode))
+ return 0;
+
+ if (TARGET_M6812 && GET_CODE (operand) == PLUS
+@@ -654,12 +709,21 @@
+ rtx operand;
+ enum machine_mode mode;
+ {
++ int addr_mode;
++
++ if (GET_CODE (operand) == REG && reload_in_progress
++ && REGNO (operand) >= FIRST_PSEUDO_REGISTER
++ && reg_equiv_memory_loc[REGNO (operand)])
++ {
++ operand = reg_equiv_memory_loc[REGNO (operand)];
++ operand = eliminate_regs (operand, 0, NULL_RTX);
++ }
+ if (GET_CODE (operand) != MEM)
+ return 0;
+
+ operand = XEXP (operand, 0);
+- return register_indirect_p (operand, mode,
+- (reload_completed | reload_in_progress));
++ addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);
++ return register_indirect_p (operand, mode, addr_mode);
+ }
+
+ static int
+@@ -668,6 +732,8 @@
+ enum machine_mode mode;
+ int strict;
+ {
++ int addr_mode;
++
+ if (CONSTANT_ADDRESS_P (operand) && TARGET_M6812)
+ {
+ /* Reject the global variables if they are too wide. This forces
+@@ -677,7 +743,8 @@
+
+ return 1;
+ }
+- if (register_indirect_p (operand, mode, strict))
++ addr_mode = m68hc11_addr_mode | (strict ? ADDR_STRICT : 0);
++ if (register_indirect_p (operand, mode, addr_mode))
+ {
+ return 1;
+ }
+@@ -930,6 +997,27 @@
+ return general_operand (operand, mode);
+ }
+
++/* Predicate for nonimmediate operands but which rejects the
++ auto-increment/decrement modes. We must use this predicate
++ for operand 0 (and sometimes operand 1) when an insn can have
++ an operand that would create a RELOAD_OTHER in which a reload
++ part (RELOAD_FOR_OUTPUT_ADDRESS) could be created. When this
++ happens, the RELOAD_FOR_OUTPUT_ADDRESS is emitted after the RELOAD_OTHER
++ and this will not be valid. */
++int
++nonimmediate_noinc_operand (operand, mode)
++ rtx operand;
++ enum machine_mode mode;
++{
++ if (GET_CODE (operand) == MEM)
++ {
++ rtx addr = XEXP (operand, 0);
++ if (m68hc11_auto_inc_p (addr))
++ return 0;
++ }
++ return nonimmediate_operand (operand, mode);
++}
++
+ int
+ non_push_operand (operand, mode)
+ rtx operand;
+@@ -944,6 +1032,43 @@
+ }
+
+ int
++splitable_operand (operand, mode)
++ rtx operand;
++ enum machine_mode mode;
++{
++ if (general_operand (operand, mode) == 0)
++ return 0;
++
++ if (push_operand (operand, mode) == 1)
++ return 0;
++
++ /* Reject a (MEM (MEM X)) because the patterns that use non_push_operand
++ need to split such addresses to access the low and high part but it
++ is not possible to express a valid address for the low part. */
++ if (mode != QImode && GET_CODE (operand) == MEM
++ && GET_CODE (XEXP (operand, 0)) == MEM)
++ return 0;
++ return 1;
++}
++
++int
++push_or_splitable_operand (operand, mode)
++ rtx operand;
++ enum machine_mode mode;
++{
++ if (general_operand (operand, mode) == 0)
++ return 0;
++
++ /* Reject a (MEM (MEM X)) because the patterns that use non_push_operand
++ need to split such addresses to access the low and high part but it
++ is not possible to express a valid address for the low part. */
++ if (mode != QImode && GET_CODE (operand) == MEM
++ && GET_CODE (XEXP (operand, 0)) == MEM)
++ return 0;
++ return 1;
++}
++
++int
+ reg_or_some_mem_operand (operand, mode)
+ rtx operand;
+ enum machine_mode mode;
+@@ -951,6 +1076,7 @@
+ if (GET_CODE (operand) == MEM)
+ {
+ rtx op = XEXP (operand, 0);
++ int addr_mode;
+
+ if (symbolic_memory_operand (op, mode))
+ return 1;
+@@ -958,10 +1084,20 @@
+ if (IS_STACK_PUSH (operand))
+ return 1;
+
+- if (m68hc11_register_indirect_p (operand, mode))
+- return 1;
++ if (GET_CODE (operand) == REG && reload_in_progress
++ && REGNO (operand) >= FIRST_PSEUDO_REGISTER
++ && reg_equiv_memory_loc[REGNO (operand)])
++ {
++ operand = reg_equiv_memory_loc[REGNO (operand)];
++ operand = eliminate_regs (operand, 0, NULL_RTX);
++ }
++ if (GET_CODE (operand) != MEM)
++ return 0;
+
+- return 0;
++ operand = XEXP (operand, 0);
++ addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);
++ addr_mode &= ~ADDR_INDIRECT;
++ return register_indirect_p (operand, mode, addr_mode);
+ }
+
+ return register_operand (operand, mode);
+@@ -987,18 +1123,23 @@
+ rtx operand;
+ enum machine_mode mode;
+ {
+- if (GET_CODE (operand) == MEM)
++ if (GET_CODE (operand) == MEM && GET_MODE (operand) == mode)
+ {
+ rtx op = XEXP (operand, 0);
++ int addr_mode;
++
++ if (m68hc11_page0_symbol_p (op))
++ return 1;
+
+ if (symbolic_memory_operand (op, mode))
+- return 0;
++ return TARGET_M6812;
+
+ if (reload_in_progress)
+ return 1;
+
+ operand = XEXP (operand, 0);
+- return register_indirect_p (operand, mode, reload_completed);
++ addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);
++ return register_indirect_p (operand, mode, addr_mode);
+ }
+ return 0;
+ }
+@@ -1234,6 +1375,31 @@
+
+ /* Declaration of types. */
+
++/* Handle an "tiny_data" attribute; arguments as in
++ struct attribute_spec.handler. */
++static tree
++m68hc11_handle_page0_attribute (node, name, args, flags, no_add_attrs)
++ tree *node;
++ tree name;
++ tree args ATTRIBUTE_UNUSED;
++ int flags ATTRIBUTE_UNUSED;
++ bool *no_add_attrs;
++{
++ tree decl = *node;
++
++ if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
++ {
++ DECL_SECTION_NAME (decl) = build_string (6, ".page0");
++ }
++ else
++ {
++ warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
++ *no_add_attrs = true;
++ }
++
++ return NULL_TREE;
++}
++
+ const struct attribute_spec m68hc11_attribute_table[] =
+ {
+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
+@@ -1241,6 +1407,7 @@
+ { "trap", 0, 0, false, true, true, m68hc11_handle_fntype_attribute },
+ { "far", 0, 0, false, true, true, m68hc11_handle_fntype_attribute },
+ { "near", 0, 0, false, true, true, m68hc11_handle_fntype_attribute },
++ { "page0", 0, 0, false, false, false, m68hc11_handle_page0_attribute },
+ { NULL, 0, 0, false, false, false, NULL }
+ };
+
+@@ -1271,6 +1438,52 @@
+
+ return NULL_TREE;
+ }
++/* Undo the effects of the above. */
++
++static const char *
++m68hc11_strip_name_encoding (str)
++ const char *str;
++{
++ return str + (*str == '*' || *str == '@' || *str == '&');
++}
++
++static void
++m68hc11_encode_label (tree decl)
++{
++ const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
++ int len = strlen (str);
++ char *newstr = alloca (len + 2);
++
++ newstr[0] = '@';
++ strcpy (&newstr[1], str);
++
++ XSTR (XEXP (DECL_RTL (decl), 0), 0) = ggc_alloc_string (newstr, len + 1);
++}
++
++/* Return 1 if this is a symbol in page0 */
++int
++m68hc11_page0_symbol_p (rtx x)
++{
++ switch (GET_CODE (x))
++ {
++ case SYMBOL_REF:
++ return XSTR (x, 0) != 0 && XSTR (x, 0)[0] == '@';
++
++ case CONST:
++ return m68hc11_page0_symbol_p (XEXP (x, 0));
++
++ case PLUS:
++ if (!m68hc11_page0_symbol_p (XEXP (x, 0)))
++ return 0;
++
++ return GET_CODE (XEXP (x, 1)) == CONST_INT
++ && INTVAL (XEXP (x, 1)) < 256
++ && INTVAL (XEXP (x, 1)) >= 0;
++
++ default:
++ return 0;
++ }
++}
+
+ /* We want to recognize trap handlers so that we handle calls to traps
+ in a special manner (by issuing the trap). This information is stored
+@@ -1286,6 +1499,13 @@
+ int is_far = 0;
+ rtx rtl;
+
++ if (TREE_CODE (decl) == VAR_DECL)
++ {
++ if (lookup_attribute ("page0", DECL_ATTRIBUTES (decl)) != 0)
++ m68hc11_encode_label (decl);
++ return;
++ }
++
+ if (TREE_CODE (decl) != FUNCTION_DECL)
+ return;
+
+@@ -1372,15 +1592,19 @@
+ /* For a trap handler, we must take into account the registers which
+ are pushed on the stack during the trap (except the PC). */
+ func_attr = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
++ current_function_interrupt = lookup_attribute ("interrupt",
++ func_attr) != NULL_TREE;
++ trap_handler = lookup_attribute ("trap", func_attr) != NULL_TREE;
+
+ if (lookup_attribute ("far", func_attr) != 0)
+ current_function_far = 1;
+ else if (lookup_attribute ("near", func_attr) != 0)
+ current_function_far = 0;
+ else
+- current_function_far = TARGET_LONG_CALLS != 0;
++ current_function_far = (TARGET_LONG_CALLS != 0
++ && !current_function_interrupt
++ && !trap_handler);
+
+- trap_handler = lookup_attribute ("trap", func_attr) != NULL_TREE;
+ if (trap_handler && from == ARG_POINTER_REGNUM)
+ size = 7;
+
+@@ -1679,7 +1903,9 @@
+ else if (lookup_attribute ("near", func_attr) != NULL_TREE)
+ current_function_far = 0;
+ else
+- current_function_far = TARGET_LONG_CALLS != 0;
++ current_function_far = (TARGET_LONG_CALLS != 0
++ && !current_function_interrupt
++ && !current_function_trap);
+
+ /* Get the scratch register to build the frame and push registers.
+ If the first argument is a 32-bit quantity, the D+X registers
+@@ -2014,6 +2240,14 @@
+ {
+ return gen_int_mode (val >> 16, HImode);
+ }
++ else if (mode == SImode)
++ {
++#if HOST_BITS_PER_WIDE_INT > 32
++ return gen_int_mode (val >> 32, SImode);
++#else
++ return (val >= 0) ? const0_rtx : constm1_rtx;
++#endif
++ }
+ }
+ if (mode == QImode && D_REG_P (x))
+ return gen_rtx (REG, mode, HARD_A_REGNUM);
+@@ -2307,7 +2541,21 @@
+ abort ();
+ break;
+
++ case MEM:
++ if (TARGET_M6812)
++ {
++ fprintf (file, "[");
++ print_operand_address (file, XEXP (base, 0));
++ fprintf (file, "]");
++ }
++ else
++ abort ();
++ break;
++
+ default:
++ if (m68hc11_page0_symbol_p (base))
++ fprintf (file, "*");
++
+ output_address (base);
+ break;
+ }
+@@ -2349,7 +2597,7 @@
+ }
+
+ /* Returns true if the operand 'op' must be printed with parenthesis
+- arround it. This must be done only if there is a symbol whose name
++ around it. This must be done only if there is a symbol whose name
+ is a processor register. */
+ static int
+ must_parenthesize (op)
+@@ -2903,15 +3151,7 @@
+ high_to = m68hc11_gen_highpart (mode, to);
+
+ low_from = m68hc11_gen_lowpart (mode, from);
+- if (mode == SImode && GET_CODE (from) == CONST_INT)
+- {
+- if (INTVAL (from) >= 0)
+- high_from = const0_rtx;
+- else
+- high_from = constm1_rtx;
+- }
+- else
+- high_from = m68hc11_gen_highpart (mode, from);
++ high_from = m68hc11_gen_highpart (mode, from);
+
+ if (offset)
+ {
+@@ -3104,26 +3344,8 @@
+ low[2] = m68hc11_gen_lowpart (mode, operands[2]);
+
+ high[0] = m68hc11_gen_highpart (mode, operands[0]);
+-
+- if (mode == SImode && GET_CODE (operands[1]) == CONST_INT)
+- {
+- if (INTVAL (operands[1]) >= 0)
+- high[1] = const0_rtx;
+- else
+- high[1] = constm1_rtx;
+- }
+- else
+- high[1] = m68hc11_gen_highpart (mode, operands[1]);
+-
+- if (mode == SImode && GET_CODE (operands[2]) == CONST_INT)
+- {
+- if (INTVAL (operands[2]) >= 0)
+- high[2] = const0_rtx;
+- else
+- high[2] = constm1_rtx;
+- }
+- else
+- high[2] = m68hc11_gen_highpart (mode, operands[2]);
++ high[1] = m68hc11_gen_highpart (mode, operands[1]);
++ high[2] = m68hc11_gen_highpart (mode, operands[2]);
+
+ low[3] = operands[3];
+ high[3] = operands[3];
+@@ -3236,10 +3458,13 @@
+
+ if (TARGET_M6812)
+ {
+- if (IS_STACK_PUSH (operands[0]) && H_REG_P (operands[1]))
++ rtx from = operands[1];
++ rtx to = operands[0];
++
++ if (IS_STACK_PUSH (to) && H_REG_P (from))
+ {
+ cc_status = cc_prev_status;
+- switch (REGNO (operands[1]))
++ switch (REGNO (from))
+ {
+ case HARD_X_REGNUM:
+ case HARD_Y_REGNUM:
+@@ -3247,17 +3472,17 @@
+ output_asm_insn ("psh%1", operands);
+ break;
+ case HARD_SP_REGNUM:
+- output_asm_insn ("sts\t-2,sp", operands);
++ output_asm_insn ("sts\t2,-sp", operands);
+ break;
+ default:
+ abort ();
+ }
+ return;
+ }
+- if (IS_STACK_POP (operands[1]) && H_REG_P (operands[0]))
++ if (IS_STACK_POP (from) && H_REG_P (to))
+ {
+ cc_status = cc_prev_status;
+- switch (REGNO (operands[0]))
++ switch (REGNO (to))
+ {
+ case HARD_X_REGNUM:
+ case HARD_Y_REGNUM:
+@@ -3278,17 +3503,6 @@
+ {
+ if (SP_REG_P (operands[0]))
+ output_asm_insn ("lds\t%1", operands);
+- else if (0 /* REG_WAS_0 note is boggus; don't rely on it. */
+- && !D_REG_P (operands[0])
+- && GET_CODE (operands[1]) == CONST_INT
+- && (INTVAL (operands[1]) == 1 || INTVAL (operands[1]) == -1)
+- && find_reg_note (insn, REG_WAS_0, 0))
+- {
+- if (INTVAL (operands[1]) == 1)
+- output_asm_insn ("in%0", operands);
+- else
+- output_asm_insn ("de%0", operands);
+- }
+ else
+ output_asm_insn ("ld%0\t%1", operands);
+ }
+@@ -3299,11 +3513,52 @@
+ else
+ output_asm_insn ("st%1\t%0", operands);
+ }
++
++ /* The 68hc12 does not support (MEM:HI (MEM:HI)) with the movw
++ instruction. We have to use a scratch register as temporary location.
++ Trying to use a specific pattern or constrain failed. */
++ else if (GET_CODE (to) == MEM && GET_CODE (XEXP (to, 0)) == MEM)
++ {
++ rtx ops[4];
++
++ ops[0] = to;
++ ops[2] = from;
++ ops[3] = 0;
++ if (dead_register_here (insn, d_reg))
++ ops[1] = d_reg;
++ else if (dead_register_here (insn, ix_reg))
++ ops[1] = ix_reg;
++ else if (dead_register_here (insn, iy_reg))
++ ops[1] = iy_reg;
++ else
++ {
++ ops[1] = d_reg;
++ ops[3] = d_reg;
++ output_asm_insn ("psh%3", ops);
++ }
++
++ ops[0] = to;
++ ops[2] = from;
++ output_asm_insn ("ld%1\t%2", ops);
++ output_asm_insn ("st%1\t%0", ops);
++ if (ops[3])
++ output_asm_insn ("pul%3", ops);
++ }
++
++ /* Use movw for non-null constants or when we are clearing
++ a volatile memory reference. However, this is possible
++ only if the memory reference has a small offset or is an
++ absolute address. */
++ else if (GET_CODE (from) == CONST_INT
++ && INTVAL (from) == 0
++ && (MEM_VOLATILE_P (to) == 0
++ || m68hc11_small_indexed_indirect_p (to, HImode) == 0))
++ {
++ output_asm_insn ("clr\t%h0", operands);
++ output_asm_insn ("clr\t%b0", operands);
++ }
+ else
+ {
+- rtx from = operands[1];
+- rtx to = operands[0];
+-
+ if ((m68hc11_register_indirect_p (from, GET_MODE (from))
+ && !m68hc11_small_indexed_indirect_p (from, GET_MODE (from)))
+ || (m68hc11_register_indirect_p (to, GET_MODE (to))
+@@ -3320,6 +3575,7 @@
+ ops[0] = to;
+ ops[1] = operands[2];
+ m68hc11_gen_movhi (insn, ops);
++ return;
+ }
+ else
+ {
+@@ -3327,19 +3583,11 @@
+ fatal_insn ("move insn not handled", insn);
+ }
+ }
+- else
+- {
+- if (GET_CODE (from) == CONST_INT && INTVAL (from) == 0)
+- {
+- output_asm_insn ("clr\t%h0", operands);
+- output_asm_insn ("clr\t%b0", operands);
+- }
+- else
+- {
+- m68hc11_notice_keep_cc (operands[0]);
+- output_asm_insn ("movw\t%1,%0", operands);
+- }
+- }
++ else
++ {
++ m68hc11_notice_keep_cc (operands[0]);
++ output_asm_insn ("movw\t%1,%0", operands);
++ }
+ }
+ return;
+ }
+@@ -3472,16 +3720,6 @@
+ cc_status = cc_prev_status;
+ output_asm_insn ("tsx", operands);
+ }
+- else if (0 /* REG_WAS_0 note is boggus; don't rely on it. */
+- && GET_CODE (operands[1]) == CONST_INT
+- && (INTVAL (operands[1]) == 1 || INTVAL (operands[1]) == -1)
+- && find_reg_note (insn, REG_WAS_0, 0))
+- {
+- if (INTVAL (operands[1]) == 1)
+- output_asm_insn ("in%0", operands);
+- else
+- output_asm_insn ("de%0", operands);
+- }
+ else
+ {
+ output_asm_insn ("ldx\t%1", operands);
+@@ -3530,16 +3768,6 @@
+ cc_status = cc_prev_status;
+ output_asm_insn ("tsy", operands);
+ }
+- else if (0 /* REG_WAS_0 note is boggus; don't rely on it. */
+- && GET_CODE (operands[1]) == CONST_INT
+- && (INTVAL (operands[1]) == 1 || INTVAL (operands[1]) == -1)
+- && find_reg_note (insn, REG_WAS_0, 0))
+- {
+- if (INTVAL (operands[1]) == 1)
+- output_asm_insn ("in%0", operands);
+- else
+- output_asm_insn ("de%0", operands);
+- }
+ else
+ {
+ output_asm_insn ("ldy\t%1", operands);
+@@ -3689,8 +3917,10 @@
+ }
+ else if (H_REG_P (operands[0]))
+ {
+- if (Q_REG_P (operands[0]))
+- output_asm_insn ("lda%0\t%b1", operands);
++ if (IS_STACK_POP (operands[1]))
++ output_asm_insn ("pul%b0", operands);
++ else if (Q_REG_P (operands[0]))
++ output_asm_insn ("lda%0\t%b1", operands);
+ else if (D_REG_P (operands[0]))
+ output_asm_insn ("ldab\t%b1", operands);
+ else
+@@ -3780,16 +4010,6 @@
+ output_asm_insn ("ldab\t%T0", operands);
+ }
+ }
+- else if (0 /* REG_WAS_0 note is boggus; don't rely on it. */
+- && GET_CODE (operands[1]) == CONST_INT
+- && (INTVAL (operands[1]) == 1 || INTVAL (operands[1]) == -1)
+- && find_reg_note (insn, REG_WAS_0, 0))
+- {
+- if (INTVAL (operands[1]) == 1)
+- output_asm_insn ("inc%b0", operands);
+- else
+- output_asm_insn ("dec%b0", operands);
+- }
+ else if (!DB_REG_P (operands[1]) && !D_REG_P (operands[1])
+ && !DA_REG_P (operands[1]))
+ {
+@@ -3935,11 +4155,34 @@
+ break;
+
+ case HARD_X_REGNUM:
+- output_asm_insn ("xgdx\n\tstab\t%b0\n\txgdx", operands);
+- break;
+-
+- case HARD_Y_REGNUM:
+- output_asm_insn ("xgdy\n\tstab\t%b0\n\txgdy", operands);
++ case HARD_Y_REGNUM:
++ if (!reg_mentioned_p (operands[1], operands[0]))
++ {
++ output_asm_insn ("xgd%1\n\tstab\t%b0\n\txgd%1", operands);
++ }
++ else if (TARGET_M6811)
++ {
++ int dead = dead_register_here (insn, d_reg);
++ output_asm_insn ("st%1\t%t1", operands);
++ if (!dead)
++ output_asm_insn ("psha", operands);
++ output_asm_insn ("ldaa\t%T1", operands);
++ output_asm_insn ("staa\t%0", operands);
++ if (!dead)
++ output_asm_insn ("pula", operands);
++ CC_STATUS_INIT;
++ }
++ else
++ {
++ int dead = dead_register_here (insn, d_reg);
++ if (!dead)
++ output_asm_insn ("psha", operands);
++ output_asm_insn ("tfr\t%1,a", operands);
++ output_asm_insn ("staa\t%0", operands);
++ if (!dead)
++ output_asm_insn ("pulb", operands);
++ CC_STATUS_INIT;
++ }
+ break;
+
+ default:
+@@ -4136,6 +4379,12 @@
+ && cc_status.value2
+ && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
+ cc_status.value2 = 0;
++
++ else if (cc_status.value1 && side_effects_p (cc_status.value1))
++ cc_status.value1 = 0;
++
++ else if (cc_status.value2 && side_effects_p (cc_status.value2))
++ cc_status.value2 = 0;
+ }
+
+ /* The current instruction does not affect the flags but changes
+@@ -4306,8 +4555,10 @@
+ {
+ if ((GET_CODE (src) == REG && REGNO (src) == HARD_Z_REGNUM)
+ || (GET_CODE (src) == COMPARE &&
+- (rtx_equal_p (XEXP (src, 0), z_reg)
+- || rtx_equal_p (XEXP (src, 1), z_reg))))
++ ((rtx_equal_p (XEXP (src, 0), z_reg)
++ && H_REG_P (XEXP (src, 1)))
++ || (rtx_equal_p (XEXP (src, 1), z_reg)
++ && H_REG_P (XEXP (src, 0))))))
+ {
+ if (insn == info->first)
+ {
+@@ -4905,7 +5156,7 @@
+ /* The insn uses the Z register. Find a replacement register for it
+ (either X or Y) and replace it in the insn and the next ones until
+ the flow changes or the replacement register is used. Instructions
+- are emited before and after the Z-block to preserve the value of
++ are emitted before and after the Z-block to preserve the value of
+ Z and of the replacement register. */
+
+ static void
+@@ -5067,9 +5318,11 @@
+ if (info.save_before_last)
+ save_pos_insn = PREV_INSN (save_pos_insn);
+
+- emit_insn_before (gen_movhi (gen_rtx (REG, HImode, SOFT_Z_REGNUM),
+- gen_rtx (REG, HImode, info.regno)),
+- save_pos_insn);
++ /* Use emit_insn_after () to ensure the new insn is part of
++ the good basic block. */
++ emit_insn_after (gen_movhi (gen_rtx (REG, HImode, SOFT_Z_REGNUM),
++ gen_rtx (REG, HImode, info.regno)),
++ PREV_INSN (save_pos_insn));
+ }
+
+ if (info.must_push_reg && info.last)
+@@ -5108,8 +5361,8 @@
+ else
+ dst = gen_rtx (REG, HImode, SOFT_SAVED_XY_REGNUM);
+
+- emit_insn_before (gen_movhi (gen_rtx (REG, HImode, info.regno),
+- dst), insn);
++ emit_insn_after (gen_movhi (gen_rtx (REG, HImode, info.regno),
++ dst), PREV_INSN (insn));
+ }
+
+ }
+@@ -5176,6 +5429,13 @@
+ }
+
+
++/* Machine-dependent reorg pass.
++ Specific optimizations are defined here:
++ - this pass changes the Z register into either X or Y
++ (it preserves X/Y previous values in a memory slot in page0).
++
++ When this pass is finished, the global variable
++ 'z_replacement_completed' is set to 2. */
+ void
+ m68hc11_reorg (first)
+ rtx first;
+@@ -5204,7 +5464,7 @@
+ z_replacement_completed = 1;
+ m68hc11_reassign_regs (first);
+
+- /* After some splitting, there are some oportunities for CSE pass.
++ /* After some splitting, there are some opportunities for CSE pass.
+ This happens quite often when 32-bit or above patterns are split. */
+ if (optimize > 0 && split_done)
+ {
+@@ -5355,7 +5615,7 @@
+ break;
+
+ case SYMBOL_REF:
+- cost = 8;
++ cost = m68hc11_page0_symbol_p (addr) ? 0 : 8;
+ break;
+
+ case LABEL_REF:
+@@ -5388,7 +5648,7 @@
+ break;
+
+ case SYMBOL_REF:
+- cost = 8;
++ cost = m68hc11_page0_symbol_p (addr) ? 0 : 8;
+ break;
+
+ case CONST:
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11-crt0.S gcc-3.3.6/gcc/config/m68hc11/m68hc11-crt0.S
+--- gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11-crt0.S 2002-08-14 08:32:52.000000000 +0100
++++ gcc-3.3.6/gcc/config/m68hc11/m68hc11-crt0.S 2010-11-09 20:47:16.000000000 +0000
+@@ -79,7 +79,7 @@
+ ;;
+ ;; int __premain(void);
+ ;;
+- jsr __premain
++ bsr __premain
+
+ ;;
+ ;;
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11.h gcc-3.3.6/gcc/config/m68hc11/m68hc11.h
+--- gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11.h 2003-07-08 22:07:33.000000000 +0100
++++ gcc-3.3.6/gcc/config/m68hc11/m68hc11.h 2010-11-09 20:47:16.000000000 +0000
+@@ -1,22 +1,23 @@
+ /* Definitions of target machine for GNU compiler.
+ Motorola 68HC11 and 68HC12.
+- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
++ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004,
++ 2005, 2006 Free Software Foundation, Inc.
+ Contributed by Stephane Carrez (stcarrez@nerim.fr)
+
+-This file is part of GNU CC.
++This file is part of GCC.
+
+-GNU CC is free software; you can redistribute it and/or modify
++GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+-GNU CC is distributed in the hope that it will be useful,
++GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+-along with GNU CC; see the file COPYING. If not, write to
++along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+@@ -41,24 +42,28 @@
+
+ #undef ENDFILE_SPEC
+
+-/* Compile and assemble for a 68hc11 unless there is a -m68hc12 option. */
++/* Default to compile and assemble for a 68hc11 */
++/* convert parameter style from 'cc1' to 'as' */
+ #ifndef ASM_SPEC
+ #define ASM_SPEC \
+ "%{m68hc12:-m68hc12}" \
+ "%{m68hcs12:-m68hcs12}" \
+-"%{!m68hc12:%{!m68hcs12:-m68hc11}} " \
++"%{m9s12x:-mm9s12x}" \
++"%{!m68hc12:%{!m68hcs12:%{!m9s12x:-m68hc11}}} " \
+ "%{mshort:-mshort}%{!mshort:-mlong} " \
+ "%{fshort-double:-mshort-double}%{!fshort-double:-mlong-double}"
+ #endif
+
+ /* We need to tell the linker the target elf format. Just pass an
+- emulation option. This can be overriden by -Wl option of gcc. */
++ emulation option. This can be overridden by -Wl option of gcc. */
+ #ifndef LINK_SPEC
+ #define LINK_SPEC \
+ "%{m68hc12:-m m68hc12elf}" \
+ "%{m68hcs12:-m m68hc12elf}" \
+-"%{!m68hc12:%{!m68hcs12:-m m68hc11elf}} " \
+-"%{!mnorelax:%{!m68hc12:%{!m68hcs12:-relax}}}"
++"%{m9s12x:-m m9s12x}" \
++"%{!m68hc12:%{!m68hcs12:%{!m9s12x:-m m68hc11elf}}} " \
++"%{!mnorelax:%{!m68hc12:%{!m68hcs12:%{!m9s12x:-relax}}}}"
++
+ #endif
+
+ #ifndef LIB_SPEC
+@@ -75,7 +80,8 @@
+ %{!mshort:-D__INT__=32}\
+ %{m68hc12:-Dmc6812 -DMC6812 -Dmc68hc12}\
+ %{m68hcs12:-Dmc6812 -DMC6812 -Dmc68hcs12}\
+- %{!m68hc12:%{!m68hcs12:-Dmc6811 -DMC6811 -Dmc68hc11}}\
++ %{m9s12x:-Dmc6812 -DMC6812 -Dmc68hcs12}\
++ %{!m68hc12:%{!m68hcs12:%{!m9s12x:-Dmc6811 -DMC6811 -Dmc68hc11}}}\
+ %{fshort-double:-D__HAVE_SHORT_DOUBLE__}\
+ %{mlong-calls:-D__USE_RTC__}"
+ #endif
+@@ -84,7 +90,9 @@
+ #define STARTFILE_SPEC "crt1%O%s"
+
+ /* Names to predefine in the preprocessor for this target machine. */
+-#define CPP_PREDEFINES "-Dmc68hc1x"
++#ifndef CPP_PREDEFINES
++#define CPP_PREDEFINES "-Dmc68hc1x -Dtarget11"
++#endif
+
+ /* As an embedded target, we have no libc. */
+ #define inhibit_libc
+@@ -125,20 +133,22 @@
+ * with -mauto-incdec.
+ */
+
+-#define MASK_SHORT 0002 /* Compile with 16-bit `int' */
+-#define MASK_AUTO_INC_DEC 0004
+-#define MASK_M6811 0010
+-#define MASK_M6812 0020
+-#define MASK_M68S12 0040
+-#define MASK_NO_DIRECT_MODE 0100
+-#define MASK_MIN_MAX 0200
+-#define MASK_LONG_CALLS 0400
++#define MASK_SHORT 0x0002 /* Compile with 16-bit `int' */
++#define MASK_AUTO_INC_DEC 0x0004 /* FIXME - tidy M68XX flags order */
++#define MASK_M6811 0x0010
++#define MASK_M6812 0x0020
++#define MASK_M68S12 0x0040
++#define MASK_NO_DIRECT_MODE 0x0100
++#define MASK_MIN_MAX 0x0200
++#define MASK_LONG_CALLS 0x0400
++#define MASK_M68S12X 0x0800
+
+ #define TARGET_OP_TIME (optimize && optimize_size == 0)
+ #define TARGET_SHORT (target_flags & MASK_SHORT)
+ #define TARGET_M6811 (target_flags & MASK_M6811)
+ #define TARGET_M6812 (target_flags & MASK_M6812)
+ #define TARGET_M68S12 (target_flags & MASK_M68S12)
++#define TARGET_M68S12X (!(target_flags & MASK_M6811) && (target_flags & MASK_M68S12X))
+ #define TARGET_AUTO_INC_DEC (target_flags & MASK_AUTO_INC_DEC)
+ #define TARGET_MIN_MAX (target_flags & MASK_MIN_MAX)
+ #define TARGET_NO_DIRECT_MODE (target_flags & MASK_NO_DIRECT_MODE)
+@@ -161,6 +171,7 @@
+ # define MULTILIB_DEFAULTS { "m68hc12" }
+ # endif
+ #endif
++/* 9s12x in own .h */
+
+ /* Macro to define tables used to set the flags. This is a list in braces of
+ pairs in braces, each pair being { "NAME", VALUE } where VALUE is the bits
+@@ -200,6 +211,10 @@
+ N_("Compile for a 68HC12")}, \
+ { "68S12", MASK_M6812 | MASK_M68S12, \
+ N_("Compile for a 68HCS12")}, \
++ { "9s12x", MASK_M6812 | MASK_M68S12 | MASK_M68S12X, \
++ N_("Compile for CPU12X")}, \
++ { "m9s12x", MASK_M6812 | MASK_M68S12 | MASK_M68S12X, \
++ N_("Compile for CPU12X")}, \
+ { "", TARGET_DEFAULT, 0 }}
+
+ /* This macro is similar to `TARGET_SWITCHES' but defines names of
+@@ -232,7 +247,7 @@
+ #endif
+
+ /* Print subsidiary information on the compiler version in use. */
+-#define TARGET_VERSION fprintf (stderr, " (MC68HC11/MC68HC12/MC68HCS12)")
++#define TARGET_VERSION fprintf (stderr, " (MC68HC11/MC68HC12/MC68HCS12/M9S12X)")
+
+ /* Sometimes certain combinations of command options do not make
+ sense on a particular target machine. You can define a macro
+@@ -277,6 +292,10 @@
+ /* Define this if most significant word of a multiword number is numbered. */
+ #define WORDS_BIG_ENDIAN 1
+
++/* Use a MAX_BITS_PER_WORD equivalent to SImode so that
++ several SI patterns can be used (mostly shift & add). */
++/* #define MAX_BITS_PER_WORD 32 */
++
+ /* Width of a word, in units (bytes). */
+ #define UNITS_PER_WORD 2
+
+@@ -804,8 +823,8 @@
+ /* A C expression that is nonzero if hard register number REGNO2 can be
+ considered for use as a rename register for REGNO1 */
+
+-#define HARD_REGNO_RENAME_OK(REGNO1,REGNO2) \
+- m68hc11_hard_regno_rename_ok ((REGNO1), (REGNO2))
++#define HARD_REGNO_RENAME_OK(REGNO1,REGNO2,MODE) \
++ m68hc11_hard_regno_rename_ok ((REGNO1), (REGNO2), (MODE))
+
+ /* A C expression whose value is nonzero if pseudos that have been
+ assigned to registers of class CLASS would likely be spilled
+@@ -874,7 +893,9 @@
+ && VALUE == CONST0_RTX (GET_MODE (VALUE))) : 0)
+
+ /* 'U' represents certain kind of memory indexed operand for 68HC12.
+- and any memory operand for 68HC11. */
++ and any memory operand for 68HC11.
++ 'R' represents indexed addressing mode or access to page0 for 68HC11.
++ For 68HC12, it represents any memory operand. */
+ #define EXTRA_CONSTRAINT(OP, C) \
+ ((C) == 'U' ? m68hc11_small_indexed_indirect_p (OP, GET_MODE (OP)) \
+ : (C) == 'Q' ? m68hc11_symbolic_p (OP, GET_MODE (OP)) \
+@@ -963,7 +984,7 @@
+ followed by "to". Eliminations of the same "from" register are listed
+ in order of preference.
+
+- We have two registers that are eliminated on the 6811. The psuedo arg
++ We have two registers that are eliminated on the 6811. The pseudo arg
+ pointer and pseudo frame pointer registers can always be eliminated;
+ they are replaced with either the stack or the real frame pointer. */
+
+@@ -1215,7 +1236,7 @@
+
+
+ /* Internal macro, return 1 if REGNO is a valid base register. */
+-#define REG_VALID_P(REGNO) (1) /* ? */
++#define REG_VALID_P(REGNO) ((REGNO) >= 0)
+
+ extern unsigned char m68hc11_reg_valid_for_base[FIRST_PSEUDO_REGISTER];
+ #define REG_VALID_FOR_BASE_P(REGNO) \
+@@ -1489,7 +1510,7 @@
+ macro is used in only one place: `find_reloads_address' in reload.c.
+
+ For M68HC11, we handle large displacements of a base register
+- by splitting the addend accors an addhi3 insn.
++ by splitting the addend across an addhi3 insn.
+
+ For M68HC12, the 64K offset range is available.
+ */
+@@ -1690,7 +1711,7 @@
+
+ /* Assembler Commands for Exception Regions. */
+
+-/* Default values provided by GCC should be ok. Assumming that DWARF-2
++/* Default values provided by GCC should be ok. Assuming that DWARF-2
+ frame unwind info is ok for this platform. */
+
+ #undef PREFERRED_DEBUGGING_TYPE
+@@ -1719,6 +1740,12 @@
+ #define IMMEDIATE_PREFIX "#"
+ #define GLOBAL_ASM_OP "\t.globl\t"
+
++/* This is how to output a reference to a user-level label named NAME.
++ `assemble_name' uses this. */
++#undef ASM_OUTPUT_LABELREF
++#define ASM_OUTPUT_LABELREF(FILE, NAME) \
++ asm_fprintf (FILE, "%U%s", (*targetm.strip_name_encoding) (NAME))
++
+
+ /* Miscellaneous Parameters. */
+
+@@ -1737,8 +1764,10 @@
+ {"m68hc11_shift_operator", {ASHIFT, ASHIFTRT, LSHIFTRT, ROTATE, ROTATERT}},\
+ {"m68hc11_eq_compare_operator", {EQ, NE}}, \
+ {"non_push_operand", {SUBREG, REG, MEM}}, \
++{"splitable_operand", {SUBREG, REG, MEM}}, \
+ {"reg_or_some_mem_operand", {SUBREG, REG, MEM}}, \
+ {"tst_operand", {SUBREG, REG, MEM}}, \
++{"nonimmediate_noinc_operand", {SUBREG, REG, MEM}}, \
+ {"cmp_operand", {SUBREG, REG, MEM, SYMBOL_REF, LABEL_REF, \
+ CONST_INT, CONST_DOUBLE}},
+
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11.md gcc-3.3.6/gcc/config/m68hc11/m68hc11.md
+--- gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11.md 2003-04-12 22:25:37.000000000 +0100
++++ gcc-3.3.6/gcc/config/m68hc11/m68hc11.md 2010-11-09 20:47:16.000000000 +0000
+@@ -1,21 +1,22 @@
+ ;;- Machine description file for Motorola 68HC11 and 68HC12.
+-;;- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
++;;- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
++;;- Free Software Foundation, Inc.
+ ;;- Contributed by Stephane Carrez (stcarrez@nerim.fr)
+
+-;; This file is part of GNU CC.
++;; This file is part of GCC.
+
+-;; GNU CC is free software; you can redistribute it and/or modify
++;; GCC is free software; you can redistribute it and/or modify
+ ;; it under the terms of the GNU General Public License as published by
+ ;; the Free Software Foundation; either version 2, or (at your option)
+ ;; any later version.
+
+-;; GNU CC is distributed in the hope that it will be useful,
++;; GCC is distributed in the hope that it will be useful,
+ ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ;; GNU General Public License for more details.
+
+ ;; You should have received a copy of the GNU General Public License
+-;; along with GNU CC; see the file COPYING. If not, write to
++;; along with GCC; see the file COPYING. If not, write to
+ ;; the Free Software Foundation, 59 Temple Place - Suite 330,
+ ;; Boston, MA 02111-1307, USA.
+
+@@ -93,7 +94,7 @@
+ ;; Operands modifiers:
+ ;;
+ ;; %b Get the low part of the operand (to obtain a QImode)
+-;; This modified must always be used for QImode operations
++;; This modifier must always be used for QImode operations
+ ;; because a correction must be applied when the operand
+ ;; is a soft register (ex: *ZD1). Otherwise, we generate
+ ;; *ZD1 and this is the high part of the register. For other
+@@ -143,7 +144,9 @@
+ (A_REGNUM 5) ; A (high part of D)
+ (B_REGNUM 6) ; B (low part of D)
+ (CC_REGNUM 7) ; Condition code register
+- (SOFT_Z_REGNUM 11) ; Z soft register
++ (SOFT_TMP_REGNUM 10) ; TMP soft register
++ (SOFT_Z_REGNUM 11) ; Z soft register
++ (SOFT_XY_REGNUM 12) ; XY soft register
+ ])
+
+ ;;--------------------------------------------------------------------
+@@ -247,19 +250,13 @@
+ ;; avoid problems with the flow+cse register pass which are made
+ ;; after Z register replacement.
+ ;;
+-(define_insn "tstqi_z_used"
++(define_insn_and_split "tstqi_z_used"
+ [(set (cc0)
+ (match_operand:QI 0 "tst_operand" "m"))
+ (use (match_operand:HI 1 "hard_reg_operand" "dxy"))
+- (use (reg:HI 11))]
+- ""
+- "#")
+-
+-(define_split /* "tstqi_z_used" */
+- [(set (cc0)
+- (match_operand:QI 0 "tst_operand" ""))
+- (use (match_operand:HI 1 "hard_reg_operand" ""))
+ (use (reg:HI SOFT_Z_REGNUM))]
++ ""
++ "#"
+ "z_replacement_completed == 2"
+ [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 1))
+ (set (match_dup 1) (match_dup 2))
+@@ -300,12 +297,24 @@
+ [(set (cc0)
+ (compare (match_operand:HI 0 "hard_reg_operand" "")
+ (match_operand:HI 1 "hard_reg_operand" "")))]
+- "reload_completed"
++ "TARGET_M6811
++ && reload_completed && !(Z_REG_P (operands[0]) || Z_REG_P (operands[1]))"
+ [(set (match_dup 2) (match_dup 1))
+ (set (cc0)
+ (compare (match_dup 0) (match_dup 2)))]
+ "operands[2] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM);")
+
++(define_split
++ [(set (cc0)
++ (compare (match_operand:HI 0 "hard_reg_operand" "")
++ (match_operand:HI 1 "hard_reg_operand" "")))]
++ "0 && TARGET_M6812
++ && reload_completed && !(Z_REG_P (operands[0]) || Z_REG_P (operands[1]))"
++ [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 1))
++ (set (cc0)
++ (compare (match_dup 0) (mem:HI (post_inc:HI (reg:HI SP_REGNUM)))))]
++ "")
++
+ (define_expand "cmphi"
+ [(set (cc0)
+ (compare (match_operand:HI 0 "tst_operand" "")
+@@ -325,7 +334,7 @@
+ [(set (cc0)
+ (compare (match_operand:HI 0 "tst_operand"
+ "d,?xy,xyd,?xy,d,m,!u,dxy,dxy")
+- (match_operand:HI 1 "cmp_operand"
++ (match_operand:HI 1 "general_operand"
+ "i,i,!u,m,m,dxy,dxy,?*d*A,!*w")))]
+ "TARGET_M6812"
+ "*
+@@ -335,8 +344,10 @@
+ cc_status.flags |= CC_REVERSED;
+ return \"cp%1\\t%0\";
+ }
++ else if (SP_REG_P (operands[1]))
++ return \"sts\\t2,-sp\n\\tcp%0\\t2,sp+\";
+ else if (H_REG_P (operands[1]))
+- return \"#\";
++ return \"psh%1\n\\tcp%0\\t2,sp+\";
+ else
+ return \"cp%0\\t%1\";
+ }")
+@@ -344,9 +355,9 @@
+ (define_insn "cmphi_1_hc11"
+ [(set (cc0)
+ (compare (match_operand:HI 0 "tst_operand"
+- "dx,y,xyd,?xy,d,m,!u,dxy,dxy")
++ "dx,y,xyd,?xy,d,m,m,dxy,dxy,?u*z,dxy,*z")
+ (match_operand:HI 1 "cmp_operand"
+- "i,i,!u,m,m,dxy,dxy,?*d*A,!*w")))]
++ "i,i,!u,m,m,?xy,d,?*d*A,?u,dxy,!*w,i")))]
+ "TARGET_M6811"
+ "*
+ {
+@@ -361,21 +372,14 @@
+ return \"cp%0\\t%1\";
+ }")
+
+-(define_insn "cmphi_z_used"
++(define_insn_and_split "cmphi_z_used"
+ [(set (cc0)
+ (compare (match_operand:HI 0 "tst_operand" "dxy,m")
+- (match_operand:HI 1 "cmp_operand" "m,dxy")))
++ (match_operand:HI 1 "cmp_operand" "mi,dxy")))
+ (use (match_operand:HI 2 "hard_reg_operand" "dxy,dxy"))
+ (use (reg:HI SOFT_Z_REGNUM))]
+ ""
+- "#")
+-
+-(define_split /* "cmphi_z_used" */
+- [(set (cc0)
+- (compare (match_operand:HI 0 "tst_operand" "")
+- (match_operand:HI 1 "cmp_operand" "")))
+- (use (match_operand:HI 2 "hard_reg_operand" ""))
+- (use (reg:HI SOFT_Z_REGNUM))]
++ "#"
+ "z_replacement_completed == 2"
+ [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 2))
+ (set (match_dup 2) (match_dup 3))
+@@ -452,21 +456,14 @@
+ operands[3] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM);
+ operands[4] = gen_rtx (REG, QImode, SOFT_TMP_REGNUM);")
+
+-(define_insn "bitcmpqi_z_used"
++(define_insn_and_split "bitcmpqi_z_used"
+ [(set (cc0)
+ (and:QI (match_operand:QI 0 "tst_operand" "d,m")
+ (match_operand:QI 1 "cmp_operand" "m,d")))
+ (use (match_operand:HI 2 "hard_reg_operand" "xy,xy"))
+ (use (reg:HI SOFT_Z_REGNUM))]
+ ""
+- "#")
+-
+-(define_split /* "bitcmpqi_z_used" */
+- [(set (cc0)
+- (and:QI (match_operand:QI 0 "tst_operand" "")
+- (match_operand:QI 1 "cmp_operand" "")))
+- (use (match_operand:HI 2 "hard_reg_operand" ""))
+- (use (reg:HI SOFT_Z_REGNUM))]
++ "#"
+ "z_replacement_completed == 2"
+ [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 2))
+ (set (match_dup 2) (match_dup 3))
+@@ -542,21 +539,14 @@
+ return \"cmpb\\t%b0\";
+ }")
+
+-(define_insn "cmpqi_z_used"
++(define_insn_and_split "cmpqi_z_used"
+ [(set (cc0)
+ (compare (match_operand:QI 0 "tst_operand" "dxy,m")
+ (match_operand:QI 1 "cmp_operand" "m,dxy")))
+ (use (match_operand:HI 2 "hard_reg_operand" "dxy,dxy"))
+ (use (reg:HI SOFT_Z_REGNUM))]
+ ""
+- "#")
+-
+-(define_split /* cmpqi_z_used */
+- [(set (cc0)
+- (compare (match_operand:QI 0 "tst_operand" "")
+- (match_operand:QI 1 "cmp_operand" "")))
+- (use (match_operand:HI 2 "hard_reg_operand" ""))
+- (use (reg:HI SOFT_Z_REGNUM))]
++ "#"
+ "z_replacement_completed == 2"
+ [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 2))
+ (set (match_dup 2) (match_dup 3))
+@@ -573,41 +563,29 @@
+ ;; (strict_low_part ...) information. This is correct for our machine
+ ;; description but not for GCC optimization passes.
+ ;;
+-(define_insn "movstrictsi"
++(define_insn_and_split "movstrictsi"
+ [(set (strict_low_part (match_operand:SI 0 "non_push_operand" "+um,D,D"))
+ (match_operand:SI 1 "general_operand" "D,Dim,uD"))]
+ ""
+- "#")
+-
+-(define_split
+- [(set (strict_low_part (match_operand:SI 0 "non_push_operand" ""))
+- (match_operand:SI 1 "general_operand" ""))]
++ "#"
+ "z_replacement_completed == 2"
+ [(set (match_dup 0) (match_dup 1))]
+ "")
+
+-(define_insn "movstricthi"
++(define_insn_and_split "movstricthi"
+ [(set (strict_low_part (match_operand:HI 0 "non_push_operand" "+um,dA,dA"))
+ (match_operand:HI 1 "general_operand" "dA,dAim,u"))]
+ ""
+- "#")
+-
+-(define_split
+- [(set (strict_low_part (match_operand:HI 0 "non_push_operand" ""))
+- (match_operand:HI 1 "general_operand" ""))]
++ "#"
+ "z_replacement_completed == 2"
+ [(set (match_dup 0) (match_dup 1))]
+ "")
+
+-(define_insn "movstrictqi"
++(define_insn_and_split "movstrictqi"
+ [(set (strict_low_part (match_operand:QI 0 "non_push_operand" "+mu,!dA"))
+ (match_operand:QI 1 "general_operand" "d,imudA"))]
+ ""
+- "#")
+-
+-(define_split
+- [(set (strict_low_part (match_operand:QI 0 "non_push_operand" ""))
+- (match_operand:QI 1 "general_operand" ""))]
++ "#"
+ "z_replacement_completed == 2"
+ [(set (match_dup 0) (match_dup 1))]
+ "")
+@@ -651,17 +629,26 @@
+ }
+ ")
+
+-(define_insn "movdi_internal"
+- [(set (match_operand:DI 0 "nonimmediate_operand" "=ou,U,!u,U,m,m,!u")
++;; Separate push from normal moves to avoid reloading problems
++;; The 'clr' is not able to push on 68HC11 so we really need a scratch.
++;; We can also accept more scratch registers.
++(define_insn_and_split "*pushdi_internal"
++ [(set (match_operand:DI 0 "push_operand" "=<,<,<,<")
++ (match_operand:DI 1 "general_operand" "i,U,m,!u"))
++ (clobber (match_scratch:HI 2 "=&dA,&d,&d,&dA"))]
++ ""
++ "#"
++ "reload_completed"
++ [(const_int 0)]
++ "m68hc11_split_move (operands[0], operands[1], operands[2]);
++ DONE;")
++
++(define_insn_and_split "movdi_internal"
++ [(set (match_operand:DI 0 "non_push_operand" "=m!u,U,!u,U,m,m,!u")
+ (match_operand:DI 1 "general_operand" "K,iU,iU,!u,mi,!u,!mu"))
+ (clobber (match_scratch:HI 2 "=X,&d,&d,&d,&d,&d,&d"))]
+ ""
+- "#")
+-
+-(define_split
+- [(set (match_operand:DI 0 "nonimmediate_operand" "")
+- (match_operand:DI 1 "general_operand" ""))
+- (clobber (match_scratch:HI 2 ""))]
++ "#"
+ "reload_completed"
+ [(const_int 0)]
+ "m68hc11_split_move (operands[0], operands[1], operands[2]);
+@@ -687,17 +674,24 @@
+ }
+ ")
+
+-(define_insn "movdf_internal"
+- [(set (match_operand:DF 0 "nonimmediate_operand" "=ou,U,!u,U,m,m,!u")
++;; See pushdi_internal
++(define_insn_and_split "*pushdf_internal"
++ [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
++ (match_operand:DF 1 "general_operand" "i,U,m,!u"))
++ (clobber (match_scratch:HI 2 "=&dA,&d,&d,&dA"))]
++ ""
++ "#"
++ "reload_completed"
++ [(const_int 0)]
++ "m68hc11_split_move (operands[0], operands[1], operands[2]);
++ DONE;")
++
++(define_insn_and_split "movdf_internal"
++ [(set (match_operand:DF 0 "non_push_operand" "=mu,U,!u,U,m,m,!u")
+ (match_operand:DF 1 "general_operand" "G,iU,iU,!u,mi,!u,!mu"))
+ (clobber (match_scratch:HI 2 "=X,&d,&d,&d,&d,&d,&d"))]
+ ""
+- "#")
+-
+-(define_split
+- [(set (match_operand:DF 0 "nonimmediate_operand" "")
+- (match_operand:DF 1 "general_operand" ""))
+- (clobber (match_scratch:HI 2 ""))]
++ "#"
+ "reload_completed"
+ [(const_int 0)]
+ "m68hc11_split_move (operands[0], operands[1], operands[2]);
+@@ -732,17 +726,23 @@
+ }
+ ")
+
+-(define_insn "movsi_internal"
+- [(set (match_operand:SI 0 "nonimmediate_operand" "=ou,mu,?D,m,?D,?u,?u,!u,D")
+- (match_operand:SI 1 "general_operand" "K,imu,im,?D,!u,?D,mi,!u,!D"))
+- (clobber (match_scratch:HI 2 "=X,&d,X,X,X,X,&d,&d,X"))]
++(define_insn_and_split "*pushsi_internal"
++ [(set (match_operand:SI 0 "push_operand" "=<,<,<,<,<")
++ (match_operand:SI 1 "general_operand" "!D,i,U,m,!u"))
++ (clobber (match_scratch:HI 2 "=X,&dA,&d,&d,&dA"))]
+ ""
+- "#")
++ "#"
++ "reload_completed"
++ [(const_int 0)]
++ "m68hc11_split_move (operands[0], operands[1], operands[2]);
++ DONE;")
+
+-(define_split
+- [(set (match_operand:SI 0 "nonimmediate_operand" "")
+- (match_operand:SI 1 "general_operand" ""))
+- (clobber (match_scratch:HI 2 ""))]
++(define_insn_and_split "movsi_internal"
++ [(set (match_operand:SI 0 "nonimmediate_operand" "=mu,mu,?D,m,?D,?u,?u,!u,D")
++ (match_operand:SI 1 "general_operand" "K,imu,im,?D,!u,?D,mi,!u,!D"))
++ (clobber (match_scratch:HI 2 "=X,&d,X,X,X,X,&d,&d,X"))]
++ ""
++ "#"
+ "reload_completed"
+ [(const_int 0)]
+ "m68hc11_split_move (operands[0], operands[1], operands[2]);
+@@ -768,17 +768,23 @@
+ }
+ ")
+
+-(define_insn "movsf_internal"
+- [(set (match_operand:SF 0 "nonimmediate_operand" "=o!u,m,D,m,D,!u,!u,!u,D")
++(define_insn_and_split "*pushsf_internal"
++ [(set (match_operand:SF 0 "push_operand" "=<,<,<,<,<")
++ (match_operand:SF 1 "general_operand" "!D,i,U,m,!u"))
++ (clobber (match_scratch:HI 2 "=X,&dA,&d,&d,&dA"))]
++ ""
++ "#"
++ "reload_completed"
++ [(const_int 0)]
++ "m68hc11_split_move (operands[0], operands[1], operands[2]);
++ DONE;")
++
++(define_insn_and_split "movsf_internal"
++ [(set (match_operand:SF 0 "nonimmediate_operand" "=m!u,m,D,m,D,!u,!u,!u,D")
+ (match_operand:SF 1 "general_operand" "G,im,im,D,!u,D,mi,!u,!D"))
+ (clobber (match_scratch:HI 2 "=X,&d,X,X,X,X,&d,&d,X"))]
+ ""
+- "#")
+-
+-(define_split
+- [(set (match_operand:SF 0 "nonimmediate_operand" "")
+- (match_operand:SF 1 "general_operand" ""))
+- (clobber (match_scratch:HI 2 ""))]
++ "#"
+ "reload_completed"
+ [(const_int 0)]
+ "m68hc11_split_move (operands[0], operands[1], operands[2]);
+@@ -849,6 +855,18 @@
+ DONE;
+ }
+ }
++
++ /* The doloop optimization can emit a move with a constant > 32767.
++ This will fail later on because the move instruction is not recognized
++ eg: (set (reg:HI 53) (const_int 0x8000))
++ because for some reason gcc expects the constant to be sign extended
++ ie, it only recognize: (set (reg:HI 53) (const_int 0xffff8000))
++ Do the sign extension here. */
++ if (GET_CODE (operands[1]) == CONST_INT
++ && INTVAL (operands[1]) > 0x7fffL && INTVAL (operands[1]) <= 0x0ffffL)
++ {
++ operands[1] = GEN_INT ((INTVAL (operands[1])) | (-1L << 16));
++ }
+ if (TARGET_M6811 && (reload_in_progress | reload_completed) == 0)
+ {
+ if (GET_CODE (operands[0]) == MEM &&
+@@ -878,18 +896,9 @@
+ }
+ }")
+
+-(define_insn "movhi_const0"
+- [(set (match_operand:HI 0 "non_push_operand" "=d,A,um")
+- (const_int 0))]
+- ""
+- "@
+- clra\\n\\tclrb
+- ld%0\\t#0
+- clr\\t%b0\\n\\tclr\\t%h0")
+-
+ (define_insn "*movhi_68hc12"
+- [(set (match_operand:HI 0 "nonimmediate_operand" "=U,dAw,U,U,m,!u")
+- (match_operand:HI 1 "general_operand" "U,rim,dAwi,!u,dAw,riU"))]
++ [(set (match_operand:HI 0 "nonimmediate_operand" "=U,dAw,dAw,m,U,U,m,!u")
++ (match_operand:HI 1 "general_operand" "U,dAwim,!u,K,dAwi,!u,dAw,riU"))]
+ "TARGET_M6812"
+ "*
+ {
+@@ -897,6 +906,15 @@
+ return \"\";
+ }")
+
++(define_insn "movhi_const0"
++ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,A,um")
++ (const_int 0))]
++ "TARGET_M6811"
++ "@
++ clra\\n\\tclrb
++ ld%0\\t#0
++ clr\\t%b0\\n\\tclr\\t%h0")
++
+ (define_insn "*movhi_m68hc11"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=dAw,!u,m,m,dAw,!*u")
+ (match_operand:HI 1 "general_operand" "dAwim,dAw,dA,?Aw,!*u,dAw"))]
+@@ -936,9 +954,9 @@
+ (define_split
+ [(set (match_operand:QI 0 "hard_addr_reg_operand" "")
+ (match_operand:QI 1 "general_operand" ""))]
+- "z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode
++ "z_replacement_completed == 2
+ && !reg_mentioned_p (operands[0], operands[1])
+- && !D_REG_P (operands[1])"
++ && !(D_REG_P (operands[1]) || Q_REG_P (operands[1]))"
+ [(parallel [(set (reg:HI D_REGNUM) (match_dup 2))
+ (set (match_dup 2) (reg:HI D_REGNUM))])
+ (set (reg:QI D_REGNUM) (match_dup 1))
+@@ -952,9 +970,9 @@
+ (define_split
+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
+ (match_operand:QI 1 "hard_addr_reg_operand" ""))]
+- "z_replacement_completed == 2 && GET_MODE (operands[1]) == QImode
++ "z_replacement_completed == 2
+ && !reg_mentioned_p (operands[1], operands[0])
+- && !D_REG_P (operands[0])"
++ && !(D_REG_P (operands[0]) || Q_REG_P (operands[0]))"
+ [(parallel [(set (reg:HI D_REGNUM) (match_dup 2))
+ (set (match_dup 2) (reg:HI D_REGNUM))])
+ (set (match_dup 0) (reg:QI D_REGNUM))
+@@ -1664,8 +1682,8 @@
+ ;;- Min and Max instructions (68HC12).
+ ;;--------------------------------------------------------------------
+ (define_insn "uminqi3"
+- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
+- (umin:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
++ [(set (match_operand:QI 0 "nonimmediate_noinc_operand" "=d,m")
++ (umin:QI (match_operand:QI 1 "nonimmediate_noinc_operand" "%0,0")
+ (match_operand:QI 2 "general_operand" "m,d")))]
+ "TARGET_M6812 && TARGET_MIN_MAX"
+ "*
+@@ -1686,8 +1704,8 @@
+ }")
+
+ (define_insn "umaxqi3"
+- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
+- (umax:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
++ [(set (match_operand:QI 0 "nonimmediate_noinc_operand" "=d,m")
++ (umax:QI (match_operand:QI 1 "nonimmediate_noinc_operand" "%0,0")
+ (match_operand:QI 2 "general_operand" "m,d")))]
+ "TARGET_M6812 && TARGET_MIN_MAX"
+ "*
+@@ -1708,8 +1726,8 @@
+ }")
+
+ (define_insn "uminhi3"
+- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
+- (umin:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
++ [(set (match_operand:HI 0 "nonimmediate_noinc_operand" "=d,m")
++ (umin:HI (match_operand:HI 1 "nonimmediate_noinc_operand" "%0,0")
+ (match_operand:HI 2 "general_operand" "m,d")))]
+ "TARGET_M6812 && TARGET_MIN_MAX"
+ "*
+@@ -1727,8 +1745,8 @@
+ }")
+
+ (define_insn "umaxhi3"
+- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
+- (umax:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
++ [(set (match_operand:HI 0 "nonimmediate_noinc_operand" "=d,m")
++ (umax:HI (match_operand:HI 1 "nonimmediate_noinc_operand" "%0,0")
+ (match_operand:HI 2 "general_operand" "m,d")))]
+ "TARGET_M6812 && TARGET_MIN_MAX"
+ "*
+@@ -2090,8 +2108,8 @@
+ }")
+
+ (define_insn "*addhi3_68hc12"
+- [(set (match_operand:HI 0 "register_operand" "=xyd,d,xy*z*w,xy*z*w,xy*z")
+- (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,xy*zw,0")
++ [(set (match_operand:HI 0 "register_operand" "=d*A,d,xy*A*w,xy*A*w,xy*A")
++ (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,xy*Aw,0")
+ (match_operand:HI 2 "general_operand" "i,m*A*wu,id,id,!mu*A")))]
+ "TARGET_M6812"
+ "*
+@@ -2279,9 +2297,9 @@
+ }")
+
+ (define_insn "*addhi3"
+- [(set (match_operand:HI 0 "hard_reg_operand" "=A,dA,d,!A,d*A,!d*A")
+- (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0,0,0")
+- (match_operand:HI 2 "general_operand" "N,I,i,I,mi*A*d,!u*d*w")))]
++ [(set (match_operand:HI 0 "hard_reg_operand" "=A,dA,d,!A,d*A,d,!d*A")
++ (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0,0,0,0")
++ (match_operand:HI 2 "general_operand" "N,I,i,I,mi*A*d,*u,!u*d*w")))]
+ "TARGET_M6811"
+ "*
+ {
+@@ -2374,7 +2392,7 @@
+ [(set (match_operand:HI 0 "hard_reg_operand" "=A,d")
+ (plus:HI (zero_extend:HI
+ (match_operand:QI 1 "nonimmediate_operand" "d,um*A"))
+- (match_operand:HI 2 "hard_reg_operand" "0,0")))]
++ (match_operand:HI 2 "general_operand" "0,0")))]
+ ""
+ "*
+ {
+@@ -2401,8 +2419,8 @@
+ "")
+
+ (define_insn "addqi3"
+- [(set (match_operand:QI 0 "nonimmediate_operand" "=!d*rm,dq,!*A")
+- (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
++ [(set (match_operand:QI 0 "nonimmediate_noinc_operand" "=!d*rm,dq,!*A")
++ (plus:QI (match_operand:QI 1 "nonimmediate_noinc_operand" "%0,0,0")
+ (match_operand:QI 2 "general_operand" "N,ium*A*d,ium*A*d")))]
+ ""
+ "*
+@@ -2707,9 +2725,9 @@
+
+
+ (define_insn "*subhi3"
+- [(set (match_operand:HI 0 "register_operand" "=d,*A,d*A")
+- (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
+- (match_operand:HI 2 "general_operand" "im*A*d,im*d*A,!u")))]
++ [(set (match_operand:HI 0 "register_operand" "=d,*A,d,*A")
++ (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
++ (match_operand:HI 2 "general_operand" "im*A*d,im*d*A,u,!u")))]
+ ""
+ "*
+ {
+@@ -2723,7 +2741,7 @@
+
+ (define_insn "*subhi3_zext"
+ [(set (match_operand:HI 0 "hard_reg_operand" "=d,d")
+- (minus:HI (match_operand:HI 1 "hard_reg_operand" "0,0")
++ (minus:HI (match_operand:HI 1 "general_operand" "0,0")
+ (zero_extend:HI (match_operand:QI 2 "general_operand" "mi*A,!u"))))]
+ ""
+ "*
+@@ -2743,7 +2761,7 @@
+
+ (define_insn "subqi3"
+ [(set (match_operand:QI 0 "hard_reg_operand" "=dq,!*x*y")
+- (minus:QI (match_operand:QI 1 "hard_reg_operand" "0,0")
++ (minus:QI (match_operand:QI 1 "general_operand" "0,0")
+ (match_operand:QI 2 "general_operand" "uim*A*d,uim*A*d")))]
+ ""
+ "*
+@@ -2837,6 +2855,32 @@
+ return \"emul\\n\\texg\\tx,y\";
+ }")
+
++(define_insn "umulhisi3_hc11"
++ [(set (match_operand:SI 0 "register_operand" "=D,D")
++ (mult:SI (zero_extend:SI
++ (match_operand:HI 1 "register_operand" "%d,Amu"))
++ (zero_extend:SI
++ (match_operand:HI 2 "register_operand" "Amu,d"))))
++ (clobber (match_scratch:HI 3 "=y,y"))]
++ "TARGET_M6811"
++ "*
++{
++ CC_STATUS_INIT;
++ if (!H_REG_P (operands[1]))
++ output_asm_insn (\"ldx\\t%1\", operands);
++ if (!H_REG_P (operands[2]))
++ output_asm_insn (\"ldx\\t%2\", operands);
++
++ if (Y_REG_P (operands[1]) || Y_REG_P (operands[2]))
++ output_asm_insn (\"pshy\", operands);
++ else if (X_REG_P (operands[1]) || X_REG_P (operands[2])
++ || !H_REG_P (operands[1]) || !H_REG_P (operands[2]))
++ output_asm_insn (\"pshx\", operands);
++
++ output_asm_insn (\"bsr\\t__mulhi32\", operands);
++ return \"ins\\n\\tins\";
++}")
++
+ (define_insn "mulhisi3"
+ [(set (match_operand:SI 0 "register_operand" "=D,D")
+ (mult:SI (sign_extend:SI
+@@ -2896,8 +2940,8 @@
+
+ (define_insn "mulqi3"
+ [(set (match_operand:QI 0 "register_operand" "=d,*x,*y")
+- (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%dum,0,0")
+- (match_operand:QI 2 "general_operand" "dium,*xium,*yium")))]
++ (mult:QI (match_operand:QI 1 "general_operand" "%di*um,0,0")
++ (match_operand:QI 2 "general_operand" "di*um,*xium,*yium")))]
+ ""
+ "*
+ {
+@@ -2952,11 +2996,11 @@
+ ")
+
+ (define_insn "mulqihi3"
+- [(set (match_operand:HI 0 "register_operand" "=d,d")
++ [(set (match_operand:HI 0 "register_operand" "=d,d,d")
+ (mult:HI (sign_extend:HI
+- (match_operand:QI 1 "register_operand" "%0,0"))
++ (match_operand:QI 1 "register_operand" "%0,0,0"))
+ (sign_extend:HI
+- (match_operand:QI 2 "nonimmediate_operand" "dm,*A"))))]
++ (match_operand:QI 2 "general_operand" "mi*u,*A,0"))))]
+ ""
+ "*
+ {
+@@ -3054,21 +3098,29 @@
+ ;;- and instructions.
+ ;;--------------------------------------------------------------------
+
+-(define_insn "anddi3"
++(define_insn_and_split "anddi3"
+ [(set (match_operand:DI 0 "reg_or_some_mem_operand" "=m,u")
+ (and:DI (match_operand:DI 1 "reg_or_some_mem_operand" "%imu,imu")
+ (match_operand:DI 2 "general_operand" "imu,imu")))
+ (clobber (match_scratch:HI 3 "=d,d"))]
+ ""
+- "#")
++ "#"
++ "reload_completed"
++ [(const_int 0)]
++ "m68hc11_split_logical (SImode, AND, operands);
++ DONE;")
+
+-(define_insn "andsi3"
++(define_insn_and_split "andsi3"
+ [(set (match_operand:SI 0 "register_operand" "=D,!u")
+ (and:SI (match_operand:SI 1 "register_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "Dimu,imu")))
+ (clobber (match_scratch:HI 3 "=X,d"))]
+ ""
+- "#")
++ "#"
++ "reload_completed"
++ [(const_int 0)]
++ "m68hc11_split_logical (HImode, AND, operands);
++ DONE;")
+
+ (define_expand "andhi3"
+ [(set (match_operand:HI 0 "register_operand" "")
+@@ -3078,10 +3130,10 @@
+ "")
+
+ (define_insn "*andhi3_mem"
+- [(set (match_operand:HI 0 "memory_operand" "=Q,R")
++ [(set (match_operand:HI 0 "memory_operand" "=R,Q")
+ (and:HI (match_dup 0)
+ (match_operand:HI 1 "immediate_operand" "i,i")))
+- (clobber (match_scratch:HI 2 "=xy,X"))]
++ (clobber (match_scratch:HI 2 "=X,xy"))]
+ "TARGET_RELAX && !TARGET_M6812"
+ "*
+ {
+@@ -3101,7 +3153,7 @@
+ /* When destination is a global variable, generate a .relax instruction
+ and load the address in the clobber register. That load can be
+ eliminated by the linker if the address is in page0. */
+- if (which_alternative == 0)
++ if (which_alternative == 1)
+ {
+ rtx ops[3];
+
+@@ -3216,8 +3268,8 @@
+
+ (define_insn "*andhi3_gen"
+ [(set (match_operand:HI 0 "register_operand" "=d,d,!*A")
+- (and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
+- (match_operand:HI 2 "general_operand" "mi,!u*A,!um*A")))]
++ (and:HI (match_operand:HI 1 "splitable_operand" "%0,0,0")
++ (match_operand:HI 2 "splitable_operand" "mi,!u*A,!um*Ai")))]
+ ""
+ "*
+ {
+@@ -3236,10 +3288,10 @@
+ "")
+
+ (define_insn "*andqi3_mem"
+- [(set (match_operand:QI 0 "memory_operand" "=Q,R")
++ [(set (match_operand:QI 0 "memory_operand" "=R,Q")
+ (and:QI (match_dup 0)
+ (match_operand:QI 1 "const_int_operand" "i,i")))
+- (clobber (match_scratch:HI 2 "=xy,X"))]
++ (clobber (match_scratch:HI 2 "=X,xy"))]
+ "TARGET_RELAX && !TARGET_M6812"
+ "*
+ {
+@@ -3257,7 +3309,7 @@
+ /* When destination is a global variable, generate a .relax instruction
+ and load the address in the clobber register. That load can be
+ eliminated by the linker if the address is in page0. */
+- if (which_alternative == 0)
++ if (which_alternative == 1)
+ {
+ rtx ops[3];
+
+@@ -3310,8 +3362,8 @@
+
+ (define_insn "*andqi3_gen"
+ [(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q")
+- (and:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
+- (match_operand:QI 2 "general_operand" "mi,!u,?*A,!um,?*A*d,!um*A")))]
++ (and:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0")
++ (match_operand:QI 2 "general_operand" "mi,!*u,?*A,!*um,?*A*d,!*um*A")))]
+ ""
+ "*
+ {
+@@ -3330,34 +3382,42 @@
+ ;;- Bit set or instructions.
+ ;;--------------------------------------------------------------------
+
+-(define_insn "iordi3"
++(define_insn_and_split "iordi3"
+ [(set (match_operand:DI 0 "reg_or_some_mem_operand" "=m,u")
+ (ior:DI (match_operand:DI 1 "reg_or_some_mem_operand" "%imu,imu")
+ (match_operand:DI 2 "general_operand" "imu,imu")))
+ (clobber (match_scratch:HI 3 "=d,d"))]
+ ""
+- "#")
++ "#"
++ "reload_completed"
++ [(const_int 0)]
++ "m68hc11_split_logical (SImode, IOR, operands);
++ DONE;")
+
+-(define_insn "iorsi3"
++(define_insn_and_split "iorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=D,!u")
+ (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "Dimu,imu")))
+ (clobber (match_scratch:HI 3 "=X,d"))]
+ ""
+- "#")
++ "#"
++ "reload_completed"
++ [(const_int 0)]
++ "m68hc11_split_logical (HImode, IOR, operands);
++ DONE;")
+
+ (define_expand "iorhi3"
+ [(set (match_operand:HI 0 "register_operand" "")
+ (ior:HI (match_operand:HI 1 "register_operand" "")
+- (match_operand:HI 2 "general_operand" "")))]
++ (match_operand:HI 2 "splitable_operand" "")))]
+ ""
+ "")
+
+ (define_insn "*iorhi3_mem"
+- [(set (match_operand:HI 0 "memory_operand" "=Q,R")
++ [(set (match_operand:HI 0 "memory_operand" "=R,Q")
+ (ior:HI (match_dup 0)
+ (match_operand:HI 1 "const_int_operand" "")))
+- (clobber (match_scratch:HI 2 "=xy,X"))]
++ (clobber (match_scratch:HI 2 "=X,xy"))]
+ "TARGET_RELAX && !TARGET_M6812"
+ "*
+ {
+@@ -3369,7 +3429,7 @@
+ return \"\";
+ }
+ CC_STATUS_INIT;
+- if (which_alternative == 0)
++ if (which_alternative == 1)
+ {
+ rtx ops[3];
+
+@@ -3437,8 +3497,8 @@
+
+ (define_insn "*iorhi3_gen"
+ [(set (match_operand:HI 0 "register_operand" "=d,d,!*A")
+- (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0")
+- (match_operand:HI 2 "general_operand" "mi,!u*A,!um*A")))]
++ (ior:HI (match_operand:HI 1 "splitable_operand" "%0,0,0")
++ (match_operand:HI 2 "splitable_operand" "mi,!u*A,!um*Ai")))]
+ ""
+ "*
+ {
+@@ -3457,10 +3517,10 @@
+ "")
+
+ (define_insn "*iorqi3_mem"
+- [(set (match_operand:QI 0 "memory_operand" "=Q,R")
++ [(set (match_operand:QI 0 "memory_operand" "=R,Q")
+ (ior:QI (match_dup 0)
+ (match_operand:QI 1 "const_int_operand" "")))
+- (clobber (match_scratch:HI 2 "=xy,X"))]
++ (clobber (match_scratch:HI 2 "=X,xy"))]
+ "TARGET_RELAX && !TARGET_M6812"
+ "*
+ {
+@@ -3471,7 +3531,7 @@
+ cc_status = cc_prev_status;
+ return \"\";
+ }
+- if (which_alternative == 0)
++ if (which_alternative == 1)
+ {
+ rtx ops[3];
+
+@@ -3520,8 +3580,8 @@
+
+ (define_insn "*iorqi3_gen"
+ [(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q")
+- (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
+- (match_operand:QI 2 "general_operand" "mi,!u,!*A,!um,?*A*d,!um*A")))]
++ (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0")
++ (match_operand:QI 2 "general_operand" "mi,!*u,!*A,!*um,?*A*d,!*um*A")))]
+ ""
+ "*
+ {
+@@ -3541,26 +3601,34 @@
+ ;;- xor instructions.
+ ;;--------------------------------------------------------------------
+
+-(define_insn "xordi3"
++(define_insn_and_split "xordi3"
+ [(set (match_operand:DI 0 "reg_or_some_mem_operand" "=m,u")
+ (xor:DI (match_operand:DI 1 "reg_or_some_mem_operand" "%imu,imu")
+ (match_operand:DI 2 "general_operand" "imu,imu")))
+ (clobber (match_scratch:HI 3 "=d,d"))]
+ ""
+- "#")
++ "#"
++ "reload_completed"
++ [(const_int 0)]
++ "m68hc11_split_logical (SImode, XOR, operands);
++ DONE;")
+
+-(define_insn "xorsi3"
++(define_insn_and_split "xorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=D,!u")
+ (xor:SI (match_operand:SI 1 "register_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "Dimu,imu")))
+ (clobber (match_scratch:HI 3 "=X,d"))]
+ ""
+- "#")
++ "#"
++ "reload_completed"
++ [(const_int 0)]
++ "m68hc11_split_logical (HImode, XOR, operands);
++ DONE;")
+
+ (define_insn "xorhi3"
+ [(set (match_operand:HI 0 "register_operand" "=d,d,!*A")
+- (xor:HI (match_operand:HI 1 "register_operand" "%0,0,0")
+- (match_operand:HI 2 "general_operand" "im,!u*A,!ium*A")))]
++ (xor:HI (match_operand:HI 1 "splitable_operand" "%0,0,0")
++ (match_operand:HI 2 "splitable_operand" "im,!u*A,!ium*A")))]
+ ""
+ "*
+ {
+@@ -3604,8 +3672,8 @@
+
+ (define_insn "xorqi3"
+ [(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q")
+- (xor:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
+- (match_operand:QI 2 "general_operand" "im,!u,!*A,!ium,?*A*d,!ium*A")))]
++ (xor:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0")
++ (match_operand:QI 2 "general_operand" "im,!*u,!*A,!i*um,?*A*d,!i*um*A")))]
+ ""
+ "*
+ {
+@@ -3641,30 +3709,47 @@
+ ;;- Bit set or instructions.
+ ;;--------------------------------------------------------------------
+
+-(define_insn "*logicalsi3_zexthi"
++(define_insn_and_split "*logicalsi3_zexthi"
+ [(set (match_operand:SI 0 "register_operand" "=D")
+ (match_operator:SI 3 "m68hc11_logical_operator"
+ [(zero_extend:SI
+ (match_operand:HI 1 "general_operand" "imudA"))
+ (match_operand:SI 2 "general_operand" "Dimu")]))]
+ ""
+- "#")
++ "#"
++ "reload_completed"
++ [(set (reg:HI D_REGNUM) (match_dup 4))
++ (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 5)]))
++ (set (reg:HI X_REGNUM) (match_dup 6))]
++ "PUT_MODE (operands[3], HImode);
++ if (X_REG_P (operands[2]))
++ {
++ operands[5] = operands[1];
++ /* Make all the (set (REG:x) (REG:y)) a nop set. */
++ operands[4] = gen_rtx (REG, HImode, HARD_D_REGNUM);
++ operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM);
++ }
++ else
++ {
++ operands[4] = operands[1];
++ operands[5] = m68hc11_gen_lowpart (HImode, operands[2]);
++ operands[6] = m68hc11_gen_highpart (HImode, operands[2]);
++ }
++ /* For an AND, make sure the high 16-bit part is cleared. */
++ if (GET_CODE (operands[3]) == AND)
++ {
++ operands[6] = const0_rtx;
++ }
++ ")
+
+-(define_insn "*logicalsi3_zextqi"
++(define_insn_and_split "*logicalsi3_zextqi"
+ [(set (match_operand:SI 0 "register_operand" "=D,D,D")
+ (match_operator:SI 3 "m68hc11_logical_operator"
+ [(zero_extend:SI
+ (match_operand:QI 1 "general_operand" "d,*A,imu"))
+ (match_operand:SI 2 "general_operand" "imu,imu,0")]))]
+ ""
+- "#")
+-
+-(define_split /* logicalsi3_zextqi */
+- [(set (match_operand:SI 0 "register_operand" "")
+- (match_operator:SI 3 "m68hc11_logical_operator"
+- [(zero_extend:SI
+- (match_operand:QI 1 "general_operand" ""))
+- (match_operand:SI 2 "general_operand" "")]))]
++ "#"
+ "z_replacement_completed == 2"
+ [(set (reg:QI A_REGNUM) (match_dup 4))
+ (set (reg:QI D_REGNUM) (match_dup 7))
+@@ -3695,63 +3780,47 @@
+ }
+ ")
+
+-(define_split /* logicalsi3_zexthi */
+- [(set (match_operand:SI 0 "register_operand" "")
+- (match_operator:SI 3 "m68hc11_logical_operator"
+- [(zero_extend:SI
+- (match_operand:HI 1 "general_operand" ""))
+- (match_operand:SI 2 "general_operand" "")]))]
+- "reload_completed"
+- [(set (reg:HI D_REGNUM) (match_dup 4))
+- (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 5)]))
+- (set (reg:HI X_REGNUM) (match_dup 6))]
+- "PUT_MODE (operands[3], HImode);
+- if (X_REG_P (operands[2]))
+- {
+- operands[5] = operands[1];
+- /* Make all the (set (REG:x) (REG:y)) a nop set. */
+- operands[4] = gen_rtx (REG, HImode, HARD_D_REGNUM);
+- operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM);
+- }
+- else
+- {
+- operands[4] = operands[1];
+- operands[5] = m68hc11_gen_lowpart (HImode, operands[2]);
+- operands[6] = m68hc11_gen_highpart (HImode, operands[2]);
+- }
+- /* For an AND, make sure the high 16-bit part is cleared. */
+- if (GET_CODE (operands[3]) == AND)
+- {
+- operands[6] = const0_rtx;
+- }
+- ")
+-
+-(define_insn "*logicalhi3_zexthi_ashift8"
++(define_insn_and_split "*logicalhi3_zexthi_ashift8"
+ [(set (match_operand:HI 0 "register_operand" "=d")
+ (match_operator:HI 3 "m68hc11_logical_operator"
+ [(zero_extend:HI
+- (match_operand:QI 1 "general_operand" "imud"))
++ (match_operand:QI 1 "general_operand" "imud*A"))
+ (ashift:HI
+- (match_operand:HI 2 "general_operand" "dimu")
++ (match_operand:HI 2 "general_operand" "imud*A")
+ (const_int 8))]))]
+ ""
+- "#")
++ "#"
++ "z_replacement_completed == 2"
++ [(set (reg:QI A_REGNUM) (match_dup 4))
++ (set (reg:QI B_REGNUM) (match_dup 5))]
++ "
++ if (GET_CODE (operands[3]) == AND)
++ {
++ emit_insn (gen_movhi (operands[0], const0_rtx));
++ DONE;
++ }
++ else
++ {
++ operands[5] = operands[1];
++ if (D_REG_P (operands[2]))
++ {
++ operands[4] = gen_rtx (REG, QImode, HARD_B_REGNUM);
++ }
++ else
++ {
++ operands[4] = m68hc11_gen_lowpart (QImode, operands[2]);
++ }
++ }
++ ")
+
+-(define_insn "*logicalhi3_zexthi"
++(define_insn_and_split "*logicalhi3_zexthi"
+ [(set (match_operand:HI 0 "register_operand" "=d,d")
+ (match_operator:HI 3 "m68hc11_logical_operator"
+ [(zero_extend:HI
+ (match_operand:QI 1 "general_operand" "imd*A,?u"))
+ (match_operand:HI 2 "general_operand" "dim,?dimu")]))]
+ ""
+- "#")
+-
+-(define_split /* logicalhi3_zexthi */
+- [(set (match_operand:HI 0 "register_operand" "")
+- (match_operator:HI 3 "m68hc11_logical_operator"
+- [(zero_extend:HI
+- (match_operand:QI 1 "general_operand" ""))
+- (match_operand:HI 2 "general_operand" "")]))]
++ "#"
+ "z_replacement_completed == 2"
+ [(set (reg:QI B_REGNUM) (match_dup 6))
+ (set (reg:QI A_REGNUM) (match_dup 4))
+@@ -3780,63 +3849,25 @@
+ }
+ ")
+
+-(define_split /* logicalhi3_zexthi_ashift8 */
+- [(set (match_operand:HI 0 "register_operand" "")
+- (match_operator:HI 3 "m68hc11_logical_operator"
+- [(zero_extend:HI
+- (match_operand:QI 1 "general_operand" ""))
+- (ashift:HI
+- (match_operand:HI 2 "general_operand" "")
+- (const_int 8))]))]
+- "z_replacement_completed == 2"
+- [(set (reg:QI A_REGNUM) (match_dup 4))
+- (set (reg:QI B_REGNUM) (match_dup 5))]
+- "
+- if (GET_CODE (operands[3]) == AND)
++
++(define_insn_and_split "*logicalsi3_silshr16"
++ [(set (match_operand:SI 0 "register_operand" "=D,D,D,?D")
++ (match_operator:SI 3 "m68hc11_logical_operator"
++ [(lshiftrt:SI
++ (match_operand:SI 1 "general_operand" "uim,uim,0,0")
++ (const_int 16))
++ (match_operand:SI 2 "general_operand" "uim,0,uim,0")]))]
++ ""
++ "#"
++ "reload_completed"
++ [(set (reg:HI D_REGNUM) (match_dup 4))
++ (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 5)]))
++ (set (reg:HI X_REGNUM) (match_dup 6))]
++ "operands[5] = m68hc11_gen_highpart (HImode, operands[1]);
++ if (X_REG_P (operands[2]))
+ {
+- emit_insn (gen_movhi (operands[0], const0_rtx));
+- DONE;
+- }
+- else
+- {
+- operands[5] = operands[1];
+- if (D_REG_P (operands[2]))
+- {
+- operands[4] = gen_rtx (REG, QImode, HARD_B_REGNUM);
+- }
+- else
+- {
+- operands[4] = m68hc11_gen_lowpart (QImode, operands[2]);
+- }
+- }
+- ")
+-
+-(define_insn "*logicalsi3_silshr16"
+- [(set (match_operand:SI 0 "register_operand" "=D,D,D")
+- (match_operator:SI 3 "m68hc11_logical_operator"
+- [(lshiftrt:SI
+- (match_operand:SI 1 "general_operand" "uim,uim,?D")
+- (const_int 16))
+- (match_operand:SI 2 "general_operand" "uim,0,0")]))]
+- ""
+- "#")
+-
+-(define_split /* logicalsi3_silshr16 */
+- [(set (match_operand:SI 0 "register_operand" "")
+- (match_operator:SI 3 "m68hc11_logical_operator"
+- [(lshiftrt:SI
+- (match_operand:SI 1 "general_operand" "")
+- (const_int 16))
+- (match_operand:SI 2 "general_operand" "")]))]
+- "reload_completed"
+- [(set (reg:HI D_REGNUM) (match_dup 4))
+- (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 5)]))
+- (set (reg:HI X_REGNUM) (match_dup 6))]
+- "operands[5] = m68hc11_gen_highpart (HImode, operands[1]);
+- if (X_REG_P (operands[2]))
+- {
+- operands[4] = gen_rtx (REG, HImode, HARD_D_REGNUM);
+- operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM);
++ operands[4] = gen_rtx (REG, HImode, HARD_D_REGNUM);
++ operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM);
+ }
+ else
+ {
+@@ -3852,7 +3883,7 @@
+ }
+ ")
+
+-(define_insn "*logicalsi3_silshl16"
++(define_insn_and_split "*logicalsi3_silshl16"
+ [(set (match_operand:SI 0 "register_operand" "=D,D")
+ (match_operator:SI 3 "m68hc11_logical_operator"
+ [(ashift:SI
+@@ -3860,15 +3891,7 @@
+ (const_int 16))
+ (match_operand:SI 2 "general_operand" "0,0")]))]
+ ""
+- "#")
+-
+-(define_split /* logicalsi3_silshl16 */
+- [(set (match_operand:SI 0 "register_operand" "")
+- (match_operator:SI 3 "m68hc11_logical_operator"
+- [(ashift:SI
+- (match_operand:SI 1 "general_operand" "")
+- (const_int 16))
+- (match_operand:SI 2 "general_operand" "")]))]
++ "#"
+ "z_replacement_completed == 2"
+ [(set (reg:HI X_REGNUM) (match_op_dup 3 [(reg:HI X_REGNUM) (match_dup 4)]))
+ (set (reg:HI D_REGNUM) (match_dup 5))]
+@@ -3881,48 +3904,45 @@
+ operands[5] = gen_rtx (REG, HImode, HARD_D_REGNUM);
+ ")
+
+-
+-;;--------------------------------------------------------------------
+-;;- 64/32-bit Logical Operations. Patterns are defined so that GCC
+-;; can optimize correctly. These insns are split by the `final'
+-;; pass (# pattern). They are split to fall in the corresponding
+-;; 16-bit logical patterns.
+-;;--------------------------------------------------------------------
+-
+-;; Split 64-bit logical operations: anddi3, iordi3, xordi3
+-(define_split
+- [(set (match_operand:DI 0 "reg_or_some_mem_operand" "")
+- (match_operator:DI 4 "m68hc11_logical_operator"
+- [(match_operand:DI 1 "reg_or_some_mem_operand" "")
+- (match_operand:DI 2 "general_operand" "")]))
+- (clobber (match_scratch:HI 3 ""))]
++(define_insn_and_split "*logicalsi3_silshl16_zext"
++ [(set (match_operand:SI 0 "register_operand" "=D,D,D")
++ (match_operator:SI 3 "m68hc11_logical_operator"
++ [(ashift:SI
++ (zero_extend:SI
++ (match_operand:HI 1 "general_operand" "uim,udA,!dA"))
++ (const_int 16))
++ (zero_extend:SI (match_operand:HI 2 "general_operand" "uidA,um,!dA"))]))]
++ ""
++ "#"
++ ;; Must split before z register replacement
+ "reload_completed"
+- [(const_int 0)]
+- "m68hc11_split_logical (SImode, GET_CODE (operands[4]), operands);
+- DONE;")
+-
+-;; Split 32-bit logical operations: andsi3, iorsi3, xorsi3
+-(define_split
+- [(set (match_operand:SI 0 "register_operand" "")
+- (match_operator:SI 3 "m68hc11_logical_operator"
+- [(match_operand:SI 1 "register_operand" "")
+- (match_operand:SI 2 "general_operand" "")]))]
+- "0 && reload_completed"
+- [(const_int 0)]
+- "m68hc11_split_logical (HImode, GET_CODE (operands[3]), operands);
+- DONE;")
++ [(set (match_dup 4) (match_dup 5))
++ (set (match_dup 6) (match_dup 7))]
++ "
++ /* set (X_REGNUM) (d), set (D_REGNUM) (1) */
++ if (GET_CODE (operands[1]) == HARD_D_REGNUM
++ && GET_CODE (operands[3]) != AND)
++ {
++ /* This particular case is too early to be split before
++ Z register replacement because the cse-reg pass we do
++ does not recognize the 'swap_areg'. It is ok to handle
++ this case after. */
++ if (z_replacement_completed != 2)
++ {
++ FAIL;
++ }
++ emit_move_insn (gen_rtx (REG, HImode, HARD_X_REGNUM), operands[2]);
++ emit_insn (gen_swap_areg (gen_rtx (REG, HImode, HARD_D_REGNUM),
++ gen_rtx (REG, HImode, HARD_X_REGNUM)));
++ }
++ operands[4] = gen_rtx (REG, HImode, HARD_D_REGNUM);
++ operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM);
++ operands[5] = operands[2];
++ operands[7] = operands[1];
+
+-;; Split 32-bit logical operations: andsi3, iorsi3, xorsi3
+-(define_split
+- [(set (match_operand:SI 0 "reg_or_some_mem_operand" "")
+- (match_operator:SI 4 "m68hc11_logical_operator"
+- [(match_operand:SI 1 "reg_or_some_mem_operand" "")
+- (match_operand:SI 2 "general_operand" "")]))
+- (clobber (match_scratch:HI 3 ""))]
+- "reload_completed"
+- [(const_int 0)]
+- "m68hc11_split_logical (HImode, GET_CODE (operands[4]), operands);
+- DONE;")
++ if (GET_CODE (operands[3]) == AND)
++ operands[5] = operands[7] = const0_rtx;
++ ")
+
+ ;;--------------------------------------------------------------------
+ ;; 16-bit Arithmetic and logical operations on X and Y:
+@@ -4323,8 +4343,8 @@
+ xgd%0\\n\\tcoma\\n\\tcomb\\n\\txgd%0\\n\\tin%0")
+
+ (define_insn "negqi2"
+- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m,!u,!*A")
+- (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,0,0")))]
++ [(set (match_operand:QI 0 "nonimmediate_noinc_operand" "=d,m,!u,!*A")
++ (neg:QI (match_operand:QI 1 "nonimmediate_noinc_operand" "0,0,0,0")))]
+ ""
+ "@
+ negb
+@@ -4421,19 +4441,13 @@
+ }
+ }")
+
+-(define_insn "*ashldi3_const32"
++(define_insn_and_split "*ashldi3_const32"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=<,m,u")
+ (ashift:DI (match_operand:DI 1 "general_operand" "umi,umi,umi")
+ (const_int 32)))
+ (clobber (match_scratch:HI 2 "=&A,d,d"))]
+ ""
+- "#")
+-
+-(define_split
+- [(set (match_operand:DI 0 "nonimmediate_operand" "")
+- (ashift:DI (match_operand:DI 1 "general_operand" "")
+- (const_int 32)))
+- (clobber (match_scratch:HI 2 ""))]
++ "#"
+ "reload_completed"
+ [(const_int 0)]
+ "/* Move the lowpart in the highpart first in case the shift
+@@ -4442,6 +4456,13 @@
+ {
+ m68hc11_split_move (m68hc11_gen_lowpart (SImode, operands[0]),
+ const0_rtx, operands[2]);
++
++ /* Adjust first operand if it uses SP so that we take into
++ account the above push. Can occur only for 68HC12. */
++ if (reg_mentioned_p (gen_rtx (REG, HImode, HARD_SP_REGNUM),
++ operands[1]))
++ operands[1] = adjust_address (operands[1],
++ GET_MODE (operands[0]), 4);
+ }
+ m68hc11_split_move (m68hc11_gen_highpart (SImode, operands[0]),
+ m68hc11_gen_lowpart (SImode, operands[1]),
+@@ -4453,19 +4474,13 @@
+ }
+ DONE;")
+
+-(define_insn "*ashldi3_const1"
++(define_insn_and_split "*ashldi3_const1"
+ [(set (match_operand:DI 0 "non_push_operand" "=m,m,u")
+ (ashift:DI (match_operand:DI 1 "general_operand" "mi,u,umi")
+ (const_int 1)))
+ (clobber (match_scratch:HI 2 "=d,d,d"))]
+ ""
+- "#")
+-
+-(define_split
+- [(set (match_operand:DI 0 "non_push_operand" "")
+- (ashift:DI (match_operand:DI 1 "general_operand" "")
+- (const_int 1)))
+- (clobber (match_scratch:HI 2 ""))]
++ "#"
+ "z_replacement_completed == 2"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 2) (ashift:HI (match_dup 2) (const_int 1)))
+@@ -4505,10 +4520,10 @@
+ operands[8] = m68hc11_gen_lowpart (HImode, operands[8]);")
+
+ (define_insn "addsi_silshr16"
+- [(set (match_operand:SI 0 "register_operand" "=D,D")
+- (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "!*uim,0")
++ [(set (match_operand:SI 0 "register_operand" "=D,D,!D")
++ (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "!*uim,0,0")
+ (const_int 16))
+- (match_operand:SI 2 "general_operand" "0,m!*u")))]
++ (match_operand:SI 2 "general_operand" "0,m!*u,0")))]
+ ""
+ "#")
+
+@@ -4530,14 +4545,24 @@
+ (const_int 16))
+ (match_operand:SI 2 "general_operand" "")))]
+ "z_replacement_completed == 2 && X_REG_P (operands[1])"
+- [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM))
++ [(set (reg:HI D_REGNUM) (match_dup 5))
+ (set (reg:HI X_REGNUM) (match_dup 3))
+ (set (reg:HI D_REGNUM) (plus:HI (reg:HI D_REGNUM) (match_dup 4)))
+ (set (reg:HI X_REGNUM) (plus:HI (plus:HI (reg:HI X_REGNUM)
+ (const_int 0))
+ (reg:HI CC_REGNUM)))]
+ "operands[3] = m68hc11_gen_highpart (HImode, operands[2]);
+- operands[4] = m68hc11_gen_lowpart (HImode, operands[2]);")
++ if (X_REG_P (operands[2]))
++ {
++ operands[4] = gen_rtx (REG, HImode, HARD_X_REGNUM);
++ operands[5] = gen_rtx (REG, HImode, HARD_D_REGNUM);
++ }
++ else
++ {
++ operands[4] = m68hc11_gen_lowpart (HImode, operands[2]);
++ operands[5] = gen_rtx (REG, HImode, HARD_X_REGNUM);
++ }
++")
+
+ (define_insn "addsi_ashift16"
+ [(set (match_operand:SI 0 "register_operand" "=D")
+@@ -4563,24 +4588,27 @@
+ operands[4] = m68hc11_gen_lowpart (HImode, operands[2]);
+ }")
+
+-(define_insn "addsi_andshr16"
++(define_insn_and_split "addsi_andshr16"
+ [(set (match_operand:SI 0 "register_operand" "=D")
+ (plus:SI (and:SI (match_operand:SI 1 "general_operand" "%uim")
+ (const_int 65535))
+ (match_operand:SI 2 "general_operand" "0")))]
+ ""
+- "#")
+-
+-(define_split
+- [(set (match_operand:SI 0 "register_operand" "")
+- (plus:SI (and:SI (match_operand:SI 1 "general_operand" "")
+- (const_int 65535))
+- (match_operand:SI 2 "general_operand" "")))]
++ "#"
+ "z_replacement_completed == 2"
+ [(set (reg:HI D_REGNUM) (plus:HI (reg:HI D_REGNUM) (match_dup 3)))
+ (set (reg:HI X_REGNUM) (plus:HI (plus:HI (reg:HI X_REGNUM) (const_int 0)) (reg:HI CC_REGNUM)))]
+ "operands[3] = m68hc11_gen_lowpart (HImode, operands[1]);")
+
++(define_insn "subhi_ashlhi8"
++ [(set (match_operand:HI 0 "register_operand" "=d")
++ (minus:HI (match_operand:HI 1 "register_operand" "0")
++ (mult:HI (match_operand:HI 2 "register_operand" "0")
++ (const_int 256))))]
++ "0"
++ "@
++ sba")
++
+ ;;
+ ;; 32-bit shifts are made by a small library routine that uses
+ ;; a specific passing convention for parameters (for efficiency reasons).
+@@ -4622,31 +4650,24 @@
+ ""
+ "#")
+
+-(define_insn "*ashlsi3_const16_zexthi"
++(define_insn_and_split "*ashlsi3_const16_zexthi"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=D")
+ (ashift:SI (zero_extend:HI
+ (match_operand:HI 1 "general_operand" "duim*A"))
+ (const_int 16)))
+ (clobber (match_scratch:HI 2 "=X"))]
+ ""
+- "#")
+-
+-(define_split /* "*ashlsi3_const16_zexthi"*/
+- [(set (match_operand:SI 0 "nonimmediate_operand" "")
+- (ashift:SI (zero_extend:HI
+- (match_operand:HI 1 "general_operand" ""))
+- (const_int 16)))
+- (clobber (match_scratch:HI 2 "=X"))]
++ "#"
+ "reload_completed"
+ [(set (reg:HI X_REGNUM) (match_dup 1))
+ (set (reg:HI D_REGNUM) (const_int 0))]
+ "")
+
+ (define_insn "*ashlsi3_const1"
+- [(set (match_operand:SI 0 "non_push_operand" "=D,D,m,!*u,?*um")
+- (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,*um,0,0,*um")
++ [(set (match_operand:SI 0 "non_push_operand" "=D,D,D,m,*u,*u")
++ (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,*u,m,*u,m")
+ (const_int 1)))
+- (clobber (match_scratch:HI 2 "=X,X,&d,&d,&d"))]
++ (clobber (match_scratch:HI 2 "=X,X,X,&d,&d,&d"))]
+ ""
+ "*
+ {
+@@ -4702,7 +4723,7 @@
+ (ashift:SI (match_dup 0)
+ (match_operand:HI 1 "const_int_operand" "")))
+ (clobber (match_scratch:HI 2 "=y"))]
+- ""
++ "TARGET_M6811 /* See *ashlsi3 note. */"
+ "*
+ {
+ CC_STATUS_INIT;
+@@ -4712,7 +4733,7 @@
+ (define_insn "*ashlsi3"
+ [(set (match_operand:SI 0 "register_operand" "+D,D")
+ (ashift:SI (match_dup 0)
+- (match_operand:HI 1 "general_operand" "y,m")))
++ (match_operand:HI 1 "general_operand" "y,mi")))
+ (clobber (match_scratch:HI 2 "=1,X"))]
+ ""
+ "*
+@@ -4725,7 +4746,12 @@
+ is not enough register in class A_REGS.
+
+ Assuming that 'operands[1]' does not refer to the stack (which
+- is true for 68hc11 only, we save temporary the value of Y. */
++ is true for 68hc11 only, we save temporary the value of Y.
++
++ For 68HC12 we must also accept a constant because Z register is
++ disabled when compiling with -fomit-frame-pointer. We can come up
++ with a reload problem and the *lshrsi3_const pattern was disabled
++ for that reason. */
+ if (!Y_REG_P (operands[2]))
+ {
+ rtx ops[1];
+@@ -4861,8 +4887,8 @@
+ "")
+
+ (define_insn "*ashlqi3_const1"
+- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m,!u,!*q,!*A")
+- (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,0,0,0")
++ [(set (match_operand:QI 0 "nonimmediate_noinc_operand" "=d,m,!u,!*q,!*A")
++ (ashift:QI (match_operand:QI 1 "nonimmediate_noinc_operand" "0,0,0,0,0")
+ (const_int 1)))]
+ ""
+ "@
+@@ -5112,7 +5138,7 @@
+ (ashiftrt:SI (match_dup 0)
+ (match_operand:HI 1 "const_int_operand" "")))
+ (clobber (match_scratch:HI 2 "=y"))]
+- ""
++ "TARGET_M6811 /* See *ashrsi3 note. */"
+ "*
+ {
+ CC_STATUS_INIT;
+@@ -5122,7 +5148,7 @@
+ (define_insn "*ashrsi3"
+ [(set (match_operand:SI 0 "register_operand" "+D,D")
+ (ashiftrt:SI (match_dup 0)
+- (match_operand:HI 1 "general_operand" "y,m")))
++ (match_operand:HI 1 "general_operand" "y,mi")))
+ (clobber (match_scratch:HI 2 "=1,X"))]
+ ""
+ "*
+@@ -5134,7 +5160,12 @@
+ is not enough register in class A_REGS.
+
+ Assuming that 'operands[1]' does not refer to the stack (which
+- is true for 68hc11 only, we save temporary the value of Y. */
++ is true for 68hc11 only, we save temporary the value of Y.
++
++ For 68HC12 we must also accept a constant because Z register is
++ disabled when compiling with -fomit-frame-pointer. We can come up
++ with a reload problem and the *lshrsi3_const pattern was disabled
++ for that reason. */
+ if (!Y_REG_P (operands[2]))
+ {
+ rtx ops[1];
+@@ -5162,8 +5193,8 @@
+ "")
+
+ (define_insn "*ashrqi3_const1"
+- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m,!u,!*q,!*A")
+- (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,0,0,0")
++ [(set (match_operand:QI 0 "nonimmediate_noinc_operand" "=d,m,!u,!*q,!*A")
++ (ashiftrt:QI (match_operand:QI 1 "nonimmediate_noinc_operand" "0,0,0,0,0")
+ (const_int 1)))]
+ ""
+ "@
+@@ -5240,19 +5271,13 @@
+ }
+ }")
+
+-(define_insn "*lshrdi3_const32"
++(define_insn_and_split "*lshrdi3_const32"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=<,m,u")
+ (lshiftrt:DI (match_operand:DI 1 "general_operand" "umi,umi,umi")
+ (const_int 32)))
+ (clobber (match_scratch:HI 2 "=&A,d,d"))]
+ ""
+- "#")
+-
+-(define_split
+- [(set (match_operand:DI 0 "nonimmediate_operand" "")
+- (lshiftrt:DI (match_operand:DI 1 "general_operand" "")
+- (const_int 32)))
+- (clobber (match_scratch:HI 2 "=&A,d"))]
++ "#"
+ "reload_completed"
+ [(const_int 0)]
+ "m68hc11_split_move (m68hc11_gen_lowpart (SImode, operands[0]),
+@@ -5322,19 +5347,13 @@
+ operands[7] = m68hc11_gen_highpart (HImode, operands[6]);
+ operands[6] = m68hc11_gen_lowpart (HImode, operands[6]);")
+
+-(define_insn "*lshrdi_const1"
++(define_insn_and_split "*lshrdi_const1"
+ [(set (match_operand:DI 0 "non_push_operand" "=m,u")
+ (lshiftrt:DI (match_operand:DI 1 "general_operand" "umi,umi")
+ (const_int 1)))
+ (clobber (match_scratch:HI 2 "=d,d"))]
+ ""
+- "#")
+-
+-(define_split
+- [(set (match_operand:DI 0 "non_push_operand" "")
+- (lshiftrt:DI (match_operand:DI 1 "general_operand" "")
+- (const_int 1)))
+- (clobber (match_scratch:HI 2 ""))]
++ "#"
+ "z_replacement_completed == 2"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 2) (lshiftrt:HI (match_dup 2) (const_int 1)))
+@@ -5407,10 +5426,10 @@
+ #")
+
+ (define_insn "*lshrsi3_const1"
+- [(set (match_operand:SI 0 "non_push_operand" "=D,m,*u")
+- (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "D*um,*um,*um")
++ [(set (match_operand:SI 0 "non_push_operand" "=D,D,D,m,*u,*u")
++ (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,*u,m,*u,m")
+ (const_int 1)))
+- (clobber (match_scratch:HI 2 "=X,&d,&d"))]
++ (clobber (match_scratch:HI 2 "=X,X,X,&d,&d,&d"))]
+ ""
+ "*
+ {
+@@ -5461,7 +5480,7 @@
+ (lshiftrt:SI (match_dup 0)
+ (match_operand:HI 1 "const_int_operand" "")))
+ (clobber (match_scratch:HI 2 "=y"))]
+- ""
++ "TARGET_M6811 /* See *lshrsi3 note. */"
+ "*
+ {
+ CC_STATUS_INIT;
+@@ -5471,7 +5490,7 @@
+ (define_insn "*lshrsi3"
+ [(set (match_operand:SI 0 "register_operand" "+D,D")
+ (lshiftrt:SI (match_dup 0)
+- (match_operand:HI 1 "general_operand" "y,m")))
++ (match_operand:HI 1 "general_operand" "y,mi")))
+ (clobber (match_scratch:HI 2 "=1,X"))]
+ ""
+ "*
+@@ -5483,7 +5502,12 @@
+ is not enough register in class A_REGS.
+
+ Assuming that 'operands[1]' does not refer to the stack (which
+- is true for 68hc11 only, we save temporary the value of Y. */
++ is true for 68hc11 only, we save temporary the value of Y.
++
++ For 68HC12 we must also accept a constant because Z register is
++ disabled when compiling with -fomit-frame-pointer. We can come up
++ with a reload problem and the *lshrsi3_const pattern was disabled
++ for that reason. */
+ if (!Y_REG_P (operands[2]))
+ {
+ rtx ops[1];
+@@ -5544,8 +5568,8 @@
+ }")
+
+ (define_insn "lshrhi3_const"
+- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,!*A,!*A")
+- (lshiftrt:HI (match_operand:HI 1 "general_operand" "dm*A,!u,dm,!u")
++ [(set (match_operand:HI 0 "nonimmediate_noinc_operand" "=d,d,!*A,!*A")
++ (lshiftrt:HI (match_operand:HI 1 "nonimmediate_noinc_operand" "dm*A,!u,dm,!u")
+ (match_operand:HI 2 "const_int_operand" "i,i,i,i")))]
+ ""
+ "*
+@@ -5649,8 +5673,8 @@
+ "")
+
+ (define_insn "*lshrqi3_const1"
+- [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d,!u,!*q,!*A")
+- (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,0,0,0")
++ [(set (match_operand:QI 0 "nonimmediate_noinc_operand" "=m,d,!u,!*q,!*A")
++ (lshiftrt:QI (match_operand:QI 1 "nonimmediate_noinc_operand" "0,0,0,0,0")
+ (const_int 1)))]
+ ""
+ "@
+@@ -5937,6 +5961,98 @@
+ "")
+
+ ;;--------------------------------------------------------------------
++;;- Bit test and branch
++;;--------------------------------------------------------------------
++;; Logical and, test if zero and branch to use "brset/brclr" instruction
++;;
++(define_insn "brclr"
++ [(set (pc)
++ (if_then_else
++ (eq (and:QI (match_operand:QI 0 "memory_operand" "R,Q")
++ (match_operand:QI 1 "const_int_operand" ""))
++ (const_int 0))
++ (label_ref (match_operand 2 "" ""))
++ (pc)))
++ (clobber (match_scratch:HI 3 "=X,xy"))]
++ "0"
++ "*
++{
++ cc_status = cc_prev_status;
++ if (which_alternative == 0 || TARGET_M6812)
++ {
++ return \"brclr\\t%0,%1,%l2\";
++ }
++ else
++ {
++ rtx ops[3];
++
++ ops[0] = operands[3];
++ ops[1] = XEXP (operands[0], 0);
++ ops[2] = gen_label_rtx ();
++ output_asm_insn (\".relax\\t%l2\", ops);
++ m68hc11_gen_movhi (insn, ops);
++ output_asm_insn (\"brclr\\t0,%3,%1,%l2\", operands);
++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
++ CODE_LABEL_NUMBER (ops[2]));
++ return \"\";
++ }
++}")
++
++(define_insn "brset"
++ [(set (pc)
++ (if_then_else
++ (eq (and:QI (not:QI (match_operand:QI 0 "memory_operand" "R,Q"))
++ (match_operand:QI 1 "const_int_operand" ""))
++ (const_int 0))
++ (label_ref (match_operand 2 "" ""))
++ (pc)))
++ (clobber (match_scratch:HI 3 "=X,xy"))]
++ "0"
++ "*
++{
++ cc_status = cc_prev_status;
++ if (which_alternative == 0 || TARGET_M6812)
++ {
++ return \"brset\\t%0,%1,%l2\";
++ }
++ else
++ {
++ rtx ops[3];
++
++ ops[0] = operands[3];
++ ops[1] = XEXP (operands[0], 0);
++ ops[2] = gen_label_rtx ();
++ output_asm_insn (\".relax\\t%l2\", ops);
++ m68hc11_gen_movhi (insn, ops);
++ output_asm_insn (\"brset\\t0,%3,%1,%l2\", operands);
++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
++ CODE_LABEL_NUMBER (ops[2]));
++ return \"\";
++ }
++}")
++
++(define_peephole2
++ [(set (match_operand:QI 0 "hard_reg_operand" "")
++ (match_operand:QI 1 "memory_operand" "m"))
++ (set (cc0) (and:HI (match_operand:HI 2 "hard_reg_operand" "")
++ (match_operand:HI 3 "const_int_operand" "")))
++ (set (pc)
++ (if_then_else (eq (cc0) (const_int 0))
++ (label_ref (match_operand 4 "" ""))
++ (pc)))]
++ "0 && REGNO (operands[0]) == REGNO (operands[2])
++ && peep2_reg_dead_p (2, operands[0])"
++ [(parallel [
++ (set (pc)
++ (if_then_else
++ (eq (and:QI (match_dup 1) (match_dup 3))
++ (const_int 0))
++ (label_ref (match_dup 4))
++ (pc)))
++ (clobber (match_dup 5))])]
++ "operands[5] = gen_rtx_SCRATCH (HImode);")
++
++;;--------------------------------------------------------------------
+ ;;- 68HC12 Decrement/Increment and branch
+ ;;--------------------------------------------------------------------
+ ;; These patterns are used by loop optimization as well as peephole2
+@@ -5976,17 +6092,24 @@
+ {
+ FAIL;
+ }
++
++ /* Note that for xxx_dbcc_dec_yy the gen_rtx_NE is only used to pass
++ the operator and its operands are not relevant. */
+ if (GET_MODE (operands[0]) == HImode)
+ {
+ emit_jump_insn (gen_m68hc12_dbcc_dec_hi (operands[0],
+- gen_rtx (NE, HImode),
++ gen_rtx (NE, HImode,
++ operands[0],
++ operands[1]),
+ operands[4]));
+ DONE;
+ }
+ if (GET_MODE (operands[0]) == QImode)
+ {
+ emit_jump_insn (gen_m68hc12_dbcc_dec_qi (operands[0],
+- gen_rtx (NE, QImode),
++ gen_rtx (NE, QImode,
++ operands[0],
++ operands[1]),
+ operands[4]));
+ DONE;
+ }
+@@ -6928,18 +7051,81 @@
+ ;;
+ ;; Replace "leas 2,sp" with a "pulx" or a "puly".
+ ;; On 68HC12, this is one cycle slower but one byte smaller.
+-;; pr target/6899: This peephole is not valid because a register CSE
+-;; pass removes the pulx/puly.
++;; pr target/6899: This peephole was not valid because a register CSE
++;; pass removes the pulx/puly. The 'use' clause ensure that the pulx is
++;; not removed.
+ ;;
+ (define_peephole2
+ [(set (reg:HI SP_REGNUM) (plus:HI (reg:HI SP_REGNUM) (const_int 2)))
+ (match_scratch:HI 0 "xy")]
+- "0 && TARGET_M6812 && optimize_size"
+- [(set (match_dup 0) (match_dup 1))]
++ "TARGET_M6812 && optimize_size"
++ [(set (match_dup 0) (match_dup 1))
++ (use (match_dup 0))]
+ "operands[1] = gen_rtx (MEM, HImode,
+ gen_rtx (POST_INC, HImode,
+ gen_rtx_REG (HImode, HARD_SP_REGNUM)));")
+
++;; Replace: "pshx; tfr d,x; stx 0,sp" into "pshd; tfr d,x"
++;;
++;; PR 14542: emit a use to pretend we need the value of initial register.
++;; Otherwise verify_local_live_at_start will abort due to a live change
++;; of that register.
++;;
++(define_peephole2
++ [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM)))
++ (match_operand:HI 0 "hard_reg_operand" ""))
++ (set (match_dup 0)
++ (match_operand:HI 1 "hard_reg_operand" ""))
++ (set (mem:HI (reg:HI SP_REGNUM))
++ (match_dup 0))]
++ "TARGET_M6812"
++ [(use (match_dup 0))
++ (set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM)))
++ (match_dup 1))
++ (set (match_dup 0) (match_dup 1))]
++ "")
++
++;;
++;; Change: "ldd 0,sp; pulx" into "puld"
++;; This sequence usually appears at end a functions.
++(define_peephole2
++ [(set (match_operand:HI 0 "hard_reg_operand" "")
++ (mem:HI (reg:HI SP_REGNUM)))
++ (use (match_dup 0))
++ (set (match_operand:HI 1 "hard_reg_operand" "")
++ (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))]
++ "peep2_reg_dead_p (2, operands[1])"
++ [(set (match_dup 0) (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))
++ (use (match_dup 0))]
++ "")
++
++;; Replace: "pshx; clr 0,sp; clr 1,sp" by "clr 1,-sp; clr 1,-sp"
++;; Appears to allocate local variables.
++(define_peephole2
++ [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM)))
++ (match_operand:HI 0 "hard_reg_operand" ""))
++ (set (mem:QI (plus:HI (reg:HI SP_REGNUM) (const_int 1)))
++ (const_int 0))
++ (set (mem:QI (reg:HI SP_REGNUM))
++ (const_int 0))]
++ "TARGET_M6812"
++ [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM)))
++ (const_int 0))]
++ "")
++
++;; Likewise for HI mode
++(define_peephole2
++ [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM)))
++ (match_operand:HI 0 "hard_reg_operand" ""))
++ (set (mem:HI (reg:HI SP_REGNUM))
++ (const_int 0))]
++ "TARGET_M6812"
++ [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM)))
++ (const_int 0))]
++ "")
++;;--------------------------------------------------------------------
++;;-
++;;--------------------------------------------------------------------
+ ;;
+ ;; Optimize memory<->memory moves when the value is also loaded in
+ ;; a register.
+@@ -6989,6 +7175,32 @@
+ (set (match_dup 0) (match_dup 2))]
+ "")
+
++;;--------------------------------------------------------------------
++;;-
++;;--------------------------------------------------------------------
++;; SCz 2005-05-08: this peephole2 is not finished. I'm not sure it is
++;; valid in all cases. Disabled but kept for documentation and futur fix.
++;; (optimize 8-bit move to/from the X or Y registers; the issue with
++;; the first (set) is that since operand 0 is either X or Y, we have to
++;; use the scratch _.tmp memory location; the peephole uses a stack location
++;; instead to save D and use D for the load)
++;;
++(define_peephole2
++ [(set (match_operand:QI 0 "hard_reg_operand" "")
++ (match_operand:QI 1 "memory_operand" ""))
++ (set (match_operand:QI 2 "memory_operand" "")
++ (match_dup 0))]
++ "0 && A_REG_P (operands[0]) && peep2_reg_dead_p (2, operands[0])
++ && !reg_mentioned_p (gen_rtx (REG, HImode, HARD_D_REGNUM), operands[1])
++ && !reg_mentioned_p (gen_rtx (REG, HImode, HARD_D_REGNUM), operands[1])
++ && !reg_mentioned_p (gen_rtx (REG, HImode, REGNO (operands[0])), operands[2])"
++ [(set (mem:QI (pre_dec:HI (reg:HI SP_REGNUM))) (reg:QI D_REGNUM))
++ (set (reg:QI D_REGNUM) (match_dup 1))
++ (set (match_dup 2) (reg:QI D_REGNUM))
++ (set (reg:QI D_REGNUM) (mem:QI (post_inc:HI (reg:HI SP_REGNUM))))
++ (use (reg:HI SP_REGNUM))]
++ "")
++
+ ;;
+ ;; Reorganize to optimize address computations.
+ ;;
+@@ -7004,6 +7216,36 @@
+ "")
+
+ ;;
++;; Replace: "ldx #N; xgdx; addd <var>; xgdx" by "ldab #N; ldx <var>; abx"
++;;
++(define_peephole2
++ [(set (match_operand:HI 0 "hard_reg_operand" "")
++ (match_operand:HI 1 "const_int_operand" ""))
++ (set (match_dup 0)
++ (plus:HI (match_dup 0)
++ (match_operand:HI 2 "general_operand" "")))
++ (match_scratch:QI 3 "d")]
++ "TARGET_M6811 && (INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 0x0ff)"
++ [(set (match_dup 3) (match_dup 4))
++ (set (match_dup 0) (match_dup 2))
++ (set (match_dup 0) (plus:HI (zero_extend:HI (match_dup 3)) (match_dup 0)))]
++ "operands[4] = m68hc11_gen_lowpart (QImode, operands[1]);")
++
++;;
++;; Replace: "ldx #N; xgdx; addd <var>; xgdx" by "ldab #N; ldx <var>; abx"
++;;
++(define_peephole2
++ [(set (match_operand:HI 0 "hard_reg_operand" "")
++ (match_operand:HI 1 "const_int_operand" ""))
++ (set (match_dup 0)
++ (plus:HI (match_dup 0)
++ (match_operand:HI 2 "general_operand" "")))]
++ "TARGET_M6812"
++ [(set (match_dup 0) (match_dup 2))
++ (set (match_dup 0) (plus:HI (match_dup 0) (match_dup 1)))]
++ "")
++
++;;
+ ;; Optimize an address register increment and a compare to use
+ ;; a PRE_INC or PRE_DEC addressing mode (disabled on the tst insn
+ ;; before reload, but can be enabled after).
+@@ -7095,6 +7337,31 @@
+ "")
+
+ ;;
++;;
++;;
++(define_peephole2
++ [(parallel
++ [(set (match_operand:SI 0 "hard_reg_operand" "")
++ (ashift:SI (match_operand:SI 1 "general_operand" "")
++ (const_int 1)))
++ (clobber (match_scratch:HI 2 ""))])
++ (set (match_operand:HI 3 "nonimmediate_operand" "") (reg:HI D_REGNUM))
++ (set (match_operand:HI 4 "nonimmediate_operand" "") (reg:HI X_REGNUM))]
++ "!X_REG_P (operands[1])
++ && peep2_reg_dead_p (2, gen_rtx (REG, HImode, D_REGNUM))
++ && peep2_reg_dead_p (3, gen_rtx (REG, HImode, X_REGNUM))"
++ [(set (reg:HI D_REGNUM) (match_dup 5))
++ (set (reg:HI D_REGNUM) (ashift:HI (reg:HI D_REGNUM) (const_int 1)))
++ (set (match_dup 3) (reg:HI D_REGNUM))
++ (set (reg:HI D_REGNUM) (match_dup 6))
++ (parallel [(set (reg:HI D_REGNUM)
++ (rotate:HI (reg:HI D_REGNUM) (const_int 1)))
++ (clobber (reg:HI CC_REGNUM))])
++ (set (match_dup 4) (reg:HI D_REGNUM))]
++ "operands[5] = m68hc11_gen_lowpart (HImode, operands[1]);
++ operands[6] = m68hc11_gen_highpart (HImode, operands[1]);")
++
++;;
+ ;; Replace a "ldd <mem>; psha; pshb" with a "ldx <mem>; pshx".
+ ;;
+ (define_peephole2
+@@ -7109,6 +7376,25 @@
+ "")
+
+ ;;
++;; Remove one load when copying a value to/from memory and also
++;; to a register. Take care not cloberring a possible register used
++;; by operand 2.
++;; Replace: "ldd 0,y; std 2,y; ldx 0,y" into "ldx 0,y; stx 2,y"
++;;
++(define_peephole2
++ [(set (match_operand:HI 0 "hard_reg_operand" "")
++ (match_operand:HI 1 "general_operand" ""))
++ (set (match_operand:HI 2 "nonimmediate_operand" "") (match_dup 0))
++ (set (match_operand:HI 3 "hard_reg_operand" "") (match_dup 1))]
++ "peep2_reg_dead_p (2, operands[0])
++ && !side_effects_p (operands[1])
++ && !side_effects_p (operands[2])
++ && !reg_mentioned_p (operands[3], operands[2])"
++ [(set (match_dup 3) (match_dup 1))
++ (set (match_dup 2) (match_dup 3))]
++ "")
++
++;;
+ ;; Replace a "ldd <mem>; addd #N; std <mem>" into a
+ ;; "ldx <mem>; leax; stx <mem>" if we have a free X/Y register
+ ;; and the constant is small.
+@@ -7131,6 +7417,174 @@
+ "if (reg_mentioned_p (operands[4], operands[1])) FAIL;
+ if (reg_mentioned_p (operands[4], operands[3])) FAIL;")
+
++;;--------------------------------------------------------------------
++;;- Bset peephole2
++;;--------------------------------------------------------------------
++;; These peepholes try to replace some logical sequences by 'bset' and 'bclr'.
++;;
++;; Replace 'ldab <mem>; orab #N; stab <mem>' by 'bset <mem> #N'.
++;; Register D must be dead and there must be no register side effects for mem.
++;; The <mem> *can* be volatile this is why we must not use 'side_effects_p'.
++;; The good side effect is that it makes the sequence atomic.
++;;
++(define_peephole2
++ [(set (match_operand:QI 0 "hard_reg_operand" "")
++ (match_operand:QI 1 "nonimmediate_operand" ""))
++ (set (match_dup 0) (ior:QI (match_dup 0)
++ (match_operand:QI 2 "const_int_operand" "")))
++ (set (match_dup 1) (match_dup 0))]
++ "(TARGET_M6812 || m68hc11_indirect_p (operands[1], QImode))
++ && (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0)))
++ && peep2_reg_dead_p (3, operands[0])"
++ [(set (match_dup 1) (ior:QI (match_dup 1) (match_dup 2)))]
++ "")
++
++(define_peephole2
++ [(set (match_operand:HI 0 "hard_reg_operand" "")
++ (match_operand:HI 1 "nonimmediate_operand" ""))
++ (set (match_dup 0) (ior:HI (match_dup 0)
++ (match_operand:HI 2 "const_int_operand" "")))
++ (set (match_dup 1) (match_dup 0))]
++ "(TARGET_M6812 || m68hc11_indirect_p (operands[1], HImode))
++ && (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0)))
++ && peep2_reg_dead_p (3, operands[0])"
++ [(set (match_dup 1) (ior:HI (match_dup 1) (match_dup 2)))]
++ "")
++
++;;--------------------------------------------------------------------
++;;- Bclr peephole2
++;;--------------------------------------------------------------------
++;; Replace 'ldab <mem>; andab #N; stab <mem>' by 'bclr <mem> #N'.
++;; See Bset peephole2.
++;;
++(define_peephole2
++ [(set (match_operand:QI 0 "hard_reg_operand" "")
++ (match_operand:QI 1 "nonimmediate_operand" ""))
++ (set (match_dup 0) (and:QI (match_dup 0)
++ (match_operand:QI 2 "const_int_operand" "")))
++ (set (match_dup 1) (match_dup 0))]
++ "(TARGET_M6812 || m68hc11_indirect_p (operands[1], QImode))
++ && (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0)))
++ && peep2_reg_dead_p (3, operands[0])"
++ [(set (match_dup 1) (and:QI (match_dup 1) (match_dup 2)))]
++ "")
++
++(define_peephole2
++ [(set (match_operand:HI 0 "hard_reg_operand" "")
++ (match_operand:HI 1 "nonimmediate_operand" ""))
++ (set (match_dup 0) (and:HI (match_dup 0)
++ (match_operand:HI 2 "const_int_operand" "")))
++ (set (match_dup 1) (match_dup 0))]
++ "(TARGET_M6812 || m68hc11_indirect_p (operands[1], HImode))
++ && (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0)))
++ && peep2_reg_dead_p (3, operands[0])"
++ [(set (match_dup 1) (and:HI (match_dup 1) (match_dup 2)))]
++ "")
++
++
++;;--------------------------------------------------------------------
++;;- Compare peephole2
++;;--------------------------------------------------------------------
++(define_peephole2
++ [(set (match_operand:HI 0 "hard_reg_operand" "")
++ (match_operand:HI 1 "hard_reg_operand" ""))
++ (set (match_dup 1) (plus:HI (match_dup 1)
++ (match_operand:HI 2 "const_int_operand" "")))
++ (set (cc0) (match_dup 0))]
++ "peep2_reg_dead_p (3, operands[0]) && !Z_REG_P (operands[1])"
++ [(set (match_dup 1) (plus:HI (match_dup 1) (match_dup 2)))
++ (set (cc0) (compare (match_dup 1) (match_dup 2)))]
++ "")
++
++(define_peephole2
++ [(set (match_operand:HI 0 "hard_reg_operand" "")
++ (match_operand:HI 1 "hard_reg_operand" ""))
++ (set (match_operand:HI 2 "hard_reg_operand" "")
++ (plus:HI (match_dup 2)
++ (match_operand:HI 3 "const_int_operand" "")))
++ (set (match_operand:HI 4 "memory_operand" "") (match_dup 2))
++ (set (cc0) (match_operand:HI 5 "hard_reg_operand" ""))]
++ "peep2_reg_dead_p (4, operands[5]) && !Z_REG_P (operands[2])
++ && !reg_mentioned_p (operands[2], operands[4])
++
++ && ((rtx_equal_p (operands[5], operands[0])
++ && rtx_equal_p (operands[2], operands[1]))
++
++ || (rtx_equal_p (operands[5], operands[1])
++ && rtx_equal_p (operands[2], operands[0])))"
++ [(set (match_dup 2) (match_dup 1))
++ (set (match_dup 2) (plus:HI (match_dup 2) (match_dup 3)))
++ (set (match_dup 4) (match_dup 2))
++ (set (cc0) (compare (match_dup 2) (match_dup 3)))]
++ "")
++
++
++;;--------------------------------------------------------------------
++;;- Load peephole2
++;;--------------------------------------------------------------------
++;;
++;; Optimize initialization of 2 hard regs from the same memory location
++;; Since we can't copy easily X, Y and D to each other, load the 2 registers
++;; from the same memory location.
++;;
++(define_peephole2
++ [(set (match_operand:HI 0 "hard_reg_operand" "")
++ (match_operand:HI 1 "memory_operand" ""))
++ (set (match_operand:HI 2 "hard_reg_operand" "") (match_dup 0))]
++ "TARGET_M6811
++ && !side_effects_p (operands[1])
++ && !reg_mentioned_p (operands[0], operands[1])"
++ [(set (match_dup 0) (match_dup 1))
++ (set (match_dup 2) (match_dup 1))]
++ "")
++
++;; Replace "ldd #N; addd <op>" with "ldd <op>; addd #N".
++;;
++(define_peephole2
++ [(set (match_operand:HI 0 "nonimmediate_operand" "") (const_int 0))
++ (set (match_operand:HI 1 "nonimmediate_operand" "") (const_int 0))
++ (set (match_operand:HI 2 "nonimmediate_operand" "") (const_int 0))
++ (set (match_operand:HI 3 "nonimmediate_operand" "") (const_int 0))
++ (match_scratch:HI 4 "d")]
++ ""
++ [(set (match_dup 4) (const_int 0))
++ (set (match_dup 0) (match_dup 4))
++ (set (match_dup 1) (match_dup 4))
++ (set (match_dup 2) (match_dup 4))
++ (set (match_dup 3) (match_dup 4))]
++ "")
++
++;;
++;; Replace "ldd #N; addd <op>" with "ldd <op>; addd #N".
++;;
++(define_peephole2
++ [(set (match_operand:HI 0 "nonimmediate_operand" "") (const_int 0))
++ (set (match_operand:HI 1 "nonimmediate_operand" "") (const_int 0))
++ (set (match_operand:HI 2 "nonimmediate_operand" "") (const_int 0))
++ (match_scratch:HI 3 "d")]
++ ""
++ [(set (match_dup 3) (const_int 0))
++ (set (match_dup 0) (match_dup 3))
++ (set (match_dup 1) (match_dup 3))
++ (set (match_dup 2) (match_dup 3))]
++ "")
++
++;;
++;; Replace "ldd #N; addd <op>" with "ldd <op>; addd #N".
++;;
++(define_peephole2
++ [(set (match_operand:HI 0 "hard_reg_operand" "") (const_int 0))
++ (set (match_operand:HI 1 "push_operand" "") (match_dup 0))
++ (set (match_operand:HI 2 "push_operand" "") (match_dup 0))
++ (set (match_operand:HI 3 "push_operand" "") (match_dup 0))
++ (match_scratch:HI 4 "x")]
++ "TARGET_M6811 && D_REG_P (operands[0]) && peep2_reg_dead_p (4, operands[0])"
++ [(set (match_dup 4) (const_int 0))
++ (set (match_dup 1) (match_dup 4))
++ (set (match_dup 2) (match_dup 4))
++ (set (match_dup 3) (match_dup 4))]
++ "")
++
+ ;;
+ ;; This peephole catches the address computations generated by the reload
+ ;; pass.
+@@ -7189,6 +7643,8 @@
+ }
+ ")
+
++;; SCz 2005-04-03: this peephole is not valid anymore because it appears
++;; we can't rely on the REG_DEAD note
+ (define_peephole
+ [(set (match_operand:HI 0 "hard_reg_operand" "h")
+ (match_operand:HI 1 "non_push_operand" "g"))
+@@ -7279,7 +7735,7 @@
+
+ ;;;
+ ;;; Catch an xgdx/xgdy followed by a (set D X/Y). If X/Y is dead, we don't
+-;;; need to emit anything. Otherwise, we just need an copy of D to X/Y.
++;;; need to emit anything. Otherwise, we just need a copy of D to X/Y.
+ ;;;
+ (define_peephole
+ [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A"))
+@@ -7295,7 +7751,7 @@
+
+ ;;;
+ ;;; Catch an xgdx/xgdy followed by a (set D X/Y). If X/Y is dead, we don't
+-;;; need to emit anything. Otherwise, we just need an copy of D to X/Y.
++;;; need to emit anything. Otherwise, we just need a copy of D to X/Y.
+ ;;;
+ (define_peephole
+ [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A"))
+@@ -7400,3 +7856,41 @@
+ return \"sts\\t%t0\\n\\tld%0\\t%t0\";
+ }
+ ")
++
++(define_peephole
++ [(set (match_operand:HI 0 "hard_reg_operand" "")
++ (match_operand:HI 1 "memory_operand" ""))
++ (set (match_operand:HI 2 "hard_reg_operand" "") (match_dup 0))]
++ "TARGET_M6811
++ && !side_effects_p (operands[1])
++ && !reg_mentioned_p (operands[0], operands[1])"
++ "*
++{
++ rtx ops[2];
++
++ ops[0] = operands[0];
++ ops[1] = operands[1];
++ m68hc11_gen_movhi (insn, ops);
++ ops[0] = operands[2];
++ m68hc11_gen_movhi (insn, ops);
++ return \"\";
++}")
++
++;; Peephole for Z register replacement.
++;; Avoid to use _.tmp register when comparing D and X if we can compare
++;; with soft register
++(define_peephole
++ [(set (match_operand:HI 0 "hard_reg_operand" "") (reg:HI SOFT_XY_REGNUM))
++ (set (reg:HI SOFT_TMP_REGNUM) (match_dup 0))
++ (set (cc0) (compare (match_operand:HI 2 "hard_reg_operand" "")
++ (reg:HI SOFT_TMP_REGNUM)))]
++ "X_REG_P (operands[0]) || Y_REG_P (operands[0])"
++ "*
++{
++ rtx ops[2];
++
++ ops[0] = operands[0];
++ ops[1] = operands[1];
++ m68hc11_gen_movhi (insn, ops);
++ return \"cp%2\\t%1\";
++}")
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11-protos.h gcc-3.3.6/gcc/config/m68hc11/m68hc11-protos.h
+--- gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11-protos.h 2003-04-12 22:53:41.000000000 +0100
++++ gcc-3.3.6/gcc/config/m68hc11/m68hc11-protos.h 2010-11-09 20:47:16.000000000 +0000
+@@ -1,5 +1,6 @@
+ /* Prototypes for exported functions defined in m68hc11.c
+- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
++ Copyright (C) 1999, 2000, 2001, 2002, 2003,
++ 2005, 2006 Free Software Foundation, Inc.
+ Contributed by Stephane Carrez (stcarrez@nerim.fr)
+
+ This file is part of GNU CC.
+@@ -24,7 +25,7 @@
+ extern int m68hc11_optimization_options PARAMS((int,int));
+ extern void m68hc11_conditional_register_usage PARAMS((void));
+ extern int hard_regno_mode_ok PARAMS((int, enum machine_mode));
+-extern int m68hc11_hard_regno_rename_ok PARAMS((int, int));
++extern int m68hc11_hard_regno_rename_ok PARAMS((int, int, int));
+
+ extern int m68hc11_total_frame_size PARAMS((void));
+ extern int m68hc11_initial_frame_pointer_offset PARAMS((void));
+@@ -105,6 +106,7 @@
+ extern int reg_or_indexed_operand PARAMS((rtx,enum machine_mode));
+ extern int tst_operand PARAMS((rtx,enum machine_mode));
+ extern int cmp_operand PARAMS((rtx,enum machine_mode));
++extern int nonimmediate_noinc_operand PARAMS((rtx,enum machine_mode));
+ extern int memory_indexed_operand PARAMS((rtx, enum machine_mode));
+
+ extern void m68hc11_split_logical PARAMS((enum machine_mode, int, rtx*));
+@@ -147,6 +149,7 @@
+
+ extern int m68hc11_is_far_symbol PARAMS((rtx));
+ extern int m68hc11_is_trap_symbol PARAMS((rtx));
++extern int m68hc11_page0_symbol_p (rtx x);
+
+ #endif /* TREE_CODE */
+
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc12.h gcc-3.3.6/gcc/config/m68hc11/m68hc12.h
+--- gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc12.h 2003-01-15 23:00:12.000000000 +0000
++++ gcc-3.3.6/gcc/config/m68hc11/m68hc12.h 2010-11-09 20:47:16.000000000 +0000
+@@ -19,11 +19,13 @@
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+-/* Compile and assemble for a 68hc12 unless there is a -m68hc11 option. */
++/* Default to compile and assemble for a 68hc12 */
+ #define ASM_SPEC \
+ "%{m68hc11:-m68hc11}" \
++"%{m6812:-m68hc12}" \
+ "%{m68hcs12:-m68hcs12}" \
+-"%{!m68hc11:%{!m68hcs12:-m68hc12}}"
++"%{m9s12x:-mm9s12x}" \
++"%{!m68hc11:%{!m68hcs12:%{!m9s12x:-m68hc12}}}"
+ #define LIB_SPEC ""
+ #define CC1_SPEC ""
+
+@@ -31,19 +33,23 @@
+ emulation option. This can be overriden by -Wl option of gcc. */
+ #define LINK_SPEC \
+ "%{m68hc11:-m m68hc11elf}" \
++"%{m9s12x:-m m9s12xelf}" \
+ "%{m68hcs12:-m m68hc12elf}" \
+-"%{!m68hc11:%{!m68hcs12:-m m68hc11elf}} %{mrelax:-relax}"
++"%{!m68hc11:%{!m68hcs12:%{!m9s12x:-m m68hc11elf}} %{mrelax:-relax}"
+
+ #define CPP_SPEC \
+ "%{mshort:-D__HAVE_SHORT_INT__ -D__INT__=16}\
+ %{!mshort:-D__INT__=32}\
+ %{m68hc11:-Dmc6811 -DMC6811 -Dmc68hc11}\
+- %{!m68hc11:%{!m68hc12:-Dmc6812 -DMC6812 -Dmc68hc12}}\
++ %{m68hc12:-Dmc6812 -DMC6812 -Dmc68hc12}\
++ %{m9s12x:-Dmc6812 -DMC6812 -Dmc68hcs12 -Dm9s12x}\
+ %{m68hcs12:-Dmc6812 -DMC6812 -Dmc68hcs12}\
+- %{!m68hc11:-Dmc6812 -DMC6812 -Dmc68hc12}\
++ %{!m68hc11:%{!m68hc12:%{!m9s12x:-Dmc6812 -DMC6812 -Dmc68hc12 -m68hc12}}}\
+ %{fshort-double:-D__HAVE_SHORT_DOUBLE__}"
+
+ /* Default target_flags if no switches specified. */
+ #define TARGET_DEFAULT (MASK_M6812)
+
+ #define TARGET_M68HC12
++
++#define CPP_PREDEFINES "-Dmc68hc1x -Dtarget12"
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/m9s12x.h gcc-3.3.6/gcc/config/m68hc11/m9s12x.h
+--- gcc-3.3.6-core-orig/gcc/config/m68hc11/m9s12x.h 1970-01-01 01:00:00.000000000 +0100
++++ gcc-3.3.6/gcc/config/m68hc11/m9s12x.h 2010-11-09 20:47:16.000000000 +0000
+@@ -0,0 +1,59 @@
++/* Definitions of target machine for GNU compiler, for m68hc12.
++ Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
++ Contributed by Stephane Carrez (stcarrez@nerim.fr).
++
++This file is part of GNU CC.
++
++GNU CC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 2, or (at your option)
++any later version.
++
++GNU CC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GNU CC; see the file COPYING. If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA. */
++
++/* Default to compile and assemble for a m9s12x */
++#define ASM_SPEC \
++"%{m68hc11:-m68hc11}" \
++"%{m6812:-m68hc12}" \
++"%{m9s12x:-mm9s12x}" \
++"%{m68hcs12:-m68hcs12}" \
++"%{!m68hc11:%{!m68hcs12:%{!m68hc12: -mm9s12x}}}"
++/* last line was "%{!m68hc11:%{!m68hcs12:%{!m68hc12:%{!m9s12x:-mm9s12x}}}}" */
++#define LIB_SPEC ""
++#define CC1_SPEC ""
++
++/* We need to tell the linker the target elf format. Just pass an
++ emulation option. This can be overriden by -Wl option of gcc. */
++#define LINK_SPEC \
++"%{m68hc11:-m m68hc11elf}" \
++"%{m9s12x:-m m68hc12elf}" \
++"%{m68hcs12:-m m68hc12elf}" \
++"%{!m68hc11:%{!m68hcs12:%{!m9s12x:-m m68hc11elf}}} %{mrelax:-relax}"
++
++#define CPP_SPEC \
++"%{mshort:-D__HAVE_SHORT_INT__ -D__INT__=16}\
++ %{!mshort:-D__INT__=32}\
++ %{m68hc11:-Dmc6811 -DMC6811 -Dmc68hc11}\
++ %{m68hc12:-Dmc6812 -DMC6812 -Dmc68hc12}\
++ %{m9s12x:-Dmc6812 -DMC6812 -Dmc68hc12 -Dmc68hcs12 -Dm9s12x -m9s12x}\
++ %{m68hcs12:-Dmc6812 -DMC6812 -Dmc68hc12 -Dmc68hcs12}\
++ %{!m68hc11:%{!m68hc12:%{!m68hcs12: -Dmc6812 -DMC6812 -Dmc68hc12 -Dmc68hcs12 -Dm9s12x -m9s12x}}}\
++ %{fshort-double:-D__HAVE_SHORT_DOUBLE__}"
++/* penultimate was %{!m68hc11:%{!m68hc12:%{!m68hcs12:%{!m9s12x:-Dmc6812 -DMC6812 -Dmc68hc12 -Dmc68hcs12 -Dm9s12x -m9s12x}}}} */
++
++/* Default target_flags if no switches specified. */
++#define TARGET_DEFAULT (MASK_M68S12X)
++
++#define TARGET_M68HC12
++
++#define MULTILIB_DEFAULTS { "m9s12x" }
++
++#define CPP_PREDEFINES "-Dmc68hc1x -Dtargets12x"
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/t-m68hc11-gas gcc-3.3.6/gcc/config/m68hc11/t-m68hc11-gas
+--- gcc-3.3.6-core-orig/gcc/config/m68hc11/t-m68hc11-gas 2005-01-28 22:21:39.000000000 +0000
++++ gcc-3.3.6/gcc/config/m68hc11/t-m68hc11-gas 2010-11-09 20:47:16.000000000 +0000
+@@ -31,13 +31,14 @@
+
+ # C implementation of 32-bit div/mod.
+ LIB2FUNCS_EXTRA = $(srcdir)/config/udivmodsi4.c \
+- $(srcdir)/config/divmod.c $(srcdir)/config/udivmod.c
++ $(srcdir)/config/divmod.c $(srcdir)/config/udivmod.c \
++ $(srcdir)/config/m68hc11/ldivmod.asm
+
+ # Don't compile with -g1 this reduces the size of some sections (.eh_frame).
+ LIBGCC2_DEBUG_CFLAGS =-g
+-LIBGCC2_CFLAGS = -Os -mrelax $(LIBGCC2_INCLUDES) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) -DIN_LIBGCC2
+-
+-MULTILIB_OPTIONS = m68hc11/m68hc12 mshort fshort-double
++LIBGCC2_CFLAGS = -O -mrelax $(LIBGCC2_INCLUDES) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) -DIN_LIBGCC2
++# -m9s12x
++MULTILIB_OPTIONS = m68hc11/m68hc12/m9s12x mshort fshort-double mlong-calls
+ MULTILIB_DIRNAMES =
+ MULTILIB_MATCHES = m68hc11=m6811 m68hc12=m6812 m68hc12=m68hcs12
+ MULTILIB_EXCEPTIONS = -mnoshort -mno68hc11
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config/udivmod.c gcc-3.3.6/gcc/config/udivmod.c
+--- gcc-3.3.6-core-orig/gcc/config/udivmod.c 2000-11-30 08:25:58.000000000 +0000
++++ gcc-3.3.6/gcc/config/udivmod.c 2010-11-09 20:47:16.000000000 +0000
+@@ -1,14 +1,36 @@
+-long udivmodsi4 ();
++/* cover the root directory case */
++#if !defined(mc68hc11) && !defined(mc68hc12) && !defined(m9s12x)
++#if defined(target11)
++#define mc68hc11
++#endif
++#if defined(target12)
++#define mc68hc12
++#endif
++#if defined(targets12x)
++#define m9s12x
++#define mc68hc12
++#endif
++#endif
+
+-long
+-__udivsi3 (long a, long b)
++#ifndef mc68hc12
++extern unsigned long __udivmodsi4 (unsigned long num, unsigned long den,
++ unsigned long *mod);
++
++unsigned long
++__inline __udivsi3 (unsigned long a, unsigned long b)
+ {
+- return udivmodsi4 (a, b, 0);
++ return __udivmodsi4 (a, b, 0);
+ }
+
+-long
+-__umodsi3 (long a, long b)
++unsigned long
++__inline __umodsi3 (unsigned long a, unsigned long b)
+ {
+- return udivmodsi4 (a, b, 1);
++ unsigned long mod;
++
++ __udivmodsi4 (a, b, &mod);
++ return mod;
+ }
+
++
++
++#endif /* !mc68hc12 */
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config/udivmodsi4.c gcc-3.3.6/gcc/config/udivmodsi4.c
+--- gcc-3.3.6-core-orig/gcc/config/udivmodsi4.c 2000-11-30 08:25:58.000000000 +0000
++++ gcc-3.3.6/gcc/config/udivmodsi4.c 2010-11-09 20:47:16.000000000 +0000
+@@ -1,10 +1,72 @@
++/* cover the root directory case */
++#if !defined(mc68hc11) && !defined(mc68hc12) && !defined(m9s12x)
++#if defined(target11)
++#define mc68hc11
++#endif
++#if defined(target12)
++#define mc68hc12
++#endif
++#if defined(targets12x)
++#define m9s12x
++#define mc68hc12
++#endif
++#endif
++
++//#ifndef mc68hc12
+ unsigned long
+-udivmodsi4(unsigned long num, unsigned long den, int modwanted)
++__udivmodsi4 (unsigned long num, unsigned long den, unsigned long* mod)
+ {
+- unsigned long bit = 1;
+- unsigned long res = 0;
++ unsigned long bit;
++ unsigned long res;
++
++ if ((unsigned short) (den >> 16) == 0)
++ {
++#ifdef mc68hc11
++ if ((unsigned short) (num >> 16) == 0)
++ {
++ /* Both numbers are 16-bit quantities, use 16-bit div/mod. */
++ unsigned short sden = (unsigned short) den;
++ unsigned short snum = (unsigned short) num;
++ unsigned short sres = snum / sden;
++ unsigned short smod = snum % sden;;
+
+- while (den < num && bit && !(den & (1L<<31)))
++ if (mod)
++ *mod = (unsigned long) smod;
++ return (unsigned long) sres;
++ }
++#endif
++#ifdef mc68hc12
++ {
++ /* To avoid to stress the gcc reload, use + operand modifier
++ and pass the input values in the same variables as the
++ outputs. */
++ unsigned short status = (unsigned short) den;
++ unsigned short smod = (unsigned short) (num & 0x0ffff);
++ unsigned short sres = (unsigned short) (num >> 16);
++
++ __asm__ __volatile__ ("ediv\n"
++ "tfr ccr,x"
++ : "+x" (status), "+y" (sres),
++ "+d" (smod));
++ /* check for overflow */
++ if (!(status & 0x03))
++ {
++ if (mod)
++ *mod = (unsigned long) smod;
++ return (unsigned long) sres;
++ }
++ }
++#endif
++ if ((unsigned short) den == 0)
++ {
++ if (mod)
++ *mod = 0;
++ return 0;
++ }
++ }
++ bit = 1;
++ res = 0;
++ while (den < num && !((unsigned short) (den >> 16) & (1L<<15)))
+ {
+ den <<=1;
+ bit <<=1;
+@@ -19,6 +81,28 @@
+ bit >>=1;
+ den >>=1;
+ }
+- if (modwanted) return num;
++ if (mod)
++ *mod = num;
+ return res;
+ }
++
++#ifdef L_udivmodsi4
++unsigned long
++udivmodsi4 (unsigned long num, unsigned long den, int modwanted)
++{
++ unsigned long mod;
++
++ if (modwanted)
++ {
++ __udivmodsi4 (num, den, &mod);
++ return mod;
++ }
++ else
++ {
++ return __udivmodsi4 (num, den, 0);
++ }
++}
++#endif
++
++//#endif /*!mc68hc12 */
++
+diff -u -r -N gcc-3.3.6-core-orig/gcc/config.gcc gcc-3.3.6/gcc/config.gcc
+--- gcc-3.3.6-core-orig/gcc/config.gcc 2004-04-29 05:42:47.000000000 +0100
++++ gcc-3.3.6/gcc/config.gcc 2010-11-09 20:47:16.000000000 +0000
+@@ -1516,6 +1516,13 @@
+ out_file="m68hc11/m68hc11.c"
+ tmake_file="m68hc11/t-m68hc11-gas"
+ ;;
++m9s12x-*-*)
++ tm_file="m68hc11/m9s12x.h dbxelf.h elfos.h m68hc11/m68hc11.h"
++ tm_p_file="m68hc11/m68hc11-protos.h"
++ md_file="m68hc11/m68hc11.md"
++ out_file="m68hc11/m68hc11.c"
++ tmake_file="m68hc11/t-m68hc11-gas"
++ ;;
+ m68000-hp-bsd*) # HP 9000/200 running BSD
+ tm_file=m68k/hp2bsd.h
+ use_collect2=yes
+diff -u -r -N gcc-3.3.6-core-orig/gcc/cppdefault.c gcc-3.3.6/gcc/cppdefault.c
+--- gcc-3.3.6-core-orig/gcc/cppdefault.c 2003-11-06 23:13:31.000000000 +0000
++++ gcc-3.3.6/gcc/cppdefault.c 2010-11-09 20:47:16.000000000 +0000
+@@ -76,11 +76,15 @@
+
+ #ifdef GCC_INCLUDE_DIR
+ const char cpp_GCC_INCLUDE_DIR[] = GCC_INCLUDE_DIR;
++#if GNU_HC1X_DONT_PATCH
+ const size_t cpp_GCC_INCLUDE_DIR_len = sizeof GCC_INCLUDE_DIR - 8;
++#endif
+ #else
+ const char cpp_GCC_INCLUDE_DIR[] = "";
++#if GNU_HC1X_DONT_PATCH
+ const size_t cpp_GCC_INCLUDE_DIR_len = 0;
+ #endif
++#endif
+
+ #ifdef TARGET_SYSTEM_ROOT
+ const char *cpp_SYSROOT = TARGET_SYSTEM_ROOT;
+diff -u -r -N gcc-3.3.6-core-orig/gcc/cppdefault.h gcc-3.3.6/gcc/cppdefault.h
+--- gcc-3.3.6-core-orig/gcc/cppdefault.h 2003-11-06 23:13:31.000000000 +0000
++++ gcc-3.3.6/gcc/cppdefault.h 2010-11-09 20:47:16.000000000 +0000
+@@ -67,7 +67,17 @@
+
+ extern const struct default_include cpp_include_defaults[];
+ extern const char cpp_GCC_INCLUDE_DIR[];
++
++/* Don't use sizeof GCC_INCLUDE_DIR because for Mingw32 we patch the
++ executable to replace this path with the good path. We must then
++ use strlen() to find the correct length. */
++#undef GNU_HC1X_DONT_PATCH
++#if GNU_HC1X_DONT_PATCH
+ extern const size_t cpp_GCC_INCLUDE_DIR_len;
++#else
++#define cpp_GCC_INCLUDE_DIR_len \
++(strlen (cpp_GCC_INCLUDE_DIR) > 7 ? strlen (cpp_GCC_INCLUDE_DIR) - 7 : 0)
++#endif
+
+ extern const char *cpp_SYSROOT;
+
+diff -u -r -N gcc-3.3.6-core-orig/gcc/doc/extend.texi gcc-3.3.6/gcc/doc/extend.texi
+--- gcc-3.3.6-core-orig/gcc/doc/extend.texi 2004-03-17 20:13:19.000000000 +0000
++++ gcc-3.3.6/gcc/doc/extend.texi 2010-11-09 20:47:16.000000000 +0000
+@@ -2528,11 +2528,14 @@
+
+ On 68HC11 the compiler will generate a sequence of instructions
+ to invoke a board-specific routine to switch the memory bank and call the
+-real function. The board-specific routine simulates a @code{call}.
++real function. The board-specific routine simulates a @code{call}.
+ At the end of a function, it will jump to a board-specific routine
+-instead of using @code{rts}. The board-specific return routine simulates
++instead of using @code{rts}. The board-specific return routine simulates
+ the @code{rtc}.
+
++The @code{far} attribute must not be used when the @code{interrupt} or
++@code{trap} attributes are used.
++
+ @item near
+ @cindex functions which do not handle memory bank switching on 68HC11/68HC12
+ On 68HC11 and 68HC12 the @code{near} attribute causes the compiler to
+@@ -2540,6 +2543,21 @@
+ This attribute can be used to cancel the effect of the @option{-mlong-calls}
+ option.
+
++@item page0
++@cindex variables in page0 section for which direct addressing mode can be used
++On 68HC11 and 68HC12, the @code{page0} attribute indicates that a global
++or static variable is put in the @code{page0} section and the compiler can
++use the direct addressing mode. On 68HC11 the compiler will be able to
++use @code{bset} and @code{bclr} on these variables. Note that the @code{page0}
++is limited to the absolute address range @code{0}..@code{0x0ff}.
++
++@item trap
++@cindex functions which are used as trap handlers (@code{swi} or @code{trap})
++On 68HC11 and 68HC12, the @code{trap} attribute marks the function as being
++a trap handler. It will use @code{rti} instead of @code{rts} to return
++from the function. Offset of function parameters are also adjusted to take
++into account the trap frame.
++
+ @item dllimport
+ @cindex @code{__declspec(dllimport)}
+ On Windows targets, the @code{dllimport} attribute causes the compiler
+diff -u -r -N gcc-3.3.6-core-orig/gcc/doc/gcc.1 gcc-3.3.6/gcc/doc/gcc.1
+--- gcc-3.3.6-core-orig/gcc/doc/gcc.1 2005-05-03 13:41:29.000000000 +0100
++++ gcc-3.3.6/gcc/doc/gcc.1 2010-11-09 20:47:16.000000000 +0000
+@@ -1,10282 +1 @@
+-.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14
+-.\"
+-.\" Standard preamble:
+-.\" ========================================================================
+-.de Sh \" Subsection heading
+-.br
+-.if t .Sp
+-.ne 5
+-.PP
+-\fB\\$1\fR
+-.PP
+-..
+-.de Sp \" Vertical space (when we can't use .PP)
+-.if t .sp .5v
+-.if n .sp
+-..
+-.de Vb \" Begin verbatim text
+-.ft CW
+-.nf
+-.ne \\$1
+-..
+-.de Ve \" End verbatim text
+-.ft R
+-.fi
+-..
+-.\" Set up some character translations and predefined strings. \*(-- will
+-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+-.\" double quote, and \*(R" will give a right double quote. | will give a
+-.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to
+-.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C'
+-.\" expand to `' in nroff, nothing in troff, for use with C<>.
+-.tr \(*W-|\(bv\*(Tr
+-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+-.ie n \{\
+-. ds -- \(*W-
+-. ds PI pi
+-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+-. ds L" ""
+-. ds R" ""
+-. ds C` ""
+-. ds C' ""
+-'br\}
+-.el\{\
+-. ds -- \|\(em\|
+-. ds PI \(*p
+-. ds L" ``
+-. ds R" ''
+-'br\}
+-.\"
+-.\" If the F register is turned on, we'll generate index entries on stderr for
+-.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+-.\" entries marked with X<> in POD. Of course, you'll have to process the
+-.\" output yourself in some meaningful fashion.
+-.if \nF \{\
+-. de IX
+-. tm Index:\\$1\t\\n%\t"\\$2"
+-..
+-. nr % 0
+-. rr F
+-.\}
+-.\"
+-.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+-.\" way too many mistakes in technical documents.
+-.hy 0
+-.if n .na
+-.\"
+-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+-.\" Fear. Run. Save yourself. No user-serviceable parts.
+-. \" fudge factors for nroff and troff
+-.if n \{\
+-. ds #H 0
+-. ds #V .8m
+-. ds #F .3m
+-. ds #[ \f1
+-. ds #] \fP
+-.\}
+-.if t \{\
+-. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+-. ds #V .6m
+-. ds #F 0
+-. ds #[ \&
+-. ds #] \&
+-.\}
+-. \" simple accents for nroff and troff
+-.if n \{\
+-. ds ' \&
+-. ds ` \&
+-. ds ^ \&
+-. ds , \&
+-. ds ~ ~
+-. ds /
+-.\}
+-.if t \{\
+-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+-.\}
+-. \" troff and (daisy-wheel) nroff accents
+-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+-.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+-.ds ae a\h'-(\w'a'u*4/10)'e
+-.ds Ae A\h'-(\w'A'u*4/10)'E
+-. \" corrections for vroff
+-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+-. \" for low resolution devices (crt and lpr)
+-.if \n(.H>23 .if \n(.V>19 \
+-\{\
+-. ds : e
+-. ds 8 ss
+-. ds o a
+-. ds d- d\h'-1'\(ga
+-. ds D- D\h'-1'\(hy
+-. ds th \o'bp'
+-. ds Th \o'LP'
+-. ds ae ae
+-. ds Ae AE
+-.\}
+-.rm #[ #] #H #V #F C
+-.\" ========================================================================
+-.\"
+-.IX Title "GCC 1"
+-.TH GCC 1 "2005-05-03" "gcc-3.3.6" "GNU"
+-.SH "NAME"
+-gcc \- GNU project C and C++ compiler
+-.SH "SYNOPSIS"
+-.IX Header "SYNOPSIS"
+-gcc [\fB\-c\fR|\fB\-S\fR|\fB\-E\fR] [\fB\-std=\fR\fIstandard\fR]
+- [\fB\-g\fR] [\fB\-pg\fR] [\fB\-O\fR\fIlevel\fR]
+- [\fB\-W\fR\fIwarn\fR...] [\fB\-pedantic\fR]
+- [\fB\-I\fR\fIdir\fR...] [\fB\-L\fR\fIdir\fR...]
+- [\fB\-D\fR\fImacro\fR[=\fIdefn\fR]...] [\fB\-U\fR\fImacro\fR]
+- [\fB\-f\fR\fIoption\fR...] [\fB\-m\fR\fImachine-option\fR...]
+- [\fB\-o\fR \fIoutfile\fR] \fIinfile\fR...
+-.PP
+-Only the most useful options are listed here; see below for the
+-remainder. \fBg++\fR accepts mostly the same options as \fBgcc\fR.
+-.SH "DESCRIPTION"
+-.IX Header "DESCRIPTION"
+-When you invoke \s-1GCC\s0, it normally does preprocessing, compilation,
+-assembly and linking. The ``overall options'' allow you to stop this
+-process at an intermediate stage. For example, the \fB\-c\fR option
+-says not to run the linker. Then the output consists of object files
+-output by the assembler.
+-.PP
+-Other options are passed on to one stage of processing. Some options
+-control the preprocessor and others the compiler itself. Yet other
+-options control the assembler and linker; most of these are not
+-documented here, since you rarely need to use any of them.
+-.PP
+-Most of the command line options that you can use with \s-1GCC\s0 are useful
+-for C programs; when an option is only useful with another language
+-(usually \*(C+), the explanation says so explicitly. If the description
+-for a particular option does not mention a source language, you can use
+-that option with all supported languages.
+-.PP
+-The \fBgcc\fR program accepts options and file names as operands. Many
+-options have multi-letter names; therefore multiple single-letter options
+-may \fInot\fR be grouped: \fB\-dr\fR is very different from \fB\-d\ \-r\fR.
+-.PP
+-You can mix options and other arguments. For the most part, the order
+-you use doesn't matter. Order does matter when you use several options
+-of the same kind; for example, if you specify \fB\-L\fR more than once,
+-the directories are searched in the order specified.
+-.PP
+-Many options have long names starting with \fB\-f\fR or with
+-\&\fB\-W\fR\-\-\-for example, \fB\-fforce\-mem\fR,
+-\&\fB\-fstrength\-reduce\fR, \fB\-Wformat\fR and so on. Most of
+-these have both positive and negative forms; the negative form of
+-\&\fB\-ffoo\fR would be \fB\-fno\-foo\fR. This manual documents
+-only one of these two forms, whichever one is not the default.
+-.SH "OPTIONS"
+-.IX Header "OPTIONS"
+-.Sh "Option Summary"
+-.IX Subsection "Option Summary"
+-Here is a summary of all the options, grouped by type. Explanations are
+-in the following sections.
+-.IP "\fIOverall Options\fR" 4
+-.IX Item "Overall Options"
+-\&\fB\-c \-S \-E \-o\fR \fIfile\fR \fB\-pipe \-pass\-exit\-codes
+-\&\-x\fR \fIlanguage\fR \fB\-v \-### \-\-help \-\-target\-help \-\-version\fR
+-.IP "\fIC Language Options\fR" 4
+-.IX Item "C Language Options"
+-\&\fB\-ansi \-std=\fR\fIstandard\fR \fB\-aux\-info\fR \fIfilename\fR
+-\&\fB\-fno\-asm \-fno\-builtin \-fno\-builtin\-\fR\fIfunction\fR
+-\&\fB\-fhosted \-ffreestanding \-fms\-extensions
+-\&\-trigraphs \-no\-integrated\-cpp \-traditional \-traditional\-cpp
+-\&\-fallow\-single\-precision \-fcond\-mismatch
+-\&\-fsigned\-bitfields \-fsigned\-char
+-\&\-funsigned\-bitfields \-funsigned\-char
+-\&\-fwritable\-strings\fR
+-.IP "\fI\*(C+ Language Options\fR" 4
+-.IX Item " Language Options"
+-\&\fB\-fabi\-version=\fR\fIn\fR \fB\-fno\-access\-control \-fcheck\-new
+-\&\-fconserve\-space \-fno\-const\-strings \-fdollars\-in\-identifiers
+-\&\-fno\-elide\-constructors
+-\&\-fno\-enforce\-eh\-specs \-fexternal\-templates
+-\&\-falt\-external\-templates
+-\&\-ffor\-scope \-fno\-for\-scope \-fno\-gnu\-keywords
+-\&\-fno\-implicit\-templates
+-\&\-fno\-implicit\-inline\-templates
+-\&\-fno\-implement\-inlines \-fms\-extensions
+-\&\-fno\-nonansi\-builtins \-fno\-operator\-names
+-\&\-fno\-optional\-diags \-fpermissive
+-\&\-frepo \-fno\-rtti \-fstats \-ftemplate\-depth\-\fR\fIn\fR
+-\&\fB\-fuse\-cxa\-atexit \-fvtable\-gc \-fno\-weak \-nostdinc++
+-\&\-fno\-default\-inline \-Wabi \-Wctor\-dtor\-privacy
+-\&\-Wnon\-virtual\-dtor \-Wreorder
+-\&\-Weffc++ \-Wno\-deprecated
+-\&\-Wno\-non\-template\-friend \-Wold\-style\-cast
+-\&\-Woverloaded\-virtual \-Wno\-pmf\-conversions
+-\&\-Wsign\-promo\fR
+-.IP "\fIObjective-C Language Options\fR" 4
+-.IX Item "Objective-C Language Options"
+-\&\fB\-fconstant\-string\-class=\fR\fIclass-name\fR
+-\&\fB\-fgnu\-runtime \-fnext\-runtime \-gen\-decls
+-\&\-Wno\-protocol \-Wselector \-Wundeclared\-selector\fR
+-.IP "\fILanguage Independent Options\fR" 4
+-.IX Item "Language Independent Options"
+-\&\fB\-fmessage\-length=\fR\fIn\fR
+-\&\fB\-fdiagnostics\-show\-location=\fR[\fBonce\fR|\fBevery-line\fR]
+-.IP "\fIWarning Options\fR" 4
+-.IX Item "Warning Options"
+-\&\fB\-fsyntax\-only \-pedantic \-pedantic\-errors
+-\&\-w \-W \-Wall \-Waggregate\-return
+-\&\-Wcast\-align \-Wcast\-qual \-Wchar\-subscripts \-Wcomment
+-\&\-Wconversion \-Wno\-deprecated\-declarations
+-\&\-Wdisabled\-optimization \-Wno\-div\-by\-zero \-Werror
+-\&\-Wfloat\-equal \-Wformat \-Wformat=2
+-\&\-Wformat\-nonliteral \-Wformat\-security
+-\&\-Wimplicit \-Wimplicit\-int
+-\&\-Wimplicit\-function\-declaration
+-\&\-Werror\-implicit\-function\-declaration
+-\&\-Wimport \-Winline \-Wno\-endif\-labels
+-\&\-Wlarger\-than\-\fR\fIlen\fR \fB\-Wlong\-long
+-\&\-Wmain \-Wmissing\-braces
+-\&\-Wmissing\-format\-attribute \-Wmissing\-noreturn
+-\&\-Wno\-multichar \-Wno\-format\-extra\-args \-Wno\-format\-y2k
+-\&\-Wno\-import \-Wnonnull \-Wpacked \-Wpadded
+-\&\-Wparentheses \-Wpointer\-arith \-Wredundant\-decls
+-\&\-Wreturn\-type \-Wsequence\-point \-Wshadow
+-\&\-Wsign\-compare \-Wstrict\-aliasing
+-\&\-Wswitch \-Wswitch\-default \-Wswitch\-enum
+-\&\-Wsystem\-headers \-Wtrigraphs \-Wundef \-Wuninitialized
+-\&\-Wunknown\-pragmas \-Wunreachable\-code
+-\&\-Wunused \-Wunused\-function \-Wunused\-label \-Wunused\-parameter
+-\&\-Wunused\-value \-Wunused\-variable \-Wwrite\-strings\fR
+-.IP "\fIC\-only Warning Options\fR" 4
+-.IX Item "C-only Warning Options"
+-\&\fB\-Wbad\-function\-cast \-Wmissing\-declarations
+-\&\-Wmissing\-prototypes \-Wnested\-externs
+-\&\-Wstrict\-prototypes \-Wtraditional\fR
+-.IP "\fIDebugging Options\fR" 4
+-.IX Item "Debugging Options"
+-\&\fB\-d\fR\fIletters\fR \fB\-dumpspecs \-dumpmachine \-dumpversion
+-\&\-fdump\-unnumbered \-fdump\-translation\-unit\fR[\fB\-\fR\fIn\fR]
+-\&\fB\-fdump\-class\-hierarchy\fR[\fB\-\fR\fIn\fR]
+-\&\fB\-fdump\-tree\-original\fR[\fB\-\fR\fIn\fR]
+-\&\fB\-fdump\-tree\-optimized\fR[\fB\-\fR\fIn\fR]
+-\&\fB\-fdump\-tree\-inlined\fR[\fB\-\fR\fIn\fR]
+-\&\fB\-feliminate\-dwarf2\-dups \-fmem\-report
+-\&\-fprofile\-arcs \-frandom\-seed=\fR\fIn\fR
+-\&\fB\-fsched\-verbose=\fR\fIn\fR \fB\-ftest\-coverage \-ftime\-report
+-\&\-g \-g\fR\fIlevel\fR \fB\-gcoff \-gdwarf \-gdwarf\-1 \-gdwarf\-1+ \-gdwarf\-2
+-\&\-ggdb \-gstabs \-gstabs+ \-gvms \-gxcoff \-gxcoff+
+-\&\-p \-pg \-print\-file\-name=\fR\fIlibrary\fR \fB\-print\-libgcc\-file\-name
+-\&\-print\-multi\-directory \-print\-multi\-lib
+-\&\-print\-prog\-name=\fR\fIprogram\fR \fB\-print\-search\-dirs \-Q
+-\&\-save\-temps \-time\fR
+-.IP "\fIOptimization Options\fR" 4
+-.IX Item "Optimization Options"
+-\&\fB\-falign\-functions=\fR\fIn\fR \fB\-falign\-jumps=\fR\fIn\fR
+-\&\fB\-falign\-labels=\fR\fIn\fR \fB\-falign\-loops=\fR\fIn\fR
+-\&\fB\-fbranch\-probabilities \-fcaller\-saves \-fcprop\-registers
+-\&\-fcse\-follow\-jumps \-fcse\-skip\-blocks \-fdata\-sections
+-\&\-fdelayed\-branch \-fdelete\-null\-pointer\-checks
+-\&\-fexpensive\-optimizations \-ffast\-math \-ffloat\-store
+-\&\-fforce\-addr \-fforce\-mem \-ffunction\-sections
+-\&\-fgcse \-fgcse\-lm \-fgcse\-sm \-floop\-optimize \-fcrossjumping
+-\&\-fif\-conversion \-fif\-conversion2
+-\&\-finline\-functions \-finline\-limit=\fR\fIn\fR \fB\-fkeep\-inline\-functions
+-\&\-fkeep\-static\-consts \-fmerge\-constants \-fmerge\-all\-constants
+-\&\-fmove\-all\-movables \-fnew\-ra \-fno\-branch\-count\-reg
+-\&\-fno\-default\-inline \-fno\-defer\-pop
+-\&\-fno\-function\-cse \-fno\-guess\-branch\-probability
+-\&\-fno\-inline \-fno\-math\-errno \-fno\-peephole \-fno\-peephole2
+-\&\-funsafe\-math\-optimizations \-ffinite\-math\-only
+-\&\-fno\-trapping\-math \-fno\-zero\-initialized\-in\-bss
+-\&\-fomit\-frame\-pointer \-foptimize\-register\-move
+-\&\-foptimize\-sibling\-calls \-fprefetch\-loop\-arrays
+-\&\-freduce\-all\-givs \-fregmove \-frename\-registers
+-\&\-freorder\-blocks \-freorder\-functions
+-\&\-frerun\-cse\-after\-loop \-frerun\-loop\-opt
+-\&\-fschedule\-insns \-fschedule\-insns2
+-\&\-fno\-sched\-interblock \-fno\-sched\-spec \-fsched\-spec\-load
+-\&\-fsched\-spec\-load\-dangerous \-fsignaling\-nans
+-\&\-fsingle\-precision\-constant \-fssa \-fssa\-ccp \-fssa\-dce
+-\&\-fstrength\-reduce \-fstrict\-aliasing \-ftracer \-fthread\-jumps
+-\&\-funroll\-all\-loops \-funroll\-loops
+-\&\-\-param\fR \fIname\fR\fB=\fR\fIvalue\fR
+-\&\fB\-O \-O0 \-O1 \-O2 \-O3 \-Os\fR
+-.IP "\fIPreprocessor Options\fR" 4
+-.IX Item "Preprocessor Options"
+-\&\fB\-$ \-A\fR\fIquestion\fR\fB=\fR\fIanswer\fR
+-\&\fB\-A\-\fR\fIquestion\fR[\fB=\fR\fIanswer\fR]
+-\&\fB\-C \-dD \-dI \-dM \-dN
+-\&\-D\fR\fImacro\fR[\fB=\fR\fIdefn\fR] \fB\-E \-H
+-\&\-idirafter\fR \fIdir\fR
+-\&\fB\-include\fR \fIfile\fR \fB\-imacros\fR \fIfile\fR
+-\&\fB\-iprefix\fR \fIfile\fR \fB\-iwithprefix\fR \fIdir\fR
+-\&\fB\-iwithprefixbefore\fR \fIdir\fR \fB\-isystem\fR \fIdir\fR
+-\&\fB\-M \-MM \-MF \-MG \-MP \-MQ \-MT \-nostdinc \-P \-remap
+-\&\-trigraphs \-undef \-U\fR\fImacro\fR \fB\-Wp,\fR\fIoption\fR
+-.IP "\fIAssembler Option\fR" 4
+-.IX Item "Assembler Option"
+-\&\fB\-Wa,\fR\fIoption\fR
+-.IP "\fILinker Options\fR" 4
+-.IX Item "Linker Options"
+-\&\fIobject-file-name\fR \fB\-l\fR\fIlibrary\fR
+-\&\fB\-nostartfiles \-nodefaultlibs \-nostdlib
+-\&\-s \-static \-static\-libgcc \-shared \-shared\-libgcc \-symbolic
+-\&\-Wl,\fR\fIoption\fR \fB\-Xlinker\fR \fIoption\fR
+-\&\fB\-u\fR \fIsymbol\fR
+-.IP "\fIDirectory Options\fR" 4
+-.IX Item "Directory Options"
+-\&\fB\-B\fR\fIprefix\fR \fB\-I\fR\fIdir\fR \fB\-I\- \-L\fR\fIdir\fR \fB\-specs=\fR\fIfile\fR
+-.IP "\fITarget Options\fR" 4
+-.IX Item "Target Options"
+-\&\fB\-V\fR \fIversion\fR \fB\-b\fR \fImachine\fR
+-.IP "\fIMachine Dependent Options\fR" 4
+-.IX Item "Machine Dependent Options"
+-\&\fIM680x0 Options\fR
+-\&\fB\-m68000 \-m68020 \-m68020\-40 \-m68020\-60 \-m68030 \-m68040
+-\&\-m68060 \-mcpu32 \-m5200 \-m68881 \-mbitfield \-mc68000 \-mc68020
+-\&\-mfpa \-mnobitfield \-mrtd \-mshort \-msoft\-float \-mpcrel
+-\&\-malign\-int \-mstrict\-align\fR
+-.Sp
+-\&\fIM68hc1x Options\fR
+-\&\fB\-m6811 \-m6812 \-m68hc11 \-m68hc12 \-m68hcs12
+-\&\-mauto\-incdec \-minmax \-mlong\-calls \-mshort
+-\&\-msoft\-reg\-count=\fR\fIcount\fR
+-.Sp
+-\&\fI\s-1VAX\s0 Options\fR
+-\&\fB\-mg \-mgnu \-munix\fR
+-.Sp
+-\&\fI\s-1SPARC\s0 Options\fR
+-\&\fB\-mcpu=\fR\fIcpu-type\fR
+-\&\fB\-mtune=\fR\fIcpu-type\fR
+-\&\fB\-mcmodel=\fR\fIcode-model\fR
+-\&\fB\-m32 \-m64
+-\&\-mapp\-regs \-mbroken\-saverestore \-mcypress
+-\&\-mfaster\-structs \-mflat
+-\&\-mfpu \-mhard\-float \-mhard\-quad\-float
+-\&\-mimpure\-text \-mlittle\-endian \-mlive\-g0 \-mno\-app\-regs
+-\&\-mno\-faster\-structs \-mno\-flat \-mno\-fpu
+-\&\-mno\-impure\-text \-mno\-stack\-bias \-mno\-unaligned\-doubles
+-\&\-msoft\-float \-msoft\-quad\-float \-msparclite \-mstack\-bias
+-\&\-msupersparc \-munaligned\-doubles \-mv8
+-\&\-threads \-pthreads\fR
+-.Sp
+-\&\fI\s-1ARM\s0 Options\fR
+-\&\fB\-mapcs\-frame \-mno\-apcs\-frame
+-\&\-mapcs\-26 \-mapcs\-32
+-\&\-mapcs\-stack\-check \-mno\-apcs\-stack\-check
+-\&\-mapcs\-float \-mno\-apcs\-float
+-\&\-mapcs\-reentrant \-mno\-apcs\-reentrant
+-\&\-msched\-prolog \-mno\-sched\-prolog
+-\&\-mlittle\-endian \-mbig\-endian \-mwords\-little\-endian
+-\&\-malignment\-traps \-mno\-alignment\-traps
+-\&\-msoft\-float \-mhard\-float \-mfpe
+-\&\-mthumb\-interwork \-mno\-thumb\-interwork
+-\&\-mcpu=\fR\fIname\fR \fB\-march=\fR\fIname\fR \fB\-mfpe=\fR\fIname\fR
+-\&\fB\-mstructure\-size\-boundary=\fR\fIn\fR
+-\&\fB\-mabort\-on\-noreturn
+-\&\-mlong\-calls \-mno\-long\-calls
+-\&\-msingle\-pic\-base \-mno\-single\-pic\-base
+-\&\-mpic\-register=\fR\fIreg\fR
+-\&\fB\-mnop\-fun\-dllimport
+-\&\-mpoke\-function\-name
+-\&\-mthumb \-marm
+-\&\-mtpcs\-frame \-mtpcs\-leaf\-frame
+-\&\-mcaller\-super\-interworking \-mcallee\-super\-interworking\fR
+-.Sp
+-\&\fI\s-1MN10200\s0 Options\fR
+-\&\fB\-mrelax\fR
+-.Sp
+-\&\fI\s-1MN10300\s0 Options\fR
+-\&\fB\-mmult\-bug \-mno\-mult\-bug
+-\&\-mam33 \-mno\-am33
+-\&\-mno\-crt0 \-mrelax\fR
+-.Sp
+-\&\fIM32R/D Options\fR
+-\&\fB\-m32rx \-m32r \-mcode\-model=\fR\fImodel-type\fR
+-\&\fB\-msdata=\fR\fIsdata-type\fR \fB\-G\fR \fInum\fR
+-.Sp
+-\&\fIM88K Options\fR
+-\&\fB\-m88000 \-m88100 \-m88110 \-mbig\-pic
+-\&\-mcheck\-zero\-division \-mhandle\-large\-shift
+-\&\-midentify\-revision \-mno\-check\-zero\-division
+-\&\-mno\-ocs\-debug\-info \-mno\-ocs\-frame\-position
+-\&\-mno\-optimize\-arg\-area \-mno\-serialize\-volatile
+-\&\-mno\-underscores \-mocs\-debug\-info
+-\&\-mocs\-frame\-position \-moptimize\-arg\-area
+-\&\-mserialize\-volatile \-mshort\-data\-\fR\fInum\fR \fB\-msvr3
+-\&\-msvr4 \-mtrap\-large\-shift \-muse\-div\-instruction
+-\&\-mversion\-03.00 \-mwarn\-passed\-structs\fR
+-.Sp
+-\&\fI\s-1RS/6000\s0 and PowerPC Options\fR
+-\&\fB\-mcpu=\fR\fIcpu-type\fR
+-\&\fB\-mtune=\fR\fIcpu-type\fR
+-\&\fB\-mpower \-mno\-power \-mpower2 \-mno\-power2
+-\&\-mpowerpc \-mpowerpc64 \-mno\-powerpc
+-\&\-maltivec \-mno\-altivec
+-\&\-mpowerpc\-gpopt \-mno\-powerpc\-gpopt
+-\&\-mpowerpc\-gfxopt \-mno\-powerpc\-gfxopt
+-\&\-mnew\-mnemonics \-mold\-mnemonics
+-\&\-mfull\-toc \-mminimal\-toc \-mno\-fp\-in\-toc \-mno\-sum\-in\-toc
+-\&\-m64 \-m32 \-mxl\-call \-mno\-xl\-call \-mpe
+-\&\-msoft\-float \-mhard\-float \-mmultiple \-mno\-multiple
+-\&\-mstring \-mno\-string \-mupdate \-mno\-update
+-\&\-mfused\-madd \-mno\-fused\-madd \-mbit\-align \-mno\-bit\-align
+-\&\-mstrict\-align \-mno\-strict\-align \-mrelocatable
+-\&\-mno\-relocatable \-mrelocatable\-lib \-mno\-relocatable\-lib
+-\&\-mtoc \-mno\-toc \-mlittle \-mlittle\-endian \-mbig \-mbig\-endian
+-\&\-mcall\-aix \-mcall\-sysv \-mcall\-netbsd
+-\&\-maix\-struct\-return \-msvr4\-struct\-return
+-\&\-mabi=altivec \-mabi=no\-altivec
+-\&\-mabi=spe \-mabi=no\-spe
+-\&\-misel=yes \-misel=no
+-\&\-mprototype \-mno\-prototype
+-\&\-msim \-mmvme \-mads \-myellowknife \-memb \-msdata
+-\&\-msdata=\fR\fIopt\fR \fB\-mvxworks \-mwindiss \-G\fR \fInum\fR \fB\-pthread\fR
+-.Sp
+-\&\fIDarwin Options\fR
+-.Sp
+-\&\fB\-all_load \-allowable_client \-arch \-arch_errors_fatal
+-\&\-arch_only \-bind_at_load \-bundle \-bundle_loader
+-\&\-client_name \-compatibility_version \-current_version
+-\&\-dependency\-file \-dylib_file \-dylinker_install_name
+-\&\-dynamic \-dynamiclib \-exported_symbols_list
+-\&\-filelist \-flat_namespace \-force_cpusubtype_ALL
+-\&\-force_flat_namespace \-headerpad_max_install_names
+-\&\-image_base \-init \-install_name \-keep_private_externs
+-\&\-multi_module \-multiply_defined \-multiply_defined_unused
+-\&\-noall_load \-nomultidefs \-noprebind \-noseglinkedit
+-\&\-pagezero_size \-prebind \-prebind_all_twolevel_modules
+-\&\-private_bundle \-read_only_relocs \-sectalign
+-\&\-sectobjectsymbols \-whyload \-seg1addr
+-\&\-sectcreate \-sectobjectsymbols \-sectorder
+-\&\-seg_addr_table \-seg_addr_table_filename \-seglinkedit
+-\&\-segprot \-segs_read_only_addr \-segs_read_write_addr
+-\&\-single_module \-static \-sub_library \-sub_umbrella
+-\&\-twolevel_namespace \-umbrella \-undefined
+-\&\-unexported_symbols_list \-weak_reference_mismatches \-whatsloaded\fR
+-.Sp
+-\&\fI\s-1RT\s0 Options\fR
+-\&\fB\-mcall\-lib\-mul \-mfp\-arg\-in\-fpregs \-mfp\-arg\-in\-gregs
+-\&\-mfull\-fp\-blocks \-mhc\-struct\-return \-min\-line\-mul
+-\&\-mminimum\-fp\-blocks \-mnohc\-struct\-return\fR
+-.Sp
+-\&\fI\s-1MIPS\s0 Options\fR
+-\&\fB\-mabicalls \-march=\fR\fIcpu-type\fR \fB\-mtune=\fR\fIcpu=type\fR
+-\&\fB\-mcpu=\fR\fIcpu-type\fR \fB\-membedded\-data \-muninit\-const\-in\-rodata
+-\&\-membedded\-pic \-mfp32 \-mfp64 \-mfused\-madd \-mno\-fused\-madd
+-\&\-mgas \-mgp32 \-mgp64
+-\&\-mgpopt \-mhalf\-pic \-mhard\-float \-mint64 \-mips1
+-\&\-mips2 \-mips3 \-mips4 \-mlong64 \-mlong32 \-mlong\-calls \-mmemcpy
+-\&\-mmips\-as \-mmips\-tfile \-mno\-abicalls
+-\&\-mno\-embedded\-data \-mno\-uninit\-const\-in\-rodata
+-\&\-mno\-embedded\-pic \-mno\-gpopt \-mno\-long\-calls
+-\&\-mno\-memcpy \-mno\-mips\-tfile \-mno\-rnames \-mno\-stats
+-\&\-mrnames \-msoft\-float
+-\&\-m4650 \-msingle\-float \-mmad
+-\&\-mstats \-EL \-EB \-G\fR \fInum\fR \fB\-nocpp
+-\&\-mabi=32 \-mabi=n32 \-mabi=64 \-mabi=eabi
+-\&\-mfix7000 \-mno\-crt0 \-mflush\-func=\fR\fIfunc\fR \fB\-mno\-flush\-func
+-\&\-mbranch\-likely \-mno\-branch\-likely\fR
+-.Sp
+-\&\fIi386 and x86\-64 Options\fR
+-\&\fB\-mcpu=\fR\fIcpu-type\fR \fB\-march=\fR\fIcpu-type\fR
+-\&\fB\-mfpmath=\fR\fIunit\fR \fB\-masm=\fR\fIdialect\fR \fB\-mno\-fancy\-math\-387
+-\&\-mno\-fp\-ret\-in\-387 \-msoft\-float \-msvr3\-shlib
+-\&\-mno\-wide\-multiply \-mrtd \-malign\-double
+-\&\-mpreferred\-stack\-boundary=\fR\fInum\fR
+-\&\fB\-mmmx \-msse \-msse2 \-msse3 \-m3dnow
+-\&\-mthreads \-mno\-align\-stringops \-minline\-all\-stringops
+-\&\-mpush\-args \-maccumulate\-outgoing\-args \-m128bit\-long\-double
+-\&\-m96bit\-long\-double \-mregparm=\fR\fInum\fR \fB\-momit\-leaf\-frame\-pointer
+-\&\-mno\-red\-zone
+-\&\-mcmodel=\fR\fIcode-model\fR
+-\&\fB\-m32 \-m64\fR
+-.Sp
+-\&\fI\s-1HPPA\s0 Options\fR
+-\&\fB\-march=\fR\fIarchitecture-type\fR
+-\&\fB\-mbig\-switch \-mdisable\-fpregs \-mdisable\-indexing
+-\&\-mfast\-indirect\-calls \-mgas \-mgnu\-ld \-mhp\-ld
+-\&\-mjump\-in\-delay \-mlinker\-opt \-mlong\-calls
+-\&\-mlong\-load\-store \-mno\-big\-switch \-mno\-disable\-fpregs
+-\&\-mno\-disable\-indexing \-mno\-fast\-indirect\-calls \-mno\-gas
+-\&\-mno\-jump\-in\-delay \-mno\-long\-load\-store
+-\&\-mno\-portable\-runtime \-mno\-soft\-float
+-\&\-mno\-space\-regs \-msoft\-float \-mpa\-risc\-1\-0
+-\&\-mpa\-risc\-1\-1 \-mpa\-risc\-2\-0 \-mportable\-runtime
+-\&\-mschedule=\fR\fIcpu-type\fR \fB\-mspace\-regs \-msio \-mwsio
+-\&\-nolibdld \-static \-threads\fR
+-.Sp
+-\&\fIIntel 960 Options\fR
+-\&\fB\-m\fR\fIcpu-type\fR \fB\-masm\-compat \-mclean\-linkage
+-\&\-mcode\-align \-mcomplex\-addr \-mleaf\-procedures
+-\&\-mic\-compat \-mic2.0\-compat \-mic3.0\-compat
+-\&\-mintel\-asm \-mno\-clean\-linkage \-mno\-code\-align
+-\&\-mno\-complex\-addr \-mno\-leaf\-procedures
+-\&\-mno\-old\-align \-mno\-strict\-align \-mno\-tail\-call
+-\&\-mnumerics \-mold\-align \-msoft\-float \-mstrict\-align
+-\&\-mtail\-call\fR
+-.Sp
+-\&\fI\s-1DEC\s0 Alpha Options\fR
+-\&\fB\-mno\-fp\-regs \-msoft\-float \-malpha\-as \-mgas
+-\&\-mieee \-mieee\-with\-inexact \-mieee\-conformant
+-\&\-mfp\-trap\-mode=\fR\fImode\fR \fB\-mfp\-rounding\-mode=\fR\fImode\fR
+-\&\fB\-mtrap\-precision=\fR\fImode\fR \fB\-mbuild\-constants
+-\&\-mcpu=\fR\fIcpu-type\fR \fB\-mtune=\fR\fIcpu-type\fR
+-\&\fB\-mbwx \-mmax \-mfix \-mcix
+-\&\-mfloat\-vax \-mfloat\-ieee
+-\&\-mexplicit\-relocs \-msmall\-data \-mlarge\-data
+-\&\-mmemory\-latency=\fR\fItime\fR
+-.Sp
+-\&\fI\s-1DEC\s0 Alpha/VMS Options\fR
+-\&\fB\-mvms\-return\-codes\fR
+-.Sp
+-\&\fIH8/300 Options\fR
+-\&\fB\-mrelax \-mh \-ms \-mn \-mint32 \-malign\-300\fR
+-.Sp
+-\&\fI\s-1SH\s0 Options\fR
+-\&\fB\-m1 \-m2 \-m3 \-m3e
+-\&\-m4\-nofpu \-m4\-single\-only \-m4\-single \-m4
+-\&\-m5\-64media \-m5\-64media\-nofpu
+-\&\-m5\-32media \-m5\-32media\-nofpu
+-\&\-m5\-compact \-m5\-compact\-nofpu
+-\&\-mb \-ml \-mdalign \-mrelax
+-\&\-mbigtable \-mfmovd \-mhitachi \-mnomacsave
+-\&\-mieee \-misize \-mpadstruct \-mspace
+-\&\-mprefergot \-musermode\fR
+-.Sp
+-\&\fISystem V Options\fR
+-\&\fB\-Qy \-Qn \-YP,\fR\fIpaths\fR \fB\-Ym,\fR\fIdir\fR
+-.Sp
+-\&\fI\s-1ARC\s0 Options\fR
+-\&\fB\-EB \-EL
+-\&\-mmangle\-cpu \-mcpu=\fR\fIcpu\fR \fB\-mtext=\fR\fItext-section\fR
+-\&\fB\-mdata=\fR\fIdata-section\fR \fB\-mrodata=\fR\fIreadonly-data-section\fR
+-.Sp
+-\&\fITMS320C3x/C4x Options\fR
+-\&\fB\-mcpu=\fR\fIcpu\fR \fB\-mbig \-msmall \-mregparm \-mmemparm
+-\&\-mfast\-fix \-mmpyi \-mbk \-mti \-mdp\-isr\-reload
+-\&\-mrpts=\fR\fIcount\fR \fB\-mrptb \-mdb \-mloop\-unsigned
+-\&\-mparallel\-insns \-mparallel\-mpy \-mpreserve\-float\fR
+-.Sp
+-\&\fIV850 Options\fR
+-\&\fB\-mlong\-calls \-mno\-long\-calls \-mep \-mno\-ep
+-\&\-mprolog\-function \-mno\-prolog\-function \-mspace
+-\&\-mtda=\fR\fIn\fR \fB\-msda=\fR\fIn\fR \fB\-mzda=\fR\fIn\fR
+-\&\fB\-mapp\-regs \-mno\-app\-regs
+-\&\-mdisable\-callt \-mno\-disable\-callt
+-\&\-mv850e
+-\&\-mv850 \-mbig\-switch\fR
+-.Sp
+-\&\fI\s-1NS32K\s0 Options\fR
+-\&\fB\-m32032 \-m32332 \-m32532 \-m32081 \-m32381
+-\&\-mmult\-add \-mnomult\-add \-msoft\-float \-mrtd \-mnortd
+-\&\-mregparam \-mnoregparam \-msb \-mnosb
+-\&\-mbitfield \-mnobitfield \-mhimem \-mnohimem\fR
+-.Sp
+-\&\fI\s-1AVR\s0 Options\fR
+-\&\fB\-mmcu=\fR\fImcu\fR \fB\-msize \-minit\-stack=\fR\fIn\fR \fB\-mno\-interrupts
+-\&\-mcall\-prologues \-mno\-tablejump \-mtiny\-stack\fR
+-.Sp
+-\&\fIMCore Options\fR
+-\&\fB\-mhardlit \-mno\-hardlit \-mdiv \-mno\-div \-mrelax\-immediates
+-\&\-mno\-relax\-immediates \-mwide\-bitfields \-mno\-wide\-bitfields
+-\&\-m4byte\-functions \-mno\-4byte\-functions \-mcallgraph\-data
+-\&\-mno\-callgraph\-data \-mslow\-bytes \-mno\-slow\-bytes \-mno\-lsim
+-\&\-mlittle\-endian \-mbig\-endian \-m210 \-m340 \-mstack\-increment\fR
+-.Sp
+-\&\fI\s-1MMIX\s0 Options\fR
+-\&\fB\-mlibfuncs \-mno\-libfuncs \-mepsilon \-mno\-epsilon \-mabi=gnu
+-\&\-mabi=mmixware \-mzero\-extend \-mknuthdiv \-mtoplevel\-symbols
+-\&\-melf \-mbranch\-predict \-mno\-branch\-predict \-mbase\-addresses
+-\&\-mno\-base\-addresses \-msingle\-exit \-mno\-single\-exit\fR
+-.Sp
+-\&\fI\s-1IA\-64\s0 Options\fR
+-\&\fB\-mbig\-endian \-mlittle\-endian \-mgnu\-as \-mgnu\-ld \-mno\-pic
+-\&\-mvolatile\-asm\-stop \-mb\-step \-mregister\-names \-mno\-sdata
+-\&\-mconstant\-gp \-mauto\-pic \-minline\-float\-divide\-min\-latency
+-\&\-minline\-float\-divide\-max\-throughput
+-\&\-minline\-int\-divide\-min\-latency
+-\&\-minline\-int\-divide\-max\-throughput \-mno\-dwarf2\-asm
+-\&\-mfixed\-range=\fR\fIregister-range\fR
+-.Sp
+-\&\fID30V Options\fR
+-\&\fB\-mextmem \-mextmemory \-monchip \-mno\-asm\-optimize
+-\&\-masm\-optimize \-mbranch\-cost=\fR\fIn\fR \fB\-mcond\-exec=\fR\fIn\fR
+-.Sp
+-\&\fIS/390 and zSeries Options\fR
+-\&\fB\-mhard\-float \-msoft\-float \-mbackchain \-mno\-backchain
+-\&\-msmall\-exec \-mno\-small\-exec \-mmvcle \-mno\-mvcle
+-\&\-m64 \-m31 \-mdebug \-mno\-debug\fR
+-.Sp
+-\&\fI\s-1CRIS\s0 Options\fR
+-\&\fB\-mcpu=\fR\fIcpu\fR \fB\-march=\fR\fIcpu\fR \fB\-mtune=\fR\fIcpu\fR
+-\&\fB\-mmax\-stack\-frame=\fR\fIn\fR \fB\-melinux\-stacksize=\fR\fIn\fR
+-\&\fB\-metrax4 \-metrax100 \-mpdebug \-mcc\-init \-mno\-side\-effects
+-\&\-mstack\-align \-mdata\-align \-mconst\-align
+-\&\-m32\-bit \-m16\-bit \-m8\-bit \-mno\-prologue\-epilogue \-mno\-gotplt
+-\&\-melf \-maout \-melinux \-mlinux \-sim \-sim2
+-\&\-mmul\-bug\-workaround \-mno\-mul\-bug\-workaround\fR
+-.Sp
+-\&\fI\s-1PDP\-11\s0 Options\fR
+-\&\fB\-mfpu \-msoft\-float \-mac0 \-mno\-ac0 \-m40 \-m45 \-m10
+-\&\-mbcopy \-mbcopy\-builtin \-mint32 \-mno\-int16
+-\&\-mint16 \-mno\-int32 \-mfloat32 \-mno\-float64
+-\&\-mfloat64 \-mno\-float32 \-mabshi \-mno\-abshi
+-\&\-mbranch\-expensive \-mbranch\-cheap
+-\&\-msplit \-mno\-split \-munix\-asm \-mdec\-asm\fR
+-.Sp
+-\&\fIXstormy16 Options\fR
+-\&\fB\-msim\fR
+-.Sp
+-\&\fIXtensa Options\fR
+-\&\fB\-mbig\-endian \-mlittle\-endian
+-\&\-mdensity \-mno\-density
+-\&\-mmac16 \-mno\-mac16
+-\&\-mmul16 \-mno\-mul16
+-\&\-mmul32 \-mno\-mul32
+-\&\-mnsa \-mno\-nsa
+-\&\-mminmax \-mno\-minmax
+-\&\-msext \-mno\-sext
+-\&\-mbooleans \-mno\-booleans
+-\&\-mhard\-float \-msoft\-float
+-\&\-mfused\-madd \-mno\-fused\-madd
+-\&\-mserialize\-volatile \-mno\-serialize\-volatile
+-\&\-mtext\-section\-literals \-mno\-text\-section\-literals
+-\&\-mtarget\-align \-mno\-target\-align
+-\&\-mlongcalls \-mno\-longcalls\fR
+-.Sp
+-\&\fI\s-1FRV\s0 Options\fR
+-\&\fB\-mgpr\-32 \-mgpr\-64 \-mfpr\-32 \-mfpr\-64
+-\&\-mhard\-float \-msoft\-float \-malloc\-cc \-mfixed\-cc
+-\&\-mdword \-mno\-dword \-mdouble \-mno\-double
+-\&\-mmedia \-mno\-media \-mmuladd \-mno\-muladd \-mlibrary\-pic
+-\&\-macc\-4 \-macc\-8 \-mpack \-mno\-pack \-mno\-eflags
+-\&\-mcond\-move \-mno\-cond\-move \-mscc \-mno\-scc
+-\&\-mcond\-exec \-mno\-cond\-exec \-mvliw\-branch \-mno\-vliw\-branch
+-\&\-mmulti\-cond\-exec \-mno\-multi\-cond\-exec \-mnested\-cond\-exec
+-\&\-mno\-nested\-cond\-exec \-mtomcat\-stats
+-\&\-mcpu=\fR\fIcpu\fR
+-.IP "\fICode Generation Options\fR" 4
+-.IX Item "Code Generation Options"
+-\&\fB\-fcall\-saved\-\fR\fIreg\fR \fB\-fcall\-used\-\fR\fIreg\fR
+-\&\fB\-ffixed\-\fR\fIreg\fR \fB\-fexceptions
+-\&\-fnon\-call\-exceptions \-funwind\-tables
+-\&\-fasynchronous\-unwind\-tables
+-\&\-finhibit\-size\-directive \-finstrument\-functions
+-\&\-fno\-common \-fno\-ident \-fno\-gnu\-linker
+-\&\-fpcc\-struct\-return \-fpic \-fPIC
+-\&\-freg\-struct\-return \-fshared\-data \-fshort\-enums
+-\&\-fshort\-double \-fshort\-wchar \-fvolatile
+-\&\-fvolatile\-global \-fvolatile\-static
+-\&\-fverbose\-asm \-fpack\-struct \-fstack\-check
+-\&\-fstack\-limit\-register=\fR\fIreg\fR \fB\-fstack\-limit\-symbol=\fR\fIsym\fR
+-\&\fB\-fargument\-alias \-fargument\-noalias
+-\&\-fargument\-noalias\-global \-fleading\-underscore
+-\&\-ftls\-model=\fR\fImodel\fR
+-\&\fB\-ftrapv \-fbounds\-check\fR
+-.Sh "Options Controlling the Kind of Output"
+-.IX Subsection "Options Controlling the Kind of Output"
+-Compilation can involve up to four stages: preprocessing, compilation
+-proper, assembly and linking, always in that order. The first three
+-stages apply to an individual source file, and end by producing an
+-object file; linking combines all the object files (those newly
+-compiled, and those specified as input) into an executable file.
+-.PP
+-For any given input file, the file name suffix determines what kind of
+-compilation is done:
+-.IP "\fIfile\fR\fB.c\fR" 4
+-.IX Item "file.c"
+-C source code which must be preprocessed.
+-.IP "\fIfile\fR\fB.i\fR" 4
+-.IX Item "file.i"
+-C source code which should not be preprocessed.
+-.IP "\fIfile\fR\fB.ii\fR" 4
+-.IX Item "file.ii"
+-\&\*(C+ source code which should not be preprocessed.
+-.IP "\fIfile\fR\fB.m\fR" 4
+-.IX Item "file.m"
+-Objective-C source code. Note that you must link with the library
+-\&\fIlibobjc.a\fR to make an Objective-C program work.
+-.IP "\fIfile\fR\fB.mi\fR" 4
+-.IX Item "file.mi"
+-Objective-C source code which should not be preprocessed.
+-.IP "\fIfile\fR\fB.h\fR" 4
+-.IX Item "file.h"
+-C header file (not to be compiled or linked).
+-.IP "\fIfile\fR\fB.cc\fR" 4
+-.IX Item "file.cc"
+-.PD 0
+-.IP "\fIfile\fR\fB.cp\fR" 4
+-.IX Item "file.cp"
+-.IP "\fIfile\fR\fB.cxx\fR" 4
+-.IX Item "file.cxx"
+-.IP "\fIfile\fR\fB.cpp\fR" 4
+-.IX Item "file.cpp"
+-.IP "\fIfile\fR\fB.c++\fR" 4
+-.IX Item "file.c++"
+-.IP "\fIfile\fR\fB.C\fR" 4
+-.IX Item "file.C"
+-.PD
+-\&\*(C+ source code which must be preprocessed. Note that in \fB.cxx\fR,
+-the last two letters must both be literally \fBx\fR. Likewise,
+-\&\fB.C\fR refers to a literal capital C.
+-.IP "\fIfile\fR\fB.f\fR" 4
+-.IX Item "file.f"
+-.PD 0
+-.IP "\fIfile\fR\fB.for\fR" 4
+-.IX Item "file.for"
+-.IP "\fIfile\fR\fB.FOR\fR" 4
+-.IX Item "file.FOR"
+-.PD
+-Fortran source code which should not be preprocessed.
+-.IP "\fIfile\fR\fB.F\fR" 4
+-.IX Item "file.F"
+-.PD 0
+-.IP "\fIfile\fR\fB.fpp\fR" 4
+-.IX Item "file.fpp"
+-.IP "\fIfile\fR\fB.FPP\fR" 4
+-.IX Item "file.FPP"
+-.PD
+-Fortran source code which must be preprocessed (with the traditional
+-preprocessor).
+-.IP "\fIfile\fR\fB.r\fR" 4
+-.IX Item "file.r"
+-Fortran source code which must be preprocessed with a \s-1RATFOR\s0
+-preprocessor (not included with \s-1GCC\s0).
+-.IP "\fIfile\fR\fB.ads\fR" 4
+-.IX Item "file.ads"
+-Ada source code file which contains a library unit declaration (a
+-declaration of a package, subprogram, or generic, or a generic
+-instantiation), or a library unit renaming declaration (a package,
+-generic, or subprogram renaming declaration). Such files are also
+-called \fIspecs\fR.
+-.IP "\fIfile\fR\fB.adb\fR" 4
+-.IX Item "file.adb"
+-Ada source code file containing a library unit body (a subprogram or
+-package body). Such files are also called \fIbodies\fR.
+-.IP "\fIfile\fR\fB.s\fR" 4
+-.IX Item "file.s"
+-Assembler code.
+-.IP "\fIfile\fR\fB.S\fR" 4
+-.IX Item "file.S"
+-Assembler code which must be preprocessed.
+-.IP "\fIother\fR" 4
+-.IX Item "other"
+-An object file to be fed straight into linking.
+-Any file name with no recognized suffix is treated this way.
+-.PP
+-You can specify the input language explicitly with the \fB\-x\fR option:
+-.IP "\fB\-x\fR \fIlanguage\fR" 4
+-.IX Item "-x language"
+-Specify explicitly the \fIlanguage\fR for the following input files
+-(rather than letting the compiler choose a default based on the file
+-name suffix). This option applies to all following input files until
+-the next \fB\-x\fR option. Possible values for \fIlanguage\fR are:
+-.Sp
+-.Vb 8
+-\& c c-header cpp-output
+-\& c++ c++-cpp-output
+-\& objective-c objc-cpp-output
+-\& assembler assembler-with-cpp
+-\& ada
+-\& f77 f77-cpp-input ratfor
+-\& java
+-\& treelang
+-.Ve
+-.IP "\fB\-x none\fR" 4
+-.IX Item "-x none"
+-Turn off any specification of a language, so that subsequent files are
+-handled according to their file name suffixes (as they are if \fB\-x\fR
+-has not been used at all).
+-.IP "\fB\-pass\-exit\-codes\fR" 4
+-.IX Item "-pass-exit-codes"
+-Normally the \fBgcc\fR program will exit with the code of 1 if any
+-phase of the compiler returns a non-success return code. If you specify
+-\&\fB\-pass\-exit\-codes\fR, the \fBgcc\fR program will instead return with
+-numerically highest error produced by any phase that returned an error
+-indication.
+-.PP
+-If you only want some of the stages of compilation, you can use
+-\&\fB\-x\fR (or filename suffixes) to tell \fBgcc\fR where to start, and
+-one of the options \fB\-c\fR, \fB\-S\fR, or \fB\-E\fR to say where
+-\&\fBgcc\fR is to stop. Note that some combinations (for example,
+-\&\fB\-x cpp-output \-E\fR) instruct \fBgcc\fR to do nothing at all.
+-.IP "\fB\-c\fR" 4
+-.IX Item "-c"
+-Compile or assemble the source files, but do not link. The linking
+-stage simply is not done. The ultimate output is in the form of an
+-object file for each source file.
+-.Sp
+-By default, the object file name for a source file is made by replacing
+-the suffix \fB.c\fR, \fB.i\fR, \fB.s\fR, etc., with \fB.o\fR.
+-.Sp
+-Unrecognized input files, not requiring compilation or assembly, are
+-ignored.
+-.IP "\fB\-S\fR" 4
+-.IX Item "-S"
+-Stop after the stage of compilation proper; do not assemble. The output
+-is in the form of an assembler code file for each non-assembler input
+-file specified.
+-.Sp
+-By default, the assembler file name for a source file is made by
+-replacing the suffix \fB.c\fR, \fB.i\fR, etc., with \fB.s\fR.
+-.Sp
+-Input files that don't require compilation are ignored.
+-.IP "\fB\-E\fR" 4
+-.IX Item "-E"
+-Stop after the preprocessing stage; do not run the compiler proper. The
+-output is in the form of preprocessed source code, which is sent to the
+-standard output.
+-.Sp
+-Input files which don't require preprocessing are ignored.
+-.IP "\fB\-o\fR \fIfile\fR" 4
+-.IX Item "-o file"
+-Place output in file \fIfile\fR. This applies regardless to whatever
+-sort of output is being produced, whether it be an executable file,
+-an object file, an assembler file or preprocessed C code.
+-.Sp
+-Since only one output file can be specified, it does not make sense to
+-use \fB\-o\fR when compiling more than one input file, unless you are
+-producing an executable file as output.
+-.Sp
+-If \fB\-o\fR is not specified, the default is to put an executable file
+-in \fIa.out\fR, the object file for \fI\fIsource\fI.\fIsuffix\fI\fR in
+-\&\fI\fIsource\fI.o\fR, its assembler file in \fI\fIsource\fI.s\fR, and
+-all preprocessed C source on standard output.
+-.IP "\fB\-v\fR" 4
+-.IX Item "-v"
+-Print (on standard error output) the commands executed to run the stages
+-of compilation. Also print the version number of the compiler driver
+-program and of the preprocessor and the compiler proper.
+-.IP "\fB\-###\fR" 4
+-.IX Item "-###"
+-Like \fB\-v\fR except the commands are not executed and all command
+-arguments are quoted. This is useful for shell scripts to capture the
+-driver-generated command lines.
+-.IP "\fB\-pipe\fR" 4
+-.IX Item "-pipe"
+-Use pipes rather than temporary files for communication between the
+-various stages of compilation. This fails to work on some systems where
+-the assembler is unable to read from a pipe; but the \s-1GNU\s0 assembler has
+-no trouble.
+-.IP "\fB\-\-help\fR" 4
+-.IX Item "--help"
+-Print (on the standard output) a description of the command line options
+-understood by \fBgcc\fR. If the \fB\-v\fR option is also specified
+-then \fB\-\-help\fR will also be passed on to the various processes
+-invoked by \fBgcc\fR, so that they can display the command line options
+-they accept. If the \fB\-W\fR option is also specified then command
+-line options which have no documentation associated with them will also
+-be displayed.
+-.IP "\fB\-\-target\-help\fR" 4
+-.IX Item "--target-help"
+-Print (on the standard output) a description of target specific command
+-line options for each tool.
+-.IP "\fB\-\-version\fR" 4
+-.IX Item "--version"
+-Display the version number and copyrights of the invoked \s-1GCC\s0.
+-.Sh "Compiling \*(C+ Programs"
+-.IX Subsection "Compiling Programs"
+-\&\*(C+ source files conventionally use one of the suffixes \fB.C\fR,
+-\&\fB.cc\fR, \fB.cpp\fR, \fB.c++\fR, \fB.cp\fR, or \fB.cxx\fR;
+-preprocessed \*(C+ files use the suffix \fB.ii\fR. \s-1GCC\s0 recognizes
+-files with these names and compiles them as \*(C+ programs even if you
+-call the compiler the same way as for compiling C programs (usually with
+-the name \fBgcc\fR).
+-.PP
+-However, \*(C+ programs often require class libraries as well as a
+-compiler that understands the \*(C+ language\-\-\-and under some
+-circumstances, you might want to compile programs from standard input,
+-or otherwise without a suffix that flags them as \*(C+ programs.
+-\&\fBg++\fR is a program that calls \s-1GCC\s0 with the default language
+-set to \*(C+, and automatically specifies linking against the \*(C+
+-library. On many systems, \fBg++\fR is also
+-installed with the name \fBc++\fR.
+-.PP
+-When you compile \*(C+ programs, you may specify many of the same
+-command-line options that you use for compiling programs in any
+-language; or command-line options meaningful for C and related
+-languages; or options that are meaningful only for \*(C+ programs.
+-.Sh "Options Controlling C Dialect"
+-.IX Subsection "Options Controlling C Dialect"
+-The following options control the dialect of C (or languages derived
+-from C, such as \*(C+ and Objective\-C) that the compiler accepts:
+-.IP "\fB\-ansi\fR" 4
+-.IX Item "-ansi"
+-In C mode, support all \s-1ISO\s0 C90 programs. In \*(C+ mode,
+-remove \s-1GNU\s0 extensions that conflict with \s-1ISO\s0 \*(C+.
+-.Sp
+-This turns off certain features of \s-1GCC\s0 that are incompatible with \s-1ISO\s0
+-C90 (when compiling C code), or of standard \*(C+ (when compiling \*(C+ code),
+-such as the \f(CW\*(C`asm\*(C'\fR and \f(CW\*(C`typeof\*(C'\fR keywords, and
+-predefined macros such as \f(CW\*(C`unix\*(C'\fR and \f(CW\*(C`vax\*(C'\fR that identify the
+-type of system you are using. It also enables the undesirable and
+-rarely used \s-1ISO\s0 trigraph feature. For the C compiler,
+-it disables recognition of \*(C+ style \fB//\fR comments as well as
+-the \f(CW\*(C`inline\*(C'\fR keyword.
+-.Sp
+-The alternate keywords \f(CW\*(C`_\|_asm_\|_\*(C'\fR, \f(CW\*(C`_\|_extension_\|_\*(C'\fR,
+-\&\f(CW\*(C`_\|_inline_\|_\*(C'\fR and \f(CW\*(C`_\|_typeof_\|_\*(C'\fR continue to work despite
+-\&\fB\-ansi\fR. You would not want to use them in an \s-1ISO\s0 C program, of
+-course, but it is useful to put them in header files that might be included
+-in compilations done with \fB\-ansi\fR. Alternate predefined macros
+-such as \f(CW\*(C`_\|_unix_\|_\*(C'\fR and \f(CW\*(C`_\|_vax_\|_\*(C'\fR are also available, with or
+-without \fB\-ansi\fR.
+-.Sp
+-The \fB\-ansi\fR option does not cause non-ISO programs to be
+-rejected gratuitously. For that, \fB\-pedantic\fR is required in
+-addition to \fB\-ansi\fR.
+-.Sp
+-The macro \f(CW\*(C`_\|_STRICT_ANSI_\|_\*(C'\fR is predefined when the \fB\-ansi\fR
+-option is used. Some header files may notice this macro and refrain
+-from declaring certain functions or defining certain macros that the
+-\&\s-1ISO\s0 standard doesn't call for; this is to avoid interfering with any
+-programs that might use these names for other things.
+-.Sp
+-Functions which would normally be built in but do not have semantics
+-defined by \s-1ISO\s0 C (such as \f(CW\*(C`alloca\*(C'\fR and \f(CW\*(C`ffs\*(C'\fR) are not built-in
+-functions with \fB\-ansi\fR is used.
+-.IP "\fB\-std=\fR" 4
+-.IX Item "-std="
+-Determine the language standard. This option is currently only
+-supported when compiling C or \*(C+. A value for this option must be
+-provided; possible values are
+-.RS 4
+-.IP "\fBc89\fR" 4
+-.IX Item "c89"
+-.PD 0
+-.IP "\fBiso9899:1990\fR" 4
+-.IX Item "iso9899:1990"
+-.PD
+-\&\s-1ISO\s0 C90 (same as \fB\-ansi\fR).
+-.IP "\fBiso9899:199409\fR" 4
+-.IX Item "iso9899:199409"
+-\&\s-1ISO\s0 C90 as modified in amendment 1.
+-.IP "\fBc99\fR" 4
+-.IX Item "c99"
+-.PD 0
+-.IP "\fBc9x\fR" 4
+-.IX Item "c9x"
+-.IP "\fBiso9899:1999\fR" 4
+-.IX Item "iso9899:1999"
+-.IP "\fBiso9899:199x\fR" 4
+-.IX Item "iso9899:199x"
+-.PD
+-\&\s-1ISO\s0 C99. Note that this standard is not yet fully supported; see
+-<\fBhttp://gcc.gnu.org/gcc\-3.3/c99status.html\fR> for more information. The
+-names \fBc9x\fR and \fBiso9899:199x\fR are deprecated.
+-.IP "\fBgnu89\fR" 4
+-.IX Item "gnu89"
+-Default, \s-1ISO\s0 C90 plus \s-1GNU\s0 extensions (including some C99 features).
+-.IP "\fBgnu99\fR" 4
+-.IX Item "gnu99"
+-.PD 0
+-.IP "\fBgnu9x\fR" 4
+-.IX Item "gnu9x"
+-.PD
+-\&\s-1ISO\s0 C99 plus \s-1GNU\s0 extensions. When \s-1ISO\s0 C99 is fully implemented in \s-1GCC\s0,
+-this will become the default. The name \fBgnu9x\fR is deprecated.
+-.IP "\fBc++98\fR" 4
+-.IX Item "c++98"
+-The 1998 \s-1ISO\s0 \*(C+ standard plus amendments.
+-.IP "\fBgnu++98\fR" 4
+-.IX Item "gnu++98"
+-The same as \fB\-std=c++98\fR plus \s-1GNU\s0 extensions. This is the
+-default for \*(C+ code.
+-.RE
+-.RS 4
+-.Sp
+-Even when this option is not specified, you can still use some of the
+-features of newer standards in so far as they do not conflict with
+-previous C standards. For example, you may use \f(CW\*(C`_\|_restrict_\|_\*(C'\fR even
+-when \fB\-std=c99\fR is not specified.
+-.Sp
+-The \fB\-std\fR options specifying some version of \s-1ISO\s0 C have the same
+-effects as \fB\-ansi\fR, except that features that were not in \s-1ISO\s0 C90
+-but are in the specified version (for example, \fB//\fR comments and
+-the \f(CW\*(C`inline\*(C'\fR keyword in \s-1ISO\s0 C99) are not disabled.
+-.RE
+-.IP "\fB\-aux\-info\fR \fIfilename\fR" 4
+-.IX Item "-aux-info filename"
+-Output to the given filename prototyped declarations for all functions
+-declared and/or defined in a translation unit, including those in header
+-files. This option is silently ignored in any language other than C.
+-.Sp
+-Besides declarations, the file indicates, in comments, the origin of
+-each declaration (source file and line), whether the declaration was
+-implicit, prototyped or unprototyped (\fBI\fR, \fBN\fR for new or
+-\&\fBO\fR for old, respectively, in the first character after the line
+-number and the colon), and whether it came from a declaration or a
+-definition (\fBC\fR or \fBF\fR, respectively, in the following
+-character). In the case of function definitions, a K&R\-style list of
+-arguments followed by their declarations is also provided, inside
+-comments, after the declaration.
+-.IP "\fB\-fno\-asm\fR" 4
+-.IX Item "-fno-asm"
+-Do not recognize \f(CW\*(C`asm\*(C'\fR, \f(CW\*(C`inline\*(C'\fR or \f(CW\*(C`typeof\*(C'\fR as a
+-keyword, so that code can use these words as identifiers. You can use
+-the keywords \f(CW\*(C`_\|_asm_\|_\*(C'\fR, \f(CW\*(C`_\|_inline_\|_\*(C'\fR and \f(CW\*(C`_\|_typeof_\|_\*(C'\fR
+-instead. \fB\-ansi\fR implies \fB\-fno\-asm\fR.
+-.Sp
+-In \*(C+, this switch only affects the \f(CW\*(C`typeof\*(C'\fR keyword, since
+-\&\f(CW\*(C`asm\*(C'\fR and \f(CW\*(C`inline\*(C'\fR are standard keywords. You may want to
+-use the \fB\-fno\-gnu\-keywords\fR flag instead, which has the same
+-effect. In C99 mode (\fB\-std=c99\fR or \fB\-std=gnu99\fR), this
+-switch only affects the \f(CW\*(C`asm\*(C'\fR and \f(CW\*(C`typeof\*(C'\fR keywords, since
+-\&\f(CW\*(C`inline\*(C'\fR is a standard keyword in \s-1ISO\s0 C99.
+-.IP "\fB\-fno\-builtin\fR" 4
+-.IX Item "-fno-builtin"
+-.PD 0
+-.IP "\fB\-fno\-builtin\-\fR\fIfunction\fR" 4
+-.IX Item "-fno-builtin-function"
+-.PD
+-Don't recognize built-in functions that do not begin with
+-\&\fB_\|_builtin_\fR as prefix.
+-.Sp
+-\&\s-1GCC\s0 normally generates special code to handle certain built-in functions
+-more efficiently; for instance, calls to \f(CW\*(C`alloca\*(C'\fR may become single
+-instructions that adjust the stack directly, and calls to \f(CW\*(C`memcpy\*(C'\fR
+-may become inline copy loops. The resulting code is often both smaller
+-and faster, but since the function calls no longer appear as such, you
+-cannot set a breakpoint on those calls, nor can you change the behavior
+-of the functions by linking with a different library.
+-.Sp
+-With the \fB\-fno\-builtin\-\fR\fIfunction\fR option
+-only the built-in function \fIfunction\fR is
+-disabled. \fIfunction\fR must not begin with \fB_\|_builtin_\fR. If a
+-function is named this is not built-in in this version of \s-1GCC\s0, this
+-option is ignored. There is no corresponding
+-\&\fB\-fbuiltin\-\fR\fIfunction\fR option; if you wish to enable
+-built-in functions selectively when using \fB\-fno\-builtin\fR or
+-\&\fB\-ffreestanding\fR, you may define macros such as:
+-.Sp
+-.Vb 2
+-\& #define abs(n) __builtin_abs ((n))
+-\& #define strcpy(d, s) __builtin_strcpy ((d), (s))
+-.Ve
+-.IP "\fB\-fhosted\fR" 4
+-.IX Item "-fhosted"
+-Assert that compilation takes place in a hosted environment. This implies
+-\&\fB\-fbuiltin\fR. A hosted environment is one in which the
+-entire standard library is available, and in which \f(CW\*(C`main\*(C'\fR has a return
+-type of \f(CW\*(C`int\*(C'\fR. Examples are nearly everything except a kernel.
+-This is equivalent to \fB\-fno\-freestanding\fR.
+-.IP "\fB\-ffreestanding\fR" 4
+-.IX Item "-ffreestanding"
+-Assert that compilation takes place in a freestanding environment. This
+-implies \fB\-fno\-builtin\fR. A freestanding environment
+-is one in which the standard library may not exist, and program startup may
+-not necessarily be at \f(CW\*(C`main\*(C'\fR. The most obvious example is an \s-1OS\s0 kernel.
+-This is equivalent to \fB\-fno\-hosted\fR.
+-.IP "\fB\-fms\-extensions\fR" 4
+-.IX Item "-fms-extensions"
+-Accept some non-standard constructs used in Microsoft header files.
+-.IP "\fB\-trigraphs\fR" 4
+-.IX Item "-trigraphs"
+-Support \s-1ISO\s0 C trigraphs. The \fB\-ansi\fR option (and \fB\-std\fR
+-options for strict \s-1ISO\s0 C conformance) implies \fB\-trigraphs\fR.
+-.IP "\fB\-no\-integrated\-cpp\fR" 4
+-.IX Item "-no-integrated-cpp"
+-Performs a compilation in two passes: preprocessing and compiling. This
+-option allows a user supplied \*(L"cc1\*(R", \*(L"cc1plus\*(R", or \*(L"cc1obj\*(R" via the
+-\&\fB\-B\fR option. The user supplied compilation step can then add in
+-an additional preprocessing step after normal preprocessing but before
+-compiling. The default is to use the integrated cpp (internal cpp)
+-.Sp
+-The semantics of this option will change if \*(L"cc1\*(R", \*(L"cc1plus\*(R", and
+-\&\*(L"cc1obj\*(R" are merged.
+-.IP "\fB\-traditional\fR" 4
+-.IX Item "-traditional"
+-.PD 0
+-.IP "\fB\-traditional\-cpp\fR" 4
+-.IX Item "-traditional-cpp"
+-.PD
+-Formerly, these options caused \s-1GCC\s0 to attempt to emulate a pre-standard
+-C compiler. They are now only supported with the \fB\-E\fR switch.
+-The preprocessor continues to support a pre-standard mode. See the \s-1GNU\s0
+-\&\s-1CPP\s0 manual for details.
+-.IP "\fB\-fcond\-mismatch\fR" 4
+-.IX Item "-fcond-mismatch"
+-Allow conditional expressions with mismatched types in the second and
+-third arguments. The value of such an expression is void. This option
+-is not supported for \*(C+.
+-.IP "\fB\-funsigned\-char\fR" 4
+-.IX Item "-funsigned-char"
+-Let the type \f(CW\*(C`char\*(C'\fR be unsigned, like \f(CW\*(C`unsigned char\*(C'\fR.
+-.Sp
+-Each kind of machine has a default for what \f(CW\*(C`char\*(C'\fR should
+-be. It is either like \f(CW\*(C`unsigned char\*(C'\fR by default or like
+-\&\f(CW\*(C`signed char\*(C'\fR by default.
+-.Sp
+-Ideally, a portable program should always use \f(CW\*(C`signed char\*(C'\fR or
+-\&\f(CW\*(C`unsigned char\*(C'\fR when it depends on the signedness of an object.
+-But many programs have been written to use plain \f(CW\*(C`char\*(C'\fR and
+-expect it to be signed, or expect it to be unsigned, depending on the
+-machines they were written for. This option, and its inverse, let you
+-make such a program work with the opposite default.
+-.Sp
+-The type \f(CW\*(C`char\*(C'\fR is always a distinct type from each of
+-\&\f(CW\*(C`signed char\*(C'\fR or \f(CW\*(C`unsigned char\*(C'\fR, even though its behavior
+-is always just like one of those two.
+-.IP "\fB\-fsigned\-char\fR" 4
+-.IX Item "-fsigned-char"
+-Let the type \f(CW\*(C`char\*(C'\fR be signed, like \f(CW\*(C`signed char\*(C'\fR.
+-.Sp
+-Note that this is equivalent to \fB\-fno\-unsigned\-char\fR, which is
+-the negative form of \fB\-funsigned\-char\fR. Likewise, the option
+-\&\fB\-fno\-signed\-char\fR is equivalent to \fB\-funsigned\-char\fR.
+-.IP "\fB\-fsigned\-bitfields\fR" 4
+-.IX Item "-fsigned-bitfields"
+-.PD 0
+-.IP "\fB\-funsigned\-bitfields\fR" 4
+-.IX Item "-funsigned-bitfields"
+-.IP "\fB\-fno\-signed\-bitfields\fR" 4
+-.IX Item "-fno-signed-bitfields"
+-.IP "\fB\-fno\-unsigned\-bitfields\fR" 4
+-.IX Item "-fno-unsigned-bitfields"
+-.PD
+-These options control whether a bit-field is signed or unsigned, when the
+-declaration does not use either \f(CW\*(C`signed\*(C'\fR or \f(CW\*(C`unsigned\*(C'\fR. By
+-default, such a bit-field is signed, because this is consistent: the
+-basic integer types such as \f(CW\*(C`int\*(C'\fR are signed types.
+-.IP "\fB\-fwritable\-strings\fR" 4
+-.IX Item "-fwritable-strings"
+-Store string constants in the writable data segment and don't uniquize
+-them. This is for compatibility with old programs which assume they can
+-write into string constants.
+-.Sp
+-Writing into string constants is a very bad idea; ``constants'' should
+-be constant.
+-.Sh "Options Controlling \*(C+ Dialect"
+-.IX Subsection "Options Controlling Dialect"
+-This section describes the command-line options that are only meaningful
+-for \*(C+ programs; but you can also use most of the \s-1GNU\s0 compiler options
+-regardless of what language your program is in. For example, you
+-might compile a file \f(CW\*(C`firstClass.C\*(C'\fR like this:
+-.PP
+-.Vb 1
+-\& g++ -g -frepo -O -c firstClass.C
+-.Ve
+-.PP
+-In this example, only \fB\-frepo\fR is an option meant
+-only for \*(C+ programs; you can use the other options with any
+-language supported by \s-1GCC\s0.
+-.PP
+-Here is a list of options that are \fIonly\fR for compiling \*(C+ programs:
+-.IP "\fB\-fabi\-version=\fR\fIn\fR" 4
+-.IX Item "-fabi-version=n"
+-Use version \fIn\fR of the \*(C+ \s-1ABI\s0. Version 1 is the version of the \*(C+
+-\&\s-1ABI\s0 that first appeared in G++ 3.2. Version 0 will always be the
+-version that conforms most closely to the \*(C+ \s-1ABI\s0 specification.
+-Therefore, the \s-1ABI\s0 obtained using version 0 will change as \s-1ABI\s0 bugs are
+-fixed.
+-.Sp
+-The default is version 1.
+-.IP "\fB\-fno\-access\-control\fR" 4
+-.IX Item "-fno-access-control"
+-Turn off all access checking. This switch is mainly useful for working
+-around bugs in the access control code.
+-.IP "\fB\-fcheck\-new\fR" 4
+-.IX Item "-fcheck-new"
+-Check that the pointer returned by \f(CW\*(C`operator new\*(C'\fR is non-null
+-before attempting to modify the storage allocated. This check is
+-normally unnecessary because the \*(C+ standard specifies that
+-\&\f(CW\*(C`operator new\*(C'\fR will only return \f(CW0\fR if it is declared
+-\&\fB\f(BIthrow()\fB\fR, in which case the compiler will always check the
+-return value even without this option. In all other cases, when
+-\&\f(CW\*(C`operator new\*(C'\fR has a non-empty exception specification, memory
+-exhaustion is signalled by throwing \f(CW\*(C`std::bad_alloc\*(C'\fR. See also
+-\&\fBnew (nothrow)\fR.
+-.IP "\fB\-fconserve\-space\fR" 4
+-.IX Item "-fconserve-space"
+-Put uninitialized or runtime-initialized global variables into the
+-common segment, as C does. This saves space in the executable at the
+-cost of not diagnosing duplicate definitions. If you compile with this
+-flag and your program mysteriously crashes after \f(CW\*(C`main()\*(C'\fR has
+-completed, you may have an object that is being destroyed twice because
+-two definitions were merged.
+-.Sp
+-This option is no longer useful on most targets, now that support has
+-been added for putting variables into \s-1BSS\s0 without making them common.
+-.IP "\fB\-fno\-const\-strings\fR" 4
+-.IX Item "-fno-const-strings"
+-Give string constants type \f(CW\*(C`char *\*(C'\fR instead of type \f(CW\*(C`const
+-char *\*(C'\fR. By default, G++ uses type \f(CW\*(C`const char *\*(C'\fR as required by
+-the standard. Even if you use \fB\-fno\-const\-strings\fR, you cannot
+-actually modify the value of a string constant, unless you also use
+-\&\fB\-fwritable\-strings\fR.
+-.Sp
+-This option might be removed in a future release of G++. For maximum
+-portability, you should structure your code so that it works with
+-string constants that have type \f(CW\*(C`const char *\*(C'\fR.
+-.IP "\fB\-fdollars\-in\-identifiers\fR" 4
+-.IX Item "-fdollars-in-identifiers"
+-Accept \fB$\fR in identifiers. You can also explicitly prohibit use of
+-\&\fB$\fR with the option \fB\-fno\-dollars\-in\-identifiers\fR. (\s-1GNU\s0 C allows
+-\&\fB$\fR by default on most target systems, but there are a few exceptions.)
+-Traditional C allowed the character \fB$\fR to form part of
+-identifiers. However, \s-1ISO\s0 C and \*(C+ forbid \fB$\fR in identifiers.
+-.IP "\fB\-fno\-elide\-constructors\fR" 4
+-.IX Item "-fno-elide-constructors"
+-The \*(C+ standard allows an implementation to omit creating a temporary
+-which is only used to initialize another object of the same type.
+-Specifying this option disables that optimization, and forces G++ to
+-call the copy constructor in all cases.
+-.IP "\fB\-fno\-enforce\-eh\-specs\fR" 4
+-.IX Item "-fno-enforce-eh-specs"
+-Don't check for violation of exception specifications at runtime. This
+-option violates the \*(C+ standard, but may be useful for reducing code
+-size in production builds, much like defining \fB\s-1NDEBUG\s0\fR. The compiler
+-will still optimize based on the exception specifications.
+-.IP "\fB\-fexternal\-templates\fR" 4
+-.IX Item "-fexternal-templates"
+-Cause \fB#pragma interface\fR and \fBimplementation\fR to apply to
+-template instantiation; template instances are emitted or not according
+-to the location of the template definition.
+-.Sp
+-This option is deprecated.
+-.IP "\fB\-falt\-external\-templates\fR" 4
+-.IX Item "-falt-external-templates"
+-Similar to \fB\-fexternal\-templates\fR, but template instances are
+-emitted or not according to the place where they are first instantiated.
+-.Sp
+-This option is deprecated.
+-.IP "\fB\-ffor\-scope\fR" 4
+-.IX Item "-ffor-scope"
+-.PD 0
+-.IP "\fB\-fno\-for\-scope\fR" 4
+-.IX Item "-fno-for-scope"
+-.PD
+-If \fB\-ffor\-scope\fR is specified, the scope of variables declared in
+-a \fIfor-init-statement\fR is limited to the \fBfor\fR loop itself,
+-as specified by the \*(C+ standard.
+-If \fB\-fno\-for\-scope\fR is specified, the scope of variables declared in
+-a \fIfor-init-statement\fR extends to the end of the enclosing scope,
+-as was the case in old versions of G++, and other (traditional)
+-implementations of \*(C+.
+-.Sp
+-The default if neither flag is given to follow the standard,
+-but to allow and give a warning for old-style code that would
+-otherwise be invalid, or have different behavior.
+-.IP "\fB\-fno\-gnu\-keywords\fR" 4
+-.IX Item "-fno-gnu-keywords"
+-Do not recognize \f(CW\*(C`typeof\*(C'\fR as a keyword, so that code can use this
+-word as an identifier. You can use the keyword \f(CW\*(C`_\|_typeof_\|_\*(C'\fR instead.
+-\&\fB\-ansi\fR implies \fB\-fno\-gnu\-keywords\fR.
+-.IP "\fB\-fno\-implicit\-templates\fR" 4
+-.IX Item "-fno-implicit-templates"
+-Never emit code for non-inline templates which are instantiated
+-implicitly (i.e. by use); only emit code for explicit instantiations.
+-.IP "\fB\-fno\-implicit\-inline\-templates\fR" 4
+-.IX Item "-fno-implicit-inline-templates"
+-Don't emit code for implicit instantiations of inline templates, either.
+-The default is to handle inlines differently so that compiles with and
+-without optimization will need the same set of explicit instantiations.
+-.IP "\fB\-fno\-implement\-inlines\fR" 4
+-.IX Item "-fno-implement-inlines"
+-To save space, do not emit out-of-line copies of inline functions
+-controlled by \fB#pragma implementation\fR. This will cause linker
+-errors if these functions are not inlined everywhere they are called.
+-.IP "\fB\-fms\-extensions\fR" 4
+-.IX Item "-fms-extensions"
+-Disable pedantic warnings about constructs used in \s-1MFC\s0, such as implicit
+-int and getting a pointer to member function via non-standard syntax.
+-.IP "\fB\-fno\-nonansi\-builtins\fR" 4
+-.IX Item "-fno-nonansi-builtins"
+-Disable built-in declarations of functions that are not mandated by
+-\&\s-1ANSI/ISO\s0 C. These include \f(CW\*(C`ffs\*(C'\fR, \f(CW\*(C`alloca\*(C'\fR, \f(CW\*(C`_exit\*(C'\fR,
+-\&\f(CW\*(C`index\*(C'\fR, \f(CW\*(C`bzero\*(C'\fR, \f(CW\*(C`conjf\*(C'\fR, and other related functions.
+-.IP "\fB\-fno\-operator\-names\fR" 4
+-.IX Item "-fno-operator-names"
+-Do not treat the operator name keywords \f(CW\*(C`and\*(C'\fR, \f(CW\*(C`bitand\*(C'\fR,
+-\&\f(CW\*(C`bitor\*(C'\fR, \f(CW\*(C`compl\*(C'\fR, \f(CW\*(C`not\*(C'\fR, \f(CW\*(C`or\*(C'\fR and \f(CW\*(C`xor\*(C'\fR as
+-synonyms as keywords.
+-.IP "\fB\-fno\-optional\-diags\fR" 4
+-.IX Item "-fno-optional-diags"
+-Disable diagnostics that the standard says a compiler does not need to
+-issue. Currently, the only such diagnostic issued by G++ is the one for
+-a name having multiple meanings within a class.
+-.IP "\fB\-fpermissive\fR" 4
+-.IX Item "-fpermissive"
+-Downgrade some diagnostics about nonconformant code from errors to
+-warnings. Thus, using \fB\-fpermissive\fR will allow some
+-nonconforming code to compile.
+-.IP "\fB\-frepo\fR" 4
+-.IX Item "-frepo"
+-Enable automatic template instantiation at link time. This option also
+-implies \fB\-fno\-implicit\-templates\fR.
+-.IP "\fB\-fno\-rtti\fR" 4
+-.IX Item "-fno-rtti"
+-Disable generation of information about every class with virtual
+-functions for use by the \*(C+ runtime type identification features
+-(\fBdynamic_cast\fR and \fBtypeid\fR). If you don't use those parts
+-of the language, you can save some space by using this flag. Note that
+-exception handling uses the same information, but it will generate it as
+-needed.
+-.IP "\fB\-fstats\fR" 4
+-.IX Item "-fstats"
+-Emit statistics about front-end processing at the end of the compilation.
+-This information is generally only useful to the G++ development team.
+-.IP "\fB\-ftemplate\-depth\-\fR\fIn\fR" 4
+-.IX Item "-ftemplate-depth-n"
+-Set the maximum instantiation depth for template classes to \fIn\fR.
+-A limit on the template instantiation depth is needed to detect
+-endless recursions during template class instantiation. \s-1ANSI/ISO\s0 \*(C+
+-conforming programs must not rely on a maximum depth greater than 17.
+-.IP "\fB\-fuse\-cxa\-atexit\fR" 4
+-.IX Item "-fuse-cxa-atexit"
+-Register destructors for objects with static storage duration with the
+-\&\f(CW\*(C`_\|_cxa_atexit\*(C'\fR function rather than the \f(CW\*(C`atexit\*(C'\fR function.
+-This option is required for fully standards-compliant handling of static
+-destructors, but will only work if your C library supports
+-\&\f(CW\*(C`_\|_cxa_atexit\*(C'\fR.
+-.IP "\fB\-fvtable\-gc\fR" 4
+-.IX Item "-fvtable-gc"
+-Emit special relocations for vtables and virtual function references
+-so that the linker can identify unused virtual functions and zero out
+-vtable slots that refer to them. This is most useful with
+-\&\fB\-ffunction\-sections\fR and \fB\-Wl,\-\-gc\-sections\fR, in order to
+-also discard the functions themselves.
+-.Sp
+-This optimization requires \s-1GNU\s0 as and \s-1GNU\s0 ld. Not all systems support
+-this option. \fB\-Wl,\-\-gc\-sections\fR is ignored without \fB\-static\fR.
+-.IP "\fB\-fno\-weak\fR" 4
+-.IX Item "-fno-weak"
+-Do not use weak symbol support, even if it is provided by the linker.
+-By default, G++ will use weak symbols if they are available. This
+-option exists only for testing, and should not be used by end\-users;
+-it will result in inferior code and has no benefits. This option may
+-be removed in a future release of G++.
+-.IP "\fB\-nostdinc++\fR" 4
+-.IX Item "-nostdinc++"
+-Do not search for header files in the standard directories specific to
+-\&\*(C+, but do still search the other standard directories. (This option
+-is used when building the \*(C+ library.)
+-.PP
+-In addition, these optimization, warning, and code generation options
+-have meanings only for \*(C+ programs:
+-.IP "\fB\-fno\-default\-inline\fR" 4
+-.IX Item "-fno-default-inline"
+-Do not assume \fBinline\fR for functions defined inside a class scope.
+- Note that these
+-functions will have linkage like inline functions; they just won't be
+-inlined by default.
+-.IP "\fB\-Wabi\fR (\*(C+ only)" 4
+-.IX Item "-Wabi ( only)"
+-Warn when G++ generates code that is probably not compatible with the
+-vendor-neutral \*(C+ \s-1ABI\s0. Although an effort has been made to warn about
+-all such cases, there are probably some cases that are not warned about,
+-even though G++ is generating incompatible code. There may also be
+-cases where warnings are emitted even though the code that is generated
+-will be compatible.
+-.Sp
+-You should rewrite your code to avoid these warnings if you are
+-concerned about the fact that code generated by G++ may not be binary
+-compatible with code generated by other compilers.
+-.Sp
+-The known incompatibilities at this point include:
+-.RS 4
+-.IP "*" 4
+-Incorrect handling of tail-padding for bit\-fields. G++ may attempt to
+-pack data into the same byte as a base class. For example:
+-.Sp
+-.Vb 2
+-\& struct A { virtual void f(); int f1 : 1; };
+-\& struct B : public A { int f2 : 1; };
+-.Ve
+-.Sp
+-In this case, G++ will place \f(CW\*(C`B::f2\*(C'\fR into the same byte
+-as\f(CW\*(C`A::f1\*(C'\fR; other compilers will not. You can avoid this problem
+-by explicitly padding \f(CW\*(C`A\*(C'\fR so that its size is a multiple of the
+-byte size on your platform; that will cause G++ and other compilers to
+-layout \f(CW\*(C`B\*(C'\fR identically.
+-.IP "*" 4
+-Incorrect handling of tail-padding for virtual bases. G++ does not use
+-tail padding when laying out virtual bases. For example:
+-.Sp
+-.Vb 3
+-\& struct A { virtual void f(); char c1; };
+-\& struct B { B(); char c2; };
+-\& struct C : public A, public virtual B {};
+-.Ve
+-.Sp
+-In this case, G++ will not place \f(CW\*(C`B\*(C'\fR into the tail-padding for
+-\&\f(CW\*(C`A\*(C'\fR; other compilers will. You can avoid this problem by
+-explicitly padding \f(CW\*(C`A\*(C'\fR so that its size is a multiple of its
+-alignment (ignoring virtual base classes); that will cause G++ and other
+-compilers to layout \f(CW\*(C`C\*(C'\fR identically.
+-.IP "*" 4
+-Incorrect handling of bit-fields with declared widths greater than that
+-of their underlying types, when the bit-fields appear in a union. For
+-example:
+-.Sp
+-.Vb 1
+-\& union U { int i : 4096; };
+-.Ve
+-.Sp
+-Assuming that an \f(CW\*(C`int\*(C'\fR does not have 4096 bits, G++ will make the
+-union too small by the number of bits in an \f(CW\*(C`int\*(C'\fR.
+-.IP "*" 4
+-Empty classes can be placed at incorrect offsets. For example:
+-.Sp
+-.Vb 1
+-\& struct A {};
+-.Ve
+-.Sp
+-.Vb 4
+-\& struct B {
+-\& A a;
+-\& virtual void f ();
+-\& };
+-.Ve
+-.Sp
+-.Vb 1
+-\& struct C : public B, public A {};
+-.Ve
+-.Sp
+-G++ will place the \f(CW\*(C`A\*(C'\fR base class of \f(CW\*(C`C\*(C'\fR at a nonzero offset;
+-it should be placed at offset zero. G++ mistakenly believes that the
+-\&\f(CW\*(C`A\*(C'\fR data member of \f(CW\*(C`B\*(C'\fR is already at offset zero.
+-.IP "*" 4
+-Names of template functions whose types involve \f(CW\*(C`typename\*(C'\fR or
+-template template parameters can be mangled incorrectly.
+-.Sp
+-.Vb 2
+-\& template <typename Q>
+-\& void f(typename Q::X) {}
+-.Ve
+-.Sp
+-.Vb 2
+-\& template <template <typename> class Q>
+-\& void f(typename Q<int>::X) {}
+-.Ve
+-.Sp
+-Instantiations of these templates may be mangled incorrectly.
+-.RE
+-.RS 4
+-.RE
+-.IP "\fB\-Wctor\-dtor\-privacy\fR (\*(C+ only)" 4
+-.IX Item "-Wctor-dtor-privacy ( only)"
+-Warn when a class seems unusable because all the constructors or
+-destructors in that class are private, and it has neither friends nor
+-public static member functions. This warning is enabled by default.
+-.IP "\fB\-Wnon\-virtual\-dtor\fR (\*(C+ only)" 4
+-.IX Item "-Wnon-virtual-dtor ( only)"
+-Warn when a class appears to be polymorphic, thereby requiring a virtual
+-destructor, yet it declares a non-virtual one.
+-This warning is enabled by \fB\-Wall\fR.
+-.IP "\fB\-Wreorder\fR (\*(C+ only)" 4
+-.IX Item "-Wreorder ( only)"
+-Warn when the order of member initializers given in the code does not
+-match the order in which they must be executed. For instance:
+-.Sp
+-.Vb 5
+-\& struct A {
+-\& int i;
+-\& int j;
+-\& A(): j (0), i (1) { }
+-\& };
+-.Ve
+-.Sp
+-The compiler will rearrange the member initializers for \fBi\fR
+-and \fBj\fR to match the declaration order of the members, emitting
+-a warning to that effect. This warning is enabled by \fB\-Wall\fR.
+-.PP
+-The following \fB\-W...\fR options are not affected by \fB\-Wall\fR.
+-.IP "\fB\-Weffc++\fR (\*(C+ only)" 4
+-.IX Item "-Weffc++ ( only)"
+-Warn about violations of the following style guidelines from Scott Meyers'
+-\&\fIEffective \*(C+\fR book:
+-.RS 4
+-.IP "*" 4
+-Item 11: Define a copy constructor and an assignment operator for classes
+-with dynamically allocated memory.
+-.IP "*" 4
+-Item 12: Prefer initialization to assignment in constructors.
+-.IP "*" 4
+-Item 14: Make destructors virtual in base classes.
+-.IP "*" 4
+-Item 15: Have \f(CW\*(C`operator=\*(C'\fR return a reference to \f(CW*this\fR.
+-.IP "*" 4
+-Item 23: Don't try to return a reference when you must return an object.
+-.RE
+-.RS 4
+-.Sp
+-Also warn about violations of the following style guidelines from
+-Scott Meyers' \fIMore Effective \*(C+\fR book:
+-.IP "*" 4
+-Item 6: Distinguish between prefix and postfix forms of increment and
+-decrement operators.
+-.IP "*" 4
+-Item 7: Never overload \f(CW\*(C`&&\*(C'\fR, \f(CW\*(C`||\*(C'\fR, or \f(CW\*(C`,\*(C'\fR.
+-.RE
+-.RS 4
+-.Sp
+-When selecting this option, be aware that the standard library
+-headers do not obey all of these guidelines; use \fBgrep \-v\fR
+-to filter out those warnings.
+-.RE
+-.IP "\fB\-Wno\-deprecated\fR (\*(C+ only)" 4
+-.IX Item "-Wno-deprecated ( only)"
+-Do not warn about usage of deprecated features.
+-.IP "\fB\-Wno\-non\-template\-friend\fR (\*(C+ only)" 4
+-.IX Item "-Wno-non-template-friend ( only)"
+-Disable warnings when non-templatized friend functions are declared
+-within a template. Since the advent of explicit template specification
+-support in G++, if the name of the friend is an unqualified-id (i.e.,
+-\&\fBfriend foo(int)\fR), the \*(C+ language specification demands that the
+-friend declare or define an ordinary, nontemplate function. (Section
+-14.5.3). Before G++ implemented explicit specification, unqualified-ids
+-could be interpreted as a particular specialization of a templatized
+-function. Because this non-conforming behavior is no longer the default
+-behavior for G++, \fB\-Wnon\-template\-friend\fR allows the compiler to
+-check existing code for potential trouble spots and is on by default.
+-This new compiler behavior can be turned off with
+-\&\fB\-Wno\-non\-template\-friend\fR which keeps the conformant compiler code
+-but disables the helpful warning.
+-.IP "\fB\-Wold\-style\-cast\fR (\*(C+ only)" 4
+-.IX Item "-Wold-style-cast ( only)"
+-Warn if an old-style (C\-style) cast to a non-void type is used within
+-a \*(C+ program. The new-style casts (\fBstatic_cast\fR,
+-\&\fBreinterpret_cast\fR, and \fBconst_cast\fR) are less vulnerable to
+-unintended effects and much easier to search for.
+-.IP "\fB\-Woverloaded\-virtual\fR (\*(C+ only)" 4
+-.IX Item "-Woverloaded-virtual ( only)"
+-Warn when a function declaration hides virtual functions from a
+-base class. For example, in:
+-.Sp
+-.Vb 3
+-\& struct A {
+-\& virtual void f();
+-\& };
+-.Ve
+-.Sp
+-.Vb 3
+-\& struct B: public A {
+-\& void f(int);
+-\& };
+-.Ve
+-.Sp
+-the \f(CW\*(C`A\*(C'\fR class version of \f(CW\*(C`f\*(C'\fR is hidden in \f(CW\*(C`B\*(C'\fR, and code
+-like:
+-.Sp
+-.Vb 2
+-\& B* b;
+-\& b->f();
+-.Ve
+-.Sp
+-will fail to compile.
+-.IP "\fB\-Wno\-pmf\-conversions\fR (\*(C+ only)" 4
+-.IX Item "-Wno-pmf-conversions ( only)"
+-Disable the diagnostic for converting a bound pointer to member function
+-to a plain pointer.
+-.IP "\fB\-Wsign\-promo\fR (\*(C+ only)" 4
+-.IX Item "-Wsign-promo ( only)"
+-Warn when overload resolution chooses a promotion from unsigned or
+-enumeral type to a signed type, over a conversion to an unsigned type of
+-the same size. Previous versions of G++ would try to preserve
+-unsignedness, but the standard mandates the current behavior.
+-.Sh "Options Controlling Objective-C Dialect"
+-.IX Subsection "Options Controlling Objective-C Dialect"
+-This section describes the command-line options that are only meaningful
+-for Objective-C programs, but you can also use most of the \s-1GNU\s0 compiler
+-options regardless of what language your program is in. For example,
+-you might compile a file \f(CW\*(C`some_class.m\*(C'\fR like this:
+-.PP
+-.Vb 1
+-\& gcc -g -fgnu-runtime -O -c some_class.m
+-.Ve
+-.PP
+-In this example, \fB\-fgnu\-runtime\fR is an option meant only for
+-Objective-C programs; you can use the other options with any language
+-supported by \s-1GCC\s0.
+-.PP
+-Here is a list of options that are \fIonly\fR for compiling Objective-C
+-programs:
+-.IP "\fB\-fconstant\-string\-class=\fR\fIclass-name\fR" 4
+-.IX Item "-fconstant-string-class=class-name"
+-Use \fIclass-name\fR as the name of the class to instantiate for each
+-literal string specified with the syntax \f(CW\*(C`@"..."\*(C'\fR. The default
+-class name is \f(CW\*(C`NXConstantString\*(C'\fR.
+-.IP "\fB\-fgnu\-runtime\fR" 4
+-.IX Item "-fgnu-runtime"
+-Generate object code compatible with the standard \s-1GNU\s0 Objective-C
+-runtime. This is the default for most types of systems.
+-.IP "\fB\-fnext\-runtime\fR" 4
+-.IX Item "-fnext-runtime"
+-Generate output compatible with the NeXT runtime. This is the default
+-for NeXT-based systems, including Darwin and Mac \s-1OS\s0 X. The macro
+-\&\f(CW\*(C`_\|_NEXT_RUNTIME_\|_\*(C'\fR is predefined if (and only if) this option is
+-used.
+-.IP "\fB\-gen\-decls\fR" 4
+-.IX Item "-gen-decls"
+-Dump interface declarations for all classes seen in the source file to a
+-file named \fI\fIsourcename\fI.decl\fR.
+-.IP "\fB\-Wno\-protocol\fR" 4
+-.IX Item "-Wno-protocol"
+-If a class is declared to implement a protocol, a warning is issued for
+-every method in the protocol that is not implemented by the class. The
+-default behavior is to issue a warning for every method not explicitly
+-implemented in the class, even if a method implementation is inherited
+-from the superclass. If you use the \f(CW\*(C`\-Wno\-protocol\*(C'\fR option, then
+-methods inherited from the superclass are considered to be implemented,
+-and no warning is issued for them.
+-.IP "\fB\-Wselector\fR" 4
+-.IX Item "-Wselector"
+-Warn if multiple methods of different types for the same selector are
+-found during compilation. The check is performed on the list of methods
+-in the final stage of compilation. Additionally, a check is performed
+-for each selector appearing in a \f(CW\*(C`@selector(...)\*(C'\fR
+-expression, and a corresponding method for that selector has been found
+-during compilation. Because these checks scan the method table only at
+-the end of compilation, these warnings are not produced if the final
+-stage of compilation is not reached, for example because an error is
+-found during compilation, or because the \f(CW\*(C`\-fsyntax\-only\*(C'\fR option is
+-being used.
+-.IP "\fB\-Wundeclared\-selector\fR" 4
+-.IX Item "-Wundeclared-selector"
+-Warn if a \f(CW\*(C`@selector(...)\*(C'\fR expression referring to an
+-undeclared selector is found. A selector is considered undeclared if no
+-method with that name has been declared before the
+-\&\f(CW\*(C`@selector(...)\*(C'\fR expression, either explicitly in an
+-\&\f(CW@interface\fR or \f(CW@protocol\fR declaration, or implicitly in
+-an \f(CW@implementation\fR section. This option always performs its
+-checks as soon as a \f(CW\*(C`@selector(...)\*(C'\fR expression is found,
+-while \f(CW\*(C`\-Wselector\*(C'\fR only performs its checks in the final stage of
+-compilation. This also enforces the coding style convention
+-that methods and selectors must be declared before being used.
+-.Sh "Options to Control Diagnostic Messages Formatting"
+-.IX Subsection "Options to Control Diagnostic Messages Formatting"
+-Traditionally, diagnostic messages have been formatted irrespective of
+-the output device's aspect (e.g. its width, ...). The options described
+-below can be used to control the diagnostic messages formatting
+-algorithm, e.g. how many characters per line, how often source location
+-information should be reported. Right now, only the \*(C+ front end can
+-honor these options. However it is expected, in the near future, that
+-the remaining front ends would be able to digest them correctly.
+-.IP "\fB\-fmessage\-length=\fR\fIn\fR" 4
+-.IX Item "-fmessage-length=n"
+-Try to format error messages so that they fit on lines of about \fIn\fR
+-characters. The default is 72 characters for \fBg++\fR and 0 for the rest of
+-the front ends supported by \s-1GCC\s0. If \fIn\fR is zero, then no
+-line-wrapping will be done; each error message will appear on a single
+-line.
+-.IP "\fB\-fdiagnostics\-show\-location=once\fR" 4
+-.IX Item "-fdiagnostics-show-location=once"
+-Only meaningful in line-wrapping mode. Instructs the diagnostic messages
+-reporter to emit \fIonce\fR source location information; that is, in
+-case the message is too long to fit on a single physical line and has to
+-be wrapped, the source location won't be emitted (as prefix) again,
+-over and over, in subsequent continuation lines. This is the default
+-behavior.
+-.IP "\fB\-fdiagnostics\-show\-location=every\-line\fR" 4
+-.IX Item "-fdiagnostics-show-location=every-line"
+-Only meaningful in line-wrapping mode. Instructs the diagnostic
+-messages reporter to emit the same source location information (as
+-prefix) for physical lines that result from the process of breaking
+-a message which is too long to fit on a single line.
+-.Sh "Options to Request or Suppress Warnings"
+-.IX Subsection "Options to Request or Suppress Warnings"
+-Warnings are diagnostic messages that report constructions which
+-are not inherently erroneous but which are risky or suggest there
+-may have been an error.
+-.PP
+-You can request many specific warnings with options beginning \fB\-W\fR,
+-for example \fB\-Wimplicit\fR to request warnings on implicit
+-declarations. Each of these specific warning options also has a
+-negative form beginning \fB\-Wno\-\fR to turn off warnings;
+-for example, \fB\-Wno\-implicit\fR. This manual lists only one of the
+-two forms, whichever is not the default.
+-.PP
+-The following options control the amount and kinds of warnings produced
+-by \s-1GCC\s0; for further, language-specific options also refer to
+-\&\fB\*(C+ Dialect Options\fR and \fBObjective-C Dialect Options\fR.
+-.IP "\fB\-fsyntax\-only\fR" 4
+-.IX Item "-fsyntax-only"
+-Check the code for syntax errors, but don't do anything beyond that.
+-.IP "\fB\-pedantic\fR" 4
+-.IX Item "-pedantic"
+-Issue all the warnings demanded by strict \s-1ISO\s0 C and \s-1ISO\s0 \*(C+;
+-reject all programs that use forbidden extensions, and some other
+-programs that do not follow \s-1ISO\s0 C and \s-1ISO\s0 \*(C+. For \s-1ISO\s0 C, follows the
+-version of the \s-1ISO\s0 C standard specified by any \fB\-std\fR option used.
+-.Sp
+-Valid \s-1ISO\s0 C and \s-1ISO\s0 \*(C+ programs should compile properly with or without
+-this option (though a rare few will require \fB\-ansi\fR or a
+-\&\fB\-std\fR option specifying the required version of \s-1ISO\s0 C). However,
+-without this option, certain \s-1GNU\s0 extensions and traditional C and \*(C+
+-features are supported as well. With this option, they are rejected.
+-.Sp
+-\&\fB\-pedantic\fR does not cause warning messages for use of the
+-alternate keywords whose names begin and end with \fB_\|_\fR. Pedantic
+-warnings are also disabled in the expression that follows
+-\&\f(CW\*(C`_\|_extension_\|_\*(C'\fR. However, only system header files should use
+-these escape routes; application programs should avoid them.
+-.Sp
+-Some users try to use \fB\-pedantic\fR to check programs for strict \s-1ISO\s0
+-C conformance. They soon find that it does not do quite what they want:
+-it finds some non-ISO practices, but not all\-\-\-only those for which
+-\&\s-1ISO\s0 C \fIrequires\fR a diagnostic, and some others for which
+-diagnostics have been added.
+-.Sp
+-A feature to report any failure to conform to \s-1ISO\s0 C might be useful in
+-some instances, but would require considerable additional work and would
+-be quite different from \fB\-pedantic\fR. We don't have plans to
+-support such a feature in the near future.
+-.Sp
+-Where the standard specified with \fB\-std\fR represents a \s-1GNU\s0
+-extended dialect of C, such as \fBgnu89\fR or \fBgnu99\fR, there is a
+-corresponding \fIbase standard\fR, the version of \s-1ISO\s0 C on which the \s-1GNU\s0
+-extended dialect is based. Warnings from \fB\-pedantic\fR are given
+-where they are required by the base standard. (It would not make sense
+-for such warnings to be given only for features not in the specified \s-1GNU\s0
+-C dialect, since by definition the \s-1GNU\s0 dialects of C include all
+-features the compiler supports with the given option, and there would be
+-nothing to warn about.)
+-.IP "\fB\-pedantic\-errors\fR" 4
+-.IX Item "-pedantic-errors"
+-Like \fB\-pedantic\fR, except that errors are produced rather than
+-warnings.
+-.IP "\fB\-w\fR" 4
+-.IX Item "-w"
+-Inhibit all warning messages.
+-.IP "\fB\-Wno\-import\fR" 4
+-.IX Item "-Wno-import"
+-Inhibit warning messages about the use of \fB#import\fR.
+-.IP "\fB\-Wchar\-subscripts\fR" 4
+-.IX Item "-Wchar-subscripts"
+-Warn if an array subscript has type \f(CW\*(C`char\*(C'\fR. This is a common cause
+-of error, as programmers often forget that this type is signed on some
+-machines.
+-.IP "\fB\-Wcomment\fR" 4
+-.IX Item "-Wcomment"
+-Warn whenever a comment-start sequence \fB/*\fR appears in a \fB/*\fR
+-comment, or whenever a Backslash-Newline appears in a \fB//\fR comment.
+-.IP "\fB\-Wformat\fR" 4
+-.IX Item "-Wformat"
+-Check calls to \f(CW\*(C`printf\*(C'\fR and \f(CW\*(C`scanf\*(C'\fR, etc., to make sure that
+-the arguments supplied have types appropriate to the format string
+-specified, and that the conversions specified in the format string make
+-sense. This includes standard functions, and others specified by format
+-attributes, in the \f(CW\*(C`printf\*(C'\fR,
+-\&\f(CW\*(C`scanf\*(C'\fR, \f(CW\*(C`strftime\*(C'\fR and \f(CW\*(C`strfmon\*(C'\fR (an X/Open extension,
+-not in the C standard) families.
+-.Sp
+-The formats are checked against the format features supported by \s-1GNU\s0
+-libc version 2.2. These include all \s-1ISO\s0 C90 and C99 features, as well
+-as features from the Single Unix Specification and some \s-1BSD\s0 and \s-1GNU\s0
+-extensions. Other library implementations may not support all these
+-features; \s-1GCC\s0 does not support warning about features that go beyond a
+-particular library's limitations. However, if \fB\-pedantic\fR is used
+-with \fB\-Wformat\fR, warnings will be given about format features not
+-in the selected standard version (but not for \f(CW\*(C`strfmon\*(C'\fR formats,
+-since those are not in any version of the C standard).
+-.Sp
+-Since \fB\-Wformat\fR also checks for null format arguments for
+-several functions, \fB\-Wformat\fR also implies \fB\-Wnonnull\fR.
+-.Sp
+-\&\fB\-Wformat\fR is included in \fB\-Wall\fR. For more control over some
+-aspects of format checking, the options \fB\-Wno\-format\-y2k\fR,
+-\&\fB\-Wno\-format\-extra\-args\fR, \fB\-Wno\-format\-zero\-length\fR,
+-\&\fB\-Wformat\-nonliteral\fR, \fB\-Wformat\-security\fR, and
+-\&\fB\-Wformat=2\fR are available, but are not included in \fB\-Wall\fR.
+-.IP "\fB\-Wno\-format\-y2k\fR" 4
+-.IX Item "-Wno-format-y2k"
+-If \fB\-Wformat\fR is specified, do not warn about \f(CW\*(C`strftime\*(C'\fR
+-formats which may yield only a two-digit year.
+-.IP "\fB\-Wno\-format\-extra\-args\fR" 4
+-.IX Item "-Wno-format-extra-args"
+-If \fB\-Wformat\fR is specified, do not warn about excess arguments to a
+-\&\f(CW\*(C`printf\*(C'\fR or \f(CW\*(C`scanf\*(C'\fR format function. The C standard specifies
+-that such arguments are ignored.
+-.Sp
+-Where the unused arguments lie between used arguments that are
+-specified with \fB$\fR operand number specifications, normally
+-warnings are still given, since the implementation could not know what
+-type to pass to \f(CW\*(C`va_arg\*(C'\fR to skip the unused arguments. However,
+-in the case of \f(CW\*(C`scanf\*(C'\fR formats, this option will suppress the
+-warning if the unused arguments are all pointers, since the Single
+-Unix Specification says that such unused arguments are allowed.
+-.IP "\fB\-Wno\-format\-zero\-length\fR" 4
+-.IX Item "-Wno-format-zero-length"
+-If \fB\-Wformat\fR is specified, do not warn about zero-length formats.
+-The C standard specifies that zero-length formats are allowed.
+-.IP "\fB\-Wformat\-nonliteral\fR" 4
+-.IX Item "-Wformat-nonliteral"
+-If \fB\-Wformat\fR is specified, also warn if the format string is not a
+-string literal and so cannot be checked, unless the format function
+-takes its format arguments as a \f(CW\*(C`va_list\*(C'\fR.
+-.IP "\fB\-Wformat\-security\fR" 4
+-.IX Item "-Wformat-security"
+-If \fB\-Wformat\fR is specified, also warn about uses of format
+-functions that represent possible security problems. At present, this
+-warns about calls to \f(CW\*(C`printf\*(C'\fR and \f(CW\*(C`scanf\*(C'\fR functions where the
+-format string is not a string literal and there are no format arguments,
+-as in \f(CW\*(C`printf (foo);\*(C'\fR. This may be a security hole if the format
+-string came from untrusted input and contains \fB%n\fR. (This is
+-currently a subset of what \fB\-Wformat\-nonliteral\fR warns about, but
+-in future warnings may be added to \fB\-Wformat\-security\fR that are not
+-included in \fB\-Wformat\-nonliteral\fR.)
+-.IP "\fB\-Wformat=2\fR" 4
+-.IX Item "-Wformat=2"
+-Enable \fB\-Wformat\fR plus format checks not included in
+-\&\fB\-Wformat\fR. Currently equivalent to \fB\-Wformat
+-\&\-Wformat\-nonliteral \-Wformat\-security\fR.
+-.IP "\fB\-Wnonnull\fR" 4
+-.IX Item "-Wnonnull"
+-Warn about passing a null pointer for arguments marked as
+-requiring a non-null value by the \f(CW\*(C`nonnull\*(C'\fR function attribute.
+-.Sp
+-\&\fB\-Wnonnull\fR is included in \fB\-Wall\fR and \fB\-Wformat\fR. It
+-can be disabled with the \fB\-Wno\-nonnull\fR option.
+-.IP "\fB\-Wimplicit\-int\fR" 4
+-.IX Item "-Wimplicit-int"
+-Warn when a declaration does not specify a type.
+-.IP "\fB\-Wimplicit\-function\-declaration\fR" 4
+-.IX Item "-Wimplicit-function-declaration"
+-.PD 0
+-.IP "\fB\-Werror\-implicit\-function\-declaration\fR" 4
+-.IX Item "-Werror-implicit-function-declaration"
+-.PD
+-Give a warning (or error) whenever a function is used before being
+-declared.
+-.IP "\fB\-Wimplicit\fR" 4
+-.IX Item "-Wimplicit"
+-Same as \fB\-Wimplicit\-int\fR and \fB\-Wimplicit\-function\-declaration\fR.
+-.IP "\fB\-Wmain\fR" 4
+-.IX Item "-Wmain"
+-Warn if the type of \fBmain\fR is suspicious. \fBmain\fR should be a
+-function with external linkage, returning int, taking either zero
+-arguments, two, or three arguments of appropriate types.
+-.IP "\fB\-Wmissing\-braces\fR" 4
+-.IX Item "-Wmissing-braces"
+-Warn if an aggregate or union initializer is not fully bracketed. In
+-the following example, the initializer for \fBa\fR is not fully
+-bracketed, but that for \fBb\fR is fully bracketed.
+-.Sp
+-.Vb 2
+-\& int a[2][2] = { 0, 1, 2, 3 };
+-\& int b[2][2] = { { 0, 1 }, { 2, 3 } };
+-.Ve
+-.IP "\fB\-Wparentheses\fR" 4
+-.IX Item "-Wparentheses"
+-Warn if parentheses are omitted in certain contexts, such
+-as when there is an assignment in a context where a truth value
+-is expected, or when operators are nested whose precedence people
+-often get confused about.
+-.Sp
+-Also warn about constructions where there may be confusion to which
+-\&\f(CW\*(C`if\*(C'\fR statement an \f(CW\*(C`else\*(C'\fR branch belongs. Here is an example of
+-such a case:
+-.Sp
+-.Vb 7
+-\& {
+-\& if (a)
+-\& if (b)
+-\& foo ();
+-\& else
+-\& bar ();
+-\& }
+-.Ve
+-.Sp
+-In C, every \f(CW\*(C`else\*(C'\fR branch belongs to the innermost possible \f(CW\*(C`if\*(C'\fR
+-statement, which in this example is \f(CW\*(C`if (b)\*(C'\fR. This is often not
+-what the programmer expected, as illustrated in the above example by
+-indentation the programmer chose. When there is the potential for this
+-confusion, \s-1GCC\s0 will issue a warning when this flag is specified.
+-To eliminate the warning, add explicit braces around the innermost
+-\&\f(CW\*(C`if\*(C'\fR statement so there is no way the \f(CW\*(C`else\*(C'\fR could belong to
+-the enclosing \f(CW\*(C`if\*(C'\fR. The resulting code would look like this:
+-.Sp
+-.Vb 9
+-\& {
+-\& if (a)
+-\& {
+-\& if (b)
+-\& foo ();
+-\& else
+-\& bar ();
+-\& }
+-\& }
+-.Ve
+-.IP "\fB\-Wsequence\-point\fR" 4
+-.IX Item "-Wsequence-point"
+-Warn about code that may have undefined semantics because of violations
+-of sequence point rules in the C standard.
+-.Sp
+-The C standard defines the order in which expressions in a C program are
+-evaluated in terms of \fIsequence points\fR, which represent a partial
+-ordering between the execution of parts of the program: those executed
+-before the sequence point, and those executed after it. These occur
+-after the evaluation of a full expression (one which is not part of a
+-larger expression), after the evaluation of the first operand of a
+-\&\f(CW\*(C`&&\*(C'\fR, \f(CW\*(C`||\*(C'\fR, \f(CW\*(C`? :\*(C'\fR or \f(CW\*(C`,\*(C'\fR (comma) operator, before a
+-function is called (but after the evaluation of its arguments and the
+-expression denoting the called function), and in certain other places.
+-Other than as expressed by the sequence point rules, the order of
+-evaluation of subexpressions of an expression is not specified. All
+-these rules describe only a partial order rather than a total order,
+-since, for example, if two functions are called within one expression
+-with no sequence point between them, the order in which the functions
+-are called is not specified. However, the standards committee have
+-ruled that function calls do not overlap.
+-.Sp
+-It is not specified when between sequence points modifications to the
+-values of objects take effect. Programs whose behavior depends on this
+-have undefined behavior; the C standard specifies that ``Between the
+-previous and next sequence point an object shall have its stored value
+-modified at most once by the evaluation of an expression. Furthermore,
+-the prior value shall be read only to determine the value to be
+-stored.''. If a program breaks these rules, the results on any
+-particular implementation are entirely unpredictable.
+-.Sp
+-Examples of code with undefined behavior are \f(CW\*(C`a = a++;\*(C'\fR, \f(CW\*(C`a[n]
+-= b[n++]\*(C'\fR and \f(CW\*(C`a[i++] = i;\*(C'\fR. Some more complicated cases are not
+-diagnosed by this option, and it may give an occasional false positive
+-result, but in general it has been found fairly effective at detecting
+-this sort of problem in programs.
+-.Sp
+-The present implementation of this option only works for C programs. A
+-future implementation may also work for \*(C+ programs.
+-.Sp
+-The C standard is worded confusingly, therefore there is some debate
+-over the precise meaning of the sequence point rules in subtle cases.
+-Links to discussions of the problem, including proposed formal
+-definitions, may be found on our readings page, at
+-<\fBhttp://gcc.gnu.org/readings.html\fR>.
+-.IP "\fB\-Wreturn\-type\fR" 4
+-.IX Item "-Wreturn-type"
+-Warn whenever a function is defined with a return-type that defaults to
+-\&\f(CW\*(C`int\*(C'\fR. Also warn about any \f(CW\*(C`return\*(C'\fR statement with no
+-return-value in a function whose return-type is not \f(CW\*(C`void\*(C'\fR.
+-.Sp
+-For \*(C+, a function without return type always produces a diagnostic
+-message, even when \fB\-Wno\-return\-type\fR is specified. The only
+-exceptions are \fBmain\fR and functions defined in system headers.
+-.IP "\fB\-Wswitch\fR" 4
+-.IX Item "-Wswitch"
+-Warn whenever a \f(CW\*(C`switch\*(C'\fR statement has an index of enumeral type
+-and lacks a \f(CW\*(C`case\*(C'\fR for one or more of the named codes of that
+-enumeration. (The presence of a \f(CW\*(C`default\*(C'\fR label prevents this
+-warning.) \f(CW\*(C`case\*(C'\fR labels outside the enumeration range also
+-provoke warnings when this option is used.
+-.IP "\fB\-Wswitch\-default\fR" 4
+-.IX Item "-Wswitch-default"
+-Warn whenever a \f(CW\*(C`switch\*(C'\fR statement does not have a \f(CW\*(C`default\*(C'\fR
+-case.
+-.IP "\fB\-Wswitch\-enum\fR" 4
+-.IX Item "-Wswitch-enum"
+-Warn whenever a \f(CW\*(C`switch\*(C'\fR statement has an index of enumeral type
+-and lacks a \f(CW\*(C`case\*(C'\fR for one or more of the named codes of that
+-enumeration. \f(CW\*(C`case\*(C'\fR labels outside the enumeration range also
+-provoke warnings when this option is used.
+-.IP "\fB\-Wtrigraphs\fR" 4
+-.IX Item "-Wtrigraphs"
+-Warn if any trigraphs are encountered that might change the meaning of
+-the program (trigraphs within comments are not warned about).
+-.IP "\fB\-Wunused\-function\fR" 4
+-.IX Item "-Wunused-function"
+-Warn whenever a static function is declared but not defined or a
+-non\e\-inline static function is unused.
+-.IP "\fB\-Wunused\-label\fR" 4
+-.IX Item "-Wunused-label"
+-Warn whenever a label is declared but not used.
+-.Sp
+-To suppress this warning use the \fBunused\fR attribute.
+-.IP "\fB\-Wunused\-parameter\fR" 4
+-.IX Item "-Wunused-parameter"
+-Warn whenever a function parameter is unused aside from its declaration.
+-.Sp
+-To suppress this warning use the \fBunused\fR attribute.
+-.IP "\fB\-Wunused\-variable\fR" 4
+-.IX Item "-Wunused-variable"
+-Warn whenever a local variable or non-constant static variable is unused
+-aside from its declaration
+-.Sp
+-To suppress this warning use the \fBunused\fR attribute.
+-.IP "\fB\-Wunused\-value\fR" 4
+-.IX Item "-Wunused-value"
+-Warn whenever a statement computes a result that is explicitly not used.
+-.Sp
+-To suppress this warning cast the expression to \fBvoid\fR.
+-.IP "\fB\-Wunused\fR" 4
+-.IX Item "-Wunused"
+-All the above \fB\-Wunused\fR options combined.
+-.Sp
+-In order to get a warning about an unused function parameter, you must
+-either specify \fB\-W \-Wunused\fR or separately specify
+-\&\fB\-Wunused\-parameter\fR.
+-.IP "\fB\-Wuninitialized\fR" 4
+-.IX Item "-Wuninitialized"
+-Warn if an automatic variable is used without first being initialized or
+-if a variable may be clobbered by a \f(CW\*(C`setjmp\*(C'\fR call.
+-.Sp
+-These warnings are possible only in optimizing compilation,
+-because they require data flow information that is computed only
+-when optimizing. If you don't specify \fB\-O\fR, you simply won't
+-get these warnings.
+-.Sp
+-These warnings occur only for variables that are candidates for
+-register allocation. Therefore, they do not occur for a variable that
+-is declared \f(CW\*(C`volatile\*(C'\fR, or whose address is taken, or whose size
+-is other than 1, 2, 4 or 8 bytes. Also, they do not occur for
+-structures, unions or arrays, even when they are in registers.
+-.Sp
+-Note that there may be no warning about a variable that is used only
+-to compute a value that itself is never used, because such
+-computations may be deleted by data flow analysis before the warnings
+-are printed.
+-.Sp
+-These warnings are made optional because \s-1GCC\s0 is not smart
+-enough to see all the reasons why the code might be correct
+-despite appearing to have an error. Here is one example of how
+-this can happen:
+-.Sp
+-.Vb 12
+-\& {
+-\& int x;
+-\& switch (y)
+-\& {
+-\& case 1: x = 1;
+-\& break;
+-\& case 2: x = 4;
+-\& break;
+-\& case 3: x = 5;
+-\& }
+-\& foo (x);
+-\& }
+-.Ve
+-.Sp
+-If the value of \f(CW\*(C`y\*(C'\fR is always 1, 2 or 3, then \f(CW\*(C`x\*(C'\fR is
+-always initialized, but \s-1GCC\s0 doesn't know this. Here is
+-another common case:
+-.Sp
+-.Vb 6
+-\& {
+-\& int save_y;
+-\& if (change_y) save_y = y, y = new_y;
+-\& ...
+-\& if (change_y) y = save_y;
+-\& }
+-.Ve
+-.Sp
+-This has no bug because \f(CW\*(C`save_y\*(C'\fR is used only if it is set.
+-.Sp
+-This option also warns when a non-volatile automatic variable might be
+-changed by a call to \f(CW\*(C`longjmp\*(C'\fR. These warnings as well are possible
+-only in optimizing compilation.
+-.Sp
+-The compiler sees only the calls to \f(CW\*(C`setjmp\*(C'\fR. It cannot know
+-where \f(CW\*(C`longjmp\*(C'\fR will be called; in fact, a signal handler could
+-call it at any point in the code. As a result, you may get a warning
+-even when there is in fact no problem because \f(CW\*(C`longjmp\*(C'\fR cannot
+-in fact be called at the place which would cause a problem.
+-.Sp
+-Some spurious warnings can be avoided if you declare all the functions
+-you use that never return as \f(CW\*(C`noreturn\*(C'\fR.
+-.IP "\fB\-Wunknown\-pragmas\fR" 4
+-.IX Item "-Wunknown-pragmas"
+-Warn when a #pragma directive is encountered which is not understood by
+-\&\s-1GCC\s0. If this command line option is used, warnings will even be issued
+-for unknown pragmas in system header files. This is not the case if
+-the warnings were only enabled by the \fB\-Wall\fR command line option.
+-.IP "\fB\-Wstrict\-aliasing\fR" 4
+-.IX Item "-Wstrict-aliasing"
+-This option is only active when \fB\-fstrict\-aliasing\fR is active.
+-It warns about code which might break the strict aliasing rules that the
+-compiler is using for optimization. The warning does not catch all
+-cases, but does attempt to catch the more common pitfalls. It is
+-included in \fB\-Wall\fR.
+-.IP "\fB\-Wall\fR" 4
+-.IX Item "-Wall"
+-All of the above \fB\-W\fR options combined. This enables all the
+-warnings about constructions that some users consider questionable, and
+-that are easy to avoid (or modify to prevent the warning), even in
+-conjunction with macros. This also enables some language-specific
+-warnings described in \fB\*(C+ Dialect Options\fR and
+-\&\fBObjective-C Dialect Options\fR.
+-.PP
+-The following \fB\-W...\fR options are not implied by \fB\-Wall\fR.
+-Some of them warn about constructions that users generally do not
+-consider questionable, but which occasionally you might wish to check
+-for; others warn about constructions that are necessary or hard to avoid
+-in some cases, and there is no simple way to modify the code to suppress
+-the warning.
+-.IP "\fB\-W\fR" 4
+-.IX Item "-W"
+-Print extra warning messages for these events:
+-.RS 4
+-.IP "*" 4
+-A function can return either with or without a value. (Falling
+-off the end of the function body is considered returning without
+-a value.) For example, this function would evoke such a
+-warning:
+-.Sp
+-.Vb 5
+-\& foo (a)
+-\& {
+-\& if (a > 0)
+-\& return a;
+-\& }
+-.Ve
+-.IP "*" 4
+-An expression-statement or the left-hand side of a comma expression
+-contains no side effects.
+-To suppress the warning, cast the unused expression to void.
+-For example, an expression such as \fBx[i,j]\fR will cause a warning,
+-but \fBx[(void)i,j]\fR will not.
+-.IP "*" 4
+-An unsigned value is compared against zero with \fB<\fR or \fB>=\fR.
+-.IP "*" 4
+-A comparison like \fBx<=y<=z\fR appears; this is equivalent to
+-\&\fB(x<=y ? 1 : 0) <= z\fR, which is a different interpretation from
+-that of ordinary mathematical notation.
+-.IP "*" 4
+-Storage-class specifiers like \f(CW\*(C`static\*(C'\fR are not the first things in
+-a declaration. According to the C Standard, this usage is obsolescent.
+-.IP "*" 4
+-The return type of a function has a type qualifier such as \f(CW\*(C`const\*(C'\fR.
+-Such a type qualifier has no effect, since the value returned by a
+-function is not an lvalue. (But don't warn about the \s-1GNU\s0 extension of
+-\&\f(CW\*(C`volatile void\*(C'\fR return types. That extension will be warned about
+-if \fB\-pedantic\fR is specified.)
+-.IP "*" 4
+-If \fB\-Wall\fR or \fB\-Wunused\fR is also specified, warn about unused
+-arguments.
+-.IP "*" 4
+-A comparison between signed and unsigned values could produce an
+-incorrect result when the signed value is converted to unsigned.
+-(But don't warn if \fB\-Wno\-sign\-compare\fR is also specified.)
+-.IP "*" 4
+-An aggregate has a partly bracketed initializer.
+-For example, the following code would evoke such a warning,
+-because braces are missing around the initializer for \f(CW\*(C`x.h\*(C'\fR:
+-.Sp
+-.Vb 3
+-\& struct s { int f, g; };
+-\& struct t { struct s h; int i; };
+-\& struct t x = { 1, 2, 3 };
+-.Ve
+-.IP "*" 4
+-An aggregate has an initializer which does not initialize all members.
+-For example, the following code would cause such a warning, because
+-\&\f(CW\*(C`x.h\*(C'\fR would be implicitly initialized to zero:
+-.Sp
+-.Vb 2
+-\& struct s { int f, g, h; };
+-\& struct s x = { 3, 4 };
+-.Ve
+-.RE
+-.RS 4
+-.RE
+-.IP "\fB\-Wno\-div\-by\-zero\fR" 4
+-.IX Item "-Wno-div-by-zero"
+-Do not warn about compile-time integer division by zero. Floating point
+-division by zero is not warned about, as it can be a legitimate way of
+-obtaining infinities and NaNs.
+-.IP "\fB\-Wsystem\-headers\fR" 4
+-.IX Item "-Wsystem-headers"
+-Print warning messages for constructs found in system header files.
+-Warnings from system headers are normally suppressed, on the assumption
+-that they usually do not indicate real problems and would only make the
+-compiler output harder to read. Using this command line option tells
+-\&\s-1GCC\s0 to emit warnings from system headers as if they occurred in user
+-code. However, note that using \fB\-Wall\fR in conjunction with this
+-option will \fInot\fR warn about unknown pragmas in system
+-headers\-\-\-for that, \fB\-Wunknown\-pragmas\fR must also be used.
+-.IP "\fB\-Wfloat\-equal\fR" 4
+-.IX Item "-Wfloat-equal"
+-Warn if floating point values are used in equality comparisons.
+-.Sp
+-The idea behind this is that sometimes it is convenient (for the
+-programmer) to consider floating-point values as approximations to
+-infinitely precise real numbers. If you are doing this, then you need
+-to compute (by analyzing the code, or in some other way) the maximum or
+-likely maximum error that the computation introduces, and allow for it
+-when performing comparisons (and when producing output, but that's a
+-different problem). In particular, instead of testing for equality, you
+-would check to see whether the two values have ranges that overlap; and
+-this is done with the relational operators, so equality comparisons are
+-probably mistaken.
+-.IP "\fB\-Wtraditional\fR (C only)" 4
+-.IX Item "-Wtraditional (C only)"
+-Warn about certain constructs that behave differently in traditional and
+-\&\s-1ISO\s0 C. Also warn about \s-1ISO\s0 C constructs that have no traditional C
+-equivalent, and/or problematic constructs which should be avoided.
+-.RS 4
+-.IP "*" 4
+-Macro parameters that appear within string literals in the macro body.
+-In traditional C macro replacement takes place within string literals,
+-but does not in \s-1ISO\s0 C.
+-.IP "*" 4
+-In traditional C, some preprocessor directives did not exist.
+-Traditional preprocessors would only consider a line to be a directive
+-if the \fB#\fR appeared in column 1 on the line. Therefore
+-\&\fB\-Wtraditional\fR warns about directives that traditional C
+-understands but would ignore because the \fB#\fR does not appear as the
+-first character on the line. It also suggests you hide directives like
+-\&\fB#pragma\fR not understood by traditional C by indenting them. Some
+-traditional implementations would not recognize \fB#elif\fR, so it
+-suggests avoiding it altogether.
+-.IP "*" 4
+-A function-like macro that appears without arguments.
+-.IP "*" 4
+-The unary plus operator.
+-.IP "*" 4
+-The \fBU\fR integer constant suffix, or the \fBF\fR or \fBL\fR floating point
+-constant suffixes. (Traditional C does support the \fBL\fR suffix on integer
+-constants.) Note, these suffixes appear in macros defined in the system
+-headers of most modern systems, e.g. the \fB_MIN\fR/\fB_MAX\fR macros in \f(CW\*(C`<limits.h>\*(C'\fR.
+-Use of these macros in user code might normally lead to spurious
+-warnings, however gcc's integrated preprocessor has enough context to
+-avoid warning in these cases.
+-.IP "*" 4
+-A function declared external in one block and then used after the end of
+-the block.
+-.IP "*" 4
+-A \f(CW\*(C`switch\*(C'\fR statement has an operand of type \f(CW\*(C`long\*(C'\fR.
+-.IP "*" 4
+-A non\-\f(CW\*(C`static\*(C'\fR function declaration follows a \f(CW\*(C`static\*(C'\fR one.
+-This construct is not accepted by some traditional C compilers.
+-.IP "*" 4
+-The \s-1ISO\s0 type of an integer constant has a different width or
+-signedness from its traditional type. This warning is only issued if
+-the base of the constant is ten. I.e. hexadecimal or octal values, which
+-typically represent bit patterns, are not warned about.
+-.IP "*" 4
+-Usage of \s-1ISO\s0 string concatenation is detected.
+-.IP "*" 4
+-Initialization of automatic aggregates.
+-.IP "*" 4
+-Identifier conflicts with labels. Traditional C lacks a separate
+-namespace for labels.
+-.IP "*" 4
+-Initialization of unions. If the initializer is zero, the warning is
+-omitted. This is done under the assumption that the zero initializer in
+-user code appears conditioned on e.g. \f(CW\*(C`_\|_STDC_\|_\*(C'\fR to avoid missing
+-initializer warnings and relies on default initialization to zero in the
+-traditional C case.
+-.IP "*" 4
+-Conversions by prototypes between fixed/floating point values and vice
+-versa. The absence of these prototypes when compiling with traditional
+-C would cause serious problems. This is a subset of the possible
+-conversion warnings, for the full set use \fB\-Wconversion\fR.
+-.IP "*" 4
+-Use of \s-1ISO\s0 C style function definitions. This warning intentionally is
+-\&\fInot\fR issued for prototype declarations or variadic functions
+-because these \s-1ISO\s0 C features will appear in your code when using
+-libiberty's traditional C compatibility macros, \f(CW\*(C`PARAMS\*(C'\fR and
+-\&\f(CW\*(C`VPARAMS\*(C'\fR. This warning is also bypassed for nested functions
+-because that feature is already a gcc extension and thus not relevant to
+-traditional C compatibility.
+-.RE
+-.RS 4
+-.RE
+-.IP "\fB\-Wundef\fR" 4
+-.IX Item "-Wundef"
+-Warn if an undefined identifier is evaluated in an \fB#if\fR directive.
+-.IP "\fB\-Wendif\-labels\fR" 4
+-.IX Item "-Wendif-labels"
+-Warn whenever an \fB#else\fR or an \fB#endif\fR are followed by text.
+-.IP "\fB\-Wshadow\fR" 4
+-.IX Item "-Wshadow"
+-Warn whenever a local variable shadows another local variable, parameter or
+-global variable or whenever a built-in function is shadowed.
+-.IP "\fB\-Wlarger\-than\-\fR\fIlen\fR" 4
+-.IX Item "-Wlarger-than-len"
+-Warn whenever an object of larger than \fIlen\fR bytes is defined.
+-.IP "\fB\-Wpointer\-arith\fR" 4
+-.IX Item "-Wpointer-arith"
+-Warn about anything that depends on the ``size of'' a function type or
+-of \f(CW\*(C`void\*(C'\fR. \s-1GNU\s0 C assigns these types a size of 1, for
+-convenience in calculations with \f(CW\*(C`void *\*(C'\fR pointers and pointers
+-to functions.
+-.IP "\fB\-Wbad\-function\-cast\fR (C only)" 4
+-.IX Item "-Wbad-function-cast (C only)"
+-Warn whenever a function call is cast to a non-matching type.
+-For example, warn if \f(CW\*(C`int malloc()\*(C'\fR is cast to \f(CW\*(C`anything *\*(C'\fR.
+-.IP "\fB\-Wcast\-qual\fR" 4
+-.IX Item "-Wcast-qual"
+-Warn whenever a pointer is cast so as to remove a type qualifier from
+-the target type. For example, warn if a \f(CW\*(C`const char *\*(C'\fR is cast
+-to an ordinary \f(CW\*(C`char *\*(C'\fR.
+-.IP "\fB\-Wcast\-align\fR" 4
+-.IX Item "-Wcast-align"
+-Warn whenever a pointer is cast such that the required alignment of the
+-target is increased. For example, warn if a \f(CW\*(C`char *\*(C'\fR is cast to
+-an \f(CW\*(C`int *\*(C'\fR on machines where integers can only be accessed at
+-two\- or four-byte boundaries.
+-.IP "\fB\-Wwrite\-strings\fR" 4
+-.IX Item "-Wwrite-strings"
+-When compiling C, give string constants the type \f(CW\*(C`const
+-char[\f(CIlength\f(CW]\*(C'\fR so that
+-copying the address of one into a non\-\f(CW\*(C`const\*(C'\fR \f(CW\*(C`char *\*(C'\fR
+-pointer will get a warning; when compiling \*(C+, warn about the
+-deprecated conversion from string constants to \f(CW\*(C`char *\*(C'\fR.
+-These warnings will help you find at
+-compile time code that can try to write into a string constant, but
+-only if you have been very careful about using \f(CW\*(C`const\*(C'\fR in
+-declarations and prototypes. Otherwise, it will just be a nuisance;
+-this is why we did not make \fB\-Wall\fR request these warnings.
+-.IP "\fB\-Wconversion\fR" 4
+-.IX Item "-Wconversion"
+-Warn if a prototype causes a type conversion that is different from what
+-would happen to the same argument in the absence of a prototype. This
+-includes conversions of fixed point to floating and vice versa, and
+-conversions changing the width or signedness of a fixed point argument
+-except when the same as the default promotion.
+-.Sp
+-Also, warn if a negative integer constant expression is implicitly
+-converted to an unsigned type. For example, warn about the assignment
+-\&\f(CW\*(C`x = \-1\*(C'\fR if \f(CW\*(C`x\*(C'\fR is unsigned. But do not warn about explicit
+-casts like \f(CW\*(C`(unsigned) \-1\*(C'\fR.
+-.IP "\fB\-Wsign\-compare\fR" 4
+-.IX Item "-Wsign-compare"
+-Warn when a comparison between signed and unsigned values could produce
+-an incorrect result when the signed value is converted to unsigned.
+-This warning is enabled by \fB\-W\fR, and by \fB\-Wall\fR
+-in \*(C+ only.
+-.IP "\fB\-Waggregate\-return\fR" 4
+-.IX Item "-Waggregate-return"
+-Warn if any functions that return structures or unions are defined or
+-called. (In languages where you can return an array, this also elicits
+-a warning.)
+-.IP "\fB\-Wstrict\-prototypes\fR (C only)" 4
+-.IX Item "-Wstrict-prototypes (C only)"
+-Warn if a function is declared or defined without specifying the
+-argument types. (An old-style function definition is permitted without
+-a warning if preceded by a declaration which specifies the argument
+-types.)
+-.IP "\fB\-Wmissing\-prototypes\fR (C only)" 4
+-.IX Item "-Wmissing-prototypes (C only)"
+-Warn if a global function is defined without a previous prototype
+-declaration. This warning is issued even if the definition itself
+-provides a prototype. The aim is to detect global functions that fail
+-to be declared in header files.
+-.IP "\fB\-Wmissing\-declarations\fR (C only)" 4
+-.IX Item "-Wmissing-declarations (C only)"
+-Warn if a global function is defined without a previous declaration.
+-Do so even if the definition itself provides a prototype.
+-Use this option to detect global functions that are not declared in
+-header files.
+-.IP "\fB\-Wmissing\-noreturn\fR" 4
+-.IX Item "-Wmissing-noreturn"
+-Warn about functions which might be candidates for attribute \f(CW\*(C`noreturn\*(C'\fR.
+-Note these are only possible candidates, not absolute ones. Care should
+-be taken to manually verify functions actually do not ever return before
+-adding the \f(CW\*(C`noreturn\*(C'\fR attribute, otherwise subtle code generation
+-bugs could be introduced. You will not get a warning for \f(CW\*(C`main\*(C'\fR in
+-hosted C environments.
+-.IP "\fB\-Wmissing\-format\-attribute\fR" 4
+-.IX Item "-Wmissing-format-attribute"
+-If \fB\-Wformat\fR is enabled, also warn about functions which might be
+-candidates for \f(CW\*(C`format\*(C'\fR attributes. Note these are only possible
+-candidates, not absolute ones. \s-1GCC\s0 will guess that \f(CW\*(C`format\*(C'\fR
+-attributes might be appropriate for any function that calls a function
+-like \f(CW\*(C`vprintf\*(C'\fR or \f(CW\*(C`vscanf\*(C'\fR, but this might not always be the
+-case, and some functions for which \f(CW\*(C`format\*(C'\fR attributes are
+-appropriate may not be detected. This option has no effect unless
+-\&\fB\-Wformat\fR is enabled (possibly by \fB\-Wall\fR).
+-.IP "\fB\-Wno\-multichar\fR" 4
+-.IX Item "-Wno-multichar"
+-Do not warn if a multicharacter constant (\fB'\s-1FOOF\s0'\fR) is used.
+-Usually they indicate a typo in the user's code, as they have
+-implementation-defined values, and should not be used in portable code.
+-.IP "\fB\-Wno\-deprecated\-declarations\fR" 4
+-.IX Item "-Wno-deprecated-declarations"
+-Do not warn about uses of functions, variables, and types marked as
+-deprecated by using the \f(CW\*(C`deprecated\*(C'\fR attribute.
+-(@pxref{Function Attributes}, \f(CW@pxref\fR{Variable Attributes},
+-\&\f(CW@pxref\fR{Type Attributes}.)
+-.IP "\fB\-Wpacked\fR" 4
+-.IX Item "-Wpacked"
+-Warn if a structure is given the packed attribute, but the packed
+-attribute has no effect on the layout or size of the structure.
+-Such structures may be mis-aligned for little benefit. For
+-instance, in this code, the variable \f(CW\*(C`f.x\*(C'\fR in \f(CW\*(C`struct bar\*(C'\fR
+-will be misaligned even though \f(CW\*(C`struct bar\*(C'\fR does not itself
+-have the packed attribute:
+-.Sp
+-.Vb 8
+-\& struct foo {
+-\& int x;
+-\& char a, b, c, d;
+-\& } __attribute__((packed));
+-\& struct bar {
+-\& char z;
+-\& struct foo f;
+-\& };
+-.Ve
+-.IP "\fB\-Wpadded\fR" 4
+-.IX Item "-Wpadded"
+-Warn if padding is included in a structure, either to align an element
+-of the structure or to align the whole structure. Sometimes when this
+-happens it is possible to rearrange the fields of the structure to
+-reduce the padding and so make the structure smaller.
+-.IP "\fB\-Wredundant\-decls\fR" 4
+-.IX Item "-Wredundant-decls"
+-Warn if anything is declared more than once in the same scope, even in
+-cases where multiple declaration is valid and changes nothing.
+-.IP "\fB\-Wnested\-externs\fR (C only)" 4
+-.IX Item "-Wnested-externs (C only)"
+-Warn if an \f(CW\*(C`extern\*(C'\fR declaration is encountered within a function.
+-.IP "\fB\-Wunreachable\-code\fR" 4
+-.IX Item "-Wunreachable-code"
+-Warn if the compiler detects that code will never be executed.
+-.Sp
+-This option is intended to warn when the compiler detects that at
+-least a whole line of source code will never be executed, because
+-some condition is never satisfied or because it is after a
+-procedure that never returns.
+-.Sp
+-It is possible for this option to produce a warning even though there
+-are circumstances under which part of the affected line can be executed,
+-so care should be taken when removing apparently-unreachable code.
+-.Sp
+-For instance, when a function is inlined, a warning may mean that the
+-line is unreachable in only one inlined copy of the function.
+-.Sp
+-This option is not made part of \fB\-Wall\fR because in a debugging
+-version of a program there is often substantial code which checks
+-correct functioning of the program and is, hopefully, unreachable
+-because the program does work. Another common use of unreachable
+-code is to provide behavior which is selectable at compile\-time.
+-.IP "\fB\-Winline\fR" 4
+-.IX Item "-Winline"
+-Warn if a function can not be inlined and it was declared as inline.
+-Even with this option, the compiler will not warn about failures to
+-inline functions declared in system headers.
+-.Sp
+-The compiler uses a variety of heuristics to determine whether or not
+-to inline a function. For example, the compiler takes into account
+-the size of the function being inlined and the the amount of inlining
+-that has already been done in the current function. Therefore,
+-seemingly insignificant changes in the source program can cause the
+-warnings produced by \fB\-Winline\fR to appear or disappear.
+-.IP "\fB\-Wlong\-long\fR" 4
+-.IX Item "-Wlong-long"
+-Warn if \fBlong long\fR type is used. This is default. To inhibit
+-the warning messages, use \fB\-Wno\-long\-long\fR. Flags
+-\&\fB\-Wlong\-long\fR and \fB\-Wno\-long\-long\fR are taken into account
+-only when \fB\-pedantic\fR flag is used.
+-.IP "\fB\-Wdisabled\-optimization\fR" 4
+-.IX Item "-Wdisabled-optimization"
+-Warn if a requested optimization pass is disabled. This warning does
+-not generally indicate that there is anything wrong with your code; it
+-merely indicates that \s-1GCC\s0's optimizers were unable to handle the code
+-effectively. Often, the problem is that your code is too big or too
+-complex; \s-1GCC\s0 will refuse to optimize programs when the optimization
+-itself is likely to take inordinate amounts of time.
+-.IP "\fB\-Werror\fR" 4
+-.IX Item "-Werror"
+-Make all warnings into errors.
+-.Sh "Options for Debugging Your Program or \s-1GCC\s0"
+-.IX Subsection "Options for Debugging Your Program or GCC"
+-\&\s-1GCC\s0 has various special options that are used for debugging
+-either your program or \s-1GCC:\s0
+-.IP "\fB\-g\fR" 4
+-.IX Item "-g"
+-Produce debugging information in the operating system's native format
+-(stabs, \s-1COFF\s0, \s-1XCOFF\s0, or \s-1DWARF\s0). \s-1GDB\s0 can work with this debugging
+-information.
+-.Sp
+-On most systems that use stabs format, \fB\-g\fR enables use of extra
+-debugging information that only \s-1GDB\s0 can use; this extra information
+-makes debugging work better in \s-1GDB\s0 but will probably make other debuggers
+-crash or
+-refuse to read the program. If you want to control for certain whether
+-to generate the extra information, use \fB\-gstabs+\fR, \fB\-gstabs\fR,
+-\&\fB\-gxcoff+\fR, \fB\-gxcoff\fR, \fB\-gdwarf\-1+\fR, \fB\-gdwarf\-1\fR,
+-or \fB\-gvms\fR (see below).
+-.Sp
+-Unlike most other C compilers, \s-1GCC\s0 allows you to use \fB\-g\fR with
+-\&\fB\-O\fR. The shortcuts taken by optimized code may occasionally
+-produce surprising results: some variables you declared may not exist
+-at all; flow of control may briefly move where you did not expect it;
+-some statements may not be executed because they compute constant
+-results or their values were already at hand; some statements may
+-execute in different places because they were moved out of loops.
+-.Sp
+-Nevertheless it proves possible to debug optimized output. This makes
+-it reasonable to use the optimizer for programs that might have bugs.
+-.Sp
+-The following options are useful when \s-1GCC\s0 is generated with the
+-capability for more than one debugging format.
+-.IP "\fB\-ggdb\fR" 4
+-.IX Item "-ggdb"
+-Produce debugging information for use by \s-1GDB\s0. This means to use the
+-most expressive format available (\s-1DWARF\s0 2, stabs, or the native format
+-if neither of those are supported), including \s-1GDB\s0 extensions if at all
+-possible.
+-.IP "\fB\-gstabs\fR" 4
+-.IX Item "-gstabs"
+-Produce debugging information in stabs format (if that is supported),
+-without \s-1GDB\s0 extensions. This is the format used by \s-1DBX\s0 on most \s-1BSD\s0
+-systems. On \s-1MIPS\s0, Alpha and System V Release 4 systems this option
+-produces stabs debugging output which is not understood by \s-1DBX\s0 or \s-1SDB\s0.
+-On System V Release 4 systems this option requires the \s-1GNU\s0 assembler.
+-.IP "\fB\-gstabs+\fR" 4
+-.IX Item "-gstabs+"
+-Produce debugging information in stabs format (if that is supported),
+-using \s-1GNU\s0 extensions understood only by the \s-1GNU\s0 debugger (\s-1GDB\s0). The
+-use of these extensions is likely to make other debuggers crash or
+-refuse to read the program.
+-.IP "\fB\-gcoff\fR" 4
+-.IX Item "-gcoff"
+-Produce debugging information in \s-1COFF\s0 format (if that is supported).
+-This is the format used by \s-1SDB\s0 on most System V systems prior to
+-System V Release 4.
+-.IP "\fB\-gxcoff\fR" 4
+-.IX Item "-gxcoff"
+-Produce debugging information in \s-1XCOFF\s0 format (if that is supported).
+-This is the format used by the \s-1DBX\s0 debugger on \s-1IBM\s0 \s-1RS/6000\s0 systems.
+-.IP "\fB\-gxcoff+\fR" 4
+-.IX Item "-gxcoff+"
+-Produce debugging information in \s-1XCOFF\s0 format (if that is supported),
+-using \s-1GNU\s0 extensions understood only by the \s-1GNU\s0 debugger (\s-1GDB\s0). The
+-use of these extensions is likely to make other debuggers crash or
+-refuse to read the program, and may cause assemblers other than the \s-1GNU\s0
+-assembler (\s-1GAS\s0) to fail with an error.
+-.IP "\fB\-gdwarf\fR" 4
+-.IX Item "-gdwarf"
+-Produce debugging information in \s-1DWARF\s0 version 1 format (if that is
+-supported). This is the format used by \s-1SDB\s0 on most System V Release 4
+-systems.
+-.Sp
+-This option is deprecated.
+-.IP "\fB\-gdwarf+\fR" 4
+-.IX Item "-gdwarf+"
+-Produce debugging information in \s-1DWARF\s0 version 1 format (if that is
+-supported), using \s-1GNU\s0 extensions understood only by the \s-1GNU\s0 debugger
+-(\s-1GDB\s0). The use of these extensions is likely to make other debuggers
+-crash or refuse to read the program.
+-.Sp
+-This option is deprecated.
+-.IP "\fB\-gdwarf\-2\fR" 4
+-.IX Item "-gdwarf-2"
+-Produce debugging information in \s-1DWARF\s0 version 2 format (if that is
+-supported). This is the format used by \s-1DBX\s0 on \s-1IRIX\s0 6.
+-.IP "\fB\-gvms\fR" 4
+-.IX Item "-gvms"
+-Produce debugging information in \s-1VMS\s0 debug format (if that is
+-supported). This is the format used by \s-1DEBUG\s0 on \s-1VMS\s0 systems.
+-.IP "\fB\-g\fR\fIlevel\fR" 4
+-.IX Item "-glevel"
+-.PD 0
+-.IP "\fB\-ggdb\fR\fIlevel\fR" 4
+-.IX Item "-ggdblevel"
+-.IP "\fB\-gstabs\fR\fIlevel\fR" 4
+-.IX Item "-gstabslevel"
+-.IP "\fB\-gcoff\fR\fIlevel\fR" 4
+-.IX Item "-gcofflevel"
+-.IP "\fB\-gxcoff\fR\fIlevel\fR" 4
+-.IX Item "-gxcofflevel"
+-.IP "\fB\-gvms\fR\fIlevel\fR" 4
+-.IX Item "-gvmslevel"
+-.PD
+-Request debugging information and also use \fIlevel\fR to specify how
+-much information. The default level is 2.
+-.Sp
+-Level 1 produces minimal information, enough for making backtraces in
+-parts of the program that you don't plan to debug. This includes
+-descriptions of functions and external variables, but no information
+-about local variables and no line numbers.
+-.Sp
+-Level 3 includes extra information, such as all the macro definitions
+-present in the program. Some debuggers support macro expansion when
+-you use \fB\-g3\fR.
+-.Sp
+-Note that in order to avoid confusion between \s-1DWARF1\s0 debug level 2,
+-and \s-1DWARF2\s0, neither \fB\-gdwarf\fR nor \fB\-gdwarf\-2\fR accept
+-a concatenated debug level. Instead use an additional \fB\-g\fR\fIlevel\fR
+-option to change the debug level for \s-1DWARF1\s0 or \s-1DWARF2\s0.
+-.IP "\fB\-feliminate\-dwarf2\-dups\fR" 4
+-.IX Item "-feliminate-dwarf2-dups"
+-Compress \s-1DWARF2\s0 debugging information by eliminating duplicated
+-information about each symbol. This option only makes sense when
+-generating \s-1DWARF2\s0 debugging information with \fB\-gdwarf\-2\fR.
+-.IP "\fB\-p\fR" 4
+-.IX Item "-p"
+-Generate extra code to write profile information suitable for the
+-analysis program \fBprof\fR. You must use this option when compiling
+-the source files you want data about, and you must also use it when
+-linking.
+-.IP "\fB\-pg\fR" 4
+-.IX Item "-pg"
+-Generate extra code to write profile information suitable for the
+-analysis program \fBgprof\fR. You must use this option when compiling
+-the source files you want data about, and you must also use it when
+-linking.
+-.IP "\fB\-Q\fR" 4
+-.IX Item "-Q"
+-Makes the compiler print out each function name as it is compiled, and
+-print some statistics about each pass when it finishes.
+-.IP "\fB\-ftime\-report\fR" 4
+-.IX Item "-ftime-report"
+-Makes the compiler print some statistics about the time consumed by each
+-pass when it finishes.
+-.IP "\fB\-fmem\-report\fR" 4
+-.IX Item "-fmem-report"
+-Makes the compiler print some statistics about permanent memory
+-allocation when it finishes.
+-.IP "\fB\-fprofile\-arcs\fR" 4
+-.IX Item "-fprofile-arcs"
+-Instrument \fIarcs\fR during compilation to generate coverage data or
+-for profile-directed block ordering. During execution the program
+-records how many times each branch is executed and how many times it is
+-taken. When the compiled program exits it saves this data to a file
+-called \fI\fIauxname\fI.da\fR for each source file. \fIauxname\fR is
+-generated from the name of the output file, if explicitly specified and
+-it is not the final executable, otherwise it is the basename of the
+-source file. In both cases any suffix is removed (e.g. \fIfoo.da\fR
+-for input file \fIdir/foo.c\fR, or \fIdir/foo.da\fR for output file
+-specified as \fB\-o dir/foo.o\fR).
+-.Sp
+-For profile-directed block ordering, compile the program with
+-\&\fB\-fprofile\-arcs\fR plus optimization and code generation options,
+-generate the arc profile information by running the program on a
+-selected workload, and then compile the program again with the same
+-optimization and code generation options plus
+-\&\fB\-fbranch\-probabilities\fR.
+-.Sp
+-The other use of \fB\-fprofile\-arcs\fR is for use with \fBgcov\fR,
+-when it is used with the \fB\-ftest\-coverage\fR option.
+-.Sp
+-With \fB\-fprofile\-arcs\fR, for each function of your program \s-1GCC\s0
+-creates a program flow graph, then finds a spanning tree for the graph.
+-Only arcs that are not on the spanning tree have to be instrumented: the
+-compiler adds code to count the number of times that these arcs are
+-executed. When an arc is the only exit or only entrance to a block, the
+-instrumentation code can be added to the block; otherwise, a new basic
+-block must be created to hold the instrumentation code.
+-.IP "\fB\-ftest\-coverage\fR" 4
+-.IX Item "-ftest-coverage"
+-Create data files for the \fBgcov\fR code-coverage utility. See
+-\&\fB\-fprofile\-arcs\fR option above for a description of \fIauxname\fR.
+-.RS 4
+-.IP "\fIauxname\fR\fB.bb\fR" 4
+-.IX Item "auxname.bb"
+-A mapping from basic blocks to line numbers, which \fBgcov\fR uses to
+-associate basic block execution counts with line numbers.
+-.IP "\fIauxname\fR\fB.bbg\fR" 4
+-.IX Item "auxname.bbg"
+-A list of all arcs in the program flow graph. This allows \fBgcov\fR
+-to reconstruct the program flow graph, so that it can compute all basic
+-block and arc execution counts from the information in the
+-\&\fI\fIauxname\fI.da\fR file.
+-.RE
+-.RS 4
+-.Sp
+-Use \fB\-ftest\-coverage\fR with \fB\-fprofile\-arcs\fR; the latter
+-option adds instrumentation to the program, which then writes
+-execution counts to another data file:
+-.IP "\fIauxname\fR\fB.da\fR" 4
+-.IX Item "auxname.da"
+-Runtime arc execution counts, used in conjunction with the arc
+-information in the file \fI\fIauxname\fI.bbg\fR.
+-.RE
+-.RS 4
+-.Sp
+-Coverage data will map better to the source files if
+-\&\fB\-ftest\-coverage\fR is used without optimization.
+-.RE
+-.IP "\fB\-d\fR\fIletters\fR" 4
+-.IX Item "-dletters"
+-Says to make debugging dumps during compilation at times specified by
+-\&\fIletters\fR. This is used for debugging the compiler. The file names
+-for most of the dumps are made by appending a pass number and a word to
+-the \fIdumpname\fR. \fIdumpname\fR is generated from the name of the
+-output file, if explicitly specified and it is not an executable,
+-otherwise it is the basename of the source file. In both cases any
+-suffix is removed (e.g. \fIfoo.00.rtl\fR or \fIfoo.01.sibling\fR).
+-Here are the possible letters for use in \fIletters\fR, and their
+-meanings:
+-.RS 4
+-.IP "\fBA\fR" 4
+-.IX Item "A"
+-Annotate the assembler output with miscellaneous debugging information.
+-.IP "\fBb\fR" 4
+-.IX Item "b"
+-Dump after computing branch probabilities, to \fI\fIfile\fI.14.bp\fR.
+-.IP "\fBB\fR" 4
+-.IX Item "B"
+-Dump after block reordering, to \fI\fIfile\fI.32.bbro\fR.
+-.IP "\fBc\fR" 4
+-.IX Item "c"
+-Dump after instruction combination, to the file \fI\fIfile\fI.19.combine\fR.
+-.IP "\fBC\fR" 4
+-.IX Item "C"
+-Dump after the first if conversion, to the file \fI\fIfile\fI.15.ce1\fR.
+-.IP "\fBd\fR" 4
+-.IX Item "d"
+-Dump after delayed branch scheduling, to \fI\fIfile\fI.34.dbr\fR.
+-.IP "\fBD\fR" 4
+-.IX Item "D"
+-Dump all macro definitions, at the end of preprocessing, in addition to
+-normal output.
+-.IP "\fBe\fR" 4
+-.IX Item "e"
+-Dump after \s-1SSA\s0 optimizations, to \fI\fIfile\fI.04.ssa\fR and
+-\&\fI\fIfile\fI.07.ussa\fR.
+-.IP "\fBE\fR" 4
+-.IX Item "E"
+-Dump after the second if conversion, to \fI\fIfile\fI.29.ce3\fR.
+-.IP "\fBf\fR" 4
+-.IX Item "f"
+-Dump after control and data flow analysis, to \fI\fIfile\fI.14.cfg\fR.
+-Also dump after life analysis, to \fI\fIfile\fI.18.life\fR.
+-.IP "\fBF\fR" 4
+-.IX Item "F"
+-Dump after purging \f(CW\*(C`ADDRESSOF\*(C'\fR codes, to \fI\fIfile\fI.10.addressof\fR.
+-.IP "\fBg\fR" 4
+-.IX Item "g"
+-Dump after global register allocation, to \fI\fIfile\fI.24.greg\fR.
+-.IP "\fBG\fR" 4
+-.IX Item "G"
+-Dump after \s-1GCSE\s0, to \fI\fIfile\fI.11.gcse\fR.
+-.IP "\fBh\fR" 4
+-.IX Item "h"
+-Dump after finalization of \s-1EH\s0 handling code, to \fI\fIfile\fI.02.eh\fR.
+-.IP "\fBi\fR" 4
+-.IX Item "i"
+-Dump after sibling call optimizations, to \fI\fIfile\fI.01.sibling\fR.
+-.IP "\fBj\fR" 4
+-.IX Item "j"
+-Dump after the first jump optimization, to \fI\fIfile\fI.03.jump\fR.
+-.IP "\fBk\fR" 4
+-.IX Item "k"
+-Dump after conversion from registers to stack, to \fI\fIfile\fI.31.stack\fR.
+-.IP "\fBl\fR" 4
+-.IX Item "l"
+-Dump after local register allocation, to \fI\fIfile\fI.23.lreg\fR.
+-.IP "\fBL\fR" 4
+-.IX Item "L"
+-Dump after loop optimization, to \fI\fIfile\fI.12.loop\fR.
+-.IP "\fBM\fR" 4
+-.IX Item "M"
+-Dump after performing the machine dependent reorganization pass, to
+-\&\fI\fIfile\fI.33.mach\fR.
+-.IP "\fBn\fR" 4
+-.IX Item "n"
+-Dump after register renumbering, to \fI\fIfile\fI.28.rnreg\fR.
+-.IP "\fBN\fR" 4
+-.IX Item "N"
+-Dump after the register move pass, to \fI\fIfile\fI.21.regmove\fR.
+-.IP "\fBo\fR" 4
+-.IX Item "o"
+-Dump after post-reload optimizations, to \fI\fIfile\fI.25.postreload\fR.
+-.IP "\fBr\fR" 4
+-.IX Item "r"
+-Dump after \s-1RTL\s0 generation, to \fI\fIfile\fI.00.rtl\fR.
+-.IP "\fBR\fR" 4
+-.IX Item "R"
+-Dump after the second scheduling pass, to \fI\fIfile\fI.30.sched2\fR.
+-.IP "\fBs\fR" 4
+-.IX Item "s"
+-Dump after \s-1CSE\s0 (including the jump optimization that sometimes follows
+-\&\s-1CSE\s0), to \fI\fIfile\fI.09.cse\fR.
+-.IP "\fBS\fR" 4
+-.IX Item "S"
+-Dump after the first scheduling pass, to \fI\fIfile\fI.22.sched\fR.
+-.IP "\fBt\fR" 4
+-.IX Item "t"
+-Dump after the second \s-1CSE\s0 pass (including the jump optimization that
+-sometimes follows \s-1CSE\s0), to \fI\fIfile\fI.17.cse2\fR.
+-.IP "\fBT\fR" 4
+-.IX Item "T"
+-Dump after running tracer, to \fI\fIfile\fI.16.tracer\fR.
+-.IP "\fBu\fR" 4
+-.IX Item "u"
+-Dump after null pointer elimination pass to \fI\fIfile\fI.08.null\fR.
+-.IP "\fBw\fR" 4
+-.IX Item "w"
+-Dump after the second flow pass, to \fI\fIfile\fI.26.flow2\fR.
+-.IP "\fBW\fR" 4
+-.IX Item "W"
+-Dump after \s-1SSA\s0 conditional constant propagation, to
+-\&\fI\fIfile\fI.05.ssaccp\fR.
+-.IP "\fBX\fR" 4
+-.IX Item "X"
+-Dump after \s-1SSA\s0 dead code elimination, to \fI\fIfile\fI.06.ssadce\fR.
+-.IP "\fBz\fR" 4
+-.IX Item "z"
+-Dump after the peephole pass, to \fI\fIfile\fI.27.peephole2\fR.
+-.IP "\fBa\fR" 4
+-.IX Item "a"
+-Produce all the dumps listed above.
+-.IP "\fBm\fR" 4
+-.IX Item "m"
+-Print statistics on memory usage, at the end of the run, to
+-standard error.
+-.IP "\fBp\fR" 4
+-.IX Item "p"
+-Annotate the assembler output with a comment indicating which
+-pattern and alternative was used. The length of each instruction is
+-also printed.
+-.IP "\fBP\fR" 4
+-.IX Item "P"
+-Dump the \s-1RTL\s0 in the assembler output as a comment before each instruction.
+-Also turns on \fB\-dp\fR annotation.
+-.IP "\fBv\fR" 4
+-.IX Item "v"
+-For each of the other indicated dump files (except for
+-\&\fI\fIfile\fI.00.rtl\fR), dump a representation of the control flow graph
+-suitable for viewing with \s-1VCG\s0 to \fI\fIfile\fI.\fIpass\fI.vcg\fR.
+-.IP "\fBx\fR" 4
+-.IX Item "x"
+-Just generate \s-1RTL\s0 for a function instead of compiling it. Usually used
+-with \fBr\fR.
+-.IP "\fBy\fR" 4
+-.IX Item "y"
+-Dump debugging information during parsing, to standard error.
+-.RE
+-.RS 4
+-.RE
+-.IP "\fB\-fdump\-unnumbered\fR" 4
+-.IX Item "-fdump-unnumbered"
+-When doing debugging dumps (see \fB\-d\fR option above), suppress instruction
+-numbers and line number note output. This makes it more feasible to
+-use diff on debugging dumps for compiler invocations with different
+-options, in particular with and without \fB\-g\fR.
+-.IP "\fB\-fdump\-translation\-unit\fR (C and \*(C+ only)" 4
+-.IX Item "-fdump-translation-unit (C and only)"
+-.PD 0
+-.IP "\fB\-fdump\-translation\-unit\-\fR\fIoptions\fR\fB \fR(C and \*(C+ only)" 4
+-.IX Item "-fdump-translation-unit-options (C and only)"
+-.PD
+-Dump a representation of the tree structure for the entire translation
+-unit to a file. The file name is made by appending \fI.tu\fR to the
+-source file name. If the \fB\-\fR\fIoptions\fR form is used, \fIoptions\fR
+-controls the details of the dump as described for the
+-\&\fB\-fdump\-tree\fR options.
+-.IP "\fB\-fdump\-class\-hierarchy\fR (\*(C+ only)" 4
+-.IX Item "-fdump-class-hierarchy ( only)"
+-.PD 0
+-.IP "\fB\-fdump\-class\-hierarchy\-\fR\fIoptions\fR\fB \fR(\*(C+ only)" 4
+-.IX Item "-fdump-class-hierarchy-options ( only)"
+-.PD
+-Dump a representation of each class's hierarchy and virtual function
+-table layout to a file. The file name is made by appending \fI.class\fR
+-to the source file name. If the \fB\-\fR\fIoptions\fR form is used,
+-\&\fIoptions\fR controls the details of the dump as described for the
+-\&\fB\-fdump\-tree\fR options.
+-.IP "\fB\-fdump\-tree\-\fR\fIswitch\fR\fB \fR(\*(C+ only)" 4
+-.IX Item "-fdump-tree-switch ( only)"
+-.PD 0
+-.IP "\fB\-fdump\-tree\-\fR\fIswitch\fR\fB\-\fR\fIoptions\fR\fB \fR(\*(C+ only)" 4
+-.IX Item "-fdump-tree-switch-options ( only)"
+-.PD
+-Control the dumping at various stages of processing the intermediate
+-language tree to a file. The file name is generated by appending a switch
+-specific suffix to the source file name. If the \fB\-\fR\fIoptions\fR
+-form is used, \fIoptions\fR is a list of \fB\-\fR separated options that
+-control the details of the dump. Not all options are applicable to all
+-dumps, those which are not meaningful will be ignored. The following
+-options are available
+-.RS 4
+-.IP "\fBaddress\fR" 4
+-.IX Item "address"
+-Print the address of each node. Usually this is not meaningful as it
+-changes according to the environment and source file. Its primary use
+-is for tying up a dump file with a debug environment.
+-.IP "\fBslim\fR" 4
+-.IX Item "slim"
+-Inhibit dumping of members of a scope or body of a function merely
+-because that scope has been reached. Only dump such items when they
+-are directly reachable by some other path.
+-.IP "\fBall\fR" 4
+-.IX Item "all"
+-Turn on all options.
+-.RE
+-.RS 4
+-.Sp
+-The following tree dumps are possible:
+-.IP "\fBoriginal\fR" 4
+-.IX Item "original"
+-Dump before any tree based optimization, to \fI\fIfile\fI.original\fR.
+-.IP "\fBoptimized\fR" 4
+-.IX Item "optimized"
+-Dump after all tree based optimization, to \fI\fIfile\fI.optimized\fR.
+-.IP "\fBinlined\fR" 4
+-.IX Item "inlined"
+-Dump after function inlining, to \fI\fIfile\fI.inlined\fR.
+-.RE
+-.RS 4
+-.RE
+-.IP "\fB\-frandom\-seed=\fR\fIstring\fR" 4
+-.IX Item "-frandom-seed=string"
+-This option provides a seed that \s-1GCC\s0 uses when it would otherwise use
+-random numbers. At present, this is used to generate certain symbol names
+-that have to be different in every compiled file.
+-.Sp
+-The \fIstring\fR should be different for every file you compile.
+-.IP "\fB\-fsched\-verbose=\fR\fIn\fR" 4
+-.IX Item "-fsched-verbose=n"
+-On targets that use instruction scheduling, this option controls the
+-amount of debugging output the scheduler prints. This information is
+-written to standard error, unless \fB\-dS\fR or \fB\-dR\fR is
+-specified, in which case it is output to the usual dump
+-listing file, \fI.sched\fR or \fI.sched2\fR respectively. However
+-for \fIn\fR greater than nine, the output is always printed to standard
+-error.
+-.Sp
+-For \fIn\fR greater than zero, \fB\-fsched\-verbose\fR outputs the
+-same information as \fB\-dRS\fR. For \fIn\fR greater than one, it
+-also output basic block probabilities, detailed ready list information
+-and unit/insn info. For \fIn\fR greater than two, it includes \s-1RTL\s0
+-at abort point, control-flow and regions info. And for \fIn\fR over
+-four, \fB\-fsched\-verbose\fR also includes dependence info.
+-.IP "\fB\-save\-temps\fR" 4
+-.IX Item "-save-temps"
+-Store the usual ``temporary'' intermediate files permanently; place them
+-in the current directory and name them based on the source file. Thus,
+-compiling \fIfoo.c\fR with \fB\-c \-save\-temps\fR would produce files
+-\&\fIfoo.i\fR and \fIfoo.s\fR, as well as \fIfoo.o\fR. This creates a
+-preprocessed \fIfoo.i\fR output file even though the compiler now
+-normally uses an integrated preprocessor.
+-.IP "\fB\-time\fR" 4
+-.IX Item "-time"
+-Report the \s-1CPU\s0 time taken by each subprocess in the compilation
+-sequence. For C source files, this is the compiler proper and assembler
+-(plus the linker if linking is done). The output looks like this:
+-.Sp
+-.Vb 2
+-\& # cc1 0.12 0.01
+-\& # as 0.00 0.01
+-.Ve
+-.Sp
+-The first number on each line is the ``user time,'' that is time spent
+-executing the program itself. The second number is ``system time,''
+-time spent executing operating system routines on behalf of the program.
+-Both numbers are in seconds.
+-.IP "\fB\-print\-file\-name=\fR\fIlibrary\fR" 4
+-.IX Item "-print-file-name=library"
+-Print the full absolute name of the library file \fIlibrary\fR that
+-would be used when linking\-\-\-and don't do anything else. With this
+-option, \s-1GCC\s0 does not compile or link anything; it just prints the
+-file name.
+-.IP "\fB\-print\-multi\-directory\fR" 4
+-.IX Item "-print-multi-directory"
+-Print the directory name corresponding to the multilib selected by any
+-other switches present in the command line. This directory is supposed
+-to exist in \fB\s-1GCC_EXEC_PREFIX\s0\fR.
+-.IP "\fB\-print\-multi\-lib\fR" 4
+-.IX Item "-print-multi-lib"
+-Print the mapping from multilib directory names to compiler switches
+-that enable them. The directory name is separated from the switches by
+-\&\fB;\fR, and each switch starts with an \fB@} instead of the
+-\&\f(CB@samp\fB{\-\fR, without spaces between multiple switches. This is supposed to
+-ease shell\-processing.
+-.IP "\fB\-print\-prog\-name=\fR\fIprogram\fR" 4
+-.IX Item "-print-prog-name=program"
+-Like \fB\-print\-file\-name\fR, but searches for a program such as \fBcpp\fR.
+-.IP "\fB\-print\-libgcc\-file\-name\fR" 4
+-.IX Item "-print-libgcc-file-name"
+-Same as \fB\-print\-file\-name=libgcc.a\fR.
+-.Sp
+-This is useful when you use \fB\-nostdlib\fR or \fB\-nodefaultlibs\fR
+-but you do want to link with \fIlibgcc.a\fR. You can do
+-.Sp
+-.Vb 1
+-\& gcc -nostdlib <files>... `gcc -print-libgcc-file-name`
+-.Ve
+-.IP "\fB\-print\-search\-dirs\fR" 4
+-.IX Item "-print-search-dirs"
+-Print the name of the configured installation directory and a list of
+-program and library directories gcc will search\-\-\-and don't do anything else.
+-.Sp
+-This is useful when gcc prints the error message
+-\&\fBinstallation problem, cannot exec cpp0: No such file or directory\fR.
+-To resolve this you either need to put \fIcpp0\fR and the other compiler
+-components where gcc expects to find them, or you can set the environment
+-variable \fB\s-1GCC_EXEC_PREFIX\s0\fR to the directory where you installed them.
+-Don't forget the trailing '/'.
+-.IP "\fB\-dumpmachine\fR" 4
+-.IX Item "-dumpmachine"
+-Print the compiler's target machine (for example,
+-\&\fBi686\-pc\-linux\-gnu\fR)\-\-\-and don't do anything else.
+-.IP "\fB\-dumpversion\fR" 4
+-.IX Item "-dumpversion"
+-Print the compiler version (for example, \fB3.0\fR)\-\-\-and don't do
+-anything else.
+-.IP "\fB\-dumpspecs\fR" 4
+-.IX Item "-dumpspecs"
+-Print the compiler's built-in specs\-\-\-and don't do anything else. (This
+-is used when \s-1GCC\s0 itself is being built.)
+-.Sh "Options That Control Optimization"
+-.IX Subsection "Options That Control Optimization"
+-These options control various sorts of optimizations.
+-.PP
+-Without any optimization option, the compiler's goal is to reduce the
+-cost of compilation and to make debugging produce the expected
+-results. Statements are independent: if you stop the program with a
+-breakpoint between statements, you can then assign a new value to any
+-variable or change the program counter to any other statement in the
+-function and get exactly the results you would expect from the source
+-code.
+-.PP
+-Turning on optimization flags makes the compiler attempt to improve
+-the performance and/or code size at the expense of compilation time
+-and possibly the ability to debug the program.
+-.PP
+-Not all optimizations are controlled directly by a flag. Only
+-optimizations that have a flag are listed.
+-.IP "\fB\-O\fR" 4
+-.IX Item "-O"
+-.PD 0
+-.IP "\fB\-O1\fR" 4
+-.IX Item "-O1"
+-.PD
+-Optimize. Optimizing compilation takes somewhat more time, and a lot
+-more memory for a large function.
+-.Sp
+-With \fB\-O\fR, the compiler tries to reduce code size and execution
+-time, without performing any optimizations that take a great deal of
+-compilation time.
+-.Sp
+-\&\fB\-O\fR turns on the following optimization flags:
+-\&\fB\-fdefer\-pop
+-\&\-fmerge\-constants
+-\&\-fthread\-jumps
+-\&\-floop\-optimize
+-\&\-fcrossjumping
+-\&\-fif\-conversion
+-\&\-fif\-conversion2
+-\&\-fdelayed\-branch
+-\&\-fguess\-branch\-probability
+-\&\-fcprop\-registers\fR
+-.Sp
+-\&\fB\-O\fR also turns on \fB\-fomit\-frame\-pointer\fR on machines
+-where doing so does not interfere with debugging.
+-.IP "\fB\-O2\fR" 4
+-.IX Item "-O2"
+-Optimize even more. \s-1GCC\s0 performs nearly all supported optimizations
+-that do not involve a space-speed tradeoff. The compiler does not
+-perform loop unrolling or function inlining when you specify \fB\-O2\fR.
+-As compared to \fB\-O\fR, this option increases both compilation time
+-and the performance of the generated code.
+-.Sp
+-\&\fB\-O2\fR turns on all optimization flags specified by \fB\-O\fR. It
+-also turns on the following optimization flags:
+-\&\fB\-fforce\-mem
+-\&\-foptimize\-sibling\-calls
+-\&\-fstrength\-reduce
+-\&\-fcse\-follow\-jumps \-fcse\-skip\-blocks
+-\&\-frerun\-cse\-after\-loop \-frerun\-loop\-opt
+-\&\-fgcse \-fgcse\-lm \-fgcse\-sm
+-\&\-fdelete\-null\-pointer\-checks
+-\&\-fexpensive\-optimizations
+-\&\-fregmove
+-\&\-fschedule\-insns \-fschedule\-insns2
+-\&\-fsched\-interblock \-fsched\-spec
+-\&\-fcaller\-saves
+-\&\-fpeephole2
+-\&\-freorder\-blocks \-freorder\-functions
+-\&\-fstrict\-aliasing
+-\&\-falign\-functions \-falign\-jumps
+-\&\-falign\-loops \-falign\-labels\fR
+-.Sp
+-Please note the warning under \fB\-fgcse\fR about
+-invoking \fB\-O2\fR on programs that use computed gotos.
+-.IP "\fB\-O3\fR" 4
+-.IX Item "-O3"
+-Optimize yet more. \fB\-O3\fR turns on all optimizations specified by
+-\&\fB\-O2\fR and also turns on the \fB\-finline\-functions\fR and
+-\&\fB\-frename\-registers\fR options.
+-.IP "\fB\-O0\fR" 4
+-.IX Item "-O0"
+-Do not optimize. This is the default.
+-.IP "\fB\-Os\fR" 4
+-.IX Item "-Os"
+-Optimize for size. \fB\-Os\fR enables all \fB\-O2\fR optimizations that
+-do not typically increase code size. It also performs further
+-optimizations designed to reduce code size.
+-.Sp
+-\&\fB\-Os\fR disables the following optimization flags:
+-\&\fB\-falign\-functions \-falign\-jumps \-falign\-loops
+-\&\-falign\-labels \-freorder\-blocks \-fprefetch\-loop\-arrays\fR
+-.Sp
+-If you use multiple \fB\-O\fR options, with or without level numbers,
+-the last such option is the one that is effective.
+-.PP
+-Options of the form \fB\-f\fR\fIflag\fR specify machine-independent
+-flags. Most flags have both positive and negative forms; the negative
+-form of \fB\-ffoo\fR would be \fB\-fno\-foo\fR. In the table
+-below, only one of the forms is listed\-\-\-the one you typically will
+-use. You can figure out the other form by either removing \fBno\-\fR
+-or adding it.
+-.PP
+-The following options control specific optimizations. They are either
+-activated by \fB\-O\fR options or are related to ones that are. You
+-can use the following flags in the rare cases when ``fine\-tuning'' of
+-optimizations to be performed is desired.
+-.IP "\fB\-fno\-default\-inline\fR" 4
+-.IX Item "-fno-default-inline"
+-Do not make member functions inline by default merely because they are
+-defined inside the class scope (\*(C+ only). Otherwise, when you specify
+-\&\fB\-O\fR, member functions defined inside class scope are compiled
+-inline by default; i.e., you don't need to add \fBinline\fR in front of
+-the member function name.
+-.IP "\fB\-fno\-defer\-pop\fR" 4
+-.IX Item "-fno-defer-pop"
+-Always pop the arguments to each function call as soon as that function
+-returns. For machines which must pop arguments after a function call,
+-the compiler normally lets arguments accumulate on the stack for several
+-function calls and pops them all at once.
+-.Sp
+-Disabled at levels \fB\-O\fR, \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fforce\-mem\fR" 4
+-.IX Item "-fforce-mem"
+-Force memory operands to be copied into registers before doing
+-arithmetic on them. This produces better code by making all memory
+-references potential common subexpressions. When they are not common
+-subexpressions, instruction combination should eliminate the separate
+-register\-load.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fforce\-addr\fR" 4
+-.IX Item "-fforce-addr"
+-Force memory address constants to be copied into registers before
+-doing arithmetic on them. This may produce better code just as
+-\&\fB\-fforce\-mem\fR may.
+-.IP "\fB\-fomit\-frame\-pointer\fR" 4
+-.IX Item "-fomit-frame-pointer"
+-Don't keep the frame pointer in a register for functions that
+-don't need one. This avoids the instructions to save, set up and
+-restore frame pointers; it also makes an extra register available
+-in many functions. \fBIt also makes debugging impossible on
+-some machines.\fR
+-.Sp
+-On some machines, such as the \s-1VAX\s0, this flag has no effect, because
+-the standard calling sequence automatically handles the frame pointer
+-and nothing is saved by pretending it doesn't exist. The
+-machine-description macro \f(CW\*(C`FRAME_POINTER_REQUIRED\*(C'\fR controls
+-whether a target machine supports this flag.
+-.Sp
+-Enabled at levels \fB\-O\fR, \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-foptimize\-sibling\-calls\fR" 4
+-.IX Item "-foptimize-sibling-calls"
+-Optimize sibling and tail recursive calls.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fno\-inline\fR" 4
+-.IX Item "-fno-inline"
+-Don't pay attention to the \f(CW\*(C`inline\*(C'\fR keyword. Normally this option
+-is used to keep the compiler from expanding any functions inline.
+-Note that if you are not optimizing, no functions can be expanded inline.
+-.IP "\fB\-finline\-functions\fR" 4
+-.IX Item "-finline-functions"
+-Integrate all simple functions into their callers. The compiler
+-heuristically decides which functions are simple enough to be worth
+-integrating in this way.
+-.Sp
+-If all calls to a given function are integrated, and the function is
+-declared \f(CW\*(C`static\*(C'\fR, then the function is normally not output as
+-assembler code in its own right.
+-.Sp
+-Enabled at level \fB\-O3\fR.
+-.IP "\fB\-finline\-limit=\fR\fIn\fR" 4
+-.IX Item "-finline-limit=n"
+-By default, gcc limits the size of functions that can be inlined. This flag
+-allows the control of this limit for functions that are explicitly marked as
+-inline (i.e., marked with the inline keyword or defined within the class
+-definition in c++). \fIn\fR is the size of functions that can be inlined in
+-number of pseudo instructions (not counting parameter handling). The default
+-value of \fIn\fR is 600.
+-Increasing this value can result in more inlined code at
+-the cost of compilation time and memory consumption. Decreasing usually makes
+-the compilation faster and less code will be inlined (which presumably
+-means slower programs). This option is particularly useful for programs that
+-use inlining heavily such as those based on recursive templates with \*(C+.
+-.Sp
+-Inlining is actually controlled by a number of parameters, which may be
+-specified individually by using \fB\-\-param\fR \fIname\fR\fB=\fR\fIvalue\fR.
+-The \fB\-finline\-limit=\fR\fIn\fR option sets some of these parameters
+-as follows:
+-.RS 4
+-.Sp
+-.Vb 10
+-\& @item max-inline-insns
+-\& is set to I<n>.
+-\& @item max-inline-insns-single
+-\& is set to I<n>/2.
+-\& @item max-inline-insns-auto
+-\& is set to I<n>/2.
+-\& @item min-inline-insns
+-\& is set to 130 or I<n>/4, whichever is smaller.
+-\& @item max-inline-insns-rtl
+-\& is set to I<n>.
+-.Ve
+-.RE
+-.RS 4
+-.Sp
+-Using \fB\-finline\-limit=600\fR thus results in the default settings
+-for these parameters. See below for a documentation of the individual
+-parameters controlling inlining.
+-.Sp
+-\&\fINote:\fR pseudo instruction represents, in this particular context, an
+-abstract measurement of function's size. In no way, it represents a count
+-of assembly instructions and as such its exact meaning might change from one
+-release to an another.
+-.RE
+-.IP "\fB\-fkeep\-inline\-functions\fR" 4
+-.IX Item "-fkeep-inline-functions"
+-Even if all calls to a given function are integrated, and the function
+-is declared \f(CW\*(C`static\*(C'\fR, nevertheless output a separate run-time
+-callable version of the function. This switch does not affect
+-\&\f(CW\*(C`extern inline\*(C'\fR functions.
+-.IP "\fB\-fkeep\-static\-consts\fR" 4
+-.IX Item "-fkeep-static-consts"
+-Emit variables declared \f(CW\*(C`static const\*(C'\fR when optimization isn't turned
+-on, even if the variables aren't referenced.
+-.Sp
+-\&\s-1GCC\s0 enables this option by default. If you want to force the compiler to
+-check if the variable was referenced, regardless of whether or not
+-optimization is turned on, use the \fB\-fno\-keep\-static\-consts\fR option.
+-.IP "\fB\-fmerge\-constants\fR" 4
+-.IX Item "-fmerge-constants"
+-Attempt to merge identical constants (string constants and floating point
+-constants) across compilation units.
+-.Sp
+-This option is the default for optimized compilation if the assembler and
+-linker support it. Use \fB\-fno\-merge\-constants\fR to inhibit this
+-behavior.
+-.Sp
+-Enabled at levels \fB\-O\fR, \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fmerge\-all\-constants\fR" 4
+-.IX Item "-fmerge-all-constants"
+-Attempt to merge identical constants and identical variables.
+-.Sp
+-This option implies \fB\-fmerge\-constants\fR. In addition to
+-\&\fB\-fmerge\-constants\fR this considers e.g. even constant initialized
+-arrays or initialized constant variables with integral or floating point
+-types. Languages like C or \*(C+ require each non-automatic variable to
+-have distinct location, so using this option will result in non-conforming
+-behavior.
+-.IP "\fB\-fno\-branch\-count\-reg\fR" 4
+-.IX Item "-fno-branch-count-reg"
+-Do not use ``decrement and branch'' instructions on a count register,
+-but instead generate a sequence of instructions that decrement a
+-register, compare it against zero, then branch based upon the result.
+-This option is only meaningful on architectures that support such
+-instructions, which include x86, PowerPC, \s-1IA\-64\s0 and S/390.
+-.Sp
+-The default is \fB\-fbranch\-count\-reg\fR, enabled when
+-\&\fB\-fstrength\-reduce\fR is enabled.
+-.IP "\fB\-fno\-function\-cse\fR" 4
+-.IX Item "-fno-function-cse"
+-Do not put function addresses in registers; make each instruction that
+-calls a constant function contain the function's address explicitly.
+-.Sp
+-This option results in less efficient code, but some strange hacks
+-that alter the assembler output may be confused by the optimizations
+-performed when this option is not used.
+-.Sp
+-The default is \fB\-ffunction\-cse\fR
+-.IP "\fB\-fno\-zero\-initialized\-in\-bss\fR" 4
+-.IX Item "-fno-zero-initialized-in-bss"
+-If the target supports a \s-1BSS\s0 section, \s-1GCC\s0 by default puts variables that
+-are initialized to zero into \s-1BSS\s0. This can save space in the resulting
+-code.
+-.Sp
+-This option turns off this behavior because some programs explicitly
+-rely on variables going to the data section. E.g., so that the
+-resulting executable can find the beginning of that section and/or make
+-assumptions based on that.
+-.Sp
+-The default is \fB\-fzero\-initialized\-in\-bss\fR.
+-.IP "\fB\-fstrength\-reduce\fR" 4
+-.IX Item "-fstrength-reduce"
+-Perform the optimizations of loop strength reduction and
+-elimination of iteration variables.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fthread\-jumps\fR" 4
+-.IX Item "-fthread-jumps"
+-Perform optimizations where we check to see if a jump branches to a
+-location where another comparison subsumed by the first is found. If
+-so, the first branch is redirected to either the destination of the
+-second branch or a point immediately following it, depending on whether
+-the condition is known to be true or false.
+-.Sp
+-Enabled at levels \fB\-O\fR, \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fcse\-follow\-jumps\fR" 4
+-.IX Item "-fcse-follow-jumps"
+-In common subexpression elimination, scan through jump instructions
+-when the target of the jump is not reached by any other path. For
+-example, when \s-1CSE\s0 encounters an \f(CW\*(C`if\*(C'\fR statement with an
+-\&\f(CW\*(C`else\*(C'\fR clause, \s-1CSE\s0 will follow the jump when the condition
+-tested is false.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fcse\-skip\-blocks\fR" 4
+-.IX Item "-fcse-skip-blocks"
+-This is similar to \fB\-fcse\-follow\-jumps\fR, but causes \s-1CSE\s0 to
+-follow jumps which conditionally skip over blocks. When \s-1CSE\s0
+-encounters a simple \f(CW\*(C`if\*(C'\fR statement with no else clause,
+-\&\fB\-fcse\-skip\-blocks\fR causes \s-1CSE\s0 to follow the jump around the
+-body of the \f(CW\*(C`if\*(C'\fR.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-frerun\-cse\-after\-loop\fR" 4
+-.IX Item "-frerun-cse-after-loop"
+-Re-run common subexpression elimination after loop optimizations has been
+-performed.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-frerun\-loop\-opt\fR" 4
+-.IX Item "-frerun-loop-opt"
+-Run the loop optimizer twice.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fgcse\fR" 4
+-.IX Item "-fgcse"
+-Perform a global common subexpression elimination pass.
+-This pass also performs global constant and copy propagation.
+-.Sp
+-\&\fINote:\fR When compiling a program using computed gotos, a \s-1GCC\s0
+-extension, you may get better runtime performance if you disable
+-the global common subexpression elimination pass by adding
+-\&\fB\-fno\-gcse\fR to the command line.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fgcse\-lm\fR" 4
+-.IX Item "-fgcse-lm"
+-When \fB\-fgcse\-lm\fR is enabled, global common subexpression elimination will
+-attempt to move loads which are only killed by stores into themselves. This
+-allows a loop containing a load/store sequence to be changed to a load outside
+-the loop, and a copy/store within the loop.
+-.Sp
+-Enabled by default when gcse is enabled.
+-.IP "\fB\-fgcse\-sm\fR" 4
+-.IX Item "-fgcse-sm"
+-When \fB\-fgcse\-sm\fR is enabled, A store motion pass is run after global common
+-subexpression elimination. This pass will attempt to move stores out of loops.
+-When used in conjunction with \fB\-fgcse\-lm\fR, loops containing a load/store sequence
+-can be changed to a load before the loop and a store after the loop.
+-.Sp
+-Enabled by default when gcse is enabled.
+-.IP "\fB\-floop\-optimize\fR" 4
+-.IX Item "-floop-optimize"
+-Perform loop optimizations: move constant expressions out of loops, simplify
+-exit test conditions and optionally do strength-reduction and loop unrolling as
+-well.
+-.Sp
+-Enabled at levels \fB\-O\fR, \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fcrossjumping\fR" 4
+-.IX Item "-fcrossjumping"
+-Perform cross-jumping transformation. This transformation unifies equivalent code and save code size. The
+-resulting code may or may not perform better than without cross\-jumping.
+-.Sp
+-Enabled at levels \fB\-O\fR, \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fif\-conversion\fR" 4
+-.IX Item "-fif-conversion"
+-Attempt to transform conditional jumps into branch-less equivalents. This
+-include use of conditional moves, min, max, set flags and abs instructions, and
+-some tricks doable by standard arithmetics. The use of conditional execution
+-on chips where it is available is controlled by \f(CW\*(C`if\-conversion2\*(C'\fR.
+-.Sp
+-Enabled at levels \fB\-O\fR, \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fif\-conversion2\fR" 4
+-.IX Item "-fif-conversion2"
+-Use conditional execution (where available) to transform conditional jumps into
+-branch-less equivalents.
+-.Sp
+-Enabled at levels \fB\-O\fR, \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fdelete\-null\-pointer\-checks\fR" 4
+-.IX Item "-fdelete-null-pointer-checks"
+-Use global dataflow analysis to identify and eliminate useless checks
+-for null pointers. The compiler assumes that dereferencing a null
+-pointer would have halted the program. If a pointer is checked after
+-it has already been dereferenced, it cannot be null.
+-.Sp
+-In some environments, this assumption is not true, and programs can
+-safely dereference null pointers. Use
+-\&\fB\-fno\-delete\-null\-pointer\-checks\fR to disable this optimization
+-for programs which depend on that behavior.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fexpensive\-optimizations\fR" 4
+-.IX Item "-fexpensive-optimizations"
+-Perform a number of minor optimizations that are relatively expensive.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-foptimize\-register\-move\fR" 4
+-.IX Item "-foptimize-register-move"
+-.PD 0
+-.IP "\fB\-fregmove\fR" 4
+-.IX Item "-fregmove"
+-.PD
+-Attempt to reassign register numbers in move instructions and as
+-operands of other simple instructions in order to maximize the amount of
+-register tying. This is especially helpful on machines with two-operand
+-instructions.
+-.Sp
+-Note \fB\-fregmove\fR and \fB\-foptimize\-register\-move\fR are the same
+-optimization.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fdelayed\-branch\fR" 4
+-.IX Item "-fdelayed-branch"
+-If supported for the target machine, attempt to reorder instructions
+-to exploit instruction slots available after delayed branch
+-instructions.
+-.Sp
+-Enabled at levels \fB\-O\fR, \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fschedule\-insns\fR" 4
+-.IX Item "-fschedule-insns"
+-If supported for the target machine, attempt to reorder instructions to
+-eliminate execution stalls due to required data being unavailable. This
+-helps machines that have slow floating point or memory load instructions
+-by allowing other instructions to be issued until the result of the load
+-or floating point instruction is required.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fschedule\-insns2\fR" 4
+-.IX Item "-fschedule-insns2"
+-Similar to \fB\-fschedule\-insns\fR, but requests an additional pass of
+-instruction scheduling after register allocation has been done. This is
+-especially useful on machines with a relatively small number of
+-registers and where memory load instructions take more than one cycle.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fno\-sched\-interblock\fR" 4
+-.IX Item "-fno-sched-interblock"
+-Don't schedule instructions across basic blocks. This is normally
+-enabled by default when scheduling before register allocation, i.e.
+-with \fB\-fschedule\-insns\fR or at \fB\-O2\fR or higher.
+-.IP "\fB\-fno\-sched\-spec\fR" 4
+-.IX Item "-fno-sched-spec"
+-Don't allow speculative motion of non-load instructions. This is normally
+-enabled by default when scheduling before register allocation, i.e.
+-with \fB\-fschedule\-insns\fR or at \fB\-O2\fR or higher.
+-.IP "\fB\-fsched\-spec\-load\fR" 4
+-.IX Item "-fsched-spec-load"
+-Allow speculative motion of some load instructions. This only makes
+-sense when scheduling before register allocation, i.e. with
+-\&\fB\-fschedule\-insns\fR or at \fB\-O2\fR or higher.
+-.IP "\fB\-fsched\-spec\-load\-dangerous\fR" 4
+-.IX Item "-fsched-spec-load-dangerous"
+-Allow speculative motion of more load instructions. This only makes
+-sense when scheduling before register allocation, i.e. with
+-\&\fB\-fschedule\-insns\fR or at \fB\-O2\fR or higher.
+-.IP "\fB\-fcaller\-saves\fR" 4
+-.IX Item "-fcaller-saves"
+-Enable values to be allocated in registers that will be clobbered by
+-function calls, by emitting extra instructions to save and restore the
+-registers around such calls. Such allocation is done only when it
+-seems to result in better code than would otherwise be produced.
+-.Sp
+-This option is always enabled by default on certain machines, usually
+-those which have no call-preserved registers to use instead.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fmove\-all\-movables\fR" 4
+-.IX Item "-fmove-all-movables"
+-Forces all invariant computations in loops to be moved
+-outside the loop.
+-.IP "\fB\-freduce\-all\-givs\fR" 4
+-.IX Item "-freduce-all-givs"
+-Forces all general-induction variables in loops to be
+-strength\-reduced.
+-.Sp
+-\&\fINote:\fR When compiling programs written in Fortran,
+-\&\fB\-fmove\-all\-movables\fR and \fB\-freduce\-all\-givs\fR are enabled
+-by default when you use the optimizer.
+-.Sp
+-These options may generate better or worse code; results are highly
+-dependent on the structure of loops within the source code.
+-.Sp
+-These two options are intended to be removed someday, once
+-they have helped determine the efficacy of various
+-approaches to improving loop optimizations.
+-.Sp
+-Please let us (<\fBgcc@gcc.gnu.org\fR> and <\fBfortran@gnu.org\fR>)
+-know how use of these options affects
+-the performance of your production code.
+-We're very interested in code that runs \fIslower\fR
+-when these options are \fIenabled\fR.
+-.IP "\fB\-fno\-peephole\fR" 4
+-.IX Item "-fno-peephole"
+-.PD 0
+-.IP "\fB\-fno\-peephole2\fR" 4
+-.IX Item "-fno-peephole2"
+-.PD
+-Disable any machine-specific peephole optimizations. The difference
+-between \fB\-fno\-peephole\fR and \fB\-fno\-peephole2\fR is in how they
+-are implemented in the compiler; some targets use one, some use the
+-other, a few use both.
+-.Sp
+-\&\fB\-fpeephole\fR is enabled by default.
+-\&\fB\-fpeephole2\fR enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fno\-guess\-branch\-probability\fR" 4
+-.IX Item "-fno-guess-branch-probability"
+-Do not guess branch probabilities using a randomized model.
+-.Sp
+-Sometimes gcc will opt to use a randomized model to guess branch
+-probabilities, when none are available from either profiling feedback
+-(\fB\-fprofile\-arcs\fR) or \fB_\|_builtin_expect\fR. This means that
+-different runs of the compiler on the same program may produce different
+-object code.
+-.Sp
+-In a hard real-time system, people don't want different runs of the
+-compiler to produce code that has different behavior; minimizing
+-non-determinism is of paramount import. This switch allows users to
+-reduce non\-determinism, possibly at the expense of inferior
+-optimization.
+-.Sp
+-The default is \fB\-fguess\-branch\-probability\fR at levels
+-\&\fB\-O\fR, \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-freorder\-blocks\fR" 4
+-.IX Item "-freorder-blocks"
+-Reorder basic blocks in the compiled function in order to reduce number of
+-taken branches and improve code locality.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR.
+-.IP "\fB\-freorder\-functions\fR" 4
+-.IX Item "-freorder-functions"
+-Reorder basic blocks in the compiled function in order to reduce number of
+-taken branches and improve code locality. This is implemented by using special
+-subsections \f(CW\*(C`text.hot\*(C'\fR for most frequently executed functions and
+-\&\f(CW\*(C`text.unlikely\*(C'\fR for unlikely executed functions. Reordering is done by
+-the linker so object file format must support named sections and linker must
+-place them in a reasonable way.
+-.Sp
+-Also profile feedback must be available in to make this option effective. See
+-\&\fB\-fprofile\-arcs\fR for details.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-fstrict\-aliasing\fR" 4
+-.IX Item "-fstrict-aliasing"
+-Allows the compiler to assume the strictest aliasing rules applicable to
+-the language being compiled. For C (and \*(C+), this activates
+-optimizations based on the type of expressions. In particular, an
+-object of one type is assumed never to reside at the same address as an
+-object of a different type, unless the types are almost the same. For
+-example, an \f(CW\*(C`unsigned int\*(C'\fR can alias an \f(CW\*(C`int\*(C'\fR, but not a
+-\&\f(CW\*(C`void*\*(C'\fR or a \f(CW\*(C`double\*(C'\fR. A character type may alias any other
+-type.
+-.Sp
+-Pay special attention to code like this:
+-.Sp
+-.Vb 4
+-\& union a_union {
+-\& int i;
+-\& double d;
+-\& };
+-.Ve
+-.Sp
+-.Vb 5
+-\& int f() {
+-\& a_union t;
+-\& t.d = 3.0;
+-\& return t.i;
+-\& }
+-.Ve
+-.Sp
+-The practice of reading from a different union member than the one most
+-recently written to (called ``type\-punning'') is common. Even with
+-\&\fB\-fstrict\-aliasing\fR, type-punning is allowed, provided the memory
+-is accessed through the union type. So, the code above will work as
+-expected. However, this code might not:
+-.Sp
+-.Vb 7
+-\& int f() {
+-\& a_union t;
+-\& int* ip;
+-\& t.d = 3.0;
+-\& ip = &t.i;
+-\& return *ip;
+-\& }
+-.Ve
+-.Sp
+-Every language that wishes to perform language-specific alias analysis
+-should define a function that computes, given an \f(CW\*(C`tree\*(C'\fR
+-node, an alias set for the node. Nodes in different alias sets are not
+-allowed to alias. For an example, see the C front-end function
+-\&\f(CW\*(C`c_get_alias_set\*(C'\fR.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.IP "\fB\-falign\-functions\fR" 4
+-.IX Item "-falign-functions"
+-.PD 0
+-.IP "\fB\-falign\-functions=\fR\fIn\fR" 4
+-.IX Item "-falign-functions=n"
+-.PD
+-Align the start of functions to the next power-of-two greater than
+-\&\fIn\fR, skipping up to \fIn\fR bytes. For instance,
+-\&\fB\-falign\-functions=32\fR aligns functions to the next 32\-byte
+-boundary, but \fB\-falign\-functions=24\fR would align to the next
+-32\-byte boundary only if this can be done by skipping 23 bytes or less.
+-.Sp
+-\&\fB\-fno\-align\-functions\fR and \fB\-falign\-functions=1\fR are
+-equivalent and mean that functions will not be aligned.
+-.Sp
+-Some assemblers only support this flag when \fIn\fR is a power of two;
+-in that case, it is rounded up.
+-.Sp
+-If \fIn\fR is not specified or is zero, use a machine-dependent default.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR.
+-.IP "\fB\-falign\-labels\fR" 4
+-.IX Item "-falign-labels"
+-.PD 0
+-.IP "\fB\-falign\-labels=\fR\fIn\fR" 4
+-.IX Item "-falign-labels=n"
+-.PD
+-Align all branch targets to a power-of-two boundary, skipping up to
+-\&\fIn\fR bytes like \fB\-falign\-functions\fR. This option can easily
+-make code slower, because it must insert dummy operations for when the
+-branch target is reached in the usual flow of the code.
+-.Sp
+-\&\fB\-fno\-align\-labels\fR and \fB\-falign\-labels=1\fR are
+-equivalent and mean that labels will not be aligned.
+-.Sp
+-If \fB\-falign\-loops\fR or \fB\-falign\-jumps\fR are applicable and
+-are greater than this value, then their values are used instead.
+-.Sp
+-If \fIn\fR is not specified or is zero, use a machine-dependent default
+-which is very likely to be \fB1\fR, meaning no alignment.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR.
+-.IP "\fB\-falign\-loops\fR" 4
+-.IX Item "-falign-loops"
+-.PD 0
+-.IP "\fB\-falign\-loops=\fR\fIn\fR" 4
+-.IX Item "-falign-loops=n"
+-.PD
+-Align loops to a power-of-two boundary, skipping up to \fIn\fR bytes
+-like \fB\-falign\-functions\fR. The hope is that the loop will be
+-executed many times, which will make up for any execution of the dummy
+-operations.
+-.Sp
+-\&\fB\-fno\-align\-loops\fR and \fB\-falign\-loops=1\fR are
+-equivalent and mean that loops will not be aligned.
+-.Sp
+-If \fIn\fR is not specified or is zero, use a machine-dependent default.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR.
+-.IP "\fB\-falign\-jumps\fR" 4
+-.IX Item "-falign-jumps"
+-.PD 0
+-.IP "\fB\-falign\-jumps=\fR\fIn\fR" 4
+-.IX Item "-falign-jumps=n"
+-.PD
+-Align branch targets to a power-of-two boundary, for branch targets
+-where the targets can only be reached by jumping, skipping up to \fIn\fR
+-bytes like \fB\-falign\-functions\fR. In this case, no dummy operations
+-need be executed.
+-.Sp
+-\&\fB\-fno\-align\-jumps\fR and \fB\-falign\-jumps=1\fR are
+-equivalent and mean that loops will not be aligned.
+-.Sp
+-If \fIn\fR is not specified or is zero, use a machine-dependent default.
+-.Sp
+-Enabled at levels \fB\-O2\fR, \fB\-O3\fR.
+-.IP "\fB\-frename\-registers\fR" 4
+-.IX Item "-frename-registers"
+-Attempt to avoid false dependencies in scheduled code by making use
+-of registers left over after register allocation. This optimization
+-will most benefit processors with lots of registers. It can, however,
+-make debugging impossible, since variables will no longer stay in
+-a ``home register''.
+-.Sp
+-Enabled at levels \fB\-O3\fR.
+-.IP "\fB\-fno\-cprop\-registers\fR" 4
+-.IX Item "-fno-cprop-registers"
+-After register allocation and post-register allocation instruction splitting,
+-we perform a copy-propagation pass to try to reduce scheduling dependencies
+-and occasionally eliminate the copy.
+-.Sp
+-Disabled at levels \fB\-O\fR, \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR.
+-.PP
+-The following options control compiler behavior regarding floating
+-point arithmetic. These options trade off between speed and
+-correctness. All must be specifically enabled.
+-.IP "\fB\-ffloat\-store\fR" 4
+-.IX Item "-ffloat-store"
+-Do not store floating point variables in registers, and inhibit other
+-options that might change whether a floating point value is taken from a
+-register or memory.
+-.Sp
+-This option prevents undesirable excess precision on machines such as
+-the 68000 where the floating registers (of the 68881) keep more
+-precision than a \f(CW\*(C`double\*(C'\fR is supposed to have. Similarly for the
+-x86 architecture. For most programs, the excess precision does only
+-good, but a few programs rely on the precise definition of \s-1IEEE\s0 floating
+-point. Use \fB\-ffloat\-store\fR for such programs, after modifying
+-them to store all pertinent intermediate computations into variables.
+-.IP "\fB\-ffast\-math\fR" 4
+-.IX Item "-ffast-math"
+-Sets \fB\-fno\-math\-errno\fR, \fB\-funsafe\-math\-optimizations\fR, \fB\-fno\-trapping\-math\fR, \fB\-ffinite\-math\-only\fR and \fB\-fno\-signaling\-nans\fR.
+-.Sp
+-This option causes the preprocessor macro \f(CW\*(C`_\|_FAST_MATH_\|_\*(C'\fR to be defined.
+-.Sp
+-This option should never be turned on by any \fB\-O\fR option since
+-it can result in incorrect output for programs which depend on
+-an exact implementation of \s-1IEEE\s0 or \s-1ISO\s0 rules/specifications for
+-math functions.
+-.IP "\fB\-fno\-math\-errno\fR" 4
+-.IX Item "-fno-math-errno"
+-Do not set \s-1ERRNO\s0 after calling math functions that are executed
+-with a single instruction, e.g., sqrt. A program that relies on
+-\&\s-1IEEE\s0 exceptions for math error handling may want to use this flag
+-for speed while maintaining \s-1IEEE\s0 arithmetic compatibility.
+-.Sp
+-This option should never be turned on by any \fB\-O\fR option since
+-it can result in incorrect output for programs which depend on
+-an exact implementation of \s-1IEEE\s0 or \s-1ISO\s0 rules/specifications for
+-math functions.
+-.Sp
+-The default is \fB\-fmath\-errno\fR.
+-.IP "\fB\-funsafe\-math\-optimizations\fR" 4
+-.IX Item "-funsafe-math-optimizations"
+-Allow optimizations for floating-point arithmetic that (a) assume
+-that arguments and results are valid and (b) may violate \s-1IEEE\s0 or
+-\&\s-1ANSI\s0 standards. When used at link\-time, it may include libraries
+-or startup files that change the default \s-1FPU\s0 control word or other
+-similar optimizations.
+-.Sp
+-This option should never be turned on by any \fB\-O\fR option since
+-it can result in incorrect output for programs which depend on
+-an exact implementation of \s-1IEEE\s0 or \s-1ISO\s0 rules/specifications for
+-math functions.
+-.Sp
+-The default is \fB\-fno\-unsafe\-math\-optimizations\fR.
+-.IP "\fB\-ffinite\-math\-only\fR" 4
+-.IX Item "-ffinite-math-only"
+-Allow optimizations for floating-point arithmetic that assume
+-that arguments and results are not NaNs or +\-Infs.
+-.Sp
+-This option should never be turned on by any \fB\-O\fR option since
+-it can result in incorrect output for programs which depend on
+-an exact implementation of \s-1IEEE\s0 or \s-1ISO\s0 rules/specifications.
+-.Sp
+-The default is \fB\-fno\-finite\-math\-only\fR.
+-.IP "\fB\-fno\-trapping\-math\fR" 4
+-.IX Item "-fno-trapping-math"
+-Compile code assuming that floating-point operations cannot generate
+-user-visible traps. These traps include division by zero, overflow,
+-underflow, inexact result and invalid operation. This option implies
+-\&\fB\-fno\-signaling\-nans\fR. Setting this option may allow faster
+-code if one relies on ``non\-stop'' \s-1IEEE\s0 arithmetic, for example.
+-.Sp
+-This option should never be turned on by any \fB\-O\fR option since
+-it can result in incorrect output for programs which depend on
+-an exact implementation of \s-1IEEE\s0 or \s-1ISO\s0 rules/specifications for
+-math functions.
+-.Sp
+-The default is \fB\-ftrapping\-math\fR.
+-.IP "\fB\-fsignaling\-nans\fR" 4
+-.IX Item "-fsignaling-nans"
+-Compile code assuming that \s-1IEEE\s0 signaling NaNs may generate user-visible
+-traps during floating-point operations. Setting this option disables
+-optimizations that may change the number of exceptions visible with
+-signaling NaNs. This option implies \fB\-ftrapping\-math\fR.
+-.Sp
+-This option causes the preprocessor macro \f(CW\*(C`_\|_SUPPORT_SNAN_\|_\*(C'\fR to
+-be defined.
+-.Sp
+-The default is \fB\-fno\-signaling\-nans\fR.
+-.Sp
+-This option is experimental and does not currently guarantee to
+-disable all \s-1GCC\s0 optimizations that affect signaling NaN behavior.
+-.IP "\fB\-fsingle\-precision\-constant\fR" 4
+-.IX Item "-fsingle-precision-constant"
+-Treat floating point constant as single precision constant instead of
+-implicitly converting it to double precision constant.
+-.PP
+-The following options control optimizations that may improve
+-performance, but are not enabled by any \fB\-O\fR options. This
+-section includes experimental options that may produce broken code.
+-.IP "\fB\-fbranch\-probabilities\fR" 4
+-.IX Item "-fbranch-probabilities"
+-After running a program compiled with \fB\-fprofile\-arcs\fR, you can compile it a second time using
+-\&\fB\-fbranch\-probabilities\fR, to improve optimizations based on
+-the number of times each branch was taken. When the program
+-compiled with \fB\-fprofile\-arcs\fR exits it saves arc execution
+-counts to a file called \fI\fIsourcename\fI.da\fR for each source
+-file The information in this data file is very dependent on the
+-structure of the generated code, so you must use the same source code
+-and the same optimization options for both compilations.
+-.Sp
+-With \fB\-fbranch\-probabilities\fR, \s-1GCC\s0 puts a
+-\&\fB\s-1REG_BR_PROB\s0\fR note on each \fB\s-1JUMP_INSN\s0\fR and \fB\s-1CALL_INSN\s0\fR.
+-These can be used to improve optimization. Currently, they are only
+-used in one place: in \fIreorg.c\fR, instead of guessing which path a
+-branch is mostly to take, the \fB\s-1REG_BR_PROB\s0\fR values are used to
+-exactly determine which path is taken more often.
+-.IP "\fB\-fnew\-ra\fR" 4
+-.IX Item "-fnew-ra"
+-Use a graph coloring register allocator. Currently this option is meant
+-only for testing. Users should not specify this option, since it is not
+-yet ready for production use.
+-.IP "\fB\-ftracer\fR" 4
+-.IX Item "-ftracer"
+-Perform tail duplication to enlarge superblock size. This transformation
+-simplifies the control flow of the function allowing other optimizations to do
+-better job.
+-.IP "\fB\-funroll\-loops\fR" 4
+-.IX Item "-funroll-loops"
+-Unroll loops whose number of iterations can be determined at compile
+-time or upon entry to the loop. \fB\-funroll\-loops\fR implies both
+-\&\fB\-fstrength\-reduce\fR and \fB\-frerun\-cse\-after\-loop\fR. This
+-option makes code larger, and may or may not make it run faster.
+-.IP "\fB\-funroll\-all\-loops\fR" 4
+-.IX Item "-funroll-all-loops"
+-Unroll all loops, even if their number of iterations is uncertain when
+-the loop is entered. This usually makes programs run more slowly.
+-\&\fB\-funroll\-all\-loops\fR implies the same options as
+-\&\fB\-funroll\-loops\fR,
+-.IP "\fB\-fprefetch\-loop\-arrays\fR" 4
+-.IX Item "-fprefetch-loop-arrays"
+-If supported by the target machine, generate instructions to prefetch
+-memory to improve the performance of loops that access large arrays.
+-.Sp
+-Disabled at level \fB\-Os\fR.
+-.IP "\fB\-ffunction\-sections\fR" 4
+-.IX Item "-ffunction-sections"
+-.PD 0
+-.IP "\fB\-fdata\-sections\fR" 4
+-.IX Item "-fdata-sections"
+-.PD
+-Place each function or data item into its own section in the output
+-file if the target supports arbitrary sections. The name of the
+-function or the name of the data item determines the section's name
+-in the output file.
+-.Sp
+-Use these options on systems where the linker can perform optimizations
+-to improve locality of reference in the instruction space. Most systems
+-using the \s-1ELF\s0 object format and \s-1SPARC\s0 processors running Solaris 2 have
+-linkers with such optimizations. \s-1AIX\s0 may have these optimizations in
+-the future.
+-.Sp
+-Only use these options when there are significant benefits from doing
+-so. When you specify these options, the assembler and linker will
+-create larger object and executable files and will also be slower.
+-You will not be able to use \f(CW\*(C`gprof\*(C'\fR on all systems if you
+-specify this option and you may have problems with debugging if
+-you specify both this option and \fB\-g\fR.
+-.IP "\fB\-fssa\fR" 4
+-.IX Item "-fssa"
+-Perform optimizations in static single assignment form. Each function's
+-flow graph is translated into \s-1SSA\s0 form, optimizations are performed, and
+-the flow graph is translated back from \s-1SSA\s0 form. Users should not
+-specify this option, since it is not yet ready for production use.
+-.IP "\fB\-fssa\-ccp\fR" 4
+-.IX Item "-fssa-ccp"
+-Perform Sparse Conditional Constant Propagation in \s-1SSA\s0 form. Requires
+-\&\fB\-fssa\fR. Like \fB\-fssa\fR, this is an experimental feature.
+-.IP "\fB\-fssa\-dce\fR" 4
+-.IX Item "-fssa-dce"
+-Perform aggressive dead-code elimination in \s-1SSA\s0 form. Requires \fB\-fssa\fR.
+-Like \fB\-fssa\fR, this is an experimental feature.
+-.IP "\fB\-\-param\fR \fIname\fR\fB=\fR\fIvalue\fR" 4
+-.IX Item "--param name=value"
+-In some places, \s-1GCC\s0 uses various constants to control the amount of
+-optimization that is done. For example, \s-1GCC\s0 will not inline functions
+-that contain more that a certain number of instructions. You can
+-control some of these constants on the command-line using the
+-\&\fB\-\-param\fR option.
+-.Sp
+-The names of specific parameters, and the meaning of the values, are
+-tied to the internals of the compiler, and are subject to change
+-without notice in future releases.
+-.Sp
+-In each case, the \fIvalue\fR is an integer. The allowable choices for
+-\&\fIname\fR are given in the following table:
+-.RS 4
+-.IP "\fBmax-crossjump-edges\fR" 4
+-.IX Item "max-crossjump-edges"
+-The maximum number of incoming edges to consider for crossjumping.
+-The algorithm used by \fB\-fcrossjumping\fR is O(N^2) in
+-the number of edges incoming to each block. Increasing values mean
+-more aggressive optimization, making the compile time increase with
+-probably small improvement in executable size.
+-.IP "\fBmax-delay-slot-insn-search\fR" 4
+-.IX Item "max-delay-slot-insn-search"
+-The maximum number of instructions to consider when looking for an
+-instruction to fill a delay slot. If more than this arbitrary number of
+-instructions is searched, the time savings from filling the delay slot
+-will be minimal so stop searching. Increasing values mean more
+-aggressive optimization, making the compile time increase with probably
+-small improvement in executable run time.
+-.IP "\fBmax-delay-slot-live-search\fR" 4
+-.IX Item "max-delay-slot-live-search"
+-When trying to fill delay slots, the maximum number of instructions to
+-consider when searching for a block with valid live register
+-information. Increasing this arbitrarily chosen value means more
+-aggressive optimization, increasing the compile time. This parameter
+-should be removed when the delay slot code is rewritten to maintain the
+-control-flow graph.
+-.IP "\fBmax-gcse-memory\fR" 4
+-.IX Item "max-gcse-memory"
+-The approximate maximum amount of memory that will be allocated in
+-order to perform the global common subexpression elimination
+-optimization. If more memory than specified is required, the
+-optimization will not be done.
+-.IP "\fBmax-gcse-passes\fR" 4
+-.IX Item "max-gcse-passes"
+-The maximum number of passes of \s-1GCSE\s0 to run.
+-.IP "\fBmax-pending-list-length\fR" 4
+-.IX Item "max-pending-list-length"
+-The maximum number of pending dependencies scheduling will allow
+-before flushing the current state and starting over. Large functions
+-with few branches or calls can create excessively large lists which
+-needlessly consume memory and resources.
+-.IP "\fBmax-inline-insns-single\fR" 4
+-.IX Item "max-inline-insns-single"
+-Several parameters control the tree inliner used in gcc.
+-This number sets the maximum number of instructions (counted in gcc's
+-internal representation) in a single function that the tree inliner
+-will consider for inlining. This only affects functions declared
+-inline and methods implemented in a class declaration (\*(C+).
+-The default value is 300.
+-.IP "\fBmax-inline-insns-auto\fR" 4
+-.IX Item "max-inline-insns-auto"
+-When you use \fB\-finline\-functions\fR (included in \fB\-O3\fR),
+-a lot of functions that would otherwise not be considered for inlining
+-by the compiler will be investigated. To those functions, a different
+-(more restrictive) limit compared to functions declared inline can
+-be applied.
+-The default value is 300.
+-.IP "\fBmax-inline-insns\fR" 4
+-.IX Item "max-inline-insns"
+-The tree inliner does decrease the allowable size for single functions
+-to be inlined after we already inlined the number of instructions
+-given here by repeated inlining. This number should be a factor of
+-two or more larger than the single function limit.
+-Higher numbers result in better runtime performance, but incur higher
+-compile-time resource (\s-1CPU\s0 time, memory) requirements and result in
+-larger binaries. Very high values are not advisable, as too large
+-binaries may adversely affect runtime performance.
+-The default value is 600.
+-.IP "\fBmax-inline-slope\fR" 4
+-.IX Item "max-inline-slope"
+-After exceeding the maximum number of inlined instructions by repeated
+-inlining, a linear function is used to decrease the allowable size
+-for single functions. The slope of that function is the negative
+-reciprocal of the number specified here.
+-The default value is 32.
+-.IP "\fBmin-inline-insns\fR" 4
+-.IX Item "min-inline-insns"
+-The repeated inlining is throttled more and more by the linear function
+-after exceeding the limit. To avoid too much throttling, a minimum for
+-this function is specified here to allow repeated inlining for very small
+-functions even when a lot of repeated inlining already has been done.
+-The default value is 130.
+-.IP "\fBmax-inline-insns-rtl\fR" 4
+-.IX Item "max-inline-insns-rtl"
+-For languages that use the \s-1RTL\s0 inliner (this happens at a later stage
+-than tree inlining), you can set the maximum allowable size (counted
+-in \s-1RTL\s0 instructions) for the \s-1RTL\s0 inliner with this parameter.
+-The default value is 600.
+-.IP "\fBmax-unrolled-insns\fR" 4
+-.IX Item "max-unrolled-insns"
+-The maximum number of instructions that a loop should have if that loop
+-is unrolled, and if the loop is unrolled, it determines how many times
+-the loop code is unrolled.
+-.IP "\fBhot-bb-count-fraction\fR" 4
+-.IX Item "hot-bb-count-fraction"
+-Select fraction of the maximal count of repetitions of basic block in program
+-given basic block needs to have to be considered hot.
+-.IP "\fBhot-bb-frequency-fraction\fR" 4
+-.IX Item "hot-bb-frequency-fraction"
+-Select fraction of the maximal frequency of executions of basic block in
+-function given basic block needs to have to be considered hot
+-.IP "\fBtracer-dynamic-coverage\fR" 4
+-.IX Item "tracer-dynamic-coverage"
+-.PD 0
+-.IP "\fBtracer-dynamic-coverage-feedback\fR" 4
+-.IX Item "tracer-dynamic-coverage-feedback"
+-.PD
+-This value is used to limit superblock formation once the given percentage of
+-executed instructions is covered. This limits unnecessary code size
+-expansion.
+-.Sp
+-The \fBtracer-dynamic-coverage-feedback\fR is used only when profile
+-feedback is available. The real profiles (as opposed to statically estimated
+-ones) are much less balanced allowing the threshold to be larger value.
+-.IP "\fBtracer-max-code-growth\fR" 4
+-.IX Item "tracer-max-code-growth"
+-Stop tail duplication once code growth has reached given percentage. This is
+-rather hokey argument, as most of the duplicates will be eliminated later in
+-cross jumping, so it may be set to much higher values than is the desired code
+-growth.
+-.IP "\fBtracer-min-branch-ratio\fR" 4
+-.IX Item "tracer-min-branch-ratio"
+-Stop reverse growth when the reverse probability of best edge is less than this
+-threshold (in percent).
+-.IP "\fBtracer-min-branch-ratio\fR" 4
+-.IX Item "tracer-min-branch-ratio"
+-.PD 0
+-.IP "\fBtracer-min-branch-ratio-feedback\fR" 4
+-.IX Item "tracer-min-branch-ratio-feedback"
+-.PD
+-Stop forward growth if the best edge do have probability lower than this
+-threshold.
+-.Sp
+-Similarly to \fBtracer-dynamic-coverage\fR two values are present, one for
+-compilation for profile feedback and one for compilation without. The value
+-for compilation with profile feedback needs to be more conservative (higher) in
+-order to make tracer effective.
+-.IP "\fBggc-min-expand\fR" 4
+-.IX Item "ggc-min-expand"
+-\&\s-1GCC\s0 uses a garbage collector to manage its own memory allocation. This
+-parameter specifies the minimum percentage by which the garbage
+-collector's heap should be allowed to expand between collections.
+-Tuning this may improve compilation speed; it has no effect on code
+-generation.
+-.Sp
+-The default is 30% + 70% * (\s-1RAM/1GB\s0) with an upper bound of 100% when
+-\&\s-1RAM\s0 >= 1GB. If \f(CW\*(C`getrlimit\*(C'\fR is available, the notion of \*(L"\s-1RAM\s0\*(R" is
+-the smallest of actual \s-1RAM\s0, \s-1RLIMIT_RSS\s0, \s-1RLIMIT_DATA\s0 and \s-1RLIMIT_AS\s0. If
+-\&\s-1GCC\s0 is not able to calculate \s-1RAM\s0 on a particular platform, the lower
+-bound of 30% is used. Setting this parameter and
+-\&\fBggc-min-heapsize\fR to zero causes a full collection to occur at
+-every opportunity. This is extremely slow, but can be useful for
+-debugging.
+-.IP "\fBggc-min-heapsize\fR" 4
+-.IX Item "ggc-min-heapsize"
+-Minimum size of the garbage collector's heap before it begins bothering
+-to collect garbage. The first collection occurs after the heap expands
+-by \fBggc-min-expand\fR% beyond \fBggc-min-heapsize\fR. Again,
+-tuning this may improve compilation speed, and has no effect on code
+-generation.
+-.Sp
+-The default is \s-1RAM/8\s0, with a lower bound of 4096 (four megabytes) and an
+-upper bound of 131072 (128 megabytes). If \f(CW\*(C`getrlimit\*(C'\fR is
+-available, the notion of \*(L"\s-1RAM\s0\*(R" is the smallest of actual \s-1RAM\s0,
+-\&\s-1RLIMIT_RSS\s0, \s-1RLIMIT_DATA\s0 and \s-1RLIMIT_AS\s0. If \s-1GCC\s0 is not able to calculate
+-\&\s-1RAM\s0 on a particular platform, the lower bound is used. Setting this
+-parameter very large effectively disables garbage collection. Setting
+-this parameter and \fBggc-min-expand\fR to zero causes a full
+-collection to occur at every opportunity.
+-.RE
+-.RS 4
+-.RE
+-.Sh "Options Controlling the Preprocessor"
+-.IX Subsection "Options Controlling the Preprocessor"
+-These options control the C preprocessor, which is run on each C source
+-file before actual compilation.
+-.PP
+-If you use the \fB\-E\fR option, nothing is done except preprocessing.
+-Some of these options make sense only together with \fB\-E\fR because
+-they cause the preprocessor output to be unsuitable for actual
+-compilation.
+-.PP
+-You can use \fB\-Wp,\fR\fIoption\fR to bypass the compiler driver
+-and pass \fIoption\fR directly through to the preprocessor. If
+-\&\fIoption\fR contains commas, it is split into multiple options at the
+-commas. However, many options are modified, translated or interpreted
+-by the compiler driver before being passed to the preprocessor, and
+-\&\fB\-Wp\fR forcibly bypasses this phase. The preprocessor's direct
+-interface is undocumented and subject to change, so whenever possible
+-you should avoid using \fB\-Wp\fR and let the driver handle the
+-options instead.
+-.IP "\fB\-D\fR \fIname\fR" 4
+-.IX Item "-D name"
+-Predefine \fIname\fR as a macro, with definition \f(CW1\fR.
+-.IP "\fB\-D\fR \fIname\fR\fB=\fR\fIdefinition\fR" 4
+-.IX Item "-D name=definition"
+-Predefine \fIname\fR as a macro, with definition \fIdefinition\fR.
+-There are no restrictions on the contents of \fIdefinition\fR, but if
+-you are invoking the preprocessor from a shell or shell-like program you
+-may need to use the shell's quoting syntax to protect characters such as
+-spaces that have a meaning in the shell syntax.
+-.Sp
+-If you wish to define a function-like macro on the command line, write
+-its argument list with surrounding parentheses before the equals sign
+-(if any). Parentheses are meaningful to most shells, so you will need
+-to quote the option. With \fBsh\fR and \fBcsh\fR,
+-\&\fB\-D'\fR\fIname\fR\fB(\fR\fIargs...\fR\fB)=\fR\fIdefinition\fR\fB'\fR works.
+-.Sp
+-\&\fB\-D\fR and \fB\-U\fR options are processed in the order they
+-are given on the command line. All \fB\-imacros\fR \fIfile\fR and
+-\&\fB\-include\fR \fIfile\fR options are processed after all
+-\&\fB\-D\fR and \fB\-U\fR options.
+-.IP "\fB\-U\fR \fIname\fR" 4
+-.IX Item "-U name"
+-Cancel any previous definition of \fIname\fR, either built in or
+-provided with a \fB\-D\fR option.
+-.IP "\fB\-undef\fR" 4
+-.IX Item "-undef"
+-Do not predefine any system-specific or GCC-specific macros. The
+-standard predefined macros remain defined.
+-.IP "\fB\-I\fR \fIdir\fR" 4
+-.IX Item "-I dir"
+-Add the directory \fIdir\fR to the list of directories to be searched
+-for header files.
+-Directories named by \fB\-I\fR are searched before the standard
+-system include directories. If the directory \fIdir\fR is a standard
+-system include directory, the option is ignored to ensure that the
+-default search order for system directories and the special treatment
+-of system headers are not defeated
+-\&.
+-.IP "\fB\-o\fR \fIfile\fR" 4
+-.IX Item "-o file"
+-Write output to \fIfile\fR. This is the same as specifying \fIfile\fR
+-as the second non-option argument to \fBcpp\fR. \fBgcc\fR has a
+-different interpretation of a second non-option argument, so you must
+-use \fB\-o\fR to specify the output file.
+-.IP "\fB\-Wall\fR" 4
+-.IX Item "-Wall"
+-Turns on all optional warnings which are desirable for normal code. At
+-present this is \fB\-Wcomment\fR and \fB\-Wtrigraphs\fR. Note that
+-many of the preprocessor's warnings are on by default and have no
+-options to control them.
+-.IP "\fB\-Wcomment\fR" 4
+-.IX Item "-Wcomment"
+-.PD 0
+-.IP "\fB\-Wcomments\fR" 4
+-.IX Item "-Wcomments"
+-.PD
+-Warn whenever a comment-start sequence \fB/*\fR appears in a \fB/*\fR
+-comment, or whenever a backslash-newline appears in a \fB//\fR comment.
+-(Both forms have the same effect.)
+-.IP "\fB\-Wtrigraphs\fR" 4
+-.IX Item "-Wtrigraphs"
+-Warn if any trigraphs are encountered. This option used to take effect
+-only if \fB\-trigraphs\fR was also specified, but now works
+-independently. Warnings are not given for trigraphs within comments, as
+-they do not affect the meaning of the program.
+-.IP "\fB\-Wtraditional\fR" 4
+-.IX Item "-Wtraditional"
+-Warn about certain constructs that behave differently in traditional and
+-\&\s-1ISO\s0 C. Also warn about \s-1ISO\s0 C constructs that have no traditional C
+-equivalent, and problematic constructs which should be avoided.
+-.IP "\fB\-Wimport\fR" 4
+-.IX Item "-Wimport"
+-Warn the first time \fB#import\fR is used.
+-.IP "\fB\-Wundef\fR" 4
+-.IX Item "-Wundef"
+-Warn whenever an identifier which is not a macro is encountered in an
+-\&\fB#if\fR directive, outside of \fBdefined\fR. Such identifiers are
+-replaced with zero.
+-.IP "\fB\-Wunused\-macros\fR" 4
+-.IX Item "-Wunused-macros"
+-Warn about macros defined in the main file that are unused. A macro
+-is \fIused\fR if it is expanded or tested for existence at least once.
+-The preprocessor will also warn if the macro has not been used at the
+-time it is redefined or undefined.
+-.Sp
+-Built-in macros, macros defined on the command line, and macros
+-defined in include files are not warned about.
+-.Sp
+-\&\fBNote:\fR If a macro is actually used, but only used in skipped
+-conditional blocks, then \s-1CPP\s0 will report it as unused. To avoid the
+-warning in such a case, you might improve the scope of the macro's
+-definition by, for example, moving it into the first skipped block.
+-Alternatively, you could provide a dummy use with something like:
+-.Sp
+-.Vb 2
+-\& #if defined the_macro_causing_the_warning
+-\& #endif
+-.Ve
+-.IP "\fB\-Wendif\-labels\fR" 4
+-.IX Item "-Wendif-labels"
+-Warn whenever an \fB#else\fR or an \fB#endif\fR are followed by text.
+-This usually happens in code of the form
+-.Sp
+-.Vb 5
+-\& #if FOO
+-\& ...
+-\& #else FOO
+-\& ...
+-\& #endif FOO
+-.Ve
+-.Sp
+-The second and third \f(CW\*(C`FOO\*(C'\fR should be in comments, but often are not
+-in older programs. This warning is on by default.
+-.IP "\fB\-Werror\fR" 4
+-.IX Item "-Werror"
+-Make all warnings into hard errors. Source code which triggers warnings
+-will be rejected.
+-.IP "\fB\-Wsystem\-headers\fR" 4
+-.IX Item "-Wsystem-headers"
+-Issue warnings for code in system headers. These are normally unhelpful
+-in finding bugs in your own code, therefore suppressed. If you are
+-responsible for the system library, you may want to see them.
+-.IP "\fB\-w\fR" 4
+-.IX Item "-w"
+-Suppress all warnings, including those which \s-1GNU\s0 \s-1CPP\s0 issues by default.
+-.IP "\fB\-pedantic\fR" 4
+-.IX Item "-pedantic"
+-Issue all the mandatory diagnostics listed in the C standard. Some of
+-them are left out by default, since they trigger frequently on harmless
+-code.
+-.IP "\fB\-pedantic\-errors\fR" 4
+-.IX Item "-pedantic-errors"
+-Issue all the mandatory diagnostics, and make all mandatory diagnostics
+-into errors. This includes mandatory diagnostics that \s-1GCC\s0 issues
+-without \fB\-pedantic\fR but treats as warnings.
+-.IP "\fB\-M\fR" 4
+-.IX Item "-M"
+-Instead of outputting the result of preprocessing, output a rule
+-suitable for \fBmake\fR describing the dependencies of the main
+-source file. The preprocessor outputs one \fBmake\fR rule containing
+-the object file name for that source file, a colon, and the names of all
+-the included files, including those coming from \fB\-include\fR or
+-\&\fB\-imacros\fR command line options.
+-.Sp
+-Unless specified explicitly (with \fB\-MT\fR or \fB\-MQ\fR), the
+-object file name consists of the basename of the source file with any
+-suffix replaced with object file suffix. If there are many included
+-files then the rule is split into several lines using \fB\e\fR\-newline.
+-The rule has no commands.
+-.Sp
+-This option does not suppress the preprocessor's debug output, such as
+-\&\fB\-dM\fR. To avoid mixing such debug output with the dependency
+-rules you should explicitly specify the dependency output file with
+-\&\fB\-MF\fR, or use an environment variable like
+-\&\fB\s-1DEPENDENCIES_OUTPUT\s0\fR. Debug output
+-will still be sent to the regular output stream as normal.
+-.Sp
+-Passing \fB\-M\fR to the driver implies \fB\-E\fR, and suppresses
+-warnings with an implicit \fB\-w\fR.
+-.IP "\fB\-MM\fR" 4
+-.IX Item "-MM"
+-Like \fB\-M\fR but do not mention header files that are found in
+-system header directories, nor header files that are included,
+-directly or indirectly, from such a header.
+-.Sp
+-This implies that the choice of angle brackets or double quotes in an
+-\&\fB#include\fR directive does not in itself determine whether that
+-header will appear in \fB\-MM\fR dependency output. This is a
+-slight change in semantics from \s-1GCC\s0 versions 3.0 and earlier.
+-.IP "\fB\-MF\fR \fIfile\fR" 4
+-.IX Item "-MF file"
+-@anchor{\-MF}
+-When used with \fB\-M\fR or \fB\-MM\fR, specifies a
+-file to write the dependencies to. If no \fB\-MF\fR switch is given
+-the preprocessor sends the rules to the same place it would have sent
+-preprocessed output.
+-.Sp
+-When used with the driver options \fB\-MD\fR or \fB\-MMD\fR,
+-\&\fB\-MF\fR overrides the default dependency output file.
+-.IP "\fB\-MG\fR" 4
+-.IX Item "-MG"
+-In conjunction with an option such as \fB\-M\fR requesting
+-dependency generation, \fB\-MG\fR assumes missing header files are
+-generated files and adds them to the dependency list without raising
+-an error. The dependency filename is taken directly from the
+-\&\f(CW\*(C`#include\*(C'\fR directive without prepending any path. \fB\-MG\fR
+-also suppresses preprocessed output, as a missing header file renders
+-this useless.
+-.Sp
+-This feature is used in automatic updating of makefiles.
+-.IP "\fB\-MP\fR" 4
+-.IX Item "-MP"
+-This option instructs \s-1CPP\s0 to add a phony target for each dependency
+-other than the main file, causing each to depend on nothing. These
+-dummy rules work around errors \fBmake\fR gives if you remove header
+-files without updating the \fIMakefile\fR to match.
+-.Sp
+-This is typical output:
+-.Sp
+-.Vb 1
+-\& test.o: test.c test.h
+-.Ve
+-.Sp
+-.Vb 1
+-\& test.h:
+-.Ve
+-.IP "\fB\-MT\fR \fItarget\fR" 4
+-.IX Item "-MT target"
+-Change the target of the rule emitted by dependency generation. By
+-default \s-1CPP\s0 takes the name of the main input file, including any path,
+-deletes any file suffix such as \fB.c\fR, and appends the platform's
+-usual object suffix. The result is the target.
+-.Sp
+-An \fB\-MT\fR option will set the target to be exactly the string you
+-specify. If you want multiple targets, you can specify them as a single
+-argument to \fB\-MT\fR, or use multiple \fB\-MT\fR options.
+-.Sp
+-For example, \fB\-MT\ '$(objpfx)foo.o'\fR might give
+-.Sp
+-.Vb 1
+-\& $(objpfx)foo.o: foo.c
+-.Ve
+-.IP "\fB\-MQ\fR \fItarget\fR" 4
+-.IX Item "-MQ target"
+-Same as \fB\-MT\fR, but it quotes any characters which are special to
+-Make. \fB\-MQ\ '$(objpfx)foo.o'\fR gives
+-.Sp
+-.Vb 1
+-\& $$(objpfx)foo.o: foo.c
+-.Ve
+-.Sp
+-The default target is automatically quoted, as if it were given with
+-\&\fB\-MQ\fR.
+-.IP "\fB\-MD\fR" 4
+-.IX Item "-MD"
+-\&\fB\-MD\fR is equivalent to \fB\-M \-MF\fR \fIfile\fR, except that
+-\&\fB\-E\fR is not implied. The driver determines \fIfile\fR based on
+-whether an \fB\-o\fR option is given. If it is, the driver uses its
+-argument but with a suffix of \fI.d\fR, otherwise it take the
+-basename of the input file and applies a \fI.d\fR suffix.
+-.Sp
+-If \fB\-MD\fR is used in conjunction with \fB\-E\fR, any
+-\&\fB\-o\fR switch is understood to specify the dependency output file
+-(but \f(CW@pxref\fR{\-MF}), but if used without \fB\-E\fR, each \fB\-o\fR
+-is understood to specify a target object file.
+-.Sp
+-Since \fB\-E\fR is not implied, \fB\-MD\fR can be used to generate
+-a dependency output file as a side-effect of the compilation process.
+-.IP "\fB\-MMD\fR" 4
+-.IX Item "-MMD"
+-Like \fB\-MD\fR except mention only user header files, not system
+-\&\-header files.
+-.IP "\fB\-x c\fR" 4
+-.IX Item "-x c"
+-.PD 0
+-.IP "\fB\-x c++\fR" 4
+-.IX Item "-x c++"
+-.IP "\fB\-x objective-c\fR" 4
+-.IX Item "-x objective-c"
+-.IP "\fB\-x assembler-with-cpp\fR" 4
+-.IX Item "-x assembler-with-cpp"
+-.PD
+-Specify the source language: C, \*(C+, Objective\-C, or assembly. This has
+-nothing to do with standards conformance or extensions; it merely
+-selects which base syntax to expect. If you give none of these options,
+-cpp will deduce the language from the extension of the source file:
+-\&\fB.c\fR, \fB.cc\fR, \fB.m\fR, or \fB.S\fR. Some other common
+-extensions for \*(C+ and assembly are also recognized. If cpp does not
+-recognize the extension, it will treat the file as C; this is the most
+-generic mode.
+-.Sp
+-\&\fBNote:\fR Previous versions of cpp accepted a \fB\-lang\fR option
+-which selected both the language and the standards conformance level.
+-This option has been removed, because it conflicts with the \fB\-l\fR
+-option.
+-.IP "\fB\-std=\fR\fIstandard\fR" 4
+-.IX Item "-std=standard"
+-.PD 0
+-.IP "\fB\-ansi\fR" 4
+-.IX Item "-ansi"
+-.PD
+-Specify the standard to which the code should conform. Currently \s-1CPP\s0
+-knows about C and \*(C+ standards; others may be added in the future.
+-.Sp
+-\&\fIstandard\fR
+-may be one of:
+-.RS 4
+-.ie n .IP """iso9899:1990""" 4
+-.el .IP "\f(CWiso9899:1990\fR" 4
+-.IX Item "iso9899:1990"
+-.PD 0
+-.ie n .IP """c89""" 4
+-.el .IP "\f(CWc89\fR" 4
+-.IX Item "c89"
+-.PD
+-The \s-1ISO\s0 C standard from 1990. \fBc89\fR is the customary shorthand for
+-this version of the standard.
+-.Sp
+-The \fB\-ansi\fR option is equivalent to \fB\-std=c89\fR.
+-.ie n .IP """iso9899:199409""" 4
+-.el .IP "\f(CWiso9899:199409\fR" 4
+-.IX Item "iso9899:199409"
+-The 1990 C standard, as amended in 1994.
+-.ie n .IP """iso9899:1999""" 4
+-.el .IP "\f(CWiso9899:1999\fR" 4
+-.IX Item "iso9899:1999"
+-.PD 0
+-.ie n .IP """c99""" 4
+-.el .IP "\f(CWc99\fR" 4
+-.IX Item "c99"
+-.ie n .IP """iso9899:199x""" 4
+-.el .IP "\f(CWiso9899:199x\fR" 4
+-.IX Item "iso9899:199x"
+-.ie n .IP """c9x""" 4
+-.el .IP "\f(CWc9x\fR" 4
+-.IX Item "c9x"
+-.PD
+-The revised \s-1ISO\s0 C standard, published in December 1999. Before
+-publication, this was known as C9X.
+-.ie n .IP """gnu89""" 4
+-.el .IP "\f(CWgnu89\fR" 4
+-.IX Item "gnu89"
+-The 1990 C standard plus \s-1GNU\s0 extensions. This is the default.
+-.ie n .IP """gnu99""" 4
+-.el .IP "\f(CWgnu99\fR" 4
+-.IX Item "gnu99"
+-.PD 0
+-.ie n .IP """gnu9x""" 4
+-.el .IP "\f(CWgnu9x\fR" 4
+-.IX Item "gnu9x"
+-.PD
+-The 1999 C standard plus \s-1GNU\s0 extensions.
+-.ie n .IP """c++98""" 4
+-.el .IP "\f(CWc++98\fR" 4
+-.IX Item "c++98"
+-The 1998 \s-1ISO\s0 \*(C+ standard plus amendments.
+-.ie n .IP """gnu++98""" 4
+-.el .IP "\f(CWgnu++98\fR" 4
+-.IX Item "gnu++98"
+-The same as \fB\-std=c++98\fR plus \s-1GNU\s0 extensions. This is the
+-default for \*(C+ code.
+-.RE
+-.RS 4
+-.RE
+-.IP "\fB\-I\-\fR" 4
+-.IX Item "-I-"
+-Split the include path. Any directories specified with \fB\-I\fR
+-options before \fB\-I\-\fR are searched only for headers requested with
+-\&\f(CW\*(C`#include\ "\f(CIfile\f(CW"\*(C'\fR; they are not searched for
+-\&\f(CW\*(C`#include\ <\f(CIfile\f(CW>\*(C'\fR. If additional directories are
+-specified with \fB\-I\fR options after the \fB\-I\-\fR, those
+-directories are searched for all \fB#include\fR directives.
+-.Sp
+-In addition, \fB\-I\-\fR inhibits the use of the directory of the current
+-file directory as the first search directory for \f(CW\*(C`#include\ "\f(CIfile\f(CW"\*(C'\fR.
+-.IP "\fB\-nostdinc\fR" 4
+-.IX Item "-nostdinc"
+-Do not search the standard system directories for header files.
+-Only the directories you have specified with \fB\-I\fR options
+-(and the directory of the current file, if appropriate) are searched.
+-.IP "\fB\-nostdinc++\fR" 4
+-.IX Item "-nostdinc++"
+-Do not search for header files in the \*(C+\-specific standard directories,
+-but do still search the other standard directories. (This option is
+-used when building the \*(C+ library.)
+-.IP "\fB\-include\fR \fIfile\fR" 4
+-.IX Item "-include file"
+-Process \fIfile\fR as if \f(CW\*(C`#include "file"\*(C'\fR appeared as the first
+-line of the primary source file. However, the first directory searched
+-for \fIfile\fR is the preprocessor's working directory \fIinstead of\fR
+-the directory containing the main source file. If not found there, it
+-is searched for in the remainder of the \f(CW\*(C`#include "..."\*(C'\fR search
+-chain as normal.
+-.Sp
+-If multiple \fB\-include\fR options are given, the files are included
+-in the order they appear on the command line.
+-.IP "\fB\-imacros\fR \fIfile\fR" 4
+-.IX Item "-imacros file"
+-Exactly like \fB\-include\fR, except that any output produced by
+-scanning \fIfile\fR is thrown away. Macros it defines remain defined.
+-This allows you to acquire all the macros from a header without also
+-processing its declarations.
+-.Sp
+-All files specified by \fB\-imacros\fR are processed before all files
+-specified by \fB\-include\fR.
+-.IP "\fB\-idirafter\fR \fIdir\fR" 4
+-.IX Item "-idirafter dir"
+-Search \fIdir\fR for header files, but do it \fIafter\fR all
+-directories specified with \fB\-I\fR and the standard system directories
+-have been exhausted. \fIdir\fR is treated as a system include directory.
+-.IP "\fB\-iprefix\fR \fIprefix\fR" 4
+-.IX Item "-iprefix prefix"
+-Specify \fIprefix\fR as the prefix for subsequent \fB\-iwithprefix\fR
+-options. If the prefix represents a directory, you should include the
+-final \fB/\fR.
+-.IP "\fB\-iwithprefix\fR \fIdir\fR" 4
+-.IX Item "-iwithprefix dir"
+-.PD 0
+-.IP "\fB\-iwithprefixbefore\fR \fIdir\fR" 4
+-.IX Item "-iwithprefixbefore dir"
+-.PD
+-Append \fIdir\fR to the prefix specified previously with
+-\&\fB\-iprefix\fR, and add the resulting directory to the include search
+-path. \fB\-iwithprefixbefore\fR puts it in the same place \fB\-I\fR
+-would; \fB\-iwithprefix\fR puts it where \fB\-idirafter\fR would.
+-.Sp
+-Use of these options is discouraged.
+-.IP "\fB\-isystem\fR \fIdir\fR" 4
+-.IX Item "-isystem dir"
+-Search \fIdir\fR for header files, after all directories specified by
+-\&\fB\-I\fR but before the standard system directories. Mark it
+-as a system directory, so that it gets the same special treatment as
+-is applied to the standard system directories.
+-.IP "\fB\-fpreprocessed\fR" 4
+-.IX Item "-fpreprocessed"
+-Indicate to the preprocessor that the input file has already been
+-preprocessed. This suppresses things like macro expansion, trigraph
+-conversion, escaped newline splicing, and processing of most directives.
+-The preprocessor still recognizes and removes comments, so that you can
+-pass a file preprocessed with \fB\-C\fR to the compiler without
+-problems. In this mode the integrated preprocessor is little more than
+-a tokenizer for the front ends.
+-.Sp
+-\&\fB\-fpreprocessed\fR is implicit if the input file has one of the
+-extensions \fB.i\fR, \fB.ii\fR or \fB.mi\fR. These are the
+-extensions that \s-1GCC\s0 uses for preprocessed files created by
+-\&\fB\-save\-temps\fR.
+-.IP "\fB\-ftabstop=\fR\fIwidth\fR" 4
+-.IX Item "-ftabstop=width"
+-Set the distance between tab stops. This helps the preprocessor report
+-correct column numbers in warnings or errors, even if tabs appear on the
+-line. If the value is less than 1 or greater than 100, the option is
+-ignored. The default is 8.
+-.IP "\fB\-fno\-show\-column\fR" 4
+-.IX Item "-fno-show-column"
+-Do not print column numbers in diagnostics. This may be necessary if
+-diagnostics are being scanned by a program that does not understand the
+-column numbers, such as \fBdejagnu\fR.
+-.IP "\fB\-A\fR \fIpredicate\fR\fB=\fR\fIanswer\fR" 4
+-.IX Item "-A predicate=answer"
+-Make an assertion with the predicate \fIpredicate\fR and answer
+-\&\fIanswer\fR. This form is preferred to the older form \fB\-A\fR
+-\&\fIpredicate\fR\fB(\fR\fIanswer\fR\fB)\fR, which is still supported, because
+-it does not use shell special characters.
+-.IP "\fB\-A \-\fR\fIpredicate\fR\fB=\fR\fIanswer\fR" 4
+-.IX Item "-A -predicate=answer"
+-Cancel an assertion with the predicate \fIpredicate\fR and answer
+-\&\fIanswer\fR.
+-.IP "\fB\-dCHARS\fR" 4
+-.IX Item "-dCHARS"
+-\&\fI\s-1CHARS\s0\fR is a sequence of one or more of the following characters,
+-and must not be preceded by a space. Other characters are interpreted
+-by the compiler proper, or reserved for future versions of \s-1GCC\s0, and so
+-are silently ignored. If you specify characters whose behavior
+-conflicts, the result is undefined.
+-.RS 4
+-.IP "\fBM\fR" 4
+-.IX Item "M"
+-Instead of the normal output, generate a list of \fB#define\fR
+-directives for all the macros defined during the execution of the
+-preprocessor, including predefined macros. This gives you a way of
+-finding out what is predefined in your version of the preprocessor.
+-Assuming you have no file \fIfoo.h\fR, the command
+-.Sp
+-.Vb 1
+-\& touch foo.h; cpp -dM foo.h
+-.Ve
+-.Sp
+-will show all the predefined macros.
+-.IP "\fBD\fR" 4
+-.IX Item "D"
+-Like \fBM\fR except in two respects: it does \fInot\fR include the
+-predefined macros, and it outputs \fIboth\fR the \fB#define\fR
+-directives and the result of preprocessing. Both kinds of output go to
+-the standard output file.
+-.IP "\fBN\fR" 4
+-.IX Item "N"
+-Like \fBD\fR, but emit only the macro names, not their expansions.
+-.IP "\fBI\fR" 4
+-.IX Item "I"
+-Output \fB#include\fR directives in addition to the result of
+-preprocessing.
+-.RE
+-.RS 4
+-.RE
+-.IP "\fB\-P\fR" 4
+-.IX Item "-P"
+-Inhibit generation of linemarkers in the output from the preprocessor.
+-This might be useful when running the preprocessor on something that is
+-not C code, and will be sent to a program which might be confused by the
+-linemarkers.
+-.IP "\fB\-C\fR" 4
+-.IX Item "-C"
+-Do not discard comments. All comments are passed through to the output
+-file, except for comments in processed directives, which are deleted
+-along with the directive.
+-.Sp
+-You should be prepared for side effects when using \fB\-C\fR; it
+-causes the preprocessor to treat comments as tokens in their own right.
+-For example, comments appearing at the start of what would be a
+-directive line have the effect of turning that line into an ordinary
+-source line, since the first token on the line is no longer a \fB#\fR.
+-.IP "\fB\-CC\fR" 4
+-.IX Item "-CC"
+-Do not discard comments, including during macro expansion. This is
+-like \fB\-C\fR, except that comments contained within macros are
+-also passed through to the output file where the macro is expanded.
+-.Sp
+-In addition to the side-effects of the \fB\-C\fR option, the
+-\&\fB\-CC\fR option causes all \*(C+\-style comments inside a macro
+-to be converted to C\-style comments. This is to prevent later use
+-of that macro from inadvertently commenting out the remainder of
+-the source line.
+-.Sp
+-The \fB\-CC\fR option is generally used to support lint comments.
+-.IP "\fB\-traditional\-cpp\fR" 4
+-.IX Item "-traditional-cpp"
+-Try to imitate the behavior of old-fashioned C preprocessors, as
+-opposed to \s-1ISO\s0 C preprocessors.
+-.IP "\fB\-trigraphs\fR" 4
+-.IX Item "-trigraphs"
+-Process trigraph sequences.
+-These are three-character sequences, all starting with \fB??\fR, that
+-are defined by \s-1ISO\s0 C to stand for single characters. For example,
+-\&\fB??/\fR stands for \fB\e\fR, so \fB'??/n'\fR is a character
+-constant for a newline. By default, \s-1GCC\s0 ignores trigraphs, but in
+-standard-conforming modes it converts them. See the \fB\-std\fR and
+-\&\fB\-ansi\fR options.
+-.Sp
+-The nine trigraphs and their replacements are
+-.Sp
+-.Vb 2
+-\& Trigraph: ??( ??) ??< ??> ??= ??/ ??' ??! ??-
+-\& Replacement: [ ] { } # \e ^ | ~
+-.Ve
+-.IP "\fB\-remap\fR" 4
+-.IX Item "-remap"
+-Enable special code to work around file systems which only permit very
+-short file names, such as \s-1MS\-DOS\s0.
+-.IP "\fB\-\-help\fR" 4
+-.IX Item "--help"
+-.PD 0
+-.IP "\fB\-\-target\-help\fR" 4
+-.IX Item "--target-help"
+-.PD
+-Print text describing all the command line options instead of
+-preprocessing anything.
+-.IP "\fB\-v\fR" 4
+-.IX Item "-v"
+-Verbose mode. Print out \s-1GNU\s0 \s-1CPP\s0's version number at the beginning of
+-execution, and report the final form of the include path.
+-.IP "\fB\-H\fR" 4
+-.IX Item "-H"
+-Print the name of each header file used, in addition to other normal
+-activities. Each name is indented to show how deep in the
+-\&\fB#include\fR stack it is.
+-.IP "\fB\-version\fR" 4
+-.IX Item "-version"
+-.PD 0
+-.IP "\fB\-\-version\fR" 4
+-.IX Item "--version"
+-.PD
+-Print out \s-1GNU\s0 \s-1CPP\s0's version number. With one dash, proceed to
+-preprocess as normal. With two dashes, exit immediately.
+-.Sh "Passing Options to the Assembler"
+-.IX Subsection "Passing Options to the Assembler"
+-You can pass options to the assembler.
+-.IP "\fB\-Wa,\fR\fIoption\fR" 4
+-.IX Item "-Wa,option"
+-Pass \fIoption\fR as an option to the assembler. If \fIoption\fR
+-contains commas, it is split into multiple options at the commas.
+-.Sh "Options for Linking"
+-.IX Subsection "Options for Linking"
+-These options come into play when the compiler links object files into
+-an executable output file. They are meaningless if the compiler is
+-not doing a link step.
+-.IP "\fIobject-file-name\fR" 4
+-.IX Item "object-file-name"
+-A file name that does not end in a special recognized suffix is
+-considered to name an object file or library. (Object files are
+-distinguished from libraries by the linker according to the file
+-contents.) If linking is done, these object files are used as input
+-to the linker.
+-.IP "\fB\-c\fR" 4
+-.IX Item "-c"
+-.PD 0
+-.IP "\fB\-S\fR" 4
+-.IX Item "-S"
+-.IP "\fB\-E\fR" 4
+-.IX Item "-E"
+-.PD
+-If any of these options is used, then the linker is not run, and
+-object file names should not be used as arguments.
+-.IP "\fB\-l\fR\fIlibrary\fR" 4
+-.IX Item "-llibrary"
+-.PD 0
+-.IP "\fB\-l\fR \fIlibrary\fR" 4
+-.IX Item "-l library"
+-.PD
+-Search the library named \fIlibrary\fR when linking. (The second
+-alternative with the library as a separate argument is only for
+-\&\s-1POSIX\s0 compliance and is not recommended.)
+-.Sp
+-It makes a difference where in the command you write this option; the
+-linker searches and processes libraries and object files in the order they
+-are specified. Thus, \fBfoo.o \-lz bar.o\fR searches library \fBz\fR
+-after file \fIfoo.o\fR but before \fIbar.o\fR. If \fIbar.o\fR refers
+-to functions in \fBz\fR, those functions may not be loaded.
+-.Sp
+-The linker searches a standard list of directories for the library,
+-which is actually a file named \fIlib\fIlibrary\fI.a\fR. The linker
+-then uses this file as if it had been specified precisely by name.
+-.Sp
+-The directories searched include several standard system directories
+-plus any that you specify with \fB\-L\fR.
+-.Sp
+-Normally the files found this way are library files\-\-\-archive files
+-whose members are object files. The linker handles an archive file by
+-scanning through it for members which define symbols that have so far
+-been referenced but not defined. But if the file that is found is an
+-ordinary object file, it is linked in the usual fashion. The only
+-difference between using an \fB\-l\fR option and specifying a file name
+-is that \fB\-l\fR surrounds \fIlibrary\fR with \fBlib\fR and \fB.a\fR
+-and searches several directories.
+-.IP "\fB\-lobjc\fR" 4
+-.IX Item "-lobjc"
+-You need this special case of the \fB\-l\fR option in order to
+-link an Objective-C program.
+-.IP "\fB\-nostartfiles\fR" 4
+-.IX Item "-nostartfiles"
+-Do not use the standard system startup files when linking.
+-The standard system libraries are used normally, unless \fB\-nostdlib\fR
+-or \fB\-nodefaultlibs\fR is used.
+-.IP "\fB\-nodefaultlibs\fR" 4
+-.IX Item "-nodefaultlibs"
+-Do not use the standard system libraries when linking.
+-Only the libraries you specify will be passed to the linker.
+-The standard startup files are used normally, unless \fB\-nostartfiles\fR
+-is used. The compiler may generate calls to memcmp, memset, and memcpy
+-for System V (and \s-1ISO\s0 C) environments or to bcopy and bzero for
+-\&\s-1BSD\s0 environments. These entries are usually resolved by entries in
+-libc. These entry points should be supplied through some other
+-mechanism when this option is specified.
+-.IP "\fB\-nostdlib\fR" 4
+-.IX Item "-nostdlib"
+-Do not use the standard system startup files or libraries when linking.
+-No startup files and only the libraries you specify will be passed to
+-the linker. The compiler may generate calls to memcmp, memset, and memcpy
+-for System V (and \s-1ISO\s0 C) environments or to bcopy and bzero for
+-\&\s-1BSD\s0 environments. These entries are usually resolved by entries in
+-libc. These entry points should be supplied through some other
+-mechanism when this option is specified.
+-.Sp
+-One of the standard libraries bypassed by \fB\-nostdlib\fR and
+-\&\fB\-nodefaultlibs\fR is \fIlibgcc.a\fR, a library of internal subroutines
+-that \s-1GCC\s0 uses to overcome shortcomings of particular machines, or special
+-needs for some languages.
+-.Sp
+-In most cases, you need \fIlibgcc.a\fR even when you want to avoid
+-other standard libraries. In other words, when you specify \fB\-nostdlib\fR
+-or \fB\-nodefaultlibs\fR you should usually specify \fB\-lgcc\fR as well.
+-This ensures that you have no unresolved references to internal \s-1GCC\s0
+-library subroutines. (For example, \fB_\|_main\fR, used to ensure \*(C+
+-constructors will be called.)
+-.IP "\fB\-s\fR" 4
+-.IX Item "-s"
+-Remove all symbol table and relocation information from the executable.
+-.IP "\fB\-static\fR" 4
+-.IX Item "-static"
+-On systems that support dynamic linking, this prevents linking with the shared
+-libraries. On other systems, this option has no effect.
+-.IP "\fB\-shared\fR" 4
+-.IX Item "-shared"
+-Produce a shared object which can then be linked with other objects to
+-form an executable. Not all systems support this option. For predictable
+-results, you must also specify the same set of options that were used to
+-generate code (\fB\-fpic\fR, \fB\-fPIC\fR, or model suboptions)
+-when you specify this option.[1]
+-.IP "\fB\-shared\-libgcc\fR" 4
+-.IX Item "-shared-libgcc"
+-.PD 0
+-.IP "\fB\-static\-libgcc\fR" 4
+-.IX Item "-static-libgcc"
+-.PD
+-On systems that provide \fIlibgcc\fR as a shared library, these options
+-force the use of either the shared or static version respectively.
+-If no shared version of \fIlibgcc\fR was built when the compiler was
+-configured, these options have no effect.
+-.Sp
+-There are several situations in which an application should use the
+-shared \fIlibgcc\fR instead of the static version. The most common
+-of these is when the application wishes to throw and catch exceptions
+-across different shared libraries. In that case, each of the libraries
+-as well as the application itself should use the shared \fIlibgcc\fR.
+-.Sp
+-Therefore, the G++ and \s-1GCJ\s0 drivers automatically add
+-\&\fB\-shared\-libgcc\fR whenever you build a shared library or a main
+-executable, because \*(C+ and Java programs typically use exceptions, so
+-this is the right thing to do.
+-.Sp
+-If, instead, you use the \s-1GCC\s0 driver to create shared libraries, you may
+-find that they will not always be linked with the shared \fIlibgcc\fR.
+-If \s-1GCC\s0 finds, at its configuration time, that you have a \s-1GNU\s0 linker that
+-does not support option \fB\-\-eh\-frame\-hdr\fR, it will link the shared
+-version of \fIlibgcc\fR into shared libraries by default. Otherwise,
+-it will take advantage of the linker and optimize away the linking with
+-the shared version of \fIlibgcc\fR, linking with the static version of
+-libgcc by default. This allows exceptions to propagate through such
+-shared libraries, without incurring relocation costs at library load
+-time.
+-.Sp
+-However, if a library or main executable is supposed to throw or catch
+-exceptions, you must link it using the G++ or \s-1GCJ\s0 driver, as appropriate
+-for the languages used in the program, or using the option
+-\&\fB\-shared\-libgcc\fR, such that it is linked with the shared
+-\&\fIlibgcc\fR.
+-.IP "\fB\-symbolic\fR" 4
+-.IX Item "-symbolic"
+-Bind references to global symbols when building a shared object. Warn
+-about any unresolved references (unless overridden by the link editor
+-option \fB\-Xlinker \-z \-Xlinker defs\fR). Only a few systems support
+-this option.
+-.IP "\fB\-Xlinker\fR \fIoption\fR" 4
+-.IX Item "-Xlinker option"
+-Pass \fIoption\fR as an option to the linker. You can use this to
+-supply system-specific linker options which \s-1GCC\s0 does not know how to
+-recognize.
+-.Sp
+-If you want to pass an option that takes an argument, you must use
+-\&\fB\-Xlinker\fR twice, once for the option and once for the argument.
+-For example, to pass \fB\-assert definitions\fR, you must write
+-\&\fB\-Xlinker \-assert \-Xlinker definitions\fR. It does not work to write
+-\&\fB\-Xlinker \*(L"\-assert definitions\*(R"\fR, because this passes the entire
+-string as a single argument, which is not what the linker expects.
+-.IP "\fB\-Wl,\fR\fIoption\fR" 4
+-.IX Item "-Wl,option"
+-Pass \fIoption\fR as an option to the linker. If \fIoption\fR contains
+-commas, it is split into multiple options at the commas.
+-.IP "\fB\-u\fR \fIsymbol\fR" 4
+-.IX Item "-u symbol"
+-Pretend the symbol \fIsymbol\fR is undefined, to force linking of
+-library modules to define it. You can use \fB\-u\fR multiple times with
+-different symbols to force loading of additional library modules.
+-.Sh "Options for Directory Search"
+-.IX Subsection "Options for Directory Search"
+-These options specify directories to search for header files, for
+-libraries and for parts of the compiler:
+-.IP "\fB\-I\fR\fIdir\fR" 4
+-.IX Item "-Idir"
+-Add the directory \fIdir\fR to the head of the list of directories to be
+-searched for header files. This can be used to override a system header
+-file, substituting your own version, since these directories are
+-searched before the system header file directories. However, you should
+-not use this option to add directories that contain vendor-supplied
+-system header files (use \fB\-isystem\fR for that). If you use more than
+-one \fB\-I\fR option, the directories are scanned in left-to-right
+-order; the standard system directories come after.
+-.Sp
+-If a standard system include directory, or a directory specified with
+-\&\fB\-isystem\fR, is also specified with \fB\-I\fR, the \fB\-I\fR
+-option will be ignored. The directory will still be searched but as a
+-system directory at its normal position in the system include chain.
+-This is to ensure that \s-1GCC\s0's procedure to fix buggy system headers and
+-the ordering for the include_next directive are not inadvertently changed.
+-If you really need to change the search order for system directories,
+-use the \fB\-nostdinc\fR and/or \fB\-isystem\fR options.
+-.IP "\fB\-I\-\fR" 4
+-.IX Item "-I-"
+-Any directories you specify with \fB\-I\fR options before the \fB\-I\-\fR
+-option are searched only for the case of \fB#include "\fR\fIfile\fR\fB"\fR;
+-they are not searched for \fB#include <\fR\fIfile\fR\fB>\fR.
+-.Sp
+-If additional directories are specified with \fB\-I\fR options after
+-the \fB\-I\-\fR, these directories are searched for all \fB#include\fR
+-directives. (Ordinarily \fIall\fR \fB\-I\fR directories are used
+-this way.)
+-.Sp
+-In addition, the \fB\-I\-\fR option inhibits the use of the current
+-directory (where the current input file came from) as the first search
+-directory for \fB#include "\fR\fIfile\fR\fB"\fR. There is no way to
+-override this effect of \fB\-I\-\fR. With \fB\-I.\fR you can specify
+-searching the directory which was current when the compiler was
+-invoked. That is not exactly the same as what the preprocessor does
+-by default, but it is often satisfactory.
+-.Sp
+-\&\fB\-I\-\fR does not inhibit the use of the standard system directories
+-for header files. Thus, \fB\-I\-\fR and \fB\-nostdinc\fR are
+-independent.
+-.IP "\fB\-L\fR\fIdir\fR" 4
+-.IX Item "-Ldir"
+-Add directory \fIdir\fR to the list of directories to be searched
+-for \fB\-l\fR.
+-.IP "\fB\-B\fR\fIprefix\fR" 4
+-.IX Item "-Bprefix"
+-This option specifies where to find the executables, libraries,
+-include files, and data files of the compiler itself.
+-.Sp
+-The compiler driver program runs one or more of the subprograms
+-\&\fIcpp\fR, \fIcc1\fR, \fIas\fR and \fIld\fR. It tries
+-\&\fIprefix\fR as a prefix for each program it tries to run, both with and
+-without \fImachine\fR\fB/\fR\fIversion\fR\fB/\fR.
+-.Sp
+-For each subprogram to be run, the compiler driver first tries the
+-\&\fB\-B\fR prefix, if any. If that name is not found, or if \fB\-B\fR
+-was not specified, the driver tries two standard prefixes, which are
+-\&\fI/usr/lib/gcc/\fR and \fI/usr/local/lib/gcc\-lib/\fR. If neither of
+-those results in a file name that is found, the unmodified program
+-name is searched for using the directories specified in your
+-\&\fB\s-1PATH\s0\fR environment variable.
+-.Sp
+-The compiler will check to see if the path provided by the \fB\-B\fR
+-refers to a directory, and if necessary it will add a directory
+-separator character at the end of the path.
+-.Sp
+-\&\fB\-B\fR prefixes that effectively specify directory names also apply
+-to libraries in the linker, because the compiler translates these
+-options into \fB\-L\fR options for the linker. They also apply to
+-includes files in the preprocessor, because the compiler translates these
+-options into \fB\-isystem\fR options for the preprocessor. In this case,
+-the compiler appends \fBinclude\fR to the prefix.
+-.Sp
+-The run-time support file \fIlibgcc.a\fR can also be searched for using
+-the \fB\-B\fR prefix, if needed. If it is not found there, the two
+-standard prefixes above are tried, and that is all. The file is left
+-out of the link if it is not found by those means.
+-.Sp
+-Another way to specify a prefix much like the \fB\-B\fR prefix is to use
+-the environment variable \fB\s-1GCC_EXEC_PREFIX\s0\fR.
+-.Sp
+-As a special kludge, if the path provided by \fB\-B\fR is
+-\&\fI[dir/]stage\fIN\fI/\fR, where \fIN\fR is a number in the range 0 to
+-9, then it will be replaced by \fI[dir/]include\fR. This is to help
+-with boot-strapping the compiler.
+-.IP "\fB\-specs=\fR\fIfile\fR" 4
+-.IX Item "-specs=file"
+-Process \fIfile\fR after the compiler reads in the standard \fIspecs\fR
+-file, in order to override the defaults that the \fIgcc\fR driver
+-program uses when determining what switches to pass to \fIcc1\fR,
+-\&\fIcc1plus\fR, \fIas\fR, \fIld\fR, etc. More than one
+-\&\fB\-specs=\fR\fIfile\fR can be specified on the command line, and they
+-are processed in order, from left to right.
+-.Sh "Specifying Target Machine and Compiler Version"
+-.IX Subsection "Specifying Target Machine and Compiler Version"
+-The usual way to run \s-1GCC\s0 is to run the executable called \fIgcc\fR, or
+-\&\fI<machine>\-gcc\fR when cross\-compiling, or
+-\&\fI<machine>\-gcc\-<version>\fR to run a version other than the one that
+-was installed last. Sometimes this is inconvenient, so \s-1GCC\s0 provides
+-options that will switch to another cross-compiler or version.
+-.IP "\fB\-b\fR \fImachine\fR" 4
+-.IX Item "-b machine"
+-The argument \fImachine\fR specifies the target machine for compilation.
+-.Sp
+-The value to use for \fImachine\fR is the same as was specified as the
+-machine type when configuring \s-1GCC\s0 as a cross\-compiler. For
+-example, if a cross-compiler was configured with \fBconfigure
+-i386v\fR, meaning to compile for an 80386 running System V, then you
+-would specify \fB\-b i386v\fR to run that cross compiler.
+-.IP "\fB\-V\fR \fIversion\fR" 4
+-.IX Item "-V version"
+-The argument \fIversion\fR specifies which version of \s-1GCC\s0 to run.
+-This is useful when multiple versions are installed. For example,
+-\&\fIversion\fR might be \fB2.0\fR, meaning to run \s-1GCC\s0 version 2.0.
+-.PP
+-The \fB\-V\fR and \fB\-b\fR options work by running the
+-\&\fI<machine>\-gcc\-<version>\fR executable, so there's no real reason to
+-use them if you can just run that directly.
+-.Sh "Hardware Models and Configurations"
+-.IX Subsection "Hardware Models and Configurations"
+-Earlier we discussed the standard option \fB\-b\fR which chooses among
+-different installed compilers for completely different target
+-machines, such as \s-1VAX\s0 vs. 68000 vs. 80386.
+-.PP
+-In addition, each of these target machine types can have its own
+-special options, starting with \fB\-m\fR, to choose among various
+-hardware models or configurations\-\-\-for example, 68010 vs 68020,
+-floating coprocessor or none. A single installed version of the
+-compiler can compile for any model or configuration, according to the
+-options specified.
+-.PP
+-Some configurations of the compiler also support additional special
+-options, usually for compatibility with other compilers on the same
+-platform.
+-.PP
+-These options are defined by the macro \f(CW\*(C`TARGET_SWITCHES\*(C'\fR in the
+-machine description. The default for the options is also defined by
+-that macro, which enables you to change the defaults.
+-.PP
+-\fIM680x0 Options\fR
+-.IX Subsection "M680x0 Options"
+-.PP
+-These are the \fB\-m\fR options defined for the 68000 series. The default
+-values for these options depends on which style of 68000 was selected when
+-the compiler was configured; the defaults for the most common choices are
+-given below.
+-.IP "\fB\-m68000\fR" 4
+-.IX Item "-m68000"
+-.PD 0
+-.IP "\fB\-mc68000\fR" 4
+-.IX Item "-mc68000"
+-.PD
+-Generate output for a 68000. This is the default
+-when the compiler is configured for 68000\-based systems.
+-.Sp
+-Use this option for microcontrollers with a 68000 or \s-1EC000\s0 core,
+-including the 68008, 68302, 68306, 68307, 68322, 68328 and 68356.
+-.IP "\fB\-m68020\fR" 4
+-.IX Item "-m68020"
+-.PD 0
+-.IP "\fB\-mc68020\fR" 4
+-.IX Item "-mc68020"
+-.PD
+-Generate output for a 68020. This is the default
+-when the compiler is configured for 68020\-based systems.
+-.IP "\fB\-m68881\fR" 4
+-.IX Item "-m68881"
+-Generate output containing 68881 instructions for floating point.
+-This is the default for most 68020 systems unless \fB\-\-nfp\fR was
+-specified when the compiler was configured.
+-.IP "\fB\-m68030\fR" 4
+-.IX Item "-m68030"
+-Generate output for a 68030. This is the default when the compiler is
+-configured for 68030\-based systems.
+-.IP "\fB\-m68040\fR" 4
+-.IX Item "-m68040"
+-Generate output for a 68040. This is the default when the compiler is
+-configured for 68040\-based systems.
+-.Sp
+-This option inhibits the use of 68881/68882 instructions that have to be
+-emulated by software on the 68040. Use this option if your 68040 does not
+-have code to emulate those instructions.
+-.IP "\fB\-m68060\fR" 4
+-.IX Item "-m68060"
+-Generate output for a 68060. This is the default when the compiler is
+-configured for 68060\-based systems.
+-.Sp
+-This option inhibits the use of 68020 and 68881/68882 instructions that
+-have to be emulated by software on the 68060. Use this option if your 68060
+-does not have code to emulate those instructions.
+-.IP "\fB\-mcpu32\fR" 4
+-.IX Item "-mcpu32"
+-Generate output for a \s-1CPU32\s0. This is the default
+-when the compiler is configured for CPU32\-based systems.
+-.Sp
+-Use this option for microcontrollers with a
+-\&\s-1CPU32\s0 or \s-1CPU32+\s0 core, including the 68330, 68331, 68332, 68333, 68334,
+-68336, 68340, 68341, 68349 and 68360.
+-.IP "\fB\-m5200\fR" 4
+-.IX Item "-m5200"
+-Generate output for a 520X ``coldfire'' family cpu. This is the default
+-when the compiler is configured for 520X\-based systems.
+-.Sp
+-Use this option for microcontroller with a 5200 core, including
+-the \s-1MCF5202\s0, \s-1MCF5203\s0, \s-1MCF5204\s0 and \s-1MCF5202\s0.
+-.IP "\fB\-m68020\-40\fR" 4
+-.IX Item "-m68020-40"
+-Generate output for a 68040, without using any of the new instructions.
+-This results in code which can run relatively efficiently on either a
+-68020/68881 or a 68030 or a 68040. The generated code does use the
+-68881 instructions that are emulated on the 68040.
+-.IP "\fB\-m68020\-60\fR" 4
+-.IX Item "-m68020-60"
+-Generate output for a 68060, without using any of the new instructions.
+-This results in code which can run relatively efficiently on either a
+-68020/68881 or a 68030 or a 68040. The generated code does use the
+-68881 instructions that are emulated on the 68060.
+-.IP "\fB\-mfpa\fR" 4
+-.IX Item "-mfpa"
+-Generate output containing Sun \s-1FPA\s0 instructions for floating point.
+-.IP "\fB\-msoft\-float\fR" 4
+-.IX Item "-msoft-float"
+-Generate output containing library calls for floating point.
+-\&\fBWarning:\fR the requisite libraries are not available for all m68k
+-targets. Normally the facilities of the machine's usual C compiler are
+-used, but this can't be done directly in cross\-compilation. You must
+-make your own arrangements to provide suitable library functions for
+-cross\-compilation. The embedded targets \fBm68k\-*\-aout\fR and
+-\&\fBm68k\-*\-coff\fR do provide software floating point support.
+-.IP "\fB\-mshort\fR" 4
+-.IX Item "-mshort"
+-Consider type \f(CW\*(C`int\*(C'\fR to be 16 bits wide, like \f(CW\*(C`short int\*(C'\fR.
+-.IP "\fB\-mnobitfield\fR" 4
+-.IX Item "-mnobitfield"
+-Do not use the bit-field instructions. The \fB\-m68000\fR, \fB\-mcpu32\fR
+-and \fB\-m5200\fR options imply \fB\-mnobitfield\fR.
+-.IP "\fB\-mbitfield\fR" 4
+-.IX Item "-mbitfield"
+-Do use the bit-field instructions. The \fB\-m68020\fR option implies
+-\&\fB\-mbitfield\fR. This is the default if you use a configuration
+-designed for a 68020.
+-.IP "\fB\-mrtd\fR" 4
+-.IX Item "-mrtd"
+-Use a different function-calling convention, in which functions
+-that take a fixed number of arguments return with the \f(CW\*(C`rtd\*(C'\fR
+-instruction, which pops their arguments while returning. This
+-saves one instruction in the caller since there is no need to pop
+-the arguments there.
+-.Sp
+-This calling convention is incompatible with the one normally
+-used on Unix, so you cannot use it if you need to call libraries
+-compiled with the Unix compiler.
+-.Sp
+-Also, you must provide function prototypes for all functions that
+-take variable numbers of arguments (including \f(CW\*(C`printf\*(C'\fR);
+-otherwise incorrect code will be generated for calls to those
+-functions.
+-.Sp
+-In addition, seriously incorrect code will result if you call a
+-function with too many arguments. (Normally, extra arguments are
+-harmlessly ignored.)
+-.Sp
+-The \f(CW\*(C`rtd\*(C'\fR instruction is supported by the 68010, 68020, 68030,
+-68040, 68060 and \s-1CPU32\s0 processors, but not by the 68000 or 5200.
+-.IP "\fB\-malign\-int\fR" 4
+-.IX Item "-malign-int"
+-.PD 0
+-.IP "\fB\-mno\-align\-int\fR" 4
+-.IX Item "-mno-align-int"
+-.PD
+-Control whether \s-1GCC\s0 aligns \f(CW\*(C`int\*(C'\fR, \f(CW\*(C`long\*(C'\fR, \f(CW\*(C`long long\*(C'\fR,
+-\&\f(CW\*(C`float\*(C'\fR, \f(CW\*(C`double\*(C'\fR, and \f(CW\*(C`long double\*(C'\fR variables on a 32\-bit
+-boundary (\fB\-malign\-int\fR) or a 16\-bit boundary (\fB\-mno\-align\-int\fR).
+-Aligning variables on 32\-bit boundaries produces code that runs somewhat
+-faster on processors with 32\-bit busses at the expense of more memory.
+-.Sp
+-\&\fBWarning:\fR if you use the \fB\-malign\-int\fR switch, \s-1GCC\s0 will
+-align structures containing the above types differently than
+-most published application binary interface specifications for the m68k.
+-.IP "\fB\-mpcrel\fR" 4
+-.IX Item "-mpcrel"
+-Use the pc-relative addressing mode of the 68000 directly, instead of
+-using a global offset table. At present, this option implies \fB\-fpic\fR,
+-allowing at most a 16\-bit offset for pc-relative addressing. \fB\-fPIC\fR is
+-not presently supported with \fB\-mpcrel\fR, though this could be supported for
+-68020 and higher processors.
+-.IP "\fB\-mno\-strict\-align\fR" 4
+-.IX Item "-mno-strict-align"
+-.PD 0
+-.IP "\fB\-mstrict\-align\fR" 4
+-.IX Item "-mstrict-align"
+-.PD
+-Do not (do) assume that unaligned memory references will be handled by
+-the system.
+-.PP
+-\fIM68hc1x Options\fR
+-.IX Subsection "M68hc1x Options"
+-.PP
+-These are the \fB\-m\fR options defined for the 68hc11 and 68hc12
+-microcontrollers. The default values for these options depends on
+-which style of microcontroller was selected when the compiler was configured;
+-the defaults for the most common choices are given below.
+-.IP "\fB\-m6811\fR" 4
+-.IX Item "-m6811"
+-.PD 0
+-.IP "\fB\-m68hc11\fR" 4
+-.IX Item "-m68hc11"
+-.PD
+-Generate output for a 68HC11. This is the default
+-when the compiler is configured for 68HC11\-based systems.
+-.IP "\fB\-m6812\fR" 4
+-.IX Item "-m6812"
+-.PD 0
+-.IP "\fB\-m68hc12\fR" 4
+-.IX Item "-m68hc12"
+-.PD
+-Generate output for a 68HC12. This is the default
+-when the compiler is configured for 68HC12\-based systems.
+-.IP "\fB\-m68S12\fR" 4
+-.IX Item "-m68S12"
+-.PD 0
+-.IP "\fB\-m68hcs12\fR" 4
+-.IX Item "-m68hcs12"
+-.PD
+-Generate output for a 68HCS12.
+-.IP "\fB\-mauto\-incdec\fR" 4
+-.IX Item "-mauto-incdec"
+-Enable the use of 68HC12 pre and post auto-increment and auto-decrement
+-addressing modes.
+-.IP "\fB\-minmax\fR" 4
+-.IX Item "-minmax"
+-.PD 0
+-.IP "\fB\-nominmax\fR" 4
+-.IX Item "-nominmax"
+-.PD
+-Enable the use of 68HC12 min and max instructions.
+-.IP "\fB\-mlong\-calls\fR" 4
+-.IX Item "-mlong-calls"
+-.PD 0
+-.IP "\fB\-mno\-long\-calls\fR" 4
+-.IX Item "-mno-long-calls"
+-.PD
+-Treat all calls as being far away (near). If calls are assumed to be
+-far away, the compiler will use the \f(CW\*(C`call\*(C'\fR instruction to
+-call a function and the \f(CW\*(C`rtc\*(C'\fR instruction for returning.
+-.IP "\fB\-mshort\fR" 4
+-.IX Item "-mshort"
+-Consider type \f(CW\*(C`int\*(C'\fR to be 16 bits wide, like \f(CW\*(C`short int\*(C'\fR.
+-.IP "\fB\-msoft\-reg\-count=\fR\fIcount\fR" 4
+-.IX Item "-msoft-reg-count=count"
+-Specify the number of pseudo-soft registers which are used for the
+-code generation. The maximum number is 32. Using more pseudo-soft
+-register may or may not result in better code depending on the program.
+-The default is 4 for 68HC11 and 2 for 68HC12.
+-.PP
+-\fI\s-1VAX\s0 Options\fR
+-.IX Subsection "VAX Options"
+-.PP
+-These \fB\-m\fR options are defined for the \s-1VAX:\s0
+-.IP "\fB\-munix\fR" 4
+-.IX Item "-munix"
+-Do not output certain jump instructions (\f(CW\*(C`aobleq\*(C'\fR and so on)
+-that the Unix assembler for the \s-1VAX\s0 cannot handle across long
+-ranges.
+-.IP "\fB\-mgnu\fR" 4
+-.IX Item "-mgnu"
+-Do output those jump instructions, on the assumption that you
+-will assemble with the \s-1GNU\s0 assembler.
+-.IP "\fB\-mg\fR" 4
+-.IX Item "-mg"
+-Output code for g\-format floating point numbers instead of d\-format.
+-.PP
+-\fI\s-1SPARC\s0 Options\fR
+-.IX Subsection "SPARC Options"
+-.PP
+-These \fB\-m\fR switches are supported on the \s-1SPARC:\s0
+-.IP "\fB\-mno\-app\-regs\fR" 4
+-.IX Item "-mno-app-regs"
+-.PD 0
+-.IP "\fB\-mapp\-regs\fR" 4
+-.IX Item "-mapp-regs"
+-.PD
+-Specify \fB\-mapp\-regs\fR to generate output using the global registers
+-2 through 4, which the \s-1SPARC\s0 \s-1SVR4\s0 \s-1ABI\s0 reserves for applications. This
+-is the default, except on Solaris.
+-.Sp
+-To be fully \s-1SVR4\s0 \s-1ABI\s0 compliant at the cost of some performance loss,
+-specify \fB\-mno\-app\-regs\fR. You should compile libraries and system
+-software with this option.
+-.IP "\fB\-mfpu\fR" 4
+-.IX Item "-mfpu"
+-.PD 0
+-.IP "\fB\-mhard\-float\fR" 4
+-.IX Item "-mhard-float"
+-.PD
+-Generate output containing floating point instructions. This is the
+-default.
+-.IP "\fB\-mno\-fpu\fR" 4
+-.IX Item "-mno-fpu"
+-.PD 0
+-.IP "\fB\-msoft\-float\fR" 4
+-.IX Item "-msoft-float"
+-.PD
+-Generate output containing library calls for floating point.
+-\&\fBWarning:\fR the requisite libraries are not available for all \s-1SPARC\s0
+-targets. Normally the facilities of the machine's usual C compiler are
+-used, but this cannot be done directly in cross\-compilation. You must make
+-your own arrangements to provide suitable library functions for
+-cross\-compilation. The embedded targets \fBsparc\-*\-aout\fR and
+-\&\fBsparclite\-*\-*\fR do provide software floating point support.
+-.Sp
+-\&\fB\-msoft\-float\fR changes the calling convention in the output file;
+-therefore, it is only useful if you compile \fIall\fR of a program with
+-this option. In particular, you need to compile \fIlibgcc.a\fR, the
+-library that comes with \s-1GCC\s0, with \fB\-msoft\-float\fR in order for
+-this to work.
+-.IP "\fB\-mhard\-quad\-float\fR" 4
+-.IX Item "-mhard-quad-float"
+-Generate output containing quad-word (long double) floating point
+-instructions.
+-.IP "\fB\-msoft\-quad\-float\fR" 4
+-.IX Item "-msoft-quad-float"
+-Generate output containing library calls for quad-word (long double)
+-floating point instructions. The functions called are those specified
+-in the \s-1SPARC\s0 \s-1ABI\s0. This is the default.
+-.Sp
+-As of this writing, there are no sparc implementations that have hardware
+-support for the quad-word floating point instructions. They all invoke
+-a trap handler for one of these instructions, and then the trap handler
+-emulates the effect of the instruction. Because of the trap handler overhead,
+-this is much slower than calling the \s-1ABI\s0 library routines. Thus the
+-\&\fB\-msoft\-quad\-float\fR option is the default.
+-.IP "\fB\-mno\-flat\fR" 4
+-.IX Item "-mno-flat"
+-.PD 0
+-.IP "\fB\-mflat\fR" 4
+-.IX Item "-mflat"
+-.PD
+-With \fB\-mflat\fR, the compiler does not generate save/restore instructions
+-and will use a ``flat'' or single register window calling convention.
+-This model uses \f(CW%i7\fR as the frame pointer and is compatible with the normal
+-register window model. Code from either may be intermixed.
+-The local registers and the input registers (0\-\-5) are still treated as
+-``call saved'' registers and will be saved on the stack as necessary.
+-.Sp
+-With \fB\-mno\-flat\fR (the default), the compiler emits save/restore
+-instructions (except for leaf functions) and is the normal mode of operation.
+-.IP "\fB\-mno\-unaligned\-doubles\fR" 4
+-.IX Item "-mno-unaligned-doubles"
+-.PD 0
+-.IP "\fB\-munaligned\-doubles\fR" 4
+-.IX Item "-munaligned-doubles"
+-.PD
+-Assume that doubles have 8 byte alignment. This is the default.
+-.Sp
+-With \fB\-munaligned\-doubles\fR, \s-1GCC\s0 assumes that doubles have 8 byte
+-alignment only if they are contained in another type, or if they have an
+-absolute address. Otherwise, it assumes they have 4 byte alignment.
+-Specifying this option avoids some rare compatibility problems with code
+-generated by other compilers. It is not the default because it results
+-in a performance loss, especially for floating point code.
+-.IP "\fB\-mno\-faster\-structs\fR" 4
+-.IX Item "-mno-faster-structs"
+-.PD 0
+-.IP "\fB\-mfaster\-structs\fR" 4
+-.IX Item "-mfaster-structs"
+-.PD
+-With \fB\-mfaster\-structs\fR, the compiler assumes that structures
+-should have 8 byte alignment. This enables the use of pairs of
+-\&\f(CW\*(C`ldd\*(C'\fR and \f(CW\*(C`std\*(C'\fR instructions for copies in structure
+-assignment, in place of twice as many \f(CW\*(C`ld\*(C'\fR and \f(CW\*(C`st\*(C'\fR pairs.
+-However, the use of this changed alignment directly violates the \s-1SPARC\s0
+-\&\s-1ABI\s0. Thus, it's intended only for use on targets where the developer
+-acknowledges that their resulting code will not be directly in line with
+-the rules of the \s-1ABI\s0.
+-.IP "\fB\-mimpure\-text\fR" 4
+-.IX Item "-mimpure-text"
+-\&\fB\-mimpure\-text\fR, used in addition to \fB\-shared\fR, tells
+-the compiler to not pass \fB\-z text\fR to the linker when linking a
+-shared object. Using this option, you can link position-dependent
+-code into a shared object.
+-.Sp
+-\&\fB\-mimpure\-text\fR suppresses the ``relocations remain against
+-allocatable but non-writable sections'' linker error message.
+-However, the necessary relocations will trigger copy\-on\-write, and the
+-shared object is not actually shared across processes. Instead of
+-using \fB\-mimpure\-text\fR, you should compile all source code with
+-\&\fB\-fpic\fR or \fB\-fPIC\fR.
+-.Sp
+-This option is only available on SunOS and Solaris.
+-.IP "\fB\-mv8\fR" 4
+-.IX Item "-mv8"
+-.PD 0
+-.IP "\fB\-msparclite\fR" 4
+-.IX Item "-msparclite"
+-.PD
+-These two options select variations on the \s-1SPARC\s0 architecture.
+-.Sp
+-By default (unless specifically configured for the Fujitsu SPARClite),
+-\&\s-1GCC\s0 generates code for the v7 variant of the \s-1SPARC\s0 architecture.
+-.Sp
+-\&\fB\-mv8\fR will give you \s-1SPARC\s0 v8 code. The only difference from v7
+-code is that the compiler emits the integer multiply and integer
+-divide instructions which exist in \s-1SPARC\s0 v8 but not in \s-1SPARC\s0 v7.
+-.Sp
+-\&\fB\-msparclite\fR will give you SPARClite code. This adds the integer
+-multiply, integer divide step and scan (\f(CW\*(C`ffs\*(C'\fR) instructions which
+-exist in SPARClite but not in \s-1SPARC\s0 v7.
+-.Sp
+-These options are deprecated and will be deleted in a future \s-1GCC\s0 release.
+-They have been replaced with \fB\-mcpu=xxx\fR.
+-.IP "\fB\-mcypress\fR" 4
+-.IX Item "-mcypress"
+-.PD 0
+-.IP "\fB\-msupersparc\fR" 4
+-.IX Item "-msupersparc"
+-.PD
+-These two options select the processor for which the code is optimized.
+-.Sp
+-With \fB\-mcypress\fR (the default), the compiler optimizes code for the
+-Cypress \s-1CY7C602\s0 chip, as used in the SPARCStation/SPARCServer 3xx series.
+-This is also appropriate for the older SPARCStation 1, 2, \s-1IPX\s0 etc.
+-.Sp
+-With \fB\-msupersparc\fR the compiler optimizes code for the SuperSPARC cpu, as
+-used in the SPARCStation 10, 1000 and 2000 series. This flag also enables use
+-of the full \s-1SPARC\s0 v8 instruction set.
+-.Sp
+-These options are deprecated and will be deleted in a future \s-1GCC\s0 release.
+-They have been replaced with \fB\-mcpu=xxx\fR.
+-.IP "\fB\-mcpu=\fR\fIcpu_type\fR" 4
+-.IX Item "-mcpu=cpu_type"
+-Set the instruction set, register set, and instruction scheduling parameters
+-for machine type \fIcpu_type\fR. Supported values for \fIcpu_type\fR are
+-\&\fBv7\fR, \fBcypress\fR, \fBv8\fR, \fBsupersparc\fR, \fBsparclite\fR,
+-\&\fBhypersparc\fR, \fBsparclite86x\fR, \fBf930\fR, \fBf934\fR,
+-\&\fBsparclet\fR, \fBtsc701\fR, \fBv9\fR, \fBultrasparc\fR, and
+-\&\fBultrasparc3\fR.
+-.Sp
+-Default instruction scheduling parameters are used for values that select
+-an architecture and not an implementation. These are \fBv7\fR, \fBv8\fR,
+-\&\fBsparclite\fR, \fBsparclet\fR, \fBv9\fR.
+-.Sp
+-Here is a list of each supported architecture and their supported
+-implementations.
+-.Sp
+-.Vb 5
+-\& v7: cypress
+-\& v8: supersparc, hypersparc
+-\& sparclite: f930, f934, sparclite86x
+-\& sparclet: tsc701
+-\& v9: ultrasparc, ultrasparc3
+-.Ve
+-.IP "\fB\-mtune=\fR\fIcpu_type\fR" 4
+-.IX Item "-mtune=cpu_type"
+-Set the instruction scheduling parameters for machine type
+-\&\fIcpu_type\fR, but do not set the instruction set or register set that the
+-option \fB\-mcpu=\fR\fIcpu_type\fR would.
+-.Sp
+-The same values for \fB\-mcpu=\fR\fIcpu_type\fR can be used for
+-\&\fB\-mtune=\fR\fIcpu_type\fR, but the only useful values are those
+-that select a particular cpu implementation. Those are \fBcypress\fR,
+-\&\fBsupersparc\fR, \fBhypersparc\fR, \fBf930\fR, \fBf934\fR,
+-\&\fBsparclite86x\fR, \fBtsc701\fR, \fBultrasparc\fR, and
+-\&\fBultrasparc3\fR.
+-.PP
+-These \fB\-m\fR switches are supported in addition to the above
+-on the \s-1SPARCLET\s0 processor.
+-.IP "\fB\-mlittle\-endian\fR" 4
+-.IX Item "-mlittle-endian"
+-Generate code for a processor running in little-endian mode.
+-.IP "\fB\-mlive\-g0\fR" 4
+-.IX Item "-mlive-g0"
+-Treat register \f(CW%g0\fR as a normal register.
+-\&\s-1GCC\s0 will continue to clobber it as necessary but will not assume
+-it always reads as 0.
+-.IP "\fB\-mbroken\-saverestore\fR" 4
+-.IX Item "-mbroken-saverestore"
+-Generate code that does not use non-trivial forms of the \f(CW\*(C`save\*(C'\fR and
+-\&\f(CW\*(C`restore\*(C'\fR instructions. Early versions of the \s-1SPARCLET\s0 processor do
+-not correctly handle \f(CW\*(C`save\*(C'\fR and \f(CW\*(C`restore\*(C'\fR instructions used with
+-arguments. They correctly handle them used without arguments. A \f(CW\*(C`save\*(C'\fR
+-instruction used without arguments increments the current window pointer
+-but does not allocate a new stack frame. It is assumed that the window
+-overflow trap handler will properly handle this case as will interrupt
+-handlers.
+-.PP
+-These \fB\-m\fR switches are supported in addition to the above
+-on \s-1SPARC\s0 V9 processors in 64\-bit environments.
+-.IP "\fB\-mlittle\-endian\fR" 4
+-.IX Item "-mlittle-endian"
+-Generate code for a processor running in little-endian mode. It is only
+-available for a few configurations and most notably not on Solaris.
+-.IP "\fB\-m32\fR" 4
+-.IX Item "-m32"
+-.PD 0
+-.IP "\fB\-m64\fR" 4
+-.IX Item "-m64"
+-.PD
+-Generate code for a 32\-bit or 64\-bit environment.
+-The 32\-bit environment sets int, long and pointer to 32 bits.
+-The 64\-bit environment sets int to 32 bits and long and pointer
+-to 64 bits.
+-.IP "\fB\-mcmodel=medlow\fR" 4
+-.IX Item "-mcmodel=medlow"
+-Generate code for the Medium/Low code model: the program must be linked
+-in the low 32 bits of the address space. Pointers are 64 bits.
+-Programs can be statically or dynamically linked.
+-.IP "\fB\-mcmodel=medmid\fR" 4
+-.IX Item "-mcmodel=medmid"
+-Generate code for the Medium/Middle code model: the program must be linked
+-in the low 44 bits of the address space, the text segment must be less than
+-2G bytes, and data segment must be within 2G of the text segment.
+-Pointers are 64 bits.
+-.IP "\fB\-mcmodel=medany\fR" 4
+-.IX Item "-mcmodel=medany"
+-Generate code for the Medium/Anywhere code model: the program may be linked
+-anywhere in the address space, the text segment must be less than
+-2G bytes, and data segment must be within 2G of the text segment.
+-Pointers are 64 bits.
+-.IP "\fB\-mcmodel=embmedany\fR" 4
+-.IX Item "-mcmodel=embmedany"
+-Generate code for the Medium/Anywhere code model for embedded systems:
+-assume a 32\-bit text and a 32\-bit data segment, both starting anywhere
+-(determined at link time). Register \f(CW%g4\fR points to the base of the
+-data segment. Pointers are still 64 bits.
+-Programs are statically linked, \s-1PIC\s0 is not supported.
+-.IP "\fB\-mstack\-bias\fR" 4
+-.IX Item "-mstack-bias"
+-.PD 0
+-.IP "\fB\-mno\-stack\-bias\fR" 4
+-.IX Item "-mno-stack-bias"
+-.PD
+-With \fB\-mstack\-bias\fR, \s-1GCC\s0 assumes that the stack pointer, and
+-frame pointer if present, are offset by \-2047 which must be added back
+-when making stack frame references.
+-Otherwise, assume no such offset is present.
+-.PP
+-These switches are supported in addition to the above on Solaris:
+-.IP "\fB\-threads\fR" 4
+-.IX Item "-threads"
+-Add support for multithreading using the Solaris threads library. This
+-option sets flags for both the preprocessor and linker. This option does
+-not affect the thread safety of object code produced by the compiler or
+-that of libraries supplied with it.
+-.IP "\fB\-pthreads\fR" 4
+-.IX Item "-pthreads"
+-Add support for multithreading using the \s-1POSIX\s0 threads library. This
+-option sets flags for both the preprocessor and linker. This option does
+-not affect the thread safety of object code produced by the compiler or
+-that of libraries supplied with it.
+-.PP
+-\fI\s-1ARM\s0 Options\fR
+-.IX Subsection "ARM Options"
+-.PP
+-These \fB\-m\fR options are defined for Advanced \s-1RISC\s0 Machines (\s-1ARM\s0)
+-architectures:
+-.IP "\fB\-mapcs\-frame\fR" 4
+-.IX Item "-mapcs-frame"
+-Generate a stack frame that is compliant with the \s-1ARM\s0 Procedure Call
+-Standard for all functions, even if this is not strictly necessary for
+-correct execution of the code. Specifying \fB\-fomit\-frame\-pointer\fR
+-with this option will cause the stack frames not to be generated for
+-leaf functions. The default is \fB\-mno\-apcs\-frame\fR.
+-.IP "\fB\-mapcs\fR" 4
+-.IX Item "-mapcs"
+-This is a synonym for \fB\-mapcs\-frame\fR.
+-.IP "\fB\-mapcs\-26\fR" 4
+-.IX Item "-mapcs-26"
+-Generate code for a processor running with a 26\-bit program counter,
+-and conforming to the function calling standards for the \s-1APCS\s0 26\-bit
+-option. This option replaces the \fB\-m2\fR and \fB\-m3\fR options
+-of previous releases of the compiler.
+-.IP "\fB\-mapcs\-32\fR" 4
+-.IX Item "-mapcs-32"
+-Generate code for a processor running with a 32\-bit program counter,
+-and conforming to the function calling standards for the \s-1APCS\s0 32\-bit
+-option. This option replaces the \fB\-m6\fR option of previous releases
+-of the compiler.
+-.IP "\fB\-mthumb\-interwork\fR" 4
+-.IX Item "-mthumb-interwork"
+-Generate code which supports calling between the \s-1ARM\s0 and Thumb
+-instruction sets. Without this option the two instruction sets cannot
+-be reliably used inside one program. The default is
+-\&\fB\-mno\-thumb\-interwork\fR, since slightly larger code is generated
+-when \fB\-mthumb\-interwork\fR is specified.
+-.IP "\fB\-mno\-sched\-prolog\fR" 4
+-.IX Item "-mno-sched-prolog"
+-Prevent the reordering of instructions in the function prolog, or the
+-merging of those instruction with the instructions in the function's
+-body. This means that all functions will start with a recognizable set
+-of instructions (or in fact one of a choice from a small set of
+-different function prologues), and this information can be used to
+-locate the start if functions inside an executable piece of code. The
+-default is \fB\-msched\-prolog\fR.
+-.IP "\fB\-mhard\-float\fR" 4
+-.IX Item "-mhard-float"
+-Generate output containing floating point instructions. This is the
+-default.
+-.IP "\fB\-msoft\-float\fR" 4
+-.IX Item "-msoft-float"
+-Generate output containing library calls for floating point.
+-\&\fBWarning:\fR the requisite libraries are not available for all \s-1ARM\s0
+-targets. Normally the facilities of the machine's usual C compiler are
+-used, but this cannot be done directly in cross\-compilation. You must make
+-your own arrangements to provide suitable library functions for
+-cross\-compilation.
+-.Sp
+-\&\fB\-msoft\-float\fR changes the calling convention in the output file;
+-therefore, it is only useful if you compile \fIall\fR of a program with
+-this option. In particular, you need to compile \fIlibgcc.a\fR, the
+-library that comes with \s-1GCC\s0, with \fB\-msoft\-float\fR in order for
+-this to work.
+-.IP "\fB\-mlittle\-endian\fR" 4
+-.IX Item "-mlittle-endian"
+-Generate code for a processor running in little-endian mode. This is
+-the default for all standard configurations.
+-.IP "\fB\-mbig\-endian\fR" 4
+-.IX Item "-mbig-endian"
+-Generate code for a processor running in big-endian mode; the default is
+-to compile code for a little-endian processor.
+-.IP "\fB\-mwords\-little\-endian\fR" 4
+-.IX Item "-mwords-little-endian"
+-This option only applies when generating code for big-endian processors.
+-Generate code for a little-endian word order but a big-endian byte
+-order. That is, a byte order of the form \fB32107654\fR. Note: this
+-option should only be used if you require compatibility with code for
+-big-endian \s-1ARM\s0 processors generated by versions of the compiler prior to
+-2.8.
+-.IP "\fB\-malignment\-traps\fR" 4
+-.IX Item "-malignment-traps"
+-Generate code that will not trap if the \s-1MMU\s0 has alignment traps enabled.
+-On \s-1ARM\s0 architectures prior to ARMv4, there were no instructions to
+-access half-word objects stored in memory. However, when reading from
+-memory a feature of the \s-1ARM\s0 architecture allows a word load to be used,
+-even if the address is unaligned, and the processor core will rotate the
+-data as it is being loaded. This option tells the compiler that such
+-misaligned accesses will cause a \s-1MMU\s0 trap and that it should instead
+-synthesize the access as a series of byte accesses. The compiler can
+-still use word accesses to load half-word data if it knows that the
+-address is aligned to a word boundary.
+-.Sp
+-This option is ignored when compiling for \s-1ARM\s0 architecture 4 or later,
+-since these processors have instructions to directly access half-word
+-objects in memory.
+-.IP "\fB\-mno\-alignment\-traps\fR" 4
+-.IX Item "-mno-alignment-traps"
+-Generate code that assumes that the \s-1MMU\s0 will not trap unaligned
+-accesses. This produces better code when the target instruction set
+-does not have half-word memory operations (i.e. implementations prior to
+-ARMv4).
+-.Sp
+-Note that you cannot use this option to access unaligned word objects,
+-since the processor will only fetch one 32\-bit aligned object from
+-memory.
+-.Sp
+-The default setting for most targets is \fB\-mno\-alignment\-traps\fR, since
+-this produces better code when there are no half-word memory
+-instructions available.
+-.IP "\fB\-mshort\-load\-bytes\fR" 4
+-.IX Item "-mshort-load-bytes"
+-.PD 0
+-.IP "\fB\-mno\-short\-load\-words\fR" 4
+-.IX Item "-mno-short-load-words"
+-.PD
+-These are deprecated aliases for \fB\-malignment\-traps\fR.
+-.IP "\fB\-mno\-short\-load\-bytes\fR" 4
+-.IX Item "-mno-short-load-bytes"
+-.PD 0
+-.IP "\fB\-mshort\-load\-words\fR" 4
+-.IX Item "-mshort-load-words"
+-.PD
+-This are deprecated aliases for \fB\-mno\-alignment\-traps\fR.
+-.IP "\fB\-mcpu=\fR\fIname\fR" 4
+-.IX Item "-mcpu=name"
+-This specifies the name of the target \s-1ARM\s0 processor. \s-1GCC\s0 uses this name
+-to determine what kind of instructions it can emit when generating
+-assembly code. Permissible names are: \fBarm2\fR, \fBarm250\fR,
+-\&\fBarm3\fR, \fBarm6\fR, \fBarm60\fR, \fBarm600\fR, \fBarm610\fR,
+-\&\fBarm620\fR, \fBarm7\fR, \fBarm7m\fR, \fBarm7d\fR, \fBarm7dm\fR,
+-\&\fBarm7di\fR, \fBarm7dmi\fR, \fBarm70\fR, \fBarm700\fR,
+-\&\fBarm700i\fR, \fBarm710\fR, \fBarm710c\fR, \fBarm7100\fR,
+-\&\fBarm7500\fR, \fBarm7500fe\fR, \fBarm7tdmi\fR, \fBarm8\fR,
+-\&\fBstrongarm\fR, \fBstrongarm110\fR, \fBstrongarm1100\fR,
+-\&\fBarm8\fR, \fBarm810\fR, \fBarm9\fR, \fBarm9e\fR, \fBarm920\fR,
+-\&\fBarm920t\fR, \fBarm940t\fR, \fBarm9tdmi\fR, \fBarm10tdmi\fR,
+-\&\fBarm1020t\fR, \fBxscale\fR.
+-.IP "\fB\-mtune=\fR\fIname\fR" 4
+-.IX Item "-mtune=name"
+-This option is very similar to the \fB\-mcpu=\fR option, except that
+-instead of specifying the actual target processor type, and hence
+-restricting which instructions can be used, it specifies that \s-1GCC\s0 should
+-tune the performance of the code as if the target were of the type
+-specified in this option, but still choosing the instructions that it
+-will generate based on the cpu specified by a \fB\-mcpu=\fR option.
+-For some \s-1ARM\s0 implementations better performance can be obtained by using
+-this option.
+-.IP "\fB\-march=\fR\fIname\fR" 4
+-.IX Item "-march=name"
+-This specifies the name of the target \s-1ARM\s0 architecture. \s-1GCC\s0 uses this
+-name to determine what kind of instructions it can emit when generating
+-assembly code. This option can be used in conjunction with or instead
+-of the \fB\-mcpu=\fR option. Permissible names are: \fBarmv2\fR,
+-\&\fBarmv2a\fR, \fBarmv3\fR, \fBarmv3m\fR, \fBarmv4\fR, \fBarmv4t\fR,
+-\&\fBarmv5\fR, \fBarmv5t\fR, \fBarmv5te\fR.
+-.IP "\fB\-mfpe=\fR\fInumber\fR" 4
+-.IX Item "-mfpe=number"
+-.PD 0
+-.IP "\fB\-mfp=\fR\fInumber\fR" 4
+-.IX Item "-mfp=number"
+-.PD
+-This specifies the version of the floating point emulation available on
+-the target. Permissible values are 2 and 3. \fB\-mfp=\fR is a synonym
+-for \fB\-mfpe=\fR, for compatibility with older versions of \s-1GCC\s0.
+-.IP "\fB\-mstructure\-size\-boundary=\fR\fIn\fR" 4
+-.IX Item "-mstructure-size-boundary=n"
+-The size of all structures and unions will be rounded up to a multiple
+-of the number of bits set by this option. Permissible values are 8 and
+-32. The default value varies for different toolchains. For the \s-1COFF\s0
+-targeted toolchain the default value is 8. Specifying the larger number
+-can produce faster, more efficient code, but can also increase the size
+-of the program. The two values are potentially incompatible. Code
+-compiled with one value cannot necessarily expect to work with code or
+-libraries compiled with the other value, if they exchange information
+-using structures or unions.
+-.IP "\fB\-mabort\-on\-noreturn\fR" 4
+-.IX Item "-mabort-on-noreturn"
+-Generate a call to the function \f(CW\*(C`abort\*(C'\fR at the end of a
+-\&\f(CW\*(C`noreturn\*(C'\fR function. It will be executed if the function tries to
+-return.
+-.IP "\fB\-mlong\-calls\fR" 4
+-.IX Item "-mlong-calls"
+-.PD 0
+-.IP "\fB\-mno\-long\-calls\fR" 4
+-.IX Item "-mno-long-calls"
+-.PD
+-Tells the compiler to perform function calls by first loading the
+-address of the function into a register and then performing a subroutine
+-call on this register. This switch is needed if the target function
+-will lie outside of the 64 megabyte addressing range of the offset based
+-version of subroutine call instruction.
+-.Sp
+-Even if this switch is enabled, not all function calls will be turned
+-into long calls. The heuristic is that static functions, functions
+-which have the \fBshort-call\fR attribute, functions that are inside
+-the scope of a \fB#pragma no_long_calls\fR directive and functions whose
+-definitions have already been compiled within the current compilation
+-unit, will not be turned into long calls. The exception to this rule is
+-that weak function definitions, functions with the \fBlong-call\fR
+-attribute or the \fBsection\fR attribute, and functions that are within
+-the scope of a \fB#pragma long_calls\fR directive, will always be
+-turned into long calls.
+-.Sp
+-This feature is not enabled by default. Specifying
+-\&\fB\-mno\-long\-calls\fR will restore the default behavior, as will
+-placing the function calls within the scope of a \fB#pragma
+-long_calls_off\fR directive. Note these switches have no effect on how
+-the compiler generates code to handle function calls via function
+-pointers.
+-.IP "\fB\-mnop\-fun\-dllimport\fR" 4
+-.IX Item "-mnop-fun-dllimport"
+-Disable support for the \f(CW\*(C`dllimport\*(C'\fR attribute.
+-.IP "\fB\-msingle\-pic\-base\fR" 4
+-.IX Item "-msingle-pic-base"
+-Treat the register used for \s-1PIC\s0 addressing as read\-only, rather than
+-loading it in the prologue for each function. The run-time system is
+-responsible for initializing this register with an appropriate value
+-before execution begins.
+-.IP "\fB\-mpic\-register=\fR\fIreg\fR" 4
+-.IX Item "-mpic-register=reg"
+-Specify the register to be used for \s-1PIC\s0 addressing. The default is R10
+-unless stack-checking is enabled, when R9 is used.
+-.IP "\fB\-mpoke\-function\-name\fR" 4
+-.IX Item "-mpoke-function-name"
+-Write the name of each function into the text section, directly
+-preceding the function prologue. The generated code is similar to this:
+-.Sp
+-.Vb 9
+-\& t0
+-\& .ascii "arm_poke_function_name", 0
+-\& .align
+-\& t1
+-\& .word 0xff000000 + (t1 - t0)
+-\& arm_poke_function_name
+-\& mov ip, sp
+-\& stmfd sp!, {fp, ip, lr, pc}
+-\& sub fp, ip, #4
+-.Ve
+-.Sp
+-When performing a stack backtrace, code can inspect the value of
+-\&\f(CW\*(C`pc\*(C'\fR stored at \f(CW\*(C`fp + 0\*(C'\fR. If the trace function then looks at
+-location \f(CW\*(C`pc \- 12\*(C'\fR and the top 8 bits are set, then we know that
+-there is a function name embedded immediately preceding this location
+-and has length \f(CW\*(C`((pc[\-3]) & 0xff000000)\*(C'\fR.
+-.IP "\fB\-mthumb\fR" 4
+-.IX Item "-mthumb"
+-Generate code for the 16\-bit Thumb instruction set. The default is to
+-use the 32\-bit \s-1ARM\s0 instruction set.
+-.IP "\fB\-mtpcs\-frame\fR" 4
+-.IX Item "-mtpcs-frame"
+-Generate a stack frame that is compliant with the Thumb Procedure Call
+-Standard for all non-leaf functions. (A leaf function is one that does
+-not call any other functions.) The default is \fB\-mno\-tpcs\-frame\fR.
+-.IP "\fB\-mtpcs\-leaf\-frame\fR" 4
+-.IX Item "-mtpcs-leaf-frame"
+-Generate a stack frame that is compliant with the Thumb Procedure Call
+-Standard for all leaf functions. (A leaf function is one that does
+-not call any other functions.) The default is \fB\-mno\-apcs\-leaf\-frame\fR.
+-.IP "\fB\-mcallee\-super\-interworking\fR" 4
+-.IX Item "-mcallee-super-interworking"
+-Gives all externally visible functions in the file being compiled an \s-1ARM\s0
+-instruction set header which switches to Thumb mode before executing the
+-rest of the function. This allows these functions to be called from
+-non-interworking code.
+-.IP "\fB\-mcaller\-super\-interworking\fR" 4
+-.IX Item "-mcaller-super-interworking"
+-Allows calls via function pointers (including virtual functions) to
+-execute correctly regardless of whether the target code has been
+-compiled for interworking or not. There is a small overhead in the cost
+-of executing a function pointer if this option is enabled.
+-.PP
+-\fI\s-1MN10200\s0 Options\fR
+-.IX Subsection "MN10200 Options"
+-.PP
+-These \fB\-m\fR options are defined for Matsushita \s-1MN10200\s0 architectures:
+-.IP "\fB\-mrelax\fR" 4
+-.IX Item "-mrelax"
+-Indicate to the linker that it should perform a relaxation optimization pass
+-to shorten branches, calls and absolute memory addresses. This option only
+-has an effect when used on the command line for the final link step.
+-.Sp
+-This option makes symbolic debugging impossible.
+-.PP
+-\fI\s-1MN10300\s0 Options\fR
+-.IX Subsection "MN10300 Options"
+-.PP
+-These \fB\-m\fR options are defined for Matsushita \s-1MN10300\s0 architectures:
+-.IP "\fB\-mmult\-bug\fR" 4
+-.IX Item "-mmult-bug"
+-Generate code to avoid bugs in the multiply instructions for the \s-1MN10300\s0
+-processors. This is the default.
+-.IP "\fB\-mno\-mult\-bug\fR" 4
+-.IX Item "-mno-mult-bug"
+-Do not generate code to avoid bugs in the multiply instructions for the
+-\&\s-1MN10300\s0 processors.
+-.IP "\fB\-mam33\fR" 4
+-.IX Item "-mam33"
+-Generate code which uses features specific to the \s-1AM33\s0 processor.
+-.IP "\fB\-mno\-am33\fR" 4
+-.IX Item "-mno-am33"
+-Do not generate code which uses features specific to the \s-1AM33\s0 processor. This
+-is the default.
+-.IP "\fB\-mno\-crt0\fR" 4
+-.IX Item "-mno-crt0"
+-Do not link in the C run-time initialization object file.
+-.IP "\fB\-mrelax\fR" 4
+-.IX Item "-mrelax"
+-Indicate to the linker that it should perform a relaxation optimization pass
+-to shorten branches, calls and absolute memory addresses. This option only
+-has an effect when used on the command line for the final link step.
+-.Sp
+-This option makes symbolic debugging impossible.
+-.PP
+-\fIM32R/D Options\fR
+-.IX Subsection "M32R/D Options"
+-.PP
+-These \fB\-m\fR options are defined for Mitsubishi M32R/D architectures:
+-.IP "\fB\-m32rx\fR" 4
+-.IX Item "-m32rx"
+-Generate code for the M32R/X.
+-.IP "\fB\-m32r\fR" 4
+-.IX Item "-m32r"
+-Generate code for the M32R. This is the default.
+-.IP "\fB\-mcode\-model=small\fR" 4
+-.IX Item "-mcode-model=small"
+-Assume all objects live in the lower 16MB of memory (so that their addresses
+-can be loaded with the \f(CW\*(C`ld24\*(C'\fR instruction), and assume all subroutines
+-are reachable with the \f(CW\*(C`bl\*(C'\fR instruction.
+-This is the default.
+-.Sp
+-The addressability of a particular object can be set with the
+-\&\f(CW\*(C`model\*(C'\fR attribute.
+-.IP "\fB\-mcode\-model=medium\fR" 4
+-.IX Item "-mcode-model=medium"
+-Assume objects may be anywhere in the 32\-bit address space (the compiler
+-will generate \f(CW\*(C`seth/add3\*(C'\fR instructions to load their addresses), and
+-assume all subroutines are reachable with the \f(CW\*(C`bl\*(C'\fR instruction.
+-.IP "\fB\-mcode\-model=large\fR" 4
+-.IX Item "-mcode-model=large"
+-Assume objects may be anywhere in the 32\-bit address space (the compiler
+-will generate \f(CW\*(C`seth/add3\*(C'\fR instructions to load their addresses), and
+-assume subroutines may not be reachable with the \f(CW\*(C`bl\*(C'\fR instruction
+-(the compiler will generate the much slower \f(CW\*(C`seth/add3/jl\*(C'\fR
+-instruction sequence).
+-.IP "\fB\-msdata=none\fR" 4
+-.IX Item "-msdata=none"
+-Disable use of the small data area. Variables will be put into
+-one of \fB.data\fR, \fBbss\fR, or \fB.rodata\fR (unless the
+-\&\f(CW\*(C`section\*(C'\fR attribute has been specified).
+-This is the default.
+-.Sp
+-The small data area consists of sections \fB.sdata\fR and \fB.sbss\fR.
+-Objects may be explicitly put in the small data area with the
+-\&\f(CW\*(C`section\*(C'\fR attribute using one of these sections.
+-.IP "\fB\-msdata=sdata\fR" 4
+-.IX Item "-msdata=sdata"
+-Put small global and static data in the small data area, but do not
+-generate special code to reference them.
+-.IP "\fB\-msdata=use\fR" 4
+-.IX Item "-msdata=use"
+-Put small global and static data in the small data area, and generate
+-special instructions to reference them.
+-.IP "\fB\-G\fR \fInum\fR" 4
+-.IX Item "-G num"
+-Put global and static objects less than or equal to \fInum\fR bytes
+-into the small data or bss sections instead of the normal data or bss
+-sections. The default value of \fInum\fR is 8.
+-The \fB\-msdata\fR option must be set to one of \fBsdata\fR or \fBuse\fR
+-for this option to have any effect.
+-.Sp
+-All modules should be compiled with the same \fB\-G\fR \fInum\fR value.
+-Compiling with different values of \fInum\fR may or may not work; if it
+-doesn't the linker will give an error message\-\-\-incorrect code will not be
+-generated.
+-.PP
+-\fIM88K Options\fR
+-.IX Subsection "M88K Options"
+-.PP
+-These \fB\-m\fR options are defined for Motorola 88k architectures:
+-.IP "\fB\-m88000\fR" 4
+-.IX Item "-m88000"
+-Generate code that works well on both the m88100 and the
+-m88110.
+-.IP "\fB\-m88100\fR" 4
+-.IX Item "-m88100"
+-Generate code that works best for the m88100, but that also
+-runs on the m88110.
+-.IP "\fB\-m88110\fR" 4
+-.IX Item "-m88110"
+-Generate code that works best for the m88110, and may not run
+-on the m88100.
+-.IP "\fB\-mbig\-pic\fR" 4
+-.IX Item "-mbig-pic"
+-Obsolete option to be removed from the next revision.
+-Use \fB\-fPIC\fR.
+-.IP "\fB\-midentify\-revision\fR" 4
+-.IX Item "-midentify-revision"
+-Include an \f(CW\*(C`ident\*(C'\fR directive in the assembler output recording the
+-source file name, compiler name and version, timestamp, and compilation
+-flags used.
+-.IP "\fB\-mno\-underscores\fR" 4
+-.IX Item "-mno-underscores"
+-In assembler output, emit symbol names without adding an underscore
+-character at the beginning of each name. The default is to use an
+-underscore as prefix on each name.
+-.IP "\fB\-mocs\-debug\-info\fR" 4
+-.IX Item "-mocs-debug-info"
+-.PD 0
+-.IP "\fB\-mno\-ocs\-debug\-info\fR" 4
+-.IX Item "-mno-ocs-debug-info"
+-.PD
+-Include (or omit) additional debugging information (about registers used
+-in each stack frame) as specified in the 88open Object Compatibility
+-Standard, ``\s-1OCS\s0''. This extra information allows debugging of code that
+-has had the frame pointer eliminated. The default for SVr4 and Delta 88
+-SVr3.2 is to include this information; other 88k configurations omit this
+-information by default.
+-.IP "\fB\-mocs\-frame\-position\fR" 4
+-.IX Item "-mocs-frame-position"
+-When emitting \s-1COFF\s0 debugging information for automatic variables and
+-parameters stored on the stack, use the offset from the canonical frame
+-address, which is the stack pointer (register 31) on entry to the
+-function. The SVr4 and Delta88 SVr3.2, and \s-1BCS\s0 configurations use
+-\&\fB\-mocs\-frame\-position\fR; other 88k configurations have the default
+-\&\fB\-mno\-ocs\-frame\-position\fR.
+-.IP "\fB\-mno\-ocs\-frame\-position\fR" 4
+-.IX Item "-mno-ocs-frame-position"
+-When emitting \s-1COFF\s0 debugging information for automatic variables and
+-parameters stored on the stack, use the offset from the frame pointer
+-register (register 30). When this option is in effect, the frame
+-pointer is not eliminated when debugging information is selected by the
+-\&\-g switch.
+-.IP "\fB\-moptimize\-arg\-area\fR" 4
+-.IX Item "-moptimize-arg-area"
+-Save space by reorganizing the stack frame. This option generates code
+-that does not agree with the 88open specifications, but uses less
+-memory.
+-.IP "\fB\-mno\-optimize\-arg\-area\fR" 4
+-.IX Item "-mno-optimize-arg-area"
+-Do not reorganize the stack frame to save space. This is the default.
+-The generated conforms to the specification, but uses more memory.
+-.IP "\fB\-mshort\-data\-\fR\fInum\fR" 4
+-.IX Item "-mshort-data-num"
+-Generate smaller data references by making them relative to \f(CW\*(C`r0\*(C'\fR,
+-which allows loading a value using a single instruction (rather than the
+-usual two). You control which data references are affected by
+-specifying \fInum\fR with this option. For example, if you specify
+-\&\fB\-mshort\-data\-512\fR, then the data references affected are those
+-involving displacements of less than 512 bytes.
+-\&\fB\-mshort\-data\-\fR\fInum\fR is not effective for \fInum\fR greater
+-than 64k.
+-.IP "\fB\-mserialize\-volatile\fR" 4
+-.IX Item "-mserialize-volatile"
+-.PD 0
+-.IP "\fB\-mno\-serialize\-volatile\fR" 4
+-.IX Item "-mno-serialize-volatile"
+-.PD
+-Do, or don't, generate code to guarantee sequential consistency
+-of volatile memory references. By default, consistency is
+-guaranteed.
+-.Sp
+-The order of memory references made by the \s-1MC88110\s0 processor does
+-not always match the order of the instructions requesting those
+-references. In particular, a load instruction may execute before
+-a preceding store instruction. Such reordering violates
+-sequential consistency of volatile memory references, when there
+-are multiple processors. When consistency must be guaranteed,
+-\&\s-1GCC\s0 generates special instructions, as needed, to force
+-execution in the proper order.
+-.Sp
+-The \s-1MC88100\s0 processor does not reorder memory references and so
+-always provides sequential consistency. However, by default, \s-1GCC\s0
+-generates the special instructions to guarantee consistency
+-even when you use \fB\-m88100\fR, so that the code may be run on an
+-\&\s-1MC88110\s0 processor. If you intend to run your code only on the
+-\&\s-1MC88100\s0 processor, you may use \fB\-mno\-serialize\-volatile\fR.
+-.Sp
+-The extra code generated to guarantee consistency may affect the
+-performance of your application. If you know that you can safely
+-forgo this guarantee, you may use \fB\-mno\-serialize\-volatile\fR.
+-.IP "\fB\-msvr4\fR" 4
+-.IX Item "-msvr4"
+-.PD 0
+-.IP "\fB\-msvr3\fR" 4
+-.IX Item "-msvr3"
+-.PD
+-Turn on (\fB\-msvr4\fR) or off (\fB\-msvr3\fR) compiler extensions
+-related to System V release 4 (SVr4). This controls the following:
+-.RS 4
+-.IP "1." 4
+-Which variant of the assembler syntax to emit.
+-.IP "2." 4
+-\&\fB\-msvr4\fR makes the C preprocessor recognize \fB#pragma weak\fR
+-that is used on System V release 4.
+-.IP "3." 4
+-\&\fB\-msvr4\fR makes \s-1GCC\s0 issue additional declaration directives used in
+-SVr4.
+-.RE
+-.RS 4
+-.Sp
+-\&\fB\-msvr4\fR is the default for the m88k\-motorola\-sysv4 configuration.
+-\&\fB\-msvr3\fR is the default for all other m88k configurations.
+-.RE
+-.IP "\fB\-mversion\-03.00\fR" 4
+-.IX Item "-mversion-03.00"
+-This option is obsolete, and is ignored.
+-.IP "\fB\-mno\-check\-zero\-division\fR" 4
+-.IX Item "-mno-check-zero-division"
+-.PD 0
+-.IP "\fB\-mcheck\-zero\-division\fR" 4
+-.IX Item "-mcheck-zero-division"
+-.PD
+-Do, or don't, generate code to guarantee that integer division by
+-zero will be detected. By default, detection is guaranteed.
+-.Sp
+-Some models of the \s-1MC88100\s0 processor fail to trap upon integer
+-division by zero under certain conditions. By default, when
+-compiling code that might be run on such a processor, \s-1GCC\s0
+-generates code that explicitly checks for zero-valued divisors
+-and traps with exception number 503 when one is detected. Use of
+-\&\fB\-mno\-check\-zero\-division\fR suppresses such checking for code
+-generated to run on an \s-1MC88100\s0 processor.
+-.Sp
+-\&\s-1GCC\s0 assumes that the \s-1MC88110\s0 processor correctly detects all instances
+-of integer division by zero. When \fB\-m88110\fR is specified, no
+-explicit checks for zero-valued divisors are generated, and both
+-\&\fB\-mcheck\-zero\-division\fR and \fB\-mno\-check\-zero\-division\fR are
+-ignored.
+-.IP "\fB\-muse\-div\-instruction\fR" 4
+-.IX Item "-muse-div-instruction"
+-Use the div instruction for signed integer division on the
+-\&\s-1MC88100\s0 processor. By default, the div instruction is not used.
+-.Sp
+-On the \s-1MC88100\s0 processor the signed integer division instruction
+-div) traps to the operating system on a negative operand. The
+-operating system transparently completes the operation, but at a
+-large cost in execution time. By default, when compiling code
+-that might be run on an \s-1MC88100\s0 processor, \s-1GCC\s0 emulates signed
+-integer division using the unsigned integer division instruction
+-divu), thereby avoiding the large penalty of a trap to the
+-operating system. Such emulation has its own, smaller, execution
+-cost in both time and space. To the extent that your code's
+-important signed integer division operations are performed on two
+-nonnegative operands, it may be desirable to use the div
+-instruction directly.
+-.Sp
+-On the \s-1MC88110\s0 processor the div instruction (also known as the
+-divs instruction) processes negative operands without trapping to
+-the operating system. When \fB\-m88110\fR is specified,
+-\&\fB\-muse\-div\-instruction\fR is ignored, and the div instruction is used
+-for signed integer division.
+-.Sp
+-Note that the result of dividing \f(CW\*(C`INT_MIN\*(C'\fR by \-1 is undefined. In
+-particular, the behavior of such a division with and without
+-\&\fB\-muse\-div\-instruction\fR may differ.
+-.IP "\fB\-mtrap\-large\-shift\fR" 4
+-.IX Item "-mtrap-large-shift"
+-.PD 0
+-.IP "\fB\-mhandle\-large\-shift\fR" 4
+-.IX Item "-mhandle-large-shift"
+-.PD
+-Include code to detect bit-shifts of more than 31 bits; respectively,
+-trap such shifts or emit code to handle them properly. By default \s-1GCC\s0
+-makes no special provision for large bit shifts.
+-.IP "\fB\-mwarn\-passed\-structs\fR" 4
+-.IX Item "-mwarn-passed-structs"
+-Warn when a function passes a struct as an argument or result.
+-Structure-passing conventions have changed during the evolution of the C
+-language, and are often the source of portability problems. By default,
+-\&\s-1GCC\s0 issues no such warning.
+-.PP
+-\fI\s-1IBM\s0 \s-1RS/6000\s0 and PowerPC Options\fR
+-.IX Subsection "IBM RS/6000 and PowerPC Options"
+-.PP
+-These \fB\-m\fR options are defined for the \s-1IBM\s0 \s-1RS/6000\s0 and PowerPC:
+-.IP "\fB\-mpower\fR" 4
+-.IX Item "-mpower"
+-.PD 0
+-.IP "\fB\-mno\-power\fR" 4
+-.IX Item "-mno-power"
+-.IP "\fB\-mpower2\fR" 4
+-.IX Item "-mpower2"
+-.IP "\fB\-mno\-power2\fR" 4
+-.IX Item "-mno-power2"
+-.IP "\fB\-mpowerpc\fR" 4
+-.IX Item "-mpowerpc"
+-.IP "\fB\-mno\-powerpc\fR" 4
+-.IX Item "-mno-powerpc"
+-.IP "\fB\-mpowerpc\-gpopt\fR" 4
+-.IX Item "-mpowerpc-gpopt"
+-.IP "\fB\-mno\-powerpc\-gpopt\fR" 4
+-.IX Item "-mno-powerpc-gpopt"
+-.IP "\fB\-mpowerpc\-gfxopt\fR" 4
+-.IX Item "-mpowerpc-gfxopt"
+-.IP "\fB\-mno\-powerpc\-gfxopt\fR" 4
+-.IX Item "-mno-powerpc-gfxopt"
+-.IP "\fB\-mpowerpc64\fR" 4
+-.IX Item "-mpowerpc64"
+-.IP "\fB\-mno\-powerpc64\fR" 4
+-.IX Item "-mno-powerpc64"
+-.PD
+-\&\s-1GCC\s0 supports two related instruction set architectures for the
+-\&\s-1RS/6000\s0 and PowerPC. The \fI\s-1POWER\s0\fR instruction set are those
+-instructions supported by the \fBrios\fR chip set used in the original
+-\&\s-1RS/6000\s0 systems and the \fIPowerPC\fR instruction set is the
+-architecture of the Motorola MPC5xx, MPC6xx, MPC8xx microprocessors, and
+-the \s-1IBM\s0 4xx microprocessors.
+-.Sp
+-Neither architecture is a subset of the other. However there is a
+-large common subset of instructions supported by both. An \s-1MQ\s0
+-register is included in processors supporting the \s-1POWER\s0 architecture.
+-.Sp
+-You use these options to specify which instructions are available on the
+-processor you are using. The default value of these options is
+-determined when configuring \s-1GCC\s0. Specifying the
+-\&\fB\-mcpu=\fR\fIcpu_type\fR overrides the specification of these
+-options. We recommend you use the \fB\-mcpu=\fR\fIcpu_type\fR option
+-rather than the options listed above.
+-.Sp
+-The \fB\-mpower\fR option allows \s-1GCC\s0 to generate instructions that
+-are found only in the \s-1POWER\s0 architecture and to use the \s-1MQ\s0 register.
+-Specifying \fB\-mpower2\fR implies \fB\-power\fR and also allows \s-1GCC\s0
+-to generate instructions that are present in the \s-1POWER2\s0 architecture but
+-not the original \s-1POWER\s0 architecture.
+-.Sp
+-The \fB\-mpowerpc\fR option allows \s-1GCC\s0 to generate instructions that
+-are found only in the 32\-bit subset of the PowerPC architecture.
+-Specifying \fB\-mpowerpc\-gpopt\fR implies \fB\-mpowerpc\fR and also allows
+-\&\s-1GCC\s0 to use the optional PowerPC architecture instructions in the
+-General Purpose group, including floating-point square root. Specifying
+-\&\fB\-mpowerpc\-gfxopt\fR implies \fB\-mpowerpc\fR and also allows \s-1GCC\s0 to
+-use the optional PowerPC architecture instructions in the Graphics
+-group, including floating-point select.
+-.Sp
+-The \fB\-mpowerpc64\fR option allows \s-1GCC\s0 to generate the additional
+-64\-bit instructions that are found in the full PowerPC64 architecture
+-and to treat GPRs as 64\-bit, doubleword quantities. \s-1GCC\s0 defaults to
+-\&\fB\-mno\-powerpc64\fR.
+-.Sp
+-If you specify both \fB\-mno\-power\fR and \fB\-mno\-powerpc\fR, \s-1GCC\s0
+-will use only the instructions in the common subset of both
+-architectures plus some special \s-1AIX\s0 common-mode calls, and will not use
+-the \s-1MQ\s0 register. Specifying both \fB\-mpower\fR and \fB\-mpowerpc\fR
+-permits \s-1GCC\s0 to use any instruction from either architecture and to
+-allow use of the \s-1MQ\s0 register; specify this for the Motorola \s-1MPC601\s0.
+-.IP "\fB\-mnew\-mnemonics\fR" 4
+-.IX Item "-mnew-mnemonics"
+-.PD 0
+-.IP "\fB\-mold\-mnemonics\fR" 4
+-.IX Item "-mold-mnemonics"
+-.PD
+-Select which mnemonics to use in the generated assembler code. With
+-\&\fB\-mnew\-mnemonics\fR, \s-1GCC\s0 uses the assembler mnemonics defined for
+-the PowerPC architecture. With \fB\-mold\-mnemonics\fR it uses the
+-assembler mnemonics defined for the \s-1POWER\s0 architecture. Instructions
+-defined in only one architecture have only one mnemonic; \s-1GCC\s0 uses that
+-mnemonic irrespective of which of these options is specified.
+-.Sp
+-\&\s-1GCC\s0 defaults to the mnemonics appropriate for the architecture in
+-use. Specifying \fB\-mcpu=\fR\fIcpu_type\fR sometimes overrides the
+-value of these option. Unless you are building a cross\-compiler, you
+-should normally not specify either \fB\-mnew\-mnemonics\fR or
+-\&\fB\-mold\-mnemonics\fR, but should instead accept the default.
+-.IP "\fB\-mcpu=\fR\fIcpu_type\fR" 4
+-.IX Item "-mcpu=cpu_type"
+-Set architecture type, register usage, choice of mnemonics, and
+-instruction scheduling parameters for machine type \fIcpu_type\fR.
+-Supported values for \fIcpu_type\fR are \fBrios\fR, \fBrios1\fR,
+-\&\fBrsc\fR, \fBrios2\fR, \fBrs64a\fR, \fB601\fR, \fB602\fR,
+-\&\fB603\fR, \fB603e\fR, \fB604\fR, \fB604e\fR, \fB620\fR,
+-\&\fB630\fR, \fB740\fR, \fB7400\fR, \fB7450\fR, \fB750\fR,
+-\&\fBpower\fR, \fBpower2\fR, \fBpowerpc\fR, \fB403\fR, \fB505\fR,
+-\&\fB801\fR, \fB821\fR, \fB823\fR, and \fB860\fR and \fBcommon\fR.
+-.Sp
+-\&\fB\-mcpu=common\fR selects a completely generic processor. Code
+-generated under this option will run on any \s-1POWER\s0 or PowerPC processor.
+-\&\s-1GCC\s0 will use only the instructions in the common subset of both
+-architectures, and will not use the \s-1MQ\s0 register. \s-1GCC\s0 assumes a generic
+-processor model for scheduling purposes.
+-.Sp
+-\&\fB\-mcpu=power\fR, \fB\-mcpu=power2\fR, \fB\-mcpu=powerpc\fR, and
+-\&\fB\-mcpu=powerpc64\fR specify generic \s-1POWER\s0, \s-1POWER2\s0, pure 32\-bit
+-PowerPC (i.e., not \s-1MPC601\s0), and 64\-bit PowerPC architecture machine
+-types, with an appropriate, generic processor model assumed for
+-scheduling purposes.
+-.Sp
+-The other options specify a specific processor. Code generated under
+-those options will run best on that processor, and may not run at all on
+-others.
+-.Sp
+-The \fB\-mcpu\fR options automatically enable or disable other
+-\&\fB\-m\fR options as follows:
+-.RS 4
+-.IP "\fBcommon\fR" 4
+-.IX Item "common"
+-\&\fB\-mno\-power\fR, \fB\-mno\-powerpc\fR
+-.IP "\fBpower\fR" 4
+-.IX Item "power"
+-.PD 0
+-.IP "\fBpower2\fR" 4
+-.IX Item "power2"
+-.IP "\fBrios1\fR" 4
+-.IX Item "rios1"
+-.IP "\fBrios2\fR" 4
+-.IX Item "rios2"
+-.IP "\fBrsc\fR" 4
+-.IX Item "rsc"
+-.PD
+-\&\fB\-mpower\fR, \fB\-mno\-powerpc\fR, \fB\-mno\-new\-mnemonics\fR
+-.IP "\fBpowerpc\fR" 4
+-.IX Item "powerpc"
+-.PD 0
+-.IP "\fBrs64a\fR" 4
+-.IX Item "rs64a"
+-.IP "\fB602\fR" 4
+-.IX Item "602"
+-.IP "\fB603\fR" 4
+-.IX Item "603"
+-.IP "\fB603e\fR" 4
+-.IX Item "603e"
+-.IP "\fB604\fR" 4
+-.IX Item "604"
+-.IP "\fB620\fR" 4
+-.IX Item "620"
+-.IP "\fB630\fR" 4
+-.IX Item "630"
+-.IP "\fB740\fR" 4
+-.IX Item "740"
+-.IP "\fB7400\fR" 4
+-.IX Item "7400"
+-.IP "\fB7450\fR" 4
+-.IX Item "7450"
+-.IP "\fB750\fR" 4
+-.IX Item "750"
+-.IP "\fB505\fR" 4
+-.IX Item "505"
+-.PD
+-\&\fB\-mno\-power\fR, \fB\-mpowerpc\fR, \fB\-mnew\-mnemonics\fR
+-.IP "\fB601\fR" 4
+-.IX Item "601"
+-\&\fB\-mpower\fR, \fB\-mpowerpc\fR, \fB\-mnew\-mnemonics\fR
+-.IP "\fB403\fR" 4
+-.IX Item "403"
+-.PD 0
+-.IP "\fB821\fR" 4
+-.IX Item "821"
+-.IP "\fB860\fR" 4
+-.IX Item "860"
+-.PD
+-\&\fB\-mno\-power\fR, \fB\-mpowerpc\fR, \fB\-mnew\-mnemonics\fR, \fB\-msoft\-float\fR
+-.RE
+-.RS 4
+-.RE
+-.IP "\fB\-mtune=\fR\fIcpu_type\fR" 4
+-.IX Item "-mtune=cpu_type"
+-Set the instruction scheduling parameters for machine type
+-\&\fIcpu_type\fR, but do not set the architecture type, register usage, or
+-choice of mnemonics, as \fB\-mcpu=\fR\fIcpu_type\fR would. The same
+-values for \fIcpu_type\fR are used for \fB\-mtune\fR as for
+-\&\fB\-mcpu\fR. If both are specified, the code generated will use the
+-architecture, registers, and mnemonics set by \fB\-mcpu\fR, but the
+-scheduling parameters set by \fB\-mtune\fR.
+-.IP "\fB\-maltivec\fR" 4
+-.IX Item "-maltivec"
+-.PD 0
+-.IP "\fB\-mno\-altivec\fR" 4
+-.IX Item "-mno-altivec"
+-.PD
+-These switches enable or disable the use of built-in functions that
+-allow access to the AltiVec instruction set. You may also need to set
+-\&\fB\-mabi=altivec\fR to adjust the current \s-1ABI\s0 with AltiVec \s-1ABI\s0
+-enhancements.
+-.IP "\fB\-mabi=spe\fR" 4
+-.IX Item "-mabi=spe"
+-Extend the current \s-1ABI\s0 with \s-1SPE\s0 \s-1ABI\s0 extensions. This does not change
+-the default \s-1ABI\s0, instead it adds the \s-1SPE\s0 \s-1ABI\s0 extensions to the current
+-\&\s-1ABI\s0.
+-.IP "\fB\-mabi=no\-spe\fR" 4
+-.IX Item "-mabi=no-spe"
+-Disable Booke \s-1SPE\s0 \s-1ABI\s0 extensions for the current \s-1ABI\s0.
+-.IP "\fB\-misel=\fR\fIyes/no\fR" 4
+-.IX Item "-misel=yes/no"
+-.PD 0
+-.IP "\fB\-misel\fR" 4
+-.IX Item "-misel"
+-.PD
+-This switch enables or disables the generation of \s-1ISEL\s0 instructions.
+-.IP "\fB\-mfull\-toc\fR" 4
+-.IX Item "-mfull-toc"
+-.PD 0
+-.IP "\fB\-mno\-fp\-in\-toc\fR" 4
+-.IX Item "-mno-fp-in-toc"
+-.IP "\fB\-mno\-sum\-in\-toc\fR" 4
+-.IX Item "-mno-sum-in-toc"
+-.IP "\fB\-mminimal\-toc\fR" 4
+-.IX Item "-mminimal-toc"
+-.PD
+-Modify generation of the \s-1TOC\s0 (Table Of Contents), which is created for
+-every executable file. The \fB\-mfull\-toc\fR option is selected by
+-default. In that case, \s-1GCC\s0 will allocate at least one \s-1TOC\s0 entry for
+-each unique non-automatic variable reference in your program. \s-1GCC\s0
+-will also place floating-point constants in the \s-1TOC\s0. However, only
+-16,384 entries are available in the \s-1TOC\s0.
+-.Sp
+-If you receive a linker error message that saying you have overflowed
+-the available \s-1TOC\s0 space, you can reduce the amount of \s-1TOC\s0 space used
+-with the \fB\-mno\-fp\-in\-toc\fR and \fB\-mno\-sum\-in\-toc\fR options.
+-\&\fB\-mno\-fp\-in\-toc\fR prevents \s-1GCC\s0 from putting floating-point
+-constants in the \s-1TOC\s0 and \fB\-mno\-sum\-in\-toc\fR forces \s-1GCC\s0 to
+-generate code to calculate the sum of an address and a constant at
+-run-time instead of putting that sum into the \s-1TOC\s0. You may specify one
+-or both of these options. Each causes \s-1GCC\s0 to produce very slightly
+-slower and larger code at the expense of conserving \s-1TOC\s0 space.
+-.Sp
+-If you still run out of space in the \s-1TOC\s0 even when you specify both of
+-these options, specify \fB\-mminimal\-toc\fR instead. This option causes
+-\&\s-1GCC\s0 to make only one \s-1TOC\s0 entry for every file. When you specify this
+-option, \s-1GCC\s0 will produce code that is slower and larger but which
+-uses extremely little \s-1TOC\s0 space. You may wish to use this option
+-only on files that contain less frequently executed code.
+-.IP "\fB\-maix64\fR" 4
+-.IX Item "-maix64"
+-.PD 0
+-.IP "\fB\-maix32\fR" 4
+-.IX Item "-maix32"
+-.PD
+-Enable 64\-bit \s-1AIX\s0 \s-1ABI\s0 and calling convention: 64\-bit pointers, 64\-bit
+-\&\f(CW\*(C`long\*(C'\fR type, and the infrastructure needed to support them.
+-Specifying \fB\-maix64\fR implies \fB\-mpowerpc64\fR and
+-\&\fB\-mpowerpc\fR, while \fB\-maix32\fR disables the 64\-bit \s-1ABI\s0 and
+-implies \fB\-mno\-powerpc64\fR. \s-1GCC\s0 defaults to \fB\-maix32\fR.
+-.IP "\fB\-mxl\-call\fR" 4
+-.IX Item "-mxl-call"
+-.PD 0
+-.IP "\fB\-mno\-xl\-call\fR" 4
+-.IX Item "-mno-xl-call"
+-.PD
+-On \s-1AIX\s0, pass floating-point arguments to prototyped functions beyond the
+-register save area (\s-1RSA\s0) on the stack in addition to argument FPRs. The
+-\&\s-1AIX\s0 calling convention was extended but not initially documented to
+-handle an obscure K&R C case of calling a function that takes the
+-address of its arguments with fewer arguments than declared. \s-1AIX\s0 \s-1XL\s0
+-compilers access floating point arguments which do not fit in the
+-\&\s-1RSA\s0 from the stack when a subroutine is compiled without
+-optimization. Because always storing floating-point arguments on the
+-stack is inefficient and rarely needed, this option is not enabled by
+-default and only is necessary when calling subroutines compiled by \s-1AIX\s0
+-\&\s-1XL\s0 compilers without optimization.
+-.IP "\fB\-mpe\fR" 4
+-.IX Item "-mpe"
+-Support \fI\s-1IBM\s0 \s-1RS/6000\s0 \s-1SP\s0\fR \fIParallel Environment\fR (\s-1PE\s0). Link an
+-application written to use message passing with special startup code to
+-enable the application to run. The system must have \s-1PE\s0 installed in the
+-standard location (\fI/usr/lpp/ppe.poe/\fR), or the \fIspecs\fR file
+-must be overridden with the \fB\-specs=\fR option to specify the
+-appropriate directory location. The Parallel Environment does not
+-support threads, so the \fB\-mpe\fR option and the \fB\-pthread\fR
+-option are incompatible.
+-.IP "\fB\-msoft\-float\fR" 4
+-.IX Item "-msoft-float"
+-.PD 0
+-.IP "\fB\-mhard\-float\fR" 4
+-.IX Item "-mhard-float"
+-.PD
+-Generate code that does not use (uses) the floating-point register set.
+-Software floating point emulation is provided if you use the
+-\&\fB\-msoft\-float\fR option, and pass the option to \s-1GCC\s0 when linking.
+-.IP "\fB\-mmultiple\fR" 4
+-.IX Item "-mmultiple"
+-.PD 0
+-.IP "\fB\-mno\-multiple\fR" 4
+-.IX Item "-mno-multiple"
+-.PD
+-Generate code that uses (does not use) the load multiple word
+-instructions and the store multiple word instructions. These
+-instructions are generated by default on \s-1POWER\s0 systems, and not
+-generated on PowerPC systems. Do not use \fB\-mmultiple\fR on little
+-endian PowerPC systems, since those instructions do not work when the
+-processor is in little endian mode. The exceptions are \s-1PPC740\s0 and
+-\&\s-1PPC750\s0 which permit the instructions usage in little endian mode.
+-.IP "\fB\-mstring\fR" 4
+-.IX Item "-mstring"
+-.PD 0
+-.IP "\fB\-mno\-string\fR" 4
+-.IX Item "-mno-string"
+-.PD
+-Generate code that uses (does not use) the load string instructions
+-and the store string word instructions to save multiple registers and
+-do small block moves. These instructions are generated by default on
+-\&\s-1POWER\s0 systems, and not generated on PowerPC systems. Do not use
+-\&\fB\-mstring\fR on little endian PowerPC systems, since those
+-instructions do not work when the processor is in little endian mode.
+-The exceptions are \s-1PPC740\s0 and \s-1PPC750\s0 which permit the instructions
+-usage in little endian mode.
+-.IP "\fB\-mupdate\fR" 4
+-.IX Item "-mupdate"
+-.PD 0
+-.IP "\fB\-mno\-update\fR" 4
+-.IX Item "-mno-update"
+-.PD
+-Generate code that uses (does not use) the load or store instructions
+-that update the base register to the address of the calculated memory
+-location. These instructions are generated by default. If you use
+-\&\fB\-mno\-update\fR, there is a small window between the time that the
+-stack pointer is updated and the address of the previous frame is
+-stored, which means code that walks the stack frame across interrupts or
+-signals may get corrupted data.
+-.IP "\fB\-mfused\-madd\fR" 4
+-.IX Item "-mfused-madd"
+-.PD 0
+-.IP "\fB\-mno\-fused\-madd\fR" 4
+-.IX Item "-mno-fused-madd"
+-.PD
+-Generate code that uses (does not use) the floating point multiply and
+-accumulate instructions. These instructions are generated by default if
+-hardware floating is used.
+-.IP "\fB\-mno\-bit\-align\fR" 4
+-.IX Item "-mno-bit-align"
+-.PD 0
+-.IP "\fB\-mbit\-align\fR" 4
+-.IX Item "-mbit-align"
+-.PD
+-On System V.4 and embedded PowerPC systems do not (do) force structures
+-and unions that contain bit-fields to be aligned to the base type of the
+-bit\-field.
+-.Sp
+-For example, by default a structure containing nothing but 8
+-\&\f(CW\*(C`unsigned\*(C'\fR bit-fields of length 1 would be aligned to a 4 byte
+-boundary and have a size of 4 bytes. By using \fB\-mno\-bit\-align\fR,
+-the structure would be aligned to a 1 byte boundary and be one byte in
+-size.
+-.IP "\fB\-mno\-strict\-align\fR" 4
+-.IX Item "-mno-strict-align"
+-.PD 0
+-.IP "\fB\-mstrict\-align\fR" 4
+-.IX Item "-mstrict-align"
+-.PD
+-On System V.4 and embedded PowerPC systems do not (do) assume that
+-unaligned memory references will be handled by the system.
+-.IP "\fB\-mrelocatable\fR" 4
+-.IX Item "-mrelocatable"
+-.PD 0
+-.IP "\fB\-mno\-relocatable\fR" 4
+-.IX Item "-mno-relocatable"
+-.PD
+-On embedded PowerPC systems generate code that allows (does not allow)
+-the program to be relocated to a different address at runtime. If you
+-use \fB\-mrelocatable\fR on any module, all objects linked together must
+-be compiled with \fB\-mrelocatable\fR or \fB\-mrelocatable\-lib\fR.
+-.IP "\fB\-mrelocatable\-lib\fR" 4
+-.IX Item "-mrelocatable-lib"
+-.PD 0
+-.IP "\fB\-mno\-relocatable\-lib\fR" 4
+-.IX Item "-mno-relocatable-lib"
+-.PD
+-On embedded PowerPC systems generate code that allows (does not allow)
+-the program to be relocated to a different address at runtime. Modules
+-compiled with \fB\-mrelocatable\-lib\fR can be linked with either modules
+-compiled without \fB\-mrelocatable\fR and \fB\-mrelocatable\-lib\fR or
+-with modules compiled with the \fB\-mrelocatable\fR options.
+-.IP "\fB\-mno\-toc\fR" 4
+-.IX Item "-mno-toc"
+-.PD 0
+-.IP "\fB\-mtoc\fR" 4
+-.IX Item "-mtoc"
+-.PD
+-On System V.4 and embedded PowerPC systems do not (do) assume that
+-register 2 contains a pointer to a global area pointing to the addresses
+-used in the program.
+-.IP "\fB\-mlittle\fR" 4
+-.IX Item "-mlittle"
+-.PD 0
+-.IP "\fB\-mlittle\-endian\fR" 4
+-.IX Item "-mlittle-endian"
+-.PD
+-On System V.4 and embedded PowerPC systems compile code for the
+-processor in little endian mode. The \fB\-mlittle\-endian\fR option is
+-the same as \fB\-mlittle\fR.
+-.IP "\fB\-mbig\fR" 4
+-.IX Item "-mbig"
+-.PD 0
+-.IP "\fB\-mbig\-endian\fR" 4
+-.IX Item "-mbig-endian"
+-.PD
+-On System V.4 and embedded PowerPC systems compile code for the
+-processor in big endian mode. The \fB\-mbig\-endian\fR option is
+-the same as \fB\-mbig\fR.
+-.IP "\fB\-mcall\-sysv\fR" 4
+-.IX Item "-mcall-sysv"
+-On System V.4 and embedded PowerPC systems compile code using calling
+-conventions that adheres to the March 1995 draft of the System V
+-Application Binary Interface, PowerPC processor supplement. This is the
+-default unless you configured \s-1GCC\s0 using \fBpowerpc\-*\-eabiaix\fR.
+-.IP "\fB\-mcall\-sysv\-eabi\fR" 4
+-.IX Item "-mcall-sysv-eabi"
+-Specify both \fB\-mcall\-sysv\fR and \fB\-meabi\fR options.
+-.IP "\fB\-mcall\-sysv\-noeabi\fR" 4
+-.IX Item "-mcall-sysv-noeabi"
+-Specify both \fB\-mcall\-sysv\fR and \fB\-mno\-eabi\fR options.
+-.IP "\fB\-mcall\-aix\fR" 4
+-.IX Item "-mcall-aix"
+-On System V.4 and embedded PowerPC systems compile code using calling
+-conventions that are similar to those used on \s-1AIX\s0. This is the
+-default if you configured \s-1GCC\s0 using \fBpowerpc\-*\-eabiaix\fR.
+-.IP "\fB\-mcall\-solaris\fR" 4
+-.IX Item "-mcall-solaris"
+-On System V.4 and embedded PowerPC systems compile code for the Solaris
+-operating system.
+-.IP "\fB\-mcall\-linux\fR" 4
+-.IX Item "-mcall-linux"
+-On System V.4 and embedded PowerPC systems compile code for the
+-Linux-based \s-1GNU\s0 system.
+-.IP "\fB\-mcall\-gnu\fR" 4
+-.IX Item "-mcall-gnu"
+-On System V.4 and embedded PowerPC systems compile code for the
+-Hurd-based \s-1GNU\s0 system.
+-.IP "\fB\-mcall\-netbsd\fR" 4
+-.IX Item "-mcall-netbsd"
+-On System V.4 and embedded PowerPC systems compile code for the
+-NetBSD operating system.
+-.IP "\fB\-maix\-struct\-return\fR" 4
+-.IX Item "-maix-struct-return"
+-Return all structures in memory (as specified by the \s-1AIX\s0 \s-1ABI\s0).
+-.IP "\fB\-msvr4\-struct\-return\fR" 4
+-.IX Item "-msvr4-struct-return"
+-Return structures smaller than 8 bytes in registers (as specified by the
+-\&\s-1SVR4\s0 \s-1ABI\s0).
+-.IP "\fB\-mabi=altivec\fR" 4
+-.IX Item "-mabi=altivec"
+-Extend the current \s-1ABI\s0 with AltiVec \s-1ABI\s0 extensions. This does not
+-change the default \s-1ABI\s0, instead it adds the AltiVec \s-1ABI\s0 extensions to
+-the current \s-1ABI\s0.
+-.IP "\fB\-mabi=no\-altivec\fR" 4
+-.IX Item "-mabi=no-altivec"
+-Disable AltiVec \s-1ABI\s0 extensions for the current \s-1ABI\s0.
+-.IP "\fB\-mprototype\fR" 4
+-.IX Item "-mprototype"
+-.PD 0
+-.IP "\fB\-mno\-prototype\fR" 4
+-.IX Item "-mno-prototype"
+-.PD
+-On System V.4 and embedded PowerPC systems assume that all calls to
+-variable argument functions are properly prototyped. Otherwise, the
+-compiler must insert an instruction before every non prototyped call to
+-set or clear bit 6 of the condition code register (\fI\s-1CR\s0\fR) to
+-indicate whether floating point values were passed in the floating point
+-registers in case the function takes a variable arguments. With
+-\&\fB\-mprototype\fR, only calls to prototyped variable argument functions
+-will set or clear the bit.
+-.IP "\fB\-msim\fR" 4
+-.IX Item "-msim"
+-On embedded PowerPC systems, assume that the startup module is called
+-\&\fIsim\-crt0.o\fR and that the standard C libraries are \fIlibsim.a\fR and
+-\&\fIlibc.a\fR. This is the default for \fBpowerpc\-*\-eabisim\fR.
+-configurations.
+-.IP "\fB\-mmvme\fR" 4
+-.IX Item "-mmvme"
+-On embedded PowerPC systems, assume that the startup module is called
+-\&\fIcrt0.o\fR and the standard C libraries are \fIlibmvme.a\fR and
+-\&\fIlibc.a\fR.
+-.IP "\fB\-mads\fR" 4
+-.IX Item "-mads"
+-On embedded PowerPC systems, assume that the startup module is called
+-\&\fIcrt0.o\fR and the standard C libraries are \fIlibads.a\fR and
+-\&\fIlibc.a\fR.
+-.IP "\fB\-myellowknife\fR" 4
+-.IX Item "-myellowknife"
+-On embedded PowerPC systems, assume that the startup module is called
+-\&\fIcrt0.o\fR and the standard C libraries are \fIlibyk.a\fR and
+-\&\fIlibc.a\fR.
+-.IP "\fB\-mvxworks\fR" 4
+-.IX Item "-mvxworks"
+-On System V.4 and embedded PowerPC systems, specify that you are
+-compiling for a VxWorks system.
+-.IP "\fB\-mwindiss\fR" 4
+-.IX Item "-mwindiss"
+-Specify that you are compiling for the WindISS simulation environment.
+-.IP "\fB\-memb\fR" 4
+-.IX Item "-memb"
+-On embedded PowerPC systems, set the \fI\s-1PPC_EMB\s0\fR bit in the \s-1ELF\s0 flags
+-header to indicate that \fBeabi\fR extended relocations are used.
+-.IP "\fB\-meabi\fR" 4
+-.IX Item "-meabi"
+-.PD 0
+-.IP "\fB\-mno\-eabi\fR" 4
+-.IX Item "-mno-eabi"
+-.PD
+-On System V.4 and embedded PowerPC systems do (do not) adhere to the
+-Embedded Applications Binary Interface (eabi) which is a set of
+-modifications to the System V.4 specifications. Selecting \fB\-meabi\fR
+-means that the stack is aligned to an 8 byte boundary, a function
+-\&\f(CW\*(C`_\|_eabi\*(C'\fR is called to from \f(CW\*(C`main\*(C'\fR to set up the eabi
+-environment, and the \fB\-msdata\fR option can use both \f(CW\*(C`r2\*(C'\fR and
+-\&\f(CW\*(C`r13\*(C'\fR to point to two separate small data areas. Selecting
+-\&\fB\-mno\-eabi\fR means that the stack is aligned to a 16 byte boundary,
+-do not call an initialization function from \f(CW\*(C`main\*(C'\fR, and the
+-\&\fB\-msdata\fR option will only use \f(CW\*(C`r13\*(C'\fR to point to a single
+-small data area. The \fB\-meabi\fR option is on by default if you
+-configured \s-1GCC\s0 using one of the \fBpowerpc*\-*\-eabi*\fR options.
+-.IP "\fB\-msdata=eabi\fR" 4
+-.IX Item "-msdata=eabi"
+-On System V.4 and embedded PowerPC systems, put small initialized
+-\&\f(CW\*(C`const\*(C'\fR global and static data in the \fB.sdata2\fR section, which
+-is pointed to by register \f(CW\*(C`r2\*(C'\fR. Put small initialized
+-non\-\f(CW\*(C`const\*(C'\fR global and static data in the \fB.sdata\fR section,
+-which is pointed to by register \f(CW\*(C`r13\*(C'\fR. Put small uninitialized
+-global and static data in the \fB.sbss\fR section, which is adjacent to
+-the \fB.sdata\fR section. The \fB\-msdata=eabi\fR option is
+-incompatible with the \fB\-mrelocatable\fR option. The
+-\&\fB\-msdata=eabi\fR option also sets the \fB\-memb\fR option.
+-.IP "\fB\-msdata=sysv\fR" 4
+-.IX Item "-msdata=sysv"
+-On System V.4 and embedded PowerPC systems, put small global and static
+-data in the \fB.sdata\fR section, which is pointed to by register
+-\&\f(CW\*(C`r13\*(C'\fR. Put small uninitialized global and static data in the
+-\&\fB.sbss\fR section, which is adjacent to the \fB.sdata\fR section.
+-The \fB\-msdata=sysv\fR option is incompatible with the
+-\&\fB\-mrelocatable\fR option.
+-.IP "\fB\-msdata=default\fR" 4
+-.IX Item "-msdata=default"
+-.PD 0
+-.IP "\fB\-msdata\fR" 4
+-.IX Item "-msdata"
+-.PD
+-On System V.4 and embedded PowerPC systems, if \fB\-meabi\fR is used,
+-compile code the same as \fB\-msdata=eabi\fR, otherwise compile code the
+-same as \fB\-msdata=sysv\fR.
+-.IP "\fB\-msdata\-data\fR" 4
+-.IX Item "-msdata-data"
+-On System V.4 and embedded PowerPC systems, put small global and static
+-data in the \fB.sdata\fR section. Put small uninitialized global and
+-static data in the \fB.sbss\fR section. Do not use register \f(CW\*(C`r13\*(C'\fR
+-to address small data however. This is the default behavior unless
+-other \fB\-msdata\fR options are used.
+-.IP "\fB\-msdata=none\fR" 4
+-.IX Item "-msdata=none"
+-.PD 0
+-.IP "\fB\-mno\-sdata\fR" 4
+-.IX Item "-mno-sdata"
+-.PD
+-On embedded PowerPC systems, put all initialized global and static data
+-in the \fB.data\fR section, and all uninitialized data in the
+-\&\fB.bss\fR section.
+-.IP "\fB\-G\fR \fInum\fR" 4
+-.IX Item "-G num"
+-On embedded PowerPC systems, put global and static items less than or
+-equal to \fInum\fR bytes into the small data or bss sections instead of
+-the normal data or bss section. By default, \fInum\fR is 8. The
+-\&\fB\-G\fR \fInum\fR switch is also passed to the linker.
+-All modules should be compiled with the same \fB\-G\fR \fInum\fR value.
+-.IP "\fB\-mregnames\fR" 4
+-.IX Item "-mregnames"
+-.PD 0
+-.IP "\fB\-mno\-regnames\fR" 4
+-.IX Item "-mno-regnames"
+-.PD
+-On System V.4 and embedded PowerPC systems do (do not) emit register
+-names in the assembly language output using symbolic forms.
+-.IP "\fB\-mlongcall\fR" 4
+-.IX Item "-mlongcall"
+-.PD 0
+-.IP "\fB\-mno\-longcall\fR" 4
+-.IX Item "-mno-longcall"
+-.PD
+-Default to making all function calls via pointers, so that functions
+-which reside further than 64 megabytes (67,108,864 bytes) from the
+-current location can be called. This setting can be overridden by the
+-\&\f(CW\*(C`shortcall\*(C'\fR function attribute, or by \f(CW\*(C`#pragma longcall(0)\*(C'\fR.
+-.Sp
+-Some linkers are capable of detecting out-of-range calls and generating
+-glue code on the fly. On these systems, long calls are unnecessary and
+-generate slower code. As of this writing, the \s-1AIX\s0 linker can do this,
+-as can the \s-1GNU\s0 linker for PowerPC/64. It is planned to add this feature
+-to the \s-1GNU\s0 linker for 32\-bit PowerPC systems as well.
+-.Sp
+-In the future, we may cause \s-1GCC\s0 to ignore all longcall specifications
+-when the linker is known to generate glue.
+-.IP "\fB\-pthread\fR" 4
+-.IX Item "-pthread"
+-Adds support for multithreading with the \fIpthreads\fR library.
+-This option sets flags for both the preprocessor and linker.
+-.PP
+-\fIDarwin Options\fR
+-.IX Subsection "Darwin Options"
+-.PP
+-These options are defined for all architectures running the Darwin operating
+-system. They are useful for compatibility with other Mac \s-1OS\s0 compilers.
+-.IP "\fB\-all_load\fR" 4
+-.IX Item "-all_load"
+-Loads all members of static archive libraries.
+-See man \fIld\fR\|(1) for more information.
+-.IP "\fB\-arch_errors_fatal\fR" 4
+-.IX Item "-arch_errors_fatal"
+-Cause the errors having to do with files that have the wrong architecture
+-to be fatal.
+-.IP "\fB\-bind_at_load\fR" 4
+-.IX Item "-bind_at_load"
+-Causes the output file to be marked such that the dynamic linker will
+-bind all undefined references when the file is loaded or launched.
+-.IP "\fB\-bundle\fR" 4
+-.IX Item "-bundle"
+-Produce a Mach-o bundle format file.
+-See man \fIld\fR\|(1) for more information.
+-.IP "\fB\-bundle_loader\fR \fIexecutable\fR" 4
+-.IX Item "-bundle_loader executable"
+-This specifies the \fIexecutable\fR that will be loading the build
+-output file being linked. See man \fIld\fR\|(1) for more information.
+-.IP "\fB\-allowable_client\fR \fIclient_name\fR" 4
+-.IX Item "-allowable_client client_name"
+-.PD 0
+-.IP "\fB\-arch_only\fR" 4
+-.IX Item "-arch_only"
+-.IP "\fB\-client_name\fR" 4
+-.IX Item "-client_name"
+-.IP "\fB\-compatibility_version\fR" 4
+-.IX Item "-compatibility_version"
+-.IP "\fB\-current_version\fR" 4
+-.IX Item "-current_version"
+-.IP "\fB\-dependency\-file\fR" 4
+-.IX Item "-dependency-file"
+-.IP "\fB\-dylib_file\fR" 4
+-.IX Item "-dylib_file"
+-.IP "\fB\-dylinker_install_name\fR" 4
+-.IX Item "-dylinker_install_name"
+-.IP "\fB\-dynamic\fR" 4
+-.IX Item "-dynamic"
+-.IP "\fB\-dynamiclib\fR" 4
+-.IX Item "-dynamiclib"
+-.IP "\fB\-exported_symbols_list\fR" 4
+-.IX Item "-exported_symbols_list"
+-.IP "\fB\-filelist\fR" 4
+-.IX Item "-filelist"
+-.IP "\fB\-flat_namespace\fR" 4
+-.IX Item "-flat_namespace"
+-.IP "\fB\-force_cpusubtype_ALL\fR" 4
+-.IX Item "-force_cpusubtype_ALL"
+-.IP "\fB\-force_flat_namespace\fR" 4
+-.IX Item "-force_flat_namespace"
+-.IP "\fB\-headerpad_max_install_names\fR" 4
+-.IX Item "-headerpad_max_install_names"
+-.IP "\fB\-image_base\fR" 4
+-.IX Item "-image_base"
+-.IP "\fB\-init\fR" 4
+-.IX Item "-init"
+-.IP "\fB\-install_name\fR" 4
+-.IX Item "-install_name"
+-.IP "\fB\-keep_private_externs\fR" 4
+-.IX Item "-keep_private_externs"
+-.IP "\fB\-multi_module\fR" 4
+-.IX Item "-multi_module"
+-.IP "\fB\-multiply_defined\fR" 4
+-.IX Item "-multiply_defined"
+-.IP "\fB\-multiply_defined_unused\fR" 4
+-.IX Item "-multiply_defined_unused"
+-.IP "\fB\-noall_load\fR" 4
+-.IX Item "-noall_load"
+-.IP "\fB\-nomultidefs\fR" 4
+-.IX Item "-nomultidefs"
+-.IP "\fB\-noprebind\fR" 4
+-.IX Item "-noprebind"
+-.IP "\fB\-noseglinkedit\fR" 4
+-.IX Item "-noseglinkedit"
+-.IP "\fB\-pagezero_size\fR" 4
+-.IX Item "-pagezero_size"
+-.IP "\fB\-prebind\fR" 4
+-.IX Item "-prebind"
+-.IP "\fB\-prebind_all_twolevel_modules\fR" 4
+-.IX Item "-prebind_all_twolevel_modules"
+-.IP "\fB\-private_bundle\fR" 4
+-.IX Item "-private_bundle"
+-.IP "\fB\-read_only_relocs\fR" 4
+-.IX Item "-read_only_relocs"
+-.IP "\fB\-sectalign\fR" 4
+-.IX Item "-sectalign"
+-.IP "\fB\-sectobjectsymbols\fR" 4
+-.IX Item "-sectobjectsymbols"
+-.IP "\fB\-whyload\fR" 4
+-.IX Item "-whyload"
+-.IP "\fB\-seg1addr\fR" 4
+-.IX Item "-seg1addr"
+-.IP "\fB\-sectcreate\fR" 4
+-.IX Item "-sectcreate"
+-.IP "\fB\-sectobjectsymbols\fR" 4
+-.IX Item "-sectobjectsymbols"
+-.IP "\fB\-sectorder\fR" 4
+-.IX Item "-sectorder"
+-.IP "\fB\-seg_addr_table\fR" 4
+-.IX Item "-seg_addr_table"
+-.IP "\fB\-seg_addr_table_filename\fR" 4
+-.IX Item "-seg_addr_table_filename"
+-.IP "\fB\-seglinkedit\fR" 4
+-.IX Item "-seglinkedit"
+-.IP "\fB\-segprot\fR" 4
+-.IX Item "-segprot"
+-.IP "\fB\-segs_read_only_addr\fR" 4
+-.IX Item "-segs_read_only_addr"
+-.IP "\fB\-segs_read_write_addr\fR" 4
+-.IX Item "-segs_read_write_addr"
+-.IP "\fB\-single_module\fR" 4
+-.IX Item "-single_module"
+-.IP "\fB\-static\fR" 4
+-.IX Item "-static"
+-.IP "\fB\-sub_library\fR" 4
+-.IX Item "-sub_library"
+-.IP "\fB\-sub_umbrella\fR" 4
+-.IX Item "-sub_umbrella"
+-.IP "\fB\-twolevel_namespace\fR" 4
+-.IX Item "-twolevel_namespace"
+-.IP "\fB\-umbrella\fR" 4
+-.IX Item "-umbrella"
+-.IP "\fB\-undefined\fR" 4
+-.IX Item "-undefined"
+-.IP "\fB\-unexported_symbols_list\fR" 4
+-.IX Item "-unexported_symbols_list"
+-.IP "\fB\-weak_reference_mismatches\fR" 4
+-.IX Item "-weak_reference_mismatches"
+-.IP "\fB\-whatsloaded\fR" 4
+-.IX Item "-whatsloaded"
+-.PD
+-This options are available for Darwin linker. Darwin linker man page
+-describes them in detail.
+-.PP
+-\fI\s-1IBM\s0 \s-1RT\s0 Options\fR
+-.IX Subsection "IBM RT Options"
+-.PP
+-These \fB\-m\fR options are defined for the \s-1IBM\s0 \s-1RT\s0 \s-1PC:\s0
+-.IP "\fB\-min\-line\-mul\fR" 4
+-.IX Item "-min-line-mul"
+-Use an in-line code sequence for integer multiplies. This is the
+-default.
+-.IP "\fB\-mcall\-lib\-mul\fR" 4
+-.IX Item "-mcall-lib-mul"
+-Call \f(CW\*(C`lmul$$\*(C'\fR for integer multiples.
+-.IP "\fB\-mfull\-fp\-blocks\fR" 4
+-.IX Item "-mfull-fp-blocks"
+-Generate full-size floating point data blocks, including the minimum
+-amount of scratch space recommended by \s-1IBM\s0. This is the default.
+-.IP "\fB\-mminimum\-fp\-blocks\fR" 4
+-.IX Item "-mminimum-fp-blocks"
+-Do not include extra scratch space in floating point data blocks. This
+-results in smaller code, but slower execution, since scratch space must
+-be allocated dynamically.
+-.IP "\fB\-mfp\-arg\-in\-fpregs\fR" 4
+-.IX Item "-mfp-arg-in-fpregs"
+-Use a calling sequence incompatible with the \s-1IBM\s0 calling convention in
+-which floating point arguments are passed in floating point registers.
+-Note that \f(CW\*(C`stdarg.h\*(C'\fR will not work with floating point operands
+-if this option is specified.
+-.IP "\fB\-mfp\-arg\-in\-gregs\fR" 4
+-.IX Item "-mfp-arg-in-gregs"
+-Use the normal calling convention for floating point arguments. This is
+-the default.
+-.IP "\fB\-mhc\-struct\-return\fR" 4
+-.IX Item "-mhc-struct-return"
+-Return structures of more than one word in memory, rather than in a
+-register. This provides compatibility with the MetaWare HighC (hc)
+-compiler. Use the option \fB\-fpcc\-struct\-return\fR for compatibility
+-with the Portable C Compiler (pcc).
+-.IP "\fB\-mnohc\-struct\-return\fR" 4
+-.IX Item "-mnohc-struct-return"
+-Return some structures of more than one word in registers, when
+-convenient. This is the default. For compatibility with the
+-IBM-supplied compilers, use the option \fB\-fpcc\-struct\-return\fR or the
+-option \fB\-mhc\-struct\-return\fR.
+-.PP
+-\fI\s-1MIPS\s0 Options\fR
+-.IX Subsection "MIPS Options"
+-.PP
+-These \fB\-m\fR options are defined for the \s-1MIPS\s0 family of computers:
+-.IP "\fB\-march=\fR\fIarch\fR" 4
+-.IX Item "-march=arch"
+-Generate code that will run on \fIarch\fR, which can be the name of a
+-generic \s-1MIPS\s0 \s-1ISA\s0, or the name of a particular processor. The \s-1ISA\s0 names
+-are: \fBmips1\fR, \fBmips2\fR, \fBmips3\fR, \fBmips4\fR, \fBmips32\fR
+-and \fBmips64\fR. The processor names are: \fBr2000\fR,
+-\&\fBr3000\fR, \fBr3900\fR, \fBr4000\fR, \fBvr4100\fR, \fBvr4300\fR,
+-\&\fBr4400\fR, \fBr4600\fR, \fBr4650\fR, \fBvr5000\fR, \fBr6000\fR,
+-\&\fBr8000\fR, \fB4kc\fR, \fB4kp\fR, \fB5kc\fR, \fB20kc\fR,
+-\&\fBorion\fR, and \fBsb1\fR. The special value \fBfrom-abi\fR selects the
+-most compatible architecture for the selected \s-1ABI\s0 (that is,
+-\&\fBmips1\fR for 32\-bit ABIs and \fBmips3\fR for 64\-bit ABIs).
+-.Sp
+-In processor names, a final \fB000\fR can be abbreviated as \fBk\fR
+-(for example, \fB\-march=r2k\fR). Prefixes are optional, and
+-\&\fBvr\fR may be written \fBr\fR.
+-.Sp
+-\&\s-1GCC\s0 defines two macros based on the value of this option. The first
+-is \fB_MIPS_ARCH\fR, which gives the name of target architecture, as
+-a string. The second has the form \fB_MIPS_ARCH_\fR\fIfoo\fR,
+-where \fIfoo\fR is the capitalized value of \fB_MIPS_ARCH\fR.
+-For example, \fB\-march=r2000\fR will set \fB_MIPS_ARCH\fR
+-to \fB\*(L"r2000\*(R"\fR and define the macro \fB_MIPS_ARCH_R2000\fR.
+-.Sp
+-Note that the \fB_MIPS_ARCH\fR macro uses the processor names given
+-above. In other words, it will have the full prefix and will not
+-abbreviate \fB000\fR as \fBk\fR. In the case of \fBfrom-abi\fR,
+-the macro names the resolved architecture (either \fB\*(L"mips1\*(R"\fR or
+-\&\fB\*(L"mips3\*(R"\fR). It names the default architecture when no
+-\&\fB\-march\fR option is given.
+-.IP "\fB\-mtune=\fR\fIarch\fR" 4
+-.IX Item "-mtune=arch"
+-Optimize for \fIarch\fR. Among other things, this option controls
+-the way instructions are scheduled, and the perceived cost of arithmetic
+-operations. The list of \fIarch\fR values is the same as for
+-\&\fB\-march\fR.
+-.Sp
+-When this option is not used, \s-1GCC\s0 will optimize for the processor
+-specified by \fB\-march\fR. By using \fB\-march\fR and
+-\&\fB\-mtune\fR together, it is possible to generate code that will
+-run on a family of processors, but optimize the code for one
+-particular member of that family.
+-.Sp
+-\&\fB\-mtune\fR defines the macros \fB_MIPS_TUNE\fR and
+-\&\fB_MIPS_TUNE_\fR\fIfoo\fR, which work in the same way as the
+-\&\fB\-march\fR ones described above.
+-.IP "\fB\-mips1\fR" 4
+-.IX Item "-mips1"
+-Equivalent to \fB\-march=mips1\fR.
+-.IP "\fB\-mips2\fR" 4
+-.IX Item "-mips2"
+-Equivalent to \fB\-march=mips2\fR.
+-.IP "\fB\-mips3\fR" 4
+-.IX Item "-mips3"
+-Equivalent to \fB\-march=mips3\fR.
+-.IP "\fB\-mips4\fR" 4
+-.IX Item "-mips4"
+-Equivalent to \fB\-march=mips4\fR.
+-.IP "\fB\-mips32\fR" 4
+-.IX Item "-mips32"
+-Equivalent to \fB\-march=mips32\fR.
+-.IP "\fB\-mips64\fR" 4
+-.IX Item "-mips64"
+-Equivalent to \fB\-march=mips64\fR.
+-.IP "\fB\-mfused\-madd\fR" 4
+-.IX Item "-mfused-madd"
+-.PD 0
+-.IP "\fB\-mno\-fused\-madd\fR" 4
+-.IX Item "-mno-fused-madd"
+-.PD
+-Generate code that uses (does not use) the floating point multiply and
+-accumulate instructions, when they are available. These instructions
+-are generated by default if they are available, but this may be
+-undesirable if the extra precision causes problems or on certain chips
+-in the mode where denormals are rounded to zero where denormals
+-generated by multiply and accumulate instructions cause exceptions
+-anyway.
+-.IP "\fB\-mfp32\fR" 4
+-.IX Item "-mfp32"
+-Assume that floating point registers are 32 bits wide.
+-.IP "\fB\-mfp64\fR" 4
+-.IX Item "-mfp64"
+-Assume that floating point registers are 64 bits wide.
+-.IP "\fB\-mgp32\fR" 4
+-.IX Item "-mgp32"
+-Assume that general purpose registers are 32 bits wide.
+-.IP "\fB\-mgp64\fR" 4
+-.IX Item "-mgp64"
+-Assume that general purpose registers are 64 bits wide.
+-.IP "\fB\-mint64\fR" 4
+-.IX Item "-mint64"
+-Force int and long types to be 64 bits wide. See \fB\-mlong32\fR for an
+-explanation of the default, and the width of pointers.
+-.IP "\fB\-mlong64\fR" 4
+-.IX Item "-mlong64"
+-Force long types to be 64 bits wide. See \fB\-mlong32\fR for an
+-explanation of the default, and the width of pointers.
+-.IP "\fB\-mlong32\fR" 4
+-.IX Item "-mlong32"
+-Force long, int, and pointer types to be 32 bits wide.
+-.Sp
+-The default size of ints, longs and pointers depends on the \s-1ABI\s0. All
+-the supported ABIs use 32\-bit ints. The n64 \s-1ABI\s0 uses 64\-bit longs, as
+-does the 64\-bit Cygnus \s-1EABI\s0; the others use 32\-bit longs. Pointers
+-are the same size as longs, or the same size as integer registers,
+-whichever is smaller.
+-.IP "\fB\-mabi=32\fR" 4
+-.IX Item "-mabi=32"
+-.PD 0
+-.IP "\fB\-mabi=o64\fR" 4
+-.IX Item "-mabi=o64"
+-.IP "\fB\-mabi=n32\fR" 4
+-.IX Item "-mabi=n32"
+-.IP "\fB\-mabi=64\fR" 4
+-.IX Item "-mabi=64"
+-.IP "\fB\-mabi=eabi\fR" 4
+-.IX Item "-mabi=eabi"
+-.IP "\fB\-mabi=meabi\fR" 4
+-.IX Item "-mabi=meabi"
+-.PD
+-Generate code for the given \s-1ABI\s0.
+-.Sp
+-Note that there are two embedded ABIs: \fB\-mabi=eabi\fR
+-selects the one defined by Cygnus while \fB\-meabi=meabi\fR
+-selects the one defined by \s-1MIPS\s0. Both these ABIs have
+-32\-bit and 64\-bit variants. Normally, \s-1GCC\s0 will generate
+-64\-bit code when you select a 64\-bit architecture, but you
+-can use \fB\-mgp32\fR to get 32\-bit code instead.
+-.IP "\fB\-mmips\-as\fR" 4
+-.IX Item "-mmips-as"
+-Generate code for the \s-1MIPS\s0 assembler, and invoke \fImips-tfile\fR to
+-add normal debug information. This is the default for all
+-platforms except for the \s-1OSF/1\s0 reference platform, using the OSF/rose
+-object format. If the either of the \fB\-gstabs\fR or \fB\-gstabs+\fR
+-switches are used, the \fImips-tfile\fR program will encapsulate the
+-stabs within \s-1MIPS\s0 \s-1ECOFF\s0.
+-.IP "\fB\-mgas\fR" 4
+-.IX Item "-mgas"
+-Generate code for the \s-1GNU\s0 assembler. This is the default on the \s-1OSF/1\s0
+-reference platform, using the OSF/rose object format. Also, this is
+-the default if the configure option \fB\-\-with\-gnu\-as\fR is used.
+-.IP "\fB\-msplit\-addresses\fR" 4
+-.IX Item "-msplit-addresses"
+-.PD 0
+-.IP "\fB\-mno\-split\-addresses\fR" 4
+-.IX Item "-mno-split-addresses"
+-.PD
+-Generate code to load the high and low parts of address constants separately.
+-This allows \s-1GCC\s0 to optimize away redundant loads of the high order
+-bits of addresses. This optimization requires \s-1GNU\s0 as and \s-1GNU\s0 ld.
+-This optimization is enabled by default for some embedded targets where
+-\&\s-1GNU\s0 as and \s-1GNU\s0 ld are standard.
+-.IP "\fB\-mrnames\fR" 4
+-.IX Item "-mrnames"
+-.PD 0
+-.IP "\fB\-mno\-rnames\fR" 4
+-.IX Item "-mno-rnames"
+-.PD
+-The \fB\-mrnames\fR switch says to output code using the \s-1MIPS\s0 software
+-names for the registers, instead of the hardware names (ie, \fIa0\fR
+-instead of \fI$4\fR). The only known assembler that supports this option
+-is the Algorithmics assembler.
+-.IP "\fB\-mgpopt\fR" 4
+-.IX Item "-mgpopt"
+-.PD 0
+-.IP "\fB\-mno\-gpopt\fR" 4
+-.IX Item "-mno-gpopt"
+-.PD
+-The \fB\-mgpopt\fR switch says to write all of the data declarations
+-before the instructions in the text section, this allows the \s-1MIPS\s0
+-assembler to generate one word memory references instead of using two
+-words for short global or static data items. This is on by default if
+-optimization is selected.
+-.IP "\fB\-mstats\fR" 4
+-.IX Item "-mstats"
+-.PD 0
+-.IP "\fB\-mno\-stats\fR" 4
+-.IX Item "-mno-stats"
+-.PD
+-For each non-inline function processed, the \fB\-mstats\fR switch
+-causes the compiler to emit one line to the standard error file to
+-print statistics about the program (number of registers saved, stack
+-size, etc.).
+-.IP "\fB\-mmemcpy\fR" 4
+-.IX Item "-mmemcpy"
+-.PD 0
+-.IP "\fB\-mno\-memcpy\fR" 4
+-.IX Item "-mno-memcpy"
+-.PD
+-The \fB\-mmemcpy\fR switch makes all block moves call the appropriate
+-string function (\fBmemcpy\fR or \fBbcopy\fR) instead of possibly
+-generating inline code.
+-.IP "\fB\-mmips\-tfile\fR" 4
+-.IX Item "-mmips-tfile"
+-.PD 0
+-.IP "\fB\-mno\-mips\-tfile\fR" 4
+-.IX Item "-mno-mips-tfile"
+-.PD
+-The \fB\-mno\-mips\-tfile\fR switch causes the compiler not
+-postprocess the object file with the \fImips-tfile\fR program,
+-after the \s-1MIPS\s0 assembler has generated it to add debug support. If
+-\&\fImips-tfile\fR is not run, then no local variables will be
+-available to the debugger. In addition, \fIstage2\fR and
+-\&\fIstage3\fR objects will have the temporary file names passed to the
+-assembler embedded in the object file, which means the objects will
+-not compare the same. The \fB\-mno\-mips\-tfile\fR switch should only
+-be used when there are bugs in the \fImips-tfile\fR program that
+-prevents compilation.
+-.IP "\fB\-msoft\-float\fR" 4
+-.IX Item "-msoft-float"
+-Generate output containing library calls for floating point.
+-\&\fBWarning:\fR the requisite libraries are not part of \s-1GCC\s0.
+-Normally the facilities of the machine's usual C compiler are used, but
+-this can't be done directly in cross\-compilation. You must make your
+-own arrangements to provide suitable library functions for
+-cross\-compilation.
+-.IP "\fB\-mhard\-float\fR" 4
+-.IX Item "-mhard-float"
+-Generate output containing floating point instructions. This is the
+-default if you use the unmodified sources.
+-.IP "\fB\-mabicalls\fR" 4
+-.IX Item "-mabicalls"
+-.PD 0
+-.IP "\fB\-mno\-abicalls\fR" 4
+-.IX Item "-mno-abicalls"
+-.PD
+-Emit (or do not emit) the pseudo operations \fB.abicalls\fR,
+-\&\fB.cpload\fR, and \fB.cprestore\fR that some System V.4 ports use for
+-position independent code.
+-.IP "\fB\-mlong\-calls\fR" 4
+-.IX Item "-mlong-calls"
+-.PD 0
+-.IP "\fB\-mno\-long\-calls\fR" 4
+-.IX Item "-mno-long-calls"
+-.PD
+-Do all calls with the \fB\s-1JALR\s0\fR instruction, which requires
+-loading up a function's address into a register before the call.
+-You need to use this switch, if you call outside of the current
+-512 megabyte segment to functions that are not through pointers.
+-.IP "\fB\-mhalf\-pic\fR" 4
+-.IX Item "-mhalf-pic"
+-.PD 0
+-.IP "\fB\-mno\-half\-pic\fR" 4
+-.IX Item "-mno-half-pic"
+-.PD
+-Put pointers to extern references into the data section and load them
+-up, rather than put the references in the text section.
+-.IP "\fB\-membedded\-pic\fR" 4
+-.IX Item "-membedded-pic"
+-.PD 0
+-.IP "\fB\-mno\-embedded\-pic\fR" 4
+-.IX Item "-mno-embedded-pic"
+-.PD
+-Generate \s-1PIC\s0 code suitable for some embedded systems. All calls are
+-made using \s-1PC\s0 relative address, and all data is addressed using the \f(CW$gp\fR
+-register. No more than 65536 bytes of global data may be used. This
+-requires \s-1GNU\s0 as and \s-1GNU\s0 ld which do most of the work. This currently
+-only works on targets which use \s-1ECOFF\s0; it does not work with \s-1ELF\s0.
+-.IP "\fB\-membedded\-data\fR" 4
+-.IX Item "-membedded-data"
+-.PD 0
+-.IP "\fB\-mno\-embedded\-data\fR" 4
+-.IX Item "-mno-embedded-data"
+-.PD
+-Allocate variables to the read-only data section first if possible, then
+-next in the small data section if possible, otherwise in data. This gives
+-slightly slower code than the default, but reduces the amount of \s-1RAM\s0 required
+-when executing, and thus may be preferred for some embedded systems.
+-.IP "\fB\-muninit\-const\-in\-rodata\fR" 4
+-.IX Item "-muninit-const-in-rodata"
+-.PD 0
+-.IP "\fB\-mno\-uninit\-const\-in\-rodata\fR" 4
+-.IX Item "-mno-uninit-const-in-rodata"
+-.PD
+-When used together with \fB\-membedded\-data\fR, it will always store uninitialized
+-const variables in the read-only data section.
+-.IP "\fB\-msingle\-float\fR" 4
+-.IX Item "-msingle-float"
+-.PD 0
+-.IP "\fB\-mdouble\-float\fR" 4
+-.IX Item "-mdouble-float"
+-.PD
+-The \fB\-msingle\-float\fR switch tells gcc to assume that the floating
+-point coprocessor only supports single precision operations, as on the
+-\&\fBr4650\fR chip. The \fB\-mdouble\-float\fR switch permits gcc to use
+-double precision operations. This is the default.
+-.IP "\fB\-mmad\fR" 4
+-.IX Item "-mmad"
+-.PD 0
+-.IP "\fB\-mno\-mad\fR" 4
+-.IX Item "-mno-mad"
+-.PD
+-Permit use of the \fBmad\fR, \fBmadu\fR and \fBmul\fR instructions,
+-as on the \fBr4650\fR chip.
+-.IP "\fB\-m4650\fR" 4
+-.IX Item "-m4650"
+-Turns on \fB\-msingle\-float\fR, \fB\-mmad\fR, and, at least for now,
+-\&\fB\-mcpu=r4650\fR.
+-.IP "\fB\-mips16\fR" 4
+-.IX Item "-mips16"
+-.PD 0
+-.IP "\fB\-mno\-mips16\fR" 4
+-.IX Item "-mno-mips16"
+-.PD
+-Enable 16\-bit instructions.
+-.IP "\fB\-mentry\fR" 4
+-.IX Item "-mentry"
+-Use the entry and exit pseudo ops. This option can only be used with
+-\&\fB\-mips16\fR.
+-.IP "\fB\-EL\fR" 4
+-.IX Item "-EL"
+-Compile code for the processor in little endian mode.
+-The requisite libraries are assumed to exist.
+-.IP "\fB\-EB\fR" 4
+-.IX Item "-EB"
+-Compile code for the processor in big endian mode.
+-The requisite libraries are assumed to exist.
+-.IP "\fB\-G\fR \fInum\fR" 4
+-.IX Item "-G num"
+-Put global and static items less than or equal to \fInum\fR bytes into
+-the small data or bss sections instead of the normal data or bss
+-section. This allows the assembler to emit one word memory reference
+-instructions based on the global pointer (\fIgp\fR or \fI$28\fR),
+-instead of the normal two words used. By default, \fInum\fR is 8 when
+-the \s-1MIPS\s0 assembler is used, and 0 when the \s-1GNU\s0 assembler is used. The
+-\&\fB\-G\fR \fInum\fR switch is also passed to the assembler and linker.
+-All modules should be compiled with the same \fB\-G\fR \fInum\fR
+-value.
+-.IP "\fB\-nocpp\fR" 4
+-.IX Item "-nocpp"
+-Tell the \s-1MIPS\s0 assembler to not run its preprocessor over user
+-assembler files (with a \fB.s\fR suffix) when assembling them.
+-.IP "\fB\-mfix7000\fR" 4
+-.IX Item "-mfix7000"
+-Pass an option to gas which will cause nops to be inserted if
+-the read of the destination register of an mfhi or mflo instruction
+-occurs in the following two instructions.
+-.IP "\fB\-no\-crt0\fR" 4
+-.IX Item "-no-crt0"
+-Do not include the default crt0.
+-.IP "\fB\-mflush\-func=\fR\fIfunc\fR" 4
+-.IX Item "-mflush-func=func"
+-.PD 0
+-.IP "\fB\-mno\-flush\-func\fR" 4
+-.IX Item "-mno-flush-func"
+-.PD
+-Specifies the function to call to flush the I and D caches, or to not
+-call any such function. If called, the function must take the same
+-arguments as the common \f(CW\*(C`_flush_func()\*(C'\fR, that is, the address of the
+-memory range for which the cache is being flushed, the size of the
+-memory range, and the number 3 (to flush both caches). The default
+-depends on the target gcc was configured for, but commonly is either
+-\&\fB_flush_func\fR or \fB_\|_cpu_flush\fR.
+-.IP "\fB\-mbranch\-likely\fR" 4
+-.IX Item "-mbranch-likely"
+-.PD 0
+-.IP "\fB\-mno\-branch\-likely\fR" 4
+-.IX Item "-mno-branch-likely"
+-.PD
+-Enable or disable use of Branch Likely instructions, regardless of the
+-default for the selected architecture. By default, Branch Likely
+-instructions may be generated if they are supported by the selected
+-architecture. An exception is for the \s-1MIPS32\s0 and \s-1MIPS64\s0 architectures
+-and processors which implement those architectures; for those, Branch
+-Likely instructions will not be generated by default because the \s-1MIPS32\s0
+-and \s-1MIPS64\s0 architectures specifically deprecate their use.
+-.PP
+-\fIIntel 386 and \s-1AMD\s0 x86\-64 Options\fR
+-.IX Subsection "Intel 386 and AMD x86-64 Options"
+-.PP
+-These \fB\-m\fR options are defined for the i386 and x86\-64 family of
+-computers:
+-.IP "\fB\-mcpu=\fR\fIcpu-type\fR" 4
+-.IX Item "-mcpu=cpu-type"
+-Tune to \fIcpu-type\fR everything applicable about the generated code, except
+-for the \s-1ABI\s0 and the set of available instructions. The choices for
+-\&\fIcpu-type\fR are \fBi386\fR, \fBi486\fR, \fBi586\fR, \fBi686\fR,
+-\&\fBpentium\fR, \fBpentium-mmx\fR, \fBpentiumpro\fR, \fBpentium2\fR,
+-\&\fBpentium3\fR, \fBpentium4\fR, \fBprescott\fR, \fBnocona\fR,
+-\&\fBk6\fR, \fBk6\-2\fR, \fBk6\-3\fR,
+-\&\fBathlon\fR, \fBathlon-tbird\fR, \fBathlon\-4\fR, \fBathlon-xp\fR,
+-\&\fBathlon-mp\fR, \fBwinchip\-c6\fR, \fBwinchip2\fR and \fBc3\fR.
+-.Sp
+-While picking a specific \fIcpu-type\fR will schedule things appropriately
+-for that particular chip, the compiler will not generate any code that
+-does not run on the i386 without the \fB\-march=\fR\fIcpu-type\fR option
+-being used. \fBi586\fR is equivalent to \fBpentium\fR and \fBi686\fR
+-is equivalent to \fBpentiumpro\fR. \fBk6\fR and \fBathlon\fR are the
+-\&\s-1AMD\s0 chips as opposed to the Intel ones.
+-.IP "\fB\-march=\fR\fIcpu-type\fR" 4
+-.IX Item "-march=cpu-type"
+-Generate instructions for the machine type \fIcpu-type\fR. The choices
+-for \fIcpu-type\fR are the same as for \fB\-mcpu\fR. Moreover,
+-specifying \fB\-march=\fR\fIcpu-type\fR implies \fB\-mcpu=\fR\fIcpu-type\fR.
+-.IP "\fB\-m386\fR" 4
+-.IX Item "-m386"
+-.PD 0
+-.IP "\fB\-m486\fR" 4
+-.IX Item "-m486"
+-.IP "\fB\-mpentium\fR" 4
+-.IX Item "-mpentium"
+-.IP "\fB\-mpentiumpro\fR" 4
+-.IX Item "-mpentiumpro"
+-.PD
+-These options are synonyms for \fB\-mcpu=i386\fR, \fB\-mcpu=i486\fR,
+-\&\fB\-mcpu=pentium\fR, and \fB\-mcpu=pentiumpro\fR respectively.
+-These synonyms are deprecated.
+-.IP "\fB\-mfpmath=\fR\fIunit\fR" 4
+-.IX Item "-mfpmath=unit"
+-Generate floating point arithmetics for selected unit \fIunit\fR. The choices
+-for \fIunit\fR are:
+-.RS 4
+-.IP "\fB387\fR" 4
+-.IX Item "387"
+-Use the standard 387 floating point coprocessor present majority of chips and
+-emulated otherwise. Code compiled with this option will run almost everywhere.
+-The temporary results are computed in 80bit precision instead of precision
+-specified by the type resulting in slightly different results compared to most
+-of other chips. See \fB\-ffloat\-store\fR for more detailed description.
+-.Sp
+-This is the default choice for i386 compiler.
+-.IP "\fBsse\fR" 4
+-.IX Item "sse"
+-Use scalar floating point instructions present in the \s-1SSE\s0 instruction set.
+-This instruction set is supported by Pentium3 and newer chips, in the \s-1AMD\s0 line
+-by Athlon\-4, Athlon-xp and Athlon-mp chips. The earlier version of \s-1SSE\s0
+-instruction set supports only single precision arithmetics, thus the double and
+-extended precision arithmetics is still done using 387. Later version, present
+-only in Pentium4 and the future \s-1AMD\s0 x86\-64 chips supports double precision
+-arithmetics too.
+-.Sp
+-For i387 you need to use \fB\-march=\fR\fIcpu-type\fR, \fB\-msse\fR or
+-\&\fB\-msse2\fR switches to enable \s-1SSE\s0 extensions and make this option
+-effective. For x86\-64 compiler, these extensions are enabled by default.
+-.Sp
+-The resulting code should be considerably faster in the majority of cases and avoid
+-the numerical instability problems of 387 code, but may break some existing
+-code that expects temporaries to be 80bit.
+-.Sp
+-This is the default choice for the x86\-64 compiler.
+-.IP "\fBsse,387\fR" 4
+-.IX Item "sse,387"
+-Attempt to utilize both instruction sets at once. This effectively double the
+-amount of available registers and on chips with separate execution units for
+-387 and \s-1SSE\s0 the execution resources too. Use this option with care, as it is
+-still experimental, because the gcc register allocator does not model separate
+-functional units well.
+-.RE
+-.RS 4
+-.RE
+-.IP "\fB\-masm=\fR\fIdialect\fR" 4
+-.IX Item "-masm=dialect"
+-Output asm instructions using selected \fIdialect\fR. Supported choices are
+-\&\fBintel\fR or \fBatt\fR (the default one).
+-.IP "\fB\-mieee\-fp\fR" 4
+-.IX Item "-mieee-fp"
+-.PD 0
+-.IP "\fB\-mno\-ieee\-fp\fR" 4
+-.IX Item "-mno-ieee-fp"
+-.PD
+-Control whether or not the compiler uses \s-1IEEE\s0 floating point
+-comparisons. These handle correctly the case where the result of a
+-comparison is unordered.
+-.IP "\fB\-msoft\-float\fR" 4
+-.IX Item "-msoft-float"
+-Generate output containing library calls for floating point.
+-\&\fBWarning:\fR the requisite libraries are not part of \s-1GCC\s0.
+-Normally the facilities of the machine's usual C compiler are used, but
+-this can't be done directly in cross\-compilation. You must make your
+-own arrangements to provide suitable library functions for
+-cross\-compilation.
+-.Sp
+-On machines where a function returns floating point results in the 80387
+-register stack, some floating point opcodes may be emitted even if
+-\&\fB\-msoft\-float\fR is used.
+-.IP "\fB\-mno\-fp\-ret\-in\-387\fR" 4
+-.IX Item "-mno-fp-ret-in-387"
+-Do not use the \s-1FPU\s0 registers for return values of functions.
+-.Sp
+-The usual calling convention has functions return values of types
+-\&\f(CW\*(C`float\*(C'\fR and \f(CW\*(C`double\*(C'\fR in an \s-1FPU\s0 register, even if there
+-is no \s-1FPU\s0. The idea is that the operating system should emulate
+-an \s-1FPU\s0.
+-.Sp
+-The option \fB\-mno\-fp\-ret\-in\-387\fR causes such values to be returned
+-in ordinary \s-1CPU\s0 registers instead.
+-.IP "\fB\-mno\-fancy\-math\-387\fR" 4
+-.IX Item "-mno-fancy-math-387"
+-Some 387 emulators do not support the \f(CW\*(C`sin\*(C'\fR, \f(CW\*(C`cos\*(C'\fR and
+-\&\f(CW\*(C`sqrt\*(C'\fR instructions for the 387. Specify this option to avoid
+-generating those instructions. This option is the default on FreeBSD,
+-OpenBSD and NetBSD. This option is overridden when \fB\-march\fR
+-indicates that the target cpu will always have an \s-1FPU\s0 and so the
+-instruction will not need emulation. As of revision 2.6.1, these
+-instructions are not generated unless you also use the
+-\&\fB\-funsafe\-math\-optimizations\fR switch.
+-.IP "\fB\-malign\-double\fR" 4
+-.IX Item "-malign-double"
+-.PD 0
+-.IP "\fB\-mno\-align\-double\fR" 4
+-.IX Item "-mno-align-double"
+-.PD
+-Control whether \s-1GCC\s0 aligns \f(CW\*(C`double\*(C'\fR, \f(CW\*(C`long double\*(C'\fR, and
+-\&\f(CW\*(C`long long\*(C'\fR variables on a two word boundary or a one word
+-boundary. Aligning \f(CW\*(C`double\*(C'\fR variables on a two word boundary will
+-produce code that runs somewhat faster on a \fBPentium\fR at the
+-expense of more memory.
+-.Sp
+-\&\fBWarning:\fR if you use the \fB\-malign\-double\fR switch,
+-structures containing the above types will be aligned differently than
+-the published application binary interface specifications for the 386
+-and will not be binary compatible with structures in code compiled
+-without that switch.
+-.IP "\fB\-m96bit\-long\-double\fR" 4
+-.IX Item "-m96bit-long-double"
+-.PD 0
+-.IP "\fB\-m128bit\-long\-double\fR" 4
+-.IX Item "-m128bit-long-double"
+-.PD
+-These switches control the size of \f(CW\*(C`long double\*(C'\fR type. The i386
+-application binary interface specifies the size to be 96 bits,
+-so \fB\-m96bit\-long\-double\fR is the default in 32 bit mode.
+-.Sp
+-Modern architectures (Pentium and newer) would prefer \f(CW\*(C`long double\*(C'\fR
+-to be aligned to an 8 or 16 byte boundary. In arrays or structures
+-conforming to the \s-1ABI\s0, this would not be possible. So specifying a
+-\&\fB\-m128bit\-long\-double\fR will align \f(CW\*(C`long double\*(C'\fR
+-to a 16 byte boundary by padding the \f(CW\*(C`long double\*(C'\fR with an additional
+-32 bit zero.
+-.Sp
+-In the x86\-64 compiler, \fB\-m128bit\-long\-double\fR is the default choice as
+-its \s-1ABI\s0 specifies that \f(CW\*(C`long double\*(C'\fR is to be aligned on 16 byte boundary.
+-.Sp
+-Notice that neither of these options enable any extra precision over the x87
+-standard of 80 bits for a \f(CW\*(C`long double\*(C'\fR.
+-.Sp
+-\&\fBWarning:\fR if you override the default value for your target \s-1ABI\s0, the
+-structures and arrays containing \f(CW\*(C`long double\*(C'\fR variables will change their size as
+-well as function calling convention for function taking \f(CW\*(C`long double\*(C'\fR
+-will be modified. Hence they will not be binary compatible with arrays or
+-structures in code compiled without that switch.
+-.IP "\fB\-msvr3\-shlib\fR" 4
+-.IX Item "-msvr3-shlib"
+-.PD 0
+-.IP "\fB\-mno\-svr3\-shlib\fR" 4
+-.IX Item "-mno-svr3-shlib"
+-.PD
+-Control whether \s-1GCC\s0 places uninitialized local variables into the
+-\&\f(CW\*(C`bss\*(C'\fR or \f(CW\*(C`data\*(C'\fR segments. \fB\-msvr3\-shlib\fR places them
+-into \f(CW\*(C`bss\*(C'\fR. These options are meaningful only on System V Release 3.
+-.IP "\fB\-mrtd\fR" 4
+-.IX Item "-mrtd"
+-Use a different function-calling convention, in which functions that
+-take a fixed number of arguments return with the \f(CW\*(C`ret\*(C'\fR \fInum\fR
+-instruction, which pops their arguments while returning. This saves one
+-instruction in the caller since there is no need to pop the arguments
+-there.
+-.Sp
+-You can specify that an individual function is called with this calling
+-sequence with the function attribute \fBstdcall\fR. You can also
+-override the \fB\-mrtd\fR option by using the function attribute
+-\&\fBcdecl\fR.
+-.Sp
+-\&\fBWarning:\fR this calling convention is incompatible with the one
+-normally used on Unix, so you cannot use it if you need to call
+-libraries compiled with the Unix compiler.
+-.Sp
+-Also, you must provide function prototypes for all functions that
+-take variable numbers of arguments (including \f(CW\*(C`printf\*(C'\fR);
+-otherwise incorrect code will be generated for calls to those
+-functions.
+-.Sp
+-In addition, seriously incorrect code will result if you call a
+-function with too many arguments. (Normally, extra arguments are
+-harmlessly ignored.)
+-.IP "\fB\-mregparm=\fR\fInum\fR" 4
+-.IX Item "-mregparm=num"
+-Control how many registers are used to pass integer arguments. By
+-default, no registers are used to pass arguments, and at most 3
+-registers can be used. You can control this behavior for a specific
+-function by using the function attribute \fBregparm\fR.
+-.Sp
+-\&\fBWarning:\fR if you use this switch, and
+-\&\fInum\fR is nonzero, then you must build all modules with the same
+-value, including any libraries. This includes the system libraries and
+-startup modules.
+-.IP "\fB\-mpreferred\-stack\-boundary=\fR\fInum\fR" 4
+-.IX Item "-mpreferred-stack-boundary=num"
+-Attempt to keep the stack boundary aligned to a 2 raised to \fInum\fR
+-byte boundary. If \fB\-mpreferred\-stack\-boundary\fR is not specified,
+-the default is 4 (16 bytes or 128 bits), except when optimizing for code
+-size (\fB\-Os\fR), in which case the default is the minimum correct
+-alignment (4 bytes for x86, and 8 bytes for x86\-64).
+-.Sp
+-On Pentium and PentiumPro, \f(CW\*(C`double\*(C'\fR and \f(CW\*(C`long double\*(C'\fR values
+-should be aligned to an 8 byte boundary (see \fB\-malign\-double\fR) or
+-suffer significant run time performance penalties. On Pentium \s-1III\s0, the
+-Streaming \s-1SIMD\s0 Extension (\s-1SSE\s0) data type \f(CW\*(C`_\|_m128\*(C'\fR suffers similar
+-penalties if it is not 16 byte aligned.
+-.Sp
+-To ensure proper alignment of this values on the stack, the stack boundary
+-must be as aligned as that required by any value stored on the stack.
+-Further, every function must be generated such that it keeps the stack
+-aligned. Thus calling a function compiled with a higher preferred
+-stack boundary from a function compiled with a lower preferred stack
+-boundary will most likely misalign the stack. It is recommended that
+-libraries that use callbacks always use the default setting.
+-.Sp
+-This extra alignment does consume extra stack space, and generally
+-increases code size. Code that is sensitive to stack space usage, such
+-as embedded systems and operating system kernels, may want to reduce the
+-preferred alignment to \fB\-mpreferred\-stack\-boundary=2\fR.
+-.IP "\fB\-mmmx\fR" 4
+-.IX Item "-mmmx"
+-.PD 0
+-.IP "\fB\-mno\-mmx\fR" 4
+-.IX Item "-mno-mmx"
+-.IP "\fB\-msse\fR" 4
+-.IX Item "-msse"
+-.IP "\fB\-mno\-sse\fR" 4
+-.IX Item "-mno-sse"
+-.IP "\fB\-msse2\fR" 4
+-.IX Item "-msse2"
+-.IP "\fB\-mno\-sse2\fR" 4
+-.IX Item "-mno-sse2"
+-.IP "\fB\-msse3\fR" 4
+-.IX Item "-msse3"
+-.IP "\fB\-mno\-sse3\fR" 4
+-.IX Item "-mno-sse3"
+-.IP "\fB\-m3dnow\fR" 4
+-.IX Item "-m3dnow"
+-.IP "\fB\-mno\-3dnow\fR" 4
+-.IX Item "-mno-3dnow"
+-.PD
+-These switches enable or disable the use of built-in functions that allow
+-direct access to the \s-1MMX\s0, \s-1SSE\s0, \s-1SSE2\s0, \s-1SSE3\s0 and 3Dnow extensions of the
+-instruction set.
+-.Sp
+-To have \s-1SSE/SSE2\s0 instructions generated automatically from floating-point
+-code, see \fB\-mfpmath=sse\fR.
+-.IP "\fB\-mpush\-args\fR" 4
+-.IX Item "-mpush-args"
+-.PD 0
+-.IP "\fB\-mno\-push\-args\fR" 4
+-.IX Item "-mno-push-args"
+-.PD
+-Use \s-1PUSH\s0 operations to store outgoing parameters. This method is shorter
+-and usually equally fast as method using \s-1SUB/MOV\s0 operations and is enabled
+-by default. In some cases disabling it may improve performance because of
+-improved scheduling and reduced dependencies.
+-.IP "\fB\-maccumulate\-outgoing\-args\fR" 4
+-.IX Item "-maccumulate-outgoing-args"
+-If enabled, the maximum amount of space required for outgoing arguments will be
+-computed in the function prologue. This is faster on most modern CPUs
+-because of reduced dependencies, improved scheduling and reduced stack usage
+-when preferred stack boundary is not equal to 2. The drawback is a notable
+-increase in code size. This switch implies \fB\-mno\-push\-args\fR.
+-.IP "\fB\-mthreads\fR" 4
+-.IX Item "-mthreads"
+-Support thread-safe exception handling on \fBMingw32\fR. Code that relies
+-on thread-safe exception handling must compile and link all code with the
+-\&\fB\-mthreads\fR option. When compiling, \fB\-mthreads\fR defines
+-\&\fB\-D_MT\fR; when linking, it links in a special thread helper library
+-\&\fB\-lmingwthrd\fR which cleans up per thread exception handling data.
+-.IP "\fB\-mno\-align\-stringops\fR" 4
+-.IX Item "-mno-align-stringops"
+-Do not align destination of inlined string operations. This switch reduces
+-code size and improves performance in case the destination is already aligned,
+-but gcc don't know about it.
+-.IP "\fB\-minline\-all\-stringops\fR" 4
+-.IX Item "-minline-all-stringops"
+-By default \s-1GCC\s0 inlines string operations only when destination is known to be
+-aligned at least to 4 byte boundary. This enables more inlining, increase code
+-size, but may improve performance of code that depends on fast memcpy, strlen
+-and memset for short lengths.
+-.IP "\fB\-momit\-leaf\-frame\-pointer\fR" 4
+-.IX Item "-momit-leaf-frame-pointer"
+-Don't keep the frame pointer in a register for leaf functions. This
+-avoids the instructions to save, set up and restore frame pointers and
+-makes an extra register available in leaf functions. The option
+-\&\fB\-fomit\-frame\-pointer\fR removes the frame pointer for all functions
+-which might make debugging harder.
+-.PP
+-These \fB\-m\fR switches are supported in addition to the above
+-on \s-1AMD\s0 x86\-64 processors in 64\-bit environments.
+-.IP "\fB\-m32\fR" 4
+-.IX Item "-m32"
+-.PD 0
+-.IP "\fB\-m64\fR" 4
+-.IX Item "-m64"
+-.PD
+-Generate code for a 32\-bit or 64\-bit environment.
+-The 32\-bit environment sets int, long and pointer to 32 bits and
+-generates code that runs on any i386 system.
+-The 64\-bit environment sets int to 32 bits and long and pointer
+-to 64 bits and generates code for \s-1AMD\s0's x86\-64 architecture.
+-.IP "\fB\-mno\-red\-zone\fR" 4
+-.IX Item "-mno-red-zone"
+-Do not use a so called red zone for x86\-64 code. The red zone is mandated
+-by the x86\-64 \s-1ABI\s0, it is a 128\-byte area beyond the location of the
+-stack pointer that will not be modified by signal or interrupt handlers
+-and therefore can be used for temporary data without adjusting the stack
+-pointer. The flag \fB\-mno\-red\-zone\fR disables this red zone.
+-.IP "\fB\-mcmodel=small\fR" 4
+-.IX Item "-mcmodel=small"
+-Generate code for the small code model: the program and its symbols must
+-be linked in the lower 2 \s-1GB\s0 of the address space. Pointers are 64 bits.
+-Programs can be statically or dynamically linked. This is the default
+-code model.
+-.IP "\fB\-mcmodel=kernel\fR" 4
+-.IX Item "-mcmodel=kernel"
+-Generate code for the kernel code model. The kernel runs in the
+-negative 2 \s-1GB\s0 of the address space.
+-This model has to be used for Linux kernel code.
+-.IP "\fB\-mcmodel=medium\fR" 4
+-.IX Item "-mcmodel=medium"
+-Generate code for the medium model: The program is linked in the lower 2
+-\&\s-1GB\s0 of the address space but symbols can be located anywhere in the
+-address space. Programs can be statically or dynamically linked, but
+-building of shared libraries are not supported with the medium model.
+-.IP "\fB\-mcmodel=large\fR" 4
+-.IX Item "-mcmodel=large"
+-Generate code for the large model: This model makes no assumptions
+-about addresses and sizes of sections. Currently \s-1GCC\s0 does not implement
+-this model.
+-.PP
+-\fI\s-1HPPA\s0 Options\fR
+-.IX Subsection "HPPA Options"
+-.PP
+-These \fB\-m\fR options are defined for the \s-1HPPA\s0 family of computers:
+-.IP "\fB\-march=\fR\fIarchitecture-type\fR" 4
+-.IX Item "-march=architecture-type"
+-Generate code for the specified architecture. The choices for
+-\&\fIarchitecture-type\fR are \fB1.0\fR for \s-1PA\s0 1.0, \fB1.1\fR for \s-1PA\s0
+-1.1, and \fB2.0\fR for \s-1PA\s0 2.0 processors. Refer to
+-\&\fI/usr/lib/sched.models\fR on an HP-UX system to determine the proper
+-architecture option for your machine. Code compiled for lower numbered
+-architectures will run on higher numbered architectures, but not the
+-other way around.
+-.Sp
+-\&\s-1PA\s0 2.0 support currently requires gas snapshot 19990413 or later. The
+-next release of binutils (current is 2.9.1) will probably contain \s-1PA\s0 2.0
+-support.
+-.IP "\fB\-mpa\-risc\-1\-0\fR" 4
+-.IX Item "-mpa-risc-1-0"
+-.PD 0
+-.IP "\fB\-mpa\-risc\-1\-1\fR" 4
+-.IX Item "-mpa-risc-1-1"
+-.IP "\fB\-mpa\-risc\-2\-0\fR" 4
+-.IX Item "-mpa-risc-2-0"
+-.PD
+-Synonyms for \fB\-march=1.0\fR, \fB\-march=1.1\fR, and \fB\-march=2.0\fR respectively.
+-.IP "\fB\-mbig\-switch\fR" 4
+-.IX Item "-mbig-switch"
+-Generate code suitable for big switch tables. Use this option only if
+-the assembler/linker complain about out of range branches within a switch
+-table.
+-.IP "\fB\-mjump\-in\-delay\fR" 4
+-.IX Item "-mjump-in-delay"
+-Fill delay slots of function calls with unconditional jump instructions
+-by modifying the return pointer for the function call to be the target
+-of the conditional jump.
+-.IP "\fB\-mdisable\-fpregs\fR" 4
+-.IX Item "-mdisable-fpregs"
+-Prevent floating point registers from being used in any manner. This is
+-necessary for compiling kernels which perform lazy context switching of
+-floating point registers. If you use this option and attempt to perform
+-floating point operations, the compiler will abort.
+-.IP "\fB\-mdisable\-indexing\fR" 4
+-.IX Item "-mdisable-indexing"
+-Prevent the compiler from using indexing address modes. This avoids some
+-rather obscure problems when compiling \s-1MIG\s0 generated code under \s-1MACH\s0.
+-.IP "\fB\-mno\-space\-regs\fR" 4
+-.IX Item "-mno-space-regs"
+-Generate code that assumes the target has no space registers. This allows
+-\&\s-1GCC\s0 to generate faster indirect calls and use unscaled index address modes.
+-.Sp
+-Such code is suitable for level 0 \s-1PA\s0 systems and kernels.
+-.IP "\fB\-mfast\-indirect\-calls\fR" 4
+-.IX Item "-mfast-indirect-calls"
+-Generate code that assumes calls never cross space boundaries. This
+-allows \s-1GCC\s0 to emit code which performs faster indirect calls.
+-.Sp
+-This option will not work in the presence of shared libraries or nested
+-functions.
+-.IP "\fB\-mlong\-load\-store\fR" 4
+-.IX Item "-mlong-load-store"
+-Generate 3\-instruction load and store sequences as sometimes required by
+-the HP-UX 10 linker. This is equivalent to the \fB+k\fR option to
+-the \s-1HP\s0 compilers.
+-.IP "\fB\-mportable\-runtime\fR" 4
+-.IX Item "-mportable-runtime"
+-Use the portable calling conventions proposed by \s-1HP\s0 for \s-1ELF\s0 systems.
+-.IP "\fB\-mgas\fR" 4
+-.IX Item "-mgas"
+-Enable the use of assembler directives only \s-1GAS\s0 understands.
+-.IP "\fB\-mschedule=\fR\fIcpu-type\fR" 4
+-.IX Item "-mschedule=cpu-type"
+-Schedule code according to the constraints for the machine type
+-\&\fIcpu-type\fR. The choices for \fIcpu-type\fR are \fB700\fR
+-\&\fB7100\fR, \fB7100LC\fR, \fB7200\fR, \fB7300\fR and \fB8000\fR. Refer
+-to \fI/usr/lib/sched.models\fR on an HP-UX system to determine the
+-proper scheduling option for your machine. The default scheduling is
+-\&\fB8000\fR.
+-.IP "\fB\-mlinker\-opt\fR" 4
+-.IX Item "-mlinker-opt"
+-Enable the optimization pass in the HP-UX linker. Note this makes symbolic
+-debugging impossible. It also triggers a bug in the HP-UX 8 and HP-UX 9
+-linkers in which they give bogus error messages when linking some programs.
+-.IP "\fB\-msoft\-float\fR" 4
+-.IX Item "-msoft-float"
+-Generate output containing library calls for floating point.
+-\&\fBWarning:\fR the requisite libraries are not available for all \s-1HPPA\s0
+-targets. Normally the facilities of the machine's usual C compiler are
+-used, but this cannot be done directly in cross\-compilation. You must make
+-your own arrangements to provide suitable library functions for
+-cross\-compilation. The embedded target \fBhppa1.1\-*\-pro\fR
+-does provide software floating point support.
+-.Sp
+-\&\fB\-msoft\-float\fR changes the calling convention in the output file;
+-therefore, it is only useful if you compile \fIall\fR of a program with
+-this option. In particular, you need to compile \fIlibgcc.a\fR, the
+-library that comes with \s-1GCC\s0, with \fB\-msoft\-float\fR in order for
+-this to work.
+-.IP "\fB\-msio\fR" 4
+-.IX Item "-msio"
+-Generate the predefine, \f(CW\*(C`_SIO\*(C'\fR, for server \s-1IO\s0. The default is
+-\&\fB\-mwsio\fR. This generates the predefines, \f(CW\*(C`_\|_hp9000s700\*(C'\fR,
+-\&\f(CW\*(C`_\|_hp9000s700_\|_\*(C'\fR and \f(CW\*(C`_WSIO\*(C'\fR, for workstation \s-1IO\s0. These
+-options are available under HP-UX and \s-1HI\-UX\s0.
+-.IP "\fB\-mgnu\-ld\fR" 4
+-.IX Item "-mgnu-ld"
+-Use \s-1GNU\s0 ld specific options. This passes \fB\-shared\fR to ld when
+-building a shared library. It is the default when \s-1GCC\s0 is configured,
+-explicitly or implicitly, with the \s-1GNU\s0 linker. This option does not
+-have any affect on which ld is called, it only changes what parameters
+-are passed to that ld. The ld that is called is determined by the
+-\&\fB\-\-with\-ld\fR configure option, gcc's program search path, and
+-finally by the user's \fB\s-1PATH\s0\fR. The linker used by \s-1GCC\s0 can be printed
+-using \fBwhich `gcc \-print\-prog\-name=ld`\fR.
+-.IP "\fB\-mhp\-ld\fR" 4
+-.IX Item "-mhp-ld"
+-Use \s-1HP\s0 ld specific options. This passes \fB\-b\fR to ld when building
+-a shared library and passes \fB+Accept TypeMismatch\fR to ld on all
+-links. It is the default when \s-1GCC\s0 is configured, explicitly or
+-implicitly, with the \s-1HP\s0 linker. This option does not have any affect on
+-which ld is called, it only changes what parameters are passed to that
+-ld. The ld that is called is determined by the \fB\-\-with\-ld\fR
+-configure option, gcc's program search path, and finally by the user's
+-\&\fB\s-1PATH\s0\fR. The linker used by \s-1GCC\s0 can be printed using \fBwhich
+-`gcc \-print\-prog\-name=ld`\fR.
+-.IP "\fB\-mlong\-calls\fR" 4
+-.IX Item "-mlong-calls"
+-Generate code that uses long call sequences. This ensures that a call
+-is always able to reach linker generated stubs. The default is to generate
+-long calls only when the distance from the call site to the beginning
+-of the function or translation unit, as the case may be, exceeds a
+-predefined limit set by the branch type being used. The limits for
+-normal calls are 7,600,000 and 240,000 bytes, respectively for the
+-\&\s-1PA\s0 2.0 and \s-1PA\s0 1.X architectures. Sibcalls are always limited at
+-240,000 bytes.
+-.Sp
+-Distances are measured from the beginning of functions when using the
+-\&\fB\-ffunction\-sections\fR option, or when using the \fB\-mgas\fR
+-and \fB\-mno\-portable\-runtime\fR options together under HP-UX with
+-the \s-1SOM\s0 linker.
+-.Sp
+-It is normally not desirable to use this option as it will degrade
+-performance. However, it may be useful in large applications,
+-particularly when partial linking is used to build the application.
+-.Sp
+-The types of long calls used depends on the capabilities of the
+-assembler and linker, and the type of code being generated. The
+-impact on systems that support long absolute calls, and long pic
+-symbol-difference or pc-relative calls should be relatively small.
+-However, an indirect call is used on 32\-bit \s-1ELF\s0 systems in pic code
+-and it is quite long.
+-.IP "\fB\-nolibdld\fR" 4
+-.IX Item "-nolibdld"
+-Suppress the generation of link options to search libdld.sl when the
+-\&\fB\-static\fR option is specified on HP-UX 10 and later.
+-.IP "\fB\-static\fR" 4
+-.IX Item "-static"
+-The HP-UX implementation of setlocale in libc has a dependency on
+-libdld.sl. There isn't an archive version of libdld.sl. Thus,
+-when the \fB\-static\fR option is specified, special link options
+-are needed to resolve this dependency.
+-.Sp
+-On HP-UX 10 and later, the \s-1GCC\s0 driver adds the necessary options to
+-link with libdld.sl when the \fB\-static\fR option is specified.
+-This causes the resulting binary to be dynamic. On the 64\-bit port,
+-the linkers generate dynamic binaries by default in any case. The
+-\&\fB\-nolibdld\fR option can be used to prevent the \s-1GCC\s0 driver from
+-adding these link options.
+-.IP "\fB\-threads\fR" 4
+-.IX Item "-threads"
+-Add support for multithreading with the \fIdce thread\fR library
+-under \s-1HP\-UX\s0. This option sets flags for both the preprocessor and
+-linker.
+-.PP
+-\fIIntel 960 Options\fR
+-.IX Subsection "Intel 960 Options"
+-.PP
+-These \fB\-m\fR options are defined for the Intel 960 implementations:
+-.IP "\fB\-m\fR\fIcpu-type\fR" 4
+-.IX Item "-mcpu-type"
+-Assume the defaults for the machine type \fIcpu-type\fR for some of
+-the other options, including instruction scheduling, floating point
+-support, and addressing modes. The choices for \fIcpu-type\fR are
+-\&\fBka\fR, \fBkb\fR, \fBmc\fR, \fBca\fR, \fBcf\fR,
+-\&\fBsa\fR, and \fBsb\fR.
+-The default is
+-\&\fBkb\fR.
+-.IP "\fB\-mnumerics\fR" 4
+-.IX Item "-mnumerics"
+-.PD 0
+-.IP "\fB\-msoft\-float\fR" 4
+-.IX Item "-msoft-float"
+-.PD
+-The \fB\-mnumerics\fR option indicates that the processor does support
+-floating-point instructions. The \fB\-msoft\-float\fR option indicates
+-that floating-point support should not be assumed.
+-.IP "\fB\-mleaf\-procedures\fR" 4
+-.IX Item "-mleaf-procedures"
+-.PD 0
+-.IP "\fB\-mno\-leaf\-procedures\fR" 4
+-.IX Item "-mno-leaf-procedures"
+-.PD
+-Do (or do not) attempt to alter leaf procedures to be callable with the
+-\&\f(CW\*(C`bal\*(C'\fR instruction as well as \f(CW\*(C`call\*(C'\fR. This will result in more
+-efficient code for explicit calls when the \f(CW\*(C`bal\*(C'\fR instruction can be
+-substituted by the assembler or linker, but less efficient code in other
+-cases, such as calls via function pointers, or using a linker that doesn't
+-support this optimization.
+-.IP "\fB\-mtail\-call\fR" 4
+-.IX Item "-mtail-call"
+-.PD 0
+-.IP "\fB\-mno\-tail\-call\fR" 4
+-.IX Item "-mno-tail-call"
+-.PD
+-Do (or do not) make additional attempts (beyond those of the
+-machine-independent portions of the compiler) to optimize tail-recursive
+-calls into branches. You may not want to do this because the detection of
+-cases where this is not valid is not totally complete. The default is
+-\&\fB\-mno\-tail\-call\fR.
+-.IP "\fB\-mcomplex\-addr\fR" 4
+-.IX Item "-mcomplex-addr"
+-.PD 0
+-.IP "\fB\-mno\-complex\-addr\fR" 4
+-.IX Item "-mno-complex-addr"
+-.PD
+-Assume (or do not assume) that the use of a complex addressing mode is a
+-win on this implementation of the i960. Complex addressing modes may not
+-be worthwhile on the K\-series, but they definitely are on the C\-series.
+-The default is currently \fB\-mcomplex\-addr\fR for all processors except
+-the \s-1CB\s0 and \s-1CC\s0.
+-.IP "\fB\-mcode\-align\fR" 4
+-.IX Item "-mcode-align"
+-.PD 0
+-.IP "\fB\-mno\-code\-align\fR" 4
+-.IX Item "-mno-code-align"
+-.PD
+-Align code to 8\-byte boundaries for faster fetching (or don't bother).
+-Currently turned on by default for C\-series implementations only.
+-.IP "\fB\-mic\-compat\fR" 4
+-.IX Item "-mic-compat"
+-.PD 0
+-.IP "\fB\-mic2.0\-compat\fR" 4
+-.IX Item "-mic2.0-compat"
+-.IP "\fB\-mic3.0\-compat\fR" 4
+-.IX Item "-mic3.0-compat"
+-.PD
+-Enable compatibility with iC960 v2.0 or v3.0.
+-.IP "\fB\-masm\-compat\fR" 4
+-.IX Item "-masm-compat"
+-.PD 0
+-.IP "\fB\-mintel\-asm\fR" 4
+-.IX Item "-mintel-asm"
+-.PD
+-Enable compatibility with the iC960 assembler.
+-.IP "\fB\-mstrict\-align\fR" 4
+-.IX Item "-mstrict-align"
+-.PD 0
+-.IP "\fB\-mno\-strict\-align\fR" 4
+-.IX Item "-mno-strict-align"
+-.PD
+-Do not permit (do permit) unaligned accesses.
+-.IP "\fB\-mold\-align\fR" 4
+-.IX Item "-mold-align"
+-Enable structure-alignment compatibility with Intel's gcc release version
+-1.3 (based on gcc 1.37). This option implies \fB\-mstrict\-align\fR.
+-.IP "\fB\-mlong\-double\-64\fR" 4
+-.IX Item "-mlong-double-64"
+-Implement type \fBlong double\fR as 64\-bit floating point numbers.
+-Without the option \fBlong double\fR is implemented by 80\-bit
+-floating point numbers. The only reason we have it because there is
+-no 128\-bit \fBlong double\fR support in \fBfp\-bit.c\fR yet. So it
+-is only useful for people using soft-float targets. Otherwise, we
+-should recommend against use of it.
+-.PP
+-\fI\s-1DEC\s0 Alpha Options\fR
+-.IX Subsection "DEC Alpha Options"
+-.PP
+-These \fB\-m\fR options are defined for the \s-1DEC\s0 Alpha implementations:
+-.IP "\fB\-mno\-soft\-float\fR" 4
+-.IX Item "-mno-soft-float"
+-.PD 0
+-.IP "\fB\-msoft\-float\fR" 4
+-.IX Item "-msoft-float"
+-.PD
+-Use (do not use) the hardware floating-point instructions for
+-floating-point operations. When \fB\-msoft\-float\fR is specified,
+-functions in \fIlibgcc.a\fR will be used to perform floating-point
+-operations. Unless they are replaced by routines that emulate the
+-floating-point operations, or compiled in such a way as to call such
+-emulations routines, these routines will issue floating-point
+-operations. If you are compiling for an Alpha without floating-point
+-operations, you must ensure that the library is built so as not to call
+-them.
+-.Sp
+-Note that Alpha implementations without floating-point operations are
+-required to have floating-point registers.
+-.IP "\fB\-mfp\-reg\fR" 4
+-.IX Item "-mfp-reg"
+-.PD 0
+-.IP "\fB\-mno\-fp\-regs\fR" 4
+-.IX Item "-mno-fp-regs"
+-.PD
+-Generate code that uses (does not use) the floating-point register set.
+-\&\fB\-mno\-fp\-regs\fR implies \fB\-msoft\-float\fR. If the floating-point
+-register set is not used, floating point operands are passed in integer
+-registers as if they were integers and floating-point results are passed
+-in \f(CW$0\fR instead of \f(CW$f0\fR. This is a non-standard calling sequence,
+-so any function with a floating-point argument or return value called by code
+-compiled with \fB\-mno\-fp\-regs\fR must also be compiled with that
+-option.
+-.Sp
+-A typical use of this option is building a kernel that does not use,
+-and hence need not save and restore, any floating-point registers.
+-.IP "\fB\-mieee\fR" 4
+-.IX Item "-mieee"
+-The Alpha architecture implements floating-point hardware optimized for
+-maximum performance. It is mostly compliant with the \s-1IEEE\s0 floating
+-point standard. However, for full compliance, software assistance is
+-required. This option generates code fully \s-1IEEE\s0 compliant code
+-\&\fIexcept\fR that the \fIinexact-flag\fR is not maintained (see below).
+-If this option is turned on, the preprocessor macro \f(CW\*(C`_IEEE_FP\*(C'\fR is
+-defined during compilation. The resulting code is less efficient but is
+-able to correctly support denormalized numbers and exceptional \s-1IEEE\s0
+-values such as not-a-number and plus/minus infinity. Other Alpha
+-compilers call this option \fB\-ieee_with_no_inexact\fR.
+-.IP "\fB\-mieee\-with\-inexact\fR" 4
+-.IX Item "-mieee-with-inexact"
+-This is like \fB\-mieee\fR except the generated code also maintains
+-the \s-1IEEE\s0 \fIinexact-flag\fR. Turning on this option causes the
+-generated code to implement fully-compliant \s-1IEEE\s0 math. In addition to
+-\&\f(CW\*(C`_IEEE_FP\*(C'\fR, \f(CW\*(C`_IEEE_FP_EXACT\*(C'\fR is defined as a preprocessor
+-macro. On some Alpha implementations the resulting code may execute
+-significantly slower than the code generated by default. Since there is
+-very little code that depends on the \fIinexact-flag\fR, you should
+-normally not specify this option. Other Alpha compilers call this
+-option \fB\-ieee_with_inexact\fR.
+-.IP "\fB\-mfp\-trap\-mode=\fR\fItrap-mode\fR" 4
+-.IX Item "-mfp-trap-mode=trap-mode"
+-This option controls what floating-point related traps are enabled.
+-Other Alpha compilers call this option \fB\-fptm\fR \fItrap-mode\fR.
+-The trap mode can be set to one of four values:
+-.RS 4
+-.IP "\fBn\fR" 4
+-.IX Item "n"
+-This is the default (normal) setting. The only traps that are enabled
+-are the ones that cannot be disabled in software (e.g., division by zero
+-trap).
+-.IP "\fBu\fR" 4
+-.IX Item "u"
+-In addition to the traps enabled by \fBn\fR, underflow traps are enabled
+-as well.
+-.IP "\fBsu\fR" 4
+-.IX Item "su"
+-Like \fBsu\fR, but the instructions are marked to be safe for software
+-completion (see Alpha architecture manual for details).
+-.IP "\fBsui\fR" 4
+-.IX Item "sui"
+-Like \fBsu\fR, but inexact traps are enabled as well.
+-.RE
+-.RS 4
+-.RE
+-.IP "\fB\-mfp\-rounding\-mode=\fR\fIrounding-mode\fR" 4
+-.IX Item "-mfp-rounding-mode=rounding-mode"
+-Selects the \s-1IEEE\s0 rounding mode. Other Alpha compilers call this option
+-\&\fB\-fprm\fR \fIrounding-mode\fR. The \fIrounding-mode\fR can be one
+-of:
+-.RS 4
+-.IP "\fBn\fR" 4
+-.IX Item "n"
+-Normal \s-1IEEE\s0 rounding mode. Floating point numbers are rounded towards
+-the nearest machine number or towards the even machine number in case
+-of a tie.
+-.IP "\fBm\fR" 4
+-.IX Item "m"
+-Round towards minus infinity.
+-.IP "\fBc\fR" 4
+-.IX Item "c"
+-Chopped rounding mode. Floating point numbers are rounded towards zero.
+-.IP "\fBd\fR" 4
+-.IX Item "d"
+-Dynamic rounding mode. A field in the floating point control register
+-(\fIfpcr\fR, see Alpha architecture reference manual) controls the
+-rounding mode in effect. The C library initializes this register for
+-rounding towards plus infinity. Thus, unless your program modifies the
+-\&\fIfpcr\fR, \fBd\fR corresponds to round towards plus infinity.
+-.RE
+-.RS 4
+-.RE
+-.IP "\fB\-mtrap\-precision=\fR\fItrap-precision\fR" 4
+-.IX Item "-mtrap-precision=trap-precision"
+-In the Alpha architecture, floating point traps are imprecise. This
+-means without software assistance it is impossible to recover from a
+-floating trap and program execution normally needs to be terminated.
+-\&\s-1GCC\s0 can generate code that can assist operating system trap handlers
+-in determining the exact location that caused a floating point trap.
+-Depending on the requirements of an application, different levels of
+-precisions can be selected:
+-.RS 4
+-.IP "\fBp\fR" 4
+-.IX Item "p"
+-Program precision. This option is the default and means a trap handler
+-can only identify which program caused a floating point exception.
+-.IP "\fBf\fR" 4
+-.IX Item "f"
+-Function precision. The trap handler can determine the function that
+-caused a floating point exception.
+-.IP "\fBi\fR" 4
+-.IX Item "i"
+-Instruction precision. The trap handler can determine the exact
+-instruction that caused a floating point exception.
+-.RE
+-.RS 4
+-.Sp
+-Other Alpha compilers provide the equivalent options called
+-\&\fB\-scope_safe\fR and \fB\-resumption_safe\fR.
+-.RE
+-.IP "\fB\-mieee\-conformant\fR" 4
+-.IX Item "-mieee-conformant"
+-This option marks the generated code as \s-1IEEE\s0 conformant. You must not
+-use this option unless you also specify \fB\-mtrap\-precision=i\fR and either
+-\&\fB\-mfp\-trap\-mode=su\fR or \fB\-mfp\-trap\-mode=sui\fR. Its only effect
+-is to emit the line \fB.eflag 48\fR in the function prologue of the
+-generated assembly file. Under \s-1DEC\s0 Unix, this has the effect that
+-IEEE-conformant math library routines will be linked in.
+-.IP "\fB\-mbuild\-constants\fR" 4
+-.IX Item "-mbuild-constants"
+-Normally \s-1GCC\s0 examines a 32\- or 64\-bit integer constant to
+-see if it can construct it from smaller constants in two or three
+-instructions. If it cannot, it will output the constant as a literal and
+-generate code to load it from the data segment at runtime.
+-.Sp
+-Use this option to require \s-1GCC\s0 to construct \fIall\fR integer constants
+-using code, even if it takes more instructions (the maximum is six).
+-.Sp
+-You would typically use this option to build a shared library dynamic
+-loader. Itself a shared library, it must relocate itself in memory
+-before it can find the variables and constants in its own data segment.
+-.IP "\fB\-malpha\-as\fR" 4
+-.IX Item "-malpha-as"
+-.PD 0
+-.IP "\fB\-mgas\fR" 4
+-.IX Item "-mgas"
+-.PD
+-Select whether to generate code to be assembled by the vendor-supplied
+-assembler (\fB\-malpha\-as\fR) or by the \s-1GNU\s0 assembler \fB\-mgas\fR.
+-.IP "\fB\-mbwx\fR" 4
+-.IX Item "-mbwx"
+-.PD 0
+-.IP "\fB\-mno\-bwx\fR" 4
+-.IX Item "-mno-bwx"
+-.IP "\fB\-mcix\fR" 4
+-.IX Item "-mcix"
+-.IP "\fB\-mno\-cix\fR" 4
+-.IX Item "-mno-cix"
+-.IP "\fB\-mfix\fR" 4
+-.IX Item "-mfix"
+-.IP "\fB\-mno\-fix\fR" 4
+-.IX Item "-mno-fix"
+-.IP "\fB\-mmax\fR" 4
+-.IX Item "-mmax"
+-.IP "\fB\-mno\-max\fR" 4
+-.IX Item "-mno-max"
+-.PD
+-Indicate whether \s-1GCC\s0 should generate code to use the optional \s-1BWX\s0,
+-\&\s-1CIX\s0, \s-1FIX\s0 and \s-1MAX\s0 instruction sets. The default is to use the instruction
+-sets supported by the \s-1CPU\s0 type specified via \fB\-mcpu=\fR option or that
+-of the \s-1CPU\s0 on which \s-1GCC\s0 was built if none was specified.
+-.IP "\fB\-mfloat\-vax\fR" 4
+-.IX Item "-mfloat-vax"
+-.PD 0
+-.IP "\fB\-mfloat\-ieee\fR" 4
+-.IX Item "-mfloat-ieee"
+-.PD
+-Generate code that uses (does not use) \s-1VAX\s0 F and G floating point
+-arithmetic instead of \s-1IEEE\s0 single and double precision.
+-.IP "\fB\-mexplicit\-relocs\fR" 4
+-.IX Item "-mexplicit-relocs"
+-.PD 0
+-.IP "\fB\-mno\-explicit\-relocs\fR" 4
+-.IX Item "-mno-explicit-relocs"
+-.PD
+-Older Alpha assemblers provided no way to generate symbol relocations
+-except via assembler macros. Use of these macros does not allow
+-optimal instruction scheduling. \s-1GNU\s0 binutils as of version 2.12
+-supports a new syntax that allows the compiler to explicitly mark
+-which relocations should apply to which instructions. This option
+-is mostly useful for debugging, as \s-1GCC\s0 detects the capabilities of
+-the assembler when it is built and sets the default accordingly.
+-.IP "\fB\-msmall\-data\fR" 4
+-.IX Item "-msmall-data"
+-.PD 0
+-.IP "\fB\-mlarge\-data\fR" 4
+-.IX Item "-mlarge-data"
+-.PD
+-When \fB\-mexplicit\-relocs\fR is in effect, static data is
+-accessed via \fIgp-relative\fR relocations. When \fB\-msmall\-data\fR
+-is used, objects 8 bytes long or smaller are placed in a \fIsmall data area\fR
+-(the \f(CW\*(C`.sdata\*(C'\fR and \f(CW\*(C`.sbss\*(C'\fR sections) and are accessed via
+-16\-bit relocations off of the \f(CW$gp\fR register. This limits the
+-size of the small data area to 64KB, but allows the variables to be
+-directly accessed via a single instruction.
+-.Sp
+-The default is \fB\-mlarge\-data\fR. With this option the data area
+-is limited to just below 2GB. Programs that require more than 2GB of
+-data must use \f(CW\*(C`malloc\*(C'\fR or \f(CW\*(C`mmap\*(C'\fR to allocate the data in the
+-heap instead of in the program's data segment.
+-.Sp
+-When generating code for shared libraries, \fB\-fpic\fR implies
+-\&\fB\-msmall\-data\fR and \fB\-fPIC\fR implies \fB\-mlarge\-data\fR.
+-.IP "\fB\-mcpu=\fR\fIcpu_type\fR" 4
+-.IX Item "-mcpu=cpu_type"
+-Set the instruction set and instruction scheduling parameters for
+-machine type \fIcpu_type\fR. You can specify either the \fB\s-1EV\s0\fR
+-style name or the corresponding chip number. \s-1GCC\s0 supports scheduling
+-parameters for the \s-1EV4\s0, \s-1EV5\s0 and \s-1EV6\s0 family of processors and will
+-choose the default values for the instruction set from the processor
+-you specify. If you do not specify a processor type, \s-1GCC\s0 will default
+-to the processor on which the compiler was built.
+-.Sp
+-Supported values for \fIcpu_type\fR are
+-.RS 4
+-.IP "\fBev4\fR" 4
+-.IX Item "ev4"
+-.PD 0
+-.IP "\fBev45\fR" 4
+-.IX Item "ev45"
+-.IP "\fB21064\fR" 4
+-.IX Item "21064"
+-.PD
+-Schedules as an \s-1EV4\s0 and has no instruction set extensions.
+-.IP "\fBev5\fR" 4
+-.IX Item "ev5"
+-.PD 0
+-.IP "\fB21164\fR" 4
+-.IX Item "21164"
+-.PD
+-Schedules as an \s-1EV5\s0 and has no instruction set extensions.
+-.IP "\fBev56\fR" 4
+-.IX Item "ev56"
+-.PD 0
+-.IP "\fB21164a\fR" 4
+-.IX Item "21164a"
+-.PD
+-Schedules as an \s-1EV5\s0 and supports the \s-1BWX\s0 extension.
+-.IP "\fBpca56\fR" 4
+-.IX Item "pca56"
+-.PD 0
+-.IP "\fB21164pc\fR" 4
+-.IX Item "21164pc"
+-.IP "\fB21164PC\fR" 4
+-.IX Item "21164PC"
+-.PD
+-Schedules as an \s-1EV5\s0 and supports the \s-1BWX\s0 and \s-1MAX\s0 extensions.
+-.IP "\fBev6\fR" 4
+-.IX Item "ev6"
+-.PD 0
+-.IP "\fB21264\fR" 4
+-.IX Item "21264"
+-.PD
+-Schedules as an \s-1EV6\s0 and supports the \s-1BWX\s0, \s-1FIX\s0, and \s-1MAX\s0 extensions.
+-.IP "\fBev67\fR" 4
+-.IX Item "ev67"
+-.PD 0
+-.IP "\fB21264a\fR" 4
+-.IX Item "21264a"
+-.PD
+-Schedules as an \s-1EV6\s0 and supports the \s-1BWX\s0, \s-1CIX\s0, \s-1FIX\s0, and \s-1MAX\s0 extensions.
+-.RE
+-.RS 4
+-.RE
+-.IP "\fB\-mtune=\fR\fIcpu_type\fR" 4
+-.IX Item "-mtune=cpu_type"
+-Set only the instruction scheduling parameters for machine type
+-\&\fIcpu_type\fR. The instruction set is not changed.
+-.IP "\fB\-mmemory\-latency=\fR\fItime\fR" 4
+-.IX Item "-mmemory-latency=time"
+-Sets the latency the scheduler should assume for typical memory
+-references as seen by the application. This number is highly
+-dependent on the memory access patterns used by the application
+-and the size of the external cache on the machine.
+-.Sp
+-Valid options for \fItime\fR are
+-.RS 4
+-.IP "\fInumber\fR" 4
+-.IX Item "number"
+-A decimal number representing clock cycles.
+-.IP "\fBL1\fR" 4
+-.IX Item "L1"
+-.PD 0
+-.IP "\fBL2\fR" 4
+-.IX Item "L2"
+-.IP "\fBL3\fR" 4
+-.IX Item "L3"
+-.IP "\fBmain\fR" 4
+-.IX Item "main"
+-.PD
+-The compiler contains estimates of the number of clock cycles for
+-``typical'' \s-1EV4\s0 & \s-1EV5\s0 hardware for the Level 1, 2 & 3 caches
+-(also called Dcache, Scache, and Bcache), as well as to main memory.
+-Note that L3 is only valid for \s-1EV5\s0.
+-.RE
+-.RS 4
+-.RE
+-.PP
+-\fI\s-1DEC\s0 Alpha/VMS Options\fR
+-.IX Subsection "DEC Alpha/VMS Options"
+-.PP
+-These \fB\-m\fR options are defined for the \s-1DEC\s0 Alpha/VMS implementations:
+-.IP "\fB\-mvms\-return\-codes\fR" 4
+-.IX Item "-mvms-return-codes"
+-Return \s-1VMS\s0 condition codes from main. The default is to return \s-1POSIX\s0
+-style condition (e.g. error) codes.
+-.PP
+-\fIH8/300 Options\fR
+-.IX Subsection "H8/300 Options"
+-.PP
+-These \fB\-m\fR options are defined for the H8/300 implementations:
+-.IP "\fB\-mrelax\fR" 4
+-.IX Item "-mrelax"
+-Shorten some address references at link time, when possible; uses the
+-linker option \fB\-relax\fR.
+-.IP "\fB\-mh\fR" 4
+-.IX Item "-mh"
+-Generate code for the H8/300H.
+-.IP "\fB\-ms\fR" 4
+-.IX Item "-ms"
+-Generate code for the H8S.
+-.IP "\fB\-mn\fR" 4
+-.IX Item "-mn"
+-Generate code for the H8S and H8/300H in the normal mode. This switch
+-must be used either with \-mh or \-ms.
+-.IP "\fB\-ms2600\fR" 4
+-.IX Item "-ms2600"
+-Generate code for the H8S/2600. This switch must be used with \fB\-ms\fR.
+-.IP "\fB\-mint32\fR" 4
+-.IX Item "-mint32"
+-Make \f(CW\*(C`int\*(C'\fR data 32 bits by default.
+-.IP "\fB\-malign\-300\fR" 4
+-.IX Item "-malign-300"
+-On the H8/300H and H8S, use the same alignment rules as for the H8/300.
+-The default for the H8/300H and H8S is to align longs and floats on 4
+-byte boundaries.
+-\&\fB\-malign\-300\fR causes them to be aligned on 2 byte boundaries.
+-This option has no effect on the H8/300.
+-.PP
+-\fI\s-1SH\s0 Options\fR
+-.IX Subsection "SH Options"
+-.PP
+-These \fB\-m\fR options are defined for the \s-1SH\s0 implementations:
+-.IP "\fB\-m1\fR" 4
+-.IX Item "-m1"
+-Generate code for the \s-1SH1\s0.
+-.IP "\fB\-m2\fR" 4
+-.IX Item "-m2"
+-Generate code for the \s-1SH2\s0.
+-.IP "\fB\-m3\fR" 4
+-.IX Item "-m3"
+-Generate code for the \s-1SH3\s0.
+-.IP "\fB\-m3e\fR" 4
+-.IX Item "-m3e"
+-Generate code for the SH3e.
+-.IP "\fB\-m4\-nofpu\fR" 4
+-.IX Item "-m4-nofpu"
+-Generate code for the \s-1SH4\s0 without a floating-point unit.
+-.IP "\fB\-m4\-single\-only\fR" 4
+-.IX Item "-m4-single-only"
+-Generate code for the \s-1SH4\s0 with a floating-point unit that only
+-supports single-precision arithmetic.
+-.IP "\fB\-m4\-single\fR" 4
+-.IX Item "-m4-single"
+-Generate code for the \s-1SH4\s0 assuming the floating-point unit is in
+-single-precision mode by default.
+-.IP "\fB\-m4\fR" 4
+-.IX Item "-m4"
+-Generate code for the \s-1SH4\s0.
+-.IP "\fB\-mb\fR" 4
+-.IX Item "-mb"
+-Compile code for the processor in big endian mode.
+-.IP "\fB\-ml\fR" 4
+-.IX Item "-ml"
+-Compile code for the processor in little endian mode.
+-.IP "\fB\-mdalign\fR" 4
+-.IX Item "-mdalign"
+-Align doubles at 64\-bit boundaries. Note that this changes the calling
+-conventions, and thus some functions from the standard C library will
+-not work unless you recompile it first with \fB\-mdalign\fR.
+-.IP "\fB\-mrelax\fR" 4
+-.IX Item "-mrelax"
+-Shorten some address references at link time, when possible; uses the
+-linker option \fB\-relax\fR.
+-.IP "\fB\-mbigtable\fR" 4
+-.IX Item "-mbigtable"
+-Use 32\-bit offsets in \f(CW\*(C`switch\*(C'\fR tables. The default is to use
+-16\-bit offsets.
+-.IP "\fB\-mfmovd\fR" 4
+-.IX Item "-mfmovd"
+-Enable the use of the instruction \f(CW\*(C`fmovd\*(C'\fR.
+-.IP "\fB\-mhitachi\fR" 4
+-.IX Item "-mhitachi"
+-Comply with the calling conventions defined by Renesas.
+-.IP "\fB\-mnomacsave\fR" 4
+-.IX Item "-mnomacsave"
+-Mark the \f(CW\*(C`MAC\*(C'\fR register as call\-clobbered, even if
+-\&\fB\-mhitachi\fR is given.
+-.IP "\fB\-mieee\fR" 4
+-.IX Item "-mieee"
+-Increase IEEE-compliance of floating-point code.
+-.IP "\fB\-misize\fR" 4
+-.IX Item "-misize"
+-Dump instruction size and location in the assembly code.
+-.IP "\fB\-mpadstruct\fR" 4
+-.IX Item "-mpadstruct"
+-This option is deprecated. It pads structures to multiple of 4 bytes,
+-which is incompatible with the \s-1SH\s0 \s-1ABI\s0.
+-.IP "\fB\-mspace\fR" 4
+-.IX Item "-mspace"
+-Optimize for space instead of speed. Implied by \fB\-Os\fR.
+-.IP "\fB\-mprefergot\fR" 4
+-.IX Item "-mprefergot"
+-When generating position-independent code, emit function calls using
+-the Global Offset Table instead of the Procedure Linkage Table.
+-.IP "\fB\-musermode\fR" 4
+-.IX Item "-musermode"
+-Generate a library function call to invalidate instruction cache
+-entries, after fixing up a trampoline. This library function call
+-doesn't assume it can write to the whole memory address space. This
+-is the default when the target is \f(CW\*(C`sh\-*\-linux*\*(C'\fR.
+-.PP
+-\fIOptions for System V\fR
+-.IX Subsection "Options for System V"
+-.PP
+-These additional options are available on System V Release 4 for
+-compatibility with other compilers on those systems:
+-.IP "\fB\-G\fR" 4
+-.IX Item "-G"
+-Create a shared object.
+-It is recommended that \fB\-symbolic\fR or \fB\-shared\fR be used instead.
+-.IP "\fB\-Qy\fR" 4
+-.IX Item "-Qy"
+-Identify the versions of each tool used by the compiler, in a
+-\&\f(CW\*(C`.ident\*(C'\fR assembler directive in the output.
+-.IP "\fB\-Qn\fR" 4
+-.IX Item "-Qn"
+-Refrain from adding \f(CW\*(C`.ident\*(C'\fR directives to the output file (this is
+-the default).
+-.IP "\fB\-YP,\fR\fIdirs\fR" 4
+-.IX Item "-YP,dirs"
+-Search the directories \fIdirs\fR, and no others, for libraries
+-specified with \fB\-l\fR.
+-.IP "\fB\-Ym,\fR\fIdir\fR" 4
+-.IX Item "-Ym,dir"
+-Look in the directory \fIdir\fR to find the M4 preprocessor.
+-The assembler uses this option.
+-.PP
+-\fITMS320C3x/C4x Options\fR
+-.IX Subsection "TMS320C3x/C4x Options"
+-.PP
+-These \fB\-m\fR options are defined for TMS320C3x/C4x implementations:
+-.IP "\fB\-mcpu=\fR\fIcpu_type\fR" 4
+-.IX Item "-mcpu=cpu_type"
+-Set the instruction set, register set, and instruction scheduling
+-parameters for machine type \fIcpu_type\fR. Supported values for
+-\&\fIcpu_type\fR are \fBc30\fR, \fBc31\fR, \fBc32\fR, \fBc40\fR, and
+-\&\fBc44\fR. The default is \fBc40\fR to generate code for the
+-\&\s-1TMS320C40\s0.
+-.IP "\fB\-mbig\-memory\fR" 4
+-.IX Item "-mbig-memory"
+-.PD 0
+-.IP "\fB\-mbig\fR" 4
+-.IX Item "-mbig"
+-.IP "\fB\-msmall\-memory\fR" 4
+-.IX Item "-msmall-memory"
+-.IP "\fB\-msmall\fR" 4
+-.IX Item "-msmall"
+-.PD
+-Generates code for the big or small memory model. The small memory
+-model assumed that all data fits into one 64K word page. At run-time
+-the data page (\s-1DP\s0) register must be set to point to the 64K page
+-containing the .bss and .data program sections. The big memory model is
+-the default and requires reloading of the \s-1DP\s0 register for every direct
+-memory access.
+-.IP "\fB\-mbk\fR" 4
+-.IX Item "-mbk"
+-.PD 0
+-.IP "\fB\-mno\-bk\fR" 4
+-.IX Item "-mno-bk"
+-.PD
+-Allow (disallow) allocation of general integer operands into the block
+-count register \s-1BK\s0.
+-.IP "\fB\-mdb\fR" 4
+-.IX Item "-mdb"
+-.PD 0
+-.IP "\fB\-mno\-db\fR" 4
+-.IX Item "-mno-db"
+-.PD
+-Enable (disable) generation of code using decrement and branch,
+-DBcond(D), instructions. This is enabled by default for the C4x. To be
+-on the safe side, this is disabled for the C3x, since the maximum
+-iteration count on the C3x is 2^{23 + 1} (but who iterates loops more than
+-2^{23} times on the C3x?). Note that \s-1GCC\s0 will try to reverse a loop so
+-that it can utilize the decrement and branch instruction, but will give
+-up if there is more than one memory reference in the loop. Thus a loop
+-where the loop counter is decremented can generate slightly more
+-efficient code, in cases where the \s-1RPTB\s0 instruction cannot be utilized.
+-.IP "\fB\-mdp\-isr\-reload\fR" 4
+-.IX Item "-mdp-isr-reload"
+-.PD 0
+-.IP "\fB\-mparanoid\fR" 4
+-.IX Item "-mparanoid"
+-.PD
+-Force the \s-1DP\s0 register to be saved on entry to an interrupt service
+-routine (\s-1ISR\s0), reloaded to point to the data section, and restored on
+-exit from the \s-1ISR\s0. This should not be required unless someone has
+-violated the small memory model by modifying the \s-1DP\s0 register, say within
+-an object library.
+-.IP "\fB\-mmpyi\fR" 4
+-.IX Item "-mmpyi"
+-.PD 0
+-.IP "\fB\-mno\-mpyi\fR" 4
+-.IX Item "-mno-mpyi"
+-.PD
+-For the C3x use the 24\-bit \s-1MPYI\s0 instruction for integer multiplies
+-instead of a library call to guarantee 32\-bit results. Note that if one
+-of the operands is a constant, then the multiplication will be performed
+-using shifts and adds. If the \fB\-mmpyi\fR option is not specified for the C3x,
+-then squaring operations are performed inline instead of a library call.
+-.IP "\fB\-mfast\-fix\fR" 4
+-.IX Item "-mfast-fix"
+-.PD 0
+-.IP "\fB\-mno\-fast\-fix\fR" 4
+-.IX Item "-mno-fast-fix"
+-.PD
+-The C3x/C4x \s-1FIX\s0 instruction to convert a floating point value to an
+-integer value chooses the nearest integer less than or equal to the
+-floating point value rather than to the nearest integer. Thus if the
+-floating point number is negative, the result will be incorrectly
+-truncated an additional code is necessary to detect and correct this
+-case. This option can be used to disable generation of the additional
+-code required to correct the result.
+-.IP "\fB\-mrptb\fR" 4
+-.IX Item "-mrptb"
+-.PD 0
+-.IP "\fB\-mno\-rptb\fR" 4
+-.IX Item "-mno-rptb"
+-.PD
+-Enable (disable) generation of repeat block sequences using the \s-1RPTB\s0
+-instruction for zero overhead looping. The \s-1RPTB\s0 construct is only used
+-for innermost loops that do not call functions or jump across the loop
+-boundaries. There is no advantage having nested \s-1RPTB\s0 loops due to the
+-overhead required to save and restore the \s-1RC\s0, \s-1RS\s0, and \s-1RE\s0 registers.
+-This is enabled by default with \fB\-O2\fR.
+-.IP "\fB\-mrpts=\fR\fIcount\fR" 4
+-.IX Item "-mrpts=count"
+-.PD 0
+-.IP "\fB\-mno\-rpts\fR" 4
+-.IX Item "-mno-rpts"
+-.PD
+-Enable (disable) the use of the single instruction repeat instruction
+-\&\s-1RPTS\s0. If a repeat block contains a single instruction, and the loop
+-count can be guaranteed to be less than the value \fIcount\fR, \s-1GCC\s0 will
+-emit a \s-1RPTS\s0 instruction instead of a \s-1RPTB\s0. If no value is specified,
+-then a \s-1RPTS\s0 will be emitted even if the loop count cannot be determined
+-at compile time. Note that the repeated instruction following \s-1RPTS\s0 does
+-not have to be reloaded from memory each iteration, thus freeing up the
+-\&\s-1CPU\s0 buses for operands. However, since interrupts are blocked by this
+-instruction, it is disabled by default.
+-.IP "\fB\-mloop\-unsigned\fR" 4
+-.IX Item "-mloop-unsigned"
+-.PD 0
+-.IP "\fB\-mno\-loop\-unsigned\fR" 4
+-.IX Item "-mno-loop-unsigned"
+-.PD
+-The maximum iteration count when using \s-1RPTS\s0 and \s-1RPTB\s0 (and \s-1DB\s0 on the C40)
+-is 2^{31 + 1} since these instructions test if the iteration count is
+-negative to terminate the loop. If the iteration count is unsigned
+-there is a possibility than the 2^{31 + 1} maximum iteration count may be
+-exceeded. This switch allows an unsigned iteration count.
+-.IP "\fB\-mti\fR" 4
+-.IX Item "-mti"
+-Try to emit an assembler syntax that the \s-1TI\s0 assembler (asm30) is happy
+-with. This also enforces compatibility with the \s-1API\s0 employed by the \s-1TI\s0
+-C3x C compiler. For example, long doubles are passed as structures
+-rather than in floating point registers.
+-.IP "\fB\-mregparm\fR" 4
+-.IX Item "-mregparm"
+-.PD 0
+-.IP "\fB\-mmemparm\fR" 4
+-.IX Item "-mmemparm"
+-.PD
+-Generate code that uses registers (stack) for passing arguments to functions.
+-By default, arguments are passed in registers where possible rather
+-than by pushing arguments on to the stack.
+-.IP "\fB\-mparallel\-insns\fR" 4
+-.IX Item "-mparallel-insns"
+-.PD 0
+-.IP "\fB\-mno\-parallel\-insns\fR" 4
+-.IX Item "-mno-parallel-insns"
+-.PD
+-Allow the generation of parallel instructions. This is enabled by
+-default with \fB\-O2\fR.
+-.IP "\fB\-mparallel\-mpy\fR" 4
+-.IX Item "-mparallel-mpy"
+-.PD 0
+-.IP "\fB\-mno\-parallel\-mpy\fR" 4
+-.IX Item "-mno-parallel-mpy"
+-.PD
+-Allow the generation of MPY||ADD and MPY||SUB parallel instructions,
+-provided \fB\-mparallel\-insns\fR is also specified. These instructions have
+-tight register constraints which can pessimize the code generation
+-of large functions.
+-.PP
+-\fIV850 Options\fR
+-.IX Subsection "V850 Options"
+-.PP
+-These \fB\-m\fR options are defined for V850 implementations:
+-.IP "\fB\-mlong\-calls\fR" 4
+-.IX Item "-mlong-calls"
+-.PD 0
+-.IP "\fB\-mno\-long\-calls\fR" 4
+-.IX Item "-mno-long-calls"
+-.PD
+-Treat all calls as being far away (near). If calls are assumed to be
+-far away, the compiler will always load the functions address up into a
+-register, and call indirect through the pointer.
+-.IP "\fB\-mno\-ep\fR" 4
+-.IX Item "-mno-ep"
+-.PD 0
+-.IP "\fB\-mep\fR" 4
+-.IX Item "-mep"
+-.PD
+-Do not optimize (do optimize) basic blocks that use the same index
+-pointer 4 or more times to copy pointer into the \f(CW\*(C`ep\*(C'\fR register, and
+-use the shorter \f(CW\*(C`sld\*(C'\fR and \f(CW\*(C`sst\*(C'\fR instructions. The \fB\-mep\fR
+-option is on by default if you optimize.
+-.IP "\fB\-mno\-prolog\-function\fR" 4
+-.IX Item "-mno-prolog-function"
+-.PD 0
+-.IP "\fB\-mprolog\-function\fR" 4
+-.IX Item "-mprolog-function"
+-.PD
+-Do not use (do use) external functions to save and restore registers
+-at the prologue and epilogue of a function. The external functions
+-are slower, but use less code space if more than one function saves
+-the same number of registers. The \fB\-mprolog\-function\fR option
+-is on by default if you optimize.
+-.IP "\fB\-mspace\fR" 4
+-.IX Item "-mspace"
+-Try to make the code as small as possible. At present, this just turns
+-on the \fB\-mep\fR and \fB\-mprolog\-function\fR options.
+-.IP "\fB\-mtda=\fR\fIn\fR" 4
+-.IX Item "-mtda=n"
+-Put static or global variables whose size is \fIn\fR bytes or less into
+-the tiny data area that register \f(CW\*(C`ep\*(C'\fR points to. The tiny data
+-area can hold up to 256 bytes in total (128 bytes for byte references).
+-.IP "\fB\-msda=\fR\fIn\fR" 4
+-.IX Item "-msda=n"
+-Put static or global variables whose size is \fIn\fR bytes or less into
+-the small data area that register \f(CW\*(C`gp\*(C'\fR points to. The small data
+-area can hold up to 64 kilobytes.
+-.IP "\fB\-mzda=\fR\fIn\fR" 4
+-.IX Item "-mzda=n"
+-Put static or global variables whose size is \fIn\fR bytes or less into
+-the first 32 kilobytes of memory.
+-.IP "\fB\-mv850\fR" 4
+-.IX Item "-mv850"
+-Specify that the target processor is the V850.
+-.IP "\fB\-mbig\-switch\fR" 4
+-.IX Item "-mbig-switch"
+-Generate code suitable for big switch tables. Use this option only if
+-the assembler/linker complain about out of range branches within a switch
+-table.
+-.IP "\fB\-mapp\-regs\fR" 4
+-.IX Item "-mapp-regs"
+-This option will cause r2 and r5 to be used in the code generated by
+-the compiler. This setting is the default.
+-.IP "\fB\-mno\-app\-regs\fR" 4
+-.IX Item "-mno-app-regs"
+-This option will cause r2 and r5 to be treated as fixed registers.
+-.IP "\fB\-mv850e\fR" 4
+-.IX Item "-mv850e"
+-Specify that the target processor is the V850E. The preprocessor
+-constant \fB_\|_v850e_\|_\fR will be defined if this option is used.
+-.Sp
+-If neither \fB\-mv850\fR nor \fB\-mv850e\fR are defined
+-then a default target processor will be chosen and the relevant
+-\&\fB_\|_v850*_\|_\fR preprocessor constant will be defined.
+-.Sp
+-The preprocessor constants \fB_\|_v850\fR and \fB_\|_v851_\|_\fR are always
+-defined, regardless of which processor variant is the target.
+-.IP "\fB\-mdisable\-callt\fR" 4
+-.IX Item "-mdisable-callt"
+-This option will suppress generation of the \s-1CALLT\s0 instruction for the
+-v850e flavors of the v850 architecture. The default is
+-\&\fB\-mno\-disable\-callt\fR which allows the \s-1CALLT\s0 instruction to be used.
+-.PP
+-\fI\s-1ARC\s0 Options\fR
+-.IX Subsection "ARC Options"
+-.PP
+-These options are defined for \s-1ARC\s0 implementations:
+-.IP "\fB\-EL\fR" 4
+-.IX Item "-EL"
+-Compile code for little endian mode. This is the default.
+-.IP "\fB\-EB\fR" 4
+-.IX Item "-EB"
+-Compile code for big endian mode.
+-.IP "\fB\-mmangle\-cpu\fR" 4
+-.IX Item "-mmangle-cpu"
+-Prepend the name of the cpu to all public symbol names.
+-In multiple-processor systems, there are many \s-1ARC\s0 variants with different
+-instruction and register set characteristics. This flag prevents code
+-compiled for one cpu to be linked with code compiled for another.
+-No facility exists for handling variants that are ``almost identical''.
+-This is an all or nothing option.
+-.IP "\fB\-mcpu=\fR\fIcpu\fR" 4
+-.IX Item "-mcpu=cpu"
+-Compile code for \s-1ARC\s0 variant \fIcpu\fR.
+-Which variants are supported depend on the configuration.
+-All variants support \fB\-mcpu=base\fR, this is the default.
+-.IP "\fB\-mtext=\fR\fItext-section\fR" 4
+-.IX Item "-mtext=text-section"
+-.PD 0
+-.IP "\fB\-mdata=\fR\fIdata-section\fR" 4
+-.IX Item "-mdata=data-section"
+-.IP "\fB\-mrodata=\fR\fIreadonly-data-section\fR" 4
+-.IX Item "-mrodata=readonly-data-section"
+-.PD
+-Put functions, data, and readonly data in \fItext-section\fR,
+-\&\fIdata-section\fR, and \fIreadonly-data-section\fR respectively
+-by default. This can be overridden with the \f(CW\*(C`section\*(C'\fR attribute.
+-.PP
+-\fI\s-1NS32K\s0 Options\fR
+-.IX Subsection "NS32K Options"
+-.PP
+-These are the \fB\-m\fR options defined for the 32000 series. The default
+-values for these options depends on which style of 32000 was selected when
+-the compiler was configured; the defaults for the most common choices are
+-given below.
+-.IP "\fB\-m32032\fR" 4
+-.IX Item "-m32032"
+-.PD 0
+-.IP "\fB\-m32032\fR" 4
+-.IX Item "-m32032"
+-.PD
+-Generate output for a 32032. This is the default
+-when the compiler is configured for 32032 and 32016 based systems.
+-.IP "\fB\-m32332\fR" 4
+-.IX Item "-m32332"
+-.PD 0
+-.IP "\fB\-m32332\fR" 4
+-.IX Item "-m32332"
+-.PD
+-Generate output for a 32332. This is the default
+-when the compiler is configured for 32332\-based systems.
+-.IP "\fB\-m32532\fR" 4
+-.IX Item "-m32532"
+-.PD 0
+-.IP "\fB\-m32532\fR" 4
+-.IX Item "-m32532"
+-.PD
+-Generate output for a 32532. This is the default
+-when the compiler is configured for 32532\-based systems.
+-.IP "\fB\-m32081\fR" 4
+-.IX Item "-m32081"
+-Generate output containing 32081 instructions for floating point.
+-This is the default for all systems.
+-.IP "\fB\-m32381\fR" 4
+-.IX Item "-m32381"
+-Generate output containing 32381 instructions for floating point. This
+-also implies \fB\-m32081\fR. The 32381 is only compatible with the 32332
+-and 32532 cpus. This is the default for the pc532\-netbsd configuration.
+-.IP "\fB\-mmulti\-add\fR" 4
+-.IX Item "-mmulti-add"
+-Try and generate multiply-add floating point instructions \f(CW\*(C`polyF\*(C'\fR
+-and \f(CW\*(C`dotF\*(C'\fR. This option is only available if the \fB\-m32381\fR
+-option is in effect. Using these instructions requires changes to
+-register allocation which generally has a negative impact on
+-performance. This option should only be enabled when compiling code
+-particularly likely to make heavy use of multiply-add instructions.
+-.IP "\fB\-mnomulti\-add\fR" 4
+-.IX Item "-mnomulti-add"
+-Do not try and generate multiply-add floating point instructions
+-\&\f(CW\*(C`polyF\*(C'\fR and \f(CW\*(C`dotF\*(C'\fR. This is the default on all platforms.
+-.IP "\fB\-msoft\-float\fR" 4
+-.IX Item "-msoft-float"
+-Generate output containing library calls for floating point.
+-\&\fBWarning:\fR the requisite libraries may not be available.
+-.IP "\fB\-mieee\-compare\fR" 4
+-.IX Item "-mieee-compare"
+-.PD 0
+-.IP "\fB\-mno\-ieee\-compare\fR" 4
+-.IX Item "-mno-ieee-compare"
+-.PD
+-Control whether or not the compiler uses \s-1IEEE\s0 floating point
+-comparisons. These handle correctly the case where the result of a
+-comparison is unordered.
+-\&\fBWarning:\fR the requisite kernel support may not be available.
+-.IP "\fB\-mnobitfield\fR" 4
+-.IX Item "-mnobitfield"
+-Do not use the bit-field instructions. On some machines it is faster to
+-use shifting and masking operations. This is the default for the pc532.
+-.IP "\fB\-mbitfield\fR" 4
+-.IX Item "-mbitfield"
+-Do use the bit-field instructions. This is the default for all platforms
+-except the pc532.
+-.IP "\fB\-mrtd\fR" 4
+-.IX Item "-mrtd"
+-Use a different function-calling convention, in which functions
+-that take a fixed number of arguments return pop their
+-arguments on return with the \f(CW\*(C`ret\*(C'\fR instruction.
+-.Sp
+-This calling convention is incompatible with the one normally
+-used on Unix, so you cannot use it if you need to call libraries
+-compiled with the Unix compiler.
+-.Sp
+-Also, you must provide function prototypes for all functions that
+-take variable numbers of arguments (including \f(CW\*(C`printf\*(C'\fR);
+-otherwise incorrect code will be generated for calls to those
+-functions.
+-.Sp
+-In addition, seriously incorrect code will result if you call a
+-function with too many arguments. (Normally, extra arguments are
+-harmlessly ignored.)
+-.Sp
+-This option takes its name from the 680x0 \f(CW\*(C`rtd\*(C'\fR instruction.
+-.IP "\fB\-mregparam\fR" 4
+-.IX Item "-mregparam"
+-Use a different function-calling convention where the first two arguments
+-are passed in registers.
+-.Sp
+-This calling convention is incompatible with the one normally
+-used on Unix, so you cannot use it if you need to call libraries
+-compiled with the Unix compiler.
+-.IP "\fB\-mnoregparam\fR" 4
+-.IX Item "-mnoregparam"
+-Do not pass any arguments in registers. This is the default for all
+-targets.
+-.IP "\fB\-msb\fR" 4
+-.IX Item "-msb"
+-It is \s-1OK\s0 to use the sb as an index register which is always loaded with
+-zero. This is the default for the pc532\-netbsd target.
+-.IP "\fB\-mnosb\fR" 4
+-.IX Item "-mnosb"
+-The sb register is not available for use or has not been initialized to
+-zero by the run time system. This is the default for all targets except
+-the pc532\-netbsd. It is also implied whenever \fB\-mhimem\fR or
+-\&\fB\-fpic\fR is set.
+-.IP "\fB\-mhimem\fR" 4
+-.IX Item "-mhimem"
+-Many ns32000 series addressing modes use displacements of up to 512MB.
+-If an address is above 512MB then displacements from zero can not be used.
+-This option causes code to be generated which can be loaded above 512MB.
+-This may be useful for operating systems or \s-1ROM\s0 code.
+-.IP "\fB\-mnohimem\fR" 4
+-.IX Item "-mnohimem"
+-Assume code will be loaded in the first 512MB of virtual address space.
+-This is the default for all platforms.
+-.PP
+-\fI\s-1AVR\s0 Options\fR
+-.IX Subsection "AVR Options"
+-.PP
+-These options are defined for \s-1AVR\s0 implementations:
+-.IP "\fB\-mmcu=\fR\fImcu\fR" 4
+-.IX Item "-mmcu=mcu"
+-Specify \s-1ATMEL\s0 \s-1AVR\s0 instruction set or \s-1MCU\s0 type.
+-.Sp
+-Instruction set avr1 is for the minimal \s-1AVR\s0 core, not supported by the C
+-compiler, only for assembler programs (\s-1MCU\s0 types: at90s1200, attiny10,
+-attiny11, attiny12, attiny15, attiny28).
+-.Sp
+-Instruction set avr2 (default) is for the classic \s-1AVR\s0 core with up to
+-8K program memory space (\s-1MCU\s0 types: at90s2313, at90s2323, attiny22,
+-at90s2333, at90s2343, at90s4414, at90s4433, at90s4434, at90s8515,
+-at90c8534, at90s8535).
+-.Sp
+-Instruction set avr3 is for the classic \s-1AVR\s0 core with up to 128K program
+-memory space (\s-1MCU\s0 types: atmega103, atmega603, at43usb320, at76c711).
+-.Sp
+-Instruction set avr4 is for the enhanced \s-1AVR\s0 core with up to 8K program
+-memory space (\s-1MCU\s0 types: atmega8, atmega83, atmega85).
+-.Sp
+-Instruction set avr5 is for the enhanced \s-1AVR\s0 core with up to 128K program
+-memory space (\s-1MCU\s0 types: atmega16, atmega161, atmega163, atmega32, atmega323,
+-atmega64, atmega128, at43usb355, at94k).
+-.IP "\fB\-msize\fR" 4
+-.IX Item "-msize"
+-Output instruction sizes to the asm file.
+-.IP "\fB\-minit\-stack=\fR\fIN\fR" 4
+-.IX Item "-minit-stack=N"
+-Specify the initial stack address, which may be a symbol or numeric value,
+-\&\fB_\|_stack\fR is the default.
+-.IP "\fB\-mno\-interrupts\fR" 4
+-.IX Item "-mno-interrupts"
+-Generated code is not compatible with hardware interrupts.
+-Code size will be smaller.
+-.IP "\fB\-mcall\-prologues\fR" 4
+-.IX Item "-mcall-prologues"
+-Functions prologues/epilogues expanded as call to appropriate
+-subroutines. Code size will be smaller.
+-.IP "\fB\-mno\-tablejump\fR" 4
+-.IX Item "-mno-tablejump"
+-Do not generate tablejump insns which sometimes increase code size.
+-.IP "\fB\-mtiny\-stack\fR" 4
+-.IX Item "-mtiny-stack"
+-Change only the low 8 bits of the stack pointer.
+-.PP
+-\fIMCore Options\fR
+-.IX Subsection "MCore Options"
+-.PP
+-These are the \fB\-m\fR options defined for the Motorola M*Core
+-processors.
+-.IP "\fB\-mhardlit\fR" 4
+-.IX Item "-mhardlit"
+-.PD 0
+-.IP "\fB\-mno\-hardlit\fR" 4
+-.IX Item "-mno-hardlit"
+-.PD
+-Inline constants into the code stream if it can be done in two
+-instructions or less.
+-.IP "\fB\-mdiv\fR" 4
+-.IX Item "-mdiv"
+-.PD 0
+-.IP "\fB\-mno\-div\fR" 4
+-.IX Item "-mno-div"
+-.PD
+-Use the divide instruction. (Enabled by default).
+-.IP "\fB\-mrelax\-immediate\fR" 4
+-.IX Item "-mrelax-immediate"
+-.PD 0
+-.IP "\fB\-mno\-relax\-immediate\fR" 4
+-.IX Item "-mno-relax-immediate"
+-.PD
+-Allow arbitrary sized immediates in bit operations.
+-.IP "\fB\-mwide\-bitfields\fR" 4
+-.IX Item "-mwide-bitfields"
+-.PD 0
+-.IP "\fB\-mno\-wide\-bitfields\fR" 4
+-.IX Item "-mno-wide-bitfields"
+-.PD
+-Always treat bit-fields as int\-sized.
+-.IP "\fB\-m4byte\-functions\fR" 4
+-.IX Item "-m4byte-functions"
+-.PD 0
+-.IP "\fB\-mno\-4byte\-functions\fR" 4
+-.IX Item "-mno-4byte-functions"
+-.PD
+-Force all functions to be aligned to a four byte boundary.
+-.IP "\fB\-mcallgraph\-data\fR" 4
+-.IX Item "-mcallgraph-data"
+-.PD 0
+-.IP "\fB\-mno\-callgraph\-data\fR" 4
+-.IX Item "-mno-callgraph-data"
+-.PD
+-Emit callgraph information.
+-.IP "\fB\-mslow\-bytes\fR" 4
+-.IX Item "-mslow-bytes"
+-.PD 0
+-.IP "\fB\-mno\-slow\-bytes\fR" 4
+-.IX Item "-mno-slow-bytes"
+-.PD
+-Prefer word access when reading byte quantities.
+-.IP "\fB\-mlittle\-endian\fR" 4
+-.IX Item "-mlittle-endian"
+-.PD 0
+-.IP "\fB\-mbig\-endian\fR" 4
+-.IX Item "-mbig-endian"
+-.PD
+-Generate code for a little endian target.
+-.IP "\fB\-m210\fR" 4
+-.IX Item "-m210"
+-.PD 0
+-.IP "\fB\-m340\fR" 4
+-.IX Item "-m340"
+-.PD
+-Generate code for the 210 processor.
+-.PP
+-\fI\s-1IA\-64\s0 Options\fR
+-.IX Subsection "IA-64 Options"
+-.PP
+-These are the \fB\-m\fR options defined for the Intel \s-1IA\-64\s0 architecture.
+-.IP "\fB\-mbig\-endian\fR" 4
+-.IX Item "-mbig-endian"
+-Generate code for a big endian target. This is the default for \s-1HP\-UX\s0.
+-.IP "\fB\-mlittle\-endian\fR" 4
+-.IX Item "-mlittle-endian"
+-Generate code for a little endian target. This is the default for \s-1AIX5\s0
+-and Linux.
+-.IP "\fB\-mgnu\-as\fR" 4
+-.IX Item "-mgnu-as"
+-.PD 0
+-.IP "\fB\-mno\-gnu\-as\fR" 4
+-.IX Item "-mno-gnu-as"
+-.PD
+-Generate (or don't) code for the \s-1GNU\s0 assembler. This is the default.
+-.IP "\fB\-mgnu\-ld\fR" 4
+-.IX Item "-mgnu-ld"
+-.PD 0
+-.IP "\fB\-mno\-gnu\-ld\fR" 4
+-.IX Item "-mno-gnu-ld"
+-.PD
+-Generate (or don't) code for the \s-1GNU\s0 linker. This is the default.
+-.IP "\fB\-mno\-pic\fR" 4
+-.IX Item "-mno-pic"
+-Generate code that does not use a global pointer register. The result
+-is not position independent code, and violates the \s-1IA\-64\s0 \s-1ABI\s0.
+-.IP "\fB\-mvolatile\-asm\-stop\fR" 4
+-.IX Item "-mvolatile-asm-stop"
+-.PD 0
+-.IP "\fB\-mno\-volatile\-asm\-stop\fR" 4
+-.IX Item "-mno-volatile-asm-stop"
+-.PD
+-Generate (or don't) a stop bit immediately before and after volatile asm
+-statements.
+-.IP "\fB\-mb\-step\fR" 4
+-.IX Item "-mb-step"
+-Generate code that works around Itanium B step errata.
+-.IP "\fB\-mregister\-names\fR" 4
+-.IX Item "-mregister-names"
+-.PD 0
+-.IP "\fB\-mno\-register\-names\fR" 4
+-.IX Item "-mno-register-names"
+-.PD
+-Generate (or don't) \fBin\fR, \fBloc\fR, and \fBout\fR register names for
+-the stacked registers. This may make assembler output more readable.
+-.IP "\fB\-mno\-sdata\fR" 4
+-.IX Item "-mno-sdata"
+-.PD 0
+-.IP "\fB\-msdata\fR" 4
+-.IX Item "-msdata"
+-.PD
+-Disable (or enable) optimizations that use the small data section. This may
+-be useful for working around optimizer bugs.
+-.IP "\fB\-mconstant\-gp\fR" 4
+-.IX Item "-mconstant-gp"
+-Generate code that uses a single constant global pointer value. This is
+-useful when compiling kernel code.
+-.IP "\fB\-mauto\-pic\fR" 4
+-.IX Item "-mauto-pic"
+-Generate code that is self\-relocatable. This implies \fB\-mconstant\-gp\fR.
+-This is useful when compiling firmware code.
+-.IP "\fB\-minline\-float\-divide\-min\-latency\fR" 4
+-.IX Item "-minline-float-divide-min-latency"
+-Generate code for inline divides of floating point values
+-using the minimum latency algorithm.
+-.IP "\fB\-minline\-float\-divide\-max\-throughput\fR" 4
+-.IX Item "-minline-float-divide-max-throughput"
+-Generate code for inline divides of floating point values
+-using the maximum throughput algorithm.
+-.IP "\fB\-minline\-int\-divide\-min\-latency\fR" 4
+-.IX Item "-minline-int-divide-min-latency"
+-Generate code for inline divides of integer values
+-using the minimum latency algorithm.
+-.IP "\fB\-minline\-int\-divide\-max\-throughput\fR" 4
+-.IX Item "-minline-int-divide-max-throughput"
+-Generate code for inline divides of integer values
+-using the maximum throughput algorithm.
+-.IP "\fB\-mno\-dwarf2\-asm\fR" 4
+-.IX Item "-mno-dwarf2-asm"
+-.PD 0
+-.IP "\fB\-mdwarf2\-asm\fR" 4
+-.IX Item "-mdwarf2-asm"
+-.PD
+-Don't (or do) generate assembler code for the \s-1DWARF2\s0 line number debugging
+-info. This may be useful when not using the \s-1GNU\s0 assembler.
+-.IP "\fB\-mfixed\-range=\fR\fIregister-range\fR" 4
+-.IX Item "-mfixed-range=register-range"
+-Generate code treating the given register range as fixed registers.
+-A fixed register is one that the register allocator can not use. This is
+-useful when compiling kernel code. A register range is specified as
+-two registers separated by a dash. Multiple register ranges can be
+-specified separated by a comma.
+-.PP
+-\fID30V Options\fR
+-.IX Subsection "D30V Options"
+-.PP
+-These \fB\-m\fR options are defined for D30V implementations:
+-.IP "\fB\-mextmem\fR" 4
+-.IX Item "-mextmem"
+-Link the \fB.text\fR, \fB.data\fR, \fB.bss\fR, \fB.strings\fR,
+-\&\fB.rodata\fR, \fB.rodata1\fR, \fB.data1\fR sections into external
+-memory, which starts at location \f(CW0x80000000\fR.
+-.IP "\fB\-mextmemory\fR" 4
+-.IX Item "-mextmemory"
+-Same as the \fB\-mextmem\fR switch.
+-.IP "\fB\-monchip\fR" 4
+-.IX Item "-monchip"
+-Link the \fB.text\fR section into onchip text memory, which starts at
+-location \f(CW0x0\fR. Also link \fB.data\fR, \fB.bss\fR,
+-\&\fB.strings\fR, \fB.rodata\fR, \fB.rodata1\fR, \fB.data1\fR sections
+-into onchip data memory, which starts at location \f(CW0x20000000\fR.
+-.IP "\fB\-mno\-asm\-optimize\fR" 4
+-.IX Item "-mno-asm-optimize"
+-.PD 0
+-.IP "\fB\-masm\-optimize\fR" 4
+-.IX Item "-masm-optimize"
+-.PD
+-Disable (enable) passing \fB\-O\fR to the assembler when optimizing.
+-The assembler uses the \fB\-O\fR option to automatically parallelize
+-adjacent short instructions where possible.
+-.IP "\fB\-mbranch\-cost=\fR\fIn\fR" 4
+-.IX Item "-mbranch-cost=n"
+-Increase the internal costs of branches to \fIn\fR. Higher costs means
+-that the compiler will issue more instructions to avoid doing a branch.
+-The default is 2.
+-.IP "\fB\-mcond\-exec=\fR\fIn\fR" 4
+-.IX Item "-mcond-exec=n"
+-Specify the maximum number of conditionally executed instructions that
+-replace a branch. The default is 4.
+-.PP
+-\fIS/390 and zSeries Options\fR
+-.IX Subsection "S/390 and zSeries Options"
+-.PP
+-These are the \fB\-m\fR options defined for the S/390 and zSeries architecture.
+-.IP "\fB\-mhard\-float\fR" 4
+-.IX Item "-mhard-float"
+-.PD 0
+-.IP "\fB\-msoft\-float\fR" 4
+-.IX Item "-msoft-float"
+-.PD
+-Use (do not use) the hardware floating-point instructions and registers
+-for floating-point operations. When \fB\-msoft\-float\fR is specified,
+-functions in \fIlibgcc.a\fR will be used to perform floating-point
+-operations. When \fB\-mhard\-float\fR is specified, the compiler
+-generates \s-1IEEE\s0 floating-point instructions. This is the default.
+-.IP "\fB\-mbackchain\fR" 4
+-.IX Item "-mbackchain"
+-.PD 0
+-.IP "\fB\-mno\-backchain\fR" 4
+-.IX Item "-mno-backchain"
+-.PD
+-Generate (or do not generate) code which maintains an explicit
+-backchain within the stack frame that points to the caller's frame.
+-This is currently needed to allow debugging. The default is to
+-generate the backchain.
+-.IP "\fB\-msmall\-exec\fR" 4
+-.IX Item "-msmall-exec"
+-.PD 0
+-.IP "\fB\-mno\-small\-exec\fR" 4
+-.IX Item "-mno-small-exec"
+-.PD
+-Generate (or do not generate) code using the \f(CW\*(C`bras\*(C'\fR instruction
+-to do subroutine calls.
+-This only works reliably if the total executable size does not
+-exceed 64k. The default is to use the \f(CW\*(C`basr\*(C'\fR instruction instead,
+-which does not have this limitation.
+-.IP "\fB\-m64\fR" 4
+-.IX Item "-m64"
+-.PD 0
+-.IP "\fB\-m31\fR" 4
+-.IX Item "-m31"
+-.PD
+-When \fB\-m31\fR is specified, generate code compliant to the
+-Linux for S/390 \s-1ABI\s0. When \fB\-m64\fR is specified, generate
+-code compliant to the Linux for zSeries \s-1ABI\s0. This allows \s-1GCC\s0 in
+-particular to generate 64\-bit instructions. For the \fBs390\fR
+-targets, the default is \fB\-m31\fR, while the \fBs390x\fR
+-targets default to \fB\-m64\fR.
+-.IP "\fB\-mmvcle\fR" 4
+-.IX Item "-mmvcle"
+-.PD 0
+-.IP "\fB\-mno\-mvcle\fR" 4
+-.IX Item "-mno-mvcle"
+-.PD
+-Generate (or do not generate) code using the \f(CW\*(C`mvcle\*(C'\fR instruction
+-to perform block moves. When \fB\-mno\-mvcle\fR is specified,
+-use a \f(CW\*(C`mvc\*(C'\fR loop instead. This is the default.
+-.IP "\fB\-mdebug\fR" 4
+-.IX Item "-mdebug"
+-.PD 0
+-.IP "\fB\-mno\-debug\fR" 4
+-.IX Item "-mno-debug"
+-.PD
+-Print (or do not print) additional debug information when compiling.
+-The default is to not print debug information.
+-.PP
+-\fI\s-1CRIS\s0 Options\fR
+-.IX Subsection "CRIS Options"
+-.PP
+-These options are defined specifically for the \s-1CRIS\s0 ports.
+-.IP "\fB\-march=\fR\fIarchitecture-type\fR" 4
+-.IX Item "-march=architecture-type"
+-.PD 0
+-.IP "\fB\-mcpu=\fR\fIarchitecture-type\fR" 4
+-.IX Item "-mcpu=architecture-type"
+-.PD
+-Generate code for the specified architecture. The choices for
+-\&\fIarchitecture-type\fR are \fBv3\fR, \fBv8\fR and \fBv10\fR for
+-respectively \s-1ETRAX\s0\ 4, \s-1ETRAX\s0\ 100, and \s-1ETRAX\s0\ 100\ \s-1LX\s0.
+-Default is \fBv0\fR except for cris\-axis\-linux\-gnu, where the default is
+-\&\fBv10\fR.
+-.IP "\fB\-mtune=\fR\fIarchitecture-type\fR" 4
+-.IX Item "-mtune=architecture-type"
+-Tune to \fIarchitecture-type\fR everything applicable about the generated
+-code, except for the \s-1ABI\s0 and the set of available instructions. The
+-choices for \fIarchitecture-type\fR are the same as for
+-\&\fB\-march=\fR\fIarchitecture-type\fR.
+-.IP "\fB\-mmax\-stack\-frame=\fR\fIn\fR" 4
+-.IX Item "-mmax-stack-frame=n"
+-Warn when the stack frame of a function exceeds \fIn\fR bytes.
+-.IP "\fB\-melinux\-stacksize=\fR\fIn\fR" 4
+-.IX Item "-melinux-stacksize=n"
+-Only available with the \fBcris-axis-aout\fR target. Arranges for
+-indications in the program to the kernel loader that the stack of the
+-program should be set to \fIn\fR bytes.
+-.IP "\fB\-metrax4\fR" 4
+-.IX Item "-metrax4"
+-.PD 0
+-.IP "\fB\-metrax100\fR" 4
+-.IX Item "-metrax100"
+-.PD
+-The options \fB\-metrax4\fR and \fB\-metrax100\fR are synonyms for
+-\&\fB\-march=v3\fR and \fB\-march=v8\fR respectively.
+-.IP "\fB\-mmul\-bug\-workaround\fR" 4
+-.IX Item "-mmul-bug-workaround"
+-.PD 0
+-.IP "\fB\-mno\-mul\-bug\-workaround\fR" 4
+-.IX Item "-mno-mul-bug-workaround"
+-.PD
+-Work around a bug in the \f(CW\*(C`muls\*(C'\fR and \f(CW\*(C`mulu\*(C'\fR instructions for \s-1CPU\s0
+-models where it applies. This option is active by default.
+-.IP "\fB\-mpdebug\fR" 4
+-.IX Item "-mpdebug"
+-Enable CRIS-specific verbose debug-related information in the assembly
+-code. This option also has the effect to turn off the \fB#NO_APP\fR
+-formatted-code indicator to the assembler at the beginning of the
+-assembly file.
+-.IP "\fB\-mcc\-init\fR" 4
+-.IX Item "-mcc-init"
+-Do not use condition-code results from previous instruction; always emit
+-compare and test instructions before use of condition codes.
+-.IP "\fB\-mno\-side\-effects\fR" 4
+-.IX Item "-mno-side-effects"
+-Do not emit instructions with side-effects in addressing modes other than
+-post\-increment.
+-.IP "\fB\-mstack\-align\fR" 4
+-.IX Item "-mstack-align"
+-.PD 0
+-.IP "\fB\-mno\-stack\-align\fR" 4
+-.IX Item "-mno-stack-align"
+-.IP "\fB\-mdata\-align\fR" 4
+-.IX Item "-mdata-align"
+-.IP "\fB\-mno\-data\-align\fR" 4
+-.IX Item "-mno-data-align"
+-.IP "\fB\-mconst\-align\fR" 4
+-.IX Item "-mconst-align"
+-.IP "\fB\-mno\-const\-align\fR" 4
+-.IX Item "-mno-const-align"
+-.PD
+-These options (no\-options) arranges (eliminate arrangements) for the
+-stack\-frame, individual data and constants to be aligned for the maximum
+-single data access size for the chosen \s-1CPU\s0 model. The default is to
+-arrange for 32\-bit alignment. \s-1ABI\s0 details such as structure layout are
+-not affected by these options.
+-.IP "\fB\-m32\-bit\fR" 4
+-.IX Item "-m32-bit"
+-.PD 0
+-.IP "\fB\-m16\-bit\fR" 4
+-.IX Item "-m16-bit"
+-.IP "\fB\-m8\-bit\fR" 4
+-.IX Item "-m8-bit"
+-.PD
+-Similar to the stack\- data\- and const-align options above, these options
+-arrange for stack\-frame, writable data and constants to all be 32\-bit,
+-16\-bit or 8\-bit aligned. The default is 32\-bit alignment.
+-.IP "\fB\-mno\-prologue\-epilogue\fR" 4
+-.IX Item "-mno-prologue-epilogue"
+-.PD 0
+-.IP "\fB\-mprologue\-epilogue\fR" 4
+-.IX Item "-mprologue-epilogue"
+-.PD
+-With \fB\-mno\-prologue\-epilogue\fR, the normal function prologue and
+-epilogue that sets up the stack-frame are omitted and no return
+-instructions or return sequences are generated in the code. Use this
+-option only together with visual inspection of the compiled code: no
+-warnings or errors are generated when call-saved registers must be saved,
+-or storage for local variable needs to be allocated.
+-.IP "\fB\-mno\-gotplt\fR" 4
+-.IX Item "-mno-gotplt"
+-.PD 0
+-.IP "\fB\-mgotplt\fR" 4
+-.IX Item "-mgotplt"
+-.PD
+-With \fB\-fpic\fR and \fB\-fPIC\fR, don't generate (do generate)
+-instruction sequences that load addresses for functions from the \s-1PLT\s0 part
+-of the \s-1GOT\s0 rather than (traditional on other architectures) calls to the
+-\&\s-1PLT\s0. The default is \fB\-mgotplt\fR.
+-.IP "\fB\-maout\fR" 4
+-.IX Item "-maout"
+-Legacy no-op option only recognized with the cris-axis-aout target.
+-.IP "\fB\-melf\fR" 4
+-.IX Item "-melf"
+-Legacy no-op option only recognized with the cris-axis-elf and
+-cris-axis-linux-gnu targets.
+-.IP "\fB\-melinux\fR" 4
+-.IX Item "-melinux"
+-Only recognized with the cris-axis-aout target, where it selects a
+-GNU/linux\-like multilib, include files and instruction set for
+-\&\fB\-march=v8\fR.
+-.IP "\fB\-mlinux\fR" 4
+-.IX Item "-mlinux"
+-Legacy no-op option only recognized with the cris-axis-linux-gnu target.
+-.IP "\fB\-sim\fR" 4
+-.IX Item "-sim"
+-This option, recognized for the cris-axis-aout and cris-axis-elf arranges
+-to link with input-output functions from a simulator library. Code,
+-initialized data and zero-initialized data are allocated consecutively.
+-.IP "\fB\-sim2\fR" 4
+-.IX Item "-sim2"
+-Like \fB\-sim\fR, but pass linker options to locate initialized data at
+-0x40000000 and zero-initialized data at 0x80000000.
+-.PP
+-\fI\s-1MMIX\s0 Options\fR
+-.IX Subsection "MMIX Options"
+-.PP
+-These options are defined for the \s-1MMIX:\s0
+-.IP "\fB\-mlibfuncs\fR" 4
+-.IX Item "-mlibfuncs"
+-.PD 0
+-.IP "\fB\-mno\-libfuncs\fR" 4
+-.IX Item "-mno-libfuncs"
+-.PD
+-Specify that intrinsic library functions are being compiled, passing all
+-values in registers, no matter the size.
+-.IP "\fB\-mepsilon\fR" 4
+-.IX Item "-mepsilon"
+-.PD 0
+-.IP "\fB\-mno\-epsilon\fR" 4
+-.IX Item "-mno-epsilon"
+-.PD
+-Generate floating-point comparison instructions that compare with respect
+-to the \f(CW\*(C`rE\*(C'\fR epsilon register.
+-.IP "\fB\-mabi=mmixware\fR" 4
+-.IX Item "-mabi=mmixware"
+-.PD 0
+-.IP "\fB\-mabi=gnu\fR" 4
+-.IX Item "-mabi=gnu"
+-.PD
+-Generate code that passes function parameters and return values that (in
+-the called function) are seen as registers \f(CW$0\fR and up, as opposed to
+-the \s-1GNU\s0 \s-1ABI\s0 which uses global registers \f(CW$231\fR and up.
+-.IP "\fB\-mzero\-extend\fR" 4
+-.IX Item "-mzero-extend"
+-.PD 0
+-.IP "\fB\-mno\-zero\-extend\fR" 4
+-.IX Item "-mno-zero-extend"
+-.PD
+-When reading data from memory in sizes shorter than 64 bits, use (do not
+-use) zero-extending load instructions by default, rather than
+-sign-extending ones.
+-.IP "\fB\-mknuthdiv\fR" 4
+-.IX Item "-mknuthdiv"
+-.PD 0
+-.IP "\fB\-mno\-knuthdiv\fR" 4
+-.IX Item "-mno-knuthdiv"
+-.PD
+-Make the result of a division yielding a remainder have the same sign as
+-the divisor. With the default, \fB\-mno\-knuthdiv\fR, the sign of the
+-remainder follows the sign of the dividend. Both methods are
+-arithmetically valid, the latter being almost exclusively used.
+-.IP "\fB\-mtoplevel\-symbols\fR" 4
+-.IX Item "-mtoplevel-symbols"
+-.PD 0
+-.IP "\fB\-mno\-toplevel\-symbols\fR" 4
+-.IX Item "-mno-toplevel-symbols"
+-.PD
+-Prepend (do not prepend) a \fB:\fR to all global symbols, so the assembly
+-code can be used with the \f(CW\*(C`PREFIX\*(C'\fR assembly directive.
+-.IP "\fB\-melf\fR" 4
+-.IX Item "-melf"
+-Generate an executable in the \s-1ELF\s0 format, rather than the default
+-\&\fBmmo\fR format used by the \fBmmix\fR simulator.
+-.IP "\fB\-mbranch\-predict\fR" 4
+-.IX Item "-mbranch-predict"
+-.PD 0
+-.IP "\fB\-mno\-branch\-predict\fR" 4
+-.IX Item "-mno-branch-predict"
+-.PD
+-Use (do not use) the probable-branch instructions, when static branch
+-prediction indicates a probable branch.
+-.IP "\fB\-mbase\-addresses\fR" 4
+-.IX Item "-mbase-addresses"
+-.PD 0
+-.IP "\fB\-mno\-base\-addresses\fR" 4
+-.IX Item "-mno-base-addresses"
+-.PD
+-Generate (do not generate) code that uses \fIbase addresses\fR. Using a
+-base address automatically generates a request (handled by the assembler
+-and the linker) for a constant to be set up in a global register. The
+-register is used for one or more base address requests within the range 0
+-to 255 from the value held in the register. The generally leads to short
+-and fast code, but the number of different data items that can be
+-addressed is limited. This means that a program that uses lots of static
+-data may require \fB\-mno\-base\-addresses\fR.
+-.IP "\fB\-msingle\-exit\fR" 4
+-.IX Item "-msingle-exit"
+-.PD 0
+-.IP "\fB\-mno\-single\-exit\fR" 4
+-.IX Item "-mno-single-exit"
+-.PD
+-Force (do not force) generated code to have a single exit point in each
+-function.
+-.PP
+-\fI\s-1PDP\-11\s0 Options\fR
+-.IX Subsection "PDP-11 Options"
+-.PP
+-These options are defined for the \s-1PDP\-11:\s0
+-.IP "\fB\-mfpu\fR" 4
+-.IX Item "-mfpu"
+-Use hardware \s-1FPP\s0 floating point. This is the default. (\s-1FIS\s0 floating
+-point on the \s-1PDP\-11/40\s0 is not supported.)
+-.IP "\fB\-msoft\-float\fR" 4
+-.IX Item "-msoft-float"
+-Do not use hardware floating point.
+-.IP "\fB\-mac0\fR" 4
+-.IX Item "-mac0"
+-Return floating-point results in ac0 (fr0 in Unix assembler syntax).
+-.IP "\fB\-mno\-ac0\fR" 4
+-.IX Item "-mno-ac0"
+-Return floating-point results in memory. This is the default.
+-.IP "\fB\-m40\fR" 4
+-.IX Item "-m40"
+-Generate code for a \s-1PDP\-11/40\s0.
+-.IP "\fB\-m45\fR" 4
+-.IX Item "-m45"
+-Generate code for a \s-1PDP\-11/45\s0. This is the default.
+-.IP "\fB\-m10\fR" 4
+-.IX Item "-m10"
+-Generate code for a \s-1PDP\-11/10\s0.
+-.IP "\fB\-mbcopy\-builtin\fR" 4
+-.IX Item "-mbcopy-builtin"
+-Use inline \f(CW\*(C`movstrhi\*(C'\fR patterns for copying memory. This is the
+-default.
+-.IP "\fB\-mbcopy\fR" 4
+-.IX Item "-mbcopy"
+-Do not use inline \f(CW\*(C`movstrhi\*(C'\fR patterns for copying memory.
+-.IP "\fB\-mint16\fR" 4
+-.IX Item "-mint16"
+-.PD 0
+-.IP "\fB\-mno\-int32\fR" 4
+-.IX Item "-mno-int32"
+-.PD
+-Use 16\-bit \f(CW\*(C`int\*(C'\fR. This is the default.
+-.IP "\fB\-mint32\fR" 4
+-.IX Item "-mint32"
+-.PD 0
+-.IP "\fB\-mno\-int16\fR" 4
+-.IX Item "-mno-int16"
+-.PD
+-Use 32\-bit \f(CW\*(C`int\*(C'\fR.
+-.IP "\fB\-mfloat64\fR" 4
+-.IX Item "-mfloat64"
+-.PD 0
+-.IP "\fB\-mno\-float32\fR" 4
+-.IX Item "-mno-float32"
+-.PD
+-Use 64\-bit \f(CW\*(C`float\*(C'\fR. This is the default.
+-.IP "\fB\-mfloat32\fR" 4
+-.IX Item "-mfloat32"
+-.PD 0
+-.IP "\fB\-mno\-float64\fR" 4
+-.IX Item "-mno-float64"
+-.PD
+-Use 32\-bit \f(CW\*(C`float\*(C'\fR.
+-.IP "\fB\-mabshi\fR" 4
+-.IX Item "-mabshi"
+-Use \f(CW\*(C`abshi2\*(C'\fR pattern. This is the default.
+-.IP "\fB\-mno\-abshi\fR" 4
+-.IX Item "-mno-abshi"
+-Do not use \f(CW\*(C`abshi2\*(C'\fR pattern.
+-.IP "\fB\-mbranch\-expensive\fR" 4
+-.IX Item "-mbranch-expensive"
+-Pretend that branches are expensive. This is for experimenting with
+-code generation only.
+-.IP "\fB\-mbranch\-cheap\fR" 4
+-.IX Item "-mbranch-cheap"
+-Do not pretend that branches are expensive. This is the default.
+-.IP "\fB\-msplit\fR" 4
+-.IX Item "-msplit"
+-Generate code for a system with split I&D.
+-.IP "\fB\-mno\-split\fR" 4
+-.IX Item "-mno-split"
+-Generate code for a system without split I&D. This is the default.
+-.IP "\fB\-munix\-asm\fR" 4
+-.IX Item "-munix-asm"
+-Use Unix assembler syntax. This is the default when configured for
+-\&\fBpdp11\-*\-bsd\fR.
+-.IP "\fB\-mdec\-asm\fR" 4
+-.IX Item "-mdec-asm"
+-Use \s-1DEC\s0 assembler syntax. This is the default when configured for any
+-\&\s-1PDP\-11\s0 target other than \fBpdp11\-*\-bsd\fR.
+-.PP
+-\fIXstormy16 Options\fR
+-.IX Subsection "Xstormy16 Options"
+-.PP
+-These options are defined for Xstormy16:
+-.IP "\fB\-msim\fR" 4
+-.IX Item "-msim"
+-Choose startup files and linker script suitable for the simulator.
+-.PP
+-\fI\s-1FRV\s0 Options\fR
+-.IX Subsection "FRV Options"
+-.IP "\fB\-mgpr\-32\fR" 4
+-.IX Item "-mgpr-32"
+-Only use the first 32 general purpose registers.
+-.IP "\fB\-mgpr\-64\fR" 4
+-.IX Item "-mgpr-64"
+-Use all 64 general purpose registers.
+-.IP "\fB\-mfpr\-32\fR" 4
+-.IX Item "-mfpr-32"
+-Use only the first 32 floating point registers.
+-.IP "\fB\-mfpr\-64\fR" 4
+-.IX Item "-mfpr-64"
+-Use all 64 floating point registers
+-.IP "\fB\-mhard\-float\fR" 4
+-.IX Item "-mhard-float"
+-Use hardware instructions for floating point operations.
+-.IP "\fB\-msoft\-float\fR" 4
+-.IX Item "-msoft-float"
+-Use library routines for floating point operations.
+-.IP "\fB\-malloc\-cc\fR" 4
+-.IX Item "-malloc-cc"
+-Dynamically allocate condition code registers.
+-.IP "\fB\-mfixed\-cc\fR" 4
+-.IX Item "-mfixed-cc"
+-Do not try to dynamically allocate condition code registers, only
+-use \f(CW\*(C`icc0\*(C'\fR and \f(CW\*(C`fcc0\*(C'\fR.
+-.IP "\fB\-mdword\fR" 4
+-.IX Item "-mdword"
+-Change \s-1ABI\s0 to use double word insns.
+-.IP "\fB\-mno\-dword\fR" 4
+-.IX Item "-mno-dword"
+-Do not use double word instructions.
+-.IP "\fB\-mdouble\fR" 4
+-.IX Item "-mdouble"
+-Use floating point double instructions.
+-.IP "\fB\-mno\-double\fR" 4
+-.IX Item "-mno-double"
+-Do not use floating point double instructions.
+-.IP "\fB\-mmedia\fR" 4
+-.IX Item "-mmedia"
+-Use media instructions.
+-.IP "\fB\-mno\-media\fR" 4
+-.IX Item "-mno-media"
+-Do not use media instructions.
+-.IP "\fB\-mmuladd\fR" 4
+-.IX Item "-mmuladd"
+-Use multiply and add/subtract instructions.
+-.IP "\fB\-mno\-muladd\fR" 4
+-.IX Item "-mno-muladd"
+-Do not use multiply and add/subtract instructions.
+-.IP "\fB\-mlibrary\-pic\fR" 4
+-.IX Item "-mlibrary-pic"
+-Enable \s-1PIC\s0 support for building libraries
+-.IP "\fB\-macc\-4\fR" 4
+-.IX Item "-macc-4"
+-Use only the first four media accumulator registers.
+-.IP "\fB\-macc\-8\fR" 4
+-.IX Item "-macc-8"
+-Use all eight media accumulator registers.
+-.IP "\fB\-mpack\fR" 4
+-.IX Item "-mpack"
+-Pack \s-1VLIW\s0 instructions.
+-.IP "\fB\-mno\-pack\fR" 4
+-.IX Item "-mno-pack"
+-Do not pack \s-1VLIW\s0 instructions.
+-.IP "\fB\-mno\-eflags\fR" 4
+-.IX Item "-mno-eflags"
+-Do not mark \s-1ABI\s0 switches in e_flags.
+-.IP "\fB\-mcond\-move\fR" 4
+-.IX Item "-mcond-move"
+-Enable the use of conditional-move instructions (default).
+-.Sp
+-This switch is mainly for debugging the compiler and will likely be removed
+-in a future version.
+-.IP "\fB\-mno\-cond\-move\fR" 4
+-.IX Item "-mno-cond-move"
+-Disable the use of conditional-move instructions.
+-.Sp
+-This switch is mainly for debugging the compiler and will likely be removed
+-in a future version.
+-.IP "\fB\-mscc\fR" 4
+-.IX Item "-mscc"
+-Enable the use of conditional set instructions (default).
+-.Sp
+-This switch is mainly for debugging the compiler and will likely be removed
+-in a future version.
+-.IP "\fB\-mno\-scc\fR" 4
+-.IX Item "-mno-scc"
+-Disable the use of conditional set instructions.
+-.Sp
+-This switch is mainly for debugging the compiler and will likely be removed
+-in a future version.
+-.IP "\fB\-mcond\-exec\fR" 4
+-.IX Item "-mcond-exec"
+-Enable the use of conditional execution (default).
+-.Sp
+-This switch is mainly for debugging the compiler and will likely be removed
+-in a future version.
+-.IP "\fB\-mno\-cond\-exec\fR" 4
+-.IX Item "-mno-cond-exec"
+-Disable the use of conditional execution.
+-.Sp
+-This switch is mainly for debugging the compiler and will likely be removed
+-in a future version.
+-.IP "\fB\-mvliw\-branch\fR" 4
+-.IX Item "-mvliw-branch"
+-Run a pass to pack branches into \s-1VLIW\s0 instructions (default).
+-.Sp
+-This switch is mainly for debugging the compiler and will likely be removed
+-in a future version.
+-.IP "\fB\-mno\-vliw\-branch\fR" 4
+-.IX Item "-mno-vliw-branch"
+-Do not run a pass to pack branches into \s-1VLIW\s0 instructions.
+-.Sp
+-This switch is mainly for debugging the compiler and will likely be removed
+-in a future version.
+-.IP "\fB\-mmulti\-cond\-exec\fR" 4
+-.IX Item "-mmulti-cond-exec"
+-Enable optimization of \f(CW\*(C`&&\*(C'\fR and \f(CW\*(C`||\*(C'\fR in conditional execution
+-(default).
+-.Sp
+-This switch is mainly for debugging the compiler and will likely be removed
+-in a future version.
+-.IP "\fB\-mno\-multi\-cond\-exec\fR" 4
+-.IX Item "-mno-multi-cond-exec"
+-Disable optimization of \f(CW\*(C`&&\*(C'\fR and \f(CW\*(C`||\*(C'\fR in conditional execution.
+-.Sp
+-This switch is mainly for debugging the compiler and will likely be removed
+-in a future version.
+-.IP "\fB\-mnested\-cond\-exec\fR" 4
+-.IX Item "-mnested-cond-exec"
+-Enable nested conditional execution optimizations (default).
+-.Sp
+-This switch is mainly for debugging the compiler and will likely be removed
+-in a future version.
+-.IP "\fB\-mno\-nested\-cond\-exec\fR" 4
+-.IX Item "-mno-nested-cond-exec"
+-Disable nested conditional execution optimizations.
+-.Sp
+-This switch is mainly for debugging the compiler and will likely be removed
+-in a future version.
+-.IP "\fB\-mtomcat\-stats\fR" 4
+-.IX Item "-mtomcat-stats"
+-Cause gas to print out tomcat statistics.
+-.IP "\fB\-mcpu=\fR\fIcpu\fR" 4
+-.IX Item "-mcpu=cpu"
+-Select the processor type for which to generate code. Possible values are
+-\&\fBsimple\fR, \fBtomcat\fR, \fBfr500\fR, \fBfr400\fR, \fBfr300\fR,
+-\&\fBfrv\fR.
+-.PP
+-\fIXtensa Options\fR
+-.IX Subsection "Xtensa Options"
+-.PP
+-The Xtensa architecture is designed to support many different
+-configurations. The compiler's default options can be set to match a
+-particular Xtensa configuration by copying a configuration file into the
+-\&\s-1GCC\s0 sources when building \s-1GCC\s0. The options below may be used to
+-override the default options.
+-.IP "\fB\-mbig\-endian\fR" 4
+-.IX Item "-mbig-endian"
+-.PD 0
+-.IP "\fB\-mlittle\-endian\fR" 4
+-.IX Item "-mlittle-endian"
+-.PD
+-Specify big-endian or little-endian byte ordering for the target Xtensa
+-processor.
+-.IP "\fB\-mdensity\fR" 4
+-.IX Item "-mdensity"
+-.PD 0
+-.IP "\fB\-mno\-density\fR" 4
+-.IX Item "-mno-density"
+-.PD
+-Enable or disable use of the optional Xtensa code density instructions.
+-.IP "\fB\-mmac16\fR" 4
+-.IX Item "-mmac16"
+-.PD 0
+-.IP "\fB\-mno\-mac16\fR" 4
+-.IX Item "-mno-mac16"
+-.PD
+-Enable or disable use of the Xtensa \s-1MAC16\s0 option. When enabled, \s-1GCC\s0
+-will generate \s-1MAC16\s0 instructions from standard C code, with the
+-limitation that it will use neither the \s-1MR\s0 register file nor any
+-instruction that operates on the \s-1MR\s0 registers. When this option is
+-disabled, \s-1GCC\s0 will translate 16\-bit multiply/accumulate operations to a
+-combination of core instructions and library calls, depending on whether
+-any other multiplier options are enabled.
+-.IP "\fB\-mmul16\fR" 4
+-.IX Item "-mmul16"
+-.PD 0
+-.IP "\fB\-mno\-mul16\fR" 4
+-.IX Item "-mno-mul16"
+-.PD
+-Enable or disable use of the 16\-bit integer multiplier option. When
+-enabled, the compiler will generate 16\-bit multiply instructions for
+-multiplications of 16 bits or smaller in standard C code. When this
+-option is disabled, the compiler will either use 32\-bit multiply or
+-\&\s-1MAC16\s0 instructions if they are available or generate library calls to
+-perform the multiply operations using shifts and adds.
+-.IP "\fB\-mmul32\fR" 4
+-.IX Item "-mmul32"
+-.PD 0
+-.IP "\fB\-mno\-mul32\fR" 4
+-.IX Item "-mno-mul32"
+-.PD
+-Enable or disable use of the 32\-bit integer multiplier option. When
+-enabled, the compiler will generate 32\-bit multiply instructions for
+-multiplications of 32 bits or smaller in standard C code. When this
+-option is disabled, the compiler will generate library calls to perform
+-the multiply operations using either shifts and adds or 16\-bit multiply
+-instructions if they are available.
+-.IP "\fB\-mnsa\fR" 4
+-.IX Item "-mnsa"
+-.PD 0
+-.IP "\fB\-mno\-nsa\fR" 4
+-.IX Item "-mno-nsa"
+-.PD
+-Enable or disable use of the optional normalization shift amount
+-(\f(CW\*(C`NSA\*(C'\fR) instructions to implement the built-in \f(CW\*(C`ffs\*(C'\fR function.
+-.IP "\fB\-mminmax\fR" 4
+-.IX Item "-mminmax"
+-.PD 0
+-.IP "\fB\-mno\-minmax\fR" 4
+-.IX Item "-mno-minmax"
+-.PD
+-Enable or disable use of the optional minimum and maximum value
+-instructions.
+-.IP "\fB\-msext\fR" 4
+-.IX Item "-msext"
+-.PD 0
+-.IP "\fB\-mno\-sext\fR" 4
+-.IX Item "-mno-sext"
+-.PD
+-Enable or disable use of the optional sign extend (\f(CW\*(C`SEXT\*(C'\fR)
+-instruction.
+-.IP "\fB\-mbooleans\fR" 4
+-.IX Item "-mbooleans"
+-.PD 0
+-.IP "\fB\-mno\-booleans\fR" 4
+-.IX Item "-mno-booleans"
+-.PD
+-Enable or disable support for the boolean register file used by Xtensa
+-coprocessors. This is not typically useful by itself but may be
+-required for other options that make use of the boolean registers (e.g.,
+-the floating-point option).
+-.IP "\fB\-mhard\-float\fR" 4
+-.IX Item "-mhard-float"
+-.PD 0
+-.IP "\fB\-msoft\-float\fR" 4
+-.IX Item "-msoft-float"
+-.PD
+-Enable or disable use of the floating-point option. When enabled, \s-1GCC\s0
+-generates floating-point instructions for 32\-bit \f(CW\*(C`float\*(C'\fR
+-operations. When this option is disabled, \s-1GCC\s0 generates library calls
+-to emulate 32\-bit floating-point operations using integer instructions.
+-Regardless of this option, 64\-bit \f(CW\*(C`double\*(C'\fR operations are always
+-emulated with calls to library functions.
+-.IP "\fB\-mfused\-madd\fR" 4
+-.IX Item "-mfused-madd"
+-.PD 0
+-.IP "\fB\-mno\-fused\-madd\fR" 4
+-.IX Item "-mno-fused-madd"
+-.PD
+-Enable or disable use of fused multiply/add and multiply/subtract
+-instructions in the floating-point option. This has no effect if the
+-floating-point option is not also enabled. Disabling fused multiply/add
+-and multiply/subtract instructions forces the compiler to use separate
+-instructions for the multiply and add/subtract operations. This may be
+-desirable in some cases where strict \s-1IEEE\s0 754\-compliant results are
+-required: the fused multiply add/subtract instructions do not round the
+-intermediate result, thereby producing results with \fImore\fR bits of
+-precision than specified by the \s-1IEEE\s0 standard. Disabling fused multiply
+-add/subtract instructions also ensures that the program output is not
+-sensitive to the compiler's ability to combine multiply and add/subtract
+-operations.
+-.IP "\fB\-mserialize\-volatile\fR" 4
+-.IX Item "-mserialize-volatile"
+-.PD 0
+-.IP "\fB\-mno\-serialize\-volatile\fR" 4
+-.IX Item "-mno-serialize-volatile"
+-.PD
+-When this option is enabled, \s-1GCC\s0 inserts \f(CW\*(C`MEMW\*(C'\fR instructions before
+-\&\f(CW\*(C`volatile\*(C'\fR memory references to guarantee sequential consistency.
+-The default is \fB\-mserialize\-volatile\fR. Use
+-\&\fB\-mno\-serialize\-volatile\fR to omit the \f(CW\*(C`MEMW\*(C'\fR instructions.
+-.IP "\fB\-mtext\-section\-literals\fR" 4
+-.IX Item "-mtext-section-literals"
+-.PD 0
+-.IP "\fB\-mno\-text\-section\-literals\fR" 4
+-.IX Item "-mno-text-section-literals"
+-.PD
+-Control the treatment of literal pools. The default is
+-\&\fB\-mno\-text\-section\-literals\fR, which places literals in a separate
+-section in the output file. This allows the literal pool to be placed
+-in a data \s-1RAM/ROM\s0, and it also allows the linker to combine literal
+-pools from separate object files to remove redundant literals and
+-improve code size. With \fB\-mtext\-section\-literals\fR, the literals
+-are interspersed in the text section in order to keep them as close as
+-possible to their references. This may be necessary for large assembly
+-files.
+-.IP "\fB\-mtarget\-align\fR" 4
+-.IX Item "-mtarget-align"
+-.PD 0
+-.IP "\fB\-mno\-target\-align\fR" 4
+-.IX Item "-mno-target-align"
+-.PD
+-When this option is enabled, \s-1GCC\s0 instructs the assembler to
+-automatically align instructions to reduce branch penalties at the
+-expense of some code density. The assembler attempts to widen density
+-instructions to align branch targets and the instructions following call
+-instructions. If there are not enough preceding safe density
+-instructions to align a target, no widening will be performed. The
+-default is \fB\-mtarget\-align\fR. These options do not affect the
+-treatment of auto-aligned instructions like \f(CW\*(C`LOOP\*(C'\fR, which the
+-assembler will always align, either by widening density instructions or
+-by inserting no-op instructions.
+-.IP "\fB\-mlongcalls\fR" 4
+-.IX Item "-mlongcalls"
+-.PD 0
+-.IP "\fB\-mno\-longcalls\fR" 4
+-.IX Item "-mno-longcalls"
+-.PD
+-When this option is enabled, \s-1GCC\s0 instructs the assembler to translate
+-direct calls to indirect calls unless it can determine that the target
+-of a direct call is in the range allowed by the call instruction. This
+-translation typically occurs for calls to functions in other source
+-files. Specifically, the assembler translates a direct \f(CW\*(C`CALL\*(C'\fR
+-instruction into an \f(CW\*(C`L32R\*(C'\fR followed by a \f(CW\*(C`CALLX\*(C'\fR instruction.
+-The default is \fB\-mno\-longcalls\fR. This option should be used in
+-programs where the call target can potentially be out of range. This
+-option is implemented in the assembler, not the compiler, so the
+-assembly code generated by \s-1GCC\s0 will still show direct call
+-instructions\-\-\-look at the disassembled object code to see the actual
+-instructions. Note that the assembler will use an indirect call for
+-every cross-file call, not just those that really will be out of range.
+-.Sh "Options for Code Generation Conventions"
+-.IX Subsection "Options for Code Generation Conventions"
+-These machine-independent options control the interface conventions
+-used in code generation.
+-.PP
+-Most of them have both positive and negative forms; the negative form
+-of \fB\-ffoo\fR would be \fB\-fno\-foo\fR. In the table below, only
+-one of the forms is listed\-\-\-the one which is not the default. You
+-can figure out the other form by either removing \fBno\-\fR or adding
+-it.
+-.IP "\fB\-fbounds\-check\fR" 4
+-.IX Item "-fbounds-check"
+-For front-ends that support it, generate additional code to check that
+-indices used to access arrays are within the declared range. This is
+-currently only supported by the Java and Fortran 77 front\-ends, where
+-this option defaults to true and false respectively.
+-.IP "\fB\-ftrapv\fR" 4
+-.IX Item "-ftrapv"
+-This option generates traps for signed overflow on addition, subtraction,
+-multiplication operations.
+-.IP "\fB\-fexceptions\fR" 4
+-.IX Item "-fexceptions"
+-Enable exception handling. Generates extra code needed to propagate
+-exceptions. For some targets, this implies \s-1GCC\s0 will generate frame
+-unwind information for all functions, which can produce significant data
+-size overhead, although it does not affect execution. If you do not
+-specify this option, \s-1GCC\s0 will enable it by default for languages like
+-\&\*(C+ which normally require exception handling, and disable it for
+-languages like C that do not normally require it. However, you may need
+-to enable this option when compiling C code that needs to interoperate
+-properly with exception handlers written in \*(C+. You may also wish to
+-disable this option if you are compiling older \*(C+ programs that don't
+-use exception handling.
+-.IP "\fB\-fnon\-call\-exceptions\fR" 4
+-.IX Item "-fnon-call-exceptions"
+-Generate code that allows trapping instructions to throw exceptions.
+-Note that this requires platform-specific runtime support that does
+-not exist everywhere. Moreover, it only allows \fItrapping\fR
+-instructions to throw exceptions, i.e. memory references or floating
+-point instructions. It does not allow exceptions to be thrown from
+-arbitrary signal handlers such as \f(CW\*(C`SIGALRM\*(C'\fR.
+-.IP "\fB\-funwind\-tables\fR" 4
+-.IX Item "-funwind-tables"
+-Similar to \fB\-fexceptions\fR, except that it will just generate any needed
+-static data, but will not affect the generated code in any other way.
+-You will normally not enable this option; instead, a language processor
+-that needs this handling would enable it on your behalf.
+-.IP "\fB\-fasynchronous\-unwind\-tables\fR" 4
+-.IX Item "-fasynchronous-unwind-tables"
+-Generate unwind table in dwarf2 format, if supported by target machine. The
+-table is exact at each instruction boundary, so it can be used for stack
+-unwinding from asynchronous events (such as debugger or garbage collector).
+-.IP "\fB\-fpcc\-struct\-return\fR" 4
+-.IX Item "-fpcc-struct-return"
+-Return ``short'' \f(CW\*(C`struct\*(C'\fR and \f(CW\*(C`union\*(C'\fR values in memory like
+-longer ones, rather than in registers. This convention is less
+-efficient, but it has the advantage of allowing intercallability between
+-GCC-compiled files and files compiled with other compilers, particularly
+-the Portable C Compiler (pcc).
+-.Sp
+-The precise convention for returning structures in memory depends
+-on the target configuration macros.
+-.Sp
+-Short structures and unions are those whose size and alignment match
+-that of some integer type.
+-.Sp
+-\&\fBWarning:\fR code compiled with the \fB\-fpcc\-struct\-return\fR
+-switch is not binary compatible with code compiled with the
+-\&\fB\-freg\-struct\-return\fR switch.
+-Use it to conform to a non-default application binary interface.
+-.IP "\fB\-freg\-struct\-return\fR" 4
+-.IX Item "-freg-struct-return"
+-Return \f(CW\*(C`struct\*(C'\fR and \f(CW\*(C`union\*(C'\fR values in registers when possible.
+-This is more efficient for small structures than
+-\&\fB\-fpcc\-struct\-return\fR.
+-.Sp
+-If you specify neither \fB\-fpcc\-struct\-return\fR nor
+-\&\fB\-freg\-struct\-return\fR, \s-1GCC\s0 defaults to whichever convention is
+-standard for the target. If there is no standard convention, \s-1GCC\s0
+-defaults to \fB\-fpcc\-struct\-return\fR, except on targets where \s-1GCC\s0 is
+-the principal compiler. In those cases, we can choose the standard, and
+-we chose the more efficient register return alternative.
+-.Sp
+-\&\fBWarning:\fR code compiled with the \fB\-freg\-struct\-return\fR
+-switch is not binary compatible with code compiled with the
+-\&\fB\-fpcc\-struct\-return\fR switch.
+-Use it to conform to a non-default application binary interface.
+-.IP "\fB\-fshort\-enums\fR" 4
+-.IX Item "-fshort-enums"
+-Allocate to an \f(CW\*(C`enum\*(C'\fR type only as many bytes as it needs for the
+-declared range of possible values. Specifically, the \f(CW\*(C`enum\*(C'\fR type
+-will be equivalent to the smallest integer type which has enough room.
+-.Sp
+-\&\fBWarning:\fR the \fB\-fshort\-enums\fR switch causes \s-1GCC\s0 to generate
+-code that is not binary compatible with code generated without that switch.
+-Use it to conform to a non-default application binary interface.
+-.IP "\fB\-fshort\-double\fR" 4
+-.IX Item "-fshort-double"
+-Use the same size for \f(CW\*(C`double\*(C'\fR as for \f(CW\*(C`float\*(C'\fR.
+-.Sp
+-\&\fBWarning:\fR the \fB\-fshort\-double\fR switch causes \s-1GCC\s0 to generate
+-code that is not binary compatible with code generated without that switch.
+-Use it to conform to a non-default application binary interface.
+-.IP "\fB\-fshort\-wchar\fR" 4
+-.IX Item "-fshort-wchar"
+-Override the underlying type for \fBwchar_t\fR to be \fBshort
+-unsigned int\fR instead of the default for the target. This option is
+-useful for building programs to run under \s-1WINE\s0.
+-.Sp
+-\&\fBWarning:\fR the \fB\-fshort\-wchar\fR switch causes \s-1GCC\s0 to generate
+-code that is not binary compatible with code generated without that switch.
+-Use it to conform to a non-default application binary interface.
+-.IP "\fB\-fshared\-data\fR" 4
+-.IX Item "-fshared-data"
+-Requests that the data and non\-\f(CW\*(C`const\*(C'\fR variables of this
+-compilation be shared data rather than private data. The distinction
+-makes sense only on certain operating systems, where shared data is
+-shared between processes running the same program, while private data
+-exists in one copy per process.
+-.IP "\fB\-fno\-common\fR" 4
+-.IX Item "-fno-common"
+-In C, allocate even uninitialized global variables in the data section of the
+-object file, rather than generating them as common blocks. This has the
+-effect that if the same variable is declared (without \f(CW\*(C`extern\*(C'\fR) in
+-two different compilations, you will get an error when you link them.
+-The only reason this might be useful is if you wish to verify that the
+-program will work on other systems which always work this way.
+-.IP "\fB\-fno\-ident\fR" 4
+-.IX Item "-fno-ident"
+-Ignore the \fB#ident\fR directive.
+-.IP "\fB\-fno\-gnu\-linker\fR" 4
+-.IX Item "-fno-gnu-linker"
+-Do not output global initializations (such as \*(C+ constructors and
+-destructors) in the form used by the \s-1GNU\s0 linker (on systems where the \s-1GNU\s0
+-linker is the standard method of handling them). Use this option when
+-you want to use a non-GNU linker, which also requires using the
+-\&\fBcollect2\fR program to make sure the system linker includes
+-constructors and destructors. (\fBcollect2\fR is included in the \s-1GCC\s0
+-distribution.) For systems which \fImust\fR use \fBcollect2\fR, the
+-compiler driver \fBgcc\fR is configured to do this automatically.
+-.IP "\fB\-finhibit\-size\-directive\fR" 4
+-.IX Item "-finhibit-size-directive"
+-Don't output a \f(CW\*(C`.size\*(C'\fR assembler directive, or anything else that
+-would cause trouble if the function is split in the middle, and the
+-two halves are placed at locations far apart in memory. This option is
+-used when compiling \fIcrtstuff.c\fR; you should not need to use it
+-for anything else.
+-.IP "\fB\-fverbose\-asm\fR" 4
+-.IX Item "-fverbose-asm"
+-Put extra commentary information in the generated assembly code to
+-make it more readable. This option is generally only of use to those
+-who actually need to read the generated assembly code (perhaps while
+-debugging the compiler itself).
+-.Sp
+-\&\fB\-fno\-verbose\-asm\fR, the default, causes the
+-extra information to be omitted and is useful when comparing two assembler
+-files.
+-.IP "\fB\-fvolatile\fR" 4
+-.IX Item "-fvolatile"
+-Consider all memory references through pointers to be volatile.
+-.IP "\fB\-fvolatile\-global\fR" 4
+-.IX Item "-fvolatile-global"
+-Consider all memory references to extern and global data items to
+-be volatile. \s-1GCC\s0 does not consider static data items to be volatile
+-because of this switch.
+-.IP "\fB\-fvolatile\-static\fR" 4
+-.IX Item "-fvolatile-static"
+-Consider all memory references to static data to be volatile.
+-.IP "\fB\-fpic\fR" 4
+-.IX Item "-fpic"
+-Generate position-independent code (\s-1PIC\s0) suitable for use in a shared
+-library, if supported for the target machine. Such code accesses all
+-constant addresses through a global offset table (\s-1GOT\s0). The dynamic
+-loader resolves the \s-1GOT\s0 entries when the program starts (the dynamic
+-loader is not part of \s-1GCC\s0; it is part of the operating system). If
+-the \s-1GOT\s0 size for the linked executable exceeds a machine-specific
+-maximum size, you get an error message from the linker indicating that
+-\&\fB\-fpic\fR does not work; in that case, recompile with \fB\-fPIC\fR
+-instead. (These maximums are 16k on the m88k, 8k on the \s-1SPARC\s0, and 32k
+-on the m68k and \s-1RS/6000\s0. The 386 has no such limit.)
+-.Sp
+-Position-independent code requires special support, and therefore works
+-only on certain machines. For the 386, \s-1GCC\s0 supports \s-1PIC\s0 for System V
+-but not for the Sun 386i. Code generated for the \s-1IBM\s0 \s-1RS/6000\s0 is always
+-position\-independent.
+-.IP "\fB\-fPIC\fR" 4
+-.IX Item "-fPIC"
+-If supported for the target machine, emit position-independent code,
+-suitable for dynamic linking and avoiding any limit on the size of the
+-global offset table. This option makes a difference on the m68k, m88k,
+-and the \s-1SPARC\s0.
+-.Sp
+-Position-independent code requires special support, and therefore works
+-only on certain machines.
+-.IP "\fB\-ffixed\-\fR\fIreg\fR" 4
+-.IX Item "-ffixed-reg"
+-Treat the register named \fIreg\fR as a fixed register; generated code
+-should never refer to it (except perhaps as a stack pointer, frame
+-pointer or in some other fixed role).
+-.Sp
+-\&\fIreg\fR must be the name of a register. The register names accepted
+-are machine-specific and are defined in the \f(CW\*(C`REGISTER_NAMES\*(C'\fR
+-macro in the machine description macro file.
+-.Sp
+-This flag does not have a negative form, because it specifies a
+-three-way choice.
+-.IP "\fB\-fcall\-used\-\fR\fIreg\fR" 4
+-.IX Item "-fcall-used-reg"
+-Treat the register named \fIreg\fR as an allocable register that is
+-clobbered by function calls. It may be allocated for temporaries or
+-variables that do not live across a call. Functions compiled this way
+-will not save and restore the register \fIreg\fR.
+-.Sp
+-It is an error to used this flag with the frame pointer or stack pointer.
+-Use of this flag for other registers that have fixed pervasive roles in
+-the machine's execution model will produce disastrous results.
+-.Sp
+-This flag does not have a negative form, because it specifies a
+-three-way choice.
+-.IP "\fB\-fcall\-saved\-\fR\fIreg\fR" 4
+-.IX Item "-fcall-saved-reg"
+-Treat the register named \fIreg\fR as an allocable register saved by
+-functions. It may be allocated even for temporaries or variables that
+-live across a call. Functions compiled this way will save and restore
+-the register \fIreg\fR if they use it.
+-.Sp
+-It is an error to used this flag with the frame pointer or stack pointer.
+-Use of this flag for other registers that have fixed pervasive roles in
+-the machine's execution model will produce disastrous results.
+-.Sp
+-A different sort of disaster will result from the use of this flag for
+-a register in which function values may be returned.
+-.Sp
+-This flag does not have a negative form, because it specifies a
+-three-way choice.
+-.IP "\fB\-fpack\-struct\fR" 4
+-.IX Item "-fpack-struct"
+-Pack all structure members together without holes.
+-.Sp
+-\&\fBWarning:\fR the \fB\-fpack\-struct\fR switch causes \s-1GCC\s0 to generate
+-code that is not binary compatible with code generated without that switch.
+-Additionally, it makes the code suboptimal.
+-Use it to conform to a non-default application binary interface.
+-.IP "\fB\-finstrument\-functions\fR" 4
+-.IX Item "-finstrument-functions"
+-Generate instrumentation calls for entry and exit to functions. Just
+-after function entry and just before function exit, the following
+-profiling functions will be called with the address of the current
+-function and its call site. (On some platforms,
+-\&\f(CW\*(C`_\|_builtin_return_address\*(C'\fR does not work beyond the current
+-function, so the call site information may not be available to the
+-profiling functions otherwise.)
+-.Sp
+-.Vb 4
+-\& void __cyg_profile_func_enter (void *this_fn,
+-\& void *call_site);
+-\& void __cyg_profile_func_exit (void *this_fn,
+-\& void *call_site);
+-.Ve
+-.Sp
+-The first argument is the address of the start of the current function,
+-which may be looked up exactly in the symbol table.
+-.Sp
+-This instrumentation is also done for functions expanded inline in other
+-functions. The profiling calls will indicate where, conceptually, the
+-inline function is entered and exited. This means that addressable
+-versions of such functions must be available. If all your uses of a
+-function are expanded inline, this may mean an additional expansion of
+-code size. If you use \fBextern inline\fR in your C code, an
+-addressable version of such functions must be provided. (This is
+-normally the case anyways, but if you get lucky and the optimizer always
+-expands the functions inline, you might have gotten away without
+-providing static copies.)
+-.Sp
+-A function may be given the attribute \f(CW\*(C`no_instrument_function\*(C'\fR, in
+-which case this instrumentation will not be done. This can be used, for
+-example, for the profiling functions listed above, high-priority
+-interrupt routines, and any functions from which the profiling functions
+-cannot safely be called (perhaps signal handlers, if the profiling
+-routines generate output or allocate memory).
+-.IP "\fB\-fstack\-check\fR" 4
+-.IX Item "-fstack-check"
+-Generate code to verify that you do not go beyond the boundary of the
+-stack. You should specify this flag if you are running in an
+-environment with multiple threads, but only rarely need to specify it in
+-a single-threaded environment since stack overflow is automatically
+-detected on nearly all systems if there is only one stack.
+-.Sp
+-Note that this switch does not actually cause checking to be done; the
+-operating system must do that. The switch causes generation of code
+-to ensure that the operating system sees the stack being extended.
+-.IP "\fB\-fstack\-limit\-register=\fR\fIreg\fR" 4
+-.IX Item "-fstack-limit-register=reg"
+-.PD 0
+-.IP "\fB\-fstack\-limit\-symbol=\fR\fIsym\fR" 4
+-.IX Item "-fstack-limit-symbol=sym"
+-.IP "\fB\-fno\-stack\-limit\fR" 4
+-.IX Item "-fno-stack-limit"
+-.PD
+-Generate code to ensure that the stack does not grow beyond a certain value,
+-either the value of a register or the address of a symbol. If the stack
+-would grow beyond the value, a signal is raised. For most targets,
+-the signal is raised before the stack overruns the boundary, so
+-it is possible to catch the signal without taking special precautions.
+-.Sp
+-For instance, if the stack starts at absolute address \fB0x80000000\fR
+-and grows downwards, you can use the flags
+-\&\fB\-fstack\-limit\-symbol=_\|_stack_limit\fR and
+-\&\fB\-Wl,\-\-defsym,_\|_stack_limit=0x7ffe0000\fR to enforce a stack limit
+-of 128KB. Note that this may only work with the \s-1GNU\s0 linker.
+-.IP "\fB\-fargument\-alias\fR" 4
+-.IX Item "-fargument-alias"
+-.PD 0
+-.IP "\fB\-fargument\-noalias\fR" 4
+-.IX Item "-fargument-noalias"
+-.IP "\fB\-fargument\-noalias\-global\fR" 4
+-.IX Item "-fargument-noalias-global"
+-.PD
+-Specify the possible relationships among parameters and between
+-parameters and global data.
+-.Sp
+-\&\fB\-fargument\-alias\fR specifies that arguments (parameters) may
+-alias each other and may alias global storage.\fB\-fargument\-noalias\fR specifies that arguments do not alias
+-each other, but may alias global storage.\fB\-fargument\-noalias\-global\fR specifies that arguments do not
+-alias each other and do not alias global storage.
+-.Sp
+-Each language will automatically use whatever option is required by
+-the language standard. You should not need to use these options yourself.
+-.IP "\fB\-fleading\-underscore\fR" 4
+-.IX Item "-fleading-underscore"
+-This option and its counterpart, \fB\-fno\-leading\-underscore\fR, forcibly
+-change the way C symbols are represented in the object file. One use
+-is to help link with legacy assembly code.
+-.Sp
+-\&\fBWarning:\fR the \fB\-fleading\-underscore\fR switch causes \s-1GCC\s0 to
+-generate code that is not binary compatible with code generated without that
+-switch. Use it to conform to a non-default application binary interface.
+-Not all targets provide complete support for this switch.
+-.IP "\fB\-ftls\-model=\fR\fImodel\fR" 4
+-.IX Item "-ftls-model=model"
+-Alter the thread-local storage model to be used.
+-The \fImodel\fR argument should be one of \f(CW\*(C`global\-dynamic\*(C'\fR,
+-\&\f(CW\*(C`local\-dynamic\*(C'\fR, \f(CW\*(C`initial\-exec\*(C'\fR or \f(CW\*(C`local\-exec\*(C'\fR.
+-.Sp
+-The default without \fB\-fpic\fR is \f(CW\*(C`initial\-exec\*(C'\fR; with
+-\&\fB\-fpic\fR the default is \f(CW\*(C`global\-dynamic\*(C'\fR.
+-.SH "ENVIRONMENT"
+-.IX Header "ENVIRONMENT"
+-This section describes several environment variables that affect how \s-1GCC\s0
+-operates. Some of them work by specifying directories or prefixes to use
+-when searching for various kinds of files. Some are used to specify other
+-aspects of the compilation environment.
+-.PP
+-Note that you can also specify places to search using options such as
+-\&\fB\-B\fR, \fB\-I\fR and \fB\-L\fR. These
+-take precedence over places specified using environment variables, which
+-in turn take precedence over those specified by the configuration of \s-1GCC\s0.
+-.IP "\fB\s-1LANG\s0\fR" 4
+-.IX Item "LANG"
+-.PD 0
+-.IP "\fB\s-1LC_CTYPE\s0\fR" 4
+-.IX Item "LC_CTYPE"
+-.IP "\fB\s-1LC_MESSAGES\s0\fR" 4
+-.IX Item "LC_MESSAGES"
+-.IP "\fB\s-1LC_ALL\s0\fR" 4
+-.IX Item "LC_ALL"
+-.PD
+-These environment variables control the way that \s-1GCC\s0 uses
+-localization information that allow \s-1GCC\s0 to work with different
+-national conventions. \s-1GCC\s0 inspects the locale categories
+-\&\fB\s-1LC_CTYPE\s0\fR and \fB\s-1LC_MESSAGES\s0\fR if it has been configured to do
+-so. These locale categories can be set to any value supported by your
+-installation. A typical value is \fBen_UK\fR for English in the United
+-Kingdom.
+-.Sp
+-The \fB\s-1LC_CTYPE\s0\fR environment variable specifies character
+-classification. \s-1GCC\s0 uses it to determine the character boundaries in
+-a string; this is needed for some multibyte encodings that contain quote
+-and escape characters that would otherwise be interpreted as a string
+-end or escape.
+-.Sp
+-The \fB\s-1LC_MESSAGES\s0\fR environment variable specifies the language to
+-use in diagnostic messages.
+-.Sp
+-If the \fB\s-1LC_ALL\s0\fR environment variable is set, it overrides the value
+-of \fB\s-1LC_CTYPE\s0\fR and \fB\s-1LC_MESSAGES\s0\fR; otherwise, \fB\s-1LC_CTYPE\s0\fR
+-and \fB\s-1LC_MESSAGES\s0\fR default to the value of the \fB\s-1LANG\s0\fR
+-environment variable. If none of these variables are set, \s-1GCC\s0
+-defaults to traditional C English behavior.
+-.IP "\fB\s-1TMPDIR\s0\fR" 4
+-.IX Item "TMPDIR"
+-If \fB\s-1TMPDIR\s0\fR is set, it specifies the directory to use for temporary
+-files. \s-1GCC\s0 uses temporary files to hold the output of one stage of
+-compilation which is to be used as input to the next stage: for example,
+-the output of the preprocessor, which is the input to the compiler
+-proper.
+-.IP "\fB\s-1GCC_EXEC_PREFIX\s0\fR" 4
+-.IX Item "GCC_EXEC_PREFIX"
+-If \fB\s-1GCC_EXEC_PREFIX\s0\fR is set, it specifies a prefix to use in the
+-names of the subprograms executed by the compiler. No slash is added
+-when this prefix is combined with the name of a subprogram, but you can
+-specify a prefix that ends with a slash if you wish.
+-.Sp
+-If \fB\s-1GCC_EXEC_PREFIX\s0\fR is not set, \s-1GCC\s0 will attempt to figure out
+-an appropriate prefix to use based on the pathname it was invoked with.
+-.Sp
+-If \s-1GCC\s0 cannot find the subprogram using the specified prefix, it
+-tries looking in the usual places for the subprogram.
+-.Sp
+-The default value of \fB\s-1GCC_EXEC_PREFIX\s0\fR is
+-\&\fI\fIprefix\fI/lib/gcc\-lib/\fR where \fIprefix\fR is the value
+-of \f(CW\*(C`prefix\*(C'\fR when you ran the \fIconfigure\fR script.
+-.Sp
+-Other prefixes specified with \fB\-B\fR take precedence over this prefix.
+-.Sp
+-This prefix is also used for finding files such as \fIcrt0.o\fR that are
+-used for linking.
+-.Sp
+-In addition, the prefix is used in an unusual way in finding the
+-directories to search for header files. For each of the standard
+-directories whose name normally begins with \fB/usr/local/lib/gcc\-lib\fR
+-(more precisely, with the value of \fB\s-1GCC_INCLUDE_DIR\s0\fR), \s-1GCC\s0 tries
+-replacing that beginning with the specified prefix to produce an
+-alternate directory name. Thus, with \fB\-Bfoo/\fR, \s-1GCC\s0 will search
+-\&\fIfoo/bar\fR where it would normally search \fI/usr/local/lib/bar\fR.
+-These alternate directories are searched first; the standard directories
+-come next.
+-.IP "\fB\s-1COMPILER_PATH\s0\fR" 4
+-.IX Item "COMPILER_PATH"
+-The value of \fB\s-1COMPILER_PATH\s0\fR is a colon-separated list of
+-directories, much like \fB\s-1PATH\s0\fR. \s-1GCC\s0 tries the directories thus
+-specified when searching for subprograms, if it can't find the
+-subprograms using \fB\s-1GCC_EXEC_PREFIX\s0\fR.
+-.IP "\fB\s-1LIBRARY_PATH\s0\fR" 4
+-.IX Item "LIBRARY_PATH"
+-The value of \fB\s-1LIBRARY_PATH\s0\fR is a colon-separated list of
+-directories, much like \fB\s-1PATH\s0\fR. When configured as a native compiler,
+-\&\s-1GCC\s0 tries the directories thus specified when searching for special
+-linker files, if it can't find them using \fB\s-1GCC_EXEC_PREFIX\s0\fR. Linking
+-using \s-1GCC\s0 also uses these directories when searching for ordinary
+-libraries for the \fB\-l\fR option (but directories specified with
+-\&\fB\-L\fR come first).
+-.IP "\fB\s-1LANG\s0\fR" 4
+-.IX Item "LANG"
+-This variable is used to pass locale information to the compiler. One way in
+-which this information is used is to determine the character set to be used
+-when character literals, string literals and comments are parsed in C and \*(C+.
+-When the compiler is configured to allow multibyte characters,
+-the following values for \fB\s-1LANG\s0\fR are recognized:
+-.RS 4
+-.IP "\fBC\-JIS\fR" 4
+-.IX Item "C-JIS"
+-Recognize \s-1JIS\s0 characters.
+-.IP "\fBC\-SJIS\fR" 4
+-.IX Item "C-SJIS"
+-Recognize \s-1SJIS\s0 characters.
+-.IP "\fBC\-EUCJP\fR" 4
+-.IX Item "C-EUCJP"
+-Recognize \s-1EUCJP\s0 characters.
+-.RE
+-.RS 4
+-.Sp
+-If \fB\s-1LANG\s0\fR is not defined, or if it has some other value, then the
+-compiler will use mblen and mbtowc as defined by the default locale to
+-recognize and translate multibyte characters.
+-.RE
+-.PP
+-Some additional environments variables affect the behavior of the
+-preprocessor.
+-.IP "\fB\s-1CPATH\s0\fR" 4
+-.IX Item "CPATH"
+-.PD 0
+-.IP "\fBC_INCLUDE_PATH\fR" 4
+-.IX Item "C_INCLUDE_PATH"
+-.IP "\fB\s-1CPLUS_INCLUDE_PATH\s0\fR" 4
+-.IX Item "CPLUS_INCLUDE_PATH"
+-.IP "\fB\s-1OBJC_INCLUDE_PATH\s0\fR" 4
+-.IX Item "OBJC_INCLUDE_PATH"
+-.PD
+-Each variable's value is a list of directories separated by a special
+-character, much like \fB\s-1PATH\s0\fR, in which to look for header files.
+-The special character, \f(CW\*(C`PATH_SEPARATOR\*(C'\fR, is target-dependent and
+-determined at \s-1GCC\s0 build time. For Windows-based targets it is a
+-semicolon, and for almost all other targets it is a colon.
+-.Sp
+-\&\fB\s-1CPATH\s0\fR specifies a list of directories to be searched as if
+-specified with \fB\-I\fR, but after any paths given with \fB\-I\fR
+-options on the command line. This environment variable is used
+-regardless of which language is being preprocessed.
+-.Sp
+-The remaining environment variables apply only when preprocessing the
+-particular language indicated. Each specifies a list of directories
+-to be searched as if specified with \fB\-isystem\fR, but after any
+-paths given with \fB\-isystem\fR options on the command line.
+-.Sp
+-In all these variables, an empty element instructs the compiler to
+-search its current working directory. Empty elements can appear at the
+-beginning or end of a path. For instance, if the value of
+-\&\fB\s-1CPATH\s0\fR is \f(CW\*(C`:/special/include\*(C'\fR, that has the same
+-effect as \fB\-I.\ \-I/special/include\fR.
+-.IP "\fB\s-1DEPENDENCIES_OUTPUT\s0\fR" 4
+-.IX Item "DEPENDENCIES_OUTPUT"
+-If this variable is set, its value specifies how to output
+-dependencies for Make based on the non-system header files processed
+-by the compiler. System header files are ignored in the dependency
+-output.
+-.Sp
+-The value of \fB\s-1DEPENDENCIES_OUTPUT\s0\fR can be just a file name, in
+-which case the Make rules are written to that file, guessing the target
+-name from the source file name. Or the value can have the form
+-\&\fIfile\fR\fB \fR\fItarget\fR, in which case the rules are written to
+-file \fIfile\fR using \fItarget\fR as the target name.
+-.Sp
+-In other words, this environment variable is equivalent to combining
+-the options \fB\-MM\fR and \fB\-MF\fR,
+-with an optional \fB\-MT\fR switch too.
+-.IP "\fB\s-1SUNPRO_DEPENDENCIES\s0\fR" 4
+-.IX Item "SUNPRO_DEPENDENCIES"
+-This variable is the same as \fB\s-1DEPENDENCIES_OUTPUT\s0\fR (see above),
+-except that system header files are not ignored, so it implies
+-\&\fB\-M\fR rather than \fB\-MM\fR. However, the dependence on the
+-main input file is omitted.
+-.SH "BUGS"
+-.IX Header "BUGS"
+-For instructions on reporting bugs, see
+-<\fBhttp://gcc.gnu.org/bugs.html\fR>. Use of the \fBgccbug\fR
+-script to report bugs is recommended.
+-.SH "FOOTNOTES"
+-.IX Header "FOOTNOTES"
+-.IP "1." 4
+-On some systems, \fBgcc \-shared\fR
+-needs to build supplementary stub code for constructors to work. On
+-multi-libbed systems, \fBgcc \-shared\fR must select the correct support
+-libraries to link against. Failing to supply the correct flags may lead
+-to subtle defects. Supplying them in cases where they are not necessary
+-is innocuous.
+-.SH "SEE ALSO"
+-.IX Header "SEE ALSO"
+-\&\fIgpl\fR\|(7), \fIgfdl\fR\|(7), \fIfsf\-funding\fR\|(7),
+-\&\fIcpp\fR\|(1), \fIgcov\fR\|(1), \fIg77\fR\|(1), \fIas\fR\|(1), \fIld\fR\|(1), \fIgdb\fR\|(1), \fIadb\fR\|(1), \fIdbx\fR\|(1), \fIsdb\fR\|(1)
+-and the Info entries for \fIgcc\fR, \fIcpp\fR, \fIg77\fR, \fIas\fR,
+-\&\fIld\fR, \fIbinutils\fR and \fIgdb\fR.
+-.SH "AUTHOR"
+-.IX Header "AUTHOR"
+-See the Info entry for \fBgcc\fR, or
+-<\fBhttp://gcc.gnu.org/onlinedocs/gcc/Contributors.html\fR>,
+-for contributors to \s-1GCC\s0.
+-.SH "COPYRIGHT"
+-.IX Header "COPYRIGHT"
+-Copyright (c) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
+-1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+-.PP
+-Permission is granted to copy, distribute and/or modify this document
+-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.2 or
+-any later version published by the Free Software Foundation; with the
+-Invariant Sections being ``\s-1GNU\s0 General Public License'' and ``Funding
+-Free Software'', the Front-Cover texts being (a) (see below), and with
+-the Back-Cover Texts being (b) (see below). A copy of the license is
+-included in the \fIgfdl\fR\|(7) man page.
+-.PP
+-(a) The \s-1FSF\s0's Front-Cover Text is:
+-.PP
+-.Vb 1
+-\& A GNU Manual
+-.Ve
+-.PP
+-(b) The \s-1FSF\s0's Back-Cover Text is:
+-.PP
+-.Vb 3
+-\& You have freedom to copy and modify this GNU Manual, like GNU
+-\& software. Copies published by the Free Software Foundation raise
+-\& funds for GNU development.
+-.Ve
++timestamp
+diff -u -r -N gcc-3.3.6-core-orig/gcc/doc/invoke.texi gcc-3.3.6/gcc/doc/invoke.texi
+--- gcc-3.3.6-core-orig/gcc/doc/invoke.texi 2005-04-22 07:52:33.000000000 +0100
++++ gcc-3.3.6/gcc/doc/invoke.texi 2010-11-09 20:47:16.000000000 +0000
+@@ -329,7 +329,7 @@
+
+ @emph{M68hc1x Options}
+ @gccoptlist{-m6811 -m6812 -m68hc11 -m68hc12 -m68hcs12 @gol
+--mauto-incdec -minmax -mlong-calls -mshort @gol
++-mauto-incdec -minmax -mlong-calls -mrelax -mshort @gol
+ -msoft-reg-count=@var{count}}
+
+ @emph{VAX Options}
+@@ -5624,7 +5624,20 @@
+ @opindex mno-long-calls
+ Treat all calls as being far away (near). If calls are assumed to be
+ far away, the compiler will use the @code{call} instruction to
+-call a function and the @code{rtc} instruction for returning.
++call a function and the @code{rtc} instruction for returning. An interrupt
++or a trap handler is not affected by this option and is always considered near.
++
++@item -mrelax
++@opindex mrelax
++Indicate to the compiler and linker that they should perform a relaxation
++optimization pass to shorten branches, calls and absolute memory addresses.
++The compiler will not use direct addressing mode for pseudo-soft registers and
++it will also emit some @code{bset} and @code{bclr} sequences that can be
++optimized by the linker. The linker option @option{-relax} will be used
++and the linker will transform 16-bit addressing modes into direct addressing
++modes if possible.
++
++This option makes symbolic debugging impossible.
+
+ @item -mshort
+ @opindex mshort
+diff -u -r -N gcc-3.3.6-core-orig/gcc/expmed.c gcc-3.3.6/gcc/expmed.c
+--- gcc-3.3.6-core-orig/gcc/expmed.c 2005-04-30 17:01:29.000000000 +0100
++++ gcc-3.3.6/gcc/expmed.c 2010-11-09 20:47:16.000000000 +0000
+@@ -474,6 +474,15 @@
+ result in an abort. */
+ fieldmode = smallest_mode_for_size (nwords * BITS_PER_WORD, MODE_INT);
+
++ /* When the value is a constant, the constant_subword applies a
++ correction on big endian targets. If the bitfield contains less words
++ than the value (fieldmode), the constant that is extracted is shifted
++ by the word difference. Example: bitfield = 33, fieldmode = DImode
++ and constant_subword extracts word 1 2 3 instead of 0 1 2. */
++ int correction = 0;
++ if (WORDS_BIG_ENDIAN && CONSTANT_P (value))
++ correction = GET_MODE_BITSIZE (fieldmode) / BITS_PER_WORD - nwords;
++
+ for (i = 0; i < nwords; i++)
+ {
+ /* If I is 0, use the low-order word in both field and target;
+@@ -488,7 +497,7 @@
+ store_bit_field (op0, MIN (BITS_PER_WORD,
+ bitsize - i * BITS_PER_WORD),
+ bitnum + bit_offset, word_mode,
+- operand_subword_force (value, wordnum,
++ operand_subword_force (value, correction + wordnum,
+ (GET_MODE (value) == VOIDmode
+ ? fieldmode
+ : GET_MODE (value))),
+@@ -2142,7 +2151,7 @@
+ if ((t & 1) == 0)
+ {
+ m = floor_log2 (t & -t); /* m = number of low zero bits */
+- if (m < BITS_PER_WORD)
++ if (m < MAX_BITS_PER_WORD)
+ {
+ q = t >> m;
+ cost = shift_cost[m];
+@@ -2227,7 +2236,7 @@
+ unsigned HOST_WIDE_INT d;
+
+ d = ((unsigned HOST_WIDE_INT) 1 << m) + 1;
+- if (t % d == 0 && t > d && m < BITS_PER_WORD)
++ if (t % d == 0 && t > d && m < MAX_BITS_PER_WORD)
+ {
+ cost = MIN (shiftadd_cost[m], add_cost + shift_cost[m]);
+ synth_mult (alg_in, t / d, cost_limit - cost);
+@@ -2246,7 +2255,7 @@
+ }
+
+ d = ((unsigned HOST_WIDE_INT) 1 << m) - 1;
+- if (t % d == 0 && t > d && m < BITS_PER_WORD)
++ if (t % d == 0 && t > d && m < MAX_BITS_PER_WORD)
+ {
+ cost = MIN (shiftsub_cost[m], add_cost + shift_cost[m]);
+ synth_mult (alg_in, t / d, cost_limit - cost);
+@@ -2271,7 +2280,7 @@
+ q = t - 1;
+ q = q & -q;
+ m = exact_log2 (q);
+- if (m >= 0 && m < BITS_PER_WORD)
++ if (m >= 0 && m < MAX_BITS_PER_WORD)
+ {
+ cost = shiftadd_cost[m];
+ synth_mult (alg_in, (t - 1) >> m, cost_limit - cost);
+@@ -2290,7 +2299,7 @@
+ q = t + 1;
+ q = q & -q;
+ m = exact_log2 (q);
+- if (m >= 0 && m < BITS_PER_WORD)
++ if (m >= 0 && m < MAX_BITS_PER_WORD)
+ {
+ cost = shiftsub_cost[m];
+ synth_mult (alg_in, (t + 1) >> m, cost_limit - cost);
+@@ -2793,7 +2802,7 @@
+
+ /* expand_mult handles constant multiplication of word_mode
+ or narrower. It does a poor job for large modes. */
+- if (size < BITS_PER_WORD
++ if (size < MAX_BITS_PER_WORD
+ && mul_cost[(int) wider_mode] + shift_cost[size-1] < max_cost)
+ {
+ /* We have to do this, since expand_binop doesn't do conversion for
+@@ -2824,7 +2833,7 @@
+
+ /* Secondly, same as above, but use sign flavor opposite of unsignedp.
+ Need to adjust the result after the multiplication. */
+- if (size - 1 < BITS_PER_WORD
++ if (size - 1 < MAX_BITS_PER_WORD
+ && (mul_highpart_cost[(int) mode] + 2 * shift_cost[size-1] + 4 * add_cost
+ < max_cost))
+ {
+@@ -2849,7 +2858,7 @@
+ /* Try widening the mode and perform a non-widening multiplication. */
+ moptab = smul_optab;
+ if (smul_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
+- && size - 1 < BITS_PER_WORD
++ && size - 1 < MAX_BITS_PER_WORD
+ && mul_cost[(int) wider_mode] + shift_cost[size-1] < max_cost)
+ {
+ op1 = wide_op1;
+@@ -2859,7 +2868,7 @@
+ /* Try widening multiplication of opposite signedness, and adjust. */
+ moptab = unsignedp ? smul_widen_optab : umul_widen_optab;
+ if (moptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
+- && size - 1 < BITS_PER_WORD
++ && size - 1 < MAX_BITS_PER_WORD
+ && (mul_widen_cost[(int) wider_mode]
+ + 2 * shift_cost[size-1] + 4 * add_cost < max_cost))
+ {
+@@ -3199,7 +3208,7 @@
+ {
+ rtx t1, t2, t3, t4;
+
+- if (post_shift - 1 >= BITS_PER_WORD)
++ if (post_shift - 1 >= MAX_BITS_PER_WORD)
+ goto fail1;
+
+ extra_cost = (shift_cost[post_shift - 1]
+@@ -3226,8 +3235,8 @@
+ {
+ rtx t1, t2;
+
+- if (pre_shift >= BITS_PER_WORD
+- || post_shift >= BITS_PER_WORD)
++ if (pre_shift >= MAX_BITS_PER_WORD
++ || post_shift >= MAX_BITS_PER_WORD)
+ goto fail1;
+
+ t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
+@@ -3363,8 +3372,8 @@
+ {
+ rtx t1, t2, t3;
+
+- if (post_shift >= BITS_PER_WORD
+- || size - 1 >= BITS_PER_WORD)
++ if (post_shift >= MAX_BITS_PER_WORD
++ || size - 1 >= MAX_BITS_PER_WORD)
+ goto fail1;
+
+ extra_cost = (shift_cost[post_shift]
+@@ -3393,8 +3402,8 @@
+ {
+ rtx t1, t2, t3, t4;
+
+- if (post_shift >= BITS_PER_WORD
+- || size - 1 >= BITS_PER_WORD)
++ if (post_shift >= MAX_BITS_PER_WORD
++ || size - 1 >= MAX_BITS_PER_WORD)
+ goto fail1;
+
+ ml |= (~(unsigned HOST_WIDE_INT) 0) << (size - 1);
+@@ -3480,8 +3489,8 @@
+ if (mh)
+ abort ();
+
+- if (post_shift < BITS_PER_WORD
+- && size - 1 < BITS_PER_WORD)
++ if (post_shift < MAX_BITS_PER_WORD
++ && size - 1 < MAX_BITS_PER_WORD)
+ {
+ t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
+ build_int_2 (size - 1, 0),
+@@ -4135,8 +4144,12 @@
+
+ case SIGN_EXTEND:
+ case ZERO_EXTEND:
+- t = (*lang_hooks.types.type_for_mode) (GET_MODE (XEXP (x, 0)),
+- GET_CODE (x) == ZERO_EXTEND);
++ if (CONSTANT_P (XEXP (x, 0)))
++ t = (*lang_hooks.types.type_for_mode) (GET_MODE (x),
++ GET_CODE (x) == ZERO_EXTEND);
++ else
++ t = (*lang_hooks.types.type_for_mode) (GET_MODE (XEXP (x, 0)),
++ GET_CODE (x) == ZERO_EXTEND);
+ return fold (convert (type, make_tree (t, XEXP (x, 0))));
+
+ default:
+diff -u -r -N gcc-3.3.6-core-orig/gcc/final.c gcc-3.3.6/gcc/final.c
+--- gcc-3.3.6-core-orig/gcc/final.c 2003-12-01 08:18:36.000000000 +0000
++++ gcc-3.3.6/gcc/final.c 2010-11-09 20:47:16.000000000 +0000
+@@ -2909,7 +2909,22 @@
+ /* simplify_subreg does not remove subreg from volatile references.
+ We are required to. */
+ if (GET_CODE (y) == MEM)
+- *xp = adjust_address (y, GET_MODE (x), SUBREG_BYTE (x));
++ {
++ unsigned outer_size = GET_MODE_SIZE (GET_MODE (x));
++ unsigned inner_size = GET_MODE_SIZE (GET_MODE (y));
++ int offset = SUBREG_BYTE (x);
++
++ /* If this is a paradoxical subreg with a SUBREG_BYTE set
++ to 0 we must adjust the offset for big-endian machines
++ (otherwise we take the address of the high part). */
++ if (BYTES_BIG_ENDIAN && !offset && outer_size > inner_size)
++ {
++ offset += MIN (inner_size, UNITS_PER_WORD);
++ offset -= MIN (outer_size, UNITS_PER_WORD);
++ }
++
++ *xp = adjust_address (y, GET_MODE (x), offset);
++ }
+ else
+ {
+ rtx new = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
+diff -u -r -N gcc-3.3.6-core-orig/gcc/flow.c gcc-3.3.6/gcc/flow.c
+--- gcc-3.3.6-core-orig/gcc/flow.c 2004-12-04 00:36:35.000000000 +0000
++++ gcc-3.3.6/gcc/flow.c 2010-11-09 20:47:16.000000000 +0000
+@@ -571,7 +571,7 @@
+ fputs ("Old:\n", rtl_dump_file);
+ dump_bb (bb, rtl_dump_file);
+ }
+- abort ();
++ // SCz: abort ();
+ }
+ }
+ else
+diff -u -r -N gcc-3.3.6-core-orig/gcc/gcse.c gcc-3.3.6/gcc/gcse.c
+--- gcc-3.3.6-core-orig/gcc/gcse.c 2003-12-20 19:59:50.000000000 +0000
++++ gcc-3.3.6/gcc/gcse.c 2010-11-09 20:47:16.000000000 +0000
+@@ -3513,8 +3513,7 @@
+ /* ??? If the change fails, we return 0, even though we created
+ an insn. I think this is ok. */
+ new_insn
+- = emit_insn_after (gen_rtx_SET (VOIDmode, to,
+- SET_DEST (expr_set)),
++ = emit_insn_after (gen_move_insn (to, SET_DEST (expr_set)),
+ insn_computes_expr);
+
+ /* Keep register set table up to date. */
+@@ -3525,7 +3524,7 @@
+ {
+ fprintf (gcse_file, "GCSE: Creating insn %d to copy value of reg %d",
+ INSN_UID (NEXT_INSN (insn_computes_expr)),
+- REGNO (SET_SRC (PATTERN (NEXT_INSN (insn_computes_expr)))));
++ REGNO (SET_DEST (expr_set)));
+ fprintf (gcse_file, ", computed in insn %d,\n",
+ INSN_UID (insn_computes_expr));
+ fprintf (gcse_file, " into newly allocated reg %d\n",
+diff -u -r -N gcc-3.3.6-core-orig/gcc/libgcc2.c gcc-3.3.6/gcc/libgcc2.c
+--- gcc-3.3.6-core-orig/gcc/libgcc2.c 2002-10-23 11:47:24.000000000 +0100
++++ gcc-3.3.6/gcc/libgcc2.c 2010-11-09 20:47:16.000000000 +0000
+@@ -490,7 +490,12 @@
+
+ #if (defined (L_udivdi3) || defined (L_divdi3) || \
+ defined (L_umoddi3) || defined (L_moddi3))
+-#define L_udivmoddi4
++#if !defined(mc6811) && !defined(mc6812)
++# define L_udivmoddi4
++#else
++extern UDWtype
++__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp);
++#endif
+ #endif
+
+ #ifdef L_clz
+diff -u -r -N gcc-3.3.6-core-orig/gcc/longlong.h gcc-3.3.6/gcc/longlong.h
+--- gcc-3.3.6-core-orig/gcc/longlong.h 2002-10-03 21:39:08.000000000 +0100
++++ gcc-3.3.6/gcc/longlong.h 2010-11-09 20:47:16.000000000 +0000
+@@ -1162,6 +1162,67 @@
+
+ #endif /* __GNUC__ */
+
++#if defined(mc6811) || defined(mc6812)
++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
++ do { \
++ __asm__ ("subd 2+%2\n" \
++ "\txgdx\n" \
++ "\tsbcb 1+%2\n" \
++ "\tsbca %2\n" \
++ "\txgdx" : "=D"((USItype) (sl)) \
++ : "0"((USItype) (al)), "m"((USItype) (bl))); \
++ /* Assumes that the carry is not modified. */ \
++ /* which is true since the reload instructions */ \
++ /* generated between the two __asm__ only do load/store. */ \
++ __asm__ ("sbcb 3+%2\n" \
++ "\tsbca 2+%2\n" \
++ "\txgdx\n" \
++ "\tsbcb 1+%2\n" \
++ "\tsbca %2\n" \
++ "\txgdx" : "=D"((USItype) (sh)) \
++ : "0"((USItype) (ah)), "m"((USItype) (bh))); \
++ } while (0)
++#if defined(mc6812)
++#define umul_ppmm(w1, w0, u, v) \
++ do { \
++ UWtype __x0, __x1, __x2, __x3; \
++ \
++ __x0 = ((UWtype) ((UHItype) __ll_lowpart (u))) * ((UWtype) ((UHItype) __ll_lowpart (v))); \
++ __x1 = ((UWtype) ((UHItype) __ll_lowpart (u))) * ((UWtype) ((UHItype) __ll_highpart (v))); \
++ __x2 = ((UWtype) ((UHItype) __ll_highpart (u))) * ((UWtype) ((UHItype) __ll_lowpart (v))); \
++ __x3 = ((UWtype) ((UHItype) __ll_highpart (u))) * ((UWtype) ((UHItype) __ll_highpart (v))); \
++ \
++ __x1 += __ll_highpart (__x0);/* this can't give carry */ \
++ __x1 += __x2; /* but this indeed can */ \
++ __asm__ ("bcc 1f\n" \
++ "\tinx\n" \
++ "1:" : "=D"(__x3) : "0"(__x3)); \
++ \
++ (w1) = __x3 + __ll_highpart (__x1); \
++ (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
++ } while (0)
++#else
++#define umul_ppmm(w1, w0, u, v) \
++ do { \
++ UWtype __x0, __x1, __x2, __x3; \
++ extern UWtype __attribute__((near)) __mulhi32 (UHItype, UHItype); \
++ \
++ __x0 = __mulhi32 (__ll_lowpart (u), __ll_lowpart (v)); \
++ __x1 = __mulhi32 (__ll_lowpart (u), __ll_highpart (v)); \
++ __x2 = __mulhi32 (__ll_highpart (u), __ll_lowpart (v)); \
++ __x3 = __mulhi32 (__ll_highpart (u), __ll_highpart (v)); \
++ \
++ __x1 += __ll_highpart (__x0);/* this can't give carry */ \
++ __x1 += __x2; /* but this indeed can */ \
++ __asm__ ("bcc 1f\n" \
++ "\tinx\n" \
++ "1:" : "=D"(__x3) : "0"(__x3)); \
++ \
++ (w1) = __x3 + __ll_highpart (__x1); \
++ (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
++ } while (0)
++#endif
++#endif
+ /* If this machine has no inline assembler, use C macros. */
+
+ #if !defined (add_ssaaaa)
+@@ -1232,6 +1293,45 @@
+ #endif
+
+ /* Define this unconditionally, so it can be used for debugging. */
++#if defined(mc6811) || defined(mc6812)
++extern USItype __udivmodsi4(USItype num, USItype den, USItype* mod);
++
++#define __udiv_qrnnd_c(q, r, n1, n0, d) \
++ do { \
++ USItype __d1, __d0, __q1, __q0; \
++ USItype __r0, __m; \
++ __d1 = __ll_highpart (d); \
++ __d0 = __ll_lowpart (d); \
++ \
++ __q1 = __udivmodsi4 (n1,__d1,&__r0); \
++ __m = (USItype) __q1 * __d0; \
++ __r0 = __r0 * __ll_B | __ll_highpart (n0); \
++ if (__r0 < __m) \
++ { \
++ __q1--, __r0 += (d); \
++ if (__r0 >= (d)) /* i.e. we didn't get carry when adding to __r0 */\
++ if (__r0 < __m) \
++ __q1--, __r0 += (d); \
++ } \
++ __r0 -= __m; \
++ \
++ __q0 = __udivmodsi4 (__r0,__d1,&__r0); \
++ __m = (USItype) __q0 * __d0; \
++ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
++ if (__r0 < __m) \
++ { \
++ __q0--, __r0 += (d); \
++ if (__r0 >= (d)) \
++ if (__r0 < __m) \
++ __q0--, __r0 += (d); \
++ } \
++ __r0 -= __m; \
++ \
++ (q) = (USItype) __q1 * __ll_B | __q0; \
++ (r) = __r0; \
++ } while (0)
++#else
++/* Define this unconditionally, so it can be used for debugging. */
+ #define __udiv_qrnnd_c(q, r, n1, n0, d) \
+ do { \
+ UWtype __d1, __d0, __q1, __q0; \
+@@ -1268,6 +1368,7 @@
+ (q) = (UWtype) __q1 * __ll_B | __q0; \
+ (r) = __r0; \
+ } while (0)
++#endif
+
+ /* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
+ __udiv_w_sdiv (defined in libgcc or elsewhere). */
+diff -u -r -N gcc-3.3.6-core-orig/gcc/loop.c gcc-3.3.6/gcc/loop.c
+--- gcc-3.3.6-core-orig/gcc/loop.c 2004-05-30 00:27:30.000000000 +0100
++++ gcc-3.3.6/gcc/loop.c 2010-11-09 20:47:16.000000000 +0000
+@@ -4703,7 +4703,8 @@
+ this is an address giv, then try to put the increment
+ immediately after its use, so that flow can create an
+ auto-increment addressing mode. */
+- if (v->giv_type == DEST_ADDR && bl->biv_count == 1
++ if ((HAVE_POST_INCREMENT || HAVE_POST_DECREMENT)
++ && v->giv_type == DEST_ADDR && bl->biv_count == 1
+ && bl->biv->always_executed && ! bl->biv->maybe_multiple
+ /* We don't handle reversed biv's because bl->biv->insn
+ does not have a valid INSN_LUID. */
+@@ -8979,7 +8980,13 @@
+ || (GET_CODE (v->add_val) == REG
+ && REG_POINTER (v->add_val)))
+ && ! v->ignore && ! v->maybe_dead && v->always_computable
+- && v->mode == mode)
++ && v->mode == mode
++ /* SCz: There is a possible overflow here.
++ If we compare to a constant value, the constant is
++ re-computed (CST * mult_add + add_val) and there may
++ be an overflow. CST was 16399, mult was 8, and integers
++ are 16-bits. (execute/loop-3c.c, -Os -mshort). */
++ && 0)
+ {
+ if (! biv_elimination_giv_has_0_offset (bl->biv, v, insn))
+ continue;
+diff -u -r -N gcc-3.3.6-core-orig/gcc/regrename.c gcc-3.3.6/gcc/regrename.c
+--- gcc-3.3.6-core-orig/gcc/regrename.c 2002-11-04 16:57:02.000000000 +0000
++++ gcc-3.3.6/gcc/regrename.c 2010-11-09 20:47:16.000000000 +0000
+@@ -102,6 +102,9 @@
+ HARD_REG_SET *pset = (HARD_REG_SET *) data;
+ unsigned int regno;
+ int nregs;
++
++ if (GET_CODE (x) == SUBREG)
++ x = SUBREG_REG (x);
+ if (GET_CODE (x) != REG)
+ return;
+ regno = REGNO (x);
+@@ -292,6 +295,7 @@
+ for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
+ {
+ int nregs = HARD_REGNO_NREGS (new_reg, GET_MODE (*this->loc));
++ int mode = GET_MODE (*this->loc);
+
+ for (i = nregs - 1; i >= 0; --i)
+ if (TEST_HARD_REG_BIT (this_unavailable, new_reg + i)
+@@ -307,7 +311,7 @@
+ && !LEAF_REGISTERS[new_reg + i])
+ #endif
+ #ifdef HARD_REGNO_RENAME_OK
+- || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i)
++ || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i, mode)
+ #endif
+ )
+ break;
+diff -u -r -N gcc-3.3.6-core-orig/gcc/reload1.c gcc-3.3.6/gcc/reload1.c
+--- gcc-3.3.6-core-orig/gcc/reload1.c 2004-11-26 05:08:45.000000000 +0000
++++ gcc-3.3.6/gcc/reload1.c 2010-11-09 20:47:16.000000000 +0000
+@@ -1777,9 +1777,6 @@
+ if (best_reg == -1)
+ return 0;
+
+- if (rtl_dump_file)
+- fprintf (rtl_dump_file, "Using reg %d for reload %d\n", best_reg, rnum);
+-
+ rl->nregs = HARD_REGNO_NREGS (best_reg, rl->mode);
+ rl->regno = best_reg;
+
+@@ -1930,6 +1927,7 @@
+ {
+ error ("unable to find a register to spill in class `%s'",
+ reg_class_names[class]);
++
+ fatal_insn ("this is the insn:", insn);
+ }
+ }
+@@ -3979,7 +3977,7 @@
+ for this insn in order to be stored in
+ (obeying register constraints). That is correct; such reload
+ registers ARE still valid. */
+- note_stores (oldpat, forget_old_reloads_1, NULL);
++ note_stores (oldpat, forget_old_reloads_1, NULL);
+
+ /* There may have been CLOBBER insns placed after INSN. So scan
+ between INSN and NEXT and use them to forget old reloads. */
+@@ -4580,6 +4578,9 @@
+ case RELOAD_OTHER:
+ /* Since a RELOAD_OTHER reload claims the reg for the entire insn,
+ its value must reach the end. */
++ for (i = 0; i < reload_n_operands; i++)
++ if (TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
++ return 0;
+ return 1;
+
+ /* If this use is for part of the insn,
+@@ -5298,6 +5299,13 @@
+ CLEAR_HARD_REG_SET (reload_reg_used_in_insn);
+ CLEAR_HARD_REG_SET (reload_reg_used_in_other_addr);
+
++#if 0 /* TARGET_M68HC11 or NO_SPILL_REG_ROUND_ROBIN */
++ /* Don't use the round-robin fashion for allocation of spill registers.
++ If we use round-robin, the reload pass allocates Y and Z registers
++ which are expensive compared to X and D. */
++ last_spill_reg = -1;
++#endif
++
+ CLEAR_HARD_REG_SET (reg_used_in_insn);
+ {
+ HARD_REG_SET tmp;
+@@ -6037,6 +6045,29 @@
+ reload_spill_index[r] = -1;
+ }
+
++
++/* Returns true if merging reloads i and j should result in a
++ RELOAD_FOR_OTHER_ADDRESS reload, else false for RELOAD_OTHER. */
++static int
++merge_becomes_other_address (int i, int j)
++{
++ int wn1 = rld[i].when_needed;
++ int wn2 = rld[j].when_needed;
++
++ if (wn2 == RELOAD_FOR_OTHER_ADDRESS)
++ wn2 = wn1;
++ else if (wn1 != RELOAD_FOR_OTHER_ADDRESS)
++ return 0;
++
++ return (wn2 == RELOAD_FOR_INPUT_ADDRESS
++ || wn2 == RELOAD_FOR_INPADDR_ADDRESS
++ || wn2 == RELOAD_FOR_OUTPUT_ADDRESS
++ || wn2 == RELOAD_FOR_OUTADDR_ADDRESS
++ || wn2 == RELOAD_FOR_OPERAND_ADDRESS
++ || wn2 == RELOAD_FOR_OPADDR_ADDR
++ || wn2 == RELOAD_FOR_OTHER_ADDRESS);
++}
++
+ /* If SMALL_REGISTER_CLASSES is nonzero, we may not have merged two
+ reloads of the same item for fear that we might not have enough reload
+ registers. However, normally they will get the same reload register
+@@ -6050,6 +6081,7 @@
+ This will not increase the number of spill registers needed and will
+ prevent redundant code. */
+
++extern const char *const reload_when_needed_name[];
+ static void
+ merge_assigned_reloads (insn)
+ rtx insn;
+@@ -6114,6 +6146,7 @@
+ if (j == n_reloads
+ && max_input_address_opnum <= min_conflicting_input_opnum)
+ {
++ int changed = 0;
+ for (j = 0; j < n_reloads; j++)
+ if (i != j && rld[j].reg_rtx != 0
+ && rtx_equal_p (rld[i].reg_rtx, rld[j].reg_rtx)
+@@ -6121,12 +6154,22 @@
+ || rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS
+ || rld[j].when_needed == RELOAD_FOR_OTHER_ADDRESS))
+ {
+- rld[i].when_needed = RELOAD_OTHER;
++ if (merge_becomes_other_address (i, j))
++ rld[i].when_needed = RELOAD_FOR_OTHER_ADDRESS;
++ else
++ rld[i].when_needed = RELOAD_OTHER;
+ rld[j].in = 0;
+ reload_spill_index[j] = -1;
+ transfer_replacements (i, j);
++ changed = 1;
+ }
+
++ /* If this is now RELOAD_OTHER or RELOAD_FOR_OTHER_ADDRESS,
++ look for any reloads that load parts of this operand and
++ set them to RELOAD_FOR_OTHER_ADDRESS if they were for
++ inputs, RELOAD_OTHER for outputs. Note that this test is
++ equivalent to looking for reloads for this operand
++ number. */
+ /* If this is now RELOAD_OTHER, look for any reloads that load
+ parts of this operand and set them to RELOAD_FOR_OTHER_ADDRESS
+ if they were for inputs, RELOAD_OTHER for outputs. Note that
+@@ -6137,7 +6180,9 @@
+ same value or a part of it; we must not change its type if there
+ is a conflicting input. */
+
+- if (rld[i].when_needed == RELOAD_OTHER)
++ if (changed
++ && (rld[i].when_needed == RELOAD_OTHER
++ || rld[i].when_needed == RELOAD_FOR_OTHER_ADDRESS))
+ for (j = 0; j < n_reloads; j++)
+ if (rld[j].in != 0
+ && rld[j].when_needed != RELOAD_OTHER
+@@ -6152,7 +6197,8 @@
+
+ rld[j].when_needed
+ = ((rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS
+- || rld[j].when_needed == RELOAD_FOR_INPADDR_ADDRESS)
++ || rld[j].when_needed == RELOAD_FOR_INPADDR_ADDRESS
++ || rld[j].when_needed == RELOAD_FOR_OPADDR_ADDR)
+ ? RELOAD_FOR_OTHER_ADDRESS : RELOAD_OTHER);
+
+ /* Check to see if we accidentally converted two reloads
+@@ -6164,8 +6210,13 @@
+ if (rld[k].in != 0 && rld[k].reg_rtx != 0
+ && rld[k].when_needed == rld[j].when_needed
+ && rtx_equal_p (rld[k].reg_rtx, rld[j].reg_rtx)
+- && ! rtx_equal_p (rld[k].in, rld[j].in))
++ && ! rtx_equal_p (rld[k].in, rld[j].in)) {
++ printf("Changed reload %d, conflict %d with %d\n",
++ i, k, j);
++
+ abort ();
++ }
++
+ }
+ }
+ }
+@@ -7306,6 +7357,13 @@
+ rld[r].when_needed))
+ CLEAR_HARD_REG_BIT (reg_reloaded_valid, i + k);
+ }
++ else
++ {
++ /* When the reload does not reach the end, we must
++ invalidate the old info. */
++ for (k = 0; k < nr; k++)
++ CLEAR_HARD_REG_BIT (reg_reloaded_valid, i + k);
++ }
+ }
+
+ /* The following if-statement was #if 0'd in 1.34 (or before...).
+diff -u -r -N gcc-3.3.6-core-orig/gcc/reload.c gcc-3.3.6/gcc/reload.c
+--- gcc-3.3.6-core-orig/gcc/reload.c 2004-03-05 17:09:34.000000000 +0000
++++ gcc-3.3.6/gcc/reload.c 2010-11-09 20:47:16.000000000 +0000
+@@ -4216,6 +4216,20 @@
+
+ if (goal_alternative_matches[rld[i].opnum] >= 0)
+ rld[i].opnum = goal_alternative_matches[rld[i].opnum];
++
++ /* If an operand's reload is RELOAD_OTHER, change any
++ RELOAD_FOR_OPERAND_ADDRESS and RELOAD_FOR_OUTPUT_ADDRESS reloads
++ of that operand to RELOAD_FOR_OTHER_ADDRESS. This is necessary
++ to make sure the reloads are emitted in the good order. We only need
++ to scan backward. */
++ if (rld[i].when_needed == RELOAD_OTHER
++ && rld[i].optional == 0)
++ {
++ for (j = i - 1; j >= 0; j--)
++ if (rld[j].opnum == rld[i].opnum
++ && rld[j].when_needed == RELOAD_FOR_OPERAND_ADDRESS)
++ rld[j].when_needed = RELOAD_FOR_OTHER_ADDRESS;
++ }
+ }
+
+ /* Scan all the reloads, and check for RELOAD_FOR_OPERAND_ADDRESS reloads.
+@@ -4556,10 +4570,8 @@
+ force a reload in that case. So we should not do anything here. */
+
+ else if (regno >= FIRST_PSEUDO_REGISTER
+-#ifdef LOAD_EXTEND_OP
+ && (GET_MODE_SIZE (GET_MODE (x))
+ <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+-#endif
+ && (reg_equiv_address[regno] != 0
+ || (reg_equiv_mem[regno] != 0
+ && (! strict_memory_address_p (GET_MODE (x),
+@@ -5913,7 +5925,7 @@
+ }
+
+ find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
+- &XEXP (tem, 0), opnum, ADDR_TYPE (type),
++ &XEXP (tem, 0), opnum, type,
+ ind_levels, insn);
+
+ /* If this is not a toplevel operand, find_reloads doesn't see
+diff -u -r -N gcc-3.3.6-core-orig/gcc/toplev.c gcc-3.3.6/gcc/toplev.c
+--- gcc-3.3.6-core-orig/gcc/toplev.c 2004-03-05 17:55:51.000000000 +0000
++++ gcc-3.3.6/gcc/toplev.c 2010-11-09 20:47:16.000000000 +0000
+@@ -3101,7 +3101,10 @@
+ setjmp_args_warning ();
+ }
+
+- if (optimize)
++ /* SCz: PR target/5854, this is initializing registers by inserting
++ instructions before the prologue instructions that save incomming
++ registers. */
++ if (optimize && 0)
+ {
+ if (!flag_new_regalloc && initialize_uninitialized_subregs ())
+ {
+diff -u -r -N gcc-3.3.6-core-orig/gcc/version.c gcc-3.3.6/gcc/version.c
+--- gcc-3.3.6-core-orig/gcc/version.c 2005-05-03 11:56:18.000000000 +0100
++++ gcc-3.3.6/gcc/version.c 2010-11-09 20:47:16.000000000 +0000
+@@ -6,7 +6,7 @@
+ please modify this string to indicate that, e.g. by putting your
+ organization's name in parentheses at the end of the string. */
+
+-const char version_string[] = "3.3.6";
++const char version_string[] = "3.3.6-9s12x-20101028";
+
+ /* This is the location of the online document giving instructions for
+ reporting bugs. If you distribute a modified version of GCC,
diff --git a/misc/buildroot/toolchain/gcc/3.3.6/910-create-mode.patch b/misc/buildroot/toolchain/gcc/3.3.6/910-create-mode.patch
new file mode 100644
index 000000000..20a9e8378
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.3.6/910-create-mode.patch
@@ -0,0 +1,11 @@
+--- gcc-3.3.6/gcc/collect2.c 2011-04-06 18:36:17.269806677 -0600
++++ gcc-3.3.6/gcc/collect2.c 2011-04-06 18:36:34.385799826 -0600
+@@ -1580,7 +1580,7 @@
+ if (redir)
+ {
+ /* Open response file. */
+- redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT);
++ redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT, 0666);
+
+ /* Duplicate the stdout and stderr file handles
+ so they can be restored later. */
diff --git a/misc/buildroot/toolchain/gcc/3.4.6/300-libstdc++-pic.patch b/misc/buildroot/toolchain/gcc/3.4.6/300-libstdc++-pic.patch
new file mode 100644
index 000000000..9f304a4c4
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.4.6/300-libstdc++-pic.patch
@@ -0,0 +1,47 @@
+# DP: Build and install libstdc++_pic.a library.
+
+--- gcc/libstdc++-v3/src/Makefile.am
++++ gcc/libstdc++-v3/src/Makefile.am
+@@ -224,6 +224,10 @@
+ @OPT_LDFLAGS@ @SECTION_LDFLAGS@ $(AM_CXXFLAGS) $(LDFLAGS) -o $@
+
+
++install-exec-local:
++ $(AR) cru libstdc++_pic.a .libs/*.o $(top_builddir)/libsupc++/*.o
++ $(INSTALL_DATA) libstdc++_pic.a $(DESTDIR)$(toolexeclibdir)
++
+ # Added bits to build debug library.
+ if GLIBCPP_BUILD_DEBUG
+ all-local: build_debug
+
+--- gcc/libstdc++-v3/src/Makefile.in
++++ gcc/libstdc++-v3/src/Makefile.in
+@@ -585,7 +585,7 @@
+
+ install-data-am: install-data-local
+
+-install-exec-am: install-toolexeclibLTLIBRARIES
++install-exec-am: install-toolexeclibLTLIBRARIES install-exec-local
+
+ install-info: install-info-am
+
+@@ -618,6 +618,7 @@
+ distclean-tags distdir dvi dvi-am info info-am install \
+ install-am install-data install-data-am install-data-local \
+ install-exec install-exec-am install-info install-info-am \
++ install-exec-local \
+ install-man install-strip install-toolexeclibLTLIBRARIES \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+@@ -707,6 +708,11 @@
+ install_debug:
+ (cd ${debugdir} && $(MAKE) \
+ toolexeclibdir=$(glibcxx_toolexeclibdir)/debug install)
++
++install-exec-local:
++ $(AR) cru libstdc++_pic.a .libs/*.o $(top_builddir)/libsupc++/*.o
++ $(INSTALL_DATA) libstdc++_pic.a $(DESTDIR)$(toolexeclibdir)
++
+ # Tell versions [3.59,3.63) of GNU make to not export all variables.
+ # Otherwise a system limit (for SysV at least) may be exceeded.
+ .NOEXPORT:
diff --git a/misc/buildroot/toolchain/gcc/3.4.6/304-index_macro.patch b/misc/buildroot/toolchain/gcc/3.4.6/304-index_macro.patch
new file mode 100644
index 000000000..1fac112fa
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.4.6/304-index_macro.patch
@@ -0,0 +1,24 @@
+--- gcc-4.1.0/libstdc++-v3/include/ext/rope.mps 2006-03-24 01:49:51 +0100
++++ gcc-4.1.0/libstdc++-v3/include/ext/rope 2006-03-24 01:49:37 +0100
+@@ -59,6 +59,9 @@
+ #include <bits/allocator.h>
+ #include <ext/hash_fun.h>
+
++/* cope w/ index defined as macro, SuSv3 proposal */
++#undef index
++
+ # ifdef __GC
+ # define __GC_CONST const
+ # else
+--- gcc-4.1.0/libstdc++-v3/include/ext/ropeimpl.h.mps 2006-03-24 01:50:04 +0100
++++ gcc-4.1.0/libstdc++-v3/include/ext/ropeimpl.h 2006-03-24 01:50:28 +0100
+@@ -53,6 +53,9 @@
+ #include <ext/memory> // For uninitialized_copy_n
+ #include <ext/numeric> // For power
+
++/* cope w/ index defined as macro, SuSv3 proposal */
++#undef index
++
+ namespace __gnu_cxx
+ {
+ using std::size_t;
diff --git a/misc/buildroot/toolchain/gcc/3.4.6/600-gcc34-arm-ldm-peephole.patch b/misc/buildroot/toolchain/gcc/3.4.6/600-gcc34-arm-ldm-peephole.patch
new file mode 100644
index 000000000..0c370502c
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.4.6/600-gcc34-arm-ldm-peephole.patch
@@ -0,0 +1,65 @@
+--- gcc-3.4.0/gcc/config/arm/arm.md.arm-ldm-peephole 2004-01-13 08:24:37.000000000 -0500
++++ gcc-3.4.0/gcc/config/arm/arm.md 2004-04-24 18:18:04.000000000 -0400
+@@ -8810,13 +8810,16 @@
+ (set_attr "length" "4,8,8")]
+ )
+
++; Try to convert LDR+LDR+arith into [add+]LDM+arith
++; On XScale, LDM is always slower than two LDRs, so only do this if
++; optimising for size.
+ (define_insn "*arith_adjacentmem"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (match_operator:SI 1 "shiftable_operator"
+ [(match_operand:SI 2 "memory_operand" "m")
+ (match_operand:SI 3 "memory_operand" "m")]))
+ (clobber (match_scratch:SI 4 "=r"))]
+- "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
++ "TARGET_ARM && (!arm_tune_xscale || optimize_size) && adjacent_mem_locations (operands[2], operands[3])"
+ "*
+ {
+ rtx ldm[3];
+@@ -8851,6 +8854,8 @@
+ }
+ if (val1 && val2)
+ {
++ /* This would be a loss on a Harvard core, but adjacent_mem_locations()
++ will prevent it from happening. */
+ rtx ops[3];
+ ldm[0] = ops[0] = operands[4];
+ ops[1] = XEXP (XEXP (operands[2], 0), 0);
+--- gcc-3.4.0/gcc/config/arm/arm.c.arm-ldm-peephole 2004-04-24 18:16:25.000000000 -0400
++++ gcc-3.4.0/gcc/config/arm/arm.c 2004-04-24 18:18:04.000000000 -0400
+@@ -4838,6 +4841,11 @@
+ *load_offset = unsorted_offsets[order[0]];
+ }
+
++ /* For XScale a two-word LDM is a performance loss, so only do this if
++ size is more important. See comments in arm_gen_load_multiple. */
++ if (nops == 2 && arm_tune_xscale && !optimize_size)
++ return 0;
++
+ if (unsorted_offsets[order[0]] == 0)
+ return 1; /* ldmia */
+
+@@ -5064,6 +5072,11 @@
+ *load_offset = unsorted_offsets[order[0]];
+ }
+
++ /* For XScale a two-word LDM is a performance loss, so only do this if
++ size is more important. See comments in arm_gen_load_multiple. */
++ if (nops == 2 && arm_tune_xscale && !optimize_size)
++ return 0;
++
+ if (unsorted_offsets[order[0]] == 0)
+ return 1; /* stmia */
+
+--- gcc-3.4.0/gcc/genpeep.c.arm-ldm-peephole 2003-07-05 01:27:22.000000000 -0400
++++ gcc-3.4.0/gcc/genpeep.c 2004-04-24 18:18:04.000000000 -0400
+@@ -381,6 +381,7 @@
+ printf ("#include \"recog.h\"\n");
+ printf ("#include \"except.h\"\n\n");
+ printf ("#include \"function.h\"\n\n");
++ printf ("#include \"flags.h\"\n\n");
+
+ printf ("#ifdef HAVE_peephole\n");
+ printf ("extern rtx peep_operand[];\n\n");
diff --git a/misc/buildroot/toolchain/gcc/3.4.6/601-gcc34-arm-ldm-peephole2.patch b/misc/buildroot/toolchain/gcc/3.4.6/601-gcc34-arm-ldm-peephole2.patch
new file mode 100644
index 000000000..27f7c07db
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.4.6/601-gcc34-arm-ldm-peephole2.patch
@@ -0,0 +1,42 @@
+The 30_all_gcc34-arm-ldm-peephole.patch from Debian was conflicting
+with the newer 36_all_pr16201-fix.patch, so i cut out the hunk from
+it that was causing problems and grabbed an updated version from
+upstream cvs.
+
+Index: gcc/config/arm/arm.c
+===================================================================
+RCS file: /cvsroot/gcc/gcc/gcc/config/arm/arm.c,v
+retrieving revision 1.432
+retrieving revision 1.433
+diff -u -r1.432 -r1.433
+--- gcc-3.4.4/gcc/config/arm/arm.c 29 Mar 2005 03:00:23 -0000 1.432
++++ gcc-3.4.4/gcc/config/arm/arm.c 1 Apr 2005 11:02:22 -0000 1.433
+@@ -5139,6 +5139,10 @@
+ int
+ adjacent_mem_locations (rtx a, rtx b)
+ {
++ /* We don't guarantee to preserve the order of these memory refs. */
++ if (volatile_refs_p (a) || volatile_refs_p (b))
++ return 0;
++
+ if ((GET_CODE (XEXP (a, 0)) == REG
+ || (GET_CODE (XEXP (a, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
+@@ -5178,6 +5182,17 @@
+ return 0;
+
+ val_diff = val1 - val0;
++
++ if (arm_ld_sched)
++ {
++ /* If the target has load delay slots, then there's no benefit
++ to using an ldm instruction unless the offset is zero and
++ we are optimizing for size. */
++ return (optimize_size && (REGNO (reg0) == REGNO (reg1))
++ && (val0 == 0 || val1 == 0 || val0 == 4 || val1 == 4)
++ && (val_diff == 4 || val_diff == -4));
++ }
++
+ return ((REGNO (reg0) == REGNO (reg1))
+ && (val_diff == 4 || val_diff == -4));
+ }
diff --git a/misc/buildroot/toolchain/gcc/3.4.6/601-gcc34-arm-ldm.patch b/misc/buildroot/toolchain/gcc/3.4.6/601-gcc34-arm-ldm.patch
new file mode 100644
index 000000000..142052fdf
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.4.6/601-gcc34-arm-ldm.patch
@@ -0,0 +1,119 @@
+--- gcc-3.4.0/gcc/config/arm/arm.c.arm-ldm 2004-02-27 09:51:05.000000000 -0500
++++ gcc-3.4.0/gcc/config/arm/arm.c 2004-04-24 18:16:25.000000000 -0400
+@@ -8520,6 +8520,26 @@
+ return_used_this_function = 0;
+ }
+
++/* Return the number (counting from 0) of
++ the least significant set bit in MASK. */
++
++#ifdef __GNUC__
++inline
++#endif
++static int
++number_of_first_bit_set (mask)
++ int mask;
++{
++ int bit;
++
++ for (bit = 0;
++ (mask & (1 << bit)) == 0;
++ ++bit)
++ continue;
++
++ return bit;
++}
++
+ const char *
+ arm_output_epilogue (rtx sibling)
+ {
+@@ -8753,27 +8773,47 @@
+ saved_regs_mask |= (1 << PC_REGNUM);
+ }
+
+- /* Load the registers off the stack. If we only have one register
+- to load use the LDR instruction - it is faster. */
+- if (saved_regs_mask == (1 << LR_REGNUM))
+- {
+- /* The exception handler ignores the LR, so we do
+- not really need to load it off the stack. */
+- if (eh_ofs)
+- asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
+- else
+- asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM);
+- }
+- else if (saved_regs_mask)
++ if (saved_regs_mask)
+ {
+- if (saved_regs_mask & (1 << SP_REGNUM))
+- /* Note - write back to the stack register is not enabled
+- (ie "ldmfd sp!..."). We know that the stack pointer is
+- in the list of registers and if we add writeback the
+- instruction becomes UNPREDICTABLE. */
+- print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
++ /* Load the registers off the stack. If we only have one register
++ to load use the LDR instruction - it is faster. */
++ if (bit_count (saved_regs_mask) == 1)
++ {
++ int reg = number_of_first_bit_set (saved_regs_mask);
++
++ switch (reg)
++ {
++ case SP_REGNUM:
++ /* Mustn't use base writeback when loading SP. */
++ asm_fprintf (f, "\tldr\t%r, [%r]\n", SP_REGNUM, SP_REGNUM);
++ break;
++
++ case LR_REGNUM:
++ if (eh_ofs)
++ {
++ /* The exception handler ignores the LR, so we do
++ not really need to load it off the stack. */
++ asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
++ break;
++ }
++ /* else fall through */
++
++ default:
++ asm_fprintf (f, "\tldr\t%r, [%r], #4\n", reg, SP_REGNUM);
++ break;
++ }
++ }
+ else
+- print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
++ {
++ if (saved_regs_mask & (1 << SP_REGNUM))
++ /* Note - write back to the stack register is not enabled
++ (ie "ldmfd sp!..."). We know that the stack pointer is
++ in the list of registers and if we add writeback the
++ instruction becomes UNPREDICTABLE. */
++ print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
++ else
++ print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
++ }
+ }
+
+ if (current_function_pretend_args_size)
+@@ -11401,22 +11441,6 @@
+ }
+ }
+
+-/* Return the number (counting from 0) of
+- the least significant set bit in MASK. */
+-
+-inline static int
+-number_of_first_bit_set (int mask)
+-{
+- int bit;
+-
+- for (bit = 0;
+- (mask & (1 << bit)) == 0;
+- ++bit)
+- continue;
+-
+- return bit;
+-}
+-
+ /* Generate code to return from a thumb function.
+ If 'reg_containing_return_addr' is -1, then the return address is
+ actually on the stack, at the stack pointer. */
diff --git a/misc/buildroot/toolchain/gcc/3.4.6/602-sdk-libstdc++-includes.patch b/misc/buildroot/toolchain/gcc/3.4.6/602-sdk-libstdc++-includes.patch
new file mode 100644
index 000000000..4377c2143
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.4.6/602-sdk-libstdc++-includes.patch
@@ -0,0 +1,22 @@
+--- gcc-3.4.1/libstdc++-v3/libmath/Makefile.am~ 2003-08-27 22:29:42.000000000 +0100
++++ gcc-3.4.1/libstdc++-v3/libmath/Makefile.am 2004-07-22 16:41:45.152130128 +0100
+@@ -32,7 +32,7 @@
+
+ libmath_la_SOURCES = stubs.c
+
+-AM_CPPFLAGS = $(CANADIAN_INCLUDES)
++AM_CPPFLAGS = $(CANADIAN_INCLUDES) -I$(toplevel_srcdir)/include
+
+ # Only compiling "C" sources in this directory.
+ LIBTOOL = @LIBTOOL@ --tag CC
+--- gcc-3.4.1/libstdc++-v3/fragment.am.old 2004-07-22 18:24:58.024083656 +0100
++++ gcc-3.4.1/libstdc++-v3/fragment.am 2004-07-22 18:24:59.019932264 +0100
+@@ -18,7 +18,7 @@
+ $(WARN_FLAGS) $(WERROR) -fdiagnostics-show-location=once
+
+ # -I/-D flags to pass when compiling.
+-AM_CPPFLAGS = $(GLIBCXX_INCLUDES)
++AM_CPPFLAGS = $(GLIBCXX_INCLUDES) -I$(toplevel_srcdir)/include
+
+
+
diff --git a/misc/buildroot/toolchain/gcc/3.4.6/700-pr15068-fix.patch b/misc/buildroot/toolchain/gcc/3.4.6/700-pr15068-fix.patch
new file mode 100644
index 000000000..2977765c5
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.4.6/700-pr15068-fix.patch
@@ -0,0 +1,44 @@
+See http://gcc.gnu.org/PR15068
+
+Fixes error
+
+../sysdeps/generic/s_fmax.c: In function `__fmax':
+../sysdeps/generic/s_fmax.c:28: internal compiler error: in elim_reg_cond, at flow.c:3257
+Please submit a full bug report,
+with preprocessed source if appropriate.
+See <URL:http://gcc.gnu.org/bugs.html> for instructions.
+make[2]: *** [/home/dank/wk/crosstool-0.28-rc35/build/arm-unknown-linux-gnu/gcc-3.4.1-glibc-20040822/build-glibc/math/s_fmax.o] Error 1
+make[2]: Leaving directory `/home/dank/wk/crosstool-0.28-rc35/build/arm-unknown-linux-gnu/gcc-3.4.1-glibc-20040822/glibc-20040822/math'
+make[1]: *** [math/others] Error 2
+make[1]: Leaving directory `/home/dank/wk/crosstool-0.28-rc35/build/arm-unknown-linux-gnu/gcc-3.4.1-glibc-20040822/glibc-20040822'
+make: *** [all] Error 2
+
+[ rediffed against gcc-3.4.1, with elbow grease, ending up with same thing as
+http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/flow.c.diff?cvsroot=gcc&only_with_tag=csl-arm-branch&r1=1.563.4.2&r2=1.563.4.3 ]
+
+--- gcc-3.4.1/gcc/flow.c.old 2004-02-27 19:39:19.000000000 -0800
++++ gcc-3.4.1/gcc/flow.c 2004-08-26 07:29:46.000000000 -0700
+@@ -1878,6 +1878,7 @@
+ rtx set_src = SET_SRC (pc_set (BB_END (bb)));
+ rtx cond_true = XEXP (set_src, 0);
+ rtx reg = XEXP (cond_true, 0);
++ enum rtx_code inv_cond;
+
+ if (GET_CODE (reg) == SUBREG)
+ reg = SUBREG_REG (reg);
+@@ -1886,11 +1887,13 @@
+ in the form of a comparison of a register against zero.
+ If the condition is more complex than that, then it is safe
+ not to record any information. */
+- if (GET_CODE (reg) == REG
++ inv_cond = reversed_comparison_code (cond_true, BB_END (bb));
++ if (inv_cond != UNKNOWN
++ && GET_CODE (reg) == REG
+ && XEXP (cond_true, 1) == const0_rtx)
+ {
+ rtx cond_false
+- = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond_true)),
++ = gen_rtx_fmt_ee (inv_cond,
+ GET_MODE (cond_true), XEXP (cond_true, 0),
+ XEXP (cond_true, 1));
+ if (GET_CODE (XEXP (set_src, 1)) == PC)
diff --git a/misc/buildroot/toolchain/gcc/3.4.6/71_all_sh-pr16665-fix.patch b/misc/buildroot/toolchain/gcc/3.4.6/71_all_sh-pr16665-fix.patch
new file mode 100644
index 000000000..680bb3978
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.4.6/71_all_sh-pr16665-fix.patch
@@ -0,0 +1,43 @@
+--- gcc/gcc/config/sh/sh.c
++++ gcc/gcc/config/sh/sh.c
+@@ -9106,6 +9106,15 @@ sh_output_mi_thunk (FILE *file, tree thu
+ }
+ this = FUNCTION_ARG (cum, Pmode, ptr_type_node, 1);
+
++ /* In PIC case, we set PIC register to compute the target address. We
++ can use a scratch register to save and restore the original value
++ except for SHcompact. For SHcompact, use stack. */
++ if (flag_pic && TARGET_SHCOMPACT)
++ {
++ push (PIC_OFFSET_TABLE_REGNUM);
++ emit_insn (gen_GOTaddr2picreg ());
++ }
++
+ /* For SHcompact, we only have r0 for a scratch register: r1 is the
+ static chain pointer (even if you can't have nested virtual functions
+ right now, someone might implement them sometime), and the rest of the
+@@ -9188,8 +9197,24 @@ sh_output_mi_thunk (FILE *file, tree thu
+ assemble_external (function);
+ TREE_USED (function) = 1;
+ }
++ /* We can use scratch1 to save and restore the original value of
++ PIC register except for SHcompact. */
++ if (flag_pic && ! TARGET_SHCOMPACT)
++ {
++ emit_move_insn (scratch1,
++ gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM));
++ emit_insn (gen_GOTaddr2picreg ());
++ }
+ funexp = XEXP (DECL_RTL (function), 0);
+ emit_move_insn (scratch2, funexp);
++ if (flag_pic)
++ {
++ if (! TARGET_SHCOMPACT)
++ emit_move_insn (gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM),
++ scratch1);
++ else
++ pop (PIC_OFFSET_TABLE_REGNUM);
++ }
+ funexp = gen_rtx_MEM (FUNCTION_MODE, scratch2);
+ sibcall = emit_call_insn (gen_sibcall (funexp, const0_rtx, NULL_RTX));
+ SIBLING_CALL_P (sibcall) = 1;
diff --git a/misc/buildroot/toolchain/gcc/3.4.6/72_all_sh-no-reorder-blocks.patch b/misc/buildroot/toolchain/gcc/3.4.6/72_all_sh-no-reorder-blocks.patch
new file mode 100644
index 000000000..8b9826831
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.4.6/72_all_sh-no-reorder-blocks.patch
@@ -0,0 +1,13 @@
+--- g/gcc/config/sh/sh.h
++++ g/gcc/config/sh/sh.h
+@@ -422,6 +422,10 @@
+ do { \
+ if (LEVEL) \
+ flag_omit_frame_pointer = -1; \
++ if (LEVEL <= 2) \
++ { \
++ flag_reorder_blocks = 0; \
++ } \
+ if (SIZE) \
+ target_flags |= SPACE_BIT; \
+ if (TARGET_SHMEDIA && LEVEL > 1) \
diff --git a/misc/buildroot/toolchain/gcc/3.4.6/73_all_sh-pr20617.patch b/misc/buildroot/toolchain/gcc/3.4.6/73_all_sh-pr20617.patch
new file mode 100644
index 000000000..6d8021cc7
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.4.6/73_all_sh-pr20617.patch
@@ -0,0 +1,28 @@
+2005-03-24 J"orn Rennecke <joern.rennecke@st.com>
+
+ Band aid for PR target/20617:
+ * config/sh/lib1funcs.asm (FUNC, ALIAS): Add .hidden directive.
+
+--- g/gcc/config/sh/lib1funcs.asm
++++ g/gcc/config/sh/lib1funcs.asm
+@@ -37,9 +37,19 @@ Boston, MA 02111-1307, USA. */
+ ELF local label prefixes by J"orn Rennecke
+ amylaar@cygnus.com */
+
++#define ALIAS(X,Y) .global GLOBAL(X); .set GLOBAL(X),GLOBAL(Y)
++
+ #ifdef __ELF__
+ #define LOCAL(X) .L_##X
+-#define FUNC(X) .type X,@function
++
++#if 1 /* ??? The export list mechanism is broken, everything that is not
++ hidden is exported. */
++#undef FUNC
++#define FUNC(X) .type X,@function; .hidden X
++#undef ALIAS
++#define ALIAS(X,Y) .global GLOBAL(X); .set GLOBAL(X),GLOBAL(Y); .hidden GLOBAL(X)
++#endif
++
+ #define ENDFUNC0(X) .Lfe_##X: .size X,.Lfe_##X-X
+ #define ENDFUNC(X) ENDFUNC0(X)
+ #else
diff --git a/misc/buildroot/toolchain/gcc/3.4.6/800-arm-bigendian.patch b/misc/buildroot/toolchain/gcc/3.4.6/800-arm-bigendian.patch
new file mode 100644
index 000000000..04e998419
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.4.6/800-arm-bigendian.patch
@@ -0,0 +1,68 @@
+By Lennert Buytenhek <buytenh@wantstofly.org>
+Adds support for arm*b-linux* big-endian ARM targets
+
+See http://gcc.gnu.org/PR16350
+
+--- gcc-3.4.1-dist/gcc/config/arm/linux-elf.h
++++ gcc-3.4.1/gcc/config/arm/linux-elf.h
+@@ -30,17 +30,34 @@
+ /* Do not assume anything about header files. */
+ #define NO_IMPLICIT_EXTERN_C
+
++/*
++ * 'config.gcc' defines TARGET_BIG_ENDIAN_DEFAULT as 1 for arm*b-*
++ * (big endian) configurations.
++ */
++#if TARGET_BIG_ENDIAN_DEFAULT
++#define TARGET_ENDIAN_DEFAULT ARM_FLAG_BIG_END
++#define TARGET_ENDIAN_OPTION "mbig-endian"
++#define TARGET_LINKER_EMULATION "armelfb_linux"
++#else
++#define TARGET_ENDIAN_DEFAULT 0
++#define TARGET_ENDIAN_OPTION "mlittle-endian"
++#define TARGET_LINKER_EMULATION "armelf_linux"
++#endif
++
+ /* Default is to use APCS-32 mode. */
+ #undef TARGET_DEFAULT
+-#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_MMU_TRAPS)
++#define TARGET_DEFAULT \
++ ( ARM_FLAG_APCS_32 | \
++ ARM_FLAG_MMU_TRAPS | \
++ TARGET_ENDIAN_DEFAULT )
+
+ #define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm6
+
+-#define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux -p"
++#define SUBTARGET_EXTRA_LINK_SPEC " -m " TARGET_LINKER_EMULATION " -p"
+
+ #undef MULTILIB_DEFAULTS
+ #define MULTILIB_DEFAULTS \
+- { "marm", "mlittle-endian", "mhard-float", "mapcs-32", "mno-thumb-interwork" }
++ { "marm", TARGET_ENDIAN_OPTION, "mhard-float", "mapcs-32", "mno-thumb-interwork" }
+
+ #define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__"
+
+@@ -101,7 +118,7 @@
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2} \
+ -X \
+- %{mbig-endian:-EB}" \
++ %{mbig-endian:-EB} %{mlittle-endian:-EL}" \
+ SUBTARGET_EXTRA_LINK_SPEC
+ #endif
+
+--- gcc-3.4.1-dist/gcc/config.gcc
++++ gcc-3.4.1/gcc/config.gcc
+@@ -672,6 +672,11 @@
+ ;;
+ arm*-*-linux*) # ARM GNU/Linux with ELF
+ tm_file="dbxelf.h elfos.h linux.h arm/elf.h arm/linux-gas.h arm/linux-elf.h arm/aout.h arm/arm.h"
++ case $target in
++ arm*b-*)
++ tm_defines="TARGET_BIG_ENDIAN_DEFAULT=1 $tm_defines"
++ ;;
++ esac
+ tmake_file="t-slibgcc-elf-ver t-linux arm/t-linux"
+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
+ gnu_ld=yes
diff --git a/misc/buildroot/toolchain/gcc/3.4.6/810-mips-xgot.patch b/misc/buildroot/toolchain/gcc/3.4.6/810-mips-xgot.patch
new file mode 100644
index 000000000..14e8d126e
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.4.6/810-mips-xgot.patch
@@ -0,0 +1,6 @@
+--- gcc.orig/gcc/config/mips/t-linux 1970-01-01 01:00:00.000000000 +0100
++++ gcc/gcc/config/mips/t-linux 2004-08-26 18:28:12.000000000 +0200
+@@ -0,0 +1,3 @@
++# Compile crtbegin/end with xgot so it works for both
++# normal and large GOTs.
++CRTSTUFF_T_CFLAGS = -mxgot
diff --git a/misc/buildroot/toolchain/gcc/3.4.6/900-nios2.patch b/misc/buildroot/toolchain/gcc/3.4.6/900-nios2.patch
new file mode 100644
index 000000000..bfa06a21c
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.4.6/900-nios2.patch
@@ -0,0 +1,10211 @@
+--- gcc-3.4.3/gcc/Makefile.in
++++ gcc-3.4.3-nios2/gcc/Makefile.in
+@@ -3085,7 +3085,7 @@ install-mkheaders: stmp-int-hdrs $(STMP_
+ $(INSTALL_DATA) $(srcdir)/README-fixinc \
+ $(DESTDIR)$(itoolsdatadir)/include/README ; \
+ $(INSTALL_SCRIPT) fixinc.sh $(DESTDIR)$(itoolsdir)/fixinc.sh ; \
+- $(INSTALL_PROGRAM) fixinc/fixincl $(DESTDIR)$(itoolsdir)/fixincl ; \
++ $(INSTALL_PROGRAM) fixinc/fixincl$(build_exeext) $(DESTDIR)$(itoolsdir)/fixincl$(build_exeext) ; \
+ $(INSTALL_DATA) $(srcdir)/gsyslimits.h \
+ $(DESTDIR)$(itoolsdatadir)/gsyslimits.h ; \
+ else :; fi
+--- gcc-3.4.3/gcc/combine.c
++++ gcc-3.4.3-nios2/gcc/combine.c
+@@ -4380,6 +4380,14 @@ combine_simplify_rtx (rtx x, enum machin
+ mode);
+ }
+
++#ifndef __nios2__
++/* This screws up Nios II in this test case:
++
++if (x & 1)
++ return 2;
++else
++ return 3;
++*/
+ else if (STORE_FLAG_VALUE == 1
+ && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
+ && op1 == const0_rtx
+@@ -4391,6 +4399,7 @@ combine_simplify_rtx (rtx x, enum machin
+ gen_lowpart_for_combine (mode, op0),
+ const1_rtx);
+ }
++#endif
+
+ else if (STORE_FLAG_VALUE == 1
+ && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
+--- gcc-3.4.3/gcc/config/nios2/crti.asm
++++ gcc-3.4.3-nios2/gcc/config/nios2/crti.asm
+@@ -0,0 +1,88 @@
++/*
++ Copyright (C) 2003
++ by Jonah Graham (jgraham@altera.com)
++
++This file is free software; you can redistribute it and/or modify it
++under the terms of the GNU General Public License as published by the
++Free Software Foundation; either version 2, or (at your option) any
++later version.
++
++In addition to the permissions in the GNU General Public License, the
++Free Software Foundation gives you unlimited permission to link the
++compiled version of this file with other programs, and to distribute
++those programs without any restriction coming from the use of this
++file. (The General Public License restrictions do apply in other
++respects; for example, they cover modification of the file, and
++distribution when not linked into another program.)
++
++This file is distributed in the hope that it will be useful, but
++WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with this program; see the file COPYING. If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA.
++
++ As a special exception, if you link this library with files
++ compiled with GCC to produce an executable, this does not cause
++ the resulting executable to be covered by the GNU General Public License.
++ This exception does not however invalidate any other reasons why
++ the executable file might be covered by the GNU General Public License.
++
++
++This file just make a stack frame for the contents of the .fini and
++.init sections. Users may put any desired instructions in those
++sections.
++
++
++While technically any code can be put in the init and fini sections
++most stuff will not work other than stuff which obeys the call frame
++and ABI. All the call-preserved registers are saved, the call clobbered
++registers should have been saved by the code calling init and fini.
++
++See crtstuff.c for an example of code that inserts itself in the
++init and fini sections.
++
++See crt0.s for the code that calls init and fini.
++*/
++
++ .file "crti.asm"
++
++ .section ".init"
++ .align 2
++ .global _init
++_init:
++ addi sp, sp, -48
++ stw ra, 44(sp)
++ stw r23, 40(sp)
++ stw r22, 36(sp)
++ stw r21, 32(sp)
++ stw r20, 28(sp)
++ stw r19, 24(sp)
++ stw r18, 20(sp)
++ stw r17, 16(sp)
++ stw r16, 12(sp)
++ stw fp, 8(sp)
++ mov fp, sp
++
++
++ .section ".fini"
++ .align 2
++ .global _fini
++_fini:
++ addi sp, sp, -48
++ stw ra, 44(sp)
++ stw r23, 40(sp)
++ stw r22, 36(sp)
++ stw r21, 32(sp)
++ stw r20, 28(sp)
++ stw r19, 24(sp)
++ stw r18, 20(sp)
++ stw r17, 16(sp)
++ stw r16, 12(sp)
++ stw fp, 8(sp)
++ mov fp, sp
++
++
+--- gcc-3.4.3/gcc/config/nios2/crtn.asm
++++ gcc-3.4.3-nios2/gcc/config/nios2/crtn.asm
+@@ -0,0 +1,70 @@
++/*
++ Copyright (C) 2003
++ by Jonah Graham (jgraham@altera.com)
++
++This file is free software; you can redistribute it and/or modify it
++under the terms of the GNU General Public License as published by the
++Free Software Foundation; either version 2, or (at your option) any
++later version.
++
++In addition to the permissions in the GNU General Public License, the
++Free Software Foundation gives you unlimited permission to link the
++compiled version of this file with other programs, and to distribute
++those programs without any restriction coming from the use of this
++file. (The General Public License restrictions do apply in other
++respects; for example, they cover modification of the file, and
++distribution when not linked into another program.)
++
++This file is distributed in the hope that it will be useful, but
++WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with this program; see the file COPYING. If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA.
++
++ As a special exception, if you link this library with files
++ compiled with GCC to produce an executable, this does not cause
++ the resulting executable to be covered by the GNU General Public License.
++ This exception does not however invalidate any other reasons why
++ the executable file might be covered by the GNU General Public License.
++
++
++This file just makes sure that the .fini and .init sections do in
++fact return. Users may put any desired instructions in those sections.
++This file is the last thing linked into any executable.
++*/
++ .file "crtn.asm"
++
++
++
++ .section ".init"
++ ldw ra, 44(sp)
++ ldw r23, 40(sp)
++ ldw r22, 36(sp)
++ ldw r21, 32(sp)
++ ldw r20, 28(sp)
++ ldw r19, 24(sp)
++ ldw r18, 20(sp)
++ ldw r17, 16(sp)
++ ldw r16, 12(sp)
++ ldw fp, 8(sp)
++ addi sp, sp, -48
++ ret
++
++ .section ".fini"
++ ldw ra, 44(sp)
++ ldw r23, 40(sp)
++ ldw r22, 36(sp)
++ ldw r21, 32(sp)
++ ldw r20, 28(sp)
++ ldw r19, 24(sp)
++ ldw r18, 20(sp)
++ ldw r17, 16(sp)
++ ldw r16, 12(sp)
++ ldw fp, 8(sp)
++ addi sp, sp, -48
++ ret
++
+--- gcc-3.4.3/gcc/config/nios2/lib2-divmod-hi.c
++++ gcc-3.4.3-nios2/gcc/config/nios2/lib2-divmod-hi.c
+@@ -0,0 +1,123 @@
++
++/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
++ supposedly valid even though this is a "target" file. */
++#include "auto-host.h"
++
++
++#include "tconfig.h"
++#include "tsystem.h"
++#include "coretypes.h"
++#include "tm.h"
++
++
++/* Don't use `fancy_abort' here even if config.h says to use it. */
++#ifdef abort
++#undef abort
++#endif
++
++
++#ifdef HAVE_GAS_HIDDEN
++#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
++#else
++#define ATTRIBUTE_HIDDEN
++#endif
++
++#include "libgcc2.h"
++
++extern HItype __modhi3 (HItype, HItype);
++extern HItype __divhi3 (HItype, HItype);
++extern HItype __umodhi3 (HItype, HItype);
++extern HItype __udivhi3 (HItype, HItype);
++
++static UHItype udivmodhi4(UHItype, UHItype, word_type);
++
++static UHItype
++udivmodhi4(UHItype num, UHItype den, word_type modwanted)
++{
++ UHItype bit = 1;
++ UHItype res = 0;
++
++ while (den < num && bit && !(den & (1L<<15)))
++ {
++ den <<=1;
++ bit <<=1;
++ }
++ while (bit)
++ {
++ if (num >= den)
++ {
++ num -= den;
++ res |= bit;
++ }
++ bit >>=1;
++ den >>=1;
++ }
++ if (modwanted) return num;
++ return res;
++}
++
++
++HItype
++__divhi3 (HItype a, HItype b)
++{
++ word_type neg = 0;
++ HItype res;
++
++ if (a < 0)
++ {
++ a = -a;
++ neg = !neg;
++ }
++
++ if (b < 0)
++ {
++ b = -b;
++ neg = !neg;
++ }
++
++ res = udivmodhi4 (a, b, 0);
++
++ if (neg)
++ res = -res;
++
++ return res;
++}
++
++
++HItype
++__modhi3 (HItype a, HItype b)
++{
++ word_type neg = 0;
++ HItype res;
++
++ if (a < 0)
++ {
++ a = -a;
++ neg = 1;
++ }
++
++ if (b < 0)
++ b = -b;
++
++ res = udivmodhi4 (a, b, 1);
++
++ if (neg)
++ res = -res;
++
++ return res;
++}
++
++
++HItype
++__udivhi3 (HItype a, HItype b)
++{
++ return udivmodhi4 (a, b, 0);
++}
++
++
++HItype
++__umodhi3 (HItype a, HItype b)
++{
++ return udivmodhi4 (a, b, 1);
++}
++
+--- gcc-3.4.3/gcc/config/nios2/lib2-divmod.c
++++ gcc-3.4.3-nios2/gcc/config/nios2/lib2-divmod.c
+@@ -0,0 +1,126 @@
++
++/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
++ supposedly valid even though this is a "target" file. */
++#include "auto-host.h"
++
++
++#include "tconfig.h"
++#include "tsystem.h"
++#include "coretypes.h"
++#include "tm.h"
++
++
++/* Don't use `fancy_abort' here even if config.h says to use it. */
++#ifdef abort
++#undef abort
++#endif
++
++
++#ifdef HAVE_GAS_HIDDEN
++#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
++#else
++#define ATTRIBUTE_HIDDEN
++#endif
++
++#include "libgcc2.h"
++
++extern SItype __modsi3 (SItype, SItype);
++extern SItype __divsi3 (SItype, SItype);
++extern SItype __umodsi3 (SItype, SItype);
++extern SItype __udivsi3 (SItype, SItype);
++
++static USItype udivmodsi4(USItype, USItype, word_type);
++
++/* 16-bit SI divide and modulo as used in NIOS */
++
++
++static USItype
++udivmodsi4(USItype num, USItype den, word_type modwanted)
++{
++ USItype bit = 1;
++ USItype res = 0;
++
++ while (den < num && bit && !(den & (1L<<31)))
++ {
++ den <<=1;
++ bit <<=1;
++ }
++ while (bit)
++ {
++ if (num >= den)
++ {
++ num -= den;
++ res |= bit;
++ }
++ bit >>=1;
++ den >>=1;
++ }
++ if (modwanted) return num;
++ return res;
++}
++
++
++SItype
++__divsi3 (SItype a, SItype b)
++{
++ word_type neg = 0;
++ SItype res;
++
++ if (a < 0)
++ {
++ a = -a;
++ neg = !neg;
++ }
++
++ if (b < 0)
++ {
++ b = -b;
++ neg = !neg;
++ }
++
++ res = udivmodsi4 (a, b, 0);
++
++ if (neg)
++ res = -res;
++
++ return res;
++}
++
++
++SItype
++__modsi3 (SItype a, SItype b)
++{
++ word_type neg = 0;
++ SItype res;
++
++ if (a < 0)
++ {
++ a = -a;
++ neg = 1;
++ }
++
++ if (b < 0)
++ b = -b;
++
++ res = udivmodsi4 (a, b, 1);
++
++ if (neg)
++ res = -res;
++
++ return res;
++}
++
++
++SItype
++__udivsi3 (SItype a, SItype b)
++{
++ return udivmodsi4 (a, b, 0);
++}
++
++
++SItype
++__umodsi3 (SItype a, SItype b)
++{
++ return udivmodsi4 (a, b, 1);
++}
++
+--- gcc-3.4.3/gcc/config/nios2/lib2-divtable.c
++++ gcc-3.4.3-nios2/gcc/config/nios2/lib2-divtable.c
+@@ -0,0 +1,46 @@
++
++/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
++ supposedly valid even though this is a "target" file. */
++#include "auto-host.h"
++
++
++#include "tconfig.h"
++#include "tsystem.h"
++#include "coretypes.h"
++#include "tm.h"
++
++
++/* Don't use `fancy_abort' here even if config.h says to use it. */
++#ifdef abort
++#undef abort
++#endif
++
++
++#ifdef HAVE_GAS_HIDDEN
++#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
++#else
++#define ATTRIBUTE_HIDDEN
++#endif
++
++#include "libgcc2.h"
++
++UQItype __divsi3_table[] =
++{
++ 0, 0/1, 0/2, 0/3, 0/4, 0/5, 0/6, 0/7, 0/8, 0/9, 0/10, 0/11, 0/12, 0/13, 0/14, 0/15,
++ 0, 1/1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1/12, 1/13, 1/14, 1/15,
++ 0, 2/1, 2/2, 2/3, 2/4, 2/5, 2/6, 2/7, 2/8, 2/9, 2/10, 2/11, 2/12, 2/13, 2/14, 2/15,
++ 0, 3/1, 3/2, 3/3, 3/4, 3/5, 3/6, 3/7, 3/8, 3/9, 3/10, 3/11, 3/12, 3/13, 3/14, 3/15,
++ 0, 4/1, 4/2, 4/3, 4/4, 4/5, 4/6, 4/7, 4/8, 4/9, 4/10, 4/11, 4/12, 4/13, 4/14, 4/15,
++ 0, 5/1, 5/2, 5/3, 5/4, 5/5, 5/6, 5/7, 5/8, 5/9, 5/10, 5/11, 5/12, 5/13, 5/14, 5/15,
++ 0, 6/1, 6/2, 6/3, 6/4, 6/5, 6/6, 6/7, 6/8, 6/9, 6/10, 6/11, 6/12, 6/13, 6/14, 6/15,
++ 0, 7/1, 7/2, 7/3, 7/4, 7/5, 7/6, 7/7, 7/8, 7/9, 7/10, 7/11, 7/12, 7/13, 7/14, 7/15,
++ 0, 8/1, 8/2, 8/3, 8/4, 8/5, 8/6, 8/7, 8/8, 8/9, 8/10, 8/11, 8/12, 8/13, 8/14, 8/15,
++ 0, 9/1, 9/2, 9/3, 9/4, 9/5, 9/6, 9/7, 9/8, 9/9, 9/10, 9/11, 9/12, 9/13, 9/14, 9/15,
++ 0, 10/1, 10/2, 10/3, 10/4, 10/5, 10/6, 10/7, 10/8, 10/9, 10/10, 10/11, 10/12, 10/13, 10/14, 10/15,
++ 0, 11/1, 11/2, 11/3, 11/4, 11/5, 11/6, 11/7, 11/8, 11/9, 11/10, 11/11, 11/12, 11/13, 11/14, 11/15,
++ 0, 12/1, 12/2, 12/3, 12/4, 12/5, 12/6, 12/7, 12/8, 12/9, 12/10, 12/11, 12/12, 12/13, 12/14, 12/15,
++ 0, 13/1, 13/2, 13/3, 13/4, 13/5, 13/6, 13/7, 13/8, 13/9, 13/10, 13/11, 13/12, 13/13, 13/14, 13/15,
++ 0, 14/1, 14/2, 14/3, 14/4, 14/5, 14/6, 14/7, 14/8, 14/9, 14/10, 14/11, 14/12, 14/13, 14/14, 14/15,
++ 0, 15/1, 15/2, 15/3, 15/4, 15/5, 15/6, 15/7, 15/8, 15/9, 15/10, 15/11, 15/12, 15/13, 15/14, 15/15,
++};
++
+--- gcc-3.4.3/gcc/config/nios2/lib2-mul.c
++++ gcc-3.4.3-nios2/gcc/config/nios2/lib2-mul.c
+@@ -0,0 +1,103 @@
++/* while we are debugging (ie compile outside of gcc build)
++ disable gcc specific headers */
++#ifndef DEBUG_MULSI3
++
++
++/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
++ supposedly valid even though this is a "target" file. */
++#include "auto-host.h"
++
++
++#include "tconfig.h"
++#include "tsystem.h"
++#include "coretypes.h"
++#include "tm.h"
++
++
++/* Don't use `fancy_abort' here even if config.h says to use it. */
++#ifdef abort
++#undef abort
++#endif
++
++
++#ifdef HAVE_GAS_HIDDEN
++#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
++#else
++#define ATTRIBUTE_HIDDEN
++#endif
++
++#include "libgcc2.h"
++
++#else
++#define SItype int
++#define USItype unsigned int
++#endif
++
++
++extern SItype __mulsi3 (SItype, SItype);
++
++SItype
++__mulsi3 (SItype a, SItype b)
++{
++ SItype res = 0;
++ USItype cnt = a;
++
++ while (cnt)
++ {
++ if (cnt & 1)
++ {
++ res += b;
++ }
++ b <<= 1;
++ cnt >>= 1;
++ }
++
++ return res;
++}
++/*
++TODO: Choose best alternative implementation.
++
++SItype
++__divsi3 (SItype a, SItype b)
++{
++ SItype res = 0;
++ USItype cnt = 0;
++
++ while (cnt < 32)
++ {
++ if (a & (1L << cnt))
++ {
++ res += b;
++ }
++ b <<= 1;
++ cnt++;
++ }
++
++ return res;
++}
++*/
++
++
++#ifdef DEBUG_MULSI3
++
++int
++main ()
++{
++ int i, j;
++ int error = 0;
++
++ for (i = -1000; i < 1000; i++)
++ for (j = -1000; j < 1000; j++)
++ {
++ int expect = i * j;
++ int actual = A__divsi3 (i, j);
++ if (expect != actual)
++ {
++ printf ("error: %d * %d = %d not %d\n", i, j, expect, actual);
++ error = 1;
++ }
++ }
++
++ return error;
++}
++#endif
+--- gcc-3.4.3/gcc/config/nios2/nios2-dp-bit.c
++++ gcc-3.4.3-nios2/gcc/config/nios2/nios2-dp-bit.c
+@@ -0,0 +1,1652 @@
++
++/* This is a software floating point library which can be used
++ for targets without hardware floating point.
++ Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
++ Free Software Foundation, Inc.
++
++This file is free software; you can redistribute it and/or modify it
++under the terms of the GNU General Public License as published by the
++Free Software Foundation; either version 2, or (at your option) any
++later version.
++
++In addition to the permissions in the GNU General Public License, the
++Free Software Foundation gives you unlimited permission to link the
++compiled version of this file with other programs, and to distribute
++those programs without any restriction coming from the use of this
++file. (The General Public License restrictions do apply in other
++respects; for example, they cover modification of the file, and
++distribution when not linked into another program.)
++
++This file is distributed in the hope that it will be useful, but
++WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with this program; see the file COPYING. If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA. */
++
++/* As a special exception, if you link this library with other files,
++ some of which are compiled with GCC, to produce an executable,
++ this library does not by itself cause the resulting executable
++ to be covered by the GNU General Public License.
++ This exception does not however invalidate any other reasons why
++ the executable file might be covered by the GNU General Public License. */
++
++/* This implements IEEE 754 format arithmetic, but does not provide a
++ mechanism for setting the rounding mode, or for generating or handling
++ exceptions.
++
++ The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
++ Wilson, all of Cygnus Support. */
++
++/* The intended way to use this file is to make two copies, add `#define FLOAT'
++ to one copy, then compile both copies and add them to libgcc.a. */
++
++#include "tconfig.h"
++#include "coretypes.h"
++#include "tm.h"
++#include "config/fp-bit.h"
++
++/* The following macros can be defined to change the behavior of this file:
++ FLOAT: Implement a `float', aka SFmode, fp library. If this is not
++ defined, then this file implements a `double', aka DFmode, fp library.
++ FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
++ don't include float->double conversion which requires the double library.
++ This is useful only for machines which can't support doubles, e.g. some
++ 8-bit processors.
++ CMPtype: Specify the type that floating point compares should return.
++ This defaults to SItype, aka int.
++ US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
++ US Software goFast library.
++ _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
++ two integers to the FLO_union_type.
++ NO_DENORMALS: Disable handling of denormals.
++ NO_NANS: Disable nan and infinity handling
++ SMALL_MACHINE: Useful when operations on QIs and HIs are faster
++ than on an SI */
++
++/* We don't currently support extended floats (long doubles) on machines
++ without hardware to deal with them.
++
++ These stubs are just to keep the linker from complaining about unresolved
++ references which can be pulled in from libio & libstdc++, even if the
++ user isn't using long doubles. However, they may generate an unresolved
++ external to abort if abort is not used by the function, and the stubs
++ are referenced from within libc, since libgcc goes before and after the
++ system library. */
++
++#ifdef DECLARE_LIBRARY_RENAMES
++ DECLARE_LIBRARY_RENAMES
++#endif
++
++#ifdef EXTENDED_FLOAT_STUBS
++extern void abort (void);
++void __extendsfxf2 (void) { abort(); }
++void __extenddfxf2 (void) { abort(); }
++void __truncxfdf2 (void) { abort(); }
++void __truncxfsf2 (void) { abort(); }
++void __fixxfsi (void) { abort(); }
++void __floatsixf (void) { abort(); }
++void __addxf3 (void) { abort(); }
++void __subxf3 (void) { abort(); }
++void __mulxf3 (void) { abort(); }
++void __divxf3 (void) { abort(); }
++void __negxf2 (void) { abort(); }
++void __eqxf2 (void) { abort(); }
++void __nexf2 (void) { abort(); }
++void __gtxf2 (void) { abort(); }
++void __gexf2 (void) { abort(); }
++void __lexf2 (void) { abort(); }
++void __ltxf2 (void) { abort(); }
++
++void __extendsftf2 (void) { abort(); }
++void __extenddftf2 (void) { abort(); }
++void __trunctfdf2 (void) { abort(); }
++void __trunctfsf2 (void) { abort(); }
++void __fixtfsi (void) { abort(); }
++void __floatsitf (void) { abort(); }
++void __addtf3 (void) { abort(); }
++void __subtf3 (void) { abort(); }
++void __multf3 (void) { abort(); }
++void __divtf3 (void) { abort(); }
++void __negtf2 (void) { abort(); }
++void __eqtf2 (void) { abort(); }
++void __netf2 (void) { abort(); }
++void __gttf2 (void) { abort(); }
++void __getf2 (void) { abort(); }
++void __letf2 (void) { abort(); }
++void __lttf2 (void) { abort(); }
++#else /* !EXTENDED_FLOAT_STUBS, rest of file */
++
++/* IEEE "special" number predicates */
++
++#ifdef NO_NANS
++
++#define nan() 0
++#define isnan(x) 0
++#define isinf(x) 0
++#else
++
++#if defined L_thenan_sf
++const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
++#elif defined L_thenan_df
++const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
++#elif defined L_thenan_tf
++const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
++#elif defined TFLOAT
++extern const fp_number_type __thenan_tf;
++#elif defined FLOAT
++extern const fp_number_type __thenan_sf;
++#else
++extern const fp_number_type __thenan_df;
++#endif
++
++INLINE
++static fp_number_type *
++nan (void)
++{
++ /* Discard the const qualifier... */
++#ifdef TFLOAT
++ return (fp_number_type *) (& __thenan_tf);
++#elif defined FLOAT
++ return (fp_number_type *) (& __thenan_sf);
++#else
++ return (fp_number_type *) (& __thenan_df);
++#endif
++}
++
++INLINE
++static int
++isnan ( fp_number_type * x)
++{
++ return x->class == CLASS_SNAN || x->class == CLASS_QNAN;
++}
++
++INLINE
++static int
++isinf ( fp_number_type * x)
++{
++ return x->class == CLASS_INFINITY;
++}
++
++#endif /* NO_NANS */
++
++INLINE
++static int
++iszero ( fp_number_type * x)
++{
++ return x->class == CLASS_ZERO;
++}
++
++INLINE
++static void
++flip_sign ( fp_number_type * x)
++{
++ x->sign = !x->sign;
++}
++
++extern FLO_type pack_d ( fp_number_type * );
++
++#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
++FLO_type
++pack_d ( fp_number_type * src)
++{
++ FLO_union_type dst;
++ fractype fraction = src->fraction.ll; /* wasn't unsigned before? */
++ int sign = src->sign;
++ int exp = 0;
++
++ if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
++ {
++ /* We can't represent these values accurately. By using the
++ largest possible magnitude, we guarantee that the conversion
++ of infinity is at least as big as any finite number. */
++ exp = EXPMAX;
++ fraction = ((fractype) 1 << FRACBITS) - 1;
++ }
++ else if (isnan (src))
++ {
++ exp = EXPMAX;
++ if (src->class == CLASS_QNAN || 1)
++ {
++#ifdef QUIET_NAN_NEGATED
++ fraction |= QUIET_NAN - 1;
++#else
++ fraction |= QUIET_NAN;
++#endif
++ }
++ }
++ else if (isinf (src))
++ {
++ exp = EXPMAX;
++ fraction = 0;
++ }
++ else if (iszero (src))
++ {
++ exp = 0;
++ fraction = 0;
++ }
++ else if (fraction == 0)
++ {
++ exp = 0;
++ }
++ else
++ {
++ if (src->normal_exp < NORMAL_EXPMIN)
++ {
++#ifdef NO_DENORMALS
++ /* Go straight to a zero representation if denormals are not
++ supported. The denormal handling would be harmless but
++ isn't unnecessary. */
++ exp = 0;
++ fraction = 0;
++#else /* NO_DENORMALS */
++ /* This number's exponent is too low to fit into the bits
++ available in the number, so we'll store 0 in the exponent and
++ shift the fraction to the right to make up for it. */
++
++ int shift = NORMAL_EXPMIN - src->normal_exp;
++
++ exp = 0;
++
++ if (shift > FRAC_NBITS - NGARDS)
++ {
++ /* No point shifting, since it's more that 64 out. */
++ fraction = 0;
++ }
++ else
++ {
++ int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
++ fraction = (fraction >> shift) | lowbit;
++ }
++ if ((fraction & GARDMASK) == GARDMSB)
++ {
++ if ((fraction & (1 << NGARDS)))
++ fraction += GARDROUND + 1;
++ }
++ else
++ {
++ /* Add to the guards to round up. */
++ fraction += GARDROUND;
++ }
++ /* Perhaps the rounding means we now need to change the
++ exponent, because the fraction is no longer denormal. */
++ if (fraction >= IMPLICIT_1)
++ {
++ exp += 1;
++ }
++ fraction >>= NGARDS;
++#endif /* NO_DENORMALS */
++ }
++ else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
++ && src->normal_exp > EXPBIAS)
++ {
++ exp = EXPMAX;
++ fraction = 0;
++ }
++ else
++ {
++ exp = src->normal_exp + EXPBIAS;
++ if (!ROUND_TOWARDS_ZERO)
++ {
++ /* IF the gard bits are the all zero, but the first, then we're
++ half way between two numbers, choose the one which makes the
++ lsb of the answer 0. */
++ if ((fraction & GARDMASK) == GARDMSB)
++ {
++ if (fraction & (1 << NGARDS))
++ fraction += GARDROUND + 1;
++ }
++ else
++ {
++ /* Add a one to the guards to round up */
++ fraction += GARDROUND;
++ }
++ if (fraction >= IMPLICIT_2)
++ {
++ fraction >>= 1;
++ exp += 1;
++ }
++ }
++ fraction >>= NGARDS;
++
++ if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
++ {
++ /* Saturate on overflow. */
++ exp = EXPMAX;
++ fraction = ((fractype) 1 << FRACBITS) - 1;
++ }
++ }
++ }
++
++ /* We previously used bitfields to store the number, but this doesn't
++ handle little/big endian systems conveniently, so use shifts and
++ masks */
++#ifdef FLOAT_BIT_ORDER_MISMATCH
++ dst.bits.fraction = fraction;
++ dst.bits.exp = exp;
++ dst.bits.sign = sign;
++#else
++# if defined TFLOAT && defined HALFFRACBITS
++ {
++ halffractype high, low, unity;
++ int lowsign, lowexp;
++
++ unity = (halffractype) 1 << HALFFRACBITS;
++
++ /* Set HIGH to the high double's significand, masking out the implicit 1.
++ Set LOW to the low double's full significand. */
++ high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
++ low = fraction & (unity * 2 - 1);
++
++ /* Get the initial sign and exponent of the low double. */
++ lowexp = exp - HALFFRACBITS - 1;
++ lowsign = sign;
++
++ /* HIGH should be rounded like a normal double, making |LOW| <=
++ 0.5 ULP of HIGH. Assume round-to-nearest. */
++ if (exp < EXPMAX)
++ if (low > unity || (low == unity && (high & 1) == 1))
++ {
++ /* Round HIGH up and adjust LOW to match. */
++ high++;
++ if (high == unity)
++ {
++ /* May make it infinite, but that's OK. */
++ high = 0;
++ exp++;
++ }
++ low = unity * 2 - low;
++ lowsign ^= 1;
++ }
++
++ high |= (halffractype) exp << HALFFRACBITS;
++ high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
++
++ if (exp == EXPMAX || exp == 0 || low == 0)
++ low = 0;
++ else
++ {
++ while (lowexp > 0 && low < unity)
++ {
++ low <<= 1;
++ lowexp--;
++ }
++
++ if (lowexp <= 0)
++ {
++ halffractype roundmsb, round;
++ int shift;
++
++ shift = 1 - lowexp;
++ roundmsb = (1 << (shift - 1));
++ round = low & ((roundmsb << 1) - 1);
++
++ low >>= shift;
++ lowexp = 0;
++
++ if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
++ {
++ low++;
++ if (low == unity)
++ /* LOW rounds up to the smallest normal number. */
++ lowexp++;
++ }
++ }
++
++ low &= unity - 1;
++ low |= (halffractype) lowexp << HALFFRACBITS;
++ low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
++ }
++ dst.value_raw = ((fractype) high << HALFSHIFT) | low;
++ }
++# else
++ dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
++ dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
++ dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
++# endif
++#endif
++
++#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
++#ifdef TFLOAT
++ {
++ qrtrfractype tmp1 = dst.words[0];
++ qrtrfractype tmp2 = dst.words[1];
++ dst.words[0] = dst.words[3];
++ dst.words[1] = dst.words[2];
++ dst.words[2] = tmp2;
++ dst.words[3] = tmp1;
++ }
++#else
++ {
++ halffractype tmp = dst.words[0];
++ dst.words[0] = dst.words[1];
++ dst.words[1] = tmp;
++ }
++#endif
++#endif
++
++ return dst.value;
++}
++#endif
++
++#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
++void
++unpack_d (FLO_union_type * src, fp_number_type * dst)
++{
++ /* We previously used bitfields to store the number, but this doesn't
++ handle little/big endian systems conveniently, so use shifts and
++ masks */
++ fractype fraction;
++ int exp;
++ int sign;
++
++#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
++ FLO_union_type swapped;
++
++#ifdef TFLOAT
++ swapped.words[0] = src->words[3];
++ swapped.words[1] = src->words[2];
++ swapped.words[2] = src->words[1];
++ swapped.words[3] = src->words[0];
++#else
++ swapped.words[0] = src->words[1];
++ swapped.words[1] = src->words[0];
++#endif
++ src = &swapped;
++#endif
++
++#ifdef FLOAT_BIT_ORDER_MISMATCH
++ fraction = src->bits.fraction;
++ exp = src->bits.exp;
++ sign = src->bits.sign;
++#else
++# if defined TFLOAT && defined HALFFRACBITS
++ {
++ halffractype high, low;
++
++ high = src->value_raw >> HALFSHIFT;
++ low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
++
++ fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
++ fraction <<= FRACBITS - HALFFRACBITS;
++ exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
++ sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
++
++ if (exp != EXPMAX && exp != 0 && low != 0)
++ {
++ int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
++ int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
++ int shift;
++ fractype xlow;
++
++ xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
++ if (lowexp)
++ xlow |= (((halffractype)1) << HALFFRACBITS);
++ else
++ lowexp = 1;
++ shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
++ if (shift > 0)
++ xlow <<= shift;
++ else if (shift < 0)
++ xlow >>= -shift;
++ if (sign == lowsign)
++ fraction += xlow;
++ else if (fraction >= xlow)
++ fraction -= xlow;
++ else
++ {
++ /* The high part is a power of two but the full number is lower.
++ This code will leave the implicit 1 in FRACTION, but we'd
++ have added that below anyway. */
++ fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
++ exp--;
++ }
++ }
++ }
++# else
++ fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
++ exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
++ sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
++# endif
++#endif
++
++ dst->sign = sign;
++ if (exp == 0)
++ {
++ /* Hmm. Looks like 0 */
++ if (fraction == 0
++#ifdef NO_DENORMALS
++ || 1
++#endif
++ )
++ {
++ /* tastes like zero */
++ dst->class = CLASS_ZERO;
++ }
++ else
++ {
++ /* Zero exponent with nonzero fraction - it's denormalized,
++ so there isn't a leading implicit one - we'll shift it so
++ it gets one. */
++ dst->normal_exp = exp - EXPBIAS + 1;
++ fraction <<= NGARDS;
++
++ dst->class = CLASS_NUMBER;
++#if 1
++ while (fraction < IMPLICIT_1)
++ {
++ fraction <<= 1;
++ dst->normal_exp--;
++ }
++#endif
++ dst->fraction.ll = fraction;
++ }
++ }
++ else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp == EXPMAX)
++ {
++ /* Huge exponent*/
++ if (fraction == 0)
++ {
++ /* Attached to a zero fraction - means infinity */
++ dst->class = CLASS_INFINITY;
++ }
++ else
++ {
++ /* Nonzero fraction, means nan */
++#ifdef QUIET_NAN_NEGATED
++ if ((fraction & QUIET_NAN) == 0)
++#else
++ if (fraction & QUIET_NAN)
++#endif
++ {
++ dst->class = CLASS_QNAN;
++ }
++ else
++ {
++ dst->class = CLASS_SNAN;
++ }
++ /* Keep the fraction part as the nan number */
++ dst->fraction.ll = fraction;
++ }
++ }
++ else
++ {
++ /* Nothing strange about this number */
++ dst->normal_exp = exp - EXPBIAS;
++ dst->class = CLASS_NUMBER;
++ dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
++ }
++}
++#endif /* L_unpack_df || L_unpack_sf */
++
++#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
++static fp_number_type *
++_fpadd_parts (fp_number_type * a,
++ fp_number_type * b,
++ fp_number_type * tmp)
++{
++ intfrac tfraction;
++
++ /* Put commonly used fields in local variables. */
++ int a_normal_exp;
++ int b_normal_exp;
++ fractype a_fraction;
++ fractype b_fraction;
++
++ if (isnan (a))
++ {
++ return a;
++ }
++ if (isnan (b))
++ {
++ return b;
++ }
++ if (isinf (a))
++ {
++ /* Adding infinities with opposite signs yields a NaN. */
++ if (isinf (b) && a->sign != b->sign)
++ return nan ();
++ return a;
++ }
++ if (isinf (b))
++ {
++ return b;
++ }
++ if (iszero (b))
++ {
++ if (iszero (a))
++ {
++ *tmp = *a;
++ tmp->sign = a->sign & b->sign;
++ return tmp;
++ }
++ return a;
++ }
++ if (iszero (a))
++ {
++ return b;
++ }
++
++ /* Got two numbers. shift the smaller and increment the exponent till
++ they're the same */
++ {
++ int diff;
++
++ a_normal_exp = a->normal_exp;
++ b_normal_exp = b->normal_exp;
++ a_fraction = a->fraction.ll;
++ b_fraction = b->fraction.ll;
++
++ diff = a_normal_exp - b_normal_exp;
++
++ if (diff < 0)
++ diff = -diff;
++ if (diff < FRAC_NBITS)
++ {
++ /* ??? This does shifts one bit at a time. Optimize. */
++ while (a_normal_exp > b_normal_exp)
++ {
++ b_normal_exp++;
++ LSHIFT (b_fraction);
++ }
++ while (b_normal_exp > a_normal_exp)
++ {
++ a_normal_exp++;
++ LSHIFT (a_fraction);
++ }
++ }
++ else
++ {
++ /* Somethings's up.. choose the biggest */
++ if (a_normal_exp > b_normal_exp)
++ {
++ b_normal_exp = a_normal_exp;
++ b_fraction = 0;
++ }
++ else
++ {
++ a_normal_exp = b_normal_exp;
++ a_fraction = 0;
++ }
++ }
++ }
++
++ if (a->sign != b->sign)
++ {
++ if (a->sign)
++ {
++ tfraction = -a_fraction + b_fraction;
++ }
++ else
++ {
++ tfraction = a_fraction - b_fraction;
++ }
++ if (tfraction >= 0)
++ {
++ tmp->sign = 0;
++ tmp->normal_exp = a_normal_exp;
++ tmp->fraction.ll = tfraction;
++ }
++ else
++ {
++ tmp->sign = 1;
++ tmp->normal_exp = a_normal_exp;
++ tmp->fraction.ll = -tfraction;
++ }
++ /* and renormalize it */
++
++ while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
++ {
++ tmp->fraction.ll <<= 1;
++ tmp->normal_exp--;
++ }
++ }
++ else
++ {
++ tmp->sign = a->sign;
++ tmp->normal_exp = a_normal_exp;
++ tmp->fraction.ll = a_fraction + b_fraction;
++ }
++ tmp->class = CLASS_NUMBER;
++ /* Now the fraction is added, we have to shift down to renormalize the
++ number */
++
++ if (tmp->fraction.ll >= IMPLICIT_2)
++ {
++ LSHIFT (tmp->fraction.ll);
++ tmp->normal_exp++;
++ }
++ return tmp;
++
++}
++
++FLO_type
++add (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ fp_number_type tmp;
++ fp_number_type *res;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ res = _fpadd_parts (&a, &b, &tmp);
++
++ return pack_d (res);
++}
++
++FLO_type
++sub (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ fp_number_type tmp;
++ fp_number_type *res;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ b.sign ^= 1;
++
++ res = _fpadd_parts (&a, &b, &tmp);
++
++ return pack_d (res);
++}
++#endif /* L_addsub_sf || L_addsub_df */
++
++#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
++static inline __attribute__ ((__always_inline__)) fp_number_type *
++_fpmul_parts ( fp_number_type * a,
++ fp_number_type * b,
++ fp_number_type * tmp)
++{
++ fractype low = 0;
++ fractype high = 0;
++
++ if (isnan (a))
++ {
++ a->sign = a->sign != b->sign;
++ return a;
++ }
++ if (isnan (b))
++ {
++ b->sign = a->sign != b->sign;
++ return b;
++ }
++ if (isinf (a))
++ {
++ if (iszero (b))
++ return nan ();
++ a->sign = a->sign != b->sign;
++ return a;
++ }
++ if (isinf (b))
++ {
++ if (iszero (a))
++ {
++ return nan ();
++ }
++ b->sign = a->sign != b->sign;
++ return b;
++ }
++ if (iszero (a))
++ {
++ a->sign = a->sign != b->sign;
++ return a;
++ }
++ if (iszero (b))
++ {
++ b->sign = a->sign != b->sign;
++ return b;
++ }
++
++ /* Calculate the mantissa by multiplying both numbers to get a
++ twice-as-wide number. */
++ {
++#if defined(NO_DI_MODE) || defined(TFLOAT)
++ {
++ fractype x = a->fraction.ll;
++ fractype ylow = b->fraction.ll;
++ fractype yhigh = 0;
++ int bit;
++
++ /* ??? This does multiplies one bit at a time. Optimize. */
++ for (bit = 0; bit < FRAC_NBITS; bit++)
++ {
++ int carry;
++
++ if (x & 1)
++ {
++ carry = (low += ylow) < ylow;
++ high += yhigh + carry;
++ }
++ yhigh <<= 1;
++ if (ylow & FRACHIGH)
++ {
++ yhigh |= 1;
++ }
++ ylow <<= 1;
++ x >>= 1;
++ }
++ }
++#elif defined(FLOAT)
++ /* Multiplying two USIs to get a UDI, we're safe. */
++ {
++ UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
++
++ high = answer >> BITS_PER_SI;
++ low = answer;
++ }
++#else
++ /* fractype is DImode, but we need the result to be twice as wide.
++ Assuming a widening multiply from DImode to TImode is not
++ available, build one by hand. */
++ {
++ USItype nl = a->fraction.ll;
++ USItype nh = a->fraction.ll >> BITS_PER_SI;
++ USItype ml = b->fraction.ll;
++ USItype mh = b->fraction.ll >> BITS_PER_SI;
++ UDItype pp_ll = (UDItype) ml * nl;
++ UDItype pp_hl = (UDItype) mh * nl;
++ UDItype pp_lh = (UDItype) ml * nh;
++ UDItype pp_hh = (UDItype) mh * nh;
++ UDItype res2 = 0;
++ UDItype res0 = 0;
++ UDItype ps_hh__ = pp_hl + pp_lh;
++ if (ps_hh__ < pp_hl)
++ res2 += (UDItype)1 << BITS_PER_SI;
++ pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
++ res0 = pp_ll + pp_hl;
++ if (res0 < pp_ll)
++ res2++;
++ res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
++ high = res2;
++ low = res0;
++ }
++#endif
++ }
++
++ tmp->normal_exp = a->normal_exp + b->normal_exp
++ + FRAC_NBITS - (FRACBITS + NGARDS);
++ tmp->sign = a->sign != b->sign;
++ while (high >= IMPLICIT_2)
++ {
++ tmp->normal_exp++;
++ if (high & 1)
++ {
++ low >>= 1;
++ low |= FRACHIGH;
++ }
++ high >>= 1;
++ }
++ while (high < IMPLICIT_1)
++ {
++ tmp->normal_exp--;
++
++ high <<= 1;
++ if (low & FRACHIGH)
++ high |= 1;
++ low <<= 1;
++ }
++ /* rounding is tricky. if we only round if it won't make us round later. */
++#if 0
++ if (low & FRACHIGH2)
++ {
++ if (((high & GARDMASK) != GARDMSB)
++ && (((high + 1) & GARDMASK) == GARDMSB))
++ {
++ /* don't round, it gets done again later. */
++ }
++ else
++ {
++ high++;
++ }
++ }
++#endif
++ if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
++ {
++ if (high & (1 << NGARDS))
++ {
++ /* half way, so round to even */
++ high += GARDROUND + 1;
++ }
++ else if (low)
++ {
++ /* but we really weren't half way */
++ high += GARDROUND + 1;
++ }
++ }
++ tmp->fraction.ll = high;
++ tmp->class = CLASS_NUMBER;
++ return tmp;
++}
++
++FLO_type
++multiply (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ fp_number_type tmp;
++ fp_number_type *res;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ res = _fpmul_parts (&a, &b, &tmp);
++
++ return pack_d (res);
++}
++#endif /* L_mul_sf || L_mul_df */
++
++#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
++static inline __attribute__ ((__always_inline__)) fp_number_type *
++_fpdiv_parts (fp_number_type * a,
++ fp_number_type * b)
++{
++ fractype bit;
++ fractype numerator;
++ fractype denominator;
++ fractype quotient;
++
++ if (isnan (a))
++ {
++ return a;
++ }
++ if (isnan (b))
++ {
++ return b;
++ }
++
++ a->sign = a->sign ^ b->sign;
++
++ if (isinf (a) || iszero (a))
++ {
++ if (a->class == b->class)
++ return nan ();
++ return a;
++ }
++
++ if (isinf (b))
++ {
++ a->fraction.ll = 0;
++ a->normal_exp = 0;
++ return a;
++ }
++ if (iszero (b))
++ {
++ a->class = CLASS_INFINITY;
++ return a;
++ }
++
++ /* Calculate the mantissa by multiplying both 64bit numbers to get a
++ 128 bit number */
++ {
++ /* quotient =
++ ( numerator / denominator) * 2^(numerator exponent - denominator exponent)
++ */
++
++ a->normal_exp = a->normal_exp - b->normal_exp;
++ numerator = a->fraction.ll;
++ denominator = b->fraction.ll;
++
++ if (numerator < denominator)
++ {
++ /* Fraction will be less than 1.0 */
++ numerator *= 2;
++ a->normal_exp--;
++ }
++ bit = IMPLICIT_1;
++ quotient = 0;
++ /* ??? Does divide one bit at a time. Optimize. */
++ while (bit)
++ {
++ if (numerator >= denominator)
++ {
++ quotient |= bit;
++ numerator -= denominator;
++ }
++ bit >>= 1;
++ numerator *= 2;
++ }
++
++ if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
++ {
++ if (quotient & (1 << NGARDS))
++ {
++ /* half way, so round to even */
++ quotient += GARDROUND + 1;
++ }
++ else if (numerator)
++ {
++ /* but we really weren't half way, more bits exist */
++ quotient += GARDROUND + 1;
++ }
++ }
++
++ a->fraction.ll = quotient;
++ return (a);
++ }
++}
++
++FLO_type
++divide (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ fp_number_type *res;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ res = _fpdiv_parts (&a, &b);
++
++ return pack_d (res);
++}
++#endif /* L_div_sf || L_div_df */
++
++#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
++ || defined(L_fpcmp_parts_tf)
++/* according to the demo, fpcmp returns a comparison with 0... thus
++ a<b -> -1
++ a==b -> 0
++ a>b -> +1
++ */
++
++int
++__fpcmp_parts (fp_number_type * a, fp_number_type * b)
++{
++#if 0
++ /* either nan -> unordered. Must be checked outside of this routine. */
++ if (isnan (a) && isnan (b))
++ {
++ return 1; /* still unordered! */
++ }
++#endif
++
++ if (isnan (a) || isnan (b))
++ {
++ return 1; /* how to indicate unordered compare? */
++ }
++ if (isinf (a) && isinf (b))
++ {
++ /* +inf > -inf, but +inf != +inf */
++ /* b \a| +inf(0)| -inf(1)
++ ______\+--------+--------
++ +inf(0)| a==b(0)| a<b(-1)
++ -------+--------+--------
++ -inf(1)| a>b(1) | a==b(0)
++ -------+--------+--------
++ So since unordered must be nonzero, just line up the columns...
++ */
++ return b->sign - a->sign;
++ }
++ /* but not both... */
++ if (isinf (a))
++ {
++ return a->sign ? -1 : 1;
++ }
++ if (isinf (b))
++ {
++ return b->sign ? 1 : -1;
++ }
++ if (iszero (a) && iszero (b))
++ {
++ return 0;
++ }
++ if (iszero (a))
++ {
++ return b->sign ? 1 : -1;
++ }
++ if (iszero (b))
++ {
++ return a->sign ? -1 : 1;
++ }
++ /* now both are "normal". */
++ if (a->sign != b->sign)
++ {
++ /* opposite signs */
++ return a->sign ? -1 : 1;
++ }
++ /* same sign; exponents? */
++ if (a->normal_exp > b->normal_exp)
++ {
++ return a->sign ? -1 : 1;
++ }
++ if (a->normal_exp < b->normal_exp)
++ {
++ return a->sign ? 1 : -1;
++ }
++ /* same exponents; check size. */
++ if (a->fraction.ll > b->fraction.ll)
++ {
++ return a->sign ? -1 : 1;
++ }
++ if (a->fraction.ll < b->fraction.ll)
++ {
++ return a->sign ? 1 : -1;
++ }
++ /* after all that, they're equal. */
++ return 0;
++}
++#endif
++
++#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
++CMPtype
++compare (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ return __fpcmp_parts (&a, &b);
++}
++#endif /* L_compare_sf || L_compare_df */
++
++#ifndef US_SOFTWARE_GOFAST
++
++/* These should be optimized for their specific tasks someday. */
++
++#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
++CMPtype
++_eq_f2 (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ if (isnan (&a) || isnan (&b))
++ return 1; /* false, truth == 0 */
++
++ return __fpcmp_parts (&a, &b) ;
++}
++#endif /* L_eq_sf || L_eq_df */
++
++#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
++CMPtype
++_ne_f2 (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ if (isnan (&a) || isnan (&b))
++ return 1; /* true, truth != 0 */
++
++ return __fpcmp_parts (&a, &b) ;
++}
++#endif /* L_ne_sf || L_ne_df */
++
++#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
++CMPtype
++_gt_f2 (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ if (isnan (&a) || isnan (&b))
++ return -1; /* false, truth > 0 */
++
++ return __fpcmp_parts (&a, &b);
++}
++#endif /* L_gt_sf || L_gt_df */
++
++#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
++CMPtype
++_ge_f2 (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ if (isnan (&a) || isnan (&b))
++ return -1; /* false, truth >= 0 */
++ return __fpcmp_parts (&a, &b) ;
++}
++#endif /* L_ge_sf || L_ge_df */
++
++#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
++CMPtype
++_lt_f2 (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ if (isnan (&a) || isnan (&b))
++ return 1; /* false, truth < 0 */
++
++ return __fpcmp_parts (&a, &b);
++}
++#endif /* L_lt_sf || L_lt_df */
++
++#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
++CMPtype
++_le_f2 (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ if (isnan (&a) || isnan (&b))
++ return 1; /* false, truth <= 0 */
++
++ return __fpcmp_parts (&a, &b) ;
++}
++#endif /* L_le_sf || L_le_df */
++
++#endif /* ! US_SOFTWARE_GOFAST */
++
++#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
++CMPtype
++_unord_f2 (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ return (isnan (&a) || isnan (&b));
++}
++#endif /* L_unord_sf || L_unord_df */
++
++#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
++FLO_type
++si_to_float (SItype arg_a)
++{
++ fp_number_type in;
++
++ in.class = CLASS_NUMBER;
++ in.sign = arg_a < 0;
++ if (!arg_a)
++ {
++ in.class = CLASS_ZERO;
++ }
++ else
++ {
++ in.normal_exp = FRACBITS + NGARDS;
++ if (in.sign)
++ {
++ /* Special case for minint, since there is no +ve integer
++ representation for it */
++ if (arg_a == (- MAX_SI_INT - 1))
++ {
++ return (FLO_type)(- MAX_SI_INT - 1);
++ }
++ in.fraction.ll = (-arg_a);
++ }
++ else
++ in.fraction.ll = arg_a;
++
++ while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
++ {
++ in.fraction.ll <<= 1;
++ in.normal_exp -= 1;
++ }
++ }
++ return pack_d (&in);
++}
++#endif /* L_si_to_sf || L_si_to_df */
++
++#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
++FLO_type
++usi_to_float (USItype arg_a)
++{
++ fp_number_type in;
++
++ in.sign = 0;
++ if (!arg_a)
++ {
++ in.class = CLASS_ZERO;
++ }
++ else
++ {
++ in.class = CLASS_NUMBER;
++ in.normal_exp = FRACBITS + NGARDS;
++ in.fraction.ll = arg_a;
++
++ while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS)))
++ {
++ in.fraction.ll >>= 1;
++ in.normal_exp += 1;
++ }
++ while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
++ {
++ in.fraction.ll <<= 1;
++ in.normal_exp -= 1;
++ }
++ }
++ return pack_d (&in);
++}
++#endif
++
++#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
++SItype
++float_to_si (FLO_type arg_a)
++{
++ fp_number_type a;
++ SItype tmp;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &a);
++
++ if (iszero (&a))
++ return 0;
++ if (isnan (&a))
++ return 0;
++ /* get reasonable MAX_SI_INT... */
++ if (isinf (&a))
++ return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
++ /* it is a number, but a small one */
++ if (a.normal_exp < 0)
++ return 0;
++ if (a.normal_exp > BITS_PER_SI - 2)
++ return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
++ tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
++ return a.sign ? (-tmp) : (tmp);
++}
++#endif /* L_sf_to_si || L_df_to_si */
++
++#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi)
++#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi)
++/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
++ we also define them for GOFAST because the ones in libgcc2.c have the
++ wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
++ out of libgcc2.c. We can't define these here if not GOFAST because then
++ there'd be duplicate copies. */
++
++USItype
++float_to_usi (FLO_type arg_a)
++{
++ fp_number_type a;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &a);
++
++ if (iszero (&a))
++ return 0;
++ if (isnan (&a))
++ return 0;
++ /* it is a negative number */
++ if (a.sign)
++ return 0;
++ /* get reasonable MAX_USI_INT... */
++ if (isinf (&a))
++ return MAX_USI_INT;
++ /* it is a number, but a small one */
++ if (a.normal_exp < 0)
++ return 0;
++ if (a.normal_exp > BITS_PER_SI - 1)
++ return MAX_USI_INT;
++ else if (a.normal_exp > (FRACBITS + NGARDS))
++ return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
++ else
++ return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
++}
++#endif /* US_SOFTWARE_GOFAST */
++#endif /* L_sf_to_usi || L_df_to_usi */
++
++#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
++FLO_type
++negate (FLO_type arg_a)
++{
++ fp_number_type a;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &a);
++
++ flip_sign (&a);
++ return pack_d (&a);
++}
++#endif /* L_negate_sf || L_negate_df */
++
++#ifdef FLOAT
++
++#if defined(L_make_sf)
++SFtype
++__make_fp(fp_class_type class,
++ unsigned int sign,
++ int exp,
++ USItype frac)
++{
++ fp_number_type in;
++
++ in.class = class;
++ in.sign = sign;
++ in.normal_exp = exp;
++ in.fraction.ll = frac;
++ return pack_d (&in);
++}
++#endif /* L_make_sf */
++
++#ifndef FLOAT_ONLY
++
++/* This enables one to build an fp library that supports float but not double.
++ Otherwise, we would get an undefined reference to __make_dp.
++ This is needed for some 8-bit ports that can't handle well values that
++ are 8-bytes in size, so we just don't support double for them at all. */
++
++#if defined(L_sf_to_df)
++DFtype
++sf_to_df (SFtype arg_a)
++{
++ fp_number_type in;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &in);
++
++ return __make_dp (in.class, in.sign, in.normal_exp,
++ ((UDItype) in.fraction.ll) << F_D_BITOFF);
++}
++#endif /* L_sf_to_df */
++
++#if defined(L_sf_to_tf) && defined(TMODES)
++TFtype
++sf_to_tf (SFtype arg_a)
++{
++ fp_number_type in;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &in);
++
++ return __make_tp (in.class, in.sign, in.normal_exp,
++ ((UTItype) in.fraction.ll) << F_T_BITOFF);
++}
++#endif /* L_sf_to_df */
++
++#endif /* ! FLOAT_ONLY */
++#endif /* FLOAT */
++
++#ifndef FLOAT
++
++extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
++
++#if defined(L_make_df)
++DFtype
++__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
++{
++ fp_number_type in;
++
++ in.class = class;
++ in.sign = sign;
++ in.normal_exp = exp;
++ in.fraction.ll = frac;
++ return pack_d (&in);
++}
++#endif /* L_make_df */
++
++#if defined(L_df_to_sf)
++SFtype
++df_to_sf (DFtype arg_a)
++{
++ fp_number_type in;
++ USItype sffrac;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &in);
++
++ sffrac = in.fraction.ll >> F_D_BITOFF;
++
++ /* We set the lowest guard bit in SFFRAC if we discarded any non
++ zero bits. */
++ if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
++ sffrac |= 1;
++
++ return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
++}
++#endif /* L_df_to_sf */
++
++#if defined(L_df_to_tf) && defined(TMODES) \
++ && !defined(FLOAT) && !defined(TFLOAT)
++TFtype
++df_to_tf (DFtype arg_a)
++{
++ fp_number_type in;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &in);
++
++ return __make_tp (in.class, in.sign, in.normal_exp,
++ ((UTItype) in.fraction.ll) << D_T_BITOFF);
++}
++#endif /* L_sf_to_df */
++
++#ifdef TFLOAT
++#if defined(L_make_tf)
++TFtype
++__make_tp(fp_class_type class,
++ unsigned int sign,
++ int exp,
++ UTItype frac)
++{
++ fp_number_type in;
++
++ in.class = class;
++ in.sign = sign;
++ in.normal_exp = exp;
++ in.fraction.ll = frac;
++ return pack_d (&in);
++}
++#endif /* L_make_tf */
++
++#if defined(L_tf_to_df)
++DFtype
++tf_to_df (TFtype arg_a)
++{
++ fp_number_type in;
++ UDItype sffrac;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &in);
++
++ sffrac = in.fraction.ll >> D_T_BITOFF;
++
++ /* We set the lowest guard bit in SFFRAC if we discarded any non
++ zero bits. */
++ if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
++ sffrac |= 1;
++
++ return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
++}
++#endif /* L_tf_to_df */
++
++#if defined(L_tf_to_sf)
++SFtype
++tf_to_sf (TFtype arg_a)
++{
++ fp_number_type in;
++ USItype sffrac;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &in);
++
++ sffrac = in.fraction.ll >> F_T_BITOFF;
++
++ /* We set the lowest guard bit in SFFRAC if we discarded any non
++ zero bits. */
++ if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
++ sffrac |= 1;
++
++ return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
++}
++#endif /* L_tf_to_sf */
++#endif /* TFLOAT */
++
++#endif /* ! FLOAT */
++#endif /* !EXTENDED_FLOAT_STUBS */
+--- gcc-3.4.3/gcc/config/nios2/nios2-fp-bit.c
++++ gcc-3.4.3-nios2/gcc/config/nios2/nios2-fp-bit.c
+@@ -0,0 +1,1652 @@
++#define FLOAT
++/* This is a software floating point library which can be used
++ for targets without hardware floating point.
++ Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
++ Free Software Foundation, Inc.
++
++This file is free software; you can redistribute it and/or modify it
++under the terms of the GNU General Public License as published by the
++Free Software Foundation; either version 2, or (at your option) any
++later version.
++
++In addition to the permissions in the GNU General Public License, the
++Free Software Foundation gives you unlimited permission to link the
++compiled version of this file with other programs, and to distribute
++those programs without any restriction coming from the use of this
++file. (The General Public License restrictions do apply in other
++respects; for example, they cover modification of the file, and
++distribution when not linked into another program.)
++
++This file is distributed in the hope that it will be useful, but
++WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with this program; see the file COPYING. If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA. */
++
++/* As a special exception, if you link this library with other files,
++ some of which are compiled with GCC, to produce an executable,
++ this library does not by itself cause the resulting executable
++ to be covered by the GNU General Public License.
++ This exception does not however invalidate any other reasons why
++ the executable file might be covered by the GNU General Public License. */
++
++/* This implements IEEE 754 format arithmetic, but does not provide a
++ mechanism for setting the rounding mode, or for generating or handling
++ exceptions.
++
++ The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
++ Wilson, all of Cygnus Support. */
++
++/* The intended way to use this file is to make two copies, add `#define FLOAT'
++ to one copy, then compile both copies and add them to libgcc.a. */
++
++#include "tconfig.h"
++#include "coretypes.h"
++#include "tm.h"
++#include "config/fp-bit.h"
++
++/* The following macros can be defined to change the behavior of this file:
++ FLOAT: Implement a `float', aka SFmode, fp library. If this is not
++ defined, then this file implements a `double', aka DFmode, fp library.
++ FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
++ don't include float->double conversion which requires the double library.
++ This is useful only for machines which can't support doubles, e.g. some
++ 8-bit processors.
++ CMPtype: Specify the type that floating point compares should return.
++ This defaults to SItype, aka int.
++ US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
++ US Software goFast library.
++ _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
++ two integers to the FLO_union_type.
++ NO_DENORMALS: Disable handling of denormals.
++ NO_NANS: Disable nan and infinity handling
++ SMALL_MACHINE: Useful when operations on QIs and HIs are faster
++ than on an SI */
++
++/* We don't currently support extended floats (long doubles) on machines
++ without hardware to deal with them.
++
++ These stubs are just to keep the linker from complaining about unresolved
++ references which can be pulled in from libio & libstdc++, even if the
++ user isn't using long doubles. However, they may generate an unresolved
++ external to abort if abort is not used by the function, and the stubs
++ are referenced from within libc, since libgcc goes before and after the
++ system library. */
++
++#ifdef DECLARE_LIBRARY_RENAMES
++ DECLARE_LIBRARY_RENAMES
++#endif
++
++#ifdef EXTENDED_FLOAT_STUBS
++extern void abort (void);
++void __extendsfxf2 (void) { abort(); }
++void __extenddfxf2 (void) { abort(); }
++void __truncxfdf2 (void) { abort(); }
++void __truncxfsf2 (void) { abort(); }
++void __fixxfsi (void) { abort(); }
++void __floatsixf (void) { abort(); }
++void __addxf3 (void) { abort(); }
++void __subxf3 (void) { abort(); }
++void __mulxf3 (void) { abort(); }
++void __divxf3 (void) { abort(); }
++void __negxf2 (void) { abort(); }
++void __eqxf2 (void) { abort(); }
++void __nexf2 (void) { abort(); }
++void __gtxf2 (void) { abort(); }
++void __gexf2 (void) { abort(); }
++void __lexf2 (void) { abort(); }
++void __ltxf2 (void) { abort(); }
++
++void __extendsftf2 (void) { abort(); }
++void __extenddftf2 (void) { abort(); }
++void __trunctfdf2 (void) { abort(); }
++void __trunctfsf2 (void) { abort(); }
++void __fixtfsi (void) { abort(); }
++void __floatsitf (void) { abort(); }
++void __addtf3 (void) { abort(); }
++void __subtf3 (void) { abort(); }
++void __multf3 (void) { abort(); }
++void __divtf3 (void) { abort(); }
++void __negtf2 (void) { abort(); }
++void __eqtf2 (void) { abort(); }
++void __netf2 (void) { abort(); }
++void __gttf2 (void) { abort(); }
++void __getf2 (void) { abort(); }
++void __letf2 (void) { abort(); }
++void __lttf2 (void) { abort(); }
++#else /* !EXTENDED_FLOAT_STUBS, rest of file */
++
++/* IEEE "special" number predicates */
++
++#ifdef NO_NANS
++
++#define nan() 0
++#define isnan(x) 0
++#define isinf(x) 0
++#else
++
++#if defined L_thenan_sf
++const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
++#elif defined L_thenan_df
++const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
++#elif defined L_thenan_tf
++const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
++#elif defined TFLOAT
++extern const fp_number_type __thenan_tf;
++#elif defined FLOAT
++extern const fp_number_type __thenan_sf;
++#else
++extern const fp_number_type __thenan_df;
++#endif
++
++INLINE
++static fp_number_type *
++nan (void)
++{
++ /* Discard the const qualifier... */
++#ifdef TFLOAT
++ return (fp_number_type *) (& __thenan_tf);
++#elif defined FLOAT
++ return (fp_number_type *) (& __thenan_sf);
++#else
++ return (fp_number_type *) (& __thenan_df);
++#endif
++}
++
++INLINE
++static int
++isnan ( fp_number_type * x)
++{
++ return x->class == CLASS_SNAN || x->class == CLASS_QNAN;
++}
++
++INLINE
++static int
++isinf ( fp_number_type * x)
++{
++ return x->class == CLASS_INFINITY;
++}
++
++#endif /* NO_NANS */
++
++INLINE
++static int
++iszero ( fp_number_type * x)
++{
++ return x->class == CLASS_ZERO;
++}
++
++INLINE
++static void
++flip_sign ( fp_number_type * x)
++{
++ x->sign = !x->sign;
++}
++
++extern FLO_type pack_d ( fp_number_type * );
++
++#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
++FLO_type
++pack_d ( fp_number_type * src)
++{
++ FLO_union_type dst;
++ fractype fraction = src->fraction.ll; /* wasn't unsigned before? */
++ int sign = src->sign;
++ int exp = 0;
++
++ if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
++ {
++ /* We can't represent these values accurately. By using the
++ largest possible magnitude, we guarantee that the conversion
++ of infinity is at least as big as any finite number. */
++ exp = EXPMAX;
++ fraction = ((fractype) 1 << FRACBITS) - 1;
++ }
++ else if (isnan (src))
++ {
++ exp = EXPMAX;
++ if (src->class == CLASS_QNAN || 1)
++ {
++#ifdef QUIET_NAN_NEGATED
++ fraction |= QUIET_NAN - 1;
++#else
++ fraction |= QUIET_NAN;
++#endif
++ }
++ }
++ else if (isinf (src))
++ {
++ exp = EXPMAX;
++ fraction = 0;
++ }
++ else if (iszero (src))
++ {
++ exp = 0;
++ fraction = 0;
++ }
++ else if (fraction == 0)
++ {
++ exp = 0;
++ }
++ else
++ {
++ if (src->normal_exp < NORMAL_EXPMIN)
++ {
++#ifdef NO_DENORMALS
++ /* Go straight to a zero representation if denormals are not
++ supported. The denormal handling would be harmless but
++ isn't unnecessary. */
++ exp = 0;
++ fraction = 0;
++#else /* NO_DENORMALS */
++ /* This number's exponent is too low to fit into the bits
++ available in the number, so we'll store 0 in the exponent and
++ shift the fraction to the right to make up for it. */
++
++ int shift = NORMAL_EXPMIN - src->normal_exp;
++
++ exp = 0;
++
++ if (shift > FRAC_NBITS - NGARDS)
++ {
++ /* No point shifting, since it's more that 64 out. */
++ fraction = 0;
++ }
++ else
++ {
++ int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
++ fraction = (fraction >> shift) | lowbit;
++ }
++ if ((fraction & GARDMASK) == GARDMSB)
++ {
++ if ((fraction & (1 << NGARDS)))
++ fraction += GARDROUND + 1;
++ }
++ else
++ {
++ /* Add to the guards to round up. */
++ fraction += GARDROUND;
++ }
++ /* Perhaps the rounding means we now need to change the
++ exponent, because the fraction is no longer denormal. */
++ if (fraction >= IMPLICIT_1)
++ {
++ exp += 1;
++ }
++ fraction >>= NGARDS;
++#endif /* NO_DENORMALS */
++ }
++ else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
++ && src->normal_exp > EXPBIAS)
++ {
++ exp = EXPMAX;
++ fraction = 0;
++ }
++ else
++ {
++ exp = src->normal_exp + EXPBIAS;
++ if (!ROUND_TOWARDS_ZERO)
++ {
++ /* IF the gard bits are the all zero, but the first, then we're
++ half way between two numbers, choose the one which makes the
++ lsb of the answer 0. */
++ if ((fraction & GARDMASK) == GARDMSB)
++ {
++ if (fraction & (1 << NGARDS))
++ fraction += GARDROUND + 1;
++ }
++ else
++ {
++ /* Add a one to the guards to round up */
++ fraction += GARDROUND;
++ }
++ if (fraction >= IMPLICIT_2)
++ {
++ fraction >>= 1;
++ exp += 1;
++ }
++ }
++ fraction >>= NGARDS;
++
++ if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
++ {
++ /* Saturate on overflow. */
++ exp = EXPMAX;
++ fraction = ((fractype) 1 << FRACBITS) - 1;
++ }
++ }
++ }
++
++ /* We previously used bitfields to store the number, but this doesn't
++ handle little/big endian systems conveniently, so use shifts and
++ masks */
++#ifdef FLOAT_BIT_ORDER_MISMATCH
++ dst.bits.fraction = fraction;
++ dst.bits.exp = exp;
++ dst.bits.sign = sign;
++#else
++# if defined TFLOAT && defined HALFFRACBITS
++ {
++ halffractype high, low, unity;
++ int lowsign, lowexp;
++
++ unity = (halffractype) 1 << HALFFRACBITS;
++
++ /* Set HIGH to the high double's significand, masking out the implicit 1.
++ Set LOW to the low double's full significand. */
++ high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
++ low = fraction & (unity * 2 - 1);
++
++ /* Get the initial sign and exponent of the low double. */
++ lowexp = exp - HALFFRACBITS - 1;
++ lowsign = sign;
++
++ /* HIGH should be rounded like a normal double, making |LOW| <=
++ 0.5 ULP of HIGH. Assume round-to-nearest. */
++ if (exp < EXPMAX)
++ if (low > unity || (low == unity && (high & 1) == 1))
++ {
++ /* Round HIGH up and adjust LOW to match. */
++ high++;
++ if (high == unity)
++ {
++ /* May make it infinite, but that's OK. */
++ high = 0;
++ exp++;
++ }
++ low = unity * 2 - low;
++ lowsign ^= 1;
++ }
++
++ high |= (halffractype) exp << HALFFRACBITS;
++ high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
++
++ if (exp == EXPMAX || exp == 0 || low == 0)
++ low = 0;
++ else
++ {
++ while (lowexp > 0 && low < unity)
++ {
++ low <<= 1;
++ lowexp--;
++ }
++
++ if (lowexp <= 0)
++ {
++ halffractype roundmsb, round;
++ int shift;
++
++ shift = 1 - lowexp;
++ roundmsb = (1 << (shift - 1));
++ round = low & ((roundmsb << 1) - 1);
++
++ low >>= shift;
++ lowexp = 0;
++
++ if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
++ {
++ low++;
++ if (low == unity)
++ /* LOW rounds up to the smallest normal number. */
++ lowexp++;
++ }
++ }
++
++ low &= unity - 1;
++ low |= (halffractype) lowexp << HALFFRACBITS;
++ low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
++ }
++ dst.value_raw = ((fractype) high << HALFSHIFT) | low;
++ }
++# else
++ dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
++ dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
++ dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
++# endif
++#endif
++
++#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
++#ifdef TFLOAT
++ {
++ qrtrfractype tmp1 = dst.words[0];
++ qrtrfractype tmp2 = dst.words[1];
++ dst.words[0] = dst.words[3];
++ dst.words[1] = dst.words[2];
++ dst.words[2] = tmp2;
++ dst.words[3] = tmp1;
++ }
++#else
++ {
++ halffractype tmp = dst.words[0];
++ dst.words[0] = dst.words[1];
++ dst.words[1] = tmp;
++ }
++#endif
++#endif
++
++ return dst.value;
++}
++#endif
++
++#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
++void
++unpack_d (FLO_union_type * src, fp_number_type * dst)
++{
++ /* We previously used bitfields to store the number, but this doesn't
++ handle little/big endian systems conveniently, so use shifts and
++ masks */
++ fractype fraction;
++ int exp;
++ int sign;
++
++#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
++ FLO_union_type swapped;
++
++#ifdef TFLOAT
++ swapped.words[0] = src->words[3];
++ swapped.words[1] = src->words[2];
++ swapped.words[2] = src->words[1];
++ swapped.words[3] = src->words[0];
++#else
++ swapped.words[0] = src->words[1];
++ swapped.words[1] = src->words[0];
++#endif
++ src = &swapped;
++#endif
++
++#ifdef FLOAT_BIT_ORDER_MISMATCH
++ fraction = src->bits.fraction;
++ exp = src->bits.exp;
++ sign = src->bits.sign;
++#else
++# if defined TFLOAT && defined HALFFRACBITS
++ {
++ halffractype high, low;
++
++ high = src->value_raw >> HALFSHIFT;
++ low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
++
++ fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
++ fraction <<= FRACBITS - HALFFRACBITS;
++ exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
++ sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
++
++ if (exp != EXPMAX && exp != 0 && low != 0)
++ {
++ int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
++ int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
++ int shift;
++ fractype xlow;
++
++ xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
++ if (lowexp)
++ xlow |= (((halffractype)1) << HALFFRACBITS);
++ else
++ lowexp = 1;
++ shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
++ if (shift > 0)
++ xlow <<= shift;
++ else if (shift < 0)
++ xlow >>= -shift;
++ if (sign == lowsign)
++ fraction += xlow;
++ else if (fraction >= xlow)
++ fraction -= xlow;
++ else
++ {
++ /* The high part is a power of two but the full number is lower.
++ This code will leave the implicit 1 in FRACTION, but we'd
++ have added that below anyway. */
++ fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
++ exp--;
++ }
++ }
++ }
++# else
++ fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
++ exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
++ sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
++# endif
++#endif
++
++ dst->sign = sign;
++ if (exp == 0)
++ {
++ /* Hmm. Looks like 0 */
++ if (fraction == 0
++#ifdef NO_DENORMALS
++ || 1
++#endif
++ )
++ {
++ /* tastes like zero */
++ dst->class = CLASS_ZERO;
++ }
++ else
++ {
++ /* Zero exponent with nonzero fraction - it's denormalized,
++ so there isn't a leading implicit one - we'll shift it so
++ it gets one. */
++ dst->normal_exp = exp - EXPBIAS + 1;
++ fraction <<= NGARDS;
++
++ dst->class = CLASS_NUMBER;
++#if 1
++ while (fraction < IMPLICIT_1)
++ {
++ fraction <<= 1;
++ dst->normal_exp--;
++ }
++#endif
++ dst->fraction.ll = fraction;
++ }
++ }
++ else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp == EXPMAX)
++ {
++ /* Huge exponent*/
++ if (fraction == 0)
++ {
++ /* Attached to a zero fraction - means infinity */
++ dst->class = CLASS_INFINITY;
++ }
++ else
++ {
++ /* Nonzero fraction, means nan */
++#ifdef QUIET_NAN_NEGATED
++ if ((fraction & QUIET_NAN) == 0)
++#else
++ if (fraction & QUIET_NAN)
++#endif
++ {
++ dst->class = CLASS_QNAN;
++ }
++ else
++ {
++ dst->class = CLASS_SNAN;
++ }
++ /* Keep the fraction part as the nan number */
++ dst->fraction.ll = fraction;
++ }
++ }
++ else
++ {
++ /* Nothing strange about this number */
++ dst->normal_exp = exp - EXPBIAS;
++ dst->class = CLASS_NUMBER;
++ dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
++ }
++}
++#endif /* L_unpack_df || L_unpack_sf */
++
++#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
++static fp_number_type *
++_fpadd_parts (fp_number_type * a,
++ fp_number_type * b,
++ fp_number_type * tmp)
++{
++ intfrac tfraction;
++
++ /* Put commonly used fields in local variables. */
++ int a_normal_exp;
++ int b_normal_exp;
++ fractype a_fraction;
++ fractype b_fraction;
++
++ if (isnan (a))
++ {
++ return a;
++ }
++ if (isnan (b))
++ {
++ return b;
++ }
++ if (isinf (a))
++ {
++ /* Adding infinities with opposite signs yields a NaN. */
++ if (isinf (b) && a->sign != b->sign)
++ return nan ();
++ return a;
++ }
++ if (isinf (b))
++ {
++ return b;
++ }
++ if (iszero (b))
++ {
++ if (iszero (a))
++ {
++ *tmp = *a;
++ tmp->sign = a->sign & b->sign;
++ return tmp;
++ }
++ return a;
++ }
++ if (iszero (a))
++ {
++ return b;
++ }
++
++ /* Got two numbers. shift the smaller and increment the exponent till
++ they're the same */
++ {
++ int diff;
++
++ a_normal_exp = a->normal_exp;
++ b_normal_exp = b->normal_exp;
++ a_fraction = a->fraction.ll;
++ b_fraction = b->fraction.ll;
++
++ diff = a_normal_exp - b_normal_exp;
++
++ if (diff < 0)
++ diff = -diff;
++ if (diff < FRAC_NBITS)
++ {
++ /* ??? This does shifts one bit at a time. Optimize. */
++ while (a_normal_exp > b_normal_exp)
++ {
++ b_normal_exp++;
++ LSHIFT (b_fraction);
++ }
++ while (b_normal_exp > a_normal_exp)
++ {
++ a_normal_exp++;
++ LSHIFT (a_fraction);
++ }
++ }
++ else
++ {
++ /* Somethings's up.. choose the biggest */
++ if (a_normal_exp > b_normal_exp)
++ {
++ b_normal_exp = a_normal_exp;
++ b_fraction = 0;
++ }
++ else
++ {
++ a_normal_exp = b_normal_exp;
++ a_fraction = 0;
++ }
++ }
++ }
++
++ if (a->sign != b->sign)
++ {
++ if (a->sign)
++ {
++ tfraction = -a_fraction + b_fraction;
++ }
++ else
++ {
++ tfraction = a_fraction - b_fraction;
++ }
++ if (tfraction >= 0)
++ {
++ tmp->sign = 0;
++ tmp->normal_exp = a_normal_exp;
++ tmp->fraction.ll = tfraction;
++ }
++ else
++ {
++ tmp->sign = 1;
++ tmp->normal_exp = a_normal_exp;
++ tmp->fraction.ll = -tfraction;
++ }
++ /* and renormalize it */
++
++ while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
++ {
++ tmp->fraction.ll <<= 1;
++ tmp->normal_exp--;
++ }
++ }
++ else
++ {
++ tmp->sign = a->sign;
++ tmp->normal_exp = a_normal_exp;
++ tmp->fraction.ll = a_fraction + b_fraction;
++ }
++ tmp->class = CLASS_NUMBER;
++ /* Now the fraction is added, we have to shift down to renormalize the
++ number */
++
++ if (tmp->fraction.ll >= IMPLICIT_2)
++ {
++ LSHIFT (tmp->fraction.ll);
++ tmp->normal_exp++;
++ }
++ return tmp;
++
++}
++
++FLO_type
++add (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ fp_number_type tmp;
++ fp_number_type *res;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ res = _fpadd_parts (&a, &b, &tmp);
++
++ return pack_d (res);
++}
++
++FLO_type
++sub (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ fp_number_type tmp;
++ fp_number_type *res;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ b.sign ^= 1;
++
++ res = _fpadd_parts (&a, &b, &tmp);
++
++ return pack_d (res);
++}
++#endif /* L_addsub_sf || L_addsub_df */
++
++#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
++static inline __attribute__ ((__always_inline__)) fp_number_type *
++_fpmul_parts ( fp_number_type * a,
++ fp_number_type * b,
++ fp_number_type * tmp)
++{
++ fractype low = 0;
++ fractype high = 0;
++
++ if (isnan (a))
++ {
++ a->sign = a->sign != b->sign;
++ return a;
++ }
++ if (isnan (b))
++ {
++ b->sign = a->sign != b->sign;
++ return b;
++ }
++ if (isinf (a))
++ {
++ if (iszero (b))
++ return nan ();
++ a->sign = a->sign != b->sign;
++ return a;
++ }
++ if (isinf (b))
++ {
++ if (iszero (a))
++ {
++ return nan ();
++ }
++ b->sign = a->sign != b->sign;
++ return b;
++ }
++ if (iszero (a))
++ {
++ a->sign = a->sign != b->sign;
++ return a;
++ }
++ if (iszero (b))
++ {
++ b->sign = a->sign != b->sign;
++ return b;
++ }
++
++ /* Calculate the mantissa by multiplying both numbers to get a
++ twice-as-wide number. */
++ {
++#if defined(NO_DI_MODE) || defined(TFLOAT)
++ {
++ fractype x = a->fraction.ll;
++ fractype ylow = b->fraction.ll;
++ fractype yhigh = 0;
++ int bit;
++
++ /* ??? This does multiplies one bit at a time. Optimize. */
++ for (bit = 0; bit < FRAC_NBITS; bit++)
++ {
++ int carry;
++
++ if (x & 1)
++ {
++ carry = (low += ylow) < ylow;
++ high += yhigh + carry;
++ }
++ yhigh <<= 1;
++ if (ylow & FRACHIGH)
++ {
++ yhigh |= 1;
++ }
++ ylow <<= 1;
++ x >>= 1;
++ }
++ }
++#elif defined(FLOAT)
++ /* Multiplying two USIs to get a UDI, we're safe. */
++ {
++ UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
++
++ high = answer >> BITS_PER_SI;
++ low = answer;
++ }
++#else
++ /* fractype is DImode, but we need the result to be twice as wide.
++ Assuming a widening multiply from DImode to TImode is not
++ available, build one by hand. */
++ {
++ USItype nl = a->fraction.ll;
++ USItype nh = a->fraction.ll >> BITS_PER_SI;
++ USItype ml = b->fraction.ll;
++ USItype mh = b->fraction.ll >> BITS_PER_SI;
++ UDItype pp_ll = (UDItype) ml * nl;
++ UDItype pp_hl = (UDItype) mh * nl;
++ UDItype pp_lh = (UDItype) ml * nh;
++ UDItype pp_hh = (UDItype) mh * nh;
++ UDItype res2 = 0;
++ UDItype res0 = 0;
++ UDItype ps_hh__ = pp_hl + pp_lh;
++ if (ps_hh__ < pp_hl)
++ res2 += (UDItype)1 << BITS_PER_SI;
++ pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
++ res0 = pp_ll + pp_hl;
++ if (res0 < pp_ll)
++ res2++;
++ res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
++ high = res2;
++ low = res0;
++ }
++#endif
++ }
++
++ tmp->normal_exp = a->normal_exp + b->normal_exp
++ + FRAC_NBITS - (FRACBITS + NGARDS);
++ tmp->sign = a->sign != b->sign;
++ while (high >= IMPLICIT_2)
++ {
++ tmp->normal_exp++;
++ if (high & 1)
++ {
++ low >>= 1;
++ low |= FRACHIGH;
++ }
++ high >>= 1;
++ }
++ while (high < IMPLICIT_1)
++ {
++ tmp->normal_exp--;
++
++ high <<= 1;
++ if (low & FRACHIGH)
++ high |= 1;
++ low <<= 1;
++ }
++ /* rounding is tricky. if we only round if it won't make us round later. */
++#if 0
++ if (low & FRACHIGH2)
++ {
++ if (((high & GARDMASK) != GARDMSB)
++ && (((high + 1) & GARDMASK) == GARDMSB))
++ {
++ /* don't round, it gets done again later. */
++ }
++ else
++ {
++ high++;
++ }
++ }
++#endif
++ if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
++ {
++ if (high & (1 << NGARDS))
++ {
++ /* half way, so round to even */
++ high += GARDROUND + 1;
++ }
++ else if (low)
++ {
++ /* but we really weren't half way */
++ high += GARDROUND + 1;
++ }
++ }
++ tmp->fraction.ll = high;
++ tmp->class = CLASS_NUMBER;
++ return tmp;
++}
++
++FLO_type
++multiply (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ fp_number_type tmp;
++ fp_number_type *res;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ res = _fpmul_parts (&a, &b, &tmp);
++
++ return pack_d (res);
++}
++#endif /* L_mul_sf || L_mul_df */
++
++#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
++static inline __attribute__ ((__always_inline__)) fp_number_type *
++_fpdiv_parts (fp_number_type * a,
++ fp_number_type * b)
++{
++ fractype bit;
++ fractype numerator;
++ fractype denominator;
++ fractype quotient;
++
++ if (isnan (a))
++ {
++ return a;
++ }
++ if (isnan (b))
++ {
++ return b;
++ }
++
++ a->sign = a->sign ^ b->sign;
++
++ if (isinf (a) || iszero (a))
++ {
++ if (a->class == b->class)
++ return nan ();
++ return a;
++ }
++
++ if (isinf (b))
++ {
++ a->fraction.ll = 0;
++ a->normal_exp = 0;
++ return a;
++ }
++ if (iszero (b))
++ {
++ a->class = CLASS_INFINITY;
++ return a;
++ }
++
++ /* Calculate the mantissa by multiplying both 64bit numbers to get a
++ 128 bit number */
++ {
++ /* quotient =
++ ( numerator / denominator) * 2^(numerator exponent - denominator exponent)
++ */
++
++ a->normal_exp = a->normal_exp - b->normal_exp;
++ numerator = a->fraction.ll;
++ denominator = b->fraction.ll;
++
++ if (numerator < denominator)
++ {
++ /* Fraction will be less than 1.0 */
++ numerator *= 2;
++ a->normal_exp--;
++ }
++ bit = IMPLICIT_1;
++ quotient = 0;
++ /* ??? Does divide one bit at a time. Optimize. */
++ while (bit)
++ {
++ if (numerator >= denominator)
++ {
++ quotient |= bit;
++ numerator -= denominator;
++ }
++ bit >>= 1;
++ numerator *= 2;
++ }
++
++ if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
++ {
++ if (quotient & (1 << NGARDS))
++ {
++ /* half way, so round to even */
++ quotient += GARDROUND + 1;
++ }
++ else if (numerator)
++ {
++ /* but we really weren't half way, more bits exist */
++ quotient += GARDROUND + 1;
++ }
++ }
++
++ a->fraction.ll = quotient;
++ return (a);
++ }
++}
++
++FLO_type
++divide (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ fp_number_type *res;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ res = _fpdiv_parts (&a, &b);
++
++ return pack_d (res);
++}
++#endif /* L_div_sf || L_div_df */
++
++#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
++ || defined(L_fpcmp_parts_tf)
++/* according to the demo, fpcmp returns a comparison with 0... thus
++ a<b -> -1
++ a==b -> 0
++ a>b -> +1
++ */
++
++int
++__fpcmp_parts (fp_number_type * a, fp_number_type * b)
++{
++#if 0
++ /* either nan -> unordered. Must be checked outside of this routine. */
++ if (isnan (a) && isnan (b))
++ {
++ return 1; /* still unordered! */
++ }
++#endif
++
++ if (isnan (a) || isnan (b))
++ {
++ return 1; /* how to indicate unordered compare? */
++ }
++ if (isinf (a) && isinf (b))
++ {
++ /* +inf > -inf, but +inf != +inf */
++ /* b \a| +inf(0)| -inf(1)
++ ______\+--------+--------
++ +inf(0)| a==b(0)| a<b(-1)
++ -------+--------+--------
++ -inf(1)| a>b(1) | a==b(0)
++ -------+--------+--------
++ So since unordered must be nonzero, just line up the columns...
++ */
++ return b->sign - a->sign;
++ }
++ /* but not both... */
++ if (isinf (a))
++ {
++ return a->sign ? -1 : 1;
++ }
++ if (isinf (b))
++ {
++ return b->sign ? 1 : -1;
++ }
++ if (iszero (a) && iszero (b))
++ {
++ return 0;
++ }
++ if (iszero (a))
++ {
++ return b->sign ? 1 : -1;
++ }
++ if (iszero (b))
++ {
++ return a->sign ? -1 : 1;
++ }
++ /* now both are "normal". */
++ if (a->sign != b->sign)
++ {
++ /* opposite signs */
++ return a->sign ? -1 : 1;
++ }
++ /* same sign; exponents? */
++ if (a->normal_exp > b->normal_exp)
++ {
++ return a->sign ? -1 : 1;
++ }
++ if (a->normal_exp < b->normal_exp)
++ {
++ return a->sign ? 1 : -1;
++ }
++ /* same exponents; check size. */
++ if (a->fraction.ll > b->fraction.ll)
++ {
++ return a->sign ? -1 : 1;
++ }
++ if (a->fraction.ll < b->fraction.ll)
++ {
++ return a->sign ? 1 : -1;
++ }
++ /* after all that, they're equal. */
++ return 0;
++}
++#endif
++
++#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
++CMPtype
++compare (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ return __fpcmp_parts (&a, &b);
++}
++#endif /* L_compare_sf || L_compare_df */
++
++#ifndef US_SOFTWARE_GOFAST
++
++/* These should be optimized for their specific tasks someday. */
++
++#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
++CMPtype
++_eq_f2 (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ if (isnan (&a) || isnan (&b))
++ return 1; /* false, truth == 0 */
++
++ return __fpcmp_parts (&a, &b) ;
++}
++#endif /* L_eq_sf || L_eq_df */
++
++#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
++CMPtype
++_ne_f2 (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ if (isnan (&a) || isnan (&b))
++ return 1; /* true, truth != 0 */
++
++ return __fpcmp_parts (&a, &b) ;
++}
++#endif /* L_ne_sf || L_ne_df */
++
++#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
++CMPtype
++_gt_f2 (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ if (isnan (&a) || isnan (&b))
++ return -1; /* false, truth > 0 */
++
++ return __fpcmp_parts (&a, &b);
++}
++#endif /* L_gt_sf || L_gt_df */
++
++#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
++CMPtype
++_ge_f2 (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ if (isnan (&a) || isnan (&b))
++ return -1; /* false, truth >= 0 */
++ return __fpcmp_parts (&a, &b) ;
++}
++#endif /* L_ge_sf || L_ge_df */
++
++#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
++CMPtype
++_lt_f2 (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ if (isnan (&a) || isnan (&b))
++ return 1; /* false, truth < 0 */
++
++ return __fpcmp_parts (&a, &b);
++}
++#endif /* L_lt_sf || L_lt_df */
++
++#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
++CMPtype
++_le_f2 (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ if (isnan (&a) || isnan (&b))
++ return 1; /* false, truth <= 0 */
++
++ return __fpcmp_parts (&a, &b) ;
++}
++#endif /* L_le_sf || L_le_df */
++
++#endif /* ! US_SOFTWARE_GOFAST */
++
++#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
++CMPtype
++_unord_f2 (FLO_type arg_a, FLO_type arg_b)
++{
++ fp_number_type a;
++ fp_number_type b;
++ FLO_union_type au, bu;
++
++ au.value = arg_a;
++ bu.value = arg_b;
++
++ unpack_d (&au, &a);
++ unpack_d (&bu, &b);
++
++ return (isnan (&a) || isnan (&b));
++}
++#endif /* L_unord_sf || L_unord_df */
++
++#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
++FLO_type
++si_to_float (SItype arg_a)
++{
++ fp_number_type in;
++
++ in.class = CLASS_NUMBER;
++ in.sign = arg_a < 0;
++ if (!arg_a)
++ {
++ in.class = CLASS_ZERO;
++ }
++ else
++ {
++ in.normal_exp = FRACBITS + NGARDS;
++ if (in.sign)
++ {
++ /* Special case for minint, since there is no +ve integer
++ representation for it */
++ if (arg_a == (- MAX_SI_INT - 1))
++ {
++ return (FLO_type)(- MAX_SI_INT - 1);
++ }
++ in.fraction.ll = (-arg_a);
++ }
++ else
++ in.fraction.ll = arg_a;
++
++ while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
++ {
++ in.fraction.ll <<= 1;
++ in.normal_exp -= 1;
++ }
++ }
++ return pack_d (&in);
++}
++#endif /* L_si_to_sf || L_si_to_df */
++
++#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
++FLO_type
++usi_to_float (USItype arg_a)
++{
++ fp_number_type in;
++
++ in.sign = 0;
++ if (!arg_a)
++ {
++ in.class = CLASS_ZERO;
++ }
++ else
++ {
++ in.class = CLASS_NUMBER;
++ in.normal_exp = FRACBITS + NGARDS;
++ in.fraction.ll = arg_a;
++
++ while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS)))
++ {
++ in.fraction.ll >>= 1;
++ in.normal_exp += 1;
++ }
++ while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
++ {
++ in.fraction.ll <<= 1;
++ in.normal_exp -= 1;
++ }
++ }
++ return pack_d (&in);
++}
++#endif
++
++#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
++SItype
++float_to_si (FLO_type arg_a)
++{
++ fp_number_type a;
++ SItype tmp;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &a);
++
++ if (iszero (&a))
++ return 0;
++ if (isnan (&a))
++ return 0;
++ /* get reasonable MAX_SI_INT... */
++ if (isinf (&a))
++ return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
++ /* it is a number, but a small one */
++ if (a.normal_exp < 0)
++ return 0;
++ if (a.normal_exp > BITS_PER_SI - 2)
++ return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
++ tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
++ return a.sign ? (-tmp) : (tmp);
++}
++#endif /* L_sf_to_si || L_df_to_si */
++
++#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi)
++#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi)
++/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
++ we also define them for GOFAST because the ones in libgcc2.c have the
++ wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
++ out of libgcc2.c. We can't define these here if not GOFAST because then
++ there'd be duplicate copies. */
++
++USItype
++float_to_usi (FLO_type arg_a)
++{
++ fp_number_type a;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &a);
++
++ if (iszero (&a))
++ return 0;
++ if (isnan (&a))
++ return 0;
++ /* it is a negative number */
++ if (a.sign)
++ return 0;
++ /* get reasonable MAX_USI_INT... */
++ if (isinf (&a))
++ return MAX_USI_INT;
++ /* it is a number, but a small one */
++ if (a.normal_exp < 0)
++ return 0;
++ if (a.normal_exp > BITS_PER_SI - 1)
++ return MAX_USI_INT;
++ else if (a.normal_exp > (FRACBITS + NGARDS))
++ return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
++ else
++ return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
++}
++#endif /* US_SOFTWARE_GOFAST */
++#endif /* L_sf_to_usi || L_df_to_usi */
++
++#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
++FLO_type
++negate (FLO_type arg_a)
++{
++ fp_number_type a;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &a);
++
++ flip_sign (&a);
++ return pack_d (&a);
++}
++#endif /* L_negate_sf || L_negate_df */
++
++#ifdef FLOAT
++
++#if defined(L_make_sf)
++SFtype
++__make_fp(fp_class_type class,
++ unsigned int sign,
++ int exp,
++ USItype frac)
++{
++ fp_number_type in;
++
++ in.class = class;
++ in.sign = sign;
++ in.normal_exp = exp;
++ in.fraction.ll = frac;
++ return pack_d (&in);
++}
++#endif /* L_make_sf */
++
++#ifndef FLOAT_ONLY
++
++/* This enables one to build an fp library that supports float but not double.
++ Otherwise, we would get an undefined reference to __make_dp.
++ This is needed for some 8-bit ports that can't handle well values that
++ are 8-bytes in size, so we just don't support double for them at all. */
++
++#if defined(L_sf_to_df)
++DFtype
++sf_to_df (SFtype arg_a)
++{
++ fp_number_type in;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &in);
++
++ return __make_dp (in.class, in.sign, in.normal_exp,
++ ((UDItype) in.fraction.ll) << F_D_BITOFF);
++}
++#endif /* L_sf_to_df */
++
++#if defined(L_sf_to_tf) && defined(TMODES)
++TFtype
++sf_to_tf (SFtype arg_a)
++{
++ fp_number_type in;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &in);
++
++ return __make_tp (in.class, in.sign, in.normal_exp,
++ ((UTItype) in.fraction.ll) << F_T_BITOFF);
++}
++#endif /* L_sf_to_df */
++
++#endif /* ! FLOAT_ONLY */
++#endif /* FLOAT */
++
++#ifndef FLOAT
++
++extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
++
++#if defined(L_make_df)
++DFtype
++__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
++{
++ fp_number_type in;
++
++ in.class = class;
++ in.sign = sign;
++ in.normal_exp = exp;
++ in.fraction.ll = frac;
++ return pack_d (&in);
++}
++#endif /* L_make_df */
++
++#if defined(L_df_to_sf)
++SFtype
++df_to_sf (DFtype arg_a)
++{
++ fp_number_type in;
++ USItype sffrac;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &in);
++
++ sffrac = in.fraction.ll >> F_D_BITOFF;
++
++ /* We set the lowest guard bit in SFFRAC if we discarded any non
++ zero bits. */
++ if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
++ sffrac |= 1;
++
++ return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
++}
++#endif /* L_df_to_sf */
++
++#if defined(L_df_to_tf) && defined(TMODES) \
++ && !defined(FLOAT) && !defined(TFLOAT)
++TFtype
++df_to_tf (DFtype arg_a)
++{
++ fp_number_type in;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &in);
++
++ return __make_tp (in.class, in.sign, in.normal_exp,
++ ((UTItype) in.fraction.ll) << D_T_BITOFF);
++}
++#endif /* L_sf_to_df */
++
++#ifdef TFLOAT
++#if defined(L_make_tf)
++TFtype
++__make_tp(fp_class_type class,
++ unsigned int sign,
++ int exp,
++ UTItype frac)
++{
++ fp_number_type in;
++
++ in.class = class;
++ in.sign = sign;
++ in.normal_exp = exp;
++ in.fraction.ll = frac;
++ return pack_d (&in);
++}
++#endif /* L_make_tf */
++
++#if defined(L_tf_to_df)
++DFtype
++tf_to_df (TFtype arg_a)
++{
++ fp_number_type in;
++ UDItype sffrac;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &in);
++
++ sffrac = in.fraction.ll >> D_T_BITOFF;
++
++ /* We set the lowest guard bit in SFFRAC if we discarded any non
++ zero bits. */
++ if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
++ sffrac |= 1;
++
++ return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
++}
++#endif /* L_tf_to_df */
++
++#if defined(L_tf_to_sf)
++SFtype
++tf_to_sf (TFtype arg_a)
++{
++ fp_number_type in;
++ USItype sffrac;
++ FLO_union_type au;
++
++ au.value = arg_a;
++ unpack_d (&au, &in);
++
++ sffrac = in.fraction.ll >> F_T_BITOFF;
++
++ /* We set the lowest guard bit in SFFRAC if we discarded any non
++ zero bits. */
++ if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
++ sffrac |= 1;
++
++ return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
++}
++#endif /* L_tf_to_sf */
++#endif /* TFLOAT */
++
++#endif /* ! FLOAT */
++#endif /* !EXTENDED_FLOAT_STUBS */
+--- gcc-3.4.3/gcc/config/nios2/nios2-protos.h
++++ gcc-3.4.3-nios2/gcc/config/nios2/nios2-protos.h
+@@ -0,0 +1,70 @@
++/* Subroutines for assembler code output for Altera NIOS 2G NIOS2 version.
++ Copyright (C) 2003 Altera
++ Contributed by Jonah Graham (jgraham@altera.com).
++
++This file is part of GNU CC.
++
++GNU CC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 2, or (at your option)
++any later version.
++
++GNU CC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GNU CC; see the file COPYING. If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA. */
++
++extern void dump_frame_size (FILE *);
++extern HOST_WIDE_INT compute_frame_size (void);
++extern int nios2_initial_elimination_offset (int, int);
++extern void override_options (void);
++extern void optimization_options (int, int);
++extern int nios2_can_use_return_insn (void);
++extern void expand_prologue (void);
++extern void expand_epilogue (bool);
++extern void function_profiler (FILE *, int);
++
++
++#ifdef RTX_CODE
++extern int nios2_legitimate_address (rtx, enum machine_mode, int);
++extern void nios2_print_operand (FILE *, rtx, int);
++extern void nios2_print_operand_address (FILE *, rtx);
++
++extern int nios2_emit_move_sequence (rtx *, enum machine_mode);
++extern int nios2_emit_expensive_div (rtx *, enum machine_mode);
++
++extern void gen_int_relational (enum rtx_code, rtx, rtx, rtx, rtx);
++extern void gen_conditional_move (rtx *, enum machine_mode);
++extern const char *asm_output_opcode (FILE *, const char *);
++
++/* predicates */
++extern int arith_operand (rtx, enum machine_mode);
++extern int uns_arith_operand (rtx, enum machine_mode);
++extern int logical_operand (rtx, enum machine_mode);
++extern int shift_operand (rtx, enum machine_mode);
++extern int reg_or_0_operand (rtx, enum machine_mode);
++extern int equality_op (rtx, enum machine_mode);
++extern int custom_insn_opcode (rtx, enum machine_mode);
++extern int rdwrctl_operand (rtx, enum machine_mode);
++
++# ifdef HAVE_MACHINE_MODES
++# if defined TREE_CODE
++extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
++extern rtx function_arg (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
++extern int function_arg_partial_nregs (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
++extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
++extern int nios2_setup_incoming_varargs (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
++
++# endif /* TREE_CODE */
++# endif /* HAVE_MACHINE_MODES */
++#endif
++
++#ifdef TREE_CODE
++extern int nios2_return_in_memory (tree);
++
++#endif /* TREE_CODE */
+--- gcc-3.4.3/gcc/config/nios2/nios2.c
++++ gcc-3.4.3-nios2/gcc/config/nios2/nios2.c
+@@ -0,0 +1,2853 @@
++/* Subroutines for assembler code output for Altera NIOS 2G NIOS2 version.
++ Copyright (C) 2003 Altera
++ Contributed by Jonah Graham (jgraham@altera.com).
++
++This file is part of GNU CC.
++
++GNU CC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 2, or (at your option)
++any later version.
++
++GNU CC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GNU CC; see the file COPYING. If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA. */
++
++
++#include <stdio.h>
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++#include "rtl.h"
++#include "tree.h"
++#include "tm_p.h"
++#include "regs.h"
++#include "hard-reg-set.h"
++#include "real.h"
++#include "insn-config.h"
++#include "conditions.h"
++#include "output.h"
++#include "insn-attr.h"
++#include "flags.h"
++#include "recog.h"
++#include "expr.h"
++#include "toplev.h"
++#include "basic-block.h"
++#include "function.h"
++#include "ggc.h"
++#include "reload.h"
++#include "debug.h"
++#include "optabs.h"
++#include "target.h"
++#include "target-def.h"
++
++/* local prototypes */
++static bool nios2_rtx_costs (rtx, int, int, int *);
++
++static void nios2_asm_function_prologue (FILE *, HOST_WIDE_INT);
++static int nios2_use_dfa_pipeline_interface (void);
++static int nios2_issue_rate (void);
++static struct machine_function *nios2_init_machine_status (void);
++static bool nios2_in_small_data_p (tree);
++static rtx save_reg (int, HOST_WIDE_INT, rtx);
++static rtx restore_reg (int, HOST_WIDE_INT);
++static unsigned int nios2_section_type_flags (tree, const char *, int);
++static void nios2_init_builtins (void);
++static rtx nios2_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
++static bool nios2_function_ok_for_sibcall (tree, tree);
++static void nios2_encode_section_info (tree, rtx, int);
++
++/* Initialize the GCC target structure. */
++#undef TARGET_ASM_FUNCTION_PROLOGUE
++#define TARGET_ASM_FUNCTION_PROLOGUE nios2_asm_function_prologue
++
++#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
++#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE \
++ nios2_use_dfa_pipeline_interface
++#undef TARGET_SCHED_ISSUE_RATE
++#define TARGET_SCHED_ISSUE_RATE nios2_issue_rate
++#undef TARGET_IN_SMALL_DATA_P
++#define TARGET_IN_SMALL_DATA_P nios2_in_small_data_p
++#undef TARGET_ENCODE_SECTION_INFO
++#define TARGET_ENCODE_SECTION_INFO nios2_encode_section_info
++#undef TARGET_SECTION_TYPE_FLAGS
++#define TARGET_SECTION_TYPE_FLAGS nios2_section_type_flags
++
++#undef TARGET_INIT_BUILTINS
++#define TARGET_INIT_BUILTINS nios2_init_builtins
++#undef TARGET_EXPAND_BUILTIN
++#define TARGET_EXPAND_BUILTIN nios2_expand_builtin
++
++#undef TARGET_FUNCTION_OK_FOR_SIBCALL
++#define TARGET_FUNCTION_OK_FOR_SIBCALL nios2_function_ok_for_sibcall
++
++#undef TARGET_RTX_COSTS
++#define TARGET_RTX_COSTS nios2_rtx_costs
++
++
++struct gcc_target targetm = TARGET_INITIALIZER;
++
++
++
++/* Threshold for data being put into the small data/bss area, instead
++ of the normal data area (references to the small data/bss area take
++ 1 instruction, and use the global pointer, references to the normal
++ data area takes 2 instructions). */
++unsigned HOST_WIDE_INT nios2_section_threshold = NIOS2_DEFAULT_GVALUE;
++
++
++/* Structure to be filled in by compute_frame_size with register
++ save masks, and offsets for the current function. */
++
++struct nios2_frame_info
++GTY (())
++{
++ long total_size; /* # bytes that the entire frame takes up */
++ long var_size; /* # bytes that variables take up */
++ long args_size; /* # bytes that outgoing arguments take up */
++ int save_reg_size; /* # bytes needed to store gp regs */
++ int save_reg_rounded; /* # bytes needed to store gp regs */
++ long save_regs_offset; /* offset from new sp to store gp registers */
++ int initialized; /* != 0 if frame size already calculated */
++ int num_regs; /* number of gp registers saved */
++};
++
++struct machine_function
++GTY (())
++{
++
++ /* Current frame information, calculated by compute_frame_size. */
++ struct nios2_frame_info frame;
++};
++
++
++/***************************************
++ * Section encodings
++ ***************************************/
++
++
++
++
++
++/***************************************
++ * Stack Layout and Calling Conventions
++ ***************************************/
++
++
++#define TOO_BIG_OFFSET(X) ((X) > ((1 << 15) - 1))
++#define TEMP_REG_NUM 8
++
++static void
++nios2_asm_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
++{
++ if (flag_verbose_asm || flag_debug_asm)
++ {
++ compute_frame_size ();
++ dump_frame_size (file);
++ }
++}
++
++static rtx
++save_reg (int regno, HOST_WIDE_INT offset, rtx cfa_store_reg)
++{
++ rtx insn, stack_slot;
++
++ stack_slot = gen_rtx_PLUS (SImode,
++ cfa_store_reg,
++ GEN_INT (offset));
++
++ insn = emit_insn (gen_rtx_SET (SImode,
++ gen_rtx_MEM (SImode, stack_slot),
++ gen_rtx_REG (SImode, regno)));
++
++ RTX_FRAME_RELATED_P (insn) = 1;
++
++ return insn;
++}
++
++static rtx
++restore_reg (int regno, HOST_WIDE_INT offset)
++{
++ rtx insn, stack_slot;
++
++ if (TOO_BIG_OFFSET (offset))
++ {
++ stack_slot = gen_rtx_REG (SImode, TEMP_REG_NUM);
++ insn = emit_insn (gen_rtx_SET (SImode,
++ stack_slot,
++ GEN_INT (offset)));
++
++ insn = emit_insn (gen_rtx_SET (SImode,
++ stack_slot,
++ gen_rtx_PLUS (SImode,
++ stack_slot,
++ stack_pointer_rtx)));
++ }
++ else
++ {
++ stack_slot = gen_rtx_PLUS (SImode,
++ stack_pointer_rtx,
++ GEN_INT (offset));
++ }
++
++ stack_slot = gen_rtx_MEM (SImode, stack_slot);
++
++ insn = emit_move_insn (gen_rtx_REG (SImode, regno), stack_slot);
++
++ return insn;
++}
++
++
++/* There are two possible paths for prologue expansion,
++- the first is if the total frame size is < 2^15-1. In that
++case all the immediates will fit into the 16-bit immediate
++fields.
++- the second is when the frame size is too big, in that
++case an additional temporary register is used, first
++as a cfa_temp to offset the sp, second as the cfa_store
++register.
++
++See the comment above dwarf2out_frame_debug_expr in
++dwarf2out.c for more explanation of the "rules."
++
++
++Case 1:
++Rule # Example Insn Effect
++2 addi sp, sp, -total_frame_size cfa.reg=sp, cfa.offset=total_frame_size
++ cfa_store.reg=sp, cfa_store.offset=total_frame_size
++12 stw ra, offset(sp)
++12 stw r16, offset(sp)
++1 mov fp, sp
++
++Case 2:
++Rule # Example Insn Effect
++6 movi r8, total_frame_size cfa_temp.reg=r8, cfa_temp.offset=total_frame_size
++2 sub sp, sp, r8 cfa.reg=sp, cfa.offset=total_frame_size
++ cfa_store.reg=sp, cfa_store.offset=total_frame_size
++5 add r8, r8, sp cfa_store.reg=r8, cfa_store.offset=0
++12 stw ra, offset(r8)
++12 stw r16, offset(r8)
++1 mov fp, sp
++
++*/
++
++void
++expand_prologue ()
++{
++ int i;
++ HOST_WIDE_INT total_frame_size;
++ int cfa_store_offset;
++ rtx insn;
++ rtx cfa_store_reg = 0;
++
++ total_frame_size = compute_frame_size ();
++
++ if (total_frame_size)
++ {
++
++ if (TOO_BIG_OFFSET (total_frame_size))
++ {
++ /* cfa_temp and cfa_store_reg are the same register,
++ cfa_store_reg overwrites cfa_temp */
++ cfa_store_reg = gen_rtx_REG (SImode, TEMP_REG_NUM);
++ insn = emit_insn (gen_rtx_SET (SImode,
++ cfa_store_reg,
++ GEN_INT (total_frame_size)));
++
++ RTX_FRAME_RELATED_P (insn) = 1;
++
++
++ insn = gen_rtx_SET (SImode,
++ stack_pointer_rtx,
++ gen_rtx_MINUS (SImode,
++ stack_pointer_rtx,
++ cfa_store_reg));
++
++ insn = emit_insn (insn);
++ RTX_FRAME_RELATED_P (insn) = 1;
++
++
++ /* if there are no registers to save, I don't need to
++ create a cfa_store */
++ if (cfun->machine->frame.save_reg_size)
++ {
++ insn = gen_rtx_SET (SImode,
++ cfa_store_reg,
++ gen_rtx_PLUS (SImode,
++ cfa_store_reg,
++ stack_pointer_rtx));
++
++ insn = emit_insn (insn);
++ RTX_FRAME_RELATED_P (insn) = 1;
++ }
++
++ cfa_store_offset
++ = total_frame_size
++ - (cfun->machine->frame.save_regs_offset
++ + cfun->machine->frame.save_reg_rounded);
++ }
++ else
++ {
++ insn = gen_rtx_SET (SImode,
++ stack_pointer_rtx,
++ gen_rtx_PLUS (SImode,
++ stack_pointer_rtx,
++ GEN_INT (-total_frame_size)));
++ insn = emit_insn (insn);
++ RTX_FRAME_RELATED_P (insn) = 1;
++
++ cfa_store_reg = stack_pointer_rtx;
++ cfa_store_offset
++ = cfun->machine->frame.save_regs_offset
++ + cfun->machine->frame.save_reg_rounded;
++ }
++ }
++
++ if (MUST_SAVE_REGISTER (RA_REGNO))
++ {
++ cfa_store_offset -= 4;
++ save_reg (RA_REGNO, cfa_store_offset, cfa_store_reg);
++ }
++ if (MUST_SAVE_REGISTER (FP_REGNO))
++ {
++ cfa_store_offset -= 4;
++ save_reg (FP_REGNO, cfa_store_offset, cfa_store_reg);
++ }
++
++ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
++ {
++ if (MUST_SAVE_REGISTER (i) && i != FP_REGNO && i != RA_REGNO)
++ {
++ cfa_store_offset -= 4;
++ save_reg (i, cfa_store_offset, cfa_store_reg);
++ }
++ }
++
++ if (frame_pointer_needed)
++ {
++ insn = emit_insn (gen_rtx_SET (SImode,
++ gen_rtx_REG (SImode, FP_REGNO),
++ gen_rtx_REG (SImode, SP_REGNO)));
++
++ RTX_FRAME_RELATED_P (insn) = 1;
++ }
++
++ /* If we are profiling, make sure no instructions are scheduled before
++ the call to mcount. */
++ if (current_function_profile)
++ emit_insn (gen_blockage ());
++}
++
++void
++expand_epilogue (bool sibcall_p)
++{
++ rtx insn;
++ int i;
++ HOST_WIDE_INT total_frame_size;
++ int register_store_offset;
++
++ total_frame_size = compute_frame_size ();
++
++ if (!sibcall_p && nios2_can_use_return_insn ())
++ {
++ insn = emit_jump_insn (gen_return ());
++ return;
++ }
++
++ emit_insn (gen_blockage ());
++
++ register_store_offset =
++ cfun->machine->frame.save_regs_offset +
++ cfun->machine->frame.save_reg_rounded;
++
++ if (MUST_SAVE_REGISTER (RA_REGNO))
++ {
++ register_store_offset -= 4;
++ restore_reg (RA_REGNO, register_store_offset);
++ }
++
++ if (MUST_SAVE_REGISTER (FP_REGNO))
++ {
++ register_store_offset -= 4;
++ restore_reg (FP_REGNO, register_store_offset);
++ }
++
++ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
++ {
++ if (MUST_SAVE_REGISTER (i) && i != FP_REGNO && i != RA_REGNO)
++ {
++ register_store_offset -= 4;
++ restore_reg (i, register_store_offset);
++ }
++ }
++
++ if (total_frame_size)
++ {
++ rtx sp_adjust;
++
++ if (TOO_BIG_OFFSET (total_frame_size))
++ {
++ sp_adjust = gen_rtx_REG (SImode, TEMP_REG_NUM);
++ insn = emit_insn (gen_rtx_SET (SImode,
++ sp_adjust,
++ GEN_INT (total_frame_size)));
++
++ }
++ else
++ {
++ sp_adjust = GEN_INT (total_frame_size);
++ }
++
++ insn = gen_rtx_SET (SImode,
++ stack_pointer_rtx,
++ gen_rtx_PLUS (SImode,
++ stack_pointer_rtx,
++ sp_adjust));
++ insn = emit_insn (insn);
++ }
++
++
++ if (!sibcall_p)
++ {
++ insn = emit_jump_insn (gen_return_from_epilogue (gen_rtx (REG, Pmode,
++ RA_REGNO)));
++ }
++}
++
++
++bool
++nios2_function_ok_for_sibcall (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED)
++{
++ return true;
++}
++
++
++
++
++
++/* ----------------------- *
++ * Profiling
++ * ----------------------- */
++
++void
++function_profiler (FILE *file, int labelno)
++{
++ fprintf (file, "\t%s mcount begin, label: .LP%d\n",
++ ASM_COMMENT_START, labelno);
++ fprintf (file, "\tnextpc\tr8\n");
++ fprintf (file, "\tmov\tr9, ra\n");
++ fprintf (file, "\tmovhi\tr10, %%hiadj(.LP%d)\n", labelno);
++ fprintf (file, "\taddi\tr10, r10, %%lo(.LP%d)\n", labelno);
++ fprintf (file, "\tcall\tmcount\n");
++ fprintf (file, "\tmov\tra, r9\n");
++ fprintf (file, "\t%s mcount end\n", ASM_COMMENT_START);
++}
++
++
++/***************************************
++ * Stack Layout
++ ***************************************/
++
++
++void
++dump_frame_size (FILE *file)
++{
++ fprintf (file, "\t%s Current Frame Info\n", ASM_COMMENT_START);
++
++ fprintf (file, "\t%s total_size = %ld\n", ASM_COMMENT_START,
++ cfun->machine->frame.total_size);
++ fprintf (file, "\t%s var_size = %ld\n", ASM_COMMENT_START,
++ cfun->machine->frame.var_size);
++ fprintf (file, "\t%s args_size = %ld\n", ASM_COMMENT_START,
++ cfun->machine->frame.args_size);
++ fprintf (file, "\t%s save_reg_size = %d\n", ASM_COMMENT_START,
++ cfun->machine->frame.save_reg_size);
++ fprintf (file, "\t%s save_reg_rounded = %d\n", ASM_COMMENT_START,
++ cfun->machine->frame.save_reg_rounded);
++ fprintf (file, "\t%s initialized = %d\n", ASM_COMMENT_START,
++ cfun->machine->frame.initialized);
++ fprintf (file, "\t%s num_regs = %d\n", ASM_COMMENT_START,
++ cfun->machine->frame.num_regs);
++ fprintf (file, "\t%s save_regs_offset = %ld\n", ASM_COMMENT_START,
++ cfun->machine->frame.save_regs_offset);
++ fprintf (file, "\t%s current_function_is_leaf = %d\n", ASM_COMMENT_START,
++ current_function_is_leaf);
++ fprintf (file, "\t%s frame_pointer_needed = %d\n", ASM_COMMENT_START,
++ frame_pointer_needed);
++ fprintf (file, "\t%s pretend_args_size = %d\n", ASM_COMMENT_START,
++ current_function_pretend_args_size);
++
++}
++
++
++/* Return the bytes needed to compute the frame pointer from the current
++ stack pointer.
++*/
++
++HOST_WIDE_INT
++compute_frame_size ()
++{
++ unsigned int regno;
++ HOST_WIDE_INT var_size; /* # of var. bytes allocated */
++ HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up */
++ HOST_WIDE_INT save_reg_size; /* # bytes needed to store callee save regs */
++ HOST_WIDE_INT save_reg_rounded;
++ /* # bytes needed to store callee save regs (rounded) */
++ HOST_WIDE_INT out_args_size; /* # bytes needed for outgoing args */
++
++ save_reg_size = 0;
++ var_size = STACK_ALIGN (get_frame_size ());
++ out_args_size = STACK_ALIGN (current_function_outgoing_args_size);
++
++ total_size = var_size + out_args_size;
++
++ /* Calculate space needed for gp registers. */
++ for (regno = 0; regno <= FIRST_PSEUDO_REGISTER; regno++)
++ {
++ if (MUST_SAVE_REGISTER (regno))
++ {
++ save_reg_size += 4;
++ }
++ }
++
++ save_reg_rounded = STACK_ALIGN (save_reg_size);
++ total_size += save_reg_rounded;
++
++ total_size += STACK_ALIGN (current_function_pretend_args_size);
++
++ /* Save other computed information. */
++ cfun->machine->frame.total_size = total_size;
++ cfun->machine->frame.var_size = var_size;
++ cfun->machine->frame.args_size = current_function_outgoing_args_size;
++ cfun->machine->frame.save_reg_size = save_reg_size;
++ cfun->machine->frame.save_reg_rounded = save_reg_rounded;
++ cfun->machine->frame.initialized = reload_completed;
++ cfun->machine->frame.num_regs = save_reg_size / UNITS_PER_WORD;
++
++ cfun->machine->frame.save_regs_offset
++ = save_reg_rounded ? current_function_outgoing_args_size + var_size : 0;
++
++ return total_size;
++}
++
++
++int
++nios2_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
++{
++ int offset;
++
++ /* Set OFFSET to the offset from the stack pointer. */
++ switch (from)
++ {
++ case FRAME_POINTER_REGNUM:
++ offset = 0;
++ break;
++
++ case ARG_POINTER_REGNUM:
++ compute_frame_size ();
++ offset = cfun->machine->frame.total_size;
++ offset -= current_function_pretend_args_size;
++ break;
++
++ case RETURN_ADDRESS_POINTER_REGNUM:
++ compute_frame_size ();
++ /* since the return address is always the first of the
++ saved registers, return the offset to the beginning
++ of the saved registers block */
++ offset = cfun->machine->frame.save_regs_offset;
++ break;
++
++ default:
++ abort ();
++ }
++
++ return offset;
++}
++
++/* Return nonzero if this function is known to have a null epilogue.
++ This allows the optimizer to omit jumps to jumps if no stack
++ was created. */
++int
++nios2_can_use_return_insn ()
++{
++ if (!reload_completed)
++ return 0;
++
++ if (regs_ever_live[RA_REGNO] || current_function_profile)
++ return 0;
++
++ if (cfun->machine->frame.initialized)
++ return cfun->machine->frame.total_size == 0;
++
++ return compute_frame_size () == 0;
++}
++
++
++
++
++
++/***************************************
++ *
++ ***************************************/
++
++const char *nios2_sys_nosys_string; /* for -msys=nosys */
++const char *nios2_sys_lib_string; /* for -msys-lib= */
++const char *nios2_sys_crt0_string; /* for -msys-crt0= */
++
++void
++override_options ()
++{
++ /* Function to allocate machine-dependent function status. */
++ init_machine_status = &nios2_init_machine_status;
++
++ nios2_section_threshold
++ = g_switch_set ? g_switch_value : NIOS2_DEFAULT_GVALUE;
++
++ if (nios2_sys_nosys_string && *nios2_sys_nosys_string)
++ {
++ error ("invalid option '-msys=nosys%s'", nios2_sys_nosys_string);
++ }
++
++ /* If we don't have mul, we don't have mulx either! */
++ if (!TARGET_HAS_MUL && TARGET_HAS_MULX)
++ {
++ target_flags &= ~HAS_MULX_FLAG;
++ }
++
++}
++
++void
++optimization_options (int level, int size)
++{
++ if (level || size)
++ {
++ target_flags |= INLINE_MEMCPY_FLAG;
++ }
++
++ if (level >= 3 && !size)
++ {
++ target_flags |= FAST_SW_DIV_FLAG;
++ }
++}
++
++/* Allocate a chunk of memory for per-function machine-dependent data. */
++static struct machine_function *
++nios2_init_machine_status ()
++{
++ return ((struct machine_function *)
++ ggc_alloc_cleared (sizeof (struct machine_function)));
++}
++
++
++
++/*****************
++ * Describing Relative Costs of Operations
++ *****************/
++
++/* Compute a (partial) cost for rtx X. Return true if the complete
++ cost has been computed, and false if subexpressions should be
++ scanned. In either case, *TOTAL contains the cost result. */
++
++
++
++static bool
++nios2_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total)
++{
++ switch (code)
++ {
++ case CONST_INT:
++ if (INTVAL (x) == 0)
++ {
++ *total = COSTS_N_INSNS (0);
++ return true;
++ }
++ else if (SMALL_INT (INTVAL (x))
++ || SMALL_INT_UNSIGNED (INTVAL (x))
++ || UPPER16_INT (INTVAL (x)))
++ {
++ *total = COSTS_N_INSNS (2);
++ return true;
++ }
++ else
++ {
++ *total = COSTS_N_INSNS (4);
++ return true;
++ }
++
++ case LABEL_REF:
++ case SYMBOL_REF:
++ /* ??? gp relative stuff will fit in here */
++ /* fall through */
++ case CONST:
++ case CONST_DOUBLE:
++ {
++ *total = COSTS_N_INSNS (4);
++ return true;
++ }
++
++ case MULT:
++ {
++ *total = COSTS_N_INSNS (1);
++ return false;
++ }
++ case SIGN_EXTEND:
++ {
++ *total = COSTS_N_INSNS (3);
++ return false;
++ }
++ case ZERO_EXTEND:
++ {
++ *total = COSTS_N_INSNS (1);
++ return false;
++ }
++
++ default:
++ return false;
++ }
++}
++
++
++/***************************************
++ * INSTRUCTION SUPPORT
++ *
++ * These functions are used within the Machine Description to
++ * handle common or complicated output and expansions from
++ * instructions.
++ ***************************************/
++
++int
++nios2_emit_move_sequence (rtx *operands, enum machine_mode mode)
++{
++ rtx to = operands[0];
++ rtx from = operands[1];
++
++ if (!register_operand (to, mode) && !reg_or_0_operand (from, mode))
++ {
++ if (no_new_pseudos)
++ internal_error ("Trying to force_reg no_new_pseudos == 1");
++ from = copy_to_mode_reg (mode, from);
++ }
++
++ operands[0] = to;
++ operands[1] = from;
++ return 0;
++}
++
++/* Divide Support */
++
++/*
++ If -O3 is used, we want to output a table lookup for
++ divides between small numbers (both num and den >= 0
++ and < 0x10). The overhead of this method in the worse
++ case is 40 bytes in the text section (10 insns) and
++ 256 bytes in the data section. Additional divides do
++ not incur additional penalties in the data section.
++
++ Code speed is improved for small divides by about 5x
++ when using this method in the worse case (~9 cycles
++ vs ~45). And in the worse case divides not within the
++ table are penalized by about 10% (~5 cycles vs ~45).
++ However in the typical case the penalty is not as bad
++ because doing the long divide in only 45 cycles is
++ quite optimistic.
++
++ ??? It would be nice to have some benchmarks other
++ than Dhrystone to back this up.
++
++ This bit of expansion is to create this instruction
++ sequence as rtl.
++ or $8, $4, $5
++ slli $9, $4, 4
++ cmpgeui $3, $8, 16
++ beq $3, $0, .L3
++ or $10, $9, $5
++ add $12, $11, divide_table
++ ldbu $2, 0($12)
++ br .L1
++.L3:
++ call slow_div
++.L1:
++# continue here with result in $2
++
++ ??? Ideally I would like the emit libcall block to contain
++ all of this code, but I don't know how to do that. What it
++ means is that if the divide can be eliminated, it may not
++ completely disappear.
++
++ ??? The __divsi3_table label should ideally be moved out
++ of this block and into a global. If it is placed into the
++ sdata section we can save even more cycles by doing things
++ gp relative.
++*/
++int
++nios2_emit_expensive_div (rtx *operands, enum machine_mode mode)
++{
++ rtx or_result, shift_left_result;
++ rtx lookup_value;
++ rtx lab1, lab3;
++ rtx insns;
++ rtx libfunc;
++ rtx final_result;
++ rtx tmp;
++
++ /* it may look a little generic, but only SImode
++ is supported for now */
++ if (mode != SImode)
++ abort ();
++
++ libfunc = sdiv_optab->handlers[(int) SImode].libfunc;
++
++
++
++ lab1 = gen_label_rtx ();
++ lab3 = gen_label_rtx ();
++
++ or_result = expand_simple_binop (SImode, IOR,
++ operands[1], operands[2],
++ 0, 0, OPTAB_LIB_WIDEN);
++
++ emit_cmp_and_jump_insns (or_result, GEN_INT (15), GTU, 0,
++ GET_MODE (or_result), 0, lab3);
++ JUMP_LABEL (get_last_insn ()) = lab3;
++
++ shift_left_result = expand_simple_binop (SImode, ASHIFT,
++ operands[1], GEN_INT (4),
++ 0, 0, OPTAB_LIB_WIDEN);
++
++ lookup_value = expand_simple_binop (SImode, IOR,
++ shift_left_result, operands[2],
++ 0, 0, OPTAB_LIB_WIDEN);
++
++ convert_move (operands[0],
++ gen_rtx (MEM, QImode,
++ gen_rtx (PLUS, SImode,
++ lookup_value,
++ gen_rtx_SYMBOL_REF (SImode, "__divsi3_table"))),
++ 1);
++
++
++ tmp = emit_jump_insn (gen_jump (lab1));
++ JUMP_LABEL (tmp) = lab1;
++ emit_barrier ();
++
++ emit_label (lab3);
++ LABEL_NUSES (lab3) = 1;
++
++ start_sequence ();
++ final_result = emit_library_call_value (libfunc, NULL_RTX,
++ LCT_CONST, SImode, 2,
++ operands[1], SImode,
++ operands[2], SImode);
++
++
++ insns = get_insns ();
++ end_sequence ();
++ emit_libcall_block (insns, operands[0], final_result,
++ gen_rtx (DIV, SImode, operands[1], operands[2]));
++
++ emit_label (lab1);
++ LABEL_NUSES (lab1) = 1;
++ return 1;
++}
++
++/* Branches/Compares */
++
++/* the way of handling branches/compares
++ in gcc is heavily borrowed from MIPS */
++
++enum internal_test
++{
++ ITEST_EQ,
++ ITEST_NE,
++ ITEST_GT,
++ ITEST_GE,
++ ITEST_LT,
++ ITEST_LE,
++ ITEST_GTU,
++ ITEST_GEU,
++ ITEST_LTU,
++ ITEST_LEU,
++ ITEST_MAX
++};
++
++static enum internal_test map_test_to_internal_test (enum rtx_code);
++
++/* Cached operands, and operator to compare for use in set/branch/trap
++ on condition codes. */
++rtx branch_cmp[2];
++enum cmp_type branch_type;
++
++/* Make normal rtx_code into something we can index from an array */
++
++static enum internal_test
++map_test_to_internal_test (enum rtx_code test_code)
++{
++ enum internal_test test = ITEST_MAX;
++
++ switch (test_code)
++ {
++ case EQ:
++ test = ITEST_EQ;
++ break;
++ case NE:
++ test = ITEST_NE;
++ break;
++ case GT:
++ test = ITEST_GT;
++ break;
++ case GE:
++ test = ITEST_GE;
++ break;
++ case LT:
++ test = ITEST_LT;
++ break;
++ case LE:
++ test = ITEST_LE;
++ break;
++ case GTU:
++ test = ITEST_GTU;
++ break;
++ case GEU:
++ test = ITEST_GEU;
++ break;
++ case LTU:
++ test = ITEST_LTU;
++ break;
++ case LEU:
++ test = ITEST_LEU;
++ break;
++ default:
++ break;
++ }
++
++ return test;
++}
++
++/* Generate the code to compare (and possibly branch) two integer values
++ TEST_CODE is the comparison code we are trying to emulate
++ (or implement directly)
++ RESULT is where to store the result of the comparison,
++ or null to emit a branch
++ CMP0 CMP1 are the two comparison operands
++ DESTINATION is the destination of the branch, or null to only compare
++ */
++
++void
++gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
++ rtx result, /* result to store comp. or 0 if branch */
++ rtx cmp0, /* first operand to compare */
++ rtx cmp1, /* second operand to compare */
++ rtx destination) /* destination of the branch, or 0 if compare */
++{
++ struct cmp_info
++ {
++ /* for register (or 0) compares */
++ enum rtx_code test_code_reg; /* code to use in instruction (LT vs. LTU) */
++ int reverse_regs; /* reverse registers in test */
++
++ /* for immediate compares */
++ enum rtx_code test_code_const;
++ /* code to use in instruction (LT vs. LTU) */
++ int const_low; /* low bound of constant we can accept */
++ int const_high; /* high bound of constant we can accept */
++ int const_add; /* constant to add */
++
++ /* generic info */
++ int unsignedp; /* != 0 for unsigned comparisons. */
++ };
++
++ static const struct cmp_info info[(int) ITEST_MAX] = {
++
++ {EQ, 0, EQ, -32768, 32767, 0, 0}, /* EQ */
++ {NE, 0, NE, -32768, 32767, 0, 0}, /* NE */
++
++ {LT, 1, GE, -32769, 32766, 1, 0}, /* GT */
++ {GE, 0, GE, -32768, 32767, 0, 0}, /* GE */
++ {LT, 0, LT, -32768, 32767, 0, 0}, /* LT */
++ {GE, 1, LT, -32769, 32766, 1, 0}, /* LE */
++
++ {LTU, 1, GEU, 0, 65534, 1, 0}, /* GTU */
++ {GEU, 0, GEU, 0, 65535, 0, 0}, /* GEU */
++ {LTU, 0, LTU, 0, 65535, 0, 0}, /* LTU */
++ {GEU, 1, LTU, 0, 65534, 1, 0}, /* LEU */
++ };
++
++ enum internal_test test;
++ enum machine_mode mode;
++ const struct cmp_info *p_info;
++ int branch_p;
++
++
++
++
++ test = map_test_to_internal_test (test_code);
++ if (test == ITEST_MAX)
++ abort ();
++
++ p_info = &info[(int) test];
++
++ mode = GET_MODE (cmp0);
++ if (mode == VOIDmode)
++ mode = GET_MODE (cmp1);
++
++ branch_p = (destination != 0);
++
++ /* We can't, under any circumstances, have const_ints in cmp0
++ ??? Actually we could have const0 */
++ if (GET_CODE (cmp0) == CONST_INT)
++ cmp0 = force_reg (mode, cmp0);
++
++ /* if the comparison is against an int not in legal range
++ move it into a register */
++ if (GET_CODE (cmp1) == CONST_INT)
++ {
++ HOST_WIDE_INT value = INTVAL (cmp1);
++
++ if (value < p_info->const_low || value > p_info->const_high)
++ cmp1 = force_reg (mode, cmp1);
++ }
++
++ /* Comparison to constants, may involve adding 1 to change a GT into GE.
++ Comparison between two registers, may involve switching operands. */
++ if (GET_CODE (cmp1) == CONST_INT)
++ {
++ if (p_info->const_add != 0)
++ {
++ HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add;
++
++ /* If modification of cmp1 caused overflow,
++ we would get the wrong answer if we follow the usual path;
++ thus, x > 0xffffffffU would turn into x > 0U. */
++ if ((p_info->unsignedp
++ ? (unsigned HOST_WIDE_INT) new >
++ (unsigned HOST_WIDE_INT) INTVAL (cmp1)
++ : new > INTVAL (cmp1)) != (p_info->const_add > 0))
++ {
++ /* ??? This case can never happen with the current numbers,
++ but I am paranoid and would rather an abort than
++ a bug I will never find */
++ abort ();
++ }
++ else
++ cmp1 = GEN_INT (new);
++ }
++ }
++
++ else if (p_info->reverse_regs)
++ {
++ rtx temp = cmp0;
++ cmp0 = cmp1;
++ cmp1 = temp;
++ }
++
++
++
++ if (branch_p)
++ {
++ if (register_operand (cmp0, mode) && register_operand (cmp1, mode))
++ {
++ rtx insn;
++ rtx cond = gen_rtx (p_info->test_code_reg, mode, cmp0, cmp1);
++ rtx label = gen_rtx_LABEL_REF (VOIDmode, destination);
++
++ insn = gen_rtx_SET (VOIDmode, pc_rtx,
++ gen_rtx_IF_THEN_ELSE (VOIDmode,
++ cond, label, pc_rtx));
++ emit_jump_insn (insn);
++ }
++ else
++ {
++ rtx cond, label;
++
++ result = gen_reg_rtx (mode);
++
++ emit_move_insn (result,
++ gen_rtx (p_info->test_code_const, mode, cmp0,
++ cmp1));
++
++ cond = gen_rtx (NE, mode, result, const0_rtx);
++ label = gen_rtx_LABEL_REF (VOIDmode, destination);
++
++ emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
++ gen_rtx_IF_THEN_ELSE (VOIDmode,
++ cond,
++ label, pc_rtx)));
++ }
++ }
++ else
++ {
++ if (register_operand (cmp0, mode) && register_operand (cmp1, mode))
++ {
++ emit_move_insn (result,
++ gen_rtx (p_info->test_code_reg, mode, cmp0, cmp1));
++ }
++ else
++ {
++ emit_move_insn (result,
++ gen_rtx (p_info->test_code_const, mode, cmp0,
++ cmp1));
++ }
++ }
++
++}
++
++
++/* ??? For now conditional moves are only supported
++ when the mode of the operands being compared are
++ the same as the ones being moved */
++
++void
++gen_conditional_move (rtx *operands, enum machine_mode mode)
++{
++ rtx insn, cond;
++ rtx cmp_reg = gen_reg_rtx (mode);
++ enum rtx_code cmp_code = GET_CODE (operands[1]);
++ enum rtx_code move_code = EQ;
++
++ /* emit a comparison if it is not "simple".
++ Simple comparisons are X eq 0 and X ne 0 */
++ if ((cmp_code == EQ || cmp_code == NE) && branch_cmp[1] == const0_rtx)
++ {
++ cmp_reg = branch_cmp[0];
++ move_code = cmp_code;
++ }
++ else if ((cmp_code == EQ || cmp_code == NE) && branch_cmp[0] == const0_rtx)
++ {
++ cmp_reg = branch_cmp[1];
++ move_code = cmp_code == EQ ? NE : EQ;
++ }
++ else
++ gen_int_relational (cmp_code, cmp_reg, branch_cmp[0], branch_cmp[1],
++ NULL_RTX);
++
++ cond = gen_rtx (move_code, VOIDmode, cmp_reg, CONST0_RTX (mode));
++ insn = gen_rtx_SET (mode, operands[0],
++ gen_rtx_IF_THEN_ELSE (mode,
++ cond, operands[2], operands[3]));
++ emit_insn (insn);
++}
++
++/*******************
++ * Addressing Modes
++ *******************/
++
++int
++nios2_legitimate_address (rtx operand, enum machine_mode mode ATTRIBUTE_UNUSED,
++ int strict)
++{
++ int ret_val = 0;
++
++ switch (GET_CODE (operand))
++ {
++ /* direct. */
++ case SYMBOL_REF:
++ if (SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (operand))
++ {
++ ret_val = 1;
++ break;
++ }
++ /* else, fall through */
++ case LABEL_REF:
++ case CONST_INT:
++ case CONST:
++ case CONST_DOUBLE:
++ /* ??? In here I need to add gp addressing */
++ ret_val = 0;
++
++ break;
++
++ /* Register indirect. */
++ case REG:
++ ret_val = REG_OK_FOR_BASE_P2 (operand, strict);
++ break;
++
++ /* Register indirect with displacement */
++ case PLUS:
++ {
++ rtx op0 = XEXP (operand, 0);
++ rtx op1 = XEXP (operand, 1);
++
++ if (REG_P (op0) && REG_P (op1))
++ ret_val = 0;
++ else if (REG_P (op0) && CONSTANT_P (op1))
++ ret_val = REG_OK_FOR_BASE_P2 (op0, strict)
++ && SMALL_INT (INTVAL (op1));
++ else if (REG_P (op1) && CONSTANT_P (op0))
++ ret_val = REG_OK_FOR_BASE_P2 (op1, strict)
++ && SMALL_INT (INTVAL (op0));
++ else
++ ret_val = 0;
++ }
++ break;
++
++ default:
++ ret_val = 0;
++ break;
++ }
++
++ return ret_val;
++}
++
++/* Return true if EXP should be placed in the small data section. */
++
++static bool
++nios2_in_small_data_p (tree exp)
++{
++ /* We want to merge strings, so we never consider them small data. */
++ if (TREE_CODE (exp) == STRING_CST)
++ return false;
++
++ if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
++ {
++ const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
++ /* ??? these string names need moving into
++ an array in some header file */
++ if (nios2_section_threshold > 0
++ && (strcmp (section, ".sbss") == 0
++ || strncmp (section, ".sbss.", 6) == 0
++ || strcmp (section, ".sdata") == 0
++ || strncmp (section, ".sdata.", 7) == 0))
++ return true;
++ }
++ else if (TREE_CODE (exp) == VAR_DECL)
++ {
++ HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
++
++ /* If this is an incomplete type with size 0, then we can't put it
++ in sdata because it might be too big when completed. */
++ if (size > 0 && size <= nios2_section_threshold)
++ return true;
++ }
++
++ return false;
++}
++
++static void
++nios2_encode_section_info (tree decl, rtx rtl, int first)
++{
++
++ rtx symbol;
++ int flags;
++
++ default_encode_section_info (decl, rtl, first);
++
++ /* Careful not to prod global register variables. */
++ if (GET_CODE (rtl) != MEM)
++ return;
++ symbol = XEXP (rtl, 0);
++ if (GET_CODE (symbol) != SYMBOL_REF)
++ return;
++
++ flags = SYMBOL_REF_FLAGS (symbol);
++
++ /* We don't want weak variables to be addressed with gp in case they end up with
++ value 0 which is not within 2^15 of $gp */
++ if (DECL_P (decl) && DECL_WEAK (decl))
++ flags |= SYMBOL_FLAG_WEAK_DECL;
++
++ SYMBOL_REF_FLAGS (symbol) = flags;
++}
++
++
++static unsigned int
++nios2_section_type_flags (tree decl, const char *name, int reloc)
++{
++ unsigned int flags;
++
++ flags = default_section_type_flags (decl, name, reloc);
++
++ /* ??? these string names need moving into an array in some header file */
++ if (strcmp (name, ".sbss") == 0
++ || strncmp (name, ".sbss.", 6) == 0
++ || strcmp (name, ".sdata") == 0
++ || strncmp (name, ".sdata.", 7) == 0)
++ flags |= SECTION_SMALL;
++
++ return flags;
++}
++
++
++
++
++/*****************************************
++ * Defining the Output Assembler Language
++ *****************************************/
++
++/* -------------- *
++ * Output of Data
++ * -------------- */
++
++
++/* -------------------------------- *
++ * Output of Assembler Instructions
++ * -------------------------------- */
++
++
++/* print the operand OP to file stream
++ FILE modified by LETTER. LETTER
++ can be one of:
++ i: print "i" if OP is an immediate, except 0
++ o: print "io" if OP is volatile
++
++ z: for const0_rtx print $0 instead of 0
++ H: for %hiadj
++ L: for %lo
++ U: for upper half of 32 bit value
++ */
++
++void
++nios2_print_operand (FILE *file, rtx op, int letter)
++{
++
++ switch (letter)
++ {
++ case 'i':
++ if (CONSTANT_P (op) && (op != const0_rtx))
++ fprintf (file, "i");
++ return;
++
++ case 'o':
++ if (GET_CODE (op) == MEM
++ && ((MEM_VOLATILE_P (op) && !TARGET_CACHE_VOLATILE)
++ || TARGET_BYPASS_CACHE))
++ fprintf (file, "io");
++ return;
++
++ default:
++ break;
++ }
++
++ if (comparison_operator (op, VOIDmode))
++ {
++ if (letter == 0)
++ {
++ fprintf (file, "%s", GET_RTX_NAME (GET_CODE (op)));
++ return;
++ }
++ }
++
++
++ switch (GET_CODE (op))
++ {
++ case REG:
++ if (letter == 0 || letter == 'z')
++ {
++ fprintf (file, "%s", reg_names[REGNO (op)]);
++ return;
++ }
++
++ case CONST_INT:
++ if (INTVAL (op) == 0 && letter == 'z')
++ {
++ fprintf (file, "zero");
++ return;
++ }
++ else if (letter == 'U')
++ {
++ HOST_WIDE_INT val = INTVAL (op);
++ rtx new_op;
++ val = (val / 65536) & 0xFFFF;
++ new_op = GEN_INT (val);
++ output_addr_const (file, new_op);
++ return;
++ }
++
++ /* else, fall through */
++ case CONST:
++ case LABEL_REF:
++ case SYMBOL_REF:
++ case CONST_DOUBLE:
++ if (letter == 0 || letter == 'z')
++ {
++ output_addr_const (file, op);
++ return;
++ }
++ else if (letter == 'H')
++ {
++ fprintf (file, "%%hiadj(");
++ output_addr_const (file, op);
++ fprintf (file, ")");
++ return;
++ }
++ else if (letter == 'L')
++ {
++ fprintf (file, "%%lo(");
++ output_addr_const (file, op);
++ fprintf (file, ")");
++ return;
++ }
++
++
++ case SUBREG:
++ case MEM:
++ if (letter == 0)
++ {
++ output_address (op);
++ return;
++ }
++
++ case CODE_LABEL:
++ if (letter == 0)
++ {
++ output_addr_const (file, op);
++ return;
++ }
++
++ default:
++ break;
++ }
++
++ fprintf (stderr, "Missing way to print (%c) ", letter);
++ debug_rtx (op);
++ abort ();
++}
++
++static int gprel_constant (rtx);
++
++static int
++gprel_constant (rtx op)
++{
++ if (GET_CODE (op) == SYMBOL_REF
++ && SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (op))
++ {
++ return 1;
++ }
++ else if (GET_CODE (op) == CONST
++ && GET_CODE (XEXP (op, 0)) == PLUS)
++ {
++ return gprel_constant (XEXP (XEXP (op, 0), 0));
++ }
++ else
++ {
++ return 0;
++ }
++}
++
++void
++nios2_print_operand_address (FILE *file, rtx op)
++{
++ switch (GET_CODE (op))
++ {
++ case CONST:
++ case CONST_INT:
++ case LABEL_REF:
++ case CONST_DOUBLE:
++ case SYMBOL_REF:
++ if (gprel_constant (op))
++ {
++ fprintf (file, "%%gprel(");
++ output_addr_const (file, op);
++ fprintf (file, ")(%s)", reg_names[GP_REGNO]);
++ return;
++ }
++
++ break;
++
++ case PLUS:
++ {
++ rtx op0 = XEXP (op, 0);
++ rtx op1 = XEXP (op, 1);
++
++ if (REG_P (op0) && CONSTANT_P (op1))
++ {
++ output_addr_const (file, op1);
++ fprintf (file, "(%s)", reg_names[REGNO (op0)]);
++ return;
++ }
++ else if (REG_P (op1) && CONSTANT_P (op0))
++ {
++ output_addr_const (file, op0);
++ fprintf (file, "(%s)", reg_names[REGNO (op1)]);
++ return;
++ }
++ }
++ break;
++
++ case REG:
++ fprintf (file, "0(%s)", reg_names[REGNO (op)]);
++ return;
++
++ case MEM:
++ {
++ rtx base = XEXP (op, 0);
++ PRINT_OPERAND_ADDRESS (file, base);
++ return;
++ }
++ default:
++ break;
++ }
++
++ fprintf (stderr, "Missing way to print address\n");
++ debug_rtx (op);
++ abort ();
++}
++
++
++
++
++
++/****************************
++ * Predicates
++ ****************************/
++
++int
++arith_operand (rtx op, enum machine_mode mode)
++{
++ if (GET_CODE (op) == CONST_INT && SMALL_INT (INTVAL (op)))
++ return 1;
++
++ return register_operand (op, mode);
++}
++
++int
++uns_arith_operand (rtx op, enum machine_mode mode)
++{
++ if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (INTVAL (op)))
++ return 1;
++
++ return register_operand (op, mode);
++}
++
++int
++logical_operand (rtx op, enum machine_mode mode)
++{
++ if (GET_CODE (op) == CONST_INT
++ && (SMALL_INT_UNSIGNED (INTVAL (op)) || UPPER16_INT (INTVAL (op))))
++ return 1;
++
++ return register_operand (op, mode);
++}
++
++int
++shift_operand (rtx op, enum machine_mode mode)
++{
++ if (GET_CODE (op) == CONST_INT && SHIFT_INT (INTVAL (op)))
++ return 1;
++
++ return register_operand (op, mode);
++}
++
++int
++rdwrctl_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
++{
++ return GET_CODE (op) == CONST_INT && RDWRCTL_INT (INTVAL (op));
++}
++
++/* Return truth value of whether OP is a register or the constant 0. */
++
++int
++reg_or_0_operand (rtx op, enum machine_mode mode)
++{
++ switch (GET_CODE (op))
++ {
++ case CONST_INT:
++ return INTVAL (op) == 0;
++
++ case CONST_DOUBLE:
++ return op == CONST0_RTX (mode);
++
++ default:
++ break;
++ }
++
++ return register_operand (op, mode);
++}
++
++
++int
++equality_op (rtx op, enum machine_mode mode)
++{
++ if (mode != GET_MODE (op))
++ return 0;
++
++ return GET_CODE (op) == EQ || GET_CODE (op) == NE;
++}
++
++int
++custom_insn_opcode (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
++{
++ return GET_CODE (op) == CONST_INT && CUSTOM_INSN_OPCODE (INTVAL (op));
++}
++
++
++
++
++
++
++
++/*****************************************************************************
++**
++** instruction scheduler
++**
++*****************************************************************************/
++static int
++nios2_use_dfa_pipeline_interface ()
++{
++ return 1;
++}
++
++
++static int
++nios2_issue_rate ()
++{
++#ifdef MAX_DFA_ISSUE_RATE
++ return MAX_DFA_ISSUE_RATE;
++#else
++ return 1;
++#endif
++}
++
++
++const char *
++asm_output_opcode (FILE *file ATTRIBUTE_UNUSED,
++ const char *ptr ATTRIBUTE_UNUSED)
++{
++ const char *p;
++
++ p = ptr;
++ return ptr;
++}
++
++
++
++/*****************************************************************************
++**
++** function arguments
++**
++*****************************************************************************/
++
++void
++init_cumulative_args (CUMULATIVE_ARGS *cum,
++ tree fntype ATTRIBUTE_UNUSED,
++ rtx libname ATTRIBUTE_UNUSED,
++ tree fndecl ATTRIBUTE_UNUSED,
++ int n_named_args ATTRIBUTE_UNUSED)
++{
++ cum->regs_used = 0;
++}
++
++
++/* Update the data in CUM to advance over an argument
++ of mode MODE and data type TYPE.
++ (TYPE is null for libcalls where that information may not be available.) */
++
++void
++function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
++ tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED)
++{
++ HOST_WIDE_INT param_size;
++
++ if (mode == BLKmode)
++ {
++ param_size = int_size_in_bytes (type);
++ if (param_size < 0)
++ internal_error
++ ("Do not know how to handle large structs or variable length types");
++ }
++ else
++ {
++ param_size = GET_MODE_SIZE (mode);
++ }
++
++ /* convert to words (round up) */
++ param_size = (3 + param_size) / 4;
++
++ if (cum->regs_used + param_size > NUM_ARG_REGS)
++ {
++ cum->regs_used = NUM_ARG_REGS;
++ }
++ else
++ {
++ cum->regs_used += param_size;
++ }
++
++ return;
++}
++
++/* Define where to put the arguments to a function. Value is zero to
++ push the argument on the stack, or a hard register in which to
++ store the argument.
++
++ MODE is the argument's machine mode.
++ TYPE is the data type of the argument (as a tree).
++ This is null for libcalls where that information may
++ not be available.
++ CUM is a variable of type CUMULATIVE_ARGS which gives info about
++ the preceding args and about the function being called.
++ NAMED is nonzero if this argument is a named parameter
++ (otherwise it is an extra parameter matching an ellipsis). */
++rtx
++function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
++ tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED)
++{
++ rtx return_rtx = NULL_RTX;
++
++ if (cum->regs_used < NUM_ARG_REGS)
++ {
++ return_rtx = gen_rtx_REG (mode, FIRST_ARG_REGNO + cum->regs_used);
++ }
++
++ return return_rtx;
++}
++
++int
++function_arg_partial_nregs (const CUMULATIVE_ARGS *cum,
++ enum machine_mode mode, tree type,
++ int named ATTRIBUTE_UNUSED)
++{
++ HOST_WIDE_INT param_size;
++
++ if (mode == BLKmode)
++ {
++ param_size = int_size_in_bytes (type);
++ if (param_size < 0)
++ internal_error
++ ("Do not know how to handle large structs or variable length types");
++ }
++ else
++ {
++ param_size = GET_MODE_SIZE (mode);
++ }
++
++ /* convert to words (round up) */
++ param_size = (3 + param_size) / 4;
++
++ if (cum->regs_used < NUM_ARG_REGS
++ && cum->regs_used + param_size > NUM_ARG_REGS)
++ {
++ return NUM_ARG_REGS - cum->regs_used;
++ }
++ else
++ {
++ return 0;
++ }
++}
++
++
++int
++nios2_return_in_memory (tree type)
++{
++ int res = ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
++ || (int_size_in_bytes (type) == -1));
++
++ return res;
++}
++
++/* ??? It may be possible to eliminate the copyback and implement
++ my own va_arg type, but that is more work for now. */
++int
++nios2_setup_incoming_varargs (const CUMULATIVE_ARGS *cum,
++ enum machine_mode mode, tree type,
++ int no_rtl)
++{
++ CUMULATIVE_ARGS local_cum;
++ int regs_to_push;
++
++ local_cum = *cum;
++ FUNCTION_ARG_ADVANCE (local_cum, mode, type, 1);
++
++ regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
++
++ if (!no_rtl)
++ {
++ if (regs_to_push > 0)
++ {
++ rtx ptr, mem;
++
++ ptr = virtual_incoming_args_rtx;
++ mem = gen_rtx_MEM (BLKmode, ptr);
++
++ /* va_arg is an array access in this case, which causes
++ it to get MEM_IN_STRUCT_P set. We must set it here
++ so that the insn scheduler won't assume that these
++ stores can't possibly overlap with the va_arg loads. */
++ MEM_SET_IN_STRUCT_P (mem, 1);
++
++ emit_insn (gen_blockage ());
++ move_block_from_reg (local_cum.regs_used + FIRST_ARG_REGNO, mem,
++ regs_to_push);
++ emit_insn (gen_blockage ());
++ }
++ }
++
++ return regs_to_push * UNITS_PER_WORD;
++
++}
++
++
++
++/*****************************************************************************
++**
++** builtins
++**
++** This method for handling builtins is from CSP where _many_ more types of
++** expanders have already been written. Check there first before writing
++** new ones.
++**
++*****************************************************************************/
++
++enum nios2_builtins
++{
++ NIOS2_BUILTIN_LDBIO,
++ NIOS2_BUILTIN_LDBUIO,
++ NIOS2_BUILTIN_LDHIO,
++ NIOS2_BUILTIN_LDHUIO,
++ NIOS2_BUILTIN_LDWIO,
++ NIOS2_BUILTIN_STBIO,
++ NIOS2_BUILTIN_STHIO,
++ NIOS2_BUILTIN_STWIO,
++ NIOS2_BUILTIN_SYNC,
++ NIOS2_BUILTIN_RDCTL,
++ NIOS2_BUILTIN_WRCTL,
++
++ NIOS2_BUILTIN_CUSTOM_N,
++ NIOS2_BUILTIN_CUSTOM_NI,
++ NIOS2_BUILTIN_CUSTOM_NF,
++ NIOS2_BUILTIN_CUSTOM_NP,
++ NIOS2_BUILTIN_CUSTOM_NII,
++ NIOS2_BUILTIN_CUSTOM_NIF,
++ NIOS2_BUILTIN_CUSTOM_NIP,
++ NIOS2_BUILTIN_CUSTOM_NFI,
++ NIOS2_BUILTIN_CUSTOM_NFF,
++ NIOS2_BUILTIN_CUSTOM_NFP,
++ NIOS2_BUILTIN_CUSTOM_NPI,
++ NIOS2_BUILTIN_CUSTOM_NPF,
++ NIOS2_BUILTIN_CUSTOM_NPP,
++ NIOS2_BUILTIN_CUSTOM_IN,
++ NIOS2_BUILTIN_CUSTOM_INI,
++ NIOS2_BUILTIN_CUSTOM_INF,
++ NIOS2_BUILTIN_CUSTOM_INP,
++ NIOS2_BUILTIN_CUSTOM_INII,
++ NIOS2_BUILTIN_CUSTOM_INIF,
++ NIOS2_BUILTIN_CUSTOM_INIP,
++ NIOS2_BUILTIN_CUSTOM_INFI,
++ NIOS2_BUILTIN_CUSTOM_INFF,
++ NIOS2_BUILTIN_CUSTOM_INFP,
++ NIOS2_BUILTIN_CUSTOM_INPI,
++ NIOS2_BUILTIN_CUSTOM_INPF,
++ NIOS2_BUILTIN_CUSTOM_INPP,
++ NIOS2_BUILTIN_CUSTOM_FN,
++ NIOS2_BUILTIN_CUSTOM_FNI,
++ NIOS2_BUILTIN_CUSTOM_FNF,
++ NIOS2_BUILTIN_CUSTOM_FNP,
++ NIOS2_BUILTIN_CUSTOM_FNII,
++ NIOS2_BUILTIN_CUSTOM_FNIF,
++ NIOS2_BUILTIN_CUSTOM_FNIP,
++ NIOS2_BUILTIN_CUSTOM_FNFI,
++ NIOS2_BUILTIN_CUSTOM_FNFF,
++ NIOS2_BUILTIN_CUSTOM_FNFP,
++ NIOS2_BUILTIN_CUSTOM_FNPI,
++ NIOS2_BUILTIN_CUSTOM_FNPF,
++ NIOS2_BUILTIN_CUSTOM_FNPP,
++ NIOS2_BUILTIN_CUSTOM_PN,
++ NIOS2_BUILTIN_CUSTOM_PNI,
++ NIOS2_BUILTIN_CUSTOM_PNF,
++ NIOS2_BUILTIN_CUSTOM_PNP,
++ NIOS2_BUILTIN_CUSTOM_PNII,
++ NIOS2_BUILTIN_CUSTOM_PNIF,
++ NIOS2_BUILTIN_CUSTOM_PNIP,
++ NIOS2_BUILTIN_CUSTOM_PNFI,
++ NIOS2_BUILTIN_CUSTOM_PNFF,
++ NIOS2_BUILTIN_CUSTOM_PNFP,
++ NIOS2_BUILTIN_CUSTOM_PNPI,
++ NIOS2_BUILTIN_CUSTOM_PNPF,
++ NIOS2_BUILTIN_CUSTOM_PNPP,
++
++
++ LIM_NIOS2_BUILTINS
++};
++
++struct builtin_description
++{
++ const enum insn_code icode;
++ const char *const name;
++ const enum nios2_builtins code;
++ const tree *type;
++ rtx (* expander) PARAMS ((const struct builtin_description *,
++ tree, rtx, rtx, enum machine_mode, int));
++};
++
++static rtx nios2_expand_STXIO (const struct builtin_description *,
++ tree, rtx, rtx, enum machine_mode, int);
++static rtx nios2_expand_LDXIO (const struct builtin_description *,
++ tree, rtx, rtx, enum machine_mode, int);
++static rtx nios2_expand_sync (const struct builtin_description *,
++ tree, rtx, rtx, enum machine_mode, int);
++static rtx nios2_expand_rdctl (const struct builtin_description *,
++ tree, rtx, rtx, enum machine_mode, int);
++static rtx nios2_expand_wrctl (const struct builtin_description *,
++ tree, rtx, rtx, enum machine_mode, int);
++
++static rtx nios2_expand_custom_n (const struct builtin_description *,
++ tree, rtx, rtx, enum machine_mode, int);
++static rtx nios2_expand_custom_Xn (const struct builtin_description *,
++ tree, rtx, rtx, enum machine_mode, int);
++static rtx nios2_expand_custom_nX (const struct builtin_description *,
++ tree, rtx, rtx, enum machine_mode, int);
++static rtx nios2_expand_custom_XnX (const struct builtin_description *,
++ tree, rtx, rtx, enum machine_mode, int);
++static rtx nios2_expand_custom_nXX (const struct builtin_description *,
++ tree, rtx, rtx, enum machine_mode, int);
++static rtx nios2_expand_custom_XnXX (const struct builtin_description *,
++ tree, rtx, rtx, enum machine_mode, int);
++
++static tree endlink;
++
++/* int fn (volatile const void *)
++ */
++static tree int_ftype_volatile_const_void_p;
++
++/* int fn (int)
++ */
++static tree int_ftype_int;
++
++/* void fn (int, int)
++ */
++static tree void_ftype_int_int;
++
++/* void fn (volatile void *, int)
++ */
++static tree void_ftype_volatile_void_p_int;
++
++/* void fn (void)
++ */
++static tree void_ftype_void;
++
++static tree custom_n;
++static tree custom_ni;
++static tree custom_nf;
++static tree custom_np;
++static tree custom_nii;
++static tree custom_nif;
++static tree custom_nip;
++static tree custom_nfi;
++static tree custom_nff;
++static tree custom_nfp;
++static tree custom_npi;
++static tree custom_npf;
++static tree custom_npp;
++static tree custom_in;
++static tree custom_ini;
++static tree custom_inf;
++static tree custom_inp;
++static tree custom_inii;
++static tree custom_inif;
++static tree custom_inip;
++static tree custom_infi;
++static tree custom_inff;
++static tree custom_infp;
++static tree custom_inpi;
++static tree custom_inpf;
++static tree custom_inpp;
++static tree custom_fn;
++static tree custom_fni;
++static tree custom_fnf;
++static tree custom_fnp;
++static tree custom_fnii;
++static tree custom_fnif;
++static tree custom_fnip;
++static tree custom_fnfi;
++static tree custom_fnff;
++static tree custom_fnfp;
++static tree custom_fnpi;
++static tree custom_fnpf;
++static tree custom_fnpp;
++static tree custom_pn;
++static tree custom_pni;
++static tree custom_pnf;
++static tree custom_pnp;
++static tree custom_pnii;
++static tree custom_pnif;
++static tree custom_pnip;
++static tree custom_pnfi;
++static tree custom_pnff;
++static tree custom_pnfp;
++static tree custom_pnpi;
++static tree custom_pnpf;
++static tree custom_pnpp;
++
++
++static const struct builtin_description bdesc[] = {
++ {CODE_FOR_ldbio, "__builtin_ldbio", NIOS2_BUILTIN_LDBIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
++ {CODE_FOR_ldbuio, "__builtin_ldbuio", NIOS2_BUILTIN_LDBUIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
++ {CODE_FOR_ldhio, "__builtin_ldhio", NIOS2_BUILTIN_LDHIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
++ {CODE_FOR_ldhuio, "__builtin_ldhuio", NIOS2_BUILTIN_LDHUIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
++ {CODE_FOR_ldwio, "__builtin_ldwio", NIOS2_BUILTIN_LDWIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
++
++ {CODE_FOR_stbio, "__builtin_stbio", NIOS2_BUILTIN_STBIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
++ {CODE_FOR_sthio, "__builtin_sthio", NIOS2_BUILTIN_STHIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
++ {CODE_FOR_stwio, "__builtin_stwio", NIOS2_BUILTIN_STWIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
++
++ {CODE_FOR_sync, "__builtin_sync", NIOS2_BUILTIN_SYNC, &void_ftype_void, nios2_expand_sync},
++ {CODE_FOR_rdctl, "__builtin_rdctl", NIOS2_BUILTIN_RDCTL, &int_ftype_int, nios2_expand_rdctl},
++ {CODE_FOR_wrctl, "__builtin_wrctl", NIOS2_BUILTIN_WRCTL, &void_ftype_int_int, nios2_expand_wrctl},
++
++ {CODE_FOR_custom_n, "__builtin_custom_n", NIOS2_BUILTIN_CUSTOM_N, &custom_n, nios2_expand_custom_n},
++ {CODE_FOR_custom_ni, "__builtin_custom_ni", NIOS2_BUILTIN_CUSTOM_NI, &custom_ni, nios2_expand_custom_nX},
++ {CODE_FOR_custom_nf, "__builtin_custom_nf", NIOS2_BUILTIN_CUSTOM_NF, &custom_nf, nios2_expand_custom_nX},
++ {CODE_FOR_custom_np, "__builtin_custom_np", NIOS2_BUILTIN_CUSTOM_NP, &custom_np, nios2_expand_custom_nX},
++ {CODE_FOR_custom_nii, "__builtin_custom_nii", NIOS2_BUILTIN_CUSTOM_NII, &custom_nii, nios2_expand_custom_nXX},
++ {CODE_FOR_custom_nif, "__builtin_custom_nif", NIOS2_BUILTIN_CUSTOM_NIF, &custom_nif, nios2_expand_custom_nXX},
++ {CODE_FOR_custom_nip, "__builtin_custom_nip", NIOS2_BUILTIN_CUSTOM_NIP, &custom_nip, nios2_expand_custom_nXX},
++ {CODE_FOR_custom_nfi, "__builtin_custom_nfi", NIOS2_BUILTIN_CUSTOM_NFI, &custom_nfi, nios2_expand_custom_nXX},
++ {CODE_FOR_custom_nff, "__builtin_custom_nff", NIOS2_BUILTIN_CUSTOM_NFF, &custom_nff, nios2_expand_custom_nXX},
++ {CODE_FOR_custom_nfp, "__builtin_custom_nfp", NIOS2_BUILTIN_CUSTOM_NFP, &custom_nfp, nios2_expand_custom_nXX},
++ {CODE_FOR_custom_npi, "__builtin_custom_npi", NIOS2_BUILTIN_CUSTOM_NPI, &custom_npi, nios2_expand_custom_nXX},
++ {CODE_FOR_custom_npf, "__builtin_custom_npf", NIOS2_BUILTIN_CUSTOM_NPF, &custom_npf, nios2_expand_custom_nXX},
++ {CODE_FOR_custom_npp, "__builtin_custom_npp", NIOS2_BUILTIN_CUSTOM_NPP, &custom_npp, nios2_expand_custom_nXX},
++ {CODE_FOR_custom_in, "__builtin_custom_in", NIOS2_BUILTIN_CUSTOM_IN, &custom_in, nios2_expand_custom_Xn},
++ {CODE_FOR_custom_ini, "__builtin_custom_ini", NIOS2_BUILTIN_CUSTOM_INI, &custom_ini, nios2_expand_custom_XnX},
++ {CODE_FOR_custom_inf, "__builtin_custom_inf", NIOS2_BUILTIN_CUSTOM_INF, &custom_inf, nios2_expand_custom_XnX},
++ {CODE_FOR_custom_inp, "__builtin_custom_inp", NIOS2_BUILTIN_CUSTOM_INP, &custom_inp, nios2_expand_custom_XnX},
++ {CODE_FOR_custom_inii, "__builtin_custom_inii", NIOS2_BUILTIN_CUSTOM_INII, &custom_inii, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_inif, "__builtin_custom_inif", NIOS2_BUILTIN_CUSTOM_INIF, &custom_inif, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_inip, "__builtin_custom_inip", NIOS2_BUILTIN_CUSTOM_INIP, &custom_inip, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_infi, "__builtin_custom_infi", NIOS2_BUILTIN_CUSTOM_INFI, &custom_infi, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_inff, "__builtin_custom_inff", NIOS2_BUILTIN_CUSTOM_INFF, &custom_inff, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_infp, "__builtin_custom_infp", NIOS2_BUILTIN_CUSTOM_INFP, &custom_infp, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_inpi, "__builtin_custom_inpi", NIOS2_BUILTIN_CUSTOM_INPI, &custom_inpi, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_inpf, "__builtin_custom_inpf", NIOS2_BUILTIN_CUSTOM_INPF, &custom_inpf, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_inpp, "__builtin_custom_inpp", NIOS2_BUILTIN_CUSTOM_INPP, &custom_inpp, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_fn, "__builtin_custom_fn", NIOS2_BUILTIN_CUSTOM_FN, &custom_fn, nios2_expand_custom_Xn},
++ {CODE_FOR_custom_fni, "__builtin_custom_fni", NIOS2_BUILTIN_CUSTOM_FNI, &custom_fni, nios2_expand_custom_XnX},
++ {CODE_FOR_custom_fnf, "__builtin_custom_fnf", NIOS2_BUILTIN_CUSTOM_FNF, &custom_fnf, nios2_expand_custom_XnX},
++ {CODE_FOR_custom_fnp, "__builtin_custom_fnp", NIOS2_BUILTIN_CUSTOM_FNP, &custom_fnp, nios2_expand_custom_XnX},
++ {CODE_FOR_custom_fnii, "__builtin_custom_fnii", NIOS2_BUILTIN_CUSTOM_FNII, &custom_fnii, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_fnif, "__builtin_custom_fnif", NIOS2_BUILTIN_CUSTOM_FNIF, &custom_fnif, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_fnip, "__builtin_custom_fnip", NIOS2_BUILTIN_CUSTOM_FNIP, &custom_fnip, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_fnfi, "__builtin_custom_fnfi", NIOS2_BUILTIN_CUSTOM_FNFI, &custom_fnfi, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_fnff, "__builtin_custom_fnff", NIOS2_BUILTIN_CUSTOM_FNFF, &custom_fnff, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_fnfp, "__builtin_custom_fnfp", NIOS2_BUILTIN_CUSTOM_FNFP, &custom_fnfp, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_fnpi, "__builtin_custom_fnpi", NIOS2_BUILTIN_CUSTOM_FNPI, &custom_fnpi, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_fnpf, "__builtin_custom_fnpf", NIOS2_BUILTIN_CUSTOM_FNPF, &custom_fnpf, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_fnpp, "__builtin_custom_fnpp", NIOS2_BUILTIN_CUSTOM_FNPP, &custom_fnpp, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_pn, "__builtin_custom_pn", NIOS2_BUILTIN_CUSTOM_PN, &custom_pn, nios2_expand_custom_Xn},
++ {CODE_FOR_custom_pni, "__builtin_custom_pni", NIOS2_BUILTIN_CUSTOM_PNI, &custom_pni, nios2_expand_custom_XnX},
++ {CODE_FOR_custom_pnf, "__builtin_custom_pnf", NIOS2_BUILTIN_CUSTOM_PNF, &custom_pnf, nios2_expand_custom_XnX},
++ {CODE_FOR_custom_pnp, "__builtin_custom_pnp", NIOS2_BUILTIN_CUSTOM_PNP, &custom_pnp, nios2_expand_custom_XnX},
++ {CODE_FOR_custom_pnii, "__builtin_custom_pnii", NIOS2_BUILTIN_CUSTOM_PNII, &custom_pnii, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_pnif, "__builtin_custom_pnif", NIOS2_BUILTIN_CUSTOM_PNIF, &custom_pnif, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_pnip, "__builtin_custom_pnip", NIOS2_BUILTIN_CUSTOM_PNIP, &custom_pnip, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_pnfi, "__builtin_custom_pnfi", NIOS2_BUILTIN_CUSTOM_PNFI, &custom_pnfi, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_pnff, "__builtin_custom_pnff", NIOS2_BUILTIN_CUSTOM_PNFF, &custom_pnff, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_pnfp, "__builtin_custom_pnfp", NIOS2_BUILTIN_CUSTOM_PNFP, &custom_pnfp, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_pnpi, "__builtin_custom_pnpi", NIOS2_BUILTIN_CUSTOM_PNPI, &custom_pnpi, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_pnpf, "__builtin_custom_pnpf", NIOS2_BUILTIN_CUSTOM_PNPF, &custom_pnpf, nios2_expand_custom_XnXX},
++ {CODE_FOR_custom_pnpp, "__builtin_custom_pnpp", NIOS2_BUILTIN_CUSTOM_PNPP, &custom_pnpp, nios2_expand_custom_XnXX},
++
++
++ {0, 0, 0, 0, 0},
++};
++
++/* This does not have a closing bracket on purpose (see use) */
++#define def_param(TYPE) \
++ tree_cons (NULL_TREE, TYPE,
++
++static void
++nios2_init_builtins ()
++{
++ const struct builtin_description *d;
++
++
++ endlink = void_list_node;
++
++ /* Special indenting here because one of the brackets is in def_param */
++ /* *INDENT-OFF* */
++
++ /* int fn (volatile const void *)
++ */
++ int_ftype_volatile_const_void_p
++ = build_function_type (integer_type_node,
++ def_param (build_qualified_type (ptr_type_node,
++ TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))
++ endlink));
++
++
++ /* void fn (volatile void *, int)
++ */
++ void_ftype_volatile_void_p_int
++ = build_function_type (void_type_node,
++ def_param (build_qualified_type (ptr_type_node,
++ TYPE_QUAL_VOLATILE))
++ def_param (integer_type_node)
++ endlink)));
++
++ /* void fn (void)
++ */
++ void_ftype_void
++ = build_function_type (void_type_node,
++ endlink);
++
++ /* int fn (int)
++ */
++ int_ftype_int
++ = build_function_type (integer_type_node,
++ def_param (integer_type_node)
++ endlink));
++
++ /* void fn (int, int)
++ */
++ void_ftype_int_int
++ = build_function_type (void_type_node,
++ def_param (integer_type_node)
++ def_param (integer_type_node)
++ endlink)));
++
++
++#define CUSTOM_NUM def_param (integer_type_node)
++
++ custom_n
++ = build_function_type (void_type_node,
++ CUSTOM_NUM
++ endlink));
++ custom_ni
++ = build_function_type (void_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ endlink)));
++ custom_nf
++ = build_function_type (void_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ endlink)));
++ custom_np
++ = build_function_type (void_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ endlink)));
++ custom_nii
++ = build_function_type (void_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ def_param (integer_type_node)
++ endlink))));
++ custom_nif
++ = build_function_type (void_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ def_param (float_type_node)
++ endlink))));
++ custom_nip
++ = build_function_type (void_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ def_param (ptr_type_node)
++ endlink))));
++ custom_nfi
++ = build_function_type (void_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ def_param (integer_type_node)
++ endlink))));
++ custom_nff
++ = build_function_type (void_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ def_param (float_type_node)
++ endlink))));
++ custom_nfp
++ = build_function_type (void_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ def_param (ptr_type_node)
++ endlink))));
++ custom_npi
++ = build_function_type (void_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ def_param (integer_type_node)
++ endlink))));
++ custom_npf
++ = build_function_type (void_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ def_param (float_type_node)
++ endlink))));
++ custom_npp
++ = build_function_type (void_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ def_param (ptr_type_node)
++ endlink))));
++
++ custom_in
++ = build_function_type (integer_type_node,
++ CUSTOM_NUM
++ endlink));
++ custom_ini
++ = build_function_type (integer_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ endlink)));
++ custom_inf
++ = build_function_type (integer_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ endlink)));
++ custom_inp
++ = build_function_type (integer_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ endlink)));
++ custom_inii
++ = build_function_type (integer_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ def_param (integer_type_node)
++ endlink))));
++ custom_inif
++ = build_function_type (integer_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ def_param (float_type_node)
++ endlink))));
++ custom_inip
++ = build_function_type (integer_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ def_param (ptr_type_node)
++ endlink))));
++ custom_infi
++ = build_function_type (integer_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ def_param (integer_type_node)
++ endlink))));
++ custom_inff
++ = build_function_type (integer_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ def_param (float_type_node)
++ endlink))));
++ custom_infp
++ = build_function_type (integer_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ def_param (ptr_type_node)
++ endlink))));
++ custom_inpi
++ = build_function_type (integer_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ def_param (integer_type_node)
++ endlink))));
++ custom_inpf
++ = build_function_type (integer_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ def_param (float_type_node)
++ endlink))));
++ custom_inpp
++ = build_function_type (integer_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ def_param (ptr_type_node)
++ endlink))));
++
++ custom_fn
++ = build_function_type (float_type_node,
++ CUSTOM_NUM
++ endlink));
++ custom_fni
++ = build_function_type (float_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ endlink)));
++ custom_fnf
++ = build_function_type (float_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ endlink)));
++ custom_fnp
++ = build_function_type (float_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ endlink)));
++ custom_fnii
++ = build_function_type (float_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ def_param (integer_type_node)
++ endlink))));
++ custom_fnif
++ = build_function_type (float_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ def_param (float_type_node)
++ endlink))));
++ custom_fnip
++ = build_function_type (float_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ def_param (ptr_type_node)
++ endlink))));
++ custom_fnfi
++ = build_function_type (float_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ def_param (integer_type_node)
++ endlink))));
++ custom_fnff
++ = build_function_type (float_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ def_param (float_type_node)
++ endlink))));
++ custom_fnfp
++ = build_function_type (float_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ def_param (ptr_type_node)
++ endlink))));
++ custom_fnpi
++ = build_function_type (float_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ def_param (integer_type_node)
++ endlink))));
++ custom_fnpf
++ = build_function_type (float_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ def_param (float_type_node)
++ endlink))));
++ custom_fnpp
++ = build_function_type (float_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ def_param (ptr_type_node)
++ endlink))));
++
++
++ custom_pn
++ = build_function_type (ptr_type_node,
++ CUSTOM_NUM
++ endlink));
++ custom_pni
++ = build_function_type (ptr_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ endlink)));
++ custom_pnf
++ = build_function_type (ptr_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ endlink)));
++ custom_pnp
++ = build_function_type (ptr_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ endlink)));
++ custom_pnii
++ = build_function_type (ptr_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ def_param (integer_type_node)
++ endlink))));
++ custom_pnif
++ = build_function_type (ptr_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ def_param (float_type_node)
++ endlink))));
++ custom_pnip
++ = build_function_type (ptr_type_node,
++ CUSTOM_NUM
++ def_param (integer_type_node)
++ def_param (ptr_type_node)
++ endlink))));
++ custom_pnfi
++ = build_function_type (ptr_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ def_param (integer_type_node)
++ endlink))));
++ custom_pnff
++ = build_function_type (ptr_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ def_param (float_type_node)
++ endlink))));
++ custom_pnfp
++ = build_function_type (ptr_type_node,
++ CUSTOM_NUM
++ def_param (float_type_node)
++ def_param (ptr_type_node)
++ endlink))));
++ custom_pnpi
++ = build_function_type (ptr_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ def_param (integer_type_node)
++ endlink))));
++ custom_pnpf
++ = build_function_type (ptr_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ def_param (float_type_node)
++ endlink))));
++ custom_pnpp
++ = build_function_type (ptr_type_node,
++ CUSTOM_NUM
++ def_param (ptr_type_node)
++ def_param (ptr_type_node)
++ endlink))));
++
++
++
++ /* *INDENT-ON* */
++
++
++ for (d = bdesc; d->name; d++)
++ {
++ builtin_function (d->name, *d->type, d->code,
++ BUILT_IN_MD, NULL, NULL);
++ }
++}
++
++/* Expand an expression EXP that calls a built-in function,
++ with result going to TARGET if that's convenient
++ (and in mode MODE if that's convenient).
++ SUBTARGET may be used as the target for computing one of EXP's operands.
++ IGNORE is nonzero if the value is to be ignored. */
++
++static rtx
++nios2_expand_builtin (tree exp, rtx target, rtx subtarget,
++ enum machine_mode mode, int ignore)
++{
++ const struct builtin_description *d;
++ tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
++ unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
++
++ for (d = bdesc; d->name; d++)
++ if (d->code == fcode)
++ return (d->expander) (d, exp, target, subtarget, mode, ignore);
++
++ /* we should have seen one of the functins we registered */
++ abort ();
++}
++
++static rtx nios2_create_target (const struct builtin_description *, rtx);
++
++
++static rtx
++nios2_create_target (const struct builtin_description *d, rtx target)
++{
++ if (!target
++ || !(*insn_data[d->icode].operand[0].predicate) (target,
++ insn_data[d->icode].operand[0].mode))
++ {
++ target = gen_reg_rtx (insn_data[d->icode].operand[0].mode);
++ }
++
++ return target;
++}
++
++
++static rtx nios2_extract_opcode (const struct builtin_description *, int, tree);
++static rtx nios2_extract_operand (const struct builtin_description *, int, int, tree);
++
++static rtx
++nios2_extract_opcode (const struct builtin_description *d, int op, tree arglist)
++{
++ enum machine_mode mode = insn_data[d->icode].operand[op].mode;
++ tree arg = TREE_VALUE (arglist);
++ rtx opcode = expand_expr (arg, NULL_RTX, mode, 0);
++ opcode = protect_from_queue (opcode, 0);
++
++ if (!(*insn_data[d->icode].operand[op].predicate) (opcode, mode))
++ error ("Custom instruction opcode must be compile time constant in the range 0-255 for %s", d->name);
++
++ return opcode;
++}
++
++static rtx
++nios2_extract_operand (const struct builtin_description *d, int op, int argnum, tree arglist)
++{
++ enum machine_mode mode = insn_data[d->icode].operand[op].mode;
++ tree arg = TREE_VALUE (arglist);
++ rtx operand = expand_expr (arg, NULL_RTX, mode, 0);
++ operand = protect_from_queue (operand, 0);
++
++ if (!(*insn_data[d->icode].operand[op].predicate) (operand, mode))
++ operand = copy_to_mode_reg (mode, operand);
++
++ /* ??? Better errors would be nice */
++ if (!(*insn_data[d->icode].operand[op].predicate) (operand, mode))
++ error ("Invalid argument %d to %s", argnum, d->name);
++
++ return operand;
++}
++
++
++static rtx
++nios2_expand_custom_n (const struct builtin_description *d, tree exp,
++ rtx target ATTRIBUTE_UNUSED, rtx subtarget ATTRIBUTE_UNUSED,
++ enum machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED)
++{
++ tree arglist = TREE_OPERAND (exp, 1);
++ rtx pat;
++ rtx opcode;
++
++ /* custom_n should have exactly one operand */
++ if (insn_data[d->icode].n_operands != 1)
++ abort ();
++
++ opcode = nios2_extract_opcode (d, 0, arglist);
++
++ pat = GEN_FCN (d->icode) (opcode);
++ if (!pat)
++ return 0;
++ emit_insn (pat);
++ return 0;
++}
++
++static rtx
++nios2_expand_custom_Xn (const struct builtin_description *d, tree exp,
++ rtx target, rtx subtarget ATTRIBUTE_UNUSED,
++ enum machine_mode mode ATTRIBUTE_UNUSED,
++ int ignore ATTRIBUTE_UNUSED)
++{
++ tree arglist = TREE_OPERAND (exp, 1);
++ rtx pat;
++ rtx opcode;
++
++ /* custom_Xn should have exactly two operands */
++ if (insn_data[d->icode].n_operands != 2)
++ abort ();
++
++ target = nios2_create_target (d, target);
++ opcode = nios2_extract_opcode (d, 1, arglist);
++
++ pat = GEN_FCN (d->icode) (target, opcode);
++ if (!pat)
++ return 0;
++ emit_insn (pat);
++ return target;
++}
++
++static rtx
++nios2_expand_custom_nX (const struct builtin_description *d, tree exp,
++ rtx target ATTRIBUTE_UNUSED, rtx subtarget ATTRIBUTE_UNUSED,
++ enum machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED)
++{
++ tree arglist = TREE_OPERAND (exp, 1);
++ rtx pat;
++ rtx opcode;
++ rtx operands[1];
++ int i;
++
++
++ /* custom_nX should have exactly two operands */
++ if (insn_data[d->icode].n_operands != 2)
++ abort ();
++
++ opcode = nios2_extract_opcode (d, 0, arglist);
++ for (i = 0; i < 1; i++)
++ {
++ arglist = TREE_CHAIN (arglist);
++ operands[i] = nios2_extract_operand (d, i + 1, i + 1, arglist);
++ }
++
++ pat = GEN_FCN (d->icode) (opcode, operands[0]);
++ if (!pat)
++ return 0;
++ emit_insn (pat);
++ return 0;
++}
++
++static rtx
++nios2_expand_custom_XnX (const struct builtin_description *d, tree exp, rtx target,
++ rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
++ int ignore ATTRIBUTE_UNUSED)
++{
++ tree arglist = TREE_OPERAND (exp, 1);
++ rtx pat;
++ rtx opcode;
++ rtx operands[1];
++ int i;
++
++ /* custom_Xn should have exactly three operands */
++ if (insn_data[d->icode].n_operands != 3)
++ abort ();
++
++ target = nios2_create_target (d, target);
++ opcode = nios2_extract_opcode (d, 1, arglist);
++
++ for (i = 0; i < 1; i++)
++ {
++ arglist = TREE_CHAIN (arglist);
++ operands[i] = nios2_extract_operand (d, i + 2, i + 1, arglist);
++ }
++
++ pat = GEN_FCN (d->icode) (target, opcode, operands[0]);
++
++ if (!pat)
++ return 0;
++ emit_insn (pat);
++ return target;
++}
++
++static rtx
++nios2_expand_custom_nXX (const struct builtin_description *d, tree exp, rtx target ATTRIBUTE_UNUSED,
++ rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
++ int ignore ATTRIBUTE_UNUSED)
++{
++ tree arglist = TREE_OPERAND (exp, 1);
++ rtx pat;
++ rtx opcode;
++ rtx operands[2];
++ int i;
++
++
++ /* custom_nX should have exactly three operands */
++ if (insn_data[d->icode].n_operands != 3)
++ abort ();
++
++ opcode = nios2_extract_opcode (d, 0, arglist);
++ for (i = 0; i < 2; i++)
++ {
++ arglist = TREE_CHAIN (arglist);
++ operands[i] = nios2_extract_operand (d, i + 1, i + 1, arglist);
++ }
++
++ pat = GEN_FCN (d->icode) (opcode, operands[0], operands[1]);
++ if (!pat)
++ return 0;
++ emit_insn (pat);
++ return 0;
++}
++
++static rtx
++nios2_expand_custom_XnXX (const struct builtin_description *d, tree exp, rtx target,
++ rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
++ int ignore ATTRIBUTE_UNUSED)
++{
++ tree arglist = TREE_OPERAND (exp, 1);
++ rtx pat;
++ rtx opcode;
++ rtx operands[2];
++ int i;
++
++
++ /* custom_XnX should have exactly four operands */
++ if (insn_data[d->icode].n_operands != 4)
++ abort ();
++
++ target = nios2_create_target (d, target);
++ opcode = nios2_extract_opcode (d, 1, arglist);
++ for (i = 0; i < 2; i++)
++ {
++ arglist = TREE_CHAIN (arglist);
++ operands[i] = nios2_extract_operand (d, i + 2, i + 1, arglist);
++ }
++
++ pat = GEN_FCN (d->icode) (target, opcode, operands[0], operands[1]);
++
++ if (!pat)
++ return 0;
++ emit_insn (pat);
++ return target;
++}
++
++
++
++static rtx
++nios2_expand_STXIO (const struct builtin_description *d, tree exp, rtx target ATTRIBUTE_UNUSED,
++ rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
++ int ignore ATTRIBUTE_UNUSED)
++{
++ tree arglist = TREE_OPERAND (exp, 1);
++ rtx pat;
++ rtx store_dest, store_val;
++ enum insn_code icode = d->icode;
++
++ /* stores should have exactly two operands */
++ if (insn_data[icode].n_operands != 2)
++ abort ();
++
++ /* process the destination of the store */
++ {
++ enum machine_mode mode = insn_data[icode].operand[0].mode;
++ tree arg = TREE_VALUE (arglist);
++ store_dest = expand_expr (arg, NULL_RTX, VOIDmode, 0);
++ store_dest = protect_from_queue (store_dest, 0);
++
++ store_dest = gen_rtx_MEM (mode, copy_to_mode_reg (Pmode, store_dest));
++
++ /* ??? Better errors would be nice */
++ if (!(*insn_data[icode].operand[0].predicate) (store_dest, mode))
++ error ("Invalid argument 1 to %s", d->name);
++ }
++
++
++ /* process the value to store */
++ {
++ enum machine_mode mode = insn_data[icode].operand[1].mode;
++ tree arg = TREE_VALUE (TREE_CHAIN (arglist));
++ store_val = expand_expr (arg, NULL_RTX, mode, 0);
++ store_val = protect_from_queue (store_val, 0);
++
++ if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
++ store_val = copy_to_mode_reg (mode, store_val);
++
++ /* ??? Better errors would be nice */
++ if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
++ error ("Invalid argument 2 to %s", d->name);
++ }
++
++ pat = GEN_FCN (d->icode) (store_dest, store_val);
++ if (!pat)
++ return 0;
++ emit_insn (pat);
++ return 0;
++}
++
++
++static rtx
++nios2_expand_LDXIO (const struct builtin_description * d, tree exp, rtx target,
++ rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
++ int ignore ATTRIBUTE_UNUSED)
++{
++ tree arglist = TREE_OPERAND (exp, 1);
++ rtx pat;
++ rtx ld_src;
++ enum insn_code icode = d->icode;
++
++ /* loads should have exactly two operands */
++ if (insn_data[icode].n_operands != 2)
++ abort ();
++
++ target = nios2_create_target (d, target);
++
++ {
++ enum machine_mode mode = insn_data[icode].operand[1].mode;
++ tree arg = TREE_VALUE (arglist);
++ ld_src = expand_expr (arg, NULL_RTX, VOIDmode, 0);
++ ld_src = protect_from_queue (ld_src, 0);
++
++ ld_src = gen_rtx_MEM (mode, copy_to_mode_reg (Pmode, ld_src));
++
++ /* ??? Better errors would be nice */
++ if (!(*insn_data[icode].operand[1].predicate) (ld_src, mode))
++ {
++ error ("Invalid argument 1 to %s", d->name);
++ }
++ }
++
++ pat = GEN_FCN (d->icode) (target, ld_src);
++ if (!pat)
++ return 0;
++ emit_insn (pat);
++ return target;
++}
++
++
++static rtx
++nios2_expand_sync (const struct builtin_description * d ATTRIBUTE_UNUSED,
++ tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED,
++ rtx subtarget ATTRIBUTE_UNUSED,
++ enum machine_mode mode ATTRIBUTE_UNUSED,
++ int ignore ATTRIBUTE_UNUSED)
++{
++ emit_insn (gen_sync ());
++ return 0;
++}
++
++static rtx
++nios2_expand_rdctl (const struct builtin_description * d ATTRIBUTE_UNUSED,
++ tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED,
++ rtx subtarget ATTRIBUTE_UNUSED,
++ enum machine_mode mode ATTRIBUTE_UNUSED,
++ int ignore ATTRIBUTE_UNUSED)
++{
++ tree arglist = TREE_OPERAND (exp, 1);
++ rtx pat;
++ rtx rdctl_reg;
++ enum insn_code icode = d->icode;
++
++ /* rdctl should have exactly two operands */
++ if (insn_data[icode].n_operands != 2)
++ abort ();
++
++ target = nios2_create_target (d, target);
++
++ {
++ enum machine_mode mode = insn_data[icode].operand[1].mode;
++ tree arg = TREE_VALUE (arglist);
++ rdctl_reg = expand_expr (arg, NULL_RTX, VOIDmode, 0);
++ rdctl_reg = protect_from_queue (rdctl_reg, 0);
++
++ if (!(*insn_data[icode].operand[1].predicate) (rdctl_reg, mode))
++ {
++ error ("Control register number must be in range 0-31 for %s", d->name);
++ }
++ }
++
++ pat = GEN_FCN (d->icode) (target, rdctl_reg);
++ if (!pat)
++ return 0;
++ emit_insn (pat);
++ return target;
++}
++
++static rtx
++nios2_expand_wrctl (const struct builtin_description * d ATTRIBUTE_UNUSED,
++ tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED,
++ rtx subtarget ATTRIBUTE_UNUSED,
++ enum machine_mode mode ATTRIBUTE_UNUSED,
++ int ignore ATTRIBUTE_UNUSED)
++{
++ tree arglist = TREE_OPERAND (exp, 1);
++ rtx pat;
++ rtx wrctl_reg, store_val;
++ enum insn_code icode = d->icode;
++
++ /* stores should have exactly two operands */
++ if (insn_data[icode].n_operands != 2)
++ abort ();
++
++ /* process the destination of the store */
++ {
++ enum machine_mode mode = insn_data[icode].operand[0].mode;
++ tree arg = TREE_VALUE (arglist);
++ wrctl_reg = expand_expr (arg, NULL_RTX, VOIDmode, 0);
++ wrctl_reg = protect_from_queue (wrctl_reg, 0);
++
++ if (!(*insn_data[icode].operand[0].predicate) (wrctl_reg, mode))
++ error ("Control register number must be in range 0-31 for %s", d->name);
++ }
++
++
++ /* process the value to store */
++ {
++ enum machine_mode mode = insn_data[icode].operand[1].mode;
++ tree arg = TREE_VALUE (TREE_CHAIN (arglist));
++ store_val = expand_expr (arg, NULL_RTX, mode, 0);
++ store_val = protect_from_queue (store_val, 0);
++
++ if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
++ store_val = copy_to_mode_reg (mode, store_val);
++
++ /* ??? Better errors would be nice */
++ if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
++ error ("Invalid argument 2 to %s", d->name);
++ }
++
++ pat = GEN_FCN (d->icode) (wrctl_reg, store_val);
++ if (!pat)
++ return 0;
++ emit_insn (pat);
++ return 0;
++}
++
++
++#include "gt-nios2.h"
++
+--- gcc-3.4.3/gcc/config/nios2/nios2.h
++++ gcc-3.4.3-nios2/gcc/config/nios2/nios2.h
+@@ -0,0 +1,824 @@
++/* Definitions of target machine for Altera NIOS 2G NIOS2 version.
++ Copyright (C) 2003 Altera
++ Contributed by Jonah Graham (jgraham@altera.com).
++
++This file is part of GNU CC.
++
++GNU CC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 2, or (at your option)
++any later version.
++
++GNU CC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GNU CC; see the file COPYING. If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA. */
++
++
++
++#define TARGET_CPU_CPP_BUILTINS() \
++ do \
++ { \
++ builtin_define_std ("NIOS2"); \
++ builtin_define_std ("nios2"); \
++ builtin_define ("_GNU_SOURCE"); \
++ } \
++ while (0)
++#define TARGET_VERSION fprintf (stderr, " (Altera Nios II)")
++
++
++
++
++
++/*********************************
++ * Run-time Target Specification
++ *********************************/
++
++#define HAS_DIV_FLAG 0x0001
++#define HAS_MUL_FLAG 0x0002
++#define HAS_MULX_FLAG 0x0004
++#define FAST_SW_DIV_FLAG 0x0008
++#define INLINE_MEMCPY_FLAG 0x00010
++#define CACHE_VOLATILE_FLAG 0x0020
++#define BYPASS_CACHE_FLAG 0x0040
++
++extern int target_flags;
++#define TARGET_HAS_DIV (target_flags & HAS_DIV_FLAG)
++#define TARGET_HAS_MUL (target_flags & HAS_MUL_FLAG)
++#define TARGET_HAS_MULX (target_flags & HAS_MULX_FLAG)
++#define TARGET_FAST_SW_DIV (target_flags & FAST_SW_DIV_FLAG)
++#define TARGET_INLINE_MEMCPY (target_flags & INLINE_MEMCPY_FLAG)
++#define TARGET_CACHE_VOLATILE (target_flags & CACHE_VOLATILE_FLAG)
++#define TARGET_BYPASS_CACHE (target_flags & BYPASS_CACHE_FLAG)
++
++#define TARGET_SWITCHES \
++{ \
++ { "hw-div", HAS_DIV_FLAG, \
++ N_("Enable DIV, DIVU") }, \
++ { "no-hw-div", -HAS_DIV_FLAG, \
++ N_("Disable DIV, DIVU (default)") }, \
++ { "hw-mul", HAS_MUL_FLAG, \
++ N_("Enable MUL instructions (default)") }, \
++ { "hw-mulx", HAS_MULX_FLAG, \
++ N_("Enable MULX instructions, assume fast shifter") }, \
++ { "no-hw-mul", -HAS_MUL_FLAG, \
++ N_("Disable MUL instructions") }, \
++ { "no-hw-mulx", -HAS_MULX_FLAG, \
++ N_("Disable MULX instructions, assume slow shifter (default and implied by -mno-hw-mul)") }, \
++ { "fast-sw-div", FAST_SW_DIV_FLAG, \
++ N_("Use table based fast divide (default at -O3)") }, \
++ { "no-fast-sw-div", -FAST_SW_DIV_FLAG, \
++ N_("Don't use table based fast divide ever") }, \
++ { "inline-memcpy", INLINE_MEMCPY_FLAG, \
++ N_("Inline small memcpy (default when optimizing)") }, \
++ { "no-inline-memcpy", -INLINE_MEMCPY_FLAG, \
++ N_("Don't Inline small memcpy") }, \
++ { "cache-volatile", CACHE_VOLATILE_FLAG, \
++ N_("Volatile accesses use non-io variants of instructions (default)") }, \
++ { "no-cache-volatile", -CACHE_VOLATILE_FLAG, \
++ N_("Volatile accesses use io variants of instructions") }, \
++ { "bypass-cache", BYPASS_CACHE_FLAG, \
++ N_("All ld/st instructins use io variants") }, \
++ { "no-bypass-cache", -BYPASS_CACHE_FLAG, \
++ N_("All ld/st instructins do not use io variants (default)") }, \
++ { "smallc", 0, \
++ N_("Link with a limited version of the C library") }, \
++ { "ctors-in-init", 0, \
++ "" /* undocumented: N_("Link with static constructors and destructors in init") */ }, \
++ { "", TARGET_DEFAULT, 0 } \
++}
++
++
++extern const char *nios2_sys_nosys_string; /* for -msys=nosys */
++extern const char *nios2_sys_lib_string; /* for -msys-lib= */
++extern const char *nios2_sys_crt0_string; /* for -msys-crt0= */
++
++#define TARGET_OPTIONS \
++{ \
++ { "sys=nosys", &nios2_sys_nosys_string, \
++ N_("Use stub versions of OS library calls (default)"), 0}, \
++ { "sys-lib=", &nios2_sys_lib_string, \
++ N_("Name of System Library to link against. (Converted to a -l option)"), 0}, \
++ { "sys-crt0=", &nios2_sys_crt0_string, \
++ N_("Name of the startfile. (default is a crt0 for the ISS only)"), 0}, \
++}
++
++
++/* Default target_flags if no switches specified. */
++#ifndef TARGET_DEFAULT
++# define TARGET_DEFAULT (HAS_MUL_FLAG | CACHE_VOLATILE_FLAG)
++#endif
++
++/* Switch Recognition by gcc.c. Add -G xx support */
++#undef SWITCH_TAKES_ARG
++#define SWITCH_TAKES_ARG(CHAR) \
++ (DEFAULT_SWITCH_TAKES_ARG (CHAR) || (CHAR) == 'G')
++
++#define OVERRIDE_OPTIONS override_options ()
++#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) optimization_options (LEVEL, SIZE)
++#define CAN_DEBUG_WITHOUT_FP
++
++#define CC1_SPEC "\
++%{G*}"
++
++#undef LIB_SPEC
++#define LIB_SPEC \
++"--start-group %{msmallc: -lsmallc} %{!msmallc: -lc} -lgcc \
++ %{msys-lib=*: -l%*} \
++ %{!msys-lib=*: -lc } \
++ --end-group \
++ %{msys-lib=: %eYou need a library name for -msys-lib=} \
++"
++
++
++#undef STARTFILE_SPEC
++#define STARTFILE_SPEC \
++"%{msys-crt0=*: %*} %{!msys-crt0=*: crt1%O%s} \
++ %{msys-crt0=: %eYou need a C startup file for -msys-crt0=} \
++ %{mctors-in-init: crti%O%s crtbegin%O%s} \
++"
++
++#undef ENDFILE_SPEC
++#define ENDFILE_SPEC \
++ "%{mctors-in-init: crtend%O%s crtn%O%s}"
++
++
++/***********************
++ * Storage Layout
++ ***********************/
++
++#define DEFAULT_SIGNED_CHAR 1
++#define BITS_BIG_ENDIAN 0
++#define BYTES_BIG_ENDIAN 0
++#define WORDS_BIG_ENDIAN 0
++#define BITS_PER_UNIT 8
++#define BITS_PER_WORD 32
++#define UNITS_PER_WORD 4
++#define POINTER_SIZE 32
++#define BIGGEST_ALIGNMENT 32
++#define STRICT_ALIGNMENT 1
++#define FUNCTION_BOUNDARY 32
++#define PARM_BOUNDARY 32
++#define STACK_BOUNDARY 32
++#define PREFERRED_STACK_BOUNDARY 32
++#define MAX_FIXED_MODE_SIZE 64
++
++#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
++ ((TREE_CODE (EXP) == STRING_CST) \
++ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
++
++
++/**********************
++ * Layout of Source Language Data Types
++ **********************/
++
++#define INT_TYPE_SIZE 32
++#define SHORT_TYPE_SIZE 16
++#define LONG_TYPE_SIZE 32
++#define LONG_LONG_TYPE_SIZE 64
++#define FLOAT_TYPE_SIZE 32
++#define DOUBLE_TYPE_SIZE 64
++#define LONG_DOUBLE_TYPE_SIZE DOUBLE_TYPE_SIZE
++
++
++/*************************
++ * Condition Code Status
++ ************************/
++
++/* comparison type */
++/* ??? currently only CMP_SI is used */
++enum cmp_type {
++ CMP_SI, /* compare four byte integers */
++ CMP_DI, /* compare eight byte integers */
++ CMP_SF, /* compare single precision floats */
++ CMP_DF, /* compare double precision floats */
++ CMP_MAX /* max comparison type */
++};
++
++extern GTY(()) rtx branch_cmp[2]; /* operands for compare */
++extern enum cmp_type branch_type; /* what type of branch to use */
++
++/**********************
++ * Register Usage
++ **********************/
++
++/* ---------------------------------- *
++ * Basic Characteristics of Registers
++ * ---------------------------------- */
++
++/*
++Register Number
++ Register Name
++ Alternate Name
++ Purpose
++0 r0 zero always zero
++1 r1 at Assembler Temporary
++2-3 r2-r3 Return Location
++4-7 r4-r7 Register Arguments
++8-15 r8-r15 Caller Saved Registers
++16-22 r16-r22 Callee Saved Registers
++23 r23 sc Static Chain (Callee Saved)
++ ??? Does $sc want to be caller or callee
++ saved. If caller, 15, else 23.
++24 r24 Exception Temporary
++25 r25 Breakpoint Temporary
++26 r26 gp Global Pointer
++27 r27 sp Stack Pointer
++28 r28 fp Frame Pointer
++29 r29 ea Exception Return Address
++30 r30 ba Breakpoint Return Address
++31 r31 ra Return Address
++
++32 ctl0 status
++33 ctl1 estatus STATUS saved by exception ?
++34 ctl2 bstatus STATUS saved by break ?
++35 ctl3 ipri Interrupt Priority Mask ?
++36 ctl4 ecause Exception Cause ?
++
++37 pc Not an actual register
++
++38 rap Return address pointer, this does not
++ actually exist and will be eliminated
++
++39 fake_fp Fake Frame Pointer which will always be eliminated.
++40 fake_ap Fake Argument Pointer which will always be eliminated.
++
++41 First Pseudo Register
++
++
++The definitions for all the hard register numbers
++are located in nios2.md.
++*/
++
++#define FIRST_PSEUDO_REGISTER 41
++#define NUM_ARG_REGS (LAST_ARG_REGNO - FIRST_ARG_REGNO + 1)
++
++
++
++/* also see CONDITIONAL_REGISTER_USAGE */
++#define FIXED_REGISTERS \
++ { \
++/* +0 1 2 3 4 5 6 7 8 9 */ \
++/* 0 */ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, \
++/* 10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
++/* 20 */ 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \
++/* 30 */ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \
++/* 40 */ 1, \
++ }
++
++/* call used is the same as caller saved
++ + fixed regs + args + ret vals */
++#define CALL_USED_REGISTERS \
++ { \
++/* +0 1 2 3 4 5 6 7 8 9 */ \
++/* 0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
++/* 10 */ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, \
++/* 20 */ 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \
++/* 30 */ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \
++/* 40 */ 1, \
++ }
++
++#define HARD_REGNO_NREGS(REGNO, MODE) \
++ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
++ / UNITS_PER_WORD)
++
++/* --------------------------- *
++ * How Values Fit in Registers
++ * --------------------------- */
++
++#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
++
++#define MODES_TIEABLE_P(MODE1, MODE2) 1
++
++
++/*************************
++ * Register Classes
++ *************************/
++
++enum reg_class
++{
++ NO_REGS,
++ ALL_REGS,
++ LIM_REG_CLASSES
++};
++
++#define N_REG_CLASSES (int) LIM_REG_CLASSES
++
++#define REG_CLASS_NAMES \
++ {"NO_REGS", \
++ "ALL_REGS"}
++
++#define GENERAL_REGS ALL_REGS
++
++#define REG_CLASS_CONTENTS \
++/* NO_REGS */ {{ 0, 0}, \
++/* ALL_REGS */ {~0,~0}} \
++
++#define REGNO_REG_CLASS(REGNO) ALL_REGS
++
++#define BASE_REG_CLASS ALL_REGS
++#define INDEX_REG_CLASS ALL_REGS
++
++/* only one reg class, 'r', is handled automatically */
++#define REG_CLASS_FROM_LETTER(CHAR) NO_REGS
++
++#define REGNO_OK_FOR_BASE_P2(REGNO, STRICT) \
++ ((STRICT) \
++ ? (REGNO) < FIRST_PSEUDO_REGISTER \
++ : (REGNO) < FIRST_PSEUDO_REGISTER || (reg_renumber && reg_renumber[REGNO] < FIRST_PSEUDO_REGISTER))
++
++#define REGNO_OK_FOR_INDEX_P2(REGNO, STRICT) \
++ (REGNO_OK_FOR_BASE_P2 (REGNO, STRICT))
++
++#define REGNO_OK_FOR_BASE_P(REGNO) \
++ (REGNO_OK_FOR_BASE_P2 (REGNO, 1))
++
++#define REGNO_OK_FOR_INDEX_P(REGNO) \
++ (REGNO_OK_FOR_INDEX_P2 (REGNO, 1))
++
++#define REG_OK_FOR_BASE_P2(X, STRICT) \
++ (STRICT \
++ ? REGNO_OK_FOR_BASE_P2 (REGNO (X), 1) \
++ : REGNO_OK_FOR_BASE_P2 (REGNO (X), 1) || REGNO(X) >= FIRST_PSEUDO_REGISTER)
++
++#define REG_OK_FOR_INDEX_P2(X, STRICT) \
++ (STRICT \
++ ? REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1) \
++ : REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1) || REGNO(X) >= FIRST_PSEUDO_REGISTER)
++
++#define CLASS_MAX_NREGS(CLASS, MODE) \
++ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
++ / UNITS_PER_WORD)
++
++
++#define SMALL_INT(X) ((unsigned HOST_WIDE_INT) ((X) + 0x8000) < 0x10000)
++#define SMALL_INT_UNSIGNED(X) ((unsigned HOST_WIDE_INT) (X) < 0x10000)
++#define UPPER16_INT(X) (((X) & 0xffff) == 0)
++#define SHIFT_INT(X) ((X) >= 0 && (X) <= 31)
++#define RDWRCTL_INT(X) ((X) >= 0 && (X) <= 31)
++#define CUSTOM_INSN_OPCODE(X) ((X) >= 0 && (X) <= 255)
++
++#define CONST_OK_FOR_LETTER_P(VALUE, C) \
++ ( \
++ (C) == 'I' ? SMALL_INT (VALUE) : \
++ (C) == 'J' ? SMALL_INT_UNSIGNED (VALUE) : \
++ (C) == 'K' ? UPPER16_INT (VALUE) : \
++ (C) == 'L' ? SHIFT_INT (VALUE) : \
++ (C) == 'M' ? (VALUE) == 0 : \
++ (C) == 'N' ? CUSTOM_INSN_OPCODE (VALUE) : \
++ (C) == 'O' ? RDWRCTL_INT (VALUE) : \
++ 0)
++
++#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0
++
++#define PREFERRED_RELOAD_CLASS(X, CLASS) \
++ ((CLASS) == NO_REGS ? GENERAL_REGS : (CLASS))
++
++/* 'S' matches immediates which are in small data
++ and therefore can be added to gp to create a
++ 32-bit value. */
++#define EXTRA_CONSTRAINT(VALUE, C) \
++ ((C) == 'S' \
++ && (GET_CODE (VALUE) == SYMBOL_REF) \
++ && SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (VALUE))
++
++
++
++
++/* Say that the epilogue uses the return address register. Note that
++ in the case of sibcalls, the values "used by the epilogue" are
++ considered live at the start of the called function. */
++#define EPILOGUE_USES(REGNO) ((REGNO) == RA_REGNO)
++
++
++#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node)
++
++/**********************************
++ * Trampolines for Nested Functions
++ ***********************************/
++
++#define TRAMPOLINE_TEMPLATE(FILE) \
++ error ("trampolines not yet implemented")
++#define TRAMPOLINE_SIZE 20
++#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
++ error ("trampolines not yet implemented")
++
++/***************************
++ * Stack Layout and Calling Conventions
++ ***************************/
++
++/* ------------------ *
++ * Basic Stack Layout
++ * ------------------ */
++
++/* The downward variants are used by the compiler,
++ the upward ones serve as documentation */
++#define STACK_GROWS_DOWNWARD
++#define FRAME_GROWS_UPWARD
++#define ARGS_GROW_UPWARD
++
++#define STARTING_FRAME_OFFSET current_function_outgoing_args_size
++#define FIRST_PARM_OFFSET(FUNDECL) 0
++
++/* Before the prologue, RA lives in r31. */
++#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (VOIDmode, RA_REGNO)
++
++/* -------------------------------------- *
++ * Registers That Address the Stack Frame
++ * -------------------------------------- */
++
++#define STACK_POINTER_REGNUM SP_REGNO
++#define STATIC_CHAIN_REGNUM SC_REGNO
++#define PC_REGNUM PC_REGNO
++#define DWARF_FRAME_RETURN_COLUMN RA_REGNO
++
++/* Base register for access to local variables of the function. We
++ pretend that the frame pointer is a non-existent hard register, and
++ then eliminate it to HARD_FRAME_POINTER_REGNUM. */
++#define FRAME_POINTER_REGNUM FAKE_FP_REGNO
++
++#define HARD_FRAME_POINTER_REGNUM FP_REGNO
++#define RETURN_ADDRESS_POINTER_REGNUM RAP_REGNO
++/* the argumnet pointer needs to always be eliminated
++ so it is set to a fake hard register. */
++#define ARG_POINTER_REGNUM FAKE_AP_REGNO
++
++/* ----------------------------------------- *
++ * Eliminating Frame Pointer and Arg Pointer
++ * ----------------------------------------- */
++
++#define FRAME_POINTER_REQUIRED 0
++
++#define ELIMINABLE_REGS \
++{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
++ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
++ { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
++ { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
++ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
++ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
++
++#define CAN_ELIMINATE(FROM, TO) 1
++
++#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
++ (OFFSET) = nios2_initial_elimination_offset ((FROM), (TO))
++
++#define MUST_SAVE_REGISTER(regno) \
++ ((regs_ever_live[regno] && !call_used_regs[regno]) \
++ || (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) \
++ || (regno == RA_REGNO && regs_ever_live[RA_REGNO]))
++
++/* Treat LOC as a byte offset from the stack pointer and round it up
++ to the next fully-aligned offset. */
++#define STACK_ALIGN(LOC) \
++ (((LOC) + ((PREFERRED_STACK_BOUNDARY / 8) - 1)) & ~((PREFERRED_STACK_BOUNDARY / 8) - 1))
++
++
++/* ------------------------------ *
++ * Passing Arguments in Registers
++ * ------------------------------ */
++
++/* see nios2.c */
++#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
++ (function_arg (&CUM, MODE, TYPE, NAMED))
++
++#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
++ (function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED))
++
++#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) 0
++
++#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 0
++
++typedef struct nios2_args
++{
++ int regs_used;
++} CUMULATIVE_ARGS;
++
++/* This is to initialize the above unused CUM data type */
++#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
++ (init_cumulative_args (&CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS))
++
++#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
++ (function_arg_advance (&CUM, MODE, TYPE, NAMED))
++
++#define FUNCTION_ARG_REGNO_P(REGNO) \
++ ((REGNO) >= FIRST_ARG_REGNO && (REGNO) <= LAST_ARG_REGNO)
++
++#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
++ { \
++ int pret_size = nios2_setup_incoming_varargs (&(CUM), (MODE), \
++ (TYPE), (NO_RTL)); \
++ if (pret_size) \
++ (PRETEND_SIZE) = pret_size; \
++ }
++
++/* ----------------------------- *
++ * Generating Code for Profiling
++ * ----------------------------- */
++
++#define PROFILE_BEFORE_PROLOGUE
++
++#define FUNCTION_PROFILER(FILE, LABELNO) \
++ function_profiler ((FILE), (LABELNO))
++
++/* --------------------------------------- *
++ * Passing Function Arguments on the Stack
++ * --------------------------------------- */
++
++#define PROMOTE_PROTOTYPES 1
++
++#define PUSH_ARGS 0
++#define ACCUMULATE_OUTGOING_ARGS 1
++
++#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACKSIZE) 0
++
++/* --------------------------------------- *
++ * How Scalar Function Values Are Returned
++ * --------------------------------------- */
++
++#define FUNCTION_VALUE(VALTYPE, FUNC) \
++ gen_rtx(REG, TYPE_MODE(VALTYPE), FIRST_RETVAL_REGNO)
++
++#define LIBCALL_VALUE(MODE) \
++ gen_rtx(REG, MODE, FIRST_RETVAL_REGNO)
++
++#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == FIRST_RETVAL_REGNO)
++
++/* ----------------------------- *
++ * How Large Values Are Returned
++ * ----------------------------- */
++
++
++#define RETURN_IN_MEMORY(TYPE) \
++ nios2_return_in_memory (TYPE)
++
++
++#define STRUCT_VALUE 0
++
++#define DEFAULT_PCC_STRUCT_RETURN 0
++
++/*******************
++ * Addressing Modes
++ *******************/
++
++
++#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)
++
++#define CONSTANT_ADDRESS_P(X) (CONSTANT_P (X))
++
++#define MAX_REGS_PER_ADDRESS 1
++
++/* Go to ADDR if X is a valid address. */
++#ifndef REG_OK_STRICT
++#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
++ { \
++ if (nios2_legitimate_address ((X), (MODE), 0)) \
++ goto ADDR; \
++ }
++#else
++#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
++ { \
++ if (nios2_legitimate_address ((X), (MODE), 1)) \
++ goto ADDR; \
++ }
++#endif
++
++#ifndef REG_OK_STRICT
++#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P2 (REGNO (X), 0)
++#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P2 (REGNO (X), 0)
++#else
++#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P2 (REGNO (X), 1)
++#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1)
++#endif
++
++#define LEGITIMATE_CONSTANT_P(X) 1
++
++/* Nios II has no mode dependent addresses. */
++#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
++
++/* Set if this has a weak declaration */
++#define SYMBOL_FLAG_WEAK_DECL (1 << SYMBOL_FLAG_MACH_DEP_SHIFT)
++#define SYMBOL_REF_WEAK_DECL_P(RTX) \
++ ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_WEAK_DECL) != 0)
++
++
++/* true if a symbol is both small and not weak. In this case, gp
++ relative access can be used */
++#define SYMBOL_REF_IN_NIOS2_SMALL_DATA_P(RTX) \
++ (SYMBOL_REF_SMALL_P(RTX) && !SYMBOL_REF_WEAK_DECL_P(RTX))
++
++/*****************
++ * Describing Relative Costs of Operations
++ *****************/
++
++#define SLOW_BYTE_ACCESS 1
++
++/* It is as good to call a constant function address as to call an address
++ kept in a register.
++ ??? Not true anymore really. Now that call cannot address full range
++ of memory callr may need to be used */
++
++#define NO_FUNCTION_CSE
++#define NO_RECURSIVE_FUNCTION_CSE
++
++
++
++/*****************************************
++ * Defining the Output Assembler Language
++ *****************************************/
++
++/* ------------------------------------------ *
++ * The Overall Framework of an Assembler File
++ * ------------------------------------------ */
++
++#define ASM_APP_ON "#APP\n"
++#define ASM_APP_OFF "#NO_APP\n"
++
++#define ASM_COMMENT_START "# "
++
++/* ------------------------------- *
++ * Output and Generation of Labels
++ * ------------------------------- */
++
++#define GLOBAL_ASM_OP "\t.global\t"
++
++
++/* -------------- *
++ * Output of Data
++ * -------------- */
++
++#define DWARF2_UNWIND_INFO 0
++
++
++/* -------------------------------- *
++ * Assembler Commands for Alignment
++ * -------------------------------- */
++
++#define ASM_OUTPUT_ALIGN(FILE, LOG) \
++ do { \
++ fprintf ((FILE), "%s%d\n", ALIGN_ASM_OP, (LOG)); \
++ } while (0)
++
++
++/* -------------------------------- *
++ * Output of Assembler Instructions
++ * -------------------------------- */
++
++#define REGISTER_NAMES \
++{ \
++ "zero", \
++ "at", \
++ "r2", \
++ "r3", \
++ "r4", \
++ "r5", \
++ "r6", \
++ "r7", \
++ "r8", \
++ "r9", \
++ "r10", \
++ "r11", \
++ "r12", \
++ "r13", \
++ "r14", \
++ "r15", \
++ "r16", \
++ "r17", \
++ "r18", \
++ "r19", \
++ "r20", \
++ "r21", \
++ "r22", \
++ "r23", \
++ "r24", \
++ "r25", \
++ "gp", \
++ "sp", \
++ "fp", \
++ "ta", \
++ "ba", \
++ "ra", \
++ "status", \
++ "estatus", \
++ "bstatus", \
++ "ipri", \
++ "ecause", \
++ "pc", \
++ "rap", \
++ "fake_fp", \
++ "fake_ap", \
++}
++
++#define ASM_OUTPUT_OPCODE(STREAM, PTR)\
++ (PTR) = asm_output_opcode (STREAM, PTR)
++
++#define PRINT_OPERAND(STREAM, X, CODE) \
++ nios2_print_operand (STREAM, X, CODE)
++
++#define PRINT_OPERAND_ADDRESS(STREAM, X) \
++ nios2_print_operand_address (STREAM, X)
++
++#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
++do { fputs (integer_asm_op (POINTER_SIZE / BITS_PER_UNIT, TRUE), FILE); \
++ fprintf (FILE, ".L%u\n", (unsigned) (VALUE)); \
++ } while (0)
++
++
++/* ------------ *
++ * Label Output
++ * ------------ */
++
++
++/* ---------------------------------------------------- *
++ * Dividing the Output into Sections (Texts, Data, ...)
++ * ---------------------------------------------------- */
++
++/* Output before read-only data. */
++#define TEXT_SECTION_ASM_OP ("\t.section\t.text")
++
++/* Output before writable data. */
++#define DATA_SECTION_ASM_OP ("\t.section\t.data")
++
++
++/* Default the definition of "small data" to 8 bytes. */
++/* ??? How come I can't use HOST_WIDE_INT here? */
++extern unsigned long nios2_section_threshold;
++#define NIOS2_DEFAULT_GVALUE 8
++
++
++
++/* This says how to output assembler code to declare an
++ uninitialized external linkage data object. Under SVR4,
++ the linker seems to want the alignment of data objects
++ to depend on their types. We do exactly that here. */
++
++#undef COMMON_ASM_OP
++#define COMMON_ASM_OP "\t.comm\t"
++
++#undef ASM_OUTPUT_ALIGNED_COMMON
++#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
++do \
++{ \
++ if ((SIZE) <= nios2_section_threshold) \
++ { \
++ named_section (0, ".sbss", 0); \
++ (*targetm.asm_out.globalize_label) (FILE, NAME); \
++ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
++ if (!flag_inhibit_size_directive) \
++ ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE); \
++ ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT)); \
++ ASM_OUTPUT_LABEL(FILE, NAME); \
++ ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1); \
++ } \
++ else \
++ { \
++ fprintf ((FILE), "%s", COMMON_ASM_OP); \
++ assemble_name ((FILE), (NAME)); \
++ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
++ } \
++} \
++while (0)
++
++
++/* This says how to output assembler code to declare an
++ uninitialized internal linkage data object. Under SVR4,
++ the linker seems to want the alignment of data objects
++ to depend on their types. We do exactly that here. */
++
++#undef ASM_OUTPUT_ALIGNED_LOCAL
++#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
++do { \
++ if ((SIZE) <= nios2_section_threshold) \
++ named_section (0, ".sbss", 0); \
++ else \
++ named_section (0, ".bss", 0); \
++ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
++ if (!flag_inhibit_size_directive) \
++ ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE); \
++ ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT)); \
++ ASM_OUTPUT_LABEL(FILE, NAME); \
++ ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1); \
++} while (0)
++
++
++
++/***************************
++ * Miscellaneous Parameters
++ ***************************/
++
++#define MOVE_MAX 4
++
++#define Pmode SImode
++#define FUNCTION_MODE QImode
++
++#define CASE_VECTOR_MODE Pmode
++
++#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
++
++#define LOAD_EXTEND_OP(MODE) (ZERO_EXTEND)
++
++#define WORD_REGISTER_OPERATIONS
+--- gcc-3.4.3/gcc/config/nios2/nios2.md
++++ gcc-3.4.3-nios2/gcc/config/nios2/nios2.md
+@@ -0,0 +1,2078 @@
++;; Machine Description for Altera NIOS 2G NIOS2 version.
++;; Copyright (C) 2003 Altera
++;; Contributed by Jonah Graham (jgraham@altera.com).
++;;
++;; This file is part of GNU CC.
++;;
++;; GNU CC is free software; you can redistribute it and/or modify
++;; it under the terms of the GNU General Public License as published by
++;; the Free Software Foundation; either version 2, or (at your option)
++;; any later version.
++;;
++;; GNU CC is distributed in the hope that it will be useful,
++;; but WITHOUT ANY WARRANTY; without even the implied warranty of
++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++;; GNU General Public License for more details.
++;;
++;; You should have received a copy of the GNU General Public License
++;; along with GNU CC; see the file COPYING. If not, write to
++;; the Free Software Foundation, 59 Temple Place - Suite 330,
++;; Boston, MA 02111-1307, USA. */
++
++
++
++;*****************************************************************************
++;*
++;* constants
++;*
++;*****************************************************************************
++(define_constants [
++ (GP_REGNO 26)
++ (SP_REGNO 27)
++ (FP_REGNO 28)
++ (RA_REGNO 31)
++ (RAP_REGNO 38)
++ (FIRST_RETVAL_REGNO 2)
++ (LAST_RETVAL_REGNO 3)
++ (FIRST_ARG_REGNO 4)
++ (LAST_ARG_REGNO 7)
++ (SC_REGNO 23)
++ (PC_REGNO 37)
++ (FAKE_FP_REGNO 39)
++ (FAKE_AP_REGNO 40)
++
++
++ (UNSPEC_BLOCKAGE 0)
++ (UNSPEC_LDBIO 1)
++ (UNSPEC_LDBUIO 2)
++ (UNSPEC_LDHIO 3)
++ (UNSPEC_LDHUIO 4)
++ (UNSPEC_LDWIO 5)
++ (UNSPEC_STBIO 6)
++ (UNSPEC_STHIO 7)
++ (UNSPEC_STWIO 8)
++ (UNSPEC_SYNC 9)
++ (UNSPEC_WRCTL 10)
++ (UNSPEC_RDCTL 11)
++
++])
++
++
++
++;*****************************************************************************
++;*
++;* instruction scheduler
++;*
++;*****************************************************************************
++
++; No schedule info is currently available, using an assumption that no
++; instruction can use the results of the previous instruction without
++; incuring a stall.
++
++; length of an instruction (in bytes)
++(define_attr "length" "" (const_int 4))
++(define_attr "type" "unknown,complex,control,alu,cond_alu,st,ld,shift,mul,div,custom" (const_string "complex"))
++
++(define_asm_attributes
++ [(set_attr "length" "4")
++ (set_attr "type" "complex")])
++
++(define_automaton "nios2")
++(automata_option "v")
++;(automata_option "no-minimization")
++(automata_option "ndfa")
++
++; The nios2 pipeline is fairly straightforward for the fast model.
++; Every alu operation is pipelined so that an instruction can
++; be issued every cycle. However, there are still potential
++; stalls which this description tries to deal with.
++
++(define_cpu_unit "cpu" "nios2")
++
++(define_insn_reservation "complex" 1
++ (eq_attr "type" "complex")
++ "cpu")
++
++(define_insn_reservation "control" 1
++ (eq_attr "type" "control")
++ "cpu")
++
++(define_insn_reservation "alu" 1
++ (eq_attr "type" "alu")
++ "cpu")
++
++(define_insn_reservation "cond_alu" 1
++ (eq_attr "type" "cond_alu")
++ "cpu")
++
++(define_insn_reservation "st" 1
++ (eq_attr "type" "st")
++ "cpu")
++
++(define_insn_reservation "custom" 1
++ (eq_attr "type" "custom")
++ "cpu")
++
++; shifts, muls and lds have three cycle latency
++(define_insn_reservation "ld" 3
++ (eq_attr "type" "ld")
++ "cpu")
++
++(define_insn_reservation "shift" 3
++ (eq_attr "type" "shift")
++ "cpu")
++
++(define_insn_reservation "mul" 3
++ (eq_attr "type" "mul")
++ "cpu")
++
++(define_insn_reservation "div" 1
++ (eq_attr "type" "div")
++ "cpu")
++
++
++;*****************************************************************************
++;*
++;* MOV Instructions
++;*
++;*****************************************************************************
++
++(define_expand "movqi"
++ [(set (match_operand:QI 0 "nonimmediate_operand" "")
++ (match_operand:QI 1 "general_operand" ""))]
++ ""
++{
++ if (nios2_emit_move_sequence (operands, QImode))
++ DONE;
++})
++
++(define_insn "movqi_internal"
++ [(set (match_operand:QI 0 "nonimmediate_operand" "=m, r,r, r")
++ (match_operand:QI 1 "general_operand" "rM,m,rM,I"))]
++ "(register_operand (operands[0], QImode)
++ || register_operand (operands[1], QImode)
++ || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
++ "@
++ stb%o0\\t%z1, %0
++ ldbu%o1\\t%0, %1
++ mov\\t%0, %z1
++ movi\\t%0, %1"
++ [(set_attr "type" "st,ld,alu,alu")])
++
++(define_insn "ldbio"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(const_int 0)] UNSPEC_LDBIO))
++ (use (match_operand:SI 1 "memory_operand" "m"))]
++ ""
++ "ldbio\\t%0, %1"
++ [(set_attr "type" "ld")])
++
++(define_insn "ldbuio"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(const_int 0)] UNSPEC_LDBUIO))
++ (use (match_operand:SI 1 "memory_operand" "m"))]
++ ""
++ "ldbuio\\t%0, %1"
++ [(set_attr "type" "ld")])
++
++(define_insn "stbio"
++ [(set (match_operand:SI 0 "memory_operand" "=m")
++ (match_operand:SI 1 "register_operand" "r"))
++ (unspec_volatile:SI [(const_int 0)] UNSPEC_STBIO)]
++ ""
++ "stbio\\t%z1, %0"
++ [(set_attr "type" "st")])
++
++
++(define_expand "movhi"
++ [(set (match_operand:HI 0 "nonimmediate_operand" "")
++ (match_operand:HI 1 "general_operand" ""))]
++ ""
++{
++ if (nios2_emit_move_sequence (operands, HImode))
++ DONE;
++})
++
++(define_insn "movhi_internal"
++ [(set (match_operand:HI 0 "nonimmediate_operand" "=m, r,r, r,r")
++ (match_operand:HI 1 "general_operand" "rM,m,rM,I,J"))]
++ "(register_operand (operands[0], HImode)
++ || register_operand (operands[1], HImode)
++ || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
++ "@
++ sth%o0\\t%z1, %0
++ ldhu%o1\\t%0, %1
++ mov\\t%0, %z1
++ movi\\t%0, %1
++ movui\\t%0, %1"
++ [(set_attr "type" "st,ld,alu,alu,alu")])
++
++(define_insn "ldhio"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(const_int 0)] UNSPEC_LDHIO))
++ (use (match_operand:SI 1 "memory_operand" "m"))]
++ ""
++ "ldhio\\t%0, %1"
++ [(set_attr "type" "ld")])
++
++(define_insn "ldhuio"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(const_int 0)] UNSPEC_LDHUIO))
++ (use (match_operand:SI 1 "memory_operand" "m"))]
++ ""
++ "ldhuio\\t%0, %1"
++ [(set_attr "type" "ld")])
++
++(define_insn "sthio"
++ [(set (match_operand:SI 0 "memory_operand" "=m")
++ (match_operand:SI 1 "register_operand" "r"))
++ (unspec_volatile:SI [(const_int 0)] UNSPEC_STHIO)]
++ ""
++ "sthio\\t%z1, %0"
++ [(set_attr "type" "st")])
++
++(define_expand "movsi"
++ [(set (match_operand:SI 0 "nonimmediate_operand" "")
++ (match_operand:SI 1 "general_operand" ""))]
++ ""
++{
++ if (nios2_emit_move_sequence (operands, SImode))
++ DONE;
++})
++
++(define_insn "movsi_internal"
++ [(set (match_operand:SI 0 "nonimmediate_operand" "=m, r,r, r,r,r,r")
++ (match_operand:SI 1 "general_operand" "rM,m,rM,I,J,S,i"))]
++ "(register_operand (operands[0], SImode)
++ || register_operand (operands[1], SImode)
++ || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
++ "@
++ stw%o0\\t%z1, %0
++ ldw%o1\\t%0, %1
++ mov\\t%0, %z1
++ movi\\t%0, %1
++ movui\\t%0, %1
++ addi\\t%0, gp, %%gprel(%1)
++ movhi\\t%0, %H1\;addi\\t%0, %0, %L1"
++ [(set_attr "type" "st,ld,alu,alu,alu,alu,alu")])
++
++(define_insn "ldwio"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(const_int 0)] UNSPEC_LDWIO))
++ (use (match_operand:SI 1 "memory_operand" "m"))]
++ ""
++ "ldwio\\t%0, %1"
++ [(set_attr "type" "ld")])
++
++(define_insn "stwio"
++ [(set (match_operand:SI 0 "memory_operand" "=m")
++ (match_operand:SI 1 "register_operand" "r"))
++ (unspec_volatile:SI [(const_int 0)] UNSPEC_STWIO)]
++ ""
++ "stwio\\t%z1, %0"
++ [(set_attr "type" "st")])
++
++
++
++;*****************************************************************************
++;*
++;* zero extension
++;*
++;*****************************************************************************
++
++
++(define_insn "zero_extendhisi2"
++ [(set (match_operand:SI 0 "register_operand" "=r,r")
++ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
++ ""
++ "@
++ andi\\t%0, %1, 0xffff
++ ldhu%o1\\t%0, %1"
++ [(set_attr "type" "alu,ld")])
++
++(define_insn "zero_extendqihi2"
++ [(set (match_operand:HI 0 "register_operand" "=r,r")
++ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
++ ""
++ "@
++ andi\\t%0, %1, 0xff
++ ldbu%o1\\t%0, %1"
++ [(set_attr "type" "alu,ld")])
++
++(define_insn "zero_extendqisi2"
++ [(set (match_operand:SI 0 "register_operand" "=r,r")
++ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
++ ""
++ "@
++ andi\\t%0, %1, 0xff
++ ldbu%o1\\t%0, %1"
++ [(set_attr "type" "alu,ld")])
++
++
++
++;*****************************************************************************
++;*
++;* sign extension
++;*
++;*****************************************************************************
++
++(define_expand "extendhisi2"
++ [(set (match_operand:SI 0 "register_operand" "")
++ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
++ ""
++{
++ if (optimize && GET_CODE (operands[1]) == MEM)
++ operands[1] = force_not_mem (operands[1]);
++
++ if (GET_CODE (operands[1]) != MEM)
++ {
++ rtx op1 = gen_lowpart (SImode, operands[1]);
++ rtx temp = gen_reg_rtx (SImode);
++ rtx shift = GEN_INT (16);
++
++ emit_insn (gen_ashlsi3 (temp, op1, shift));
++ emit_insn (gen_ashrsi3 (operands[0], temp, shift));
++ DONE;
++ }
++})
++
++(define_insn "extendhisi2_internal"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
++ ""
++ "ldh%o1\\t%0, %1"
++ [(set_attr "type" "ld")])
++
++(define_expand "extendqihi2"
++ [(set (match_operand:HI 0 "register_operand" "")
++ (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
++ ""
++{
++ if (optimize && GET_CODE (operands[1]) == MEM)
++ operands[1] = force_not_mem (operands[1]);
++
++ if (GET_CODE (operands[1]) != MEM)
++ {
++ rtx op0 = gen_lowpart (SImode, operands[0]);
++ rtx op1 = gen_lowpart (SImode, operands[1]);
++ rtx temp = gen_reg_rtx (SImode);
++ rtx shift = GEN_INT (24);
++
++ emit_insn (gen_ashlsi3 (temp, op1, shift));
++ emit_insn (gen_ashrsi3 (op0, temp, shift));
++ DONE;
++ }
++})
++
++(define_insn "extendqihi2_internal"
++ [(set (match_operand:HI 0 "register_operand" "=r")
++ (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
++ ""
++ "ldb%o1\\t%0, %1"
++ [(set_attr "type" "ld")])
++
++
++(define_expand "extendqisi2"
++ [(set (match_operand:SI 0 "register_operand" "")
++ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
++ ""
++{
++ if (optimize && GET_CODE (operands[1]) == MEM)
++ operands[1] = force_not_mem (operands[1]);
++
++ if (GET_CODE (operands[1]) != MEM)
++ {
++ rtx op1 = gen_lowpart (SImode, operands[1]);
++ rtx temp = gen_reg_rtx (SImode);
++ rtx shift = GEN_INT (24);
++
++ emit_insn (gen_ashlsi3 (temp, op1, shift));
++ emit_insn (gen_ashrsi3 (operands[0], temp, shift));
++ DONE;
++ }
++})
++
++(define_insn "extendqisi2_insn"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
++ ""
++ "ldb%o1\\t%0, %1"
++ [(set_attr "type" "ld")])
++
++
++
++;*****************************************************************************
++;*
++;* Arithmetic Operations
++;*
++;*****************************************************************************
++
++(define_insn "addsi3"
++ [(set (match_operand:SI 0 "register_operand" "=r,r")
++ (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
++ (match_operand:SI 2 "arith_operand" "r,I")))]
++ ""
++ "add%i2\\t%0, %1, %z2"
++ [(set_attr "type" "alu")])
++
++(define_insn "subsi3"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
++ (match_operand:SI 2 "register_operand" "r")))]
++ ""
++ "sub\\t%0, %z1, %2"
++ [(set_attr "type" "alu")])
++
++(define_insn "mulsi3"
++ [(set (match_operand:SI 0 "register_operand" "=r,r")
++ (mult:SI (match_operand:SI 1 "register_operand" "r,r")
++ (match_operand:SI 2 "arith_operand" "r,I")))]
++ "TARGET_HAS_MUL"
++ "mul%i2\\t%0, %1, %z2"
++ [(set_attr "type" "mul")])
++
++(define_expand "divsi3"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (div:SI (match_operand:SI 1 "register_operand" "r")
++ (match_operand:SI 2 "register_operand" "r")))]
++ ""
++{
++ if (!TARGET_HAS_DIV)
++ {
++ if (!TARGET_FAST_SW_DIV)
++ FAIL;
++ else
++ {
++ if (nios2_emit_expensive_div (operands, SImode))
++ DONE;
++ }
++ }
++})
++
++(define_insn "divsi3_insn"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (div:SI (match_operand:SI 1 "register_operand" "r")
++ (match_operand:SI 2 "register_operand" "r")))]
++ "TARGET_HAS_DIV"
++ "div\\t%0, %1, %2"
++ [(set_attr "type" "div")])
++
++(define_insn "udivsi3"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (udiv:SI (match_operand:SI 1 "register_operand" "r")
++ (match_operand:SI 2 "register_operand" "r")))]
++ "TARGET_HAS_DIV"
++ "divu\\t%0, %1, %2"
++ [(set_attr "type" "div")])
++
++(define_insn "smulsi3_highpart"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (truncate:SI
++ (lshiftrt:DI
++ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
++ (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
++ (const_int 32))))]
++ "TARGET_HAS_MULX"
++ "mulxss\\t%0, %1, %2"
++ [(set_attr "type" "mul")])
++
++(define_insn "umulsi3_highpart"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (truncate:SI
++ (lshiftrt:DI
++ (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
++ (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
++ (const_int 32))))]
++ "TARGET_HAS_MULX"
++ "mulxuu\\t%0, %1, %2"
++ [(set_attr "type" "mul")])
++
++
++(define_expand "mulsidi3"
++ [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 0)
++ (mult:SI (match_operand:SI 1 "register_operand" "")
++ (match_operand:SI 2 "register_operand" "")))
++ (set (subreg:SI (match_dup 0) 4)
++ (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
++ (sign_extend:DI (match_dup 2)))
++ (const_int 32))))]
++ "TARGET_HAS_MULX"
++ "")
++
++(define_expand "umulsidi3"
++ [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 0)
++ (mult:SI (match_operand:SI 1 "register_operand" "")
++ (match_operand:SI 2 "register_operand" "")))
++ (set (subreg:SI (match_dup 0) 4)
++ (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
++ (zero_extend:DI (match_dup 2)))
++ (const_int 32))))]
++ "TARGET_HAS_MULX"
++ "")
++
++
++
++;*****************************************************************************
++;*
++;* Negate and ones complement
++;*
++;*****************************************************************************
++
++(define_insn "negsi2"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (neg:SI (match_operand:SI 1 "register_operand" "r")))]
++ ""
++{
++ operands[2] = const0_rtx;
++ return "sub\\t%0, %z2, %1";
++}
++ [(set_attr "type" "alu")])
++
++(define_insn "one_cmplsi2"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (not:SI (match_operand:SI 1 "register_operand" "r")))]
++ ""
++{
++ operands[2] = const0_rtx;
++ return "nor\\t%0, %z2, %1";
++}
++ [(set_attr "type" "alu")])
++
++
++
++; Logical Operantions
++
++(define_insn "andsi3"
++ [(set (match_operand:SI 0 "register_operand" "=r, r,r")
++ (and:SI (match_operand:SI 1 "register_operand" "%r, r,r")
++ (match_operand:SI 2 "logical_operand" "rM,J,K")))]
++ ""
++ "@
++ and\\t%0, %1, %z2
++ and%i2\\t%0, %1, %2
++ andh%i2\\t%0, %1, %U2"
++ [(set_attr "type" "alu")])
++
++(define_insn "iorsi3"
++ [(set (match_operand:SI 0 "register_operand" "=r, r,r")
++ (ior:SI (match_operand:SI 1 "register_operand" "%r, r,r")
++ (match_operand:SI 2 "logical_operand" "rM,J,K")))]
++ ""
++ "@
++ or\\t%0, %1, %z2
++ or%i2\\t%0, %1, %2
++ orh%i2\\t%0, %1, %U2"
++ [(set_attr "type" "alu")])
++
++(define_insn "*norsi3"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
++ (not:SI (match_operand:SI 2 "reg_or_0_operand" "rM"))))]
++ ""
++ "nor\\t%0, %1, %z2"
++ [(set_attr "type" "alu")])
++
++(define_insn "xorsi3"
++ [(set (match_operand:SI 0 "register_operand" "=r, r,r")
++ (xor:SI (match_operand:SI 1 "register_operand" "%r, r,r")
++ (match_operand:SI 2 "logical_operand" "rM,J,K")))]
++ ""
++ "@
++ xor\\t%0, %1, %z2
++ xor%i2\\t%0, %1, %2
++ xorh%i2\\t%0, %1, %U2"
++ [(set_attr "type" "alu")])
++
++
++
++;*****************************************************************************
++;*
++;* Shifts
++;*
++;*****************************************************************************
++
++(define_insn "ashlsi3"
++ [(set (match_operand:SI 0 "register_operand" "=r,r")
++ (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
++ (match_operand:SI 2 "shift_operand" "r,L")))]
++ ""
++ "sll%i2\\t%0, %1, %z2"
++ [(set_attr "type" "shift")])
++
++(define_insn "ashrsi3"
++ [(set (match_operand:SI 0 "register_operand" "=r,r")
++ (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
++ (match_operand:SI 2 "shift_operand" "r,L")))]
++ ""
++ "sra%i2\\t%0, %1, %z2"
++ [(set_attr "type" "shift")])
++
++(define_insn "lshrsi3"
++ [(set (match_operand:SI 0 "register_operand" "=r,r")
++ (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
++ (match_operand:SI 2 "shift_operand" "r,L")))]
++ ""
++ "srl%i2\\t%0, %1, %z2"
++ [(set_attr "type" "shift")])
++
++(define_insn "rotlsi3"
++ [(set (match_operand:SI 0 "register_operand" "=r,r")
++ (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
++ (match_operand:SI 2 "shift_operand" "r,L")))]
++ ""
++ "rol%i2\\t%0, %1, %z2"
++ [(set_attr "type" "shift")])
++
++(define_insn "rotrsi3"
++ [(set (match_operand:SI 0 "register_operand" "=r,r")
++ (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
++ (match_operand:SI 2 "register_operand" "r,r")))]
++ ""
++ "ror\\t%0, %1, %2"
++ [(set_attr "type" "shift")])
++
++(define_insn "*shift_mul_constants"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (ashift:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
++ (match_operand:SI 2 "const_int_operand" "I"))
++ (match_operand:SI 3 "const_int_operand" "I")))]
++ "TARGET_HAS_MUL && SMALL_INT (INTVAL (operands[2]) << INTVAL (operands[3]))"
++{
++ HOST_WIDE_INT mul = INTVAL (operands[2]) << INTVAL (operands[3]);
++ rtx ops[3];
++
++ ops[0] = operands[0];
++ ops[1] = operands[1];
++ ops[2] = GEN_INT (mul);
++
++ output_asm_insn ("muli\t%0, %1, %2", ops);
++ return "";
++}
++ [(set_attr "type" "mul")])
++
++
++
++
++;*****************************************************************************
++;*
++;* Prologue, Epilogue and Return
++;*
++;*****************************************************************************
++
++(define_expand "prologue"
++ [(const_int 1)]
++ ""
++{
++ expand_prologue ();
++ DONE;
++})
++
++(define_expand "epilogue"
++ [(return)]
++ ""
++{
++ expand_epilogue (false);
++ DONE;
++})
++
++(define_expand "sibcall_epilogue"
++ [(return)]
++ ""
++{
++ expand_epilogue (true);
++ DONE;
++})
++
++(define_insn "return"
++ [(return)]
++ "reload_completed && nios2_can_use_return_insn ()"
++ "ret\\t"
++)
++
++(define_insn "return_from_epilogue"
++ [(use (match_operand 0 "pmode_register_operand" ""))
++ (return)]
++ "reload_completed"
++ "ret\\t"
++)
++
++;; Block any insns from being moved before this point, since the
++;; profiling call to mcount can use various registers that aren't
++;; saved or used to pass arguments.
++
++(define_insn "blockage"
++ [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
++ ""
++ ""
++ [(set_attr "type" "unknown")
++ (set_attr "length" "0")])
++
++
++
++;*****************************************************************************
++;*
++;* Jumps and Calls
++;*
++;*****************************************************************************
++
++(define_insn "indirect_jump"
++ [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
++ ""
++ "jmp\\t%0"
++ [(set_attr "type" "control")])
++
++(define_insn "jump"
++ [(set (pc)
++ (label_ref (match_operand 0 "" "")))]
++ ""
++ "br\\t%0"
++ [(set_attr "type" "control")])
++
++
++(define_insn "indirect_call"
++ [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
++ (match_operand 1 "" ""))
++ (clobber (reg:SI RA_REGNO))]
++ ""
++ "callr\\t%0"
++ [(set_attr "type" "control")])
++
++(define_insn "indirect_call_value"
++ [(set (match_operand 0 "" "")
++ (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
++ (match_operand 2 "" "")))
++ (clobber (reg:SI RA_REGNO))]
++ ""
++ "callr\\t%1"
++)
++
++(define_expand "call"
++ [(parallel [(call (match_operand 0 "" "")
++ (match_operand 1 "" ""))
++ (clobber (reg:SI RA_REGNO))])]
++ ""
++ "")
++
++(define_expand "call_value"
++ [(parallel [(set (match_operand 0 "" "")
++ (call (match_operand 1 "" "")
++ (match_operand 2 "" "")))
++ (clobber (reg:SI RA_REGNO))])]
++ ""
++ "")
++
++(define_insn "*call"
++ [(call (mem:QI (match_operand:SI 0 "immediate_operand" "i"))
++ (match_operand 1 "" ""))
++ (clobber (match_operand:SI 2 "register_operand" "=r"))]
++ ""
++ "call\\t%0"
++ [(set_attr "type" "control")])
++
++(define_insn "*call_value"
++ [(set (match_operand 0 "" "")
++ (call (mem:QI (match_operand:SI 1 "immediate_operand" "i"))
++ (match_operand 2 "" "")))
++ (clobber (match_operand:SI 3 "register_operand" "=r"))]
++ ""
++ "call\\t%1"
++ [(set_attr "type" "control")])
++
++(define_expand "sibcall"
++ [(parallel [(call (match_operand 0 "" "")
++ (match_operand 1 "" ""))
++ (return)
++ (use (match_operand 2 "" ""))])]
++ ""
++ {
++ XEXP (operands[0], 0) = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
++
++ if (operands[2] == NULL_RTX)
++ operands[2] = const0_rtx;
++ }
++)
++
++(define_expand "sibcall_value"
++ [(parallel [(set (match_operand 0 "" "")
++ (call (match_operand 1 "" "")
++ (match_operand 2 "" "")))
++ (return)
++ (use (match_operand 3 "" ""))])]
++ ""
++ {
++ XEXP (operands[1], 0) = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
++
++ if (operands[3] == NULL_RTX)
++ operands[3] = const0_rtx;
++ }
++)
++
++(define_insn "sibcall_insn"
++ [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
++ (match_operand 1 "" ""))
++ (return)
++ (use (match_operand 2 "" ""))]
++ ""
++ "jmp\\t%0"
++)
++
++(define_insn "sibcall_value_insn"
++ [(set (match_operand 0 "register_operand" "")
++ (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
++ (match_operand 2 "" "")))
++ (return)
++ (use (match_operand 3 "" ""))]
++ ""
++ "jmp\\t%1"
++)
++
++
++
++
++(define_expand "tablejump"
++ [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
++ (use (label_ref (match_operand 1 "" "")))])]
++ ""
++ ""
++)
++
++(define_insn "*tablejump"
++ [(set (pc)
++ (match_operand:SI 0 "register_operand" "r"))
++ (use (label_ref (match_operand 1 "" "")))]
++ ""
++ "jmp\\t%0"
++ [(set_attr "type" "control")])
++
++
++
++;*****************************************************************************
++;*
++;* Comparisons
++;*
++;*****************************************************************************
++;; Flow here is rather complex (based on MIPS):
++;;
++;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
++;; arguments into the branch_cmp array, and the type into
++;; branch_type. No RTL is generated.
++;;
++;; 2) The appropriate branch define_expand is called, which then
++;; creates the appropriate RTL for the comparison and branch.
++;; Different CC modes are used, based on what type of branch is
++;; done, so that we can constrain things appropriately. There
++;; are assumptions in the rest of GCC that break if we fold the
++;; operands into the branchs for integer operations, and use cc0
++;; for floating point, so we use the fp status register instead.
++;; If needed, an appropriate temporary is created to hold the
++;; of the integer compare.
++
++(define_expand "cmpsi"
++ [(set (cc0)
++ (compare:CC (match_operand:SI 0 "register_operand" "")
++ (match_operand:SI 1 "arith_operand" "")))]
++ ""
++{
++ branch_cmp[0] = operands[0];
++ branch_cmp[1] = operands[1];
++ branch_type = CMP_SI;
++ DONE;
++})
++
++(define_expand "tstsi"
++ [(set (cc0)
++ (match_operand:SI 0 "register_operand" ""))]
++ ""
++{
++ branch_cmp[0] = operands[0];
++ branch_cmp[1] = const0_rtx;
++ branch_type = CMP_SI;
++ DONE;
++})
++
++
++;*****************************************************************************
++;*
++;* setting a register from a comparison
++;*
++;*****************************************************************************
++
++(define_expand "seq"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (eq:SI (match_dup 1)
++ (match_dup 2)))]
++ ""
++{
++ if (branch_type != CMP_SI)
++ FAIL;
++
++ /* set up operands from compare. */
++ operands[1] = branch_cmp[0];
++ operands[2] = branch_cmp[1];
++
++ gen_int_relational (EQ, operands[0], operands[1], operands[2], NULL_RTX);
++ DONE;
++})
++
++
++(define_insn "*seq"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (eq:SI (match_operand:SI 1 "reg_or_0_operand" "%rM")
++ (match_operand:SI 2 "arith_operand" "rI")))]
++ ""
++ "cmpeq%i2\\t%0, %z1, %z2"
++ [(set_attr "type" "alu")])
++
++
++(define_expand "sne"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (ne:SI (match_dup 1)
++ (match_dup 2)))]
++ ""
++{
++ if (branch_type != CMP_SI)
++ FAIL;
++
++ /* set up operands from compare. */
++ operands[1] = branch_cmp[0];
++ operands[2] = branch_cmp[1];
++
++ gen_int_relational (NE, operands[0], operands[1], operands[2], NULL_RTX);
++ DONE;
++})
++
++
++(define_insn "*sne"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (ne:SI (match_operand:SI 1 "reg_or_0_operand" "%rM")
++ (match_operand:SI 2 "arith_operand" "rI")))]
++ ""
++ "cmpne%i2\\t%0, %z1, %z2"
++ [(set_attr "type" "alu")])
++
++
++(define_expand "sgt"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (gt:SI (match_dup 1)
++ (match_dup 2)))]
++ ""
++{
++ if (branch_type != CMP_SI)
++ FAIL;
++
++ /* set up operands from compare. */
++ operands[1] = branch_cmp[0];
++ operands[2] = branch_cmp[1];
++
++ gen_int_relational (GT, operands[0], operands[1], operands[2], NULL_RTX);
++ DONE;
++})
++
++
++(define_insn "*sgt"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (gt:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
++ (match_operand:SI 2 "reg_or_0_operand" "rM")))]
++ ""
++ "cmplt\\t%0, %z2, %z1"
++ [(set_attr "type" "alu")])
++
++
++(define_expand "sge"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (ge:SI (match_dup 1)
++ (match_dup 2)))]
++ ""
++{
++ if (branch_type != CMP_SI)
++ FAIL;
++
++ /* set up operands from compare. */
++ operands[1] = branch_cmp[0];
++ operands[2] = branch_cmp[1];
++
++ gen_int_relational (GE, operands[0], operands[1], operands[2], NULL_RTX);
++ DONE;
++})
++
++
++(define_insn "*sge"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (ge:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
++ (match_operand:SI 2 "arith_operand" "rI")))]
++ ""
++ "cmpge%i2\\t%0, %z1, %z2"
++ [(set_attr "type" "alu")])
++
++(define_expand "sle"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (le:SI (match_dup 1)
++ (match_dup 2)))]
++ ""
++{
++ if (branch_type != CMP_SI)
++ FAIL;
++
++ /* set up operands from compare. */
++ operands[1] = branch_cmp[0];
++ operands[2] = branch_cmp[1];
++
++ gen_int_relational (LE, operands[0], operands[1], operands[2], NULL_RTX);
++ DONE;
++})
++
++
++(define_insn "*sle"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (le:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
++ (match_operand:SI 2 "reg_or_0_operand" "rM")))]
++ ""
++ "cmpge\\t%0, %z2, %z1"
++ [(set_attr "type" "alu")])
++
++
++(define_expand "slt"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (lt:SI (match_dup 1)
++ (match_dup 2)))]
++ ""
++{
++ if (branch_type != CMP_SI)
++ FAIL;
++
++ /* set up operands from compare. */
++ operands[1] = branch_cmp[0];
++ operands[2] = branch_cmp[1];
++
++ gen_int_relational (LT, operands[0], operands[1], operands[2], NULL_RTX);
++ DONE;
++})
++
++
++(define_insn "*slt"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (lt:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
++ (match_operand:SI 2 "arith_operand" "rI")))]
++ ""
++ "cmplt%i2\\t%0, %z1, %z2"
++ [(set_attr "type" "alu")])
++
++
++(define_expand "sgtu"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (gtu:SI (match_dup 1)
++ (match_dup 2)))]
++ ""
++{
++ if (branch_type != CMP_SI)
++ FAIL;
++
++ /* set up operands from compare. */
++ operands[1] = branch_cmp[0];
++ operands[2] = branch_cmp[1];
++
++ gen_int_relational (GTU, operands[0], operands[1], operands[2], NULL_RTX);
++ DONE;
++})
++
++
++(define_insn "*sgtu"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (gtu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
++ (match_operand:SI 2 "reg_or_0_operand" "rM")))]
++ ""
++ "cmpltu\\t%0, %z2, %z1"
++ [(set_attr "type" "alu")])
++
++
++(define_expand "sgeu"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (geu:SI (match_dup 1)
++ (match_dup 2)))]
++ ""
++{
++ if (branch_type != CMP_SI)
++ FAIL;
++
++ /* set up operands from compare. */
++ operands[1] = branch_cmp[0];
++ operands[2] = branch_cmp[1];
++
++ gen_int_relational (GEU, operands[0], operands[1], operands[2], NULL_RTX);
++ DONE;
++})
++
++
++(define_insn "*sgeu"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (geu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
++ (match_operand:SI 2 "uns_arith_operand" "rJ")))]
++ ""
++ "cmpgeu%i2\\t%0, %z1, %z2"
++ [(set_attr "type" "alu")])
++
++(define_expand "sleu"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (leu:SI (match_dup 1)
++ (match_dup 2)))]
++ ""
++{
++ if (branch_type != CMP_SI)
++ FAIL;
++
++ /* set up operands from compare. */
++ operands[1] = branch_cmp[0];
++ operands[2] = branch_cmp[1];
++
++ gen_int_relational (LEU, operands[0], operands[1], operands[2], NULL_RTX);
++ DONE;
++})
++
++
++(define_insn "*sleu"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (leu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
++ (match_operand:SI 2 "reg_or_0_operand" "rM")))]
++ ""
++ "cmpgeu\\t%0, %z2, %z1"
++ [(set_attr "type" "alu")])
++
++
++(define_expand "sltu"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (ltu:SI (match_dup 1)
++ (match_dup 2)))]
++ ""
++{
++ if (branch_type != CMP_SI)
++ FAIL;
++
++ /* set up operands from compare. */
++ operands[1] = branch_cmp[0];
++ operands[2] = branch_cmp[1];
++
++ gen_int_relational (LTU, operands[0], operands[1], operands[2], NULL_RTX);
++ DONE;
++})
++
++
++(define_insn "*sltu"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (ltu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
++ (match_operand:SI 2 "uns_arith_operand" "rJ")))]
++ ""
++ "cmpltu%i2\\t%0, %z1, %z2"
++ [(set_attr "type" "alu")])
++
++
++
++
++;*****************************************************************************
++;*
++;* branches
++;*
++;*****************************************************************************
++
++(define_insn "*cbranch"
++ [(set (pc)
++ (if_then_else
++ (match_operator:SI 0 "comparison_operator"
++ [(match_operand:SI 2 "reg_or_0_operand" "rM")
++ (match_operand:SI 3 "reg_or_0_operand" "rM")])
++ (label_ref (match_operand 1 "" ""))
++ (pc)))]
++ ""
++ "b%0\\t%z2, %z3, %l1"
++ [(set_attr "type" "control")])
++
++
++(define_expand "beq"
++ [(set (pc)
++ (if_then_else (eq:CC (cc0)
++ (const_int 0))
++ (label_ref (match_operand 0 "" ""))
++ (pc)))]
++ ""
++{
++ gen_int_relational (EQ, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
++ DONE;
++})
++
++
++(define_expand "bne"
++ [(set (pc)
++ (if_then_else (ne:CC (cc0)
++ (const_int 0))
++ (label_ref (match_operand 0 "" ""))
++ (pc)))]
++ ""
++{
++ gen_int_relational (NE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
++ DONE;
++})
++
++
++(define_expand "bgt"
++ [(set (pc)
++ (if_then_else (gt:CC (cc0)
++ (const_int 0))
++ (label_ref (match_operand 0 "" ""))
++ (pc)))]
++ ""
++{
++ gen_int_relational (GT, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
++ DONE;
++})
++
++(define_expand "bge"
++ [(set (pc)
++ (if_then_else (ge:CC (cc0)
++ (const_int 0))
++ (label_ref (match_operand 0 "" ""))
++ (pc)))]
++ ""
++{
++ gen_int_relational (GE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
++ DONE;
++})
++
++(define_expand "ble"
++ [(set (pc)
++ (if_then_else (le:CC (cc0)
++ (const_int 0))
++ (label_ref (match_operand 0 "" ""))
++ (pc)))]
++ ""
++{
++ gen_int_relational (LE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
++ DONE;
++})
++
++(define_expand "blt"
++ [(set (pc)
++ (if_then_else (lt:CC (cc0)
++ (const_int 0))
++ (label_ref (match_operand 0 "" ""))
++ (pc)))]
++ ""
++{
++ gen_int_relational (LT, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
++ DONE;
++})
++
++
++(define_expand "bgtu"
++ [(set (pc)
++ (if_then_else (gtu:CC (cc0)
++ (const_int 0))
++ (label_ref (match_operand 0 "" ""))
++ (pc)))]
++ ""
++{
++ gen_int_relational (GTU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
++ DONE;
++})
++
++(define_expand "bgeu"
++ [(set (pc)
++ (if_then_else (geu:CC (cc0)
++ (const_int 0))
++ (label_ref (match_operand 0 "" ""))
++ (pc)))]
++ ""
++{
++ gen_int_relational (GEU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
++ DONE;
++})
++
++(define_expand "bleu"
++ [(set (pc)
++ (if_then_else (leu:CC (cc0)
++ (const_int 0))
++ (label_ref (match_operand 0 "" ""))
++ (pc)))]
++ ""
++{
++ gen_int_relational (LEU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
++ DONE;
++})
++
++(define_expand "bltu"
++ [(set (pc)
++ (if_then_else (ltu:CC (cc0)
++ (const_int 0))
++ (label_ref (match_operand 0 "" ""))
++ (pc)))]
++ ""
++{
++ gen_int_relational (LTU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
++ DONE;
++})
++
++
++;*****************************************************************************
++;*
++;* String and Block Operations
++;*
++;*****************************************************************************
++
++; ??? This is all really a hack to get Dhrystone to work as fast as possible
++; things to be fixed:
++; * let the compiler core handle all of this, for that to work the extra
++; aliasing needs to be addressed.
++; * we use three temporary registers for loading and storing to ensure no
++; ld use stalls, this is excessive, because after the first ld/st only
++; two are needed. Only two would be needed all the way through if
++; we could schedule with other code. Consider:
++; 1 ld $1, 0($src)
++; 2 ld $2, 4($src)
++; 3 ld $3, 8($src)
++; 4 st $1, 0($dest)
++; 5 ld $1, 12($src)
++; 6 st $2, 4($src)
++; 7 etc.
++; The first store has to wait until 4. If it does not there will be one
++; cycle of stalling. However, if any other instruction could be placed
++; between 1 and 4, $3 would not be needed.
++; * In small we probably don't want to ever do this ourself because there
++; is no ld use stall.
++
++(define_expand "movstrsi"
++ [(parallel [(set (match_operand:BLK 0 "general_operand" "")
++ (match_operand:BLK 1 "general_operand" ""))
++ (use (match_operand:SI 2 "const_int_operand" ""))
++ (use (match_operand:SI 3 "const_int_operand" ""))
++ (clobber (match_scratch:SI 4 "=&r"))
++ (clobber (match_scratch:SI 5 "=&r"))
++ (clobber (match_scratch:SI 6 "=&r"))])]
++ "TARGET_INLINE_MEMCPY"
++{
++ rtx ld_addr_reg, st_addr_reg;
++
++ /* If the predicate for op2 fails in expr.c:emit_block_move_via_movstr
++ it trys to copy to a register, but does not re-try the predicate.
++ ??? Intead of fixing expr.c, I fix it here. */
++ if (!const_int_operand (operands[2], SImode))
++ FAIL;
++
++ /* ??? there are some magic numbers which need to be sorted out here.
++ the basis for them is not increasing code size hugely or going
++ out of range of offset addressing */
++ if (INTVAL (operands[3]) < 4)
++ FAIL;
++ if (!optimize
++ || (optimize_size && INTVAL (operands[2]) > 12)
++ || (optimize < 3 && INTVAL (operands[2]) > 100)
++ || INTVAL (operands[2]) > 200)
++ FAIL;
++
++ st_addr_reg
++ = replace_equiv_address (operands[0],
++ copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
++ ld_addr_reg
++ = replace_equiv_address (operands[1],
++ copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
++ emit_insn (gen_movstrsi_internal (st_addr_reg, ld_addr_reg,
++ operands[2], operands[3]));
++
++ DONE;
++})
++
++
++(define_insn "movstrsi_internal"
++ [(set (match_operand:BLK 0 "memory_operand" "=o")
++ (match_operand:BLK 1 "memory_operand" "o"))
++ (use (match_operand:SI 2 "const_int_operand" "i"))
++ (use (match_operand:SI 3 "const_int_operand" "i"))
++ (clobber (match_scratch:SI 4 "=&r"))
++ (clobber (match_scratch:SI 5 "=&r"))
++ (clobber (match_scratch:SI 6 "=&r"))]
++ "TARGET_INLINE_MEMCPY"
++{
++ int ld_offset = INTVAL (operands[2]);
++ int ld_len = INTVAL (operands[2]);
++ int ld_reg = 0;
++ rtx ld_addr_reg = XEXP (operands[1], 0);
++ int st_offset = INTVAL (operands[2]);
++ int st_len = INTVAL (operands[2]);
++ int st_reg = 0;
++ rtx st_addr_reg = XEXP (operands[0], 0);
++ int delay_count = 0;
++
++ /* ops[0] is the address used by the insn
++ ops[1] is the register being loaded or stored */
++ rtx ops[2];
++
++ if (INTVAL (operands[3]) < 4)
++ abort ();
++
++ while (ld_offset >= 4)
++ {
++ /* if the load use delay has been met, I can start
++ storing */
++ if (delay_count >= 3)
++ {
++ ops[0] = gen_rtx (MEM, SImode,
++ plus_constant (st_addr_reg, st_len - st_offset));
++ ops[1] = operands[st_reg + 4];
++ output_asm_insn ("stw\t%1, %0", ops);
++
++ st_reg = (st_reg + 1) % 3;
++ st_offset -= 4;
++ }
++
++ ops[0] = gen_rtx (MEM, SImode,
++ plus_constant (ld_addr_reg, ld_len - ld_offset));
++ ops[1] = operands[ld_reg + 4];
++ output_asm_insn ("ldw\t%1, %0", ops);
++
++ ld_reg = (ld_reg + 1) % 3;
++ ld_offset -= 4;
++ delay_count++;
++ }
++
++ if (ld_offset >= 2)
++ {
++ /* if the load use delay has been met, I can start
++ storing */
++ if (delay_count >= 3)
++ {
++ ops[0] = gen_rtx (MEM, SImode,
++ plus_constant (st_addr_reg, st_len - st_offset));
++ ops[1] = operands[st_reg + 4];
++ output_asm_insn ("stw\t%1, %0", ops);
++
++ st_reg = (st_reg + 1) % 3;
++ st_offset -= 4;
++ }
++
++ ops[0] = gen_rtx (MEM, HImode,
++ plus_constant (ld_addr_reg, ld_len - ld_offset));
++ ops[1] = operands[ld_reg + 4];
++ output_asm_insn ("ldh\t%1, %0", ops);
++
++ ld_reg = (ld_reg + 1) % 3;
++ ld_offset -= 2;
++ delay_count++;
++ }
++
++ if (ld_offset >= 1)
++ {
++ /* if the load use delay has been met, I can start
++ storing */
++ if (delay_count >= 3)
++ {
++ ops[0] = gen_rtx (MEM, SImode,
++ plus_constant (st_addr_reg, st_len - st_offset));
++ ops[1] = operands[st_reg + 4];
++ output_asm_insn ("stw\t%1, %0", ops);
++
++ st_reg = (st_reg + 1) % 3;
++ st_offset -= 4;
++ }
++
++ ops[0] = gen_rtx (MEM, QImode,
++ plus_constant (ld_addr_reg, ld_len - ld_offset));
++ ops[1] = operands[ld_reg + 4];
++ output_asm_insn ("ldb\t%1, %0", ops);
++
++ ld_reg = (ld_reg + 1) % 3;
++ ld_offset -= 1;
++ delay_count++;
++ }
++
++ while (st_offset >= 4)
++ {
++ ops[0] = gen_rtx (MEM, SImode,
++ plus_constant (st_addr_reg, st_len - st_offset));
++ ops[1] = operands[st_reg + 4];
++ output_asm_insn ("stw\t%1, %0", ops);
++
++ st_reg = (st_reg + 1) % 3;
++ st_offset -= 4;
++ }
++
++ while (st_offset >= 2)
++ {
++ ops[0] = gen_rtx (MEM, HImode,
++ plus_constant (st_addr_reg, st_len - st_offset));
++ ops[1] = operands[st_reg + 4];
++ output_asm_insn ("sth\t%1, %0", ops);
++
++ st_reg = (st_reg + 1) % 3;
++ st_offset -= 2;
++ }
++
++ while (st_offset >= 1)
++ {
++ ops[0] = gen_rtx (MEM, QImode,
++ plus_constant (st_addr_reg, st_len - st_offset));
++ ops[1] = operands[st_reg + 4];
++ output_asm_insn ("stb\t%1, %0", ops);
++
++ st_reg = (st_reg + 1) % 3;
++ st_offset -= 1;
++ }
++
++ return "";
++}
++; ??? lengths are not being used yet, but I will probably forget
++; to update this once I am using lengths, so set it to something
++; definetely big enough to cover it. 400 allows for 200 bytes
++; of motion.
++ [(set_attr "length" "400")])
++
++
++
++;*****************************************************************************
++;*
++;* Custom instructions
++;*
++;*****************************************************************************
++
++(define_constants [
++ (CUSTOM_N 100)
++ (CUSTOM_NI 101)
++ (CUSTOM_NF 102)
++ (CUSTOM_NP 103)
++ (CUSTOM_NII 104)
++ (CUSTOM_NIF 105)
++ (CUSTOM_NIP 106)
++ (CUSTOM_NFI 107)
++ (CUSTOM_NFF 108)
++ (CUSTOM_NFP 109)
++ (CUSTOM_NPI 110)
++ (CUSTOM_NPF 111)
++ (CUSTOM_NPP 112)
++ (CUSTOM_IN 113)
++ (CUSTOM_INI 114)
++ (CUSTOM_INF 115)
++ (CUSTOM_INP 116)
++ (CUSTOM_INII 117)
++ (CUSTOM_INIF 118)
++ (CUSTOM_INIP 119)
++ (CUSTOM_INFI 120)
++ (CUSTOM_INFF 121)
++ (CUSTOM_INFP 122)
++ (CUSTOM_INPI 123)
++ (CUSTOM_INPF 124)
++ (CUSTOM_INPP 125)
++ (CUSTOM_FN 126)
++ (CUSTOM_FNI 127)
++ (CUSTOM_FNF 128)
++ (CUSTOM_FNP 129)
++ (CUSTOM_FNII 130)
++ (CUSTOM_FNIF 131)
++ (CUSTOM_FNIP 132)
++ (CUSTOM_FNFI 133)
++ (CUSTOM_FNFF 134)
++ (CUSTOM_FNFP 135)
++ (CUSTOM_FNPI 136)
++ (CUSTOM_FNPF 137)
++ (CUSTOM_FNPP 138)
++ (CUSTOM_PN 139)
++ (CUSTOM_PNI 140)
++ (CUSTOM_PNF 141)
++ (CUSTOM_PNP 142)
++ (CUSTOM_PNII 143)
++ (CUSTOM_PNIF 144)
++ (CUSTOM_PNIP 145)
++ (CUSTOM_PNFI 146)
++ (CUSTOM_PNFF 147)
++ (CUSTOM_PNFP 148)
++ (CUSTOM_PNPI 149)
++ (CUSTOM_PNPF 150)
++ (CUSTOM_PNPP 151)
++])
++
++
++(define_insn "custom_n"
++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")] CUSTOM_N)]
++ ""
++ "custom\\t%0, zero, zero, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_ni"
++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
++ (match_operand:SI 1 "register_operand" "r")] CUSTOM_NI)]
++ ""
++ "custom\\t%0, zero, %1, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_nf"
++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
++ (match_operand:SF 1 "register_operand" "r")] CUSTOM_NF)]
++ ""
++ "custom\\t%0, zero, %1, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_np"
++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
++ (match_operand:SI 1 "register_operand" "r")] CUSTOM_NP)]
++ ""
++ "custom\\t%0, zero, %1, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_nii"
++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
++ (match_operand:SI 1 "register_operand" "r")
++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_NII)]
++ ""
++ "custom\\t%0, zero, %1, %2"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_nif"
++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
++ (match_operand:SI 1 "register_operand" "r")
++ (match_operand:SF 2 "register_operand" "r")] CUSTOM_NIF)]
++ ""
++ "custom\\t%0, zero, %1, %2"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_nip"
++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
++ (match_operand:SI 1 "register_operand" "r")
++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_NIP)]
++ ""
++ "custom\\t%0, zero, %1, %2"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_nfi"
++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
++ (match_operand:SF 1 "register_operand" "r")
++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_NFI)]
++ ""
++ "custom\\t%0, zero, %1, %2"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_nff"
++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
++ (match_operand:SF 1 "register_operand" "r")
++ (match_operand:SF 2 "register_operand" "r")] CUSTOM_NFF)]
++ ""
++ "custom\\t%0, zero, %1, %2"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_nfp"
++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
++ (match_operand:SF 1 "register_operand" "r")
++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_NFP)]
++ ""
++ "custom\\t%0, zero, %1, %2"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_npi"
++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
++ (match_operand:SI 1 "register_operand" "r")
++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_NPI)]
++ ""
++ "custom\\t%0, zero, %1, %2"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_npf"
++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
++ (match_operand:SI 1 "register_operand" "r")
++ (match_operand:SF 2 "register_operand" "r")] CUSTOM_NPF)]
++ ""
++ "custom\\t%0, zero, %1, %2"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_npp"
++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
++ (match_operand:SI 1 "register_operand" "r")
++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_NPP)]
++ ""
++ "custom\\t%0, zero, %1, %2"
++ [(set_attr "type" "custom")])
++
++
++
++(define_insn "custom_in"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_IN))]
++ ""
++ "custom\\t%1, %0, zero, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_ini"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_INI))]
++ ""
++ "custom\\t%1, %0, %2, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_inf"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SF 2 "register_operand" "r")] CUSTOM_INF))]
++ ""
++ "custom\\t%1, %0, %2, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_inp"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_INP))]
++ ""
++ "custom\\t%1, %0, %2, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_inii"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_INII))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_inif"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_INIF))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_inip"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_INIP))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_infi"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SF 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_INFI))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_inff"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SF 2 "register_operand" "r")
++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_INFF))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_infp"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SF 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_INFP))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_inpi"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_INPI))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_inpf"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_INPF))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_inpp"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_INPP))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++
++
++
++
++(define_insn "custom_fn"
++ [(set (match_operand:SF 0 "register_operand" "=r")
++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_FN))]
++ ""
++ "custom\\t%1, %0, zero, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_fni"
++ [(set (match_operand:SF 0 "register_operand" "=r")
++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_FNI))]
++ ""
++ "custom\\t%1, %0, %2, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_fnf"
++ [(set (match_operand:SF 0 "register_operand" "=r")
++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SF 2 "register_operand" "r")] CUSTOM_FNF))]
++ ""
++ "custom\\t%1, %0, %2, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_fnp"
++ [(set (match_operand:SF 0 "register_operand" "=r")
++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_FNP))]
++ ""
++ "custom\\t%1, %0, %2, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_fnii"
++ [(set (match_operand:SF 0 "register_operand" "=r")
++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNII))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_fnif"
++ [(set (match_operand:SF 0 "register_operand" "=r")
++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_FNIF))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_fnip"
++ [(set (match_operand:SF 0 "register_operand" "=r")
++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNIP))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_fnfi"
++ [(set (match_operand:SF 0 "register_operand" "=r")
++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SF 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNFI))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_fnff"
++ [(set (match_operand:SF 0 "register_operand" "=r")
++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SF 2 "register_operand" "r")
++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_FNFF))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_fnfp"
++ [(set (match_operand:SF 0 "register_operand" "=r")
++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SF 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNFP))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_fnpi"
++ [(set (match_operand:SF 0 "register_operand" "=r")
++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNPI))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_fnpf"
++ [(set (match_operand:SF 0 "register_operand" "=r")
++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_FNPF))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_fnpp"
++ [(set (match_operand:SF 0 "register_operand" "=r")
++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNPP))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++
++
++(define_insn "custom_pn"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_PN))]
++ ""
++ "custom\\t%1, %0, zero, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_pni"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_PNI))]
++ ""
++ "custom\\t%1, %0, %2, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_pnf"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SF 2 "register_operand" "r")] CUSTOM_PNF))]
++ ""
++ "custom\\t%1, %0, %2, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_pnp"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_PNP))]
++ ""
++ "custom\\t%1, %0, %2, zero"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_pnii"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNII))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_pnif"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_PNIF))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_pnip"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNIP))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_pnfi"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SF 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNFI))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_pnff"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SF 2 "register_operand" "r")
++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_PNFF))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_pnfp"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SF 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNFP))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_pnpi"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNPI))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_pnpf"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_PNPF))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++(define_insn "custom_pnpp"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
++ (match_operand:SI 2 "register_operand" "r")
++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNPP))]
++ ""
++ "custom\\t%1, %0, %2, %3"
++ [(set_attr "type" "custom")])
++
++
++
++
++
++
++;*****************************************************************************
++;*
++;* Misc
++;*
++;*****************************************************************************
++
++(define_insn "nop"
++ [(const_int 0)]
++ ""
++ "nop\\t"
++ [(set_attr "type" "alu")])
++
++(define_insn "sync"
++ [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
++ ""
++ "sync\\t"
++ [(set_attr "type" "control")])
++
++
++(define_insn "rdctl"
++ [(set (match_operand:SI 0 "register_operand" "=r")
++ (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")] UNSPEC_RDCTL))]
++ ""
++ "rdctl\\t%0, ctl%1"
++ [(set_attr "type" "control")])
++
++(define_insn "wrctl"
++ [(unspec_volatile:SI [(match_operand:SI 0 "rdwrctl_operand" "O")
++ (match_operand:SI 1 "register_operand" "r")] UNSPEC_WRCTL)]
++ ""
++ "wrctl\\tctl%0, %1"
++ [(set_attr "type" "control")])
++
++
++
++;*****************************************************************************
++;*
++;* Peepholes
++;*
++;*****************************************************************************
++
++
+--- gcc-3.4.3/gcc/config/nios2/t-nios2
++++ gcc-3.4.3-nios2/gcc/config/nios2/t-nios2
+@@ -0,0 +1,123 @@
++##
++## Compiler flags to use when compiling libgcc2.c.
++##
++## LIB2FUNCS_EXTRA
++## A list of source file names to be compiled or assembled and inserted into libgcc.a.
++
++LIB2FUNCS_EXTRA=$(srcdir)/config/nios2/lib2-divmod.c \
++ $(srcdir)/config/nios2/lib2-divmod-hi.c \
++ $(srcdir)/config/nios2/lib2-divtable.c \
++ $(srcdir)/config/nios2/lib2-mul.c
++
++##
++## Floating Point Emulation
++## To have GCC include software floating point libraries in libgcc.a define FPBIT
++## and DPBIT along with a few rules as follows:
++##
++## # We want fine grained libraries, so use the new code
++## # to build the floating point emulation libraries.
++FPBIT=$(srcdir)/config/nios2/nios2-fp-bit.c
++DPBIT=$(srcdir)/config/nios2/nios2-dp-bit.c
++
++TARGET_LIBGCC2_CFLAGS = -O2
++
++# FLOAT_ONLY - no doubles
++# SMALL_MACHINE - QI/HI is faster than SI
++# Actually SMALL_MACHINE uses chars and shorts instead of ints
++# since ints (16-bit ones as they are today) are at least as fast
++# as chars and shorts, don't define SMALL_MACHINE
++# CMPtype - type returned by FP compare, i.e. INT (hard coded in fp-bit - see code )
++
++$(FPBIT): $(srcdir)/config/fp-bit.c Makefile
++ echo '#define FLOAT' > ${FPBIT}
++ cat $(srcdir)/config/fp-bit.c >> ${FPBIT}
++
++$(DPBIT): $(srcdir)/config/fp-bit.c Makefile
++ echo '' > ${DPBIT}
++ cat $(srcdir)/config/fp-bit.c >> ${DPBIT}
++
++EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
++
++# Assemble startup files.
++$(T)crti.o: $(srcdir)/config/nios2/crti.asm $(GCC_PASSES)
++ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
++ -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/nios2/crti.asm
++
++$(T)crtn.o: $(srcdir)/config/nios2/crtn.asm $(GCC_PASSES)
++ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
++ -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/nios2/crtn.asm
++
++
++## You may need to provide additional #defines at the beginning of
++## fp-bit.c and dp-bit.c to control target endianness and other options
++##
++## CRTSTUFF_T_CFLAGS
++## Special flags used when compiling crtstuff.c. See Initialization.
++##
++## CRTSTUFF_T_CFLAGS_S
++## Special flags used when compiling crtstuff.c for shared linking. Used
++## if you use crtbeginS.o and crtendS.o in EXTRA-PARTS. See Initialization.
++##
++## MULTILIB_OPTIONS
++## For some targets, invoking GCC in different ways produces objects that
++## can not be linked together. For example, for some targets GCC produces
++## both big and little endian code. For these targets, you must arrange
++## for multiple versions of libgcc.a to be compiled, one for each set of
++## incompatible options. When GCC invokes the linker, it arranges to link
++## in the right version of libgcc.a, based on the command line options
++## used.
++## The MULTILIB_OPTIONS macro lists the set of options for which special
++## versions of libgcc.a must be built. Write options that are mutually
++## incompatible side by side, separated by a slash. Write options that may
++## be used together separated by a space. The build procedure will build
++## all combinations of compatible options.
++##
++## For example, if you set MULTILIB_OPTIONS to m68000/m68020 msoft-float,
++## Makefile will build special versions of libgcc.a using the following
++## sets of options: -m68000, -m68020, -msoft-float, -m68000 -msoft-float,
++## and -m68020 -msoft-float.
++
++MULTILIB_OPTIONS = mno-hw-mul mhw-mulx
++
++## MULTILIB_DIRNAMES
++## If MULTILIB_OPTIONS is used, this variable specifies the directory names
++## that should be used to hold the various libraries. Write one element in
++## MULTILIB_DIRNAMES for each element in MULTILIB_OPTIONS. If
++## MULTILIB_DIRNAMES is not used, the default value will be
++## MULTILIB_OPTIONS, with all slashes treated as spaces.
++## For example, if MULTILIB_OPTIONS is set to m68000/m68020 msoft-float,
++## then the default value of MULTILIB_DIRNAMES is m68000 m68020
++## msoft-float. You may specify a different value if you desire a
++## different set of directory names.
++
++# MULTILIB_DIRNAMES =
++
++## MULTILIB_MATCHES
++## Sometimes the same option may be written in two different ways. If an
++## option is listed in MULTILIB_OPTIONS, GCC needs to know about any
++## synonyms. In that case, set MULTILIB_MATCHES to a list of items of the
++## form option=option to describe all relevant synonyms. For example,
++## m68000=mc68000 m68020=mc68020.
++##
++## MULTILIB_EXCEPTIONS
++## Sometimes when there are multiple sets of MULTILIB_OPTIONS being
++## specified, there are combinations that should not be built. In that
++## case, set MULTILIB_EXCEPTIONS to be all of the switch exceptions in
++## shell case syntax that should not be built.
++## For example, in the PowerPC embedded ABI support, it is not desirable to
++## build libraries compiled with the -mcall-aix option and either of the
++## -fleading-underscore or -mlittle options at the same time. Therefore
++## MULTILIB_EXCEPTIONS is set to
++##
++## *mcall-aix/*fleading-underscore* *mlittle/*mcall-aix*
++##
++
++MULTILIB_EXCEPTIONS = *mno-hw-mul/*mhw-mulx*
++
++##
++## MULTILIB_EXTRA_OPTS Sometimes it is desirable that when building
++## multiple versions of libgcc.a certain options should always be passed on
++## to the compiler. In that case, set MULTILIB_EXTRA_OPTS to be the list
++## of options to be used for all builds.
++##
++
+--- gcc-3.4.3/gcc/config.gcc
++++ gcc-3.4.3-nios2/gcc/config.gcc
+@@ -1321,6 +1321,10 @@ m32rle-*-linux*)
+ thread_file='posix'
+ fi
+ ;;
++# JBG
++nios2-*-* | nios2-*-*)
++ tm_file="elfos.h ${tm_file}"
++ ;;
+ # m68hc11 and m68hc12 share the same machine description.
+ m68hc11-*-*|m6811-*-*)
+ tm_file="dbxelf.h elfos.h m68hc11/m68hc11.h"
+--- gcc-3.4.3/gcc/cse.c
++++ gcc-3.4.3-nios2/gcc/cse.c
+@@ -3134,6 +3134,10 @@ find_comparison_args (enum rtx_code code
+ #ifdef FLOAT_STORE_FLAG_VALUE
+ REAL_VALUE_TYPE fsfv;
+ #endif
++#ifdef __nios2__
++ if (p->is_const)
++ break;
++#endif
+
+ /* If the entry isn't valid, skip it. */
+ if (! exp_equiv_p (p->exp, p->exp, 1, 0))
+--- gcc-3.4.3/gcc/doc/extend.texi
++++ gcc-3.4.3-nios2/gcc/doc/extend.texi
+@@ -5636,12 +5636,118 @@ to those machines. Generally these gene
+ instructions, but allow the compiler to schedule those calls.
+
+ @menu
++* Altera Nios II Built-in Functions::
+ * Alpha Built-in Functions::
+ * ARM Built-in Functions::
+ * X86 Built-in Functions::
+ * PowerPC AltiVec Built-in Functions::
+ @end menu
+
++@node Altera Nios II Built-in Functions
++@subsection Altera Nios II Built-in Functions
++
++These built-in functions are available for the Altera Nios II
++family of processors.
++
++The following built-in functions are always available. They
++all generate the machine instruction that is part of the name.
++
++@example
++int __builtin_ldbio (volatile const void *)
++int __builtin_ldbuio (volatile const void *)
++int __builtin_ldhio (volatile const void *)
++int __builtin_ldhuio (volatile const void *)
++int __builtin_ldwio (volatile const void *)
++void __builtin_stbio (volatile void *, int)
++void __builtin_sthio (volatile void *, int)
++void __builtin_stwio (volatile void *, int)
++void __builtin_sync (void)
++int __builtin_rdctl (int)
++void __builtin_wrctl (int, int)
++@end example
++
++The following built-in functions are always available. They
++all generate a Nios II Custom Instruction. The name of the
++function represents the types that the function takes and
++returns. The letter before the @code{n} is the return type
++or void if absent. The @code{n} represnts the first parameter
++to all the custom instructions, the custom instruction number.
++The two letters after the @code{n} represent the up to two
++parameters to the function.
++
++The letters reprsent the following data types:
++@table @code
++@item <no letter>
++@code{void} for return type and no parameter for parameter types.
++
++@item i
++@code{int} for return type and parameter type
++
++@item f
++@code{float} for return type and parameter type
++
++@item p
++@code{void *} for return type and parameter type
++
++@end table
++
++And the function names are:
++@example
++void __builtin_custom_n (void)
++void __builtin_custom_ni (int)
++void __builtin_custom_nf (float)
++void __builtin_custom_np (void *)
++void __builtin_custom_nii (int, int)
++void __builtin_custom_nif (int, float)
++void __builtin_custom_nip (int, void *)
++void __builtin_custom_nfi (float, int)
++void __builtin_custom_nff (float, float)
++void __builtin_custom_nfp (float, void *)
++void __builtin_custom_npi (void *, int)
++void __builtin_custom_npf (void *, float)
++void __builtin_custom_npp (void *, void *)
++int __builtin_custom_in (void)
++int __builtin_custom_ini (int)
++int __builtin_custom_inf (float)
++int __builtin_custom_inp (void *)
++int __builtin_custom_inii (int, int)
++int __builtin_custom_inif (int, float)
++int __builtin_custom_inip (int, void *)
++int __builtin_custom_infi (float, int)
++int __builtin_custom_inff (float, float)
++int __builtin_custom_infp (float, void *)
++int __builtin_custom_inpi (void *, int)
++int __builtin_custom_inpf (void *, float)
++int __builtin_custom_inpp (void *, void *)
++float __builtin_custom_fn (void)
++float __builtin_custom_fni (int)
++float __builtin_custom_fnf (float)
++float __builtin_custom_fnp (void *)
++float __builtin_custom_fnii (int, int)
++float __builtin_custom_fnif (int, float)
++float __builtin_custom_fnip (int, void *)
++float __builtin_custom_fnfi (float, int)
++float __builtin_custom_fnff (float, float)
++float __builtin_custom_fnfp (float, void *)
++float __builtin_custom_fnpi (void *, int)
++float __builtin_custom_fnpf (void *, float)
++float __builtin_custom_fnpp (void *, void *)
++void * __builtin_custom_pn (void)
++void * __builtin_custom_pni (int)
++void * __builtin_custom_pnf (float)
++void * __builtin_custom_pnp (void *)
++void * __builtin_custom_pnii (int, int)
++void * __builtin_custom_pnif (int, float)
++void * __builtin_custom_pnip (int, void *)
++void * __builtin_custom_pnfi (float, int)
++void * __builtin_custom_pnff (float, float)
++void * __builtin_custom_pnfp (float, void *)
++void * __builtin_custom_pnpi (void *, int)
++void * __builtin_custom_pnpf (void *, float)
++void * __builtin_custom_pnpp (void *, void *)
++@end example
++
++
+ @node Alpha Built-in Functions
+ @subsection Alpha Built-in Functions
+
+--- gcc-3.4.3/gcc/doc/invoke.texi
++++ gcc-3.4.3-nios2/gcc/doc/invoke.texi
+@@ -337,6 +337,14 @@ in the following sections.
+ @item Machine Dependent Options
+ @xref{Submodel Options,,Hardware Models and Configurations}.
+
++@emph{Altera Nios II Options}
++@gccoptlist{-msmallc -mno-bypass-cache -mbypass-cache @gol
++-mno-cache-volatile -mcache-volatile -mno-inline-memcpy @gol
++-minline-memcpy -mno-fast-sw-div -mfast-sw-div @gol
++-mhw-mul -mno-hw-mul -mhw-mulx -mno-hw-mulx @gol
++-mno-hw-div -mhw-div @gol
++-msys-crt0= -msys-lib= -msys=nosys }
++
+ @emph{M680x0 Options}
+ @gccoptlist{-m68000 -m68020 -m68020-40 -m68020-60 -m68030 -m68040 @gol
+ -m68060 -mcpu32 -m5200 -m68881 -mbitfield -mc68000 -mc68020 @gol
+@@ -5836,6 +5844,7 @@ machine description. The default for th
+ that macro, which enables you to change the defaults.
+
+ @menu
++* Altera Nios II Options::
+ * M680x0 Options::
+ * M68hc1x Options::
+ * VAX Options::
+@@ -5871,6 +5880,103 @@ that macro, which enables you to change
+ * FRV Options::
+ @end menu
+
++
++@node Altera Nios II Options
++@subsection Altera Nios II Options
++@cindex Altera Nios II options
++
++These are the @samp{-m} options defined for the Altera Nios II
++processor.
++
++@table @gcctabopt
++
++@item -msmallc
++@opindex msmallc
++
++Link with a limited version of the C library, -lsmallc. For more
++information see the C Library Documentation.
++
++
++@item -mbypass-cache
++@itemx -mno-bypass-cache
++@opindex mno-bypass-cache
++@opindex mbypass-cache
++
++Force all load and store instructions to always bypass cache by
++using io variants of the instructions. The default is to not
++bypass the cache.
++
++@item -mno-cache-volatile
++@itemx -mcache-volatile
++@opindex mcache-volatile
++@opindex mno-cache-volatile
++
++Volatile memory access bypass the cache using the io variants of
++the ld and st instructions. The default is to cache volatile
++accesses.
++
++-mno-cache-volatile is deprecated and will be deleted in a
++future GCC release.
++
++
++@item -mno-inline-memcpy
++@itemx -minline-memcpy
++@opindex mno-inline-memcpy
++@opindex minline-memcpy
++
++Do not inline memcpy. The default is to inline when -O is on.
++
++
++@item -mno-fast-sw-div
++@itemx -mfast-sw-div
++@opindex mno-fast-sw-div
++@opindex mfast-sw-div
++
++Do no use table based fast divide for small numbers. The default
++is to use the fast divide at -O3 and above.
++
++
++@item -mno-hw-mul
++@itemx -mhw-mul
++@itemx -mno-hw-mulx
++@itemx -mhw-mulx
++@itemx -mno-hw-div
++@itemx -mhw-div
++@opindex mno-hw-mul
++@opindex mhw-mul
++@opindex mno-hw-mulx
++@opindex mhw-mulx
++@opindex mno-hw-div
++@opindex mhw-div
++
++Enable or disable emitting @code{mul}, @code{mulx} and @code{div} family of
++instructions by the compiler. The default is to emit @code{mul}
++and not emit @code{div} and @code{mulx}.
++
++The different combinations of @code{mul} and @code{mulx} instructions
++generate a different multilib options.
++
++
++@item -msys-crt0=@var{startfile}
++@opindex msys-crt0
++
++@var{startfile} is the file name of the startfile (crt0) to use
++when linking. The default is crt0.o that comes with libgloss
++and is only suitable for use with the instruction set
++simulator.
++
++@item -msys-lib=@var{systemlib}
++@itemx -msys-lib=nosys
++@opindex msys-lib
++
++@var{systemlib} is the library name of the library which provides
++the system calls required by the C library, e.g. @code{read}, @code{write}
++etc. The default is to use nosys, this library provides
++stub implementations of the calls and is part of libgloss.
++
++@end table
++
++
+ @node M680x0 Options
+ @subsection M680x0 Options
+ @cindex M680x0 options
+--- gcc-3.4.3/gcc/doc/md.texi
++++ gcc-3.4.3-nios2/gcc/doc/md.texi
+@@ -1335,6 +1335,49 @@ However, here is a summary of the machin
+ available on some particular machines.
+
+ @table @emph
++
++@item Altera Nios II family---@file{nios2.h}
++@table @code
++
++@item I
++Integer that is valid as an immediate operand in an
++instruction taking a signed 16-bit number. Range
++@minus{}32768 to 32767.
++
++@item J
++Integer that is valid as an immediate operand in an
++instruction taking an unsigned 16-bit number. Range
++0 to 65535.
++
++@item K
++Integer that is valid as an immediate operand in an
++instruction taking only the upper 16-bits of a
++32-bit number. Range 32-bit numbers with the lower
++16-bits being 0.
++
++@item L
++Integer that is valid as an immediate operand for a
++shift instruction. Range 0 to 31.
++
++
++@item M
++Integer that is valid as an immediate operand for
++only the value 0. Can be used in conjunction with
++the format modifier @code{z} to use @code{r0}
++instead of @code{0} in the assembly output.
++
++@item N
++Integer that is valid as an immediate operand for
++a custom instruction opcode. Range 0 to 255.
++
++@item S
++Matches immediates which are addresses in the small
++data section and therefore can be added to @code{gp}
++as a 16-bit immediate to re-create their 32-bit value.
++
++@end table
++
++
+ @item ARM family---@file{arm.h}
+ @table @code
+ @item f
diff --git a/misc/buildroot/toolchain/gcc/3.4.6/910-gcc-3.4.6-ocreatmode.patch b/misc/buildroot/toolchain/gcc/3.4.6/910-gcc-3.4.6-ocreatmode.patch
new file mode 100644
index 000000000..d6d7c1a8d
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.4.6/910-gcc-3.4.6-ocreatmode.patch
@@ -0,0 +1,12 @@
+diff -u gcc-3.4.6/gcc/collect2.c.orig gcc-3.4.6/gcc/collect2.c
+--- gcc-3.4.6/gcc/collect2.c.orig 2009-05-05 20:37:56.000000000 -0600
++++ gcc-3.4.6/gcc/collect2.c 2009-05-05 20:39:06.000000000 -0600
+@@ -1534,7 +1534,7 @@
+ if (redir)
+ {
+ /* Open response file. */
+- redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT);
++ redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT, 0666);
+
+ /* Duplicate the stdout and stderr file handles
+ so they can be restored later. */
diff --git a/misc/buildroot/toolchain/gcc/3.4.6/arm-softfloat.patch.conditional b/misc/buildroot/toolchain/gcc/3.4.6/arm-softfloat.patch.conditional
new file mode 100644
index 000000000..19d1b90da
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/3.4.6/arm-softfloat.patch.conditional
@@ -0,0 +1,270 @@
+Note... modified my mjn3 to not conflict with the big endian arm patch.
+Warning!!! Only the linux target is aware of TARGET_ENDIAN_DEFAULT.
+Also changed
+ #define SUBTARGET_EXTRA_ASM_SPEC "\
+ %{!mcpu=*:-mcpu=xscale} \
+ %{mhard-float:-mfpu=fpa} \
+ %{!mhard-float: %{msoft-float:-mfpu=softfpa} %{!msoft-float:-mfpu=softvfp}}"
+to
+ #define SUBTARGET_EXTRA_ASM_SPEC "\
+ %{mhard-float:-mfpu=fpa} \
+ %{!mhard-float: %{msoft-float:-mfpu=softfpa} %{!msoft-float:-mfpu=softvfp}}"
+in gcc/config/arm/linux-elf.h.
+#
+# Submitted:
+#
+# Dimitry Andric <dimitry@andric.com>, 2004-05-01
+#
+# Description:
+#
+# Nicholas Pitre released this patch for gcc soft-float support here:
+# http://lists.arm.linux.org.uk/pipermail/linux-arm/2003-October/006436.html
+#
+# This version has been adapted to work with gcc 3.4.0.
+#
+# The original patch doesn't distinguish between softfpa and softvfp modes
+# in the way Nicholas Pitre probably meant. His description is:
+#
+# "Default is to use APCS-32 mode with soft-vfp. The old Linux default for
+# floats can be achieved with -mhard-float or with the configure
+# --with-float=hard option. If -msoft-float or --with-float=soft is used then
+# software float support will be used just like the default but with the legacy
+# big endian word ordering for double float representation instead."
+#
+# Which means the following:
+#
+# * If you compile without -mhard-float or -msoft-float, you should get
+# software floating point, using the VFP format. The produced object file
+# should have these flags in its header:
+#
+# private flags = 600: [APCS-32] [VFP float format] [software FP]
+#
+# * If you compile with -mhard-float, you should get hardware floating point,
+# which always uses the FPA format. Object file header flags should be:
+#
+# private flags = 0: [APCS-32] [FPA float format]
+#
+# * If you compile with -msoft-float, you should get software floating point,
+# using the FPA format. This is done for compatibility reasons with many
+# existing distributions. Object file header flags should be:
+#
+# private flags = 200: [APCS-32] [FPA float format] [software FP]
+#
+# The original patch from Nicholas Pitre contained the following constructs:
+#
+# #define SUBTARGET_EXTRA_ASM_SPEC "%{!mcpu=*:-mcpu=xscale} \
+# %{mhard-float:-mfpu=fpa} \
+# %{!mhard-float: %{msoft-float:-mfpu=softfpa;:-mfpu=softvfp}}"
+#
+# However, gcc doesn't accept this ";:" notation, used in the 3rd line. This
+# is probably the reason Robert Schwebel modified it to:
+#
+# #define SUBTARGET_EXTRA_ASM_SPEC "%{!mcpu=*:-mcpu=xscale} \
+# %{mhard-float:-mfpu=fpa} \
+# %{!mhard-float: %{msoft-float:-mfpu=softfpa -mfpu=softvfp}}"
+#
+# But this causes the following behaviour:
+#
+# * If you compile without -mhard-float or -msoft-float, the compiler generates
+# software floating point instructions, but *nothing* is passed to the
+# assembler, which results in an object file which has flags:
+#
+# private flags = 0: [APCS-32] [FPA float format]
+#
+# This is not correct!
+#
+# * If you compile with -mhard-float, the compiler generates hardware floating
+# point instructions, and passes "-mfpu=fpa" to the assembler, which results
+# in an object file which has the same flags as in the previous item, but now
+# those *are* correct.
+#
+# * If you compile with -msoft-float, the compiler generates software floating
+# point instructions, and passes "-mfpu=softfpa -mfpu=softvfp" (in that
+# order) to the assembler, which results in an object file with flags:
+#
+# private flags = 600: [APCS-32] [VFP float format] [software FP]
+#
+# This is not correct, because the last "-mfpu=" option on the assembler
+# command line determines the actual FPU convention used (which should be FPA
+# in this case).
+#
+# Therefore, I modified this patch to get the desired behaviour. Every
+# instance of the notation:
+#
+# %{msoft-float:-mfpu=softfpa -mfpu=softvfp}
+#
+# was changed to:
+#
+# %{msoft-float:-mfpu=softfpa} %{!msoft-float:-mfpu=softvfp}
+#
+# I also did the following:
+#
+# * Modified all TARGET_DEFAULT macros I could find to include ARM_FLAG_VFP, to
+# be consistent with Nicholas' original patch.
+# * Removed any "msoft-float" or "mhard-float" from all MULTILIB_DEFAULTS
+# macros I could find. I think that if you compile without any options, you
+# would like to get the defaults. :)
+# * Removed the extra -lfloat option from LIBGCC_SPEC, since it isn't needed
+# anymore. (The required functions are now in libgcc.)
+
+diff -urN gcc-3.4.1-old/gcc/config/arm/coff.h gcc-3.4.1/gcc/config/arm/coff.h
+--- gcc-3.4.1-old/gcc/config/arm/coff.h 2004-02-24 08:25:22.000000000 -0600
++++ gcc-3.4.1/gcc/config/arm/coff.h 2004-09-02 21:51:15.000000000 -0500
+@@ -31,11 +31,16 @@
+ #define TARGET_VERSION fputs (" (ARM/coff)", stderr)
+
+ #undef TARGET_DEFAULT
+-#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
++#define TARGET_DEFAULT \
++ ( ARM_FLAG_SOFT_FLOAT \
++ | ARM_FLAG_VFP \
++ | ARM_FLAG_APCS_32 \
++ | ARM_FLAG_APCS_FRAME \
++ | ARM_FLAG_MMU_TRAPS )
+
+ #ifndef MULTILIB_DEFAULTS
+ #define MULTILIB_DEFAULTS \
+- { "marm", "mlittle-endian", "msoft-float", "mapcs-32", "mno-thumb-interwork" }
++ { "marm", "mlittle-endian", "mapcs-32", "mno-thumb-interwork" }
+ #endif
+
+ /* This is COFF, but prefer stabs. */
+diff -urN gcc-3.4.1-old/gcc/config/arm/elf.h gcc-3.4.1/gcc/config/arm/elf.h
+--- gcc-3.4.1-old/gcc/config/arm/elf.h 2004-02-24 08:25:22.000000000 -0600
++++ gcc-3.4.1/gcc/config/arm/elf.h 2004-09-02 21:51:15.000000000 -0500
+@@ -46,7 +46,9 @@
+
+ #ifndef SUBTARGET_ASM_FLOAT_SPEC
+ #define SUBTARGET_ASM_FLOAT_SPEC "\
+-%{mapcs-float:-mfloat} %{msoft-float:-mfpu=softfpa}"
++%{mapcs-float:-mfloat} \
++%{mhard-float:-mfpu=fpa} \
++%{!mhard-float: %{msoft-float:-mfpu=softfpa} %{!msoft-float:-mfpu=softvfp}}"
+ #endif
+
+ #ifndef ASM_SPEC
+@@ -106,12 +108,17 @@
+ #endif
+
+ #ifndef TARGET_DEFAULT
+-#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
++#define TARGET_DEFAULT \
++ ( ARM_FLAG_SOFT_FLOAT \
++ | ARM_FLAG_VFP \
++ | ARM_FLAG_APCS_32 \
++ | ARM_FLAG_APCS_FRAME \
++ | ARM_FLAG_MMU_TRAPS )
+ #endif
+
+ #ifndef MULTILIB_DEFAULTS
+ #define MULTILIB_DEFAULTS \
+- { "marm", "mlittle-endian", "msoft-float", "mapcs-32", "mno-thumb-interwork", "fno-leading-underscore" }
++ { "marm", "mlittle-endian", "mapcs-32", "mno-thumb-interwork", "fno-leading-underscore" }
+ #endif
+
+ #define TARGET_ASM_FILE_START_APP_OFF true
+diff -urN gcc-3.4.1-old/gcc/config/arm/linux-elf.h gcc-3.4.1/gcc/config/arm/linux-elf.h
+--- gcc-3.4.1-old/gcc/config/arm/linux-elf.h 2004-09-02 21:50:52.000000000 -0500
++++ gcc-3.4.1/gcc/config/arm/linux-elf.h 2004-09-02 22:00:49.000000000 -0500
+@@ -44,12 +44,26 @@
+ #define TARGET_LINKER_EMULATION "armelf_linux"
+ #endif
+
+-/* Default is to use APCS-32 mode. */
++/*
++ * Default is to use APCS-32 mode with soft-vfp.
++ * The old Linux default for floats can be achieved with -mhard-float
++ * or with the configure --with-float=hard option.
++ * If -msoft-float or --with-float=soft is used then software float
++ * support will be used just like the default but with the legacy
++ * big endian word ordering for double float representation instead.
++ */
+ #undef TARGET_DEFAULT
+-#define TARGET_DEFAULT \
+- ( ARM_FLAG_APCS_32 | \
+- ARM_FLAG_MMU_TRAPS | \
+- TARGET_ENDIAN_DEFAULT )
++#define TARGET_DEFAULT \
++ ( ARM_FLAG_APCS_32 \
++ | ARM_FLAG_SOFT_FLOAT \
++ | TARGET_ENDIAN_DEFAULT \
++ | ARM_FLAG_VFP \
++ | ARM_FLAG_MMU_TRAPS )
++
++#undef SUBTARGET_EXTRA_ASM_SPEC
++#define SUBTARGET_EXTRA_ASM_SPEC "\
++%{mhard-float:-mfpu=fpa} \
++%{!mhard-float: %{msoft-float:-mfpu=softfpa} %{!msoft-float:-mfpu=softvfp}}"
+
+ #define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm6
+
+@@ -57,7 +71,7 @@
+
+ #undef MULTILIB_DEFAULTS
+ #define MULTILIB_DEFAULTS \
+- { "marm", TARGET_ENDIAN_OPTION, "mhard-float", "mapcs-32", "mno-thumb-interwork" }
++ { "marm", TARGET_ENDIAN_OPTION, "mapcs-32", "mno-thumb-interwork" }
+
+ #define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__"
+
+@@ -72,7 +86,7 @@
+ %{shared:-lc} \
+ %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
+
+-#define LIBGCC_SPEC "%{msoft-float:-lfloat} -lgcc"
++#define LIBGCC_SPEC "-lgcc"
+
+ /* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add
+ the GNU/Linux magical crtbegin.o file (see crtstuff.c) which
+diff -urN gcc-3.4.1-old/gcc/config/arm/t-linux gcc-3.4.1/gcc/config/arm/t-linux
+--- gcc-3.4.1-old/gcc/config/arm/t-linux 2003-09-20 16:09:07.000000000 -0500
++++ gcc-3.4.1/gcc/config/arm/t-linux 2004-09-02 21:51:15.000000000 -0500
+@@ -4,7 +4,10 @@
+ LIBGCC2_DEBUG_CFLAGS = -g0
+
+ LIB1ASMSRC = arm/lib1funcs.asm
+-LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
++LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx \
++ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
++ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
++ _fixsfsi _fixunssfsi
+
+ # MULTILIB_OPTIONS = mhard-float/msoft-float
+ # MULTILIB_DIRNAMES = hard-float soft-float
+diff -urN gcc-3.4.1-old/gcc/config/arm/unknown-elf.h gcc-3.4.1/gcc/config/arm/unknown-elf.h
+--- gcc-3.4.1-old/gcc/config/arm/unknown-elf.h 2004-02-24 08:25:22.000000000 -0600
++++ gcc-3.4.1/gcc/config/arm/unknown-elf.h 2004-09-02 21:51:15.000000000 -0500
+@@ -30,7 +30,12 @@
+
+ /* Default to using APCS-32 and software floating point. */
+ #ifndef TARGET_DEFAULT
+-#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
++#define TARGET_DEFAULT \
++ ( ARM_FLAG_SOFT_FLOAT \
++ | ARM_FLAG_VFP \
++ | ARM_FLAG_APCS_32 \
++ | ARM_FLAG_APCS_FRAME \
++ | ARM_FLAG_MMU_TRAPS )
+ #endif
+
+ /* Now we define the strings used to build the spec file. */
+diff -urN gcc-3.4.1-old/gcc/config/arm/xscale-elf.h gcc-3.4.1/gcc/config/arm/xscale-elf.h
+--- gcc-3.4.1-old/gcc/config/arm/xscale-elf.h 2003-07-01 18:26:43.000000000 -0500
++++ gcc-3.4.1/gcc/config/arm/xscale-elf.h 2004-09-02 21:51:15.000000000 -0500
+@@ -49,11 +49,12 @@
+ endian, regardless of the endian-ness of the memory
+ system. */
+
+-#define SUBTARGET_EXTRA_ASM_SPEC "%{!mcpu=*:-mcpu=xscale} \
+- %{mhard-float:-mfpu=fpa} \
+- %{!mhard-float: %{msoft-float:-mfpu=softfpa;:-mfpu=softvfp}}"
++#define SUBTARGET_EXTRA_ASM_SPEC "\
++%{!mcpu=*:-mcpu=xscale} \
++%{mhard-float:-mfpu=fpa} \
++%{!mhard-float: %{msoft-float:-mfpu=softfpa} %{!msoft-float:-mfpu=softvfp}}"
+
+ #ifndef MULTILIB_DEFAULTS
+ #define MULTILIB_DEFAULTS \
+- { "mlittle-endian", "mno-thumb-interwork", "marm", "msoft-float" }
++ { "mlittle-endian", "mno-thumb-interwork", "marm" }
+ #endif
diff --git a/misc/buildroot/toolchain/gcc/4.2.4/300-libstdc++-pic.patch b/misc/buildroot/toolchain/gcc/4.2.4/300-libstdc++-pic.patch
new file mode 100644
index 000000000..560bcb237
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.2.4/300-libstdc++-pic.patch
@@ -0,0 +1,50 @@
+# DP: Build and install libstdc++_pic.a library.
+
+--- gcc/libstdc++-v3/src/Makefile.am
++++ gcc/libstdc++-v3/src/Makefile.am
+@@ -214,6 +214,12 @@
+ $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LDFLAGS) -o $@
+
+
++install-exec-local:
++ifeq ($(enable_shared),yes)
++ $(AR) cru libstdc++_pic.a .libs/*.o $(top_builddir)/libsupc++/*.o
++ $(INSTALL_DATA) libstdc++_pic.a $(DESTDIR)$(toolexeclibdir)
++endif
++
+ # Added bits to build debug library.
+ if GLIBCXX_BUILD_DEBUG
+ all-local: build_debug
+--- gcc/libstdc++-v3/src/Makefile.in
++++ gcc/libstdc++-v3/src/Makefile.in
+@@ -627,7 +627,7 @@
+
+ install-data-am: install-data-local
+
+-install-exec-am: install-toolexeclibLTLIBRARIES
++install-exec-am: install-toolexeclibLTLIBRARIES install-exec-local
+
+ install-info: install-info-am
+
+@@ -660,6 +660,7 @@
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-data-local install-exec \
++ install-exec-local \
+ install-exec-am install-info install-info-am install-man \
+ install-strip install-toolexeclibLTLIBRARIES installcheck \
+ installcheck-am installdirs maintainer-clean \
+@@ -743,6 +743,13 @@
+ install_debug:
+ (cd ${debugdir} && $(MAKE) \
+ toolexeclibdir=$(glibcxx_toolexeclibdir)/debug install)
++
++install-exec-local:
++ifeq ($(enable_shared),yes)
++ $(AR) cru libstdc++_pic.a *.o $(top_builddir)/libsupc++/*.o
++ $(INSTALL_DATA) libstdc++_pic.a $(DESTDIR)$(toolexeclibdir)
++endif
++
+ # Tell versions [3.59,3.63) of GNU make to not export all variables.
+ # Otherwise a system limit (for SysV at least) may be exceeded.
+ .NOEXPORT:
diff --git a/misc/buildroot/toolchain/gcc/4.2.4/304-index_macro.patch b/misc/buildroot/toolchain/gcc/4.2.4/304-index_macro.patch
new file mode 100644
index 000000000..d8e476555
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.2.4/304-index_macro.patch
@@ -0,0 +1,24 @@
+--- gcc-4.1.0/libstdc++-v3/include/ext/rope.mps 2006-03-24 01:49:51 +0100
++++ gcc-4.1.0/libstdc++-v3/include/ext/rope 2006-03-24 01:49:37 +0100
+@@ -59,6 +59,9 @@
+ #include <bits/allocator.h>
+ #include <ext/hash_fun.h>
+
++/* cope w/ index defined as macro, SuSv3 proposal */
++#undef index
++
+ # ifdef __GC
+ # define __GC_CONST const
+ # else
+--- gcc-4.1.0/libstdc++-v3/include/ext/ropeimpl.h.mps 2006-03-24 01:50:04 +0100
++++ gcc-4.1.0/libstdc++-v3/include/ext/ropeimpl.h 2006-03-24 01:50:28 +0100
+@@ -53,6 +53,9 @@
+ #include <ext/memory> // For uninitialized_copy_n
+ #include <ext/numeric> // For power
+
++/* cope w/ index defined as macro, SuSv3 proposal */
++#undef index
++
+ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
+
+ using std::size_t;
diff --git a/misc/buildroot/toolchain/gcc/4.2.4/305-libmudflap-susv3-legacy.patch b/misc/buildroot/toolchain/gcc/4.2.4/305-libmudflap-susv3-legacy.patch
new file mode 100644
index 000000000..374b1f865
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.2.4/305-libmudflap-susv3-legacy.patch
@@ -0,0 +1,49 @@
+Index: gcc-4.2/libmudflap/mf-hooks2.c
+===================================================================
+--- gcc-4.2/libmudflap/mf-hooks2.c (revision 119834)
++++ gcc-4.2/libmudflap/mf-hooks2.c (working copy)
+@@ -427,7 +427,7 @@
+ {
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
+- bzero (s, n);
++ memset (s, 0, n);
+ }
+
+
+@@ -437,7 +437,7 @@
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
+ MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
+- bcopy (src, dest, n);
++ memmove (dest, src, n);
+ }
+
+
+@@ -447,7 +447,7 @@
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
+ MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
+- return bcmp (s1, s2, n);
++ return n == 0 ? 0 : memcmp (s1, s2, n);
+ }
+
+
+@@ -456,7 +456,7 @@
+ size_t n = strlen (s);
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
+- return index (s, c);
++ return strchr (s, c);
+ }
+
+
+@@ -465,7 +465,7 @@
+ size_t n = strlen (s);
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
+- return rindex (s, c);
++ return strrchr (s, c);
+ }
+
+ /* XXX: stpcpy, memccpy */
diff --git a/misc/buildroot/toolchain/gcc/4.2.4/307-locale_facets.patch b/misc/buildroot/toolchain/gcc/4.2.4/307-locale_facets.patch
new file mode 100644
index 000000000..412f8657d
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.2.4/307-locale_facets.patch
@@ -0,0 +1,26 @@
+This patch fixes a bug into ostream::operator<<(double) due to the wrong size
+passed into the __convert_from_v method. The wrong size is then passed to
+std::snprintf function, that, on uClibc, doens't handle sized 0 buffer.
+
+Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
+
+--- gcc-4.2.1/libstdc++-v3/include/bits/locale_facets.tcc 2006-10-17 18:43:47.000000000 +0200
++++ gcc-4.2.1-st/libstdc++-v3/include/bits/locale_facets.tcc 2007-08-22 18:54:23.000000000 +0200
+@@ -1143,7 +1143,7 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
+ const int __cs_size = __fixed ? __max_exp + __prec + 4
+ : __max_digits * 2 + __prec;
+ char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+- __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, __fbuf,
++ __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, __fbuf,
+ __prec, __v);
+ #endif
+
+@@ -1777,7 +1777,7 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
+ // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
+ const int __cs_size = numeric_limits<long double>::max_exponent10 + 3;
+ char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
+- int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf",
++ int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, "%.*Lf",
+ 0, __units);
+ #endif
+ string_type __digits(__len, char_type());
diff --git a/misc/buildroot/toolchain/gcc/4.2.4/402-libbackend_dep_gcov-iov.h.patch b/misc/buildroot/toolchain/gcc/4.2.4/402-libbackend_dep_gcov-iov.h.patch
new file mode 100644
index 000000000..0bf115c45
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.2.4/402-libbackend_dep_gcov-iov.h.patch
@@ -0,0 +1,13 @@
+Index: gcc-4.2/gcc/Makefile.in
+===================================================================
+--- gcc-4.2/gcc/Makefile.in (revision 121758)
++++ gcc-4.2/gcc/Makefile.in (working copy)
+@@ -2658,7 +2658,7 @@ mips-tdump.o : mips-tdump.c $(CONFIG_H)
+ # FIXME: writing proper dependencies for this is a *LOT* of work.
+ libbackend.o : $(OBJS-common:.o=.c) $(out_file) \
+ insn-config.h insn-flags.h insn-codes.h insn-constants.h \
+- insn-attr.h $(DATESTAMP) $(BASEVER) $(DEVPHASE)
++ insn-attr.h $(DATESTAMP) $(BASEVER) $(DEVPHASE) gcov-iov.h
+ $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
+ -DTARGET_NAME=\"$(target_noncanonical)\" \
+ -DLOCALEDIR=\"$(localedir)\" \
diff --git a/misc/buildroot/toolchain/gcc/4.2.4/800-arm-bigendian.patch b/misc/buildroot/toolchain/gcc/4.2.4/800-arm-bigendian.patch
new file mode 100644
index 000000000..07c609337
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.2.4/800-arm-bigendian.patch
@@ -0,0 +1,67 @@
+By Lennert Buytenhek <buytenh@wantstofly.org>
+Adds support for arm*b-linux* big-endian ARM targets
+
+See http://gcc.gnu.org/PR16350
+
+--- gcc-4.2.0/gcc/config/arm/linux-elf.h
++++ gcc-4.2.0/gcc/config/arm/linux-elf.h
+@@ -28,19 +28,33 @@
+ #undef TARGET_VERSION
+ #define TARGET_VERSION fputs (" (ARM GNU/Linux with ELF)", stderr);
+
++/*
++ * 'config.gcc' defines TARGET_BIG_ENDIAN_DEFAULT as 1 for arm*b-*
++ * (big endian) configurations.
++ */
++#if TARGET_BIG_ENDIAN_DEFAULT
++#define TARGET_ENDIAN_DEFAULT MASK_BIG_END
++#define TARGET_ENDIAN_OPTION "mbig-endian"
++#define TARGET_LINKER_EMULATION "armelfb_linux"
++#else
++#define TARGET_ENDIAN_DEFAULT 0
++#define TARGET_ENDIAN_OPTION "mlittle-endian"
++#define TARGET_LINKER_EMULATION "armelf_linux"
++#endif
++
+ #undef TARGET_DEFAULT_FLOAT_ABI
+ #define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_HARD
+
+ #undef TARGET_DEFAULT
+-#define TARGET_DEFAULT (0)
++#define TARGET_DEFAULT (TARGET_ENDIAN_DEFAULT)
+
+ #define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm6
+
+-#define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux -p"
++#define SUBTARGET_EXTRA_LINK_SPEC " -m " TARGET_LINKER_EMULATION " -p"
+
+ #undef MULTILIB_DEFAULTS
+ #define MULTILIB_DEFAULTS \
+- { "marm", "mlittle-endian", "mhard-float", "mno-thumb-interwork" }
++ { "marm", TARGET_ENDIAN_OPTION, "mhard-float", "mno-thumb-interwork" }
+
+ /* Now we define the strings used to build the spec file. */
+ #undef LIB_SPEC
+@@ -61,7 +75,7 @@
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker " LINUX_DYNAMIC_LINKER "} \
+ -X \
+- %{mbig-endian:-EB}" \
++ %{mbig-endian:-EB} %{mlittle-endian:-EL}" \
+ SUBTARGET_EXTRA_LINK_SPEC
+
+ #undef LINK_SPEC
+--- gcc-4.2.0/gcc/config.gcc.orig 2006-09-22 14:53:41.000000000 +0200
++++ gcc-4.2.0/gcc/config.gcc 2006-09-25 10:45:21.000000000 +0200
+@@ -696,6 +696,11 @@
+ tm_file="dbxelf.h elfos.h linux.h arm/elf.h arm/linux-gas.h arm/linux-elf.h"
+ tmake_file="${tmake_file} t-linux arm/t-arm"
+ case ${target} in
++ arm*b-*)
++ tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
++ ;;
++ esac
++ case ${target} in
+ arm*-*-linux-*eabi)
+ tm_file="$tm_file arm/bpabi.h arm/linux-eabi.h"
+ tmake_file="$tmake_file arm/t-arm-elf arm/t-bpabi arm/t-linux-eabi"
diff --git a/misc/buildroot/toolchain/gcc/4.2.4/904-flatten-switch-stmt-00.patch b/misc/buildroot/toolchain/gcc/4.2.4/904-flatten-switch-stmt-00.patch
new file mode 100644
index 000000000..8fac37c4d
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.2.4/904-flatten-switch-stmt-00.patch
@@ -0,0 +1,153 @@
+Hi,
+
+The attached patch makes sure that we create smaller object code for
+simple switch statements. We just make sure to flatten the switch
+statement into an if-else chain, basically.
+
+This fixes a size-regression as compared to gcc-3.4, as can be seen
+below.
+
+2007-04-15 Bernhard Fischer <..>
+
+ * stmt.c (expand_case): Do not create a complex binary tree when
+ optimizing for size but rather use the simple ordered list.
+ (emit_case_nodes): do not emit jumps to the default_label when
+ optimizing for size.
+
+Not regtested so far.
+Comments?
+
+Attached is the test switch.c mentioned below.
+
+$ for i in 2.95 3.3 3.4 4.0 4.1 4.2.orig-HEAD 4.3.orig-HEAD 4.3-HEAD;do
+gcc-$i -DCHAIN -Os -o switch-CHAIN-$i.o -c switch.c ;done
+$ for i in 2.95 3.3 3.4 4.0 4.1 4.2.orig-HEAD 4.3.orig-HEAD 4.3-HEAD;do
+gcc-$i -UCHAIN -Os -o switch-$i.o -c switch.c ;done
+
+$ size switch-*.o
+ text data bss dec hex filename
+ 169 0 0 169 a9 switch-2.95.o
+ 115 0 0 115 73 switch-3.3.o
+ 103 0 0 103 67 switch-3.4.o
+ 124 0 0 124 7c switch-4.0.o
+ 124 0 0 124 7c switch-4.1.o
+ 124 0 0 124 7c switch-4.2.orig-HEAD.o
+ 95 0 0 95 5f switch-4.3-HEAD.o
+ 124 0 0 124 7c switch-4.3.orig-HEAD.o
+ 166 0 0 166 a6 switch-CHAIN-2.95.o
+ 111 0 0 111 6f switch-CHAIN-3.3.o
+ 95 0 0 95 5f switch-CHAIN-3.4.o
+ 95 0 0 95 5f switch-CHAIN-4.0.o
+ 95 0 0 95 5f switch-CHAIN-4.1.o
+ 95 0 0 95 5f switch-CHAIN-4.2.orig-HEAD.o
+ 95 0 0 95 5f switch-CHAIN-4.3-HEAD.o
+ 95 0 0 95 5f switch-CHAIN-4.3.orig-HEAD.o
+
+
+Content-Type: text/x-diff; charset=us-ascii
+Content-Disposition: attachment; filename="gcc-4.3.gcc-flatten-switch-stmt.00.diff"
+
+Index: gcc-4.2.0/gcc/stmt.c
+===================================================================
+--- gcc-4.2.0.orig/gcc/stmt.c (revision 123843)
++++ gcc-4.2.0/gcc/stmt.c (working copy)
+@@ -2517,7 +2517,11 @@ expand_case (tree exp)
+ use_cost_table
+ = (TREE_CODE (orig_type) != ENUMERAL_TYPE
+ && estimate_case_costs (case_list));
+- balance_case_nodes (&case_list, NULL);
++ /* When optimizing for size, we want a straight list to avoid
++ jumps as much as possible. This basically creates an if-else
++ chain. */
++ if (!optimize_size)
++ balance_case_nodes (&case_list, NULL);
+ emit_case_nodes (index, case_list, default_label, index_type);
+ emit_jump (default_label);
+ }
+@@ -3075,6 +3079,7 @@ emit_case_nodes (rtx index, case_node_pt
+ {
+ if (!node_has_low_bound (node, index_type))
+ {
++ if (!optimize_size) /* don't jl to the .default_label. */
+ emit_cmp_and_jump_insns (index,
+ convert_modes
+ (mode, imode,
+
+
+Content-Type: text/x-csrc; charset=us-ascii
+Content-Disposition: attachment; filename="switch.c"
+
+int
+commutative_tree_code (int code)
+{
+#define CASE(val, ret) case val:/* __asm__("# val="#val ",ret="#ret);*/ return ret;
+#ifndef CHAIN
+ switch (code)
+ {
+# if 1
+ CASE(1,3)
+ CASE(3,2)
+ CASE(5,8)
+ CASE(7,1)
+ CASE(33,4)
+ CASE(44,9)
+ CASE(55,10)
+ CASE(66,-1)
+ CASE(77,99)
+ CASE(666,0)
+# else
+ case 1:
+ return 3;
+ case 3:
+ return 2;
+ case 5:
+ return 8;
+ case 7:
+ return 1;
+ case 33:
+ return 4;
+ case 44:
+ return 9;
+ case 55:
+ return 10;
+ case 66:
+ return -1;
+ case 77:
+ return 99;
+ case 666:
+ return 0;
+# endif
+ default:
+ break;
+ }
+ return 4711;
+
+#else
+ if (code == 1)
+ return 3;
+ else if (code == 3)
+ return 2;
+ else if (code == 5)
+ return 8;
+ else if (code == 7)
+ return 1;
+ else if (code == 33)
+ return 4;
+ else if (code == 44)
+ return 9;
+ else if (code == 55)
+ return 10;
+ else if (code == 66)
+ return -1;
+ else if (code == 77)
+ return 99;
+ else if (code == 666)
+ return 0;
+ else
+ return 4711;
+#endif
+}
+
+
+--AhhlLboLdkugWU4S--
+
diff --git a/misc/buildroot/toolchain/gcc/4.2.4/910-soft-float.patch b/misc/buildroot/toolchain/gcc/4.2.4/910-soft-float.patch
new file mode 100644
index 000000000..3f886acbf
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.2.4/910-soft-float.patch
@@ -0,0 +1,26 @@
+--- gcc-4.2-20061205/gcc/config/arm/t-linux 2006-12-08 15:18:33.000000000 -0800
++++ gcc-4.2-20061205/gcc/config/arm/t-linux 2006-12-08 15:18:33.000000000 -0800
+@@ -4,7 +4,10 @@
+ LIBGCC2_DEBUG_CFLAGS = -g0
+
+ LIB1ASMSRC = arm/lib1funcs.asm
+-LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
++LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx \
++ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
++ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
++ _fixsfsi _fixunssfsi _floatdidf _floatundidf _floatdisf _floatundisf
+
+ # MULTILIB_OPTIONS = mhard-float/msoft-float
+ # MULTILIB_DIRNAMES = hard-float soft-float
+
+--- gcc-4.2-20061205/gcc/config/arm/linux-elf.h 2006-12-08 15:18:33.000000000 -0800
++++ gcc-4.2-20061205/gcc/config/arm/linux-elf.h 2006-12-08 15:18:33.000000000 -0800
+@@ -63,7 +63,7 @@
+ %{shared:-lc} \
+ %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
+
+-#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc"
++#define LIBGCC_SPEC "-lgcc"
+
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
+
diff --git a/misc/buildroot/toolchain/gcc/4.2.4/920-soft-float.patch b/misc/buildroot/toolchain/gcc/4.2.4/920-soft-float.patch
new file mode 100644
index 000000000..4287bfae2
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.2.4/920-soft-float.patch
@@ -0,0 +1,21 @@
+diff -uNpr gcc-4.2.1_orig/gcc/config/rs6000/darwin-ldouble.c gcc-4.2.1/gcc/config/rs6000/darwin-ldouble.c
+--- gcc-4.2.1_orig/gcc/config/rs6000/darwin-ldouble.c 2007-03-05 11:54:00.000000000 -0500
++++ gcc-4.2.1/gcc/config/rs6000/darwin-ldouble.c 2008-01-31 17:51:24.000000000 -0500
+@@ -70,6 +70,8 @@ Software Foundation, 51 Franklin Street,
+ but GCC currently generates poor code when a union is used to turn
+ a long double into a pair of doubles. */
+
++#if defined (_SOFT_FLOAT) && defined (__LONG_DOUBLE_128__)
++
+ long double __gcc_qadd (double, double, double, double);
+ long double __gcc_qsub (double, double, double, double);
+ long double __gcc_qmul (double, double, double, double);
+@@ -219,8 +221,6 @@ __gcc_qdiv (double a, double b, double c
+ return z.ldval;
+ }
+
+-#if defined (_SOFT_FLOAT) && defined (__LONG_DOUBLE_128__)
+-
+ long double __gcc_qneg (double, double);
+ int __gcc_qeq (double, double, double, double);
+ int __gcc_qne (double, double, double, double);
diff --git a/misc/buildroot/toolchain/gcc/4.2.4/930-nuttx-nolibc.patch b/misc/buildroot/toolchain/gcc/4.2.4/930-nuttx-nolibc.patch
new file mode 100644
index 000000000..4503ed619
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.2.4/930-nuttx-nolibc.patch
@@ -0,0 +1,30 @@
+At present, libstdc++ will not build. My understanding is that it needs to have
+the NuttX libc characterized in crossconfig.m4. This is a first attempt to do that --
+unfortunately, it still does not work.
+
+diff -u gcc-4.2.4/libstdc++-v3/configure.orig gcc-4.2.4/libstdc++-v3/configure
+--- gcc-4.2.4/libstdc++-v3/configure.orig 2009-01-05 17:52:11.000000000 -0600
++++ gcc-4.2.4/libstdc++-v3/configure 2009-01-05 17:52:43.000000000 -0600
+@@ -108515,9 +108515,7 @@
+
+ ;;
+ *)
+- { { echo "$as_me:$LINENO: error: No support for this host/target combination." >&5
+-echo "$as_me: error: No support for this host/target combination." >&2;}
+- { (exit 1); exit 1; }; }
++ # Assume bare hardware
+ ;;
+ esac
+
+diff -u gcc-4.2.4/libstdc++-v3/crossconfig.m4.orig gcc-4.2.4/libstdc++-v3/crossconfig.m4
+--- gcc-4.2.4/libstdc++-v3/crossconfig.m4.orig 2009-01-05 17:51:07.000000000 -0600
++++ gcc-4.2.4/libstdc++-v3/crossconfig.m4 2009-01-05 17:52:02.000000000 -0600
+@@ -412,7 +412,7 @@
+ AC_DEFINE(HAVE_TANHL)
+ ;;
+ *)
+- AC_MSG_ERROR([No support for this host/target combination.])
++ # Assume bare hardware
+ ;;
+ esac
+ ])
diff --git a/misc/buildroot/toolchain/gcc/4.2.4/940-nuttx-nolibstdc.patch b/misc/buildroot/toolchain/gcc/4.2.4/940-nuttx-nolibstdc.patch
new file mode 100644
index 000000000..1e25fd001
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.2.4/940-nuttx-nolibstdc.patch
@@ -0,0 +1,13 @@
+--- gcc-4.2.4/configure.orig 2009-04-18 18:07:18.250951700 -0400
++++ gcc-4.2.4/configure 2009-04-18 18:20:20.369521100 -0400
+@@ -1649,6 +1649,10 @@
+ ;;
+ esac
+
++# If we are building against NuttX, then don't attempt to build libstdc++
++# (should be conditioned on --with-nuttx)
++noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3"
++
+ # If we aren't building newlib, then don't build libgloss, since libgloss
+ # depends upon some newlib header files.
+ case "${noconfigdirs}" in
diff --git a/misc/buildroot/toolchain/gcc/4.3.3/300-libmudflap-susv3-legacy.patch b/misc/buildroot/toolchain/gcc/4.3.3/300-libmudflap-susv3-legacy.patch
new file mode 100644
index 000000000..374b1f865
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.3.3/300-libmudflap-susv3-legacy.patch
@@ -0,0 +1,49 @@
+Index: gcc-4.2/libmudflap/mf-hooks2.c
+===================================================================
+--- gcc-4.2/libmudflap/mf-hooks2.c (revision 119834)
++++ gcc-4.2/libmudflap/mf-hooks2.c (working copy)
+@@ -427,7 +427,7 @@
+ {
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
+- bzero (s, n);
++ memset (s, 0, n);
+ }
+
+
+@@ -437,7 +437,7 @@
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
+ MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
+- bcopy (src, dest, n);
++ memmove (dest, src, n);
+ }
+
+
+@@ -447,7 +447,7 @@
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
+ MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
+- return bcmp (s1, s2, n);
++ return n == 0 ? 0 : memcmp (s1, s2, n);
+ }
+
+
+@@ -456,7 +456,7 @@
+ size_t n = strlen (s);
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
+- return index (s, c);
++ return strchr (s, c);
+ }
+
+
+@@ -465,7 +465,7 @@
+ size_t n = strlen (s);
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
+- return rindex (s, c);
++ return strrchr (s, c);
+ }
+
+ /* XXX: stpcpy, memccpy */
diff --git a/misc/buildroot/toolchain/gcc/4.3.3/310-arm-softfloat-libgcc.patch b/misc/buildroot/toolchain/gcc/4.3.3/310-arm-softfloat-libgcc.patch
new file mode 100644
index 000000000..1639c39a8
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.3.3/310-arm-softfloat-libgcc.patch
@@ -0,0 +1,29 @@
+Index: gcc-4.3.0/gcc/config/arm/t-linux
+===================================================================
+--- gcc-4.3.0/gcc/config/arm/t-linux (revision 129896)
++++ gcc-4.3.0/gcc/config/arm/t-linux (working copy)
+@@ -3,7 +3,10 @@
+ TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC
+
+ LIB1ASMSRC = arm/lib1funcs.asm
+-LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
++LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx \
++ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
++ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
++ _fixsfsi _fixunssfsi _floatdidf _floatundidf _floatdisf _floatundisf
+
+ # MULTILIB_OPTIONS = mhard-float/msoft-float
+ # MULTILIB_DIRNAMES = hard-float soft-float
+Index: gcc-4.3.0/gcc/config/arm/linux-elf.h
+===================================================================
+--- gcc-4.3.0/gcc/config/arm/linux-elf.h (revision 129896)
++++ gcc-4.3.0/gcc/config/arm/linux-elf.h (working copy)
+@@ -48,7 +62,7 @@
+ %{shared:-lc} \
+ %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
+
+-#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc"
++#define LIBGCC_SPEC "-lgcc"
+
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
+
diff --git a/misc/buildroot/toolchain/gcc/4.3.3/500-backport-fix-for-bug-39076.patch b/misc/buildroot/toolchain/gcc/4.3.3/500-backport-fix-for-bug-39076.patch
new file mode 100644
index 000000000..f76e8ae0e
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.3.3/500-backport-fix-for-bug-39076.patch
@@ -0,0 +1,11 @@
+--- gcc-4.3.2.orig/gcc/regrename.c 2007-09-09 04:23:47.000000000 +0200
++++ gcc-4.3.2/gcc/regrename.c 2009-02-05 10:23:59.000000000 +0100
+@@ -813,7 +813,7 @@
+ OP_IN, 0);
+
+ for (i = 0; i < recog_data.n_dups; i++)
+- *recog_data.dup_loc[i] = copy_rtx (old_dups[i]);
++ *recog_data.dup_loc[i] = old_dups[i];
+ for (i = 0; i < n_ops; i++)
+ *recog_data.operand_loc[i] = old_operands[i];
+ if (recog_data.n_dups)
diff --git a/misc/buildroot/toolchain/gcc/4.3.3/510-backport-fix-for-bug-32044.patch b/misc/buildroot/toolchain/gcc/4.3.3/510-backport-fix-for-bug-32044.patch
new file mode 100644
index 000000000..9337bf9ee
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.3.3/510-backport-fix-for-bug-32044.patch
@@ -0,0 +1,188 @@
+Index: gcc-4.3.2/gcc/tree-scalar-evolution.c
+===================================================================
+--- gcc-4.3.2.orig/gcc/tree-scalar-evolution.c 2009-01-28 10:14:37.000000000 +0100
++++ gcc-4.3.2/gcc/tree-scalar-evolution.c 2009-01-28 10:17:50.000000000 +0100
+@@ -2716,6 +2716,50 @@
+ scalar_evolution_info = NULL;
+ }
+
++/* Returns true if the expression EXPR is considered to be too expensive
++ for scev_const_prop. */
++
++bool
++expression_expensive_p (tree expr)
++{
++ enum tree_code code;
++
++ if (is_gimple_val (expr))
++ return false;
++
++ code = TREE_CODE (expr);
++ if (code == TRUNC_DIV_EXPR
++ || code == CEIL_DIV_EXPR
++ || code == FLOOR_DIV_EXPR
++ || code == ROUND_DIV_EXPR
++ || code == TRUNC_MOD_EXPR
++ || code == CEIL_MOD_EXPR
++ || code == FLOOR_MOD_EXPR
++ || code == ROUND_MOD_EXPR
++ || code == EXACT_DIV_EXPR)
++ {
++ /* Division by power of two is usually cheap, so we allow it.
++ Forbid anything else. */
++ if (!integer_pow2p (TREE_OPERAND (expr, 1)))
++ return true;
++ }
++
++ switch (TREE_CODE_CLASS (code))
++ {
++ case tcc_binary:
++ case tcc_comparison:
++ if (expression_expensive_p (TREE_OPERAND (expr, 1)))
++ return true;
++
++ /* Fallthru. */
++ case tcc_unary:
++ return expression_expensive_p (TREE_OPERAND (expr, 0));
++
++ default:
++ return true;
++ }
++}
++
+ /* Replace ssa names for that scev can prove they are constant by the
+ appropriate constants. Also perform final value replacement in loops,
+ in case the replacement expressions are cheap.
+@@ -2802,12 +2846,6 @@
+ continue;
+
+ niter = number_of_latch_executions (loop);
+- /* We used to check here whether the computation of NITER is expensive,
+- and avoided final value elimination if that is the case. The problem
+- is that it is hard to evaluate whether the expression is too
+- expensive, as we do not know what optimization opportunities the
+- the elimination of the final value may reveal. Therefore, we now
+- eliminate the final values of induction variables unconditionally. */
+ if (niter == chrec_dont_know)
+ continue;
+
+@@ -2838,7 +2876,15 @@
+ /* Moving the computation from the loop may prolong life range
+ of some ssa names, which may cause problems if they appear
+ on abnormal edges. */
+- || contains_abnormal_ssa_name_p (def))
++ || contains_abnormal_ssa_name_p (def)
++ /* Do not emit expensive expressions. The rationale is that
++ when someone writes a code like
++
++ while (n > 45) n -= 45;
++
++ he probably knows that n is not large, and does not want it
++ to be turned into n %= 45. */
++ || expression_expensive_p (def))
+ continue;
+
+ /* Eliminate the PHI node and replace it by a computation outside
+Index: gcc-4.3.2/gcc/tree-scalar-evolution.h
+===================================================================
+--- gcc-4.3.2.orig/gcc/tree-scalar-evolution.h 2009-01-28 10:22:47.000000000 +0100
++++ gcc-4.3.2/gcc/tree-scalar-evolution.h 2009-01-28 10:23:10.000000000 +0100
+@@ -35,6 +35,7 @@
+ extern void scev_analysis (void);
+ unsigned int scev_const_prop (void);
+
++bool expression_expensive_p (tree);
+ extern bool simple_iv (struct loop *, tree, tree, affine_iv *, bool);
+
+ /* Returns the loop of the polynomial chrec CHREC. */
+Index: gcc-4.3.2/gcc/testsuite/gcc.dg/pr34027-1.c
+===================================================================
+--- gcc-4.3.2.orig/gcc/testsuite/gcc.dg/pr34027-1.c 2009-01-28 10:24:09.000000000 +0100
++++ gcc-4.3.2/gcc/testsuite/gcc.dg/pr34027-1.c 2009-01-28 10:24:43.000000000 +0100
+@@ -8,5 +8,9 @@
+ return ns;
+ }
+
+-/* { dg-final { scan-tree-dump "ns % 10000" "optimized" } } */
++/* This test was originally introduced to test that we transform
++ to ns % 10000. See the discussion of PR 32044 why we do not do
++ that anymore. */
++/* { dg-final { scan-tree-dump-times "%" 0 "optimized" } } */
++/* { dg-final { scan-tree-dump-times "/" 0 "optimized" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */
+Index: gcc-4.3.2/gcc/testsuite/gcc.dg/tree-ssa/pr32044.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gcc-4.3.2/gcc/testsuite/gcc.dg/tree-ssa/pr32044.c 2009-01-28 10:25:50.000000000 +0100
+@@ -0,0 +1,55 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -fdump-tree-empty -fdump-tree-final_cleanup" } */
++
++int foo (int n)
++{
++ while (n >= 45)
++ n -= 45;
++
++ return n;
++}
++
++int bar (int n)
++{
++ while (n >= 64)
++ n -= 64;
++
++ return n;
++}
++
++int bla (int n)
++{
++ int i = 0;
++
++ while (n >= 45)
++ {
++ i++;
++ n -= 45;
++ }
++
++ return i;
++}
++
++int baz (int n)
++{
++ int i = 0;
++
++ while (n >= 64)
++ {
++ i++;
++ n -= 64;
++ }
++
++ return i;
++}
++
++/* The loops computing division/modulo by 64 should be eliminated. */
++/* { dg-final { scan-tree-dump-times "Removing empty loop" 2 "empty" } } */
++
++/* There should be no division/modulo in the final dump (division and modulo
++ by 64 are done using bit operations). */
++/* { dg-final { scan-tree-dump-times "/" 0 "final_cleanup" } } */
++/* { dg-final { scan-tree-dump-times "%" 0 "final_cleanup" } } */
++
++/* { dg-final { cleanup-tree-dump "empty" } } */
++/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
+Index: gcc-4.3.2/gcc/tree-ssa-loop-ivopts.c
+===================================================================
+--- gcc-4.3.2.orig/gcc/tree-ssa-loop-ivopts.c 2009-01-28 10:26:04.000000000 +0100
++++ gcc-4.3.2/gcc/tree-ssa-loop-ivopts.c 2009-01-28 10:27:09.000000000 +0100
+@@ -3778,7 +3778,12 @@
+ return false;
+
+ cand_value_at (loop, cand, use->stmt, nit, &bnd);
++
+ *bound = aff_combination_to_tree (&bnd);
++ /* It is unlikely that computing the number of iterations using division
++ would be more profitable than keeping the original induction variable. */
++ if (expression_expensive_p (*bound))
++ return false;
+ return true;
+ }
diff --git a/misc/buildroot/toolchain/gcc/4.3.3/600-arm_insn-opinit-RTX_CODE-fixup.patch b/misc/buildroot/toolchain/gcc/4.3.3/600-arm_insn-opinit-RTX_CODE-fixup.patch
new file mode 100644
index 000000000..69f0c372d
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.3.3/600-arm_insn-opinit-RTX_CODE-fixup.patch
@@ -0,0 +1,41 @@
+gcc/ChangeLog
+2007-11-27 Bernhard Fischer <>
+
+ * config/arm/arm-protos.h (arm_vector_mode_supported_p,
+ arm_hard_regno_mode_ok, const_ok_for_arm): Do not hide non-rtx related
+ function prototypes in RTX_CODE.
+ * genopinit.c: Include tm_p.h.
+
+Index: gcc-4.3.0/gcc/config/arm/arm-protos.h
+===================================================================
+--- gcc-4.3.0/gcc/config/arm/arm-protos.h (revision 130463)
++++ gcc-4.3.0/gcc/config/arm/arm-protos.h (working copy)
+@@ -40,15 +40,14 @@
+ unsigned int);
+ extern unsigned int arm_dbx_register_number (unsigned int);
+ extern void arm_output_fn_unwind (FILE *, bool);
+-
+
+ #ifdef TREE_CODE
+ extern int arm_return_in_memory (const_tree);
+ #endif
+-#ifdef RTX_CODE
+ extern bool arm_vector_mode_supported_p (enum machine_mode);
+ extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
+ extern int const_ok_for_arm (HOST_WIDE_INT);
++#ifdef RTX_CODE
+ extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
+ HOST_WIDE_INT, rtx, rtx, int);
+ extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, enum machine_mode,
+Index: gcc-4.3.0/gcc/genopinit.c
+===================================================================
+--- gcc-4.3.0/gcc/genopinit.c (revision 130463)
++++ gcc-4.3.0/gcc/genopinit.c (working copy)
+@@ -486,6 +486,7 @@
+ printf ("#include \"expr.h\"\n");
+ printf ("#include \"optabs.h\"\n");
+ printf ("#include \"reload.h\"\n\n");
++ printf ("#include \"tm_p.h\"\n\n");
+
+ printf ("void\ninit_all_optabs (void)\n{\n");
+
diff --git a/misc/buildroot/toolchain/gcc/4.3.3/610-gcc-4.3.0-fix-header.00.patch b/misc/buildroot/toolchain/gcc/4.3.3/610-gcc-4.3.0-fix-header.00.patch
new file mode 100644
index 000000000..7fe59d2dd
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.3.3/610-gcc-4.3.0-fix-header.00.patch
@@ -0,0 +1,15 @@
+\\\\
+\\ gcc PR33200
+Index: gcc-4.3.0/gcc/config.gcc
+===================================================================
+--- gcc-4.3.0/gcc/config.gcc (revision 131628)
++++ gcc-4.3.0/gcc/config.gcc (working copy)
+@@ -2302,7 +2305,7 @@ sh-*-symbianelf* | sh[12346l]*-*-symbian
+ if test x${enable_incomplete_targets} = xyes ; then
+ tm_defines="$tm_defines SUPPORT_SH1=1 SUPPORT_SH2E=1 SUPPORT_SH4=1 SUPPORT_SH4_SINGLE=1 SUPPORT_SH2A=1 SUPPORT_SH2A_SINGLE=1 SUPPORT_SH5_32MEDIA=1 SUPPORT_SH5_32MEDIA_NOFPU=1 SUPPORT_SH5_64MEDIA=1 SUPPORT_SH5_64MEDIA_NOFPU=1"
+ fi
+- use_fixproto=yes
++ # XXX: why? use_fixproto=yes
+ ;;
+ sh-*-rtemscoff*)
+ tmake_file="sh/t-sh t-rtems sh/t-rtems"
diff --git a/misc/buildroot/toolchain/gcc/4.3.3/620-gcc-4.3.2-armeabi-aapcs-linux.patch b/misc/buildroot/toolchain/gcc/4.3.3/620-gcc-4.3.2-armeabi-aapcs-linux.patch
new file mode 100644
index 000000000..f4b1c9c06
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.3.3/620-gcc-4.3.2-armeabi-aapcs-linux.patch
@@ -0,0 +1,18 @@
+\\\\ followup of PR34205; trying to use aapcs-linux
+\\ gcc/ChangeLog
+\\
+\\ 2008-09-18 Bernhard Reutner-Fischer <aldot@>
+\\
+\\ * config.gcc (arm*-*-*): Add aapcs-linux to supported ABIs.
+\\
+--- gcc-4.3.2.orig/gcc/config.gcc 2008-09-18 20:33:55.000000000 +0200
++++ gcc-4.3.2/gcc/config.gcc 2008-09-18 21:38:52.000000000 +0200
+@@ -2921,7 +2921,7 @@
+
+ case "$with_abi" in
+ "" \
+- | apcs-gnu | atpcs | aapcs | iwmmxt )
++ | apcs-gnu | atpcs | aapcs | iwmmxt | aapcs-linux )
+ #OK
+ ;;
+ *)
diff --git a/misc/buildroot/toolchain/gcc/4.3.3/630-gcc-4.3.0-cris-pragma-pack-warning-remove.patch b/misc/buildroot/toolchain/gcc/4.3.3/630-gcc-4.3.0-cris-pragma-pack-warning-remove.patch
new file mode 100644
index 000000000..dcf01f24b
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.3.3/630-gcc-4.3.0-cris-pragma-pack-warning-remove.patch
@@ -0,0 +1,13 @@
+diff -urN gcc-4.3.1.orig/gcc/config/cris/cris.h gcc-4.3.1/gcc/config/cris/cris.h
+--- gcc-4.3.1.orig/gcc/config/cris/cris.h 2008-02-22 12:11:01.000000000 +0100
++++ gcc-4.3.1/gcc/config/cris/cris.h 2008-07-02 10:42:42.000000000 +0200
+@@ -1529,9 +1529,6 @@
+
+ #define NO_IMPLICIT_EXTERN_C
+
+-/* No specific purpose other than warningless compatibility. */
+-#define HANDLE_PRAGMA_PACK_PUSH_POP 1
+-
+ /*
+ * Local variables:
+ * eval: (c-set-style "gnu")
diff --git a/misc/buildroot/toolchain/gcc/4.3.3/700-gcc-4.3.3-arm7arch.patch b/misc/buildroot/toolchain/gcc/4.3.3/700-gcc-4.3.3-arm7arch.patch
new file mode 100644
index 000000000..ad16445a2
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.3.3/700-gcc-4.3.3-arm7arch.patch
@@ -0,0 +1,16 @@
+diff -u gcc-4.3.3/gcc/config.gcc.orig gcc-4.3.3/gcc/config.gcc
+--- gcc-4.3.3/gcc/config.gcc.orig 2009-04-24 22:08:23.523688500 -0400
++++ gcc-4.3.3/gcc/config.gcc 2009-04-24 22:13:43.869488700 -0400
+@@ -2880,9 +2880,9 @@
+
+ case "$with_arch" in
+ "" \
+- | armv[23456] | armv2a | armv3m | armv4t | armv5t \
+- | armv5te | armv6j |armv6k | armv6z | armv6zk \
+- | iwmmxt | ep9312)
++ | armv[234567] | armv2a | armv3m | armv4t | armv5t | armv5e \
++ | armv5te | armv6j |armv6k | armv6z | armv6zk | armv6t2 \
++ | armv7-a | armv7-r | armv7-m | ep9312 | iwmmxt)
+ # OK
+ ;;
+ *)
diff --git a/misc/buildroot/toolchain/gcc/4.3.3/900-nuttx-nolibc.patch b/misc/buildroot/toolchain/gcc/4.3.3/900-nuttx-nolibc.patch
new file mode 100755
index 000000000..c22dc7b9e
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.3.3/900-nuttx-nolibc.patch
@@ -0,0 +1,30 @@
+At present, libstdc++ will not build. My understanding is that it needs to have
+the NuttX libc characterized in crossconfig.m4. This is a first attempt to do that --
+unfortunately, it still does not work.
+
+diff -u gcc-4.2.4/libstdc++-v3/configure.orig gcc-4.2.4/libstdc++-v3/configure
+--- gcc-4.2.4/libstdc++-v3/configure.orig 2009-01-05 17:52:11.000000000 -0600
++++ gcc-4.2.4/libstdc++-v3/configure 2009-01-05 17:52:43.000000000 -0600
+@@ -114335,9 +114335,7 @@
+
+ ;;
+ *)
+- { { echo "$as_me:$LINENO: error: No support for this host/target combination." >&5
+-echo "$as_me: error: No support for this host/target combination." >&2;}
+- { (exit 1); exit 1; }; }
++ # Assume bare hardware
+ ;;
+ esac
+
+diff -u gcc-4.2.4/libstdc++-v3/crossconfig.m4.orig gcc-4.2.4/libstdc++-v3/crossconfig.m4
+--- gcc-4.2.4/libstdc++-v3/crossconfig.m4.orig 2009-01-05 17:51:07.000000000 -0600
++++ gcc-4.2.4/libstdc++-v3/crossconfig.m4 2009-01-05 17:52:02.000000000 -0600
+@@ -464,7 +464,7 @@
+ AC_DEFINE(HAVE_TANHL)
+ ;;
+ *)
+- AC_MSG_ERROR([No support for this host/target combination.])
++ # Assume bare hardware
+ ;;
+ esac
+ ])
diff --git a/misc/buildroot/toolchain/gcc/4.3.3/910-nuttx-nolibstdc.patch b/misc/buildroot/toolchain/gcc/4.3.3/910-nuttx-nolibstdc.patch
new file mode 100644
index 000000000..dea5c4e0f
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.3.3/910-nuttx-nolibstdc.patch
@@ -0,0 +1,13 @@
+--- gcc-4.2.4/configure.orig 2009-04-18 18:07:18.250951700 -0400
++++ gcc-4.2.4/configure 2009-04-18 18:20:20.369521100 -0400
+@@ -2614,6 +2614,10 @@
+ ;;
+ esac
+
++# If we are building against NuttX, then don't attempt to build libstdc++
++# (should be conditioned on --with-nuttx)
++noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3"
++
+ # If we aren't building newlib, then don't build libgloss, since libgloss
+ # depends upon some newlib header files.
+ case "${noconfigdirs}" in
diff --git a/misc/buildroot/toolchain/gcc/4.3.3/920-gcc-4.3.3-objext.patch b/misc/buildroot/toolchain/gcc/4.3.3/920-gcc-4.3.3-objext.patch
new file mode 100644
index 000000000..b6e42952e
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.3.3/920-gcc-4.3.3-objext.patch
@@ -0,0 +1,22 @@
+diff -u gcc-4.3.3/configure.orig gcc-4.3.3/configure
+--- gcc-4.3.3/configure.orig 2009-04-25 08:02:42.953125000 -0400
++++ gcc-4.3.3/configure 2009-04-25 08:11:52.453125000 -0400
+@@ -3346,7 +3346,6 @@
+ return 0;
+ }
+ _ACEOF
+-rm -f conftest.o conftest.obj
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+diff -u gcc-4.3.3/libgcc/configure.orig gcc-4.3.3/libgcc/configure
+--- gcc-4.3.3/libgcc/configure.orig 2009-04-25 08:55:17.656250000 -0400
++++ gcc-4.3.3/libgcc/configure 2009-04-25 08:55:42.203125000 -0400
+@@ -2584,7 +2584,6 @@
+ return 0;
+ }
+ _ACEOF
+-rm -f conftest.o conftest.obj
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
diff --git a/misc/buildroot/toolchain/gcc/4.5.2/305-libmudflap-susv3-legacy.patch b/misc/buildroot/toolchain/gcc/4.5.2/305-libmudflap-susv3-legacy.patch
new file mode 100644
index 000000000..374b1f865
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.5.2/305-libmudflap-susv3-legacy.patch
@@ -0,0 +1,49 @@
+Index: gcc-4.2/libmudflap/mf-hooks2.c
+===================================================================
+--- gcc-4.2/libmudflap/mf-hooks2.c (revision 119834)
++++ gcc-4.2/libmudflap/mf-hooks2.c (working copy)
+@@ -427,7 +427,7 @@
+ {
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
+- bzero (s, n);
++ memset (s, 0, n);
+ }
+
+
+@@ -437,7 +437,7 @@
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
+ MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
+- bcopy (src, dest, n);
++ memmove (dest, src, n);
+ }
+
+
+@@ -447,7 +447,7 @@
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
+ MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
+- return bcmp (s1, s2, n);
++ return n == 0 ? 0 : memcmp (s1, s2, n);
+ }
+
+
+@@ -456,7 +456,7 @@
+ size_t n = strlen (s);
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
+- return index (s, c);
++ return strchr (s, c);
+ }
+
+
+@@ -465,7 +465,7 @@
+ size_t n = strlen (s);
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
+- return rindex (s, c);
++ return strrchr (s, c);
+ }
+
+ /* XXX: stpcpy, memccpy */
diff --git a/misc/buildroot/toolchain/gcc/4.5.2/810-arm-softfloat-libgcc.patch b/misc/buildroot/toolchain/gcc/4.5.2/810-arm-softfloat-libgcc.patch
new file mode 100644
index 000000000..e6a30a3f0
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.5.2/810-arm-softfloat-libgcc.patch
@@ -0,0 +1,38 @@
+[PATCH] add the correct symbols to libgcc for uclibc arm softfloat
+
+Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
+---
+ gcc/config/arm/linux-elf.h | 2 +-
+ gcc/config/arm/t-linux | 6 +++++-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+Index: gcc-4.4.0/gcc/config/arm/t-linux
+===================================================================
+--- gcc-4.4.0.orig/gcc/config/arm/t-linux
++++ gcc-4.4.0/gcc/config/arm/t-linux
+@@ -4,7 +4,11 @@
+
+ LIB1ASMSRC = arm/lib1funcs.asm
+ LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx _clzsi2 _clzdi2 \
+- _arm_addsubdf3 _arm_addsubsf3
++ _arm_addsubdf3 _arm_addsubsf3 \
++ _arm_negdf2 _arm_muldivdf3 _arm_cmpdf2 _arm_unorddf2 \
++ _arm_fixdfsi _arm_fixunsdfsi _arm_truncdfsf2 \
++ _arm_negsf2 _arm_muldivsf3 _arm_cmpsf2 _arm_unordsf2 \
++ _arm_fixsfsi _arm_fixunssfsi
+
+ # MULTILIB_OPTIONS = mhard-float/msoft-float
+ # MULTILIB_DIRNAMES = hard-float soft-float
+Index: gcc-4.4.0/gcc/config/arm/linux-elf.h
+===================================================================
+--- gcc-4.4.0.orig/gcc/config/arm/linux-elf.h
++++ gcc-4.4.0/gcc/config/arm/linux-elf.h
+@@ -60,7 +60,7 @@
+ %{shared:-lc} \
+ %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
+
+-#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc"
++#define LIBGCC_SPEC "-lgcc"
+
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
+
diff --git a/misc/buildroot/toolchain/gcc/4.5.2/820-arm-unbreak-armv4t.patch b/misc/buildroot/toolchain/gcc/4.5.2/820-arm-unbreak-armv4t.patch
new file mode 100644
index 000000000..8651afcd8
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.5.2/820-arm-unbreak-armv4t.patch
@@ -0,0 +1,14 @@
+http://sourceware.org/ml/crossgcc/2008-05/msg00009.html
+
+diff -Nura gcc-4.5.1.orig/gcc/config/arm/linux-eabi.h gcc-4.5.1/gcc/config/arm/linux-eabi.h
+--- gcc-4.5.1.orig/gcc/config/arm/linux-eabi.h 2009-10-30 17:03:09.000000000 -0300
++++ gcc-4.5.1/gcc/config/arm/linux-eabi.h 2010-11-02 15:38:25.792208500 -0300
+@@ -44,7 +44,7 @@
+ The ARM10TDMI core is the default for armv5t, so set
+ SUBTARGET_CPU_DEFAULT to achieve this. */
+ #undef SUBTARGET_CPU_DEFAULT
+-#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm10tdmi
++#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm9tdmi
+
+ /* TARGET_BIG_ENDIAN_DEFAULT is set in
+ config.gcc for big endian configurations. */
diff --git a/misc/buildroot/toolchain/gcc/4.5.2/830-arm-pr43440.patch b/misc/buildroot/toolchain/gcc/4.5.2/830-arm-pr43440.patch
new file mode 100644
index 000000000..811d1f249
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.5.2/830-arm-pr43440.patch
@@ -0,0 +1,345 @@
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43440
+
+--- gcc-4.4.4.orig/gcc/config/arm/aout.h
++++ gcc-4.4.4/gcc/config/arm/aout.h
+@@ -163,34 +163,49 @@
+ {"mvdx12", 39}, \
+ {"mvdx13", 40}, \
+ {"mvdx14", 41}, \
+- {"mvdx15", 42}, \
+- {"d0", 63}, {"q0", 63}, \
+- {"d1", 65}, \
+- {"d2", 67}, {"q1", 67}, \
+- {"d3", 69}, \
+- {"d4", 71}, {"q2", 71}, \
+- {"d5", 73}, \
+- {"d6", 75}, {"q3", 75}, \
+- {"d7", 77}, \
+- {"d8", 79}, {"q4", 79}, \
+- {"d9", 81}, \
+- {"d10", 83}, {"q5", 83}, \
+- {"d11", 85}, \
+- {"d12", 87}, {"q6", 87}, \
+- {"d13", 89}, \
+- {"d14", 91}, {"q7", 91}, \
+- {"d15", 93}, \
+- {"q8", 95}, \
+- {"q9", 99}, \
+- {"q10", 103}, \
+- {"q11", 107}, \
+- {"q12", 111}, \
+- {"q13", 115}, \
+- {"q14", 119}, \
+- {"q15", 123} \
++ {"mvdx15", 42} \
+ }
+ #endif
+
++#ifndef OVERLAPPING_REGISTER_NAMES
++#define OVERLAPPING_REGISTER_NAMES \
++{ \
++ {"d0", 63, 2}, \
++ {"d1", 65, 2}, \
++ {"d2", 67, 2}, \
++ {"d3", 69, 2}, \
++ {"d4", 71, 2}, \
++ {"d5", 73, 2}, \
++ {"d6", 75, 2}, \
++ {"d7", 77, 2}, \
++ {"d8", 79, 2}, \
++ {"d9", 81, 2}, \
++ {"d10", 83, 2}, \
++ {"d11", 85, 2}, \
++ {"d12", 87, 2}, \
++ {"d13", 89, 2}, \
++ {"d14", 91, 2}, \
++ {"d15", 93, 2}, \
++ {"q0", 63, 4}, \
++ {"q1", 67, 4}, \
++ {"q2", 71, 4}, \
++ {"q3", 75, 4}, \
++ {"q4", 79, 4}, \
++ {"q5", 83, 4}, \
++ {"q6", 87, 4}, \
++ {"q7", 91, 4}, \
++ {"q8", 95, 4}, \
++ {"q9", 99, 4}, \
++ {"q10", 103, 4}, \
++ {"q11", 107, 4}, \
++ {"q12", 111, 4}, \
++ {"q13", 115, 4}, \
++ {"q14", 119, 4}, \
++ {"q15", 123, 4} \
++}
++#endif
++
++
+ #ifndef NO_DOLLAR_IN_LABEL
+ #define NO_DOLLAR_IN_LABEL 1
+ #endif
+--- gcc-4.4.4.orig/gcc/output.h
++++ gcc-4.4.4/gcc/output.h
+@@ -169,6 +169,11 @@
+ Prefixes such as % are optional. */
+ extern int decode_reg_name (const char *);
+
++/* Similar to decode_reg_name, but takes an extra parameter that is a
++ pointer to the number of (internal) registers described by the
++ external name. */
++extern int decode_reg_name_and_count (const char *, int *);
++
+ extern void assemble_alias (tree, tree);
+
+ extern void default_assemble_visibility (tree, int);
+--- gcc-4.4.4.orig/gcc/reginfo.c
++++ gcc-4.4.4/gcc/reginfo.c
+@@ -800,39 +800,44 @@
+ fix_register (const char *name, int fixed, int call_used)
+ {
+ int i;
++ int reg, nregs;
+
+ /* Decode the name and update the primary form of
+ the register info. */
+-
+- if ((i = decode_reg_name (name)) >= 0)
++ if ((reg = decode_reg_name_and_count (name, &nregs)) >= 0)
+ {
+- if ((i == STACK_POINTER_REGNUM
++ gcc_assert (nregs >= 1);
++ for (i = reg; i < reg + nregs; i++)
++ {
++ if ((i == STACK_POINTER_REGNUM
+ #ifdef HARD_FRAME_POINTER_REGNUM
+- || i == HARD_FRAME_POINTER_REGNUM
++ || i == HARD_FRAME_POINTER_REGNUM
+ #else
+- || i == FRAME_POINTER_REGNUM
++ || i == FRAME_POINTER_REGNUM
+ #endif
+- )
+- && (fixed == 0 || call_used == 0))
+- {
+- static const char * const what_option[2][2] = {
+- { "call-saved", "call-used" },
+- { "no-such-option", "fixed" }};
++ )
++ && (fixed == 0 || call_used == 0))
++ {
++ static const char * const what_option[2][2] = {
++ { "call-saved", "call-used" },
++ { "no-such-option", "fixed" }};
+
+- error ("can't use '%s' as a %s register", name,
+- what_option[fixed][call_used]);
+- }
+- else
+- {
+- fixed_regs[i] = fixed;
+- call_used_regs[i] = call_used;
++ error ("can't use '%s' as a %s register", name,
++ what_option[fixed][call_used]);
++ }
++ else
++ {
++ fixed_regs[i] = fixed;
++ call_used_regs[i] = call_used;
+ #ifdef CALL_REALLY_USED_REGISTERS
+- if (fixed == 0)
+- call_really_used_regs[i] = call_used;
++ if (fixed == 0)
++ call_really_used_regs[i] = call_used;
+ #endif
+- }
+- }
+- else
++ }
++ }
++ }
++ else
++
+ {
+ warning (0, "unknown register name: %s", name);
+ }
+--- gcc-4.4.4.orig/gcc/stmt.c
++++ gcc-4.4.4/gcc/stmt.c
+@@ -681,13 +681,14 @@
+ for (tail = clobbers; tail; tail = TREE_CHAIN (tail))
+ {
+ const char *regname;
++ int nregs;
+
+ if (TREE_VALUE (tail) == error_mark_node)
+ return;
+ regname = TREE_STRING_POINTER (TREE_VALUE (tail));
+
+- i = decode_reg_name (regname);
+- if (i >= 0 || i == -4)
++ i = decode_reg_name_and_count (regname, &nregs);
++ if (i == -4)
+ ++nclobbers;
+ else if (i == -2)
+ error ("unknown register name %qs in %<asm%>", regname);
+@@ -695,14 +696,21 @@
+ /* Mark clobbered registers. */
+ if (i >= 0)
+ {
+- /* Clobbering the PIC register is an error. */
+- if (i == (int) PIC_OFFSET_TABLE_REGNUM)
+- {
+- error ("PIC register %qs clobbered in %<asm%>", regname);
+- return;
+- }
++ int reg;
+
+- SET_HARD_REG_BIT (clobbered_regs, i);
++ for (reg = i; reg < i + nregs; reg++)
++ {
++ ++nclobbers;
++
++ /* Clobbering the PIC register is an error. */
++ if (reg == (int) PIC_OFFSET_TABLE_REGNUM)
++ {
++ error ("PIC register clobbered by %qs in %<asm%>", regname);
++ return;
++ }
++
++ SET_HARD_REG_BIT (clobbered_regs, reg);
++ }
+ }
+ }
+
+@@ -1012,8 +1020,9 @@
+ for (tail = clobbers; tail; tail = TREE_CHAIN (tail))
+ {
+ const char *regname = TREE_STRING_POINTER (TREE_VALUE (tail));
+- int j = decode_reg_name (regname);
+- rtx clobbered_reg;
++ int reg, nregs;
++ int j = decode_reg_name_and_count (regname, &nregs);
++ rtx clobbered_reg;
+
+ if (j < 0)
+ {
+@@ -1033,31 +1042,40 @@
+ /* Ignore unknown register, error already signaled. */
+ continue;
+ }
+-
+- /* Use QImode since that's guaranteed to clobber just one reg. */
+- clobbered_reg = gen_rtx_REG (QImode, j);
+-
+- /* Do sanity check for overlap between clobbers and respectively
+- input and outputs that hasn't been handled. Such overlap
+- should have been detected and reported above. */
+- if (!clobber_conflict_found)
+- {
+- int opno;
+-
+- /* We test the old body (obody) contents to avoid tripping
+- over the under-construction body. */
+- for (opno = 0; opno < noutputs; opno++)
+- if (reg_overlap_mentioned_p (clobbered_reg, output_rtx[opno]))
+- internal_error ("asm clobber conflict with output operand");
+-
+- for (opno = 0; opno < ninputs - ninout; opno++)
+- if (reg_overlap_mentioned_p (clobbered_reg,
+- ASM_OPERANDS_INPUT (obody, opno)))
+- internal_error ("asm clobber conflict with input operand");
++
++ for (reg = j; reg < j + nregs; reg++)
++ {
++ /* Use QImode since that's guaranteed to clobber just
++ * one reg. */
++ clobbered_reg = gen_rtx_REG (QImode, reg);
++
++ /* Do sanity check for overlap between clobbers and
++ respectively input and outputs that hasn't been
++ handled. Such overlap should have been detected and
++ reported above. */
++ if (!clobber_conflict_found)
++ {
++ int opno;
++
++ /* We test the old body (obody) contents to avoid
++ tripping over the under-construction body. */
++ for (opno = 0; opno < noutputs; opno++)
++ if (reg_overlap_mentioned_p (clobbered_reg,
++ output_rtx[opno]))
++ internal_error
++ ("asm clobber conflict with output operand");
++
++ for (opno = 0; opno < ninputs - ninout; opno++)
++ if (reg_overlap_mentioned_p (clobbered_reg,
++ ASM_OPERANDS_INPUT (obody,
++ opno)))
++ internal_error
++ ("asm clobber conflict with input operand");
++ }
++
++ XVECEXP (body, 0, i++)
++ = gen_rtx_CLOBBER (VOIDmode, clobbered_reg);
+ }
+-
+- XVECEXP (body, 0, i++)
+- = gen_rtx_CLOBBER (VOIDmode, clobbered_reg);
+ }
+
+ emit_insn (body);
+--- gcc-4.4.4.orig/gcc/varasm.c
++++ gcc-4.4.4/gcc/varasm.c
+@@ -1031,8 +1031,11 @@
+ Prefixes such as % are optional. */
+
+ int
+-decode_reg_name (const char *asmspec)
++decode_reg_name_and_count (const char *asmspec, int *pnregs)
+ {
++ /* Presume just one register is clobbered. */
++ *pnregs = 1;
++
+ if (asmspec != 0)
+ {
+ int i;
+@@ -1058,6 +1061,25 @@
+ && ! strcmp (asmspec, strip_reg_name (reg_names[i])))
+ return i;
+
++#ifdef OVERLAPPING_REGISTER_NAMES
++ {
++ static const struct
++ {
++ const char *const name;
++ const int number;
++ const int nregs;
++ } table[] = OVERLAPPING_REGISTER_NAMES;
++
++ for (i = 0; i < (int) ARRAY_SIZE (table); i++)
++ if (table[i].name[0]
++ && ! strcmp (asmspec, table[i].name))
++ {
++ *pnregs = table[i].nregs;
++ return table[i].number;
++ }
++ }
++#endif /* OVERLAPPING_REGISTER_NAMES */
++
+ #ifdef ADDITIONAL_REGISTER_NAMES
+ {
+ static const struct { const char *const name; const int number; } table[]
+@@ -1081,6 +1103,15 @@
+
+ return -1;
+ }
++
++int
++decode_reg_name (const char *name)
++{
++ int count;
++ return decode_reg_name_and_count (name, &count);
++}
++
++
+
+ /* Return true if DECL's initializer is suitable for a BSS section. */
+
diff --git a/misc/buildroot/toolchain/gcc/4.5.2/850-arm-pr44392.patch b/misc/buildroot/toolchain/gcc/4.5.2/850-arm-pr44392.patch
new file mode 100644
index 000000000..4ad6c448d
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.5.2/850-arm-pr44392.patch
@@ -0,0 +1,70 @@
+>From d0557763b0713a4c006bd2405eede3924569cafd Mon Sep 17 00:00:00 2001
+From: Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+Date: Mon, 5 Jul 2010 11:28:49 +0100
+Subject: [PATCH 2/2] Fix PR44392
+
+---
+ gcc/config/arm/arm.md | 43 +++++++++++++++++++------------------------
+ 1 files changed, 19 insertions(+), 24 deletions(-)
+
+diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
+index 2096ec6..f0348f3 100644
+--- a/gcc/config/arm/arm.md
++++ b/gcc/config/arm/arm.md
+@@ -11318,34 +11318,29 @@
+ (define_expand "bswapsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
+-"TARGET_EITHER"
++"TARGET_EITHER && (arm_arch6 || !optimize_size)"
+ "
+- if (!arm_arch6)
+- {
+- if (!optimize_size)
+- {
+- rtx op2 = gen_reg_rtx (SImode);
+- rtx op3 = gen_reg_rtx (SImode);
++ if (!arm_arch6)
++ {
++ rtx op2 = gen_reg_rtx (SImode);
++ rtx op3 = gen_reg_rtx (SImode);
+
+- if (TARGET_THUMB)
+- {
+- rtx op4 = gen_reg_rtx (SImode);
+- rtx op5 = gen_reg_rtx (SImode);
++ if (TARGET_THUMB)
++ {
++ rtx op4 = gen_reg_rtx (SImode);
++ rtx op5 = gen_reg_rtx (SImode);
+
+- emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
+- op2, op3, op4, op5));
+- }
+- else
+- {
+- emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
+- op2, op3));
+- }
++ emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
++ op2, op3, op4, op5));
++ }
++ else
++ {
++ emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
++ op2, op3));
++ }
+
+- DONE;
+- }
+- else
+- FAIL;
+- }
++ DONE;
++ }
+ "
+ )
+
+--
+1.6.2
+
diff --git a/misc/buildroot/toolchain/gcc/4.5.2/900-nuttx-nolibstdc.patch b/misc/buildroot/toolchain/gcc/4.5.2/900-nuttx-nolibstdc.patch
new file mode 100644
index 000000000..5628646a6
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.5.2/900-nuttx-nolibstdc.patch
@@ -0,0 +1,13 @@
+--- gcc-4.5.2/configure.orig 2011-04-28 17:25:37.091035400 -0600
++++ gcc-4.5.2/configure 2011-04-28 17:26:26.868332200 -0600
+@@ -3741,6 +3741,10 @@
+ ;;
+ esac
+
++# If we are building against NuttX, then don't attempt to build libstdc++
++# (should be conditioned on --with-nuttx)
++noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3"
++
+ # If we aren't building newlib, then don't build libgloss, since libgloss
+ # depends upon some newlib header files.
+ case "${noconfigdirs}" in
diff --git a/misc/buildroot/toolchain/gcc/4.5.2/901-bug43999-fix-mismatch-between-conditions-of-an-IT-block.patch b/misc/buildroot/toolchain/gcc/4.5.2/901-bug43999-fix-mismatch-between-conditions-of-an-IT-block.patch
new file mode 100644
index 000000000..fb5cd5e4c
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/4.5.2/901-bug43999-fix-mismatch-between-conditions-of-an-IT-block.patch
@@ -0,0 +1,13 @@
+diff --git a/gcc/config/arm/lib1funcs.asm b/gcc/config/arm/lib1funcs.asm
+index 085e690..2e76c01 100644
+--- a/gcc/config/arm/lib1funcs.asm
++++ b/gcc/config/arm/lib1funcs.asm
+@@ -641,7 +641,7 @@ pc .req r15
+ subhs \dividend, \dividend, \divisor, lsr #3
+ orrhs \result, \result, \curbit, lsr #3
+ cmp \dividend, #0 @ Early termination?
+- do_it hs, t
++ do_it ne, t
+ movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
+ movne \divisor, \divisor, lsr #4
+ bne 1b
diff --git a/misc/buildroot/toolchain/gcc/Config.in b/misc/buildroot/toolchain/gcc/Config.in
new file mode 100644
index 000000000..d2b4b69fe
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/Config.in
@@ -0,0 +1,106 @@
+# Choose gcc version.
+
+comment "GCC Options"
+
+config BR2_PACKAGE_GCC
+ bool "Build GCC cross-compiler"
+ default n
+ help
+ Build the GCC cross-compiler for the target architecture.
+
+choice
+ prompt "GCC compiler Version"
+ default BR2_GCC_VERSION_4_3_3 if BR2_cortex_m3
+ default BR2_GCC_VERSION_4_2_4 if !BR2_avr32 && !BR2_cortex_m3 && !BR2_m9s12x
+ default BR2_GCC_VERSION_3_4_6 if BR2_avr32
+ default BR2_GCC_VERSION_3_3_6 if BR2_m9s12x
+ depends on BR2_PACKAGE_GCC
+ help
+ Select the version of gcc you wish to use.
+
+ config BR2_GCC_VERSION_3_3_6
+ depends on BR2_m9s12x
+ bool "gcc 3.3.6"
+
+ config BR2_GCC_VERSION_3_4_6
+ depends on !BR2_m32c && !BR2_cortex_m3 && !BR2_m9s12x
+ bool "gcc 3.4.6"
+
+ config BR2_GCC_VERSION_4_2_4
+ depends on !BR2_avr32 && !BR2_nios2 && !BR2_cortex_m3 && !BR2_m9s12x
+ select BR2_GCC_SUPPORTS_SYSROOT
+ bool "gcc 4.2.4"
+
+ config BR2_GCC_VERSION_4_3_3
+ depends on !BR2_avr32 && !BR2_nios2 && !BR2_m9s12x
+ select BR2_GCC_SUPPORTS_SYSROOT
+ bool "gcc 4.3.3"
+
+ config BR2_GCC_VERSION_4_5_2
+ depends on !BR2_avr32 && !BR2_nios2 && !BR2_m9s12x
+ select BR2_GCC_SUPPORTS_SYSROOT
+ bool "gcc 4.5.2"
+
+endchoice
+
+config BR2_GCC_SUPPORTS_SYSROOT
+ bool
+ default n
+
+config BR2_GCC_VERSION
+ string
+ default "3.3.6" if BR2_GCC_VERSION_3_3_6
+ default "3.4.6" if BR2_GCC_VERSION_3_4_6
+ default "4.2.4" if BR2_GCC_VERSION_4_2_4
+ default "4.3.3" if BR2_GCC_VERSION_4_3_3
+ default "4.5.2" if BR2_GCC_VERSION_4_5_2
+
+config BR2_GCC_USE_SJLJ_EXCEPTIONS
+ bool "Enable setjmp/longjmp exceptions?"
+ default n
+ depends on BR2_PACKAGE_GCC
+ help
+ For some platforms, proper stack unwinding works perfectly,
+ while other platforms must use setjmp/longjmp exceptions for
+ proper stack unwinding during exception handling. Most people
+ can leave this set to n.
+
+config BR2_EXTRA_GCC_CONFIG_OPTIONS
+ string "Additional gcc options"
+ depends on BR2_PACKAGE_GCC
+ default ""
+ help
+ Any additional gcc configure options you may want to include....
+
+config BR2_INSTALL_LIBSTDCPP
+ bool "Build C++ compiler?"
+ depends on BR2_PACKAGE_GCC
+ default n
+ # >= 4.2.0 work fine without LARGEFILE
+ select BR2_LARGEFILE if !BR2_GCC_SUPPORTS_SYSROOT
+ help
+ Build/install c++ compiler? NOTE: libstdc++ is not built for NuttX?
+
+config BR2_INSTALL_LIBGCJ
+ bool "Build/install java compiler and libgcj?"
+ default n
+ depends on BR2_PACKAGE_GCC && !BR2_avr32 && BR2_INSTALL_LIBSTDCPP
+ help
+ Build/install java compiler and libgcj?
+
+config BR2_INSTALL_OBJC
+ bool "Build/install Objective-C compiler and runtime?"
+ default n
+ depends on BR2_PACKAGE_GCC && !BR2_avr32
+ help
+ Build/install Objective-C compiler and runtime?
+
+config BR2_INSTALL_FORTRAN
+ bool "Build/install Fortran compiler and runtime?"
+ default n
+ depends on BR2_PACKAGE_GCC && !BR2_avr32
+ help
+ Build/install Fortran compiler and runtime?
+ Note that it is highly recommended NOT to use gfortran
+ from gcc older than 4.2.0
+
diff --git a/misc/buildroot/toolchain/gcc/Makefile.in b/misc/buildroot/toolchain/gcc/Makefile.in
new file mode 100644
index 000000000..aaec774dc
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/Makefile.in
@@ -0,0 +1,62 @@
+#
+
+GCC_VERSION:=$(strip $(subst ",, $(BR2_GCC_VERSION)))
+#"))
+TARGET_OPTIMIZATION:=$(strip $(subst ",, $(BR2_TARGET_OPTIMIZATION)))
+#"))
+EXTRA_GCC_CONFIG_OPTIONS:=$(strip $(subst ",, $(BR2_EXTRA_GCC_CONFIG_OPTIONS)))
+#"))
+#")))
+
+ifeq ($(strip $(BR2_GCC_USE_SJLJ_EXCEPTIONS)),y)
+GCC_USE_SJLJ_EXCEPTIONS:=--enable-sjlj-exceptions
+endif
+
+ifeq ($(BR2_SOFT_FLOAT),y)
+# gcc 3.4.x soft float configuration is different than previous versions.
+ifeq ($(findstring x3.4.,x$(GCC_VERSION)),x3.4.)
+ifneq ($(BR2_nios2),y)
+SOFT_FLOAT_CONFIG_OPTION:=--with-float=soft
+endif
+else
+SOFT_FLOAT_CONFIG_OPTION:=--without-float
+endif
+
+# again... there must be a better way
+ifeq ($(findstring x4.,x$(GCC_VERSION)),x4.)
+SOFT_FLOAT_CONFIG_OPTION:=--with-float=soft
+ifeq ($(BR2_SOFT_FLOAT_FP),y)
+TARGET_SOFT_FLOAT:=-mfloat-abi=softfp
+else # no fp at all
+ifeq ($(BR2_arm),y) # only set float-abi for arm
+TARGET_SOFT_FLOAT:=-mfloat-abi=soft
+else
+TARGET_SOFT_FLOAT:=-msoft-float
+endif
+endif
+else # not gcc-4.x
+TARGET_SOFT_FLOAT:=-msoft-float
+endif
+ARCH_FPU_SUFFIX:=_nofpu
+else # no softfloat support
+SOFT_FLOAT_CONFIG_OPTION:=
+TARGET_SOFT_FLOAT:=
+ARCH_FPU_SUFFIX:=
+endif
+
+# some additional tuning values
+ifneq ($(strip $(subst ",,$(BR2_GCC_TARGET_ARCH))),)
+# ")))
+GCC_WITH_ARCH:=--with-arch=$(BR2_GCC_TARGET_ARCH)
+endif
+ifneq ($(strip $(subst ",,$(BR2_GCC_TARGET_TUNE))),)
+# ")))
+GCC_WITH_TUNE:=--with-tune=$(BR2_GCC_TARGET_TUNE)
+endif
+ifneq ($(strip $(subst ",,$(BR2_GCC_TARGET_ABI))),)
+# ")))
+GCC_WITH_ABI:=--with-abi=$(BR2_GCC_TARGET_ABI)
+endif
+ifdef BR2_cortex_m3
+GCC_WITH_MODE:=--with-mode=thumb
+endif
diff --git a/misc/buildroot/toolchain/gcc/gcc-nuttx-3.x.mk b/misc/buildroot/toolchain/gcc/gcc-nuttx-3.x.mk
new file mode 100644
index 000000000..cc55e5b43
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/gcc-nuttx-3.x.mk
@@ -0,0 +1,226 @@
+# Makefile for to build a gcc/nuttx toolchain
+#
+# Copyright (C) 2002-2003 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# Without sysroot support. Sysroot toolchain is gcc-uclibc-4.x.mk
+ifneq ($(BR2_GCC_SUPPORTS_SYSROOT),y)
+
+GCC_OFFICIAL_VER:=$(GCC_VERSION)
+GCC_SITE:=http://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VERSION)
+
+GCC_SOURCE:=gcc-$(GCC_OFFICIAL_VER).tar.bz2
+GCC_DIR:=$(TOOL_BUILD_DIR)/gcc-$(GCC_OFFICIAL_VER)
+GCC_CAT:=$(BZCAT)
+GCC_STRIP_HOST_BINARIES:=true
+
+#############################################################
+#
+# Setup some initial stuff
+#
+#############################################################
+
+GCC_TARGET_LANGUAGES:=c
+GCC_TARGET_PREREQ=
+GCC_STAGING_PREREQ=
+
+ifeq ($(BR2_INSTALL_LIBSTDCPP),y)
+GCC_TARGET_LANGUAGES:=$(GCC_TARGET_LANGUAGES),c++
+endif
+
+ifeq ($(BR2_INSTALL_LIBGCJ),y)
+GCC_TARGET_LANGUAGES:=$(GCC_TARGET_LANGUAGES),java
+endif
+
+ifeq ($(BR2_INSTALL_OBJC),y)
+GCC_TARGET_LANGUAGES:=$(GCC_TARGET_LANGUAGES),objc
+endif
+
+ifeq ($(BR2_INSTALL_FORTRAN),y)
+GCC_TARGET_LANGUAGES:=$(GCC_TARGET_LANGUAGES),fortran
+endif
+
+GCC_SHARED_LIBGCC:=--disable-shared
+
+ifneq ($(BR2_ENABLE_LOCALE),y)
+GCC_ENABLE_CLOCALE:=--disable-clocale
+endif
+
+
+#############################################################
+#
+# build the gcc compiler
+#
+#############################################################
+GCC_BUILD_DIR:=$(TOOL_BUILD_DIR)/gcc-$(GCC_VERSION)-build
+
+$(DL_DIR)/$(GCC_SOURCE):
+ mkdir -p $(DL_DIR)
+ $(WGET) -P $(DL_DIR) $(GCC_SITE)/$(GCC_SOURCE)
+
+gcc-unpacked: $(GCC_DIR)/.unpacked
+$(GCC_DIR)/.unpacked: $(DL_DIR)/$(GCC_SOURCE)
+ mkdir -p $(TOOL_BUILD_DIR)
+ $(GCC_CAT) $(DL_DIR)/$(GCC_SOURCE) | tar -C $(TOOL_BUILD_DIR) $(TAR_OPTIONS) -
+ $(CONFIG_UPDATE) $(GCC_DIR)
+ touch $@
+
+gcc-patched: $(GCC_DIR)/.patched
+$(GCC_DIR)/.patched: $(GCC_DIR)/.unpacked
+ # Apply any files named gcc-*.patch from the source directory to gcc
+ toolchain/patch-kernel.sh $(GCC_DIR) toolchain/gcc/$(GCC_VERSION) \*.patch
+
+ # Note: The soft float situation has improved considerably with gcc 3.4.x.
+ # We can dispense with the custom spec files, as well as libfloat for the arm case.
+ # However, we still need a patch for arm. There's a similar patch for gcc 3.3.x
+ # which needs to be integrated so we can kill of libfloat for good, except for
+ # anyone (?) who might still be using gcc 2.95. mjn3
+ifeq ($(BR2_SOFT_FLOAT),y)
+ifeq ("$(strip $(ARCH))","arm")
+ toolchain/patch-kernel.sh $(GCC_DIR) toolchain/gcc/$(GCC_VERSION) arm-softfloat.patch.conditional
+endif
+ifeq ("$(strip $(ARCH))","armeb")
+ toolchain/patch-kernel.sh $(GCC_DIR) toolchain/gcc/$(GCC_VERSION) arm-softfloat.patch.conditional
+endif
+ # Not yet updated to 3.4.1.
+ #ifeq ("$(strip $(ARCH))","i386")
+ #toolchain/patch-kernel.sh $(GCC_DIR) toolchain/gcc i386-gcc-soft-float.patch
+ #endif
+endif
+ touch $@
+
+$(GCC_BUILD_DIR)/.configured: $(GCC_DIR)/.patched $(GCC_STAGING_PREREQ)
+ mkdir -p $(GCC_BUILD_DIR)
+ # Important! Required for limits.h to be fixed.
+ ln -snf ../include $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/sys-include
+ (cd $(GCC_BUILD_DIR); rm -rf config.cache; PATH=$(TARGET_PATH) \
+ CC="$(HOSTCC)" \
+ $(GCC_DIR)/configure \
+ --prefix=$(STAGING_DIR) \
+ --build=$(GNU_HOST_NAME) \
+ --host=$(GNU_HOST_NAME) \
+ --target=$(REAL_GNU_TARGET_NAME) \
+ --enable-languages=$(GCC_TARGET_LANGUAGES) \
+ --disable-__cxa_atexit \
+ --enable-target-optspace \
+ --with-gnu-ld \
+ $(GCC_SHARED_LIBGCC) \
+ $(DISABLE_NLS) \
+ $(THREADS) \
+ $(MULTILIB) \
+ $(SOFT_FLOAT_CONFIG_OPTION) \
+ $(GCC_WITH_ARCH) $(GCC_WITH_TUNE) $(GCC_WITH_MODE) \
+ $(GCC_USE_SJLJ_EXCEPTIONS) \
+ $(DISABLE_LARGEFILE) \
+ $(EXTRA_GCC_CONFIG_OPTIONS));
+ touch $@
+
+$(GCC_BUILD_DIR)/.compiled: $(GCC_BUILD_DIR)/.configured
+ PATH=$(TARGET_PATH) $(MAKE) -C $(GCC_BUILD_DIR) all
+ touch $@
+
+$(GCC_BUILD_DIR)/.installed: $(GCC_BUILD_DIR)/.compiled
+ PATH=$(TARGET_PATH) $(MAKE) -C $(GCC_BUILD_DIR) install
+ if [ -d "$(STAGING_DIR)/lib64" ] ; then \
+ if [ ! -e "$(STAGING_DIR)/lib" ] ; then \
+ mkdir "$(STAGING_DIR)/lib" ; \
+ fi ; \
+ mv "$(STAGING_DIR)/lib64/"* "$(STAGING_DIR)/lib/" ; \
+ rmdir "$(STAGING_DIR)/lib64" ; \
+ fi
+ # Strip the host binaries
+ifeq ($(GCC_STRIP_HOST_BINARIES),true)
+ -strip --strip-all -R .note -R .comment $(STAGING_DIR)/bin/*
+endif
+ # Make sure we have 'cc'.
+ if [ ! -e $(STAGING_DIR)/bin/$(REAL_GNU_TARGET_NAME)-cc ] ; then \
+ ln -snf $(REAL_GNU_TARGET_NAME)-gcc \
+ $(STAGING_DIR)/bin/$(REAL_GNU_TARGET_NAME)-cc ; \
+ fi;
+ if [ ! -e $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/bin/cc ] ; then \
+ ln -snf gcc $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/bin/cc ; \
+ fi;
+ # Set up the symlinks to enable lying about target name.
+ set -e; \
+ (cd $(STAGING_DIR); \
+ if [ "$(REAL_GNU_TARGET_NAME)" != "$(GNU_TARGET_NAME)" ]; then \
+ ln -snf $(REAL_GNU_TARGET_NAME) $(GNU_TARGET_NAME); \
+ cd bin; \
+ for app in $(REAL_GNU_TARGET_NAME)-* ; do \
+ ln -snf $${app} \
+ $(GNU_TARGET_NAME)$${app##$(REAL_GNU_TARGET_NAME)}; \
+ done; \
+ fi; \
+ );
+ #
+ # Now for the ugly 3.3.x soft float hack...
+ #
+ifeq ($(BR2_SOFT_FLOAT),y)
+ifeq ($(findstring 3.3.,$(GCC_VERSION)),3.3.)
+ # Make sure we have a soft float specs file for this arch
+ if [ ! -f toolchain/gcc/$(GCC_VERSION)/specs-$(ARCH)-soft-float ] ; then \
+ echo soft float configured but no specs file for this arch ; \
+ /bin/false ; \
+ fi;
+ # Replace specs file with one that defaults to soft float mode.
+ if [ ! -f $(STAGING_DIR)/lib/gcc-lib/$(REAL_GNU_TARGET_NAME)/$(GCC_VERSION)/specs ] ; then \
+ echo staging dir specs file is missing ; \
+ /bin/false ; \
+ fi;
+ cp toolchain/gcc/$(GCC_VERSION)/specs-$(ARCH)-soft-float $(STAGING_DIR)/lib/gcc-lib/$(REAL_GNU_TARGET_NAME)/$(GCC_VERSION)/specs
+endif
+endif
+ #
+ # Ok... that's enough of that.
+ #
+ touch $@
+
+$(GCC_BUILD_DIR)/.libs_installed: $(GCC_BUILD_DIR)/.installed
+ifeq ($(BR2_INSTALL_LIBSTDCPP),y)
+ # We have disabled building of libstdc++ for NuttX
+ #-cp -dpf $(STAGING_DIR)/lib/libstdc++.so* $(TARGET_DIR)/lib/
+endif
+ifeq ($(BR2_INSTALL_LIBGCJ),y)
+ -cp -dpf $(STAGING_DIR)/lib/libgcj.so* $(TARGET_DIR)/lib/
+ -cp -dpf $(STAGING_DIR)/lib/lib-org-w3c-dom.so* $(TARGET_DIR)/lib/
+ -cp -dpf $(STAGING_DIR)/lib/lib-org-xml-sax.so* $(TARGET_DIR)/lib/
+ -mkdir -p $(TARGET_DIR)/usr/lib/security
+ -cp -dpf $(STAGING_DIR)/usr/lib/security/libgcj.security $(TARGET_DIR)/usr/lib/security/
+ -cp -dpf $(STAGING_DIR)/usr/lib/security/classpath.security $(TARGET_DIR)/usr/lib/security/
+endif
+ touch $@
+
+gcc: binutils $(LIBFLOAT_TARGET) \
+ $(GCC_BUILD_DIR)/.installed $(GCC_BUILD_DIR)/.libs_installed \
+ $(GCC_TARGETS)
+
+gcc-source: $(DL_DIR)/$(GCC_SOURCE)
+
+gcc-clean:
+ rm -rf $(GCC_BUILD_DIR)
+ for prog in cpp gcc gcc-[0-9]* protoize unprotoize gcov gccbug cc; do \
+ rm -f $(STAGING_DIR)/bin/$(REAL_GNU_TARGET_NAME)-$$prog \
+ rm -f $(STAGING_DIR)/bin/$(GNU_TARGET_NAME)-$$prog; \
+ done
+
+gcc-dirclean:
+ rm -rf $(GCC_BUILD_DIR)
+
+ifeq ($(strip $(BR2_PACKAGE_GCC)),y)
+TARGETS += gcc
+endif
+endif
diff --git a/misc/buildroot/toolchain/gcc/gcc-nuttx-4.x.mk b/misc/buildroot/toolchain/gcc/gcc-nuttx-4.x.mk
new file mode 100644
index 000000000..25da37e29
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/gcc-nuttx-4.x.mk
@@ -0,0 +1,208 @@
+# Makefile for to build a gcc/nuttx toolchain
+#
+# Copyright (C) 2002-2003 Erik Andersen <andersen@uclibc.org>
+# Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# sysroot support works with gcc >= 4.2.0 only
+ifeq ($(BR2_GCC_SUPPORTS_SYSROOT),y)
+
+GCC_OFFICIAL_VER:=$(GCC_VERSION)
+GCC_SITE:=http://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VERSION)
+#GCC_SITE:=ftp://ftp.ibiblio.org/pub/mirrors/gnu/ftp/gnu/gcc/gcc-$(GCC_OFFICIAL_VER)
+
+GCC_SOURCE:=gcc-$(GCC_OFFICIAL_VER).tar.bz2
+GCC_DIR:=$(TOOL_BUILD_DIR)/gcc-$(GCC_OFFICIAL_VER)
+GCC_CAT:=$(BZCAT)
+GCC_STRIP_HOST_BINARIES:=true
+
+# gcc 4.6.x quadmath requires wchar
+ifneq ($(BR2_TOOLCHAIN_BUILDROOT_WCHAR),y)
+GCC_QUADMATH=--disable-libquadmath
+endif
+
+#############################################################
+#
+# Setup some initial stuff
+#
+#############################################################
+
+GCC_TARGET_LANGUAGES:=c
+
+ifeq ($(BR2_INSTALL_LIBSTDCPP),y)
+GCC_TARGET_LANGUAGES:=$(GCC_TARGET_LANGUAGES),c++
+endif
+
+ifeq ($(BR2_INSTALL_LIBGCJ),y)
+GCC_TARGET_LANGUAGES:=$(GCC_TARGET_LANGUAGES),java
+endif
+
+ifeq ($(BR2_INSTALL_OBJC),y)
+GCC_TARGET_LANGUAGES:=$(GCC_TARGET_LANGUAGES),objc
+endif
+
+ifeq ($(BR2_INSTALL_FORTRAN),y)
+GCC_TARGET_LANGUAGES:=$(GCC_TARGET_LANGUAGES),fortran
+endif
+
+GCC_SHARED_LIBGCC:=--disable-shared
+
+ifneq ($(BR2_ENABLE_LOCALE),y)
+GCC_ENABLE_CLOCALE:=--disable-clocale
+endif
+
+#############################################################
+#
+# build the gcc compiler
+#
+#############################################################
+GCC_BUILD_DIR:=$(TOOL_BUILD_DIR)/gcc-$(GCC_VERSION)-build
+
+$(DL_DIR)/$(GCC_SOURCE):
+ mkdir -p $(DL_DIR)
+ $(WGET) -P $(DL_DIR) $(GCC_SITE)/$(GCC_SOURCE)
+
+gcc-unpacked: $(GCC_DIR)/.unpacked
+$(GCC_DIR)/.unpacked: $(DL_DIR)/$(GCC_SOURCE)
+ mkdir -p $(TOOL_BUILD_DIR)
+ $(GCC_CAT) $(DL_DIR)/$(GCC_SOURCE) | tar -C $(TOOL_BUILD_DIR) $(TAR_OPTIONS) -
+ $(CONFIG_UPDATE) $(GCC_DIR)
+ touch $@
+
+gcc-patched: $(GCC_DIR)/.patched
+$(GCC_DIR)/.patched: $(GCC_DIR)/.unpacked
+ # Apply any files named gcc-*.patch from the source directory to gcc
+ toolchain/patch-kernel.sh $(GCC_DIR) toolchain/gcc/$(GCC_VERSION) \*.patch
+
+ # Note: The soft float situation has improved considerably with gcc 3.4.x.
+ # We can dispense with the custom spec files, as well as libfloat for the arm case.
+ # However, we still need a patch for arm. There's a similar patch for gcc 3.3.x
+ # which needs to be integrated so we can kill of libfloat for good, except for
+ # anyone (?) who might still be using gcc 2.95. mjn3
+ifeq ($(BR2_SOFT_FLOAT),y)
+ifeq ("$(strip $(ARCH))","arm")
+ toolchain/patch-kernel.sh $(GCC_DIR) toolchain/gcc/$(GCC_VERSION) arm-softfloat.patch.conditional
+endif
+ifeq ("$(strip $(ARCH))","armeb")
+ toolchain/patch-kernel.sh $(GCC_DIR) toolchain/gcc/$(GCC_VERSION) arm-softfloat.patch.conditional
+endif
+endif
+ touch $@
+
+$(GCC_BUILD_DIR)/.configured: $(GCC_DIR)/.patched
+ mkdir -p $(GCC_BUILD_DIR)
+ # Important! Required for limits.h to be fixed.
+ ln -snf ../include/ $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/sys-include
+ (cd $(GCC_BUILD_DIR); rm -rf config.cache; PATH=$(TARGET_PATH) \
+ CC="$(HOSTCC)" \
+ $(GCC_DIR)/configure \
+ --prefix=$(STAGING_DIR) \
+ --build=$(GNU_HOST_NAME) \
+ --host=$(GNU_HOST_NAME) \
+ --target=$(REAL_GNU_TARGET_NAME) \
+ --enable-languages=$(GCC_TARGET_LANGUAGES) \
+ --disable-__cxa_atexit \
+ --disable-libssp \
+ --enable-target-optspace \
+ --with-gnu-ld \
+ $(GCC_SHARED_LIBGCC) \
+ $(DISABLE_NLS) \
+ $(THREADS) \
+ $(MULTILIB) \
+ $(SOFT_FLOAT_CONFIG_OPTION) \
+ $(GCC_WITH_ABI) $(GCC_WITH_ARCH) $(GCC_WITH_TUNE) $(GCC_WITH_MODE) \
+ $(GCC_USE_SJLJ_EXCEPTIONS) \
+ $(DISABLE_LARGEFILE) \
+ $(EXTRA_GCC_CONFIG_OPTIONS));
+ touch $@
+
+$(GCC_BUILD_DIR)/.compiled: $(GCC_BUILD_DIR)/.configured
+ PATH=$(TARGET_PATH) $(MAKE) -C $(GCC_BUILD_DIR) all
+ touch $@
+
+$(GCC_BUILD_DIR)/.installed: $(GCC_BUILD_DIR)/.compiled
+ PATH=$(TARGET_PATH) $(MAKE) -C $(GCC_BUILD_DIR) install
+ if [ -d "$(STAGING_DIR)/lib64" ] ; then \
+ if [ ! -e "$(STAGING_DIR)/lib" ] ; then \
+ mkdir "$(STAGING_DIR)/lib" ; \
+ fi ; \
+ mv "$(STAGING_DIR)/lib64/"* "$(STAGING_DIR)/lib/" ; \
+ rmdir "$(STAGING_DIR)/lib64" ; \
+ fi
+ # Strip the host binaries
+ifeq ($(GCC_STRIP_HOST_BINARIES),true)
+ -strip --strip-all -R .note -R .comment $(STAGING_DIR)/bin/*
+endif
+ # Make sure we have 'cc'.
+ if [ ! -e $(STAGING_DIR)/bin/$(REAL_GNU_TARGET_NAME)-cc ] ; then \
+ ln -snf $(REAL_GNU_TARGET_NAME)-gcc \
+ $(STAGING_DIR)/bin/$(REAL_GNU_TARGET_NAME)-cc ; \
+ fi;
+ if [ ! -e $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/bin/cc ] ; then \
+ ln -snf gcc $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/bin/cc ; \
+ fi;
+ # Set up the symlinks to enable lying about target name.
+ set -e; \
+ (cd $(STAGING_DIR); \
+ if [ "$(REAL_GNU_TARGET_NAME)" != "$(GNU_TARGET_NAME)" ]; then \
+ ln -snf $(REAL_GNU_TARGET_NAME) $(GNU_TARGET_NAME); \
+ cd bin; \
+ for app in $(REAL_GNU_TARGET_NAME)-* ; do \
+ ln -snf $${app} \
+ $(GNU_TARGET_NAME)$${app##$(REAL_GNU_TARGET_NAME)}; \
+ done; \
+ fi; \
+ );
+ #
+ # Ok... that's enough of that.
+ #
+ touch $@
+
+$(GCC_BUILD_DIR)/.libs_installed: $(GCC_BUILD_DIR)/.installed
+ifeq ($(BR2_INSTALL_LIBSTDCPP),y)
+ # We have disabled building of libstdc++ for NuttX
+ #-cp -dpf $(STAGING_DIR)/lib/libstdc++.so* $(TARGET_DIR)/lib/
+endif
+ifeq ($(BR2_INSTALL_LIBGCJ),y)
+ -cp -dpf $(STAGING_DIR)/lib/libgcj.so* $(TARGET_DIR)/lib/
+ -cp -dpf $(STAGING_DIR)/lib/lib-org-w3c-dom.so* $(TARGET_DIR)/lib/
+ -cp -dpf $(STAGING_DIR)/lib/lib-org-xml-sax.so* $(TARGET_DIR)/lib/
+ -mkdir -p $(TARGET_DIR)/usr/lib/security
+ -cp -dpf $(STAGING_DIR)/usr/lib/security/libgcj.security $(TARGET_DIR)/usr/lib/security/
+ -cp -dpf $(STAGING_DIR)/usr/lib/security/classpath.security $(TARGET_DIR)/usr/lib/security/
+endif
+ touch $@
+
+gcc: binutils $(LIBFLOAT_TARGET) \
+ $(GCC_BUILD_DIR)/.installed $(GCC_BUILD_DIR)/.libs_installed \
+ $(GCC_TARGETS)
+
+gcc-source: $(DL_DIR)/$(GCC_SOURCE)
+
+gcc-clean:
+ rm -rf $(GCC_BUILD_DIR)
+ for prog in cpp gcc gcc-[0-9]* protoize unprotoize gcov gccbug cc; do \
+ rm -f $(STAGING_DIR)/bin/$(REAL_GNU_TARGET_NAME)-$$prog \
+ rm -f $(STAGING_DIR)/bin/$(GNU_TARGET_NAME)-$$prog; \
+ done
+
+gcc-dirclean:
+ rm -rf $(GCC_BUILD_DIR)
+
+ifeq ($(strip $(BR2_PACKAGE_GCC)),y)
+TARGETS += gcc
+endif
+endif
diff --git a/misc/buildroot/toolchain/gcc/i386-gcc-soft-float.patch b/misc/buildroot/toolchain/gcc/i386-gcc-soft-float.patch
new file mode 100644
index 000000000..97501087e
--- /dev/null
+++ b/misc/buildroot/toolchain/gcc/i386-gcc-soft-float.patch
@@ -0,0 +1,61 @@
+diff -urN gcc-3.3.2-orig/gcc/config/i386/i386.h gcc-3.3.2/gcc/config/i386/i386.h
+--- gcc-3.3.2-orig/gcc/config/i386/i386.h 2003-06-25 16:18:31.000000000 -0500
++++ gcc-3.3.2/gcc/config/i386/i386.h 2003-10-22 01:46:57.000000000 -0500
+@@ -653,6 +653,7 @@
+ /* Define for XFmode or TFmode extended real floating point support.
+ The XFmode is specified by i386 ABI, while TFmode may be faster
+ due to alignment and simplifications in the address calculations. */
++#if 0
+ #define LONG_DOUBLE_TYPE_SIZE (TARGET_128BIT_LONG_DOUBLE ? 128 : 96)
+ #define MAX_LONG_DOUBLE_TYPE_SIZE 128
+ #ifdef __x86_64__
+@@ -660,6 +661,17 @@
+ #else
+ #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 96
+ #endif
++#else
++ /* Set up for x86 soft float with 64-bit long doubles, since that's
++ * all the soft float emulation supports. */
++#define LONG_DOUBLE_TYPE_SIZE (TARGET_128BIT_LONG_DOUBLE ? 128 : (TARGET_80387 ? 96 : 64))
++#define MAX_LONG_DOUBLE_TYPE_SIZE 128
++#ifdef __x86_64__
++#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128
++#else
++#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE (TARGET_80387 ? 96 : 64)
++#endif
++#endif
+
+ /* Set the value of FLT_EVAL_METHOD in float.h. When using only the
+ FPU, assume that the fpcw is set to extended precision; when using
+diff -urN gcc-3.3.2-orig/gcc/config/t-linux gcc-3.3.2/gcc/config/t-linux
+--- gcc-3.3.2-orig/gcc/config/t-linux-uclibc 2003-06-04 11:56:11.000000000 -0500
++++ gcc-3.3.2/gcc/config/t-linux-uclibc 2003-10-22 01:46:39.000000000 -0500
+@@ -21,3 +21,28 @@
+ LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \
+ $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
+ LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h
++
++##############################################
++# We want fine grained libraries, so use the new code to build the
++# floating point emulation libraries.
++FPBIT = fp-bit.c
++DPBIT = dp-bit.c
++
++#LIB2FUNCS_EXTRA = xp-bit.c
++
++dp-bit.c: $(srcdir)/config/fp-bit.c
++ echo '#ifdef __LITTLE_ENDIAN__' > dp-bit.c
++ echo '#define FLOAT_BIT_ORDER_MISMATCH' >>dp-bit.c
++ echo '#endif' >> dp-bit.c
++ cat $(srcdir)/config/fp-bit.c >> dp-bit.c
++
++fp-bit.c: $(srcdir)/config/fp-bit.c
++ echo '#define FLOAT' > fp-bit.c
++ echo '#ifdef __LITTLE_ENDIAN__' >> fp-bit.c
++ echo '#define FLOAT_BIT_ORDER_MISMATCH' >>fp-bit.c
++ echo '#endif' >> fp-bit.c
++ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
++
++#MULTILIB_OPTIONS = msoft-float
++#MULTILIB_DIRNAMES = soft-float
++
diff --git a/misc/buildroot/toolchain/gdb/6.3/400-mips-coredump.patch-2.4.23-29 b/misc/buildroot/toolchain/gdb/6.3/400-mips-coredump.patch-2.4.23-29
new file mode 100644
index 000000000..4e17ba7be
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/400-mips-coredump.patch-2.4.23-29
@@ -0,0 +1,28 @@
+Sometime around 2.4.22-23, the mips pt_regs.h fields were reordered, breaking
+coredump handling by gdb for current kernels. Update the hardcoded constants
+to reflect the change.
+--- gdb-6.2.1/gdb/mips-linux-tdep.c-orig 2004-10-29 14:23:55.000000000 -0500
++++ gdb-6.2.1/gdb/mips-linux-tdep.c 2004-10-29 14:26:44.000000000 -0500
+@@ -53,12 +53,22 @@
+
+ #define EF_REG0 6
+ #define EF_REG31 37
++
++#if 0
+ #define EF_LO 38
+ #define EF_HI 39
+ #define EF_CP0_EPC 40
+ #define EF_CP0_BADVADDR 41
+ #define EF_CP0_STATUS 42
+ #define EF_CP0_CAUSE 43
++#else
++#define EF_CP0_STATUS 38
++#define EF_LO 39
++#define EF_HI 40
++#define EF_CP0_BADVADDR 41
++#define EF_CP0_CAUSE 42
++#define EF_CP0_EPC 43
++#endif
+
+ #define EF_SIZE 180
+
diff --git a/misc/buildroot/toolchain/gdb/6.3/500-thread-timeout.patch b/misc/buildroot/toolchain/gdb/6.3/500-thread-timeout.patch
new file mode 100644
index 000000000..6db0a7a47
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/500-thread-timeout.patch
@@ -0,0 +1,34 @@
+--- gdb-6.3.org/gdb/gdbserver/thread-db.c 2004-10-17 02:42:00.000000000 +0900
++++ gdb-6.3/gdb/gdbserver/thread-db.c 2005-01-27 12:19:29.000000000 +0900
+@@ -21,6 +21,7 @@
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
++#include <unistd.h>
+ #include "server.h"
+
+ #include "linux-low.h"
+@@ -142,6 +143,7 @@
+ td_event_msg_t msg;
+ td_err_e err;
+ struct inferior_linux_data *tdata;
++ int timeout;
+
+ if (debug_threads)
+ fprintf (stderr, "Thread creation event.\n");
+@@ -152,7 +154,13 @@
+ In the LinuxThreads implementation, this is safe,
+ because all events come from the manager thread
+ (except for its own creation, of course). */
+- err = td_ta_event_getmsg (thread_agent, &msg);
++ for (timeout = 0; timeout < 50000; timeout++)
++ {
++ err = td_ta_event_getmsg (thread_agent, &msg);
++ if (err != TD_NOMSG)
++ break;
++ usleep(1000);
++ }
+ if (err != TD_OK)
+ fprintf (stderr, "thread getmsg err: %s\n",
+ thread_db_err_str (err));
+
diff --git a/misc/buildroot/toolchain/gdb/6.3/600-debian_10.selected-frame.patch b/misc/buildroot/toolchain/gdb/6.3/600-debian_10.selected-frame.patch
new file mode 100644
index 000000000..5970f9ba4
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/600-debian_10.selected-frame.patch
@@ -0,0 +1,552 @@
+2004-10-11
+
+This patch is not submitted. Many of these functions should be passing
+a frame around rather than calling get_selected_frame, but at least it
+is an improvement over deprecated_selected_frame.
+
+Index: gdb-6.3/gdb/breakpoint.c
+===================================================================
+--- gdb-6.3.orig/gdb/breakpoint.c 2004-10-08 13:30:46.000000000 -0400
++++ gdb-6.3/gdb/breakpoint.c 2004-11-09 22:55:11.231620957 -0500
+@@ -922,7 +922,7 @@ insert_bp_location (struct bp_location *
+ /* FIXME drow/2003-09-09: It would be nice if evaluate_expression
+ took a frame parameter, so that we didn't have to change the
+ selected frame. */
+- saved_frame_id = get_frame_id (deprecated_selected_frame);
++ saved_frame_id = get_frame_id (get_selected_frame ());
+
+ /* Determine if the watchpoint is within scope. */
+ if (bpt->owner->exp_valid_block == NULL)
+@@ -5464,14 +5464,9 @@ break_at_finish_at_depth_command_1 (char
+
+ if (default_breakpoint_valid)
+ {
+- if (deprecated_selected_frame)
+- {
+- selected_pc = get_frame_pc (deprecated_selected_frame);
+- if (arg)
+- if_arg = 1;
+- }
+- else
+- error ("No selected frame.");
++ selected_pc = get_frame_pc (get_selected_frame ());
++ if (arg)
++ if_arg = 1;
+ }
+ else
+ error ("No default breakpoint address now.");
+@@ -5542,15 +5537,10 @@ break_at_finish_command_1 (char *arg, in
+ {
+ if (default_breakpoint_valid)
+ {
+- if (deprecated_selected_frame)
+- {
+- addr_string = xstrprintf ("*0x%s",
+- paddr_nz (get_frame_pc (deprecated_selected_frame)));
+- if (arg)
+- if_arg = 1;
+- }
+- else
+- error ("No selected frame.");
++ addr_string = xstrprintf ("*0x%s",
++ paddr_nz (get_frame_pc (get_selected_frame ())));
++ if (arg)
++ if_arg = 1;
+ }
+ else
+ error ("No default breakpoint address now.");
+@@ -6082,7 +6072,7 @@ until_break_command (char *arg, int from
+ {
+ struct symtabs_and_lines sals;
+ struct symtab_and_line sal;
+- struct frame_info *prev_frame = get_prev_frame (deprecated_selected_frame);
++ struct frame_info *prev_frame = get_prev_frame (get_selected_frame ());
+ struct breakpoint *breakpoint;
+ struct cleanup *old_chain;
+ struct continuation_arg *arg1;
+@@ -6119,7 +6109,7 @@ until_break_command (char *arg, int from
+ /* Otherwise, specify the current frame, because we want to stop only
+ at the very same frame. */
+ breakpoint = set_momentary_breakpoint (sal,
+- get_frame_id (deprecated_selected_frame),
++ get_frame_id (get_selected_frame ()),
+ bp_until);
+
+ if (!target_can_async_p ())
+Index: gdb-6.3/gdb/cli/cli-cmds.c
+===================================================================
+--- gdb-6.3.orig/gdb/cli/cli-cmds.c 2004-09-11 06:24:53.000000000 -0400
++++ gdb-6.3/gdb/cli/cli-cmds.c 2004-11-09 22:51:07.323246218 -0500
+@@ -845,10 +845,7 @@ disassemble_command (char *arg, int from
+ name = NULL;
+ if (!arg)
+ {
+- if (!deprecated_selected_frame)
+- error ("No frame selected.\n");
+-
+- pc = get_frame_pc (deprecated_selected_frame);
++ pc = get_frame_pc (get_selected_frame ());
+ if (find_pc_partial_function (pc, &name, &low, &high) == 0)
+ error ("No function contains program counter for selected frame.\n");
+ #if defined(TUI)
+Index: gdb-6.3/gdb/f-valprint.c
+===================================================================
+--- gdb-6.3.orig/gdb/f-valprint.c 2003-10-14 02:51:14.000000000 -0400
++++ gdb-6.3/gdb/f-valprint.c 2004-11-09 22:51:07.326245632 -0500
+@@ -76,7 +76,7 @@ f77_get_dynamic_lowerbound (struct type
+ switch (TYPE_ARRAY_LOWER_BOUND_TYPE (type))
+ {
+ case BOUND_BY_VALUE_ON_STACK:
+- current_frame_addr = get_frame_base (deprecated_selected_frame);
++ current_frame_addr = get_frame_base (get_selected_frame ());
+ if (current_frame_addr > 0)
+ {
+ *lower_bound =
+@@ -100,7 +100,7 @@ f77_get_dynamic_lowerbound (struct type
+ break;
+
+ case BOUND_BY_REF_ON_STACK:
+- current_frame_addr = get_frame_base (deprecated_selected_frame);
++ current_frame_addr = get_frame_base (get_selected_frame ());
+ if (current_frame_addr > 0)
+ {
+ ptr_to_lower_bound =
+@@ -134,7 +134,7 @@ f77_get_dynamic_upperbound (struct type
+ switch (TYPE_ARRAY_UPPER_BOUND_TYPE (type))
+ {
+ case BOUND_BY_VALUE_ON_STACK:
+- current_frame_addr = get_frame_base (deprecated_selected_frame);
++ current_frame_addr = get_frame_base (get_selected_frame ());
+ if (current_frame_addr > 0)
+ {
+ *upper_bound =
+@@ -163,7 +163,7 @@ f77_get_dynamic_upperbound (struct type
+ break;
+
+ case BOUND_BY_REF_ON_STACK:
+- current_frame_addr = get_frame_base (deprecated_selected_frame);
++ current_frame_addr = get_frame_base (get_selected_frame ());
+ if (current_frame_addr > 0)
+ {
+ ptr_to_upper_bound =
+@@ -630,10 +630,7 @@ info_common_command (char *comname, int
+ first make sure that it is visible and if so, let
+ us display its contents */
+
+- fi = deprecated_selected_frame;
+-
+- if (fi == NULL)
+- error ("No frame selected");
++ fi = get_selected_frame ();
+
+ /* The following is generally ripped off from stack.c's routine
+ print_frame_info() */
+@@ -722,10 +719,7 @@ there_is_a_visible_common_named (char *c
+ if (comname == NULL)
+ error ("Cannot deal with NULL common name!");
+
+- fi = deprecated_selected_frame;
+-
+- if (fi == NULL)
+- error ("No frame selected");
++ fi = get_selected_frame ();
+
+ /* The following is generally ripped off from stack.c's routine
+ print_frame_info() */
+Index: gdb-6.3/gdb/infcmd.c
+===================================================================
+--- gdb-6.3.orig/gdb/infcmd.c 2004-09-13 14:26:28.000000000 -0400
++++ gdb-6.3/gdb/infcmd.c 2004-11-09 22:57:37.274099559 -0500
+@@ -1214,10 +1214,8 @@ finish_command (char *arg, int from_tty)
+ error ("The \"finish\" command does not take any arguments.");
+ if (!target_has_execution)
+ error ("The program is not running.");
+- if (deprecated_selected_frame == NULL)
+- error ("No selected frame.");
+
+- frame = get_prev_frame (deprecated_selected_frame);
++ frame = get_prev_frame (get_selected_frame ());
+ if (frame == 0)
+ error ("\"finish\" not meaningful in the outermost frame.");
+
+@@ -1235,7 +1233,7 @@ finish_command (char *arg, int from_tty)
+
+ /* Find the function we will return from. */
+
+- function = find_pc_function (get_frame_pc (deprecated_selected_frame));
++ function = find_pc_function (get_frame_pc (get_selected_frame ()));
+
+ /* Print info on the selected frame, including level number but not
+ source. */
+@@ -1600,13 +1598,11 @@ registers_info (char *addr_exp, int fpre
+
+ if (!target_has_registers)
+ error ("The program has no registers now.");
+- if (deprecated_selected_frame == NULL)
+- error ("No selected frame.");
+
+ if (!addr_exp)
+ {
+ gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
+- deprecated_selected_frame, -1, fpregs);
++ get_selected_frame (), -1, fpregs);
+ return;
+ }
+
+@@ -1644,7 +1640,7 @@ registers_info (char *addr_exp, int fpre
+ if (regnum >= 0)
+ {
+ gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
+- deprecated_selected_frame, regnum, fpregs);
++ get_selected_frame (), regnum, fpregs);
+ continue;
+ }
+ }
+@@ -1658,7 +1654,7 @@ registers_info (char *addr_exp, int fpre
+ && regnum < NUM_REGS + NUM_PSEUDO_REGS)
+ {
+ gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
+- deprecated_selected_frame, regnum, fpregs);
++ get_selected_frame (), regnum, fpregs);
+ continue;
+ }
+ }
+@@ -1684,7 +1680,7 @@ registers_info (char *addr_exp, int fpre
+ if (gdbarch_register_reggroup_p (current_gdbarch, regnum,
+ group))
+ gdbarch_print_registers_info (current_gdbarch,
+- gdb_stdout, deprecated_selected_frame,
++ gdb_stdout, get_selected_frame (),
+ regnum, fpregs);
+ }
+ continue;
+@@ -1714,8 +1710,6 @@ print_vector_info (struct gdbarch *gdbar
+ {
+ if (!target_has_registers)
+ error ("The program has no registers now.");
+- if (deprecated_selected_frame == NULL)
+- error ("No selected frame.");
+
+ if (gdbarch_print_vector_info_p (gdbarch))
+ gdbarch_print_vector_info (gdbarch, file, frame, args);
+@@ -1740,7 +1734,7 @@ print_vector_info (struct gdbarch *gdbar
+ static void
+ vector_info (char *args, int from_tty)
+ {
+- print_vector_info (current_gdbarch, gdb_stdout, deprecated_selected_frame, args);
++ print_vector_info (current_gdbarch, gdb_stdout, get_selected_frame (), args);
+ }
+
+
+@@ -1910,8 +1904,6 @@ print_float_info (struct gdbarch *gdbarc
+ {
+ if (!target_has_registers)
+ error ("The program has no registers now.");
+- if (deprecated_selected_frame == NULL)
+- error ("No selected frame.");
+
+ if (gdbarch_print_float_info_p (gdbarch))
+ gdbarch_print_float_info (gdbarch, file, frame, args);
+@@ -1937,7 +1929,7 @@ No floating-point info available for thi
+ static void
+ float_info (char *args, int from_tty)
+ {
+- print_float_info (current_gdbarch, gdb_stdout, deprecated_selected_frame, args);
++ print_float_info (current_gdbarch, gdb_stdout, get_selected_frame (), args);
+ }
+
+ static void
+Index: gdb-6.3/gdb/inflow.c
+===================================================================
+--- gdb-6.3.orig/gdb/inflow.c 2004-08-11 05:00:57.000000000 -0400
++++ gdb-6.3/gdb/inflow.c 2004-11-09 22:58:37.488338883 -0500
+@@ -591,10 +591,7 @@ kill_command (char *arg, int from_tty)
+ if (target_has_stack)
+ {
+ printf_filtered ("In %s,\n", target_longname);
+- if (deprecated_selected_frame == NULL)
+- fputs_filtered ("No selected stack frame.\n", gdb_stdout);
+- else
+- print_stack_frame (get_selected_frame (), 1, SRC_AND_LOC);
++ print_stack_frame (get_selected_frame (), 1, SRC_AND_LOC);
+ }
+ bfd_cache_close_all ();
+ }
+Index: gdb-6.3/gdb/infrun.c
+===================================================================
+--- gdb-6.3.orig/gdb/infrun.c 2004-09-27 13:58:08.000000000 -0400
++++ gdb-6.3/gdb/infrun.c 2004-11-09 22:51:07.351240752 -0500
+@@ -3485,7 +3485,7 @@ save_inferior_status (int restore_stack_
+
+ inf_status->registers = regcache_dup (current_regcache);
+
+- inf_status->selected_frame_id = get_frame_id (deprecated_selected_frame);
++ inf_status->selected_frame_id = get_frame_id (get_selected_frame ());
+ return inf_status;
+ }
+
+Index: gdb-6.3/gdb/mi/mi-main.c
+===================================================================
+--- gdb-6.3.orig/gdb/mi/mi-main.c 2004-09-12 11:00:42.000000000 -0400
++++ gdb-6.3/gdb/mi/mi-main.c 2004-11-09 22:53:29.998389013 -0500
+@@ -388,7 +388,7 @@ register_changed_p (int regnum)
+ {
+ char raw_buffer[MAX_REGISTER_SIZE];
+
+- if (! frame_register_read (deprecated_selected_frame, regnum, raw_buffer))
++ if (! frame_register_read (get_selected_frame (), regnum, raw_buffer))
+ return -1;
+
+ if (memcmp (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer,
+@@ -509,7 +509,7 @@ get_register (int regnum, int format)
+ if (format == 'N')
+ format = 0;
+
+- frame_register (deprecated_selected_frame, regnum, &optim, &lval, &addr,
++ frame_register (get_selected_frame (), regnum, &optim, &lval, &addr,
+ &realnum, buffer);
+
+ if (optim)
+Index: gdb-6.3/gdb/mn10300-tdep.c
+===================================================================
+--- gdb-6.3.orig/gdb/mn10300-tdep.c 2004-08-02 22:02:22.000000000 -0400
++++ gdb-6.3/gdb/mn10300-tdep.c 2004-11-09 22:51:07.356239776 -0500
+@@ -1154,7 +1154,7 @@ mn10300_print_register (const char *name
+ printf_filtered ("%s: ", name);
+
+ /* Get the data */
+- if (!frame_register_read (deprecated_selected_frame, regnum, raw_buffer))
++ if (!frame_register_read (get_selected_frame (), regnum, raw_buffer))
+ {
+ printf_filtered ("[invalid]");
+ return;
+Index: gdb-6.3/gdb/stack.c
+===================================================================
+--- gdb-6.3.orig/gdb/stack.c 2004-08-02 20:57:26.000000000 -0400
++++ gdb-6.3/gdb/stack.c 2004-11-09 22:51:07.361238800 -0500
+@@ -758,9 +758,7 @@ parse_frame_specification (char *frame_e
+ switch (numargs)
+ {
+ case 0:
+- if (deprecated_selected_frame == NULL)
+- error ("No selected frame.");
+- return deprecated_selected_frame;
++ return get_selected_frame ();
+ /* NOTREACHED */
+ case 1:
+ {
+@@ -902,10 +900,10 @@ frame_info (char *addr_exp, int from_tty
+ }
+ calling_frame_info = get_prev_frame (fi);
+
+- if (!addr_exp && frame_relative_level (deprecated_selected_frame) >= 0)
++ if (!addr_exp && frame_relative_level (get_selected_frame ()) >= 0)
+ {
+ printf_filtered ("Stack level %d, frame at ",
+- frame_relative_level (deprecated_selected_frame));
++ frame_relative_level (get_selected_frame ()));
+ print_address_numeric (get_frame_base (fi), 1, gdb_stdout);
+ printf_filtered (":\n");
+ }
+@@ -1445,9 +1443,7 @@ print_frame_label_vars (struct frame_inf
+ void
+ locals_info (char *args, int from_tty)
+ {
+- if (!deprecated_selected_frame)
+- error ("No frame selected.");
+- print_frame_local_vars (deprecated_selected_frame, 0, gdb_stdout);
++ print_frame_local_vars (get_selected_frame (), 0, gdb_stdout);
+ }
+
+ static void
+@@ -1470,7 +1466,7 @@ catch_info (char *ignore, int from_tty)
+ if (!deprecated_selected_frame)
+ error ("No frame selected.");
+
+- print_frame_label_vars (deprecated_selected_frame, 0, gdb_stdout);
++ print_frame_label_vars (get_selected_frame (), 0, gdb_stdout);
+ }
+ }
+
+@@ -1537,9 +1533,7 @@ print_frame_arg_vars (struct frame_info
+ void
+ args_info (char *ignore, int from_tty)
+ {
+- if (!deprecated_selected_frame)
+- error ("No frame selected.");
+- print_frame_arg_vars (deprecated_selected_frame, gdb_stdout);
++ print_frame_arg_vars (get_selected_frame (), gdb_stdout);
+ }
+
+
+@@ -1724,7 +1718,7 @@ down_silently_base (char *count_exp)
+ if (target_has_stack == 0 || deprecated_selected_frame == 0)
+ error ("No stack.");
+
+- frame = find_relative_frame (deprecated_selected_frame, &count1);
++ frame = find_relative_frame (get_selected_frame (), &count1);
+ if (count1 != 0 && count_exp == 0)
+ {
+
+@@ -1944,7 +1938,7 @@ func_command (char *arg, int from_tty)
+
+ if (!found)
+ printf_filtered ("'%s' not within current stack frame.\n", arg);
+- else if (fp != deprecated_selected_frame)
++ else if (fp != get_selected_frame ())
+ select_and_print_frame (fp);
+ }
+
+@@ -1965,7 +1959,7 @@ get_frame_language (void)
+ instruction of another function. So we rely on
+ get_frame_address_in_block(), it provides us with a PC which is
+ guaranteed to be inside the frame's code block. */
+- s = find_pc_symtab (get_frame_address_in_block (deprecated_selected_frame));
++ s = find_pc_symtab (get_frame_address_in_block (get_selected_frame ()));
+ if (s)
+ flang = s->language;
+ else
+Index: gdb-6.3/gdb/tui/tui-disasm.c
+===================================================================
+--- gdb-6.3.orig/gdb/tui/tui-disasm.c 2004-02-24 20:10:01.000000000 -0500
++++ gdb-6.3/gdb/tui/tui-disasm.c 2004-11-09 22:51:07.370237044 -0500
+@@ -382,7 +382,7 @@ tui_vertical_disassem_scroll (enum tui_s
+
+ content = (tui_win_content) TUI_DISASM_WIN->generic.content;
+ if (cursal.symtab == (struct symtab *) NULL)
+- s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
++ s = find_pc_symtab (get_frame_pc (get_selected_frame ()));
+ else
+ s = cursal.symtab;
+
+Index: gdb-6.3/gdb/tui/tui-source.c
+===================================================================
+--- gdb-6.3.orig/gdb/tui/tui-source.c 2004-02-16 16:05:09.000000000 -0500
++++ gdb-6.3/gdb/tui/tui-source.c 2004-11-09 22:51:07.370237044 -0500
+@@ -326,7 +326,7 @@ tui_vertical_source_scroll (enum tui_scr
+ struct symtab_and_line cursal = get_current_source_symtab_and_line ();
+
+ if (cursal.symtab == (struct symtab *) NULL)
+- s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
++ s = find_pc_symtab (get_frame_pc (get_selected_frame ()));
+ else
+ s = cursal.symtab;
+
+Index: gdb-6.3/gdb/tui/tui-winsource.c
+===================================================================
+--- gdb-6.3.orig/gdb/tui/tui-winsource.c 2004-02-16 16:05:09.000000000 -0500
++++ gdb-6.3/gdb/tui/tui-winsource.c 2004-11-09 22:51:07.371236848 -0500
+@@ -311,7 +311,7 @@ tui_horizontal_source_scroll (struct tui
+ struct symtab_and_line cursal = get_current_source_symtab_and_line ();
+
+ if (cursal.symtab == (struct symtab *) NULL)
+- s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
++ s = find_pc_symtab (get_frame_pc (get_selected_frame ()));
+ else
+ s = cursal.symtab;
+
+Index: gdb-6.3/gdb/valops.c
+===================================================================
+--- gdb-6.3.orig/gdb/valops.c 2004-09-13 23:01:48.000000000 -0400
++++ gdb-6.3/gdb/valops.c 2004-11-09 22:51:07.374236263 -0500
+@@ -2663,15 +2663,10 @@ value_of_local (const char *name, int co
+ struct block *b;
+ struct value * ret;
+
+- if (deprecated_selected_frame == 0)
+- {
+- if (complain)
+- error ("no frame selected");
+- else
+- return 0;
+- }
++ if (!complain && deprecated_selected_frame == 0)
++ return 0;
+
+- func = get_frame_function (deprecated_selected_frame);
++ func = get_frame_function (get_selected_frame ());
+ if (!func)
+ {
+ if (complain)
+@@ -2700,7 +2695,7 @@ value_of_local (const char *name, int co
+ return NULL;
+ }
+
+- ret = read_var_value (sym, deprecated_selected_frame);
++ ret = read_var_value (sym, get_selected_frame ());
+ if (ret == 0 && complain)
+ error ("`%s' argument unreadable", name);
+ return ret;
+Index: gdb-6.3/gdb/varobj.c
+===================================================================
+--- gdb-6.3.orig/gdb/varobj.c 2004-07-26 10:53:06.000000000 -0400
++++ gdb-6.3/gdb/varobj.c 2004-11-09 22:51:07.377235677 -0500
+@@ -488,7 +488,7 @@ varobj_create (char *objname,
+ if (fi != NULL)
+ {
+ var->root->frame = get_frame_id (fi);
+- old_fi = deprecated_selected_frame;
++ old_fi = get_selected_frame ();
+ select_frame (fi);
+ }
+
+Index: gdb-6.3/gdb/testsuite/gdb.base/default.exp
+===================================================================
+--- gdb-6.3.orig/gdb/testsuite/gdb.base/default.exp 2003-03-20 09:45:50.000000000 -0500
++++ gdb-6.3/gdb/testsuite/gdb.base/default.exp 2004-11-09 22:51:07.379235287 -0500
+@@ -167,7 +167,7 @@ gdb_test "disable breakpoints" "" "disab
+ #test disable display
+ gdb_test "disable display" "" "disable display"
+ #test disassemble
+-gdb_test "disassemble" "No frame selected." "disassemble"
++gdb_test "disassemble" "No (frame selected|registers)." "disassemble"
+ #test display
+ gdb_test "display" "" "display"
+ #test do
+@@ -229,9 +229,9 @@ gdb_expect {
+ }
+
+ #test frame "f" abbreviation
+-gdb_test "f" "No stack." "frame \"f\" abbreviation"
++gdb_test "f" "No (stack|registers)." "frame \"f\" abbreviation"
+ #test frame
+-gdb_test "frame" "No stack." "frame"
++gdb_test "frame" "No (stack|registers)." "frame"
+ #test fg
+ gdb_test "fg" "The program is not being run." "fg"
+ # FIXME: fg kills the udi connection
+@@ -294,9 +294,9 @@ gdb_test "ignore" "Argument required .a
+ #test info address
+ gdb_test "info address" "Argument required." "info address"
+ #test info all-registers
+-gdb_test "info all-registers" "The program has no registers now." "info all-registers"
++gdb_test "info all-registers" "(The program has no registers now|No registers)." "info all-registers"
+ #test info args
+-gdb_test "info args" "No frame selected." "info args"
++gdb_test "info args" "No (frame selected|registers)." "info args"
+ #test info bogus-gdb-command
+ gdb_test "info bogus-gdb-command" "Undefined info command: \"bogus-gdb-command\". Try \"help info\".*" "info bogus-gdb-command"
+ #test info breakpoints
+@@ -320,11 +320,11 @@ gdb_test "info frame" "No stack.|No sele
+ #test info files
+ gdb_test "info files" "" "info files"
+ #test info float
+-gdb_test "info float" "The program has no registers now." "info float"
++gdb_test "info float" "(The program has no registers now|No registers)." "info float"
+ #test info functions
+ gdb_test "info functions" "All defined functions:" "info functions"
+ #test info locals
+-gdb_test "info locals" "No frame selected." "info locals"
++gdb_test "info locals" "(No frame selected|No registers)." "info locals"
+ #test info program
+ gdb_test "info program" "The program being debugged is not being run." "info program"
+ #test info registers
+@@ -352,7 +352,7 @@ gdb_test "info types" "All defined types
+ #test info variables
+ gdb_test "info variables" "All defined variables:" "info variables"
+ #test info vector
+-gdb_test "info vector" "The program has no registers now." "info vector"
++gdb_test "info vector" "(The program has no registers now|No registers)." "info vector"
+ #test info warranty
+ gdb_test "info warranty" "NO WARRANTY(\[^\r\n\]*\[\r\n\])+ *11. *BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY(\[^\r\n\]*\[\r\n\])+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN(\[^\r\n\]*\[\r\n\])+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES(\[^\r\n\]*\[\r\n\])+PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED(\[^\r\n\]*\[\r\n\])+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF(\[^\r\n\]*\[\r\n\])+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS(\[^\r\n\]*\[\r\n\])+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE(\[^\r\n\]*\[\r\n\])+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,(\[^\r\n\]*\[\r\n\])+REPAIR OR CORRECTION.(\[^\r\n\]*\[\r\n\])+ *12. *IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING(\[^\r\n\]*\[\r\n\])+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR(\[^\r\n\]*\[\r\n\])+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,(\[^\r\n\]*\[\r\n\])+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING(\[^\r\n\]*\[\r\n\])+OUT OF THE USE OR INABILITY TO USE THE PROGRAM .INCLUDING BUT NOT LIMITED(\[^\r\n\]*\[\r\n\])+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY(\[^\r\n\]*\[\r\n\])+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER(\[^\r\n\]*\[\r\n\])+PROGRAMS., EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE(\[^\r\n\]*\[\r\n\])+POSSIBILITY OF SUCH DAMAGES.*" "info warranty"
+ #test info watchpoints
diff --git a/misc/buildroot/toolchain/gdb/6.3/620-debian_static-thread-db.patch b/misc/buildroot/toolchain/gdb/6.3/620-debian_static-thread-db.patch
new file mode 100644
index 000000000..c5ac5a623
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/620-debian_static-thread-db.patch
@@ -0,0 +1,156 @@
+Status: submitted similar patch 2004-12-08
+
+This patch cleans up the initialization of thread_db. It works for static
+binaries now. The vsyscall patches hide this problem, since new static
+binaries will load the vsyscall DSO and then trigger thread_db; but
+this is still a good cleanup.
+
+Index: gdb-6.3/gdb/thread-db.c
+===================================================================
+--- gdb-6.3.orig/gdb/thread-db.c 2004-10-08 16:29:56.000000000 -0400
++++ gdb-6.3/gdb/thread-db.c 2004-11-10 00:19:30.626530413 -0500
+@@ -34,6 +34,7 @@
+ #include "target.h"
+ #include "regcache.h"
+ #include "solib-svr4.h"
++#include "observer.h"
+
+ #ifdef HAVE_GNU_LIBC_VERSION_H
+ #include <gnu/libc-version.h>
+@@ -627,59 +628,49 @@ check_thread_signals (void)
+ #endif
+ }
+
++/* Check whether thread_db is usable. This function is called when
++ an inferior is created (or otherwise acquired, e.g. attached to)
++ and when new shared libraries are loaded into a running process. */
++
+ static void
+-thread_db_new_objfile (struct objfile *objfile)
++check_for_thread_db (void)
+ {
+ td_err_e err;
++ static int already_loaded;
+
+ /* First time through, report that libthread_db was successfuly
+ loaded. Can't print this in in thread_db_load as, at that stage,
+- the interpreter and it's console haven't started. The real
+- problem here is that libthread_db is loaded too early - it should
+- only be loaded when there is a program to debug. */
+- {
+- static int dejavu;
+- if (!dejavu)
+- {
+- Dl_info info;
+- const char *library = NULL;
+- /* Try dladdr. */
+- if (dladdr ((*td_ta_new_p), &info) != 0)
+- library = info.dli_fname;
+- /* Try dlinfo? */
+- if (library == NULL)
+- /* Paranoid - don't let a NULL path slip through. */
+- library = LIBTHREAD_DB_SO;
+- printf_unfiltered ("Using host libthread_db library \"%s\".\n",
+- library);
+- dejavu = 1;
+- }
+- }
++ the interpreter and it's console haven't started. */
+
+- /* Don't attempt to use thread_db on targets which can not run
+- (core files). */
+- if (objfile == NULL || !target_has_execution)
++ if (!already_loaded)
+ {
+- /* All symbols have been discarded. If the thread_db target is
+- active, deactivate it now. */
+- if (using_thread_db)
+- {
+- gdb_assert (proc_handle.pid == 0);
+- unpush_target (&thread_db_ops);
+- using_thread_db = 0;
+- }
++ Dl_info info;
++ const char *library = NULL;
++ if (dladdr ((*td_ta_new_p), &info) != 0)
++ library = info.dli_fname;
++
++ /* Try dlinfo? */
+
+- goto quit;
++ if (library == NULL)
++ /* Paranoid - don't let a NULL path slip through. */
++ library = LIBTHREAD_DB_SO;
++
++ printf_unfiltered ("Using host libthread_db library \"%s\".\n",
++ library);
++ already_loaded = 1;
+ }
+
+ if (using_thread_db)
+ /* Nothing to do. The thread library was already detected and the
+ target vector was already activated. */
+- goto quit;
++ return;
++
++ /* Don't attempt to use thread_db on targets which can not run
++ (executables not running yet, core files) for now. */
++ if (!target_has_execution)
++ return;
+
+- /* Initialize the structure that identifies the child process. Note
+- that at this point there is no guarantee that we actually have a
+- child process. */
++ /* Initialize the structure that identifies the child process. */
+ proc_handle.pid = GET_PID (inferior_ptid);
+
+ /* Now attempt to open a connection to the thread library. */
+@@ -706,12 +697,24 @@ thread_db_new_objfile (struct objfile *o
+ thread_db_err_str (err));
+ break;
+ }
++}
++
++static void
++thread_db_new_objfile (struct objfile *objfile)
++{
++ if (objfile != NULL)
++ check_for_thread_db ();
+
+-quit:
+ if (target_new_objfile_chain)
+ target_new_objfile_chain (objfile);
+ }
+
++static void
++check_for_thread_db_observer (struct target_ops *target, int from_tty)
++{
++ check_for_thread_db ();
++}
++
+ /* Attach to a new thread. This function is called when we receive a
+ TD_CREATE event or when we iterate over all threads and find one
+ that wasn't already in our list. */
+@@ -1366,5 +1369,8 @@ _initialize_thread_db (void)
+ /* Add ourselves to objfile event chain. */
+ target_new_objfile_chain = deprecated_target_new_objfile_hook;
+ deprecated_target_new_objfile_hook = thread_db_new_objfile;
++
++ /* Register ourselves for the new inferior observer. */
++ observer_attach_inferior_created (check_for_thread_db_observer);
+ }
+ }
+Index: gdb-6.3/gdb/Makefile.in
+===================================================================
+--- gdb-6.3.orig/gdb/Makefile.in 2004-11-09 23:04:57.000000000 -0500
++++ gdb-6.3/gdb/Makefile.in 2004-11-10 00:19:26.440347022 -0500
+@@ -2626,7 +2626,8 @@ thread.o: thread.c $(defs_h) $(symtab_h)
+ $(gdbcmd_h) $(regcache_h) $(gdb_h) $(gdb_string_h) $(ui_out_h)
+ thread-db.o: thread-db.c $(defs_h) $(gdb_assert_h) $(gdb_proc_service_h) \
+ $(gdb_thread_db_h) $(bfd_h) $(gdbthread_h) $(inferior_h) \
+- $(symfile_h) $(objfiles_h) $(target_h) $(regcache_h) $(solib_svr4_h)
++ $(symfile_h) $(objfiles_h) $(target_h) $(regcache_h) $(solib_svr4_h) \
++ $(observer_h)
+ top.o: top.c $(defs_h) $(gdbcmd_h) $(call_cmds_h) $(cli_cmds_h) \
+ $(cli_script_h) $(cli_setshow_h) $(cli_decode_h) $(symtab_h) \
+ $(inferior_h) $(target_h) $(breakpoint_h) $(gdbtypes_h) \
diff --git a/misc/buildroot/toolchain/gdb/6.3/630-debian_24.tracepoint-segv.patch b/misc/buildroot/toolchain/gdb/6.3/630-debian_24.tracepoint-segv.patch
new file mode 100644
index 000000000..d038ff8ec
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/630-debian_24.tracepoint-segv.patch
@@ -0,0 +1,15 @@
+Trivial. Still need to submit this.
+
+Index: gdb-6.1/gdb/tracepoint.c
+===================================================================
+--- gdb-6.1.orig/gdb/tracepoint.c 2004-04-05 13:26:43.000000000 -0400
++++ gdb-6.1/gdb/tracepoint.c 2004-04-05 13:26:45.000000000 -0400
+@@ -853,6 +853,8 @@ read_actions (struct tracepoint *t)
+ else
+ line = gdb_readline (0);
+
++ if (line == NULL || *line == EOF)
++ break;
+ linetype = validate_actionline (&line, t);
+ if (linetype == BADLINE)
+ continue; /* already warned -- collect another line */
diff --git a/misc/buildroot/toolchain/gdb/6.3/640-debian_dwarf2-frame-signal-unwinder.patch b/misc/buildroot/toolchain/gdb/6.3/640-debian_dwarf2-frame-signal-unwinder.patch
new file mode 100644
index 000000000..246427ee6
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/640-debian_dwarf2-frame-signal-unwinder.patch
@@ -0,0 +1,120 @@
+Status: Checked in to HEAD after 6.3.
+
+2004-11-07 Daniel Jacobowitz <dan@debian.org>
+
+ * dwarf2-frame.c (struct dwarf2_frame_ops): Add signal_frame_p.
+ (dwarf2_frame_set_signal_frame_p, dwarf2_frame_signal_frame_p)
+ (dwarf2_signal_frame_unwind): New.
+ (dwarf2_frame_sniffer): Use dwarf2_frame_signal_frame_p.
+ * dwarf2-frame.h (dwarf2_frame_set_signal_frame_p): New prototype.
+
+Index: src/gdb/dwarf2-frame.c
+===================================================================
+RCS file: /big/fsf/rsync/src-cvs/src/gdb/dwarf2-frame.c,v
+retrieving revision 1.41
+diff -u -p -r1.41 dwarf2-frame.c
+--- src/gdb/dwarf2-frame.c 4 Nov 2004 21:15:15 -0000 1.41
++++ src/gdb/dwarf2-frame.c 7 Nov 2004 17:41:58 -0000
+@@ -471,6 +471,10 @@ struct dwarf2_frame_ops
+ {
+ /* Pre-initialize the register state REG for register REGNUM. */
+ void (*init_reg) (struct gdbarch *, int, struct dwarf2_frame_state_reg *);
++
++ /* Check whether the frame preceding NEXT_FRAME will be a signal
++ trampoline. */
++ int (*signal_frame_p) (struct gdbarch *, struct frame_info *);
+ };
+
+ /* Default architecture-specific register state initialization
+@@ -547,6 +551,33 @@ dwarf2_frame_init_reg (struct gdbarch *g
+
+ ops->init_reg (gdbarch, regnum, reg);
+ }
++
++/* Set the architecture-specific signal trampoline recognition
++ function for GDBARCH to SIGNAL_FRAME_P. */
++
++void
++dwarf2_frame_set_signal_frame_p (struct gdbarch *gdbarch,
++ int (*signal_frame_p) (struct gdbarch *,
++ struct frame_info *))
++{
++ struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
++
++ ops->signal_frame_p = signal_frame_p;
++}
++
++/* Query the architecture-specific signal frame recognizer for
++ NEXT_FRAME. */
++
++static int
++dwarf2_frame_signal_frame_p (struct gdbarch *gdbarch,
++ struct frame_info *next_frame)
++{
++ struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
++
++ if (ops->signal_frame_p == NULL)
++ return 0;
++ return ops->signal_frame_p (gdbarch, next_frame);
++}
+
+
+ struct dwarf2_frame_cache
+@@ -841,6 +872,13 @@ static const struct frame_unwind dwarf2_
+ dwarf2_frame_prev_register
+ };
+
++static const struct frame_unwind dwarf2_signal_frame_unwind =
++{
++ SIGTRAMP_FRAME,
++ dwarf2_frame_this_id,
++ dwarf2_frame_prev_register
++};
++
+ const struct frame_unwind *
+ dwarf2_frame_sniffer (struct frame_info *next_frame)
+ {
+@@ -848,10 +886,18 @@ dwarf2_frame_sniffer (struct frame_info
+ function. frame_pc_unwind(), for a no-return next function, can
+ end up returning something past the end of this function's body. */
+ CORE_ADDR block_addr = frame_unwind_address_in_block (next_frame);
+- if (dwarf2_frame_find_fde (&block_addr))
+- return &dwarf2_frame_unwind;
++ if (!dwarf2_frame_find_fde (&block_addr))
++ return NULL;
+
+- return NULL;
++ /* On some targets, signal trampolines may have unwind information.
++ We need to recognize them so that we set the frame type
++ correctly. */
++
++ if (dwarf2_frame_signal_frame_p (get_frame_arch (next_frame),
++ next_frame))
++ return &dwarf2_signal_frame_unwind;
++
++ return &dwarf2_frame_unwind;
+ }
+
+
+Index: src/gdb/dwarf2-frame.h
+===================================================================
+RCS file: /big/fsf/rsync/src-cvs/src/gdb/dwarf2-frame.h,v
+retrieving revision 1.6
+diff -u -p -r1.6 dwarf2-frame.h
+--- src/gdb/dwarf2-frame.h 28 Feb 2004 16:59:32 -0000 1.6
++++ src/gdb/dwarf2-frame.h 7 Nov 2004 17:40:41 -0000
+@@ -79,6 +79,14 @@ extern void dwarf2_frame_set_init_reg (s
+ void (*init_reg) (struct gdbarch *, int,
+ struct dwarf2_frame_state_reg *));
+
++/* Set the architecture-specific signal trampoline recognition
++ function for GDBARCH to SIGNAL_FRAME_P. */
++
++extern void
++ dwarf2_frame_set_signal_frame_p (struct gdbarch *gdbarch,
++ int (*signal_frame_p) (struct gdbarch *,
++ struct frame_info *));
++
+ /* Return the frame unwind methods for the function that contains PC,
+ or NULL if it can't be handled by DWARF CFI frame unwinder. */
+
diff --git a/misc/buildroot/toolchain/gdb/6.3/650-debian_vsyscall-gdb-support.patch b/misc/buildroot/toolchain/gdb/6.3/650-debian_vsyscall-gdb-support.patch
new file mode 100644
index 000000000..e725f9c54
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/650-debian_vsyscall-gdb-support.patch
@@ -0,0 +1,245 @@
+Status: Checked in to HEAD after 6.3.
+
+2004-11-07 Andrew Cagney <cagney@redhat.com>
+ Daniel Jacobowitz <dan@debian.org>
+ Roland McGrath <roland@redhat.com>
+
+ * Makefile.in (symfile-mem.o): Update dependencies.
+ * i386-linux-tdep.c (i386_linux_dwarf_signal_frame_p): New.
+ (i386_linux_init_abi): Call dwarf2_frame_set_signal_frame_p.
+ * inf-ptrace.c (inf_ptrace_attach): Call
+ observer_notify_inferior_created.
+ * inftarg.c (child_attach): Likewise.
+ * symfile-mem.c: Include "observer.h", "auxv.h", and "elf/common.h".
+ (symbol_file_add_from_memory): Take NAME argument. Use it for
+ the new BFD's filename.
+ (add_symbol_file_from_memory_command): Update call to
+ symbol_file_add_from_memory.
+ (struct symbol_file_add_from_memory_args, add_vsyscall_page)
+ (symbol_file_add_from_memory_wrapper): New.
+ (_initialize_symfile_mem): Register add_vsyscall_page as an
+ inferior_created observer.
+
+Index: gdb-6.3/gdb/i386-linux-tdep.c
+===================================================================
+--- gdb-6.3.orig/gdb/i386-linux-tdep.c 2004-08-06 16:58:28.000000000 -0400
++++ gdb-6.3/gdb/i386-linux-tdep.c 2004-11-10 00:55:06.669398770 -0500
+@@ -27,6 +27,7 @@
+ #include "inferior.h"
+ #include "osabi.h"
+ #include "reggroups.h"
++#include "dwarf2-frame.h"
+
+ #include "gdb_string.h"
+
+@@ -244,6 +245,27 @@ i386_linux_sigtramp_p (struct frame_info
+ || strcmp ("__restore_rt", name) == 0);
+ }
+
++/* Return one if the unwound PC from NEXT_FRAME is in a signal trampoline
++ which may have DWARF-2 CFI. */
++
++static int
++i386_linux_dwarf_signal_frame_p (struct gdbarch *gdbarch,
++ struct frame_info *next_frame)
++{
++ CORE_ADDR pc = frame_pc_unwind (next_frame);
++ char *name;
++
++ find_pc_partial_function (pc, &name, NULL, NULL);
++
++ /* If a vsyscall DSO is in use, the signal trampolines may have these
++ names. */
++ if (name && (strcmp (name, "__kernel_sigreturn") == 0
++ || strcmp (name, "__kernel_rt_sigreturn") == 0))
++ return 1;
++
++ return 0;
++}
++
+ /* Offset to struct sigcontext in ucontext, from <asm/ucontext.h>. */
+ #define I386_LINUX_UCONTEXT_SIGCONTEXT_OFFSET 20
+
+@@ -414,6 +436,8 @@ i386_linux_init_abi (struct gdbarch_info
+
+ /* GNU/Linux uses the dynamic linker included in the GNU C Library. */
+ set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
++
++ dwarf2_frame_set_signal_frame_p (gdbarch, i386_linux_dwarf_signal_frame_p);
+ }
+
+ /* Provide a prototype to silence -Wmissing-prototypes. */
+Index: gdb-6.3/gdb/inf-ptrace.c
+===================================================================
+--- gdb-6.3.orig/gdb/inf-ptrace.c 2004-10-15 09:29:33.000000000 -0400
++++ gdb-6.3/gdb/inf-ptrace.c 2004-11-10 00:53:43.697615843 -0500
+@@ -220,6 +220,10 @@ inf_ptrace_attach (char *args, int from_
+
+ inferior_ptid = pid_to_ptid (pid);
+ push_target (ptrace_ops_hack);
++
++ /* Do this first, before anything has had a chance to query the
++ inferior's symbol table or similar. */
++ observer_notify_inferior_created (&current_target, from_tty);
+ }
+
+ static void
+Index: gdb-6.3/gdb/inftarg.c
+===================================================================
+--- gdb-6.3.orig/gdb/inftarg.c 2004-10-08 16:29:47.000000000 -0400
++++ gdb-6.3/gdb/inftarg.c 2004-11-10 00:53:43.711613107 -0500
+@@ -211,6 +211,10 @@ child_attach (char *args, int from_tty)
+
+ inferior_ptid = pid_to_ptid (pid);
+ push_target (&deprecated_child_ops);
++
++ /* Do this first, before anything has had a chance to query the
++ inferior's symbol table or similar. */
++ observer_notify_inferior_created (&current_target, from_tty);
+ }
+
+ #if !defined(CHILD_POST_ATTACH)
+Index: gdb-6.3/gdb/symfile-mem.c
+===================================================================
+--- gdb-6.3.orig/gdb/symfile-mem.c 2004-07-17 10:24:07.000000000 -0400
++++ gdb-6.3/gdb/symfile-mem.c 2004-11-10 00:53:43.722610958 -0500
+@@ -52,13 +52,19 @@
+ #include "target.h"
+ #include "value.h"
+ #include "symfile.h"
++#include "observer.h"
++#include "auxv.h"
++#include "elf/common.h"
+
+
+ /* Read inferior memory at ADDR to find the header of a loaded object file
+ and read its in-core symbols out of inferior memory. TEMPL is a bfd
+- representing the target's format. */
++ representing the target's format. NAME is the name to use for this
++ symbol file in messages; it can be NULL or a malloc-allocated string
++ which will be attached to the BFD. */
+ static struct objfile *
+-symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, int from_tty)
++symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name,
++ int from_tty)
+ {
+ struct objfile *objf;
+ struct bfd *nbfd;
+@@ -75,7 +81,10 @@ symbol_file_add_from_memory (struct bfd
+ if (nbfd == NULL)
+ error ("Failed to read a valid object file image from memory.");
+
+- nbfd->filename = xstrdup ("shared object read from target memory");
++ if (name == NULL)
++ nbfd->filename = xstrdup ("shared object read from target memory");
++ else
++ nbfd->filename = name;
+
+ if (!bfd_check_format (nbfd, bfd_object))
+ {
+@@ -129,7 +138,73 @@ add_symbol_file_from_memory_command (cha
+ error ("\
+ Must use symbol-file or exec-file before add-symbol-file-from-memory.");
+
+- symbol_file_add_from_memory (templ, addr, from_tty);
++ symbol_file_add_from_memory (templ, addr, NULL, from_tty);
++}
++
++/* Arguments for symbol_file_add_from_memory_wrapper. */
++
++struct symbol_file_add_from_memory_args
++{
++ struct bfd *bfd;
++ CORE_ADDR sysinfo_ehdr;
++ char *name;
++ int from_tty;
++};
++
++/* Wrapper function for symbol_file_add_from_memory, for
++ catch_exceptions. */
++
++static int
++symbol_file_add_from_memory_wrapper (struct ui_out *uiout, void *data)
++{
++ struct symbol_file_add_from_memory_args *args = data;
++
++ symbol_file_add_from_memory (args->bfd, args->sysinfo_ehdr, args->name,
++ args->from_tty);
++ return 0;
++}
++
++/* Try to add the symbols for the vsyscall page, if there is one. This function
++ is called via the inferior_created observer. */
++
++static void
++add_vsyscall_page (struct target_ops *target, int from_tty)
++{
++ CORE_ADDR sysinfo_ehdr;
++
++ if (target_auxv_search (target, AT_SYSINFO_EHDR, &sysinfo_ehdr) > 0
++ && sysinfo_ehdr != (CORE_ADDR) 0)
++ {
++ struct bfd *bfd;
++ struct symbol_file_add_from_memory_args args;
++
++ if (core_bfd != NULL)
++ bfd = core_bfd;
++ else if (exec_bfd != NULL)
++ bfd = exec_bfd;
++ else
++ /* FIXME: cagney/2004-05-06: Should not require an existing
++ BFD when trying to create a run-time BFD of the VSYSCALL
++ page in the inferior. Unfortunately that's the current
++ interface so for the moment bail. Introducing a
++ ``bfd_runtime'' (a BFD created using the loaded image) file
++ format should fix this. */
++ {
++ warning ("could not load vsyscall page because no executable was specified");
++ warning ("try using the \"file\" command first");
++ return;
++ }
++ args.bfd = bfd;
++ args.sysinfo_ehdr = sysinfo_ehdr;
++ xasprintf (&args.name, "system-supplied DSO at 0x%s",
++ paddr_nz (sysinfo_ehdr));
++ /* Pass zero for FROM_TTY, because the action of loading the
++ vsyscall DSO was not triggered by the user, even if the user
++ typed "run" at the TTY. */
++ args.from_tty = 0;
++ catch_exceptions (uiout, symbol_file_add_from_memory_wrapper,
++ &args, NULL, RETURN_MASK_ALL);
++ }
+ }
+
+
+@@ -143,4 +218,7 @@ Load the symbols out of memory from a dy
+ Give an expression for the address of the file's shared object file header.",
+ &cmdlist);
+
++ /* Want to know of each new inferior so that its vsyscall info can
++ be extracted. */
++ observer_attach_inferior_created (add_vsyscall_page);
+ }
+Index: gdb-6.3/gdb/Makefile.in
+===================================================================
+--- gdb-6.3.orig/gdb/Makefile.in 2004-11-10 00:29:00.000000000 -0500
++++ gdb-6.3/gdb/Makefile.in 2004-11-10 00:54:47.728100986 -0500
+@@ -2020,7 +2020,7 @@ i386-linux-nat.o: i386-linux-nat.c $(def
+ i386-linux-tdep.o: i386-linux-tdep.c $(defs_h) $(gdbcore_h) $(frame_h) \
+ $(value_h) $(regcache_h) $(inferior_h) $(osabi_h) $(reggroups_h) \
+ $(gdb_string_h) $(i386_tdep_h) $(i386_linux_tdep_h) $(glibc_tdep_h) \
+- $(solib_svr4_h)
++ $(solib_svr4_h) $(dwarf2_frame_h)
+ i386ly-tdep.o: i386ly-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) \
+ $(regcache_h) $(target_h) $(osabi_h) $(i386_tdep_h)
+ i386-nat.o: i386-nat.c $(defs_h) $(breakpoint_h) $(command_h) $(gdbcmd_h)
+@@ -2606,7 +2606,8 @@ symfile.o: symfile.c $(defs_h) $(bfdlink
+ $(hashtab_h) $(readline_h) $(gdb_assert_h) $(block_h) \
+ $(gdb_string_h) $(gdb_stat_h)
+ symfile-mem.o: symfile-mem.c $(defs_h) $(symtab_h) $(gdbcore_h) \
+- $(objfiles_h) $(gdbcmd_h) $(target_h) $(value_h) $(symfile_h)
++ $(objfiles_h) $(gdbcmd_h) $(target_h) $(value_h) $(symfile_h) \
++ $(observer_h) $(auxv_h) $(elf_common_h)
+ symmisc.o: symmisc.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(bfd_h) \
+ $(symfile_h) $(objfiles_h) $(breakpoint_h) $(command_h) \
+ $(gdb_obstack_h) $(language_h) $(bcache_h) $(block_h) $(gdb_regex_h) \
diff --git a/misc/buildroot/toolchain/gdb/6.3/660-debian_dwarf-cfa-restore.patch b/misc/buildroot/toolchain/gdb/6.3/660-debian_dwarf-cfa-restore.patch
new file mode 100644
index 000000000..8b81cca71
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/660-debian_dwarf-cfa-restore.patch
@@ -0,0 +1,23 @@
+Status: Checked in to HEAD after 6.3.
+
+2004-11-09 Daniel Jacobowitz <dan@debian.org>
+
+ * dwarf2-frame.c (dwarf2_frame_state_alloc_regs): Correct allocated
+ size.
+
+Index: src/gdb/dwarf2-frame.c
+===================================================================
+RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v
+retrieving revision 1.45
+diff -u -p -r1.45 dwarf2-frame.c
+--- src/gdb/dwarf2-frame.c 7 Nov 2004 21:16:11 -0000 1.45
++++ src/gdb/dwarf2-frame.c 9 Nov 2004 14:42:52 -0000
+@@ -162,7 +162,7 @@ dwarf2_frame_state_alloc_regs (struct dw
+ static struct dwarf2_frame_state_reg *
+ dwarf2_frame_state_copy_regs (struct dwarf2_frame_state_reg_info *rs)
+ {
+- size_t size = rs->num_regs * sizeof (struct dwarf2_frame_state_reg_info);
++ size_t size = rs->num_regs * sizeof (struct dwarf2_frame_state_reg);
+ struct dwarf2_frame_state_reg *reg;
+
+ reg = (struct dwarf2_frame_state_reg *) xmalloc (size);
diff --git a/misc/buildroot/toolchain/gdb/6.3/680-debian_sim-destdir.patch b/misc/buildroot/toolchain/gdb/6.3/680-debian_sim-destdir.patch
new file mode 100644
index 000000000..71f60b5c6
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/680-debian_sim-destdir.patch
@@ -0,0 +1,53 @@
+Fix some missing uses of DESTDIR in the sim/ directories. The Debian
+packages use DESTDIR to build.
+
+%patch
+Index: gdb-6.3/sim/Makefile.in
+===================================================================
+--- gdb-6.3.orig/sim/Makefile.in 2003-09-03 14:46:52.000000000 -0400
++++ gdb-6.3/sim/Makefile.in 2004-11-10 00:39:25.381315738 -0500
+@@ -93,6 +93,7 @@ FLAGS_TO_PASS = \
+ "CC=$(CC)" \
+ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+ "CFLAGS=$(CFLAGS)" \
++ "DESTDIR=$(DESTDIR)" \
+ "RANLIB=$(RANLIB)" \
+ "MAKEINFO=$(MAKEINFO)" \
+ "INSTALL=$(INSTALL)" \
+Index: gdb-6.3/sim/common/Make-common.in
+===================================================================
+--- gdb-6.3.orig/sim/common/Make-common.in 2003-09-08 13:24:59.000000000 -0400
++++ gdb-6.3/sim/common/Make-common.in 2004-11-10 00:39:25.383315347 -0500
+@@ -581,14 +581,14 @@ install: install-common $(SIM_EXTRA_INST
+
+ install-common: installdirs
+ n=`echo run | sed '$(program_transform_name)'`; \
+- $(INSTALL_PROGRAM) run$(EXEEXT) $(bindir)/$$n$(EXEEXT)
++ $(INSTALL_PROGRAM) run$(EXEEXT) $(DESTDIR)$(bindir)/$$n$(EXEEXT)
+ n=`echo libsim.a | sed s/libsim.a/lib$(target_alias)-sim.a/`; \
+- $(INSTALL_DATA) libsim.a $(libdir)/$$n ; \
+- ( cd $(libdir) ; $(RANLIB) $$n )
++ $(INSTALL_DATA) libsim.a $(DESTDIR)$(libdir)/$$n ; \
++ ( cd $(DESTDIR)$(libdir) ; $(RANLIB) $$n )
+
+ installdirs:
+- $(SHELL) $(srcdir)/../../mkinstalldirs $(bindir)
+- $(SHELL) $(srcdir)/../../mkinstalldirs $(libdir)
++ $(SHELL) $(srcdir)/../../mkinstalldirs $(DESTDIR)$(bindir)
++ $(SHELL) $(srcdir)/../../mkinstalldirs $(DESTDIR)$(libdir)
+
+ check:
+ cd ../testsuite && $(MAKE) check RUNTESTFLAGS="$(RUNTESTFLAGS)"
+Index: gdb-6.3/sim/erc32/Makefile.in
+===================================================================
+--- gdb-6.3.orig/sim/erc32/Makefile.in 2000-03-07 10:32:49.000000000 -0500
++++ gdb-6.3/sim/erc32/Makefile.in 2004-11-10 00:39:25.385314957 -0500
+@@ -53,7 +53,7 @@ end.h: end
+ # Copy the files into directories where they will be run.
+ install-sis: installdirs
+ n=`echo sis | sed '$(program_transform_name)'`; \
+- $(INSTALL_PROGRAM) sis$(EXEEXT) $(bindir)/$$n$(EXEEXT)
++ $(INSTALL_PROGRAM) sis$(EXEEXT) $(DESTDIR)$(bindir)/$$n$(EXEEXT)
+
+ clean-sis:
+ rm -f sis end end.h
diff --git a/misc/buildroot/toolchain/gdb/6.3/690-debian_member-field-symtab.patch b/misc/buildroot/toolchain/gdb/6.3/690-debian_member-field-symtab.patch
new file mode 100644
index 000000000..4f5fb45c3
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/690-debian_member-field-symtab.patch
@@ -0,0 +1,35 @@
+Status: unsubmitted
+
+This patch was for Debian bug #239535. It needs to be tested, and
+submitted.
+
+Index: gdb-6.3/gdb/valops.c
+===================================================================
+--- gdb-6.3.orig/gdb/valops.c 2004-11-09 22:51:07.000000000 -0500
++++ gdb-6.3/gdb/valops.c 2004-11-10 00:43:54.036837699 -0500
+@@ -2314,8 +2314,10 @@ check_field_in (struct type *type, const
+ return 1;
+ }
+
++ /* Check each baseclass. Call check_typedef, which will follow typedefs
++ and do opaque/stub type resolution. */
+ for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
+- if (check_field_in (TYPE_BASECLASS (type, i), name))
++ if (check_field_in (check_typedef (TYPE_BASECLASS (type, i)), name))
+ return 1;
+
+ return 0;
+Index: gdb-6.3/gdb/dwarf2read.c
+===================================================================
+--- gdb-6.3.orig/gdb/dwarf2read.c 2004-10-15 20:41:00.000000000 -0400
++++ gdb-6.3/gdb/dwarf2read.c 2004-11-10 00:46:21.970935829 -0500
+@@ -2099,8 +2099,8 @@ guess_structure_name (struct partial_die
+ strlen (actual_class_name),
+ &cu->comp_unit_obstack);
+ xfree (actual_class_name);
++ break;
+ }
+- break;
+ }
+
+ child_pdi = child_pdi->die_sibling;
diff --git a/misc/buildroot/toolchain/gdb/6.3/700-debian_cp-pass-by-reference.patch b/misc/buildroot/toolchain/gdb/6.3/700-debian_cp-pass-by-reference.patch
new file mode 100644
index 000000000..666d34342
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/700-debian_cp-pass-by-reference.patch
@@ -0,0 +1,464 @@
+This patch needs to be submitted for the FSF. Also, there may be testcases
+already in the GDB testsuite (currently disabled) that it would probably fix.
+
+Index: gdb-6.3/gdb/infcall.c
+===================================================================
+--- gdb-6.3.orig/gdb/infcall.c 2004-10-08 04:15:56.000000000 -0400
++++ gdb-6.3/gdb/infcall.c 2004-11-10 12:30:07.000000000 -0500
+@@ -36,6 +36,7 @@
+ #include "gdb_string.h"
+ #include "infcall.h"
+ #include "dummy-frame.h"
++#include "cp-abi.h"
+
+ /* NOTE: cagney/2003-04-16: What's the future of this code?
+
+@@ -297,8 +298,8 @@ call_function_by_hand (struct value *fun
+ {
+ CORE_ADDR sp;
+ CORE_ADDR dummy_addr;
+- struct type *value_type;
+- unsigned char struct_return;
++ struct type *value_type, *target_value_type;
++ unsigned char struct_return = 0, cp_struct_return = 0;
+ CORE_ADDR struct_addr = 0;
+ struct regcache *retbuf;
+ struct cleanup *retbuf_cleanup;
+@@ -312,6 +313,7 @@ call_function_by_hand (struct value *fun
+ struct regcache *caller_regcache;
+ struct cleanup *caller_regcache_cleanup;
+ struct frame_id dummy_id;
++ struct cleanup *args_cleanup;
+
+ if (!target_has_execution)
+ noprocess ();
+@@ -410,10 +412,31 @@ call_function_by_hand (struct value *fun
+ using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b));
+ }
+
+- /* Are we returning a value using a structure return or a normal
+- value return? */
++ /* Are we returning a value using a structure return (passing a
++ hidden argument pointing to storage) or a normal value return?
++ There are two cases: C++ ABI mandated structure return and
++ target ABI structure return. The variable STRUCT_RETURN only
++ describes the latter. The C++ version is handled by passing
++ the return location as the first parameter to the function,
++ even preceding "this". This is different from the target
++ ABI version, which is target-specific; for instance, on ia64
++ the first argument is passed in out0 but the hidden structure
++ return pointer would normally be passed in r8. */
+
+- struct_return = using_struct_return (value_type, using_gcc);
++ if (current_language->la_language == language_cplus
++ && cp_pass_by_reference (value_type))
++ {
++ cp_struct_return = 1;
++
++ /* Tell the target specific argument pushing routine not to
++ expect a value. */
++ target_value_type = builtin_type_void;
++ }
++ else
++ {
++ struct_return = using_struct_return (value_type, using_gcc);
++ target_value_type = value_type;
++ }
+
+ /* Determine the location of the breakpoint (and possibly other
+ stuff) that the called function will return to. The SPARC, for a
+@@ -432,7 +455,7 @@ call_function_by_hand (struct value *fun
+ if (INNER_THAN (1, 2))
+ {
+ sp = push_dummy_code (current_gdbarch, sp, funaddr,
+- using_gcc, args, nargs, value_type,
++ using_gcc, args, nargs, target_value_type,
+ &real_pc, &bp_addr);
+ dummy_addr = sp;
+ }
+@@ -440,7 +463,7 @@ call_function_by_hand (struct value *fun
+ {
+ dummy_addr = sp;
+ sp = push_dummy_code (current_gdbarch, sp, funaddr,
+- using_gcc, args, nargs, value_type,
++ using_gcc, args, nargs, target_value_type,
+ &real_pc, &bp_addr);
+ }
+ break;
+@@ -507,9 +530,15 @@ call_function_by_hand (struct value *fun
+ param_type = TYPE_FIELD_TYPE (ftype, i);
+ else
+ param_type = NULL;
+-
++
+ args[i] = value_arg_coerce (args[i], param_type, prototyped);
+
++ /* FIXME: Is current_language the right language? */
++ if (current_language->la_language == language_cplus
++ && param_type != NULL
++ && cp_pass_by_reference (param_type))
++ args[i] = value_addr (args[i]);
++
+ /* elz: this code is to handle the case in which the function
+ to be called has a pointer to function as parameter and the
+ corresponding actual argument is the address of a function
+@@ -607,7 +636,7 @@ You must use a pointer to function type
+ stack, if necessary. Make certain that the value is correctly
+ aligned. */
+
+- if (struct_return)
++ if (struct_return || cp_struct_return)
+ {
+ int len = TYPE_LENGTH (value_type);
+ if (INNER_THAN (1, 2))
+@@ -632,6 +661,22 @@ You must use a pointer to function type
+ }
+ }
+
++ if (cp_struct_return)
++ {
++ struct value **new_args;
++
++ /* Add the new argument to the front of the argument list. */
++ new_args = xmalloc (sizeof (struct value *) * (nargs + 1));
++ new_args[0] = value_from_pointer (lookup_pointer_type (value_type),
++ struct_addr);
++ memcpy (&new_args[1], &args[0], sizeof (struct value *) * nargs);
++ args = new_args;
++ nargs++;
++ args_cleanup = make_cleanup (xfree, args);
++ }
++ else
++ args_cleanup = make_cleanup (null_cleanup, NULL);
++
+ /* Create the dummy stack frame. Pass in the call dummy address as,
+ presumably, the ABI code knows where, in the call dummy, the
+ return address should be pointed. */
+@@ -649,6 +694,8 @@ You must use a pointer to function type
+ else
+ error ("This target does not support function calls");
+
++ do_cleanups (args_cleanup);
++
+ /* Set up a frame ID for the dummy frame so we can pass it to
+ set_momentary_breakpoint. We need to give the breakpoint a frame
+ ID so that the breakpoint code can correctly re-identify the
+@@ -839,11 +886,7 @@ the function call).", name);
+ /* Figure out the value returned by the function, return that. */
+ {
+ struct value *retval;
+- if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
+- /* If the function returns void, don't bother fetching the
+- return value. */
+- retval = allocate_value (value_type);
+- else if (struct_return)
++ if (struct_return || cp_struct_return)
+ /* NOTE: cagney/2003-09-27: This assumes that PUSH_DUMMY_CALL
+ has correctly stored STRUCT_ADDR in the target. In the past
+ that hasn't been the case, the old MIPS PUSH_ARGUMENTS
+@@ -853,6 +896,10 @@ the function call).", name);
+ "struct return convention", check that PUSH_DUMMY_CALL isn't
+ playing tricks. */
+ retval = value_at (value_type, struct_addr, NULL);
++ else if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
++ /* If the function returns void, don't bother fetching the
++ return value. */
++ retval = allocate_value (value_type);
+ else
+ {
+ /* This code only handles "register convention". */
+Index: gdb-6.3/gdb/cp-abi.h
+===================================================================
+--- gdb-6.3.orig/gdb/cp-abi.h 2003-04-12 13:41:25.000000000 -0400
++++ gdb-6.3/gdb/cp-abi.h 2004-11-10 12:30:07.000000000 -0500
+@@ -1,7 +1,7 @@
+ /* Abstraction of various C++ ABI's we support, and the info we need
+ to get from them.
+ Contributed by Daniel Berlin <dberlin@redhat.com>
+- Copyright 2001 Free Software Foundation, Inc.
++ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+@@ -145,6 +145,10 @@ extern struct type *value_rtti_type (str
+ extern int baseclass_offset (struct type *type, int index, char *valaddr,
+ CORE_ADDR address);
+
++/* Return non-zero if an argument of type TYPE should be passed by reference
++ instead of value. */
++extern int cp_pass_by_reference (struct type *type);
++
+ struct cp_abi_ops
+ {
+ const char *shortname;
+@@ -162,6 +166,7 @@ struct cp_abi_ops
+ int *using_enc);
+ int (*baseclass_offset) (struct type *type, int index, char *valaddr,
+ CORE_ADDR address);
++ int (*pass_by_reference) (struct type *type);
+ };
+
+
+Index: gdb-6.3/gdb/cp-abi.c
+===================================================================
+--- gdb-6.3.orig/gdb/cp-abi.c 2003-11-26 17:04:00.000000000 -0500
++++ gdb-6.3/gdb/cp-abi.c 2004-11-10 12:30:07.000000000 -0500
+@@ -1,5 +1,5 @@
+ /* Generic code for supporting multiple C++ ABI's
+- Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
++ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+@@ -94,6 +94,14 @@ value_rtti_type (struct value *v, int *f
+ return (*current_cp_abi.rtti_type) (v, full, top, using_enc);
+ }
+
++int
++cp_pass_by_reference (struct type *type)
++{
++ if ((current_cp_abi.pass_by_reference) == NULL)
++ return 0;
++ return (*current_cp_abi.pass_by_reference) (type);
++}
++
+ /* Set the current C++ ABI to SHORT_NAME. */
+
+ static int
+Index: gdb-6.3/gdb/gnu-v3-abi.c
+===================================================================
+--- gdb-6.3.orig/gdb/gnu-v3-abi.c 2004-03-15 15:38:08.000000000 -0500
++++ gdb-6.3/gdb/gnu-v3-abi.c 2004-11-10 12:30:07.000000000 -0500
+@@ -1,7 +1,7 @@
+ /* Abstraction of GNU v3 abi.
+ Contributed by Jim Blandy <jimb@redhat.com>
+
+- Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
++ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+@@ -419,6 +419,84 @@ gnuv3_baseclass_offset (struct type *typ
+ return base_offset;
+ }
+
++/* Return nonzero if a type should be passed by reference.
++
++ The rule in the v3 ABI document comes from section 3.1.1. If the
++ type has a non-trivial copy constructor or destructor, then the
++ caller must make a copy (by calling the copy constructor if there
++ is one or perform the copy itself otherwise), pass the address of
++ the copy, and then destroy the temporary (if necessary).
++
++ For return values with non-trivial copy constructors or
++ destructors, space will be allocated in the caller, and a pointer
++ will be passed as the first argument (preceding "this").
++
++ We don't have a bulletproof mechanism for determining whether a
++ constructor or destructor is trivial. For GCC and DWARF2 debug
++ information, we can check the artificial flag.
++
++ We don't do anything with the constructors or destructors yet,
++ but we have to get the argument passing right anyway. */
++static int
++gnuv3_pass_by_reference (struct type *type)
++{
++ int fieldnum, fieldelem, basenum;
++
++ CHECK_TYPEDEF (type);
++
++ /* We're only interested in things that can have methods. */
++ if (TYPE_CODE (type) != TYPE_CODE_STRUCT
++ && TYPE_CODE (type) != TYPE_CODE_CLASS
++ && TYPE_CODE (type) != TYPE_CODE_UNION)
++ return 0;
++
++ for (fieldnum = 0; fieldnum < TYPE_NFN_FIELDS (type); fieldnum++)
++ for (fieldelem = 0; fieldelem < TYPE_FN_FIELDLIST_LENGTH (type, fieldnum);
++ fieldelem++)
++ {
++ struct fn_field *fn = TYPE_FN_FIELDLIST1 (type, fieldnum);
++ char *name = TYPE_FN_FIELDLIST_NAME (type, fieldnum);
++ struct type *fieldtype = TYPE_FN_FIELD_TYPE (fn, fieldelem);
++
++ /* If this function is marked as artificial, it is compiler-generated,
++ and we assume it is trivial. */
++ if (TYPE_FN_FIELD_ARTIFICIAL (fn, fieldelem))
++ continue;
++
++ /* If we've found a destructor, we must pass this by reference. */
++ if (name[0] == '~')
++ return 1;
++
++ /* If the mangled name of this method doesn't indicate that it
++ is a constructor, we're not interested.
++
++ FIXME drow/2004-05-27: We could do this using the name of
++ the method and the name of the class instead of dealing
++ with the mangled name. We don't have a convenient function
++ to strip off both leading scope qualifiers and trailing
++ template arguments yet. */
++ if (!is_constructor_name (TYPE_FN_FIELD_PHYSNAME (fn, fieldelem)))
++ continue;
++
++ /* If this method takes two arguments, and the second argument is
++ a reference to this class, then it is a copy constructor. */
++ if (TYPE_NFIELDS (fieldtype) == 2
++ && TYPE_CODE (TYPE_FIELD_TYPE (fieldtype, 1)) == TYPE_CODE_REF
++ && check_typedef (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (fieldtype, 1))) == type)
++ return 1;
++ }
++
++ /* Even if all the constructors and destructors were artificial, one
++ of them may have invoked a non-artificial constructor or
++ destructor in a base class. If any base class needs to be passed
++ by reference, so does this class. */
++ for (basenum = 0; basenum < TYPE_N_BASECLASSES (type); basenum++)
++ if (gnuv3_pass_by_reference (TYPE_BASECLASS (type, basenum)))
++ return 1;
++
++ return 0;
++}
++
+ static void
+ init_gnuv3_ops (void)
+ {
+@@ -434,6 +512,7 @@ init_gnuv3_ops (void)
+ gnu_v3_abi_ops.rtti_type = gnuv3_rtti_type;
+ gnu_v3_abi_ops.virtual_fn_field = gnuv3_virtual_fn_field;
+ gnu_v3_abi_ops.baseclass_offset = gnuv3_baseclass_offset;
++ gnu_v3_abi_ops.pass_by_reference = gnuv3_pass_by_reference;
+ }
+
+ extern initialize_file_ftype _initialize_gnu_v3_abi; /* -Wmissing-prototypes */
+Index: gdb-6.3/gdb/hpacc-abi.c
+===================================================================
+--- gdb-6.3.orig/gdb/hpacc-abi.c 2003-06-08 14:27:13.000000000 -0400
++++ gdb-6.3/gdb/hpacc-abi.c 2004-11-10 12:30:07.000000000 -0500
+@@ -3,7 +3,7 @@
+ Most of the real code is from HP, i've just fiddled it to fit in
+ the C++ ABI abstraction framework.
+
+- Copyright 2001 Free Software Foundation, Inc.
++ Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+Index: gdb-6.3/gdb/Makefile.in
+===================================================================
+--- gdb-6.3.orig/gdb/Makefile.in 2004-11-10 12:30:06.000000000 -0500
++++ gdb-6.3/gdb/Makefile.in 2004-11-10 12:30:07.000000000 -0500
+@@ -2073,7 +2073,7 @@ ia64-tdep.o: ia64-tdep.c $(defs_h) $(inf
+ infcall.o: infcall.c $(defs_h) $(breakpoint_h) $(target_h) $(regcache_h) \
+ $(inferior_h) $(gdb_assert_h) $(block_h) $(gdbcore_h) $(language_h) \
+ $(objfiles_h) $(gdbcmd_h) $(command_h) $(gdb_string_h) $(infcall_h) \
+- $(dummy_frame_h)
++ $(dummy_frame_h) $(cp_abi_h)
+ inf-child.o: inf-child.c $(defs_h) $(regcache_h) $(memattr_h) $(symtab_h) \
+ $(target_h) $(inferior_h) $(gdb_string_h)
+ infcmd.o: infcmd.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
+Index: gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.exp
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.exp 2004-11-11 09:48:00.498518899 -0500
+@@ -0,0 +1,38 @@
++# This testcase is part of GDB, the GNU debugger.
++
++# Copyright 2004 Free Software Foundation, Inc.
++
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++
++# Check that GDB can call C++ functions whose parameters have
++# object type, but are passed by reference.
++
++set testfile "pass-by-ref"
++set srcfile ${testfile}.cc
++set binfile ${objdir}/${subdir}/${testfile}
++if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
++ return -1
++}
++
++gdb_exit
++gdb_start
++gdb_reinitialize_dir $srcdir/$subdir
++gdb_load ${binfile}
++
++if ![runto_main] then {
++ return -1
++}
++
++gdb_test "print foo (global_obj)" " = 3" "call function"
+Index: gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.cc
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.cc 2004-11-11 09:44:17.815014667 -0500
+@@ -0,0 +1,57 @@
++/* This testcase is part of GDB, the GNU debugger.
++
++ Copyright 2004 Free Software Foundation, Inc.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++ USA. */
++
++class Obj {
++public:
++ Obj ();
++ Obj (const Obj &);
++ ~Obj ();
++ int var[2];
++};
++
++int foo (Obj arg)
++{
++ return arg.var[0] + arg.var[1];
++}
++
++Obj::Obj ()
++{
++ var[0] = 1;
++ var[1] = 2;
++}
++
++Obj::Obj (const Obj &obj)
++{
++ var[0] = obj.var[0];
++ var[1] = obj.var[1];
++}
++
++Obj::~Obj ()
++{
++
++}
++
++Obj global_obj;
++
++int
++main ()
++{
++ int bar = foo (global_obj);
++ return bar;
++}
diff --git a/misc/buildroot/toolchain/gdb/6.3/710-debian_thread-db-multiple-libraries.patch b/misc/buildroot/toolchain/gdb/6.3/710-debian_thread-db-multiple-libraries.patch
new file mode 100644
index 000000000..c164bd11a
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/710-debian_thread-db-multiple-libraries.patch
@@ -0,0 +1,593 @@
+Support loading two libthread_db DSOs. In this case, the LinuxThreads
+and NPTL ones.
+
+Index: gdb-6.3/gdb/thread-db.c
+===================================================================
+--- gdb-6.3.orig/gdb/thread-db.c 2004-11-10 10:46:24.000000000 -0500
++++ gdb-6.3/gdb/thread-db.c 2004-11-10 11:22:34.858812426 -0500
+@@ -79,53 +79,63 @@ static td_thragent_t *thread_agent;
+
+ /* Pointers to the libthread_db functions. */
+
+-static td_err_e (*td_init_p) (void);
++struct thread_db_pointers
++{
++ const char *filename;
++
++ td_err_e (*td_init_p) (void);
+
+-static td_err_e (*td_ta_new_p) (struct ps_prochandle * ps,
+- td_thragent_t **ta);
+-static td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
+- td_thrhandle_t *__th);
+-static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta,
+- lwpid_t lwpid, td_thrhandle_t *th);
+-static td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
+- td_thr_iter_f *callback, void *cbdata_p,
+- td_thr_state_e state, int ti_pri,
+- sigset_t *ti_sigmask_p,
+- unsigned int ti_user_flags);
+-static td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
+- td_event_e event, td_notify_t *ptr);
+-static td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
+- td_thr_events_t *event);
+-static td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
+- td_event_msg_t *msg);
+-
+-static td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
+-static td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
+- td_thrinfo_t *infop);
+-static td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
+- gdb_prfpregset_t *regset);
+-static td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
+- prgregset_t gregs);
+-static td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
+- const gdb_prfpregset_t *fpregs);
+-static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
+- prgregset_t gregs);
+-static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th,
+- int event);
+-
+-static td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
+- void *map_address,
+- size_t offset, void **address);
++ td_err_e (*td_ta_new_p) (struct ps_prochandle * ps,
++ td_thragent_t **ta);
++ td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
++ td_thrhandle_t *__th);
++ td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta,
++ lwpid_t lwpid, td_thrhandle_t *th);
++
++ td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
++ td_thr_iter_f *callback, void *cbdata_p,
++ td_thr_state_e state, int ti_pri,
++ sigset_t *ti_sigmask_p,
++ unsigned int ti_user_flags);
++ td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
++ td_event_e event, td_notify_t *ptr);
++ td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
++ td_thr_events_t *event);
++ td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
++ td_event_msg_t *msg);
++
++ td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
++ td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
++ td_thrinfo_t *infop);
++ td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
++ gdb_prfpregset_t *regset);
++ td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
++ prgregset_t gregs);
++ td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
++ const gdb_prfpregset_t *fpregs);
++ td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
++ prgregset_t gregs);
++ td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th,
++ int event);
++
++ td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
++ void *map_address,
++ size_t offset, void **address);
++
++ struct thread_db_pointers *next;
++};
+
+ /* Location of the thread creation event breakpoint. The code at this
+ location in the child process will be called by the pthread library
+ whenever a new thread is created. By setting a special breakpoint
+ at this location, GDB can detect when a new thread is created. We
+ obtain this location via the td_ta_event_addr call. */
+-static CORE_ADDR td_create_bp_addr;
++CORE_ADDR td_create_bp_addr;
+
+ /* Location of the thread death event breakpoint. */
+-static CORE_ADDR td_death_bp_addr;
++CORE_ADDR td_death_bp_addr;
++
++static struct thread_db_pointers *current_pointers, *all_pointers;
+
+ /* Prototypes for local functions. */
+ static void thread_db_find_new_threads (void);
+@@ -262,7 +272,7 @@ thread_get_info_callback (const td_thrha
+ struct thread_info *thread_info;
+ ptid_t thread_ptid;
+
+- err = td_thr_get_info_p (thp, &ti);
++ err = current_pointers->td_thr_get_info_p (thp, &ti);
+ if (err != TD_OK)
+ error ("thread_get_info_callback: cannot get thread info: %s",
+ thread_db_err_str (err));
+@@ -316,8 +326,9 @@ thread_db_map_id2thr (struct thread_info
+ if (thread_info->private->th_valid)
+ return;
+
+- err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (thread_info->ptid),
+- &thread_info->private->th);
++ err = current_pointers->td_ta_map_id2thr_p (thread_agent,
++ GET_THREAD (thread_info->ptid),
++ &thread_info->private->th);
+ if (err != TD_OK)
+ {
+ if (fatal)
+@@ -340,8 +351,8 @@ thread_db_get_info (struct thread_info *
+ if (!thread_info->private->th_valid)
+ thread_db_map_id2thr (thread_info, 1);
+
+- err =
+- td_thr_get_info_p (&thread_info->private->th, &thread_info->private->ti);
++ err = current_pointers->td_thr_get_info_p (&thread_info->private->th,
++ &thread_info->private->ti);
+ if (err != TD_OK)
+ error ("thread_db_get_info: cannot get thread info: %s",
+ thread_db_err_str (err));
+@@ -365,7 +376,8 @@ thread_from_lwp (ptid_t ptid)
+
+ gdb_assert (is_lwp (ptid));
+
+- err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
++ err = current_pointers->td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid),
++ &th);
+ if (err != TD_OK)
+ error ("Cannot find user-level thread for LWP %ld: %s",
+ GET_LWP (ptid), thread_db_err_str (err));
+@@ -420,85 +432,102 @@ verbose_dlsym (void *handle, const char
+ return sym;
+ }
+
+-static int
+-thread_db_load (void)
++static struct thread_db_pointers *
++thread_db_load (const char *name)
+ {
++ struct thread_db_pointers *ptrs;
++ Dl_info info;
+ void *handle;
+ td_err_e err;
+
+- handle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW);
++ ptrs = xcalloc (1, sizeof (struct thread_db_pointers));
++
++ handle = dlopen (name, RTLD_NOW);
+ if (handle == NULL)
+ {
+- fprintf_filtered (gdb_stderr, "\n\ndlopen failed on '%s' - %s\n",
+- LIBTHREAD_DB_SO, dlerror ());
+- fprintf_filtered (gdb_stderr,
+- "GDB will not be able to debug pthreads.\n\n");
++ if (all_pointers == NULL)
++ {
++ fprintf_filtered (gdb_stderr, "\n\ndlopen failed on '%s' - %s\n",
++ name, dlerror ());
++ fprintf_filtered (gdb_stderr,
++ "GDB will not be able to debug pthreads.\n\n");
++ }
+ return 0;
+ }
+
+ /* Initialize pointers to the dynamic library functions we will use.
+ Essential functions first. */
+
+- td_init_p = verbose_dlsym (handle, "td_init");
+- if (td_init_p == NULL)
++ ptrs->td_init_p = verbose_dlsym (handle, "td_init");
++ if (ptrs->td_init_p == NULL)
+ return 0;
+
+- td_ta_new_p = verbose_dlsym (handle, "td_ta_new");
+- if (td_ta_new_p == NULL)
++ ptrs->td_ta_new_p = verbose_dlsym (handle, "td_ta_new");
++ if (ptrs->td_ta_new_p == NULL)
+ return 0;
+
+- td_ta_map_id2thr_p = verbose_dlsym (handle, "td_ta_map_id2thr");
+- if (td_ta_map_id2thr_p == NULL)
++ ptrs->td_ta_map_id2thr_p = verbose_dlsym (handle, "td_ta_map_id2thr");
++ if (ptrs->td_ta_map_id2thr_p == NULL)
+ return 0;
+
+- td_ta_map_lwp2thr_p = verbose_dlsym (handle, "td_ta_map_lwp2thr");
+- if (td_ta_map_lwp2thr_p == NULL)
++ ptrs->td_ta_map_lwp2thr_p = verbose_dlsym (handle, "td_ta_map_lwp2thr");
++ if (ptrs->td_ta_map_lwp2thr_p == NULL)
+ return 0;
+
+- td_ta_thr_iter_p = verbose_dlsym (handle, "td_ta_thr_iter");
+- if (td_ta_thr_iter_p == NULL)
++ ptrs->td_ta_thr_iter_p = verbose_dlsym (handle, "td_ta_thr_iter");
++ if (ptrs->td_ta_thr_iter_p == NULL)
+ return 0;
+
+- td_thr_validate_p = verbose_dlsym (handle, "td_thr_validate");
+- if (td_thr_validate_p == NULL)
++ ptrs->td_thr_validate_p = verbose_dlsym (handle, "td_thr_validate");
++ if (ptrs->td_thr_validate_p == NULL)
+ return 0;
+
+- td_thr_get_info_p = verbose_dlsym (handle, "td_thr_get_info");
+- if (td_thr_get_info_p == NULL)
++ ptrs->td_thr_get_info_p = verbose_dlsym (handle, "td_thr_get_info");
++ if (ptrs->td_thr_get_info_p == NULL)
+ return 0;
+
+- td_thr_getfpregs_p = verbose_dlsym (handle, "td_thr_getfpregs");
+- if (td_thr_getfpregs_p == NULL)
++ ptrs->td_thr_getfpregs_p = verbose_dlsym (handle, "td_thr_getfpregs");
++ if (ptrs->td_thr_getfpregs_p == NULL)
+ return 0;
+
+- td_thr_getgregs_p = verbose_dlsym (handle, "td_thr_getgregs");
+- if (td_thr_getgregs_p == NULL)
++ ptrs->td_thr_getgregs_p = verbose_dlsym (handle, "td_thr_getgregs");
++ if (ptrs->td_thr_getgregs_p == NULL)
+ return 0;
+
+- td_thr_setfpregs_p = verbose_dlsym (handle, "td_thr_setfpregs");
+- if (td_thr_setfpregs_p == NULL)
++ ptrs->td_thr_setfpregs_p = verbose_dlsym (handle, "td_thr_setfpregs");
++ if (ptrs->td_thr_setfpregs_p == NULL)
+ return 0;
+
+- td_thr_setgregs_p = verbose_dlsym (handle, "td_thr_setgregs");
+- if (td_thr_setgregs_p == NULL)
++ ptrs->td_thr_setgregs_p = verbose_dlsym (handle, "td_thr_setgregs");
++ if (ptrs->td_thr_setgregs_p == NULL)
+ return 0;
+
+ /* Initialize the library. */
+- err = td_init_p ();
++ err = ptrs->td_init_p ();
+ if (err != TD_OK)
+ {
+ warning ("Cannot initialize libthread_db: %s", thread_db_err_str (err));
++ xfree (ptrs);
+ return 0;
+ }
+
+ /* These are not essential. */
+- td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
+- td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
+- td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
+- td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
+- td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr");
++ ptrs->td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
++ ptrs->td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
++ ptrs->td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
++ ptrs->td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
++ ptrs->td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr");
++
++ if (dladdr (ptrs->td_ta_new_p, &info) != 0)
++ ptrs->filename = info.dli_fname;
++
++ /* Try dlinfo? */
++
++ if (ptrs->filename == NULL)
++ /* Paranoid - don't let a NULL path slip through. */
++ ptrs->filename = name;
+
+- return 1;
++ return ptrs;
+ }
+
+ static td_err_e
+@@ -508,7 +537,7 @@ enable_thread_event (td_thragent_t *thre
+ td_err_e err;
+
+ /* Get the breakpoint address for thread EVENT. */
+- err = td_ta_event_addr_p (thread_agent, event, &notify);
++ err = current_pointers->td_ta_event_addr_p (thread_agent, event, &notify);
+ if (err != TD_OK)
+ return err;
+
+@@ -534,8 +563,10 @@ enable_thread_event_reporting (void)
+
+ /* We cannot use the thread event reporting facility if these
+ functions aren't available. */
+- if (td_ta_event_addr_p == NULL || td_ta_set_event_p == NULL
+- || td_ta_event_getmsg_p == NULL || td_thr_event_enable_p == NULL)
++ if (current_pointers->td_ta_event_addr_p == NULL
++ || current_pointers->td_ta_set_event_p == NULL
++ || current_pointers->td_ta_event_getmsg_p == NULL
++ || current_pointers->td_thr_event_enable_p == NULL)
+ return;
+
+ /* Set the process wide mask saying which events we're interested in. */
+@@ -552,7 +583,7 @@ enable_thread_event_reporting (void)
+ #endif
+ td_event_addset (&events, TD_DEATH);
+
+- err = td_ta_set_event_p (thread_agent, &events);
++ err = current_pointers->td_ta_set_event_p (thread_agent, &events);
+ if (err != TD_OK)
+ {
+ warning ("Unable to set global thread event mask: %s",
+@@ -592,7 +623,7 @@ disable_thread_event_reporting (void)
+ /* Set the process wide mask saying we aren't interested in any
+ events anymore. */
+ td_event_emptyset (&events);
+- td_ta_set_event_p (thread_agent, &events);
++ current_pointers->td_ta_set_event_p (thread_agent, &events);
+
+ /* Delete thread event breakpoints, if any. */
+ remove_thread_event_breakpoints ();
+@@ -635,7 +666,6 @@ check_thread_signals (void)
+ static void
+ check_for_thread_db (void)
+ {
+- td_err_e err;
+ static int already_loaded;
+
+ /* First time through, report that libthread_db was successfuly
+@@ -644,19 +674,8 @@ check_for_thread_db (void)
+
+ if (!already_loaded)
+ {
+- Dl_info info;
+- const char *library = NULL;
+- if (dladdr ((*td_ta_new_p), &info) != 0)
+- library = info.dli_fname;
+-
+- /* Try dlinfo? */
+-
+- if (library == NULL)
+- /* Paranoid - don't let a NULL path slip through. */
+- library = LIBTHREAD_DB_SO;
+-
+ printf_unfiltered ("Using host libthread_db library \"%s\".\n",
+- library);
++ all_pointers->filename);
+ already_loaded = 1;
+ }
+
+@@ -674,28 +693,34 @@ check_for_thread_db (void)
+ proc_handle.pid = GET_PID (inferior_ptid);
+
+ /* Now attempt to open a connection to the thread library. */
+- err = td_ta_new_p (&proc_handle, &thread_agent);
+- switch (err)
++ for (current_pointers = all_pointers;
++ current_pointers != NULL;
++ current_pointers = current_pointers->next)
+ {
+- case TD_NOLIBTHREAD:
+- /* No thread library was detected. */
+- break;
+-
+- case TD_OK:
+- printf_unfiltered ("[Thread debugging using libthread_db enabled]\n");
++ td_err_e err;
++ err = current_pointers->td_ta_new_p (&proc_handle, &thread_agent);
++ switch (err)
++ {
++ case TD_NOLIBTHREAD:
++ /* No thread library was detected. */
++ break;
+
+- /* The thread library was detected. Activate the thread_db target. */
+- push_target (&thread_db_ops);
+- using_thread_db = 1;
++ case TD_OK:
++ printf_unfiltered ("[Thread debugging using libthread_db enabled]\n");
+
+- enable_thread_event_reporting ();
+- thread_db_find_new_threads ();
+- break;
++ /* The thread library was detected. Activate the thread_db target. */
++ push_target (&thread_db_ops);
++ using_thread_db = 1;
++
++ enable_thread_event_reporting ();
++ thread_db_find_new_threads ();
++ return;
+
+- default:
+- warning ("Cannot initialize thread debugging library: %s",
+- thread_db_err_str (err));
+- break;
++ default:
++ warning ("Cannot initialize thread debugging library: %s",
++ thread_db_err_str (err));
++ break;
++ }
+ }
+ }
+
+@@ -766,7 +791,7 @@ attach_thread (ptid_t ptid, const td_thr
+ #endif
+
+ /* Enable thread event reporting for this thread. */
+- err = td_thr_event_enable_p (th_p, 1);
++ err = current_pointers->td_thr_event_enable_p (th_p, 1);
+ if (err != TD_OK)
+ error ("Cannot enable thread event reporting for %s: %s",
+ target_pid_to_str (ptid), thread_db_err_str (err));
+@@ -892,7 +917,7 @@ check_event (ptid_t ptid)
+
+ do
+ {
+- err = td_ta_event_getmsg_p (thread_agent, &msg);
++ err = current_pointers->td_ta_event_getmsg_p (thread_agent, &msg);
+ if (err != TD_OK)
+ {
+ if (err == TD_NOMSG)
+@@ -902,7 +927,7 @@ check_event (ptid_t ptid)
+ thread_db_err_str (err));
+ }
+
+- err = td_thr_get_info_p (msg.th_p, &ti);
++ err = current_pointers->td_thr_get_info_p (msg.th_p, &ti);
+ if (err != TD_OK)
+ error ("Cannot get thread info: %s", thread_db_err_str (err));
+
+@@ -1015,12 +1040,14 @@ thread_db_fetch_registers (int regno)
+ thread_info = find_thread_pid (inferior_ptid);
+ thread_db_map_id2thr (thread_info, 1);
+
+- err = td_thr_getgregs_p (&thread_info->private->th, gregset);
++ err = current_pointers->td_thr_getgregs_p (&thread_info->private->th,
++ gregset);
+ if (err != TD_OK)
+ error ("Cannot fetch general-purpose registers for thread %ld: %s",
+ (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
+
+- err = td_thr_getfpregs_p (&thread_info->private->th, &fpregset);
++ err = current_pointers->td_thr_getfpregs_p (&thread_info->private->th,
++ &fpregset);
+ if (err != TD_OK)
+ error ("Cannot get floating-point registers for thread %ld: %s",
+ (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
+@@ -1062,11 +1089,13 @@ thread_db_store_registers (int regno)
+ fill_gregset ((gdb_gregset_t *) gregset, -1);
+ fill_fpregset (&fpregset, -1);
+
+- err = td_thr_setgregs_p (&thread_info->private->th, gregset);
++ err = current_pointers->td_thr_setgregs_p (&thread_info->private->th,
++ gregset);
+ if (err != TD_OK)
+ error ("Cannot store general-purpose registers for thread %ld: %s",
+ (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
+- err = td_thr_setfpregs_p (&thread_info->private->th, &fpregset);
++ err = current_pointers->td_thr_setfpregs_p (&thread_info->private->th,
++ &fpregset);
+ if (err != TD_OK)
+ error ("Cannot store floating-point registers for thread %ld: %s",
+ (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
+@@ -1136,15 +1165,14 @@ thread_db_thread_alive (ptid_t ptid)
+ if (!thread_info->private->th_valid)
+ return 0;
+
+- err = td_thr_validate_p (&thread_info->private->th);
++ err = current_pointers->td_thr_validate_p (&thread_info->private->th);
+ if (err != TD_OK)
+ return 0;
+
+ if (!thread_info->private->ti_valid)
+ {
+- err =
+- td_thr_get_info_p (&thread_info->private->th,
+- &thread_info->private->ti);
++ err = current_pointers->td_thr_get_info_p
++ (&thread_info->private->th, &thread_info->private->ti);
+ if (err != TD_OK)
+ return 0;
+ thread_info->private->ti_valid = 1;
+@@ -1170,7 +1198,7 @@ find_new_threads_callback (const td_thrh
+ td_err_e err;
+ ptid_t ptid;
+
+- err = td_thr_get_info_p (th_p, &ti);
++ err = current_pointers->td_thr_get_info_p (th_p, &ti);
+ if (err != TD_OK)
+ error ("find_new_threads_callback: cannot get thread info: %s",
+ thread_db_err_str (err));
+@@ -1192,9 +1220,10 @@ thread_db_find_new_threads (void)
+ td_err_e err;
+
+ /* Iterate over all user-space threads to discover new threads. */
+- err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL,
+- TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
+- TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
++ err = current_pointers->td_ta_thr_iter_p
++ (thread_agent, find_new_threads_callback, NULL,
++ TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
++ TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
+ if (err != TD_OK)
+ error ("Cannot find new threads: %s", thread_db_err_str (err));
+ }
+@@ -1257,7 +1286,7 @@ thread_db_get_thread_local_address (ptid
+ struct thread_info *thread_info;
+
+ /* glibc doesn't provide the needed interface. */
+- if (!td_thr_tls_get_addr_p)
++ if (!current_pointers->td_thr_tls_get_addr_p)
+ error ("Cannot find thread-local variables in this thread library.");
+
+ /* Get the address of the link map for this objfile. */
+@@ -1279,8 +1308,8 @@ thread_db_get_thread_local_address (ptid
+ thread_db_map_id2thr (thread_info, 1);
+
+ /* Finally, get the address of the variable. */
+- err = td_thr_tls_get_addr_p (&thread_info->private->th, (void *) lm,
+- offset, &address);
++ err = current_pointers->td_thr_tls_get_addr_p
++ (&thread_info->private->th, (void *) lm, offset, &address);
+
+ #ifdef THREAD_DB_HAS_TD_NOTALLOC
+ /* The memory hasn't been allocated, yet. */
+@@ -1360,17 +1389,49 @@ init_thread_db_ops (void)
+ void
+ _initialize_thread_db (void)
+ {
++ struct thread_db_pointers *ptrs;
++ const char *p;
++
+ /* Only initialize the module if we can load libthread_db. */
+- if (thread_db_load ())
+- {
+- init_thread_db_ops ();
+- add_target (&thread_db_ops);
++ ptrs = thread_db_load (LIBTHREAD_DB_SO);
++ if (ptrs == NULL)
++ return;
++
++ all_pointers = ptrs;
+
+- /* Add ourselves to objfile event chain. */
+- target_new_objfile_chain = deprecated_target_new_objfile_hook;
+- deprecated_target_new_objfile_hook = thread_db_new_objfile;
++ /* Some GNU/Linux systems have more than one binary-compatible copy
++ of libthread_db. If we can find a second one, load that too.
++ The inferior may force the use of a different threading package
++ than we expect. Our guess for the location is somewhat hokey:
++ strip out anything between /lib (or /lib64) and LIBTHREAD_DB_SO.
++ If we loaded the NPTL libthread_db by default, this may find us
++ the LinuxThreads copy. */
++ p = strrchr (ptrs->filename, '/');
++ while (p != NULL && p > ptrs->filename)
++ {
++ const char *component;
+
+- /* Register ourselves for the new inferior observer. */
+- observer_attach_inferior_created (check_for_thread_db_observer);
++ component = memrchr (ptrs->filename, '/', p - ptrs->filename);
++ if (component != NULL && strncmp (component, "/lib", 4) == 0)
++ {
++ char *new_name = xmalloc (p - ptrs->filename + 2
++ + strlen (LIBTHREAD_DB_SO));
++ memcpy (new_name, ptrs->filename, p - ptrs->filename + 1);
++ strcpy (new_name + (p - ptrs->filename) + 1, LIBTHREAD_DB_SO);
++ ptrs->next = thread_db_load (new_name);
++ xfree (new_name);
++ break;
++ }
++ p = component;
+ }
++
++ init_thread_db_ops ();
++ add_target (&thread_db_ops);
++
++ /* Add ourselves to objfile event chain. */
++ target_new_objfile_chain = deprecated_target_new_objfile_hook;
++ deprecated_target_new_objfile_hook = thread_db_new_objfile;
++
++ /* Register ourselves for the new inferior observer. */
++ observer_attach_inferior_created (check_for_thread_db_observer);
+ }
diff --git a/misc/buildroot/toolchain/gdb/6.3/720-debian_static-threads-test.patch b/misc/buildroot/toolchain/gdb/6.3/720-debian_static-threads-test.patch
new file mode 100644
index 000000000..448c9b1d7
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/720-debian_static-threads-test.patch
@@ -0,0 +1,36 @@
+Update staticthreads.exp to handle debugging info in libpthread.a.
+
+Index: gdb-6.3/gdb/testsuite/gdb.threads/staticthreads.exp
+===================================================================
+--- gdb-6.3.orig/gdb/testsuite/gdb.threads/staticthreads.exp 2004-11-10 10:35:15.000000000 -0500
++++ gdb-6.3/gdb/testsuite/gdb.threads/staticthreads.exp 2004-11-10 11:22:48.671121466 -0500
+@@ -53,6 +53,10 @@ gdb_test_multiple "continue" "$test" {
+ -re " sem_post .*$gdb_prompt " {
+ pass "$test"
+ }
++ -re " (.*_)sem_post .*$gdb_prompt " {
++ # Glibc uses aliases for internal symbols; match __new_sem_post.
++ pass "$test"
++ }
+ -re "Program received signal .*$gdb_prompt " {
+ kfail gdb/1328 "$test"
+ }
+@@ -64,8 +68,16 @@ gdb_test_multiple "continue" "$test" {
+
+ rerun_to_main
+ gdb_test "handle SIG32 nostop noprint pass"
+-set test "Handle SIG32 helps"
+-gdb_test "continue" " sem_post .*" "handle SIG32 helps"
++set test "handle SIG32 helps"
++gdb_test_multiple "continue" "$test" {
++ -re " sem_post .*$gdb_prompt $" {
++ pass "$test"
++ }
++ -re " (.*_)sem_post .*$gdb_prompt $" {
++ # Glibc uses aliases for internal symbols; match __new_sem_post.
++ pass "$test"
++ }
++}
+
+
+ # See if info threads produces anything approaching a thread list.
diff --git a/misc/buildroot/toolchain/gdb/6.3/730-debian_gdb-fix-tracefork-check.patch b/misc/buildroot/toolchain/gdb/6.3/730-debian_gdb-fix-tracefork-check.patch
new file mode 100644
index 000000000..9890d80c3
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/730-debian_gdb-fix-tracefork-check.patch
@@ -0,0 +1,225 @@
+Status: submitted for comments
+
+2004-11-12 Daniel Jacobowitz <dan@debian.org>
+
+ * linux-nat.c (my_waitpid): New function.
+ (linux_test_for_tracefork): Make more robust and verbose. Take
+ an ORIGINAL_PID argument and test for PTRACE_SETOPTIONS first.
+ (linux_supports_tracefork, linux_supports_tracevforkdone): Take a PID
+ argument. Update calls to linux_test_for_tracefork.
+ (linux_enable_event_reporting, child_follow_fork)
+ (child_insert_fork_catchpoint, child_insert_vfork_catchpoint)
+ (child_insert_exec_catchpoint): Update calls to
+ linux_supports_tracefork and linux_supports_tracevforkdone.
+
+Index: gdb-6.3/gdb/linux-nat.c
+===================================================================
+--- gdb-6.3.orig/gdb/linux-nat.c 2004-10-08 16:29:47.000000000 -0400
++++ gdb-6.3/gdb/linux-nat.c 2004-11-13 16:41:51.368720845 -0500
+@@ -150,18 +150,47 @@ linux_tracefork_child (void)
+ exit (0);
+ }
+
+-/* Determine if PTRACE_O_TRACEFORK can be used to follow fork events. We
++/* Wrapper function for waitpid which handles EINTR. */
++
++static int
++my_waitpid (int pid, int *status, int flags)
++{
++ int ret;
++ do
++ {
++ ret = waitpid (pid, status, flags);
++ }
++ while (ret == -1 && errno == EINTR);
++
++ return ret;
++}
++
++/* Determine if PTRACE_O_TRACEFORK can be used to follow fork events.
++
++ First, we try to enable fork tracing on ORIGINAL_PID. If this fails,
++ we know that the feature is not available. This may change the tracing
++ options for ORIGINAL_PID, but we'll be setting them shortly anyway.
++
++ However, if it succeeds, we don't know for sure that the feature is
++ available; old versions of PTRACE_SETOPTIONS ignored unknown options. We
+ create a child process, attach to it, use PTRACE_SETOPTIONS to enable
+- fork tracing, and let it fork. If the process exits, we assume that
+- we can't use TRACEFORK; if we get the fork notification, and we can
+- extract the new child's PID, then we assume that we can. */
++ fork tracing, and let it fork. If the process exits, we assume that we
++ can't use TRACEFORK; if we get the fork notification, and we can extract
++ the new child's PID, then we assume that we can. */
+
+ static void
+-linux_test_for_tracefork (void)
++linux_test_for_tracefork (int original_pid)
+ {
+ int child_pid, ret, status;
+ long second_pid;
+
++ linux_supports_tracefork_flag = 0;
++ linux_supports_tracevforkdone_flag = 0;
++
++ ret = ptrace (PTRACE_SETOPTIONS, original_pid, 0, PTRACE_O_TRACEFORK);
++ if (ret != 0)
++ return;
++
+ child_pid = fork ();
+ if (child_pid == -1)
+ perror_with_name ("linux_test_for_tracefork: fork");
+@@ -169,7 +198,7 @@ linux_test_for_tracefork (void)
+ if (child_pid == 0)
+ linux_tracefork_child ();
+
+- ret = waitpid (child_pid, &status, 0);
++ ret = my_waitpid (child_pid, &status, 0);
+ if (ret == -1)
+ perror_with_name ("linux_test_for_tracefork: waitpid");
+ else if (ret != child_pid)
+@@ -177,13 +206,23 @@ linux_test_for_tracefork (void)
+ if (! WIFSTOPPED (status))
+ error ("linux_test_for_tracefork: waitpid: unexpected status %d.", status);
+
+- linux_supports_tracefork_flag = 0;
+-
+ ret = ptrace (PTRACE_SETOPTIONS, child_pid, 0, PTRACE_O_TRACEFORK);
+ if (ret != 0)
+ {
+- ptrace (PTRACE_KILL, child_pid, 0, 0);
+- waitpid (child_pid, &status, 0);
++ ret = ptrace (PTRACE_KILL, child_pid, 0, 0);
++ if (ret != 0)
++ {
++ warning ("linux_test_for_tracefork: failed to kill child");
++ return;
++ }
++
++ ret = my_waitpid (child_pid, &status, 0);
++ if (ret != child_pid)
++ warning ("linux_test_for_tracefork: failed to wait for killed child");
++ else if (!WIFSIGNALED (status))
++ warning ("linux_test_for_tracefork: unexpected wait status 0x%x from "
++ "killed child", status);
++
+ return;
+ }
+
+@@ -192,8 +231,12 @@ linux_test_for_tracefork (void)
+ PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORKDONE);
+ linux_supports_tracevforkdone_flag = (ret == 0);
+
+- ptrace (PTRACE_CONT, child_pid, 0, 0);
+- ret = waitpid (child_pid, &status, 0);
++ ret = ptrace (PTRACE_CONT, child_pid, 0, 0);
++ if (ret != 0)
++ warning ("linux_test_for_tracefork: failed to resume child");
++
++ ret = my_waitpid (child_pid, &status, 0);
++
+ if (ret == child_pid && WIFSTOPPED (status)
+ && status >> 16 == PTRACE_EVENT_FORK)
+ {
+@@ -204,34 +247,38 @@ linux_test_for_tracefork (void)
+ int second_status;
+
+ linux_supports_tracefork_flag = 1;
+- waitpid (second_pid, &second_status, 0);
+- ptrace (PTRACE_DETACH, second_pid, 0, 0);
++ my_waitpid (second_pid, &second_status, 0);
++ ret = ptrace (PTRACE_KILL, second_pid, 0, 0);
++ if (ret != 0)
++ warning ("linux_test_for_tracefork: failed to kill second child");
+ }
+ }
++ else
++ warning ("linux_test_for_tracefork: unexpected result from waitpid "
++ "(%d, status 0x%x)", ret, status);
+
+- if (WIFSTOPPED (status))
+- {
+- ptrace (PTRACE_DETACH, child_pid, 0, 0);
+- waitpid (child_pid, &status, 0);
+- }
++ ret = ptrace (PTRACE_KILL, child_pid, 0, 0);
++ if (ret != 0)
++ warning ("linux_test_for_tracefork: failed to kill child");
++ my_waitpid (child_pid, &status, 0);
+ }
+
+ /* Return non-zero iff we have tracefork functionality available.
+ This function also sets linux_supports_tracefork_flag. */
+
+ static int
+-linux_supports_tracefork (void)
++linux_supports_tracefork (int pid)
+ {
+ if (linux_supports_tracefork_flag == -1)
+- linux_test_for_tracefork ();
++ linux_test_for_tracefork (pid);
+ return linux_supports_tracefork_flag;
+ }
+
+ static int
+-linux_supports_tracevforkdone (void)
++linux_supports_tracevforkdone (int pid)
+ {
+ if (linux_supports_tracefork_flag == -1)
+- linux_test_for_tracefork ();
++ linux_test_for_tracefork (pid);
+ return linux_supports_tracevforkdone_flag;
+ }
+
+@@ -242,12 +289,12 @@ linux_enable_event_reporting (ptid_t pti
+ int pid = ptid_get_pid (ptid);
+ int options;
+
+- if (! linux_supports_tracefork ())
++ if (! linux_supports_tracefork (pid))
+ return;
+
+ options = PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACEEXEC
+ | PTRACE_O_TRACECLONE;
+- if (linux_supports_tracevforkdone ())
++ if (linux_supports_tracevforkdone (pid))
+ options |= PTRACE_O_TRACEVFORKDONE;
+
+ /* Do not enable PTRACE_O_TRACEEXIT until GDB is more prepared to support
+@@ -308,7 +355,8 @@ child_follow_fork (int follow_child)
+
+ if (has_vforked)
+ {
+- if (linux_supports_tracevforkdone ())
++ gdb_assert (linux_supports_tracefork_flag >= 0);
++ if (linux_supports_tracevforkdone (0))
+ {
+ int status;
+
+@@ -476,7 +524,7 @@ linux_handle_extended_wait (int pid, int
+ int
+ child_insert_fork_catchpoint (int pid)
+ {
+- if (! linux_supports_tracefork ())
++ if (! linux_supports_tracefork (pid))
+ error ("Your system does not support fork catchpoints.");
+
+ return 0;
+@@ -485,7 +533,7 @@ child_insert_fork_catchpoint (int pid)
+ int
+ child_insert_vfork_catchpoint (int pid)
+ {
+- if (!linux_supports_tracefork ())
++ if (!linux_supports_tracefork (pid))
+ error ("Your system does not support vfork catchpoints.");
+
+ return 0;
+@@ -494,7 +542,7 @@ child_insert_vfork_catchpoint (int pid)
+ int
+ child_insert_exec_catchpoint (int pid)
+ {
+- if (!linux_supports_tracefork ())
++ if (!linux_supports_tracefork (pid))
+ error ("Your system does not support exec catchpoints.");
+
+ return 0;
diff --git a/misc/buildroot/toolchain/gdb/6.3/740-debian_make-cv-type-crash.patch b/misc/buildroot/toolchain/gdb/6.3/740-debian_make-cv-type-crash.patch
new file mode 100644
index 000000000..4e0b8cd72
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/740-debian_make-cv-type-crash.patch
@@ -0,0 +1,132 @@
+2004-11-04 Jim Blandy <jimb@redhat.com>
+
+ * gdbtypes.c (make_qualified_type): Doc fix. Add assertion to
+ prevent cross-objfile references.
+ (make_cv_type): Doc fix. Don't create cross-objfile references,
+ even for stub types.
+ (replace_type): Add assertion to prevent cross-objfile references.
+ (check_typedef): Never resolve a stub type by copying over a type
+ from another file.
+
+Index: src/gdb/gdbtypes.c
+===================================================================
+RCS file: /big/fsf/rsync/src-cvs/src/gdb/gdbtypes.c,v
+retrieving revision 1.92
+retrieving revision 1.93
+diff -u -p -r1.92 -r1.93
+--- src/gdb/gdbtypes.c 8 Aug 2004 17:18:16 -0000 1.92
++++ src/gdb/gdbtypes.c 4 Nov 2004 17:50:16 -0000 1.93
+@@ -433,7 +433,9 @@ address_space_int_to_name (int space_fla
+ }
+
+ /* Create a new type with instance flags NEW_FLAGS, based on TYPE.
+- If STORAGE is non-NULL, create the new type instance there. */
++
++ If STORAGE is non-NULL, create the new type instance there.
++ STORAGE must be in the same obstack as TYPE. */
+
+ static struct type *
+ make_qualified_type (struct type *type, int new_flags,
+@@ -453,6 +455,12 @@ make_qualified_type (struct type *type,
+ ntype = alloc_type_instance (type);
+ else
+ {
++ /* If STORAGE was provided, it had better be in the same objfile as
++ TYPE. Otherwise, we can't link it into TYPE's cv chain: if one
++ objfile is freed and the other kept, we'd have dangling
++ pointers. */
++ gdb_assert (TYPE_OBJFILE (type) == TYPE_OBJFILE (storage));
++
+ ntype = storage;
+ TYPE_MAIN_TYPE (ntype) = TYPE_MAIN_TYPE (type);
+ TYPE_CHAIN (ntype) = ntype;
+@@ -501,11 +509,12 @@ make_type_with_address_space (struct typ
+ CNST is a flag for setting the const attribute
+ VOLTL is a flag for setting the volatile attribute
+ TYPE is the base type whose variant we are creating.
+- TYPEPTR, if nonzero, points
+- to a pointer to memory where the reference type should be stored.
+- If *TYPEPTR is zero, update it to point to the reference type we return.
+- We allocate new memory if needed. */
+
++ If TYPEPTR and *TYPEPTR are non-zero, then *TYPEPTR points to
++ storage to hold the new qualified type; *TYPEPTR and TYPE must be
++ in the same objfile. Otherwise, allocate fresh memory for the new
++ type whereever TYPE lives. If TYPEPTR is non-zero, set it to the
++ new type we construct. */
+ struct type *
+ make_cv_type (int cnst, int voltl, struct type *type, struct type **typeptr)
+ {
+@@ -524,20 +533,19 @@ make_cv_type (int cnst, int voltl, struc
+
+ if (typeptr && *typeptr != NULL)
+ {
+- /* Objfile is per-core-type. This const-qualified type had best
+- belong to the same objfile as the type it is qualifying, unless
+- we are overwriting a stub type, in which case the safest thing
+- to do is to copy the core type into the new objfile. */
+-
+- gdb_assert (TYPE_OBJFILE (*typeptr) == TYPE_OBJFILE (type)
+- || TYPE_STUB (*typeptr));
+- if (TYPE_OBJFILE (*typeptr) != TYPE_OBJFILE (type))
+- {
+- TYPE_MAIN_TYPE (*typeptr)
+- = TYPE_ALLOC (*typeptr, sizeof (struct main_type));
+- *TYPE_MAIN_TYPE (*typeptr)
+- = *TYPE_MAIN_TYPE (type);
+- }
++ /* TYPE and *TYPEPTR must be in the same objfile. We can't have
++ a C-V variant chain that threads across objfiles: if one
++ objfile gets freed, then the other has a broken C-V chain.
++
++ This code used to try to copy over the main type from TYPE to
++ *TYPEPTR if they were in different objfiles, but that's
++ wrong, too: TYPE may have a field list or member function
++ lists, which refer to types of their own, etc. etc. The
++ whole shebang would need to be copied over recursively; you
++ can't have inter-objfile pointers. The only thing to do is
++ to leave stub types as stub types, and look them up afresh by
++ name each time you encounter them. */
++ gdb_assert (TYPE_OBJFILE (*typeptr) == TYPE_OBJFILE (type));
+ }
+
+ ntype = make_qualified_type (type, new_flags, typeptr ? *typeptr : NULL);
+@@ -562,6 +570,12 @@ replace_type (struct type *ntype, struct
+ {
+ struct type *chain;
+
++ /* These two types had better be in the same objfile. Otherwise,
++ the assignment of one type's main type structure to the other
++ will produce a type with references to objects (names; field
++ lists; etc.) allocated on an objfile other than its own. */
++ gdb_assert (TYPE_OBJFILE (ntype) == TYPE_OBJFILE (ntype));
++
+ *TYPE_MAIN_TYPE (ntype) = *TYPE_MAIN_TYPE (type);
+
+ /* The type length is not a part of the main type. Update it for each
+@@ -1416,8 +1430,24 @@ check_typedef (struct type *type)
+ return type;
+ }
+ newtype = lookup_transparent_type (name);
++
+ if (newtype)
+- make_cv_type (is_const, is_volatile, newtype, &type);
++ {
++ /* If the resolved type and the stub are in the same objfile,
++ then replace the stub type with the real deal. But if
++ they're in separate objfiles, leave the stub alone; we'll
++ just look up the transparent type every time we call
++ check_typedef. We can't create pointers between types
++ allocated to different objfiles, since they may have
++ different lifetimes. Trying to copy NEWTYPE over to TYPE's
++ objfile is pointless, too, since you'll have to move over any
++ other types NEWTYPE refers to, which could be an unbounded
++ amount of stuff. */
++ if (TYPE_OBJFILE (newtype) == TYPE_OBJFILE (type))
++ make_cv_type (is_const, is_volatile, newtype, &type);
++ else
++ type = newtype;
++ }
+ }
+ /* Otherwise, rely on the stub flag being set for opaque/stubbed types */
+ else if (TYPE_STUB (type) && !currently_reading_symtab)
diff --git a/misc/buildroot/toolchain/gdb/6.3/750-debian_sparc-singlestep.patch b/misc/buildroot/toolchain/gdb/6.3/750-debian_sparc-singlestep.patch
new file mode 100644
index 000000000..904883c2f
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/750-debian_sparc-singlestep.patch
@@ -0,0 +1,37 @@
+Status: submitted for comments
+
+2004-11-13 Daniel Jacobowitz <dan@debian.org>
+
+ * sparc-tdep.c (sparc_software_single_step): Handle stepping to NULL.
+
+Index: gdb-6.3/gdb/sparc-tdep.c
+===================================================================
+--- gdb-6.3.orig/gdb/sparc-tdep.c 2004-06-06 22:02:55.000000000 -0400
++++ gdb-6.3/gdb/sparc-tdep.c 2004-11-13 17:06:05.000000000 -0500
+@@ -1026,10 +1026,10 @@
+
+ if (insert_breakpoints_p)
+ {
+- CORE_ADDR pc;
++ CORE_ADDR pc, orig_npc;
+
+ pc = sparc_address_from_register (tdep->pc_regnum);
+- npc = sparc_address_from_register (tdep->npc_regnum);
++ orig_npc = npc = sparc_address_from_register (tdep->npc_regnum);
+
+ /* Analyze the instruction at PC. */
+ nnpc = sparc_analyze_control_transfer (pc, &npc);
+@@ -1039,9 +1039,10 @@
+ target_insert_breakpoint (nnpc, nnpc_save);
+
+ /* Assert that we have set at least one breakpoint, and that
+- they're not set at the same spot. */
+- gdb_assert (npc != 0 || nnpc != 0);
+- gdb_assert (nnpc != npc);
++ they're not set at the same spot - unless we're going
++ from here straight to NULL, i.e. a call or jump to 0. */
++ gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0);
++ gdb_assert (nnpc != npc || orig_npc == 0);
+ }
+ else
+ {
diff --git a/misc/buildroot/toolchain/gdb/6.3/760-debian_vsyscall-bfd-close-result.patch b/misc/buildroot/toolchain/gdb/6.3/760-debian_vsyscall-bfd-close-result.patch
new file mode 100644
index 000000000..56002bed0
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/760-debian_vsyscall-bfd-close-result.patch
@@ -0,0 +1,20 @@
+2004-10-24 Daniel Jacobowitz <dan@debian.org>
+
+ * opncls.c (bfd_close): Return TRUE for BFD_IN_MEMORY.
+
+Index: src/bfd/opncls.c
+===================================================================
+RCS file: /big/fsf/rsync/src-cvs/src/bfd/opncls.c,v
+retrieving revision 1.25
+diff -u -p -r1.25 opncls.c
+--- src/bfd/opncls.c 10 Oct 2004 13:58:05 -0000 1.25
++++ src/bfd/opncls.c 24 Oct 2004 17:52:53 -0000
+@@ -598,7 +598,7 @@ bfd_close (bfd *abfd)
+ if (!(abfd->flags & BFD_IN_MEMORY))
+ ret = abfd->iovec->bclose (abfd);
+ else
+- ret = 0;
++ ret = TRUE;
+
+ /* If the file was open for writing and is now executable,
+ make it so. */
diff --git a/misc/buildroot/toolchain/gdb/6.3/770-debian_vfork-done-spelling.patch b/misc/buildroot/toolchain/gdb/6.3/770-debian_vfork-done-spelling.patch
new file mode 100644
index 000000000..f65db8d09
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/770-debian_vfork-done-spelling.patch
@@ -0,0 +1,31 @@
+Index: gdb-6.3/gdb/linux-nat.c
+===================================================================
+--- gdb-6.3.orig/gdb/linux-nat.c 2004-11-14 00:36:41.000000000 -0500
++++ gdb-6.3/gdb/linux-nat.c 2004-11-15 11:51:43.954161476 -0500
+@@ -69,7 +69,7 @@
+ #define PTRACE_EVENT_VFORK 2
+ #define PTRACE_EVENT_CLONE 3
+ #define PTRACE_EVENT_EXEC 4
+-#define PTRACE_EVENT_VFORKDONE 5
++#define PTRACE_EVENT_VFORK_DONE 5
+ #define PTRACE_EVENT_EXIT 6
+
+ #endif /* PTRACE_EVENT_FORK */
+@@ -362,7 +362,7 @@ child_follow_fork (int follow_child)
+
+ ptrace (PTRACE_CONT, parent_pid, 0, 0);
+ waitpid (parent_pid, &status, __WALL);
+- if ((status >> 16) != PTRACE_EVENT_VFORKDONE)
++ if ((status >> 16) != PTRACE_EVENT_VFORK_DONE)
+ warning ("Unexpected waitpid result %06x when waiting for "
+ "vfork-done", status);
+ }
+@@ -434,7 +434,7 @@ child_follow_fork (int follow_child)
+ generally not encounter vfork (vfork is defined to fork
+ in libpthread.so).
+
+- The holding part is very easy if we have VFORKDONE events;
++ The holding part is very easy if we have VFORK_DONE events;
+ but keeping track of both processes is beyond GDB at the
+ moment. So we don't expose the parent to the rest of GDB.
+ Instead we quietly hold onto it until such time as we can
diff --git a/misc/buildroot/toolchain/gdb/6.3/780-debian_gdbserver-rdynamic.patch b/misc/buildroot/toolchain/gdb/6.3/780-debian_gdbserver-rdynamic.patch
new file mode 100644
index 000000000..0311dde39
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/780-debian_gdbserver-rdynamic.patch
@@ -0,0 +1,675 @@
+Status: Commited to GDB after 6.3.
+
+Index: gdb-6.3/gdb/gdbserver/acinclude.m4
+===================================================================
+--- gdb-6.3.orig/gdb/gdbserver/acinclude.m4 2002-06-11 13:32:39.000000000 -0400
++++ gdb-6.3/gdb/gdbserver/acinclude.m4 2004-12-07 17:19:31.115089905 -0500
+@@ -13,6 +13,7 @@ AC_DEFUN([SRV_CHECK_THREAD_DB],
+ void ps_lsetregs() {}
+ void ps_lgetfpregs() {}
+ void ps_lsetfpregs() {}
++ void ps_get_thread_area() {}
+ void ps_getpid() {}],
+ [td_ta_new();],
+ [srv_cv_thread_db="-lthread_db"],
+@@ -32,10 +33,11 @@ AC_DEFUN([SRV_CHECK_THREAD_DB],
+ void ps_lsetregs() {}
+ void ps_lgetfpregs() {}
+ void ps_lsetfpregs() {}
++ void ps_get_thread_area() {}
+ void ps_getpid() {}],
+ [td_ta_new();],
+ [srv_cv_thread_db="$thread_db"],
+ [srv_cv_thread_db=no])
++ ]])
+ LIBS="$old_LIBS"
+- ]])
+ )])
+Index: gdb-6.3/gdb/gdbserver/configure
+===================================================================
+--- gdb-6.3.orig/gdb/gdbserver/configure 2004-10-16 12:18:54.000000000 -0400
++++ gdb-6.3/gdb/gdbserver/configure 2004-12-07 17:22:17.343129771 -0500
+@@ -28,6 +28,7 @@ program_suffix=NONE
+ program_transform_name=s,x,x,
+ silent=
+ site=
++sitefile=
+ srcdir=
+ target=NONE
+ verbose=
+@@ -142,6 +143,7 @@ Configuration:
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
++ --site-file=FILE use FILE as the site file
+ --version print the version of autoconf that created configure
+ Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+@@ -312,6 +314,11 @@ EOF
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
++ -site-file | --site-file | --site-fil | --site-fi | --site-f)
++ ac_prev=sitefile ;;
++ -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
++ sitefile="$ac_optarg" ;;
++
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+@@ -477,12 +484,16 @@ fi
+ srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+ # Prefer explicitly selected file to automatically selected ones.
+-if test -z "$CONFIG_SITE"; then
+- if test "x$prefix" != xNONE; then
+- CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+- else
+- CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
++if test -z "$sitefile"; then
++ if test -z "$CONFIG_SITE"; then
++ if test "x$prefix" != xNONE; then
++ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
++ else
++ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
++ fi
+ fi
++else
++ CONFIG_SITE="$sitefile"
+ fi
+ for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+@@ -526,7 +537,7 @@ fi
+ # Extract the first word of "gcc", so it can be a program name with args.
+ set dummy gcc; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:530: checking for $ac_word" >&5
++echo "configure:541: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -556,7 +567,7 @@ if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+ set dummy cc; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:560: checking for $ac_word" >&5
++echo "configure:571: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -607,7 +618,7 @@ fi
+ # Extract the first word of "cl", so it can be a program name with args.
+ set dummy cl; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:611: checking for $ac_word" >&5
++echo "configure:622: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -639,7 +650,7 @@ fi
+ fi
+
+ echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+-echo "configure:643: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
++echo "configure:654: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ ac_ext=c
+ # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+@@ -650,12 +661,12 @@ cross_compiling=$ac_cv_prog_cc_cross
+
+ cat > conftest.$ac_ext << EOF
+
+-#line 654 "configure"
++#line 665 "configure"
+ #include "confdefs.h"
+
+ main(){return(0);}
+ EOF
+-if { (eval echo configure:659: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
++if { (eval echo configure:670: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+@@ -681,12 +692,12 @@ if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+-echo "configure:685: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
++echo "configure:696: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+ echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+ cross_compiling=$ac_cv_prog_cc_cross
+
+ echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+-echo "configure:690: checking whether we are using GNU C" >&5
++echo "configure:701: checking whether we are using GNU C" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -695,7 +706,7 @@ else
+ yes;
+ #endif
+ EOF
+-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:699: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
++if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:710: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+ else
+ ac_cv_prog_gcc=no
+@@ -714,7 +725,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+-echo "configure:718: checking whether ${CC-cc} accepts -g" >&5
++echo "configure:729: checking whether ${CC-cc} accepts -g" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -793,7 +804,7 @@ else { echo "configure: error: can not r
+ fi
+
+ echo $ac_n "checking host system type""... $ac_c" 1>&6
+-echo "configure:797: checking host system type" >&5
++echo "configure:808: checking host system type" >&5
+
+ host_alias=$host
+ case "$host_alias" in
+@@ -814,7 +825,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-
+ echo "$ac_t""$host" 1>&6
+
+ echo $ac_n "checking target system type""... $ac_c" 1>&6
+-echo "configure:818: checking target system type" >&5
++echo "configure:829: checking target system type" >&5
+
+ target_alias=$target
+ case "$target_alias" in
+@@ -832,7 +843,7 @@ target_os=`echo $target | sed 's/^\([^-]
+ echo "$ac_t""$target" 1>&6
+
+ echo $ac_n "checking build system type""... $ac_c" 1>&6
+-echo "configure:836: checking build system type" >&5
++echo "configure:847: checking build system type" >&5
+
+ build_alias=$build
+ case "$build_alias" in
+@@ -867,7 +878,7 @@ test "$host_alias" != "$target_alias" &&
+ # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+ # ./install, which can be erroneously created by make from ./install.sh.
+ echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+-echo "configure:871: checking for a BSD compatible install" >&5
++echo "configure:882: checking for a BSD compatible install" >&5
+ if test -z "$INSTALL"; then
+ if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+@@ -921,7 +932,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA=
+
+
+ echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+-echo "configure:925: checking how to run the C preprocessor" >&5
++echo "configure:936: checking how to run the C preprocessor" >&5
+ # On Suns, sometimes $CPP names a directory.
+ if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+@@ -936,13 +947,13 @@ else
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+-#line 940 "configure"
++#line 951 "configure"
+ #include "confdefs.h"
+ #include <assert.h>
+ Syntax Error
+ EOF
+ ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+-{ (eval echo configure:946: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
++{ (eval echo configure:957: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+ if test -z "$ac_err"; then
+ :
+@@ -953,13 +964,13 @@ else
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+-#line 957 "configure"
++#line 968 "configure"
+ #include "confdefs.h"
+ #include <assert.h>
+ Syntax Error
+ EOF
+ ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+-{ (eval echo configure:963: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
++{ (eval echo configure:974: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+ if test -z "$ac_err"; then
+ :
+@@ -970,13 +981,13 @@ else
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+-#line 974 "configure"
++#line 985 "configure"
+ #include "confdefs.h"
+ #include <assert.h>
+ Syntax Error
+ EOF
+ ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+-{ (eval echo configure:980: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
++{ (eval echo configure:991: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+ if test -z "$ac_err"; then
+ :
+@@ -1001,12 +1012,12 @@ fi
+ echo "$ac_t""$CPP" 1>&6
+
+ echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+-echo "configure:1005: checking for ANSI C header files" >&5
++echo "configure:1016: checking for ANSI C header files" >&5
+ if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+ cat > conftest.$ac_ext <<EOF
+-#line 1010 "configure"
++#line 1021 "configure"
+ #include "confdefs.h"
+ #include <stdlib.h>
+ #include <stdarg.h>
+@@ -1014,7 +1025,7 @@ else
+ #include <float.h>
+ EOF
+ ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+-{ (eval echo configure:1018: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
++{ (eval echo configure:1029: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+ if test -z "$ac_err"; then
+ rm -rf conftest*
+@@ -1031,7 +1042,7 @@ rm -f conftest*
+ if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat > conftest.$ac_ext <<EOF
+-#line 1035 "configure"
++#line 1046 "configure"
+ #include "confdefs.h"
+ #include <string.h>
+ EOF
+@@ -1049,7 +1060,7 @@ fi
+ if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat > conftest.$ac_ext <<EOF
+-#line 1053 "configure"
++#line 1064 "configure"
+ #include "confdefs.h"
+ #include <stdlib.h>
+ EOF
+@@ -1070,7 +1081,7 @@ if test "$cross_compiling" = yes; then
+ :
+ else
+ cat > conftest.$ac_ext <<EOF
+-#line 1074 "configure"
++#line 1085 "configure"
+ #include "confdefs.h"
+ #include <ctype.h>
+ #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+@@ -1081,7 +1092,7 @@ if (XOR (islower (i), ISLOWER (i)) || to
+ exit (0); }
+
+ EOF
+-if { (eval echo configure:1085: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
++if { (eval echo configure:1096: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+ then
+ :
+ else
+@@ -1109,17 +1120,17 @@ for ac_hdr in sgtty.h termio.h termios.h
+ do
+ ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+ echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+-echo "configure:1113: checking for $ac_hdr" >&5
++echo "configure:1124: checking for $ac_hdr" >&5
+ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+ cat > conftest.$ac_ext <<EOF
+-#line 1118 "configure"
++#line 1129 "configure"
+ #include "confdefs.h"
+ #include <$ac_hdr>
+ EOF
+ ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+-{ (eval echo configure:1123: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
++{ (eval echo configure:1134: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+ if test -z "$ac_err"; then
+ rm -rf conftest*
+@@ -1147,12 +1158,12 @@ done
+
+
+ echo $ac_n "checking whether strerror must be declared""... $ac_c" 1>&6
+-echo "configure:1151: checking whether strerror must be declared" >&5
++echo "configure:1162: checking whether strerror must be declared" >&5
+ if eval "test \"`echo '$''{'bfd_cv_decl_needed_strerror'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+ cat > conftest.$ac_ext <<EOF
+-#line 1156 "configure"
++#line 1167 "configure"
+ #include "confdefs.h"
+
+ #include <stdio.h>
+@@ -1173,7 +1184,7 @@ int main() {
+ char *(*pfn) = (char *(*)) strerror
+ ; return 0; }
+ EOF
+-if { (eval echo configure:1177: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++if { (eval echo configure:1188: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_strerror=no
+ else
+@@ -1205,19 +1216,19 @@ fi
+
+ if test "${srv_linux_regsets}" = "yes"; then
+ echo $ac_n "checking for PTRACE_GETREGS""... $ac_c" 1>&6
+-echo "configure:1209: checking for PTRACE_GETREGS" >&5
++echo "configure:1220: checking for PTRACE_GETREGS" >&5
+ if eval "test \"`echo '$''{'gdbsrv_cv_have_ptrace_getregs'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+ cat > conftest.$ac_ext <<EOF
+-#line 1214 "configure"
++#line 1225 "configure"
+ #include "confdefs.h"
+ #include <sys/ptrace.h>
+ int main() {
+ PTRACE_GETREGS;
+ ; return 0; }
+ EOF
+-if { (eval echo configure:1221: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++if { (eval echo configure:1232: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdbsrv_cv_have_ptrace_getregs=yes
+ else
+@@ -1238,19 +1249,19 @@ EOF
+ fi
+
+ echo $ac_n "checking for PTRACE_GETFPXREGS""... $ac_c" 1>&6
+-echo "configure:1242: checking for PTRACE_GETFPXREGS" >&5
++echo "configure:1253: checking for PTRACE_GETFPXREGS" >&5
+ if eval "test \"`echo '$''{'gdbsrv_cv_have_ptrace_getfpxregs'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+ cat > conftest.$ac_ext <<EOF
+-#line 1247 "configure"
++#line 1258 "configure"
+ #include "confdefs.h"
+ #include <sys/ptrace.h>
+ int main() {
+ PTRACE_GETFPXREGS;
+ ; return 0; }
+ EOF
+-if { (eval echo configure:1254: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++if { (eval echo configure:1265: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdbsrv_cv_have_ptrace_getfpxregs=yes
+ else
+@@ -1273,12 +1284,12 @@ fi
+
+ if test "$ac_cv_header_sys_procfs_h" = yes; then
+ echo $ac_n "checking for lwpid_t in sys/procfs.h""... $ac_c" 1>&6
+-echo "configure:1277: checking for lwpid_t in sys/procfs.h" >&5
++echo "configure:1288: checking for lwpid_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_lwpid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+ cat > conftest.$ac_ext <<EOF
+-#line 1282 "configure"
++#line 1293 "configure"
+ #include "confdefs.h"
+
+ #define _SYSCALL32
+@@ -1287,7 +1298,7 @@ int main() {
+ lwpid_t avar
+ ; return 0; }
+ EOF
+-if { (eval echo configure:1291: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++if { (eval echo configure:1302: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_lwpid_t=yes
+ else
+@@ -1309,12 +1320,12 @@ EOF
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_lwpid_t" 1>&6
+
+ echo $ac_n "checking for psaddr_t in sys/procfs.h""... $ac_c" 1>&6
+-echo "configure:1313: checking for psaddr_t in sys/procfs.h" >&5
++echo "configure:1324: checking for psaddr_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_psaddr_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+ cat > conftest.$ac_ext <<EOF
+-#line 1318 "configure"
++#line 1329 "configure"
+ #include "confdefs.h"
+
+ #define _SYSCALL32
+@@ -1323,7 +1334,7 @@ int main() {
+ psaddr_t avar
+ ; return 0; }
+ EOF
+-if { (eval echo configure:1327: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++if { (eval echo configure:1338: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_psaddr_t=yes
+ else
+@@ -1345,12 +1356,12 @@ EOF
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_psaddr_t" 1>&6
+
+ echo $ac_n "checking for prgregset_t in sys/procfs.h""... $ac_c" 1>&6
+-echo "configure:1349: checking for prgregset_t in sys/procfs.h" >&5
++echo "configure:1360: checking for prgregset_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prgregset_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+ cat > conftest.$ac_ext <<EOF
+-#line 1354 "configure"
++#line 1365 "configure"
+ #include "confdefs.h"
+
+ #define _SYSCALL32
+@@ -1359,7 +1370,7 @@ int main() {
+ prgregset_t avar
+ ; return 0; }
+ EOF
+-if { (eval echo configure:1363: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++if { (eval echo configure:1374: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prgregset_t=yes
+ else
+@@ -1381,12 +1392,12 @@ EOF
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_prgregset_t" 1>&6
+
+ echo $ac_n "checking for prfpregset_t in sys/procfs.h""... $ac_c" 1>&6
+-echo "configure:1385: checking for prfpregset_t in sys/procfs.h" >&5
++echo "configure:1396: checking for prfpregset_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prfpregset_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+ cat > conftest.$ac_ext <<EOF
+-#line 1390 "configure"
++#line 1401 "configure"
+ #include "confdefs.h"
+
+ #define _SYSCALL32
+@@ -1395,7 +1406,7 @@ int main() {
+ prfpregset_t avar
+ ; return 0; }
+ EOF
+-if { (eval echo configure:1399: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++if { (eval echo configure:1410: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prfpregset_t=yes
+ else
+@@ -1421,7 +1432,7 @@ EOF
+
+ if test $bfd_cv_have_sys_procfs_type_prfpregset_t = yes; then
+ echo $ac_n "checking whether prfpregset_t type is broken""... $ac_c" 1>&6
+-echo "configure:1425: checking whether prfpregset_t type is broken" >&5
++echo "configure:1436: checking whether prfpregset_t type is broken" >&5
+ if eval "test \"`echo '$''{'gdb_cv_prfpregset_t_broken'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1429,7 +1440,7 @@ else
+ gdb_cv_prfpregset_t_broken=yes
+ else
+ cat > conftest.$ac_ext <<EOF
+-#line 1433 "configure"
++#line 1444 "configure"
+ #include "confdefs.h"
+ #include <sys/procfs.h>
+ int main ()
+@@ -1439,7 +1450,7 @@ else
+ return 0;
+ }
+ EOF
+-if { (eval echo configure:1443: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
++if { (eval echo configure:1454: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+ then
+ gdb_cv_prfpregset_t_broken=no
+ else
+@@ -1463,12 +1474,12 @@ EOF
+ fi
+
+ echo $ac_n "checking for elf_fpregset_t in sys/procfs.h""... $ac_c" 1>&6
+-echo "configure:1467: checking for elf_fpregset_t in sys/procfs.h" >&5
++echo "configure:1478: checking for elf_fpregset_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_elf_fpregset_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+ cat > conftest.$ac_ext <<EOF
+-#line 1472 "configure"
++#line 1483 "configure"
+ #include "confdefs.h"
+
+ #define _SYSCALL32
+@@ -1477,7 +1488,7 @@ int main() {
+ elf_fpregset_t avar
+ ; return 0; }
+ EOF
+-if { (eval echo configure:1481: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++if { (eval echo configure:1492: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_elf_fpregset_t=yes
+ else
+@@ -1506,14 +1517,14 @@ USE_THREAD_DB=
+
+ if test "$srv_linux_thread_db" = "yes"; then
+ echo $ac_n "checking for libthread_db""... $ac_c" 1>&6
+-echo "configure:1510: checking for libthread_db" >&5
++echo "configure:1521: checking for libthread_db" >&5
+ if eval "test \"`echo '$''{'srv_cv_thread_db'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+ old_LIBS="$LIBS"
+ LIBS="$LIBS -lthread_db"
+ cat > conftest.$ac_ext <<EOF
+-#line 1517 "configure"
++#line 1528 "configure"
+ #include "confdefs.h"
+ void ps_pglobal_lookup() {}
+ void ps_pdread() {}
+@@ -1522,12 +1533,13 @@ void ps_pglobal_lookup() {}
+ void ps_lsetregs() {}
+ void ps_lgetfpregs() {}
+ void ps_lsetfpregs() {}
++ void ps_get_thread_area() {}
+ void ps_getpid() {}
+ int main() {
+ td_ta_new();
+ ; return 0; }
+ EOF
+-if { (eval echo configure:1531: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
++if { (eval echo configure:1543: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ srv_cv_thread_db="-lthread_db"
+ else
+@@ -1543,7 +1555,7 @@ else
+ fi
+ LIBS="$old_LIBS `eval echo "$thread_db"`"
+ cat > conftest.$ac_ext <<EOF
+-#line 1547 "configure"
++#line 1559 "configure"
+ #include "confdefs.h"
+ void ps_pglobal_lookup() {}
+ void ps_pdread() {}
+@@ -1552,12 +1564,13 @@ void ps_pglobal_lookup() {}
+ void ps_lsetregs() {}
+ void ps_lgetfpregs() {}
+ void ps_lsetfpregs() {}
++ void ps_get_thread_area() {}
+ void ps_getpid() {}
+ int main() {
+ td_ta_new();
+ ; return 0; }
+ EOF
+-if { (eval echo configure:1561: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
++if { (eval echo configure:1574: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ srv_cv_thread_db="$thread_db"
+ else
+@@ -1567,11 +1580,11 @@ else
+ srv_cv_thread_db=no
+ fi
+ rm -f conftest*
+- LIBS="$old_LIBS"
+-
++
+ fi
+
+ echo "$ac_t""$srv_cv_thread_db" 1>&6
++ LIBS="$old_LIBS"
+
+ fi
+ rm -f conftest*
+@@ -1585,14 +1598,14 @@ rm -f conftest*
+ old_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -rdynamic"
+ cat > conftest.$ac_ext <<EOF
+-#line 1589 "configure"
++#line 1602 "configure"
+ #include "confdefs.h"
+
+ int main() {
+
+ ; return 0; }
+ EOF
+-if { (eval echo configure:1596: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
++if { (eval echo configure:1609: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ RDYNAMIC=-rdynamic
+ else
+Index: gdb-6.3/gdb/gdbserver/aclocal.m4
+===================================================================
+--- gdb-6.3.orig/gdb/gdbserver/aclocal.m4 2002-06-11 13:32:39.000000000 -0400
++++ gdb-6.3/gdb/gdbserver/aclocal.m4 2004-12-07 17:22:00.382495519 -0500
+@@ -1,4 +1,4 @@
+-dnl aclocal.m4 generated automatically by aclocal 1.4-p4
++dnl aclocal.m4 generated automatically by aclocal 1.4
+
+ dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+ dnl This file is free software; the Free Software Foundation
+@@ -25,6 +25,7 @@ AC_DEFUN([SRV_CHECK_THREAD_DB],
+ void ps_lsetregs() {}
+ void ps_lgetfpregs() {}
+ void ps_lsetfpregs() {}
++ void ps_get_thread_area() {}
+ void ps_getpid() {}],
+ [td_ta_new();],
+ [srv_cv_thread_db="-lthread_db"],
+@@ -44,11 +45,12 @@ AC_DEFUN([SRV_CHECK_THREAD_DB],
+ void ps_lsetregs() {}
+ void ps_lgetfpregs() {}
+ void ps_lsetfpregs() {}
++ void ps_get_thread_area() {}
+ void ps_getpid() {}],
+ [td_ta_new();],
+ [srv_cv_thread_db="$thread_db"],
+ [srv_cv_thread_db=no])
++ ]])
+ LIBS="$old_LIBS"
+- ]])
+ )])
+
diff --git a/misc/buildroot/toolchain/gdb/6.3/790-debian_dwarf2-cfi-warning.patch b/misc/buildroot/toolchain/gdb/6.3/790-debian_dwarf2-cfi-warning.patch
new file mode 100644
index 000000000..cfb3d95de
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/790-debian_dwarf2-cfi-warning.patch
@@ -0,0 +1,39 @@
+Status: Unsuitable for upstream (at least, without a lot of arguing).
+
+GCC does not specify the state of every last register in the CIE. Since
+GCC's focus is on correctness of runtime unwinding, any registers which
+have to be unwound will be specified; but unmodified registers will not
+be explicitly marked. (How about modified, call-clobbered registers?
+I'm not sure if they are marked as unavailable.)
+
+GDB issues a noisy warning about this. The warning is generally not useful,
+and we can get it extremely frequently (any time we load a new CIE).
+
+This patch disables the warning. Alternately we could set the complaints
+threshold to zero, or implement a default frame init-register method for
+every architecture. But someday the compiler will support using different
+calling conventions for internal functions, so that's not much of a stopgap.
+ARM has a complex algorithm for handling this, involving scanning all CIEs -
+benefit not completely clear outside of the ARM context of flexible register
+sets.
+
+Index: gdb-6.3/gdb/dwarf2-frame.c
+===================================================================
+--- gdb-6.3.orig/gdb/dwarf2-frame.c 2004-11-15 11:54:57.000000000 -0500
++++ gdb-6.3/gdb/dwarf2-frame.c 2004-12-08 18:02:23.896409471 -0500
+@@ -705,9 +705,12 @@ dwarf2_frame_cache (struct frame_info *n
+ table. We need a way of iterating through all the valid
+ DWARF2 register numbers. */
+ if (fs->regs.reg[column].how == DWARF2_FRAME_REG_UNSPECIFIED)
+- complaint (&symfile_complaints,
+- "Incomplete CFI data; unspecified registers at 0x%s",
+- paddr (fs->pc));
++ {
++ if (0)
++ complaint (&symfile_complaints,
++ "Incomplete CFI data; unspecified registers at 0x%s",
++ paddr (fs->pc));
++ }
+ else
+ cache->reg[regnum] = fs->regs.reg[column];
+ }
diff --git a/misc/buildroot/toolchain/gdb/6.3/800-debian_linux-use-underscore-exit.patch b/misc/buildroot/toolchain/gdb/6.3/800-debian_linux-use-underscore-exit.patch
new file mode 100644
index 000000000..198918ccc
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/800-debian_linux-use-underscore-exit.patch
@@ -0,0 +1,22 @@
+Status: committed upstream after 6.3. Fixes some terminal mangling in
+gdbtui.
+
+2004-12-04 Daniel Jacobowitz <dan@debian.org>
+
+ PR tui/1703
+ * linux-nat.c (linux_tracefork_child): Use _exit instead of exit.
+ Suggested by Joshua Neuheisel.
+
+Index: gdb-6.3/gdb/linux-nat.c
+===================================================================
+--- gdb-6.3.orig/gdb/linux-nat.c 2004-12-08 18:22:04.996973094 -0500
++++ gdb-6.3/gdb/linux-nat.c 2004-12-08 18:22:20.386956067 -0500
+@@ -147,7 +147,7 @@ linux_tracefork_child (void)
+ ptrace (PTRACE_TRACEME, 0, 0, 0);
+ kill (getpid (), SIGSTOP);
+ fork ();
+- exit (0);
++ _exit (0);
+ }
+
+ /* Wrapper function for waitpid which handles EINTR. */
diff --git a/misc/buildroot/toolchain/gdb/6.3/810-debian_bfd-no-kylix-crash.patch b/misc/buildroot/toolchain/gdb/6.3/810-debian_bfd-no-kylix-crash.patch
new file mode 100644
index 000000000..9aba5ca23
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/810-debian_bfd-no-kylix-crash.patch
@@ -0,0 +1,47 @@
+Status: committed upstream after 6.3.
+
+Fix a crash triggered by Kylix libraries.
+
+2004-12-06 Daniel Jacobowitz <dan@debian.org>
+
+ Suggested by Fergal Daly <fergal@esatclear.ie>:
+ * simple.c (simple_dummy_multiple_definition): New function.
+ (bfd_simple_get_relocated_section_contents): Use it.
+
+Index: src/bfd/simple.c
+===================================================================
+RCS file: /cvs/src/src/bfd/simple.c,v
+retrieving revision 1.19
+retrieving revision 1.20
+Index: gdb-6.3/bfd/simple.c
+===================================================================
+--- gdb-6.3.orig/bfd/simple.c 2004-09-24 03:07:19.000000000 -0400
++++ gdb-6.3/bfd/simple.c 2004-12-08 18:25:58.415216808 -0500
+@@ -78,6 +78,19 @@ simple_dummy_unattached_reloc (struct bf
+ return TRUE;
+ }
+
++static bfd_boolean
++simple_dummy_multiple_definition (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
++ const char *name ATTRIBUTE_UNUSED,
++ bfd *obfd ATTRIBUTE_UNUSED,
++ asection *osec ATTRIBUTE_UNUSED,
++ bfd_vma oval ATTRIBUTE_UNUSED,
++ bfd *nbfd ATTRIBUTE_UNUSED,
++ asection *nsec ATTRIBUTE_UNUSED,
++ bfd_vma nval ATTRIBUTE_UNUSED)
++{
++ return TRUE;
++}
++
+ struct saved_output_info
+ {
+ bfd_vma offset;
+@@ -172,6 +185,7 @@ bfd_simple_get_relocated_section_content
+ callbacks.reloc_overflow = simple_dummy_reloc_overflow;
+ callbacks.reloc_dangerous = simple_dummy_reloc_dangerous;
+ callbacks.unattached_reloc = simple_dummy_unattached_reloc;
++ callbacks.multiple_definition = simple_dummy_multiple_definition;
+
+ memset (&link_order, 0, sizeof (link_order));
+ link_order.next = NULL;
diff --git a/misc/buildroot/toolchain/gdb/6.3/820-debian_disable-linux-fork-messages.patch b/misc/buildroot/toolchain/gdb/6.3/820-debian_disable-linux-fork-messages.patch
new file mode 100644
index 000000000..60730abc1
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.3/820-debian_disable-linux-fork-messages.patch
@@ -0,0 +1,46 @@
+Status: Proposed upstream after 6.3, not yet committed.
+
+2004-12-06 Daniel Jacobowitz <dan@debian.org>
+
+ * linux-nat.c (child_follow_fork): Call target_terminal_ours before
+ printing output. Use fprintf_unfiltered. Only print output when
+ debugging.
+
+Index: gdb-6.3/gdb/linux-nat.c
+===================================================================
+--- gdb-6.3.orig/gdb/linux-nat.c 2004-12-08 18:22:20.386956067 -0500
++++ gdb-6.3/gdb/linux-nat.c 2004-12-08 18:28:49.995585970 -0500
+@@ -347,9 +347,13 @@ child_follow_fork (int follow_child)
+ also, but they'll be reinserted below. */
+ detach_breakpoints (child_pid);
+
+- fprintf_filtered (gdb_stdout,
+- "Detaching after fork from child process %d.\n",
+- child_pid);
++ if (debug_linux_nat)
++ {
++ target_terminal_ours ();
++ fprintf_unfiltered (gdb_stdlog,
++ "Detaching after fork from child process %d.\n",
++ child_pid);
++ }
+
+ ptrace (PTRACE_DETACH, child_pid, 0, 0);
+
+@@ -418,9 +422,13 @@ child_follow_fork (int follow_child)
+ /* Before detaching from the parent, remove all breakpoints from it. */
+ remove_breakpoints ();
+
+- fprintf_filtered (gdb_stdout,
+- "Attaching after fork to child process %d.\n",
+- child_pid);
++ if (debug_linux_nat)
++ {
++ target_terminal_ours ();
++ fprintf_unfiltered (gdb_stdlog,
++ "Attaching after fork to child process %d.\n",
++ child_pid);
++ }
+
+ /* If we're vforking, we may want to hold on to the parent until
+ the child exits or execs. At exec time we can remove the old
diff --git a/misc/buildroot/toolchain/gdb/6.4/400-mips-coredump.patch-2.4.23-29 b/misc/buildroot/toolchain/gdb/6.4/400-mips-coredump.patch-2.4.23-29
new file mode 100644
index 000000000..4e17ba7be
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.4/400-mips-coredump.patch-2.4.23-29
@@ -0,0 +1,28 @@
+Sometime around 2.4.22-23, the mips pt_regs.h fields were reordered, breaking
+coredump handling by gdb for current kernels. Update the hardcoded constants
+to reflect the change.
+--- gdb-6.2.1/gdb/mips-linux-tdep.c-orig 2004-10-29 14:23:55.000000000 -0500
++++ gdb-6.2.1/gdb/mips-linux-tdep.c 2004-10-29 14:26:44.000000000 -0500
+@@ -53,12 +53,22 @@
+
+ #define EF_REG0 6
+ #define EF_REG31 37
++
++#if 0
+ #define EF_LO 38
+ #define EF_HI 39
+ #define EF_CP0_EPC 40
+ #define EF_CP0_BADVADDR 41
+ #define EF_CP0_STATUS 42
+ #define EF_CP0_CAUSE 43
++#else
++#define EF_CP0_STATUS 38
++#define EF_LO 39
++#define EF_HI 40
++#define EF_CP0_BADVADDR 41
++#define EF_CP0_CAUSE 42
++#define EF_CP0_EPC 43
++#endif
+
+ #define EF_SIZE 180
+
diff --git a/misc/buildroot/toolchain/gdb/6.4/500-thread-timeout.patch b/misc/buildroot/toolchain/gdb/6.4/500-thread-timeout.patch
new file mode 100644
index 000000000..6db0a7a47
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.4/500-thread-timeout.patch
@@ -0,0 +1,34 @@
+--- gdb-6.3.org/gdb/gdbserver/thread-db.c 2004-10-17 02:42:00.000000000 +0900
++++ gdb-6.3/gdb/gdbserver/thread-db.c 2005-01-27 12:19:29.000000000 +0900
+@@ -21,6 +21,7 @@
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
++#include <unistd.h>
+ #include "server.h"
+
+ #include "linux-low.h"
+@@ -142,6 +143,7 @@
+ td_event_msg_t msg;
+ td_err_e err;
+ struct inferior_linux_data *tdata;
++ int timeout;
+
+ if (debug_threads)
+ fprintf (stderr, "Thread creation event.\n");
+@@ -152,7 +154,13 @@
+ In the LinuxThreads implementation, this is safe,
+ because all events come from the manager thread
+ (except for its own creation, of course). */
+- err = td_ta_event_getmsg (thread_agent, &msg);
++ for (timeout = 0; timeout < 50000; timeout++)
++ {
++ err = td_ta_event_getmsg (thread_agent, &msg);
++ if (err != TD_NOMSG)
++ break;
++ usleep(1000);
++ }
+ if (err != TD_OK)
+ fprintf (stderr, "thread getmsg err: %s\n",
+ thread_db_err_str (err));
+
diff --git a/misc/buildroot/toolchain/gdb/6.4/600-fix-compile-flag-mismatch.patch b/misc/buildroot/toolchain/gdb/6.4/600-fix-compile-flag-mismatch.patch
new file mode 100644
index 000000000..659a5f03a
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.4/600-fix-compile-flag-mismatch.patch
@@ -0,0 +1,87 @@
+diff -ur gdb-6.4/gdb/configure gdb-6.4-patched/gdb/configure
+--- gdb-6.4/gdb/configure 2005-07-25 10:08:40.000000000 -0500
++++ gdb-6.4-patched/gdb/configure 2007-02-05 13:22:36.000000000 -0600
+@@ -309,7 +309,7 @@
+ # include <unistd.h>
+ #endif"
+
+-ac_subdirs_all="$ac_subdirs_all doc testsuite"
++ac_subdirs_all="$ac_subdirs_all doc"
+ ac_subdirs_all="$ac_subdirs_all gdbtk"
+ ac_subdirs_all="$ac_subdirs_all multi-ice"
+ ac_subdirs_all="$ac_subdirs_all gdbserver"
+@@ -5940,7 +5940,7 @@
+
+
+
+-subdirs="$subdirs doc testsuite"
++subdirs="$subdirs doc"
+
+
+ . $srcdir/configure.host
+diff -ur gdb-6.4/gdb/gdbserver/configure gdb-6.4-patched/gdb/gdbserver/configure
+--- gdb-6.4/gdb/gdbserver/configure 2005-09-17 18:14:37.000000000 -0500
++++ gdb-6.4-patched/gdb/gdbserver/configure 2007-02-05 13:22:58.000000000 -0600
+@@ -1239,7 +1239,7 @@
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+- if test "x$ac_old_val" != "x$ac_new_val"; then
++ if test "`echo $ac_old_val`" != "`echo $ac_new_val`"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+ echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+diff -ur gdb-6.4/gdb/testsuite/configure gdb-6.4-patched/gdb/testsuite/configure
+--- gdb-6.4/gdb/testsuite/configure 2005-04-11 09:13:12.000000000 -0500
++++ gdb-6.4-patched/gdb/testsuite/configure 2007-02-05 13:22:36.000000000 -0600
+@@ -1248,7 +1248,7 @@
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+- if test "x$ac_old_val" != "x$ac_new_val"; then
++ if test "`echo $ac_old_val" != "`echo $ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+ echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+diff -ur gdb-6.4/Makefile.in gdb-6.4-patched/Makefile.in
+--- gdb-6.4/Makefile.in 2005-12-01 23:29:54.000000000 -0600
++++ gdb-6.4-patched/Makefile.in 2007-02-05 13:22:36.000000000 -0600
+@@ -383,7 +383,7 @@
+ # CFLAGS will be just -g. We want to ensure that TARGET libraries
+ # (which we know are built with gcc) are built with optimizations so
+ # prepend -O2 when setting CFLAGS_FOR_TARGET.
+-CFLAGS_FOR_TARGET = -O2 $(CFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET)
++CFLAGS_FOR_TARGET = $(strip $(CFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET))
+ SYSROOT_CFLAGS_FOR_TARGET = @SYSROOT_CFLAGS_FOR_TARGET@
+
+ # If GCC_FOR_TARGET is not overriden on the command line, then this
+@@ -423,7 +423,7 @@
+ fi; \
+ fi`
+
+-CXXFLAGS_FOR_TARGET = $(CXXFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET)
++CXXFLAGS_FOR_TARGET = $(strip $(CXXFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET))
+ LIBCXXFLAGS_FOR_TARGET = $(CXXFLAGS_FOR_TARGET) -fno-implicit-templates
+
+ GCJ_FOR_TARGET=$(STAGE_CC_WRAPPER) @GCJ_FOR_TARGET@ $(FLAGS_FOR_TARGET)
+diff -ur gdb-6.4/Makefile.tpl gdb-6.4-patched/Makefile.tpl
+--- gdb-6.4/Makefile.tpl 2005-10-22 05:37:55.000000000 -0500
++++ gdb-6.4-patched/Makefile.tpl 2007-02-05 13:22:36.000000000 -0600
+@@ -386,7 +386,7 @@
+ # CFLAGS will be just -g. We want to ensure that TARGET libraries
+ # (which we know are built with gcc) are built with optimizations so
+ # prepend -O2 when setting CFLAGS_FOR_TARGET.
+-CFLAGS_FOR_TARGET = -O2 $(CFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET)
++CFLAGS_FOR_TARGET = $(strip $(CFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET))
+ SYSROOT_CFLAGS_FOR_TARGET = @SYSROOT_CFLAGS_FOR_TARGET@
+
+ # If GCC_FOR_TARGET is not overriden on the command line, then this
+@@ -426,7 +426,7 @@
+ fi; \
+ fi`
+
+-CXXFLAGS_FOR_TARGET = $(CXXFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET)
++CXXFLAGS_FOR_TARGET = $(strip $(CXXFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET))
+ LIBCXXFLAGS_FOR_TARGET = $(CXXFLAGS_FOR_TARGET) -fno-implicit-templates
+
+ GCJ_FOR_TARGET=$(STAGE_CC_WRAPPER) @GCJ_FOR_TARGET@ $(FLAGS_FOR_TARGET)
diff --git a/misc/buildroot/toolchain/gdb/6.4/700-m68hc1x-20060122.patch b/misc/buildroot/toolchain/gdb/6.4/700-m68hc1x-20060122.patch
new file mode 100644
index 000000000..fbb364c4c
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.4/700-m68hc1x-20060122.patch
@@ -0,0 +1,5682 @@
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/bfd/ChangeLog.M68HC11 gdb-6.4-m68hc1x/bfd/ChangeLog.M68HC11
+--- gdb-6.4/bfd/ChangeLog.M68HC11 Thu Jan 1 01:00:00 1970
++++ gdb-6.4-m68hc1x/bfd/ChangeLog.M68HC11 Sun Jan 22 22:18:25 2006
+@@ -0,0 +1,7 @@
++2006-01-21 Stephane Carrez <stcarrez@nerim.fr>
++
++ * elf32-m68hc1x.c: Include "alloca-conf.h"
++
++2004-02-01 Stephane Carrez <stcarrez@nerim.fr>
++
++ * opncls.c: Merge from mingw32 20031011 port.
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/bfd/elf32-m68hc1x.c gdb-6.4-m68hc1x/bfd/elf32-m68hc1x.c
+--- gdb-6.4/bfd/elf32-m68hc1x.c Mon Jun 20 20:12:07 2005
++++ gdb-6.4-m68hc1x/bfd/elf32-m68hc1x.c Sat Jan 21 17:53:08 2006
+@@ -1,5 +1,5 @@
+ /* Motorola 68HC11/HC12-specific support for 32-bit ELF
+- Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005
++ Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+ Contributed by Stephane Carrez (stcarrez@nerim.fr)
+
+@@ -19,6 +19,7 @@ You should have received a copy of the G
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
++#include "alloca-conf.h"
+ #include "bfd.h"
+ #include "sysdep.h"
+ #include "bfdlink.h"
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/ChangeLog.M68HC11 gdb-6.4-m68hc1x/gdb/ChangeLog.M68HC11
+--- gdb-6.4/gdb/ChangeLog.M68HC11 Thu Jan 1 01:00:00 1970
++++ gdb-6.4-m68hc1x/gdb/ChangeLog.M68HC11 Sat Jan 21 17:14:12 2006
+@@ -0,0 +1,147 @@
++2006-01-21 Stephane Carrez <stcarrez@nerim.fr>
++
++ * m68hc11-rom.c (dbug_xfer_memory): Use gdb_byte
++ * remote-bdm12.c (gdbbdm12_insert_breakpoint): Use gdb_byte
++ (gdbbdm12_remove_breakpoint): Likewise.
++ (gdbbdm12_xfer_inferior_memory): Likewise.
++ (gdbbdm12_fetch_register): Use regcache_raw_supply to set the
++ register in gdb's cache. Use register_size.
++ (gdbbdm12_store_register): Likewise.
++
++2004-08-05 Stephane Carrez <stcarrez@nerim.fr>
++
++ * ser-mingw.c (do_mingw_readchar): Use deprecated_ui_loop_hook instead of
++ ui_loop_hook
++
++2004-08-01 Stephane Carrez <stcarrez@nerim.fr>
++
++ * signals/signals.c (SIGTRAP): Define if not defined so that the
++ simulator works on mingw32.
++
++2004-08-01 Stephane Carrez <stcarrez@nerim.fr>
++
++ Patch Savannah/3123:
++ From Marek Peca <marek@tynska.cuni.cz>:
++
++ * remote-bdm12.c (gdbbdm12_cntrl_c): Set stop requested flag.
++ (gdbbdm12_wait): Call gdbbdm12_stop here instead of from sig handler.
++ * remote-bdm12.c (gdbbdm12_stop): Clear stop requested flag.
++
++2004-08-01 Stephane Carrez <stcarrez@nerim.fr>
++
++ * remote-bdm12.c (gdbbdm12_create_inferior): Fix prototype.
++
++2004-08-01 Stephane Carrez <stcarrez@nerim.fr>
++
++ * remote-bdm12.c (gdbbdm12_fetch_register): Use DEPRECATED_REGISTER_RAW_SIZE.
++ (gdbbdm12_store_register): Likewise.
++
++2004-02-08 Stephane Carrez <stcarrez@nerim.fr>
++
++ * remote-bdm12.c (gdbbdm12_wait): Use TARGET_SIGNAL_SIGABRT,
++ TARGET_SIGNAL_INT, TARGET_SIGNAL_TRAP
++
++ * bdm12.c (bdm12_stop_reason): Use TARGET_SIGNAL_TRAP and
++ TARGET_SIGNAL_INT.
++
++2004-02-01 Stephane Carrez <stcarrez@nerim.fr>
++
++ * version.in: Bump to 2004-02-01
++
++2004-02-01 Stephane Carrez <stcarrez@nerim.fr>
++
++ * bdm12.h (bdm12_create_inferior): Update prototype.
++ Convert prototypes.
++ * bdm12.c (bdm12_create_inferior): Use bfd type.
++
++ * remote-bdm12.c (gdbbdm12_fetch_register): Use MAX_REGISTER_SIZE.
++ (gdbbdm12_store_register): Likewise.
++ (gdbbdm12_store_register): Use deprecated_read_register_gen.
++
++2004-02-01 Stephane Carrez <stcarrez@nerim.fr>
++
++ * configure.in, environ.c, environ.h, infcmd.c, inferior.h,
++ win32-nat.c, event-loop.c, event-loop.h, utils.c, top.c, ser-mingw.c,
++ set-mingw.h, ser-tcp.c, ser-unix.c, inferior.h:
++
++ Merge http://www.ming.org 20031011 gdb patch for Mingw32 host.
++
++2002-06-15 Stephane Carrez <stcarrez@nerim.fr>
++
++ * remote-bdm12.c (gdbbdm12_kill): Use null_ptid.
++ (gdbbdm12_load): Likewise.
++ (gdbbdm12_resume): Use PIDGET.
++ (gdbbdm12_wait): Update prototype.
++ (pass_command): Use target_fetch_register.
++
++2002-06-10 Martin Rod <martin.rod@ct.cz>
++
++ * bdm12.c: Add small delay after RTS asserting (Linux)
++
++2001-10-14 Stephane Carrez <Stephane.Carrez@worldnet.fr>
++
++ * bdm12.c: Don't compile under Mingw32 since serial line code is
++ not ported.
++ * remote-bdm12.c: Likewise.
++
++2001-09-28 Tim Housel <thousel@usa.net>
++
++ * bdm12.c: New file (BDM12 pod communication support).
++ * bdm12.h: New file.
++ * remote-bdm12.c: New file (BDM12 gdb backend).
++ * bdm12_eraseflash.h: New file.
++ * bdm12_programflash.h: New file.
++ * Makefile.in (ALLDEPFILES): Add new files.
++
++2001-01-13 Stephane Carrez <Stephane.Carrez@worldnet.fr>
++
++ * dsrec.c (load_srec): Use the LMA address when loading.
++
++2001-01-06 Stephane Carrez <Stephane.Carrez@worldnet.fr>
++
++ * dsrec.c (load_srec): Use serial_write function to send
++ data on the serial line.
++ * srec.h (load_srec): Add serial_write parameter.
++
++2000-12-28 Stephane Carrez <Stephane.Carrez@worldnet.fr>
++
++ * monitor.h (serial_write): New member.
++ * monitor.c (monitor_write): Use it if it is set.
++ (monitor_read_memory): Use monitor_write.
++
++2000-12-28 Stephane Carrez <Stephane.Carrez@worldnet.fr>
++
++ * m68hc11-rom.c (set_gdbarch): New function.
++ (m68hc11_serial_write): New function.
++ (console_input): New function.
++ (do_console_input): New function.
++ (m68hc11_wait_filter): New function.
++ (init_buffalo_cmds): Install them.
++ (dbug_dumpregs): New function.
++ (dbug_xfer_memory): New function.
++ (init_dbug_cmds): New function.
++ (dbug_open): New function.
++ (_initialize_m68hc11_rom): Register DBUG monitor.
++
++2000-12-03 Stephane Carrez <Stephane.Carrez@worldnet.fr>
++
++ * Makefile.in (m68hc11-tdep.o): Define dependencies.
++ (m68hc11-rom.o): Likewise.
++ (ALLDEPFILES): Add m68hc11-tdep.c
++ * m68hc11-rom.c: New file for 68HC11/68HC12 monitors.
++ * config/m68hc11/m68hc11.mt (TDEPFILES): Add files for monitor
++ support.
++
++2000-09-10 Stephane Carrez <Stephane.Carrez@worldnet.fr>
++
++ * monitor.c (monitor_fetch_register): Fix allocation of zerobuf
++ and regbuf (from GDB cvs main branch).
++
++2000-09-10 Stephane Carrez <Stephane.Carrez@worldnet.fr>
++
++ * monitor.c (monitor_write_memory): If setmem.resp_delim is set,
++ use a regular expression to check the write memory command.
++ (monitor_store_register): Likewise with setreg.resp_delim.
++ (monitor_open): Compile the setmem and setreg regular expressions.
++ * m68hc11-rom.c: New file for 68hc11 monitors support.
++ * config/m68hc11/m68hc11.mt (TDEPFILES): Add the monitor support.
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/bdm12.c gdb-6.4-m68hc1x/gdb/bdm12.c
+--- gdb-6.4/gdb/bdm12.c Thu Jan 1 01:00:00 1970
++++ gdb-6.4-m68hc1x/gdb/bdm12.c Sat Jan 21 15:28:49 2006
+@@ -0,0 +1,1340 @@
++/* Target communications support for Kevin Ross' BDM12 pod for the 68HC12
++ Copyright 2001
++ Free Software Foundation, Inc.
++ Contributed by Tim Housel (thousel@usa.net)
++
++ This file is part of GDB.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place - Suite 330,
++ Boston, MA 02111-1307, USA. */
++
++#include "defs.h"
++#include "gdbcore.h"
++#include "gdb_string.h"
++#include <fcntl.h>
++#include "frame.h"
++#include "inferior.h"
++#include "bfd.h"
++#include "symfile.h"
++#include "target.h"
++#include "gdbcmd.h"
++#include "objfiles.h"
++#include "gdb-stabs.h"
++#include <sys/types.h>
++#include <sys/time.h>
++#include <signal.h>
++#include "serial.h"
++#include "bdm12.h"
++#include "bdm12_eraseflash.h"
++#include "bdm12_programflash.h"
++
++#if defined(__CYGWIN32__) || defined(__MINGW32__)
++#include <windows.h>
++#include <io.h>
++#else
++/* assuming UNIX */
++#include <sys/ioctl.h>
++#endif
++
++#define xfree(ptr) free(ptr)
++
++#define BDM12_RTS_DELAY 1
++
++/* Prototypes for local functions */
++
++static int bdm12_eeprom_write (CORE_ADDR memaddr, char *buf, int len);
++
++static int bdm12_flash_write (CORE_ADDR memaddr, char *buf, int len);
++
++static int erase_flash(void);
++
++static int bdm12_put_packet (unsigned char *packet, int pktlen);
++
++static int bdm12_get_packet (unsigned char *packet, int pktlen);
++
++static void write_rts_state (int state);
++
++static int read_cts_state (void);
++
++static int valid_write_range (CORE_ADDR start_addr, CORE_ADDR end_addr);
++
++static int valid_read_range (CORE_ADDR start_addr, CORE_ADDR end_addr);
++
++static long diffms (struct timeval t1, struct timeval t2);
++
++/* serial descriptor for interface to BDM pod */
++static struct serial* ser_desc = NULL;
++
++/* since cygwin doesn't support the ioctls for manually mucking with the
++ RTS and CTS lines, we must use win32 calls. This provides a place to
++ store the windows handle */
++#if defined(__CYGWIN32__) || defined(__MINGW32__)
++static HANDLE win_ser_desc = INVALID_HANDLE_VALUE;
++#endif
++
++static unsigned char reg_page = 0;
++static unsigned int reg_base = 0;
++static unsigned int ram_base = 0;
++static unsigned int eeprom_base = 0;
++static unsigned int flash_base = 0;
++static int num_breakpoints = 0;
++static int program_loaded = 0;
++static int flash_erased = 0;
++static int stopped = 0;
++static int singlestepped = 1;
++
++static CORE_ADDR breakpoint[BDM12_MAX_BREAKPOINTS] = {0, 0};
++
++struct memory_region_list
++ {
++ CORE_ADDR addr;
++ unsigned int size;
++ unsigned char* data;
++ struct memory_region_list* next;
++ struct memory_region_list* prev;
++ } flash_regions;
++
++struct memory_region_list *cur_region = &flash_regions;
++
++/* Open a connection to a remote debugger.
++ NAME is the filename used for communication. */
++
++BDM12_RC
++bdm12_open (char **argv)
++{
++ char *ser_name;
++ unsigned char buf[5];
++ int erate, rc;
++
++ if (argv == NULL)
++ return BDM12_RC_FAIL;
++ if (argv[0] == NULL)
++ return BDM12_RC_FAIL;
++ if (argv[1] == NULL)
++ return BDM12_RC_FAIL;
++ if (argv[2] == NULL)
++ return BDM12_RC_FAIL;
++ if (argv[3] == NULL)
++ return BDM12_RC_FAIL;
++ if (argv[4] == NULL)
++ return BDM12_RC_FAIL;
++ if (argv[5] == NULL)
++ return BDM12_RC_FAIL;
++
++ ser_name = alloca (strlen (argv[0]) + 6); /* for "/dev/\0" */
++ if (!ser_name)
++ return BDM12_RC_FAIL;
++
++ strcpy (ser_name, "/dev/");
++ strcat (ser_name, argv[0]);
++ erate = atoi (argv[1]);
++ switch (erate)
++ {
++ case 1:
++ erate = BDM12_ECLOCK_1MHZ;
++ break;
++ case 2:
++ erate = BDM12_ECLOCK_2MHZ;
++ break;
++ case 4:
++ erate = BDM12_ECLOCK_4MHZ;
++ break;
++ case 8:
++ erate = BDM12_ECLOCK_8MHZ;
++ break;
++ default:
++ error ("bad value for target E clock rate - use 1, 2, 4, or 8)");
++ return BDM12_RC_FAIL;
++ break;
++ }
++
++ reg_base = strtoul (argv[2], NULL, 16);
++ if (reg_base & 0x7ff)
++ {
++ error ("bad value for target register base - should be on 2K boundary");
++ return BDM12_RC_FAIL;
++ }
++
++ ram_base = strtoul (argv[3], NULL, 16);
++ if (ram_base & 0x7ff)
++ {
++ error ("bad value for target RAM base - should be on 2K boundary");
++ return BDM12_RC_FAIL;
++ }
++
++ eeprom_base = strtoul (argv[4], NULL, 16);
++ if ((eeprom_base & 0x2ff) || !((eeprom_base & 0xfff) | 0xd00))
++ {
++ error ("bad value for target EEPROM base - should be on 4K boundary + 0xd00");
++ return BDM12_RC_FAIL;
++ }
++
++ flash_base = strtoul (argv[5], NULL, 16);
++ if (flash_base & 0x7fff)
++ {
++ error ("bad value for target FLASH base - should be on 32K boundary");
++ return BDM12_RC_FAIL;
++ }
++
++ reg_page = reg_base >> 8;
++
++ ser_desc = serial_open (ser_name);
++ if (!ser_desc)
++ {
++ error ("unable to open serial port");
++ return BDM12_RC_FAIL;
++ }
++
++#if defined(__CYGWIN32__)
++ win_ser_desc = (HANDLE) get_osfhandle (ser_desc->fd);
++#elif defined(__MINGW32__)
++ win_ser_desc = (HANDLE) ser_desc->fd;
++#endif
++
++ if (!ser_desc)
++ {
++ perror_with_name (ser_name);
++ return BDM12_RC_FAIL;
++ }
++
++ if (serial_setbaudrate (ser_desc, BDM12_BAUD_RATE))
++ {
++ serial_close (ser_desc);
++ perror_with_name (ser_name);
++ return BDM12_RC_FAIL;
++ }
++
++ serial_raw (ser_desc);
++
++ /* If there is something sitting in the buffer we might take it as a
++ response to a command, which would be bad. */
++ serial_flush_input (ser_desc);
++
++ rc = 0;
++
++ /* synchronize the pod */
++ buf[0] = BDM12_CMD_SYNC;
++ rc = bdm12_put_packet (buf, 1);
++ /* if the first command doesn't work, bail */
++ if (rc)
++ return BDM12_RC_FAIL;
++
++ /* now just collect the errors for the next set of commands */
++
++ /* set the target parameters */
++ buf[0] = BDM12_CMD_EXT;
++ buf[1] = BDM12_CMD_EXT_SETPARAM;
++ buf[2] = erate;
++ buf[3] = 0; /* We don't need no steekin' delays, I hope ;-) */
++ buf[4] = 0;
++ rc += bdm12_put_packet (buf, 5);
++
++ /* reset the target */
++ buf[0] = BDM12_CMD_RESET;
++ rc += bdm12_put_packet (buf, 1);
++
++ /* make sure BDM is enabled */
++ buf[0] = BDM12_CMD_WRITE_BD_BYTE;
++ buf[1] = BDM12_BDM_HI;
++ buf[2] = BDM12_ENABLE_BDM_LO;
++ buf[3] = BDM12_INIT_ENABLE_BDM;
++ buf[4] = buf[3];
++ rc += bdm12_put_packet (buf, 5);
++
++ /* map the registers */
++ buf[0] = BDM12_CMD_WRITE_BYTE;
++ buf[1] = 0;
++ buf[2] = BDM12_REG_INITRG;
++ buf[3] = reg_page;
++ buf[4] = buf[3];
++ rc += bdm12_put_packet (buf, 5);
++
++ /* Let the POD know where we've mapped the registers */
++ buf[0] = BDM12_CMD_SET_REGBASE;
++ buf[1] = reg_page;
++ rc += bdm12_put_packet (buf, 2);
++
++ /* map RAM */
++ buf[0] = BDM12_CMD_WRITE_BYTE;
++ buf[2] = BDM12_REG_INITRM;
++ buf[3] = ram_base >> 8;
++ buf[4] = buf[3];
++ rc += bdm12_put_packet (buf, 5);
++
++ /* map EEPROM */
++ buf[2] = BDM12_REG_INITEE;
++ buf[3] = ((eeprom_base >> 8) & 0xf0) | 0x1;
++ buf[4] = buf[3];
++ rc += bdm12_put_packet (buf, 5);
++
++ /* map FLASH */
++ buf[2] = BDM12_REG_MISC;
++ buf[3] = 0x0d | (flash_base >> 14);
++ buf[4] = buf[3];
++ rc += bdm12_put_packet (buf, 5);
++
++ /* setup breakpoints */
++ buf[2] = BDM12_REG_BRKCT0;
++ buf[3] = BDM12_INIT_BRKCT0;
++ buf[4] = buf[3];
++ rc += bdm12_put_packet (buf, 5);
++
++ /* setup breakpoints */
++ buf[2] = BDM12_REG_BRKCT1;
++ buf[3] = BDM12_INIT_BRKCT1;
++ buf[4] = buf[3];
++ rc += bdm12_put_packet (buf, 5);
++
++ /* disable flash protection */
++ buf[2] = BDM12_REG_FEEMCR;
++ buf[3] = BDM12_INIT_FEEMCR;
++ buf[4] = buf[3];
++ rc += bdm12_put_packet (buf, 5);
++
++ if (rc)
++ return BDM12_RC_FAIL;
++
++ serial_flush_input (ser_desc);
++ return BDM12_RC_OK;
++}
++
++/* Clean up connection to a remote debugger. */
++
++void
++bdm12_close (int quitting)
++{
++ if (ser_desc)
++ serial_close (ser_desc);
++ ser_desc = NULL;
++#if defined(__CYGWIN32__) || defined(__MINGW32__)
++ win_ser_desc = INVALID_HANDLE_VALUE;
++#endif
++ program_loaded = 0;
++ flash_erased = 0;
++ stopped = 0;
++
++ while (cur_region->prev != NULL)
++ {
++ if (cur_region->data)
++ xfree(cur_region->data);
++ if (cur_region->next)
++ xfree(cur_region->next);
++
++ cur_region = cur_region->prev;
++ }
++}
++
++/* Init processor state - for us just set the PC to _start from the bfd */
++BDM12_RC
++bdm12_create_inferior (bfd *abfd, char **argv, char **env)
++{
++ CORE_ADDR start = bfd_get_start_address (abfd);
++ unsigned char cmdbuf[2];
++
++ /* set the PC */
++ cmdbuf[0] = start >> 8;
++ cmdbuf[1] = start;
++ return (bdm12_store_register (HARD_PC_REGNUM, cmdbuf, 2) != 2);
++}
++
++/* Tell the remote machine to resume. */
++
++int
++bdm12_resume (int step)
++{
++ unsigned char buf;
++ int rc;
++
++ if (step)
++ {
++ buf = BDM12_CMD_TRACE1;
++ singlestepped = 1;
++ }
++ else
++ {
++ buf = BDM12_CMD_GO;
++ singlestepped = 0;
++ }
++
++ if (!(rc = bdm12_put_packet (&buf, 1)))
++ stopped = 0;
++ return rc;
++}
++
++int
++bdm12_stop (void)
++{
++ BDM12_RC rc;
++ unsigned char buf = BDM12_CMD_BACKGROUND;
++
++ rc = bdm12_put_packet (&buf, 1);
++ if (rc == BDM12_RC_OK)
++ stopped = 1;
++ return !rc;
++}
++
++/* Read register */
++
++int
++bdm12_fetch_register (int regno, unsigned char* buf, int length)
++{
++ unsigned char cmdbuf[3];
++ int rc;
++
++ switch (regno)
++ {
++ case HARD_A_REGNUM:
++ case HARD_B_REGNUM:
++ case HARD_D_REGNUM:
++ cmdbuf[0] = BDM12_CMD_READ_D;
++ break;
++ case HARD_X_REGNUM:
++ cmdbuf[0] = BDM12_CMD_READ_X;
++ break;
++ case HARD_Y_REGNUM:
++ cmdbuf[0] = BDM12_CMD_READ_Y;
++ break;
++ case HARD_SP_REGNUM:
++ cmdbuf[0] = BDM12_CMD_READ_SP;
++ break;
++ case HARD_PC_REGNUM:
++ cmdbuf[0] = BDM12_CMD_READ_PC;
++ break;
++ case HARD_PSW_REGNUM:
++ cmdbuf[0] = BDM12_CMD_READ_BD_BYTE;
++ cmdbuf[1] = BDM12_BDM_HI;
++ cmdbuf[2] = BDM12_CCRSAV_BDM_LO;
++ break;
++ default:
++ return 0;
++ }
++
++ if (regno == HARD_PSW_REGNUM)
++ rc = bdm12_put_packet (cmdbuf, 3);
++ else
++ rc = bdm12_put_packet (cmdbuf, 1);
++
++ if (rc)
++ return 0;
++
++ rc = bdm12_get_packet (cmdbuf, 2);
++ if (rc)
++ return 0;
++
++ switch (regno)
++ {
++ case HARD_A_REGNUM:
++ case HARD_PSW_REGNUM:
++ buf[0] = 0;
++ buf[1] = cmdbuf[0];
++ break;
++ case HARD_B_REGNUM:
++ buf[0] = 0;
++ buf[1] = cmdbuf[1];
++ break;
++ default:
++ buf[0] = cmdbuf[0];
++ buf[1] = cmdbuf[1];
++ break;
++ }
++
++ return length;
++}
++
++/* Write register */
++
++int
++bdm12_store_register (int regno, unsigned char* buf, int length)
++{
++ unsigned char cmdbuf[5];
++ int rc = 0;
++
++ switch (regno)
++ {
++ case HARD_A_REGNUM:
++ cmdbuf[0] = BDM12_CMD_READ_D;
++ rc += bdm12_put_packet (cmdbuf, 1);
++ rc += bdm12_get_packet (cmdbuf, 2);
++ cmdbuf[2] = cmdbuf[1];
++ cmdbuf[1] = buf[0];
++ cmdbuf[0] = BDM12_CMD_WRITE_D;
++ break;
++ case HARD_B_REGNUM:
++ cmdbuf[0] = BDM12_CMD_READ_D;
++ rc += bdm12_put_packet (cmdbuf, 1);
++ rc += bdm12_get_packet (cmdbuf, 2);
++ cmdbuf[2] = buf[1];
++ cmdbuf[1] = cmdbuf[0];
++ cmdbuf[0] = BDM12_CMD_WRITE_D;
++ break;
++ case HARD_D_REGNUM:
++ cmdbuf[0] = BDM12_CMD_WRITE_D;
++ cmdbuf[1] = buf[0];
++ cmdbuf[2] = buf[1];
++ break;
++ case HARD_X_REGNUM:
++ cmdbuf[0] = BDM12_CMD_WRITE_X;
++ cmdbuf[1] = buf[0];
++ cmdbuf[2] = buf[1];
++ break;
++ case HARD_Y_REGNUM:
++ cmdbuf[0] = BDM12_CMD_WRITE_Y;
++ cmdbuf[1] = buf[0];
++ cmdbuf[2] = buf[1];
++ break;
++ case HARD_SP_REGNUM:
++ cmdbuf[0] = BDM12_CMD_WRITE_SP;
++ cmdbuf[1] = buf[0];
++ cmdbuf[2] = buf[1];
++ break;
++ case HARD_PC_REGNUM:
++ cmdbuf[0] = BDM12_CMD_WRITE_PC;
++ cmdbuf[1] = buf[0];
++ cmdbuf[2] = buf[1];
++ break;
++ case HARD_PSW_REGNUM:
++ cmdbuf[0] = BDM12_CMD_WRITE_BD_BYTE;
++ cmdbuf[1] = BDM12_BDM_HI;
++ cmdbuf[2] = BDM12_CCRSAV_BDM_LO;
++ cmdbuf[3] = buf[1];
++ cmdbuf[4] = buf[1];
++ break;
++ default:
++ return 0;
++ }
++
++ if (regno == HARD_PSW_REGNUM)
++ rc += bdm12_put_packet (cmdbuf, 5);
++ else
++ rc += bdm12_put_packet (cmdbuf, 3);
++
++ if (rc)
++ return 0;
++
++ return length;
++}
++
++/* Write memory to the target. */
++
++int
++bdm12_write (CORE_ADDR memaddr, unsigned char *buf, int len)
++{
++ unsigned char *cmdbuf;
++ unsigned int numwritten = 0;
++ int need_final_write = 0;
++
++ /* allow writes to flash and eeprom if the program isn't loaded yet */
++ if (!program_loaded && !valid_write_range (memaddr, memaddr + len - 1))
++ {
++ if (!valid_read_range (memaddr, memaddr + len - 1) || len <= 0)
++ return 0;
++ if (memaddr >= eeprom_base &&
++ memaddr < (eeprom_base + BDM12_SIZE_EEPROM) &&
++ (memaddr + len - 1) >= eeprom_base &&
++ (memaddr + len - 1) < (eeprom_base + BDM12_SIZE_EEPROM))
++ return bdm12_eeprom_write (memaddr, buf, len);
++ else if (memaddr >= flash_base &&
++ memaddr < (flash_base + BDM12_SIZE_FLASH) &&
++ (memaddr + len - 1) >= flash_base &&
++ (memaddr + len - 1) < (flash_base + BDM12_SIZE_FLASH))
++ return bdm12_flash_write (memaddr, buf, len);
++ else
++ {
++ error ("writing between different regions of memory");
++ return 0;
++ }
++ }
++ else if (!valid_write_range (memaddr, memaddr + len - 1) || len <= 0)
++ return 0;
++
++ cmdbuf = alloca (len + 6);
++ if (!cmdbuf)
++ return 0;
++
++ if (memaddr & 0x1)
++ {
++ cmdbuf[0] = BDM12_CMD_WRITE_BYTE;
++ cmdbuf[1] = memaddr >> 8;
++ cmdbuf[2] = memaddr;
++ cmdbuf[3] = *buf;
++ cmdbuf[4] = cmdbuf[3];
++ if (bdm12_put_packet (cmdbuf, 5))
++ return numwritten;
++ len--;
++ buf++;
++ numwritten++;
++ memaddr++;
++ }
++
++ if (len & 0x1)
++ {
++ need_final_write = 1;
++ len--;
++ }
++#if 0 /* MEMPUT command seems to cause communications hangups easily */
++ if (len)
++ {
++ cmdbuf[0] = BDM12_CMD_EXT;
++ cmdbuf[1] = BDM12_CMD_EXT_MEMPUT;
++ cmdbuf[2] = memaddr >> 8;
++ cmdbuf[3] = memaddr ;
++ cmdbuf[4] = (len / 2) >> 8;
++ cmdbuf[5] = (len / 2);
++ memcpy (cmdbuf + 6, buf, len);
++ if (bdm12_put_packet (cmdbuf, len + 6))
++ return numwritten;
++ buf += len;
++ numwritten += len;
++ memaddr += len;
++ }
++#endif
++
++#if 1
++
++ cmdbuf[0] = BDM12_CMD_WRITE_WORD;
++ while (len)
++ {
++ cmdbuf[1] = memaddr >> 8;
++ cmdbuf[2] = memaddr;
++ cmdbuf[3] = *(buf++);
++ cmdbuf[4] = *(buf++);
++ if (bdm12_put_packet (cmdbuf, 5))
++ return numwritten;
++ memaddr += 2;
++ numwritten += 2;
++ len -= 2;
++ }
++
++#endif
++
++ if (need_final_write)
++ {
++ cmdbuf[0] = BDM12_CMD_WRITE_BYTE;
++ cmdbuf[1] = memaddr >> 8;
++ cmdbuf[2] = memaddr;
++ cmdbuf[3] = *buf;
++ cmdbuf[4] = cmdbuf[3];
++ if (bdm12_put_packet (cmdbuf, 5))
++ return numwritten;
++ numwritten++;
++ }
++
++ return numwritten;
++}
++
++static int
++bdm12_eeprom_write (CORE_ADDR memaddr, char *buf, int len)
++{
++ unsigned char cmdbuf[6], recvbuf[2];
++ int numwritten = 0, need_final_write = 0;
++
++ if (memaddr & 0x1)
++ {
++ cmdbuf[0] = BDM12_CMD_READ_BYTE;
++ cmdbuf[1] = (memaddr - 1) >> 8;
++ cmdbuf[2] = (memaddr - 1);
++ if (bdm12_put_packet (cmdbuf, 3))
++ return numwritten;
++ if (bdm12_get_packet (recvbuf, 2))
++ return numwritten;
++ cmdbuf[0] = BDM12_CMD_EEPROM_WRITE;
++ cmdbuf[3] = recvbuf[0];
++ cmdbuf[4] = *buf;
++ if (bdm12_put_packet (cmdbuf, 5))
++ return numwritten;
++ len--;
++ buf++;
++ numwritten++;
++ memaddr++;
++ }
++
++ if (len & 0x1)
++ {
++ need_final_write = 1;
++ len--;
++ }
++
++ while (len)
++ {
++ cmdbuf[1] = memaddr >> 8;
++ cmdbuf[2] = memaddr;
++ cmdbuf[3] = *(buf++);
++ cmdbuf[4] = *(buf++);
++ if (bdm12_put_packet (cmdbuf, 5))
++ return numwritten;
++ memaddr += 2;
++ numwritten += 2;
++ len -= 2;
++ }
++
++ if (need_final_write)
++ {
++ cmdbuf[0] = BDM12_CMD_READ_BYTE;
++ cmdbuf[1] = (memaddr + 1) >> 8;
++ cmdbuf[2] = (memaddr + 1);
++ if (bdm12_put_packet (cmdbuf, 3))
++ return numwritten;
++ if (bdm12_get_packet (recvbuf, 2))
++ return numwritten;
++ cmdbuf[0] = BDM12_CMD_EEPROM_WRITE;
++ cmdbuf[3] = *buf;
++ cmdbuf[4] = recvbuf[1];
++ if (bdm12_put_packet (cmdbuf, 5))
++ return numwritten;
++ numwritten++;
++ }
++ return numwritten;
++}
++
++static int
++bdm12_flash_write (CORE_ADDR memaddr, char *buf, int len)
++{
++ unsigned char cmdbuf[2];
++ int numwritten = 0, dum, expectedsize, actualsize;
++ int packetsize = BDM12_SIZE_RAM - BDM12_PROGRAMFLASH_SIZE;
++
++ struct timeval start_time, cur_time;
++ enum bdm12_stop reason;
++
++ if (!flash_erased)
++ {
++ /* check to see if what is going to be written is the same as
++ what is already in flash, so that we don't write to flash
++ needlessly */
++ cur_region->next = xmalloc (sizeof (struct memory_region_list));
++ if (!cur_region->next)
++ return numwritten;
++ cur_region->data = xmalloc (len);
++ if (!cur_region->data)
++ {
++ xfree (cur_region->next);
++ cur_region->next = NULL;
++ return numwritten;
++ }
++ if (bdm12_read (memaddr, cur_region->data, len) != len)
++ {
++ xfree (cur_region->next);
++ xfree (cur_region->data);
++ cur_region->next = NULL;
++ cur_region->data = NULL;
++ return numwritten;
++ }
++ if (memcmp (cur_region->data, buf, len) == 0)
++ {
++ cur_region->size = len;
++ cur_region->addr = memaddr;
++ cur_region->next->prev = cur_region;
++ cur_region->next->next = NULL;
++ cur_region->next->size = 0;
++ cur_region->next->data = NULL;
++ cur_region = cur_region->next;
++ return len;
++ }
++
++ xfree(cur_region->next);
++ cur_region->next = NULL;
++
++ /* erase the flash array */
++ if (erase_flash ())
++ {
++ error ("Unable to erase flash");
++ return numwritten;
++ }
++ flash_erased = 1;
++ /* write the flash burning program into RAM - the program is in
++ bdm12_programflash.h */
++ if (bdm12_write (ram_base, programflash, BDM12_PROGRAMFLASH_SIZE) !=
++ BDM12_PROGRAMFLASH_SIZE)
++ return numwritten;
++ /* tell the burn program where the registers are */
++ cmdbuf[0] = reg_base >> 8;
++ cmdbuf[1] = reg_base;
++ if (bdm12_write (ram_base + BDM12_PROGRAMFLASH_REGSTART, cmdbuf, 2) != 2)
++ return numwritten;
++ /* tell the burn program where the data starts */
++ cmdbuf[0] = (ram_base + BDM12_PROGRAMFLASH_SIZE) >> 8;
++ cmdbuf[1] = (ram_base + BDM12_PROGRAMFLASH_SIZE);
++ if (bdm12_write (ram_base + BDM12_PROGRAMFLASH_DATASTART, cmdbuf, 2) != 2)
++ return numwritten;
++
++ /* now write all the previously stored regions */
++ for (cur_region = &flash_regions; cur_region->next != NULL;
++ cur_region = cur_region->next)
++ {
++ if (bdm12_flash_write (cur_region->addr, cur_region->data,
++ cur_region->size) != cur_region->size)
++ return numwritten;
++ }
++ }
++
++ /* tell the burn program where flash is */
++ while (len > 0)
++ {
++ if (len < packetsize)
++ expectedsize = len;
++ else
++ expectedsize = packetsize;
++
++ /* write the next packet in target RAM */
++ if (bdm12_write (ram_base + BDM12_PROGRAMFLASH_SIZE, buf,
++ expectedsize) != expectedsize)
++ break;
++
++ /* tell the burn program the starting flash address */
++ cmdbuf[0] = memaddr >> 8;
++ cmdbuf[1] = memaddr;
++ if (bdm12_write (ram_base + BDM12_PROGRAMFLASH_FLASHSTART, cmdbuf, 2) != 2)
++ break;
++
++ /* tell the burn program the ending flash address (noninclusive) */
++ cmdbuf[0] = (memaddr + expectedsize) >> 8;
++ cmdbuf[1] = (memaddr + expectedsize);
++ if (bdm12_write (ram_base + BDM12_PROGRAMFLASH_FLASHEND, cmdbuf, 2) != 2)
++ break;
++
++ /* set the PC */
++ cmdbuf[0] = (ram_base + BDM12_PROGRAMFLASH_PROGSTART) >> 8;
++ cmdbuf[1] = (ram_base + BDM12_PROGRAMFLASH_PROGSTART);
++ if (bdm12_store_register (HARD_PC_REGNUM, cmdbuf, 2) != 2)
++ break;
++
++ /* run the burn program */
++ if (bdm12_resume (0))
++ break;
++
++ /* wait for burn program t finish; it should go back into bdm mode */
++ gettimeofday (&start_time, NULL);
++ do
++ {
++ bdm12_stop_reason (&reason, &dum);
++ gettimeofday (&cur_time, NULL);
++ if (diffms (start_time, cur_time) > BDM12_PROGRAMFLASH_TIMEOUT *
++ expectedsize)
++ {
++ bdm12_stop_reason (&reason, &dum);
++ if (reason == BDM12_RUNNING)
++ break;
++ }
++ } while (reason == BDM12_RUNNING);
++ /* check error flag */
++ if (bdm12_read (ram_base + BDM12_PROGRAMFLASH_NUMWRITTEN, cmdbuf, 2) != 2)
++ break;
++
++ actualsize = (cmdbuf[0] << 8) + cmdbuf[1];
++ numwritten += actualsize;
++ if (expectedsize != actualsize)
++ break;
++ memaddr += actualsize;
++ buf += actualsize;
++ len -= actualsize;
++ }
++ return numwritten;
++}
++
++static int
++erase_flash(void)
++{
++ unsigned char buf[2];
++ struct timeval start_time, cur_time;
++ int dum;
++ enum bdm12_stop reason;
++
++ /* write the erase program into RAM - the program is in bdm12_eraseflash.h */
++ if (bdm12_write (ram_base, eraseflash, BDM12_ERASEFLASH_SIZE) !=
++ BDM12_ERASEFLASH_SIZE)
++ return 1;
++
++ /* tell the erase program where flash is */
++ buf[0] = flash_base >> 8;
++ buf[1] = flash_base;
++ if (bdm12_write (ram_base + BDM12_ERASEFLASH_FLASHSTART, buf, 2) != 2)
++ return 1;
++
++ /* tell the erase program where the registers are */
++ buf[0] = reg_base >> 8;
++ buf[1] = reg_base;
++ if (bdm12_write (ram_base + BDM12_ERASEFLASH_REGSTART, buf, 2) != 2)
++ return 1;
++
++ /* set the PC */
++ buf[0] = (ram_base + BDM12_ERASEFLASH_PROGSTART) >> 8;
++ buf[1] = (ram_base + BDM12_ERASEFLASH_PROGSTART);
++ if (bdm12_store_register (HARD_PC_REGNUM, buf, 2) != 2)
++ return 1;
++
++ /* run the erase program */
++ if (bdm12_resume (0))
++ return 1;
++ /* wait for erase program to finish; it should go back into bdm mode */
++
++ gettimeofday (&start_time, NULL);
++ do
++ {
++ bdm12_stop_reason (&reason, &dum);
++ gettimeofday (&cur_time, NULL);
++ if (diffms (start_time, cur_time) > BDM12_ERASEFLASH_TIMEOUT)
++ {
++ bdm12_stop_reason (&reason, &dum);
++ if (reason == BDM12_RUNNING)
++ return 1;
++ }
++ } while (reason == BDM12_RUNNING);
++
++ /* check error flag */
++ if (bdm12_read (ram_base + BDM12_ERASEFLASH_ERRORFLAG, buf, 1) != 1)
++ return 1;
++
++ return buf[0];
++}
++
++void
++bdm12_stop_reason (enum bdm12_stop *reason, int *sigrc)
++{
++ unsigned char buf[3];
++
++ buf[0] = BDM12_CMD_READ_BD_BYTE;
++ buf[1] = BDM12_BDM_HI;
++ buf[2] = BDM12_ENABLE_BDM_LO;
++ if (bdm12_put_packet (buf, 3))
++ {
++ *reason = BDM12_POLLING;
++ return;
++ }
++ if (bdm12_get_packet (buf, 2))
++ {
++ *reason = BDM12_POLLING;
++ return;
++ }
++
++ if (!(buf[1] & BDM12_STATUS_STOPPED))
++ {
++ *reason = BDM12_RUNNING;
++ return;
++ }
++ if (num_breakpoints > 0)
++ {
++ unsigned char pcbuf[2];
++ CORE_ADDR pc;
++ if (bdm12_fetch_register (HARD_PC_REGNUM, pcbuf, 2) != 2)
++ {
++ *reason = BDM12_POLLING;
++ return;
++ }
++ pc = (pcbuf[0] << 8) + pcbuf[1];
++ if (pc == breakpoint[0])
++ {
++ *reason = BDM12_STOPPED;
++ *sigrc = TARGET_SIGNAL_TRAP;
++ return;
++ }
++ if ((num_breakpoints == 2) && (pc == breakpoint[1]))
++ {
++ *reason = BDM12_STOPPED;
++ *sigrc = TARGET_SIGNAL_TRAP;
++ return;
++ }
++ }
++
++ if (stopped)
++ {
++ *reason = BDM12_STOPPED;
++ *sigrc = TARGET_SIGNAL_INT;
++ return;
++ }
++ if (singlestepped)
++ {
++ *reason = BDM12_STOPPED;
++ *sigrc = TARGET_SIGNAL_TRAP;
++ return;
++ }
++
++ /* don't know why we stopped */
++ *reason = BDM12_POLLING;
++ return;
++}
++
++static int
++valid_write_range (CORE_ADDR start_addr, CORE_ADDR end_addr)
++{
++ if (((start_addr >= reg_base && start_addr < (reg_base + BDM12_SIZE_REG)) &&
++ (end_addr >= reg_base && end_addr < (reg_base + BDM12_SIZE_RAM))) ||
++ ((start_addr >= ram_base && start_addr < (ram_base + BDM12_SIZE_RAM)) &&
++ (end_addr >= ram_base && end_addr < (ram_base + BDM12_SIZE_RAM))))
++ return 1;
++
++ return 0;
++}
++
++/* Read memory from the target. */
++
++int
++bdm12_read (CORE_ADDR memaddr, unsigned char *buf, int len)
++{
++ unsigned char cmdbuf[6], *recvbuf;
++ unsigned int numread = 0;
++ int need_final_read = 0;
++
++ if (!valid_read_range (memaddr, memaddr + len - 1) || len < 0)
++ return 0;
++
++ if (len == 0)
++ return 0;
++
++ recvbuf = alloca (len);
++ if (!recvbuf)
++ return 0;
++
++ if (memaddr & 0x1)
++ {
++ cmdbuf[0] = BDM12_CMD_READ_BYTE;
++ cmdbuf[1] = memaddr >> 8;
++ cmdbuf[2] = memaddr;
++ if (bdm12_put_packet (cmdbuf, 3))
++ return numread;
++ if (bdm12_get_packet (recvbuf, 2))
++ return numread;
++ *(buf++) = recvbuf[1];
++ len--;
++ numread++;
++ memaddr++;
++ }
++
++ if (len & 0x1)
++ {
++ need_final_read = 1;
++ len--;
++ }
++
++ if (len)
++ {
++ cmdbuf[0] = BDM12_CMD_EXT;
++ cmdbuf[1] = BDM12_CMD_EXT_MEMDUMP;
++ cmdbuf[2] = memaddr >> 8;
++ cmdbuf[3] = memaddr ;
++ cmdbuf[4] = (len / 2) >> 8;
++ cmdbuf[5] = (len / 2);
++ if (bdm12_put_packet (cmdbuf, 6))
++ return numread;
++ if (bdm12_get_packet (recvbuf, len))
++ return numread;
++ memcpy (buf, recvbuf, len);
++ buf += len;
++ numread += len;
++ memaddr += len;
++ }
++
++ if (need_final_read)
++ {
++ cmdbuf[0] = BDM12_CMD_READ_BYTE;
++ cmdbuf[1] = memaddr >> 8;
++ cmdbuf[2] = memaddr;
++ if (bdm12_put_packet (cmdbuf, 3))
++ return numread;
++ if (bdm12_get_packet (recvbuf, 2))
++ return numread;
++ *(buf++) = recvbuf[0];
++ numread++;
++ }
++
++ return numread;
++}
++
++static int
++valid_read_range (CORE_ADDR start_addr, CORE_ADDR end_addr)
++{
++ if (((start_addr >= reg_base && start_addr < (reg_base + BDM12_SIZE_REG)) &&
++ (end_addr >= reg_base && end_addr < (reg_base + BDM12_SIZE_REG))) ||
++ ((start_addr >= ram_base && start_addr < (ram_base + BDM12_SIZE_RAM)) &&
++ (end_addr >= ram_base && end_addr < (ram_base + BDM12_SIZE_RAM))) ||
++ ((start_addr >= eeprom_base && start_addr < (eeprom_base + BDM12_SIZE_EEPROM)) &&
++ (end_addr >= eeprom_base && end_addr < (eeprom_base + BDM12_SIZE_EEPROM))) ||
++ ((start_addr >= flash_base && start_addr < (flash_base + BDM12_SIZE_FLASH)) &&
++ (end_addr >= flash_base && end_addr < (flash_base + BDM12_SIZE_FLASH))))
++ return 1;
++
++ return 0;
++}
++
++/* Send a packet to the BDM12 pod. This is basically copied from Kevin's
++ BDM12 User Manual */
++
++static int
++bdm12_put_packet (unsigned char *packet, int len)
++{
++ int i, iloop;
++ struct timeval start_time, cur_time;
++
++ for (i = 0; i < len; i++)
++ {
++ write_rts_state (1);
++
++ iloop = 5;
++ gettimeofday (&start_time, NULL);
++ cur_time = start_time;
++ while ((diffms (start_time, cur_time) < BDM12_COMM_TIMEOUT) || iloop)
++ {
++ if (read_cts_state ())
++ break;
++
++ write_rts_state (0);
++ gettimeofday (&cur_time, NULL);
++ if (iloop)
++ --iloop;
++
++ write_rts_state (1);
++ }
++ if (!read_cts_state ())
++ {
++ error ("bdm12_put_packet RTS1->CTS1: Couldn't communicate with BDM12 pod");
++ return 1;
++ }
++
++ if (serial_write (ser_desc, packet, 1))
++ {
++ write_rts_state (0);
++ perror_with_name ("bdm12_put_packet");
++ return 1;
++ }
++
++ iloop = 5;
++ gettimeofday (&start_time, NULL);
++ cur_time = start_time;
++ while ((diffms (start_time, cur_time) < BDM12_COMM_TIMEOUT) || iloop)
++ {
++ if (!read_cts_state ())
++ break;
++
++ gettimeofday (&cur_time, NULL);
++ if (iloop)
++ --iloop;
++
++ }
++ write_rts_state (0);
++ if (read_cts_state ())
++ {
++ error ("bdm12_put_packet RTS0->CTS0: Couldn't communicate with BDM12 pod");
++ return 1;
++ }
++ packet++;
++ }
++ return 0;
++}
++
++/* Raise or lower the RTS line (clear if state==0, set otherwise). This is
++ also based on code from Kevin's BDM12 User's Manual. */
++
++static void
++write_rts_state (int state)
++{
++
++#if defined(__CYGWIN32__) || defined(__MINGW32__)
++ EscapeCommFunction (win_ser_desc, state ? SETRTS : CLRRTS);
++#else
++ struct timeval start_time, cur_time;
++
++ int tiocm = TIOCM_RTS;
++ ioctl (ser_desc->fd, state ? TIOCMBIS : TIOCMBIC, &tiocm);
++
++ gettimeofday (&start_time, NULL);
++ cur_time = start_time;
++ while ((diffms (start_time, cur_time) < BDM12_RTS_DELAY))
++ {
++ gettimeofday (&cur_time, NULL);
++ }
++#endif
++}
++
++/* Return the state of the CTS line (0 if clear, 1 if set). This is also
++ based on code from Kevin's BDM12 User's Manual. */
++
++static int
++read_cts_state (void)
++{
++#if defined(__CYGWIN32__) || defined(__MINGW32__)
++ DWORD cts_state;
++ GetCommModemStatus (win_ser_desc, &cts_state);
++ return (cts_state & MS_CTS_ON) ? 1 : 0;
++#else
++ /* assuming UNIX - if not, add your own #elseif above */
++ unsigned int cts_state;
++ ioctl (ser_desc->fd, TIOCMGET, &cts_state);
++ return (cts_state & TIOCM_CTS) ? 1 : 0;
++#endif
++}
++
++/* take the difference of t2 - t1 in milliseconds */
++
++static long
++diffms (struct timeval t1, struct timeval t2)
++{
++ long diffsec, diffusec;
++
++ diffsec = t2.tv_sec - t1.tv_sec;
++ diffusec = t2.tv_usec - t1.tv_usec;
++
++ if (diffusec < 0)
++ {
++ diffsec--;
++ diffusec += 1000000;
++ }
++
++ return (diffsec * 1000) + (diffusec / 1000);
++}
++
++/* Get a packet from the BDM12. Timeout is only enforced for the
++ first byte of the packet. Subsequent bytes are expected to arrive in
++ time <= remote_timeout. Returns a pointer to a static buffer containing
++ the payload of the packet. *LENP contains the length of the packet.
++ */
++
++static int bdm12_get_packet (unsigned char *packet, int pktlen)
++{
++ int i, ch;
++
++ for (i = 0; i < pktlen; i++)
++ {
++ ch = serial_readchar (ser_desc, BDM12_COMM_TIMEOUT);
++ switch (ch)
++ {
++ case SERIAL_EOF:
++ error ("Remote connection closed");
++ return 1;
++ break;
++ case SERIAL_ERROR:
++ perror_with_name ("bdm12_get_packet");
++ return 1;
++ break;
++ case SERIAL_TIMEOUT:
++ error ("Remote connection timed out");
++ return 1;
++ break;
++ default:
++ *(packet++) = ch;
++ break;
++ }
++ }
++ return 0;
++}
++
++/* All we actually do is set the PC to the start address of exec_bfd, and start
++ the program at that point. */
++
++/* load a program into target memory, the bfd struct is not used here */
++
++BDM12_RC
++bdm12_load (char *prog, struct _bfd *abfd, int from_tty)
++{
++ generic_load (prog, from_tty);
++
++ program_loaded = 1;
++/* This is necessary because many things were based on the PC at the time that
++ we attached to the monitor, which is no longer valid now that we have loaded
++ new code (and just changed the PC). Another way to do this might be to call
++ normal_stop, except that the stack may not be valid, and things would get
++ horribly confused... */
++
++ clear_symtab_users ();
++ return BDM12_RC_OK;
++}
++
++BDM12_RC
++bdm12_set_breakpoint (CORE_ADDR addr)
++{
++ unsigned char buf[5];
++
++ if (num_breakpoints >= BDM12_MAX_BREAKPOINTS)
++ {
++ error ("Maximum breakpoints have already been set");
++ return BDM12_RC_INSUFFICIENT_RESOURCES;
++ }
++
++ if (num_breakpoints == 0)
++ buf[2] = BDM12_REG_BRKAH;
++ else
++ buf[2] = BDM12_REG_BRKDH;
++
++ buf[0] = BDM12_CMD_WRITE_WORD;
++ buf[1] = reg_page;
++ buf[3] = addr >> 8;
++ buf[4] = addr;
++ if (bdm12_put_packet (buf, 5))
++ return BDM12_RC_FAIL;
++ breakpoint[num_breakpoints] = addr;
++ num_breakpoints++;
++ return BDM12_RC_OK;
++}
++
++BDM12_RC
++bdm12_clear_breakpoint (CORE_ADDR addr)
++{
++ unsigned char buf[5];
++ if (breakpoint[0] == addr)
++ {
++ buf[2] = BDM12_REG_BRKAH;
++ breakpoint[0] = 0;
++ }
++ else if (breakpoint[1] == addr)
++ {
++ buf[2] = BDM12_REG_BRKDH;
++ breakpoint[1] = 0;
++ }
++ else
++ {
++ error ("breakpoint doesn't exist");
++ return BDM12_RC_UNKNOWN_BREAKPOINT;
++ }
++
++ buf[0] = BDM12_CMD_WRITE_WORD;
++ buf[1] = reg_page;
++ buf[3] = 0;
++ buf[4] = 0;
++ if (bdm12_put_packet (buf, 5))
++ return BDM12_RC_FAIL;
++
++ num_breakpoints--;
++ return BDM12_RC_OK;
++}
++
++
++void
++_initialize_bdm12 (void)
++{
++ flash_regions.next = NULL;
++ flash_regions.prev = NULL;
++ flash_regions.data = NULL;
++ flash_regions.size = 0;
++}
++
++#if 0
++/* maybe I should do something like this - later*/
++void _initialize_remote_ocd (void)
++{
++ extern struct cmd_list_element *cmdlist;
++ static struct cmd_list_element *ocd_cmd_list = NULL;
++
++ add_show_from_set (add_set_cmd ("remotetimeout", no_class,
++ var_integer, (char *) &remote_timeout,
++ "Set timeout value for remote read.\n", &setlist),
++ &showlist);
++
++ add_prefix_cmd ("ocd", class_obscure, bdm_command, "", &ocd_cmd_list, "ocd ",
++ 0, &cmdlist);
++
++ add_cmd ("reset", class_obscure, bdm_reset_command, "", &ocd_cmd_list);
++ add_cmd ("restart", class_obscure, bdm_restart_command, "", &ocd_cmd_list);
++ add_cmd ("update-flash", class_obscure, bdm_update_flash_command, "", &ocd_cmd_list);
++}
++#endif
++
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/bdm12.h gdb-6.4-m68hc1x/gdb/bdm12.h
+--- gdb-6.4/gdb/bdm12.h Thu Jan 1 01:00:00 1970
++++ gdb-6.4-m68hc1x/gdb/bdm12.h Sat Jan 21 15:28:49 2006
+@@ -0,0 +1,289 @@
++/* This file defines the interface between the BDM12 target and gdb.
++ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
++ Contributed by Tim Housel (thousel@usa.net)
++
++This file is part of GDB.
++
++This program is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 2 of the License, or
++(at your option) any later version.
++
++This program is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with this program; if not, write to the Free Software
++Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
++
++/* This is basically */
++#if !defined (BDM12_H)
++#define BDM12_H 1
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#ifndef REGISTER_BDM12_REGNO
++#define REGISTER_BDM12_REGNO(N) (N)
++#endif
++
++/* Return codes from various functions. */
++
++typedef enum {
++ BDM12_RC_FAIL = 0,
++ BDM12_RC_OK = 1,
++ BDM12_RC_UNKNOWN_BREAKPOINT = 2,
++ BDM12_RC_INSUFFICIENT_RESOURCES = 3,
++ BDM12_RC_DUPLICATE_BREAKPOINT = 4
++} BDM12_RC;
++
++/* these defines were pulled from Stephane's code in
++ m68hc11-tdep.c */
++
++#define HARD_X_REGNUM 0
++#define HARD_D_REGNUM 1
++#define HARD_Y_REGNUM 2
++#define HARD_SP_REGNUM 3
++#define HARD_PC_REGNUM 4
++#define HARD_A_REGNUM 5
++#define HARD_B_REGNUM 6
++#define HARD_PSW_REGNUM 7
++
++/* commands for the BDM12 pod */
++
++typedef enum {
++ BDM12_CMD_SYNC = 0x0,
++ BDM12_CMD_RESET = 0x1,
++ BDM12_CMD_EXT = 0x4,
++ BDM12_CMD_EXT_MEMDUMP = 0x3,
++ BDM12_CMD_EXT_SETPARAM = 0x4,
++ BDM12_CMD_EXT_MEMPUT = 0x6,
++ BDM12_CMD_EEPROM_WRITE = 0x5,
++ BDM12_CMD_SET_REGBASE = 0x6,
++ BDM12_CMD_EEPROM_ERASE = 0x7,
++ BDM12_CMD_BACKGROUND = 0x90,
++ BDM12_CMD_READ_BD_BYTE = 0xe4,
++ BDM12_CMD_READ_BD_WORD = 0xec,
++ BDM12_CMD_READ_WORD = 0xe8,
++ BDM12_CMD_READ_BYTE = 0xe0,
++ BDM12_CMD_WRITE_BD_BYTE = 0xc4,
++ BDM12_CMD_WRITE_BD_WORD = 0xcc,
++ BDM12_CMD_WRITE_WORD = 0xc8,
++ BDM12_CMD_WRITE_BYTE = 0xc0,
++ BDM12_CMD_READ_NEXT = 0x62,
++ BDM12_CMD_READ_PC = 0x63,
++ BDM12_CMD_READ_D = 0x64,
++ BDM12_CMD_READ_X = 0x65,
++ BDM12_CMD_READ_Y = 0x66,
++ BDM12_CMD_READ_SP = 0x67,
++ BDM12_CMD_WRITE_NEXT = 0x42,
++ BDM12_CMD_WRITE_PC = 0x43,
++ BDM12_CMD_WRITE_D = 0x44,
++ BDM12_CMD_WRITE_X = 0x45,
++ BDM12_CMD_WRITE_Y = 0x46,
++ BDM12_CMD_WRITE_SP = 0x47,
++ BDM12_CMD_GO = 0x8,
++ BDM12_CMD_TRACE1 = 0x10,
++ BDM12_CMD_TAGGO = 0x18
++} BDM12_CMD;
++
++/* e-clock rates as required by the BDM12 pod */
++
++typedef enum {
++ BDM12_ECLOCK_1MHZ = 0x0,
++ BDM12_ECLOCK_2MHZ = 0x1,
++ BDM12_ECLOCK_4MHZ = 0x2,
++ BDM12_ECLOCK_8MHZ = 0x3
++} BDM12_ECLOCK;
++
++/* misc stuff used to avoid magic constants */
++
++typedef enum {
++ BDM12_BDM_HI = 0xff,
++ BDM12_ENABLE_BDM_LO = 0x01,
++ BDM12_CCRSAV_BDM_LO = 0x06,
++ BDM12_REG_INITRG = 0x11,
++ BDM12_REG_INITRM = 0x10,
++ BDM12_REG_INITEE = 0x12,
++ BDM12_REG_MISC = 0x13,
++ BDM12_REG_BRKCT0 = 0x20,
++ BDM12_REG_BRKCT1 = 0x21,
++ BDM12_REG_BRKAH = 0x22,
++ BDM12_REG_BRKAL = 0x23,
++ BDM12_REG_BRKDH = 0x24,
++ BDM12_REG_BRKDL = 0x25,
++ BDM12_REG_FEEMCR = 0xf5,
++ BDM12_SIZE_REG = 512,
++ BDM12_SIZE_RAM = 1024,
++ BDM12_SIZE_EEPROM = 768,
++ BDM12_SIZE_FLASH = 32768,
++ BDM12_INIT_ENABLE_BDM = 0x80,
++ BDM12_INIT_BRKCT0 = 0xec,
++ BDM12_INIT_BRKCT1 = 0x40,
++ BDM12_INIT_FEEMCR = 0x0,
++ BDM12_STATUS_STOPPED = 0x40,
++ BDM12_MAX_BREAKPOINTS = 2,
++ BDM12_BAUD_RATE = 115200,
++ BDM12_COMM_TIMEOUT = 1, /* 1s timeout for serial ops */
++ BDM12_ERASEFLASH_TIMEOUT = 1000, /* 200 ms timeout for flash erase program */
++ BDM12_PROGRAMFLASH_TIMEOUT = 3 /* 3 ms/byte timeout for flash burn program */
++} BDM12_MISC;
++
++/* The bfd struct, as an opaque type. */
++
++struct _bfd;
++
++
++/* Main bdm12 entry points. */
++
++
++/* Create a fully initialized bdm12 instance.
++
++ (This function is called when the bdm12 target is selected from the
++ gdb command line.)
++
++ ARGV is a standard ARGV pointer such as that passed from the
++ command line. The syntax of the argument list is is assumed to be
++ ``BDM12 { BDM12-OPTION }''.
++
++ While the bdm12 configuration can be parameterized by (in decreasing
++ precedence) ARGV's BDM12-OPTION and the ABFD argument, the
++ successful creation of the bdm12 target shall not be dependent on the
++ presence of any of these arguments/options. */
++
++
++extern BDM12_RC bdm12_open (char **argv);
++
++
++/* Destory a bdm12 instance.
++
++ QUITTING is non-zero if we cannot hang on errors.
++*/
++
++extern void bdm12_close (int quitting);
++
++
++/* Load program PROG into the target memory.
++
++ If ABFD is non-NULL, the bfd for the file has already been opened.
++ The result is a return code indicating success. */
++
++extern BDM12_RC bdm12_load (char *prog, struct _bfd *abfd, int from_tty);
++
++
++/* Prepare to run the program.
++
++ ABFD, if not NULL, provides initial processor state information.
++ ARGV and ENV, if non NULL, are NULL terminated lists of pointers.
++
++ This function shall initialize the processor
++ registers to a known value. The program counter and possibly stack
++ pointer shall be set using information obtained from ABFD (or
++ hardware reset defaults). ARGV and ENV, dependant on the target
++ ABI, may be written to memory. */
++
++extern BDM12_RC bdm12_create_inferior (bfd *abfd, char **argv, char **env);
++
++
++/* Fetch LENGTH bytes of the target's memory. Start fetch
++ at virtual address MEM and store in BUF. Result is number of bytes
++ read, or zero if error. */
++
++extern int bdm12_read (CORE_ADDR mem, unsigned char *buf, int length);
++
++
++/* Store LENGTH bytes from BUF into the target's
++ memory. Store bytes starting at virtual address MEM. Result is
++ number of bytes write, or zero if error. */
++
++extern int bdm12_write (CORE_ADDR mem, unsigned char *buf, int length);
++
++
++/* Fetch register REGNO storing its raw (target endian) value in the
++ LENGTH byte buffer BUF. Return the actual size of the register or
++ zero if REGNO is not applicable.
++
++ Legacy implementations ignore LENGTH and always return -1.
++
++ If LENGTH does not match the size of REGNO no data is transfered
++ (the actual register size is still returned). */
++
++extern int bdm12_fetch_register (int regno, unsigned char *buf, int length);
++
++
++/* Store register REGNO from the raw (target endian) value in BUF.
++ Return the actual size of the register or zero if REGNO is not
++ applicable.
++
++ Legacy implementations ignore LENGTH and always return -1.
++
++ If LENGTH does not match the size of REGNO no data is transfered
++ (the actual register size is still returned). */
++
++extern int bdm12_store_register (int regno, unsigned char *buf, int length);
++
++
++/* Run (or resume) the program.
++
++ STEP, when non-zero indicates that only a single instruction
++ should be executed. */
++
++extern int bdm12_resume (int step);
++
++
++/* Asynchronous request to stop execution.
++ A nonzero return indicates that the target is able to handle
++ the request */
++
++extern int bdm12_stop (void);
++
++
++/* Fetch the REASON why the program stopped.
++
++ BDM12_EXITED: The program has terminated. SIGRC indicates the target
++ dependant exit status.
++
++ BDM12_STOPPED: The program has stopped. SIGRC uses the host's signal
++ numbering as a way of identifying the reaon: program interrupted by
++ user via a bdm12_stop request (SIGINT); a breakpoint instruction
++ (SIGTRAP); a completed single step (SIGTRAP); an internal error
++ condition (SIGABRT); an illegal instruction (SIGILL); Access to an
++ undefined memory region (SIGSEGV); Mis-aligned memory access
++ (SIGBUS). For some signals information in addition to the signal
++ number may be retained by the target (e.g. offending address);
++ that information is not directly accessable via this interface.
++
++ BDM12_SIGNALLED: The program has been terminated by a signal. The
++ target has encountered code that causes the the program
++ to exit with signal SIGRC.
++
++ BDM12_RUNNING, BDM12_POLLING: The return of one of these values
++ indicates a problem internal to the BDM12 interface. */
++
++enum bdm12_stop { BDM12_RUNNING, BDM12_POLLING, BDM12_EXITED, BDM12_STOPPED, BDM12_SIGNALLED };
++
++extern void bdm12_stop_reason (enum bdm12_stop *reason, int *sigrc);
++
++#if 0
++/* implement later */
++/* Passthru for other commands that the bdm12 interface might support.
++ The interface should be prepared to deal with any combination of NULL
++ or empty CMD. */
++
++void bdm12_do_command PARAMS ((char *cmd));
++
++#endif
++
++/* Call these functions to set and clear breakpoints at ADDR. */
++
++extern BDM12_RC bdm12_set_breakpoint (CORE_ADDR addr);
++extern BDM12_RC bdm12_clear_breakpoint (CORE_ADDR addr);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* !defined (BDM12_H) */
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/bdm12_eraseflash.h gdb-6.4-m68hc1x/gdb/bdm12_eraseflash.h
+--- gdb-6.4/gdb/bdm12_eraseflash.h Thu Jan 1 01:00:00 1970
++++ gdb-6.4-m68hc1x/gdb/bdm12_eraseflash.h Sat Jan 21 15:28:49 2006
+@@ -0,0 +1,249 @@
++#define BDM12_ERASEFLASH_SIZE 208
++#define BDM12_ERASEFLASH_FLASHSTART 0
++#define BDM12_ERASEFLASH_REGSTART 2
++#define BDM12_ERASEFLASH_ERRORFLAG 9
++#define BDM12_ERASEFLASH_PROGSTART 10
++
++unsigned char eraseflash[BDM12_ERASEFLASH_SIZE] = {
++ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x01, 0x1B, 0xD4, 0x14, 0x10, 0xEE, 0xF2,
++ 0x00, 0x00, 0x69, 0xF2, 0x00, 0x06, 0x69, 0xF2,
++ 0x00, 0x07, 0x69, 0xF2, 0x00, 0x08, 0xED, 0xF2,
++ 0x00, 0x02, 0x0F, 0xE8, 0xF7, 0x08, 0x74, 0x19,
++ 0xE8, 0xF7, 0x18, 0x08, 0x40, 0x06, 0x6C, 0x00,
++ 0xED, 0xF2, 0x00, 0x02, 0x0C, 0xE8, 0xF7, 0x01,
++ 0x19, 0xC6, 0x6D, 0xF2, 0x00, 0x04, 0x20, 0x7B,
++ 0xED, 0xF2, 0x00, 0x02, 0x0D, 0xE8, 0xF7, 0x01,
++ 0x19, 0xC6, 0x6D, 0xF2, 0x00, 0x04, 0x20, 0x6B,
++ 0xE7, 0xF2, 0x00, 0x07, 0x27, 0x1E, 0x63, 0xF2,
++ 0x00, 0x06, 0x26, 0xD4, 0x19, 0xC6, 0x6D, 0xF2,
++ 0x00, 0x04, 0x20, 0x38, 0xE7, 0xF2, 0x00, 0x08,
++ 0x27, 0x31, 0xED, 0xF2, 0x00, 0x02, 0x0D, 0xE8,
++ 0xF7, 0x06, 0x20, 0x22, 0x62, 0xF2, 0x00, 0x06,
++ 0x19, 0xC6, 0x6D, 0xF2, 0x00, 0x04, 0x20, 0x1C,
++ 0xE7, 0xF2, 0x00, 0x08, 0x26, 0x0A, 0xE6, 0xF2,
++ 0x00, 0x06, 0xC1, 0x05, 0x23, 0xA2, 0x20, 0x0B,
++ 0x62, 0xF2, 0x00, 0x07, 0x20, 0x9A, 0x69, 0xF2,
++ 0x00, 0x09, 0x00, 0x00, 0x69, 0xF2, 0x00, 0x08,
++ 0xCD, 0x3C, 0x00, 0xEE, 0xF2, 0x00, 0x00, 0xCC,
++ 0xFF, 0xFF, 0xAC, 0x31, 0x26, 0x07, 0x04, 0x36,
++ 0xF9, 0x62, 0xF2, 0x00, 0x08, 0xED, 0xF2, 0x00,
++ 0x04, 0x05, 0x40, 0xCC, 0x00, 0x0A, 0x20, 0x00,
++ 0xCE, 0x07, 0xD0, 0xA7, 0x04, 0x35, 0xFC, 0x04,
++ 0x34, 0xF6, 0xED, 0xF2, 0x00, 0x04, 0x05, 0x40 };
++/* The above was produced by assembling the following program with
++ > m6812-elf-as -o bdm12_eraseflash.o bdm12_eraseflash.s
++ > m6812-elf-objcopy.exe --change-addresses 0x800 -O srec bdm12_eraseflash.o
++ bdm12_eraseflash.s19
++ > ./convert < bdm12_eraseflash.s19 > bdm12_eraseflash.h
++
++ convert.c is listed following the assembly
++
++;-------------------bdm12_eraseflash.s-------------------
++;--------------------------------------------------------
++;--- Application Note Source Code for AN1836 ---
++;--- Erasing and Programming the FLASH ---
++;--- EEPROM on the MC68HC912B32 ---
++;--- ---
++;--- FLASH EEPROM erase routine ---
++;--- MC68HC912B32 1.5T FLASH Module ---
++;--- ---
++;--- Rev. 1.2 February 9, 2000 ---
++;--- Fixed bug in ReadArray routine ---
++;--- Created Bit Name Labels for easier reading ---
++;--- Streamlined Code for efficiency ---
++;--- Rev. 1.1 January 11, 2000 ---
++;--- Changed to 10ms delay for tepulse ---
++;--- to match specification change ---
++;--- Rev. 1.0 April 16, 1998 ---
++;--- Changed to 100ms delay for tepulse ---
++;--- Written November 6, 1997 ---
++;--- ---
++;--- ASSEMBLER: IASM12 v. 3.06 ---
++;--- P & E Microcomputer Systems ---
++;--- ---
++;--- by Matt Ruff, BE/OS Systems Engineering ---
++;--- ---
++;--- This code is intended for instructional use ---
++;--- only. Motorola assumes no liability for use ---
++;--- or modification of this code. It is the ---
++;--- responsibility of the user to verify all ---
++;--- parameters, variables, timings, etc. ---
++;--- ---
++;--------------------------------------------------------
++;----------------------------- Equates -----------------------------
++
++TmpStorage:
++FLASHStart: .word 0x8000 ;FLASH Start address
++REGStart: .word 0x0 ;Register Start Address
++SavePC: .word 0x0 ;saved PC
++Nep: .byte 0 ;Number of programming pulses applied
++MarginFlag: .byte 0 ;Programming margin flag
++ErasedFlag: .byte 0 ;Array Erased Flag
++ErrorFlag: .byte 1 ;Error Flag
++ .equ FLASHSize, 0x8000
++ .equ BootBlkSize, 0x800 ;Size of the boot block
++ .equ BCFEEWords, ((FLASHSize-BootBlkSize)/2)
++ ;Num of words to blank check
++ .equ MaxNep, 5 ;5 pulses maximum
++ .equ FEELCK, 0xF4 ;FLASH Lock Control Register
++ .equ FEEMCR, 0xF5 ;FLASH Module Configuration Register
++ .equ FEECTL, 0xF7 ;FLASH Control Register
++ .equ LOCK, 0x01 ;Lock register Bit in FEELCK
++ .equ BOOTP, 0x01 ;Boot Protect Bit in FEEMCR
++ .equ SVFP, 0x08 ;Status Vfp Voltage Bit in FEECTL
++ .equ ERAS, 0x04 ;Erase Control Bit in FEECTL
++ .equ LAT, 0x02 ;Programming Latch Control bit in FEECTL
++ .equ ENPE, 0x01 ;Enable Program/Erase Voltage Bit in FEECTL
++ .equ Mult, 1000 ;Multiplier for EClock, assembler won't do
++ ; values over 2^16
++ .equ EClock,(Mult*8000) ;E-clock frequency in Hz.
++ .equ mS1LoopTime, 4 ;Num of clock cycles per loop.
++ .equ mS1Delay, (EClock/(mS1LoopTime*1000))
++ ;Factor of 1000 used for base time of 1 ms.
++
++Start:
++ LEAS TmpStorage,PC
++ SEI ;disable interrupts - no SP
++ LDX FLASHStart,SP
++ CLR Nep,SP ;Clear number of pulses
++ CLR MarginFlag,SP ;Clear margin flag
++ CLR ErasedFlag,SP ;Clear erased flag
++ LDY REGStart,SP
++ BRCLR FEECTL,Y, SVFP,Error
++ ;If Vfp not present, output an error
++;- Step 2 -
++ LEAY FEECTL,Y
++ MOVB #ERAS|LAT, 0,Y
++ ;Set ERAS and LAT in FEECTL ( | is bitwise or)
++;- Step 3 -
++ STD 0,X ;Write some data to a valid FLASH address
++;- Step 4 -
++STEP4:
++ LDY REGStart,SP
++ BSET FEECTL,Y, ENPE ;Apply erase voltage (Set ENPE)
++;- Step 5 -
++ LEAY 6,PC
++ STY SavePC,SP
++ BRA dly_10ms ;Delay time for erase pulse (Tepulse)
++
++;- Step 6 -
++ LDY REGStart,SP
++ BCLR FEECTL,Y, ENPE ;Remove erase voltage (Clear ENPE)
++;- Step 7 -
++ LEAY 6,PC
++ STY SavePC,SP
++ BRA dly_10ms ;Delay for high voltage turn off (Tverase)
++ TST MarginFlag,SP ;Is margin flag set??
++ ; (TST sets Z bit in CCR if MarginFlag is 0)
++ BEQ NoFlag ;If not, go bump counter and check data
++ ; (BEQ branches if MarginFlag is 0)
++YesFlag:
++ DEC Nep,SP ;Decrement Nep - mod. Z bit in CCR for coming
++ ; BNE branch
++ BNE STEP4 ;If Nep not 0, go to Step 4
++ LEAY 6,PC
++ STY SavePC,SP
++ BRA ReadArray ;Verify entire array is erased
++ TST ErasedFlag,SP ;Is the array erased?
++ ; (TST sets Z bit in CCR if ErasedFlag is 0)
++ BEQ Error ;If not, Erase failed, output an error
++ ; (BEQ branches if ErasedFlag is 0)
++;- Step 10 -
++ LDY REGStart,SP
++ BCLR FEECTL,Y, ERAS|LAT
++ ;Clear ERAS and LAT in FEECTL
++ BRA Done ;If so, quit.
++NoFlag:
++ INC Nep,SP ;Increment number of erase pulses applied
++ LEAY 6,PC
++ STY SavePC,SP
++ BRA ReadArray ;Verify entire array is erased
++ TST ErasedFlag,SP ;Is it erased?
++ ; (TST sets Z bit in CCR if ErasedFlag is 0)
++ BNE SetMarginFlag ;If so, set margin flag
++ ; (BNE branches if ErasedFlag is 1)
++ LDAB Nep,SP
++ CMPB #MaxNep ;Have we applied max number of pulses?
++ BLS STEP4 ;If not, continue erasing
++ BRA Error ;If so, we have a problem
++SetMarginFlag:
++ INC MarginFlag,SP ;Set Margin Flag
++ BRA STEP4
++Done:
++ CLR ErrorFlag,SP
++ BGND
++Error:
++ BGND
++;-----------------------------------------------------------------------
++;----------------- Read and Verify Erase subroutine ----------------
++;-----------------------------------------------------------------------
++ReadArray:
++ CLR ErasedFlag,SP ; Always start with clear flag.
++ LDY #BCFEEWords ; Num of words to check in FLASH. (No boot
++ ; block check)
++ LDX FLASHStart,SP ; Index to the start of FLASH.
++ LDD #0xFFFF ; Erased word value for comparison.
++CheckLoop:
++ CPD 2,X+ ; Is word erased?
++ BNE VerifyBad ; If not, return without setting ErasedFlag.
++ ; (failure)
++ DBNE Y,CheckLoop ; Yes, Dec the word count, if not done check
++ ; the next word.
++ INC ErasedFlag,SP ; All words checked & are erased. Set
++ ; ErasedFlag.
++VerifyBad:
++ LDY SavePC,SP
++ JMP 0,Y
++;-----------------------------------------------------------------------
++;---------------------- Delay Subroutines -----------------------
++;-----------------------------------------------------------------------
++dly_10ms:
++ LDD #10 ;Delay for 10ms
++ BRA DelaymS
++
++;-----------------------------------------------------------------------
++;--- Millisecond Delay Routine ---
++;--- ---
++;--- Call with the number of mS to delay in the D accumulator. ---
++;--- The delay is not exact, but close enough when delaying ms. ---
++;-----------------------------------------------------------------------
++DelaymS:
++DlyLoop1mS:
++ LDX #mS1Delay ;Load 1ms delay count into X
++DlyLoop:
++ NOP ;Decrement count
++ DBNE X,DlyLoop ;Loop until done.
++ DBNE D,DlyLoop1mS
++ LDY SavePC,SP
++ JMP 0,Y
++------------------------convert.c---------------------------------------
++#include <stdio.h>
++#include <string.h>
++main()
++{
++ char line[200];
++ char *data = line + 8;
++ int i;
++ int count = 0;
++
++ printf ("unsigned char prog[] = {\n ");
++ while (fgets (line, 200, stdin))
++ {
++ if (strncmp (line, "S1", 2) != 0)
++ continue;
++ for (i = 0; i < strlen(data) - 4; i += 2)
++ {
++ printf ("0x");
++ putchar (data[i]);
++ putchar (data[i+1]);
++ printf (", ");
++ count++;
++ if (!(count % 8))
++ printf("\n ");
++ }
++ }
++ printf(" };\n");
++ printf("#define SIZE_PROG %d\n", count);
++}
++*/
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/bdm12_programflash.h gdb-6.4-m68hc1x/gdb/bdm12_programflash.h
+--- gdb-6.4/gdb/bdm12_programflash.h Thu Jan 1 01:00:00 1970
++++ gdb-6.4-m68hc1x/gdb/bdm12_programflash.h Sat Jan 21 15:28:49 2006
+@@ -0,0 +1,236 @@
++#define BDM12_PROGRAMFLASH_SIZE 207
++#define BDM12_PROGRAMFLASH_FLASHSTART 0
++#define BDM12_PROGRAMFLASH_FLASHEND 2
++#define BDM12_PROGRAMFLASH_REGSTART 4
++#define BDM12_PROGRAMFLASH_DATASTART 6
++#define BDM12_PROGRAMFLASH_NUMWRITTEN 10
++#define BDM12_PROGRAMFLASH_PROGSTART 14
++
++unsigned char programflash[BDM12_PROGRAMFLASH_SIZE] = {
++ 0x80, 0x00, 0x80, 0x02, 0x00, 0x00, 0x09, 0x00,
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xD0,
++ 0x14, 0x10, 0x87, 0xC7, 0x6C, 0xF2, 0x00, 0x0A,
++ 0xEE, 0xF2, 0x00, 0x00, 0xED, 0xF2, 0x00, 0x04,
++ 0x0E, 0xE8, 0xF7, 0x08, 0x04, 0x18, 0x20, 0x00,
++ 0x8B, 0xED, 0xF2, 0x00, 0x06, 0x69, 0xF2, 0x00,
++ 0x0C, 0x69, 0xF2, 0x00, 0x0D, 0x6D, 0xF2, 0x00,
++ 0x08, 0xED, 0xF2, 0x00, 0x04, 0xC6, 0x02, 0x6B,
++ 0xE8, 0xF7, 0xED, 0xF2, 0x00, 0x08, 0xE6, 0x40,
++ 0x6B, 0x00, 0x6D, 0xF2, 0x00, 0x08, 0xED, 0xF2,
++ 0x00, 0x04, 0x0C, 0xE8, 0xF7, 0x01, 0x19, 0xC2,
++ 0x20, 0x65, 0xED, 0xF2, 0x00, 0x04, 0x0D, 0xE8,
++ 0xF7, 0x01, 0x19, 0xC2, 0x20, 0x61, 0xED, 0xF2,
++ 0x00, 0x08, 0xE7, 0xF2, 0x00, 0x0D, 0x27, 0x2A,
++ 0x63, 0xF2, 0x00, 0x0C, 0xE7, 0xF2, 0x00, 0x0C,
++ 0x26, 0xD0, 0xA6, 0x00, 0xA1, 0x40, 0x26, 0x34,
++ 0x6D, 0xF2, 0x00, 0x08, 0xED, 0xF2, 0x00, 0x04,
++ 0x0D, 0xE8, 0xF7, 0x02, 0xED, 0xF2, 0x00, 0x08,
++ 0x08, 0x02, 0xAE, 0xF2, 0x00, 0x02, 0x26, 0x95,
++ 0x20, 0x1A, 0x62, 0xF2, 0x00, 0x0C, 0xA6, 0x00,
++ 0xA1, 0x40, 0x27, 0x0A, 0xE6, 0xF2, 0x00, 0x0C,
++ 0xC1, 0x32, 0x23, 0x9E, 0x20, 0x06, 0x62, 0xF2,
++ 0x00, 0x0D, 0x20, 0x96, 0xB7, 0x54, 0xA3, 0xF2,
++ 0x00, 0x00, 0x6C, 0xF2, 0x00, 0x0A, 0x00, 0xCC,
++ 0x00, 0x34, 0x04, 0x34, 0xFD, 0x05, 0x40, 0xCC,
++ 0x00, 0x18, 0x04, 0x34, 0xFD, 0x05, 0x40 };
++
++/* The above was produced by assembling the following program with
++ > m6812-elf-as bdm12_programflash.s
++ > m6812-elf-objcopy.exe --change-addresses 0x800 -O srec
++ bdm12_programflash.o bdm12_programflash.s19
++ > ./convert < bdm12_programflash.s19 > bdm12_programflash.h
++
++ Convert.c is listed following the assembly
++
++;----------------bdm12_programflash.s-----------------
++;-----------------------------------------------------
++;--- Application Note Source Code for AN1836 ---
++;--- Erasing and Programming the FLASH ---
++;--- EEPROM on the MC68HC912B32 ---
++;--- ---
++;--- FLASH EEPROM program routine ---
++;--- MC68HC912B32 1.5T FLASH Module ---
++;--- ---
++;--- Rev. 1.2 February 9, 2000 ---
++;--- Created Bit Name Labels for easier reading---
++;--- Streamlined Code for efficiency ---
++;--- Rev. 1.0 - April 23,1998 ---
++;--- Fixed Tppulse = 25us and Tvprog = 10us ---
++;--- Written November 6, 1997 ---
++;--- ---
++;--- ASSEMBLER: IASM12 v. 3.06 ---
++;--- P & E Microcomputer Systems---
++;--- ---
++;--- by Matt Ruff, BE/OS Systems Engineering ---
++;--- ---
++;--- This code is intended for instructional use ---
++;--- only. Motorola assumes no liability for use ---
++;--- or modification of this code. It is the ---
++;--- responsibility of the user to verify all ---
++;--- parameters, variables, timings, etc. ---
++;--- ---
++;--------------------------------------------------------
++;------------------------------ Equates ----------------------------------
++
++TmpStorage:
++FLASHStart: .word 0x8000 ;FLASH Start address
++FLASHEnd: .word 0x8002 ;FLASH End address (non-inclusive)
++REGStart: .word 0x0 ;Register Start address
++DATAStart: .word 0x900 ;Start of memory address to read from
++SaveY: .word 0x0 ;tmp storage for Y since I don't want
++ ;to mess with stack
++NumWritten: .word 0x0 ;how many words have been written
++Npp: .byte 0 ;Number of programming pulses applied
++MarginFlag: .byte 0 ;Programming margin flag
++
++ .equ MaxNpp, 50 ;50 pulses maximum
++ .equ FEELCK, 0xF4 ;FLASH Lock Control Register
++ .equ FEEMCR, 0xF5 ;FLASH Module Configuration Register
++ .equ FEECTL, 0xF7 ;FLASH Control Register
++ .equ LOCK, 0x01 ;Lock register Bit in FEELCK
++ .equ BOOTP, 0x01 ;Boot Protect Bit in FEEMCR
++ .equ SVFP, 0x08 ;Status Vfp Voltage Bit in FEECTL
++ .equ ERASE, 0x04 ;Erase Control Bit in FEECTL
++ .equ LAT, 0x02 ;Programming Latch Control bit in FEECTL
++ .equ ENPE, 0x01 ;Enable Program/Erase Voltage Bit in FEECTL
++Start:
++ LEAS TmpStorage,PC ;Set SP to the beginning of tmp vars
++ SEI ;disable interrupts - no SP
++ CLRA
++ CLRB
++ STD NumWritten,SP ;Clear Num Bytes Written counter
++ LDX FLASHStart,SP
++ LDY REGStart,SP
++ BRSET FEECTL,Y, 8,NoError
++ ;If Vfp not present, output an error
++ LBRA Done
++NoError:
++ LDY DATAStart,SP
++Loop:
++ CLR Npp,SP ;Clear number of pulses
++ CLR MarginFlag,SP ;Clear MarginFlag
++;- Step 2 -
++ STY SaveY,SP
++ LDY REGStart,SP
++ LDAB #LAT
++ STAB FEECTL,Y
++ LDY SaveY,SP
++ ;Set LAT in FEECTL
++ LDAB 0,Y ;Load from RAM
++;- Step 3 -
++ STAB 0,X ;Store in Flash
++;- Step 4 -
++STEP4:
++ STY SaveY,SP
++ LDY REGStart,SP
++ BSET FEECTL,Y,ENPE
++ ;Apply programming voltage (Set ENPE)
++;- Step 5 -
++ LEAY 2,PC
++ BRA dly_22us ;Delay time for prog pulse (Tppulse)
++;- Step 6 -
++ LDY REGStart,SP
++ BCLR FEECTL,Y,ENPE
++ ;Remove programming voltage (Clear ENPE)
++;- Step 7 -
++ LEAY 2,PC
++ BRA dly_10us ;Delay for high voltage turn off (Tvprog)
++ LDY SaveY,SP
++ TST MarginFlag,SP ;Is MarginFlag set??
++ BEQ NoFlag ;If not, go bump counter and check data
++YesFlag:
++ DEC Npp,SP ;Decrement Npp
++ TST Npp,SP ;Is Npp=0?
++ BNE STEP4 ;If not, go to Step 4
++;- Step 9 -
++ LDAA 0,X ;Read FEEPROM location to verify programming
++ CMPA 0,Y ;Is it the same as the byte to be programmed?
++ BNE Done ;Programming failed, output an error
++;- Step 10 -
++ STY SaveY,SP
++ LDY REGStart,SP
++ BCLR FEECTL,Y,LAT ;Clear LAT in FEECTL
++ LDY SaveY,SP
++
++ INX
++ INY
++ CPX FLASHEnd,SP ;Check for end
++ BNE Loop ;If not, go back to start!
++ BRA Done ;If so, quit.
++NoFlag:
++ INC Npp,SP ;Increment number of prog pulses applied
++ LDAA 0,X ;Read FEEPROM location to verify programming
++ CMPA 0,Y ;Is it the same as the byte to be programmed?
++ BEQ SetMarginFlag
++ ;If so, set the margin flag
++ LDAB Npp,SP
++ CMPB #MaxNpp ;Have we applied max number of pulses?
++ BLS STEP4 ;If not, continue programming
++ BRA Done ;If so, we have a problem
++SetMarginFlag:
++ INC MarginFlag,SP ;Set MarginFlag
++ BRA STEP4
++Done:
++ TFR X, D
++ SUBD FLASHStart,SP
++ STD NumWritten,SP
++ BGND
++;-----------------------------------------------------------------------
++;---------------------- Delay Subroutines -----------------------
++;-----------------------------------------------------------------------
++;-----------------------------------------------------------------------
++;--- Microsecond Delay Routines (8MHz e clock) ---
++;--- ---
++;--- To reduce loop overhead, the following routines have been ---
++;--- optimized by counting cycle time and calculating the delay ---
++;--- based on an 8MHz system clock. ---
++;-----------------------------------------------------------------------
++dly_22us: ; Delay for about 22-23us
++; JSR or BSR is 4 cycles
++; Total delay is {4+2+(loopcount*3)+5}*125ns
++; For a loopcount of 52 yields 20.875us
++ LDD #52 ; -2 cycles-
++d_22u:
++ DBNE D,d_22u ; -3 cycles-
++ JMP 0,Y
++ ; -5 cycles-
++
++dly_10us: ; Delay for about 10us
++ ; JSR or BSR is 4 cycles
++ ; Total delay is {4+2+(loopcount*3)+5}*125ns
++ ; For a loopcount of 24 yields 10.375us
++ LDD #24 ; -2 cycles-
++d_10u:
++ DBNE D,d_10u ; -3 cycles-
++ JMP 0,Y
++ ; -5 cycles-
++--------------------------------convert.c-------------------------------
++#include <stdio.h>
++#include <string.h>
++main()
++{
++ char line[200];
++ char *data = line + 8;
++ int i;
++ int count = 0;
++
++ printf ("unsigned char prog[] = {\n ");
++ while (fgets (line, 200, stdin))
++ {
++ if (strncmp (line, "S1", 2) != 0)
++ continue;
++ for (i = 0; i < strlen(data) - 4; i += 2)
++ {
++ printf ("0x");
++ putchar (data[i]);
++ putchar (data[i+1]);
++ printf (", ");
++ count++;
++ if (!(count % 8))
++ printf("\n ");
++ }
++ }
++ printf(" };\n");
++ printf("#define SIZE_PROG %d\n", count);
++}
++*/
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/config/m68hc11/m68hc11.mt gdb-6.4-m68hc1x/gdb/config/m68hc11/m68hc11.mt
+--- gdb-6.4/gdb/config/m68hc11/m68hc11.mt Wed Sep 3 17:02:50 2003
++++ gdb-6.4-m68hc1x/gdb/config/m68hc11/m68hc11.mt Sat Jan 21 15:28:49 2006
+@@ -1,5 +1,5 @@
+ # Target: Motorola 68HC11 processor
+-TDEPFILES= m68hc11-tdep.o
++TDEPFILES= m68hc11-tdep.o m68hc11-rom.o monitor.o dsrec.o remote-bdm12.o bdm12.o
+ SIM_OBS= remote-sim.o
+ SIM= ../sim/m68hc11/libsim.a -lm
+
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/dsrec.c gdb-6.4-m68hc1x/gdb/dsrec.c
+--- gdb-6.4/gdb/dsrec.c Sat Feb 12 01:39:18 2005
++++ gdb-6.4-m68hc1x/gdb/dsrec.c Sat Jan 21 15:28:49 2006
+@@ -49,7 +49,8 @@ static int make_srec (char *srec, CORE_A
+ void
+ load_srec (struct serial *desc, const char *file, bfd_vma load_offset,
+ int maxrecsize,
+- int flags, int hashmark, int (*waitack) (void))
++ int flags, int hashmark, int (*waitack) (void),
++ int (*serial_write) PARAMS ((struct serial*, char*, int)))
+ {
+ bfd *abfd;
+ asection *s;
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/m68hc11-rom.c gdb-6.4-m68hc1x/gdb/m68hc11-rom.c
+--- gdb-6.4/gdb/m68hc11-rom.c Thu Jan 1 01:00:00 1970
++++ gdb-6.4-m68hc1x/gdb/m68hc11-rom.c Sat Jan 21 17:12:43 2006
+@@ -0,0 +1,732 @@
++/* Remote target glue for various Motorola 68HC11/68HC12 monitors.
++ Copyright (C) 2000 Free Software Foundation, Inc.
++ Contributed by Stephane Carrez, stcarrez@worldnet.fr
++
++This file is part of GDB.
++
++This program is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 2 of the License, or
++(at your option) any later version.
++
++This program is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with this program; if not, write to the Free Software
++Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
++
++
++#include "defs.h"
++#include "gdbcore.h"
++#include "target.h"
++#include "monitor.h"
++#include "serial.h"
++#include "arch-utils.h"
++#include "event-loop.h"
++#include "event-top.h"
++#include "target.h"
++#include "inferior.h"
++#include <bfd/libbfd.h>
++#include <string.h>
++#ifndef __MINGW32__
++#include <sys/poll.h>
++#endif
++
++/* Register numbers of various important registers. */
++#define HARD_X_REGNUM 0
++#define HARD_D_REGNUM 1
++#define HARD_Y_REGNUM 2
++#define HARD_SP_REGNUM 3
++#define HARD_PC_REGNUM 4
++
++#define HARD_A_REGNUM 5
++#define HARD_B_REGNUM 6
++#define HARD_CCR_REGNUM 7
++#define M68HC11_LAST_HARD_REG (HARD_CCR_REGNUM)
++#define M68HC11_NUM_REGS (8)
++
++/* Switch gdb to use the given architecture. The architecture is
++ controlled by the monitor we are connected to, not by our program.
++ Each time we connect to the monitor, update the gdb-arch to
++ reflect the target arch. */
++static void
++set_gdbarch (enum bfd_architecture arch, unsigned long mach)
++{
++ struct gdbarch_info info;
++ bfd abfd;
++
++ bfd_default_set_arch_mach (&abfd, arch, mach);
++
++ memset (&info, 0, sizeof info);
++ info.bfd_arch_info = bfd_get_arch_info (&abfd);
++
++ if (!gdbarch_update_p (info))
++ {
++ internal_error (__FILE__, __LINE__,
++ "monitor: failed to select architecture");
++ }
++}
++
++/* Special write routine to send monitor commands on the serial line.
++ The 68HC11/68HC12 have a 1 character SCI input queue. When a character
++ is sent, it is echoed by the monitor. SCI read/write operations are
++ made in polling mode. Due to the 1 character length, the polling
++ and the echo, a character sent by Gdb can be lost. We pad the
++ monitor command with a \0. If the \0 is lost we don't care and
++ otherwise it is ignored by the monitor. */
++static int
++m68hc11_serial_write (struct serial* scb, char* str, int len)
++{
++ int result = 0;
++
++ while (len)
++ {
++ result = serial_write (scb, str, 1);
++ str++;
++ len--;
++ if (result)
++ break;
++
++ if (str[-1] == '\r' && len == 0)
++ break;
++
++ /* Pad with a \0. */
++ result = serial_write (scb, "", 1);
++ if (result)
++ break;
++ }
++ return result;
++}
++
++typedef struct console
++{
++ int escaped;
++ int escape_char;
++ int pos;
++ struct serial* target;
++ char cmd[256];
++ int cmdlen;
++ int interrupt;
++} *console_t;
++
++static struct console console_data;
++
++static int
++console_input (console_t cons, char c)
++{
++ int result;
++
++ if (cons->escaped)
++ {
++ if (c == '.')
++ cons->interrupt = 1;
++
++ cons->escaped = 0;
++ return 0;
++ }
++ if (cons->pos == 0 && cons->escape_char == c)
++ {
++ cons->escaped = 1;
++ return 0;
++ }
++
++ result = serial_write (cons->target, &c, 1);
++ return 0;
++}
++
++static void
++do_console_input (gdb_client_data d)
++{
++ char c;
++ int result;
++
++ result = read (input_fd, &c, 1);
++ if (result == 1)
++ {
++ console_input (&console_data, c);
++ }
++}
++
++static int
++m68hc11_wait_filter (char *buf,
++ int bufmax,
++ int *ext_resp_len,
++ struct target_waitstatus *status)
++{
++ char c;
++ int result;
++ extern struct serial* monitor_desc;
++ int seen_zero = 0;
++ int timeout;
++ int i, cnt;
++#ifndef __MINGW32__
++ struct pollfd fds[2];
++
++ fds[0].fd = input_fd;
++ fds[0].events = POLLIN;
++ fds[1].fd = deprecated_serial_fd (monitor_desc);
++ fds[1].events = POLLIN;
++
++ console_data.escaped = 0;
++ console_data.escape_char = '~';
++ console_data.pos = 0;
++ console_data.target = monitor_desc;
++ console_data.interrupt = 0;
++ cnt = 0;
++ timeout = -1;
++ while (1)
++ {
++ gdb_flush (gdb_stdout);
++ result = poll (fds, 2, timeout);
++ if (result > 0 && (fds[0].revents & POLLIN))
++ {
++ do_console_input (0);
++ }
++ if (result > 0 && (fds[1].revents & POLLIN))
++ {
++ while (1)
++ {
++ c = serial_readchar (monitor_desc, 0);
++ if (c == SERIAL_TIMEOUT)
++ break;
++
++ /* For Buffalo monitor, a \0 is printed before the prompt
++ and before the monitor output in general. */
++ if (seen_zero && c == '>')
++ {
++ *ext_resp_len = 0;
++ return 0;
++ }
++
++ /* If we see a \0, keep track of the characters for some
++ delay to have a chance to identify the monitor prompt.
++ If the delay is too long, what we received is printed
++ as a standard output produced by the program. */
++ if (c == 0)
++ {
++ seen_zero++;
++ timeout = 1000; /* 250 ms timeout */
++ }
++ else if (seen_zero && step_range_end == 0)
++ {
++ if (cnt < bufmax)
++ buf[cnt++] = c;
++ }
++ /* Don't print when doing a single step. */
++ else if (step_range_end == 0)
++ {
++ putchar_unfiltered (c);
++ }
++ }
++ }
++ else if (result < 0)
++ {
++ for (i = 0; i < cnt; i++)
++ putchar_unfiltered (buf[i]);
++
++ cnt = 0;
++ seen_zero = 0;
++ timeout = -1;
++ }
++ }
++#else
++ int dt;
++
++ console_data.escaped = 0;
++ console_data.escape_char = '~';
++ console_data.pos = 0;
++ console_data.target = monitor_desc;
++ console_data.interrupt = 0;
++ cnt = 0;
++ dt = 0;
++ timeout = -1;
++ while (1)
++ {
++ gdb_flush (gdb_stdout);
++ if (_rl_input_available ())
++ {
++ do_console_input (0);
++ }
++ result = serial_readchar (monitor_desc, 10);
++ if (result == SERIAL_TIMEOUT && (timeout < 0 || dt > 0))
++ {
++ if (timeout > 0)
++ dt--;
++ continue;
++ }
++
++ if (result != SERIAL_TIMEOUT)
++ {
++ c = result;
++ while (1)
++ {
++ /* For Buffalo monitor, a \0 is printed before the prompt
++ and before the monitor output in general. */
++ if (seen_zero && c == '>')
++ {
++ *ext_resp_len = 0;
++ return 0;
++ }
++
++ /* If we see a \0, keep track of the characters for some
++ delay to have a chance to identify the monitor prompt.
++ If the delay is too long, what we received is printed
++ as a standard output produced by the program. */
++ if (c == 0)
++ {
++ seen_zero++;
++ timeout = 1000; /* 250 ms timeout */
++ }
++ else if (seen_zero && step_range_end == 0)
++ {
++ if (cnt < bufmax)
++ buf[cnt++] = c;
++ }
++ /* Don't print when doing a single step. */
++ else if (step_range_end == 0)
++ {
++ putchar_unfiltered (c);
++ }
++
++ c = serial_readchar (monitor_desc, 0);
++ if (c == SERIAL_TIMEOUT)
++ break;
++ }
++ if (timeout > 0)
++ dt = timeout / 10;
++ }
++ else
++ {
++ for (i = 0; i < cnt; i++)
++ putchar_unfiltered (buf[i]);
++
++ cnt = 0;
++ seen_zero = 0;
++ timeout = -1;
++ }
++ }
++#endif
++ return 0;
++}
++
++
++/* Buffalo 68HC11 monitor. */
++
++static void buffalo_open (char *args, int from_tty);
++
++/* This array of registers needs to match the indexes used by GDB. The
++ whole reason this exists is because the various ROM monitors use
++ different names than GDB does, and don't support all the registers
++ either. So, typing "info reg sp" becomes an "S". */
++
++static char *buffalo_regnames[M68HC11_NUM_REGS] =
++{
++ "X", NULL, "Y", "S", "P", "A", "B", "C"
++};
++
++static struct target_ops buffalo_ops;
++static struct monitor_ops buffalo_cmds;
++
++/* Initialization strings to wakeup the monitor.
++ Send both \r and \030 (^X) to abort a possible current command. */
++static char *buffalo_inits[] = {
++ /* First command to invalidate a possible command ('~') and
++ to acknowledge the monitor after a reset ('\r'). */
++ "~\r",
++
++ /* Second command ^X to abort a possible current command
++ such as 'asm' and 'rm'. */
++ "\030",
++ NULL
++};
++
++static int
++m68hc11_dumpregs (void)
++{
++ char buf[256];
++ int resp_len;
++ char *p;
++ char reg_d[5];
++
++ /* Send the dump register command to the monitor and
++ get the reply. */
++ monitor_printf ("rd\r");
++ resp_len = monitor_expect ("\r", buf, sizeof (buf));
++
++ memset (reg_d, 0, sizeof (reg_d));
++ p = buf;
++ while (p && (p[0] == '\r' || p[0] == '\n'))
++ p++;
++
++ while (p && p[0] != '\r' && p[0] != '\n' && p[1] == '-')
++ {
++ int reg;
++ char *q;
++
++ if (p[0] == 'P')
++ reg = HARD_PC_REGNUM;
++ else if (p[0] == 'Y')
++ reg = HARD_Y_REGNUM;
++ else if (p[0] == 'X')
++ reg = HARD_X_REGNUM;
++ else if (p[0] == 'S')
++ reg = HARD_SP_REGNUM;
++ else if (p[0] == 'C')
++ reg = HARD_CCR_REGNUM;
++ else if (p[0] == 'A')
++ reg = HARD_A_REGNUM;
++ else if (p[0] == 'B')
++ reg = HARD_B_REGNUM;
++ else
++ break;
++
++ q = &p[2];
++ p = strchr (q, ' ');
++ if (p == 0)
++ p = strchr (q, '\t');
++ if (p == 0)
++ p = strchr (q, '\n');
++ if (p)
++ *p++ = 0;
++
++ if (reg == HARD_A_REGNUM)
++ {
++ reg_d[0] = q[0];
++ reg_d[1] = q[1];
++ }
++ else if (reg == HARD_B_REGNUM)
++ {
++ reg_d[2] = q[0];
++ reg_d[3] = q[1];
++ }
++ monitor_supply_register (reg, q);
++ }
++
++ /* If we got the value of both A and B, set the value of D. */
++ if (reg_d[0] && reg_d[2])
++ monitor_supply_register (HARD_D_REGNUM, reg_d);
++
++
++ monitor_expect (" ", 0, 0);
++ monitor_printf_noecho ("\r");
++ monitor_expect_prompt (0, 0);
++ return 0;
++}
++
++static void
++init_buffalo_cmds (void)
++{
++ buffalo_cmds.dumpregs = m68hc11_dumpregs;
++ buffalo_cmds.flags = MO_NO_ECHO_ON_OPEN | MO_GETMEM_16_BOUNDARY |
++ MO_SETMEM_INTERACTIVE | MO_SETREG_INTERACTIVE |
++ MO_CLR_BREAK_USES_ADDR | MO_GETMEM_NEEDS_RANGE | MO_FILL_USES_ADDR;
++ buffalo_cmds.init = buffalo_inits; /* Init strings */
++ buffalo_cmds.cont = "p\r"; /* continue command */
++ buffalo_cmds.step = "t 1\r"; /* single step */
++ buffalo_cmds.stop = NULL; /* interrupt command */
++ buffalo_cmds.set_break = "br %x\r"; /* set a breakpoint */
++ buffalo_cmds.clr_break = "br -%x\r"; /* clear a breakpoint */
++ buffalo_cmds.clr_all_break = "br -\r"; /* clear all breakpoints */
++ buffalo_cmds.fill = "bf %x %x %x\r"; /* fill (start end val) */
++ buffalo_cmds.setmem.cmdb = "mm %x\r"; /* setmem.cmdb (addr, value) */
++ buffalo_cmds.setmem.cmdw = NULL;
++ buffalo_cmds.setmem.cmdl = NULL;
++ buffalo_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
++ buffalo_cmds.setmem.resp_delim = "[\r\n]*[0-9a-fA-F]+ [0-9a-fA-F]+ ";
++ buffalo_cmds.setmem.term = NULL; /* setmem.term */
++ buffalo_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */
++ buffalo_cmds.getmem.cmdb = "md %x %x\r"; /* getmem.cmdb (addr, addr2) */
++ buffalo_cmds.getmem.cmdw = NULL;
++ buffalo_cmds.getmem.cmdl = NULL;
++ buffalo_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, addr2) */
++ buffalo_cmds.getmem.resp_delim = " "; /* getmem.resp_delim */
++ buffalo_cmds.getmem.term = NULL; /* getmem.term */
++ buffalo_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
++ buffalo_cmds.setreg.cmd = "rm %s\r"; /* setreg.cmd (name, value) */
++ buffalo_cmds.setreg.resp_delim =
++ "\nP.*S\\-[0-9a-fA-F]+ [\r\n]+.[PXYABCS]\\-[0-9a-fA-F]+ ";
++ buffalo_cmds.setreg.term = NULL; /* setreg.term */
++ buffalo_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
++ buffalo_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */
++ buffalo_cmds.getreg.resp_delim = NULL;/* getreg.resp_delim */
++ buffalo_cmds.getreg.term = NULL; /* getreg.term */
++ buffalo_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
++ buffalo_cmds.dump_registers = NULL; /* dump_registers */
++ /* register_pattern */
++ buffalo_cmds.register_pattern = NULL;
++ buffalo_cmds.supply_register = NULL; /* supply_register */
++ buffalo_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
++ buffalo_cmds.load = "load t\r"; /* download command */
++ buffalo_cmds.loadresp = NULL; /* load response */
++ buffalo_cmds.prompt = ">"; /* monitor command prompt */
++ buffalo_cmds.line_term = "\r"; /* end-of-line terminator */
++ buffalo_cmds.cmd_end = NULL; /* optional command terminator */
++ buffalo_cmds.target = &buffalo_ops; /* target operations */
++ buffalo_cmds.stopbits = SERIAL_2_STOPBITS; /* number of stop bits */
++ buffalo_cmds.regnames = buffalo_regnames; /* registers names */
++ buffalo_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
++ buffalo_cmds.serial_write = m68hc11_serial_write;
++ buffalo_cmds.wait_filter = m68hc11_wait_filter;
++}
++
++static void
++buffalo_open (char *args, int from_tty)
++{
++ monitor_open (args, &buffalo_cmds, from_tty);
++ set_gdbarch (bfd_arch_m68hc11, 0);
++}
++
++
++/* DBug 68HC12 monitor. */
++
++static void dbug_open (char *args, int from_tty);
++
++/* This array of registers needs to match the indexes used by GDB. The
++ whole reason this exists is because the various ROM monitors use
++ different names than GDB does, and don't support all the registers
++ either. So, typing "info reg sp" becomes an "S". */
++
++static char *dbug_regnames[M68HC11_NUM_REGS] =
++{
++ "X", "D", "Y", "SP", "PC", "A", "B", "CCR"
++};
++
++static struct target_ops dbug_ops;
++static struct monitor_ops dbug_cmds;
++
++/* Initialization strings to wakeup the monitor.
++ Send both \r and \030 (^X) to abort a possible current command. */
++static char *dbug_inits[] =
++{ "\r\030", NULL};
++
++static int
++dbug_dumpregs (void)
++{
++ char buf[256];
++ int resp_len;
++ char *p;
++ int i;
++ static int reg_list[] = {
++ HARD_PC_REGNUM,
++ HARD_SP_REGNUM,
++ HARD_X_REGNUM,
++ HARD_Y_REGNUM,
++ HARD_D_REGNUM,
++ -1
++ };
++
++ /* Send the dump register command to the monitor and
++ get the reply. */
++ monitor_printf ("rd\r");
++ monitor_printf_noecho ("\r");
++ resp_len = monitor_expect_prompt (buf, sizeof (buf));
++
++ p = buf;
++ while (p && strncmp (p, "CCR = SXHI NZVC", 15) != 0)
++ p++;
++
++ if (p == 0)
++ {
++ return -1;
++ }
++
++ /* Skip the CCR marker. */
++ while (p && p[0] != '\r' && p[0] != '\n')
++ p++;
++
++ /* Skip end of line markers. */
++ while (p && (p[0] == '\r' || p[0] == '\n'))
++ p++;
++
++ for (i = 0; p && reg_list[i] >= 0; i++)
++ {
++ char *q;
++
++ q = strchr (p, ' ');
++ if (q == 0)
++ q = strchr (p, '\t');
++
++ if (q)
++ *q++ = 0;
++
++ /* Value for register D is split with ':' ex: 45:23. */
++ if (p[2] == ':')
++ {
++ p[2] = p[1];
++ p[1] = p[0];
++ p++;
++ }
++ monitor_supply_register (reg_list[i], p);
++ p = q;
++ while (p && p[0] == ' ')
++ p++;
++ }
++
++ /* Last value is the CCR expressed in bits. */
++ if (p)
++ {
++ int bit, val;
++
++ val = 0;
++ for (bit = 7; p[0] && bit >= 0; )
++ {
++ char c = *p++;
++
++ if (c == ' ')
++ continue;
++
++ if (c == '1')
++ val |= (1 << bit);
++ bit--;
++ }
++ sprintf (buf, "%x", val);
++ monitor_supply_register (HARD_CCR_REGNUM, buf);
++ }
++ return 0;
++}
++
++static int (* monitor_xfer_memory) (CORE_ADDR, gdb_byte*, int, int,
++ struct mem_attrib *attrib,
++ struct target_ops*);
++
++static int
++dbug_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
++ struct mem_attrib *attrib,
++ struct target_ops *target)
++{
++ unsigned char val;
++ int written = 0;
++ char buf[16];
++ int result;
++
++ if (write == 0)
++ return monitor_xfer_memory (memaddr, myaddr, len, write, attrib, target);
++
++ if (len == 0)
++ return 0;
++
++ /* Enter the sub mode */
++ monitor_printf ("mm %x\r", (int) memaddr);
++
++ /* Wait output (7 chars); If we get the prompt, that's too bad. */
++ result = monitor_expect (">", buf, 8);
++ if (result > 0)
++ return 0;
++
++ while (len)
++ {
++ val = *myaddr;
++ monitor_printf ("%x\r", val);
++
++ result = monitor_expect (">", buf, 8);
++ if (result > 0)
++ return written;
++
++ myaddr++;
++ memaddr++;
++ written++;
++ /* If we wanted to, here we could validate the address */
++ len--;
++ }
++ /* Now exit the sub mode */
++ monitor_printf (".\r");
++ monitor_expect_prompt (NULL, 0);
++ return written;
++}
++
++static void
++init_dbug_cmds (void)
++{
++ dbug_cmds.dumpregs = dbug_dumpregs;
++ dbug_cmds.flags = MO_NO_ECHO_ON_OPEN | MO_GETMEM_16_BOUNDARY |
++ MO_SETMEM_INTERACTIVE |
++ MO_CLR_BREAK_USES_ADDR | MO_GETMEM_NEEDS_RANGE | MO_FILL_USES_ADDR;
++ dbug_cmds.init = dbug_inits; /* Init strings */
++ dbug_cmds.cont = "g\r"; /* continue command */
++ dbug_cmds.step = "t 1\r"; /* single step */
++ dbug_cmds.stop = NULL; /* interrupt command */
++ dbug_cmds.set_break = "br %x\r"; /* set a breakpoint */
++ dbug_cmds.clr_break = "nobr %x\r"; /* clear a breakpoint */
++ dbug_cmds.clr_all_break = "nobr\r"; /* clear all breakpoints */
++ dbug_cmds.fill = "bf %x %x %x\r"; /* fill (start end val) */
++ dbug_cmds.setmem.cmdb = "mm %x\r"; /* setmem.cmdb (addr, value) */
++ dbug_cmds.setmem.cmdw = NULL;
++ dbug_cmds.setmem.cmdl = NULL;
++ dbug_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
++ dbug_cmds.setmem.resp_delim = NULL;
++ dbug_cmds.setmem.term = NULL; /* setmem.term */
++ dbug_cmds.setmem.term_cmd = ".\r"; /* setmem.term_cmd */
++ dbug_cmds.getmem.cmdb = "md %x %x\r"; /* getmem.cmdb (addr, addr2) */
++ dbug_cmds.getmem.cmdw = NULL;
++ dbug_cmds.getmem.cmdl = NULL;
++ dbug_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, addr2) */
++ dbug_cmds.getmem.resp_delim = " "; /* getmem.resp_delim */
++ dbug_cmds.getmem.term = NULL; /* getmem.term */
++ dbug_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
++ dbug_cmds.setreg.cmd = "%s %x\r"; /* setreg.cmd (name, value) */
++ dbug_cmds.setreg.resp_delim = NULL;
++ dbug_cmds.setreg.term = NULL; /* setreg.term */
++ dbug_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
++ dbug_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */
++ dbug_cmds.getreg.resp_delim = " "; /* getreg.resp_delim */
++ dbug_cmds.getreg.term = NULL; /* getreg.term */
++ dbug_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
++ dbug_cmds.dump_registers = NULL;; /* dump_registers */
++ /* register_pattern */
++ dbug_cmds.register_pattern = NULL;
++ dbug_cmds.supply_register = NULL; /* supply_register */
++ dbug_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
++ dbug_cmds.load = "load\r"; /* download command */
++ dbug_cmds.loadresp = NULL; /* load response */
++ dbug_cmds.prompt = ">"; /* monitor command prompt */
++ dbug_cmds.line_term = "\r"; /* end-of-line terminator */
++ dbug_cmds.cmd_end = NULL; /* optional command terminator */
++ dbug_cmds.target = &dbug_ops; /* target operations */
++ dbug_cmds.stopbits = SERIAL_2_STOPBITS; /* number of stop bits */
++ dbug_cmds.regnames = dbug_regnames; /* registers names */
++ dbug_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
++}
++
++static void
++dbug_open (char *args, int from_tty)
++{
++ monitor_open (args, &dbug_cmds, from_tty);
++ set_gdbarch (bfd_arch_m68hc12, 0);
++}
++
++
++/* Initialize all 68HC11/68HC12 monitors. */
++
++void
++_initialize_m68hc11_rom (void)
++{
++ /* 68HC11 Buffalo monitor. */
++ init_buffalo_cmds ();
++ init_monitor_ops (&buffalo_ops);
++
++ buffalo_ops.to_shortname = "buffalo";
++ buffalo_ops.to_longname = "Buffalo monitor";
++ buffalo_ops.to_doc = "Debug via the Buffalo 68HC11 monitor.\n\
++Specify the serial device it is connected to (e.g. /dev/ttya).";
++ buffalo_ops.to_open = buffalo_open;
++
++ add_target (&buffalo_ops);
++
++ /* 68HC12 DBug monitor. */
++ init_dbug_cmds ();
++ init_monitor_ops (&dbug_ops);
++
++ dbug_ops.to_shortname = "dbug";
++ dbug_ops.to_longname = "DBug monitor";
++ dbug_ops.to_doc = "Debug via the DBug 68HC12 monitor.\n\
++Specify the serial device it is connected to (e.g. /dev/ttya).";
++ dbug_ops.to_open = dbug_open;
++ monitor_xfer_memory = dbug_ops.deprecated_xfer_memory;
++ dbug_ops.deprecated_xfer_memory = dbug_xfer_memory;
++
++ add_target (&dbug_ops);
++}
++
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/monitor.c gdb-6.4-m68hc1x/gdb/monitor.c
+--- gdb-6.4/gdb/monitor.c Fri Feb 18 19:58:56 2005
++++ gdb-6.4-m68hc1x/gdb/monitor.c Sat Jan 21 15:28:49 2006
+@@ -122,7 +122,7 @@ static CORE_ADDR *breakaddr;
+ that monitor_open knows that we don't have a file open when the
+ program starts. */
+
+-static struct serial *monitor_desc = NULL;
++struct serial *monitor_desc = NULL;
+
+ /* Pointer to regexp pattern matching data */
+
+@@ -138,6 +138,12 @@ static char setmem_resp_delim_fastmap[25
+ static struct re_pattern_buffer setreg_resp_delim_pattern;
+ static char setreg_resp_delim_fastmap[256];
+
++static struct re_pattern_buffer setmem_resp_delim_pattern;
++static char setmem_resp_delim_fastmap[256];
++
++static struct re_pattern_buffer setreg_resp_delim_pattern;
++static char setreg_resp_delim_fastmap[256];
++
+ static int dump_reg_flag; /* Non-zero means do a dump_registers cmd when
+ monitor_wait wakes up. */
+
+@@ -2161,7 +2167,8 @@ monitor_load (char *file, int from_tty)
+ load_srec (monitor_desc, file, (bfd_vma) load_offset,
+ 32, SREC_ALL, hashmark,
+ current_monitor->flags & MO_SREC_ACK ?
+- monitor_wait_srec_ack : NULL);
++ monitor_wait_srec_ack : NULL,
++ current_monitor->serial_write);
+
+ monitor_expect_prompt (NULL, 0);
+ }
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/monitor.h gdb-6.4-m68hc1x/gdb/monitor.h
+--- gdb-6.4/gdb/monitor.h Tue Aug 5 04:44:50 2003
++++ gdb-6.4-m68hc1x/gdb/monitor.h Sat Jan 21 15:28:49 2006
+@@ -109,6 +109,7 @@ struct monitor_ops
+ int bufmax,
+ int *response_length,
+ struct target_waitstatus * status);
++ int (*serial_write) (struct serial*, char* buf, int buflen);
+ char *load; /* load command */
+ char *loadresp; /* Response to load command */
+ char *prompt; /* monitor command prompt */
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/remote-bdm12.c gdb-6.4-m68hc1x/gdb/remote-bdm12.c
+--- gdb-6.4/gdb/remote-bdm12.c Thu Jan 1 01:00:00 1970
++++ gdb-6.4-m68hc1x/gdb/remote-bdm12.c Sat Jan 21 17:09:25 2006
+@@ -0,0 +1,718 @@
++/* remote debugging interface for Kevin Ross' BDM12 BDM pod for the 68HC12.
++ Copyright 2001
++ Free Software Foundation, Inc.
++ Contributed by Tim Housel (thousel@usa.net)
++
++ This file is part of GDB.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place - Suite 330,
++ Boston, MA 02111-1307, USA. */
++
++#include "defs.h"
++#include "inferior.h"
++#include "value.h"
++#include "gdb_string.h"
++#include <ctype.h>
++#include <fcntl.h>
++#include <signal.h>
++#include <setjmp.h>
++#include <errno.h>
++#include "terminal.h"
++#include "target.h"
++#include "gdbcore.h"
++#include "gdb/callback.h"
++#include "gdb/signals.h"
++#include "bdm12.h"
++#include "remote-utils.h"
++#include "command.h"
++#include "regcache.h"
++
++/* Prototypes */
++
++extern void _initialize_remote_bdm12 (void);
++
++static void dump_mem (char *buf, int len);
++
++static void gdbbdm12_fetch_register (int regno);
++
++static void gdbbdm12_store_register (int regno);
++
++static void gdbbdm12_kill (void);
++
++static void gdbbdm12_load (char *prog, int fromtty);
++
++static void gdbbdm12_create_inferior (char *exec_file, char *args, char **env, int);
++
++static void gdbbdm12_open (char *args, int from_tty);
++
++static void gdbbdm12_close (int quitting);
++
++static void gdbbdm12_detach (char *args, int from_tty);
++
++static void gdbbdm12_resume (ptid_t pid, int step, enum target_signal siggnal);
++
++static ptid_t gdbbdm12_wait (ptid_t pid, struct target_waitstatus *status);
++
++static void gdbbdm12_prepare_to_store (void);
++struct mem_attrib;
++static int gdbbdm12_xfer_inferior_memory (CORE_ADDR memaddr, gdb_byte *myaddr,
++ int len, int write,
++ struct mem_attrib *attrib,
++ struct target_ops *target);
++
++static void gdbbdm12_files_info (struct target_ops *target);
++
++static void gdbbdm12_mourn_inferior (void);
++
++static void gdbbdm12_stop (void);
++
++static int gdbbdm12_insert_breakpoint (CORE_ADDR addr, gdb_byte *contents_cache);
++
++static int gdbbdm12_remove_breakpoint (CORE_ADDR addr, gdb_byte *contents_cache);
++
++void pass_command (char *args, int from_tty);
++
++/* Naming convention:
++
++ bdm12_* are the interface to the BDM Hardware (see bdm12.h).
++ gdbbdm12_* are stuff which is internal to gdb. */
++
++/* Forward data declarations */
++extern struct target_ops gdbbdm12_ops;
++
++static int program_loaded = 0;
++
++/* We must keep track of whether the BDM has been opened or not because
++ GDB can call a target's close routine twice, but bdm12_close doesn't allow
++ this. We also need to record the result of bdm12_open so we can pass it
++ back to the other bdm12_foo routines. */
++static int gdbbdm12_opened = 0;
++
++static int bdm12_stop_requested = 0;
++
++static void
++dump_mem (char *buf, int len)
++{
++ if (len <= 8)
++ {
++ if (len == 8 || len == 4)
++ {
++ long l[2];
++ memcpy (l, buf, len);
++ printf_filtered ("\t0x%lx", l[0]);
++ if (len == 8)
++ printf_filtered (" 0x%lx", l[1]);
++ printf_filtered ("\n");
++ }
++ else
++ {
++ int i;
++ printf_filtered ("\t");
++ for (i = 0; i < len; i++)
++ printf_filtered ("0x%x ", buf[i]);
++ printf_filtered ("\n");
++ }
++ }
++}
++
++static void
++gdbbdm12_fetch_register (int regno)
++{
++ static int warn_user = 1;
++ if (regno == -1)
++ {
++ for (regno = 0; regno < NUM_REGS; regno++)
++ gdbbdm12_fetch_register (regno);
++ }
++ else if (REGISTER_NAME (regno) != NULL
++ && *REGISTER_NAME (regno) != '\0')
++ {
++ char buf[MAX_REGISTER_SIZE];
++ int nr_bytes;
++ if (REGISTER_BDM12_REGNO (regno) >= 0)
++ nr_bytes = bdm12_fetch_register (REGISTER_BDM12_REGNO (regno),
++ buf, register_size (current_gdbarch, regno));
++ else
++ nr_bytes = 0;
++ if (nr_bytes == 0)
++ /* register not applicable, supply zero's */
++ memset (buf, 0, MAX_REGISTER_SIZE);
++ else if (nr_bytes > 0 && nr_bytes != register_size (current_gdbarch, regno)
++ && warn_user)
++ {
++ fprintf_unfiltered (gdb_stderr,
++ "Size of register %s (%d/%d) incorrect (%d instead of %d))",
++ REGISTER_NAME (regno),
++ regno, REGISTER_BDM12_REGNO (regno),
++ nr_bytes, register_size (current_gdbarch, regno));
++ warn_user = 0;
++ }
++ regcache_raw_supply (current_regcache, regno, buf);
++ if (sr_get_debug ())
++ {
++ printf_filtered ("gdbbdm12_fetch_register: %d", regno);
++ /* FIXME: We could print something more intelligible. */
++ dump_mem (buf, register_size (current_gdbarch, regno));
++ }
++ }
++}
++
++
++static void
++gdbbdm12_store_register (int regno)
++{
++ if (regno == -1)
++ {
++ for (regno = 0; regno < NUM_REGS; regno++)
++ gdbbdm12_store_register (regno);
++ }
++ else if (REGISTER_NAME (regno) != NULL
++ && *REGISTER_NAME (regno) != '\0'
++ && REGISTER_BDM12_REGNO (regno) >= 0)
++ {
++ char tmp[MAX_REGISTER_SIZE];
++ int nr_bytes;
++ deprecated_read_register_gen (regno, tmp);
++ nr_bytes = bdm12_store_register (REGISTER_BDM12_REGNO (regno),
++ tmp, register_size (current_gdbarch, regno));
++ if (nr_bytes > 0 && nr_bytes != register_size (current_gdbarch, regno))
++ internal_error (__FILE__, __LINE__,
++ "Register size different than expected");
++ if (sr_get_debug ())
++ {
++ printf_filtered ("gdbbdm12_store_register: %d", regno);
++ /* FIXME: We could print something more intelligible. */
++ dump_mem (tmp, register_size (current_gdbarch, regno));
++ }
++ }
++}
++
++/* Kill the running program. */
++
++static void
++gdbbdm12_kill (void)
++{
++ if (sr_get_debug ())
++ printf_filtered ("gdbbdm12_kill\n");
++
++ /* make sure everything is closed up okay (e.g. serial port) */
++
++ bdm12_close (1);
++ inferior_ptid = null_ptid;
++}
++
++/* Load an executable file into the target process. This is expected to
++ not only bring new code into the target process, but also to update
++ GDB's symbol tables to match. */
++
++static void
++gdbbdm12_load (char *prog, int fromtty)
++{
++ if (sr_get_debug ())
++ printf_filtered ("gdbbdm12_load: prog \"%s\"\n", prog);
++
++ inferior_ptid = null_ptid;
++
++ /* FIXME: We will print two messages on error.
++ Need error to either not print anything if passed NULL or need
++ another routine that doesn't take any arguments. */
++ if (bdm12_load (prog, NULL, fromtty) == BDM12_RC_FAIL)
++ error ("unable to load program");
++
++ /* FIXME: If a load command should reset the targets registers then
++ a call to bdm12_create_inferior() should go here. */
++
++ program_loaded = 1;
++}
++
++
++/* Start an inferior process and set inferior_pid to its pid.
++ EXEC_FILE is the file to run.
++ ARGS is a string containing the arguments to the program.
++ ENV is the environment vector to pass. Errors reported with error().
++ This is called not only when we first attach, but also when the
++ user types "run" after having attached. */
++
++static void
++gdbbdm12_create_inferior (char *exec_file, char *args, char **env, int from_tty)
++{
++ int len;
++ char *arg_buf, **argv;
++
++ if (exec_file == 0 || exec_bfd == 0)
++ warning ("No executable file specified.");
++ if (!program_loaded)
++ warning ("No program loaded.");
++ if (!gdbbdm12_opened)
++ error ("Not connected to the bdm12 interface");
++
++ if (sr_get_debug ())
++ printf_filtered ("gdbbdm12_create_inferior: exec_file \"%s\", args \"%s\"\n",
++ (exec_file ? exec_file : "(NULL)"),
++ args);
++
++ remove_breakpoints ();
++ init_wait_for_inferior ();
++
++ if (exec_file != NULL)
++ {
++ len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10;
++ arg_buf = (char *) alloca (len);
++ arg_buf[0] = '\0';
++ strcat (arg_buf, exec_file);
++ strcat (arg_buf, " ");
++ strcat (arg_buf, args);
++ argv = buildargv (arg_buf);
++ make_cleanup_freeargv (argv);
++ }
++ else
++ argv = NULL;
++ bdm12_create_inferior (exec_bfd, argv, env);
++
++ inferior_ptid = pid_to_ptid (42);
++ insert_breakpoints ();
++
++ clear_proceed_status ();
++
++ /* NB: Entry point already set by bdm12_create_inferior. */
++ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
++}
++
++/* The open routine takes the rest of the parameters from the command,
++ and (if successful) pushes a new target onto the stack.
++ Called when selecting the bdm12 target. EG: (gdb) target bdm12 name. */
++
++static void
++gdbbdm12_open (char *args, int from_tty)
++{
++ int len;
++ char **argv;
++ BDM12_RC retval;
++
++ if (sr_get_debug ())
++ printf_filtered ("gdbbdm12_open: args \"%s\"\n", args ? args : "(null)");
++
++ /* Remove current bdm12 if one exists. Only do this if the bdm12 interface
++ has been opened because bdm12_close requires it.
++ This is important because the call to push_target below will cause
++ bdm12_close to be called if the bdm12 interface is already open, but
++ push_target is called after bdm12_open! We can't move the call to
++ push_target before the call to bdm12_open because bdm12_open may invoke
++ 'error'. */
++
++ if (args == NULL)
++ error("\n\
++Usage: target bdm12 <serial_device> <E-clock rate (1,2,4, or 8 MHz) \n\
++ <register base> <ram base> <eeprom base> <flash base> \n\
++(ex. target bdm12 com1 8 0x0 0x800 0xd00 0x8000 on Win32, \n\
++ or target bdm12 ttya 8 0x0 0x800 0xd00 0x8000 on UNIX)");
++
++ if (gdbbdm12_opened != 0)
++ unpush_target (&gdbbdm12_ops);
++
++ argv = buildargv (args);
++ if (argv == NULL)
++ error("Insufficient memory available to allocate arg list");
++ make_cleanup_freeargv (argv);
++
++ retval = bdm12_open (argv);
++ if (retval != BDM12_RC_OK)
++ error ("unable to open bdm12 interface\n\
++Usage: target bdm12 <serial_device> <E-clock rate (1,2,4, or 8 MHz) \n\
++ <register base> <ram base> <eeprom base> <flash base> \n\
++(ex. target bdm12 com1 8 0x0 0x800 0xd00 0x8000 on Win32, \n\
++ or target bdm12 ttya 8 0x0 0x800 0xd00 0x8000 on UNIX)");
++ else
++ gdbbdm12_opened = 1;
++
++ push_target (&gdbbdm12_ops);
++ target_fetch_registers (-1);
++ printf_filtered ("Connected to the bdm12 interface.\n");
++}
++
++/* Does whatever cleanup is required for a target that we are no longer
++ going to be calling. Argument says whether we are quitting gdb and
++ should not get hung in case of errors, or whether we want a clean
++ termination even if it takes a while. This routine is automatically
++ always called just before a routine is popped off the target stack.
++ Closing file and freeing memory are typical things it should
++ do. */
++/* Close out all files and local state before this target loses control. */
++
++static void
++gdbbdm12_close (int quitting)
++{
++ if (sr_get_debug ())
++ printf_filtered ("gdbbdm12_close: quitting %d\n", quitting);
++
++ program_loaded = 0;
++
++ if (gdbbdm12_opened != 0)
++ {
++ bdm12_close (quitting);
++ gdbbdm12_opened = 0;
++ }
++
++ generic_mourn_inferior ();
++}
++
++/* Takes a program previously attached to and detaches it.
++ The program may resume execution (some targets do, some don't) and will
++ no longer stop on signals, etc. We better not have left any breakpoints
++ in the program or it'll die when it hits one. ARGS is arguments
++ typed by the user (e.g. a signal to send the process). FROM_TTY
++ says whether to be verbose or not. */
++/* Terminate the open connection to the remote debugger.
++ Use this when you want to detach and do something else with your gdb. */
++
++static void
++gdbbdm12_detach (char *args, int from_tty)
++{
++ if (sr_get_debug ())
++ printf_filtered ("gdbbdm12_detach: args \"%s\"\n", args);
++
++ pop_target (); /* calls gdbbdm12_close to do the real work */
++ if (from_tty)
++ printf_filtered ("Ending %s debugging\n", target_shortname);
++}
++
++/* Resume execution of the target process. STEP says whether to single-step
++ or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given
++ to the target, or zero for no signal. */
++
++static enum target_signal resume_siggnal;
++static int resume_step;
++
++static void
++gdbbdm12_resume (ptid_t pid, int step, enum target_signal siggnal)
++{
++ if (PIDGET (inferior_ptid) != 42)
++ error ("The program is not being run.");
++
++ if (sr_get_debug ())
++ printf_filtered ("gdbbdm12_resume: step %d, signal %d\n", step, siggnal);
++
++ resume_siggnal = siggnal;
++ resume_step = step;
++}
++
++/* Notify the bdm12 interface of an asynchronous request to stop. */
++
++static void
++gdbbdm12_stop (void)
++{
++ bdm12_stop_requested = 0;
++ if (!bdm12_stop ())
++ {
++ quit ();
++ }
++}
++
++static void
++gdbbdm12_cntrl_c (int signo)
++{
++ bdm12_stop_requested = 1;
++}
++
++/* Wait for inferior process to do something. Return pid of child,
++ or -1 in case of error; store status through argument pointer STATUS,
++ just as `wait' would. */
++
++static ptid_t
++gdbbdm12_wait (ptid_t pid, struct target_waitstatus *status)
++{
++ static RETSIGTYPE (*prev_sigint) ();
++ int sigrc = 0;
++ enum bdm12_stop reason;
++
++ if (sr_get_debug ())
++ printf_filtered ("gdbbdm12_wait\n");
++
++#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
++ {
++ struct sigaction sa, osa;
++ sa.sa_handler = gdbbdm12_cntrl_c;
++ sigemptyset (&sa.sa_mask);
++ sa.sa_flags = 0;
++ sigaction (SIGINT, &sa, &osa);
++ prev_sigint = osa.sa_handler;
++ }
++#else
++ prev_sigint = signal (SIGINT, gdbbdm12_cntrl_c);
++#endif
++
++ bdm12_resume (resume_step);
++
++ do
++ bdm12_stop_reason (&reason, &sigrc);
++ while ((reason == BDM12_RUNNING) && !bdm12_stop_requested);
++
++ if (bdm12_stop_requested)
++ gdbbdm12_stop ();
++
++ signal (SIGINT, prev_sigint);
++ resume_step = 0;
++
++ switch (reason)
++ {
++ case BDM12_EXITED:
++ status->kind = TARGET_WAITKIND_EXITED;
++ status->value.integer = sigrc;
++ break;
++ case BDM12_STOPPED:
++ switch (sigrc)
++ {
++ case TARGET_SIGNAL_ABRT:
++ quit ();
++ break;
++ case TARGET_SIGNAL_INT:
++ case TARGET_SIGNAL_TRAP:
++ default:
++ status->kind = TARGET_WAITKIND_STOPPED;
++ status->value.sig = sigrc;
++ break;
++ }
++ break;
++ case BDM12_SIGNALLED:
++ status->kind = TARGET_WAITKIND_SIGNALLED;
++ status->value.sig = sigrc;
++ break;
++ case BDM12_RUNNING:
++ case BDM12_POLLING:
++ /* FIXME: Is this correct? */
++ break;
++ }
++
++ return inferior_ptid;
++}
++
++/* Get ready to modify the registers array. On machines which store
++ individual registers, this doesn't need to do anything. On machines
++ which store all the registers in one fell swoop, this makes sure
++ that registers contains all the registers from the program being
++ debugged. */
++
++static void
++gdbbdm12_prepare_to_store (void)
++{
++ /* Do nothing, since we can store individual regs */
++}
++
++/* Transfer LEN bytes between GDB address MYADDR and target address
++ MEMADDR. If WRITE is non-zero, transfer them to the target,
++ otherwise transfer them from the target. TARGET is unused.
++
++ Returns the number of bytes transferred. */
++
++static int
++gdbbdm12_xfer_inferior_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
++ int write,
++ struct mem_attrib *attrib ATTRIBUTE_UNUSED,
++ struct target_ops *target ATTRIBUTE_UNUSED)
++{
++ if (sr_get_debug ())
++ {
++ /* FIXME: Send to something other than STDOUT? */
++ printf_filtered ("gdbbdm12_xfer_inferior_memory: myaddr 0x");
++ gdb_print_host_address (myaddr, gdb_stdout);
++ printf_filtered (", memaddr 0x%s, len %d, write %d\n",
++ paddr_nz (memaddr), len, write);
++ if (sr_get_debug () && write)
++ dump_mem (myaddr, len);
++ }
++
++ if (write)
++ {
++ len = bdm12_write (memaddr, myaddr, len);
++ }
++ else
++ {
++ len = bdm12_read (memaddr, myaddr, len);
++ if (sr_get_debug () && len > 0)
++ dump_mem (myaddr, len);
++ }
++ return len;
++}
++
++static void
++gdbbdm12_files_info (struct target_ops *target)
++{
++ char *file = "nothing";
++
++ if (exec_bfd)
++ file = bfd_get_filename (exec_bfd);
++
++ if (sr_get_debug ())
++ printf_filtered ("gdbbdm12_files_info: file \"%s\"\n", file);
++
++ if (exec_bfd)
++ {
++ printf_filtered ("\tAttached to %s running program %s\n",
++ target_shortname, file);
++ }
++}
++
++/* Clear the BDM interface's notion of what the breakpoints are. */
++
++static void
++gdbbdm12_mourn_inferior (void)
++{
++ if (sr_get_debug ())
++ printf_filtered ("gdbbdm12_mourn_inferior:\n");
++
++ remove_breakpoints ();
++ generic_mourn_inferior ();
++}
++
++static int
++gdbbdm12_insert_breakpoint (CORE_ADDR addr, gdb_byte *contents_cache)
++{
++ BDM12_RC retcode;
++
++ retcode = bdm12_set_breakpoint (addr);
++
++ switch (retcode)
++ {
++ case BDM12_RC_OK:
++ return 0;
++ case BDM12_RC_INSUFFICIENT_RESOURCES:
++ return ENOMEM;
++ default:
++ return EIO;
++ }
++}
++
++static int
++gdbbdm12_remove_breakpoint (CORE_ADDR addr, gdb_byte *contents_cache)
++{
++ BDM12_RC retcode;
++
++ retcode = bdm12_clear_breakpoint (addr);
++
++ switch (retcode)
++ {
++ case BDM12_RC_OK:
++ case BDM12_RC_UNKNOWN_BREAKPOINT:
++ return 0;
++ case BDM12_RC_INSUFFICIENT_RESOURCES:
++ return ENOMEM;
++ default:
++ return EIO;
++ }
++}
++
++/* Pass the command argument through to the bdm12 interface verbatim. The
++ bdm12 must do any command interpretation work. */
++
++void
++pass_command (char *args, int from_tty)
++{
++ if (gdbbdm12_opened == 0)
++ {
++ /* Don't send commands if the interface isn't opened! */
++ error ("Not connected to the bdm12 interface");
++ }
++
++#if 0
++ /* implement later */
++ bdm12_do_command (args);
++#endif
++
++ /* Invalidate the register cache, in case the command does
++ something funny. */
++ registers_changed ();
++}
++
++/* Define the target subroutine names */
++
++struct target_ops gdbbdm12_ops;
++
++static void
++init_gdbbdm12_ops (void)
++{
++ gdbbdm12_ops.to_shortname = "bdm12";
++ gdbbdm12_ops.to_longname = "Kevin Ross' BDM12 Pod for BDM on the 68HC12";
++ gdbbdm12_ops.to_doc = "Debug using Kevin Ross' BDM12 Pod\n\
++(http://www.nwlink.com/~kevinro/bdm.html) for the Motorola 68HC12 series of\n\
++microcontrollers. This processor features a single wire background debug mode\n\
++interface.\n\
++Usage: target bdm12 <serial_device> <E-clock rate (1,2,4, or 8 MHz) \n\
++ <register base> <ram base> <eeprom base> <flash base> \n\
++(ex. target bdm12 com1 8 0x0 0x800 0xd00 0x8000 on Win32, \n\
++ or target bdm12 ttya 8 0x0 0x800 0xd00 0x8000 on UNIX)";
++ gdbbdm12_ops.to_open = gdbbdm12_open;
++ gdbbdm12_ops.to_close = gdbbdm12_close;
++ gdbbdm12_ops.to_attach = NULL;
++ gdbbdm12_ops.to_post_attach = NULL;
++ gdbbdm12_ops.to_detach = gdbbdm12_detach;
++ gdbbdm12_ops.to_resume = gdbbdm12_resume;
++ gdbbdm12_ops.to_wait = gdbbdm12_wait;
++ gdbbdm12_ops.to_fetch_registers = gdbbdm12_fetch_register;
++ gdbbdm12_ops.to_store_registers = gdbbdm12_store_register;
++ gdbbdm12_ops.to_prepare_to_store = gdbbdm12_prepare_to_store;
++ gdbbdm12_ops.deprecated_xfer_memory = gdbbdm12_xfer_inferior_memory;
++ gdbbdm12_ops.to_files_info = gdbbdm12_files_info;
++ gdbbdm12_ops.to_insert_breakpoint = gdbbdm12_insert_breakpoint;
++ gdbbdm12_ops.to_remove_breakpoint = gdbbdm12_remove_breakpoint;
++ gdbbdm12_ops.to_terminal_init = NULL;
++ gdbbdm12_ops.to_terminal_inferior = NULL;
++ gdbbdm12_ops.to_terminal_ours_for_output = NULL;
++ gdbbdm12_ops.to_terminal_ours = NULL;
++ gdbbdm12_ops.to_terminal_info = NULL;
++ gdbbdm12_ops.to_kill = gdbbdm12_kill;
++ gdbbdm12_ops.to_load = gdbbdm12_load;
++ gdbbdm12_ops.to_lookup_symbol = NULL;
++ gdbbdm12_ops.to_create_inferior = gdbbdm12_create_inferior;
++ gdbbdm12_ops.to_post_startup_inferior = NULL;
++ gdbbdm12_ops.to_acknowledge_created_inferior = NULL;
++ gdbbdm12_ops.to_insert_fork_catchpoint = NULL;
++ gdbbdm12_ops.to_remove_fork_catchpoint = NULL;
++ gdbbdm12_ops.to_insert_vfork_catchpoint = NULL;
++ gdbbdm12_ops.to_remove_vfork_catchpoint = NULL;
++ gdbbdm12_ops.to_insert_exec_catchpoint = NULL;
++ gdbbdm12_ops.to_remove_exec_catchpoint = NULL;
++ gdbbdm12_ops.to_reported_exec_events_per_exec_call = NULL;
++ gdbbdm12_ops.to_has_exited = NULL;
++ gdbbdm12_ops.to_mourn_inferior = gdbbdm12_mourn_inferior;
++ gdbbdm12_ops.to_can_run = 0;
++ gdbbdm12_ops.to_notice_signals = 0;
++ gdbbdm12_ops.to_thread_alive = 0;
++ gdbbdm12_ops.to_stop = gdbbdm12_stop;
++ gdbbdm12_ops.to_pid_to_exec_file = NULL;
++ gdbbdm12_ops.to_stratum = process_stratum;
++ gdbbdm12_ops.to_has_all_memory = 1;
++ gdbbdm12_ops.to_has_memory = 1;
++ gdbbdm12_ops.to_has_stack = 1;
++ gdbbdm12_ops.to_has_registers = 1;
++ gdbbdm12_ops.to_has_execution = 1;
++ gdbbdm12_ops.to_sections = NULL;
++ gdbbdm12_ops.to_sections_end = NULL;
++ gdbbdm12_ops.to_magic = OPS_MAGIC;
++
++#ifdef TARGET_REDEFINE_DEFAULT_OPS
++ TARGET_REDEFINE_DEFAULT_OPS (&gdbbdm12_ops);
++#endif
++}
++
++
++void
++_initialize_remote_bdm12 (void)
++{
++ init_gdbbdm12_ops ();
++ add_target (&gdbbdm12_ops);
++
++ add_com ("bdm12 <command>", class_obscure, pass_command,
++ "Send a command to the BDM interface directly.");
++}
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/ser-dummy.c gdb-6.4-m68hc1x/gdb/ser-dummy.c
+--- gdb-6.4/gdb/ser-dummy.c Thu Jan 1 01:00:00 1970
++++ gdb-6.4-m68hc1x/gdb/ser-dummy.c Sat Jan 21 15:28:49 2006
+@@ -0,0 +1,153 @@
++/* Dummy (do-nothing) serial interface */
++
++/*
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place - Suite 330,
++ Boston, MA 02111-1307, USA. */
++
++#include "defs.h"
++#include "serial.h"
++
++static int
++ser_dummy_open (struct serial *scb ATTRIBUTE_UNUSED, const char *name ATTRIBUTE_UNUSED)
++{
++ scb->fd = -1;
++ return 0;
++}
++
++void
++ser_dummy_close (struct serial *scb ATTRIBUTE_UNUSED)
++{
++}
++
++/* Wait for the output to drain away, as opposed to flushing (discarding) it */
++
++serial_ttystate
++ser_dummy_get_tty_state (struct serial *scb ATTRIBUTE_UNUSED)
++{
++ /* allocate a dummy */
++ return (serial_ttystate) xmalloc (8);
++}
++
++int
++ser_dummy_set_tty_state (struct serial *scb ATTRIBUTE_UNUSED, serial_ttystate ttystate ATTRIBUTE_UNUSED)
++{
++ return 0;
++}
++
++void
++ser_dummy_go_raw (struct serial *scb ATTRIBUTE_UNUSED)
++{
++ return; /* Always in raw mode */
++}
++
++
++int
++ser_dummy_readchar (struct serial *scb ATTRIBUTE_UNUSED, int timeout ATTRIBUTE_UNUSED)
++{
++ return SERIAL_EOF;
++}
++
++int
++ser_dummy_noflush_set_tty_state (struct serial *scb ATTRIBUTE_UNUSED,
++ serial_ttystate new_ttystate ATTRIBUTE_UNUSED,
++ serial_ttystate old_ttystate ATTRIBUTE_UNUSED)
++{
++ return 0;
++}
++
++void
++ser_dummy_print_tty_state (struct serial *scb ATTRIBUTE_UNUSED,
++ serial_ttystate ttystate ATTRIBUTE_UNUSED,
++ struct ui_file *stream ATTRIBUTE_UNUSED)
++{
++ /* Nothing to print. */
++ return;
++}
++
++int
++ser_dummy_setbaudrate (struct serial *scb ATTRIBUTE_UNUSED, int rate ATTRIBUTE_UNUSED)
++{
++ return 0; /* Never fails! */
++}
++
++int
++ser_dummy_setstopbits (struct serial *scb ATTRIBUTE_UNUSED, int num ATTRIBUTE_UNUSED)
++{
++ return 0; /* Never fails! */
++}
++
++int
++ser_dummy_write (struct serial *scb ATTRIBUTE_UNUSED, const char *str ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED)
++{
++ return 0;
++}
++
++int
++ser_dummy_flush_output (struct serial *scb ATTRIBUTE_UNUSED)
++{
++ return 0;
++}
++
++int
++ser_dummy_flush_input (struct serial *scb ATTRIBUTE_UNUSED)
++{
++ return 0;
++}
++
++int
++ser_dummy_send_break (struct serial *scb ATTRIBUTE_UNUSED)
++{
++ return 0;
++}
++
++static int
++ser_dummy_drain_output (struct serial *scb ATTRIBUTE_UNUSED)
++{
++ return 0;
++}
++
++/* Put the SERIAL device into/out-of ASYNC mode. */
++
++void
++ser_dummy_async (struct serial *scb ATTRIBUTE_UNUSED,
++ int async_p ATTRIBUTE_UNUSED)
++{
++}
++
++void
++_initialize_dummy_ser_hardwire (void)
++{
++ struct serial_ops *ops = (struct serial_ops *) xmalloc (sizeof (struct serial_ops));
++ memset (ops, sizeof (struct serial_ops), 0);
++ ops->name = "hardwire";
++ ops->next = 0;
++ ops->open = ser_dummy_open;
++ ops->close = ser_dummy_close;
++ ops->readchar = ser_dummy_readchar;
++ ops->write = ser_dummy_write;
++ ops->flush_output = ser_dummy_flush_output;
++ ops->flush_input = ser_dummy_flush_input;
++ ops->send_break = ser_dummy_send_break;
++ ops->go_raw = ser_dummy_go_raw;
++ ops->get_tty_state = ser_dummy_get_tty_state;
++ ops->set_tty_state = ser_dummy_set_tty_state;
++ ops->print_tty_state = ser_dummy_print_tty_state;
++ ops->noflush_set_tty_state = ser_dummy_noflush_set_tty_state;
++ ops->setbaudrate = ser_dummy_setbaudrate;
++ ops->setstopbits = ser_dummy_setstopbits;
++ ops->drain_output = ser_dummy_drain_output;
++ ops->async = ser_dummy_async;
++ serial_add_interface (ops);
++}
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/ser-mingw.c gdb-6.4-m68hc1x/gdb/ser-mingw.c
+--- gdb-6.4/gdb/ser-mingw.c Thu Jan 1 01:00:00 1970
++++ gdb-6.4-m68hc1x/gdb/ser-mingw.c Sat Jan 21 15:28:49 2006
+@@ -0,0 +1,533 @@
++/* Serial interface for TCP connections on MingW Windows systems
++ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
++ Free Software Foundation, Inc.
++
++ This file is part of GDB.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place - Suite 330,
++ Boston, MA 02111-1307, USA. */
++
++#include "defs.h"
++#include "serial.h"
++#include "ser-mingw.h"
++
++#include <fcntl.h>
++#include <sys/time.h>
++#include <sys/timeb.h>
++
++#include <winsock2.h>
++
++#include "gdb_string.h"
++#include "event-loop.h"
++
++void
++gettimeofday(struct timeval* tv, struct timezone* tz)
++{
++ struct timeb tb;
++
++ ftime(&tb);
++ tv->tv_sec = (unsigned long) tb.time;
++ tv->tv_usec = ((unsigned long) tb.millitm) * 1000L;
++}
++
++static int do_mingw_readchar (struct serial *scb, int timeout);
++static timer_handler_func push_event;
++static handler_func fd_event;
++static void reschedule (struct serial *scb);
++
++extern int (*deprecated_ui_loop_hook) (int);
++
++/* Generic operations used by all UNIX/FD based serial interfaces. */
++
++serial_ttystate
++ser_mingw_nop_get_tty_state (struct serial *scb)
++{
++ /* allocate a dummy */
++ return (serial_ttystate) XMALLOC (int);
++}
++
++int
++ser_mingw_nop_set_tty_state (struct serial *scb, serial_ttystate ttystate)
++{
++ return 0;
++}
++
++void
++ser_mingw_nop_raw (struct serial *scb)
++{
++ return; /* Always in raw mode */
++}
++
++/* Wait for input on scb, with timeout seconds. Returns 0 on success,
++ otherwise SERIAL_TIMEOUT or SERIAL_ERROR. */
++
++int
++ser_mingw_wait_for (struct serial *scb, int timeout)
++{
++ while (1)
++ {
++ int numfds;
++ struct timeval tv;
++ fd_set readfds, exceptfds;
++
++ /* NOTE: Some OS's can scramble the READFDS when the select()
++ call fails (ex the kernel with Red Hat 5.2). Initialize all
++ arguments before each call. */
++
++ tv.tv_sec = timeout;
++ tv.tv_usec = 0;
++
++ FD_ZERO (&readfds);
++ FD_ZERO (&exceptfds);
++ FD_SET (scb->fd, &readfds);
++ FD_SET (scb->fd, &exceptfds);
++
++ if (timeout >= 0)
++ numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
++ else
++ numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, 0);
++
++ if (numfds <= 0)
++ {
++ if (numfds == 0)
++ return SERIAL_TIMEOUT;
++ else if (errno == EINTR)
++ continue;
++ else
++ return SERIAL_ERROR; /* Got an error from select or poll */
++ }
++
++ return 0;
++ }
++}
++
++/* Read a character with user-specified timeout. TIMEOUT is number of seconds
++ to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
++ char if successful. Returns -2 if timeout expired, EOF if line dropped
++ dead, or -3 for any other error (see errno in that case). */
++
++static int
++do_mingw_readchar (struct serial *scb, int timeout)
++{
++ int status;
++ int delta;
++
++ /* We have to be able to keep the GUI alive here, so we break the original
++ timeout into steps of 1 second, running the "keep the GUI alive" hook
++ each time through the loop.
++
++ Also, timeout = 0 means to poll, so we just set the delta to 0, so we
++ will only go through the loop once. */
++
++ delta = (timeout == 0 ? 0 : 1);
++ while (1)
++ {
++
++ /* N.B. The UI may destroy our world (for instance by calling
++ remote_stop,) in which case we want to get out of here as
++ quickly as possible. It is not safe to touch scb, since
++ someone else might have freed it. The ui_loop_hook signals that
++ we should exit by returning 1. */
++
++ if (deprecated_ui_loop_hook)
++ {
++ if (deprecated_ui_loop_hook (0))
++ return SERIAL_TIMEOUT;
++ }
++
++ status = ser_mingw_wait_for (scb, delta);
++ if (timeout > 0)
++ timeout -= delta;
++
++ /* If we got a character or an error back from wait_for, then we can
++ break from the loop before the timeout is completed. */
++
++ if (status != SERIAL_TIMEOUT)
++ {
++ break;
++ }
++
++ /* If we have exhausted the original timeout, then generate
++ a SERIAL_TIMEOUT, and pass it out of the loop. */
++
++ else if (timeout == 0)
++ {
++ status = SERIAL_TIMEOUT;
++ break;
++ }
++ }
++
++ if (status < 0)
++ return status;
++
++ while (1)
++ {
++ status = recv (scb->fd, scb->buf, BUFSIZ, 0);
++ if (status != -1 || errno != EINTR)
++ break;
++ }
++
++ if (status <= 0)
++ {
++ if (status == 0)
++ return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
++ distinguish between EOF & timeouts
++ someday] */
++ else
++ return SERIAL_ERROR; /* Got an error from read */
++ }
++
++ scb->bufcnt = status;
++ scb->bufcnt--;
++ scb->bufp = scb->buf;
++ return *scb->bufp++;
++}
++
++/* Perform operations common to both old and new readchar. */
++
++/* Return the next character from the input FIFO. If the FIFO is
++ empty, call the SERIAL specific routine to try and read in more
++ characters.
++
++ Initially data from the input FIFO is returned (fd_event()
++ pre-reads the input into that FIFO. Once that has been emptied,
++ further data is obtained by polling the input FD using the device
++ specific readchar() function. Note: reschedule() is called after
++ every read. This is because there is no guarentee that the lower
++ level fd_event() poll_event() code (which also calls reschedule())
++ will be called. */
++
++static int
++generic_readchar (struct serial *scb, int timeout,
++ int (do_readchar) (struct serial *scb, int timeout))
++{
++ int ch;
++ if (scb->bufcnt > 0)
++ {
++ ch = *scb->bufp;
++ scb->bufcnt--;
++ scb->bufp++;
++ }
++ else if (scb->bufcnt < 0)
++ {
++ /* Some errors/eof are are sticky. */
++ ch = scb->bufcnt;
++ }
++ else
++ {
++ ch = do_readchar (scb, timeout);
++ if (ch < 0)
++ {
++ switch ((enum serial_rc) ch)
++ {
++ case SERIAL_EOF:
++ case SERIAL_ERROR:
++ /* Make the error/eof stick. */
++ scb->bufcnt = ch;
++ break;
++ case SERIAL_TIMEOUT:
++ scb->bufcnt = 0;
++ break;
++ }
++ }
++ }
++ reschedule (scb);
++ return ch;
++}
++
++int
++ser_mingw_readchar (struct serial *scb, int timeout)
++{
++ return generic_readchar (scb, timeout, do_mingw_readchar);
++}
++
++int
++ser_mingw_nop_noflush_set_tty_state (struct serial *scb,
++ serial_ttystate new_ttystate,
++ serial_ttystate old_ttystate)
++{
++ return 0;
++}
++
++void
++ser_mingw_nop_print_tty_state (struct serial *scb,
++ serial_ttystate ttystate,
++ struct ui_file *stream)
++{
++ /* Nothing to print. */
++ return;
++}
++
++int
++ser_mingw_nop_setbaudrate (struct serial *scb, int rate)
++{
++ return 0; /* Never fails! */
++}
++
++int
++ser_mingw_nop_setstopbits (struct serial *scb, int num)
++{
++ return 0; /* Never fails! */
++}
++
++int
++ser_mingw_write (struct serial *scb, const char *str, int len)
++{
++ int cc;
++
++ while (len > 0)
++ {
++ cc = send (scb->fd, str, len, 0);
++
++ if (cc < 0)
++ return 1;
++ len -= cc;
++ str += cc;
++ }
++ return 0;
++}
++
++int
++ser_mingw_nop_flush_output (struct serial *scb)
++{
++ return 0;
++}
++
++int
++ser_mingw_flush_input (struct serial *scb)
++{
++ if (scb->bufcnt >= 0)
++ {
++ scb->bufcnt = 0;
++ scb->bufp = scb->buf;
++ return 0;
++ }
++ else
++ return SERIAL_ERROR;
++}
++
++int
++ser_mingw_nop_send_break (struct serial *scb)
++{
++ return 0;
++}
++
++int
++ser_mingw_nop_drain_output (struct serial *scb)
++{
++ return 0;
++}
++
++
++
++/* Event handling for ASYNC serial code.
++
++ At any time the SERIAL device either: has an empty FIFO and is
++ waiting on a FD event; or has a non-empty FIFO/error condition and
++ is constantly scheduling timer events.
++
++ ASYNC only stops pestering its client when it is de-async'ed or it
++ is told to go away. */
++
++/* Value of scb->async_state: */
++enum {
++ /* >= 0 (TIMER_SCHEDULED) */
++ /* The ID of the currently scheduled timer event. This state is
++ rarely encountered. Timer events are one-off so as soon as the
++ event is delivered the state is shanged to NOTHING_SCHEDULED. */
++ FD_SCHEDULED = -1,
++ /* The fd_event() handler is scheduled. It is called when ever the
++ file descriptor becomes ready. */
++ NOTHING_SCHEDULED = -2
++ /* Either no task is scheduled (just going into ASYNC mode) or a
++ timer event has just gone off and the current state has been
++ forced into nothing scheduled. */
++};
++
++/* Identify and schedule the next ASYNC task based on scb->async_state
++ and scb->buf* (the input FIFO). A state machine is used to avoid
++ the need to make redundant calls into the event-loop - the next
++ scheduled task is only changed when needed. */
++
++static void
++reschedule (struct serial *scb)
++{
++ if (serial_is_async_p (scb))
++ {
++ int next_state;
++ switch (scb->async_state)
++ {
++ case FD_SCHEDULED:
++ if (scb->bufcnt == 0)
++ next_state = FD_SCHEDULED;
++ else
++ {
++ delete_file_handler (scb->fd);
++ next_state = create_timer (0, push_event, scb);
++ }
++ break;
++ case NOTHING_SCHEDULED:
++ if (scb->bufcnt == 0)
++ {
++ add_file_handler (scb->fd, fd_event, scb);
++ next_state = FD_SCHEDULED;
++ }
++ else
++ {
++ next_state = create_timer (0, push_event, scb);
++ }
++ break;
++ default: /* TIMER SCHEDULED */
++ if (scb->bufcnt == 0)
++ {
++ delete_timer (scb->async_state);
++ add_file_handler (scb->fd, fd_event, scb);
++ next_state = FD_SCHEDULED;
++ }
++ else
++ next_state = scb->async_state;
++ break;
++ }
++ if (serial_debug_p (scb))
++ {
++ switch (next_state)
++ {
++ case FD_SCHEDULED:
++ if (scb->async_state != FD_SCHEDULED)
++ fprintf_unfiltered (gdb_stdlog, "[fd%d->fd-scheduled]\n",
++ scb->fd);
++ break;
++ default: /* TIMER SCHEDULED */
++ if (scb->async_state == FD_SCHEDULED)
++ fprintf_unfiltered (gdb_stdlog, "[fd%d->timer-scheduled]\n",
++ scb->fd);
++ break;
++ }
++ }
++ scb->async_state = next_state;
++ }
++}
++
++/* FD_EVENT: This is scheduled when the input FIFO is empty (and there
++ is no pending error). As soon as data arrives, it is read into the
++ input FIFO and the client notified. The client should then drain
++ the FIFO using readchar(). If the FIFO isn't immediatly emptied,
++ push_event() is used to nag the client until it is. */
++
++static void
++fd_event (int error, void *context)
++{
++ struct serial *scb = context;
++ if (error != 0)
++ {
++ scb->bufcnt = SERIAL_ERROR;
++ }
++ else if (scb->bufcnt == 0)
++ {
++ /* Prime the input FIFO. The readchar() function is used to
++ pull characters out of the buffer. See also
++ generic_readchar(). */
++ int nr;
++ do
++ {
++ nr = read (scb->fd, scb->buf, BUFSIZ);
++ }
++ while (nr == -1 && errno == EINTR);
++ if (nr == 0)
++ {
++ scb->bufcnt = SERIAL_EOF;
++ }
++ else if (nr > 0)
++ {
++ scb->bufcnt = nr;
++ scb->bufp = scb->buf;
++ }
++ else
++ {
++ scb->bufcnt = SERIAL_ERROR;
++ }
++ }
++ scb->async_handler (scb, scb->async_context);
++ reschedule (scb);
++}
++
++/* PUSH_EVENT: The input FIFO is non-empty (or there is a pending
++ error). Nag the client until all the data has been read. In the
++ case of errors, the client will need to close or de-async the
++ device before naging stops. */
++
++static void
++push_event (void *context)
++{
++ struct serial *scb = context;
++ scb->async_state = NOTHING_SCHEDULED; /* Timers are one-off */
++ scb->async_handler (scb, scb->async_context);
++ /* re-schedule */
++ reschedule (scb);
++}
++
++/* Put the SERIAL device into/out-of ASYNC mode. */
++
++void
++ser_mingw_async (struct serial *scb,
++ int async_p)
++{
++ if (async_p)
++ {
++ /* Force a re-schedule. */
++ scb->async_state = NOTHING_SCHEDULED;
++ if (serial_debug_p (scb))
++ fprintf_unfiltered (gdb_stdlog, "[fd%d->asynchronous]\n",
++ scb->fd);
++ reschedule (scb);
++ }
++ else
++ {
++ if (serial_debug_p (scb))
++ fprintf_unfiltered (gdb_stdlog, "[fd%d->synchronous]\n",
++ scb->fd);
++ /* De-schedule whatever tasks are currently scheduled. */
++ switch (scb->async_state)
++ {
++ case FD_SCHEDULED:
++ delete_file_handler (scb->fd);
++ break;
++ NOTHING_SCHEDULED:
++ break;
++ default: /* TIMER SCHEDULED */
++ delete_timer (scb->async_state);
++ break;
++ }
++ }
++}
++
++void
++ser_platform_tcp_init (struct serial_ops *ops)
++{
++ ops->readchar = ser_mingw_readchar;
++ ops->write = ser_mingw_write;
++ ops->flush_output = ser_mingw_nop_flush_output;
++ ops->flush_input = ser_mingw_flush_input;
++ ops->send_break = ser_mingw_nop_send_break;
++ ops->go_raw = ser_mingw_nop_raw;
++ ops->get_tty_state = ser_mingw_nop_get_tty_state;
++ ops->set_tty_state = ser_mingw_nop_set_tty_state;
++ ops->print_tty_state = ser_mingw_nop_print_tty_state;
++ ops->noflush_set_tty_state = ser_mingw_nop_noflush_set_tty_state;
++ ops->setbaudrate = ser_mingw_nop_setbaudrate;
++ ops->setstopbits = ser_mingw_nop_setstopbits;
++ ops->drain_output = ser_mingw_nop_drain_output;
++ ops->async = ser_mingw_async;
++}
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/ser-mingw.h gdb-6.4-m68hc1x/gdb/ser-mingw.h
+--- gdb-6.4/gdb/ser-mingw.h Thu Jan 1 01:00:00 1970
++++ gdb-6.4-m68hc1x/gdb/ser-mingw.h Sat Jan 21 15:28:49 2006
+@@ -0,0 +1,51 @@
++/* Serial interface for MinGW Winsock file-descriptor based connection.
++
++ Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
++
++ This file is part of GDB.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place - Suite 330,
++ Boston, MA 02111-1307, USA. */
++
++#ifndef SER_MINGW_H
++#define SER_MINGW_H
++
++/* Generic MinGW Winsock functions */
++
++extern int ser_mingw_nop_flush_output (struct serial *scb);
++extern int ser_mingw_flush_input (struct serial *scb);
++extern int ser_mingw_nop_send_break (struct serial *scb);
++extern void ser_mingw_nop_raw (struct serial *scb);
++extern serial_ttystate ser_mingw_nop_get_tty_state (struct serial *scb);
++extern int ser_mingw_nop_set_tty_state (struct serial *scb,
++ serial_ttystate ttystate);
++extern void ser_mingw_nop_print_tty_state (struct serial *scb,
++ serial_ttystate ttystate,
++ struct ui_file *stream);
++extern int ser_mingw_nop_noflush_set_tty_state (struct serial *scb,
++ serial_ttystate new_ttystate,
++ serial_ttystate old_ttystate);
++extern int ser_mingw_nop_setbaudrate (struct serial *scb, int rate);
++extern int ser_mingw_nop_setstopbits (struct serial *scb, int rate);
++extern int ser_mingw_nop_drain_output (struct serial *scb);
++
++extern int ser_mingw_wait_for (struct serial *scb, int timeout);
++extern int ser_mingw_readchar (struct serial *scb, int timeout);
++
++extern int ser_mingw_write (struct serial *scb, const char *str, int len);
++
++extern void ser_mingw_async (struct serial *scb, int async_p);
++
++#endif
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/serial.c gdb-6.4-m68hc1x/gdb/serial.c
+--- gdb-6.4/gdb/serial.c Mon Feb 21 05:31:58 2005
++++ gdb-6.4-m68hc1x/gdb/serial.c Sat Jan 21 15:28:49 2006
+@@ -329,12 +329,16 @@ do_serial_close (struct serial *scb, int
+ void
+ serial_close (struct serial *scb)
+ {
++ if (!scb)
++ return;
+ do_serial_close (scb, 1);
+ }
+
+ void
+ serial_un_fdopen (struct serial *scb)
+ {
++ if (!scb)
++ return;
+ do_serial_close (scb, 0);
+ }
+
+@@ -343,6 +347,9 @@ serial_readchar (struct serial *scb, int
+ {
+ int ch;
+
++ if (!scb)
++ return 0;
++
+ /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC
+ code is finished. */
+ if (0 && serial_is_async_p (scb) && timeout < 0)
+@@ -384,6 +391,9 @@ serial_write (struct serial *scb, const
+ gdb_flush (serial_logfp);
+ }
+
++ if (!scb)
++ return 0;
++
+ return (scb->ops->write (scb, str, len));
+ }
+
+@@ -404,24 +414,33 @@ serial_printf (struct serial *desc, cons
+ int
+ serial_drain_output (struct serial *scb)
+ {
++ if (!scb)
++ return 0;
+ return scb->ops->drain_output (scb);
+ }
+
+ int
+ serial_flush_output (struct serial *scb)
+ {
++ if (!scb)
++ return 0;
+ return scb->ops->flush_output (scb);
+ }
+
+ int
+ serial_flush_input (struct serial *scb)
+ {
++ if (!scb)
++ return 0;
+ return scb->ops->flush_input (scb);
+ }
+
+ int
+ serial_send_break (struct serial *scb)
+ {
++ if (!scb)
++ return 0;
++
+ if (serial_logfp != NULL)
+ serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);
+
+@@ -431,18 +450,24 @@ serial_send_break (struct serial *scb)
+ void
+ serial_raw (struct serial *scb)
+ {
++ if (!scb)
++ return;
+ scb->ops->go_raw (scb);
+ }
+
+ serial_ttystate
+ serial_get_tty_state (struct serial *scb)
+ {
++ if (!scb)
++ return 0;
+ return scb->ops->get_tty_state (scb);
+ }
+
+ int
+ serial_set_tty_state (struct serial *scb, serial_ttystate ttystate)
+ {
++ if (!scb)
++ return 0;
+ return scb->ops->set_tty_state (scb, ttystate);
+ }
+
+@@ -451,6 +476,8 @@ serial_print_tty_state (struct serial *s
+ serial_ttystate ttystate,
+ struct ui_file *stream)
+ {
++ if (!scb)
++ return;
+ scb->ops->print_tty_state (scb, ttystate, stream);
+ }
+
+@@ -459,30 +486,40 @@ serial_noflush_set_tty_state (struct ser
+ serial_ttystate new_ttystate,
+ serial_ttystate old_ttystate)
+ {
++ if (!scb)
++ return 0;
+ return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
+ }
+
+ int
+ serial_setbaudrate (struct serial *scb, int rate)
+ {
++ if (!scb)
++ return 0;
+ return scb->ops->setbaudrate (scb, rate);
+ }
+
+ int
+ serial_setstopbits (struct serial *scb, int num)
+ {
++ if (!scb)
++ return 0;
+ return scb->ops->setstopbits (scb, num);
+ }
+
+ int
+ serial_can_async_p (struct serial *scb)
+ {
++ if (!scb)
++ return 0;
+ return (scb->ops->async != NULL);
+ }
+
+ int
+ serial_is_async_p (struct serial *scb)
+ {
++ if (!scb)
++ return 0;
+ return (scb->ops->async != NULL) && (scb->async_handler != NULL);
+ }
+
+@@ -491,6 +528,9 @@ serial_async (struct serial *scb,
+ serial_event_ftype *handler,
+ void *context)
+ {
++ if (!scb)
++ return;
++
+ /* Only change mode if there is a need. */
+ if ((scb->async_handler == NULL)
+ != (handler == NULL))
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/signals/signals.c gdb-6.4-m68hc1x/gdb/signals/signals.c
+--- gdb-6.4/gdb/signals/signals.c Sun Jun 8 20:27:14 2003
++++ gdb-6.4-m68hc1x/gdb/signals/signals.c Sat Jan 21 15:28:49 2006
+@@ -44,6 +44,11 @@
+ # endif
+ #endif
+
++/* SCz: We need SIGTRAP for interaction with the gdb simulator */
++#ifndef SIGTRAP
++# define SIGTRAP 5
++#endif
++
+ /* This table must match in order and size the signals in enum target_signal
+ in target.h. */
+ /* *INDENT-OFF* */
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/srec.h gdb-6.4-m68hc1x/gdb/srec.h
+--- gdb-6.4/gdb/srec.h Sat Apr 12 19:41:25 2003
++++ gdb-6.4-m68hc1x/gdb/srec.h Sat Jan 21 15:28:49 2006
+@@ -22,7 +22,8 @@ struct serial;
+
+ void load_srec (struct serial *desc, const char *file, bfd_vma load_offset,
+ int maxrecsize, int flags, int hashmark,
+- int (*waitack) (void));
++ int (*waitack) (void),
++ int (*serial_write) (struct serial*, char*, int));
+
+ /* S-record capability flags */
+
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/testsuite/ChangeLog.M68HC11 gdb-6.4-m68hc1x/gdb/testsuite/ChangeLog.M68HC11
+--- gdb-6.4/gdb/testsuite/ChangeLog.M68HC11 Thu Jan 1 01:00:00 1970
++++ gdb-6.4-m68hc1x/gdb/testsuite/ChangeLog.M68HC11 Sat Jan 21 15:28:49 2006
+@@ -0,0 +1,22 @@
++2002-11-13 Stephane Carrez <stcarrez@nerim.fr>
++
++ * gdb.base/huge.exp: Skip this test.
++ * gdb.fortran/types.exp: Likewise.
++ * gdb.fortran/exprs.exp: Don't run fortran float tests for 68HC11.
++
++2002-11-13 Stephane Carrez <stcarrez@nerim.fr>
++
++ * gdb.base/remote.exp: Compile remote.c with -mshort for 68HC11.
++ * gdb.base/printcmds.exp: Run the test after we are in the main.
++ * gdb.base/break.exp: Fix test because there is also a marker4()
++ at line 46.
++
++2002-08-12 Stephane Carrez <stcarrez@nerim.fr>
++
++ * gdb.trace/deltrace.exp: Don't fail if target does not support
++ trace points.
++ * gdb.trace/passcount.exp: Likewise.
++ * gdb.trace/save-trace.exp: Likewise.
++ * lib/gdb.exp: Don't run C++ test on 68HC11.
++ * gdb.threads/gcore-thread.exp: Don't run the test for 68HC11.
++ * gdb.asm/m68hc11.inc: New file.
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/testsuite/gdb.base/huge.exp gdb-6.4-m68hc1x/gdb/testsuite/gdb.base/huge.exp
+--- gdb-6.4/gdb/testsuite/gdb.base/huge.exp Mon Feb 2 06:15:27 2004
++++ gdb-6.4-m68hc1x/gdb/testsuite/gdb.base/huge.exp Sat Jan 21 15:28:49 2006
+@@ -32,7 +32,9 @@ set bug_id 0
+ if [target_info exists gdb,skip_huge_test] {
+ return;
+ }
+-
++if [istarget "m6811-*-*"] {
++ return;
++}
+ set testfile "huge"
+ set srcfile ${testfile}.c
+ set binfile ${objdir}/${subdir}/${testfile}
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/testsuite/gdb.base/printcmds.exp gdb-6.4-m68hc1x/gdb/testsuite/gdb.base/printcmds.exp
+--- gdb-6.4/gdb/testsuite/gdb.base/printcmds.exp Thu Feb 26 18:23:23 2004
++++ gdb-6.4-m68hc1x/gdb/testsuite/gdb.base/printcmds.exp Sat Jan 21 15:28:49 2006
+@@ -694,9 +694,9 @@ gdb_test "set print address off" ""
+ gdb_test "set width 0" ""
+
+ if [set_lang_c] then {
+- gdb_test "p ctable1\[120\]" "120 'x'" "p ctable1\[120\] #1"
+-
+ if [runto_main] then {
++ gdb_test "p ctable1\[120\]" "120 'x'" "p ctable1\[120\] #1"
++
+ test_integer_literals_accepted
+ test_integer_literals_rejected
+ test_character_literals_accepted
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/testsuite/gdb.base/remote.exp gdb-6.4-m68hc1x/gdb/testsuite/gdb.base/remote.exp
+--- gdb-6.4/gdb/testsuite/gdb.base/remote.exp Fri Sep 10 03:04:58 2004
++++ gdb-6.4-m68hc1x/gdb/testsuite/gdb.base/remote.exp Sat Jan 21 15:28:49 2006
+@@ -36,7 +36,12 @@ set binfile ${objdir}/${subdir}/${testfi
+
+ gdb_start
+
+-set result [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}]
++# Must compile remote.c with 16-bit int
++if [istarget "m6811-*-*"] then {
++ set result [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-mshort}]
++} else {
++ set result [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}]
++}
+ if {$result != "" } then {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/testsuite/gdb.fortran/exprs.exp gdb-6.4-m68hc1x/gdb/testsuite/gdb.fortran/exprs.exp
+--- gdb-6.4/gdb/testsuite/gdb.fortran/exprs.exp Tue Sep 20 08:37:03 2005
++++ gdb-6.4-m68hc1x/gdb/testsuite/gdb.fortran/exprs.exp Sat Jan 21 15:28:49 2006
+@@ -280,7 +280,9 @@ if [set_lang_fortran] then {
+ test_integer_literals_rejected
+ test_logical_literals_accepted
+ test_character_literals_accepted
+- test_float_literals_accepted
++ if {! [istarget "m6811-*-*"]} {
++ test_float_literals_accepted
++ }
+ test_arithmetic_expressions
+ } else {
+ warning "$test_name tests suppressed." 0
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/testsuite/gdb.fortran/types.exp gdb-6.4-m68hc1x/gdb/testsuite/gdb.fortran/types.exp
+--- gdb-6.4/gdb/testsuite/gdb.fortran/types.exp Mon Dec 16 20:33:53 2002
++++ gdb-6.4-m68hc1x/gdb/testsuite/gdb.fortran/types.exp Sat Jan 21 15:28:49 2006
+@@ -109,7 +109,9 @@ if [set_lang_fortran] then {
+ test_integer_literal_types_rejected
+ test_logical_literal_types_accepted
+ test_character_literal_types_accepted
+- test_float_literal_types_accepted
++ if {! [istarget "m6811-*-*"]} {
++ test_float_literal_types_accepted
++ }
+ } else {
+ warning "$test_name tests suppressed." 0
+ }
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/testsuite/gdb.threads/gcore-thread.exp gdb-6.4-m68hc1x/gdb/testsuite/gdb.threads/gcore-thread.exp
+--- gdb-6.4/gdb/testsuite/gdb.threads/gcore-thread.exp Mon Feb 2 06:15:27 2004
++++ gdb-6.4-m68hc1x/gdb/testsuite/gdb.threads/gcore-thread.exp Sat Jan 21 15:28:49 2006
+@@ -24,6 +24,11 @@ if $tracelevel then {
+ strace $tracelevel
+ }
+
++# Threads are not supported for 68HC11.
++if [istarget "m6811-*-*"] then {
++ return;
++}
++
+ set prms_id 0
+ set bug_id 0
+
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/testsuite/gdb.trace/deltrace.exp gdb-6.4-m68hc1x/gdb/testsuite/gdb.trace/deltrace.exp
+--- gdb-6.4/gdb/testsuite/gdb.trace/deltrace.exp Tue Apr 17 22:16:31 2001
++++ gdb-6.4-m68hc1x/gdb/testsuite/gdb.trace/deltrace.exp Sat Jan 21 15:28:49 2006
+@@ -50,6 +50,15 @@ gdb_reinitialize_dir $srcdir/$subdir
+
+ gdb_file_cmd $binfile
+
++
++# We generously give ourselves one "pass" if we successfully
++# detect that this test cannot be run on this target!
++if { ![gdb_target_supports_trace] } then {
++ pass "Current target does not supporst trace"
++ return 1;
++
++}
++
+ # define relative source line numbers:
+ # all subsequent line numbers are relative to this first one (baseline)
+ set baseline [gdb_find_recursion_test_baseline $srcfile];
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/testsuite/gdb.trace/passcount.exp gdb-6.4-m68hc1x/gdb/testsuite/gdb.trace/passcount.exp
+--- gdb-6.4/gdb/testsuite/gdb.trace/passcount.exp Tue Apr 17 22:16:31 2001
++++ gdb-6.4-m68hc1x/gdb/testsuite/gdb.trace/passcount.exp Sat Jan 21 15:28:49 2006
+@@ -49,6 +49,14 @@ gdb_reinitialize_dir $srcdir/$subdir
+
+ gdb_file_cmd $binfile
+
++# We generously give ourselves one "pass" if we successfully
++# detect that this test cannot be run on this target!
++if { ![gdb_target_supports_trace] } then {
++ pass "Current target does not supporst trace"
++ return 1;
++
++}
++
+ # define relative source line numbers:
+ # all subsequent line numbers are relative to this first one (baseline)
+ set baseline [gdb_find_recursion_test_baseline $srcfile];
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/testsuite/gdb.trace/save-trace.exp gdb-6.4-m68hc1x/gdb/testsuite/gdb.trace/save-trace.exp
+--- gdb-6.4/gdb/testsuite/gdb.trace/save-trace.exp Thu Aug 7 19:55:41 2003
++++ gdb-6.4-m68hc1x/gdb/testsuite/gdb.trace/save-trace.exp Sat Jan 21 15:28:49 2006
+@@ -58,6 +58,14 @@ if { $baseline == -1 } then {
+ return;
+ }
+
++# We generously give ourselves one "pass" if we successfully
++# detect that this test cannot be run on this target!
++if { ![gdb_target_supports_trace] } then {
++ pass "Current target does not supporst trace"
++ return 1;
++
++}
++
+ set testline1 [expr $baseline + 4]
+ set testline2 [expr $baseline + 5]
+ set testline3 [expr $baseline + 6]
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/gdb/testsuite/lib/gdb.exp gdb-6.4-m68hc1x/gdb/testsuite/lib/gdb.exp
+--- gdb-6.4/gdb/testsuite/lib/gdb.exp Wed Sep 28 00:39:03 2005
++++ gdb-6.4-m68hc1x/gdb/testsuite/lib/gdb.exp Sat Jan 21 15:28:49 2006
+@@ -1153,6 +1153,9 @@ proc skip_cplus_tests {} {
+ if { [istarget "m6812-*-*"] } {
+ return 1
+ }
++ if { [istarget "m6811-*-*"] } {
++ return 1
++ }
+ return 0
+ }
+
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/include/gdb/ChangeLog.M68HC11 gdb-6.4-m68hc1x/include/gdb/ChangeLog.M68HC11
+--- gdb-6.4/include/gdb/ChangeLog.M68HC11 Thu Jan 1 01:00:00 1970
++++ gdb-6.4-m68hc1x/include/gdb/ChangeLog.M68HC11 Sun Jan 22 22:19:11 2006
+@@ -0,0 +1,4 @@
++2006-01-22 Stephane Carrez <stcarrez@nerim.fr>
++
++ * remote-sim.h (SIGTRAP): Define for mingw32
++
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/include/gdb/remote-sim.h gdb-6.4-m68hc1x/include/gdb/remote-sim.h
+--- gdb-6.4/include/gdb/remote-sim.h Fri Feb 28 00:13:32 2003
++++ gdb-6.4-m68hc1x/include/gdb/remote-sim.h Sat Jan 21 17:57:30 2006
+@@ -22,6 +22,10 @@ Foundation, Inc., 59 Temple Place - Suit
+ #if !defined (REMOTE_SIM_H)
+ #define REMOTE_SIM_H 1
+
++#ifndef SIGTRAP
++#define SIGTRAP 5
++#endif
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/ChangeLog.M68HC11 gdb-6.4-m68hc1x/sim/common/ChangeLog.M68HC11
+--- gdb-6.4/sim/common/ChangeLog.M68HC11 Thu Jan 1 01:00:00 1970
++++ gdb-6.4-m68hc1x/sim/common/ChangeLog.M68HC11 Sat Jan 21 15:28:49 2006
+@@ -0,0 +1,44 @@
++2004-08-03 Stephane Carrez <stcarrez@nerim.fr>
++
++ * callback.c (os_ftruncate): Don't compile on Mingw32.
++ (os_truncate): Likewise.
++ (default_callback): Use null for the above
++
++2004-02-01 Stephane Carrez <stcarrez@nerim.fr>
++
++ * aclocal.m4 (SIM_AC_COMMON): Check for winsock.h and bind().
++
++2003-10-05 Stephane Carrez <stcarrez@nerim.fr>
++
++ From 2003-05-10 <fernando@seventh.com.br>
++ * sim-io.c (sim_io_poll_read): Fix reading of input keyboard on
++ Windows.
++
++2002-08-11 Stephane Carrez <stcarrez@nerim.fr>
++
++ * sim-core.h: Use address_word to specify the base and size
++ of the memory mapping (necessary when sizeof(address_word) >
++ sizeof(unsigned_word)).
++ * sim-memopt.h: Likewise.
++ * hw-base.c (panic_hw_io_read_buffer): Likewise.
++ (panic_hw_io_write_buffer): Likewise.
++ * sim-core.c (sim_core_write_buffer): Likewise for raddr.
++ (sim_core_read_buffer): Likewise.
++ * dv-glue.c (hw_glue_io_read_buffer): Likewise.
++ (hw_glue_io_write_buffer): Likewise.
++ * dv-pal.c (hw_pal_io_write_buffer): Likewise.
++ (hw_pal_io_read_buffer): Likewise.
++ * sim-hw.c (sim_hw_io_read_buffer): Likewise.
++ (sim_hw_io_write_buffer): Likewise.
++ (sim_cpu_hw_io_read_buffer): Likewise.
++ (sim_cpu_hw_io_write_buffer): Likewise.
++
++2002-08-11 Stephane Carrez <stcarrez@nerim.fr>
++
++ * hw-instances.c (panic_hw_instance_read): Use unsigned_cell for
++ the length to conform to hw_instance_read_method type.
++ * sim-profile.c (profile_print_addr_ranges): Compile only when
++ SIM_HAVE_ADDR_RANGE.
++ * sim-memopt.c: Include <unistd.h> for close prototype.
++ (do_memopt_add): Use %ld since bytes is a unsigned long.
++
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/aclocal.m4 gdb-6.4-m68hc1x/sim/common/aclocal.m4
+--- gdb-6.4/sim/common/aclocal.m4 Wed Mar 23 19:55:14 2005
++++ gdb-6.4-m68hc1x/sim/common/aclocal.m4 Sat Jan 21 15:28:49 2006
+@@ -53,11 +53,37 @@ AC_CHECK_HEADERS(stdlib.h string.h strin
+ AC_CHECK_HEADERS(sys/time.h sys/resource.h)
+ AC_CHECK_HEADERS(fcntl.h fpu_control.h)
+ AC_CHECK_HEADERS(dlfcn.h errno.h sys/stat.h)
++AC_CHECK_HEADERS(winsock.h)
+ AC_CHECK_FUNCS(getrusage time sigaction __setfpucw)
+
+ # Check for socket libraries
+ AC_CHECK_LIB(socket, bind)
+ AC_CHECK_LIB(nsl, gethostbyname)
++
++dnl Check for Windows socket library.
++dnl We need a special program that include <winsock.h> and we must not
++dnl define bind() because the winsock definition can be special
++dnl (The real symbol for bind() seems to be bind@12)
++ac_save_libs="$LIBS"
++LIBS="-lwsock32 ${LIBS}"
++
++AC_MSG_CHECKING([for bind in -lwsock32])
++AC_TRY_LINK([#include <winsock.h>
++],[
++ bind(0, 0, 0);
++],found=yes, found=no)
++AC_MSG_RESULT($found)
++if test $found = yes; then
++ ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
++ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
++ cat >> confdefs.h <<EOF
++#define $ac_tr_lib 1
++EOF
++ LIBS="-lwsock32 ${LIBS}"
++
++else
++ LIBS="$ac_save_libs"
++fi
+
+ . ${srcdir}/../../bfd/configure.host
+
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/callback.c gdb-6.4-m68hc1x/sim/common/callback.c
+--- gdb-6.4/sim/common/callback.c Fri Jul 8 10:05:35 2005
++++ gdb-6.4-m68hc1x/sim/common/callback.c Sat Jan 21 15:28:49 2006
+@@ -584,6 +584,7 @@ os_lstat (p, file, buf)
+ #endif
+ }
+
++#if !defined(__MINGW32__)
+ static int
+ os_ftruncate (p, fd, len)
+ host_callback *p;
+@@ -608,6 +609,7 @@ os_ftruncate (p, fd, len)
+ #endif
+ return result;
+ }
++#endif
+
+ static int
+ os_truncate (p, file, len)
+@@ -811,8 +813,12 @@ host_callback default_callback =
+ os_fstat,
+ os_lstat,
+
++#if defined(__MINGW32__)
++ 0, 0,
++#else
+ os_ftruncate,
+ os_truncate,
++#endif
+
+ os_pipe,
+ os_pipe_empty,
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/dv-glue.c gdb-6.4-m68hc1x/sim/common/dv-glue.c
+--- gdb-6.4/sim/common/dv-glue.c Tue May 18 23:20:07 2004
++++ gdb-6.4-m68hc1x/sim/common/dv-glue.c Sat Jan 21 15:28:49 2006
+@@ -278,7 +278,7 @@ static unsigned
+ hw_glue_io_read_buffer (struct hw *me,
+ void *dest,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes)
+ {
+ struct hw_glue *glue = (struct hw_glue *) hw_data (me);
+@@ -298,7 +298,7 @@ static unsigned
+ hw_glue_io_write_buffer (struct hw *me,
+ const void *source,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes)
+ {
+ struct hw_glue *glue = (struct hw_glue *) hw_data (me);
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/dv-pal.c gdb-6.4-m68hc1x/sim/common/dv-pal.c
+--- gdb-6.4/sim/common/dv-pal.c Sat Nov 23 02:12:05 2002
++++ gdb-6.4-m68hc1x/sim/common/dv-pal.c Sat Jan 21 15:28:49 2006
+@@ -341,7 +341,7 @@ static unsigned
+ hw_pal_io_read_buffer (struct hw *me,
+ void *dest,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes)
+ {
+ hw_pal_device *hw_pal = (hw_pal_device *) hw_data (me);
+@@ -426,7 +426,7 @@ static unsigned
+ hw_pal_io_write_buffer (struct hw *me,
+ const void *source,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes)
+ {
+ hw_pal_device *hw_pal = (hw_pal_device*) hw_data (me);
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/dv-sockser.c gdb-6.4-m68hc1x/sim/common/dv-sockser.c
+--- gdb-6.4/sim/common/dv-sockser.c Fri Aug 11 02:48:51 2000
++++ gdb-6.4-m68hc1x/sim/common/dv-sockser.c Sat Jan 21 15:28:49 2006
+@@ -42,6 +42,9 @@ with this program; if not, write to the
+ #include <errno.h>
+ #include <sys/types.h>
+ #include <sys/time.h>
++#ifdef _WIN32
++#include <winsock.h>
++#else
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+@@ -50,6 +53,7 @@ with this program; if not, write to the
+ #ifndef __CYGWIN32__
+ #include <netinet/tcp.h>
+ #endif
++#endif
+
+ #include "sim-assert.h"
+ #include "sim-options.h"
+@@ -198,6 +202,7 @@ dv_sockser_init (SIM_DESC sd)
+ return SIM_RC_OK;
+ }
+
++#ifdef SIGPIPE
+ /* Handle writes to missing client -> SIGPIPE.
+ ??? Need a central signal management module. */
+ {
+@@ -207,7 +212,7 @@ dv_sockser_init (SIM_DESC sd)
+ if (orig != SIG_DFL && orig != SIG_IGN)
+ signal (SIGPIPE, orig);
+ }
+-
++#endif
+ return SIM_RC_OK;
+ }
+
+@@ -274,6 +279,7 @@ connected_p (SIM_DESC sd)
+ if (sockser_fd < 0)
+ return 0;
+
++#ifdef F_GETFL
+ /* Set non-blocking i/o. */
+ flags = fcntl (sockser_fd, F_GETFL);
+ flags |= O_NONBLOCK | O_NDELAY;
+@@ -284,6 +290,7 @@ connected_p (SIM_DESC sd)
+ sockser_fd = -1;
+ return 0;
+ }
++#endif
+ return 1;
+ }
+
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/hw-base.c gdb-6.4-m68hc1x/sim/common/hw-base.c
+--- gdb-6.4/sim/common/hw-base.c Sat Nov 23 02:12:05 2002
++++ gdb-6.4-m68hc1x/sim/common/hw-base.c Sat Jan 21 15:28:49 2006
+@@ -217,7 +217,7 @@ static unsigned
+ panic_hw_io_read_buffer (struct hw *me,
+ void *dest,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes)
+ {
+ hw_abort (me, "no io-read method");
+@@ -228,7 +228,7 @@ static unsigned
+ panic_hw_io_write_buffer (struct hw *me,
+ const void *source,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes)
+ {
+ hw_abort (me, "no io-write method");
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/hw-device.h gdb-6.4-m68hc1x/sim/common/hw-device.h
+--- gdb-6.4/sim/common/hw-device.h Sat Nov 23 02:12:05 2002
++++ gdb-6.4-m68hc1x/sim/common/hw-device.h Sat Jan 21 15:28:49 2006
+@@ -231,7 +231,7 @@ typedef unsigned (hw_io_read_buffer_meth
+ (struct hw *me,
+ void *dest,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes);
+
+ #define hw_io_read_buffer(hw, dest, space, addr, nr_bytes) \
+@@ -244,7 +244,7 @@ typedef unsigned (hw_io_write_buffer_met
+ (struct hw *me,
+ const void *source,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes);
+
+ #define hw_io_write_buffer(hw, src, space, addr, nr_bytes) \
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/hw-instances.c gdb-6.4-m68hc1x/sim/common/hw-instances.c
+--- gdb-6.4/sim/common/hw-instances.c Sat Nov 23 02:12:05 2002
++++ gdb-6.4-m68hc1x/sim/common/hw-instances.c Sat Jan 21 15:28:49 2006
+@@ -126,7 +126,7 @@ hw_instance_delete (struct hw_instance *
+ static int
+ panic_hw_instance_read (struct hw_instance *instance,
+ void *addr,
+- unsigned_word len)
++ unsigned_cell len)
+ {
+ hw_abort (hw_instance_hw (instance), "no read method");
+ return -1;
+@@ -137,7 +137,7 @@ panic_hw_instance_read (struct hw_instan
+ static int
+ panic_hw_instance_write (struct hw_instance *instance,
+ const void *addr,
+- unsigned_word len)
++ unsigned_cell len)
+ {
+ hw_abort (hw_instance_hw (instance), "no write method");
+ return -1;
+@@ -146,8 +146,8 @@ panic_hw_instance_write (struct hw_insta
+
+ static int
+ panic_hw_instance_seek (struct hw_instance *instance,
+- unsigned_word pos_hi,
+- unsigned_word pos_lo)
++ unsigned_cell pos_hi,
++ unsigned_cell pos_lo)
+ {
+ hw_abort (hw_instance_hw (instance), "no seek method");
+ return -1;
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/sim-core.c gdb-6.4-m68hc1x/sim/common/sim-core.c
+--- gdb-6.4/sim/common/sim-core.c Fri Dec 19 12:43:56 2003
++++ gdb-6.4-m68hc1x/sim/common/sim-core.c Sat Jan 21 15:28:49 2006
+@@ -518,7 +518,7 @@ sim_core_read_buffer (SIM_DESC sd,
+ unsigned count = 0;
+ while (count < len)
+ {
+- unsigned_word raddr = addr + count;
++ address_word raddr = addr + count;
+ sim_core_mapping *mapping =
+ sim_core_find_mapping (core, map,
+ raddr, /*nr-bytes*/1,
+@@ -584,7 +584,7 @@ sim_core_write_buffer (SIM_DESC sd,
+ unsigned count = 0;
+ while (count < len)
+ {
+- unsigned_word raddr = addr + count;
++ address_word raddr = addr + count;
+ sim_core_mapping *mapping =
+ sim_core_find_mapping (core, map,
+ raddr, /*nr-bytes*/1,
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/sim-core.h gdb-6.4-m68hc1x/sim/common/sim-core.h
+--- gdb-6.4/sim/common/sim-core.h Sat Nov 23 02:12:05 2002
++++ gdb-6.4-m68hc1x/sim/common/sim-core.h Sat Jan 21 15:28:49 2006
+@@ -51,9 +51,9 @@ struct _sim_core_mapping {
+ /* common */
+ int level;
+ int space;
+- unsigned_word base;
+- unsigned_word bound;
+- unsigned_word nr_bytes;
++ address_word base;
++ address_word bound;
++ address_word nr_bytes;
+ unsigned mask;
+ /* memory map */
+ void *free_buffer;
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/sim-hw.c gdb-6.4-m68hc1x/sim/common/sim-hw.c
+--- gdb-6.4/sim/common/sim-hw.c Thu Jul 27 13:34:30 2000
++++ gdb-6.4-m68hc1x/sim/common/sim-hw.c Sat Jan 21 15:28:49 2006
+@@ -1,5 +1,5 @@
+ /* Simulator hardware option handling.
+- Copyright (C) 1998 Free Software Foundation, Inc.
++ Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+ Contributed by Cygnus Support and Andrew Cagney.
+
+ This file is part of GDB, the GNU debugger.
+@@ -339,7 +339,7 @@ sim_cpu_hw_io_read_buffer (sim_cpu *cpu,
+ struct hw *hw,
+ void *dest,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes)
+ {
+ SIM_DESC sd = CPU_STATE (cpu);
+@@ -355,7 +355,7 @@ sim_cpu_hw_io_write_buffer (sim_cpu *cpu
+ struct hw *hw,
+ const void *source,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes)
+ {
+ SIM_DESC sd = CPU_STATE (cpu);
+@@ -375,7 +375,7 @@ sim_hw_io_read_buffer (struct sim_state
+ struct hw *hw,
+ void *dest,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes)
+ {
+ STATE_HW (sd)->cpu = NULL;
+@@ -387,7 +387,7 @@ sim_hw_io_write_buffer (struct sim_state
+ struct hw *hw,
+ const void *source,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes)
+ {
+ STATE_HW (sd)->cpu = NULL;
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/sim-hw.h gdb-6.4-m68hc1x/sim/common/sim-hw.h
+--- gdb-6.4/sim/common/sim-hw.h Fri Apr 16 03:34:57 1999
++++ gdb-6.4-m68hc1x/sim/common/sim-hw.h Sat Jan 21 15:28:49 2006
+@@ -1,5 +1,5 @@
+ /* Device definitions.
+- Copyright (C) 1998 Free Software Foundation, Inc.
++ Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+
+ This file is part of GDB, the GNU debugger.
+@@ -62,7 +62,7 @@ void sim_cpu_hw_io_read_buffer
+ struct hw *hw,
+ void *dest,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes);
+
+ void sim_cpu_hw_io_write_buffer
+@@ -71,7 +71,7 @@ void sim_cpu_hw_io_write_buffer
+ struct hw *hw,
+ const void *source,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes);
+
+
+@@ -83,7 +83,7 @@ unsigned sim_hw_io_read_buffer
+ struct hw *hw,
+ void *dest,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes);
+
+ unsigned sim_hw_io_write_buffer
+@@ -91,7 +91,7 @@ unsigned sim_hw_io_write_buffer
+ struct hw *hw,
+ const void *source,
+ int space,
+- unsigned_word addr,
++ address_word addr,
+ unsigned nr_bytes);
+
+
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/sim-io.c gdb-6.4-m68hc1x/sim/common/sim-io.c
+--- gdb-6.4/sim/common/sim-io.c Sat Nov 23 02:12:05 2002
++++ gdb-6.4-m68hc1x/sim/common/sim-io.c Sat Jan 21 15:28:49 2006
+@@ -386,6 +386,15 @@ sim_io_poll_read (SIM_DESC sd,
+ }
+ return result;
+ #else
++#ifdef _WIN32
++ /* For Windows, use _kbhit() to see whether some input is available. */
++ if (sim_io_fd == STDIN_FILENO) {
++ int result = 0;
++ while (_kbhit() && result < sizeof_buf)
++ buf[result++] = _getch();
++ return result;
++ } else
++#endif
+ return sim_io_read (sd, sim_io_fd, buf, sizeof_buf);
+ #endif
+ }
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/sim-memopt.h gdb-6.4-m68hc1x/sim/common/sim-memopt.h
+--- gdb-6.4/sim/common/sim-memopt.h Tue Mar 20 18:13:39 2001
++++ gdb-6.4-m68hc1x/sim/common/sim-memopt.h Sat Jan 21 15:28:49 2006
+@@ -27,8 +27,8 @@ typedef struct _sim_memopt sim_memopt;
+ struct _sim_memopt {
+ int level;
+ int space;
+- unsigned_word addr;
+- unsigned_word nr_bytes;
++ address_word addr;
++ address_word nr_bytes;
+ unsigned modulo;
+ void *buffer;
+ unsigned long munmap_length;
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/sim-profile.c gdb-6.4-m68hc1x/sim/common/sim-profile.c
+--- gdb-6.4/sim/common/sim-profile.c Thu Feb 15 22:14:40 2001
++++ gdb-6.4-m68hc1x/sim/common/sim-profile.c Sat Jan 21 15:28:49 2006
+@@ -1050,6 +1050,7 @@ profile_print_speed (sim_cpu *cpu)
+ }
+ }
+
++#ifdef SIM_HAVE_ADDR_RANGE
+ /* Print selected address ranges. */
+
+ static void
+@@ -1070,6 +1071,7 @@ profile_print_addr_ranges (sim_cpu *cpu)
+ sim_io_printf (sd, "\n");
+ }
+ }
++#endif
+
+ /* Top level function to print all summary profile information.
+ It is [currently] intended that all such data is printed by this function.
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/sim-signal.c gdb-6.4-m68hc1x/sim/common/sim-signal.c
+--- gdb-6.4/sim/common/sim-signal.c Fri Apr 16 03:34:59 1999
++++ gdb-6.4-m68hc1x/sim/common/sim-signal.c Sat Jan 21 15:28:49 2006
+@@ -27,7 +27,7 @@ with this program; if not, write to the
+ to not think the process has died (so it can be debugged at the point of
+ failure). */
+
+-#ifdef _MSC_VER
++#if defined(_MSC_VER) || defined(__MINGW32__)
+ #ifndef SIGTRAP
+ #define SIGTRAP 5
+ #endif
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/common/sim-trace.c gdb-6.4-m68hc1x/sim/common/sim-trace.c
+--- gdb-6.4/sim/common/sim-trace.c Fri Oct 31 06:32:46 2003
++++ gdb-6.4-m68hc1x/sim/common/sim-trace.c Sat Jan 21 15:28:49 2006
+@@ -241,7 +241,9 @@ trace_option_handler (SIM_DESC sd, sim_c
+ char *arg, int is_command)
+ {
+ int n;
++#ifdef SIM_HAVE_ADDR_RANGE
+ int cpu_nr;
++#endif
+
+ switch (opt)
+ {
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/m68hc11/configure gdb-6.4-m68hc1x/sim/m68hc11/configure
+--- gdb-6.4/sim/m68hc11/configure Wed Mar 23 19:55:17 2005
++++ gdb-6.4-m68hc1x/sim/m68hc11/configure Sat Jan 21 15:28:49 2006
+@@ -6800,6 +6800,45 @@ _ACEOF
+ fi
+
+
++ac_save_libs="$LIBS"
++LIBS="-lwsock32 ${LIBS}"
++
++echo $ac_n "checking for bind in -lwsock32""... $ac_c" 1>&6
++echo "configure:3297: checking for bind in -lwsock32" >&5
++cat > conftest.$ac_ext <<EOF
++#line 3299 "configure"
++#include "confdefs.h"
++#include <winsock.h>
++
++int main() {
++
++ bind(0, 0, 0);
++
++; return 0; }
++EOF
++if { (eval echo configure:3309: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
++ rm -rf conftest*
++ found=yes
++else
++ echo "configure: failed program was:" >&5
++ cat conftest.$ac_ext >&5
++ rm -rf conftest*
++ found=no
++fi
++rm -f conftest*
++echo "$ac_t""$found" 1>&6
++if test $found = yes; then
++ ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/^a-zA-Z0-9_/_/g' \
++ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
++ cat >> confdefs.h <<EOF
++#define $ac_tr_lib 1
++EOF
++ LIBS="-lwsock32 ${LIBS}"
++
++else
++ LIBS="$ac_save_libs"
++fi
++
+ . ${srcdir}/../../bfd/configure.host
+
+
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/m68hc11/dv-m68hc11.c gdb-6.4-m68hc1x/sim/m68hc11/dv-m68hc11.c
+--- gdb-6.4/sim/m68hc11/dv-m68hc11.c Fri Aug 8 23:00:55 2003
++++ gdb-6.4-m68hc1x/sim/m68hc11/dv-m68hc11.c Sat Jan 21 15:28:50 2006
+@@ -831,7 +831,7 @@ static unsigned
+ m68hc11cpu_io_read_buffer (struct hw *me,
+ void *dest,
+ int space,
+- unsigned_word base,
++ address_word base,
+ unsigned nr_bytes)
+ {
+ SIM_DESC sd;
+@@ -981,7 +981,7 @@ m68hc11cpu_set_port (struct hw *me, sim_
+
+ static void
+ m68hc11cpu_io_write (struct hw *me, sim_cpu *cpu,
+- unsigned_word addr, uint8 val)
++ address_word addr, uint8 val)
+ {
+ switch (addr)
+ {
+@@ -1079,7 +1079,7 @@ static unsigned
+ m68hc11cpu_io_write_buffer (struct hw *me,
+ const void *source,
+ int space,
+- unsigned_word base,
++ address_word base,
+ unsigned nr_bytes)
+ {
+ SIM_DESC sd;
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/m68hc11/dv-m68hc11eepr.c gdb-6.4-m68hc1x/sim/m68hc11/dv-m68hc11eepr.c
+--- gdb-6.4/sim/m68hc11/dv-m68hc11eepr.c Tue Aug 13 11:01:16 2002
++++ gdb-6.4-m68hc1x/sim/m68hc11/dv-m68hc11eepr.c Sat Jan 21 15:28:50 2006
+@@ -393,7 +393,7 @@ static unsigned
+ m68hc11eepr_io_read_buffer (struct hw *me,
+ void *dest,
+ int space,
+- unsigned_word base,
++ address_word base,
+ unsigned nr_bytes)
+ {
+ SIM_DESC sd;
+@@ -448,7 +448,7 @@ static unsigned
+ m68hc11eepr_io_write_buffer (struct hw *me,
+ const void *source,
+ int space,
+- unsigned_word base,
++ address_word base,
+ unsigned nr_bytes)
+ {
+ SIM_DESC sd;
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/m68hc11/dv-m68hc11sio.c gdb-6.4-m68hc1x/sim/m68hc11/dv-m68hc11sio.c
+--- gdb-6.4/sim/m68hc11/dv-m68hc11sio.c Fri Aug 8 23:02:24 2003
++++ gdb-6.4-m68hc1x/sim/m68hc11/dv-m68hc11sio.c Sat Jan 21 15:28:50 2006
+@@ -492,7 +492,7 @@ static unsigned
+ m68hc11sio_io_read_buffer (struct hw *me,
+ void *dest,
+ int space,
+- unsigned_word base,
++ address_word base,
+ unsigned nr_bytes)
+ {
+ SIM_DESC sd;
+@@ -537,7 +537,7 @@ static unsigned
+ m68hc11sio_io_write_buffer (struct hw *me,
+ const void *source,
+ int space,
+- unsigned_word base,
++ address_word base,
+ unsigned nr_bytes)
+ {
+ SIM_DESC sd;
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/m68hc11/dv-m68hc11spi.c gdb-6.4-m68hc1x/sim/m68hc11/dv-m68hc11spi.c
+--- gdb-6.4/sim/m68hc11/dv-m68hc11spi.c Fri Aug 8 23:02:24 2003
++++ gdb-6.4-m68hc1x/sim/m68hc11/dv-m68hc11spi.c Sat Jan 21 15:28:50 2006
+@@ -381,7 +381,7 @@ static unsigned
+ m68hc11spi_io_read_buffer (struct hw *me,
+ void *dest,
+ int space,
+- unsigned_word base,
++ address_word base,
+ unsigned nr_bytes)
+ {
+ SIM_DESC sd;
+@@ -426,7 +426,7 @@ static unsigned
+ m68hc11spi_io_write_buffer (struct hw *me,
+ const void *source,
+ int space,
+- unsigned_word base,
++ address_word base,
+ unsigned nr_bytes)
+ {
+ SIM_DESC sd;
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/m68hc11/dv-m68hc11tim.c gdb-6.4-m68hc1x/sim/m68hc11/dv-m68hc11tim.c
+--- gdb-6.4/sim/m68hc11/dv-m68hc11tim.c Fri Aug 8 23:02:24 2003
++++ gdb-6.4-m68hc1x/sim/m68hc11/dv-m68hc11tim.c Sat Jan 21 15:28:50 2006
+@@ -638,7 +638,7 @@ static unsigned
+ m68hc11tim_io_read_buffer (struct hw *me,
+ void *dest,
+ int space,
+- unsigned_word base,
++ address_word base,
+ unsigned nr_bytes)
+ {
+ SIM_DESC sd;
+@@ -687,7 +687,7 @@ static unsigned
+ m68hc11tim_io_write_buffer (struct hw *me,
+ const void *source,
+ int space,
+- unsigned_word base,
++ address_word base,
+ unsigned nr_bytes)
+ {
+ SIM_DESC sd;
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/m68hc11/dv-nvram.c gdb-6.4-m68hc1x/sim/m68hc11/dv-nvram.c
+--- gdb-6.4/sim/m68hc11/dv-nvram.c Fri Nov 24 21:53:35 2000
++++ gdb-6.4-m68hc1x/sim/m68hc11/dv-nvram.c Sat Jan 21 15:28:50 2006
+@@ -258,7 +258,7 @@ static unsigned
+ nvram_io_read_buffer (struct hw *me,
+ void *dest,
+ int space,
+- unsigned_word base,
++ address_word base,
+ unsigned nr_bytes)
+ {
+ struct nvram *controller = hw_data (me);
+@@ -281,7 +281,7 @@ static unsigned
+ nvram_io_write_buffer (struct hw *me,
+ const void *source,
+ int space,
+- unsigned_word base,
++ address_word base,
+ unsigned nr_bytes)
+ {
+ struct nvram *controller = hw_data (me);
+diff --exclude-from=exclude.lst -Nrup gdb-6.4/sim/m68hc11/m68hc11_sim.c gdb-6.4-m68hc1x/sim/m68hc11/m68hc11_sim.c
+--- gdb-6.4/sim/m68hc11/m68hc11_sim.c Fri Aug 8 23:00:55 2003
++++ gdb-6.4-m68hc1x/sim/m68hc11/m68hc11_sim.c Sat Jan 21 15:28:50 2006
+@@ -291,8 +291,8 @@ cpu_get_indexed_operand_addr (sim_cpu* c
+ return 0;
+ }
+ reg = (code >> 3) & 0x03;
+- addr = cpu_get_reg (cpu, reg);
+- addr += cpu_fetch16 (cpu);
++ addr = cpu_fetch16 (cpu);
++ addr += cpu_get_reg (cpu, reg);
+ addr = memory_read16 (cpu, addr);
+ cpu_add_cycles (cpu, 1);
+ }
+@@ -765,7 +765,7 @@ cpu_special (sim_cpu *cpu, enum M6811_Sp
+ case M6811_WAI:
+ /* In the ELF-start mode, we are in a special mode where
+ the WAI corresponds to an exit. */
+- if (cpu->cpu_use_elf_start)
++ if (cpu->cpu_use_elf_start || 1)
+ {
+ cpu_set_pc (cpu, cpu->cpu_insn_pc);
+ sim_engine_halt (CPU_STATE (cpu), cpu,
diff --git a/misc/buildroot/toolchain/gdb/6.8/600-fix-compile-flag-mismatch.patch b/misc/buildroot/toolchain/gdb/6.8/600-fix-compile-flag-mismatch.patch
new file mode 100644
index 000000000..13b72bb96
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/6.8/600-fix-compile-flag-mismatch.patch
@@ -0,0 +1,31 @@
+--- a/gdb/gdbserver/configure
++++ b/gdb/gdbserver/configure
+@@ -1239,7 +1239,7 @@
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+- if test "x$ac_old_val" != "x$ac_new_val"; then
++ if test "`echo x$ac_old_val`" != "`echo x$ac_new_val`"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+ echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+--- a/gdb/configure
++++ b/gdb/configure
+@@ -272,7 +272,7 @@
+ PACKAGE_BUGREPORT=
+
+ ac_unique_file="main.c"
+-ac_subdirs_all="$ac_subdirs_all doc testsuite"
++ac_subdirs_all="$ac_subdirs_all doc"
+ # Factoring default headers for most tests.
+ ac_includes_default="\
+ #include <stdio.h>
+@@ -3077,7 +3077,7 @@
+
+
+
+-subdirs="$subdirs doc testsuite"
++subdirs="$subdirs doc"
+
+
+ # Provide defaults for some variables set by the per-host and per-target
diff --git a/misc/buildroot/toolchain/gdb/Config.in b/misc/buildroot/toolchain/gdb/Config.in
new file mode 100644
index 000000000..fbea5b143
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/Config.in
@@ -0,0 +1,48 @@
+comment "Gdb Options"
+
+config BR2_PACKAGE_GDB
+ bool "Build gdb debugger for the Target"
+ default n
+ help
+ Build the full gdb debugger to run on the target.
+
+config BR2_PACKAGE_GDB_SERVER
+ bool "Build gdb server for the Target"
+ default n
+ help
+ Build the gdbserver stub to run on the target.
+ A full gdb is needed to debug the progam.
+
+config BR2_PACKAGE_GDB_HOST
+ bool "Build gdb for the Host"
+ default n
+ help
+ Build gdb to run on the host to debug programs run on the target.
+
+choice
+ prompt "GDB debugger Version"
+ default BR2_GDB_VERSION_6_8 if !BR2_avr32 && !BR2_m9s12x
+ default BR2_GDB_VERSION_6_4 if BR2_m9s12x
+ default BR2_GDB_VERSION_6_3 if BR2_avr32
+ depends on BR2_PACKAGE_GDB || BR2_PACKAGE_GDB_SERVER || BR2_PACKAGE_GDB_HOST
+ help
+ Select the version of gdb you wish to use.
+
+ config BR2_GDB_VERSION_6_3
+ bool "gdb 6.3"
+ depends on !BR2_avr32 && !BR2_nios2
+
+ config BR2_GDB_VERSION_6_4
+ bool "gdb 6.3"
+ depends on BR2_m9s12x
+
+ config BR2_GDB_VERSION_6_8
+ bool "gdb 6.8"
+ depends on !BR2_avr32
+
+endchoice
+
+config BR2_GDB_VERSION
+ string
+ default "6.3" if BR2_GDB_VERSION_6_3
+ default "6.8" if BR2_GDB_VERSION_6_8
diff --git a/misc/buildroot/toolchain/gdb/gdb.mk b/misc/buildroot/toolchain/gdb/gdb.mk
new file mode 100644
index 000000000..aa9e126bc
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/gdb.mk
@@ -0,0 +1,224 @@
+######################################################################
+#
+# gdb
+#
+######################################################################
+GDB_VERSION:=$(strip $(subst ",, $(BR2_GDB_VERSION)))
+
+ifeq ($(GDB_VERSION),snapshot)
+# Be aware that this changes daily....
+GDB_SITE:=ftp://sources.redhat.com/pub/gdb/snapshots/current
+GDB_SOURCE:=gdb.tar.bz2
+GDB_CAT:=$(BZCAT)
+GDB_DIR:=$(TOOL_BUILD_DIR)/gdb-$(GDB_VERSION)
+else
+GDB_SITE:=http://ftp.gnu.org/gnu/gdb
+GDB_SOURCE:=gdb-$(GDB_VERSION).tar.bz2
+GDB_CAT:=$(BZCAT)
+
+GDB_DIR:=$(TOOL_BUILD_DIR)/gdb-$(GDB_VERSION)
+
+# NOTE: This option should not be used with gdb versions 6.4 and above.
+
+ifeq ($(GDB_VERSION),6.3)
+DISABLE_GDBMI:=--disable-gdbmi
+endif
+endif
+
+$(DL_DIR)/$(GDB_SOURCE):
+ $(WGET) -P $(DL_DIR) $(GDB_SITE)/$(GDB_SOURCE)
+
+gdb-unpacked: $(GDB_DIR)/.unpacked
+$(GDB_DIR)/.unpacked: $(DL_DIR)/$(GDB_SOURCE)
+ $(GDB_CAT) $(DL_DIR)/$(GDB_SOURCE) | tar -C $(TOOL_BUILD_DIR) $(TAR_OPTIONS) -
+ifeq ($(GDB_VERSION),snapshot)
+ GDB_REAL_DIR=$(shell \
+ tar jtf $(DL_DIR)/$(GDB_SOURCE) | head -1 | cut -d"/" -f1)
+ ln -sf $(TOOL_BUILD_DIR)/$(shell tar jtf $(DL_DIR)/$(GDB_SOURCE) | head -1 | cut -d"/" -f1) $(GDB_DIR)
+endif
+ toolchain/patch-kernel.sh $(GDB_DIR) toolchain/gdb/$(GDB_VERSION) \*.patch
+ $(CONFIG_UPDATE) $(GDB_DIR)
+ touch $(GDB_DIR)/.unpacked
+
+gdb-dirclean:
+ rm -rf $(GDB_DIR)
+
+######################################################################
+#
+# gdb target
+#
+######################################################################
+
+GDB_TARGET_DIR:=$(BUILD_DIR)/gdb-$(GDB_VERSION)-target
+
+GDB_TARGET_CONFIGURE_VARS:= \
+ ac_cv_type_uintptr_t=yes \
+ gt_cv_func_gettext_libintl=yes \
+ ac_cv_func_dcgettext=yes \
+ gdb_cv_func_sigsetjmp=yes \
+ bash_cv_func_strcoll_broken=no \
+ bash_cv_must_reinstall_sighandlers=no \
+ bash_cv_func_sigsetjmp=present \
+ bash_cv_have_mbstate_t=yes
+
+$(GDB_TARGET_DIR)/.configured: $(GDB_DIR)/.unpacked
+ mkdir -p $(GDB_TARGET_DIR)
+ (cd $(GDB_TARGET_DIR); \
+ gdb_cv_func_sigsetjmp=yes \
+ $(TARGET_CONFIGURE_OPTS) \
+ CFLAGS_FOR_TARGET="$(TARGET_CFLAGS) $(TARGET_LDFLAGS)" \
+ CFLAGS="$(TARGET_CFLAGS) $(TARGET_LDFLAGS)" \
+ $(GDB_TARGET_CONFIGURE_VARS) \
+ $(GDB_DIR)/configure \
+ --build=$(GNU_HOST_NAME) \
+ --host=$(REAL_GNU_TARGET_NAME) \
+ --target=$(REAL_GNU_TARGET_NAME) \
+ --prefix=/usr \
+ $(DISABLE_NLS) \
+ --without-uiout $(DISABLE_GDBMI) \
+ --disable-tui --disable-gdbtk --without-x \
+ --disable-sim --enable-gdbserver \
+ --without-included-gettext \
+ --disable-werror \
+ );
+ifeq ($(BR2_ENABLE_LOCALE),y)
+ -$(SED) "s,^INTL *=.*,INTL = -lintl,g;" $(GDB_DIR)/gdb/Makefile
+endif
+ touch $(GDB_TARGET_DIR)/.configured
+
+$(GDB_TARGET_DIR)/gdb/gdb: $(GDB_TARGET_DIR)/.configured
+ $(MAKE) CC=$(TARGET_CC) MT_CFLAGS="$(TARGET_CFLAGS)" \
+ -C $(GDB_TARGET_DIR)
+ $(STRIP) $(GDB_TARGET_DIR)/gdb/gdb
+
+$(TARGET_DIR)/usr/bin/gdb: $(GDB_TARGET_DIR)/gdb/gdb
+ install -c -D $(GDB_TARGET_DIR)/gdb/gdb $(TARGET_DIR)/usr/bin/gdb
+
+gdb_target: $(TARGET_DIR)/usr/bin/gdb
+
+gdb_target-source: $(DL_DIR)/$(GDB_SOURCE)
+
+gdb_target-clean:
+ @if [ -d $(GDB_DIR)/Makefile ] ; then \
+ $(MAKE) -C $(GDB_DIR) clean ; \
+ fi;
+
+gdb_target-dirclean:
+ rm -rf $(GDB_DIR)
+
+######################################################################
+#
+# gdbserver
+#
+######################################################################
+
+GDB_SERVER_DIR:=$(BUILD_DIR)/gdbserver-$(GDB_VERSION)
+
+$(GDB_SERVER_DIR)/.configured: $(GDB_DIR)/.unpacked
+ mkdir -p $(GDB_SERVER_DIR)
+ (cd $(GDB_SERVER_DIR); \
+ $(TARGET_CONFIGURE_OPTS) \
+ gdb_cv_func_sigsetjmp=yes \
+ $(GDB_DIR)/gdb/gdbserver/configure \
+ --build=$(GNU_HOST_NAME) \
+ --host=$(REAL_GNU_TARGET_NAME) \
+ --target=$(REAL_GNU_TARGET_NAME) \
+ --prefix=/usr \
+ --exec-prefix=/usr \
+ --bindir=/usr/bin \
+ --sbindir=/usr/sbin \
+ --libexecdir=/usr/lib \
+ --sysconfdir=/etc \
+ --datadir=/usr/share \
+ --localstatedir=/var \
+ --mandir=/usr/man \
+ --infodir=/usr/info \
+ --includedir=$(STAGING_DIR)/include \
+ $(DISABLE_NLS) \
+ --without-uiout $(DISABLE_GDBMI) \
+ --disable-tui --disable-gdbtk --without-x \
+ --without-included-gettext \
+ );
+ touch $(GDB_SERVER_DIR)/.configured
+
+$(GDB_SERVER_DIR)/gdbserver: $(GDB_SERVER_DIR)/.configured
+ $(MAKE) CC=$(TARGET_CC) MT_CFLAGS="$(TARGET_CFLAGS)" \
+ -C $(GDB_SERVER_DIR)
+ $(STRIP) $(GDB_SERVER_DIR)/gdbserver
+$(TARGET_DIR)/usr/bin/gdbserver: $(GDB_SERVER_DIR)/gdbserver
+ install -c -D $(GDB_SERVER_DIR)/gdbserver $(TARGET_DIR)/usr/bin/gdbserver
+
+gdbserver: $(TARGET_DIR)/usr/bin/gdbserver
+
+gdbserver-clean:
+ @if [ -d $(GDB_SERVER_DIR)/Makefile ] ; then \
+ $(MAKE) -C $(GDB_SERVER_DIR) clean ; \
+ fi;
+
+gdbserver-dirclean:
+ rm -rf $(GDB_SERVER_DIR)
+
+######################################################################
+#
+# gdb on host
+#
+######################################################################
+
+GDB_HOST_DIR:=$(TOOL_BUILD_DIR)/gdbhost-$(GDB_VERSION)
+
+$(GDB_HOST_DIR)/.configured: $(GDB_DIR)/.unpacked
+ mkdir -p $(GDB_HOST_DIR)
+ (cd $(GDB_HOST_DIR); \
+ gdb_cv_func_sigsetjmp=yes \
+ $(GDB_DIR)/configure \
+ --prefix=$(STAGING_DIR) \
+ --build=$(GNU_HOST_NAME) \
+ --host=$(GNU_HOST_NAME) \
+ --target=$(REAL_GNU_TARGET_NAME) \
+ $(DISABLE_NLS) \
+ --without-uiout $(DISABLE_GDBMI) \
+ --disable-tui --disable-gdbtk --without-x \
+ --without-included-gettext \
+ --enable-threads \
+ );
+ touch $(GDB_HOST_DIR)/.configured
+
+$(GDB_HOST_DIR)/gdb/gdb: $(GDB_HOST_DIR)/.configured
+ $(MAKE) -C $(GDB_HOST_DIR)
+ strip $(GDB_HOST_DIR)/gdb/gdb
+
+$(TARGET_CROSS)gdb: $(GDB_HOST_DIR)/gdb/gdb
+ install -c $(GDB_HOST_DIR)/gdb/gdb $(TARGET_CROSS)gdb
+ ln -snf ../../bin/$(REAL_GNU_TARGET_NAME)-gdb \
+ $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/bin/gdb
+ ln -snf $(REAL_GNU_TARGET_NAME)-gdb \
+ $(STAGING_DIR)/bin/$(GNU_TARGET_NAME)-gdb
+
+gdbhost: $(TARGET_CROSS)gdb
+
+gdbhost-clean:
+ @if [ -d $(GDB_HOST_DIR)/Makefile ] ; then \
+ $(MAKE) -C $(GDB_HOST_DIR) clean ; \
+ fi;
+
+gdbhost-dirclean:
+ rm -rf $(GDB_HOST_DIR)
+
+
+
+#############################################################
+#
+# Toplevel Makefile options
+#
+#############################################################
+ifeq ($(strip $(BR2_PACKAGE_GDB)),y)
+TARGETS+=gdb_target
+endif
+
+ifeq ($(strip $(BR2_PACKAGE_GDB_SERVER)),y)
+TARGETS+=gdbserver
+endif
+
+ifeq ($(strip $(BR2_PACKAGE_GDB_HOST)),y)
+TARGETS+=gdbhost
+endif
diff --git a/misc/buildroot/toolchain/gdb/snapshot/400-mips-coredump.patch-2.4.23-29 b/misc/buildroot/toolchain/gdb/snapshot/400-mips-coredump.patch-2.4.23-29
new file mode 100644
index 000000000..b7136bf8a
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/snapshot/400-mips-coredump.patch-2.4.23-29
@@ -0,0 +1,30 @@
+Sometime around 2.4.22-23, the mips pt_regs.h fields were reordered, breaking
+coredump handling by gdb for current kernels. Update the hardcoded constants
+to reflect the change.
+--
+diff -urN gdb-6.3.50.20050915/gdb/mips-linux-tdep.c gdb-6.3.50.20050915-patched/gdb/mips-linux-tdep.c
+--- gdb-6.3.50.20050915/gdb/mips-linux-tdep.c 2005-04-02 16:59:34.000000000 -0600
++++ gdb-6.3.50.20050915-patched/gdb/mips-linux-tdep.c 2005-09-15 22:33:13.000000000 -0500
+@@ -54,12 +54,22 @@
+
+ #define EF_REG0 6
+ #define EF_REG31 37
++
++#if 0
+ #define EF_LO 38
+ #define EF_HI 39
+ #define EF_CP0_EPC 40
+ #define EF_CP0_BADVADDR 41
+ #define EF_CP0_STATUS 42
+ #define EF_CP0_CAUSE 43
++#else
++#define EF_CP0_STATUS 38
++#define EF_LO 39
++#define EF_HI 40
++#define EF_CP0_BADVADDR 41
++#define EF_CP0_CAUSE 42
++#define EF_CP0_EPC 43
++#endif
+
+ #define EF_SIZE 180
+
diff --git a/misc/buildroot/toolchain/gdb/snapshot/400-mips-nptl-support.patch b/misc/buildroot/toolchain/gdb/snapshot/400-mips-nptl-support.patch
new file mode 100644
index 000000000..50be6ac41
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/snapshot/400-mips-nptl-support.patch
@@ -0,0 +1,143 @@
+2005-03-17 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * linux-mips-low.c: Include "gdb_proc_service.h".
+ (PTRACE_GET_THREAD_AREA): Define.
+ (ps_get_thread_area): New function.
+ * Makefile.in: Update dependencies for linux-mips-low.o,
+ linux-i386-low.o, and linux-x86-64-low.o.
+
+2005-03-17 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * linux-mips-low.c: Include "gdb_proc_service.h".
+ (PTRACE_GET_THREAD_AREA): Define.
+ (ps_get_thread_area): New function.
+ * Makefile.in (mips-linux-nat.o): Update dependencies.
+--
+diff -urN gdb-6.3.50.20050915/gdb/Makefile.in gdb-6.3.50.20050915-patched/gdb/Makefile.in
+--- gdb-6.3.50.20050915/gdb/Makefile.in 2005-09-10 13:11:01.000000000 -0500
++++ gdb-6.3.50.20050915-patched/gdb/Makefile.in 2005-09-15 19:24:39.000000000 -0500
+@@ -2282,7 +2282,7 @@
+ $(gdb_string_h) $(mips_tdep_h) $(solib_svr4_h)
+ mips-irix-tdep.o: mips-irix-tdep.c $(defs_h) $(osabi_h) $(elf_bfd_h)
+ mips-linux-nat.o: mips-linux-nat.c $(defs_h) $(mips_tdep_h) $(target_h) \
+- $(linux_nat_h)
++ $(linux_nat_h) $(gdb_proc_service_h)
+ mips-linux-tdep.o: mips-linux-tdep.c $(defs_h) $(gdbcore_h) $(target_h) \
+ $(solib_svr4_h) $(osabi_h) $(mips_tdep_h) $(gdb_string_h) \
+ $(gdb_assert_h) $(frame_h) $(regcache_h) $(trad_frame_h) \
+diff -urN gdb-6.3.50.20050915/gdb/gdbserver/Makefile.in gdb-6.3.50.20050915-patched/gdb/gdbserver/Makefile.in
+--- gdb-6.3.50.20050915/gdb/gdbserver/Makefile.in 2005-05-28 17:09:04.000000000 -0500
++++ gdb-6.3.50.20050915-patched/gdb/gdbserver/Makefile.in 2005-09-15 19:20:01.000000000 -0500
+@@ -267,15 +267,18 @@
+ linux-arm-low.o: linux-arm-low.c $(linux_low_h) $(server_h)
+ linux-cris-low.o: linux-cris-low.c $(linux_low_h) $(server_h)
+ linux-crisv32-low.o: linux-crisv32-low.c $(linux_low_h) $(server_h)
+-linux-i386-low.o: linux-i386-low.c $(linux_low_h) $(server_h)
++linux-i386-low.o: linux-i386-low.c $(linux_low_h) $(server_h) \
++ $(gdb_proc_service_h)
+ linux-ia64-low.o: linux-ia64-low.c $(linux_low_h) $(server_h)
+ linux-m32r-low.o: linux-m32r-low.c $(linux_low_h) $(server_h)
+-linux-mips-low.o: linux-mips-low.c $(linux_low_h) $(server_h)
++linux-mips-low.o: linux-mips-low.c $(linux_low_h) $(server_h) \
++ $(gdb_proc_service_h)
+ linux-ppc-low.o: linux-ppc-low.c $(linux_low_h) $(server_h)
+ linux-ppc64-low.o: linux-ppc64-low.c $(linux_low_h) $(server_h)
+ linux-s390-low.o: linux-s390-low.c $(linux_low_h) $(server_h)
+ linux-sh-low.o: linux-sh-low.c $(linux_low_h) $(server_h)
+-linux-x86-64-low.o: linux-x86-64-low.c $(linux_low_h) $(server_h)
++linux-x86-64-low.o: linux-x86-64-low.c $(linux_low_h) $(server_h) \
++ $(gdb_proc_service_h)
+
+ reg-arm.o : reg-arm.c $(regdef_h)
+ reg-arm.c : $(srcdir)/../regformats/reg-arm.dat $(regdat_sh)
+diff -urN gdb-6.3.50.20050915/gdb/gdbserver/linux-mips-low.c gdb-6.3.50.20050915-patched/gdb/gdbserver/linux-mips-low.c
+--- gdb-6.3.50.20050915/gdb/gdbserver/linux-mips-low.c 2005-06-12 20:59:22.000000000 -0500
++++ gdb-6.3.50.20050915-patched/gdb/gdbserver/linux-mips-low.c 2005-09-15 19:16:54.000000000 -0500
+@@ -22,6 +22,26 @@
+ #include "server.h"
+ #include "linux-low.h"
+
++#include <sys/ptrace.h>
++
++/* Correct for all GNU/Linux targets (for quite some time). */
++#define GDB_GREGSET_T elf_gregset_t
++#define GDB_FPREGSET_T elf_fpregset_t
++
++#ifndef HAVE_ELF_FPREGSET_T
++/* Make sure we have said types. Not all platforms bring in <linux/elf.h>
++ via <sys/procfs.h>. */
++#ifdef HAVE_LINUX_ELF_H
++#include <linux/elf.h>
++#endif
++#endif
++
++#include "../gdb_proc_service.h"
++
++#ifndef PTRACE_GET_THREAD_AREA
++#define PTRACE_GET_THREAD_AREA 25
++#endif
++
+ #ifdef HAVE_SYS_REG_H
+ #include <sys/reg.h>
+ #endif
+@@ -140,6 +160,23 @@
+ return 0;
+ }
+
++/* Fetch the thread-local storage pointer for libthread_db. */
++
++ps_err_e
++ps_get_thread_area (const struct ps_prochandle *ph,
++ lwpid_t lwpid, int idx, void **base)
++{
++ if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
++ return PS_ERR;
++
++ /* IDX is the bias from the thread pointer to the beginning of the
++ thread descriptor. It has to be subtracted due to implementation
++ quirks in libthread_db. */
++ *base = (void *) ((char *)*base - idx);
++
++ return PS_OK;
++}
++
+ struct linux_target_ops the_low_target = {
+ mips_num_regs,
+ mips_regmap,
+diff -urN gdb-6.3.50.20050915/gdb/mips-linux-nat.c gdb-6.3.50.20050915-patched/gdb/mips-linux-nat.c
+--- gdb-6.3.50.20050915/gdb/mips-linux-nat.c 2005-09-10 13:11:04.000000000 -0500
++++ gdb-6.3.50.20050915-patched/gdb/mips-linux-nat.c 2005-09-15 19:16:54.000000000 -0500
+@@ -24,6 +24,12 @@
+ #include "target.h"
+ #include "linux-nat.h"
+
++#include "gdb_proc_service.h"
++
++#ifndef PTRACE_GET_THREAD_AREA
++#define PTRACE_GET_THREAD_AREA 25
++#endif
++
+ /* Pseudo registers can not be read. ptrace does not provide a way to
+ read (or set) MIPS_PS_REGNUM, and there's no point in reading or
+ setting MIPS_ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or
+@@ -72,3 +78,20 @@
+ {
+ add_target (linux_target ());
+ }
++
++/* Fetch the thread-local storage pointer for libthread_db. */
++
++ps_err_e
++ps_get_thread_area (const struct ps_prochandle *ph,
++ lwpid_t lwpid, int idx, void **base)
++{
++ if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
++ return PS_ERR;
++
++ /* IDX is the bias from the thread pointer to the beginning of the
++ thread descriptor. It has to be subtracted due to implementation
++ quirks in libthread_db. */
++ *base = (void *) ((char *)*base - idx);
++
++ return PS_OK;
++}
diff --git a/misc/buildroot/toolchain/gdb/snapshot/500-thread-timeout.patch b/misc/buildroot/toolchain/gdb/snapshot/500-thread-timeout.patch
new file mode 100644
index 000000000..6db0a7a47
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/snapshot/500-thread-timeout.patch
@@ -0,0 +1,34 @@
+--- gdb-6.3.org/gdb/gdbserver/thread-db.c 2004-10-17 02:42:00.000000000 +0900
++++ gdb-6.3/gdb/gdbserver/thread-db.c 2005-01-27 12:19:29.000000000 +0900
+@@ -21,6 +21,7 @@
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
++#include <unistd.h>
+ #include "server.h"
+
+ #include "linux-low.h"
+@@ -142,6 +143,7 @@
+ td_event_msg_t msg;
+ td_err_e err;
+ struct inferior_linux_data *tdata;
++ int timeout;
+
+ if (debug_threads)
+ fprintf (stderr, "Thread creation event.\n");
+@@ -152,7 +154,13 @@
+ In the LinuxThreads implementation, this is safe,
+ because all events come from the manager thread
+ (except for its own creation, of course). */
+- err = td_ta_event_getmsg (thread_agent, &msg);
++ for (timeout = 0; timeout < 50000; timeout++)
++ {
++ err = td_ta_event_getmsg (thread_agent, &msg);
++ if (err != TD_NOMSG)
++ break;
++ usleep(1000);
++ }
+ if (err != TD_OK)
+ fprintf (stderr, "thread getmsg err: %s\n",
+ thread_db_err_str (err));
+
diff --git a/misc/buildroot/toolchain/gdb/snapshot/680-debian_sim-destdir.patch b/misc/buildroot/toolchain/gdb/snapshot/680-debian_sim-destdir.patch
new file mode 100644
index 000000000..1663f5505
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/snapshot/680-debian_sim-destdir.patch
@@ -0,0 +1,14 @@
+Fix some missing uses of DESTDIR in the sim/ directories. The Debian
+packages use DESTDIR to build.
+--
+diff -ur gdb-6.3.50.20050915/sim/Makefile.in gdb-6.3.50.20050915-patched/sim/Makefile.in
+--- gdb-6.3.50.20050915/sim/Makefile.in 2005-01-28 18:53:13.000000000 -0600
++++ gdb-6.3.50.20050915-patched/sim/Makefile.in 2005-09-15 23:17:42.000000000 -0500
+@@ -93,6 +93,7 @@
+ "CC=$(CC)" \
+ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+ "CFLAGS=$(CFLAGS)" \
++ "DESTDIR=$(DESTDIR)" \
+ "CHILLFLAGS=$(CHILLFLAGS)" \
+ "CHILL=$(CHILL_FOR_TARGET)" \
+ "CHILL_FOR_TARGET=$(CHILL_FOR_TARGET)" \
diff --git a/misc/buildroot/toolchain/gdb/snapshot/690-debian_member-field-symtab.patch b/misc/buildroot/toolchain/gdb/snapshot/690-debian_member-field-symtab.patch
new file mode 100644
index 000000000..54d43ad64
--- /dev/null
+++ b/misc/buildroot/toolchain/gdb/snapshot/690-debian_member-field-symtab.patch
@@ -0,0 +1,20 @@
+Status: unsubmitted
+
+This patch was for Debian bug #239535. It needs to be tested, and
+submitted.
+--
+diff -ur gdb-6.3.50.20050915/gdb/valops.c gdb-6.3.50.20050915-patched/gdb/valops.c
+--- gdb-6.3.50.20050915/gdb/valops.c 2005-05-26 23:39:32.000000000 -0500
++++ gdb-6.3.50.20050915-patched/gdb/valops.c 2005-09-15 23:21:49.000000000 -0500
+@@ -2256,8 +2256,10 @@
+ return 1;
+ }
+
++ /* Check each baseclass. Call check_typedef, which will follow typedefs
++ and do opaque/stub type resolution. */
+ for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
+- if (check_field_in (TYPE_BASECLASS (type, i), name))
++ if (check_field_in (check_typedef (TYPE_BASECLASS (type, i)), name))
+ return 1;
+
+ return 0;
diff --git a/misc/buildroot/toolchain/genromfs/Config.in b/misc/buildroot/toolchain/genromfs/Config.in
new file mode 100644
index 000000000..e2882c2be
--- /dev/null
+++ b/misc/buildroot/toolchain/genromfs/Config.in
@@ -0,0 +1,8 @@
+config BR2_PACKAGE_GENROMFS
+ bool "Build genromfs"
+ default n if !BR2_PACKAGE_NXFLAT
+ default y if BR2_PACKAGE_NXFLAT
+ help
+ genromfs is a tools that will convert a directory on the host
+ machine to a FLASH-able ROMFS image file. genromfs support
+ is normally required with NXFLAT.
diff --git a/misc/buildroot/toolchain/genromfs/genromfs-0.5.2.tar.gz b/misc/buildroot/toolchain/genromfs/genromfs-0.5.2.tar.gz
new file mode 100755
index 000000000..d928707f4
--- /dev/null
+++ b/misc/buildroot/toolchain/genromfs/genromfs-0.5.2.tar.gz
Binary files differ
diff --git a/misc/buildroot/toolchain/genromfs/genromfs.mk b/misc/buildroot/toolchain/genromfs/genromfs.mk
new file mode 100644
index 000000000..69b818dba
--- /dev/null
+++ b/misc/buildroot/toolchain/genromfs/genromfs.mk
@@ -0,0 +1,38 @@
+######################################################################
+#
+# genromfs
+#
+######################################################################
+
+GENROMFS_VERSION:=0.5.2
+GENROMFS_SOURCE:=genromfs-$(GENROMFS_VERSION).tar.gz
+GENROMFS_BUILD:=$(TOOL_BUILD_DIR)/genromfs-$(GENROMFS_VERSION)
+
+$(GENROMFS_BUILD)/.unpacked : $(GENROMFS_TARBALL)
+ $(ZCAT) toolchain/genromfs/$(GENROMFS_SOURCE) | tar -C $(TOOL_BUILD_DIR) $(TAR_OPTIONS) -
+ toolchain/patch-kernel.sh $(GENROMFS_BUILD) toolchain/genromfs \*.patch
+ touch $@
+
+$(GENROMFS_BUILD)/.compiled : $(GENROMFS_BUILD)/.unpacked
+ $(MAKE) -C $(GENROMFS_BUILD)
+ touch $@
+
+$(STAGING_DIR)/bin/genromfs: $(GENROMFS_BUILD)/.compiled
+ install -m 755 $(GENROMFS_BUILD)/genromfs $(STAGING_DIR)/bin/genromfs
+
+genromfs: $(STAGING_DIR)/bin/genromfs
+
+genromfs-source:
+
+genromfs-clean:
+ rm -f $(STAGING_DIR)/bin/genromfs
+ (if [ -d $(GENROMFS_BUILD) ]; then $(MAKE) -C $(GENROMFS_BUILD) clean; fi)
+ rm -f $(GENROMFS_BUILD)/.compiled
+
+genromfs-dirclean:
+ rm -rf $(GENROMFS_BUILD)
+
+ifeq ($(strip $(BR2_PACKAGE_GENROMFS)),y)
+TARGETS+=genromfs
+endif
+
diff --git a/misc/buildroot/toolchain/nxflat/Config.in b/misc/buildroot/toolchain/nxflat/Config.in
new file mode 100644
index 000000000..a977bede1
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/Config.in
@@ -0,0 +1,9 @@
+comment "NuttX Binary Support"
+
+config BR2_PACKAGE_NXFLAT
+ bool "Build NXFLAT tools"
+ default n
+ depends on BR2_arm
+ help
+ Build tools need to build NuttX NXFLAT load-able binary
+
diff --git a/misc/buildroot/toolchain/nxflat/Makefile b/misc/buildroot/toolchain/nxflat/Makefile
new file mode 100644
index 000000000..892362708
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/Makefile
@@ -0,0 +1,74 @@
+############################################################################
+# toolchain/nxflat/Makefile
+#
+# Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+CFLAGS += -Wall -I. -I$(BINUTILS_DIR1)/bfd -I$(BINUTILS_DIR)/include
+LDFLAGS += -L$(BINUTILS_DIR1)/bfd -L$(BINUTILS_DIR1)/libiberty
+LIBS = -lbfd -liberty -lz -lc
+
+LDNXFLAT_OBJS = ldnxflat.o
+MKNXFLAT_OBJS = mknxflat.o
+READNXFLAT_OBJS = readnxflat.o
+OBJS = $(LDNXFLAT_OBJS) $(MKNXFLAT_OBJS) $(READNXFLAT_OBJS)
+
+BIN = ldnxflat mknxflat readnxflat
+
+GXX_VERSION = ${shell $(ARCHCXX) -dumpversion | cut -d. -f1}
+
+all: $(BIN)
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) -o $@ $<
+
+arch:
+ @ln -sf $(ARCH) arch
+
+ldnxflat: arch $(LDNXFLAT_OBJS)
+ $(CC) $(LDFLAGS) $(LDNXFLAT_OBJS) -o $@ $(LIBS)
+
+mknxflat: arch $(MKNXFLAT_OBJS)
+ $(CC) $(LDFLAGS) $(MKNXFLAT_OBJS) -o $@ $(LIBS)
+
+arch/libarch.a:
+ $(MAKE) -C arch CC="$(CC)"
+
+readnxflat: arch $(READNXFLAT_OBJS) arch/libarch.a
+ $(CC) $(LDFLAGS) -L arch -o $@ $(READNXFLAT_OBJS) $(LIBS) -larch
+
+# Housekeeping
+
+clean:
+ -$(MAKE) -C arch clean
+ rm -f *.o $(BIN) arch *.exe *~ .*.swp
+
diff --git a/misc/buildroot/toolchain/nxflat/arm/Makefile b/misc/buildroot/toolchain/nxflat/arm/Makefile
new file mode 100644
index 000000000..967fe8054
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/arm/Makefile
@@ -0,0 +1,50 @@
+############################################################################
+# toolchain/nxflat/arm/Makefile
+#
+# Copyright (C) 2009 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+CFLAGS += -Wall
+BIN = libarch.a
+OBJS = disarm.o
+
+all: $(BIN)
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) -o $@ $<
+
+$(BIN): $(OBJS)
+ $(AR) rcs $@ $<
+
+clean:
+ rm -f *.o *.a *~ .*.swp core
+
diff --git a/misc/buildroot/toolchain/nxflat/arm/arch.h b/misc/buildroot/toolchain/nxflat/arm/arch.h
new file mode 100644
index 000000000..7839d97f8
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/arm/arch.h
@@ -0,0 +1,303 @@
+/***********************************************************************
+ * xflat/tools/arm/arch.h
+ * ARM thumb2 ELF support for BFD.
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Simply lifted with minimal change from the BFD, binutils 2.19.1:
+ *
+ * Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ * Free Software Foundation, Inc.
+ *
+ * This file is part of BFD, the Binary File Descriptor library.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ ***********************************************************************/
+
+#ifndef _TOOLCHAIN_NXFLAT_ARM_ARCH_H
+#define _TOOLCHAIN_NXFLAT_ARM_ARCH_H
+
+#include "reloc-macros.h"
+
+/* Inform ldnxflat that this is 32-bit ARM code */
+
+#define NXFLAT_ARM 1
+#undef NXFLAT_THUMB2
+
+/* Processor specific flags for the ELF header e_flags field. */
+#define EF_ARM_RELEXEC 0x01
+#define EF_ARM_HASENTRY 0x02
+#define EF_ARM_INTERWORK 0x04
+#define EF_ARM_APCS_26 0x08
+#define EF_ARM_APCS_FLOAT 0x10
+#define EF_ARM_PIC 0x20
+#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use. */
+#define EF_ARM_NEW_ABI 0x80
+#define EF_ARM_OLD_ABI 0x100
+#define EF_ARM_SOFT_FLOAT 0x200
+#define EF_ARM_VFP_FLOAT 0x400
+#define EF_ARM_MAVERICK_FLOAT 0x800
+
+/* Frame unwind information */
+#define PT_ARM_EXIDX (PT_LOPROC + 1)
+
+/* Other constants defined in the ARM ELF spec. version B-01. */
+#define EF_ARM_SYMSARESORTED 0x04 /* NB conflicts with EF_INTERWORK */
+#define EF_ARM_DYNSYMSUSESEGIDX 0x08 /* NB conflicts with EF_APCS26 */
+#define EF_ARM_MAPSYMSFIRST 0x10 /* NB conflicts with EF_APCS_FLOAT */
+#define EF_ARM_EABIMASK 0xFF000000
+
+/* Constants defined in AAELF. */
+#define EF_ARM_BE8 0x00800000
+#define EF_ARM_LE8 0x00400000
+
+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN 0x00000000
+#define EF_ARM_EABI_VER1 0x01000000
+#define EF_ARM_EABI_VER2 0x02000000
+#define EF_ARM_EABI_VER3 0x03000000
+#define EF_ARM_EABI_VER4 0x04000000
+#define EF_ARM_EABI_VER5 0x05000000
+
+/* Local aliases for some flags to match names used by COFF port. */
+#define F_INTERWORK EF_ARM_INTERWORK
+#define F_APCS26 EF_ARM_APCS_26
+#define F_APCS_FLOAT EF_ARM_APCS_FLOAT
+#define F_PIC EF_ARM_PIC
+#define F_SOFT_FLOAT EF_ARM_SOFT_FLOAT
+#define F_VFP_FLOAT EF_ARM_VFP_FLOAT
+
+/* Additional symbol types for Thumb. */
+#define STT_ARM_TFUNC 13 /* A Thumb function. */
+#define STT_ARM_16BIT 15 /* A Thumb label. */
+
+/* Additional section types. */
+#define SHT_ARM_EXIDX 0x70000001 /* Section holds ARM unwind info. */
+#define SHT_ARM_PREEMPTMAP 0x70000002 /* Section pre-emption details. */
+#define SHT_ARM_ATTRIBUTES 0x70000003 /* Section holds attributes. */
+
+/* ARM-specific values for sh_flags. */
+#define SHF_ENTRYSECT 0x10000000 /* Section contains an entry point. */
+#define SHF_COMDEF 0x80000000 /* Section may be multiply defined in the input to a link step. */
+
+/* ARM-specific program header flags. */
+#define PF_ARM_SB 0x10000000 /* Segment contains the location addressed by the static base. */
+#define PF_ARM_PI 0x20000000 /* Segment is position-independent. */
+#define PF_ARM_ABS 0x40000000 /* Segment must be loaded at its base address. */
+
+/* Values for the Tag_CPU_arch EABI attribute. */
+#define TAG_CPU_ARCH_PRE_V4 0
+#define TAG_CPU_ARCH_V4 1
+#define TAG_CPU_ARCH_V4T 2
+#define TAG_CPU_ARCH_V5T 3
+#define TAG_CPU_ARCH_V5TE 4
+#define TAG_CPU_ARCH_V5TEJ 5
+#define TAG_CPU_ARCH_V6 6
+#define TAG_CPU_ARCH_V6KZ 7
+#define TAG_CPU_ARCH_V6T2 8
+#define TAG_CPU_ARCH_V6K 9
+#define TAG_CPU_ARCH_V7 10
+
+/* Relocation types. */
+
+START_RELOC_NUMBERS (elf_arm_reloc_type)
+/* AAELF official names and numbers. */
+ RELOC_NUMBER (R_ARM_NONE, 0)
+ RELOC_NUMBER (R_ARM_PC24, 1) /* deprecated */
+ RELOC_NUMBER (R_ARM_ABS32, 2)
+ RELOC_NUMBER (R_ARM_REL32, 3)
+ RELOC_NUMBER (R_ARM_LDR_PC_G0, 4)
+ RELOC_NUMBER (R_ARM_ABS16, 5)
+ RELOC_NUMBER (R_ARM_ABS12, 6)
+ RELOC_NUMBER (R_ARM_THM_ABS5, 7)
+ RELOC_NUMBER (R_ARM_ABS8, 8)
+ RELOC_NUMBER (R_ARM_SBREL32, 9)
+ RELOC_NUMBER (R_ARM_THM_CALL, 10)
+ RELOC_NUMBER (R_ARM_THM_PC8, 11)
+ RELOC_NUMBER (R_ARM_BREL_ADJ, 12)
+ RELOC_NUMBER (R_ARM_SWI24, 13) /* obsolete */
+ RELOC_NUMBER (R_ARM_THM_SWI8, 14) /* obsolete */
+ RELOC_NUMBER (R_ARM_XPC25, 15) /* obsolete */
+ RELOC_NUMBER (R_ARM_THM_XPC22, 16) /* obsolete */
+ RELOC_NUMBER (R_ARM_TLS_DTPMOD32, 17)
+ RELOC_NUMBER (R_ARM_TLS_DTPOFF32, 18)
+ RELOC_NUMBER (R_ARM_TLS_TPOFF32, 19)
+ RELOC_NUMBER (R_ARM_COPY, 20) /* Copy symbol at runtime. */
+ RELOC_NUMBER (R_ARM_GLOB_DAT, 21) /* Create GOT entry. */
+ RELOC_NUMBER (R_ARM_JUMP_SLOT, 22) /* Create PLT entry. */
+ RELOC_NUMBER (R_ARM_RELATIVE, 23) /* Adjust by program base. */
+ RELOC_NUMBER (R_ARM_GOTOFF32, 24) /* 32 bit offset to GOT. */
+ RELOC_NUMBER (R_ARM_BASE_PREL, 25) /* 32 bit PC relative offset to GOT. */
+ RELOC_NUMBER (R_ARM_GOT_BREL, 26) /* 32 bit GOT entry. */
+ RELOC_NUMBER (R_ARM_PLT32, 27) /* deprecated - 32 bit PLT address. */
+ RELOC_NUMBER (R_ARM_CALL, 28)
+ RELOC_NUMBER (R_ARM_JUMP24, 29)
+ RELOC_NUMBER (R_ARM_THM_JUMP24, 30)
+ RELOC_NUMBER (R_ARM_BASE_ABS, 31)
+ RELOC_NUMBER (R_ARM_ALU_PCREL7_0, 32) /* obsolete */
+ RELOC_NUMBER (R_ARM_ALU_PCREL15_8, 33) /* obsolete */
+ RELOC_NUMBER (R_ARM_ALU_PCREL23_15, 34) /* obsolete */
+ RELOC_NUMBER (R_ARM_LDR_SBREL_11_0, 35) /* deprecated, should have _NC suffix */
+ RELOC_NUMBER (R_ARM_ALU_SBREL_19_12, 36) /* deprecated, should have _NC suffix */
+ RELOC_NUMBER (R_ARM_ALU_SBREL_27_20, 37) /* deprecated, should have _CK suffix */
+ RELOC_NUMBER (R_ARM_TARGET1, 38)
+ RELOC_NUMBER (R_ARM_SBREL31, 39) /* deprecated */
+ RELOC_NUMBER (R_ARM_V4BX, 40)
+ RELOC_NUMBER (R_ARM_TARGET2, 41)
+ RELOC_NUMBER (R_ARM_PREL31, 42)
+ RELOC_NUMBER (R_ARM_MOVW_ABS_NC, 43)
+ RELOC_NUMBER (R_ARM_MOVT_ABS, 44)
+ RELOC_NUMBER (R_ARM_MOVW_PREL_NC, 45)
+ RELOC_NUMBER (R_ARM_MOVT_PREL, 46)
+ RELOC_NUMBER (R_ARM_THM_MOVW_ABS_NC, 47)
+ RELOC_NUMBER (R_ARM_THM_MOVT_ABS, 48)
+ RELOC_NUMBER (R_ARM_THM_MOVW_PREL_NC, 49)
+ RELOC_NUMBER (R_ARM_THM_MOVT_PREL, 50)
+ RELOC_NUMBER (R_ARM_THM_JUMP19, 51)
+ RELOC_NUMBER (R_ARM_THM_JUMP6, 52)
+ RELOC_NUMBER (R_ARM_THM_ALU_PREL_11_0, 53)
+ RELOC_NUMBER (R_ARM_THM_PC12, 54)
+ RELOC_NUMBER (R_ARM_ABS32_NOI, 55)
+ RELOC_NUMBER (R_ARM_REL32_NOI, 56)
+ RELOC_NUMBER (R_ARM_ALU_PC_G0_NC, 57)
+ RELOC_NUMBER (R_ARM_ALU_PC_G0, 58)
+ RELOC_NUMBER (R_ARM_ALU_PC_G1_NC, 59)
+ RELOC_NUMBER (R_ARM_ALU_PC_G1, 60)
+ RELOC_NUMBER (R_ARM_ALU_PC_G2, 61)
+ RELOC_NUMBER (R_ARM_LDR_PC_G1, 62)
+ RELOC_NUMBER (R_ARM_LDR_PC_G2, 63)
+ RELOC_NUMBER (R_ARM_LDRS_PC_G0, 64)
+ RELOC_NUMBER (R_ARM_LDRS_PC_G1, 65)
+ RELOC_NUMBER (R_ARM_LDRS_PC_G2, 66)
+ RELOC_NUMBER (R_ARM_LDC_PC_G0, 67)
+ RELOC_NUMBER (R_ARM_LDC_PC_G1, 68)
+ RELOC_NUMBER (R_ARM_LDC_PC_G2, 69)
+ RELOC_NUMBER (R_ARM_ALU_SB_G0_NC, 70)
+ RELOC_NUMBER (R_ARM_ALU_SB_G0, 71)
+ RELOC_NUMBER (R_ARM_ALU_SB_G1_NC, 72)
+ RELOC_NUMBER (R_ARM_ALU_SB_G1, 73)
+ RELOC_NUMBER (R_ARM_ALU_SB_G2, 74)
+ RELOC_NUMBER (R_ARM_LDR_SB_G0, 75)
+ RELOC_NUMBER (R_ARM_LDR_SB_G1, 76)
+ RELOC_NUMBER (R_ARM_LDR_SB_G2, 77)
+ RELOC_NUMBER (R_ARM_LDRS_SB_G0, 78)
+ RELOC_NUMBER (R_ARM_LDRS_SB_G1, 79)
+ RELOC_NUMBER (R_ARM_LDRS_SB_G2, 80)
+ RELOC_NUMBER (R_ARM_LDC_SB_G0, 81)
+ RELOC_NUMBER (R_ARM_LDC_SB_G1, 82)
+ RELOC_NUMBER (R_ARM_LDC_SB_G2, 83)
+ RELOC_NUMBER (R_ARM_MOVW_BREL_NC, 84)
+ RELOC_NUMBER (R_ARM_MOVT_BREL, 85)
+ RELOC_NUMBER (R_ARM_MOVW_BREL, 86)
+ RELOC_NUMBER (R_ARM_THM_MOVW_BREL_NC, 87)
+ RELOC_NUMBER (R_ARM_THM_MOVT_BREL, 88)
+ RELOC_NUMBER (R_ARM_THM_MOVW_BREL, 89)
+ /* 90-93 unallocated */
+ RELOC_NUMBER (R_ARM_PLT32_ABS, 94)
+ RELOC_NUMBER (R_ARM_GOT_ABS, 95)
+ RELOC_NUMBER (R_ARM_GOT_PREL, 96)
+ RELOC_NUMBER (R_ARM_GOT_BREL12, 97)
+ RELOC_NUMBER (R_ARM_GOTOFF12, 98)
+ RELOC_NUMBER (R_ARM_GOTRELAX, 99)
+ RELOC_NUMBER (R_ARM_GNU_VTENTRY, 100) /* deprecated - old C++ abi */
+ RELOC_NUMBER (R_ARM_GNU_VTINHERIT, 101) /* deprecated - old C++ abi */
+ RELOC_NUMBER (R_ARM_THM_JUMP11, 102)
+ RELOC_NUMBER (R_ARM_THM_JUMP8, 103)
+ RELOC_NUMBER (R_ARM_TLS_GD32, 104)
+ RELOC_NUMBER (R_ARM_TLS_LDM32, 105)
+ RELOC_NUMBER (R_ARM_TLS_LDO32, 106)
+ RELOC_NUMBER (R_ARM_TLS_IE32, 107)
+ RELOC_NUMBER (R_ARM_TLS_LE32, 108)
+ RELOC_NUMBER (R_ARM_TLS_LDO12, 109)
+ RELOC_NUMBER (R_ARM_TLS_LE12, 110)
+ RELOC_NUMBER (R_ARM_TLS_IE12GP, 111)
+ /* 112 - 127 private range */
+ RELOC_NUMBER (R_ARM_ME_TOO, 128) /* obsolete */
+
+ /* Extensions? R=read-only? */
+ RELOC_NUMBER (R_ARM_RXPC25, 249)
+ RELOC_NUMBER (R_ARM_RSBREL32, 250)
+ RELOC_NUMBER (R_ARM_THM_RPC22, 251)
+ RELOC_NUMBER (R_ARM_RREL32, 252)
+ RELOC_NUMBER (R_ARM_RABS32, 253)
+ RELOC_NUMBER (R_ARM_RPC24, 254)
+ RELOC_NUMBER (R_ARM_RBASE, 255)
+
+ /* Unofficial names for some of the relocs. */
+ FAKE_RELOC (R_ARM_GOTOFF, R_ARM_GOTOFF32) /* 32 bit offset to GOT. */
+ FAKE_RELOC (R_ARM_THM_PC22, R_ARM_THM_CALL)
+ FAKE_RELOC (R_ARM_THM_PC11, R_ARM_THM_JUMP11)
+ FAKE_RELOC (R_ARM_THM_PC9, R_ARM_THM_JUMP8)
+
+ /* Relocs with both a different name, and (apparently) different meaning in
+ GNU usage. */
+ FAKE_RELOC (R_ARM_GOTPC, R_ARM_BASE_PREL) /* 32 bit PC relative offset to GOT. */
+ FAKE_RELOC (R_ARM_GOT32, R_ARM_GOT_BREL) /* 32 bit GOT entry. */
+ FAKE_RELOC (R_ARM_ROSEGREL32, R_ARM_SBREL31) /* ??? */
+ FAKE_RELOC (R_ARM_AMP_VCALL9, R_ARM_BREL_ADJ) /* Thumb-something. Not used. */
+
+END_RELOC_NUMBERS (R_ARM_max = 256)
+
+#ifdef BFD_ARCH_SIZE
+/* EABI object attributes. */
+
+enum
+{
+ /* 0-3 are generic. */
+ Tag_CPU_raw_name = 4,
+ Tag_CPU_name,
+ Tag_CPU_arch,
+ Tag_CPU_arch_profile,
+ Tag_ARM_ISA_use,
+ Tag_THUMB_ISA_use,
+ Tag_VFP_arch,
+ Tag_WMMX_arch,
+ Tag_NEON_arch,
+ Tag_PCS_config,
+ Tag_ABI_PCS_R9_use,
+ Tag_ABI_PCS_RW_data,
+ Tag_ABI_PCS_RO_data,
+ Tag_ABI_PCS_GOT_use,
+ Tag_ABI_PCS_wchar_t,
+ Tag_ABI_FP_rounding,
+ Tag_ABI_FP_denormal,
+ Tag_ABI_FP_exceptions,
+ Tag_ABI_FP_user_exceptions,
+ Tag_ABI_FP_number_model,
+ Tag_ABI_align8_needed,
+ Tag_ABI_align8_preserved,
+ Tag_ABI_enum_size,
+ Tag_ABI_HardFP_use,
+ Tag_ABI_VFP_args,
+ Tag_ABI_WMMX_args,
+ Tag_ABI_optimization_goals,
+ Tag_ABI_FP_optimization_goals,
+ /* 32 is generic. */
+};
+
+#endif
+
+/* The name of the note section used to identify arm variants. */
+#define ARM_NOTE_SECTION ".note.gnu.arm.ident"
+
+/* Special section names. */
+#define ELF_STRING_ARM_unwind ".ARM.exidx"
+#define ELF_STRING_ARM_unwind_info ".ARM.extab"
+#define ELF_STRING_ARM_unwind_once ".gnu.linkonce.armexidx."
+#define ELF_STRING_ARM_unwind_info_once ".gnu.linkonce.armextab."
+
+#endif /* _TOOLCHAIN_NXFLAT_ARM_ARCH_H */
diff --git a/misc/buildroot/toolchain/nxflat/arm/disarm.c b/misc/buildroot/toolchain/nxflat/arm/disarm.c
new file mode 100644
index 000000000..c1d8257de
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/arm/disarm.c
@@ -0,0 +1,1004 @@
+/***********************************************************************
+ * toolchain/nxflat/arm/disarm.c
+ * ARM Disassembler
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Derived from XFLAT:
+ *
+ * Copyright (c) 2006, Cadenux, LLC. All rights reserved.
+ * Copyright (c) 2006, Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Which simply lifted it from the BFD:
+ *
+ * Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * This file is derived from parts of of the binutils package
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ***********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#define BDISP(x) ((((x) & 0xffffff) ^ 0x800000) - 0x800000) /* 26 bit */
+
+struct arm_opcode
+{
+ u_int32_t value;
+ u_int32_t mask;
+ char *assembler;
+};
+
+static char * arm_conditional[] =
+{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
+ "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
+
+typedef struct
+{
+ const char *name;
+ const char *description;
+ const char *reg_names[16];
+}
+arm_regname;
+
+static arm_regname regnames[] =
+{
+ { "raw" , "Select raw register names",
+ { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
+ { "gcc", "Select register names used by GCC",
+ { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
+ { "std", "Select register names used in ARM's ISA documentation",
+ { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
+ { "apcs", "Select register names used in the APCS",
+ { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
+ { "atpcs", "Select register names used in the ATPCS",
+ { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
+ { "special-atpcs", "Select special register names used in the ATPCS",
+ { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }}
+};
+
+static unsigned int regname_selected = 1;
+
+#define NUM_ARM_REGNAMES NUM_ELEM (regnames)
+#define arm_regnames regnames[regname_selected].reg_names
+
+static char * arm_fp_const[] =
+{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
+
+static char * arm_shift[] =
+{"lsl", "lsr", "asr", "ror"};
+
+static struct arm_opcode arm_opcodes[] =
+ {
+ /* ARM instructions. */
+ {0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
+ {0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
+ {0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"},
+ {0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"},
+ {0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"},
+ {0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
+ {0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
+
+ /* V5J instruction. */
+ {0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
+
+ /* XScale instructions. */
+ {0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
+ {0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
+ {0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
+ {0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
+ {0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
+ {0xf450f000, 0xfc70f000, "pld\t%a"},
+
+ /* V5 Instructions. */
+ {0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
+ {0xfa000000, 0xfe000000, "blx\t%B"},
+ {0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
+ {0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
+ {0xfc100000, 0xfe100000, "ldc2%22'l\t%8-11d, cr%12-15d, %A"},
+ {0xfc000000, 0xfe100000, "stc2%22'l\t%8-11d, cr%12-15d, %A"},
+ {0xfe000000, 0xff000010, "cdp2\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
+ {0xfe000010, 0xff100010, "mcr2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
+ {0xfe100010, 0xff100010, "mrc2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
+
+ /* V5E "El Segundo" Instructions. */
+ {0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"},
+ {0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"},
+ {0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
+ {0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
+ {0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
+ {0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
+
+ {0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
+ {0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
+
+ {0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
+ {0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
+ {0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
+ {0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
+
+ {0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
+ {0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
+ {0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
+ {0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
+
+ {0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
+ {0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
+
+ {0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
+ {0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
+ {0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
+ {0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
+
+ {0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
+ {0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
+
+ /* ARM Instructions. */
+ {0x00000090, 0x0e100090, "str%c%6's%5?hb\t%12-15r, %s"},
+ {0x00100090, 0x0e100090, "ldr%c%6's%5?hb\t%12-15r, %s"},
+ {0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"},
+ {0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"},
+ {0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"},
+ {0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"},
+ {0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"},
+ {0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"},
+ {0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"},
+ {0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"},
+ {0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
+ {0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
+ {0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"},
+ {0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"},
+ {0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"},
+ {0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"},
+ {0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"},
+ {0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"},
+ {0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"},
+ {0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"},
+ {0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"},
+ {0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"},
+ {0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"},
+ {0x06000010, 0x0e000010, "undefined"},
+ {0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"},
+ {0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
+ {0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
+ {0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
+ {0x0f000000, 0x0f000000, "swi%c\t%0-23x"},
+
+ /* Floating point coprocessor (FPA) instructions */
+ {0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
+ {0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
+ {0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
+ {0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
+ {0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
+ {0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
+ {0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
+ {0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
+ {0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
+ {0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
+ {0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
+ {0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
+ {0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
+ {0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
+ {0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
+ {0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
+ {0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
+ {0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
+ {0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
+ {0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
+ {0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
+ {0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
+ {0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
+ {0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
+ {0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
+ {0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
+ {0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
+ {0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
+ {0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
+ {0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
+
+ /* Floating point coprocessor (VFP) instructions */
+ {0x0eb00bc0, 0x0fff0ff0, "fabsd%c\t%1z, %0z"},
+ {0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%1y, %0y"},
+ {0x0e300b00, 0x0ff00ff0, "faddd%c\t%1z, %2z, %0z"},
+ {0x0e300a00, 0x0fb00f50, "fadds%c\t%1y, %2y, %1y"},
+ {0x0eb40b40, 0x0fff0f70, "fcmp%7'ed%c\t%1z, %0z"},
+ {0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%1y, %0y"},
+ {0x0eb50b40, 0x0fff0f70, "fcmp%7'ezd%c\t%1z"},
+ {0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%1y"},
+ {0x0eb00b40, 0x0fff0ff0, "fcpyd%c\t%1z, %0z"},
+ {0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%1y, %0y"},
+ {0x0eb70ac0, 0x0fff0fd0, "fcvtds%c\t%1z, %0y"},
+ {0x0eb70bc0, 0x0fbf0ff0, "fcvtsd%c\t%1y, %0z"},
+ {0x0e800b00, 0x0ff00ff0, "fdivd%c\t%1z, %2z, %0z"},
+ {0x0e800a00, 0x0fb00f50, "fdivs%c\t%1y, %2y, %0y"},
+ {0x0d100b00, 0x0f700f00, "fldd%c\t%1z, %A"},
+ {0x0c900b00, 0x0fd00f00, "fldmia%0?xd%c\t%16-19r%21'!, %3z"},
+ {0x0d300b00, 0x0ff00f00, "fldmdb%0?xd%c\t%16-19r!, %3z"},
+ {0x0d100a00, 0x0f300f00, "flds%c\t%1y, %A"},
+ {0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %3y"},
+ {0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %3y"},
+ {0x0e000b00, 0x0ff00ff0, "fmacd%c\t%1z, %2z, %0z"},
+ {0x0e000a00, 0x0fb00f50, "fmacs%c\t%1y, %2y, %0y"},
+ {0x0e200b10, 0x0ff00fff, "fmdhr%c\t%2z, %12-15r"},
+ {0x0e000b10, 0x0ff00fff, "fmdlr%c\t%2z, %12-15r"},
+ {0x0c400b10, 0x0ff00ff0, "fmdrr%c\t%0z, %12-15r, %16-19r"},
+ {0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %2z"},
+ {0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %2z"},
+ {0x0c500b10, 0x0ff00ff0, "fmrrd%c\t%12-15r, %16-19r, %0z"},
+ {0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %4y"},
+ {0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %2y"},
+ {0x0ef1fa10, 0x0fffffff, "fmstat%c"},
+ {0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
+ {0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
+ {0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
+ {0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
+ {0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
+ {0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def 0x%16-19x>"},
+ {0x0e100b00, 0x0ff00ff0, "fmscd%c\t%1z, %2z, %0z"},
+ {0x0e100a00, 0x0fb00f50, "fmscs%c\t%1y, %2y, %0y"},
+ {0x0e000a10, 0x0ff00f7f, "fmsr%c\t%2y, %12-15r"},
+ {0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%12-15r, %16-19r, %4y"},
+ {0x0e200b00, 0x0ff00ff0, "fmuld%c\t%1z, %2z, %0z"},
+ {0x0e200a00, 0x0fb00f50, "fmuls%c\t%1y, %2y, %0y"},
+ {0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
+ {0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
+ {0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
+ {0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
+ {0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
+ {0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def 0x%16-19x>, %12-15r"},
+ {0x0eb10b40, 0x0fff0ff0, "fnegd%c\t%1z, %0z"},
+ {0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%1y, %0y"},
+ {0x0e000b40, 0x0ff00ff0, "fnmacd%c\t%1z, %2z, %0z"},
+ {0x0e000a40, 0x0fb00f50, "fnmacs%c\t%1y, %2y, %0y"},
+ {0x0e100b40, 0x0ff00ff0, "fnmscd%c\t%1z, %2z, %0z"},
+ {0x0e100a40, 0x0fb00f50, "fnmscs%c\t%1y, %2y, %0y"},
+ {0x0e200b40, 0x0ff00ff0, "fnmuld%c\t%1z, %2z, %0z"},
+ {0x0e200a40, 0x0fb00f50, "fnmuls%c\t%1y, %2y, %0y"},
+ {0x0eb80bc0, 0x0fff0fd0, "fsitod%c\t%1z, %0y"},
+ {0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%1y, %0y"},
+ {0x0eb10bc0, 0x0fff0ff0, "fsqrtd%c\t%1z, %0z"},
+ {0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%1y, %0y"},
+ {0x0d000b00, 0x0f700f00, "fstd%c\t%1z, %A"},
+ {0x0c800b00, 0x0fd00f00, "fstmia%0?xd%c\t%16-19r%21'!, %3z"},
+ {0x0d200b00, 0x0ff00f00, "fstmdb%0?xd%c\t%16-19r!, %3z"},
+ {0x0d000a00, 0x0f300f00, "fsts%c\t%1y, %A"},
+ {0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %3y"},
+ {0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %3y"},
+ {0x0e300b40, 0x0ff00ff0, "fsubd%c\t%1z, %2z, %0z"},
+ {0x0e300a40, 0x0fb00f50, "fsubs%c\t%1y, %2y, %0y"},
+ {0x0ebc0b40, 0x0fbe0f70, "fto%16?sui%7'zd%c\t%1y, %0z"},
+ {0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%1y, %0y"},
+ {0x0eb80b40, 0x0fff0fd0, "fuitod%c\t%1z, %0y"},
+ {0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%1y, %0y"},
+
+ /* Cirrus coprocessor instructions. */
+ {0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
+ {0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
+ {0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
+ {0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
+ {0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
+ {0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
+ {0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
+ {0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
+ {0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
+ {0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
+ {0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
+ {0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
+ {0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
+ {0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
+ {0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
+ {0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
+ {0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
+ {0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
+ {0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
+ {0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
+ {0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
+ {0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
+ {0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
+ {0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
+ {0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
+ {0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
+ {0x0e100610, 0x0ff0fff0, "cfmval32%c\tmvax%0-3d, mvfx%16-19d"},
+ {0x0e000610, 0x0ff0fff0, "cfmv32al%c\tmvfx%0-3d, mvax%16-19d"},
+ {0x0e100630, 0x0ff0fff0, "cfmvam32%c\tmvax%0-3d, mvfx%16-19d"},
+ {0x0e000630, 0x0ff0fff0, "cfmv32am%c\tmvfx%0-3d, mvax%16-19d"},
+ {0x0e100650, 0x0ff0fff0, "cfmvah32%c\tmvax%0-3d, mvfx%16-19d"},
+ {0x0e000650, 0x0ff0fff0, "cfmv32ah%c\tmvfx%0-3d, mvax%16-19d"},
+ {0x0e000670, 0x0ff0fff0, "cfmv32a%c\tmvfx%0-3d, mvax%16-19d"},
+ {0x0e100670, 0x0ff0fff0, "cfmva32%c\tmvax%0-3d, mvfx%16-19d"},
+ {0x0e000690, 0x0ff0fff0, "cfmv64a%c\tmvdx%0-3d, mvax%16-19d"},
+ {0x0e100690, 0x0ff0fff0, "cfmva64%c\tmvax%0-3d, mvdx%16-19d"},
+ {0x0e1006b0, 0x0ff0fff0, "cfmvsc32%c\tdspsc, mvfx%16-19d"},
+ {0x0e0006b0, 0x0ff0fff0, "cfmv32sc%c\tmvfx%0-3d, dspsc"},
+ {0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
+ {0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
+ {0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
+ {0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
+ {0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
+ {0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
+ {0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
+ {0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
+ {0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
+ {0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
+ {0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
+ {0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
+ {0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
+ {0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
+ {0x0e000500, 0x0ff00f00, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
+ {0x0e200500, 0x0ff00f00, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
+ {0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
+ {0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
+ {0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
+ {0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
+ {0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
+ {0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
+ {0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
+ {0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
+ {0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
+ {0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
+ {0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
+ {0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
+ {0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
+ {0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
+ {0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
+ {0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
+ {0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
+ {0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
+ {0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
+ {0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
+ {0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
+ {0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
+ {0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
+ {0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
+ {0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
+ {0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
+ {0x0e000600, 0x0ff00f00, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
+ {0x0e100600, 0x0ff00f00, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
+ {0x0e200600, 0x0ff00f00, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
+ {0x0e300600, 0x0ff00f00, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
+
+ /* Generic coprocessor instructions */
+ {0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
+ {0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
+ {0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
+ {0x0c000000, 0x0e100000, "stc%c%22'l\t%8-11d, cr%12-15d, %A"},
+ {0x0c100000, 0x0e100000, "ldc%c%22'l\t%8-11d, cr%12-15d, %A"},
+
+ /* The rest. */
+ {0x00000000, 0x00000000, "undefined instruction %0-31x"},
+ {0x00000000, 0x00000000, 0}
+ };
+
+static inline void print_address(FILE *stream, u_int32_t offset)
+{
+ fprintf(stream, "0x%08x", offset);
+}
+
+static void arm_decode_shift(u_int32_t given, FILE *stream)
+{
+ fprintf(stream, "%s", arm_regnames[given & 0xf]);
+
+ if ((given & 0xff0) != 0)
+ {
+ if ((given & 0x10) == 0)
+ {
+ int amount = (given & 0xf80) >> 7;
+ int shift = (given & 0x60) >> 5;
+
+ if (amount == 0)
+ {
+ if (shift == 3)
+ {
+ fprintf(stream, ", rrx");
+ return;
+ }
+
+ amount = 32;
+ }
+
+ fprintf(stream, ", %s #%d", arm_shift[shift], amount);
+ }
+ else
+ fprintf(stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
+ arm_regnames[(given & 0xf00) >> 8]);
+ }
+}
+
+int print_insn_arm(u_int32_t pc, FILE *stream, u_int32_t given)
+{
+ struct arm_opcode *insn;
+
+ for (insn = arm_opcodes; insn->assembler; insn++)
+ {
+ if ((given & insn->mask) == insn->value)
+ {
+ char * c;
+
+ for (c = insn->assembler; *c; c++)
+ {
+ if (*c == '%')
+ {
+ switch (*++c)
+ {
+ case '%':
+ fprintf(stream, "%%");
+ break;
+
+ case 'a':
+ if (((given & 0x000f0000) == 0x000f0000)
+ && ((given & 0x02000000) == 0))
+ {
+ int offset = given & 0xfff;
+
+ fprintf(stream, "[pc");
+
+ if (given & 0x01000000)
+ {
+ if ((given & 0x00800000) == 0)
+ offset = - offset;
+
+ /* Pre-indexed. */
+ fprintf(stream, ", #%d]", offset);
+
+ offset += pc + 8;
+
+ /* Cope with the possibility of write-back
+ being used. Probably a very dangerous thing
+ for the programmer to do, but who are we to
+ argue ? */
+ if (given & 0x00200000)
+ fprintf(stream, "!");
+ }
+ else
+ {
+ /* Post indexed. */
+ fprintf(stream, "], #%d", offset);
+
+ /* ie ignore the offset. */
+ offset = pc + 8;
+ }
+
+ fprintf(stream, "\t; ");
+ print_address(stream, offset);
+ }
+ else
+ {
+ fprintf(stream, "[%s",
+ arm_regnames[(given >> 16) & 0xf]);
+ if ((given & 0x01000000) != 0)
+ {
+ if ((given & 0x02000000) == 0)
+ {
+ int offset = given & 0xfff;
+ if (offset)
+ fprintf(stream, ", %s#%d",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""), offset);
+ }
+ else
+ {
+ fprintf(stream, ", %s",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""));
+ arm_decode_shift (given, stream);
+ }
+
+ fprintf(stream, "]%s",
+ ((given & 0x00200000) != 0) ? "!" : "");
+ }
+ else
+ {
+ if ((given & 0x02000000) == 0)
+ {
+ int offset = given & 0xfff;
+ if (offset)
+ fprintf(stream, "], %s#%d",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""), offset);
+ else
+ fprintf(stream, "]");
+ }
+ else
+ {
+ fprintf(stream, "], %s",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""));
+ arm_decode_shift (given, stream);
+ }
+ }
+ }
+ break;
+
+ case 's':
+ if ((given & 0x004f0000) == 0x004f0000)
+ {
+ /* PC relative with immediate offset. */
+ int offset = ((given & 0xf00) >> 4) | (given & 0xf);
+
+ if ((given & 0x00800000) == 0)
+ offset = -offset;
+
+ fprintf(stream, "[pc, #%d]\t; ", offset);
+
+ print_address(stream, offset + pc + 8);
+ }
+ else
+ {
+ fprintf(stream, "[%s",
+ arm_regnames[(given >> 16) & 0xf]);
+ if ((given & 0x01000000) != 0)
+ {
+ /* Pre-indexed. */
+ if ((given & 0x00400000) == 0x00400000)
+ {
+ /* Immediate. */
+ int offset = ((given & 0xf00) >> 4) | (given & 0xf);
+ if (offset)
+ fprintf(stream, ", %s#%d",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""), offset);
+ }
+ else
+ {
+ /* Register. */
+ fprintf(stream, ", %s%s",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""),
+ arm_regnames[given & 0xf]);
+ }
+
+ fprintf(stream, "]%s",
+ ((given & 0x00200000) != 0) ? "!" : "");
+ }
+ else
+ {
+ /* Post-indexed. */
+ if ((given & 0x00400000) == 0x00400000)
+ {
+ /* Immediate. */
+ int offset = ((given & 0xf00) >> 4) | (given & 0xf);
+ if (offset)
+ fprintf(stream, "], %s#%d",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""), offset);
+ else
+ fprintf(stream, "]");
+ }
+ else
+ {
+ /* Register. */
+ fprintf(stream, "], %s%s",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""),
+ arm_regnames[given & 0xf]);
+ }
+ }
+ }
+ break;
+
+ case 'b':
+ print_address(stream, BDISP (given) * 4 + pc + 8);
+ break;
+
+ case 'c':
+ fprintf(stream, "%s",
+ arm_conditional [(given >> 28) & 0xf]);
+ break;
+
+ case 'm':
+ {
+ int started = 0;
+ int reg;
+
+ fprintf(stream, "{");
+ for (reg = 0; reg < 16; reg++)
+ if ((given & (1 << reg)) != 0)
+ {
+ if (started)
+ fprintf(stream, ", ");
+ started = 1;
+ fprintf(stream, "%s", arm_regnames[reg]);
+ }
+ fprintf(stream, "}");
+ }
+ break;
+
+ case 'o':
+ if ((given & 0x02000000) != 0)
+ {
+ int rotate = (given & 0xf00) >> 7;
+ int immed = (given & 0xff);
+ immed = (((immed << (32 - rotate))
+ | (immed >> rotate)) & 0xffffffff);
+ fprintf(stream, "#%d\t; 0x%x", immed, immed);
+ }
+ else
+ arm_decode_shift (given, stream);
+ break;
+
+ case 'p':
+ if ((given & 0x0000f000) == 0x0000f000)
+ fprintf(stream, "p");
+ break;
+
+ case 't':
+ if ((given & 0x01200000) == 0x00200000)
+ fprintf(stream, "t");
+ break;
+
+ case 'A':
+ fprintf(stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
+ if ((given & 0x01000000) != 0)
+ {
+ int offset = given & 0xff;
+ if (offset)
+ fprintf(stream, ", %s#%d]%s",
+ ((given & 0x00800000) == 0 ? "-" : ""),
+ offset * 4,
+ ((given & 0x00200000) != 0 ? "!" : ""));
+ else
+ fprintf(stream, "]");
+ }
+ else
+ {
+ int offset = given & 0xff;
+ if (offset)
+ fprintf(stream, "], %s#%d",
+ ((given & 0x00800000) == 0 ? "-" : ""),
+ offset * 4);
+ else
+ fprintf(stream, "]");
+ }
+ break;
+
+ case 'B':
+ /* Print ARM V5 BLX(1) address: pc+25 bits. */
+ {
+ u_int32_t address;
+ u_int32_t offset = 0;
+
+ if (given & 0x00800000)
+ /* Is signed, hi bits should be ones. */
+ offset = (-1) ^ 0x00ffffff;
+
+ /* Offset is (SignExtend(offset field)<<2). */
+ offset += given & 0x00ffffff;
+ offset <<= 2;
+ address = offset + pc + 8;
+
+ if (given & 0x01000000)
+ /* H bit allows addressing to 2-byte boundaries. */
+ address += 2;
+
+ print_address(stream, address);
+ }
+ break;
+
+ case 'I':
+ /* Print a Cirrus/DSP shift immediate. */
+ /* Immediates are 7bit signed ints with bits 0..3 in
+ bits 0..3 of opcode and bits 4..6 in bits 5..7
+ of opcode. */
+ {
+ int imm;
+
+ imm = (given & 0xf) | ((given & 0xe0) >> 1);
+
+ /* Is ``imm'' a negative number? */
+ if (imm & 0x40)
+ imm |= (-1 << 7);
+
+ fprintf(stream, "%d", imm);
+ }
+
+ break;
+
+ case 'C':
+ fprintf(stream, "_");
+ if (given & 0x80000)
+ fprintf(stream, "f");
+ if (given & 0x40000)
+ fprintf(stream, "s");
+ if (given & 0x20000)
+ fprintf(stream, "x");
+ if (given & 0x10000)
+ fprintf(stream, "c");
+ break;
+
+ case 'F':
+ switch (given & 0x00408000)
+ {
+ case 0:
+ fprintf(stream, "4");
+ break;
+ case 0x8000:
+ fprintf(stream, "1");
+ break;
+ case 0x00400000:
+ fprintf(stream, "2");
+ break;
+ default:
+ fprintf(stream, "3");
+ }
+ break;
+
+ case 'P':
+ switch (given & 0x00080080)
+ {
+ case 0:
+ fprintf(stream, "s");
+ break;
+ case 0x80:
+ fprintf(stream, "d");
+ break;
+ case 0x00080000:
+ fprintf(stream, "e");
+ break;
+ default:
+ fprintf(stream, "<illegal precision>");
+ break;
+ }
+ break;
+ case 'Q':
+ switch (given & 0x00408000)
+ {
+ case 0:
+ fprintf(stream, "s");
+ break;
+ case 0x8000:
+ fprintf(stream, "d");
+ break;
+ case 0x00400000:
+ fprintf(stream, "e");
+ break;
+ default:
+ fprintf(stream, "p");
+ break;
+ }
+ break;
+ case 'R':
+ switch (given & 0x60)
+ {
+ case 0:
+ break;
+ case 0x20:
+ fprintf(stream, "p");
+ break;
+ case 0x40:
+ fprintf(stream, "m");
+ break;
+ default:
+ fprintf(stream, "z");
+ break;
+ }
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ {
+ int bitstart = *c++ - '0';
+ int bitend = 0;
+ while (*c >= '0' && *c <= '9')
+ bitstart = (bitstart * 10) + *c++ - '0';
+
+ switch (*c)
+ {
+ case '-':
+ c++;
+
+ while (*c >= '0' && *c <= '9')
+ bitend = (bitend * 10) + *c++ - '0';
+
+ if (!bitend)
+ return -1;
+
+ switch (*c)
+ {
+ case 'r':
+ {
+ int32_t reg;
+
+ reg = given >> bitstart;
+ reg &= (2 << (bitend - bitstart)) - 1;
+
+ fprintf(stream, "%s", arm_regnames[reg]);
+ }
+ break;
+ case 'd':
+ {
+ int32_t reg;
+
+ reg = given >> bitstart;
+ reg &= (2 << (bitend - bitstart)) - 1;
+
+ fprintf(stream, "%d", reg);
+ }
+ break;
+ case 'x':
+ {
+ int32_t reg;
+
+ reg = given >> bitstart;
+ reg &= (2 << (bitend - bitstart)) - 1;
+
+ fprintf(stream, "0x%08x", reg);
+
+ /* Some SWI instructions have special
+ meanings. */
+ if ((given & 0x0fffffff) == 0x0FF00000)
+ fprintf(stream, "\t; IMB");
+ else if ((given & 0x0fffffff) == 0x0FF00001)
+ fprintf(stream, "\t; IMBRange");
+ }
+ break;
+ case 'X':
+ {
+ int32_t reg;
+
+ reg = given >> bitstart;
+ reg &= (2 << (bitend - bitstart)) - 1;
+
+ fprintf(stream, "%01x", reg & 0xf);
+ }
+ break;
+ case 'f':
+ {
+ int32_t reg;
+
+ reg = given >> bitstart;
+ reg &= (2 << (bitend - bitstart)) - 1;
+
+ if (reg > 7)
+ fprintf(stream, "#%s",
+ arm_fp_const[reg & 7]);
+ else
+ fprintf(stream, "f%d", reg);
+ }
+ break;
+ default:
+ return -1;
+ }
+ break;
+
+ case 'y':
+ case 'z':
+ {
+ int single = *c == 'y';
+ int regno;
+
+ switch (bitstart)
+ {
+ case 4: /* Sm pair */
+ fprintf(stream, "{");
+ /* Fall through. */
+ case 0: /* Sm, Dm */
+ regno = given & 0x0000000f;
+ if (single)
+ {
+ regno <<= 1;
+ regno += (given >> 5) & 1;
+ }
+ break;
+
+ case 1: /* Sd, Dd */
+ regno = (given >> 12) & 0x0000000f;
+ if (single)
+ {
+ regno <<= 1;
+ regno += (given >> 22) & 1;
+ }
+ break;
+
+ case 2: /* Sn, Dn */
+ regno = (given >> 16) & 0x0000000f;
+ if (single)
+ {
+ regno <<= 1;
+ regno += (given >> 7) & 1;
+ }
+ break;
+
+ case 3: /* List */
+ fprintf(stream, "{");
+ regno = (given >> 12) & 0x0000000f;
+ if (single)
+ {
+ regno <<= 1;
+ regno += (given >> 22) & 1;
+ }
+ break;
+
+
+ default:
+ return -1;
+ }
+
+ fprintf(stream, "%c%d", single ? 's' : 'd', regno);
+
+ if (bitstart == 3)
+ {
+ int count = given & 0xff;
+
+ if (single == 0)
+ count >>= 1;
+
+ if (--count)
+ {
+ fprintf(stream, "-%c%d",
+ single ? 's' : 'd',
+ regno + count);
+ }
+
+ fprintf(stream, "}");
+ }
+ else if (bitstart == 4)
+ fprintf(stream, ", %c%d}", single ? 's' : 'd',
+ regno + 1);
+
+ break;
+ }
+
+ case '`':
+ c++;
+ if ((given & (1 << bitstart)) == 0)
+ fprintf(stream, "%c", *c);
+ break;
+ case '\'':
+ c++;
+ if ((given & (1 << bitstart)) != 0)
+ fprintf(stream, "%c", *c);
+ break;
+ case '?':
+ ++c;
+ if ((given & (1 << bitstart)) != 0)
+ fprintf(stream, "%c", *c++);
+ else
+ fprintf(stream, "%c", *++c);
+ break;
+ default:
+ return -1;
+ }
+ break;
+
+ default:
+ return -1;
+ }
+ }
+ }
+ else
+ fprintf(stream, "%c", *c);
+ }
+ return 0;
+ }
+ }
+ return -1;
+}
diff --git a/misc/buildroot/toolchain/nxflat/arm/dyncall_skeleton.def b/misc/buildroot/toolchain/nxflat/arm/dyncall_skeleton.def
new file mode 100644
index 000000000..8a42e6486
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/arm/dyncall_skeleton.def
@@ -0,0 +1,216 @@
+/***********************************************************************
+ * toolchain/nxflat/arm/dyncall_skeleton.def
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************************************/
+
+/*******************************************************************
+ * File Prologue
+ *******************************************************************/
+
+static const char file_prologue[] =
+ "/*******************************************************************\n"
+ " *\n"
+ " * This file contains the dynamic call logic that performs the thunk\n"
+ " * for outound calls from one module to another.\n"
+ " *\n"
+ " * ARM register quick reference:\n"
+ " *\n"
+ " * Name Number ARM Procedure Calling Standard Role\n"
+ " *\n"
+ " * a1 r0 argument 1/integer result/scratch register/argc\n"
+ " * a2 r1 argument 2/scratch register/argv\n"
+ " * a3 r2 argument 3/scratch register/envp\n"
+ " * a4 r3 argument 4/scratch register\n"
+ " * v1 r4 register variable\n"
+ " * v2 r5 register variable\n"
+ " * v3 r6 register variable\n"
+ " * v4 r7 register variable\n"
+ " * v5 r8 register variable\n"
+ " * sb/v6 r9 static base/register variable\n"
+ " * sl/v7 r10 stack limit/stack chunk handle/reg. variable\n"
+ " * fp r11 frame pointer\n"
+ " * ip r12 scratch register/new-sb in inter-link-unit calls\n"
+ " * sp r13 lower end of current stack frame\n"
+ " * lr r14 link address/scratch register\n"
+ " * pc r15 program counter\n"
+ " *******************************************************************/\n\n"
+ "/*******************************************************************\n"
+ " * Included Files\n"
+ " *******************************************************************/\n\n"
+ "/*******************************************************************\n"
+ " * Definitions\n"
+ " *******************************************************************/\n";
+
+static const char import_prologue[] = "";
+
+/*******************************************************************
+ * Import Function Name String Table
+ *******************************************************************/
+
+static const char import_name_strtab_prologue[] =
+ "\n/*******************************************************************\n"
+ " * Import Function Names\n"
+ " *******************************************************************/\n\n"
+ "/* These are the names of all of the functions that are imported.\n"
+ " * Notice that all data associated with the library names is retained\n"
+ " * in the .text section."
+ " */\n\n"
+ "\t.text\n"
+ "\t.align\t0\n";
+
+#define MKIMPSTRTABARG(fn,i) (i), (i), (i), (fn), (i), (i)
+
+static const char import_name_strtab_format[] =
+ "\n\t.local\t__dynimport%04d\n"
+ "\t.type\t__dynimport%04d, object\n\n"
+ "__dynimport%04d:\n"
+ "\t.asciz\t\"%s\"\n"
+ "\t.size\t__dynimport%04d, .-__dynimport%04d\n";
+
+/*******************************************************************
+ * Dyanamic Call Information
+ *******************************************************************/
+
+static const char dynimport_decl_prologue[] =
+ "\n/*******************************************************************\n"
+ " * Imported Symbol Table (an array of type struct flat_import)\n"
+ " *******************************************************************/\n\n"
+ "/* Notice that, unlike most other arrays in this file, this array\n"
+ " * is declared to reside in .data. Because of this, there will be\n"
+ " * per-process instances of this table.\n"
+ " */\n\n"
+ "\t.data\n"
+ "\t.align\t2\n\n"
+ "\t.global\t__dynimport_begin\n"
+ "\t.type\t__dynimport_begin, object\n"
+ "\t.global\t__dynimport_end\n"
+ "\t.type\t__dynimport_end, object\n\n";
+
+#define MKINFODECLARGS(fn, i) (i), (fn), (i)
+
+static const char dynimport_decl_format[] =
+ "\t.local\t__dyninfo%04d\t/* Dynamic info for imported symbol %s */\n"
+ "\t.type\t__dyninfo%04d, object\n";
+
+static const char dynimport_array_prologue[] =
+ "\n__dynimport_begin:\n";
+
+#define MKINFOARGS(fn, i) (i), (fn), (i), (i), (i)
+
+static const char dynimport_array_format[] =
+ "__dyninfo%04d:\t\t\t/* Dynamic info for imported symbol %s */\n"
+ "\t.word\t__dynimport%04d\t/* Offset to name of imported function */\n"
+ "\t.word\t0\t\t/* Resolved address of imported function */\n"
+ "\t.size\t__dyninfo%04d, .-__dyninfo%04d\n";
+
+static const char dynimport_array_epilogue[] =
+ "__dynimport_end:\n"
+ "\t.size\t__dynimport_begin, __dynimport_end-__dynimport_begin\n";
+
+static const char dyncall_decl_prologue[] =
+ "\n/*******************************************************************\n"
+ " * Dynamic Call Logic\n"
+ " *******************************************************************/\n\n"
+ "\t.text\n"
+ "\t.align\t2\n";
+
+#define MKCALLARGS(fn, i) (fn), (fn), (fn), (fn), (i), (i), (i), (fn), (fn)
+
+#ifndef __NO_GOT__
+
+static const char dyncall_format[] =
+ "\n/* Dynamic call logic for imported symbol %s */\n\n"
+ "\t.global\t%s\n"
+ "\t.type\t%s, function\n\n"
+ "%s:\n"
+ "\tldr\tip,.Ldyn%04d\n"
+ "\tadd\tip,ip,sl\n"
+ "\tldr\tip,[ip,#4]\n"
+ "\tbx\tip\n"
+ ".Ldyn%04d:\n"
+ "\t.word\t__dyninfo%04d(GOTOFF)\n"
+ "\t.size\t%s, .-%s\n";
+
+static const char nonreturning_dyncall_format[] =
+ "\n/* Dynamic call logic for imported, non-returning symbol %s */\n\n"
+ "\t.global\t%s\n"
+ "\t.type\t%s, function\n\n"
+ "%s:\n"
+ "\tldr\tip,.Ldyn%04d\n"
+ "\tadd\tip,ip,sl\n"
+ "\tldr\tip,[ip,#4]\n"
+ "\tbx\tip\n"
+ ".Ldyn%04d:\n"
+ "\t.word\t__dyninfo%04d(GOTOFF)\n"
+ "\t.size\t%s, .-%s\n";
+
+#else
+
+static const char dyncall_format[] =
+ "\n/* Dynamic call logic for imported symbol %s */\n\n"
+ "\t.global\t%s\n"
+ "\t.type\t%s, function\n\n"
+ "%s:\n"
+ "\tldr\tip,.Ldyn%04d\n"
+ "\tadd\tip,ip,sl\n"
+ "\tldr\tip,[ip,#4]\n"
+ "\tbx\tip\n"
+ ".Ldyn%04d:\n"
+ "\t.word\t__dyninfo%04d\n"
+ "\t.size\t%s, .-%s\n";
+
+static const char nonreturning_dyncall_format[] =
+ "\n/* Dynamic call logic for imported, non-returning symbol %s */\n\n"
+ "\t.global\t%s\n"
+ "\t.type\t%s, function\n\n"
+ "%s:\n"
+ "\tldr\tip,.Ldyn%04d\n"
+ "\tadd\tip,ip,sl\n"
+ "\tldr\tip,[ip,#4]\n"
+ "\tbx\tip\n"
+ ".Ldyn%04d:\n"
+ "\t.word\t__dyninfo%04d\n"
+ "\t.size\t%s, .-%s\n";
+
+#endif
+
+/*******************************************************************
+ * File Epilogue
+ *******************************************************************/
+
+static const char file_epilogue[] =
+ "\t.end\n";
+
+
+
+
diff --git a/misc/buildroot/toolchain/nxflat/ldnxflat.c b/misc/buildroot/toolchain/nxflat/ldnxflat.c
new file mode 100644
index 000000000..69cb19529
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/ldnxflat.c
@@ -0,0 +1,2336 @@
+/***********************************************************************
+ * toolchain/nxflat/ldnxflat.c
+ * Convert ELF (or any BFD format) to NXFLAT binary format
+ *
+ * ldnxflat takes a fully resolvable elf binary which was linked with -r
+ * and resolves all references, then generates relocation table entries for
+ * any relocation entries in data sections. This is designed to work with
+ * the options -fpic -msingle-pic-base (and -mno-got or -membedded-pic, but
+ * will and GOT relocations as well).
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ *
+ * Modified from ldelf2xflat (see http://xflat.org):
+ *
+ * Copyright (c) 2002, 2006, Cadenux, LLC. All rights reserved.
+ * Copyright (c) 2002, 2006, Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Extended from the FLAT ldnxflat.c (original copyright below )
+ *
+ * Copyright (C) 2000 NETsilicon, Inc.
+ * Copyright (C) 2000 WireSpeed Communications Corp
+ *
+ * author : Joe deBlaquiere ( joe@wirespeed.com )
+ *
+ * converted from elf2flt.c ( original copyright below )
+ *
+ * elf2flt copyright :
+ *
+ * (c) 1999, Greg Ungerer <gerg@moreton.com.au>
+ * (c) 1999, Phil Blundell, Nexus Electronics Ltd <pb@nexus.co.uk>
+ *
+ * Hacked this about badly to fully support relocating binaries.
+ *
+ * Originally obj-res.c
+ *
+ * (c) 1998, Kenneth Albanowski <kjahds@kjahds.com>
+ * (c) 1998, D. Jeff Dionne
+ * (c) 1998, The Silver Hammer Group Ltd.
+ * (c) 1996, 1997 Dionne & Associates
+ * jeff@ryeham.ee.ryerson.ca
+ *
+ * Relocation added March 1997, Kresten Krab Thorup
+ * krab@california.daimi.aau.dk
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ***********************************************************************/
+
+/***********************************************************************
+ * Included Files
+ ***********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#include "bfd.h"
+#include "arch/arch.h"
+#include "nxflat.h"
+
+/***********************************************************************
+ * Compilation Switches
+ ***********************************************************************/
+
+/* #define RELOCS_IN_NETWORK_ORDER 1 */
+
+#define LIBS_CAN_INCLUDE_LIBS 1
+
+/* Debug output */
+
+#if 0
+# define message(fmt, arg...) printf("%s: " fmt, __func__, ##arg)
+# define dbg(fmt, arg...) if (verbose) printf("%s: " fmt, __func__, ##arg)
+# define vdbg(fmt, arg...) if (verbose > 1) printf("%s: " fmt, __func__, ##arg)
+#else
+# define message(fmt, arg...) printf(fmt, ##arg)
+# define dbg(fmt, arg...) if (verbose) printf(fmt, ##arg)
+# define vdbg(fmt, arg...) if (verbose > 1) printf(fmt, ##arg)
+#endif
+#define err(fmt, arg...) fprintf(stderr, "ERROR -- " fmt, ##arg)
+#define warn(fmt, arg...) fprintf(stderr, "WARNING -- " fmt, ##arg)
+
+/***********************************************************************
+ * Definitions
+ ***********************************************************************/
+
+#ifndef PARAMS
+# define PARAMS(x) x
+#endif
+
+#ifdef __CYGWIN32__
+# define O_PLATFORM O_BINARY
+#else
+# define O_PLATFORM 0
+#endif
+
+#define MAX_SECTIONS 16
+#define DEFAULT_STACK_SIZE 4096
+
+#define IS_GLOBAL(x) ((((x)->flags)&(BSF_GLOBAL))!=0)
+
+#define NXFLAT_HDR_SIZE sizeof(struct nxflat_hdr_s)
+
+/* The names of these fields have changed in later versions of binutils
+ * (after 2.13 and before 2.15) and the meaning of _rawsize is has also
+ * changed somewhat. In the same timeframe, the name of the section
+ * structure changed.
+ */
+
+#if 0
+# define COOKED_SIZE _cooked_size
+# define RAW_SIZE _raw_size
+# define bfd_section sec
+#else
+# define COOKED_SIZE size
+# define RAW_SIZE rawsize
+#endif
+
+#define NXFLAT_RELOC_TARGET_TEXT 0
+#define NXFLAT_RELOC_TARGET_DATA 1
+#define NXFLAT_RELOC_TARGET_RODATA 2
+#define NXFLAT_RELOC_TARGET_BSS 3
+#define NXFLAT_RELOC_TARGET_UNKNOWN 4
+
+/***********************************************************************
+ * Private Types
+ ***********************************************************************/
+
+/* Needs to match definition in include/elf/internal.h. This is from binutils-2.19.1 */
+
+struct elf_internal_sym
+{
+ bfd_vma st_value; /* Value of the symbol */
+ bfd_vma st_size; /* Associated symbol size */
+ unsigned long st_name; /* Symbol name, index in string tbl */
+ unsigned char st_info; /* Type and binding attributes */
+ unsigned char st_other; /* Visibilty, and target specific */
+ unsigned int st_shndx; /* Associated section index */
+};
+
+typedef struct
+{
+ /* The BFD symbol. */
+
+ asymbol symbol;
+
+ /* ELF symbol information. */
+
+ struct elf_internal_sym internal_elf_sym;
+
+ /* Backend specific information. */
+
+ union
+ {
+ unsigned int hppa_arg_reloc;
+ void *mips_extr;
+ void *any;
+ }
+ tc_data;
+
+ /* Version information. This is from an Elf_Internal_Versym structure in a
+ * SHT_GNU_versym section. It is zero if there is no version information. */
+
+ u_int16_t version;
+
+} elf_symbol_type;
+
+typedef struct _segment_info
+{
+ const char *name;
+ bfd_vma low_mark;
+ bfd_vma high_mark;
+ size_t size;
+ void *contents;
+ asection *subsect[MAX_SECTIONS];
+ int nsubsects;
+} segment_info;
+
+typedef void (*func_type) (asymbol * sym, void *arg1, void *arg2, void *arg3);
+
+/* This structure defines the got entry for one symbol */
+
+struct nxflat_got_s
+{
+ asymbol *sym; /* Symbol */
+ u_int32_t offset; /* GOT offset for this symbol */
+};
+
+/***********************************************************************
+ * Private Variable Data
+ ***********************************************************************/
+
+static int verbose = 0;
+static int dsyms = 0;
+static int stack_size = 0;
+static int nerrors = 0;
+
+static int32_t counter = 0;
+
+static const char *program_name = NULL;
+static const char *bfd_filename = NULL;
+static const char *entry_name = NULL;
+static char *out_filename = NULL;
+
+static segment_info text_info;
+static segment_info data_info;
+static segment_info bss_info;
+
+static asymbol **symbol_table = NULL;
+static int32_t number_of_symbols = 0;
+
+static asymbol *entry_symbol = NULL;
+static asymbol *dynimport_begin_symbol = NULL;
+static asymbol *dynimport_end_symbol = NULL;
+
+struct nxflat_reloc_s *nxflat_relocs;
+static int nxflat_nrelocs;
+
+static struct nxflat_got_s *got_offsets; /* realloc'ed array of GOT entry descriptions */
+static u_int32_t got_size; /* The size of the GOT to be allocated */
+int ngot_offsets; /* Number of GOT offsets in got_offsets[] */
+
+/***********************************************************************
+ * Private Constant Data
+ ***********************************************************************/
+
+static const char default_exe_entry_name[] = "_start";
+static const char dynimport_begin_name[] = "__dynimport_begin";
+static const char dynimport_end_name[] = "__dynimport_end";
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * nxflat_swap32
+ ***********************************************************************/
+
+#ifdef ARCH_BIG_ENDIAN
+static inline u_int32_t nxflat_swap32(u_int32_t little)
+{
+ u_int32_t big =
+ ((little >> 24) & 0xff) |
+ (((little >> 16) & 0xff) << 8) |
+ (((little >> 8) & 0xff) << 16) | ((little & 0xff) << 24);
+ return big;
+}
+#endif
+
+/***********************************************************************
+ * get_xflat32
+ ***********************************************************************/
+
+static inline u_int32_t get_xflat32(u_int32_t * addr32)
+{
+ return ntohl(*addr32);
+}
+
+/***********************************************************************
+ * put_xflat32
+ ***********************************************************************/
+
+static void inline put_xflat32(u_int32_t * addr32, u_int32_t val32)
+{
+ *addr32 = htonl(val32);
+}
+
+/***********************************************************************
+ * put_xflat16
+ ***********************************************************************/
+
+static void inline put_xflat16(u_int16_t * addr16, u_int16_t val16)
+{
+#if 1
+ *addr16 = htons(val16);
+#else
+ u_int32_t *addr32 = (u_int32_t *) (((u_int32_t) addr16) & ~3);
+ u_int32_t ndx = ((((u_int32_t) addr16) >> 1) & 1);
+
+ union
+ {
+ u_int16_t hw[2];
+ u_int32_t w;
+ } uword;
+
+ /* Fetch the 32 bit value */
+
+ uword.w = get_xflat32(addr32);
+
+ /* Add in the 16 bit value */
+
+ uword.hw[ndx] = val16;
+
+ /* Then save the 32-bit value */
+
+ put_xflat32(addr32, uword.w);
+#endif
+}
+
+/***********************************************************************
+ * nxflat_write
+ ***********************************************************************/
+
+static void nxflat_write(int fd, const char *buffer, int buflen)
+{
+ vdbg("Writing fd: %d buffer: %p buflen: %d\n", fd, buffer, buflen);
+
+ /* Dump the entire buffer if very strong debug is selected */
+
+ if (verbose > 2)
+ {
+ static int offset = 0;
+ const unsigned char *ptr = (const unsigned char *)buffer;
+ int i;
+ int j;
+
+ for (i = 0; i < buflen; i += 32)
+ {
+ printf("%08x:", offset + i);
+ for (j = 0; j < 32 && (i + j) < buflen; j++)
+ {
+ printf(" %02x", *ptr++);
+ }
+ printf("\n");
+ }
+ offset += buflen;
+ }
+
+ /* Write the data to file, handling errors and interruptions */
+
+ do
+ {
+ ssize_t nwritten = write(fd, buffer, buflen);
+ if (nwritten < 0)
+ {
+ if (errno != EINTR)
+ {
+ err("Write to output file failed: %s\n", strerror(errno));
+ exit(1);
+ }
+ }
+ else
+ {
+ buffer += nwritten;
+ buflen -= nwritten;
+ }
+ }
+ while (buflen > 0);
+}
+
+/***********************************************************************
+ * get_symbols
+ ***********************************************************************/
+
+static asymbol **get_symbols(bfd *abfd, int32_t *num)
+{
+ int32_t storage_needed;
+
+ if (dsyms)
+ {
+ storage_needed = bfd_get_dynamic_symtab_upper_bound(abfd);
+ }
+ else
+ {
+ storage_needed = bfd_get_symtab_upper_bound(abfd);
+ }
+
+ if (storage_needed < 0)
+ {
+ abort();
+ }
+
+ if (storage_needed == 0)
+ {
+ return NULL;
+ }
+
+ symbol_table = (asymbol**)malloc(storage_needed);
+
+ if (dsyms)
+ {
+ number_of_symbols = bfd_canonicalize_dynamic_symtab(abfd, symbol_table);
+ }
+ else
+ {
+ number_of_symbols = bfd_canonicalize_symtab(abfd, symbol_table);
+ }
+
+ if (number_of_symbols < 0)
+ {
+ abort();
+ }
+
+ *num = number_of_symbols;
+
+ vdbg("Read %ld symbols\n", (long)number_of_symbols);
+ return symbol_table;
+}
+
+/***********************************************************************
+ * traverse_global_symbols
+ ***********************************************************************/
+
+static void
+traverse_global_symbols(void *arg1, void *arg2, void *arg3, func_type fn)
+{
+ int i;
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ /* Check if it is a global function symbol defined in this */
+
+ if (IS_GLOBAL(symbol_table[i]))
+ {
+ /* Yes, process the symbol */
+
+ fn(symbol_table[i], arg1, arg2, arg3);
+ }
+ }
+}
+
+/***********************************************************************
+ * check_special_symbol
+ ***********************************************************************/
+
+static void check_special_symbol(asymbol * sym,
+ void *arg1, void *arg2, void *arg3)
+{
+ if ((entry_name) && (strcmp(entry_name, sym->name) == 0))
+ {
+ entry_symbol = sym;
+ }
+ else if (strcmp(dynimport_begin_name, sym->name) == 0)
+ {
+ dynimport_begin_symbol = sym;
+ }
+ else if (strcmp(dynimport_end_name, sym->name) == 0)
+ {
+ dynimport_end_symbol = sym;
+ }
+ counter++;
+}
+
+/***********************************************************************
+ * find_special_symbols
+ ***********************************************************************/
+
+static void inline find_special_symbols(void)
+{
+ counter = 0;
+ traverse_global_symbols(NULL, NULL, NULL, check_special_symbol);
+
+ if (entry_symbol == NULL)
+ {
+ err("Executable entry point \"%s\" not found\n", entry_name);
+ exit(1);
+ }
+
+ if (dynimport_begin_symbol == NULL)
+ {
+ warn("Special symbol \"%s\" not found\n", dynimport_begin_name);
+ dynimport_end_symbol = NULL;
+ }
+ else if (dynimport_end_symbol == NULL)
+ {
+ err("Symbol \"%s\" found, but missing \"%s\"\n",
+ dynimport_begin_name, dynimport_end_name);
+ exit(1);
+ }
+}
+
+/***********************************************************************
+ * put_special_symbol
+ ***********************************************************************/
+
+static void
+put_special_symbol(asymbol *begin_sym, asymbol *end_sym,
+ u_int32_t *addr, u_int16_t *count,
+ u_int32_t elem_size, u_int32_t offset)
+{
+ u_int32_t file_offset = 0;
+ u_int32_t elems = 0;
+
+ u_int32_t begin_sym_value;
+ u_int32_t begin_sect_vma;
+
+ /* We'll assume its okay if this symbol was not found. */
+
+ if (begin_sym != NULL)
+ {
+ vdbg("begin: '%s' end: '%s' offset: %08lx\n",
+ begin_sym->name, end_sym->name, (long)(NXFLAT_HDR_SIZE+offset));
+
+ /* Get the value of the beginning symbol and the section that it is
+ * defined in. */
+
+ begin_sym_value = begin_sym->value;
+ if (begin_sym->section == NULL)
+ {
+ err("No section for symbol \"%s\"\n", begin_sym->name);
+ exit(1);
+ }
+ else
+ {
+ /* Get the file offset to the beginning symbol */
+
+ begin_sect_vma = begin_sym->section->vma;
+
+ file_offset = NXFLAT_HDR_SIZE + /* Size of the NXFLAT header */
+ begin_sect_vma + /* Virtual address of section */
+ begin_sym_value + /* Value of the symbol */
+ offset; /* Additional file offset */
+
+ /* If there is a begin symbol, then there MUST be a corresponding
+ * ending symbol. We must have this to get the size of the data
+ * structure. This size will be used to determined the number of
+ * elements in the array. */
+
+ if (end_sym == NULL)
+ {
+ /* No matching end symbol */
+
+ err("ERROR: Begin sym \"%s\" found, no corresponding end\n",
+ begin_sym->name);
+ exit(1);
+ }
+ else if (end_sym->section == NULL)
+ {
+ /* No section associated with the end symbol */
+
+ err("No section for symbol \"%s\"\n", end_sym->name);
+ exit(1);
+ }
+ else if (end_sym->section != begin_sym->section)
+ {
+ /* Section associated with the end symbol is not the same as the
+ * section associated with the begin symbol. */
+
+ err("Begin sym \"%s\" is defined in section \"%s\"\n",
+ begin_sym->name, begin_sym->section->name);
+ err(" but sym \"%s\" is defined in section \"%s\"\n",
+ end_sym->name, end_sym->section->name);
+ exit(1);
+ }
+ else if (end_sym->value < begin_sym_value)
+ {
+ /* End symbol is before the begin symbol? */
+
+ err("Begin sym \"%s\" lies at offset %d in section \"%s\"\n",
+ begin_sym->name, begin_sym_value, begin_sym->section->name);
+ err(" but sym \"%s\" is before that at offset: %ld\n",
+ end_sym->name, (long)end_sym->value);
+ exit(1);
+ }
+ else
+ {
+ /* Get the size of the structure in bytes */
+
+ u_int32_t array_size = end_sym->value - begin_sym_value;
+
+ /* Get the number of elements in the structure. */
+
+ elems = array_size / elem_size;
+
+ /* Verify that there are an even number of elements in the array. */
+
+ if (elems * elem_size != array_size)
+ {
+ err("Array size (%d) is not a multiple of the element size (%d)\n",
+ array_size, elem_size);
+ exit(1);
+ }
+ }
+ }
+
+ dbg("Symbol %s: value: %08x section offset: %08x file offset: %08x count: %d\n",
+ begin_sym->name, begin_sym_value, begin_sect_vma, file_offset, elems);
+ }
+
+ put_xflat32(addr, file_offset);
+ put_xflat16(count, elems);
+}
+
+/***********************************************************************
+ * put_entry_point
+ ***********************************************************************/
+
+static void put_entry_point(struct nxflat_hdr_s *hdr)
+{
+ u_int32_t entry_point = 0;
+
+ if (entry_symbol)
+ {
+ struct bfd_section *sect;
+
+ /* Does this symbol lie in the text section? */
+
+ sect = entry_symbol->section;
+ if (sect == NULL)
+ {
+ err("No section for entry symbol \"%s\"\n", entry_symbol->name);
+ exit(1);
+ }
+
+ /* Get the file offset to the entry point symbol */
+
+ entry_point = NXFLAT_HDR_SIZE + sect->vma + entry_symbol->value;
+
+ printf("Entry symbol \"%s\": %08x in section \"%s\"\n",
+ entry_symbol->name, entry_point, sect->name);
+
+ dbg(" HDR: %08lx + Section VMA: %08lx + Symbol Value: %08lx\n",
+ (long)NXFLAT_HDR_SIZE, (long)sect->vma, (long)entry_symbol->value);
+ }
+
+ /* Does the entry point lie within the text region? */
+
+ if ((entry_point < NXFLAT_HDR_SIZE) ||
+ (entry_point >= NXFLAT_HDR_SIZE + text_info.size))
+ {
+
+ /* No... One special case: A shared library may not need an
+ * initialization entry point. */
+
+ if (entry_point == 0)
+ {
+ /* Complain a little in this case... The used might have intended to
+ * specify one. */
+
+ warn("Library has no initialization entry point\n");
+ }
+ else
+ {
+ /* Otherwise, complain a lot. We either have a program with no
+ * entry_point or a bogus entry_point. */
+
+ err("Invalid entry point: %08x\n", entry_point);
+ err(" Valid TEXT range: %08lx - %08lx\n",
+ (long)NXFLAT_HDR_SIZE, (long)(NXFLAT_HDR_SIZE + text_info.size));
+ exit(1);
+ }
+ }
+
+ /* Put the entry point into the NXFLAT header. */
+
+ put_xflat32(&hdr->h_entry, entry_point);
+}
+
+/***********************************************************************
+ * get_reloc_type
+ ***********************************************************************/
+
+static int get_reloc_type(asection *sym_section, segment_info **sym_segment)
+{
+ int i;
+
+ /* Locate the address referred to by section type. In the context in which
+ * this runs, we can no longer use the flags field (it is zero for some
+ * reason). But we can search for matches with the buffered section
+ * pointers. */
+
+ /* Check if the symbol is defined in a BSS section */
+
+ for (i = 0; i < bss_info.nsubsects; i++)
+ {
+ if (bss_info.subsect[i] == sym_section)
+ {
+ /* Yes... */
+
+ vdbg("Sym section %s is BSS\n", sym_section->name);
+
+ if (sym_segment)
+ {
+ *sym_segment = &bss_info;
+ }
+ return NXFLAT_RELOC_TARGET_BSS;
+ }
+ }
+
+ /* Check if the symbol is defined in a TEXT section */
+
+ for (i = 0; i < text_info.nsubsects; i++)
+ {
+ if (text_info.subsect[i] == sym_section)
+ {
+ /* Yes... */
+
+ vdbg("Sym section %s is CODE\n", sym_section->name);
+
+ if (sym_segment)
+ {
+ *sym_segment = &text_info;
+ }
+ return NXFLAT_RELOC_TARGET_TEXT;
+ }
+ }
+
+ /* Check if the symbol is defined in a DATA section */
+
+ for (i = 0; i < data_info.nsubsects; i++)
+ {
+ if (data_info.subsect[i] == sym_section)
+ {
+ /* Yes... */
+
+ vdbg("Sym section %s is DATA\n", sym_section->name);
+
+ if (sym_segment)
+ {
+ *sym_segment = &data_info;
+ }
+ return NXFLAT_RELOC_TARGET_DATA;
+ }
+ }
+
+ err("Could not find region for sym_section \"%s\" (%p)\n",
+ sym_section->name, sym_section);
+
+ return NXFLAT_RELOC_TARGET_UNKNOWN;
+}
+
+/***********************************************************************
+ * find_got_entry
+ ***********************************************************************/
+
+/* Find the GOT entry for a particular symbol index */
+
+static struct nxflat_got_s *find_got_entry(asymbol *sym)
+{
+ int i;
+ for (i = 0; i < ngot_offsets; i++)
+ {
+ if (got_offsets[i].sym == sym)
+ {
+ return &got_offsets[i];
+ }
+ }
+ return NULL;
+}
+
+/***********************************************************************
+ * alloc_got_entry
+ ***********************************************************************/
+
+/* Allocate a new got entry */
+
+static void alloc_got_entry(asymbol *sym)
+{
+ struct nxflat_got_s *newgot;
+ int noffsets;
+
+ /* First, make sure that we don't already have an entry for this symbol */
+
+ if (find_got_entry(sym) == 0)
+ {
+ /* Realloc the array of GOT offsets to hold one more */
+
+ noffsets = ngot_offsets + 1;
+ newgot = (struct nxflat_got_s *)realloc(got_offsets, sizeof(struct nxflat_got_s) * noffsets);
+ if (!newgot)
+ {
+ err("Failed to extend the GOT offset table. noffsets: %d\n", noffsets);
+ }
+ else
+ {
+ /* Add the new symbol offset to the end of the reallocated table */
+
+ newgot[ngot_offsets].sym = sym;
+ newgot[ngot_offsets].offset = got_size;
+
+ /* Update counts and sizes */
+
+ got_offsets = newgot;
+ ngot_offsets = noffsets;
+ got_size = sizeof(u_int32_t) * noffsets;
+ }
+ }
+}
+
+/***********************************************************************
+ * resolve_segment_relocs
+ ***********************************************************************/
+
+static void
+resolve_segment_relocs(bfd *input_bfd, segment_info *inf, asymbol **syms)
+{
+ struct nxflat_reloc_s *relocs;
+ arelent **relpp;
+ int relsize;
+ int reloc_type;
+ int relcount;
+ int i;
+ int j;
+
+ for (i = 0; i < inf->nsubsects; i++)
+ {
+ relcount = inf->subsect[i]->reloc_count;
+ vdbg("Section %s has %08x relocs\n", inf->subsect[i]->name, relcount);
+
+ if (0 >= relcount)
+ {
+ continue;
+ }
+
+ relsize = bfd_get_reloc_upper_bound(input_bfd, inf->subsect[i]);
+ vdbg("Section %s reloc size: %08x\n", inf->subsect[i]->name, relsize);
+
+ if (0 >= relsize)
+ {
+ continue;
+ }
+
+ relpp = (arelent**)malloc((size_t) relsize);
+ relcount = bfd_canonicalize_reloc(input_bfd, inf->subsect[i], relpp, syms);
+
+ if (relcount < 0)
+ {
+ err("bfd_canonicalize_reloc failed!\n");
+ exit(1);
+ }
+
+ vdbg("Section %s can'd %08x relocs\n", inf->subsect[i]->name, relcount);
+
+ for (j = 0; j < relcount; j++)
+ {
+ /* Get information about this symbol */
+
+ reloc_howto_type *how_to = relpp[j]->howto;
+ asymbol *rel_sym = *relpp[j]->sym_ptr_ptr;
+ asection *rel_section = rel_sym->section;
+ int32_t *target = (int32_t*)(inf->contents + relpp[j]->address);
+ symvalue sym_value;
+
+ /* If the symbol is a thumb function, then set bit 1 of the value */
+
+ sym_value = rel_sym->value;
+#ifdef NXFLAT_THUMB2
+ if ((((elf_symbol_type *)rel_sym)->internal_elf_sym.st_info & 0x0f) == STT_ARM_TFUNC)
+ {
+ sym_value |= 1;
+ }
+ else
+#endif
+
+ /* If the symbol lies in D-Space, then we need to add the size of the GOT
+ * table to the symbol value
+ */
+
+ if ((rel_section->flags & SEC_CODE) == 0 && (rel_section->flags & SEC_ALLOC) != 0)
+ {
+ sym_value += got_size;
+ }
+
+ dbg("rel %-3d: sym [%20s] s_addr @ %08lx val %08lx-%08lx rel %08lx how %s\n",
+ j, rel_sym->name, (long)relpp[j]->address, (long)rel_sym->value,
+ (long)sym_value, (long)relpp[j]->addend, how_to->name);
+
+ switch (how_to->type)
+ {
+ case R_ARM_PLT32:
+ case R_ARM_PC24:
+ {
+ int32_t temp;
+ int32_t saved;
+
+ dbg("performing PC24 link at addr %08lx [%08lx] to sym '%s' [%08lx]\n",
+ (long)relpp[j]->address, (long)*target, rel_sym->name, (long)sym_value);
+
+ /* Can't fix what we ain't got */
+
+ if ((SEC_IN_MEMORY & rel_section->flags) == 0)
+ {
+ err("Section %s not loaded into mem!\n", rel_section->name);
+ exit(1);
+ }
+
+ /* PC24 -> can only fix text to text refs */
+
+ if ((SEC_CODE & rel_section->flags) == 0)
+ {
+ err("Section %s not code!\n", rel_section->name);
+ exit(1);
+ }
+
+ if ((SEC_CODE & inf->subsect[i]->flags) == 0)
+ {
+ err("Section %s not code!\n", rel_section->name);
+ exit(1);
+ }
+
+ if (verbose > 1)
+ {
+ vdbg(" Original opcode @ %p is %08lx ",
+#ifdef ARCH_BIG_ENDIAN
+ target, (long)nxflat_swap32(*target));
+#else
+ target, (long)*target);
+#endif
+ if (verbose > 2)
+ {
+ printf("rsh %d ", how_to->rightshift);
+ printf(" sz %d ", how_to->size);
+ printf("bit %d ", how_to->bitsize);
+ printf("rel %d ", how_to->pc_relative);
+ printf("smask %08lx ", (long)how_to->src_mask);
+ printf("dmask %08lx ", (long)how_to->dst_mask);
+ printf("off %d ", how_to->pcrel_offset);
+ }
+ printf("\n");
+ }
+
+ if (how_to->pcrel_offset)
+ {
+#ifdef ARCH_BIG_ENDIAN
+ saved = temp = (int32_t)nxflat_swap32(*target);
+#else
+ saved = temp = *target;
+#endif
+ /* mask */
+ temp &= how_to->src_mask;
+
+ /* sign extend */
+ temp <<= (32 - how_to->bitsize);
+ temp >>= (32 - how_to->bitsize);
+
+ /* offset */
+ temp +=
+ ((sym_value + rel_section->vma)
+ - relpp[j]->address) >> how_to->rightshift;
+
+ /* demote */
+ /* temp >>= how_to->rightshift; */
+
+ /* mask upper bits from rollover */
+ temp &= how_to->dst_mask;
+
+ /* replace data that was masked */
+ temp |= saved & (~how_to->dst_mask);
+ }
+ else
+ {
+ err("Do not know how pcrel_offset\n");
+ exit(1);
+ }
+
+ vdbg(" Modified opcode: %08lx\n", (long)temp);
+#ifdef ARCH_BIG_ENDIAN
+ *target = (long)nxflat_swap32(temp);
+#else
+ *target = (long)temp;
+#endif
+ }
+ break;
+
+ case R_ARM_ABS32:
+ {
+ int32_t temp;
+ int32_t saved;
+
+ dbg("Performing ABS32 link at addr %08lx [%08lx] to sym '%s' [%08lx]\n",
+ (long)relpp[j]->address, (long)*target, rel_sym->name, (long)sym_value);
+
+ /* ABS32 links from .text are easy - since the fetches will
+ * always be base relative. the ABS32 refs from data will be
+ * handled the same
+ */
+
+ if (verbose > 1)
+ {
+ vdbg(" Original location %p is %08lx ",
+#ifdef ARCH_BIG_ENDIAN
+ target, (long)nxflat_swap32(*target));
+#else
+ target, (long)*target);
+#endif
+ if (verbose > 2)
+ {
+ printf("rsh %d ", how_to->rightshift);
+ printf(" sz %d ", how_to->size);
+ printf("bit %d ", how_to->bitsize);
+ printf("rel %d ", how_to->pc_relative);
+ printf("smask %08lx ", (long)how_to->src_mask);
+ printf("dmask %08lx ", (long)how_to->dst_mask);
+ printf("off %d ", how_to->pcrel_offset);
+ }
+ printf("\n");
+ }
+
+#ifdef ARCH_BIG_ENDIAN
+ saved = temp = (int32_t) nxflat_swap32(*target);
+#else
+ saved = temp = *target;
+#endif
+ /* Mask and sign extend */
+
+ temp &= how_to->src_mask;
+ temp <<= (32 - how_to->bitsize);
+ temp >>= (32 - how_to->bitsize);
+
+ /* Offset */
+
+ temp += (sym_value + rel_section->vma) >> how_to->rightshift;
+
+ /* Mask upper bits from rollover */
+
+ temp &= how_to->dst_mask;
+
+ /* Replace data that was masked */
+
+ temp |= saved & (~how_to->dst_mask);
+
+ vdbg(" Modified location: %08lx\n", (long)temp);
+#ifdef ARCH_BIG_ENDIAN
+ *target = (long)nxflat_swap32(temp);
+#else
+ *target = (long)temp;
+#endif
+ /* Determine where the symbol lies */
+
+ switch (get_reloc_type(rel_section, NULL))
+ {
+ case NXFLAT_RELOC_TARGET_UNKNOWN:
+ default:
+ {
+ err("Symbol relocation section type is unknown\n");
+ nerrors++;
+ }
+ /* Fall through and do something wrong */
+
+ case NXFLAT_RELOC_TARGET_BSS:
+ case NXFLAT_RELOC_TARGET_DATA:
+ {
+ vdbg("Symbol '%s' lies in D-Space\n", rel_sym->name);
+ reloc_type = NXFLAT_RELOC_TYPE_REL32D;
+ }
+ break;
+
+ case NXFLAT_RELOC_TARGET_TEXT:
+ {
+ vdbg("Symbol '%s' lies in I-Space\n", rel_sym->name);
+ reloc_type = NXFLAT_RELOC_TYPE_REL32I;
+ }
+ break;
+ }
+
+ /* Re-allocate memory to include this relocation */
+
+ relocs = (struct nxflat_reloc_s*)
+ realloc(nxflat_relocs, sizeof(struct nxflat_reloc_s) * nxflat_nrelocs + 1);
+ if (!relocs)
+ {
+ err("Failed to re-allocate memory ABS32 relocations (%d relocations)\n",
+ nxflat_nrelocs);
+ nerrors++;
+ }
+ else
+ {
+ /* Reallocation was successful. Update globlas */
+
+ nxflat_nrelocs++;
+ nxflat_relocs = relocs;
+
+ /* Then add the relocation at the end of the table */
+
+ nxflat_relocs[nxflat_nrelocs-1].r_info =
+ NXFLAT_RELOC(reloc_type, relpp[j]->address + got_size);
+
+ vdbg("relocs[%d]: type: %d offset: %08x\n",
+ nxflat_nrelocs-1,
+ NXFLAT_RELOC_TYPE(nxflat_relocs[nxflat_nrelocs-1].r_info),
+ NXFLAT_RELOC_OFFSET(nxflat_relocs[nxflat_nrelocs-1].r_info));
+ }
+ }
+ break;
+
+#ifdef NXFLAT_THUMB2
+ case R_ARM_THM_XPC22:
+ case R_ARM_THM_CALL:
+ case R_ARM_THM_JUMP24:
+ /* Thumb BL (branch long instruction). */
+ {
+ u_int16_t *pinsn = (u_int16_t*)target;
+ u_int16_t upper_insn = pinsn[0];
+ u_int16_t lower_insn = pinsn[1];
+
+ /* Fetch the addend. We use the Thumb-2 encoding (backwards
+ * compatible with Thumb-1) involving the J1 and J2 bits
+ */
+
+ int32_t s = (upper_insn & (1 << 10)) >> 10;
+ int32_t upper = upper_insn & 0x3ff;
+ int32_t lower = lower_insn & 0x7ff;
+ int32_t j1 = (lower_insn & (1 << 13)) >> 13;
+ int32_t j2 = (lower_insn & (1 << 11)) >> 11;
+ int32_t i1 = j1 ^ s ? 0 : 1;
+ int32_t i2 = j2 ^ s ? 0 : 1;
+ int32_t temp;
+ int32_t signbit;
+
+ temp = (i1 << 23) | (i2 << 22) | (upper << 12) | (lower << 1);
+
+ /* Sign extend */
+
+ temp = (temp | ((s ? 0 : 1) << 24)) - (1 << 24);
+
+ dbg("Performing THM link at addr %08lx [%04x %04x] to sym '%s' [%08lx]\n",
+ (long)relpp[j]->address, upper_insn, lower_insn,
+ rel_sym->name, (long)sym_value);
+ vdbg(" Original INSN: %04x %04x temp: %08lx\n",
+ upper_insn, lower_insn, (long)temp);
+
+ /* Add the branch offset (really needs a range check) */
+
+ temp += (sym_value + rel_section->vma - relpp[j]->address);
+
+ if ((lower_insn & 0x5000) == 0x4000)
+ {
+ /* For a BLX instruction, make sure that the relocation is rounded up
+ * to a word boundary. This follows the semantics of the instruction
+ * which specifies that bit 1 of the target address will come from bit
+ * 1 of the base address.
+ */
+
+ temp = (temp + 2) & ~ 3;
+ }
+
+ /* Put RELOCATION back into the insn. Assumes two's complement.
+ * We use the Thumb-2 encoding, which is safe even if dealing with
+ * a Thumb-1 instruction by virtue of our overflow check above.
+ */
+
+ signbit = (temp < 0) ? 1 : 0;
+ upper_insn = (upper_insn & ~0x7ff) | ((temp >> 12) & 0x3ff) | (signbit << 10);
+ lower_insn = (lower_insn & ~0x2fff)
+ | (((!((temp >> 23) & 1)) ^ signbit) << 13)
+ | (((!((temp >> 22) & 1)) ^ signbit) << 11)
+ | ((temp >> 1) & 0x7ff);
+
+ vdbg(" Modified INSN: %04x %04x temp: %08lx Sec VMA: %08lx\n",
+ upper_insn, lower_insn, (long)temp, (long)rel_section->vma);
+
+ /* Put the relocated value back in the object file: */
+
+ pinsn[0] = upper_insn;
+ pinsn[1] = lower_insn;
+ }
+ break;
+#endif
+
+ case R_ARM_GOTOFF:
+ {
+ int reltype;
+
+ /* Relocation is relative to the start of the global offset
+ * table. This is used for things link known offsets to
+ * constant strings in D-Space. I think we can just ignore
+ * this relocation. The usual assembly language sequence
+ * is like:
+ *
+ * ldr r0, .L9 <- r0 holds GOT-relative offset to 'n'
+ * add r0, sl, r0 <- Adding SL produces address of 'n'
+ * ...
+ * .L9:
+ * .word n(GOTOFF)
+ */
+
+ dbg("Perfoming GOTOFF reloc at addr %08lx [%08lx] to sym '%s' [%08lx]\n",
+ (long)relpp[j]->address, (long)*target, rel_sym->name, (long)sym_value);
+
+ /* For this location, we need to set the value to the value
+ * of the symbol in D-Space. (There is obviously a problem if
+ * the symbol lies in I-Space because the offset is not relative
+ * to the PIC address which points to the GOT).
+ */
+
+ /* Check if symbols lies in I- or D-Space */
+
+ reltype = get_reloc_type(rel_section, NULL);
+ if (reltype == NXFLAT_RELOC_TARGET_TEXT)
+ {
+ err("Symbol in GOT32 relocation is in TEXT\n");
+ err(" At addr %08lx to sym '%s' [%08lx]\n",
+ (long)relpp[j]->address, rel_sym->name, (long)sym_value);
+ }
+ else
+ {
+ vdbg(" Original value: %08lx\n", (long)*target);
+ *target = sym_value;
+ vdbg(" Modified value: %08lx\n", (long)*target);
+ }
+ }
+ break;
+
+ case R_ARM_GOT32:
+ case R_ARM_GOT_PREL:
+ {
+ struct nxflat_got_s *got_entry;
+
+ /* Relocation is to the entry for this symbol in the global
+ * offset table. This relocation type is used to set the 32-bit
+ * address of global variables. The usual assembly language sequence
+ * is like:
+ *
+ * ldr r3, .L4 <- r3 holds GOT-relative offset to address of 'n'
+ * ldr r1, [sl,r3] <- r1 holds (relocated) address of 'n'
+ * ...
+ * .L4:
+ * .word n(GOT)
+ */
+
+ dbg("Performing GOT32 reloc at addr %08lx [%08lx] to sym '%s' [%08lx]\n",
+ (long)relpp[j]->address, (long)*target, rel_sym->name, (long)sym_value);
+
+ /* There should be an entry for the relocation allocated in the GOT */
+
+ got_entry = find_got_entry(rel_sym);
+ if (!got_entry)
+ {
+ err("No GOT entry from for symobl '%s'\n", rel_sym->name);
+ nerrors++;
+ }
+ else
+ {
+ /* The fixup is simply to provide the GOT offset as the relocation value */
+
+ vdbg(" Original value: %08lx\n", (long)*target);
+ *target = got_entry->offset;
+ vdbg(" Modified value: %08lx\n", (long)*target);
+ }
+ }
+ break;
+
+ case R_ARM_GOTPC:
+ {
+ /* Use the global offset table as a symbol value */
+
+ dbg("Performing GOTPC reloc at addr %08lx [%08lx] to sym '%s' [%08lx]\n",
+ (long)relpp[j]->address, (long)*target, rel_sym->name, (long)sym_value);
+
+ /* Check if this is TEXT section relocation */
+
+ if ((inf->subsect[i]->flags & SEC_CODE) != 0 &&
+ (inf->subsect[i]->flags & SEC_ALLOC) != 0)
+ {
+ /* The GOT always begins at offset 0 */
+
+ vdbg(" Original value: %08lx\n", (long)*target);
+ *target = 0;
+ vdbg(" Modified value: %08lx\n", (long)*target);
+ }
+ else
+ {
+ err("Attempted GOTPC relocation in outside of I-Space section\n");
+ err(" At addr %08lx [%08lx] to sym '%s' [%08lx]\n",
+ (long)relpp[j]->address, (long)*target,
+ rel_sym->name, (long)sym_value);
+ nerrors++;
+ }
+ }
+ break;
+
+ default:
+ err("Do not know how to handle reloc %d type %s @ %p!\n",
+ how_to->type, how_to->name, how_to);
+ nerrors++;
+ break;
+ }
+ }
+
+ /* Mark the section as having no relocs */
+
+ inf->subsect[i]->flags &= !(SEC_RELOC);
+ inf->subsect[i]->reloc_count = 0;
+ free(relpp);
+ }
+}
+
+/***********************************************************************
+ * allocate_segment_got
+ ***********************************************************************/
+
+/* The GOT lies at the beginning of D-Space. Before we can process
+ * any relocation data, we need to determine the size of the GOT.
+ */
+
+static void allocate_segment_got(bfd *input_bfd, segment_info *inf, asymbol **syms)
+{
+ arelent **relpp;
+ int relsize;
+ int relcount;
+ int i;
+ int j;
+
+ for (i = 0; i < inf->nsubsects; i++)
+ {
+ relcount = inf->subsect[i]->reloc_count;
+ vdbg("Section %s has %08x relocs\n", inf->subsect[i]->name, relcount);
+
+ if (0 >= relcount)
+ {
+ continue;
+ }
+
+ relsize = bfd_get_reloc_upper_bound(input_bfd, inf->subsect[i]);
+ vdbg("Section %s reloc size: %08x\n", inf->subsect[i]->name, relsize);
+
+ if (0 >= relsize)
+ {
+ continue;
+ }
+
+ relpp = (arelent**)malloc((size_t) relsize);
+ relcount = bfd_canonicalize_reloc(input_bfd, inf->subsect[i], relpp, syms);
+
+ if (relcount < 0)
+ {
+ err("bfd_canonicalize_reloc failed!\n");
+ exit(1);
+ }
+
+ vdbg("Section %s can'd %08x relocs\n", inf->subsect[i]->name, relcount);
+
+ for (j = 0; j < relcount; j++)
+ {
+ /* Get information about this symbol */
+
+ reloc_howto_type *how_to = relpp[j]->howto;
+ asymbol *rel_sym = *relpp[j]->sym_ptr_ptr;
+
+ dbg("rel %-3d: sym [%20s] s_addr @ %08lx rel %08lx how %s\n",
+ j, rel_sym->name, (long)relpp[j]->address,
+ (long)relpp[j]->addend, how_to->name);
+
+ switch (how_to->type)
+ {
+ case R_ARM_GOT32:
+ case R_ARM_GOT_PREL:
+ /* This symbol requires a global offset table entry. */
+ {
+ alloc_got_entry(rel_sym);
+
+ dbg(" Created GOT entry %d for sym %p (offset %d)\n",
+ ngot_offsets-1, got_offsets[ngot_offsets-1].sym, got_offsets[ngot_offsets-1].offset);
+ }
+ break;
+
+ case R_ARM_GOTOFF32:
+ case R_ARM_GOTPC:
+ /* These are relative to the GOT, but do not require GOT entries */
+ break;
+
+ default:
+ break;
+ }
+ }
+ free(relpp);
+ }
+}
+
+/***********************************************************************
+ * dump_symbol
+ ***********************************************************************/
+
+static void dump_symbol(asymbol * psym)
+{
+ struct elf_internal_sym *isym =
+ (struct elf_internal_sym *)&((elf_symbol_type *)psym)->internal_elf_sym;
+
+ if (bfd_is_com_section(psym->section))
+ {
+ /* Common Global - unplaced */
+
+ printf("Sym[%24s] @ sz %04lx ",
+ psym->name, (long)psym->value);
+ printf("align %04x ", (u_int32_t)isym->st_value);
+ }
+ else
+ {
+ printf("Sym[%24s] @ %04lx align ",
+ psym->name, (long)psym->value);
+ printf("sz %04x ", (u_int32_t)isym->st_size);
+ }
+
+ /* Symbol type */
+
+ printf("tp %02x ", isym->st_info);
+
+ /* Tag thumb specific attributes */
+
+#ifdef NXFLAT_THUMB2
+ if ((isym->st_info & 0x0f) == STT_ARM_TFUNC || (isym->st_info & 0x0f) == STT_ARM_16BIT)
+ {
+ putchar('T');
+ }
+ else
+ {
+ putchar(' ');
+ }
+#endif
+
+ /* Common attributes */
+
+ printf("|%c", psym->flags & BSF_OBJECT ? 'O' : '.');
+ printf("%c", psym->flags & BSF_DYNAMIC ? 'D' : '.');
+ printf("%c", psym->flags & BSF_FILE ? 'F' : '.');
+ printf("%c", psym->flags & BSF_INDIRECT ? 'I' : '.');
+ printf("%c", psym->flags & BSF_WARNING ? 'W' : '.');
+ printf("%c", psym->flags & BSF_CONSTRUCTOR ? 'C' : '.');
+ printf("%c", psym->flags & BSF_NOT_AT_END ? 'N' : '.');
+ printf("%c", psym->flags & BSF_OLD_COMMON ? 'c' : '.');
+ printf("%c", psym->flags & BSF_SECTION_SYM ? 'S' : '.');
+ printf("%c", psym->flags & BSF_WEAK ? 'w' : '.');
+ printf("%c", psym->flags & BSF_KEEP_G ? 'G' : '.');
+ printf("%c", psym->flags & BSF_KEEP ? 'K' : '.');
+ printf("%c", psym->flags & BSF_FUNCTION ? 'f' : '.');
+ printf("%c", psym->flags & BSF_DEBUGGING ? 'd' : '.');
+ printf("%c", psym->flags & BSF_GLOBAL ? 'g' : '.');
+ printf("%c|", psym->flags & BSF_LOCAL ? 'l' : '.');
+ printf("\n");
+}
+
+/***********************************************************************
+ * check_symbol_overlap
+ ***********************************************************************/
+
+static void check_symbol_overlap(asymbol ** symbols, int number_of_symbols)
+{
+ int i;
+ int j;
+
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ elf_symbol_type *sym_i;
+ bfd_vma base_i;
+ bfd_vma top_i;
+ bfd_vma size_i;
+
+ sym_i = (elf_symbol_type *) symbols[i];
+ base_i = sym_i->symbol.section->vma + sym_i->internal_elf_sym.st_value;
+ size_i = sym_i->internal_elf_sym.st_size;
+
+ if (0 == size_i)
+ {
+ if (sym_i->symbol.section->flags & SEC_CODE)
+ {
+ /* must be an internal branch - ignore */
+
+ vdbg("Sym [%20s] is zero len, skipping!\n", sym_i->symbol.name);
+ continue;
+ }
+ else
+ {
+ /* pointer - fake size up */
+ size_i = 4;
+ }
+ }
+
+ top_i = base_i + size_i;
+
+ dbg("Sym [%20s] base %08lx, top %08lx\n",
+ sym_i->symbol.name, (long)base_i, (long)top_i);
+
+ for (j = (i + 1); j < number_of_symbols; j++)
+ {
+ elf_symbol_type *sym_j;
+ bfd_vma base_j;
+ bfd_vma top_j;
+ bfd_vma size_j = 0;
+
+ sym_j = (elf_symbol_type *) symbols[j];
+ base_j =
+ sym_j->symbol.section->vma + sym_j->internal_elf_sym.st_value;
+
+ if (0 == size_j)
+ {
+ if (sym_j->symbol.section->flags & SEC_CODE)
+ {
+ /* must be an internal branch - ignore */
+ continue;
+ }
+ else
+ {
+ /* pointer - fake size up */
+ size_j = 4;
+ }
+ }
+
+ top_j = base_j + sym_j->internal_elf_sym.st_size;
+
+ if (0 == sym_j->internal_elf_sym.st_size)
+ {
+ continue;
+ }
+
+ if ((base_j < top_i) && (top_j > base_i))
+ {
+ /* symbols overlap - bad bad bad bad */
+
+ if (verbose)
+ {
+ warn("Symbols '%s'[%6s] and '%s'[%6s] OVERLAP!\n",
+ sym_i->symbol.name, sym_i->symbol.section->name,
+ sym_j->symbol.name, sym_j->symbol.section->name);
+ warn(" Sym '%s' base %08lx, top %08lx\n",
+ sym_i->symbol.name, (long)base_i, (long)top_i);
+ warn(" Sym '%s' base %08lx, top %08lx\n",
+ sym_j->symbol.name, (long)base_j, (long)top_j);
+ }
+ }
+
+ }
+ }
+}
+
+/***********************************************************************
+ * map_common_symbols
+ ***********************************************************************/
+
+static void
+map_common_symbols(bfd * input_bfd, asymbol ** symbols, int number_of_symbols)
+{
+ asection *bss_s;
+ int i;
+ int j;
+
+ bfd_vma baseaddr;
+ bfd_vma align;
+ bfd_vma size;
+ bfd_vma symbase;
+ bfd_vma offset;
+
+ bss_s = bss_info.subsect[0];
+ baseaddr = 0;
+
+ vdbg("Before map high mark %08lx cooked %08lx raw %08lx \n",
+ (long)bss_info.high_mark, (long)bss_info.subsect[0]->COOKED_SIZE,
+ (long)bss_info.subsect[0]->RAW_SIZE);
+ vdbg("Checking overlap before mapping\n");
+
+ check_symbol_overlap(symbols, number_of_symbols);
+
+ vdbg("Mapping COMMONS\n");
+
+ if (NULL == bss_s)
+ {
+ warn("NULL section passed to map_common_symbols\n");
+ return;
+ }
+
+ vdbg("Assigning COMMON symbols to section %s\n", bss_s->name);
+
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ if (bfd_is_com_section(symbols[i]->section))
+ {
+ if (verbose)
+ {
+ message("COMMON sym[%04d] ", i);
+ dump_symbol(symbols[i]);
+ }
+
+ /* get parameters of unmapped symbol */
+#if 0
+ align = ((elf_symbol_type *) symbols[i])->internal_elf_sym.st_value;
+#else
+ /* Ignore alignment - just make sure we're word aligned we're not
+ * worrying about page boundaries since we're flat mem and we're not
+ * really concerned with cache alignment - maybe someday */
+
+ align = 0x04;
+#endif
+ size = ((elf_symbol_type *) symbols[i])->internal_elf_sym.st_size;
+
+ if (0 == size)
+ {
+ dbg("Aero size symbol assumed to be a ptr size 4\n");
+ size = 0x04;
+ }
+
+ if (size % 0x04)
+ {
+ dbg("non-mod4 symbol rounded up 4\n");
+ size = ((size >> 2) + 1) << 2;
+ }
+
+ /* INSERT SYMBOL AT END OF BSS - MUCH MO BETTA */
+
+ /* calulate transaction effects - insert blank b4 sym to get align */
+
+ baseaddr = bss_s->COOKED_SIZE;
+ symbase = ((baseaddr + align - 1) / align) * align;
+ offset = (symbase + size) - baseaddr;
+
+ vdbg(" ba: %08lx sb: %08lx al: %04lx sz: %04lx of: %04lx\n",
+ (long)baseaddr, (long)symbase, (long)align, (long)size, (long)offset);
+
+ /* Add space to bss segment and section */
+
+ bss_info.high_mark += offset;
+ bss_info.size += offset;
+ bss_s->COOKED_SIZE += offset;
+ bss_s->RAW_SIZE += offset;
+
+ /* find all end markers and offset */
+
+ for (j = 0; j < number_of_symbols; j++)
+ {
+ if (bss_s == symbols[j]->section)
+ {
+ if (verbose)
+ {
+ message("Checking endsym? %08lx sym[%04d] ", (long)baseaddr, j);
+ dump_symbol(symbols[j]);
+ }
+
+ if (symbols[j]->value >= baseaddr)
+ {
+ symbols[j]->value += offset;
+ ((elf_symbol_type *) symbols[j])->internal_elf_sym.
+ st_value += offset;
+ if (verbose > 1)
+ {
+ message("Sym MOVED to sym[%04d] ", j);
+ dump_symbol(symbols[j]);
+ }
+ }
+ }
+ }
+
+ /* stuff sym at base */
+
+ symbols[i]->section = bss_s;
+ symbols[i]->value = symbase;
+ symbols[i]->flags = BSF_OBJECT | BSF_GLOBAL;
+ ((elf_symbol_type *) symbols[i])->internal_elf_sym.st_value = symbase;
+
+ if (verbose)
+ {
+ message("NEW sym[%04d] ", i);
+ dump_symbol(symbols[i]);
+ }
+ }
+ }
+
+ check_symbol_overlap(symbols, number_of_symbols);
+
+ vdbg("After map high mark %08lx cooked %08lx raw %08lx \n",
+ (long)bss_info.high_mark, (long)bss_info.subsect[0]->COOKED_SIZE,
+ (long)bss_info.subsect[0]->RAW_SIZE);
+}
+
+/***********************************************************************
+ * resolve_relocs
+ ***********************************************************************/
+
+static void resolve_relocs(bfd *input_bfd, asymbol **symbols)
+{
+ resolve_segment_relocs(input_bfd, &text_info, symbols);
+ resolve_segment_relocs(input_bfd, &data_info, symbols);
+ resolve_segment_relocs(input_bfd, &bss_info, symbols);
+}
+
+/***********************************************************************
+ * allocate_got
+ ***********************************************************************/
+
+/* The GOT lies at the beginning of D-Space. Before we can process
+ * any relocation data, we need to determine the size of the GOT.
+ */
+
+static void allocate_got(bfd *input_bfd, asymbol **symbols)
+{
+ allocate_segment_got(input_bfd, &text_info, symbols);
+ allocate_segment_got(input_bfd, &data_info, symbols);
+ allocate_segment_got(input_bfd, &bss_info, symbols);
+}
+
+/***********************************************************************
+ * output_got
+ ***********************************************************************/
+
+/* Pull the sections that make up this segment in off disk */
+
+static void output_got(int fd)
+{
+ struct nxflat_reloc_s *relocs;
+ u_int32_t *got;
+ int reloc_size;
+ int reloc_type;
+ int nrelocs;
+ int i;
+ int j;
+
+ if (ngot_offsets > 0)
+ {
+ /* Allocate memory for the GOT */
+
+ got = (u_int32_t*)malloc(got_size);
+ if (!got)
+ {
+ err("Failed to allocate memory for the GOT (%d bytes, %d offsets)\n",
+ got_size, ngot_offsets);
+ exit(1);
+ }
+
+ /* Re-allocate memory for the relocations to include the GOT relocations */
+
+ nrelocs = ngot_offsets + nxflat_nrelocs;
+ reloc_size = sizeof(struct nxflat_reloc_s) * nrelocs;
+ relocs = (struct nxflat_reloc_s*)realloc(nxflat_relocs, reloc_size);
+ if (!relocs)
+ {
+ err("Failed to re-allocate memory for the GOT relocations (%d bytes, %d relocations)\n",
+ reloc_size, nrelocs);
+ exit(1);
+ }
+
+ /* Then initialize the GOT contents with the value associated with each symbol */
+
+ for (i = 0; i < ngot_offsets; i++)
+ {
+ asymbol *rel_sym = got_offsets[i].sym;
+ asection *rel_section = rel_sym->section;
+ symvalue sym_value = rel_sym->value;
+
+ /* j is the offset index into the relocatino table */
+
+ j = i + nxflat_nrelocs;
+
+ /* If the symbol is a thumb function, then set bit 1 of the value */
+
+#ifdef NXFLAT_THUMB2
+ if ((((elf_symbol_type *)rel_sym)->internal_elf_sym.st_info & 0x0f) == STT_ARM_TFUNC)
+ {
+ sym_value |= 1;
+ }
+#endif
+ /* Determine where the symbol lies */
+
+ switch (get_reloc_type(rel_section, NULL))
+ {
+ /* If the symbol lies in D-Space, then we need to add the size of the GOT
+ * table to the symbol value
+ */
+
+ case NXFLAT_RELOC_TARGET_BSS:
+ case NXFLAT_RELOC_TARGET_DATA:
+ {
+ vdbg("Symbol '%s' lies in D-Space\n", rel_sym->name);
+ reloc_type = NXFLAT_RELOC_TYPE_REL32D;
+ sym_value += got_size;
+ }
+ break;
+
+ /* If the symbol lies in I-Space */
+
+ case NXFLAT_RELOC_TARGET_TEXT:
+ {
+ vdbg("Symbol '%s' lies in I-Space\n", rel_sym->name);
+ reloc_type = NXFLAT_RELOC_TYPE_REL32I;
+ }
+ break;
+
+ case NXFLAT_RELOC_TARGET_UNKNOWN:
+ default:
+ {
+ err("Relocation type is unknown\n");
+ nerrors++;
+ continue;
+ }
+ }
+
+ /* Then save the symbol offset in the got */
+
+ got[i] = sym_value;
+ vdbg("GOT[%d]: sym name: '%s' value: %08lx->%08lx\n",
+ i, rel_sym->name, (long)rel_sym->value, (long)sym_value);
+
+ /* And output the relocation information associate with the GOT entry */
+
+ relocs[j].r_info = NXFLAT_RELOC(reloc_type, sizeof(u_int32_t) * i);
+
+ vdbg("relocs[%d]: type: %d offset: %08x\n",
+ j, NXFLAT_RELOC_TYPE(relocs[j].r_info), NXFLAT_RELOC_OFFSET(relocs[j].r_info));
+ }
+
+ /* Write the GOT on the provided file descriptor */
+
+ if (verbose > 1)
+ {
+ printf("GOT:\n");
+ for (i = 0; i < ngot_offsets; i++)
+ {
+ printf(" Offset %-3ld: %08x\n",
+ (long)(sizeof(u_int32_t) * i), got[i]);
+ }
+
+ printf("Relocations:\n");
+ for (i = 0; i < nrelocs; i++)
+ {
+ printf(" Offset %-3ld: %08x\n",
+ (long)(sizeof(struct nxflat_reloc_s) * i), relocs[i].r_info);
+ }
+ }
+
+ nxflat_write(fd, (const char *)got, got_size);
+ free(got);
+
+ /* Return the relocation table (via global variables) */
+
+ nxflat_relocs = relocs;
+ nxflat_nrelocs = nrelocs;
+ }
+}
+
+/***********************************************************************
+ * is_unwanted_section
+ ***********************************************************************/
+
+/* Return 1 if this is a section that we want to throw away but can only
+ * identify by name. Normally, any section with appropriate-looking flags
+ * will get copied into the output file.
+ */
+
+static int is_unwanted_section(asection * s)
+{
+ if (!strcmp(s->name, ".hash"))
+ return 1;
+ if (!strcmp(s->name, ".dynstr") || !strcmp(s->name, ".dynsym"))
+ return 1;
+ if (s->flags & SEC_DEBUGGING)
+ return 1;
+ return 0;
+}
+
+/***********************************************************************
+ * register_section
+ ***********************************************************************/
+
+/* Mark this section for inclusion in some segment. */
+static void register_section(asection * s, segment_info * inf)
+{
+ vdbg("registering section %s to %s segment\n", s->name, inf->name);
+ inf->subsect[inf->nsubsects++] = s;
+}
+
+/***********************************************************************
+ * dump_sections
+ ***********************************************************************/
+
+/* Print out the sections that make up this segment for debugging. */
+static void dump_sections(segment_info * inf)
+{
+ int i;
+ printf(" [ ");
+ for (i = 0; i < inf->nsubsects; i++)
+ {
+ printf("%s ", inf->subsect[i]->name);
+ }
+ printf("]\n");
+}
+
+/***********************************************************************
+ * load_sections
+ ***********************************************************************/
+
+/* Pull the sections that make up this segment in off disk */
+
+static void load_sections(bfd *bfd, segment_info *inf)
+{
+ void *ptr;
+ int i;
+
+ if (inf->size > 0)
+ {
+ inf->contents = malloc(inf->size);
+ if (!inf->contents)
+ {
+ err("Failed to allocate memory for section contents.\n");
+ exit(1);
+ }
+
+ ptr = inf->contents;
+ for (i = 0; i < inf->nsubsects; i++)
+ {
+ if (!bfd_get_section_contents(bfd, inf->subsect[i], ptr,
+ 0, inf->subsect[i]->COOKED_SIZE))
+ {
+ err("Failed to read section contents.\n");
+ exit(1);
+ }
+ ptr += inf->subsect[i]->COOKED_SIZE;
+ inf->subsect[i]->flags |= SEC_IN_MEMORY;
+ }
+ }
+}
+
+/***********************************************************************
+ * stack_nxflat_segment
+ ***********************************************************************/
+
+static void stack_nxflat_segment(segment_info * inf)
+{
+ bfd_vma min_addr = 0x7fffffff;
+ bfd_vma max_addr = 0x00000000;
+ int i;
+
+ for (i = 0; i < inf->nsubsects; i++)
+ {
+ bfd_vma vma = inf->subsect[i]->vma;
+ if (vma < min_addr)
+ min_addr = vma;
+
+ vma += inf->subsect[i]->COOKED_SIZE;
+ if (vma > max_addr)
+ max_addr = vma;
+ }
+
+ inf->low_mark = min_addr;
+ inf->high_mark = max_addr;
+ inf->size = max_addr - min_addr;
+}
+
+/***********************************************************************
+ * show_usage
+ ***********************************************************************/
+
+static void show_usage(void)
+{
+ fprintf(stderr, "Usage: %s [options] <bfd-filename>\n\n", program_name);
+ fprintf(stderr, "Where options are one or more of the following. Note\n");
+ fprintf(stderr, "that a space is always required between the option and\n");
+ fprintf(stderr, "any following arguments.\n\n");
+ fprintf(stderr, " -d Use dynamic symbol table [Default: symtab]\n");
+ fprintf(stderr, " -e <entry-point>\n");
+ fprintf(stderr, " Entry point to module [Default: %s]\n",
+ default_exe_entry_name);
+ fprintf(stderr, " -o <out-filename>\n");
+ fprintf(stderr, " Output to <out-filename> [Default: <bfd-filename>.nxf]\n");
+ fprintf(stderr, " -s <stack-size>\n");
+ fprintf(stderr, " Set stack size to <stack-size> [Default: %d]\n", DEFAULT_STACK_SIZE);
+ fprintf(stderr, " -v Verbose outpu.t If -v is applied twice, additional\n");
+ fprintf(stderr, " debug output is enabled [Default: no verbose output].\n");
+ fprintf(stderr, "\n");
+ exit(2);
+}
+
+/***********************************************************************
+ * parse_args
+ ***********************************************************************/
+
+static void parse_args(int argc, char **argv)
+{
+ int opt;
+
+ /* Save our name (for show_usage) */
+
+ program_name = argv[0];
+
+ /* Set some default values */
+
+ stack_size = 0;
+ entry_name = NULL;
+
+ if (argc < 2)
+ {
+ err("Missing required arguments\n\n");
+ show_usage();
+ }
+
+ /* Get miscellaneous options from the command line. */
+
+ while ((opt = getopt(argc, argv, "de:lo:s:v")) != -1)
+ {
+ switch (opt)
+ {
+ case 'd':
+ dsyms++;
+ break;
+
+ case 'e':
+ entry_name = strdup(optarg);
+ break;
+
+ case 'o':
+ out_filename = optarg;
+ break;
+
+ case 's':
+ stack_size = atoi(optarg);
+ break;
+
+ case 'v':
+ verbose++;
+ break;
+
+ case 'l':
+ default:
+ err("%s Unknown option\n\n", argv[0]);
+ show_usage();
+ break;
+ }
+ }
+
+ /* The very last thing is also the name of the BFD input file */
+
+ bfd_filename = argv[argc - 1];
+
+ /* Verify that an appropriate stack size is selected. */
+
+ if (stack_size == 0)
+ {
+ /* Executables must have a stack_size selected. */
+
+ printf("Using default stack size: %d\n", DEFAULT_STACK_SIZE);
+ stack_size = DEFAULT_STACK_SIZE;
+ }
+
+ if (entry_name == NULL)
+ {
+ printf("Using entry_point: %s\n", default_exe_entry_name);
+ entry_name = default_exe_entry_name;
+ }
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * main
+ ***********************************************************************/
+
+int main(int argc, char **argv, char **envp)
+{
+ struct nxflat_hdr_s hdr;
+ bfd *bf;
+ asection *s;
+ asymbol **symbol_table;
+ int32_t number_of_symbols;
+ u_int32_t offset;
+ int fd;
+ int i;
+
+ /* Parse the incoming command line */
+
+ parse_args(argc, argv);
+
+ /* Open the BFD input file */
+
+ if (!(bf = bfd_openr(argv[argc - 1], 0)))
+ {
+ err("Failed to open %s\n", argv[argc - 1]);
+ exit(1);
+ }
+
+ /* Verify the format of the BFD file */
+
+ if (bfd_check_format(bf, bfd_object) == 0)
+ {
+ err("File is not an object file\n");
+ exit(2);
+ }
+
+ /* Read the symbol table from the file */
+
+ symbol_table = get_symbols(bf, &number_of_symbols);
+
+ /* Find all of the special symbols that we will need in the symbol table that
+ * we just read. */
+
+ find_special_symbols();
+
+ /* Walk the list of sections, figuring out where each one goes and how much
+ * storage it requires. */
+
+ text_info.low_mark = data_info.low_mark = bss_info.low_mark = -1;
+ text_info.high_mark = data_info.high_mark = bss_info.high_mark = 0;
+ text_info.contents = data_info.contents = bss_info.contents = NULL;
+ text_info.size = data_info.size = bss_info.size = 0;
+ text_info.nsubsects = data_info.nsubsects = bss_info.nsubsects = 0;
+ text_info.name = "text";
+ data_info.name = "data";
+ bss_info.name = "bss";
+
+ for (s = bf->sections; s != NULL; s = s->next)
+ {
+ dbg("Reading section %s\n", s->name);
+
+ /* ignore blatantly useless sections */
+
+ if (!is_unwanted_section(s))
+ {
+ if (s->flags == SEC_ALLOC)
+ {
+ vdbg(" Section %s is ALLOC only\n", s->name);
+ register_section(s, &bss_info);
+ }
+ else if ((s->flags & SEC_CODE) != 0 && (s->flags & SEC_ALLOC) != 0)
+ {
+ vdbg(" Section %s is CODE\n", s->name);
+ register_section(s, &text_info);
+ }
+ else if ((s->flags & SEC_DATA) != 0 && (s->flags & SEC_ALLOC) != 0)
+ {
+ vdbg(" Section %s is DATA\n", s->name);
+ register_section(s, &data_info);
+ }
+ else
+ {
+ vdbg("WARNING: ignoring section %s\n", s->name);
+ }
+ }
+ }
+
+ /* Fixup high and low water VMA address */
+
+ stack_nxflat_segment(&text_info);
+ stack_nxflat_segment(&data_info);
+ stack_nxflat_segment(&bss_info);
+
+ /* Check for a data offset due to the presence of a GOT */
+
+ printf("INPUT SECTIONS:\n");
+ printf("SECT LOW HIGH SIZE\n");
+ if (text_info.nsubsects == 0)
+ {
+ warn("TEXT Not found Not found ( Not found )\n");
+ }
+ else
+ {
+ printf("TEXT %08lx %08lx %08lx\n",
+ (long)text_info.low_mark, (long)text_info.high_mark,
+ (long)text_info.size);
+
+ if (text_info.low_mark != 0)
+ {
+ err("Text section must be origined at zero");
+ exit(1);
+ }
+ }
+
+ if (data_info.nsubsects == 0)
+ {
+ warn("DATA Not found Not found ( Not found )\n");
+ }
+ else
+ {
+ printf("DATA %08lx %08lx %08lx\n",
+ (long)data_info.low_mark, (long)data_info.high_mark,
+ (long)data_info.size);
+
+ if (data_info.low_mark != 0)
+ {
+ err("data section must be origined at zero");
+ exit(1);
+ }
+ }
+
+ if (bss_info.nsubsects == 0)
+ {
+ warn("BSS Not found Not found ( Not found )\n");
+ }
+ else
+ {
+ printf("BSS %08lx %08lx %08lx\n",
+ (long)bss_info.low_mark, (long)bss_info.high_mark,
+ (long)bss_info.size);
+
+ /* If data is present, then BSS was be origined immediately after the
+ * data. */
+
+ if (data_info.nsubsects > 0)
+ {
+ /* There is data... Account for possible ALIGN 0x10 at end of data */
+
+ u_int32_t bss_start1 = data_info.high_mark;
+ u_int32_t bss_start2 = ((bss_start1 + 0x0f) & ~0x0f);
+
+ if ((bss_info.low_mark < bss_start1) &&
+ (bss_info.low_mark > bss_start2))
+ {
+ err("BSS must be origined immediately after the data section\n");
+ exit(1);
+ }
+ }
+
+ /* If there is no data, then the BSS must be origined at zero */
+
+ else if (bss_info.low_mark != 0)
+ {
+ err("BSS section (with no data section) must be origined at zero\n");
+ exit(1);
+ }
+ }
+
+ if (verbose)
+ {
+ message("TEXT: ");
+ dump_sections(&text_info);
+ message("DATA: ");
+ dump_sections(&data_info);
+ message("BSS: ");
+ dump_sections(&bss_info);
+ }
+
+ /* Slurp the section contents in. No need to load BSS since we know it
+ * isn't initialised. */
+
+ load_sections(bf, &text_info);
+ load_sections(bf, &data_info);
+
+ /* Unmapped 'common' symbols need to be stuffed into bss */
+
+ map_common_symbols(bf, symbol_table, number_of_symbols);
+
+ /* Dump symbol information */
+
+ if (verbose)
+ {
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ message("sym[%04d] ", i);
+ dump_symbol(symbol_table[i]);
+ }
+ }
+
+ /* The GOT lies at the beginning of D-Space. Before we can process
+ * any relocation data, we need to determine the size of the GOT.
+ */
+
+ allocate_got(bf, symbol_table);
+
+ /* Then process all of the relocations */
+
+ resolve_relocs(bf, symbol_table);
+
+ /* Fill in the NXFLAT file header */
+
+ memcpy(hdr.h_magic, NXFLAT_MAGIC, 4);
+
+ offset = NXFLAT_HDR_SIZE + text_info.size;
+ put_xflat32(&hdr.h_datastart, offset);
+
+ offset += got_size + data_info.size;
+ put_xflat32(&hdr.h_dataend, offset);
+ put_xflat32(&hdr.h_relocstart, offset);
+
+ offset += bss_info.size;
+ put_xflat32(&hdr.h_bssend, offset);
+
+ put_xflat32(&hdr.h_stacksize, stack_size);
+ put_xflat16(&hdr.h_reloccount, nxflat_nrelocs + ngot_offsets);
+
+ put_entry_point(&hdr);
+
+ put_special_symbol(dynimport_begin_symbol, dynimport_end_symbol,
+ &hdr.h_importsymbols, &hdr.h_importcount,
+ sizeof(struct nxflat_import_s), text_info.size + got_size);
+
+ /* Open the output file */
+
+ if (!out_filename)
+ {
+ out_filename = malloc(strlen(bfd_filename) + 5); /* 5 to add suffix */
+ strcpy(out_filename, bfd_filename);
+ strcat(out_filename, ".nxf");
+ }
+
+ fd = open(out_filename, O_WRONLY | O_PLATFORM | O_CREAT | O_TRUNC, 0744);
+ if (fd < 0)
+ {
+ err("Failed open output file %s: %s\n", out_filename, strerror(errno));
+ exit(4);
+ }
+
+ /* Write the data in the following order in order to match the NXFLAT header
+ * offsets: HDR, ISPACE, GOT, DSPACE, RELOCS.
+ */
+
+ nxflat_write(fd, (const char *)&hdr, NXFLAT_HDR_SIZE);
+ nxflat_write(fd, (const char *)text_info.contents, text_info.size);
+
+ if (ngot_offsets > 0)
+ {
+ output_got(fd);
+ }
+
+ nxflat_write(fd, (const char *)data_info.contents, data_info.size);
+
+ if (nxflat_relocs)
+ {
+ vdbg("Number of GOT relocations: %d\n", ngot_offsets);
+
+#ifdef RELOCS_IN_NETWORK_ORDER
+ for (i = 0; i < nxflat_nrelocs; i++)
+ {
+ nxflat_relocs[i] = htonl(nxflat_relocs[i]);
+ }
+#endif
+ nxflat_write(fd, (const char *)nxflat_relocs, sizeof(struct nxflat_reloc_s) * nxflat_nrelocs);
+ }
+
+ /* Finished! */
+
+ close(fd);
+
+ if (nerrors > 0)
+ {
+ fprintf(stderr, "%d Errors detected\n", nerrors);
+ return 1;
+ }
+ return 0;
+}
diff --git a/misc/buildroot/toolchain/nxflat/mknxflat.c b/misc/buildroot/toolchain/nxflat/mknxflat.c
new file mode 100644
index 000000000..3e73d6287
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/mknxflat.c
@@ -0,0 +1,769 @@
+/***********************************************************************
+ * xflat/tools/mknxflat.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Modified from ldelflib (see http://xflat.org):
+ *
+ * Copyright (c) 2002, 2006, Cadenux, LLC. All rights reserved.
+ * Copyright (c) 2002, 2006, Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************************************/
+
+/***********************************************************************
+ * Included Files
+ ***********************************************************************/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <bfd.h>
+
+#include "nxflat.h"
+#include "arch/arch.h"
+
+/***********************************************************************
+ * Definitions
+ ***********************************************************************/
+
+#define dbg(format, arg...) \
+ if (verbose) printf(format, ## arg)
+
+#define BSF_GLOBL_FUNC (BSF_GLOBAL|BSF_FUNCTION)
+#define BSF_WEAK_FUNC (BSF_WEAK|BSF_FUNCTION)
+#define BSF_DEFINED (BSF_LOCAL|BSF_GLOBAL)
+
+#define IS_GLOBL_FUNC(x) ((((x)->flags)&(BSF_GLOBL_FUNC))==(BSF_GLOBL_FUNC))
+#define IS_WEAK_FUNC(x) ((((x)->flags)&(BSF_WEAK_FUNC))==(BSF_WEAK_FUNC))
+#define IS_DEFINED(x) ((((x)->flags)&(BSF_DEFINED))!=0)
+#define IS_OBJECT(x) ((((x)->flags)&(BSF_OBJECT))!=0)
+#define IS_WEAK(x) ((((x)->flags)&(BSF_WEAK))!=0)
+
+#define MAX_EXPORT_NAMES 1024
+
+/***********************************************************************
+ * Private Types
+ ***********************************************************************/
+
+typedef int (*symfunc_type) (asymbol * sym, void *arg);
+typedef int (*namefunc_type) (const char *name, void *arg);
+
+/***********************************************************************
+ * Private Variables
+ ***********************************************************************/
+
+/* Command line settings (counters but treated like booleans) */
+
+static int verbose = 0;
+static int weak_imports = 0;
+static int dsyms = 0;
+
+/* Characteristics of things */
+static int calls_nonreturning_functions = 0;
+
+/* Sizes of things */
+
+static long number_of_symbols = 0;
+static long number_undefined = 0;
+
+/* Names of things */
+
+static const char *program_name = NULL;
+static const char *bfd_filename = NULL;
+static const char *out_filename = NULL;
+
+/* The symbol table. */
+
+static asymbol **symbol_table = NULL;
+
+/* handle to included file */
+
+static FILE *include_stream = NULL;
+static char token[1024];
+
+static int counter;
+
+/***********************************************************************
+ * Private constant data
+ ***********************************************************************/
+
+/* All of the strings defining the generated file are here: */
+
+#include "arch/dyncall_skeleton.def"
+
+static const char dyn_symbol_prefix[] = "__dyn";
+#define DYN_SYMBOL_PREFIX_LEN 5
+
+/* This is the list of names of libc and libpthread functions that
+ * do not return. These may require some special handling -- at a
+ * minimum, they must tie up resources that can only be released
+ * when the function returns.
+ */
+
+static const char *const nonreturners[] = {
+ "abort", /* Never returns */
+ "exit", /* Never returns */
+ "_exit", /* Never returns */
+ "longjmp", /* Never returns */
+ "_longjmp", /* Never returns */
+ "pthread_exit", /* Never returns */
+ "siglongjmp", /* Never returns */
+ NULL /* End of list */
+};
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * show_usage
+ ***********************************************************************/
+
+static void show_usage(void)
+{
+ fprintf(stderr, "Usage: %s [options] <bfd-filename>\n\n", program_name);
+ fprintf(stderr, "Where options are one or more of the following. Note\n");
+ fprintf(stderr, "that a space is always required between the option and\n");
+ fprintf(stderr, "any following arguments.\n\n");
+ fprintf(stderr, " -d Use dynamic symbol table. [symtab]\n");
+ fprintf(stderr, " -f <cmd-filename>\n");
+ fprintf(stderr, " Take next commands from <cmd-filename> [cmd-line]\n");
+ fprintf(stderr, " -o <out-filename>\n");
+ fprintf(stderr, " Output to <out-filename> [stdout]\n");
+ fprintf(stderr, " -v Verbose output [no output]\n");
+ fprintf(stderr, " -w Import weakly declared functions, i.e., weakly\n");
+ fprintf(stderr, " declared functions are expected to be provided at\n");
+ fprintf(stderr, " load-time [not imported]\n");
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+/***********************************************************************
+ * get_symbols
+ ***********************************************************************/
+
+static asymbol **get_symbols(bfd * abfd, long *num)
+{
+ long storage_needed;
+ asymbol **symbol_table;
+ long number_of_symbols;
+
+ if (dsyms)
+ storage_needed = bfd_get_dynamic_symtab_upper_bound(abfd);
+ else
+ storage_needed = bfd_get_symtab_upper_bound(abfd);
+
+ if (storage_needed < 0)
+ abort();
+
+ if (storage_needed == 0)
+ return NULL;
+
+ symbol_table = (asymbol **) malloc(storage_needed);
+
+ if (dsyms)
+ number_of_symbols = bfd_canonicalize_dynamic_symtab(abfd, symbol_table);
+ else
+ number_of_symbols = bfd_canonicalize_symtab(abfd, symbol_table);
+ if (number_of_symbols < 0)
+ abort();
+
+ *num = number_of_symbols;
+ return symbol_table;
+}
+
+/***********************************************************************
+ * traverse_undefined_functions
+ ***********************************************************************/
+
+static int traverse_undefined_functions(void *arg, symfunc_type fn)
+{
+ int i;
+
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ /* Check if it is undefined and not an object. I have found that symbol
+ * typing can be misleading: Imported functions are not marked as
+ * BSF_FUNCTION; weakly defined objects are listed as undefined objects.
+ * Conclusion: We will error if a object is truly undefined! */
+
+ if ((symbol_table[i]->value == 0) &&
+ (!IS_DEFINED(symbol_table[i])) && (!IS_OBJECT(symbol_table[i])))
+ {
+ /* Is is imported as a "weak" symbol? If so, we will process the
+ * symbol only if we were requested to do so from the command line. */
+
+ if ((!IS_WEAK(symbol_table[i])) || (weak_imports > 0))
+ {
+ /* Yes, process the symbol */
+
+ if (fn(symbol_table[i], arg) != 0)
+ {
+ /* If the function returns a non-zero value, then we
+ * terminate the traversal and return a non-zero value also. */
+
+ return 1;
+ }
+ }
+ }
+ }
+
+ /* Return 0 meaning that all undefined symbols were examined successfully. */
+
+ return 0;
+}
+
+/***********************************************************************
+ * put_string
+ ***********************************************************************/
+
+static void put_string(int fd, const char *string)
+{
+ ssize_t bytes_available = strlen(string);
+ ssize_t bytes_written = write(fd, string, bytes_available);
+ if (bytes_written < 0)
+ {
+ fprintf(stderr,
+ "Failed to write %ld bytes of string to output, errno=%d\n",
+ (long)bytes_available, errno);
+ exit(5);
+ }
+ else if (bytes_written != bytes_available)
+ {
+ fprintf(stderr, "Only wrote %ld of %ld bytes of string to output\n",
+ (long)bytes_written, (long)bytes_available);
+ exit(6);
+ }
+}
+
+/***********************************************************************
+ * does_not_return_name/sym
+ ***********************************************************************/
+
+static int does_not_return_name(const char *func_name)
+{
+ int i;
+
+ /* Check every name in the list of (usually) non-returning function */
+
+ for (i = 0; nonreturners[i] != NULL; i++)
+ {
+ /* Is this function name in the list */
+
+ if (strcmp(func_name, nonreturners[i]) == 0)
+ {
+ /* Yes, return true now. */
+
+ return 1;
+ }
+ }
+
+ /* Its not in the list, return false */
+
+ return 0;
+}
+
+static int does_not_return_sym(asymbol * sym, void *arg)
+{
+ const char *func_name = sym->name;
+ if (func_name)
+ return does_not_return_name(func_name);
+ else
+ return 0;
+}
+
+/***********************************************************************
+ * check_for_nonreturning_functions
+ ***********************************************************************/
+
+static void check_for_nonreturning_functions(void)
+{
+ calls_nonreturning_functions =
+ traverse_undefined_functions(NULL, does_not_return_sym);
+}
+
+/***********************************************************************
+ * count_undefined
+ ***********************************************************************/
+
+static int count_undefined(asymbol * sym, void *arg)
+{
+ number_undefined++;
+ return 0;
+}
+
+/***********************************************************************
+ * put_dynimport_decl
+ ***********************************************************************/
+
+static int put_dynimport_decl(asymbol * sym, void *arg)
+{
+ char dynimport_decl[1024];
+ const char *func_name = sym->name;
+ int fd = (int)arg;
+
+ /* Put the declaration for the dynamic info structure */
+ if (func_name)
+ {
+ sprintf(dynimport_decl, dynimport_decl_format,
+ MKINFODECLARGS(func_name, counter));
+ put_string(fd, dynimport_decl);
+ counter++;
+ }
+ return 0;
+}
+
+/***********************************************************************
+ * put_dynimport_array
+ ***********************************************************************/
+
+static int put_dynimport_array(asymbol * sym, void *arg)
+{
+ char dynimport_array[1024];
+ const char *func_name = sym->name;
+ int fd = (int)arg;
+
+ /* Create the dynimport_array */
+
+ if (func_name)
+ {
+ sprintf(dynimport_array, dynimport_array_format,
+ MKINFOARGS(func_name, counter));
+ put_string(fd, dynimport_array);
+ counter++;
+ }
+ return 0;
+}
+
+/***********************************************************************
+ * put_nxflat_import
+ ***********************************************************************/
+
+static int put_nxflat_import(asymbol * sym, void *arg)
+{
+ char thunk[4096];
+ const char *func_name = sym->name;
+ int fd = (int)arg;
+
+ if (func_name)
+ {
+ /* Create the thunk */
+
+ if (does_not_return_name(func_name) != 0)
+ {
+ /* The special case for functions that may not return */
+
+ sprintf(thunk, nonreturning_dyncall_format, MKCALLARGS(func_name, counter));
+ }
+ else
+ {
+ /* The normal case */
+
+ sprintf(thunk, dyncall_format, MKCALLARGS(func_name, counter));
+ }
+
+ put_string(fd, thunk);
+ counter++;
+ }
+ return 0;
+}
+
+/***********************************************************************
+ * put_all_nxflat_import
+ ***********************************************************************/
+
+static void put_all_nxflat_import(int fd)
+{
+ if (number_undefined > 0)
+ {
+ /* Put all of the declarations for the dynimport structures together. */
+
+ put_string(fd, dynimport_decl_prologue);
+ counter = 0;
+ (void)traverse_undefined_functions((void *)fd, put_dynimport_decl);
+
+ /* Put all of the dynimport structures together as an array */
+
+ put_string(fd, dynimport_array_prologue);
+ counter = 0;
+ (void)traverse_undefined_functions((void *)fd, put_dynimport_array);
+ put_string(fd, dynimport_array_epilogue);
+
+ /* Put all of the dyncall logic together */
+
+ put_string(fd, dyncall_decl_prologue);
+ counter = 0;
+ (void)traverse_undefined_functions((void *)fd, put_nxflat_import);
+ }
+}
+
+/***********************************************************************
+ * put_import_name
+ ***********************************************************************/
+
+static int put_import_name(asymbol * sym, void *arg)
+{
+ char import_name[512];
+ const char *func_name = sym->name;
+ int fd = (int)arg;
+
+ /* Create the import_name */
+
+ if (func_name)
+ {
+ sprintf(import_name, import_name_strtab_format,
+ MKIMPSTRTABARG(func_name, counter));
+ put_string(fd, import_name);
+ counter++;
+ }
+ return 0;
+}
+
+/***********************************************************************
+ * put_import_name_strtab
+ ***********************************************************************/
+
+static void inline put_import_name_strtab(int fd)
+{
+ if (number_undefined > 0)
+ {
+ counter = 0;
+ put_string(fd, import_name_strtab_prologue);
+ (void)traverse_undefined_functions((void *)fd, put_import_name);
+ }
+}
+
+/***********************************************************************
+ * put_file_epilogue
+ ***********************************************************************/
+
+static void inline put_file_epilogue(int fd)
+{
+ put_string(fd, file_epilogue);
+}
+
+/***********************************************************************
+ * put_file_prologue
+ ***********************************************************************/
+
+static void inline put_file_prologue(int fd)
+{
+ put_string(fd, file_prologue);
+
+ if (number_undefined > 0)
+ {
+ put_string(fd, import_prologue);
+ }
+}
+
+/***********************************************************************
+ * get_file_token
+ ***********************************************************************/
+
+#define ISSPACE(c) \
+((c==' ')||(c=='\f')||(c=='\n')||(c=='\r')||(c=='\t')||(c=='\v'))
+
+#define ISTERMINATOR(c) (ISSPACE(c)||(c==EOF))
+
+static int get_file_token(FILE * in_stream)
+{
+ int i;
+ int c;
+
+ /* Skip over leading whitespace */
+
+ do
+ c = getc(in_stream);
+ while ISSPACE
+ (c);
+
+ if (c == EOF)
+ return EOF;
+
+ /* Add the token to the buffer. Copy characters until the buffer is full, or
+ * a terminator is encountered. */
+
+ for (i = 0; ((i < 1023) && !ISTERMINATOR(c)); i++, c = getc(in_stream))
+ {
+ token[i] = (char)c;
+ }
+
+ /* Handle the string truncation case. */
+
+ token[i] = '\0';
+ while (!ISTERMINATOR(c))
+ c = getc(in_stream);
+
+ /* Return success. On next entry, we will get the next character after the
+ * terminator. If the terminator was EOF, we should get EOF again. */
+
+ return 0;
+}
+
+/***********************************************************************
+ * get_token
+ ***********************************************************************/
+
+static char *get_token(int *argno, int argc, char **argv)
+{
+ char *retval = NULL;
+
+ if (include_stream)
+ {
+ if (get_file_token(include_stream) == EOF)
+ {
+ fclose(include_stream);
+ include_stream = NULL;
+ retval = get_token(argno, argc, argv);
+ }
+ else
+ {
+ retval = strdup(token);
+ }
+ }
+ else if (*argno >= argc)
+ {
+ retval = NULL;
+ }
+ else
+ {
+ retval = argv[*argno];
+ (*argno)++;
+ }
+ return retval;
+}
+
+/***********************************************************************
+ * get_arg
+ ***********************************************************************/
+
+static char *get_arg(int *argno, int argc, char **argv)
+{
+ char *retval;
+
+ /* Get the next argument */
+
+ retval = get_token(argno, argc, argv);
+ if ((retval == NULL) || (retval[0] == '-'))
+ {
+ fprintf(stderr, "Option requires an argument\n\n");
+ show_usage();
+ }
+ return retval;
+}
+
+/***********************************************************************
+ * get_opt
+ ***********************************************************************/
+
+static int get_opt(int *argno, int argc, char **argv)
+{
+ char *opt;
+ int len;
+ int retval = -1;
+
+ /* Get the next argument */
+
+ opt = get_token(argno, argc, argv);
+ if (opt != NULL)
+ {
+ /* It must be of length 2 and start with a '-' */
+
+ len = strlen(opt);
+ if ((len == 2) && (opt[0] == '-'))
+ {
+ retval = (int)opt[1];
+ }
+ else
+ {
+ fprintf(stderr, "%s Unrecognized option\n\n", opt);
+ show_usage();
+ }
+ }
+ return retval;
+}
+
+/***********************************************************************
+ * parse_args
+ ***********************************************************************/
+
+static void parse_args(int argc, char **argv)
+{
+ int argno = 1;
+ int opt;
+
+ /* Save our name (for show_usage) */
+
+ program_name = argv[0];
+
+ if (argc < 2)
+ {
+ fprintf(stderr, "ERROR: Missing required arguments\n\n");
+ show_usage();
+ }
+
+ /* Get the name of the input BFD file. This is always the last thing in the
+ * argument list. We decrement argc so that the parsing logic will not look
+ * at it. */
+
+ bfd_filename = argv[argc - 1];
+ argc--;
+
+ /* Get miscellaneous options from the command line. */
+
+ while ((opt = get_opt(&argno, argc, argv)) != -1)
+ {
+ switch (opt)
+ {
+ case 'd':
+ dsyms++;
+ break;
+
+ case 'f':
+ {
+ char *filename = get_arg(&argno, argc, argv);
+ if (include_stream)
+ {
+ fprintf(stderr, "Cannot use -f from within a cmd-file\n\n");
+ show_usage();
+ }
+ else
+ {
+ include_stream = fopen(filename, "r");
+ if (!include_stream)
+ {
+ fprintf(stderr, "Could not open cmd-file %s\n\n", filename);
+ show_usage();
+ }
+ }
+ }
+ break;
+
+ case 'o':
+ out_filename = get_arg(&argno, argc, argv);
+ break;
+
+ case 'v':
+ verbose++;
+ break;
+
+ case 'w':
+ weak_imports++;
+ break;
+
+ default:
+ fprintf(stderr, "%s Unknown option\n\n", argv[0]);
+ show_usage();
+ break;
+ }
+ }
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * main
+ ***********************************************************************/
+
+int main(int argc, char **argv, char **envp)
+{
+ bfd *bf;
+ int out_fd = 0;
+
+ /* Get the input arguments */
+
+ parse_args(argc, argv);
+
+ /* Make sure that we can option the BFD file */
+
+ dbg("Opening BFD file: %s\n", bfd_filename);
+ if (!(bf = bfd_openr(bfd_filename, 0)))
+ {
+ fprintf(stderr, "Failed to open BFD file: %s, errno=%d\n",
+ bfd_filename, errno);
+ exit(2);
+ }
+
+ dbg("Checking format\n");
+ if (bfd_check_format(bf, bfd_object) == 0)
+ {
+ fprintf(stderr, "BFD file %s is not an object file\n", bfd_filename);
+ exit(3);
+ }
+
+ dbg("Loading symbol table from BFD file %s\n", bfd_filename);
+ symbol_table = get_symbols(bf, &number_of_symbols);
+
+ /* Count the number of undefined function symbols */
+
+ (void)traverse_undefined_functions(NULL, count_undefined);
+
+ /* Check if the module calls any non-returning functions (like exit). These
+ * will require some additional setup. */
+
+ check_for_nonreturning_functions();
+
+ /* Make sure that we can open the output file if one is specified. If no
+ * out_filename is specified, we'll use stdout. */
+
+ if (out_filename)
+ {
+ out_fd = open(out_filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ if (out_fd < 0)
+ {
+ fprintf(stderr, "Failed to open output file: %s, errno=%d\n",
+ out_filename, errno);
+ exit(4);
+ }
+ }
+
+ /* Output the thunk file in three pieces: 1. The constant file prologue 2.
+ * Library path information (if any) 3. Library file name information (if
+ * any) 4. Exported symbole information (if any) 5. Imported symbole
+ * information (if any) 6. The constant file epilogue. */
+
+ put_file_prologue(out_fd);
+ put_import_name_strtab(out_fd);
+ put_all_nxflat_import(out_fd);
+ put_file_epilogue(out_fd);
+
+ if (out_fd > 0)
+ close(out_fd);
+ exit(0);
+}
diff --git a/misc/buildroot/toolchain/nxflat/nxflat.h b/misc/buildroot/toolchain/nxflat/nxflat.h
new file mode 100644
index 000000000..ff41a733d
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/nxflat.h
@@ -0,0 +1,202 @@
+/****************************************************************************
+ * toolchain/nxflat/nxflat.h
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __TOOLCHAIN_NXFLAT_NXFLAT_H
+#define __TOOLCHAIN_NXFLAT_NXFLAT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <sys/types.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define NXFLAT_MAX_STRING_SIZE 64 /* Largest size of string (w/zterminator) */
+#define NXFLAT_MAGIC "NxFT" /* NXFLAT magic number */
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * The NXFLAT file header
+ *
+ * The elements within this structure are stored in network order (i.e.,
+ * ntohs() and ntohl() should be used to access fields within the
+ * header.
+ ****************************************************************************/
+
+struct nxflat_hdr_s
+{
+ /* The "magic number" identifying the file type. This field should contain
+ * "NxFT". NOTE that there is no other versioning information other than
+ * this magic number.
+ */
+
+ char h_magic[4];
+
+ /* The following fields provide the memory map for the nxflat binary.
+ *
+ * h_entry - Offset to the first executable insruction from
+ * the beginning of the file.
+ * h_datastart - Offset to the beginning of the data segment from
+ * the beginning of the file. This field can also
+ * interpreted as the size of the ISpace segment.
+ * h_dataend - Offset to the end of the data segment from the
+ * beginning of the file.
+ * h_bssend - Offset to the end of bss segment from the beginning
+ * of the file.
+ *
+ * The text segment can be considered to be the contiguous (unrelocated)
+ * address space range from address zero through (but not including)
+ * h_datastart.
+ *
+ * The size of the data/bss segment includes (as a minimum) the data
+ * and bss regions (bss_end - data_start) as well as the size of the
+ * stack. At run time, this region will also include program arguments
+ * and environement variables.
+ *
+ * The bss segment is data_end through bss_end.
+ */
+
+ u_int32_t h_entry;
+ u_int32_t h_datastart;
+ u_int32_t h_dataend;
+ u_int32_t h_bssend;
+
+ /* Size of stack, in bytes */
+
+ u_int32_t h_stacksize;
+
+ /* Relocation entries:
+ *
+ * h_relocstart - Offset to the beginning of an array of relocation
+ * records (struct nxflat_reloc). The offset is
+ * relative to the start of the file
+ */
+
+ u_int32_t h_relocstart; /* Offset of relocation records */
+
+ /* Imported symbol table (NOTE no symbols are exported):
+ *
+ * h_importsymbols - Offset to the beginning of an array of imported
+ * symbol structures (struct nxflat_import_s). The
+ * h_importsymbols offset is relative to the
+ * beginning of the file. Each entry of the
+ * array contains an uint32 offset (again from
+ * the beginning of the file) to the name of
+ * a symbol string. This string is null-terminated.
+ */
+
+ u_int32_t h_importsymbols; /* Offset to list of imported symbols */
+
+ /* 16-bit counts
+ *
+ * h_reloccount - The number of relocation records in the arry
+ * h_importcount - The number of records in the h_importsymbols array.
+ */
+
+ u_int16_t h_reloccount; /* Number of relocation records */
+ u_int16_t h_importcount; /* Number of imported symbols */
+};
+
+/****************************************************************************
+ * NXFLAT Relocation types.
+ *
+ * The relocation records are an array of the following type.
+ ****************************************************************************/
+
+struct nxflat_reloc_s
+{
+ u_int32_t r_info; /* Bit-encoded relocation info */
+};
+
+/* Pack the type and the offset into one 32-bit value */
+
+#define NXFLAT_RELOC(t,o) (((u_int32_t)((t) & 3) << 30) | ((o) & 0x3fffffff))
+
+/* The top three bits of the relocation info is the relocation type (see the
+ * NXFLAT_RELOC_TYPE_* definitions below. This is an unsigned value.
+ */
+
+#define NXFLAT_RELOC_TYPE(r) ((u_int32_t)(r) >> 30)
+
+/* The bottom 28 bits of the relocation info is the (non-negative) offset into
+ * the D-Space that needs the fixup.
+ */
+
+#define NXFLAT_RELOC_OFFSET(r) ((u_int32_t)(r) & 0x3fffffff)
+
+/* These are possible values for the relocation type:
+ *
+ * NXFLAT_RELOC_TYPE_REL32I Meaning: Object file contains a 32-bit offset
+ * into I-Space at the offset.
+ * Fixup: Add mapped I-Space address to the offset.
+ * NXFLAT_RELOC_TYPE_REL32D Meaning: Object file contains a 32-bit offset
+ * into D-Space at the offset.
+ * Fixup: Add allocated D-Space address to the
+ * offset.
+ * NXFLAT_RELOC_TYPE_REL32ID Meaning: Object file contains a 32-bit offset
+ * into I-Space at the offset that will
+ * unfortunately be references relative
+ * to the GOT
+ * Fixup: Add allocated the mapped I-Space
+ * address MINUS the allocated D-Space
+ * address to the offset.
+ */
+
+#define NXFLAT_RELOC_TYPE_REL32I 0
+#define NXFLAT_RELOC_TYPE_REL32D 1
+#undef NXFLAT_RELOC_TYPE_REL32ID /* May not need */
+#define NXFLAT_RELOC_TYPE_NUM 2 /* Number of relocation types */
+
+/****************************************************************************
+ * NXFLAT Imported symbol type
+ *
+ * The imported symbols are an array of the following type. The fields
+ * in each element are stored in native machine order.
+ ****************************************************************************/
+
+struct nxflat_import_s
+{
+ u_int32_t i_funcname; /* Offset to name of imported function */
+ u_int32_t i_funcaddress; /* Resolved address of imported function */
+};
+
+#endif /* __TOOLCHAIN_NXFLAT_NXFLAT_H */
+
diff --git a/misc/buildroot/toolchain/nxflat/nxflat.mk b/misc/buildroot/toolchain/nxflat/nxflat.mk
new file mode 100644
index 000000000..3a7a03c0e
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/nxflat.mk
@@ -0,0 +1,69 @@
+############################################################################
+# toolchain/nxflat/nxflat.mk
+#
+# Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+NXFLAT_DIR = $(TOPDIR)/toolchain/nxflat
+
+$(NXFLAT_DIR)/.compiled:
+ifeq ($(strip $(BR2_GCC_TARGET_ARCH)),"armv7-m")
+ echo "NUTTX_DIR: $(NUTTX_DIR)"
+ $(MAKE) -C $(NXFLAT_DIR) BINUTILS_DIR="$(BINUTILS_DIR)" \
+ BINUTILS_DIR1="$(BINUTILS_DIR1)" ARCH=thumb2 CC="$(HOSTCC)"
+else
+ echo "NUTTX_DIR: $(NUTTX_DIR)"
+ $(MAKE) -C $(NXFLAT_DIR) BINUTILS_DIR="$(BINUTILS_DIR)" \
+ BINUTILS_DIR1="$(BINUTILS_DIR1)" ARCH=$(BR2_ARCH) CC="$(HOSTCC)"
+endif
+ touch $@
+
+$(NXFLAT_DIR)/.installed: $(NXFLAT_DIR)/.compiled
+ install -m 755 $(NXFLAT_DIR)/mknxflat $(STAGING_DIR)/bin/mknxflat
+ install -m 755 $(NXFLAT_DIR)/ldnxflat $(STAGING_DIR)/bin/ldnxflat
+ install -m 755 $(NXFLAT_DIR)/readnxflat $(STAGING_DIR)/bin/readnxflat
+ touch $@
+
+nxflat: binutils $(NXFLAT_DIR)/.installed
+
+nxflat-clean:
+ $(MAKE) -C $(NXFLAT_DIR) clean
+ rm -f $(STAGING_DIR)/bin/mknxflat $(STAGING_DIR)/bin/ldnxflat $(STAGING_DIR)/bin/readnxflat
+ rm -f $(NXFLAT_DIR)/.compiled $(NXFLAT_DIR)/.installed
+
+nxflat-dirclean: nxflat-clean
+ true
+
+ifeq ($(strip $(BR2_PACKAGE_NXFLAT)),y)
+TARGETS += nxflat
+endif
+
diff --git a/misc/buildroot/toolchain/nxflat/readnxflat.c b/misc/buildroot/toolchain/nxflat/readnxflat.c
new file mode 100644
index 000000000..e19e2d699
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/readnxflat.c
@@ -0,0 +1,717 @@
+/***********************************************************************
+ * toolchain/nxflat/readnxflat.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Modified from readxflat (see http://xflat.org):
+ *
+ * Copyright (c) 2002, 2006, Cadenux, LLC. All rights reserved.
+ * Copyright (c) 2002, 2006, Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************************************/
+
+/***********************************************************************
+ * Compilation Flags
+ ***********************************************************************/
+
+#define SWAP_BYTES 1
+
+/***********************************************************************
+ * Included Files
+ ***********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <netinet/in.h> /* ntohl and friends */
+#include "nxflat.h"
+
+/***********************************************************************
+ * Compilation Switches
+ ***********************************************************************/
+
+/* #define RELOCS_IN_NETWORK_ORDER */
+
+/***********************************************************************
+ * Definitions
+ ***********************************************************************/
+
+#define NXFLAT_HDR_SIZE sizeof(struct nxflat_hdr_s)
+
+/***********************************************************************
+ * Private Data
+ ***********************************************************************/
+
+static const char *program_name;
+static const char *nxflat_filename;
+
+static int dump_header = 0;
+static int dump_relocs = 0;
+static int dump_imports = 0;
+static int dump_text = 0;
+static int dump_data = 0;
+static int verbose = 0;
+
+static int num_errors = 0;
+
+#ifdef ARCH_BIG_ENDIAN
+static int big_endian = 1; /* Assume big-endian */
+#else
+static int big_endian = 0; /* Assume little-endian */
+#endif
+
+/***********************************************************************
+ * Private Constant Data
+ ***********************************************************************/
+
+static const char unknown[] = "UNKNOWN";
+
+static const char hdr_reloc_rel32i[] = "RELOC_REL32I";
+static const char hdr_reloc_rel32d[] = "RELOC_REL32D";
+#ifdef NXFLAT_RELOC_TYPE_REL32ID
+static const char hdr_reloc_rel32id[] = "RELOC_REL32ID";
+#endif
+
+static const char *reloc_type_string[] = {
+ hdr_reloc_rel32i,
+ hdr_reloc_rel32d,
+#ifdef NXFLAT_RELOC_TYPE_REL32ID
+ hdr_reloc_rel32id,
+#else
+ unknown,
+#endif
+ unknown
+};
+
+/***********************************************************************
+ * Public Function Prototypes
+ ***********************************************************************/
+
+extern void __attribute__ ((weak)) print_insn_arm(u_int32_t pc,
+ FILE * stream,
+ u_int32_t given);
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * swap32
+ ***********************************************************************/
+
+static inline u_int32_t nxflat_swap32(u_int32_t little)
+{
+ u_int32_t big =
+ ((little >> 24) & 0xff) |
+ (((little >> 16) & 0xff) << 8) |
+ (((little >> 8) & 0xff) << 16) | ((little & 0xff) << 24);
+ return big;
+}
+
+/***********************************************************************
+ * get_nxflat32
+ ***********************************************************************/
+
+static inline u_int32_t get_nxflat32(u_int32_t * addr32)
+{
+ return ntohl(*addr32);
+}
+
+/***********************************************************************
+ * get_nxflat16
+ ***********************************************************************/
+
+static inline u_int16_t get_nxflat16(u_int16_t * addr16)
+{
+ return ntohs(*addr16);
+}
+
+/***********************************************************************
+ * dump_hex_data
+ ***********************************************************************/
+
+static void dump_hex_data(FILE * in_stream, struct nxflat_hdr_s *header)
+{
+ u_int32_t data_start = get_nxflat32(&header->h_datastart);
+ u_int32_t data_end = get_nxflat32(&header->h_dataend);
+ int32_t words_left = (data_end - data_start) / sizeof(u_int32_t);
+ u_int32_t addr;
+ u_int32_t buffer[64];
+
+ printf("\nXFLAT DATA SEGMENT:\n\n");
+
+ /* Seek to the beginning of data in the file */
+
+ if (fseek(in_stream, data_start, SEEK_SET) != 0)
+ {
+ fprintf(stderr,
+ "ERROR: Failed to seek to data in file: offset: %08x\n",
+ data_start);
+ return;
+ }
+
+ /* Now dump all of the data reading 64 words at a time */
+
+ addr = 0;
+ while (words_left > 0)
+ {
+ size_t nread = fread(buffer, sizeof(u_int32_t), 64, in_stream);
+ if (nread >= 0)
+ {
+ union
+ {
+ u_int32_t l[4];
+ unsigned char b[16];
+ } row;
+ int32_t i, j, k;
+
+ for (i = 0; i < nread; i += 4)
+ {
+ for (j = 0; j < 4; j++)
+ {
+ row.l[j] = buffer[i + j];
+ }
+
+ printf("%08x: ", addr);
+
+ for (j = 0; j < 4; j++)
+ {
+ printf("%08x ", row.l[j]);
+ }
+
+ printf(" ");
+
+ for (j = 0; j < 4 * sizeof(u_int32_t); j += sizeof(u_int32_t))
+ {
+ for (k = 0; k < sizeof(u_int32_t); k++)
+ {
+ if (isprint(row.b[j + k]))
+ putchar(row.b[j + k]);
+ else
+ putchar('.');
+ }
+ }
+
+ putchar('\n');
+ addr += 4 * sizeof(u_int32_t);
+ }
+ words_left -= nread;
+ }
+ else
+ break;
+ }
+ putchar('\n');
+}
+
+/***********************************************************************
+ * disassemble_text
+ ***********************************************************************/
+
+static void disassemble_text(FILE * in_stream, struct nxflat_hdr_s *header)
+{
+ if (print_insn_arm)
+ {
+ u_int32_t text_start = NXFLAT_HDR_SIZE;
+ u_int32_t text_end = get_nxflat32(&header->h_datastart);
+ int32_t insns_left = (text_end - text_start) / sizeof(u_int32_t);
+ u_int32_t addr;
+ u_int32_t buffer[64];
+
+ printf("\nXFLAT TEXT:\n\n");
+
+ /* Seek to the beginning of text in the file */
+
+ if (fseek(in_stream, text_start, SEEK_SET) != 0)
+ {
+ fprintf(stderr,
+ "ERROR: Failed to seek to text in file: offset: %08x\n",
+ text_start);
+ return;
+ }
+
+ /* Now dump all of the data reading 64 insns at a time */
+
+ addr = text_start;
+ while (insns_left > 0)
+ {
+ size_t nread = fread(buffer, sizeof(u_int32_t), 64, in_stream);
+ if (nread > 0)
+ {
+ int i;
+ for (i = 0; i < nread; i++)
+ {
+ u_int32_t insn = buffer[i];
+ if (big_endian)
+ {
+ insn = nxflat_swap32(insn);
+ }
+
+ printf("%08x %08x\t", addr, insn);
+ print_insn_arm(addr, stdout, insn);
+ putchar('\n');
+ addr += sizeof(u_int32_t);
+ }
+ insns_left -= nread;
+ }
+ else
+ break;
+ putchar('\n');
+ }
+ }
+}
+
+/***********************************************************************
+ * dump_imported_symbols
+ ***********************************************************************/
+
+static void dump_imported_symbols(FILE *in_stream, struct nxflat_hdr_s *header)
+{
+ struct nxflat_import_s import;
+ u_int32_t import_offset;
+ u_int32_t data_start;
+ u_int32_t struct_offset;
+ u_int32_t name_offset;
+ char imported_symbol_name[NXFLAT_MAX_STRING_SIZE];
+ int status;
+ int i;
+
+ printf("\nIMPORTED SYMBOLS:\n");
+ printf(" OFFSET ADDRESS SYMBOL NAME\n\n");
+
+ import_offset = get_nxflat32(&header->h_importsymbols);
+ data_start = get_nxflat32(&header->h_datastart);
+
+ for (i = 0; i < get_nxflat16(&header->h_importcount); i++)
+ {
+ /* Seek to the next imported symbol */
+
+ struct_offset = i * sizeof(struct nxflat_import_s) + import_offset;
+
+ if (fseek(in_stream, struct_offset, SEEK_SET) != 0)
+ {
+ fprintf(stderr, "ERROR: fseek to imported symbol %d struct failed\n",
+ i);
+ fprintf(stderr, " struct_offset: %d: %s\n",
+ struct_offset, strerror(errno));
+ exit(1);
+ }
+
+ /* Read the next import entry. */
+
+ status = fread((void *)&import,
+ sizeof(struct nxflat_import_s), 1, in_stream);
+ if (status != 1)
+ {
+ if (ferror(in_stream))
+ {
+ fprintf(stderr, "ERROR: Read imported symbol %d struct failed: %s\n",
+ i + 1, strerror(errno));
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: Read imported symbol %d struct: End-of-file after %d\n",
+ i + 1, struct_offset);
+ }
+
+ exit(1);
+ }
+
+ if (big_endian)
+ {
+ import.i_funcname = nxflat_swap32(import.i_funcname);
+ import.i_funcaddress = nxflat_swap32(import.i_funcaddress);
+ }
+
+ if (verbose)
+ {
+ /* Print the raw info */
+
+ printf("[Import: %4d Offset: %08x Name: %08x Address: %08x]\n",
+ i + 1, struct_offset, import.i_funcname, import.i_funcaddress);
+ }
+
+ /* Seek to the function name in the file */
+
+ name_offset = import.i_funcname + NXFLAT_HDR_SIZE;
+
+ if (fseek(in_stream, name_offset, SEEK_SET) != 0)
+ {
+ fprintf(stderr, "ERROR: fseek to imported symbol %d name failed\n",
+ i);
+ fprintf(stderr, " name_offset: %d %s\n",
+ name_offset, strerror(errno));
+ exit(1);
+ }
+
+ /* Then, read the imported symbol name (assuming it is less than
+ * NXFLAT_MAX_STRING_SIZE in length). */
+
+ status = fread((void *)imported_symbol_name, NXFLAT_MAX_STRING_SIZE,
+ 1, in_stream);
+
+ if (status != 1)
+ {
+ if (ferror(in_stream))
+ {
+ fprintf(stderr, "ERROR: Read imported symbol %d name failed: %s\n",
+ i + 1, strerror(errno));
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: Read imported symbol %d name: End-of-file after offset=%d\n",
+ i + 1, name_offset);
+ }
+ exit(1);
+ }
+
+ imported_symbol_name[NXFLAT_MAX_STRING_SIZE - 1] = '\0';
+
+ /* And print it */
+
+ printf("%5d %08x ", i + 1, (int)struct_offset - data_start);
+
+ if (import.i_funcaddress)
+ {
+ printf("%08x ", import.i_funcaddress);
+ }
+ else
+ {
+ printf("UNKNOWN ");
+ }
+
+ printf("%s\n", imported_symbol_name);
+ }
+}
+
+/***********************************************************************
+ * dump_relocation_entries
+ ***********************************************************************/
+
+static void dump_relocation_entries(FILE * in_stream, struct nxflat_hdr_s *header)
+{
+ struct nxflat_reloc_s reloc;
+ int status;
+ int i;
+
+ /* Seek to the beginning of the relocation records. */
+
+ if (0 != fseek(in_stream, get_nxflat32(&header->h_relocstart), SEEK_SET))
+ {
+ fprintf(stderr, "ERROR: fseek to reloc records failed: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ printf("\nRELOCATION ENTRIES:\n");
+ printf(" OFFSET RELOC TYPE\n\n");
+
+ for (i = 0; i < get_nxflat16(&header->h_reloccount); i++)
+ {
+ /* Read the next reloction entry. */
+
+ status = fread((void *)&reloc, sizeof(struct nxflat_reloc_s), 1, in_stream);
+ if (status != 1)
+ {
+ if (ferror(in_stream))
+ {
+ fprintf(stderr, "ERROR: Read reloc record %d: %s\n",
+ i + 1, strerror(errno));
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: Read reloc record %d: End-of-file\n",
+ i + 1);
+ }
+ exit(1);
+ }
+
+#ifdef RELOCS_IN_NETWORK_ORDER
+ {
+ u_int32_t *ptmp;
+ ptmp = (u_int32_t *) & reloc;
+ *ptmp = get_nxflat32(ptmp);
+ }
+#endif
+
+ if (NXFLAT_RELOC_TYPE(reloc.r_info) >= NXFLAT_RELOC_TYPE_NUM)
+ {
+ printf("%5d %08x UNKNOWN(%d)\n", i + 1,
+ NXFLAT_RELOC_OFFSET(reloc.r_info), NXFLAT_RELOC_TYPE(reloc.r_info));
+ fprintf(stderr, "Error eloc type out of range(%d)\n",
+ NXFLAT_RELOC_TYPE(reloc.r_info));
+ num_errors++;
+ }
+ else
+ {
+ printf("%5d %08x %-13s\n",
+ i + 1, NXFLAT_RELOC_OFFSET(reloc.r_info),
+ reloc_type_string[NXFLAT_RELOC_TYPE(reloc.r_info)]);
+ }
+ }
+}
+
+/***********************************************************************
+ * dump_hdr
+ ***********************************************************************/
+
+static void dump_hdr(struct nxflat_hdr_s *header)
+{
+ /* Print the contents of the FLT header */
+
+ printf("\nXFLAT HEADER:\n");
+ printf("\nMagic %c%c%c%c\n",
+ header->h_magic[0], header->h_magic[1],
+ header->h_magic[2], header->h_magic[3]);
+
+ printf("\nMEMORY MAP:\n");
+ printf(" Text start %08lx\n", (long)NXFLAT_HDR_SIZE);
+ printf(" Entry point %08x\n", get_nxflat32(&header->h_entry));
+ printf(" Data start %08x\n", get_nxflat32(&header->h_datastart));
+ printf(" Data end %08x\n", get_nxflat32(&header->h_dataend) - 1);
+ printf(" Bss start %08x\n", get_nxflat32(&header->h_dataend));
+ printf(" Bss end %08x\n", get_nxflat32(&header->h_bssend) - 1);
+ printf("TOTAL SIZE %08x\n\n", get_nxflat32(&header->h_bssend));
+ printf("Stack size %08x\n", get_nxflat32(&header->h_stacksize));
+ printf("\nRELOCATIONS:\n");
+ printf(" Reloc start %08x\n", get_nxflat32(&header->h_relocstart));
+ printf(" reloc count %d\n", get_nxflat16(&header->h_reloccount));
+ printf("\nIMPORTED SYMBOLS:\n");
+ printf(" Import start %08x\n", get_nxflat32(&header->h_importsymbols));
+ printf(" Import count %d\n", get_nxflat16(&header->h_importcount));
+}
+
+/***********************************************************************
+ * show_usage
+ ***********************************************************************/
+
+static void show_usage(void)
+{
+ fprintf(stderr, "Usage: %s [options] <flat-filename>\n\n", program_name);
+#if 1
+ fprintf(stderr, "Where options are one or more of the following:\n\n");
+#else
+ fprintf(stderr, "Where options are one or more of the following. Note\n");
+ fprintf(stderr, "that a space is always required between the option and\n");
+ fprintf(stderr, "any following arguments\n\n");
+#endif
+ fprintf(stderr, " -h Dump the XFLAT file header [not dumped]\n");
+ fprintf(stderr, " -r Dump relocation entries [not dumped]\n");
+ fprintf(stderr, " -i Dump the imported symbol table [not dumped]\n");
+ fprintf(stderr, " -x Dump xFLT loader pathname [not dumped]\n");
+ fprintf(stderr, " -c Disassemble the text section [not dumped]\n");
+ fprintf(stderr, " -d Dump data section (hex) [not dumped]\n");
+ fprintf(stderr, " -a Dump all of the above [not dumped]\n");
+#ifdef ARCH_BIG_ENDIAN
+ fprintf(stderr, " -b Assume little-endian byteorder [big endian]\n");
+#else
+ fprintf(stderr, " -b Assume big-endian byteorder [little endian]\n");
+#endif
+ fprintf(stderr, " -v Output verbose debug info [no output]\n");
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+/***********************************************************************
+ * parse_args
+ ***********************************************************************/
+
+static void parse_args(int argc, char **argv)
+{
+ int opt;
+
+ /* Save our name (for show_usage) */
+
+ program_name = argv[0];
+
+ /* At least three things must appear on the program line: the program name,
+ * the BFD filname, and at least one option. */
+
+ if (argc < 3)
+ {
+ fprintf(stderr, "ERROR: Missing required arguments\n\n");
+ show_usage();
+ }
+
+ /* Get miscellaneous options from the command line. */
+
+ while ((opt = getopt(argc, argv, "hrieLlxcbdav")) != -1)
+ {
+ switch (opt)
+ {
+
+ case 'h': /* Dump the flat file header */
+ dump_header++;
+ break;
+
+ case 'r': /* Dump the flat file header */
+ dump_relocs++;
+ break;
+
+ case 'i': /* Dump the imported symbol table */
+ dump_imports++;
+ break;
+
+ case 'c': /* Disassembly text */
+ if (print_insn_arm)
+ {
+ dump_text++;
+ }
+ else
+ {
+ printf("-c ignored: No disassembler available\n");
+ }
+ break;
+
+ case 'b': /* other-endian */
+#ifdef ARCH_BIG_ENDIAN
+ big_endian = 0;
+#else
+ big_endian++;
+#endif
+ break;
+
+ case 'd': /* Dump data */
+ dump_data++;
+ break;
+
+ case 'a': /* Dump everying */
+ dump_header++;
+ dump_relocs++;
+ dump_imports++;
+ dump_text++;
+ dump_data++;
+ break;
+
+ case 'v': /* Output verbose debug information */
+ verbose++;
+ break;
+
+ default:
+ fprintf(stderr, "%s Unknown option\n\n", argv[0]);
+ show_usage();
+ break;
+ }
+ }
+
+ /* Get the name of the input BFD file. */
+
+ nxflat_filename = argv[argc - 1];
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * main
+ ***********************************************************************/
+
+int main(int argc, char **argv, char **envp)
+{
+ FILE *in_stream;
+ struct nxflat_hdr_s header;
+ int status;
+
+ /* Get the input parameters */
+
+ parse_args(argc, argv);
+
+ /* Open the FLT file */
+
+ in_stream = fopen(nxflat_filename, "rb");
+ if (NULL == in_stream)
+ {
+ fprintf(stderr, "Cannot open file %s for reading\n", nxflat_filename);
+ exit(1);
+ }
+
+ /* Read the FLT header */
+
+ status = fread((void *)&header, sizeof(struct nxflat_hdr_s), 1, in_stream);
+ if (status != 1)
+ {
+ if (ferror(in_stream))
+ {
+ fprintf(stderr, "ERROR: Read flat header: %s\n", strerror(errno));
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: Read flat header: End-of-file\n");
+ }
+ exit(1);
+ }
+
+ printf("Dumping Flat Binary File: %s\n", nxflat_filename);
+
+ /* Dump the contents of the FLT header */
+
+ if (dump_header)
+ {
+ dump_hdr(&header);
+ }
+
+ /* Dump the relocation entries */
+
+ if (dump_relocs)
+ {
+ dump_relocation_entries(in_stream, &header);
+ }
+
+ /* Dump all imported symbols */
+
+ if (dump_imports)
+ {
+ dump_imported_symbols(in_stream, &header);
+ }
+
+ if (dump_text)
+ {
+ disassemble_text(in_stream, &header);
+ }
+
+ if (dump_data)
+ {
+ dump_hex_data(in_stream, &header);
+ }
+
+ fclose(in_stream);
+
+ if (num_errors > 0)
+ {
+ fprintf(stderr, "Finished with %d errors\n", num_errors);
+ }
+
+ return 0;
+}
diff --git a/misc/buildroot/toolchain/nxflat/reloc-macros.h b/misc/buildroot/toolchain/nxflat/reloc-macros.h
new file mode 100644
index 000000000..91b9fd1ea
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/reloc-macros.h
@@ -0,0 +1,140 @@
+/***********************************************************************
+ * xflat/tools/arm/arch.h
+ * Generic relocation support for BFD.
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Simply lifted with minimal change from the BFD, binutils 2.19.1:
+ *
+ * Copyright 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
+ * Free Software Foundation, Inc.
+ *
+ * This file is part of BFD, the Binary File Descriptor library.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ ***********************************************************************/
+
+/* These macros are used by the various *.h target specific header
+ files to either generate an enum containing all the known relocations
+ for that target, or if RELOC_MACROS_GEN_FUNC is defined, a recognition
+ function is generated instead. (This is used by binutils/readelf.c)
+
+ Given a header file like this:
+
+ START_RELOC_NUMBERS (foo)
+ RELOC_NUMBER (R_foo_NONE, 0)
+ RELOC_NUMBER (R_foo_32, 1)
+ EMPTY_RELOC (R_foo_good)
+ FAKE_RELOC (R_foo_illegal, 9)
+ END_RELOC_NUMBERS (R_foo_count)
+
+ Then the following will be produced by default (ie if
+ RELOC_MACROS_GEN_FUNC is *not* defined).
+
+ enum foo
+ {
+ R_foo_NONE = 0,
+ R_foo_32 = 1,
+ R_foo_good,
+ R_foo_illegal = 9,
+ R_foo_count
+ };
+
+ Note: The value of the symbol defined in the END_RELOC_NUMBERS
+ macro (R_foo_count in the case of the example above) will be
+ set to the value of the whichever *_RELOC macro preceeds it plus
+ one. Therefore if you intend to use the symbol as a sentinel for
+ the highest valid macro value you should make sure that the
+ preceeding *_RELOC macro is the highest valid number. ie a
+ declaration like this:
+
+ START_RELOC_NUMBERS (foo)
+ RELOC_NUMBER (R_foo_NONE, 0)
+ RELOC_NUMBER (R_foo_32, 1)
+ FAKE_RELOC (R_foo_illegal, 9)
+ FAKE_RELOC (R_foo_synonym, 0)
+ END_RELOC_NUMBERS (R_foo_count)
+
+ will result in R_foo_count having a value of 1 (R_foo_synonym + 1)
+ rather than 10 or 2 as might be expected.
+
+ Alternatively you can assign a value to END_RELOC_NUMBERS symbol
+ explicitly, like this:
+
+ START_RELOC_NUMBERS (foo)
+ RELOC_NUMBER (R_foo_NONE, 0)
+ RELOC_NUMBER (R_foo_32, 1)
+ FAKE_RELOC (R_foo_illegal, 9)
+ FAKE_RELOC (R_foo_synonym, 0)
+ END_RELOC_NUMBERS (R_foo_count = 2)
+
+ If RELOC_MACROS_GEN_FUNC *is* defined, then instead the
+ following function will be generated:
+
+ static const char *foo (unsigned long rtype);
+ static const char *
+ foo (unsigned long rtype)
+ {
+ switch (rtype)
+ {
+ case 0: return "R_foo_NONE";
+ case 1: return "R_foo_32";
+ default: return NULL;
+ }
+ }
+ */
+
+#ifndef __TOOLCHAIN_NXFLAT_RELOC_MACROS_H
+#define __TOOLCHAIN_NXFLAT_RELOC_MACROS_H
+
+#ifdef RELOC_MACROS_GEN_FUNC
+
+/* This function takes the relocation number and returns the
+ string version name of the name of that relocation. If
+ the relocation is not recognised, NULL is returned. */
+
+#define START_RELOC_NUMBERS(name) \
+static const char *name (unsigned long rtype); \
+static const char * \
+name (unsigned long rtype) \
+{ \
+ switch (rtype) \
+ {
+
+#define RELOC_NUMBER(name, number) \
+ case number: return #name;
+
+#define FAKE_RELOC(name, number)
+#define EMPTY_RELOC(name)
+
+#define END_RELOC_NUMBERS(name) \
+ default: return NULL; \
+ } \
+}
+
+
+#else /* Default to generating enum. */
+
+#define START_RELOC_NUMBERS(name) enum name {
+#define RELOC_NUMBER(name, number) name = number,
+#define FAKE_RELOC(name, number) name = number,
+#define EMPTY_RELOC(name) name,
+#define END_RELOC_NUMBERS(name) name };
+
+#endif
+
+#endif /* __TOOLCHAIN_NXFLAT_RELOC_MACROS_H */
diff --git a/misc/buildroot/toolchain/nxflat/thumb2/Makefile b/misc/buildroot/toolchain/nxflat/thumb2/Makefile
new file mode 100644
index 000000000..ad87449fa
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/thumb2/Makefile
@@ -0,0 +1,50 @@
+############################################################################
+# toolchain/nxflat/thumb2/Makefile
+#
+# Copyright (C) 2009 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+CFLAGS += -Wall
+BIN = libarch.a
+OBJS = disthumb2.o
+
+all: $(BIN)
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) -o $@ $<
+
+$(BIN): $(OBJS)
+ $(AR) rcs $@ $<
+
+clean:
+ rm -f *.o *.a *~ .*.swp core
+
diff --git a/misc/buildroot/toolchain/nxflat/thumb2/arch.h b/misc/buildroot/toolchain/nxflat/thumb2/arch.h
new file mode 100644
index 000000000..c07c4f62e
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/thumb2/arch.h
@@ -0,0 +1,303 @@
+/***********************************************************************
+ * xflat/tools/thumb2/arch.h
+ * ARM thumb2 ELF support for BFD.
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Simply lifted with minimal change from the BFD, binutils 2.19.1:
+ *
+ * Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ * Free Software Foundation, Inc.
+ *
+ * This file is part of BFD, the Binary File Descriptor library.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ ***********************************************************************/
+
+#ifndef _TOOLCHAIN_NXFLAT_THUMB2_ARCH_H
+#define _TOOLCHAIN_NXFLAT_THUMB2_ARCH_H
+
+#include "reloc-macros.h"
+
+/* Inform ldnxflat that this is 16-bit Thumb2 code */
+
+#define NXFLAT_ARM 1
+#define NXFLAT_THUMB2 1
+
+/* Processor specific flags for the ELF header e_flags field. */
+#define EF_ARM_RELEXEC 0x01
+#define EF_ARM_HASENTRY 0x02
+#define EF_ARM_INTERWORK 0x04
+#define EF_ARM_APCS_26 0x08
+#define EF_ARM_APCS_FLOAT 0x10
+#define EF_ARM_PIC 0x20
+#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use. */
+#define EF_ARM_NEW_ABI 0x80
+#define EF_ARM_OLD_ABI 0x100
+#define EF_ARM_SOFT_FLOAT 0x200
+#define EF_ARM_VFP_FLOAT 0x400
+#define EF_ARM_MAVERICK_FLOAT 0x800
+
+/* Frame unwind information */
+#define PT_ARM_EXIDX (PT_LOPROC + 1)
+
+/* Other constants defined in the ARM ELF spec. version B-01. */
+#define EF_ARM_SYMSARESORTED 0x04 /* NB conflicts with EF_INTERWORK */
+#define EF_ARM_DYNSYMSUSESEGIDX 0x08 /* NB conflicts with EF_APCS26 */
+#define EF_ARM_MAPSYMSFIRST 0x10 /* NB conflicts with EF_APCS_FLOAT */
+#define EF_ARM_EABIMASK 0xFF000000
+
+/* Constants defined in AAELF. */
+#define EF_ARM_BE8 0x00800000
+#define EF_ARM_LE8 0x00400000
+
+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN 0x00000000
+#define EF_ARM_EABI_VER1 0x01000000
+#define EF_ARM_EABI_VER2 0x02000000
+#define EF_ARM_EABI_VER3 0x03000000
+#define EF_ARM_EABI_VER4 0x04000000
+#define EF_ARM_EABI_VER5 0x05000000
+
+/* Local aliases for some flags to match names used by COFF port. */
+#define F_INTERWORK EF_ARM_INTERWORK
+#define F_APCS26 EF_ARM_APCS_26
+#define F_APCS_FLOAT EF_ARM_APCS_FLOAT
+#define F_PIC EF_ARM_PIC
+#define F_SOFT_FLOAT EF_ARM_SOFT_FLOAT
+#define F_VFP_FLOAT EF_ARM_VFP_FLOAT
+
+/* Additional symbol types for Thumb. */
+#define STT_ARM_TFUNC 13 /* A Thumb function. */
+#define STT_ARM_16BIT 15 /* A Thumb label. */
+
+/* Additional section types. */
+#define SHT_ARM_EXIDX 0x70000001 /* Section holds ARM unwind info. */
+#define SHT_ARM_PREEMPTMAP 0x70000002 /* Section pre-emption details. */
+#define SHT_ARM_ATTRIBUTES 0x70000003 /* Section holds attributes. */
+
+/* ARM-specific values for sh_flags. */
+#define SHF_ENTRYSECT 0x10000000 /* Section contains an entry point. */
+#define SHF_COMDEF 0x80000000 /* Section may be multiply defined in the input to a link step. */
+
+/* ARM-specific program header flags. */
+#define PF_ARM_SB 0x10000000 /* Segment contains the location addressed by the static base. */
+#define PF_ARM_PI 0x20000000 /* Segment is position-independent. */
+#define PF_ARM_ABS 0x40000000 /* Segment must be loaded at its base address. */
+
+/* Values for the Tag_CPU_arch EABI attribute. */
+#define TAG_CPU_ARCH_PRE_V4 0
+#define TAG_CPU_ARCH_V4 1
+#define TAG_CPU_ARCH_V4T 2
+#define TAG_CPU_ARCH_V5T 3
+#define TAG_CPU_ARCH_V5TE 4
+#define TAG_CPU_ARCH_V5TEJ 5
+#define TAG_CPU_ARCH_V6 6
+#define TAG_CPU_ARCH_V6KZ 7
+#define TAG_CPU_ARCH_V6T2 8
+#define TAG_CPU_ARCH_V6K 9
+#define TAG_CPU_ARCH_V7 10
+
+/* Relocation types. */
+
+START_RELOC_NUMBERS (elf_arm_reloc_type)
+/* AAELF official names and numbers. */
+ RELOC_NUMBER (R_ARM_NONE, 0)
+ RELOC_NUMBER (R_ARM_PC24, 1) /* deprecated */
+ RELOC_NUMBER (R_ARM_ABS32, 2)
+ RELOC_NUMBER (R_ARM_REL32, 3)
+ RELOC_NUMBER (R_ARM_LDR_PC_G0, 4)
+ RELOC_NUMBER (R_ARM_ABS16, 5)
+ RELOC_NUMBER (R_ARM_ABS12, 6)
+ RELOC_NUMBER (R_ARM_THM_ABS5, 7)
+ RELOC_NUMBER (R_ARM_ABS8, 8)
+ RELOC_NUMBER (R_ARM_SBREL32, 9)
+ RELOC_NUMBER (R_ARM_THM_CALL, 10)
+ RELOC_NUMBER (R_ARM_THM_PC8, 11)
+ RELOC_NUMBER (R_ARM_BREL_ADJ, 12)
+ RELOC_NUMBER (R_ARM_SWI24, 13) /* obsolete */
+ RELOC_NUMBER (R_ARM_THM_SWI8, 14) /* obsolete */
+ RELOC_NUMBER (R_ARM_XPC25, 15) /* obsolete */
+ RELOC_NUMBER (R_ARM_THM_XPC22, 16) /* obsolete */
+ RELOC_NUMBER (R_ARM_TLS_DTPMOD32, 17)
+ RELOC_NUMBER (R_ARM_TLS_DTPOFF32, 18)
+ RELOC_NUMBER (R_ARM_TLS_TPOFF32, 19)
+ RELOC_NUMBER (R_ARM_COPY, 20) /* Copy symbol at runtime. */
+ RELOC_NUMBER (R_ARM_GLOB_DAT, 21) /* Create GOT entry. */
+ RELOC_NUMBER (R_ARM_JUMP_SLOT, 22) /* Create PLT entry. */
+ RELOC_NUMBER (R_ARM_RELATIVE, 23) /* Adjust by program base. */
+ RELOC_NUMBER (R_ARM_GOTOFF32, 24) /* 32 bit offset to GOT. */
+ RELOC_NUMBER (R_ARM_BASE_PREL, 25) /* 32 bit PC relative offset to GOT. */
+ RELOC_NUMBER (R_ARM_GOT_BREL, 26) /* 32 bit GOT entry. */
+ RELOC_NUMBER (R_ARM_PLT32, 27) /* deprecated - 32 bit PLT address. */
+ RELOC_NUMBER (R_ARM_CALL, 28)
+ RELOC_NUMBER (R_ARM_JUMP24, 29)
+ RELOC_NUMBER (R_ARM_THM_JUMP24, 30)
+ RELOC_NUMBER (R_ARM_BASE_ABS, 31)
+ RELOC_NUMBER (R_ARM_ALU_PCREL7_0, 32) /* obsolete */
+ RELOC_NUMBER (R_ARM_ALU_PCREL15_8, 33) /* obsolete */
+ RELOC_NUMBER (R_ARM_ALU_PCREL23_15, 34) /* obsolete */
+ RELOC_NUMBER (R_ARM_LDR_SBREL_11_0, 35) /* deprecated, should have _NC suffix */
+ RELOC_NUMBER (R_ARM_ALU_SBREL_19_12, 36) /* deprecated, should have _NC suffix */
+ RELOC_NUMBER (R_ARM_ALU_SBREL_27_20, 37) /* deprecated, should have _CK suffix */
+ RELOC_NUMBER (R_ARM_TARGET1, 38)
+ RELOC_NUMBER (R_ARM_SBREL31, 39) /* deprecated */
+ RELOC_NUMBER (R_ARM_V4BX, 40)
+ RELOC_NUMBER (R_ARM_TARGET2, 41)
+ RELOC_NUMBER (R_ARM_PREL31, 42)
+ RELOC_NUMBER (R_ARM_MOVW_ABS_NC, 43)
+ RELOC_NUMBER (R_ARM_MOVT_ABS, 44)
+ RELOC_NUMBER (R_ARM_MOVW_PREL_NC, 45)
+ RELOC_NUMBER (R_ARM_MOVT_PREL, 46)
+ RELOC_NUMBER (R_ARM_THM_MOVW_ABS_NC, 47)
+ RELOC_NUMBER (R_ARM_THM_MOVT_ABS, 48)
+ RELOC_NUMBER (R_ARM_THM_MOVW_PREL_NC, 49)
+ RELOC_NUMBER (R_ARM_THM_MOVT_PREL, 50)
+ RELOC_NUMBER (R_ARM_THM_JUMP19, 51)
+ RELOC_NUMBER (R_ARM_THM_JUMP6, 52)
+ RELOC_NUMBER (R_ARM_THM_ALU_PREL_11_0, 53)
+ RELOC_NUMBER (R_ARM_THM_PC12, 54)
+ RELOC_NUMBER (R_ARM_ABS32_NOI, 55)
+ RELOC_NUMBER (R_ARM_REL32_NOI, 56)
+ RELOC_NUMBER (R_ARM_ALU_PC_G0_NC, 57)
+ RELOC_NUMBER (R_ARM_ALU_PC_G0, 58)
+ RELOC_NUMBER (R_ARM_ALU_PC_G1_NC, 59)
+ RELOC_NUMBER (R_ARM_ALU_PC_G1, 60)
+ RELOC_NUMBER (R_ARM_ALU_PC_G2, 61)
+ RELOC_NUMBER (R_ARM_LDR_PC_G1, 62)
+ RELOC_NUMBER (R_ARM_LDR_PC_G2, 63)
+ RELOC_NUMBER (R_ARM_LDRS_PC_G0, 64)
+ RELOC_NUMBER (R_ARM_LDRS_PC_G1, 65)
+ RELOC_NUMBER (R_ARM_LDRS_PC_G2, 66)
+ RELOC_NUMBER (R_ARM_LDC_PC_G0, 67)
+ RELOC_NUMBER (R_ARM_LDC_PC_G1, 68)
+ RELOC_NUMBER (R_ARM_LDC_PC_G2, 69)
+ RELOC_NUMBER (R_ARM_ALU_SB_G0_NC, 70)
+ RELOC_NUMBER (R_ARM_ALU_SB_G0, 71)
+ RELOC_NUMBER (R_ARM_ALU_SB_G1_NC, 72)
+ RELOC_NUMBER (R_ARM_ALU_SB_G1, 73)
+ RELOC_NUMBER (R_ARM_ALU_SB_G2, 74)
+ RELOC_NUMBER (R_ARM_LDR_SB_G0, 75)
+ RELOC_NUMBER (R_ARM_LDR_SB_G1, 76)
+ RELOC_NUMBER (R_ARM_LDR_SB_G2, 77)
+ RELOC_NUMBER (R_ARM_LDRS_SB_G0, 78)
+ RELOC_NUMBER (R_ARM_LDRS_SB_G1, 79)
+ RELOC_NUMBER (R_ARM_LDRS_SB_G2, 80)
+ RELOC_NUMBER (R_ARM_LDC_SB_G0, 81)
+ RELOC_NUMBER (R_ARM_LDC_SB_G1, 82)
+ RELOC_NUMBER (R_ARM_LDC_SB_G2, 83)
+ RELOC_NUMBER (R_ARM_MOVW_BREL_NC, 84)
+ RELOC_NUMBER (R_ARM_MOVT_BREL, 85)
+ RELOC_NUMBER (R_ARM_MOVW_BREL, 86)
+ RELOC_NUMBER (R_ARM_THM_MOVW_BREL_NC, 87)
+ RELOC_NUMBER (R_ARM_THM_MOVT_BREL, 88)
+ RELOC_NUMBER (R_ARM_THM_MOVW_BREL, 89)
+ /* 90-93 unallocated */
+ RELOC_NUMBER (R_ARM_PLT32_ABS, 94)
+ RELOC_NUMBER (R_ARM_GOT_ABS, 95)
+ RELOC_NUMBER (R_ARM_GOT_PREL, 96)
+ RELOC_NUMBER (R_ARM_GOT_BREL12, 97)
+ RELOC_NUMBER (R_ARM_GOTOFF12, 98)
+ RELOC_NUMBER (R_ARM_GOTRELAX, 99)
+ RELOC_NUMBER (R_ARM_GNU_VTENTRY, 100) /* deprecated - old C++ abi */
+ RELOC_NUMBER (R_ARM_GNU_VTINHERIT, 101) /* deprecated - old C++ abi */
+ RELOC_NUMBER (R_ARM_THM_JUMP11, 102)
+ RELOC_NUMBER (R_ARM_THM_JUMP8, 103)
+ RELOC_NUMBER (R_ARM_TLS_GD32, 104)
+ RELOC_NUMBER (R_ARM_TLS_LDM32, 105)
+ RELOC_NUMBER (R_ARM_TLS_LDO32, 106)
+ RELOC_NUMBER (R_ARM_TLS_IE32, 107)
+ RELOC_NUMBER (R_ARM_TLS_LE32, 108)
+ RELOC_NUMBER (R_ARM_TLS_LDO12, 109)
+ RELOC_NUMBER (R_ARM_TLS_LE12, 110)
+ RELOC_NUMBER (R_ARM_TLS_IE12GP, 111)
+ /* 112 - 127 private range */
+ RELOC_NUMBER (R_ARM_ME_TOO, 128) /* obsolete */
+
+ /* Extensions? R=read-only? */
+ RELOC_NUMBER (R_ARM_RXPC25, 249)
+ RELOC_NUMBER (R_ARM_RSBREL32, 250)
+ RELOC_NUMBER (R_ARM_THM_RPC22, 251)
+ RELOC_NUMBER (R_ARM_RREL32, 252)
+ RELOC_NUMBER (R_ARM_RABS32, 253)
+ RELOC_NUMBER (R_ARM_RPC24, 254)
+ RELOC_NUMBER (R_ARM_RBASE, 255)
+
+ /* Unofficial names for some of the relocs. */
+ FAKE_RELOC (R_ARM_GOTOFF, R_ARM_GOTOFF32) /* 32 bit offset to GOT. */
+ FAKE_RELOC (R_ARM_THM_PC22, R_ARM_THM_CALL)
+ FAKE_RELOC (R_ARM_THM_PC11, R_ARM_THM_JUMP11)
+ FAKE_RELOC (R_ARM_THM_PC9, R_ARM_THM_JUMP8)
+
+ /* Relocs with both a different name, and (apparently) different meaning in
+ GNU usage. */
+ FAKE_RELOC (R_ARM_GOTPC, R_ARM_BASE_PREL) /* 32 bit PC relative offset to GOT. */
+ FAKE_RELOC (R_ARM_GOT32, R_ARM_GOT_BREL) /* 32 bit GOT entry. */
+ FAKE_RELOC (R_ARM_ROSEGREL32, R_ARM_SBREL31) /* ??? */
+ FAKE_RELOC (R_ARM_AMP_VCALL9, R_ARM_BREL_ADJ) /* Thumb-something. Not used. */
+
+END_RELOC_NUMBERS (R_ARM_max = 256)
+
+#ifdef BFD_ARCH_SIZE
+/* EABI object attributes. */
+
+enum
+{
+ /* 0-3 are generic. */
+ Tag_CPU_raw_name = 4,
+ Tag_CPU_name,
+ Tag_CPU_arch,
+ Tag_CPU_arch_profile,
+ Tag_ARM_ISA_use,
+ Tag_THUMB_ISA_use,
+ Tag_VFP_arch,
+ Tag_WMMX_arch,
+ Tag_NEON_arch,
+ Tag_PCS_config,
+ Tag_ABI_PCS_R9_use,
+ Tag_ABI_PCS_RW_data,
+ Tag_ABI_PCS_RO_data,
+ Tag_ABI_PCS_GOT_use,
+ Tag_ABI_PCS_wchar_t,
+ Tag_ABI_FP_rounding,
+ Tag_ABI_FP_denormal,
+ Tag_ABI_FP_exceptions,
+ Tag_ABI_FP_user_exceptions,
+ Tag_ABI_FP_number_model,
+ Tag_ABI_align8_needed,
+ Tag_ABI_align8_preserved,
+ Tag_ABI_enum_size,
+ Tag_ABI_HardFP_use,
+ Tag_ABI_VFP_args,
+ Tag_ABI_WMMX_args,
+ Tag_ABI_optimization_goals,
+ Tag_ABI_FP_optimization_goals,
+ /* 32 is generic. */
+};
+
+#endif
+
+/* The name of the note section used to identify arm variants. */
+#define ARM_NOTE_SECTION ".note.gnu.arm.ident"
+
+/* Special section names. */
+#define ELF_STRING_ARM_unwind ".ARM.exidx"
+#define ELF_STRING_ARM_unwind_info ".ARM.extab"
+#define ELF_STRING_ARM_unwind_once ".gnu.linkonce.armexidx."
+#define ELF_STRING_ARM_unwind_info_once ".gnu.linkonce.armextab."
+
+#endif /* _TOOLCHAIN_NXFLAT_THUMB2_ARCH_H */
diff --git a/misc/buildroot/toolchain/nxflat/thumb2/disthumb2.c b/misc/buildroot/toolchain/nxflat/thumb2/disthumb2.c
new file mode 100644
index 000000000..811c3a867
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/thumb2/disthumb2.c
@@ -0,0 +1,16 @@
+/***********************************************************************
+ * toolchain/nxflat/thumb2/disasm.c
+ * ARM Thumb2 Disassembler
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ ***********************************************************************/
+
+#include <stdio.h>
+#include <sys/types.h>
+
+int print_insn_arm(u_int32_t pc, FILE *stream, u_int32_t given)
+{
+ return -1;
+}
diff --git a/misc/buildroot/toolchain/nxflat/thumb2/dyncall_skeleton.def b/misc/buildroot/toolchain/nxflat/thumb2/dyncall_skeleton.def
new file mode 100644
index 000000000..865536c50
--- /dev/null
+++ b/misc/buildroot/toolchain/nxflat/thumb2/dyncall_skeleton.def
@@ -0,0 +1,222 @@
+/***********************************************************************
+ * toolchain/nxflat/thumb2/dyncall_skeleton.def
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************************************/
+
+/*******************************************************************
+ * File Prologue
+ *******************************************************************/
+
+static const char file_prologue[] =
+ "/*******************************************************************\n"
+ " *\n"
+ " * This file contains the dynamic call logic that performs the thunk\n"
+ " * for outound calls from one module to another.\n"
+ " *\n"
+ " * ARM register quick reference:\n"
+ " *\n"
+ " * Name Number ARM Procedure Calling Standard Role\n"
+ " *\n"
+ " * a1 r0 argument 1/integer result/scratch register/argc\n"
+ " * a2 r1 argument 2/scratch register/argv\n"
+ " * a3 r2 argument 3/scratch register/envp\n"
+ " * a4 r3 argument 4/scratch register\n"
+ " * v1 r4 register variable\n"
+ " * v2 r5 register variable\n"
+ " * v3 r6 register variable\n"
+ " * v4 r7 register variable\n"
+ " * v5 r8 register variable\n"
+ " * sb/v6 r9 static base/register variable\n"
+ " * sl/v7 r10 stack limit/stack chunk handle/reg. variable\n"
+ " * fp r11 frame pointer\n"
+ " * ip r12 scratch register/new-sb in inter-link-unit calls\n"
+ " * sp r13 lower end of current stack frame\n"
+ " * lr r14 link address/scratch register\n"
+ " * pc r15 program counter\n"
+ " *******************************************************************/\n\n"
+ "\t.syntax\tunified\n"
+ "\t.thumb\n\n"
+ "/*******************************************************************\n"
+ " * Included Files\n"
+ " *******************************************************************/\n\n"
+ "/*******************************************************************\n"
+ " * Definitions\n"
+ " *******************************************************************/\n";
+
+static const char import_prologue[] = "";
+
+/*******************************************************************
+ * Import Function Name String Table
+ *******************************************************************/
+
+static const char import_name_strtab_prologue[] =
+ "\n/*******************************************************************\n"
+ " * Import Function Names\n"
+ " *******************************************************************/\n\n"
+ "/* These are the names of all of the functions that are imported.\n"
+ " * Notice that all data associated with the library names is retained\n"
+ " * in the .text section."
+ " */\n\n"
+ "\t.text\n"
+ "\t.align\t0\n";
+
+#define MKIMPSTRTABARG(fn,i) (i), (i), (i), (fn), (i), (i)
+
+static const char import_name_strtab_format[] =
+ "\n\t.local\t__dynimport%04d\n"
+ "\t.type\t__dynimport%04d, object\n\n"
+ "__dynimport%04d:\n"
+ "\t.asciz\t\"%s\"\n"
+ "\t.size\t__dynimport%04d, .-__dynimport%04d\n";
+
+/*******************************************************************
+ * Dyanamic Call Information
+ *******************************************************************/
+
+static const char dynimport_decl_prologue[] =
+ "\n/*******************************************************************\n"
+ " * Imported Symbol Table (an array of type struct flat_import)\n"
+ " *******************************************************************/\n\n"
+ "/* Notice that, unlike most other arrays in this file, this array\n"
+ " * is declared to reside in .data. Because of this, there will be\n"
+ " * per-process instances of this table.\n"
+ " */\n\n"
+ "\t.data\n"
+ "\t.align\t2\n\n"
+ "\t.global\t__dynimport_begin\n"
+ "\t.type\t__dynimport_begin, object\n"
+ "\t.global\t__dynimport_end\n"
+ "\t.type\t__dynimport_end, object\n\n";
+
+#define MKINFODECLARGS(fn, i) (i), (fn), (i)
+
+static const char dynimport_decl_format[] =
+ "\t.local\t__dyninfo%04d\t/* Dynamic info for imported symbol %s */\n"
+ "\t.type\t__dyninfo%04d, object\n";
+
+static const char dynimport_array_prologue[] =
+ "\n__dynimport_begin:\n";
+
+#define MKINFOARGS(fn, i) (i), (fn), (i), (i), (i)
+
+static const char dynimport_array_format[] =
+ "__dyninfo%04d:\t\t\t/* Dynamic info for imported symbol %s */\n"
+ "\t.word\t__dynimport%04d\t/* Offset to name of imported function */\n"
+ "\t.word\t0\t\t/* Resolved address of imported function */\n"
+ "\t.size\t__dyninfo%04d, .-__dyninfo%04d\n";
+
+static const char dynimport_array_epilogue[] =
+ "__dynimport_end:\n"
+ "\t.size\t__dynimport_begin, __dynimport_end-__dynimport_begin\n";
+
+static const char dyncall_decl_prologue[] =
+ "\n/*******************************************************************\n"
+ " * Dynamic Call Logic\n"
+ " *******************************************************************/\n\n"
+ "\t.text\n"
+ "\t.align\t2\n";
+
+#define MKCALLARGS(fn, i) (fn), (fn), (fn), (fn), (i), (i), (i), (fn), (fn)
+
+#ifndef __NO_GOT__
+
+static const char dyncall_format[] =
+ "\n/* Dynamic call logic for imported symbol %s */\n\n"
+ "\t.global\t%s\n"
+ "\t.type\t%s, function\n"
+ "\t.thumb_func\n\n"
+ "%s:\n"
+ "\tldr\tip,.Ldyn%04d\n"
+ "\tadd\tip,ip,sl\n"
+ "\tldr\tip,[ip,#4]\n"
+ "\tbx\tip\n"
+ ".Ldyn%04d:\n"
+ "\t.word\t__dyninfo%04d(GOTOFF)\n"
+ "\t.size\t%s, .-%s\n";
+
+static const char nonreturning_dyncall_format[] =
+ "\n/* Dynamic call logic for imported, non-returning symbol %s */\n\n"
+ "\t.global\t%s\n"
+ "\t.type\t%s, function\n"
+ "\t.thumb_func\n\n"
+ "%s:\n"
+ "\tldr\tip,.Ldyn%04d\n"
+ "\tadd\tip,ip,sl\n"
+ "\tldr\tip,[ip,#4]\n"
+ "\tbx\tip\n"
+ ".Ldyn%04d:\n"
+ "\t.word\t__dyninfo%04d(GOTOFF)\n"
+ "\t.size\t%s, .-%s\n";
+
+#else
+
+static const char dyncall_format[] =
+ "\n/* Dynamic call logic for imported symbol %s */\n\n"
+ "\t.global\t%s\n"
+ "\t.type\t%s, function\n"
+ "\t.thumb_func\n\n"
+ "%s:\n"
+ "\tldr\tip,.Ldyn%04d\n"
+ "\tadd\tip,ip,sl\n"
+ "\tldr\tip,[ip,#4]\n"
+ "\tbx\tip\n"
+ ".Ldyn%04d:\n"
+ "\t.word\t__dyninfo%04d\n"
+ "\t.size\t%s, .-%s\n";
+
+static const char nonreturning_dyncall_format[] =
+ "\n/* Dynamic call logic for imported, non-returning symbol %s */\n\n"
+ "\t.global\t%s\n"
+ "\t.type\t%s, function\n"
+ "\t.thumb_func\n\n"
+ "%s:\n"
+ "\tldr\tip,.Ldyn%04d\n"
+ "\tadd\tip,ip,sl\n"
+ "\tldr\tip,[ip,#4]\n"
+ "\tbx\tip\n"
+ ".Ldyn%04d:\n"
+ "\t.word\t__dyninfo%04d\n"
+ "\t.size\t%s, .-%s\n";
+
+#endif
+
+/*******************************************************************
+ * File Epilogue
+ *******************************************************************/
+
+static const char file_epilogue[] =
+ "\t.end\n";
+
+
+
+
diff --git a/misc/buildroot/toolchain/patch-kernel.sh b/misc/buildroot/toolchain/patch-kernel.sh
new file mode 100755
index 000000000..b6722cecd
--- /dev/null
+++ b/misc/buildroot/toolchain/patch-kernel.sh
@@ -0,0 +1,54 @@
+#! /bin/sh
+# A little script I whipped up to make it easy to
+# patch source trees and have sane error handling
+# -Erik
+#
+# (c) 2002 Erik Andersen <andersen@codepoet.org>
+
+# Set directories from arguments, or use defaults.
+targetdir=${1-.}
+patchdir=${2-../kernel-patches}
+shift 2
+patchpattern=${@-*}
+
+if [ ! -d "${targetdir}" ] ; then
+ echo "Aborting. '${targetdir}' is not a directory."
+ exit 1
+fi
+if [ ! -d "${patchdir}" ] ; then
+ echo "Aborting. '${patchdir}' is not a directory."
+ exit 1
+fi
+
+for i in `cd ${patchdir}; ls -d ${patchpattern} 2> /dev/null` ; do
+ case "$i" in
+ *.gz)
+ type="gzip"; uncomp="gunzip -dc"; ;;
+ *.bz)
+ type="bzip"; uncomp="bunzip -dc"; ;;
+ *.bz2)
+ type="bzip2"; uncomp="bunzip2 -dc"; ;;
+ *.zip)
+ type="zip"; uncomp="unzip -d"; ;;
+ *.Z)
+ type="compress"; uncomp="uncompress -c"; ;;
+ *)
+ type="plaintext"; uncomp="cat"; ;;
+ esac
+ echo ""
+ echo "Applying ${i} using ${type}: "
+ ${uncomp} ${patchdir}/${i} | patch -p1 -E -d ${targetdir}
+ if [ $? != 0 ] ; then
+ echo "Patch failed! Please fix $i!"
+ exit 1
+ fi
+done
+
+# Check for rejects...
+if [ "`find $targetdir/ '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ] ; then
+ echo "Aborting. Reject files found."
+ exit 1
+fi
+
+# Remove backup files
+find $targetdir/ '(' -name '*.orig' -o -name '.*.orig' ')' -exec rm -f {} \;
diff --git a/misc/buildroot/toolchain/sstrip/Config.in b/misc/buildroot/toolchain/sstrip/Config.in
new file mode 100644
index 000000000..f6fe458e2
--- /dev/null
+++ b/misc/buildroot/toolchain/sstrip/Config.in
@@ -0,0 +1,11 @@
+config BR2_PACKAGE_SSTRIP_TARGET
+ bool "Install sstrip for the target system"
+ default n
+ help
+ Maximal 'strip'ing utility.
+
+config BR2_PACKAGE_SSTRIP_HOST
+ bool "Install sstrip for the host/build system"
+ default n
+ help
+ Maximal 'strip'ing utility.
diff --git a/misc/buildroot/toolchain/sstrip/sstrip.c b/misc/buildroot/toolchain/sstrip/sstrip.c
new file mode 100644
index 000000000..1842f053c
--- /dev/null
+++ b/misc/buildroot/toolchain/sstrip/sstrip.c
@@ -0,0 +1,468 @@
+/* http://www.muppetlabs.com/~breadbox/software/elfkickers.html */
+
+/* sstrip: Copyright (C) 1999-2001 by Brian Raiter, under the GNU
+ * General Public License. No warranty. See COPYING for details.
+ *
+ * Aug 23, 2004 Hacked by Manuel Novoa III <mjn3@codepoet.org> to
+ * handle targets of different endianness and/or elf class, making
+ * it more useful in a cross-devel environment.
+ */
+
+/* ============== original README ===================
+ *
+ * sstrip is a small utility that removes the contents at the end of an
+ * ELF file that are not part of the program's memory image.
+ *
+ * Most ELF executables are built with both a program header table and a
+ * section header table. However, only the former is required in order
+ * for the OS to load, link and execute a program. sstrip attempts to
+ * extract the ELF header, the program header table, and its contents,
+ * leaving everything else in the bit bucket. It can only remove parts of
+ * the file that occur at the end, after the parts to be saved. However,
+ * this almost always includes the section header table, and occasionally
+ * a few random sections that are not used when running a program.
+ *
+ * It should be noted that the GNU bfd library is (understandably)
+ * dependent on the section header table as an index to the file's
+ * contents. Thus, an executable file that has no section header table
+ * cannot be used with gdb, objdump, or any other program based upon the
+ * bfd library, at all. In fact, the program will not even recognize the
+ * file as a valid executable. (This limitation is noted in the source
+ * code comments for bfd, and is marked "FIXME", so this may change at
+ * some future date. However, I would imagine that it is a pretty
+ * low-priority item, as executables without a section header table are
+ * rare in the extreme.) This probably also explains why strip doesn't
+ * offer the option to do this.
+ *
+ * Shared library files may also have their section header table removed.
+ * Such a library will still function; however, it will no longer be
+ * possible for a compiler to link a new program against it.
+ *
+ * As an added bonus, sstrip also tries to removes trailing zero bytes
+ * from the end of the file. (This normally cannot be done with an
+ * executable that has a section header table.)
+ *
+ * sstrip is a very simplistic program. It depends upon the common
+ * practice of putting the parts of the file that contribute to the
+ * memory image at the front, and the remaining material at the end. This
+ * permits it to discard the latter material without affecting file
+ * offsets and memory addresses in what remains. Of course, the ELF
+ * standard permits files to be organized in almost any order, so if a
+ * pathological linker decided to put its section headers at the top,
+ * sstrip would be useless on such executables.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <elf.h>
+#include <endian.h>
+#include <byteswap.h>
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+/* The name of the program.
+ */
+static char const *progname;
+
+/* The name of the current file.
+ */
+static char const *filename;
+
+
+/* A simple error-handling function. FALSE is always returned for the
+ * convenience of the caller.
+ */
+static int err(char const *errmsg)
+{
+ fprintf(stderr, "%s: %s: %s\n", progname, filename, errmsg);
+ return FALSE;
+}
+
+/* A flag to signal the need for endian reversal.
+ */
+static int do_reverse_endian;
+
+/* Get a value from the elf header, compensating for endianness.
+ */
+#define EGET(X) \
+ (__extension__ ({ \
+ uint64_t __res; \
+ if (!do_reverse_endian) { \
+ __res = (X); \
+ } else if (sizeof(X) == 1) { \
+ __res = (X); \
+ } else if (sizeof(X) == 2) { \
+ __res = bswap_16((X)); \
+ } else if (sizeof(X) == 4) { \
+ __res = bswap_32((X)); \
+ } else if (sizeof(X) == 8) { \
+ __res = bswap_64((X)); \
+ } else { \
+ fprintf(stderr, "%s: %s: EGET failed for size %d\n", \
+ progname, filename, sizeof(X)); \
+ exit(EXIT_FAILURE); \
+ } \
+ __res; \
+ }))
+
+/* Set a value 'Y' in the elf header to 'X', compensating for endianness.
+ */
+#define ESET(Y,X) \
+ do if (!do_reverse_endian) { \
+ Y = (X); \
+ } else if (sizeof(Y) == 1) { \
+ Y = (X); \
+ } else if (sizeof(Y) == 2) { \
+ Y = bswap_16((uint16_t)(X)); \
+ } else if (sizeof(Y) == 4) { \
+ Y = bswap_32((uint32_t)(X)); \
+ } else if (sizeof(Y) == 8) { \
+ Y = bswap_64((uint64_t)(X)); \
+ } else { \
+ fprintf(stderr, "%s: %s: ESET failed for size %d\n", \
+ progname, filename, sizeof(Y)); \
+ exit(EXIT_FAILURE); \
+ } while (0)
+
+
+/* A macro for I/O errors: The given error message is used only when
+ * errno is not set.
+ */
+#define ferr(msg) (err(errno ? strerror(errno) : (msg)))
+
+
+
+#define HEADER_FUNCTIONS(CLASS) \
+ \
+/* readelfheader() reads the ELF header into our global variable, and \
+ * checks to make sure that this is in fact a file that we should be \
+ * munging. \
+ */ \
+static int readelfheader ## CLASS (int fd, Elf ## CLASS ## _Ehdr *ehdr) \
+{ \
+ if (read(fd, ((char *)ehdr)+EI_NIDENT, sizeof(*ehdr) - EI_NIDENT) \
+ != sizeof(*ehdr) - EI_NIDENT) \
+ return ferr("missing or incomplete ELF header."); \
+ \
+ /* Verify the sizes of the ELF header and the program segment \
+ * header table entries. \
+ */ \
+ if (EGET(ehdr->e_ehsize) != sizeof(Elf ## CLASS ## _Ehdr)) \
+ return err("unrecognized ELF header size."); \
+ if (EGET(ehdr->e_phentsize) != sizeof(Elf ## CLASS ## _Phdr)) \
+ return err("unrecognized program segment header size."); \
+ \
+ /* Finally, check the file type. \
+ */ \
+ if (EGET(ehdr->e_type) != ET_EXEC && EGET(ehdr->e_type) != ET_DYN) \
+ return err("not an executable or shared-object library."); \
+ \
+ return TRUE; \
+} \
+ \
+/* readphdrtable() loads the program segment header table into memory. \
+ */ \
+static int readphdrtable ## CLASS (int fd, Elf ## CLASS ## _Ehdr const *ehdr, \
+ Elf ## CLASS ## _Phdr **phdrs) \
+{ \
+ size_t size; \
+ \
+ if (!EGET(ehdr->e_phoff) || !EGET(ehdr->e_phnum) \
+) return err("ELF file has no program header table."); \
+ \
+ size = EGET(ehdr->e_phnum) * sizeof **phdrs; \
+ if (!(*phdrs = malloc(size))) \
+ return err("Out of memory!"); \
+ \
+ errno = 0; \
+ if (read(fd, *phdrs, size) != (ssize_t)size) \
+ return ferr("missing or incomplete program segment header table."); \
+ \
+ return TRUE; \
+} \
+ \
+/* getmemorysize() determines the offset of the last byte of the file \
+ * that is referenced by an entry in the program segment header table. \
+ * (Anything in the file after that point is not used when the program \
+ * is executing, and thus can be safely discarded.) \
+ */ \
+static int getmemorysize ## CLASS (Elf ## CLASS ## _Ehdr const *ehdr, \
+ Elf ## CLASS ## _Phdr const *phdrs, \
+ unsigned long *newsize) \
+{ \
+ Elf ## CLASS ## _Phdr const *phdr; \
+ unsigned long size, n; \
+ int i; \
+ \
+ /* Start by setting the size to include the ELF header and the \
+ * complete program segment header table. \
+ */ \
+ size = EGET(ehdr->e_phoff) + EGET(ehdr->e_phnum) * sizeof *phdrs; \
+ if (size < sizeof *ehdr) \
+ size = sizeof *ehdr; \
+ \
+ /* Then keep extending the size to include whatever data the \
+ * program segment header table references. \
+ */ \
+ for (i = 0, phdr = phdrs ; i < EGET(ehdr->e_phnum) ; ++i, ++phdr) { \
+ if (EGET(phdr->p_type) != PT_NULL) { \
+ n = EGET(phdr->p_offset) + EGET(phdr->p_filesz); \
+ if (n > size) \
+ size = n; \
+ } \
+ } \
+ \
+ *newsize = size; \
+ return TRUE; \
+} \
+ \
+/* modifyheaders() removes references to the section header table if \
+ * it was stripped, and reduces program header table entries that \
+ * included truncated bytes at the end of the file. \
+ */ \
+static int modifyheaders ## CLASS (Elf ## CLASS ## _Ehdr *ehdr, \
+ Elf ## CLASS ## _Phdr *phdrs, \
+ unsigned long newsize) \
+{ \
+ Elf ## CLASS ## _Phdr *phdr; \
+ int i; \
+ \
+ /* If the section header table is gone, then remove all references \
+ * to it in the ELF header. \
+ */ \
+ if (EGET(ehdr->e_shoff) >= newsize) { \
+ ESET(ehdr->e_shoff,0); \
+ ESET(ehdr->e_shnum,0); \
+ ESET(ehdr->e_shentsize,0); \
+ ESET(ehdr->e_shstrndx,0); \
+ } \
+ \
+ /* The program adjusts the file size of any segment that was \
+ * truncated. The case of a segment being completely stripped out \
+ * is handled separately. \
+ */ \
+ for (i = 0, phdr = phdrs ; i < EGET(ehdr->e_phnum) ; ++i, ++phdr) { \
+ if (EGET(phdr->p_offset) >= newsize) { \
+ ESET(phdr->p_offset,newsize); \
+ ESET(phdr->p_filesz,0); \
+ } else if (EGET(phdr->p_offset) + EGET(phdr->p_filesz) > newsize) { \
+ newsize -= EGET(phdr->p_offset); \
+ ESET(phdr->p_filesz, newsize); \
+ } \
+ } \
+ \
+ return TRUE; \
+} \
+ \
+/* commitchanges() writes the new headers back to the original file \
+ * and sets the file to its new size. \
+ */ \
+static int commitchanges ## CLASS (int fd, Elf ## CLASS ## _Ehdr const *ehdr, \
+ Elf ## CLASS ## _Phdr *phdrs, \
+ unsigned long newsize) \
+{ \
+ size_t n; \
+ \
+ /* Save the changes to the ELF header, if any. \
+ */ \
+ if (lseek(fd, 0, SEEK_SET)) \
+ return ferr("could not rewind file"); \
+ errno = 0; \
+ if (write(fd, ehdr, sizeof *ehdr) != sizeof *ehdr) \
+ return err("could not modify file"); \
+ \
+ /* Save the changes to the program segment header table, if any. \
+ */ \
+ if (lseek(fd, EGET(ehdr->e_phoff), SEEK_SET) == (off_t)-1) { \
+ err("could not seek in file."); \
+ goto warning; \
+ } \
+ n = EGET(ehdr->e_phnum) * sizeof *phdrs; \
+ if (write(fd, phdrs, n) != (ssize_t)n) { \
+ err("could not write to file"); \
+ goto warning; \
+ } \
+ \
+ /* Eleventh-hour sanity check: don't truncate before the end of \
+ * the program segment header table. \
+ */ \
+ if (newsize < EGET(ehdr->e_phoff) + n) \
+ newsize = EGET(ehdr->e_phoff) + n; \
+ \
+ /* Chop off the end of the file. \
+ */ \
+ if (ftruncate(fd, newsize)) { \
+ err("could not resize file"); \
+ goto warning; \
+ } \
+ \
+ return TRUE; \
+ \
+ warning: \
+ return err("ELF file may have been corrupted!"); \
+}
+
+
+/* First elements of Elf32_Ehdr and Elf64_Ehdr are common.
+ */
+static int readelfheaderident(int fd, Elf32_Ehdr *ehdr)
+{
+ errno = 0;
+ if (read(fd, ehdr, EI_NIDENT) != EI_NIDENT)
+ return ferr("missing or incomplete ELF header.");
+
+ /* Check the ELF signature.
+ */
+ if (!(ehdr->e_ident[EI_MAG0] == ELFMAG0 &&
+ ehdr->e_ident[EI_MAG1] == ELFMAG1 &&
+ ehdr->e_ident[EI_MAG2] == ELFMAG2 &&
+ ehdr->e_ident[EI_MAG3] == ELFMAG3))
+ {
+ err("missing ELF signature.");
+ return -1;
+ }
+
+ /* Compare the file's class and endianness with the program's.
+ */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
+ do_reverse_endian = 0;
+ } else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
+/* fprintf(stderr, "ELF file has different endianness.\n"); */
+ do_reverse_endian = 1;
+ }
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
+/* fprintf(stderr, "ELF file has different endianness.\n"); */
+ do_reverse_endian = 1;
+ } else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
+ do_reverse_endian = 0;
+ }
+#else
+#error unkown endianness
+#endif
+ else {
+ err("Unsupported endianness");
+ return -1;
+ }
+
+ /* Check the target architecture.
+ */
+/* if (EGET(ehdr->e_machine) != ELF_ARCH) { */
+/* /\* return err("ELF file created for different architecture."); *\/ */
+/* fprintf(stderr, "ELF file created for different architecture.\n"); */
+/* } */
+ return ehdr->e_ident[EI_CLASS];
+}
+
+
+HEADER_FUNCTIONS(32)
+
+HEADER_FUNCTIONS(64)
+
+/* truncatezeros() examines the bytes at the end of the file's
+ * size-to-be, and reduces the size to exclude any trailing zero
+ * bytes.
+ */
+static int truncatezeros(int fd, unsigned long *newsize)
+{
+ unsigned char contents[1024];
+ unsigned long size, n;
+
+ size = *newsize;
+ do {
+ n = sizeof contents;
+ if (n > size)
+ n = size;
+ if (lseek(fd, size - n, SEEK_SET) == (off_t)-1)
+ return ferr("cannot seek in file.");
+ if (read(fd, contents, n) != (ssize_t)n)
+ return ferr("cannot read file contents");
+ while (n && !contents[--n])
+ --size;
+ } while (size && !n);
+
+ /* Sanity check.
+ */
+ if (!size)
+ return err("ELF file is completely blank!");
+
+ *newsize = size;
+ return TRUE;
+}
+
+/* main() loops over the cmdline arguments, leaving all the real work
+ * to the other functions.
+ */
+int main(int argc, char *argv[])
+{
+ int fd;
+ union {
+ Elf32_Ehdr ehdr32;
+ Elf64_Ehdr ehdr64;
+ } e;
+ union {
+ Elf32_Phdr *phdrs32;
+ Elf64_Phdr *phdrs64;
+ } p;
+ unsigned long newsize;
+ char **arg;
+ int failures = 0;
+
+ if (argc < 2 || argv[1][0] == '-') {
+ printf("Usage: sstrip FILE...\n"
+ "sstrip discards all nonessential bytes from an executable.\n\n"
+ "Version 2.0-X Copyright (C) 2000,2001 Brian Raiter.\n"
+ "Cross-devel hacks Copyright (C) 2004 Manuel Novoa III.\n"
+ "This program is free software, licensed under the GNU\n"
+ "General Public License. There is absolutely no warranty.\n");
+ return EXIT_SUCCESS;
+ }
+
+ progname = argv[0];
+
+ for (arg = argv + 1 ; *arg != NULL ; ++arg) {
+ filename = *arg;
+
+ fd = open(*arg, O_RDWR);
+ if (fd < 0) {
+ ferr("can't open");
+ ++failures;
+ continue;
+ }
+
+ switch (readelfheaderident(fd, &e.ehdr32)) {
+ case ELFCLASS32:
+ if (!(readelfheader32(fd, &e.ehdr32) &&
+ readphdrtable32(fd, &e.ehdr32, &p.phdrs32) &&
+ getmemorysize32(&e.ehdr32, p.phdrs32, &newsize) &&
+ truncatezeros(fd, &newsize) &&
+ modifyheaders32(&e.ehdr32, p.phdrs32, newsize) &&
+ commitchanges32(fd, &e.ehdr32, p.phdrs32, newsize)))
+ ++failures;
+ break;
+ case ELFCLASS64:
+ if (!(readelfheader64(fd, &e.ehdr64) &&
+ readphdrtable64(fd, &e.ehdr64, &p.phdrs64) &&
+ getmemorysize64(&e.ehdr64, p.phdrs64, &newsize) &&
+ truncatezeros(fd, &newsize) &&
+ modifyheaders64(&e.ehdr64, p.phdrs64, newsize) &&
+ commitchanges64(fd, &e.ehdr64, p.phdrs64, newsize)))
+ ++failures;
+ break;
+ default:
+ ++failures;
+ break;
+ }
+ close(fd);
+ }
+
+ return failures ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/misc/buildroot/toolchain/sstrip/sstrip.mk b/misc/buildroot/toolchain/sstrip/sstrip.mk
new file mode 100644
index 000000000..d18853118
--- /dev/null
+++ b/misc/buildroot/toolchain/sstrip/sstrip.mk
@@ -0,0 +1,69 @@
+######################################################################
+#
+# sstrip
+#
+######################################################################
+
+SSTRIP_SOURCE_FILE:=$(TOPDIR)/toolchain/sstrip/sstrip.c
+
+######################################################################
+#
+# sstrip host
+#
+######################################################################
+
+SSTRIP_HOST:=$(STAGING_DIR)/bin/$(REAL_GNU_TARGET_NAME)-sstrip
+
+$(SSTRIP_HOST): $(SSTRIP_SOURCE_FILE)
+ ln -snf ../../bin/$(REAL_GNU_TARGET_NAME)-sstrip \
+ $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/bin/sstrip
+ ln -snf $(REAL_GNU_TARGET_NAME)-sstrip \
+ $(STAGING_DIR)/bin/$(GNU_TARGET_NAME)-sstrip
+ $(HOSTCC) $(SSTRIP_SOURCE_FILE) -o $(SSTRIP_HOST)
+
+sstrip_host: $(SSTRIP_HOST)
+
+sstrip_host-source: $(SSTRIP_SOURCE_FILE)
+
+sstrip_host-clean:
+ rm -f $(SSTRIP_HOST)
+ rm -f $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/bin/sstrip
+ rm -f $(STAGING_DIR)/bin/$(GNU_TARGET_NAME)-sstrip
+
+sstrip_host-dirclean:
+ true
+
+######################################################################
+#
+# sstrip target
+#
+######################################################################
+
+SSTRIP_TARGET:=$(TARGET_DIR)/usr/bin/sstrip
+
+$(SSTRIP_TARGET): $(SSTRIP_SOURCE_FILE)
+ $(TARGET_CC) $(TARGET_CFLAGS) $(SSTRIP_SOURCE_FILE) -o $(SSTRIP_TARGET)
+
+sstrip_target: $(SSTRIP_TARGET)
+
+sstrip_target-source: $(SSTRIP_SOURCE_FILE)
+
+sstrip_target-clean:
+ rm -f $(SSTRIP_TARGET)
+
+sstrip_target-dirclean:
+ true
+
+#############################################################
+#
+# Toplevel Makefile options
+#
+#############################################################
+
+ifeq ($(strip $(BR2_PACKAGE_SSTRIP_HOST)),y)
+TARGETS+=sstrip_host
+endif
+
+ifeq ($(strip $(BR2_PACKAGE_SSTRIP_TARGET)),y)
+TARGETS+=sstrip_target
+endif
diff --git a/misc/buildroot/zipme.sh b/misc/buildroot/zipme.sh
new file mode 100755
index 000000000..32d8b5d71
--- /dev/null
+++ b/misc/buildroot/zipme.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+#set -x
+
+WD=`pwd`
+VERSION=$1
+
+TAR="tar cvf"
+ZIP=gzip
+
+# Make sure we know what is going on
+
+if [ -z ${VERSION} ] ; then
+ echo "You must supply a version like xx.yy.zz as a parameter"
+ exit 1;
+fi
+
+# Find the directory we were executed from and where we expect to
+# see the directory to tar up
+
+MYNAME=`basename $0`
+BRNAME=buildroot-${VERSION}
+
+if [ -x ${WD}/${MYNAME} ] ; then
+ MISCDIR=`dirname ${WD}`
+else
+ if [ -x ${WD}/${BRNAME}/${MYNAME} ] ; then
+ MISCDIR=${WD}
+ else
+ echo "You must cd into the misc/ or misc/${BRNAME}/ directory to execute this script."
+ exit 1
+ fi
+fi
+
+# Get the path to the parent directory
+
+SUBDIR=`basename ${MISCDIR}`/${BRNAME}
+PARENT=`dirname ${MISCDIR}`
+
+# The name of the directory must match the version number
+
+cd ${PARENT} || \
+ { echo "Failed to cd to ${PARENT}" ; exit 1 ; }
+
+if [ ! -d ${SUBDIR} ] ; then
+ echo "${PARENT}/${SUBDIR} does not exist!"
+ exit 1
+fi
+
+TAR_NAME=${BRNAME}.tar
+ZIP_NAME=${TAR_NAME}.gz
+
+# Prepare the buildroot directory -- Remove editor garbage
+
+find ${SUBDIR} -name '*~' -exec rm -f '{}' ';' || \
+ { echo "Removal of emacs garbage failed!" ; exit 1 ; }
+find ${SUBDIR} -name '*.swp' -exec rm -f '{}' ';' || \
+ { echo "Removal of VI garbage failed!" ; exit 1 ; }
+
+# Remove any previous tarballs
+
+if [ -f ${TAR_NAME} ] ; then
+ echo "Removing ${TAR_NAME}"
+ rm -f ${TAR_NAME} || \
+ { echo "rm ${TAR_NAME} failed!" ; exit 1 ; }
+fi
+
+if [ -f ${ZIP_NAME} ] ; then
+ echo "Removing ${ZIP_NAME}"
+ rm -f ${ZIP_NAME} || \
+ { echo "rm ${ZIP_NAME} failed!" ; exit 1 ; }
+fi
+
+# Then zip it
+
+${TAR} ${TAR_NAME} ${SUBDIR} || \
+ { echo "tar of ${TAR_NAME} failed!" ; exit 1 ; }
+${ZIP} ${TAR_NAME} || \
+ { echo "zip of ${TAR_NAME} failed!" ; exit 1 ; }
+
+cd ${WD}
diff --git a/misc/drivers/INSTALL.sh b/misc/drivers/INSTALL.sh
new file mode 100755
index 000000000..d918c0dd4
--- /dev/null
+++ b/misc/drivers/INSTALL.sh
@@ -0,0 +1,101 @@
+############################################################################
+# misc/divers/INSTALL.sh
+# Install ALL optional drivers into the NuttX source tree
+#
+# Copyright (C) 2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+# Directory list
+
+DRIVERS="rtl8187x"
+
+# Parse command arguments
+
+wd=`pwd`
+usage="USAGE: $0 [-d|h] <NuttX-path>"
+
+unset nuttxdir
+unset debug
+unset force
+
+while [ ! -z "$1" ]; do
+ case "$1" in
+ -d )
+ set -x
+ debug="-d"
+ ;;
+ -f )
+ force="-f"
+ ;;
+ -h )
+ echo "$usage"
+ exit 0
+ ;;
+ *)
+ nuttxdir=$1
+ ;;
+ esac
+ shift
+done
+
+# Sanity checking
+
+if [ -z "${nuttxdir}" ]; then
+ echo "Path to the top-level NuttX directory not provided"
+ echo "$usage"
+ exit 1
+fi
+
+if [ ! -d ${nuttxdir} ]; then
+ echo "NuttX directory ${nuttxdir} does not exist"
+ exit 2
+fi
+
+# Then install each driver
+
+for dir in "$DRIVERS"; do
+
+ # More sanity checking
+
+ if [ ! -d ${dir} ]; then
+ echo "No sub-directory ${dir} under ${wd}. Please CD into the drivers directory first"
+ exit 3
+ fi
+ if [ ! -x ${dir}/INSTALL.sh ]; then
+ echo "No executable INSTALL.sh script in ${wd}/${dir}"
+ exit 3
+ fi
+
+ # Run the driver install script
+
+ ${dir}/INSTALL.sh $debug $force -t "${wd}/${dir}" -n "${nuttxdir}"
+done
diff --git a/misc/drivers/rtl8187x/INSTALL.sh b/misc/drivers/rtl8187x/INSTALL.sh
new file mode 100755
index 000000000..839fb7768
--- /dev/null
+++ b/misc/drivers/rtl8187x/INSTALL.sh
@@ -0,0 +1,134 @@
+############################################################################
+# nuttx/rtl8187x/INSTALL.sh
+# Install the GPLv2 RTL8187x driver into the NuttX source tree
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+# List of files to install and where to install them
+
+files="\
+rtl8187x.c
+rtl8187x.h
+"
+dest="drivers/usbhost"
+
+# Parse command arguments
+
+usage="USAGE: $0 [-d|f|h] -t <driver-dir> -n <nuttx-dir>"
+
+unset topdir
+unset nuttxdir
+unset force
+
+while [ ! -z "$1" ]; do
+ case "$1" in
+ -d )
+ set -x
+ ;;
+ -f )
+ force=y
+ ;;
+ -t )
+ shift
+ topdir=$1
+ ;;
+ -n )
+ shift
+ nuttxdir=$1
+ ;;
+ -h )
+ echo "$usage"
+ exit 0
+ ;;
+ *)
+ echo "Unrecognized option: $1"
+ echo "$usage"
+ exit 1
+ ;;
+ esac
+ shift
+done
+
+# Sanity checking
+
+if [ -z "${nuttxdir}" ]; then
+ echo "Path to the top-level NuttX directory not provided"
+ echo "$usage"
+ exit 2
+fi
+
+if [ -z "${topdir}" ]; then
+ echo "Path to the top-level misc/drivers directory not provided"
+ echo "$usage"
+ exit 3
+fi
+
+if [ ! -d ${nuttxdir} ]; then
+ echo "NuttX directory ${nuttxdir} does not exist"
+ exit 4
+fi
+
+if [ ! -d ${topdir} ]; then
+ echo "misc/drivers directory ${topdir} does not exist"
+ exit 5
+fi
+
+if [ ! -d ${nuttxdir}/${dest} ]; then
+ echo "NuttX driver directory ${nuttxdir}/${dest} does not exist"
+ exit 6
+fi
+
+echo "Installing the RTL8187x driver to ${nuttxdir}/${dest}"
+
+# Copy the files
+
+for file in ${files}; do
+ if [ ! -r ${topdir}/${file} ]; then
+ echo "No readable source driver file ${topdir}/${file}"
+ exit 7
+ fi
+ if [ -f ${nuttxdir}/${dest}/${file} ]; then
+ echo "Driver file ${nuttxdir}/${dest}/${file} already exists"
+ if [ "X${force}" = "Xy" ]; then
+ echo "Removing old file ${nuttxdir}/${dest}/${file}"
+ rm -f ${nuttxdir}/${dest}/${file} || \
+ { echo "ERROR: failed to remove ${nuttxdir}/${dest}/${file}"; exit 8; }
+ else
+ echo "Please remove that file and re-start the installation"
+ echo "Or use the -f option to force over writing of the file"
+ exit 8
+ fi
+ fi
+ cp ${topdir}/${file} ${nuttxdir}/${dest}/${file} || \
+ { echo "ERROR: failed to copy ${topdir}/${file} to ${nuttxdir}/${dest}/${file}"; exit 9; }
+done
diff --git a/misc/drivers/rtl8187x/rtl8187x.c b/misc/drivers/rtl8187x/rtl8187x.c
new file mode 100644
index 000000000..d8fe14740
--- /dev/null
+++ b/misc/drivers/rtl8187x/rtl8187x.c
@@ -0,0 +1,4213 @@
+/****************************************************************************
+ * drivers/usbhost/rtl8187.c
+ *
+ * Copyright (C) 2011, 2012 Gregory Nutt. All rights reserved.
+ * Authors: Rafael Noronha <rafael@pdsolucoes.com.br>
+ * Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Portions of the logic in this file derives from the KisMAC RTL8187x driver
+ *
+ * Created by pr0gg3d on 02/24/08.
+ *
+ * Which, in turn, came frm the SourceForge rt2x00 project:
+ *
+ * Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
+ * <http://rt2x00.serialmonkey.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * There are probably also pieces from the Linux RTL8187x driver
+ *
+ * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
+ * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Based on the r8187 driver, which is:
+ * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <semaphore.h>
+#include <time.h>
+#include <wdog.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/clock.h>
+#include <nuttx/arch.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/irq.h>
+
+#include <nuttx/usb/usb.h>
+#include <nuttx/usb/usbhost.h>
+
+#include <nuttx/net/uip/uip.h>
+#include <nuttx/net/uip/uip-arp.h>
+#include <nuttx/net/uip/uip-arch.h>
+
+#include "rtl8187x.h"
+
+#if defined(CONFIG_USBHOST) && defined(CONFIG_NET) && defined(CONFIG_NET_WLAN)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_NET_NOINTS
+# warning "CONFIG_NET_NOINTS must be set"
+#endif
+
+#ifndef CONFIG_NET_MULTIBUFFER
+# warning "CONFIG_NET_MULTIBUFFER must be set"
+#endif
+
+#ifndef CONFIG_SCHED_WORKQUEUE
+# warning "Worker thread support is required (CONFIG_SCHED_WORKQUEUE)"
+#endif
+
+/* Driver support ***********************************************************/
+/* This format is used to construct the /dev/wlan[n] device driver path. It
+ * defined here so that it will be used consistently in all places.
+ */
+
+#define DEV_FORMAT "wlan%d"
+
+/* Used in rtl8187x_cfgdesc() */
+
+#define USBHOST_IFFOUND 0x01
+#define USBHOST_BINFOUND 0x02
+#define USBHOST_BOUTFOUND 0x04
+#define USBHOST_ALLFOUND 0x07
+
+#define USBHOST_MAX_CREFS 0x7fff
+
+/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */
+
+#define RTL8187X_TXDELAY (1*CLK_TCK)
+#define RTL8187X_RETRYDELAY (CLK_TCK/2)
+
+/* RX poll delay = 100 millseconds. */
+
+#define RTL8187X_RXDELAY (CLK_TCK / 10)
+
+/* TX timeout = 1 minute */
+
+#define RTL8187X_TXTIMEOUT (60*CLK_TCK)
+
+/* Statistics helper */
+
+#ifdef CONFIG_NET_STATISTICS
+# define RTL8187X_STATS(p,f) (p->stats.f)++
+#else
+# define RTL8187X_STATS(p,f)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Describes one IEEE 802.11 Channel */
+
+struct ieee80211_channel_s
+{
+ uint16_t chan; /* Channel number (IEEE 802.11) */
+ uint16_t freq; /* Frequency in MHz */
+ uint32_t val; /* HW specific value for the channel */
+ uint32_t flag; /* Flag for hostapd use (IEEE80211_CHAN_*) */
+ uint8_t pwrlevel;
+ uint8_t antmax;
+};
+
+/* Driver statistics */
+
+#ifdef CONFIG_NET_STATISTICS
+struct rtl8187x_statistics_s
+{
+ uint32_t transmitted; /* Number of packets transmitted */
+ uint32_t txfailed; /* - Number of failed packet transmissions */
+ uint32_t received; /* Number of packets received: */
+ uint32_t rxdropped; /* RX Dropped: */
+ uint32_t rxtoosmall; /* - Number of bad, small packets received */
+ uint32_t rxtoobig; /* - Number of bad, big packets received */
+ uint32_t rxcrcerr; /* - Number of packets received with a CRC error */
+ uint32_t rxbadproto; /* - Number of dropped packets with bad protocol */
+ /* RX Good: received - rxdropped */
+ uint32_t rxippackets; /* - Number of good IP packets */
+ uint32_t rxarppackets; /* - Number of good ARP packets */
+};
+#endif
+
+/* This structure contains the internal, private state of the USB host class
+ * driver.
+ */
+
+struct rtl8187x_state_s
+{
+ /* This is the externally visible portion of the USB class state. This must
+ * be the first thing in the structure so that 'struct rtl8187x_state_s' can
+ * be obtained from the class instance by a simple cast.
+ */
+
+ struct usbhost_class_s class;
+
+ /* This is an instance of the USB host controller driver bound to this class instance */
+
+ struct usbhost_driver_s *hcd;
+
+ /* The following fields support the USB class driver */
+
+ volatile bool disconnected; /* TRUE: Device has been disconnected */
+ bool bifup; /* TRUE: Ethernet interface is up */
+ bool silence; /* TRUE: Packets are being received */
+ uint8_t ifno; /* Interface number */
+ uint8_t asicrev; /* ASIC revision number */
+ uint8_t rate; /* RX rate parameter */
+ uint8_t width; /* EEPROM width (see PCI_EEPROM_WIDTH_* defines) */
+ uint8_t datain; /* EEPROM data input */
+ uint8_t dataout; /* EEPROM data output */
+ uint8_t dataclk; /* EEPROM data clock */
+ uint8_t chipsel; /* EEPROM chip select */
+ uint8_t signal; /* Estimated signal strength */
+ int8_t crefs; /* >0: The driver is busy and cannot be destoryed */
+ uint16_t rxpwrbase; /* RX power base */
+ uint32_t lastpoll; /* Time of last poll */
+ sem_t exclsem; /* Used to maintain mutual exclusive access */
+ struct work_s wkdisconn; /* For performing disconnect on the worker thread */
+ struct work_s wktxpoll; /* Perform TX poll on work thread */
+ struct work_s wkrxpoll; /* Perform RX poll on work thread */
+ FAR struct usb_ctrlreq_s *ctrlreq; /* The allocated request buffer */
+ FAR uint8_t *tbuffer; /* The allocated transfer buffer */
+ size_t tbuflen; /* Size of the allocated transfer buffer */
+ usbhost_ep_t epin; /* IN endpoint */
+ usbhost_ep_t epout; /* OUT endpoint */
+ WDOG_ID wdtxpoll; /* TX poll timer */
+ WDOG_ID wdrxpoll; /* RX poll timer */
+
+ /* Chip-specific function pointers */
+
+ void (*rfinit)(FAR struct rtl8187x_state_s *);
+ void (*settxpower)(FAR struct rtl8187x_state_s *priv, int channel);
+
+ /* Channel configuration */
+
+ struct ieee80211_channel_s channels[RTL8187X_NCHANNELS];
+
+ /* Statistics */
+
+#ifdef CONFIG_NET_STATISTICS
+ struct rtl8187x_statistics_s stats;
+#endif
+
+ /* This holds the information visible to uIP/NuttX */
+
+ struct uip_driver_s ethdev; /* Interface understood by uIP */
+ FAR uint8_t *txbuffer; /* The allocated TX I/O buffer */
+ FAR uint8_t *rxbuffer; /* The allocated RX I/O buffer */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* General Utility Functions ************************************************/
+/* Semaphores */
+
+static void rtl8187x_takesem(sem_t *sem);
+#define rtl8187x_givesem(s) sem_post(s);
+
+/* Memory allocation services */
+
+static inline FAR struct rtl8187x_state_s *rtl8187x_allocclass(void);
+static inline void rtl8187x_freeclass(FAR struct rtl8187x_state_s *class);
+
+/* Standard USB host class functions ****************************************/
+/* Worker thread actions */
+
+static void rtl8187x_destroy(FAR void *arg);
+
+/* Helpers for rtl8187x_connect() */
+
+static inline int rtl8187x_cfgdesc(FAR struct rtl8187x_state_s *priv,
+ FAR const uint8_t *configdesc, int desclen,
+ uint8_t funcaddr);
+static inline int rtl8187x_devinit(FAR struct rtl8187x_state_s *priv);
+
+/* (Little Endian) Data helpers */
+
+static inline uint16_t rtl8187x_host2le16(uint16_t val);
+static inline uint16_t rtl8187x_le2host16(uint16_t val);
+static inline uint32_t rtl8187x_host2le32(uint32_t val);
+static inline uint32_t rtl8187x_le2host32(uint32_t val);
+static inline uint16_t rtl8187x_getle16(const uint8_t *val);
+static inline uint32_t rtl8187x_getle32(const uint8_t *val);
+static inline void rtl8187x_putle16(uint8_t *dest, uint16_t val);
+static void rtl8187x_putle32(uint8_t *dest, uint32_t val);
+
+/* Transfer descriptor memory management */
+
+static inline int rtl8187x_allocbuffers(FAR struct rtl8187x_state_s *priv);
+static inline int rtl8187x_freebuffers(FAR struct rtl8187x_state_s *priv);
+
+/* struct usbhost_registry_s methods */
+
+static struct usbhost_class_s *rtl8187x_create(FAR struct usbhost_driver_s *hcd,
+ FAR const struct usbhost_id_s *id);
+
+/* struct usbhost_class_s methods */
+
+static int rtl8187x_connect(FAR struct usbhost_class_s *class,
+ FAR const uint8_t *configdesc, int desclen,
+ uint8_t funcaddr);
+static int rtl8187x_disconnected(FAR struct usbhost_class_s *class);
+
+/* Vendor-Specific USB host support *****************************************/
+
+static uint8_t rtl8187x_ioread8(struct rtl8187x_state_s *priv, uint16_t addr);
+static uint16_t rtl8187x_ioread16(struct rtl8187x_state_s *priv, uint16_t addr);
+static uint32_t rtl8187x_ioread32(struct rtl8187x_state_s *priv, uint16_t addr);
+
+static int rtl8187x_iowrite8(struct rtl8187x_state_s *priv, uint16_t addr,
+ uint8_t val);
+static int rtl8187x_iowrite16(struct rtl8187x_state_s *priv, uint16_t addr,
+ uint16_t val);
+static int rtl8187x_iowrite32(struct rtl8187x_state_s *priv, uint16_t addr,
+ uint32_t val);
+
+static uint16_t rtl8187x_read(FAR struct rtl8187x_state_s *priv, uint8_t addr);
+static inline void rtl8187x_write_8051(FAR struct rtl8187x_state_s *priv,
+ uint8_t addr, uint16_t data);
+static inline void rtl8187x_write_bitbang(struct rtl8187x_state_s *priv,
+ uint8_t addr, uint16_t data);
+static void rtl8187x_write(FAR struct rtl8187x_state_s *priv, uint8_t addr,
+ uint16_t data);
+
+/* Ethernet driver methods **************************************************/
+/* TX logic */
+
+static int rtl8187x_transmit(FAR struct rtl8187x_state_s *priv);
+static int rtl8187x_uiptxpoll(struct uip_driver_s *dev);
+static void rtl8187x_txpollwork(FAR void *arg);
+static void rtl8187x_txpolltimer(int argc, uint32_t arg, ...);
+
+/* RX logic */
+
+static inline int rtl8187x_receive(FAR struct rtl8187x_state_s *priv, unsigned int iolen, unsigned int *pktlen);
+static inline void rtl8187x_rxdispatch(FAR struct rtl8187x_state_s *priv, unsigned int pktlen);
+static void rtl8187x_rxpollwork(FAR void *arg);
+static void rtl8187x_rxpolltimer(int argc, uint32_t arg, ...);
+
+/* Network callback functions */
+
+static int rtl8187x_ifup(struct uip_driver_s *dev);
+static int rtl8187x_ifdown(struct uip_driver_s *dev);
+static int rtl8187x_txavail(struct uip_driver_s *dev);
+#ifdef CONFIG_NET_IGMP
+static int rtl8187x_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
+static int rtl8187x_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
+#endif
+
+/* EEPROM support */
+
+static inline void rtl8187x_eeprom_pulsehigh(FAR struct rtl8187x_state_s *priv);
+static inline void rtl8187x_eeprom_pulselow(FAR struct rtl8187x_state_s *priv);
+static void rtl8187x_eeprom_rdsetup(FAR struct rtl8187x_state_s *priv);
+static void rtl8187x_eeprom_wrsetup(FAR struct rtl8187x_state_s *priv);
+static void rtl8187x_eeprom_cleanup(FAR struct rtl8187x_state_s *priv);
+static void rtl8187x_eeprom_wrbits(FAR struct rtl8187x_state_s *priv,
+ uint16_t data, uint16_t count);
+static void rtl8187x_eeprom_rdbits(FAR struct rtl8187x_state_s *priv,
+ FAR uint16_t * data, uint16_t count);
+static void rtl8187x_eeprom_read(FAR struct rtl8187x_state_s *priv,
+ uint8_t word, uint16_t *data);
+static void rtl8187x_eeprom_multiread(FAR struct rtl8187x_state_s *priv,
+ uint8_t word, FAR uint16_t *data,
+ uint16_t nwords);
+
+/* PHY support */
+
+static void rtl8187x_wrphy(FAR struct rtl8187x_state_s *priv, uint8_t addr,
+ uint32_t data);
+static inline void rtl8187x_wrphyofdm(FAR struct rtl8187x_state_s *priv,
+ uint8_t addr, uint32_t data);
+static inline void rtl8187x_wrphycck(FAR struct rtl8187x_state_s *priv,
+ uint8_t addr, uint32_t data);
+
+/* Chip-specific RF initialization and TX power setup */
+
+static void rtl8225_rfinit(FAR struct rtl8187x_state_s *priv);
+static void rtl8225z2_rfinit(FAR struct rtl8187x_state_s *priv);
+static void rtl8225_settxpower(FAR struct rtl8187x_state_s *priv, int channel);
+static void rtl8225z2_settxpower(FAR struct rtl8187x_state_s *priv, int channel);
+
+/* RTL8187 Ethernet initialization and registration */
+
+static int rtl8187x_reset(struct rtl8187x_state_s *priv);
+static void rtl8187x_setchannel(FAR struct rtl8187x_state_s *priv, int channel);
+static int rtl8187x_start(FAR struct rtl8187x_state_s *priv);
+static void rtl8187x_stop(FAR struct rtl8187x_state_s *priv);
+static inline int rtl8187x_setup(FAR struct rtl8187x_state_s *priv);
+static int rtl8187x_netinitialize(FAR struct rtl8187x_state_s *priv);
+static int rtl8187x_netuninitialize(FAR struct rtl8187x_state_s *priv);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* This structure provides the registry entry ID informatino that will be
+ * used to associate the USB class driver to a connected USB device.
+ */
+
+static const const struct usbhost_id_s g_id[2] =
+{
+ {
+ USB_CLASS_VENDOR_SPEC, /* base */
+ 0xff, /* subclass */
+ 0xff, /* proto */
+ CONFIG_USB_WLAN_VID, /* vid */
+ CONFIG_USB_WLAN_PID /* pid */
+ },
+ {
+ 0, /* base */
+ 0, /* subclass */
+ 0, /* proto */
+ CONFIG_USB_WLAN_VID, /* vid */
+ CONFIG_USB_WLAN_PID /* pid */
+ }
+};
+
+/* This is the USB host wireless LAN class's registry entry */
+
+static struct usbhost_registry_s g_wlan =
+{
+ NULL, /* flink */
+ rtl8187x_create, /* create */
+ 2, /* nids */
+ g_id /* id[] */
+};
+
+/* This is a bitmap that is used to allocate device names /dev/wlana-z. */
+
+static uint32_t g_devinuse;
+
+/* Default values for IEEE 802.11 channels */
+
+static const struct ieee80211_channel_s g_channels[RTL8187X_NCHANNELS] =
+{
+ { 1, 2412, 0, 0, 0, 0}, { 2, 2417, 0, 0, 0, 0},
+ { 3, 2422, 0, 0, 0, 0}, { 4, 2427, 0, 0, 0, 0},
+ { 5, 2432, 0, 0, 0, 0}, { 6, 2437, 0, 0, 0, 0},
+ { 7, 2442, 0, 0, 0, 0}, { 8, 2447, 0, 0, 0, 0},
+ { 9, 2452, 0, 0, 0, 0}, {10, 2457, 0, 0, 0, 0},
+ {11, 2462, 0, 0, 0, 0}, {12, 2467, 0, 0, 0, 0},
+ {13, 2472, 0, 0, 0, 0}, {14, 2484, 0, 0, 0, 0}
+};
+
+static const uint32_t g_chanselect[RTL8187X_NCHANNELS] =
+{
+ 0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c,
+ 0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72
+};
+
+/* RTL8225-specific settings */
+
+static const uint16_t g_rtl8225bcd_rxgain[] =
+{
+ 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
+ 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
+ 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
+ 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
+ 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
+ 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
+ 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
+ 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
+ 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
+ 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
+ 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
+ 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
+};
+
+static const uint8_t g_rtl8225_agc[] =
+{
+ 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
+ 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
+ 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
+ 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
+ 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
+ 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
+ 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
+ 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
+ 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
+ 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
+ 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
+ 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
+ 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
+};
+static const uint8_t g_rtl8225_gain[] =
+{
+ 0x23, 0x88, 0x7c, 0xa5, /* -82dBm */
+ 0x23, 0x88, 0x7c, 0xb5, /* -82dBm */
+ 0x23, 0x88, 0x7c, 0xc5, /* -82dBm */
+ 0x33, 0x80, 0x79, 0xc5, /* -78dBm */
+ 0x43, 0x78, 0x76, 0xc5, /* -74dBm */
+ 0x53, 0x60, 0x73, 0xc5, /* -70dBm */
+ 0x63, 0x58, 0x70, 0xc5, /* -66dBm */
+};
+
+static const uint8_t g_rtl8225_threshold[] =
+{
+ 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
+};
+
+static const uint8_t g_rtl8225_txgaincckofdm[] =
+{
+ 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
+};
+
+static const uint8_t g_rtl8225_txpowercck[] =
+{
+ 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
+ 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
+ 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
+ 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
+ 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
+ 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
+};
+
+static const uint8_t g_rtl8225_txpowercckch14[] =
+{
+ 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
+ 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
+ 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
+};
+
+static const uint8_t g_rtl8225_txpowerofdm[] =
+{
+ 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
+};
+
+/* RTL8225z2-Specific settings */
+
+static const uint8_t g_rtl8225z2_txpowercckch14[] =
+{
+ 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
+};
+
+static const uint8_t g_rtl8225z2_txpowercck[] =
+{
+ 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
+};
+
+static const uint8_t g_rtl8225z2_txpowerofdm[] =
+{
+ 0x42, 0x00, 0x40, 0x00, 0x40
+};
+
+static const uint8_t g_rtl8225z2_txgaincckofdm[] =
+{
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
+ 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
+ 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
+};
+
+static const uint16_t g_rtl8225z2_rxgain[] =
+{
+ 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
+ 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
+ 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
+ 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
+ 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
+ 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
+ 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
+ 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
+ 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
+ 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
+ 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
+ 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
+};
+
+static const uint8_t g_rtl8225z2_gainbg[] =
+{
+ 0x23, 0x15, 0xa5, /* -82-1dBm */
+ 0x23, 0x15, 0xb5, /* -82-2dBm */
+ 0x23, 0x15, 0xc5, /* -82-3dBm */
+ 0x33, 0x15, 0xc5, /* -78dBm */
+ 0x43, 0x15, 0xc5, /* -74dBm */
+ 0x53, 0x15, 0xc5, /* -70dBm */
+ 0x63, 0x15, 0xc5 /* -66dBm */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rtl8187x_takesem
+ *
+ * Description:
+ * This is just a wrapper to handle the annoying behavior of semaphore
+ * waits that return due to the receipt of a signal.
+ *
+ ****************************************************************************/
+
+static void rtl8187x_takesem(sem_t *sem)
+{
+ /* Take the semaphore (perhaps waiting) */
+
+ while (sem_wait(sem) != 0)
+ {
+ /* The only case that an error should occr here is if the wait was
+ * awakened by a signal.
+ */
+
+ ASSERT(errno == EINTR);
+ }
+}
+
+/****************************************************************************
+ * Name: rtl8187x_allocclass
+ *
+ * Description:
+ * This is really part of the logic that implements the create() method
+ * of struct usbhost_registry_s. This function allocates memory for one
+ * new class instance.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Values:
+ * On success, this function will return a non-NULL instance of struct
+ * usbhost_class_s. NULL is returned on failure; this function will
+ * will fail only if there are insufficient resources to create another
+ * USB host class instance.
+ *
+ ****************************************************************************/
+
+static inline FAR struct rtl8187x_state_s *rtl8187x_allocclass(void)
+{
+ FAR struct rtl8187x_state_s *priv;
+
+ DEBUGASSERT(!up_interrupt_context());
+ priv = (FAR struct rtl8187x_state_s *)kmalloc(sizeof(struct rtl8187x_state_s));
+ uvdbg("Allocated: %p\n", priv);;
+ return priv;
+}
+
+/****************************************************************************
+ * Name: rtl8187x_freeclass
+ *
+ * Description:
+ * Free a class instance previously allocated by rtl8187x_allocclass().
+ *
+ * Input Parameters:
+ * class - A reference to the class instance to be freed.
+ *
+ * Returned Values:
+ * None
+ *
+ ****************************************************************************/
+
+static inline void rtl8187x_freeclass(FAR struct rtl8187x_state_s *class)
+{
+ DEBUGASSERT(class != NULL);
+
+ /* Free the class instance (calling sched_free() in case we are executing
+ * from an interrupt handler.
+ */
+
+ uvdbg("Freeing: %p\n", class);
+ kfree(class);
+}
+
+/****************************************************************************
+ * Name: rtl8187x_destroy
+ *
+ * Description:
+ * The USB device has been disconnected and the refernce count on the USB
+ * host class instance has gone to 1.. Time to destroy the USB host class
+ * instance.
+ *
+ * Input Parameters:
+ * arg - A reference to the class instance to be destroyed.
+ *
+ * Returned Values:
+ * None
+ *
+ ****************************************************************************/
+
+static void rtl8187x_destroy(FAR void *arg)
+{
+ FAR struct rtl8187x_state_s *priv = (FAR struct rtl8187x_state_s *)arg;
+
+ DEBUGASSERT(priv != NULL);
+ uvdbg("crefs: %d\n", priv->crefs);
+
+ /* Unregister WLAN network interface */
+
+ rtl8187x_netuninitialize(priv);
+
+ /* Free the endpoints */
+
+ if (priv->epout)
+ {
+ DRVR_EPFREE(priv->hcd, priv->epout);
+ }
+
+ if (priv->epin)
+ {
+ DRVR_EPFREE(priv->hcd, priv->epin);
+ }
+
+ /* Free any transfer buffers */
+
+ rtl8187x_freebuffers(priv);
+
+ /* Destroy the semaphores */
+
+ sem_destroy(&priv->exclsem);
+
+ /* Disconnect the USB host device */
+
+ DRVR_DISCONNECT(priv->hcd);
+
+ /* And free the class instance. Hmmm.. this may execute on the worker
+ * thread and the work structure is part of what is getting freed. That
+ * should be okay because once the work contained is removed from the
+ * queue, it should not longer be accessed by the worker thread.
+ */
+
+ rtl8187x_freeclass(priv);
+}
+
+/****************************************************************************
+ * Name: rtl8187x_cfgdesc
+ *
+ * Description:
+ * This function implements the connect() method of struct
+ * usbhost_class_s. This method is a callback into the class
+ * implementation. It is used to provide the device's configuration
+ * descriptor to the class so that the class may initialize properly
+ *
+ * Input Parameters:
+ * priv - The USB host class instance.
+ * configdesc - A pointer to a uint8_t buffer container the configuration descripor.
+ * desclen - The length in bytes of the configuration descriptor.
+ * funcaddr - The USB address of the function containing the endpoint that EP0
+ * controls
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * This function will *not* be called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static inline int rtl8187x_cfgdesc(FAR struct rtl8187x_state_s *priv,
+ FAR const uint8_t *configdesc, int desclen,
+ uint8_t funcaddr)
+{
+ FAR struct usb_cfgdesc_s *cfgdesc;
+ FAR struct usb_desc_s *desc;
+ FAR struct usbhost_epdesc_s bindesc;
+ FAR struct usbhost_epdesc_s boutdesc;
+ int remaining;
+ uint8_t found = 0;
+ int ret;
+
+ uvdbg("desclen:%d funcaddr:%d\n", desclen, funcaddr);
+ DEBUGASSERT(priv != NULL &&
+ configdesc != NULL &&
+ desclen >= sizeof(struct usb_cfgdesc_s));
+
+ /* Verify that we were passed a configuration descriptor */
+
+ cfgdesc = (FAR struct usb_cfgdesc_s *)configdesc;
+ if (cfgdesc->type != USB_DESC_TYPE_CONFIG)
+ {
+ return -EINVAL;
+ }
+
+ /* Get the total length of the configuration descriptor (little endian).
+ * It might be a good check to get the number of interfaces here too.
+ */
+
+ remaining = (int)rtl8187x_getle16(cfgdesc->totallen);
+
+ /* Skip to the next entry descriptor */
+
+ configdesc += cfgdesc->len;
+ remaining -= cfgdesc->len;
+
+ /* Loop while there are more descriptors to examine */
+
+ while (remaining >= sizeof(struct usb_desc_s))
+ {
+ /* What is the next descriptor? */
+
+ desc = (FAR struct usb_desc_s *)configdesc;
+ switch (desc->type)
+ {
+ /* Interface descriptor. We really should get the number of endpoints
+ * from this descriptor too.
+ */
+
+ case USB_DESC_TYPE_INTERFACE:
+ {
+ FAR struct usb_ifdesc_s *ifdesc = (FAR struct usb_ifdesc_s *)configdesc;
+
+ uvdbg("Interface descriptor\n");
+ DEBUGASSERT(remaining >= USB_SIZEOF_IFDESC);
+
+ /* Save the interface number and mark ONLY the interface found */
+
+ priv->ifno = ifdesc->ifno;
+ found = USBHOST_IFFOUND;
+ }
+ break;
+
+ /* Endpoint descriptor. Here, we expect two bulk endpoints, an IN
+ * and an OUT.
+ */
+
+ case USB_DESC_TYPE_ENDPOINT:
+ {
+ FAR struct usb_epdesc_s *epdesc = (FAR struct usb_epdesc_s *)configdesc;
+
+ uvdbg("Endpoint descriptor\n");
+ DEBUGASSERT(remaining >= USB_SIZEOF_EPDESC);
+
+ /* Check for a bulk endpoint. */
+
+#warning "Review needed"
+/* For RTL8187B, the Linux driver hardcodes EP 3 for receiving and EP 2 for transmitting.
+ * Otherwise, it uses EP 1 receiving and some other EP for transmitting (maybe 12).
+ */
+ if ((epdesc->attr & USB_EP_ATTR_XFERTYPE_MASK) == USB_EP_ATTR_XFER_BULK)
+ {
+ /* Yes.. it is a bulk endpoint. IN or OUT? */
+
+ if (USB_ISEPOUT(epdesc->addr))
+ {
+ /* It is an OUT bulk endpoint. There should be only one
+ * bulk OUT endpoint.
+ */
+
+ if ((found & USBHOST_BOUTFOUND) != 0)
+ {
+ /* Oops.. more than one endpoint. We don't know
+ * what to do with this.
+ */
+
+ return -EINVAL;
+ }
+ found |= USBHOST_BOUTFOUND;
+
+ /* Save the bulk OUT endpoint information */
+
+ boutdesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
+ boutdesc.in = false;
+ boutdesc.funcaddr = funcaddr;
+ boutdesc.xfrtype = USB_EP_ATTR_XFER_BULK;
+ boutdesc.interval = epdesc->interval;
+ boutdesc.mxpacketsize = rtl8187x_getle16(epdesc->mxpacketsize);
+ uvdbg("Bulk OUT EP addr:%d mxpacketsize:%d\n",
+ boutdesc.addr, boutdesc.mxpacketsize);
+ }
+ else
+ {
+ /* It is an IN bulk endpoint. There should be only one
+ * bulk IN endpoint.
+ */
+
+ if ((found & USBHOST_BINFOUND) != 0)
+ {
+ /* Oops.. more than one endpoint. We don't know
+ * what to do with this.
+ */
+
+ return -EINVAL;
+ }
+ found |= USBHOST_BINFOUND;
+
+ /* Save the bulk IN endpoint information */
+
+ bindesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
+ bindesc.in = 1;
+ bindesc.funcaddr = funcaddr;
+ bindesc.xfrtype = USB_EP_ATTR_XFER_BULK;
+ bindesc.interval = epdesc->interval;
+ bindesc.mxpacketsize = rtl8187x_getle16(epdesc->mxpacketsize);
+ uvdbg("Bulk IN EP addr:%d mxpacketsize:%d\n",
+ bindesc.addr, bindesc.mxpacketsize);
+ }
+ }
+ }
+ break;
+
+ /* Other descriptors are just ignored for now */
+
+ default:
+ break;
+ }
+
+ /* If we found everything we need with this interface, then break out
+ * of the loop early.
+ */
+
+ if (found == USBHOST_ALLFOUND)
+ {
+ break;
+ }
+
+ /* Increment the address of the next descriptor */
+
+ configdesc += desc->len;
+ remaining -= desc->len;
+ }
+
+ /* Sanity checking... did we find all of things that we need? */
+
+ if (found != USBHOST_ALLFOUND)
+ {
+ udbg("ERROR: Found IF:%s BIN:%s BOUT:%s\n",
+ (found & USBHOST_IFFOUND) != 0 ? "YES" : "NO",
+ (found & USBHOST_BINFOUND) != 0 ? "YES" : "NO",
+ (found & USBHOST_BOUTFOUND) != 0 ? "YES" : "NO");
+ return -EINVAL;
+ }
+
+ /* We are good... Allocate the endpoints */
+
+ ret = DRVR_EPALLOC(priv->hcd, &boutdesc, &priv->epout);
+ if (ret != OK)
+ {
+ udbg("ERROR: Failed to allocate Bulk OUT endpoint\n");
+ return ret;
+ }
+
+ ret = DRVR_EPALLOC(priv->hcd, &bindesc, &priv->epin);
+ if (ret != OK)
+ {
+ udbg("ERROR: Failed to allocate Bulk IN endpoint\n");
+ (void)DRVR_EPFREE(priv->hcd, priv->epout);
+ return ret;
+ }
+
+ uvdbg("Endpoints allocated\n");
+ return OK;
+}
+
+/****************************************************************************
+ * Name: rtl8187x_devinit
+ *
+ * Description:
+ * The USB device has been successfully connected. This completes the
+ * initialization operations. It is first called after the
+ * configuration descriptor has been received.
+ *
+ * This function is called from the connect() method. This function always
+ * executes on the thread of the caller of connect().
+ *
+ * Input Parameters:
+ * priv - A reference to the class instance.
+ *
+ * Returned Values:
+ * None
+ *
+ ****************************************************************************/
+
+static inline int rtl8187x_devinit(FAR struct rtl8187x_state_s *priv)
+{
+ int ret = OK;
+
+ /* Set aside a transfer buffer for exclusive use by the class driver */
+
+ /* Increment the reference count. This will prevent rtl8187x_destroy() from
+ * being called asynchronously if the device is removed.
+ */
+
+ priv->crefs++;
+ DEBUGASSERT(priv->crefs == 2);
+
+ /* Configure the device and register the network driver */
+
+ uvdbg("Register ethernet device\n");
+ ret = rtl8187x_netinitialize(priv);
+
+ /* Check if we successfully initialized. We now have to be concerned
+ * about asynchronous modification of crefs because the network
+ * driver has been registered.
+ */
+
+ if (ret == OK)
+ {
+ rtl8187x_takesem(&priv->exclsem);
+
+ /* Decrement the reference count */
+
+ priv->crefs--;
+
+ /* Handle a corner case where (1) open() has been called so the
+ * reference count was > 2, but the device has been disconnected.
+ * In this case, the class instance needs to persist until close()
+ * is called.
+ */
+
+ if (priv->crefs <= 1 && priv->disconnected)
+ {
+ /* The will cause the enumeration logic to disconnect
+ * the class driver.
+ */
+
+ ret = -ENODEV;
+ }
+
+ /* Release the semaphore... there is a race condition here.
+ * Decrementing the reference count and releasing the semaphore
+ * allows usbhost_destroy() to execute (on the worker thread);
+ * the class driver instance could get destoryed before we are
+ * ready to handle it!
+ */
+
+ rtl8187x_givesem(&priv->exclsem);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: rtl8187x_host2le16 and rtl8187x_host2le32
+ *
+ * Description:
+ * Convert a 16/32-bit value in host byte order to little endian byte order.
+ *
+ * Input Parameters:
+ * val - A pointer to the first byte of the little endian value.
+ *
+ * Returned Values:
+ * A uint16_t representing the whole 16-bit integer value
+ *
+ ****************************************************************************/
+
+static inline uint16_t rtl8187x_host2le16(uint16_t val)
+{
+#ifdef CONFIG_ENDIAN_BIG
+ uint16_t ret = ((val & 0x00ff) << 8) |
+ ((val)) >> 8) & 0x00ff))
+ return ret
+#else
+ return val;
+#endif
+}
+
+static inline uint16_t rtl8187x_le2host16(uint16_t val)
+{
+#ifdef CONFIG_ENDIAN_BIG
+ uint16_t ret = ((val & 0x00ff) << 8) |
+ ((val)) >> 8) & 0x00ff))
+ return ret
+#else
+ return val;
+#endif
+}
+
+static inline uint32_t rtl8187x_host2le32(uint32_t val)
+{
+#ifdef CONFIG_ENDIAN_BIG
+ uint32_t ret = ((val & 0x000000ffL) << 24) |
+ ((val & 0x0000ff00L) << 8) |
+ ((val & 0x00ff0000L) >> 8) |
+ ((val & 0xff000000L) >> 24))
+ return ret
+#else
+ return val;
+#endif
+}
+
+static inline uint32_t rtl8187x_le2host32(uint32_t val)
+{
+#ifdef CONFIG_ENDIAN_BIG
+ uint32_t ret = ((val & 0x000000ffL) << 24) |
+ ((val & 0x0000ff00L) << 8) |
+ ((val & 0x00ff0000L) >> 8) |
+ ((val & 0xff000000L) >> 24))
+ return ret
+#else
+ return val;
+#endif
+}
+
+/****************************************************************************
+ * Name: rtl8187x_getle16 and rtl8187x_getle32
+ *
+ * Description:
+ * Get a (possibly unaligned) 16-bit little endian value.
+ *
+ * Input Parameters:
+ * val - A pointer to the first byte of the little endian value.
+ *
+ * Returned Values:
+ * A uint16_t representing the whole 16-bit integer value
+ *
+ ****************************************************************************/
+
+static inline uint16_t rtl8187x_getle16(const uint8_t *val)
+{
+ /* Little endian means LS byte first in byte stream */
+
+ return (uint16_t)val[1] << 8 | (uint16_t)val[0];
+}
+
+static inline uint32_t rtl8187x_getle32(const uint8_t *val)
+{
+ /* Little endian means LS halfword first in byte stream */
+
+ return (uint32_t)rtl8187x_getle16(&val[2]) << 16 | (uint32_t)rtl8187x_getle16(val);
+}
+
+/****************************************************************************
+ * Name: rtl8187x_putle16 and rtl8187x_putle32
+ *
+ * Description:
+ * Put a (possibly unaligned) 16/32-bit little endian value.
+ *
+ * Input Parameters:
+ * dest - A pointer to the first byte to save the little endian value.
+ * val - The 16-bit value to be saved.
+ *
+ * Returned Values:
+ * None
+ *
+ ****************************************************************************/
+
+static void rtl8187x_putle16(uint8_t *dest, uint16_t val)
+{
+ /* Little endian means LS byte first in byte stream */
+
+ dest[0] = val & 0xff; /* Little endian means LS byte first in byte stream */
+ dest[1] = val >> 8;
+}
+
+static void rtl8187x_putle32(uint8_t *dest, uint32_t val)
+{
+ /* Little endian means LS halfword first in byte stream */
+
+ rtl8187x_putle16(dest, (uint16_t)(val & 0xffff));
+ rtl8187x_putle16(dest+2, (uint16_t)(val >> 16));
+}
+
+/****************************************************************************
+ * Name: rtl8187x_allocbuffers
+ *
+ * Description:
+ * Allocate transfer buffer memory.
+ *
+ * Input Parameters:
+ * priv - A reference to the class instance.
+ *
+ * Returned Values:
+ * On sucess, zero (OK) is returned. On failure, an negated errno value
+ * is returned to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+static inline int rtl8187x_allocbuffers(FAR struct rtl8187x_state_s *priv)
+{
+ size_t buflen;
+ int ret;
+
+ DEBUGASSERT(priv && priv->ctrlreq == NULL && priv->tbuffer == NULL);
+
+ /* Allocate TD buffers for use in this driver. We will need two: One for
+ * the request and one for the data buffer.
+ */
+
+ ret = DRVR_ALLOC(priv->hcd, (FAR uint8_t **)&priv->ctrlreq, &buflen);
+ if (ret != OK)
+ {
+ uvdbg("DRVR_ALLOC(ctrlreq) failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = DRVR_ALLOC(priv->hcd, &priv->tbuffer, &priv->tbuflen);
+ if (ret != OK)
+ {
+ uvdbg("DRVR_ALLOC(tbuffer) failed: %d\n", ret);
+ return ret;
+ }
+
+ /* Allocate one TX I/O buffer big enough to hold one full packet plus
+ * the TX descriptor.
+ */
+
+ buflen = CONFIG_NET_BUFSIZE + 2 + SIZEOF_TXDESC;
+ ret = DRVR_IOALLOC(priv->hcd, &priv->txbuffer, buflen);
+ if (ret != OK)
+ {
+ uvdbg("DRVR_ALLOC(txbuffer) failed: %d\n", ret);
+ }
+
+ /* Allocate one RX I/O buffer big enough to hold one full packet plus
+ * the RX descriptor.
+ */
+
+ buflen = CONFIG_NET_BUFSIZE + 2 + SIZEOF_RXDESC;
+ ret = DRVR_IOALLOC(priv->hcd, &priv->rxbuffer, buflen);
+ if (ret != OK)
+ {
+ uvdbg("DRVR_ALLOC(rxbuffer) failed: %d\n", ret);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: rtl8187x_freebuffers
+ *
+ * Description:
+ * Free allocated buffer memory.
+ *
+ * Input Parameters:
+ * priv - A reference to the class instance.
+ *
+ * Returned Values:
+ * On sucess, zero (OK) is returned. On failure, an negated errno value
+ * is returned to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+static inline int rtl8187x_freebuffers(FAR struct rtl8187x_state_s *priv)
+{
+ DEBUGASSERT(priv);
+
+ if (priv->ctrlreq)
+ {
+ DEBUGASSERT(priv->hcd && priv->tbuffer);
+
+ /* Free the allocated control request */
+
+ (void)DRVR_FREE(priv->hcd, (FAR uint8_t *)priv->ctrlreq);
+ priv->ctrlreq = NULL;
+
+ /* Free the allocated buffer */
+
+ (void)DRVR_FREE(priv->hcd, priv->tbuffer);
+ priv->tbuffer = NULL;
+ priv->tbuflen = 0;
+ }
+ return OK;
+}
+
+/****************************************************************************
+ * struct usbhost_registry_s methods
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rtl8187x_create
+ *
+ * Description:
+ * This function implements the create() method of struct usbhost_registry_s.
+ * The create() method is a callback into the class implementation. It is
+ * used to (1) create a new instance of the USB host class state and to (2)
+ * bind a USB host driver "session" to the class instance. Use of this
+ * create() method will support environments where there may be multiple
+ * USB ports and multiple USB devices simultaneously connected.
+ *
+ * Input Parameters:
+ * hcd - An instance of struct usbhost_driver_s that the class
+ * implementation will "bind" to its state structure and will
+ * subsequently use to communicate with the USB host driver.
+ * id - In the case where the device supports multiple base classes,
+ * subclasses, or protocols, this specifies which to configure for.
+ *
+ * Returned Values:
+ * On success, this function will return a non-NULL instance of struct
+ * usbhost_class_s that can be used by the USB host driver to communicate
+ * with the USB host class. NULL is returned on failure; this function
+ * will fail only if the hcd input parameter is NULL or if there are
+ * insufficient resources to create another USB host class instance.
+ *
+ ****************************************************************************/
+
+static FAR struct usbhost_class_s *rtl8187x_create(FAR struct usbhost_driver_s *hcd,
+ FAR const struct usbhost_id_s *id)
+{
+ FAR struct rtl8187x_state_s *priv;
+ int ret;
+
+ DEBUGASSERT(hcd && id);
+
+ /* Allocate a USB host class instance */
+
+ uvdbg("vid:%04x pid:%04x\n", id->vid, id->pid);
+ priv = rtl8187x_allocclass();
+ if (priv)
+ {
+ /* Initialize the allocated storage class instance */
+
+ memset(priv, 0, sizeof(struct rtl8187x_state_s));
+
+ /* Initialize networking method function pointers */
+
+ priv->ethdev.d_ifup = rtl8187x_ifup; /* I/F down callback */
+ priv->ethdev.d_ifdown = rtl8187x_ifdown; /* I/F up (new IP address) callback */
+ priv->ethdev.d_txavail = rtl8187x_txavail; /* New TX data callback */
+#ifdef CONFIG_NET_IGMP
+ priv->ethdev.d_addmac = rtl8187x_addmac; /* Add multicast MAC address */
+ priv->ethdev.d_rmmac = rtl8187x_rmmac; /* Remove multicast MAC address */
+#endif
+ priv->ethdev.d_private = (void*)priv; /* Used to recover private state from dev */
+
+ /* Initialize class method function pointers */
+
+ priv->class.connect = rtl8187x_connect;
+ priv->class.disconnected = rtl8187x_disconnected;
+
+ /* Bind the host controller driver to the storage class instance */
+
+ priv->hcd = hcd;
+
+ /* The initial reference count is 1... One reference is held by the
+ * USB host controller driver
+ */
+
+ priv->crefs = 1;
+
+ /* Allocate buffering */
+
+ ret = rtl8187x_allocbuffers(priv);
+ if (ret != OK)
+ {
+ udbg("ERROR: Failed to allocate buffers: %d\n", ret);
+ goto errout;
+ }
+
+ /* Create a watchdog for timed polling for and timing of transfers */
+
+ priv->wdtxpoll = wd_create(); /* Create periodic TX poll timer */
+ priv->wdrxpoll = wd_create(); /* Create periodic RX poll timer */
+
+ /* Initialize semphores (this works okay in the interrupt context) */
+
+ sem_init(&priv->exclsem, 0, 1);
+
+ /* Return the instance of the USB class driver */
+
+ return &priv->class;
+ }
+
+ /* An error occurred. Free the allocation and return NULL on all failures */
+
+errout:
+ if (priv)
+ {
+ rtl8187x_freeclass(priv);
+ }
+ return NULL;
+}
+
+/****************************************************************************
+ * struct usbhost_class_s methods
+ ****************************************************************************/
+/****************************************************************************
+ * Name: rtl8187x_connect
+ *
+ * Description:
+ * This function implements the connect() method of struct
+ * usbhost_class_s. This method is a callback into the class
+ * implementation. It is used to provide the device's configuration
+ * descriptor to the class so that the class may initialize properly
+ *
+ * Input Parameters:
+ * class - The USB host class entry previously obtained from a call to create().
+ * configdesc - A pointer to a uint8_t buffer container the configuration descripor.
+ * desclen - The length in bytes of the configuration descriptor.
+ * funcaddr - The USB address of the function containing the endpoint that EP0
+ * controls
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure
+ *
+ * NOTE that the class instance remains valid upon return with a failure. It is
+ * the responsibility of the higher level enumeration logic to call
+ * CLASS_DISCONNECTED to free up the class driver resources.
+ *
+ * Assumptions:
+ * - This function will *not* be called from an interrupt handler.
+ * - If this function returns an error, the USB host controller driver
+ * must call to DISCONNECTED method to recover from the error
+ *
+ ****************************************************************************/
+
+static int rtl8187x_connect(FAR struct usbhost_class_s *class,
+ FAR const uint8_t *configdesc, int desclen,
+ uint8_t funcaddr)
+{
+ FAR struct rtl8187x_state_s *priv = (FAR struct rtl8187x_state_s *)class;
+ int ret;
+
+ DEBUGASSERT(priv != NULL &&
+ configdesc != NULL &&
+ desclen >= sizeof(struct usb_cfgdesc_s));
+
+ /* Parse the configuration descriptor to get the endpoints */
+
+ ret = rtl8187x_cfgdesc(priv, configdesc, desclen, funcaddr);
+ if (ret != OK)
+ {
+ udbg("rtl8187x_cfgdesc() failed: %d\n", ret);
+ }
+ else
+ {
+ /* Now configure the device and register the NuttX driver */
+
+ ret = rtl8187x_devinit(priv);
+ if (ret != OK)
+ {
+ udbg("rtl8187x_devinit() failed: %d\n", ret);
+ }
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: rtl8187x_disconnected
+ *
+ * Description:
+ * This function implements the disconnected() method of struct
+ * usbhost_class_s. This method is a callback into the class
+ * implementation. It is used to inform the class that the USB device has
+ * been disconnected.
+ *
+ * Input Parameters:
+ * class - The USB host class entry previously obtained from a call to
+ * create().
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value
+ * is returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * This function may be called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static int rtl8187x_disconnected(struct usbhost_class_s *class)
+{
+ FAR struct rtl8187x_state_s *priv = (FAR struct rtl8187x_state_s *)class;
+ irqstate_t flags;
+
+ DEBUGASSERT(priv != NULL);
+
+ /* Set an indication to any users of the device that the device is no
+ * longer available.
+ */
+
+ flags = irqsave();
+ priv->disconnected = true;
+
+ /* Now check the number of references on the class instance. The USB host
+ * controller driver has just reliquished its reference. If the reference
+ * count would go to zero, then we can free the class instance now. Otherwise,
+ * we will have to wait until the holders of the references free them.
+ */
+
+ ullvdbg("crefs: %d\n", priv->crefs);
+ if (--priv->crefs <= 0)
+ {
+ /* Destroy the class instance. Defer the destruction to the worker thread.
+ * (in case we were callded from an interrupt handler).
+ */
+
+ ullvdbg("Queuing destruction: worker %p->%p\n", priv->wkdisconn.worker, rtl8187x_destroy);
+ DEBUGASSERT(priv->wkdisconn.worker == NULL);
+ (void)work_queue(&priv->wkdisconn, rtl8187x_destroy, priv, 0);
+ }
+
+ irqrestore(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * Function: rtl8187x_ioread8/16/32
+ *
+ * Description:
+ * Read 8, 16, or 32 bits from the RTL8187x.
+ *
+ * Parameters:
+ * priv - Reference to the driver state structure
+ * addr - Device addresses
+ *
+ * Returned Value:
+ * The value read from the the RTL8187x (no error indication returned).
+ *
+ * Assumptions:
+ * Not called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static uint8_t rtl8187x_ioread8(struct rtl8187x_state_s *priv, uint16_t addr)
+{
+ FAR struct usb_ctrlreq_s *ctrlreq = priv->ctrlreq;
+ int ret;
+
+ DEBUGASSERT(ctrlreq && priv->tbuffer);
+ ctrlreq->type = (USB_REQ_DIR_IN | USB_REQ_TYPE_VENDOR | USB_REQ_RECIPIENT_DEVICE);
+ ctrlreq->req = RTL8187X_REQ_GETREG;
+ rtl8187x_putle16(ctrlreq->value, addr);
+ rtl8187x_putle16(ctrlreq->index, 0);
+ rtl8187x_putle16(ctrlreq->len, sizeof(uint8_t));
+
+ ret = DRVR_CTRLIN(priv->hcd, priv->ctrlreq, priv->tbuffer);
+ if (ret != OK)
+ {
+ udbg("ERROR: DRVR_CTRLIN returned %d\n", ret);
+ return 0;
+ }
+
+ return *((uint8_t*)priv->tbuffer);
+}
+
+static uint16_t rtl8187x_ioread16(struct rtl8187x_state_s*priv, uint16_t addr)
+{
+ FAR struct usb_ctrlreq_s *ctrlreq = priv->ctrlreq;
+ int ret;
+
+ DEBUGASSERT(ctrlreq && priv->tbuffer);
+ ctrlreq->type = (USB_REQ_DIR_IN | USB_REQ_TYPE_VENDOR | USB_REQ_RECIPIENT_DEVICE);
+ ctrlreq->req = RTL8187X_REQ_GETREG;
+ rtl8187x_putle16(ctrlreq->value, addr);
+ rtl8187x_putle16(ctrlreq->index, 0);
+ rtl8187x_putle16(ctrlreq->len, sizeof(uint16_t));
+
+ ret = DRVR_CTRLIN(priv->hcd, priv->ctrlreq, priv->tbuffer);
+ if (ret != OK)
+ {
+ udbg("ERROR: DRVR_CTRLIN returned %d\n", ret);
+ return 0;
+ }
+
+ return rtl8187x_getle16(priv->tbuffer);
+}
+
+static uint32_t rtl8187x_ioread32(struct rtl8187x_state_s*priv, uint16_t addr)
+{
+ FAR struct usb_ctrlreq_s *ctrlreq = priv->ctrlreq;
+ int ret;
+
+ DEBUGASSERT(ctrlreq && priv->tbuffer);
+ ctrlreq->type = (USB_REQ_DIR_IN | USB_REQ_TYPE_VENDOR | USB_REQ_RECIPIENT_DEVICE);
+ ctrlreq->req = RTL8187X_REQ_GETREG;
+ rtl8187x_putle16(ctrlreq->value, addr);
+ rtl8187x_putle16(ctrlreq->index, 0);
+ rtl8187x_putle16(ctrlreq->len, sizeof(uint32_t));
+
+ ret = DRVR_CTRLIN(priv->hcd, priv->ctrlreq, priv->tbuffer);
+ if (ret != OK)
+ {
+ udbg("ERROR: DRVR_CTRLIN returned %d\n", ret);
+ return 0;
+ }
+
+ return rtl8187x_getle32(priv->tbuffer);
+}
+
+/****************************************************************************
+ * Function: rtl8187x_iowrite8/16/32
+ *
+ * Description:
+ * Write a 8, 16, or 32 bits to the RTL8187x.
+ *
+ * Parameters:
+ * priv - Reference to the driver state structure
+ * addr - Device addresses
+ * val - The value to write
+ *
+ * Returned Value:
+ * OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ * Not called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static int rtl8187x_iowrite8(struct rtl8187x_state_s *priv, uint16_t addr, uint8_t val)
+{
+ FAR struct usb_ctrlreq_s *ctrlreq = priv->ctrlreq;
+
+ DEBUGASSERT(ctrlreq && priv->tbuffer);
+ ctrlreq->type = (USB_REQ_DIR_OUT | USB_REQ_TYPE_VENDOR | USB_REQ_RECIPIENT_DEVICE);
+ ctrlreq->req = RTL8187X_REQ_SETREG;
+ rtl8187x_putle16(ctrlreq->value, addr);
+ rtl8187x_putle16(ctrlreq->index, 0);
+ rtl8187x_putle16(ctrlreq->len, sizeof(uint8_t));
+
+ priv->tbuffer[0] = val;
+ return DRVR_CTRLOUT(priv->hcd, priv->ctrlreq, priv->tbuffer);
+}
+
+static int rtl8187x_iowrite16(struct rtl8187x_state_s *priv, uint16_t addr, uint16_t val)
+{
+ FAR struct usb_ctrlreq_s *ctrlreq = priv->ctrlreq;
+
+ DEBUGASSERT(ctrlreq && priv->tbuffer);
+ ctrlreq->type = (USB_REQ_DIR_OUT | USB_REQ_TYPE_VENDOR | USB_REQ_RECIPIENT_DEVICE);
+ ctrlreq->req = RTL8187X_REQ_SETREG;
+ rtl8187x_putle16(ctrlreq->value, addr);
+ rtl8187x_putle16(ctrlreq->index, 0);
+ rtl8187x_putle16(ctrlreq->len, sizeof(uint16_t));
+
+ rtl8187x_putle16(priv->tbuffer, val);
+ return DRVR_CTRLOUT(priv->hcd, priv->ctrlreq, priv->tbuffer);
+}
+
+static int rtl8187x_iowrite32(struct rtl8187x_state_s *priv, uint16_t addr, uint32_t val)
+{
+ FAR struct usb_ctrlreq_s *ctrlreq = priv->ctrlreq;
+
+ DEBUGASSERT(ctrlreq && priv->tbuffer);
+ ctrlreq->type = (USB_REQ_DIR_OUT | USB_REQ_TYPE_VENDOR | USB_REQ_RECIPIENT_DEVICE);
+ ctrlreq->req = RTL8187X_REQ_SETREG;
+ rtl8187x_putle16(ctrlreq->value, addr);
+ rtl8187x_putle16(ctrlreq->index, 0);
+ rtl8187x_putle16(ctrlreq->len, sizeof(uint32_t));
+
+ rtl8187x_putle32(priv->tbuffer, val);
+ return DRVR_CTRLOUT(priv->hcd, priv->ctrlreq, priv->tbuffer);
+}
+
+/****************************************************************************
+ * Function: rtl8187x_read
+ *
+ * Description:
+ * Read RTL register value
+ *
+ * Parameters:
+ * priv - Reference to the driver state structure
+ * addr - Register address
+ *
+ * Returned Value:
+ * Value
+ *
+ ****************************************************************************/
+
+static uint16_t rtl8187x_read(FAR struct rtl8187x_state_s *priv, uint8_t addr)
+{
+ uint16_t reg80;
+ uint16_t reg82;
+ uint16_t reg84;
+ uint16_t ret;
+ int i;
+
+ reg80 = rtl8187x_ioread16(priv, RTL8187X_ADDR_RFPINSOUTPUT);
+ reg82 = rtl8187x_ioread16(priv, RTL8187X_ADDR_RFPINSENABLE);
+ reg84 = rtl8187x_ioread16(priv, RTL8187X_ADDR_RFPINSSELECT);
+
+ reg80 &= ~0xf;
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSENABLE, reg82 | 0x000f);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSSELECT, reg84 | 0x000f);
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg80 | (1 << 2));
+ usleep(4);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg80);
+ usleep(5);
+
+ for (i = 4; i >= 0; i--)
+ {
+ uint16_t reg = reg80 | ((addr >> i) & 1);
+
+ if (!(i & 1))
+ {
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg);
+ usleep(1);
+ }
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg | (1 << 1));
+ usleep(2);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg | (1 << 1));
+ usleep(2);
+
+ if (i & 1)
+ {
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg);
+ usleep(1);
+ }
+ }
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT,
+ reg80 | (1 << 3) | (1 << 1));
+ usleep(2);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg80 | (1 << 3));
+ usleep(2);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg80 | (1 << 3));
+ usleep(2);
+
+ ret = 0;
+ for (i = 11; i >= 0; i--)
+ {
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg80 | (1 << 3));
+ usleep(1);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT,
+ reg80 | (1 << 3) | (1 << 1));
+ usleep(2);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT,
+ reg80 | (1 << 3) | (1 << 1));
+ usleep(2);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT,
+ reg80 | (1 << 3) | (1 << 1));
+ usleep(2);
+
+ if (rtl8187x_ioread16(priv, RTL8187X_ADDR_RFPINSINPUT) & (1 << 1))
+ ret |= 1 << i;
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg80 | (1 << 3));
+ usleep(2);
+ }
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT,
+ reg80 | (1 << 3) | (1 << 2));
+ usleep(2);
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSENABLE, reg82);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSSELECT, reg84);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, 0x03a0);
+
+ return ret;
+}
+
+/****************************************************************************
+ * Function: rtl8187x_write
+ *
+ * Description:
+ * Write RTL register value
+ *
+ * Parameters:
+ * priv - Reference to the driver state structure
+ * addr - Register address
+ *
+ * Returned Value:
+ * Value
+ *
+ ****************************************************************************/
+
+static inline void rtl8187x_write_8051(FAR struct rtl8187x_state_s *priv,
+ uint8_t addr, uint16_t data)
+{
+ struct usb_ctrlreq_s *ctrlreq;
+ uint16_t reg80;
+ uint16_t reg82;
+ uint16_t reg84;
+ int ret;
+
+ reg80 = rtl8187x_ioread16(priv, RTL8187X_ADDR_RFPINSOUTPUT);
+ reg82 = rtl8187x_ioread16(priv, RTL8187X_ADDR_RFPINSENABLE);
+ reg84 = rtl8187x_ioread16(priv, RTL8187X_ADDR_RFPINSSELECT);
+
+ reg80 &= ~(0x3 << 2);
+ reg84 &= ~0xf;
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSENABLE, reg82 | 0x0007);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSSELECT, reg84 | 0x0007);
+ usleep(10);
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg80 | (1 << 2));
+ usleep(2);
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg80);
+ usleep(10);
+
+ ctrlreq = priv->ctrlreq;
+ ctrlreq->type = (USB_REQ_DIR_OUT | USB_REQ_TYPE_VENDOR | USB_REQ_RECIPIENT_DEVICE);
+ ctrlreq->req = RTL8187X_REQ_GETREG;
+ rtl8187x_putle16(ctrlreq->value, addr);
+ rtl8187x_putle16(ctrlreq->index, 0x8225);
+ rtl8187x_putle16(ctrlreq->len, sizeof(uint16_t));
+
+ rtl8187x_putle16(priv->tbuffer, data);
+ ret = DRVR_CTRLOUT(priv->hcd, priv->ctrlreq, priv->tbuffer);
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg80 | (1 << 2));
+ usleep(10);
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg80 | (1 << 2));
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSSELECT, reg84);
+ usleep(2000);
+}
+
+static inline void rtl8187x_write_bitbang(struct rtl8187x_state_s *priv,
+ uint8_t addr, uint16_t data)
+{
+ uint16_t reg80, reg84, reg82;
+ uint32_t bangdata;
+ int i;
+
+ bangdata = (data << 4) | (addr & 0xf);
+
+ reg80 = rtl8187x_ioread16(priv, RTL8187X_ADDR_RFPINSOUTPUT) & 0xfff3;
+ reg82 = rtl8187x_ioread16(priv, RTL8187X_ADDR_RFPINSENABLE);
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSENABLE, reg82 | 0x7);
+
+ reg84 = rtl8187x_ioread16(priv, RTL8187X_ADDR_RFPINSSELECT);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSSELECT, reg84 | 0x7);
+ usleep(10);
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg80 | (1 << 2));
+ usleep(2);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg80);
+ usleep(10);
+
+ for (i = 15; i >= 0; i--)
+ {
+ uint16_t reg = reg80 | (bangdata & (1 << i)) >> i;
+
+ if (i & 1)
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg);
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg | (1 << 1));
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg | (1 << 1));
+
+ if (!(i & 1))
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg);
+ }
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg80 | (1 << 2));
+ usleep(10);
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, reg80 | (1 << 2));
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSSELECT, reg84);
+ usleep(2);
+}
+
+static void rtl8187x_write(FAR struct rtl8187x_state_s *priv, uint8_t addr, uint16_t data)
+{
+ if (priv->asicrev)
+ {
+ rtl8187x_write_8051(priv, addr, rtl8187x_host2le16(data));
+ }
+ else
+ {
+ rtl8187x_write_bitbang(priv, addr, data);
+ }
+}
+
+/****************************************************************************
+ * Function: rtl8187x_transmit
+ *
+ * Description:
+ * Start hardware transmission. Called either from the watchdog based
+ * polling or to send a response to an incoming packet.
+ *
+ * Parameters:
+ * priv - Reference to the driver state structure
+ *
+ * Returned Value:
+ * OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ * May or may not be called from an interrupt handler. In either case,
+ * global interrupts are disabled, either explicitly or indirectly through
+ * interrupt handling logic.
+ *
+ ****************************************************************************/
+
+static int rtl8187x_transmit(FAR struct rtl8187x_state_s *priv)
+{
+ int ret;
+
+ /* Get exclusive access to the USB controller interface */
+
+ DEBUGASSERT(priv && priv->txbuffer);
+ rtl8187x_takesem(&priv->exclsem);
+
+ /* Check if the RTL8187 is still connected */
+
+ if (priv->disconnected)
+ {
+ /* No... the wan driver is no longer bound to the class. That means that
+ * the USB device is no longer connected. Refuse any attempt to write to
+ * the device.
+ */
+
+ ret = -ENODEV;
+ }
+ else if (!priv->bifup)
+ {
+ /* The interface is not up.
+ */
+
+ ret = -EAGAIN;
+ }
+ else
+ {
+ FAR struct rtl8187x_txdesc_s *txdesc = (FAR struct rtl8187x_txdesc_s *)priv->txbuffer;
+ unsigned int datlen = priv->ethdev.d_len;
+ uint32_t flags;
+ uint32_t retry;
+
+ /* Increment statistics */
+
+ RTL8187X_STATS(priv, transmitted);
+
+ /* Construct the TX descriptor at the beginning of the IO buffer. This
+ * memory was previously reserved just for this use.
+ */
+
+ flags = datlen | RTL8187X_TXDESC_FLAG_NOENC | RTL8187X_RATE_11 << 24;
+ txdesc->flags = rtl8187x_host2le32(flags);
+ txdesc->rtsduration = 0;
+ txdesc->len = 0;
+ retry = rtl8187x_host2le32(3) | /* CWMIN */
+ (7 << 4) | /* CMAX */
+ (0 << 8); /* retry lim */
+ txdesc->retry = rtl8187x_host2le32(retry);
+
+#ifdef CONFIG_RTL8187B
+#warning "This number is bogus"
+ txdesc->txduration = 40;
+#endif
+
+ /* And transfer the packet */
+
+ ret = DRVR_TRANSFER(priv->hcd, priv->epout, priv->txbuffer, datlen + SIZEOF_TXDESC);
+ if (ret != OK)
+ {
+ RTL8187X_STATS(priv, txfailed);
+ }
+ }
+ rtl8187x_givesem(&priv->exclsem);
+
+ return ret;
+}
+
+/****************************************************************************
+ * Function: rtl8187x_uiptxpoll
+ *
+ * Description:
+ * The transmitter is available, check if uIP has any outgoing packets ready
+ * to send. This is a callback from uip_poll(). uip_poll() may be called:
+ *
+ * 1. When the preceding TX packet send is complete,
+ * 2. When the preceding TX packet send timesout and the interface is reset
+ * 3. During normal TX polling
+ *
+ * Parameters:
+ * dev - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ * OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ * Never called from an interrupt handler. The polling process was
+ * initiated by a normal thread (possibly the worker thread). The initiator
+ * has called uip_lock() to assure that we have exclusive access to uIP.
+ *
+ ****************************************************************************/
+
+static int rtl8187x_uiptxpoll(struct uip_driver_s *dev)
+{
+ FAR struct rtl8187x_state_s *priv = (FAR struct rtl8187x_state_s *)dev->d_private;
+
+ /* If the polling resulted in data that should be sent out on the network,
+ * the field d_len is set to a value > 0.
+ */
+
+ if (priv->ethdev.d_len > 0)
+ {
+ uip_arp_out(&priv->ethdev);
+ rtl8187x_transmit(priv);
+ }
+
+ /* If zero is returned, the polling will continue until all connections have
+ * been examined.
+ */
+
+ return 0;
+}
+
+/****************************************************************************
+ * Function: rtl8187x_txpollwork
+ *
+ * Description:
+ * Periodic timer handler. The poll occurs on the worker thread. The
+ * poll work was scheduled by rtl8187x_txpolltimer when the poll timer
+ * expired.
+ *
+ * Parameters:
+ * arg - The passed argument (priv)
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Global interrupts are disabled by the watchdog logic.
+ *
+ ****************************************************************************/
+
+static void rtl8187x_txpollwork(FAR void *arg)
+{
+ FAR struct rtl8187x_state_s *priv = (FAR struct rtl8187x_state_s *)arg;
+
+ /* Verify that the RTL8187 is still connected and that the interface is up */
+
+ if (!priv->disconnected && priv->bifup)
+ {
+ uip_lock_t lock;
+ uint32_t now;
+ uint32_t hsecs;
+
+ /* Get exclusive access to uIP */
+
+ lock = uip_lock();
+
+ /* Estimate the elapsed time in hsecs since the last poll */
+
+ now = g_system_timer;
+ hsecs = (priv->lastpoll - now + CLK_TCK / 4) / (CLK_TCK / 2);
+ priv->lastpoll = now;
+
+ /* Update TCP timing states and poll uIP for new XMIT data. Pass an
+ * offset address into the txbuffer, reserving space for the TX
+ * descriptor at the beginning of the buffer.
+ */
+
+ priv->ethdev.d_buf = &priv->txbuffer[SIZEOF_TXDESC];
+ (void)uip_timer(&priv->ethdev, rtl8187x_uiptxpoll, (int)hsecs);
+ uip_unlock(lock);
+ }
+}
+
+/****************************************************************************
+ * Function: rtl8187x_txpolltimer
+ *
+ * Description:
+ * Periodic timer handler. Called from the timer interrupt handler. The
+ * actually polling is performed by on the work threader thread by
+ * rtl8187x_txpollwork().
+ *
+ * Parameters:
+ * argc - The number of available arguments
+ * arg - The first argument
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Global interrupts are disabled by the watchdog logic.
+ *
+ ****************************************************************************/
+
+static void rtl8187x_txpolltimer(int argc, uint32_t arg, ...)
+{
+ FAR struct rtl8187x_state_s *priv = (FAR struct rtl8187x_state_s *)arg;
+ uint32_t delay = RTL8187X_TXDELAY;
+
+ /* Verify that the RTL8187 is still connected and that the interface is up */
+
+ if (!priv->disconnected && priv->bifup)
+ {
+ /* Check for over-run... What if the last queued poll work has not yet ran?
+ * That could be the case if the system were too busy, if we are polling to
+ * rapidly, or if something is hung.
+ */
+
+ if (priv->wktxpoll.worker != NULL)
+ {
+ ulldbg("ERROR: TX work overrun!\n");
+ delay = RTL8187X_RETRYDELAY;
+ }
+ else
+ {
+ (void)work_queue(&priv->wktxpoll, rtl8187x_txpollwork, priv, 0);
+ }
+ }
+
+ /* Setup the watchdog poll timer again -- possibly using a shorter retry delay */
+
+ (void)wd_start(priv->wdtxpoll, delay, rtl8187x_txpolltimer, 1, arg);
+}
+
+/****************************************************************************
+ * Function: rtl8187x_receive
+ *
+ * Description:
+ * Called upon receipt of a new USB packet on the epin endpoint. Analyzes
+ * the RX header in priv->rxbuffer and returns the packet length
+ *
+ * Parameters:
+ * priv - Reference to the driver state structure
+ * iolen - The size of the received USB packet
+ * pktlen - The returned size of the packet
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * The caller holds the exclsem and has exclusive access to the USB
+ * interface.
+ *
+ ****************************************************************************/
+
+static inline int rtl8187x_receive(FAR struct rtl8187x_state_s *priv,
+ unsigned int iolen, unsigned int *pktlen)
+{
+ struct rtl8187x_rxdesc_s *rxdesc;
+ uint32_t flags;
+ uint16_t rxlen;
+ int signal;
+
+ /* Increment statistics */
+
+ RTL8187X_STATS(priv, received);
+
+ /* Make sure that the packet was large enough to contain an RX descriptor
+ * and an Ethernet header
+ */
+
+ if (iolen < UIP_LLH_LEN + SIZEOF_RXDESC)
+ {
+ RTL8187X_STATS(priv, rxtoosmall);
+ RTL8187X_STATS(priv, rxdropped);
+ return -EINVAL;
+ }
+
+ /* The RX descriptor lies at the end of the IO buffer */
+
+ rxdesc = (struct rtl8187x_rxdesc_s *)(priv->rxbuffer + (iolen - SIZEOF_RXDESC));
+ flags = rtl8187x_le2host32(rxdesc->flags);
+ if (flags & RTL8187X_RXDESC_FLAG_CRC32ERR)
+ {
+ udbg("Bad CRC\n");
+ RTL8187X_STATS(priv, rxcrcerr);
+ RTL8187X_STATS(priv, rxdropped);
+ return -EINVAL;
+ }
+
+ /* Get the actual packet length and rate from the RX descriptor flags */
+
+ rxlen = (flags & 0xfff) - 4;
+ priv->rate = (flags >> 20) & 0xf;
+
+ /* Perform signal strength calculation */
+
+#ifdef CONFIG_RTL8187B
+/* Linux has this:
+ * signal = -4 - ((27 * hdr->agc) >> 6);
+ * antenna = (hdr->signal >> 7) & 1;
+ * mactime = le64_to_cpu(hdr->mac_time)
+ * Otherwise
+ * signal = 14 - hdr->agc / 2;
+ * antenna = (hdr->rssi >> 7) & 1;
+ * mactime = le64_to_cpu(hdr->mac_time
+ */
+#warning "Signal computations must change for RTL8187B"
+#endif
+
+ signal = rxdesc->agc >> 1;
+ if (priv->rate)
+ {
+ /* OFDM rate */
+
+ if (signal > 90)
+ {
+ signal = 90;
+ }
+ else if (signal < 25)
+ {
+ signal = 25;
+ }
+ signal = 90 - signal;
+ }
+ else
+ {
+ /* CCK rate */
+
+ if (signal > 95)
+ {
+ signal = 95;
+ }
+ else if (signal < 30)
+ {
+ signal = 30;
+ }
+ signal = 95 - signal;
+ }
+
+ /* Signal strength: (100.0 / 65.0) * signal */
+
+ priv->signal = (uint8_t) (20 * signal + 7) / 13;
+ priv->silence = false;
+
+ /* Check if uIP is configured to handle a packet of this size */
+
+ if (iolen > CONFIG_NET_BUFSIZE + SIZEOF_RXDESC + 2)
+ {
+ RTL8187X_STATS(priv, rxtoobig);
+ RTL8187X_STATS(priv, rxdropped);
+ return -EINVAL;
+ }
+
+ /* Return the packet length. This is the length of the value packet
+ * data at the beginning of the buffer (we no longer need the RX descriptor)
+ */
+
+ *pktlen = rxlen;
+ return OK;
+}
+
+/****************************************************************************
+ * Function: rtl8187x_rxdispatch
+ *
+ * Description:
+ * Analyzes the ethernet header of the received packet (in priv->rxbuffer)
+ * and fowards valid Ethernet packets to uIP.
+ *
+ * Parameters:
+ * priv - Reference to the driver state structure
+ * pktlen - Returned size of the packet
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Global interrupts are disabled by interrupt handling logic.
+ *
+ ****************************************************************************/
+
+static inline void rtl8187x_rxdispatch(FAR struct rtl8187x_state_s *priv,
+ unsigned int pktlen)
+{
+ FAR struct uip_eth_hdr *ethhdr = (FAR struct uip_eth_hdr *)priv->rxbuffer;
+ uip_lock_t lock;
+
+ /* Get exclusive access to uIP */
+
+ lock = uip_lock();
+ priv->ethdev.d_buf = priv->rxbuffer;
+ priv->ethdev.d_len = pktlen;
+
+ /* We only accept IP packets of the configured type and ARP packets */
+
+#ifdef CONFIG_NET_IPv6
+ if (ethhdr->type == HTONS(UIP_ETHTYPE_IP6))
+#else
+ if (ethhdr->type == HTONS(UIP_ETHTYPE_IP))
+#endif
+ {
+ RTL8187X_STATS(priv, rxippackets);
+ uip_arp_ipin(&priv->ethdev);
+ uip_input(&priv->ethdev);
+
+ /* If the above function invocation resulted in data that should be
+ * sent out on the network, the field d_len will set to a value > 0.
+ */
+
+ if (priv->ethdev.d_len > 0)
+ {
+ uip_arp_out(&priv->ethdev);
+ rtl8187x_transmit(priv);
+ }
+ }
+ else if (ethhdr->type == htons(UIP_ETHTYPE_ARP))
+ {
+ RTL8187X_STATS(priv, rxarppackets);
+ uip_arp_arpin(&priv->ethdev);
+
+ /* If the above function invocation resulted in data that should be
+ * sent out on the network, the field d_len will set to a value > 0.
+ */
+
+ if (priv->ethdev.d_len > 0)
+ {
+ rtl8187x_transmit(priv);
+ }
+ }
+ else
+ {
+ RTL8187X_STATS(priv, rxbadproto);
+ RTL8187X_STATS(priv, rxdropped);
+ }
+
+ uip_unlock(lock);
+}
+
+/****************************************************************************
+ * Function: rtl8187x_rxpollwork
+ *
+ * Description:
+ * Periodic timer handler. The poll occurs on the worker thread. The
+ * poll work was scheduled by rtl8187x_rxpolltimer when the poll timer
+ * expired.
+ *
+ * Parameters:
+ * arg - The passed argument (priv)
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Global interrupts are disabled by the watchdog logic.
+ *
+ ****************************************************************************/
+
+static void rtl8187x_rxpollwork(FAR void *arg)
+{
+ FAR struct rtl8187x_state_s *priv = (FAR struct rtl8187x_state_s *)arg;
+
+ /* Get exclusive access to the USB controller interface and the device
+ * structure
+ */
+
+ DEBUGASSERT(priv && priv->rxbuffer);
+ rtl8187x_takesem(&priv->exclsem);
+
+ /* Verify that the RTL8187 is still connected and that the interface is up */
+
+ if (!priv->disconnected && priv->bifup)
+ {
+ unsigned int iolen;
+ int ret;
+
+ /* Attempt to read from the bulkin endpoint */
+
+ ret = DRVR_TRANSFER(priv->hcd, priv->epin, priv->rxbuffer,
+ CONFIG_NET_BUFSIZE + SIZEOF_RXDESC + 2);
+
+ /* How dow we get the length of the transfer? */
+#warning "Missing logic"
+ iolen = 0;
+
+ if (ret == OK)
+ {
+ unsigned int pktlen;
+
+ /* Analyze the packet and copy it into the RX buffer */
+
+ ret = rtl8187x_receive(priv, iolen, &pktlen);
+ if (ret == OK)
+ {
+ /* Now we can relinquish the USB interface and device
+ * structure.
+ */
+
+ rtl8187x_givesem(&priv->exclsem);
+
+ /* Send the packet to uIP */
+
+ rtl8187x_rxdispatch(priv, pktlen);
+ return;
+ }
+ }
+ }
+
+ rtl8187x_givesem(&priv->exclsem);
+}
+
+/****************************************************************************
+ * Function: rtl8187x_rxpolltimer
+ *
+ * Description:
+ * Periodic timer handler. Called from the timer interrupt handler. The
+ * actually polling is performed by on the work threader thread by
+ * rtl8187x_rxpollwork().
+ *
+ * Parameters:
+ * argc - The number of available arguments
+ * arg - The first argument
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Global interrupts are disabled by the watchdog logic.
+ *
+ ****************************************************************************/
+
+static void rtl8187x_rxpolltimer(int argc, uint32_t arg, ...)
+{
+ FAR struct rtl8187x_state_s *priv = (FAR struct rtl8187x_state_s *)arg;
+
+ /* Verify that the RTL8187 is still connected and that the interface is up */
+
+ if (!priv->disconnected && priv->bifup)
+ {
+ /* Check for over-run... What if the last queued poll work has not yet ran?
+ * That could be the case if the system were too busy, if we are polling to
+ * rapidly, or if something is hung.
+ */
+
+ if (priv->wkrxpoll.worker != NULL)
+ {
+ ulldbg("ERROR: RX work overrun!\n");
+ }
+ else
+ {
+ (void)work_queue(&priv->wkrxpoll, rtl8187x_rxpollwork, priv, 0);
+ }
+ }
+
+ /* Setup the watchdog poll timer again -- possibly using a shorter retry delay */
+
+ (void)wd_start(priv->wdrxpoll, RTL8187X_RXDELAY, rtl8187x_rxpolltimer, 1, arg);
+}
+
+/****************************************************************************
+ * Function: rtl8187x_ifup
+ *
+ * Description:
+ * NuttX Callback: Bring up the WLAN interface when an IP address is
+ * provided
+ *
+ * Parameters:
+ * dev - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int rtl8187x_ifup(struct uip_driver_s *dev)
+{
+ FAR struct rtl8187x_state_s *priv = (FAR struct rtl8187x_state_s *)dev->d_private;
+ int ret;
+
+ ndbg("Bringing up: %d.%d.%d.%d\n",
+ dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
+ (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 );
+
+ /* Initialize PHYs and the WLAN interface */
+
+ ret = rtl8187x_start(priv);
+ if (ret == OK)
+ {
+ /* Set up and activate TX timer processes */
+
+ (void)wd_start(priv->wdtxpoll, RTL8187X_TXDELAY, rtl8187x_txpolltimer, 1, (uint32_t)priv);
+ priv->lastpoll = g_system_timer;
+
+ /* Set up and activate RX timer processes */
+
+ (void)wd_start(priv->wdrxpoll, RTL8187X_RXDELAY, rtl8187x_rxpolltimer, 1, (uint32_t)priv);
+
+ /* Mark the interface as up. */
+
+ priv->bifup = true;
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Function: rtl8187x_ifdown
+ *
+ * Description:
+ * NuttX Callback: Stop the interface.
+ *
+ * Parameters:
+ * dev - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int rtl8187x_ifdown(struct uip_driver_s *dev)
+{
+ FAR struct rtl8187x_state_s *priv = (FAR struct rtl8187x_state_s *)dev->d_private;
+ irqstate_t flags;
+
+ /* Cancel the TX and RX poll timer. */
+
+ flags = irqsave();
+ wd_cancel(priv->wdtxpoll);
+ wd_cancel(priv->wdrxpoll);
+
+ /* Put the the EMAC is its non-operational state. This should be a known
+ * configuration that will guarantee the rtl8187x_ifup() always successfully
+ * successfully brings the interface back up.
+ */
+
+ rtl8187x_stop(priv);
+
+ /* Mark the device "down" */
+
+ priv->bifup = false;
+ irqrestore(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * Function: rtl8187x_txavail
+ *
+ * Description:
+ * Driver callback invoked when new TX data is available. This is a
+ * stimulus perform an out-of-cycle poll and, thereby, reduce the TX
+ * latency.
+ *
+ * Parameters:
+ * dev - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Called in normal user mode
+ *
+ ****************************************************************************/
+
+static int rtl8187x_txavail(struct uip_driver_s *dev)
+{
+ FAR struct rtl8187x_state_s *priv = (FAR struct rtl8187x_state_s *)dev->d_private;
+
+ /* Ignore the notification if the interface is not yet up */
+
+ if (priv->bifup)
+ {
+ uip_lock_t lock;
+
+ /* If so, then poll uIP for new XMIT data. Pass the offset address
+ * into the txbuffer, reserving space for the TX descriptor at the
+ * beginning of the buffer.
+ */
+
+ lock = uip_lock();
+ priv->ethdev.d_buf = &priv->txbuffer[SIZEOF_TXDESC];
+ (void)uip_poll(&priv->ethdev, rtl8187x_uiptxpoll);
+ uip_unlock(lock);
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Function: rtl8187x_addmac
+ *
+ * Description:
+ * NuttX Callback: Add the specified MAC address to the hardware multicast
+ * address filtering
+ *
+ * Parameters:
+ * dev - Reference to the NuttX driver state structure
+ * mac - The MAC address to be added
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IGMP
+static int rtl8187x_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
+{
+ FAR struct rtl8187x_state_s *priv = (FAR struct rtl8187x_state_s *)dev->d_private;
+
+ /* Add the MAC address to the hardware multicast routing table */
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Function: rtl8187x_rmmac
+ *
+ * Description:
+ * NuttX Callback: Remove the specified MAC address from the hardware multicast
+ * address filtering
+ *
+ * Parameters:
+ * dev - Reference to the NuttX driver state structure
+ * mac - The MAC address to be removed
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IGMP
+static int rtl8187x_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
+{
+ FAR struct rtl8187x_state_s *priv = (FAR struct rtl8187x_state_s *)dev->d_private;
+
+ /* Add the MAC address to the hardware multicast routing table */
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Function: Various low-level EEPROM Support functions
+ *
+ * Description:
+ * NuttX Callback: Remove the specified MAC address from the hardware multicast
+ * address filtering
+ *
+ * Parameters:
+ * priv - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static inline void rtl8187x_eeprom_pulsehigh(FAR struct rtl8187x_state_s *priv)
+{
+ priv->dataclk = 1;
+ rtl8187x_eeprom_wrsetup(priv);
+
+ /* Add a short delay for the pulse to work. According to the specifications
+ * the "maximum minimum" time should be 450ns.
+ */
+
+ usleep(1);
+}
+
+static inline void rtl8187x_eeprom_pulselow(FAR struct rtl8187x_state_s *priv)
+{
+ priv->dataclk = 0;
+ rtl8187x_eeprom_wrsetup(priv);
+
+ /* Add a short delay for the pulse to work. According to the specifications
+ * the "maximum minimum" time should be 450ns.
+ */
+
+ usleep(1);
+}
+
+static void rtl8187x_eeprom_rdsetup(FAR struct rtl8187x_state_s *priv)
+{
+ uint8_t reg = rtl8187x_ioread8(priv, RTL8187X_ADDR_EEPROMCMD);
+
+ priv->datain = reg & RTL8187X_EEPROMCMD_WRITE;
+ priv->dataout = reg & RTL8187X_EEPROMCMD_READ;
+ priv->dataclk = reg & RTL8187X_EEPROMCMD_CK;
+ priv->chipsel = reg & RTL8187X_EEPROMCMD_CS;
+}
+
+static void rtl8187x_eeprom_wrsetup(FAR struct rtl8187x_state_s *priv)
+{
+ uint8_t reg = RTL8187X_EEPROMCMD_PROGRAM;
+
+ if (priv->datain)
+ {
+ reg |= RTL8187X_EEPROMCMD_WRITE;
+ }
+
+ if (priv->dataout)
+ {
+ reg |= RTL8187X_EEPROMCMD_READ;
+ }
+
+ if (priv->dataclk)
+ {
+ reg |= RTL8187X_EEPROMCMD_CK;
+ }
+
+ if (priv->chipsel)
+ {
+ reg |= RTL8187X_EEPROMCMD_CS;
+ }
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, reg);
+ usleep(10);
+}
+
+static void rtl8187x_eeprom_cleanup(FAR struct rtl8187x_state_s *priv)
+{
+ /* Clear chip_select and data_in flags. */
+
+ rtl8187x_eeprom_rdsetup(priv);
+ priv->datain = 0;
+ priv->chipsel = 0;
+ rtl8187x_eeprom_wrsetup(priv);
+
+ /* Kick a pulse. */
+
+ rtl8187x_eeprom_pulsehigh(priv);
+ rtl8187x_eeprom_pulselow(priv);
+}
+
+static void rtl8187x_eeprom_wrbits(FAR struct rtl8187x_state_s *priv,
+ uint16_t data, uint16_t count)
+{
+ unsigned int i;
+
+ rtl8187x_eeprom_rdsetup(priv);
+
+ /* Clear data flags. */
+
+ priv->datain = 0;
+ priv->dataout = 0;
+
+ /* Start writing all bits. */
+
+ for (i = count; i > 0; i--)
+ {
+ /* Check if this bit needs to be set. */
+
+ priv->datain = ! !(data & (1 << (i - 1)));
+
+ /* Write the bit to the eeprom register. */
+
+ rtl8187x_eeprom_wrsetup(priv);
+
+ /* Kick a pulse. */
+
+ rtl8187x_eeprom_pulsehigh(priv);
+ rtl8187x_eeprom_pulselow(priv);
+ }
+
+ priv->datain = 0;
+ rtl8187x_eeprom_wrsetup(priv);
+}
+
+static void rtl8187x_eeprom_rdbits(FAR struct rtl8187x_state_s *priv,
+ FAR uint16_t * data, uint16_t count)
+{
+ unsigned int i;
+ uint16_t buf = 0;
+
+ rtl8187x_eeprom_rdsetup(priv);
+
+ /* Clear data flags. */
+
+ priv->datain = 0;
+ priv->dataout = 0;
+
+ /* Start reading all bits. */
+
+ for (i = count; i > 0; i--)
+ {
+ rtl8187x_eeprom_pulsehigh(priv);
+
+ rtl8187x_eeprom_rdsetup(priv);
+
+ /* Clear data_in flag. */
+
+ priv->datain = 0;
+
+ /* Read if the bit has been set. */
+
+ if (priv->dataout)
+ {
+ buf |= (1 << (i - 1));
+ }
+
+ rtl8187x_eeprom_pulselow(priv);
+ }
+
+ *data = buf;
+}
+
+/****************************************************************************
+ * Function: rtl8187x_eeprom_read
+ *
+ * Description:
+ * Read data from EEPROM
+ *
+ * Parameters:
+ * priv - Reference to the NuttX driver state structure
+ * word -
+ * data - Location for data to be written
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void rtl8187x_eeprom_read(FAR struct rtl8187x_state_s *priv,
+ uint8_t word, uint16_t *data)
+{
+ uint16_t command;
+
+ /* Clear all flags, and enable chip select. */
+
+ rtl8187x_eeprom_rdsetup(priv);
+ priv->datain = 0;
+ priv->dataout = 0;
+ priv->dataclk = 0;
+ priv->chipsel = 1;
+ rtl8187x_eeprom_wrsetup(priv);
+
+ /* Kick a pulse. */
+
+ rtl8187x_eeprom_pulsehigh(priv);
+ rtl8187x_eeprom_pulselow(priv);
+
+ /* Select the read opcode and the word to be read. */
+
+ command = (PCI_EEPROM_READ_OPCODE << priv->width) | word;
+ rtl8187x_eeprom_wrbits(priv, command, PCI_EEPROM_WIDTH_OPCODE + priv->width);
+
+ /* Read the requested 16 bits. */
+
+ rtl8187x_eeprom_rdbits(priv, data, 16);
+
+ /* Cleanup eeprom register. */
+
+ rtl8187x_eeprom_cleanup(priv);
+}
+
+/****************************************************************************
+ * Function: rtl8187x_eeprom_multiread
+ *
+ * Description:
+ * A convenience wrapper around rtl8187x_eeprom_read to obtain multiple
+ * words from the EEPROM.
+ *
+ * Parameters:
+ * priv - Reference to the NuttX driver state structure
+ * word -
+ * data - Location for data to be written
+ * nwords - The number of words to be read
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void rtl8187x_eeprom_multiread(FAR struct rtl8187x_state_s *priv,
+ uint8_t word, FAR uint16_t *data,
+ uint16_t nwords)
+{
+ unsigned int i;
+ uint16_t tmp;
+
+ for (i = 0; i < nwords; i++)
+ {
+ tmp = 0;
+ rtl8187x_eeprom_read(priv, word + i, &tmp);
+ data[i] = rtl8187x_host2le16(tmp);
+ }
+}
+
+/****************************************************************************
+ * Function: PHY support functions
+ *
+ * Description:
+ * Configure PHY
+ *
+ * Parameters:
+ * priv - Private driver state information
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void rtl8187x_wrphy(FAR struct rtl8187x_state_s *priv, uint8_t addr,
+ uint32_t data)
+{
+ data <<= 8;
+ data |= addr | 0x80;
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_PHY3, (data >> 24) & 0xff);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_PHY2, (data >> 16) & 0xff);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_PHY1, (data >> 8) & 0xff);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_PHY0, data & 0xff);
+
+ usleep(1000);
+}
+
+static inline void rtl8187x_wrphyofdm(FAR struct rtl8187x_state_s *priv,
+ uint8_t addr, uint32_t data)
+{
+ rtl8187x_wrphy(priv, addr, data);
+}
+
+static inline void rtl8187x_wrphycck(FAR struct rtl8187x_state_s *priv,
+ uint8_t addr, uint32_t data)
+{
+ rtl8187x_wrphy(priv, addr, data | 0x10000);
+}
+
+/****************************************************************************
+ * Function: rtl8225_rfinit and rtl8225z2_rfinit
+ *
+ * Description:
+ * Chip-specific RF initialization
+ *
+ * Parameters:
+ * priv - Private driver state information
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void rtl8225_rfinit(FAR struct rtl8187x_state_s *priv)
+{
+ unsigned int i;
+
+ uvdbg("rfinit");
+ rtl8187x_write(priv, 0x0, 0x067);
+ usleep(1000);
+ rtl8187x_write(priv, 0x1, 0xFE0);
+ usleep(1000);
+ rtl8187x_write(priv, 0x2, 0x44D);
+ usleep(1000);
+ rtl8187x_write(priv, 0x3, 0x441);
+ usleep(1000);
+ rtl8187x_write(priv, 0x4, 0x486);
+ usleep(1000);
+ rtl8187x_write(priv, 0x5, 0xBC0);
+ usleep(1000);
+ rtl8187x_write(priv, 0x6, 0xAE6);
+ usleep(1000);
+ rtl8187x_write(priv, 0x7, 0x82A);
+ usleep(1000);
+ rtl8187x_write(priv, 0x8, 0x01F);
+ usleep(1000);
+ rtl8187x_write(priv, 0x9, 0x334);
+ usleep(1000);
+ rtl8187x_write(priv, 0xA, 0xFD4);
+ usleep(1000);
+ rtl8187x_write(priv, 0xB, 0x391);
+ usleep(1000);
+ rtl8187x_write(priv, 0xC, 0x050);
+ usleep(1000);
+ rtl8187x_write(priv, 0xD, 0x6DB);
+ usleep(1000);
+ rtl8187x_write(priv, 0xE, 0x029);
+ usleep(1000);
+ rtl8187x_write(priv, 0xF, 0x914);
+ usleep(100000);
+
+ rtl8187x_write(priv, 0x2, 0xC4D);
+ usleep(200000);
+ rtl8187x_write(priv, 0x2, 0x44D);
+ usleep(200000);
+
+ if (!(rtl8187x_read(priv, 6) & (1 << 7)))
+ {
+ rtl8187x_write(priv, 0x02, 0x0c4d);
+ usleep(200000);
+ rtl8187x_write(priv, 0x02, 0x044d);
+ usleep(100000);
+ if (!(rtl8187x_read(priv, 6) & (1 << 7)))
+ {
+ udbg("RF Calibration Failed! %x\n", rtl8187x_read(priv, 6));
+ }
+ }
+
+ rtl8187x_write(priv, 0x0, 0x127);
+
+ for (i = 0; i < ARRAY_SIZE(g_rtl8225bcd_rxgain); i++)
+ {
+ rtl8187x_write(priv, 0x1, i + 1);
+ rtl8187x_write(priv, 0x2, g_rtl8225bcd_rxgain[i]);
+ }
+
+ rtl8187x_write(priv, 0x0, 0x027);
+ rtl8187x_write(priv, 0x0, 0x22F);
+
+ for (i = 0; i < ARRAY_SIZE(g_rtl8225_agc); i++)
+ {
+ rtl8187x_wrphyofdm(priv, 0xB, g_rtl8225_agc[i]);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0xA, 0x80 + i);
+ usleep(1000);
+ }
+
+ usleep(1000);
+
+ rtl8187x_wrphyofdm(priv, 0x00, 0x01);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x01, 0x02);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x02, 0x42);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x03, 0x00);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x04, 0x00);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x05, 0x00);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x06, 0x40);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x07, 0x00);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x08, 0x40);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x09, 0xfe);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x0a, 0x09);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x0b, 0x80);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x0c, 0x01);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x0e, 0xd3);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x0f, 0x38);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x10, 0x84);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x11, 0x06);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x12, 0x20);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x13, 0x20);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x14, 0x00);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x15, 0x40);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x16, 0x00);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x17, 0x40);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x18, 0xef);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x19, 0x19);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x1a, 0x20);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x1b, 0x76);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x1c, 0x04);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x1e, 0x95);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x1f, 0x75);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x20, 0x1f);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x21, 0x27);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x22, 0x16);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x24, 0x46);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x25, 0x20);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x26, 0x90);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x27, 0x88);
+ usleep(1000);
+
+ rtl8187x_wrphyofdm(priv, 0x0d, g_rtl8225_gain[2 * 4]);
+ rtl8187x_wrphyofdm(priv, 0x1b, g_rtl8225_gain[2 * 4 + 2]);
+ rtl8187x_wrphyofdm(priv, 0x1d, g_rtl8225_gain[2 * 4 + 3]);
+ rtl8187x_wrphyofdm(priv, 0x23, g_rtl8225_gain[2 * 4 + 1]);
+
+ rtl8187x_wrphycck(priv, 0x00, 0x98);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x03, 0x20);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x04, 0x7e);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x05, 0x12);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x06, 0xfc);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x07, 0x78);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x08, 0x2e);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x10, 0x9b);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x11, 0x88);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x12, 0x47);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x13, 0xd0);
+ rtl8187x_wrphycck(priv, 0x19, 0x00);
+ rtl8187x_wrphycck(priv, 0x1a, 0xa0);
+ rtl8187x_wrphycck(priv, 0x1b, 0x08);
+ rtl8187x_wrphycck(priv, 0x40, 0x86);
+ rtl8187x_wrphycck(priv, 0x41, 0x8d);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x42, 0x15);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x43, 0x18);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x44, 0x1f);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x45, 0x1e);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x46, 0x1a);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x47, 0x15);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x48, 0x10);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x49, 0x0a);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x4a, 0x05);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x4b, 0x02);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x4c, 0x05);
+ usleep(1000);
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_TESTR, 0x0D);
+
+ rtl8225_settxpower(priv, 1);
+
+ /* RX antenna default to A */
+
+ rtl8187x_wrphycck(priv, 0x10, 0x9b);
+ usleep(1000); /* B: 0xDB */
+ rtl8187x_wrphyofdm(priv, 0x26, 0x90);
+ usleep(1000); /* B: 0x10 */
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_TXANTENNA, 0x03); /* B: 0x00 */
+ usleep(1000);
+ rtl8187x_iowrite32(priv, 0xff94, 0x3dc00002);
+
+ /* Set sensitivity */
+
+ rtl8187x_write(priv, 0x0c, 0x50);
+ rtl8187x_wrphyofdm(priv, 0x0d, g_rtl8225_gain[2 * 4]);
+ rtl8187x_wrphyofdm(priv, 0x1b, g_rtl8225_gain[2 * 4 + 2]);
+ rtl8187x_wrphyofdm(priv, 0x1d, g_rtl8225_gain[2 * 4 + 3]);
+ rtl8187x_wrphyofdm(priv, 0x23, g_rtl8225_gain[2 * 4 + 1]);
+ rtl8187x_wrphycck(priv, 0x41, g_rtl8225_threshold[2]);
+}
+
+static void rtl8225z2_rfinit(FAR struct rtl8187x_state_s *priv)
+{
+ unsigned int i;
+
+ rtl8187x_write(priv, 0x0, 0x2BF);
+ usleep(1000);
+ rtl8187x_write(priv, 0x1, 0xEE0);
+ usleep(1000);
+ rtl8187x_write(priv, 0x2, 0x44D);
+ usleep(1000);
+ rtl8187x_write(priv, 0x3, 0x441);
+ usleep(1000);
+ rtl8187x_write(priv, 0x4, 0x8C3);
+ usleep(1000);
+ rtl8187x_write(priv, 0x5, 0xC72);
+ usleep(1000);
+ rtl8187x_write(priv, 0x6, 0x0E6);
+ usleep(1000);
+ rtl8187x_write(priv, 0x7, 0x82A);
+ usleep(1000);
+ rtl8187x_write(priv, 0x8, 0x03F);
+ usleep(1000);
+ rtl8187x_write(priv, 0x9, 0x335);
+ usleep(1000);
+ rtl8187x_write(priv, 0xa, 0x9D4);
+ usleep(1000);
+ rtl8187x_write(priv, 0xb, 0x7BB);
+ usleep(1000);
+ rtl8187x_write(priv, 0xc, 0x850);
+ usleep(1000);
+ rtl8187x_write(priv, 0xd, 0xCDF);
+ usleep(1000);
+ rtl8187x_write(priv, 0xe, 0x02B);
+ usleep(1000);
+ rtl8187x_write(priv, 0xf, 0x114);
+ usleep(100000);
+
+ rtl8187x_write(priv, 0x0, 0x1B7);
+
+ for (i = 0; i < ARRAY_SIZE(g_rtl8225z2_rxgain); i++)
+ {
+ rtl8187x_write(priv, 0x1, i + 1);
+ rtl8187x_write(priv, 0x2, g_rtl8225z2_rxgain[i]);
+ }
+
+ rtl8187x_write(priv, 0x3, 0x080);
+ rtl8187x_write(priv, 0x5, 0x004);
+ rtl8187x_write(priv, 0x0, 0x0B7);
+ rtl8187x_write(priv, 0x2, 0xc4D);
+
+ usleep(200000);
+ rtl8187x_write(priv, 0x2, 0x44D);
+ usleep(100000);
+
+ if (!(rtl8187x_read(priv, 6) & (1 << 7)))
+ {
+ rtl8187x_write(priv, 0x02, 0x0C4D);
+ usleep(200000);
+ rtl8187x_write(priv, 0x02, 0x044D);
+ usleep(100000);
+ if (!(rtl8187x_read(priv, 6) & (1 << 7)))
+ {
+ udbg("RF Calibration Failed! %x\n", rtl8187x_read(priv, 6));
+ }
+ }
+
+ usleep(200000);
+
+ rtl8187x_write(priv, 0x0, 0x2BF);
+
+ for (i = 0; i < ARRAY_SIZE(g_rtl8225_agc); i++)
+ {
+ rtl8187x_wrphyofdm(priv, 0xB, g_rtl8225_agc[i]);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0xA, 0x80 + i);
+ usleep(1000);
+ }
+
+ usleep(1000);
+
+ rtl8187x_wrphyofdm(priv, 0x00, 0x01);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x01, 0x02);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x02, 0x42);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x03, 0x00);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x04, 0x00);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x05, 0x00);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x06, 0x40);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x07, 0x00);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x08, 0x40);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x09, 0xfe);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x0a, 0x08);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x0b, 0x80);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x0c, 0x01);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x0d, 0x43);
+ rtl8187x_wrphyofdm(priv, 0x0e, 0xd3);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x0f, 0x38);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x10, 0x84);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x11, 0x07);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x12, 0x20);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x13, 0x20);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x14, 0x00);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x15, 0x40);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x16, 0x00);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x17, 0x40);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x18, 0xef);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x19, 0x19);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x1a, 0x20);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x1b, 0x15);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x1c, 0x04);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x1d, 0xc5);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x1e, 0x95);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x1f, 0x75);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x20, 0x1f);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x21, 0x17);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x22, 0x16);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x23, 0x80);
+ usleep(1000); // FIXME: not needed?
+ rtl8187x_wrphyofdm(priv, 0x24, 0x46);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x25, 0x00);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x26, 0x90);
+ usleep(1000);
+ rtl8187x_wrphyofdm(priv, 0x27, 0x88);
+ usleep(1000);
+
+ rtl8187x_wrphyofdm(priv, 0x0b, g_rtl8225z2_gainbg[4 * 3]);
+ rtl8187x_wrphyofdm(priv, 0x1b, g_rtl8225z2_gainbg[4 * 3 + 1]);
+ rtl8187x_wrphyofdm(priv, 0x1d, g_rtl8225z2_gainbg[4 * 3 + 2]);
+ rtl8187x_wrphyofdm(priv, 0x21, 0x37);
+
+ rtl8187x_wrphycck(priv, 0x00, 0x98);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x03, 0x20);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x04, 0x7e);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x05, 0x12);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x06, 0xfc);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x07, 0x78);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x08, 0x2e);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x10, 0x9b);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x11, 0x88);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x12, 0x47);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x13, 0xd0);
+ rtl8187x_wrphycck(priv, 0x19, 0x00);
+ rtl8187x_wrphycck(priv, 0x1a, 0xa0);
+ rtl8187x_wrphycck(priv, 0x1b, 0x08);
+ rtl8187x_wrphycck(priv, 0x40, 0x86);
+ rtl8187x_wrphycck(priv, 0x41, 0x8d);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x42, 0x15);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x43, 0x18);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x44, 0x36);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x45, 0x35);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x46, 0x2e);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x47, 0x25);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x48, 0x1c);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x49, 0x12);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x4a, 0x09);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x4b, 0x04);
+ usleep(1000);
+ rtl8187x_wrphycck(priv, 0x4c, 0x05);
+ usleep(1000);
+
+ rtl8187x_iowrite8(priv, 0xff5B, 0x0D);
+ usleep(1000);
+
+ rtl8225z2_settxpower(priv, 1);
+
+ /* RX antenna default to A */
+
+ rtl8187x_wrphycck(priv, 0x10, 0x9b);
+ usleep(1000); /* B: 0xDB */
+ rtl8187x_wrphyofdm(priv, 0x26, 0x90);
+ usleep(1000); /* B: 0x10 */
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_TXANTENNA, 0x03); /* B: 0x00 */
+ usleep(1000);
+ rtl8187x_iowrite32(priv, 0xff94, 0x3dc00002);
+}
+
+/****************************************************************************
+ * Function: rtl8187x_anaparam2on and rtl8187x_anaparamon
+ *
+ * Description:
+ * Chip-specific TX power configuration
+ *
+ * Parameters:
+ * priv - Private driver state information
+ * channel - The selected channel
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void rtl8187x_anaparam2on(FAR struct rtl8187x_state_s *priv)
+{
+ uint8_t regval;
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL8187X_EEPROMCMD_CONFIG);
+ regval = rtl8187x_ioread8(priv, RTL8187X_ADDR_CONFIG3);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CONFIG3, regval | RTL8187X_CONFIG3_ANAPARAMWRITE);
+#ifdef CONFIG_RTL8187B
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_ANAPARAM2, RTL8187B_RTL8225_ANAPARAM2_ON);
+#else
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_ANAPARAM2, RTL8187X_RTL8225_ANAPARAM2_ON);
+#endif
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CONFIG3, regval & ~RTL8187X_CONFIG3_ANAPARAMWRITE);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL8187X_EEPROMCMD_NORMAL);
+}
+
+static void rtl8187x_anaparamon(FAR struct rtl8187x_state_s *priv)
+{
+ uint8_t regval;
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL8187X_EEPROMCMD_CONFIG);
+ regval = rtl8187x_ioread8(priv, RTL8187X_ADDR_CONFIG3);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CONFIG3, regval | RTL8187X_CONFIG3_ANAPARAMWRITE);
+
+#ifdef CONFIG_RTL8187B
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_ANAPARAM, RTL8187B_RTL8225_ANAPARAM_ON);
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_ANAPARAM2, RTL8187B_RTL8225_ANAPARAM2_ON);
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_ANAPARAM3, RTL8187B_RTL8225_ANAPARAM3_ON);
+#else
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_ANAPARAM, RTL8187X_RTL8225_ANAPARAM_ON);
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_ANAPARAM2, RTL8187X_RTL8225_ANAPARAM2_ON);
+#endif
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CONFIG3, regval & ~RTL8187X_CONFIG3_ANAPARAMWRITE);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL8187X_EEPROMCMD_NORMAL);
+}
+
+static void rtl8187x_anaparamoff(FAR struct rtl8187x_state_s *priv)
+{
+ uint8_t regval;
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL8187X_EEPROMCMD_CONFIG);
+ regval = rtl8187x_ioread8(priv, RTL8187X_ADDR_CONFIG3);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CONFIG3, regval | RTL8187X_CONFIG3_ANAPARAMWRITE);
+
+#ifdef CONFIG_RTL8187B
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_ANAPARAM, RTL8187B_RTL8225_ANAPARAM_OFF);
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_ANAPARAM2, RTL8187B_RTL8225_ANAPARAM2_OFF);
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_ANAPARAM3, RTL8187B_RTL8225_ANAPARAM3_OFF);
+#else
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_ANAPARAM, RTL8187X_RTL8225_ANAPARAM_OFF);
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_ANAPARAM2, RTL8187X_RTL8225_ANAPARAM2_OFF);
+#endif
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CONFIG3, regval & ~RTL8187X_CONFIG3_ANAPARAMWRITE);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL8187X_EEPROMCMD_NORMAL);
+}
+
+/****************************************************************************
+ * Function: rtl8225_settxpower and
+ *
+ * Description:
+ * Chip-specific TX power configuration
+ *
+ * Parameters:
+ * priv - Private driver state information
+ * channel - The selected channel
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void rtl8225_settxpower(FAR struct rtl8187x_state_s *priv, int channel)
+{
+ uint8_t cck_power, ofdm_power;
+ const uint8_t *tmp;
+ int i;
+
+ cck_power = priv->channels[channel - 1].val & 0xf;
+ ofdm_power = priv->channels[channel - 1].val >> 4;
+
+ cck_power = MIN(cck_power, (uint8_t) 11);
+ ofdm_power = MIN(ofdm_power, (uint8_t) 35);
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_TXGAINCCK,
+ g_rtl8225_txgaincckofdm[cck_power / 6] >> 1);
+
+ if (channel == 14)
+ {
+ tmp = &g_rtl8225_txpowercckch14[(cck_power % 6) * 8];
+ }
+ else
+ {
+ tmp = &g_rtl8225_txpowercck[(cck_power % 6) * 8];
+ }
+
+ for (i = 0; i < 8; i++)
+ {
+ rtl8187x_wrphycck(priv, 0x44 + i, *tmp++);
+ }
+ usleep(1000); // FIXME: optional?
+
+ /* anaparam2 on */
+
+ rtl8187x_anaparam2on(priv);
+
+ rtl8187x_wrphyofdm(priv, 2, 0x42);
+ rtl8187x_wrphyofdm(priv, 6, 0x00);
+ rtl8187x_wrphyofdm(priv, 8, 0x00);
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_TXGAINOFDM,
+ g_rtl8225_txgaincckofdm[ofdm_power / 6] >> 1);
+
+ tmp = &g_rtl8225_txpowerofdm[ofdm_power % 6];
+
+ rtl8187x_wrphyofdm(priv, 5, *tmp);
+ rtl8187x_wrphyofdm(priv, 7, *tmp);
+
+ usleep(1000);
+}
+
+static void rtl8225z2_settxpower(FAR struct rtl8187x_state_s *priv, int channel)
+{
+ uint8_t cck_power;
+ uint8_t ofdm_power;
+ const uint8_t *tmp;
+ int i;
+
+ cck_power = priv->channels[channel - 1].val & 0xF;
+ ofdm_power = priv->channels[channel - 1].val >> 4;
+
+ cck_power = MIN(cck_power, (uint8_t) 15);
+ cck_power += priv->rxpwrbase & 0xF;
+ cck_power = MIN(cck_power, (uint8_t) 35);
+
+ ofdm_power = MIN(ofdm_power, (uint8_t) 15);
+ ofdm_power += priv->rxpwrbase >> 4;
+ ofdm_power = MIN(ofdm_power, (uint8_t) 35);
+
+ if (channel == 14)
+ {
+ tmp = g_rtl8225z2_txpowercckch14;
+ }
+ else
+ {
+ tmp = g_rtl8225z2_txpowercck;
+ }
+
+ for (i = 0; i < 8; i++)
+ {
+ rtl8187x_wrphycck(priv, 0x44 + i, *tmp++);
+ }
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_TXGAINCCK,
+ g_rtl8225z2_txgaincckofdm[cck_power]);
+ usleep(1000);
+
+ /* anaparam2 on */
+
+ rtl8187x_anaparam2on(priv);
+
+ rtl8187x_wrphyofdm(priv, 2, 0x42);
+ rtl8187x_wrphyofdm(priv, 5, 0x00);
+ rtl8187x_wrphyofdm(priv, 6, 0x40);
+ rtl8187x_wrphyofdm(priv, 7, 0x00);
+ rtl8187x_wrphyofdm(priv, 8, 0x40);
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_TXGAINOFDM,
+ g_rtl8225z2_txgaincckofdm[ofdm_power]);
+ usleep(1000);
+}
+
+/****************************************************************************
+ * Function: rtl8187x_reset
+ *
+ * Description:
+ * Reset and initialize hardware
+ *
+ * Parameters:
+ * priv - Private driver state information
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int rtl8187x_reset(struct rtl8187x_state_s *priv)
+{
+ uint8_t regval;
+ int i;
+
+#ifdef CONFIG_RTL8187B
+ int ret;
+
+ /* Turn on ANAPARAM */
+
+ rtl8187x_anaparamon(priv)
+
+ /* Reset PLL sequence on 8187B. Realtek note: reduces power
+ * consumption about 30 mA
+ */
+
+ rtl8187x_iowrite8(priv, (uint8_t*)0xff61, 0x10);
+ regval = rtl818x_ioread8(priv, (uint8_t*)0xff62);
+ rtl8187x_iowrite8(priv, (uint8_t*)0xff62, regval & ~(1 << 5));
+ rtl8187x_iowrite8(priv, (uint8_t*)0xff62, regval | (1 << 5));
+
+ ret = rtl8187_cmd_reset(dev);
+ if (ret != 0)
+ {
+ return ret;
+ }
+ rtl8187x_anaparamon(priv)
+
+ /* BRSR (Basic Rate Set Register) on 8187B looks to be the same as
+ * RESP_RATE on 8187L in Realtek sources: each bit should be each
+ * one of the 12 rates, all are enabled
+ */
+
+ rtl8187x_iowrite16(priv, (uint16_t*)0xff34, 0x0fff);
+
+ regval = rtl818x_ioread8(priv, RTL8187X_ADDR_CWCONF);
+ regval |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CWCONF, regval);
+
+ /* Auto Rate Fallback Register (ARFR): 1M-54M setting */
+
+ rtl8187x_iowrite16_idx(priv, (uint16_t*)0xffe0, 0x0fff, 1);
+ rtl8187x_iowrite8_idx(priv, (uint8_t*)0xffe2, 0x00, 1);
+ rtl8187x_iowrite16_idx(priv, (uint16_t*)0xffd4, 0xffff, 1);
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL818X_EEPROMCMD_CONFIG);
+ regval = rtl818x_ioread8(priv, RTL8187X_ADDR_CONFIG1);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CONFIG1, (regval & 0x3f) | 0x80);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL818X_EEPROMCMD_NORMAL);
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_WPACONF, 0);
+ for (i = 0; i < ARRAY_SIZE(rtl8187b_reg_table); i++) {
+ rtl8187x_iowrite8_idx(priv,
+ (uint8_t*)(uintptr_t)
+ (rtl8187b_reg_table[i][0] | 0xff00),
+ rtl8187b_reg_table[i][1],
+ rtl8187b_reg_table[i][2]);
+ }
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_TIDACMAP, 0xfa50);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_INTMIG, 0);
+
+ rtl8187x_iowrite32_idx(priv, (uint32_t*)0xfff0, 0, 1);
+ rtl8187x_iowrite32_idx(priv, (uint32_t*)0xfff4, 0, 1);
+ rtl8187x_iowrite8_idx(priv, (uint8_t*)0xfff8, 0, 1);
+
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_RFTIMING, 0x00004001);
+
+ /* RFSW_CTRL register */
+
+ rtl8187x_iowrite16_idx(priv, (uint16_t*)0xff72, 0x569a, 2);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, 0x0480);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSSELECT, 0x2488);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSENABLE, 0x1fff);
+ msleep(100);
+
+ priv->rf->init(dev);
+
+ regval = RTL818X_CMD_TX_ENABLE | RTL818X_CMD_RX_ENABLE;
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CMD, regval);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_INTMASK, 0xffff);
+
+ rtl8187x_iowrite8(priv, (uint8_t*)0xfe41, 0xf4);
+ rtl8187x_iowrite8(priv, (uint8_t*)0xfe40, 0x00);
+ rtl8187x_iowrite8(priv, (uint8_t*)0xfe42, 0x00);
+ rtl8187x_iowrite8(priv, (uint8_t*)0xfe42, 0x01);
+ rtl8187x_iowrite8(priv, (uint8_t*)0xfe40, 0x0f);
+ rtl8187x_iowrite8(priv, (uint8_t*)0xfe42, 0x00);
+ rtl8187x_iowrite8(priv, (uint8_t*)0xfe42, 0x01);
+
+ regval = rtl818x_ioread8(priv, (uint8_t*)0xffdb);
+ rtl8187x_iowrite8(priv, (uint8_t*)0xffdb, regval | (1 << 2));
+ rtl8187x_iowrite16_idx(priv, (uint16_t*)0xff72, 0x59fa, 3);
+ rtl8187x_iowrite16_idx(priv, (uint16_t*)0xff74, 0x59d2, 3);
+ rtl8187x_iowrite16_idx(priv, (uint16_t*)0xff76, 0x59d2, 3);
+ rtl8187x_iowrite16_idx(priv, (uint16_t*)0xff78, 0x19fa, 3);
+ rtl8187x_iowrite16_idx(priv, (uint16_t*)0xff7a, 0x19fa, 3);
+ rtl8187x_iowrite16_idx(priv, (uint16_t*)0xff7c, 0x00d0, 3);
+ rtl8187x_iowrite8(priv, (uint8_t*)0xff61, 0);
+ rtl8187x_iowrite8_idx(priv, (uint8_t*)0xff80, 0x0f, 1);
+ rtl8187x_iowrite8_idx(priv, (uint8_t*)0xff83, 0x03, 1);
+ rtl8187x_iowrite8(priv, (uint8_t*)0xffda, 0x10);
+ rtl8187x_iowrite8_idx(priv, (uint8_t*)0xff4d, 0x08, 2);
+
+ rtl8187x_iowrite32(priv, rtl8187x_addr_hssipara, 0x0600321b);
+ rtl8187x_iowrite16_idx(priv, (uint16_t*)0xffec, 0x0800, 1);
+
+ priv->slot_time = 0x9;
+ priv->aifsn[0] = 2; /* AIFSN[AC_VO] */
+ priv->aifsn[1] = 2; /* AIFSN[AC_VI] */
+ priv->aifsn[2] = 7; /* AIFSN[AC_BK] */
+ priv->aifsn[3] = 3; /* AIFSN[AC_BE] */
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_ACMCONTROL, 0);
+
+ /* ENEDCA flag must always be set, transmit issues? */
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_MSR, RTL818X_MSR_ENEDCA);
+#else
+
+ /* reset */
+
+ rtl8187x_anaparamon(priv);
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_INTMASK, 0);
+
+ usleep(200000);
+ rtl8187x_iowrite8(priv, 0xfe18, 0x10);
+ rtl8187x_iowrite8(priv, 0xfe18, 0x11);
+ rtl8187x_iowrite8(priv, 0xfe18, 0x00);
+ usleep(200000);
+
+ regval = rtl8187x_ioread8(priv, RTL8187X_ADDR_CMD);
+ regval &= (1 << 1);
+ regval |= RTL8187X_CMD_RESET;
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CMD, regval);
+
+ i = 10;
+ do
+ {
+ usleep(2000);
+ if (!(rtl8187x_ioread8(priv, RTL8187X_ADDR_CMD) & RTL8187X_CMD_RESET))
+ break;
+ }
+ while (--i);
+
+ if (!i)
+ {
+ udbg("Reset timeout!\n");
+ return -ETIMEDOUT;
+ }
+
+ /* Reload registers from eeprom */
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL8187X_EEPROMCMD_LOAD);
+
+ i = 10;
+ do
+ {
+ usleep(4000);
+ if (!(rtl8187x_ioread8(priv, RTL8187X_ADDR_EEPROMCMD) &
+ RTL8187X_EEPROMCMD_CONFIG))
+ break;
+ }
+ while (--i);
+
+ if (!i)
+ {
+ udbg("%s: eeprom reset timeout!\n");
+ return -ETIMEDOUT;
+ }
+
+ rtl8187x_anaparamon(priv);
+
+ /* Setup card */
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSSELECT, 0);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_GPIO, 0);
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSSELECT, (4 << 8));
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_GPIO, 1);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_GPENABLE, 0);
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL8187X_EEPROMCMD_CONFIG);
+
+ rtl8187x_iowrite16(priv, 0xffF4, 0xffFF);
+ regval = rtl8187x_ioread8(priv, RTL8187X_ADDR_CONFIG1);
+ regval &= 0x3F;
+ regval |= 0x80;
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CONFIG1, regval);
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL8187X_EEPROMCMD_NORMAL);
+
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_INTTIMEOUT, 0);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_WPACONF, 0);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_RATEFALLBACK, 0x81);
+
+ // TODO: set RESP_RATE and BRSR properly
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_RESPRATE, (8 << 4) | 0);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_BRSR, 0x01F3);
+
+ /* host_usb_init */
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSSELECT, 0);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_GPIO, 0);
+ regval = rtl8187x_ioread8(priv, 0xfe53);
+ rtl8187x_iowrite8(priv, 0xfe53, regval | (1 << 7));
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSSELECT, (4 << 8));
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_GPIO, 0x20);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_GPENABLE, 0);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSOUTPUT, 0x80);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSSELECT, 0x80);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSENABLE, 0x80);
+
+ usleep(100000);
+
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_RFTIMING, 0x000a8008);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_BRSR, 0xffFF);
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_RFPARA, 0x00100044);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL8187X_EEPROMCMD_CONFIG);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CONFIG3, 0x44);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL8187X_EEPROMCMD_NORMAL);
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_RFPINSENABLE, 0x1FF7);
+ usleep(100000);
+
+ priv->rfinit(priv);
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_BRSR, 0x01F3);
+ regval = rtl8187x_ioread8(priv, RTL8187X_ADDR_PGSELECT) & ~1;
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_PGSELECT, regval | 1);
+ rtl8187x_iowrite16(priv, 0xffFE, 0x10);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_TALLYSEL, 0x80);
+ rtl8187x_iowrite8(priv, 0xffFF, 0x60);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_PGSELECT, regval);
+#endif
+
+ return OK;
+}
+
+/****************************************************************************
+ * Function: rtl8187x_setchannel
+ *
+ * Description:
+ * Select the specified channel
+ *
+ * Parameters:
+ * priv - Private driver state information
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void rtl8187x_setchannel(FAR struct rtl8187x_state_s *priv, int channel)
+{
+ uint32_t regval;
+
+ regval = rtl8187x_ioread32(priv, RTL8187X_ADDR_TXCONF);
+
+ /* Enable TX loopback on MAC level to avoid TX during channel changes, as
+ * this has be seen to causes problems and the card will stop work until next
+ * reset
+ */
+
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_TXCONF,
+ regval | RTL8187X_TXCONF_LOOPBACKMAC);
+ usleep(10000);
+
+ priv->settxpower(priv, channel);
+
+ rtl8187x_write(priv, 0x7, g_chanselect[channel - 1]);
+ usleep(20000);
+
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_TXCONF, regval);
+}
+
+/****************************************************************************
+ * Function: rtl8187_start
+ *
+ * Description:
+ * Bring up the RTL8187
+ *
+ * Parameters:
+ * priv - Private driver state information
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int rtl8187x_start(FAR struct rtl8187x_state_s *priv)
+{
+ uint32_t regval;
+ int ret;
+
+ /* Reset and initialize the hardware */
+
+ ret = rtl8187x_reset(priv);
+ if (ret != OK)
+ {
+ return ret;
+ }
+
+#ifdef CONFIG_RTL8187B
+
+ regval = RTL818X_RXCONF_MGMT | RTL818X_RXCONF_DATA | RTL818X_RXCONF_BROADCAST |
+ RTL818X_RXCONF_NICMAC | RTL818X_RX_ONF_BSSID |
+ (7 << 13 /* RX FIFO threshold NONE */) |
+ (7 << 10 /* MAX RX DMA */) |
+ RTL818X_RXCONF_RX_AUTORESETPHY | RTL818X_RXCONF_ONLYERLPKT | RTL818X_RXCONF_MULTICAST;
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_RXCONF, regval);
+
+ regval = rtl8187x_ioread8(priv, RTL8187X_ADDR_TXAGCCTL);
+ regval &= ~RTL8187X_TXAGCCTL_PERPACKETGAINSHIFT;
+ regval &= ~RTL8187X_TXAGCCTL_PERPACKETANTSELSHIFT;
+ regval &= ~RTL8187X_TXAGCCTL_FEEDBACKANT;
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_TXAGCCTL, regval);
+
+ regval = RTL818X_TXCONF_HWSEQNUM | RTL818X_TXCONF_DISREQQSIZE |
+ (7 << 8 /* short retry limit */) |
+ (7 << 0 /* long retry limit */) |
+ (7 << 21 /* MAX TX DMA */);
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_TXCONF, regval);
+
+#else
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_INTMASK, 0xffff);
+
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_MAR0, ~0);
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_MAR1, ~0);
+
+ regval = RTL8187X_RXCONF_ONLYERLPKT | RTL8187X_RXCONF_RXAUTORESETPHY | RTL8187X_RXCONF_BSSID |
+ RTL8187X_RXCONF_MGMT | RTL8187X_RXCONF_DATA | RTL8187X_RXCONF_CTRL |
+ (7 << 13 /* RX fifo threshold none */ ) |
+ (7 << 10 /* MAX RX DMA */ ) |
+ RTL8187X_RXCONF_BROADCAST | RTL8187X_RXCONF_NICMAC | RTL8187X_RXCONF_MONITOR;
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_RXCONF, regval);
+
+ regval = rtl8187x_ioread8(priv, RTL8187X_ADDR_CWCONF);
+ regval &= ~RTL8187X_CWCONF_PERPACKETCWSHIFT;
+ regval |= RTL8187X_CWCONF_PERPACKETRETRYSHIFT;
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CWCONF, regval);
+
+ regval = rtl8187x_ioread8(priv, RTL8187X_ADDR_TXAGCCTL);
+ regval &= ~RTL8187X_TXAGCCTL_PERPACKETGAINSHIFT;
+ regval &= ~RTL8187X_TXAGCCTL_PERPACKETANTSELSHIFT;
+ regval &= ~RTL8187X_TXAGCCTL_FEEDBACKANT;
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_TXAGCCTL, regval);
+
+ regval = RTL8187X_TXCONF_CWMIN | (7 << 21 /* MAX TX DMA */ ) | RTL8187X_TXCONF_NOICV;
+ rtl8187x_iowrite32(priv, RTL8187X_ADDR_TXCONF, regval);
+
+ regval = rtl8187x_ioread8(priv, RTL8187X_ADDR_CMD);
+ regval |= RTL8187X_CMD_TXENABLE;
+ regval |= RTL8187X_CMD_RXENABLE;
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CMD, regval);
+#endif
+ return OK;
+}
+
+/****************************************************************************
+ * Function: rtl8187x_stop
+ *
+ * Description:
+ * Bring down the RTL8187
+ *
+ * Parameters:
+ * priv - Private driver state information
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void rtl8187x_stop(FAR struct rtl8187x_state_s *priv)
+{
+ uint32_t regval;
+
+ rtl8187x_iowrite16(priv, RTL8187X_ADDR_INTMASK, 0);
+
+ regval = rtl8187x_ioread8(priv, RTL8187X_ADDR_CMD);
+ regval &= ~RTL8187X_CMD_TXENABLE;
+ regval &= ~RTL8187X_CMD_RXENABLE;
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CMD, regval);
+
+ rtl8187x_write(priv, 0x4, 0x1f);
+ usleep(1000);
+
+ /* RF stop */
+
+ rtl8187x_anaparamoff(priv);
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL8187X_EEPROMCMD_CONFIG);
+ regval = rtl8187x_ioread8(priv, RTL8187X_ADDR_CONFIG4);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_CONFIG4, regval | RTL8187X_CONFIG4_VCOOFF);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL8187X_EEPROMCMD_NORMAL);
+}
+
+/****************************************************************************
+ * Function: rtl8187_setup
+ *
+ * Description:
+ * Configure the RTL8187
+ *
+ * Parameters:
+ * priv - Private driver state information
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int rtl8187x_setup(FAR struct rtl8187x_state_s *priv)
+{
+ struct ieee80211_channel_s *channel;
+ uint16_t permaddr[3];
+ uint16_t txpwr, regval;
+ int i;
+
+ /* Copy the default channel information */
+
+ memcpy(priv->channels, g_channels, RTL8187X_NCHANNELS*sizeof(struct ieee80211_channel_s));
+
+ /* Get the EEPROM width */
+
+ if (rtl8187x_ioread32(priv, RTL8187X_ADDR_RXCONF) & (1 << 6))
+ {
+ priv->width = PCI_EEPROM_WIDTH_93C66;
+ }
+ else
+ {
+ priv->width = PCI_EEPROM_WIDTH_93C46;
+ }
+
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL8187X_EEPROMCMD_CONFIG);
+ usleep(10);
+
+ rtl8187x_eeprom_multiread(priv, RTL8187X_EEPROM_MACADDR, permaddr, 3);
+ udbg("MAC address: %04x.%04x.%04x", permaddr[0], permaddr[1], permaddr[2]);
+
+ channel = priv->channels;
+ for (i = 0; i < 3; i++)
+ {
+ rtl8187x_eeprom_read(priv, RTL8187X_EEPROM_TXPWRCHAN1 + i, &txpwr);
+ (*channel++).val = txpwr & 0xff;
+ (*channel++).val = txpwr >> 8;
+ }
+
+ for (i = 0; i < 2; i++)
+ {
+ rtl8187x_eeprom_read(priv, RTL8187X_EEPROM_TXPWRCHAN4 + i, &txpwr);
+ (*channel++).val = txpwr & 0xff;
+ (*channel++).val = txpwr >> 8;
+ }
+
+#ifdef CONFIG_RTL8187B
+
+ rtl8187x_eeprom_read(&priv, RTL8187_EEPROM_TXPWR_CHAN_6, &txpwr);
+ (*channel++).val = txpwr & 0xff;
+
+ rtl8187x_eeprom_read(&priv, 0x0a, &txpwr);
+ (*channel++).val = txpwr & 0xff;
+
+ rtl8187x_eeprom_read(&priv, 0x1c, &txpwr);
+ (*channel++).val = txpwr & 0xff;
+ (*channel++).val= txpwr
+
+#else
+
+ for (i = 0; i < 2; i++)
+ {
+ rtl8187x_eeprom_read(priv, RTL8187X_EEPROM_TXPWRCHAN6 + i, &txpwr);
+ (*channel++).val = txpwr & 0xff;
+ (*channel++).val = txpwr >> 8;
+ }
+
+#endif
+
+ rtl8187x_eeprom_read(priv, RTL8187X_EEPROM_TXPWRBASE, &priv->rxpwrbase);
+
+ regval = rtl8187x_ioread8(priv, RTL8187X_ADDR_PGSELECT) & ~1;
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_PGSELECT, regval | 1);
+
+ /* 0 means asic B-cut, we should use SW 3 wire bit-by-bit banging for radio.
+ * 1 means we can use USB specific request to write radio registers
+ */
+
+ priv->asicrev = rtl8187x_ioread8(priv, 0xffFE) & 0x3;
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_PGSELECT, regval);
+ rtl8187x_iowrite8(priv, RTL8187X_ADDR_EEPROMCMD, RTL8187X_EEPROMCMD_NORMAL);
+
+ rtl8187x_write(priv, 0, 0x1b7);
+
+ if (rtl8187x_read(priv, 8) != 0x588 || rtl8187x_read(priv, 9) != 0x700)
+ {
+ priv->rfinit = rtl8225_rfinit;
+ priv->settxpower = rtl8225_settxpower;
+ }
+ else
+ {
+ priv->rfinit = rtl8225z2_rfinit;
+ priv->settxpower = rtl8225z2_settxpower;
+
+ }
+
+ rtl8187x_write(priv, 0, 0x0b7);
+
+ /* Save the MAC address in the device structure */
+
+ priv->ethdev.d_mac.ether_addr_octet[0] = permaddr[0] & 0xff;
+ priv->ethdev.d_mac.ether_addr_octet[1] = permaddr[0] >> 8;
+ priv->ethdev.d_mac.ether_addr_octet[2] = permaddr[1] & 0xff;
+ priv->ethdev.d_mac.ether_addr_octet[3] = permaddr[1] >> 8;
+ priv->ethdev.d_mac.ether_addr_octet[4] = permaddr[2] & 0xff;
+ priv->ethdev.d_mac.ether_addr_octet[5] = permaddr[2] >> 8;
+
+ /* Provide information about the RTL device */
+
+ udbg("hwaddr %02x.%02x.%02x.%02x.%02x.%02x, rtl8187 V%d + %s\n",
+ priv->ethdev.d_mac.ether_addr_octet[0], priv->ethdev.d_mac.ether_addr_octet[1],
+ priv->ethdev.d_mac.ether_addr_octet[2], priv->ethdev.d_mac.ether_addr_octet[3],
+ priv->ethdev.d_mac.ether_addr_octet[4], priv->ethdev.d_mac.ether_addr_octet[5],
+ priv->asicrev,
+ priv->rfinit == rtl8225_rfinit ? "rtl8225" : "rtl8225z2");
+
+ return 0;
+}
+
+/****************************************************************************
+ * Function: rtl8187x_netinitialize
+ *
+ * Description:
+ * Initialize the WLAN controller and driver
+ *
+ * Parameters:
+ * intf - In the case where there are multiple EMACs, this value
+ * identifies which EMAC is to be initialized.
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int rtl8187x_netinitialize(FAR struct rtl8187x_state_s *priv)
+{
+ int ret;
+
+ /* Initialize the RTL8187x */
+
+ ret = rtl8187x_setup(priv);
+ if (ret == OK)
+ {
+ /* Put the interface in the down state. */
+
+ rtl8187x_ifdown(&priv->ethdev);
+
+ /* Register the device with the OS so that socket IOCTLs can be performed */
+
+ (void)netdev_register(&priv->ethdev);
+ }
+ return OK;
+}
+
+/****************************************************************************
+ * Function: rtl8187x_netuninitialize
+ *
+ * Description:
+ * Un-initialize the RTL8187x. This only happens when the RTL8187x device
+ * is removed from the USB slot.
+ *
+ * Parameters:
+ * intf - In the case where there are multiple EMACs, this value
+ * identifies which EMAC is to be initialized.
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int rtl8187x_netuninitialize(FAR struct rtl8187x_state_s *priv)
+{
+ irqstate_t flags;
+
+ /* Cancel the TX and RX poll timers */
+
+ flags = irqsave();
+ wd_cancel(priv->wdtxpoll);
+ wd_cancel(priv->wdrxpoll);
+
+ /* Mark the device "down" */
+
+ priv->bifup = false;
+ irqrestore(flags);
+
+ /* Unregister the device */
+
+ (void)netdev_unregister(&priv->ethdev);
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: usbhost_wlaninit
+ *
+ * Description:
+ * Initialize the USB class driver. This function should be called
+ * be platform-specific code in order to initialize and register support
+ * for the USB host class device.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Values:
+ * On success this function will return zero (OK); A negated errno value
+ * will be returned on failure.
+ *
+ ****************************************************************************/
+
+int usbhost_wlaninit(void)
+{
+ /* Advertise our availability to support RTL8187x devices */
+
+ uvdbg("Register RTL8187x driver\n");
+ return usbhost_registerclass(&g_wlan);
+}
+
+#endif /* CONFIG_USBHOST && CONFIG_NET && CONFIG_NET_WLAN */
+
+
diff --git a/misc/drivers/rtl8187x/rtl8187x.h b/misc/drivers/rtl8187x/rtl8187x.h
new file mode 100644
index 000000000..8783f1e92
--- /dev/null
+++ b/misc/drivers/rtl8187x/rtl8187x.h
@@ -0,0 +1,475 @@
+/****************************************************************************
+ * drivers/usbhost/rtl8187.h
+ *
+ * This file is part of NuttX:
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011 Rafael Noronha. All rights reserved.
+ * Authors: Gregoyr Nutt <gnutt@nuttx.org>
+ * Rafael Noronha <rafael@pdsolucoes.com.br>
+ *
+ * Portions of the logic in this file derives from the KisMAC RTL8187x driver
+ *
+ * Created by pr0gg3d on 02/24/08.
+ *
+ * Which, in turn, came frm the SourceForge rt2x00 project:
+ *
+ * Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
+ * <http://rt2x00.serialmonkey.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * There are probably also pieces from the Linux RTL8187x driver
+ *
+ * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
+ * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Based on the r8187 driver, which is:
+ * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *
+ ****************************************************************************/
+
+#ifndef __DRIVERS_NET_RTL8187X_H
+#define __DRIVERS_NET_RTL8187X_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* CSR Bit Field Definitions ************************************************/
+
+/* Refers to "cmd" field of "rtl8187x_csr_s" struct */
+
+#define RTL8187X_CMD_TXENABLE (1 << 2)
+#define RTL8187X_CMD_RXENABLE (1 << 3)
+#define RTL8187X_CMD_RESET (1 << 4)
+
+/* Refers to "status" field of "rtl8187x_csr_s" struct */
+
+#define RTL8187X_INT_RXOK (1 << 0)
+#define RTL8187X_INT_RXERR (1 << 1)
+#define RTL8187X_INT_TXLOK (1 << 2)
+#define RTL8187X_INT_TXLERR (1 << 3)
+#define RTL8187X_INT_RXDU (1 << 4)
+#define RTL8187X_INT_RXFO (1 << 5)
+#define RTL8187X_INT_TXNOK (1 << 6)
+#define RTL8187X_INT_TXNERR (1 << 7)
+#define RTL8187X_INT_TXHOK (1 << 8)
+#define RTL8187X_INT_TXHERR (1 << 9)
+#define RTL8187X_INT_TXBOK (1 << 10)
+#define RTL8187X_INT_TXBERR (1 << 11)
+#define RTL8187X_INT_ATIM (1 << 12)
+#define RTL8187X_INT_BEACON (1 << 13)
+#define RTL8187X_INT_TIMEOUT (1 << 14)
+#define RTL8187X_INT_TXFO (1 << 15)
+
+/* Refers to "tx_conf" field of "rtl8187x_csr_s" struct */
+
+#define RTL8187X_TXCONF_LOOPBACKMAC (1 << 17)
+#define RTL8187X_TXCONF_LOOPBACKCONT (3 << 17)
+#define RTL8187X_TXCONF_NOICV (1 << 19)
+#define RTL8187X_TXCONF_DISCW (1 << 20)
+#define RTL8187X_TXCONF_SATHWPLCP (1 << 24)
+#define RTL8187X_TXCONF_R8180ABCD (2 << 25)
+#define RTL8187X_TXCONF_R8180F (3 << 25)
+#define RTL8187X_TXCONF_R8185ABC (4 << 25)
+#define RTL8187X_TXCONF_R8185D (5 << 25)
+#define RTL8187X_TXCONF_R8187VD (5 << 25)
+#define RTL8187X_TXCONF_R8187VDB (6 << 25)
+#define RTL8187X_TXCONF_HWVERMASK (7 << 25)
+#define RTL8187X_TXCONF_DISREQQSIZE (1 << 28)
+#define RTL8187X_TXCONF_PROBEDTS (1 << 29)
+#define RTL8187X_TXCONF_HWSEQNUM (1 << 30)
+#define RTL8187X_TXCONF_CWMIN (1 << 31)
+
+/* Refers to "rx_conf" field of "rtl8187x_csr_s" struct */
+
+#define RTL8187X_RXCONF_MONITOR (1 << 0)
+#define RTL8187X_RXCONF_NICMAC (1 << 1)
+#define RTL8187X_RXCONF_MULTICAST (1 << 2)
+#define RTL8187X_RXCONF_BROADCAST (1 << 3)
+#define RTL8187X_RXCONF_FCS (1 << 5)
+#define RTL8187X_RXCONF_DATA (1 << 18)
+#define RTL8187X_RXCONF_CTRL (1 << 19)
+#define RTL8187X_RXCONF_MGMT (1 << 20)
+#define RTL8187X_RXCONF_ADDR3 (1 << 21)
+#define RTL8187X_RXCONF_PM (1 << 22)
+#define RTL8187X_RXCONF_BSSID (1 << 23)
+#define RTL8187X_RXCONF_RXAUTORESETPHY (1 << 28)
+#define RTL8187X_RXCONF_CSDM1 (1 << 29)
+#define RTL8187X_RXCONF_CSDM2 (1 << 30)
+#define RTL8187X_RXCONF_ONLYERLPKT (1 << 31)
+
+/* Refers to "eeprom_cmd" field of "rtl8187x_csr_s" struct */
+
+#define RTL8187X_EEPROMCMD_READ (1 << 0)
+#define RTL8187X_EEPROMCMD_WRITE (1 << 1)
+#define RTL8187X_EEPROMCMD_CK (1 << 2)
+#define RTL8187X_EEPROMCMD_CS (1 << 3)
+#define RTL8187X_EEPROMCMD_NORMAL (0 << 6)
+#define RTL8187X_EEPROMCMD_LOAD (1 << 6)
+#define RTL8187X_EEPROMCMD_PROGRAM (2 << 6)
+#define RTL8187X_EEPROMCMD_CONFIG (3 << 6)
+
+/* Refers to "config2" field of "rtl8187x_csr_s" struct */
+
+#define RTL8187X_CONFIG2_ANTENNADIV (1 << 6)
+
+/* Refers to "msr" field of "rtl8187x_csr_s" struct */
+
+#define RTL8187X_MSR_NOLINK (0 << 2)
+#define RTL8187X_MSR_ADHOC (1 << 2)
+#define RTL8187X_MSR_INFRA (2 << 2)
+#define RTL8187X_MSR_MASTER (3 << 2)
+#define RTL8187X_MSR_ENEDCA (4 << 2)
+
+/* Refers to "config3" field of "rtl8187x_csr_s" struct */
+
+#define RTL8187X_CONFIG3_ANAPARAMWRITE (1 << 6)
+#define RTL8187X_CONFIG3_GNTSELECT (1 << 7)
+
+/* Refers to "config4" field of "rtl8187x_csr_s" struct */
+
+#define RTL8187X_CONFIG4_POWEROFF (1 << 6)
+#define RTL8187X_CONFIG4_VCOOFF (1 << 7)
+
+/* Refers to "tx_agc_ctl" field of "rtl8187x_csr_s" struct */
+
+#define RTL8187X_TXAGCCTL_PERPACKETGAINSHIFT (1 << 0)
+#define RTL8187X_TXAGCCTL_PERPACKETANTSELSHIFT (1 << 1)
+#define RTL8187X_TXAGCCTL_FEEDBACKANT (1 << 2)
+
+/* Refers to "cw_conf" field of "rtl8187x_csr_s" struct */
+
+#define RTL8187X_CWCONF_PERPACKETCWSHIFT (1 << 0)
+#define RTL8187X_CWCONF_PERPACKETRETRYSHIFT (1 << 1)
+
+/* Refers to "rate_fallback" field of "rtl8187x_csr_s" struct */
+
+#define RTL8187X_RATEFALLBACK_ENABLE (1 << 7)
+
+/* TX/RX Descriptor Bit Field Definitions ***********************************/
+/* Tx/Rx flags are common between RTL818X chips */
+
+/* Refers to "flags" field of "rtl8187x_txdesc_s" struct */
+
+#define RTL8187X_TXDESC_FLAG_NOENC (1 << 15) /* Disable hardware based encryption */
+#define RTL8187X_TXDESC_FLAG_TXOK (1 << 15) /* TX frame was ACKed */
+#define RTL8187X_TXDESC_FLAG_SPLCP (1 << 16) /* Use short preamble */
+#define RTL8187X_TXDESC_FLAG_RXUNDER (1 << 16)
+#define RTL8187X_TXDESC_FLAG_MOREFRAG (1 << 17) /* More fragments follow */
+#define RTL8187X_TXDESC_FLAG_CTS (1 << 18) /* Use CTS-to-self protection */
+#define RTL8187X_TXDESC_FLAG_RTS (1 << 23) /* Use RTS/CTS protection */
+#define RTL8187X_TXDESC_FLAG_LS (1 << 28) /* Last segment of the frame */
+#define RTL8187X_TXDESC_FLAG_FS (1 << 29) /* First segment of the frame */
+#define RTL8187X_TXDESC_FLAG_DMA (1 << 30)
+#define RTL8187X_TXDESC_FLAG_OWN (1 << 31)
+
+/* Refers to "flags" field of "rtl8187x_rxdesc_s" struct */
+
+#define RTL8187X_RXDESC_FLAG_ICVERR (1 << 12)
+#define RTL8187X_RXDESC_FLAG_CRC32ERR (1 << 13)
+#define RTL8187X_RXDESC_FLAG_PM (1 << 14)
+#define RTL8187X_RXDESC_FLAG_RXERR (1 << 15)
+#define RTL8187X_RXDESC_FLAG_BCAST (1 << 16)
+#define RTL8187X_RXDESC_FLAG_PAM (1 << 17)
+#define RTL8187X_RXDESC_FLAG_MCAST (1 << 18)
+#define RTL8187X_RXDESC_FLAG_QOS (1 << 19) /* RTL8187(B) only */
+#define RTL8187X_RXDESC_FLAG_TRSW (1 << 24) /* RTL8187(B) only */
+#define RTL8187X_RXDESC_FLAG_SPLCP (1 << 25)
+#define RTL8187X_RXDESC_FLAG_FOF (1 << 26)
+#define RTL8187X_RXDESC_FLAG_DMAFAIL (1 << 27)
+#define RTL8187X_RXDESC_FLAG_LS (1 << 28)
+#define RTL8187X_RXDESC_FLAG_FS (1 << 29)
+#define RTL8187X_RXDESC_FLAG_EOR (1 << 30)
+#define RTL8187X_RXDESC_FLAG_OWN (1 << 31)
+
+/* TX descriptor rate values */
+
+#define RTL8187X_RATE_1 0
+#define RTL8187X_RATE_2 1
+#define RTL8187X_RATE_5p5 2
+#define RTL8187X_RATE_11 3
+#define RTL8187X_RATE_6 4
+#define RTL8187X_RATE_9 5
+#define RTL8187X_RATE_12 6
+#define RTL8187X_RATE_18 7
+#define RTL8187X_RATE_24 8
+#define RTL8187X_RATE_36 9
+#define RTL8187X_RATE_48 10
+#define RTL8187X_RATE_54 11
+
+/* Other RTL8187x Definitions **********************************************/
+
+/* Number of IEEE 802.11 Channels */
+
+#define RTL8187X_NCHANNELS 14
+
+/* Vendor-Specific Requests */
+
+#define RTL8187X_REQT_READ 0xc0 /* DIR=IN TYPE=VENDOR RECIPIENT=DEVICE */
+#define RTL8187X_REQT_WRITE 0x40 /* DIR=OUT TYPE=VENDOR RECIPIENT=DEVICE */
+#define RTL8187X_REQ_GETREG 0x05
+#define RTL8187X_REQ_SETREG 0x05
+
+/* EEPROM Definitions */
+
+#define PCI_EEPROM_WIDTH_93C46 6
+#define PCI_EEPROM_WIDTH_93C56 8
+#define PCI_EEPROM_WIDTH_93C66 8
+#define PCI_EEPROM_WIDTH_OPCODE 3
+#define PCI_EEPROM_WRITE_OPCODE 0x05
+#define PCI_EEPROM_READ_OPCODE 0x06
+#define PCI_EEPROM_EWDS_OPCODE 0x10
+#define PCI_EEPROM_EWEN_OPCODE 0x13
+
+#define RTL8187X_EEPROM_TXPWRBASE 0x05
+#define RTL8187X_EEPROM_MACADDR 0x07
+#define RTL8187X_EEPROM_TXPWRCHAN1 0x16 /* 3 channels */
+#define RTL8187X_EEPROM_TXPWRCHAN6 0x1b /* 2 channels */
+#define RTL8187X_EEPROM_TXPWRCHAN4 0x3d /* 2 channels */
+
+/* RT8187x Register Addresses ***********************************************/
+
+#define RTL8187X_ADDR_MAR0 0xff08
+#define RTL8187X_ADDR_MAR1 0xff0c
+#define RTL8187X_ADDR_BRSR 0xff2c
+#define RTL8187X_ADDR_RESPRATE 0xff34
+#define RTL8187X_ADDR_CMD 0xff37
+#define RTL8187X_ADDR_INTMASK 0xff3c
+#define RTL8187X_ADDR_TXCONF 0xff40
+#define RTL8187X_ADDR_RXCONF 0xff44
+#define RTL8187X_ADDR_INTTIMEOUT 0xff48
+#define RTL8187X_ADDR_EEPROMCMD 0xff50
+#define RTL8187X_ADDR_CONFIG1 0xff52
+#define RTL8187X_ADDR_ANAPARAM 0xff54
+#define RTL8187X_ADDR_CONFIG3 0xff59
+#define RTL8187X_ADDR_CONFIG4 0xff5a
+#define RTL8187X_ADDR_TESTR 0xff5b
+#define RTL8187X_ADDR_PGSELECT 0xff5e
+#define RTL8187X_ADDR_ANAPARAM2 0xff60
+#define RTL8187X_ADDR_PHY0 0xff7c
+#define RTL8187X_ADDR_PHY1 0xff7d
+#define RTL8187X_ADDR_PHY2 0xff7e
+#define RTL8187X_ADDR_PHY3 0xff7f
+#define RTL8187X_ADDR_RFPINSOUTPUT 0xff80
+#define RTL8187X_ADDR_RFPINSENABLE 0xff82
+#define RTL8187X_ADDR_RFPINSSELECT 0xff84
+#define RTL8187X_ADDR_RFPINSINPUT 0xff86
+#define RTL8187X_ADDR_RFPARA 0xff88
+#define RTL8187X_ADDR_RFTIMING 0xff8c
+#define RTL8187X_ADDR_GPENABLE 0xff90
+#define RTL8187X_ADDR_GPIO 0xff91
+#define RTL8187X_ADDR_TXAGCCTL 0xff9c
+#define RTL8187X_ADDR_TXGAINCCK 0xff9d
+#define RTL8187X_ADDR_TXGAINOFDM 0xff9e
+#define RTL8187X_ADDR_TXANTENNA 0xff9f
+#define RTL8187X_ADDR_WPACONF 0xffb0
+#define RTL8187X_ADDR_CWCONF 0xffbc
+#define RTL8187X_ADDR_CWVAL 0xffbd
+#define RTL8187X_ADDR_RATEFALLBACK 0xffbe
+#define RTL8187X_ADDR_ANAPARAM3 0xffee
+#define RTL8187X_ADDR_TALLYSEL 0xfffc
+
+/* Other RTL8187x Register Values ******************************************/
+
+#define RTL8187X_RTL8225_ANAPARAM_ON 0xa0000a59
+#define RTL8187X_RTL8225_ANAPARAM2_ON 0x860c7312
+#define RTL8187X_RTL8225_ANAPARAM_OFF 0xa00beb59
+#define RTL8187X_RTL8225_ANAPARAM2_OFF 0x840dec11
+
+#define RTL8187B_RTL8225_ANAPARAM_ON 0x45090658
+#define RTL8187B_RTL8225_ANAPARAM2_ON 0x727f3f52
+#define RTL8187B_RTL8225_ANAPARAM3_ON 0x00
+#define RTL8187B_RTL8225_ANAPARAM_OFF 0x55480658
+#define RTL8187B_RTL8225_ANAPARAM2_OFF 0x72003f50
+#define RTL8187B_RTL8225_ANAPARAM3_OFF 0x00
+
+/* Standard Helper Macros ***************************************************/
+
+#ifndef ARRAY_SIZE
+# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+
+#ifndef MAX
+# define MAX(a,b) (a > b ? a : b)
+#endif
+
+#ifndef MIN
+# define MIN(a,b) (a < b ? a : b)
+#endif
+
+#ifndef NULL
+# define NULL ((void*)0)
+#endif
+
+/****************************************************************************
+ * Type Definitions
+ ****************************************************************************/
+
+ /* Linux RTL-818x mapping struct. This structure is not used in this driver
+ * and will, eventually, be removed. It is retained here now for reference.
+ * See the RTL8187x_ADDR_* definitions above.
+ */
+
+struct rtl8187x_csr_s
+{
+ uint8_t mac[6]; /* 0xff00-0xff05 */
+ uint8_t reserved_0[2]; /* 0xff06-0xff07 */
+ uint32_t mar[2]; /* RTL8187X_ADDR_MARn 0xff08-0xff0f */
+ uint8_t rx_fifo_count; /* 0xff10 */
+ uint8_t reserved_1; /* 0xff11 */
+ uint8_t tx_fifo_count; /* 0xff12 */
+ uint8_t bqreq; /* 0xff13 */
+ uint8_t reserved_2[4]; /* 0xff14-0xff17 */
+ uint32_t tsft[2]; /* 0xff18-0xff1f */
+ uint32_t tlpda; /* 0xff20 */
+ uint32_t tnpda; /* 0xff24 */
+ uint32_t thpda; /* 0xff28 */
+ uint16_t brsr; /* RTL8187X_ADDR_BRSR 0xff2c */
+ uint8_t bssid[6]; /* 0xff2e-0xff33 */
+ uint8_t resp_rate; /* RTL8187X_ADDR_RESPRATE 0xff34 */
+ uint8_t eifs; /* 0xff35 */
+ uint8_t reserved_3[1]; /* 0xff36 */
+ uint8_t cmd; /* RTL8187X_ADDR_CMD 0xff37 */
+ uint8_t reserved_4[4]; /* 0xff38-0xff3b */
+ uint16_t int_mask; /* RTL8187X_ADDR_INTMASK 0xff3c */
+ uint16_t int_status; /* 0xff3e */
+ uint32_t tx_conf; /* RTL8187X_ADDR_TXCONF 0xff40 */
+ uint32_t rx_conf; /* RTL8187X_ADDR_RXCONF 0xff44 */
+ uint32_t int_timeout; /* RTL8187X_ADDR_INTTIMEOUT 0xff48 */
+ uint32_t tbda; /* 0xff4c */
+ uint8_t eeprom_cmd; /* RTL8187X_ADDR_EEPROMCMD 0xff50 */
+ uint8_t config0; /* 0xff51 */
+ uint8_t config1; /* RTL8187X_ADDR_CONFIG1 0xff52 */
+ uint8_t config2; /* 0xff53 */
+ uint32_t anaparam; /* RTL8187X_ADDR_ANAPARAM 0xff54 */
+ uint8_t msr; /* 0xff58 */
+ uint8_t config3; /* RTL8187X_ADDR_CONFIG3 0xff59 */
+ uint8_t config4; /* RTL8187X_ADDR_CONFIG4 0xff5a */
+ uint8_t testr; /* RTL8187X_ADDR_TESTR 0xff5b */
+ uint8_t reserved_9[2]; /* 0xff5c-0xff5d */
+ uint8_t pgselect; /* RTL8187X_ADDR_PGSELECT 0xff5e */
+ uint8_t security; /* 0xff5f */
+ uint32_t anaparam2; /* RTL8187X_ADDR_ANAPARAM2 0xff60 */
+ uint8_t reserved_10[12]; /* 0xff64-0xff6f */
+ uint16_t beacon_interval; /* 0xff70 */
+ uint16_t atim_wnd; /* 0xff72 */
+ uint16_t beacon_interval_time; /* 0xff74 */
+ uint16_t atimtr_interval; /* 0xff76 */
+ uint8_t phy_delay; /* 0xff78 */
+ uint8_t carrier_sense_counter; /* 0xff79 */
+ uint8_t reserved_11[2]; /* 0xff7a-0xff7b */
+ uint8_t phy[4]; /* RTL8187X_ADDR_PHYn 0xff7c-0xff7f */
+ uint16_t rfpinsoutput; /* RTL8187X_ADDR_RFPINSOUTPUT 0xff80 */
+ uint16_t rfpinsenable; /* RTL8187X_ADDR_RFPINSENABLE 0xff82 */
+ uint16_t rfpinsselect; /* RTL8187X_ADDR_RFPINSSELECT 0xff84 */
+ uint16_t rfpinsinput; /* RTL8187X_ADDR_RFPINSINPUT 0xff86 */
+ uint32_t rf_para; /* RTL8187X_ADDR_RFPARA 0xff88 */
+ uint32_t rf_timing; /* RTL8187X_ADDR_RFTIMING 0xff8c */
+ uint8_t gp_enable; /* RTL8187X_ADDR_GPENABLE 0xff90 */
+ uint8_t gpio0; /* RTL8187X_ADDR_GPIO 0xff91 */
+ uint8_t gpio1; /* 0xff92 */
+ uint8_t reserved_12; /* 0xff93 */
+ uint32_t hssi_para; /* 0xff94 */
+ uint8_t reserved_13[4]; /* 0xff98-0xff9d */
+ uint8_t tx_agc_ctl; /* RTL8187X_ADDR_TXAGCCTL 0xff9c */
+ uint8_t tx_gain_cck; /* RTL8187X_ADDR_TXGAINCCK 0xff9d */
+ uint8_t tx_gain_ofdm; /* RTL8187X_ADDR_TXGAINOFDM 0xff9e */
+ uint8_t tx_antenna; /* RTL8187X_ADDR_TXANTENNA 0xff9f */
+ uint8_t reserved_14[16]; /* 0xffa0-0xffaf */
+ uint8_t wpa_conf; /* RTL8187X_ADDR_WPACONF 0xffb0 */
+ uint8_t reserved_15[3]; /* 0xffb1-0xffb3 */
+ uint8_t sifs; /* 0xffb4 */
+ uint8_t difs; /* 0xffb5 */
+ uint8_t slot; /* 0xffb6 */
+ uint8_t reserved_16[5]; /* 0xffb7-0xffbb */
+ uint8_t cw_conf; /* RTL8187X_ADDR_CWCONF 0xffbc */
+ uint8_t cw_val; /* RTL8187X_ADDR_CWVAL 0xffbd */
+ uint8_t rate_fallback; /* RTL8187X_ADDR_RATEFALLBACK 0xffbe */
+ uint8_t acm_control; /* 0xffbf */
+ uint8_t reserved_17[24]; /* 0xffc0-ffd7 */
+ uint8_t config5; /* 0xffd8 */
+ uint8_t tx_dma_polling; /* 0xffd9 */
+ uint8_t reserved_18[2]; /* 0xffda-0xffdb */
+ uint16_t cwr; /* 0xffdc */
+ uint8_t retry_ctr; /* 0xffde */
+ uint8_t reserved_19[3]; /* 0xffdf-0xffe1 */
+ uint16_t int_mig; /* 0xffe2 */
+ uint32_t rdsar; /* 0xffe4 */
+ uint16_t tid_ac_map; /* 0xffe8 */
+ uint8_t reserved_20[4]; /* 0xffea-0xffed */
+ uint8_t anaparam3; /* RTL8187X_ADDR_ANAPARAM3 0xffee */
+ uint8_t reserved_21[5]; /* 0xffef-0xfff3 */
+ uint16_t femr; /* 0xfff4 */
+ uint8_t reserved_22[4]; /* 0xfff6-0xfff9 */
+ uint16_t tally_cnt; /* 0xfffa */
+ uint8_t tally_sel; /* RTL8187X_ADDR_TALLYSEL 0xfffc */
+} __attribute__ ((packed));
+
+/* RX and TX descriptors */
+
+struct rtl8187x_rxdesc_s
+{
+ uint32_t flags;
+ uint8_t noise;
+ uint8_t signal;
+ uint8_t agc;
+ uint8_t reserved;
+ uint64_t mactime;
+} __attribute__((packed));
+
+#define SIZEOF_RXDESC 16
+
+#ifdef CONFIG_RTL8187B
+struct rtl8187x_txdesc_s
+{
+ uint32_t flags;
+ uint16_t rtsduration;
+ uint16_t len;
+ uint32_t unused1;
+ uint16_t unused2;
+ uint16_t txduration;
+ uint32_t unused3;
+ uint32_t retry;
+ uint32_t unused4[2];
+} __attribute__((packed));
+
+#define SIZEOF_TXDESC 32
+
+#else
+struct rtl8187x_txdesc_s
+{
+ uint32_t flags;
+ uint16_t rtsduration;
+ uint16_t len;
+ uint32_t retry;
+} __attribute__((packed));
+
+#define SIZEOF_TXDESC 12
+#endif
+
+#endif /* __DRIVERS_NET_RTL8187X_H */
+
diff --git a/misc/pascal/ChangeLog b/misc/pascal/ChangeLog
new file mode 100644
index 000000000..39d9c413c
--- /dev/null
+++ b/misc/pascal/ChangeLog
@@ -0,0 +1,37 @@
+pascal-0.1.0 2008-01-07 Gregory Nutt <gnutt@nuttx.org>
+
+ * Initial release
+
+pascal-0.1.1 2008-02-01 Gregory Nutt <gnutt@nuttx.org>
+
+ * Correct some errors in the NuttX installation logic
+
+pascal-0.1.2 2008-02-10 Gregory Nutt <gnutt@nuttx.org>
+
+ * Add logic to build and link with the ZDS-II toolchain
+ use with the z16f.
+ * Make sure that POFF header structures are aligned
+ * Standardized POFF file format to big-endian
+ * Break up large switch statements to lower complexity
+ and eliminate a compiler bug
+ * Changes so that runtime compiles with SDCC.
+
+pascal-2.0 2009-12-21 Gregory Nutt <gnutt@nuttx.org>
+
+ * Updated to use standard C99 types in stdint.h and
+ stdbool.h. This change was necessary for compatibility
+ with NuttX-5.0 (any beyond).
+
+pascal-3.0 2010-05-15 Gregory Nutt <gnutt@nuttx.org>
+
+ * nuttx/: The Pascal add-on module now installs and builds under the
+ apps/interpreters directory. This means that the pascal-3.0 module is
+ incompatible with will all releases of NuttX prior to nuttx-6.0 where the
+ apps/ module was introduced.
+
+pascal-3.1 2012-xx-xx Gregory Nutt <gnutt@nuttx.org>
+
+ * nuttx/Makefile: If DIRLINK is defined, then INCDIR was not setup
+ correctly and the build failed. The value of INCDIR must be
+ initialized unconditionally.
+
diff --git a/misc/pascal/Configure b/misc/pascal/Configure
new file mode 100755
index 000000000..569ded2cf
--- /dev/null
+++ b/misc/pascal/Configure
@@ -0,0 +1,188 @@
+#! /bin/sh
+############################################################################
+# Configure
+#
+# Copyright (C) 2008, 2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+Usage=" \n
++---------------- \n
+| USAGE: \n
+| ./Configure [--debug] [--help] \n
+| \n
+| OPTIONS: \n
+| --debug \n
+| Prints what script is doing \n
+| \n
+| --reconfig \n
+| Just regenerate the Make.config file \n
+| \n
+| --help \n
+| Prints this block. \n
++---------------- \n
+"
+
+# readans prompt default
+#
+function readans () {
+ echo -n "$1 ($2): "
+ IFS='@' read ans || exit 1
+ [ -z "$ans" ] && ans=$2
+}
+
+# readyn prompt default
+#
+function readyn () {
+ while :; do
+ readans "$1 [Y/N]" $2
+ case "$ans" in
+ [yY] | [yY]es )
+ ans=y
+ break ;;
+ [nN] | [nN]o )
+ ans=n
+ break ;;
+ * )
+ echo "Please answer Y or N"
+ ;;
+ esac
+ done
+}
+
+# Process command line arguments
+#
+REGEN="NO"
+while [ $# -gt 0 ] ; do
+ case "$1" in
+ --debug )
+ set -x
+ Pause="read press return to continue"
+ ;;
+ --regen )
+ REGEN="YES"
+ ;;
+ *)
+ echo $Usage
+ exit -1
+ ;;
+ esac
+ shift
+done
+
+# Setup configurations files
+#
+CONFIGFILE=./.config
+MAKECONFIG=Make.config
+TMPCONFIGFILE=TMP.config
+TMPMAKECONFIG=TMP.Make.config
+
+# Remove temporary configuration files in case we are restarting
+# after control-C
+#
+rm -f $TMPCONFIGFILE $TMPMAKECONFIG
+
+# Get information about the configuration settings
+#
+source ./config.info
+
+# Set up default values for all configuration settings
+#
+for i in $CONFIGS
+do
+ config_name=$(echo $i|cut -d':' -f1)
+ default_value=$(echo $i|cut -d':' -f2)
+ eval $config_name=$default_value
+done
+
+# If we have been previously configured, then there should be both
+# .config and Make.config files. Source the .config file, overwriting
+# the defaults that we set up above.
+#
+if [ -e ${CONFIGFILE} ] ; then
+ source ${CONFIGFILE}
+else
+ # We can't regenerate the Make.config file if there is no
+ # .config file
+ #
+ REGEN="NO"
+fi
+
+# Output the new Config file and Makefile fragment headers
+#
+SEPARATOR="# ----------------------------------------------------------------------"
+
+if [ "${REGEN}" != "YES" ]; then
+ echo "#!/bin/sh" >${TMPCONFIGFILE}
+ echo "#" >>${TMPCONFIGFILE}
+ echo "# Auto generated by Configure. Do not edit" >>${TMPCONFIGFILE}
+ echo "#" >>${TMPCONFIGFILE}
+fi
+
+echo $SEPARATOR >${TMPMAKECONFIG}
+echo "# Make.config" >>${TMPMAKECONFIG}
+echo "#" >>${TMPMAKECONFIG}
+echo "# This file controls the configuration of the compiler" >>${TMPMAKECONFIG}
+echo "# Auto generated by Configure. Do not edit" >>${TMPMAKECONFIG}
+echo $SEPARATOR >>${TMPMAKECONFIG}
+echo "#" >>${TMPMAKECONFIG}
+
+# Prompt for the setting of each configuration variable
+for i in $CONFIGS
+do
+ config_name=$(echo $i|cut -d':' -f1)
+ eval desc=\$${config_name}_INFO
+ eval config_value=\$$config_name
+
+ if [ "${REGEN}" != "YES" ]; then
+ readyn "$desc" $config_value
+ eval config_value=$ans
+ echo "$config_name=$config_value" >>${TMPCONFIGFILE}
+ fi
+
+ echo $SEPARATOR >>${TMPMAKECONFIG}
+ echo "# $desc" >>${TMPMAKECONFIG}
+ echo $SEPARATOR >>${TMPMAKECONFIG}
+ echo "$config_name = $config_value" >>${TMPMAKECONFIG}
+ echo "" >>${TMPMAKECONFIG}
+done
+
+# Make the changes permanent
+#
+if [ "${REGEN}" != "YES" ]; then
+ mv -f $TMPCONFIGFILE $CONFIGFILE
+ chmod 755 $CONFIGFILE
+ echo "Config script \"${CONFIGFILE}\" created"
+fi
+
+mv -f $TMPMAKECONFIG $MAKECONFIG
+chmod 644 $MAKECONFIG
+echo "Make fragment \"${MAKECONFIG}\" created"
diff --git a/misc/pascal/Make.config.h b/misc/pascal/Make.config.h
new file mode 100644
index 000000000..282b253ce
--- /dev/null
+++ b/misc/pascal/Make.config.h
@@ -0,0 +1,78 @@
+############################################################################
+# Make.config.h
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Directories
+#
+PASCAL = ${shell pwd}
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+INCDIR = $(PASCAL)/include
+CONFIGH = $(INCDIR)/config.h
+
+CONFIGS = CONFIG_DEBUG CONFIG_TRACE CONFIG_INSN16 CONFIG_INSN32
+
+# ----------------------------------------------------------------------
+# Objects and targets
+
+all: config.h
+.PHONY: all config.h $(CONFIGS) header trailer clean
+
+$(CONFIGS):
+ @if [ "$($@)" = "y" ] ; then \
+ echo "#define $@ 1" >>$(CONFIGH) ; \
+ else \
+ echo "#undef $@" >>$(CONFIGH) ; \
+ fi
+
+header:
+ @$(RM) $(INCDIR)/config.h
+ @echo "/* config.h: Autogenerated -- Do not edit. */" >$(CONFIGH)
+ @echo "" >>$(CONFIGH)
+ @echo "#ifndef __CONFIG_H" >>$(CONFIGH)
+ @echo "#define __CONFIG_H 1" >>$(CONFIGH)
+ @echo "" >>$(CONFIGH)
+
+trailer:
+ @echo "" >>$(CONFIGH)
+ @echo "#endif /* __CONFIG_H */" >>$(CONFIGH)
+
+$(CONFIGH): Make.config header $(CONFIGS) trailer
+
+config.h: $(CONFIGH)
+
+clean:
+ $(RM) $(INCDIR)/config.h
diff --git a/misc/pascal/Make.defs b/misc/pascal/Make.defs
new file mode 100644
index 000000000..0348bf4d3
--- /dev/null
+++ b/misc/pascal/Make.defs
@@ -0,0 +1,50 @@
+############################################################################
+# Make.defs
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Tools
+#
+CC = /usr/bin/gcc
+CPP = /usr/bin/cpp
+LD = /usr/bin/ld
+MAKE = /usr/bin/make
+AR = /usr/bin/ar
+
+RM = /bin/rm -f
+
+DEFINES =
+INCLUDES = -I. -I$(INCDIR)
+CFLAGS = -Wall -g $(DEFINES) $(INCLUDES)
+LDFLAGS = -L$(LIBDIR)
+ARFLAGS = -r
diff --git a/misc/pascal/Makefile b/misc/pascal/Makefile
new file mode 100644
index 000000000..b8af29415
--- /dev/null
+++ b/misc/pascal/Makefile
@@ -0,0 +1,115 @@
+# ----------------------------------------------------------------------
+# Makefile
+# ----------------------------------------------------------------------
+
+# ----------------------------------------------------------------------
+# Directories
+
+PASCAL = ${shell pwd}
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+INCDIR = $(PASCAL)/include
+LIBDIR = $(PASCAL)/lib
+BINDIR-$(CONFIG_INSN16) = $(PASCAL)/bin16
+BINDIR-$(CONFIG_INSN32) = $(PASCAL)/bin32
+LIBPOFFDIR = $(PASCAL)/libpoff
+LIBPASDIR = $(PASCAL)/libpas
+PASDIR = $(PASCAL)/pascal
+PLINKDIR = $(PASCAL)/plink
+TESTDIR = $(PASCAL)/tests
+INSN-$(CONFIG_INSN16) = $(PASCAL)/insn16
+INSN-$(CONFIG_INSN32) = $(PASCAL)/insn32
+LIBINSNDIR = $(INSN-y)/libinsn
+
+# ----------------------------------------------------------------------
+# Objects and targets
+
+LIBS = $(LIBDIR)/libpoff.a $(LIBDIR)/libpas.a \
+ $(LIBDIR)/libinsn.a
+
+all: pascal popt regm plink plist prun
+.PHONY: all config.h libpoff.a libpas.a libinsn.a pascal popt regm plink plist prun clean deep-clean
+
+$(INCDIR)/config.h: Make.config
+ @$(MAKE) -f Make.config.h
+
+config.h: $(INCDIR)/config.h
+
+$(LIBDIR):
+ mkdir $(LIBDIR)
+
+$(LIBDIR)/libpoff.a: $(LIBDIR) config.h
+ @$(MAKE) -C $(LIBPOFFDIR) libpoff.a
+
+libpoff.a: $(LIBDIR)/libpoff.a
+
+$(LIBDIR)/libpas.a: $(LIBDIR) config.h
+ @$(MAKE) -C $(LIBPASDIR) libpas.a
+
+libpas.a: $(LIBDIR)/libpas.a
+
+$(LIBDIR)/libinsn.a: $(LIBDIR) config.h
+ @$(MAKE) -C $(LIBINSNDIR) libinsn.a
+
+libinsn.a: $(LIBDIR)/libinsn.a
+
+$(BINDIR-y):
+ mkdir $(BINDIR-y)
+
+$(BINDIR-y)/pascal: $(BINDIR-y) config.h $(LIBS)
+ @$(MAKE) -C $(PASDIR)
+
+pascal: $(BINDIR-y)/pascal
+
+$(BINDIR-y)/popt: $(BINDIR-y) config.h $(LIBS)
+ @$(MAKE) -C $(INSN-y) popt
+
+popt: $(BINDIR-y)/popt
+
+$(BINDIR-y)/regm: $(BINDIR-y) config.h $(LIBS)
+ifeq ($(CONFIG_REGM),y)
+ @$(MAKE) -C $(INSN-y) regm
+endif
+
+regm: $(BINDIR-y)/regm
+
+$(BINDIR-y)/plink: $(BINDIR-y) config.h $(LIBS)
+ @$(MAKE) -C $(PLINKDIR)
+
+plink: $(BINDIR-y)/plink
+
+$(BINDIR-y)/prun: $(BINDIR-y) config.h $(LIBS)
+ @$(MAKE) -C $(INSN-y) prun
+
+prun: $(BINDIR-y)/prun
+
+$(BINDIR-y)/plist: $(BINDIR-y) config.h $(LIBS)
+ @$(MAKE) -C $(INSN-y) plist
+
+plist: $(BINDIR-y)/plist
+
+clean:
+ $(RM) -f core *~
+ $(RM) -rf $(LIBDIR)
+ $(RM) -rf bin16 bin32
+ $(MAKE) -f Make.config.h clean
+ $(MAKE) -C $(LIBPOFFDIR) clean
+ $(MAKE) -C $(LIBPASDIR) clean
+ $(MAKE) -C $(PASDIR) clean
+ $(MAKE) -C $(PLINKDIR) clean
+ $(MAKE) -C $(INSN-y) clean
+ find . -name \*~ -exec rm -f {} \;
+ find tests -name "*.err" -exec rm -f {} \;
+ find tests -name "*.lst" -exec rm -f {} \;
+ find tests -name "*.pex" -exec rm -f {} \;
+ find tests -name "*.o1" -exec rm -f {} \;
+ find tests -name "*.o" -exec rm -f {} \;
+
+deep-clean: clean
+ rm -f .config include/config.h Make.config
+ $(RM) bin16/*
+ $(RM) bin32/*
+
+# ----------------------------------------------------------------------
diff --git a/misc/pascal/README b/misc/pascal/README
new file mode 100644
index 000000000..f2d72130f
--- /dev/null
+++ b/misc/pascal/README
@@ -0,0 +1,25 @@
+README
+^^^^^^
+
+Configuring Pascal
+^^^^^^^^^^^^^^^^^^
+
+ cd <pascal-directory>
+ ./Configure
+ (Answer questions)
+
+Building Pascal
+^^^^^^^^^^^^^^^
+
+ cd <pascal-directory>
+ make
+
+Installing the NuttX Runtime P-Code Interpreter
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ cd <pascal-directory>/nuttx
+ ./INSTALL.sh <apps-directory>
+
+See <pascal-directory>/nuttx/README.txt for additional information.
+
+
diff --git a/misc/pascal/Reconfigure b/misc/pascal/Reconfigure
new file mode 100755
index 000000000..38b64b8b3
--- /dev/null
+++ b/misc/pascal/Reconfigure
@@ -0,0 +1,89 @@
+#! /bin/sh
+############################################################################
+# Reconfigure
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+function show_usage ()
+{
+ echo "USAGE:"
+ echo " ./Configure [--debug] [--help] <config-file>"
+ echo "OPTIONS:"
+ echo " --debug"
+ echo " Prints what script is doing"
+ echo " --help"
+ echo " Prints this information"
+ exit 1
+}
+
+# Process command line arguments
+#
+DEBUG=
+CONFIGFILE=
+while [ $# -gt 0 ] ; do
+ case "$1" in
+ --debug )
+ DEBUG=$1
+ ;;
+ --help )
+ show_usage
+ exit 1
+ ;;
+ * )
+ CONFIGFILE=$1
+ ;;
+ esac
+ shift
+done
+
+if [ -z "${CONFIGFILE}" ]; then
+ echo "<config-file> not specified"
+ show_usage
+ exit 1
+fi
+
+if [ ! -x "${CONFIGFILE}" ]; then
+ echo "Executable <config-file>=\"${CONFIGFILE}\" does not exist"
+ show_usage
+ exit 1
+fi
+
+if [ ! -x Configure ]; then
+ echo "./Configure script does not exist"
+ exit 1
+fi
+
+cp -f ${CONFIGFILE} .config || \
+ { echo "Copy of ${CONFIGFILE} .config failed" ; exit 1 ; }
+
+./Configure --regen $DEBUG
diff --git a/misc/pascal/ReleaseNotes b/misc/pascal/ReleaseNotes
new file mode 100644
index 000000000..389aff1e4
--- /dev/null
+++ b/misc/pascal/ReleaseNotes
@@ -0,0 +1,40 @@
+pascal-0.1.2
+^^^^^^^^^^^^
+
+This is the 3rd release of the Pascal P-Code add-on to NuttX. This
+release adds support for some additional toolchains and standardizes
+the binary format to big-endian for portability of the P-Code across
+different platforms. This release is synchronized with the release
+of NuttX-0.3.8.
+
+This tarball contains a complete CVS snapshot from February 10, 2008.
+
+pascal-0.1.3
+^^^^^^^^^^^^
+
+This was a bug-fix release
+
+pascal-2.0
+^^^^^^^^^^
+
+This release updates all of the code to use the standard types defined
+in the C99 files stdint.h and stdbool.h. This change was necessary for
+compatibility with NuttX-5.0. No functional changes were made.
+
+The release version was bumped to 2.0 because these changes introduce
+typing incompatibilies with earlier versions.
+
+This tarball contains a complete CVS snapshot from December 21, 2009.
+
+pascal-3.0
+^^^^^^^^^^
+
+This release moves the Pascal installation location from the nuttx/
+source to the apps/ source tree. Specifically, the Pascall runtime now
+builds under apps/interpreters.
+
+This means that the pascal-3.0 module is incompatible with will all
+releases of NuttX prior to nuttx-6.0 where the apps/ module was
+introduced. The release version was bumped to 3.0 because these changes
+introduces installation incompatibilies with earlier versions.
+
diff --git a/misc/pascal/config.info b/misc/pascal/config.info
new file mode 100755
index 000000000..8147eba65
--- /dev/null
+++ b/misc/pascal/config.info
@@ -0,0 +1,64 @@
+#! /bin/sh
+############################################################################
+# config.info
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Configuration information
+# Format is <config-name>:<default-setting>
+#
+CONFIGS=
+
+# DEBUG configuration
+CONFIG_DEBUG_INFO="Enable DEBUG instrumentation"
+CONFIGS="$CONFIGS CONFIG_DEBUG:n"
+
+# TRACE configuration
+CONFIG_TRACE_INFO="Enable TRACE instrumentation"
+CONFIGS="$CONFIGS CONFIG_TRACE:n"
+
+# 16-bit processor model selection
+CONFIG_INSN16_INFO="Use a 16-bit processor model"
+CONFIGS="$CONFIGS CONFIG_INSN16:y"
+
+# 32-bit processor model selection
+CONFIG_INSN32_INFO="Use a 32-bit processor model"
+CONFIGS="$CONFIGS CONFIG_INSN32:n"
+
+# Register model selection
+CONFIG_REGM_INFO="Processor module supports a register machine"
+CONFIGS="$CONFIGS CONFIG_REGM:n"
+
+# Availability of libma.a
+CONFIG_HAVE_LIBM_INFO="Host toolchain supports libm.a"
+CONFIGS="$CONFIGS CONFIG_HAVE_LIBM:y"
diff --git a/misc/pascal/doc/PascalGrammar.txt b/misc/pascal/doc/PascalGrammar.txt
new file mode 100644
index 000000000..8049f536f
--- /dev/null
+++ b/misc/pascal/doc/PascalGrammar.txt
@@ -0,0 +1,455 @@
+PASCAL GRAMMAR:
+The start symbol for this grammar is pascal.
+
+ actual-parameter = expression | variable-access |
+ procedure-identifier | function-identifier
+
+ actual-parameter-list = '(' actual-parameter { ',' actual-parameter } ')'
+
+ adding-operator = '+' | '-' | 'or' | 'or_else' | 'xor'
+
+ array-type = 'array' '[' index-type-list ']' 'of' type-denoter
+
+ array-variable = variable-access
+
+ assignment-statement = assignment-statement-lhs ':=' expression
+
+ assignment-statement-lhs = variable-access | function-identifier | property-designator
+
+ binary-digit = '0' | '1'
+
+ binary-digit-sequence = binary-digit { binary-digit }
+
+ binary-integer = '%' binary-digit-sequence
+
+ block = declaration-group compound-statement
+
+ boolean-expression = expression
+
+ buffer-variable = file-variable '^' | file-variable '@'
+
+ c-string-type = 'cstring' [ max-string-length ]
+
+ case-body = case-list-elements [ [ ';' ] case-statement-completer ] |
+ case-statement-completer
+
+ case-constant = ordinal-constant
+
+ case-constant-list = case-specifier { ',' case-specifier }
+
+ case-index = ordinal-expression
+
+ case-list-element = case-constant-list ':' statement
+
+ case-list-elements = case-list-element { ';' case-list-element }
+
+ case-specifier = case-constant [ '..' case-constant ]
+
+ case-statement = 'case' case-index case-body [ ';' ] 'end'
+
+ case-statement-completer = ( 'otherwise' | 'else' ) statement-sequence
+
+ character-code = digit-sequence
+
+ character-literal = ''' string-element-one ''' |
+ '"' string-element-two '"' |
+ '#' character-code
+
+ component-variable = indexed-variable | field-designator
+
+ compound-statement = 'begin' statement-sequence 'end'
+
+ conditional-statement = if-statement | case-statement
+
+ constant = [ sign ] integer-number |
+ [ sign ] real-number |
+ [ sign ] constant-identifier |
+ character-literal |
+ string-literal
+
+ constant-definition = identifier '=' constant
+
+ constant-definition-group = 'const' constant-definition ';' { constant-definition ';' }
+
+ constant-identifier = identifier
+
+ control-variable = entire-variable
+
+ decimal-integer = digit-sequence
+
+ declaration-group =
+ label-declaration-group |
+ constant-definition-group |
+ type-definition-group |
+ variable-declaration-group |
+ function-declaration |
+ procedure-declaration
+
+ digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
+
+ digit-sequence = digit { digit }
+
+ directive = forward-directive | external-directive
+
+ dllname = string-literal
+
+ domain-type = type-identifier
+
+ else-part = 'else' statement
+
+ empty-statement =
+
+ empty-string = '''' | '""'
+
+ entire-variable = variable-identifier
+
+ enumerated-constant = identifier
+
+ enumerated-constant-list = enumerated-constant { ',' enumerated-constant }
+
+ enumerated-type = '(' enumerated-constant-list ')'
+
+ exponent = 'e' | 'E'
+
+ exported-heading = procedure-heading ';' [ directive ] | function-heading ';' [ directive ]
+
+ expression = shift-expression [ relational-operator shift-expression ]
+
+ external-directive = 'external' 'dll' '=' dllname [ 'name' '=' name ] [ 'stdcall' | 'cdecl' ]
+
+ factor = [ sign ] unsigned-constant |
+ [ sign ] variable-access |
+ [ sign ] '(' expression ')' |
+ [ sign ] function-designator |
+ [ sign ] function-method-designator |
+ [ sign ] 'not' factor |
+ set-constructor
+
+ field-designator = record-variable '.' field-specifier | field-designator-identifier
+
+ field-designator-identifier = identifier
+
+ field-identifier = identifier
+
+ field-list = [
+ fixed-part [ ';' ] variant-part [ ';' ] |
+ fixed-part [ ';' ] |
+ variant-part [ ';' ] |
+ ]
+
+ field-specifier = field-identifier
+
+ file-type = 'file' 'of' type-denoter
+
+ file-variable = variable-access
+
+ final-value = ordinal-expression
+
+ fixed-part = record-section { ';' record-section }
+
+ for-statement = 'for' control-variable ':=' initial-value ( 'to' | 'downto' ) final-value
+ 'do' statement
+
+ formal-parameter-list = '(' formal-parameter-section { ';' formal-parameter-section } ')'
+
+ formal-parameter-section = value-parameter-specification |
+ variable-parameter-specification |
+ procedure-parameter-specification |
+ function-parameter-specification
+
+ forward-directive = 'forward'
+
+ function-block = block
+
+ function-declaration =
+ function-heading ';' directive |
+ function-heading ';' function-block
+
+ function-designator = function-identifier [ actual-parameter-list ]
+
+ function-heading = 'function' function-identifier [ formal-parameter-list ] ':' result-type
+
+ function-identifier = identifier
+
+ function-method-designator = object-variable '.' function-method-identifier [ actual-parameter-list ]
+
+ function-method-identifier = identifier
+
+ function-parameter-specification = function-heading
+
+ goto-statement = 'goto' label
+
+ hex-digit = digit | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
+
+ hex-digit-sequence = hex-digit { hex-digit }
+
+ hexadecimal-integer = '$' hex-digit-sequence
+
+ identified-variable = pointer-variable '^' | pointer-variable '@'
+
+ identifier = letter { letter | digit }
+
+ identifier-list = identifier { ',' identifier }
+
+ if-statement = 'if' boolean-expression 'then' statement [ else-part ]
+
+ implementation-section = 'implementation' [ uses-section ] declaration-group
+
+ index-expression = expression
+
+ index-type = ordinal-type
+
+ index-type-list = index-type { ',' index-type }
+
+ indexed-variable = indexed-variable-array | indexed-variable-string
+
+ indexed-variable-array = array-variable '[' index-expression { ',' index-expression } ']'
+
+ indexed-variable-string = string-variable '[' integral-expression ']'
+
+ initial-value = ordinal-expression
+
+ init-section = 'initialization statement-sequence
+ ['finalization' statement-sequence] 'end' |
+ compound-statement | 'end'
+
+ integer-number = decimal-integer | hexadecimal-integer | binary-integer
+
+ integral-constant = constant
+
+ integral-expression = expression
+
+ interface-declaration = [ constant-definition-group ]
+ [ type-definition-group ] [ variable-declaration-group ]
+ exported-heading
+
+ interface-section = 'interface' [ uses-section ] interface-declaration
+
+ label = digit-sequence | identifier
+
+ label-declaration-group = 'label' label { ',' label } ';'
+
+ letter = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' |
+ 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' |
+ 'u' | 'v' | 'w' | 'x' | 'y' | 'z' |
+ '_'
+
+ list-type = 'list' 'of' type-denoter
+
+ list-variable = variable-access
+
+ max-string-length = '[' integral-constant ']' | '(' integral-constant ')'
+
+ member-designator = ordinal-expression [ '..' ordinal-expression ]
+
+ multiplying-operator = '*' | '/' | 'div' | 'mod' | 'and' | 'and_then'
+
+ name = identifier
+
+ new-complex-type = new-structured-type | new-pointer-type
+
+ new-ordinal-type = enumerated-type | subrange-type
+
+ new-pointer-type = '^' domain-type | '@' domain-type
+
+ new-structured-type =
+ [ 'packed' ] array-type |
+ [ 'packed' ] record-type |
+ [ 'packed' ] set-type |
+ [ 'packed' ] file-type |
+ [ 'packed' ] list-type |
+ object-type |
+ string-type
+
+ new-type = new-ordinal-type | new-complex-type
+
+ non-empty-string =
+ ''' string-element-one string-element-one { string-element-one } ''' |
+ '"' string-element-two string-element-two { string-element-two } '"'
+
+ object-type = 'object' | 'class'
+
+ object-variable = variable-access
+
+ ordinal-constant = constant
+
+ ordinal-expression = expression
+
+ ordinal-type = new-ordinal-type | ordinal-type-identifier
+
+ ordinal-type-identifier = identifier
+
+ pascal = program | unit
+
+ pascal-string-type = 'string' [ max-string-length ]
+
+ pointer-variable = variable-access
+
+ printable-character = any character (including a space) that has a visual representation.
+
+ procedure-block = block
+
+ procedure-declaration =
+ procedure-heading ';' directive |
+ procedure-heading ';' procedure-block
+
+ procedure-heading = 'procedure' procedure-identifier
+ [ formal-parameter-list ]
+
+ procedure-identifier = identifier
+
+ procedure-method-identifier = identifier
+
+ procedure-method-specifier = object-variable '.' procedure-method-identifier
+
+ procedure-method-statement = procedure-method-specifier [ actual-parameter-list ]
+
+ procedure-parameter-specification = procedure-heading
+
+ procedure-statement = procedure-identifier (
+ [ actual-parameter-list ] |
+ read-parameter-list | readln-parameter-list |
+ write-parameter-list | writeln-parameter-list
+ )
+
+ program = program-heading ';' [ uses-section ] block '.'
+
+ program-heading = 'program' identifier [ '(' identifier-list ')' ]
+
+ property-designator = object-variable '.' property-specifier
+
+ property-identifier = identifier
+
+ property-specifier = property-identifier | '(' property-string ')'
+
+ property-string = string-expression
+
+ read-parameter-list = '(' [ file-variable ',' ] variable-access { ',' variable-access } ')'
+
+ readln-parameter-list = [ '(' ( file-variable | variable-access ) { ',' variable-access } ')' ]
+
+ real-number =
+ digit-sequence '.' [digit-sequence] [ exponent scale-factor ] |
+ '.' digit-sequence [ exponent scale-factor ] |
+ digit-sequence exponent scale-factor
+
+ record-section = identifier-list ':' type-denoter
+
+ record-type = 'record' field-list 'end'
+
+ record-variable = variable-access
+
+ record-variable-list = record-variable { ';' record-variable }
+
+ relational-operator = '=' | '<>' | '<' | '<=' | '>' | '>=' | 'in'
+
+ repeat-statement = 'repeat' statement-sequence 'until' boolean-expression
+
+ repetitive-statement = repeat-statement | while-statement | for-statement
+
+ result-type = type-identifier
+
+ scale-factor = [ sign ] digit-sequence
+
+ selected-variable = list-variable '[' index-expression { ',' index-expression } ']'
+
+ set-constructor = '[' [ member-designator { ',' member-designator } ] ']'
+
+ set-type = 'set' 'of' ordinal-type
+
+ shift-expression = simple-expression [ shift-operator simple-expression ]
+
+ shift-operator = 'shl' | 'shr'
+
+ sign = '-' | '+'
+
+ simple-expression = term { adding-operator term }
+
+ simple-statement = empty-statement | assignment-statement |
+ procedure-statement | procedure-method-statement |
+ goto-statement
+
+ statement = [ label ':' ] ( simple-statement | structured-statement )
+
+ statement-sequence = statement { ';' statement }
+
+ string-element-one = '''' | printable-character
+
+ string-element-two = '""' | printable-character
+
+ string-expression = expression
+
+ string-literal = empty-string | non-empty-string
+
+ string-type = pascal-string-type | c-string-type
+
+ string-variable = variable-access
+
+ structured-statement = compound-statement |
+ conditional-statement |
+ repetitive-statement |
+ with-statement
+
+ subrange-type = constant '..' constant
+
+ term = factor { multiplying-operator factor }
+
+ type-definition = identifier '=' type-denoter
+
+ type-definition-group = 'type' type-definition ';' { type-definition ';' }
+
+ type-denoter = type-identifier | new-type
+
+ type-identifier = identifier
+
+ unit = 'unit' identifer ';' interface-section implementation-section
+ init-section '.'
+
+ unit-import = identifier ['in' non-empty-string ]
+
+ unit = unit-heading ';' interface-section implementation-section init-section
+
+ unit-heading = 'unit' identifer
+
+ unsigned-constant = integer-number | real-number |
+ character-literal | string-literal | constant-identifier |
+ 'nil'
+
+ uses-section = 'uses' [ uses-unit-list ] ';'
+
+ uses-unit-list = unit-import {';' uses-unit-list }
+
+ value-parameter-specification = identifier-list ':' type-identifier
+
+ variable-access = entire-variable | component-variable | identified-variable |
+ selected-variable | buffer-variable
+
+ variable-declaration = identifier-list ':' type-denoter
+
+ variable-declaration-group = 'var' variable-declaration { ';' variable-declaration }
+
+ variable-identifier = identifier
+
+ variable-parameter-specification = 'var' identifier-list ':' type-identifier
+
+ variant = case-constant-list ':' '(' field-list ')'
+
+ variant-body = variant-list [ [ ';' ] variant-part-completer ] | variant-part-completer
+
+ variant-list = variant { ';' variant }
+
+ variant-part = 'case' variant-selector 'of' variant-body
+
+ variant-part-completer = ( 'otherwise' | 'else' ) ( field-list )
+
+ variant-selector = [ identifier ':' ] ordinal-type-identifer
+
+ while-statement = 'while' boolean-expression 'do' statement
+
+ with-statement = 'with' record-variable-list 'do' statement
+
+ write-parameter = expression [ ':' expression [ ':' expression ] ]
+
+ write-parameter-list = '(' [ file-variable ',' ] write-parameter { ',' write-parameter } ')'
+
+ writeln-parameter-list = [ '(' ( file-variable | write-parameter ) { ',' write-parameter } ')' ]
diff --git a/misc/pascal/doc/PascalNotes.txt b/misc/pascal/doc/PascalNotes.txt
new file mode 100644
index 000000000..360986c59
--- /dev/null
+++ b/misc/pascal/doc/PascalNotes.txt
@@ -0,0 +1,135 @@
+ AS OF 1/18/04
+
+TYPES
+- Only types INT, BOOLEAN, CHAR, REAL, SCALAR, SUBRANGE, RECORD and SET
+ implemented
+ - No PACKED types (actually, types are always packed).
+ - FILE OF and TEXT types partially supported
+ - Not supported in TYPE block
+ - TEXT is defined as FILE OF CHAR vs PACKED FILE OF CHAR
+ - No function returning FILE OF; No FILE OF
+ procedure/function arguments
+ - Only PROGRAM arguments can be declared type FILE OF
+ - Only one file identifier per FILE OF declaration in type
+ block.
+ - SET is limit to 16/32 (# bits in int) adjacent elements
+ - Expressions are not strongly typed across different SCALAR types
+ (see exprEnum in expr.h)
+ - In RECORD CASE, there is no verification that the type of the tag
+ is consistent with a case selector; the is check if the case selector
+ constants are of the same type as the tag type identifier.
+
+- No range checks on array indices
+- Pointers
+ - Can't pass pointers as VAR parameters
+ - No pointer functions ??
+ - No pointers to pointers
+
+STATEMENTS
+- The following statements not implemented:
+ - No PROCEDURE call with PROCEDUREs or FUNCTIONs as parameters
+- The following statements are only partially implemented
+ - WITH statements cannot be nested.
+ - Cannot reference "up the chain" in WITH statements. Eg.
+ suppose RECORD "a" contains RECORD "b" which contains "c" and
+ that RECORD "a" also contains "d" so that we could write
+ a.b.c OR a.d
+ Then the following should work but is not yet supported:
+ WITH a DO
+ BEGIN
+ WITH b DO
+ BEGIN
+ c := ..
+ d := .. <== SHOULD WORK!!!
+ - GOTO only partially implemented -- no stack corrections
+ for GOTOs between loops, blocks, etc. Use is DANGEROUS.
+
+STANDARD PROCEDURES and FUNCTIONS
+- The following statement procedures/functions not implemented:
+ - GET, PUT, PACK, UNPACK, NEW
+ - TBD
+- No fieldwidth colon operator on WRITE arguments
+
+Extended Pascal Features
+- Type STRING is partially implemented.
+- PACKED ARRAY[..] OF CHAR is not a a string.
+
+NON-standard Pascal extensions/differences
+
+TYPES
+- ARRAY index type is integer constant specifying size of array
+- Hexadecimal constants.
+- INPUT and OUTPUT parameters in PROGRAM statement are
+ predeclared and optional.
+
+OPERATORS
+- Binary shift operators -- << and >> like in C
+- '#', "<>", and "><" are all equivalent
+
+COMPILER PSEUDO-OPERATIONS
+- INCLUDE
+
+STATEMENTS
+- CASE statement expects integer expression for the switch
+ variable
+- ELSE in CASE statement
+
+EXPRESSIONS
+
+- Assumes sizeof(pointer) == sizeof(integer)
+
+TODO LIST
+
+o BUGS
+- Implement PUT and GET.
+- In FUNC/PROC calls, if simpleExpression fails to find a parameter (eg.,
+ proc (,,), no error is detected.
+- Type FILE OF is totally busted -- fix it
+- Need to get max string size into stack somehow. Runtime routines like
+ strcat and strcatc need to know how big the string storage space is.
+- Need logic to release string stack used by actual parameters after
+ function/procedure call.
+- Can't declare new parameters / variables with same name as another
+ variable at higher stock. Tokenizer does not return tIDENT.
+- There are lots of cases where the string stack is not being managed
+ correctly (e.g., usesSection()).
+- Redirection of input and output is not supported (e.g. see setting of
+ input and output in CONST section of pageutils.pas).
+
+o IMPROVEMENTS
+- In PTKN, verify that string stack does not overflow when
+ character added.
+- Option to turn on listing
+- Option to interleave assembly language with listing
+- Option to select string stack size (or let it grow dynamically)
+- Option to select symbol table size (or let it grow dynamically)
+- List file should only be produced if option provided.
+- Provide instrumentation to use the line number data in the
+ object files. In debugger, display source line. Allow stepping
+ from source line to source line.
+- Optimizer needs to be incorporated into compiler.
+- arrayIndex needs to conform with Pascal standard.
+- Need to have 32-bit integers and address
+- Translation to register model
+- Native code translator
+- Linker and support multiple source files
+- Runtime package
+- Full extended pascal string support
+- Other things from extended pascal: 'list of' 'uses' 'unit'
+- Need to optimize out JMP .+1
+- For compatibility, let 'packed array [n..m] of char;' be equivalent to
+ string.
+- Need to review all uses of string stack for identifiers and strings
+ that get discarded. Probably should get a get infrastructure.
+- Add 16-bit word type
+
+o ISSUES
+- What happens in TYPE block if type is sTYPE or sFILE_OF? Need
+ to re-think all typing. Maybe replace sTYPE and sFILE_OF with
+ sINT_TYPE, sINT_ARRAY_TYPE, ..., sFILE_OF_INT,
+ sFILE_OF_INT_ARRAY, etc.
+- Is it really necessary or meaningful to allocate dstack for
+ file buffers.
+- Revisit procedure call logic in pexec.c & pdbg.c. First stack parameter
+ is calculated but never used.
+- Decide what to do about type filename in tests/src/cgimail.pas
diff --git a/misc/pascal/include/keywords.h b/misc/pascal/include/keywords.h
new file mode 100644
index 000000000..7784d8df9
--- /dev/null
+++ b/misc/pascal/include/keywords.h
@@ -0,0 +1,82 @@
+/*************************************************************
+ * keywords.h
+ * This file defines the pascal compilation environment
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ *************************************************************/
+
+#ifndef __KEYWORDS_H
+#define __KEYWORDS_H
+
+/*************************************************************
+ * Included Files
+ *************************************************************/
+
+#include "config.h"
+
+/*************************************************************
+ *Pre-processor Definitions
+ *************************************************************/
+
+#ifndef NULL
+# define NULL ((void*)0)
+#endif
+
+#ifndef CONFIG_DEBUG
+# define CONFIG_DEBUG 0
+#endif
+
+#if CONFIG_DEBUG
+# define DEBUG(stream, format, arg...) fprintf(stream, format, ##arg)
+#else
+# define DEBUG(x...)
+#endif
+
+#ifndef CONFIG_TRACE
+# define CONFIG_TRACE 0
+#endif
+
+#if CONFIG_TRACE
+# define TRACE(stream, format, arg...) fprintf(stream, format, ##arg)
+#else
+# define TRACE(x...)
+#endif
+
+#define FAR
+
+#define dbg(...) fprintf(stderr, __VA_ARGS__)
+#define vdbg(...) DEBUG(__VA_ARGS__)
+
+#endif /* __KEYWORDS_H */
+
+
+
diff --git a/misc/pascal/include/paslib.h b/misc/pascal/include/paslib.h
new file mode 100644
index 000000000..55f965c10
--- /dev/null
+++ b/misc/pascal/include/paslib.h
@@ -0,0 +1,90 @@
+/***************************************************************************
+ * include/paslib.h
+ * External Declarations associated with paslib
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PASLIB_H
+#define __PASLIB_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include "keywords.h"
+#include "stdint.h"
+#include "stdbool.h"
+#include "pdefs.h"
+#include "pofflib.h"
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+/* POFF file is always big-endian */
+
+#ifdef CONFIG_ENDIAN_BIG
+# undef CONFIG_POFF_SWAPNEEDED
+# define poff16(val) (val)
+# define poff32(val) (val)
+#else
+# define CONFIG_POFF_SWAPNEEDED 1
+# define poff16(val) poffSwap16(val)
+# define poff32(val) poffSwap32(val)
+#endif
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+/* File name extension helper */
+
+extern bool extension(const char *inName, const char *ext, char *outName,
+ bool force_default);
+
+/* Math helpers */
+
+extern int32_t signExtend16(uint16_t arg16);
+extern int32_t signExtend25(uint32_t arg25);
+
+/* Endian-ness helpers */
+
+extern uint16_t poffSwap16(uint16_t val);
+extern uint32_t poffSwap32(uint32_t val);
+
+/***************************************************************************
+ * Global Variables
+ ***************************************************************************/
+
+#endif /* __PASLIB_H */
+
diff --git a/misc/pascal/include/pdefs.h b/misc/pascal/include/pdefs.h
new file mode 100644
index 000000000..3f794a981
--- /dev/null
+++ b/misc/pascal/include/pdefs.h
@@ -0,0 +1,115 @@
+/***********************************************************************
+ * include/pdefs.h
+ * Common definitions
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************************************/
+
+#ifndef __PDEFS_H
+#define __PDEFS_H
+
+/***********************************************************************
+ * Included Files
+ ***********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h> /* for FILE */
+#include "config.h"
+
+/***********************************************************************
+ * Pre-processor Definitions
+ ***********************************************************************/
+
+/* Common Sizing Parameters */
+
+#define FNAME_SIZE 40 /* Max size file name */
+#define LINE_SIZE 256 /* Max size of input line buffer */
+
+/* Target P-Machine Data Storage Sizes */
+
+#ifdef CONFIG_INSN16
+# define sINT_SIZE 2
+# define MAXINT 32767
+# define MININT -32768
+# define BITS_IN_INTEGER 16
+# define MAXUINT 0xffff
+# define MINUINT 0
+#endif
+
+#ifdef CONFIG_INSN32
+# define sINT_SIZE 4
+# define MAXINT 2147483647
+# define MININT -2147483648
+# define BITS_IN_INTEGER 32
+# define MAXUINT 0xffffffff
+# define MINUINT 0
+#endif
+
+#define sCHAR_SIZE 1
+#define sBOOLEAN_SIZE sINT_SIZE
+#define sREAL_SIZE 8
+#define sPTR_SIZE sINT_SIZE
+#define sRETURN_SIZE (3*sPTR_SIZE)
+
+#define sSTRING_HDR_SIZE 2
+#define sSTRING_SIZE 256 /* size(2) + string(255) */
+#define sSTRING_MAX_SIZE (sSTRING_SIZE - 2) /* string storage size(254) */
+#define sRSTRING_SIZE (sPTR_SIZE + sINT_SIZE) /* ptr + size */
+#define sCSTRING_SIZE (sizeof(void*)) /* absolute C pointer */
+
+#define MAXCHAR 255
+#define MINCHAR 0
+
+/***********************************************************************
+ * Public Structure/Types
+ ***********************************************************************/
+
+/* Representation of one P-Code */
+
+#ifdef CONFIG_INSN16
+typedef struct P
+{
+ uint8_t op;
+ uint8_t arg1;
+ uint16_t arg2;
+} OPTYPE;
+#endif
+
+#ifdef CONFIG_INSN32
+typedef struct P
+{
+ uint8_t op;
+ uint32_t arg;
+} OPTYPE;
+#endif
+
+#endif /* __PDEFS_H */
diff --git a/misc/pascal/include/pedefs.h b/misc/pascal/include/pedefs.h
new file mode 100644
index 000000000..4957a9d2b
--- /dev/null
+++ b/misc/pascal/include/pedefs.h
@@ -0,0 +1,280 @@
+/***********************************************************************
+ * pedefs.h
+ * Definitions of error codes
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************************************/
+
+#ifndef __PEDEFS_H
+#define __PEDEFS_H
+
+/***********************************************************************
+ * Included Files
+ ***********************************************************************/
+
+#include <stdint.h>
+
+/***********************************************************************
+ * Pre-processor Definitions
+ ***********************************************************************/
+
+/***********************************************************************
+ * COMPILATION TIME ERRORS
+ * eASSIGN Expected ':='
+ * eBEGIN Expected 'BEGIN'
+ * eCOLON Expected ':'
+ * eCOMMA Expected ','
+ * eCOUNT Error count exceeded (FATAL)
+ * eDO Expected 'DO'
+ * eDUPFILE Attempt to re-define file
+ * eDUPSYM Attempt to declare duplicate symbol
+ * eEND Expected 'END'
+ * eEQ Expected '='
+ * eEXPONENT Error in exponent of real constant
+ * eFILE Expected file identifier declared in PROGRAM
+ * eHUH Internal error (FATAL)
+ * eIDENT Expected identifier
+ * eIMPLEMENTATION Expected implementation section in unit file
+ * eINCLUDE Include file OPEN error (FATAL)
+ * eINTCONST Expected integer constant
+ * eINTERFACE Expected interface section in unit file
+ * eINTOVF Integer overflow (or underflow)
+ * eINTVAR Integer variable name expected
+ * eINVALIDFUNC Unrecognized built-in function
+ * eINVALIDPROC Unrecognized built-in procedure
+ * eINVARG Invalid procedure/function argument type
+ * eINVCONST Invalid constant in declaration
+ * eINVSIGNEDCONST Invalid constant after sign
+ * eINVFACTOR Invalid factor
+ * eINVFILE Invalid file identifier (as declared in PROGRAM)
+ * eINVLABEL Invalid label
+ * eINVPTR Invalid pointer type
+ * eINVTYPE Invalid type identifier
+ * eINVVARPARM Invalid/unsupported VAR parameter type
+ * eLBRACKET Expected '['
+ * eLPAREN Expected '('
+ * eMULTLABEL Attempt to multiply define label
+ * eNOSQUOTE EOL encounter in a string, probable missing "'"
+ * eNOTYET Not implemented yet
+ * eNPARMS Number of parameters in function or procedure
+ * call does not match number in declaration
+ * eOF Expected 'OF'
+ * eOVF Internal table overflow (FATAL)
+ * ePERIOD Expected '.'
+ * ePOFFCONFUSION Internal logic error in POFF file generation
+ * ePOFFWRITEERROR Error writing to POFF file
+ * ePROGRAM Expected 'PROGRAM'
+ * ePTRADR Expected pointer address (probably got value) form
+ * ePTRVAL Expected pointer value form, got value form
+ * eRBRACKET Expected ']'
+ * eRPAREN Expected ')'
+ * eRPARENorCOMMA Expected ')' or ','
+ * eSEEKFAIL Seek to file position failed
+ * eSEMICOLON Expected ';'
+ * eSTRING Expected a string
+ * eTHEN Expected 'THEN'
+ * eTOorDOWNTO Expected 'TO' or 'DOWNTO' in for statement
+ * eTRUNC String truncated
+ * eUNDECLABEL Attempt to define an undeclared label.
+ * eUNDEFILE Undefined file buffer
+ * eUNDEFLABEL A declared label was not defined.
+ * eUNDEFSYM Undefined symbol
+ * eUNTIL Expected 'UNTIL'
+ * eEXPRTYPE Illegal expression type for this operation
+ * eTERMTYPE Illegal term type for this operation
+ * eFACTORTYPE Illegal factor type for this operation
+ * eREADPARM Illegal parameter in READ statement
+ * eWRITEPARM Illegal parameter in WRITE statement
+ * eARRAYTYPE Illegal type for ARRAY OF
+ * ePOINTERTYPE Illegal pointer type
+ * eVARPARMTYPE Illegal VAR parameter type
+ * eSUBRANGE Expected ".."
+ * eSUBRANGETYPE Illegal subrange type
+ * eSET Expected valid/consistent type for SET OF
+ * sSETRANGE Value out of range for SET OF
+ * eSCALARTYPE Illegal scalar type
+ * eBADSHORTINT Short integer is out of range
+ * eSYMTABINTERNAL Internal error in symbol table
+ * eRECORDDECLARE Error in RECORD declaration
+ * eRECORDOBJECT Expected a field of RECORD
+ * eRECORDVAR Expected a RECORD variable in WITH
+ * eUNIT Expected UNIT at beginning of unit file
+ * eUNITNAME File does not contain the expected UNIT
+ * eARGIGNORED An argument was provided, but ignored
+ *
+ * LINK TIME ERRORS
+ * eUNDEFINEDSYMBOL A necessary symbol was not defined
+ * eMULTIDEFSYMBOL A symbol was defined multiple times
+ *
+ * ERRORS WHICH MAY OCCUR AT EITHER COMPILATION, LINK OR RUNTIME
+ * eNOMEMORY Memory allocation failed
+ * ePOFFREADERROR Error reading a POFF file
+ * ePOFFBADFORMAT The file format does not like valid POFF
+ * eRCVDSIGNAL Received SIGSEGV (or other) signal.
+ *
+ * RUN TIME ERRORS
+ * eBADPC Program Counter is out-of-range
+ * eBADSP Stack reference is out-of-range
+ * eSTRSTKOVERFLOW String stack overflow
+ * eILLEGALOPCODE Non-executable instruction found
+ * eEXIT oEND P-Code encountered
+ * eBADSYSIOFUNC Illegal SYSIO sub-function
+ * eBADSYSLIBCALL Illegal runtime library call
+ * eBADFPOPCODE Illegal FLOAT POINT op-code
+ * eFAILEDLIBCALL Runtime library call returned failure
+ * eINTEGEROVERFLOW Integer overflow
+ **********************************************************************/
+
+/* This is the error code that indicates that no error has occurred */
+
+#define eNOERROR ((uint16_t) 0x00)
+
+/* This is the maximum number of errors that will be reported before
+ * compilation is terminated.
+ */
+
+#define MAX_ERRORS 100
+
+/* COMPILATION TIME ERRORS */
+
+#define eASSIGN ((uint16_t) 0x01)
+#define eBEGIN ((uint16_t) 0x02)
+#define eCOLON ((uint16_t) 0x03)
+#define eCOMMA ((uint16_t) 0x04)
+#define eCOUNT ((uint16_t) 0x05)
+#define eDO ((uint16_t) 0x06)
+#define eDUPFILE ((uint16_t) 0x07)
+#define eDUPSYM ((uint16_t) 0x08)
+#define eEND ((uint16_t) 0x09)
+#define eEQ ((uint16_t) 0x0a)
+#define eEXPONENT ((uint16_t) 0x0b)
+#define eFILE ((uint16_t) 0x0c)
+#define eHUH ((uint16_t) 0x0d)
+#define eIDENT ((uint16_t) 0x0e)
+#define eIMPLEMENTATION ((uint16_t) 0x0f)
+
+#define eINCLUDE ((uint16_t) 0x10)
+#define eINTCONST ((uint16_t) 0x11)
+#define eINTERFACE ((uint16_t) 0x12)
+#define eINTOVF ((uint16_t) 0x13)
+#define eINTVAR ((uint16_t) 0x14)
+#define eINVALIDFUNC ((uint16_t) 0x15)
+#define eINVALIDPROC ((uint16_t) 0x16)
+#define eINVARG ((uint16_t) 0x17)
+#define eINVCONST ((uint16_t) 0x18)
+#define eINVSIGNEDCONST ((uint16_t) 0x19)
+#define eINVFACTOR ((uint16_t) 0x1a)
+#define eINVFILE ((uint16_t) 0x1b)
+#define eINVLABEL ((uint16_t) 0x1c)
+#define eINVPTR ((uint16_t) 0x1d)
+#define eINVTYPE ((uint16_t) 0x1e)
+#define eINVVARPARM ((uint16_t) 0x1f)
+
+#define eLBRACKET ((uint16_t) 0x20)
+#define eLPAREN ((uint16_t) 0x21)
+#define eMULTLABEL ((uint16_t) 0x22)
+#define eNOSQUOTE ((uint16_t) 0x23)
+#define eNOTYET ((uint16_t) 0x24)
+#define eNPARMS ((uint16_t) 0x25)
+#define eOF ((uint16_t) 0x26)
+#define eOVF ((uint16_t) 0x27)
+#define ePERIOD ((uint16_t) 0x28)
+#define ePOFFCONFUSION ((uint16_t) 0x29)
+#define ePOFFWRITEERROR ((uint16_t) 0x2a)
+#define ePROGRAM ((uint16_t) 0x2b)
+#define ePTRADR ((uint16_t) 0x2c)
+#define ePTRVAL ((uint16_t) 0x2d)
+#define eRBRACKET ((uint16_t) 0x2e)
+#define eRPAREN ((uint16_t) 0x2f)
+
+#define eRPARENorCOMMA ((uint16_t) 0x30)
+#define eSEEKFAIL ((uint16_t) 0x31)
+#define eSEMICOLON ((uint16_t) 0x32)
+#define eSTRING ((uint16_t) 0x33)
+#define eTHEN ((uint16_t) 0x34)
+#define eTOorDOWNTO ((uint16_t) 0x35)
+#define eTRUNC ((uint16_t) 0x36)
+#define eUNDECLABEL ((uint16_t) 0x37)
+#define eUNDEFILE ((uint16_t) 0x38)
+#define eUNDEFLABEL ((uint16_t) 0x39)
+#define eUNDEFSYM ((uint16_t) 0x3a)
+#define eUNTIL ((uint16_t) 0x3b)
+#define eEXPRTYPE ((uint16_t) 0x3c)
+#define eTERMTYPE ((uint16_t) 0x3d)
+#define eFACTORTYPE ((uint16_t) 0x3e)
+#define eREADPARM ((uint16_t) 0x3f)
+
+#define eWRITEPARM ((uint16_t) 0x40)
+#define eARRAYTYPE ((uint16_t) 0x41)
+#define ePOINTERTYPE ((uint16_t) 0x42)
+#define eVARPARMTYPE ((uint16_t) 0x43)
+#define eSUBRANGE ((uint16_t) 0x44)
+#define eSUBRANGETYPE ((uint16_t) 0x45)
+#define eSET ((uint16_t) 0x46)
+#define eSETRANGE ((uint16_t) 0x47)
+#define eSCALARTYPE ((uint16_t) 0x48)
+#define eBADSHORTINT ((uint16_t) 0x49)
+#define eSYMTABINTERNAL ((uint16_t) 0x4a)
+#define eRECORDDECLARE ((uint16_t) 0x4b)
+#define eRECORDOBJECT ((uint16_t) 0x4c)
+#define eRECORDVAR ((uint16_t) 0x4d)
+#define eUNIT ((uint16_t) 0x4e)
+#define eUNITNAME ((uint16_t) 0x4f)
+
+#define eARGIGNORED ((uint16_t) 0x50)
+
+/* LINK TIME ERRORS */
+
+#define eUNDEFINEDSYMBOL ((uint16_t) 0x60)
+#define eMULTIDEFSYMBOL ((uint16_t) 0x61)
+
+/* ERRORS WHICH MAY OCCUR AT EITHER COMPILATION OR RUNTIME */
+
+#define eNOMEMORY ((uint16_t) 0x70)
+#define ePOFFREADERROR ((uint16_t) 0x71)
+#define ePOFFBADFORMAT ((uint16_t) 0x72)
+#define eRCVDSIGNAL ((uint16_t) 0x73)
+
+/* RUN TIME ERRORS */
+
+#define eBADPC ((uint16_t) 0x80)
+#define eBADSP ((uint16_t) 0x81)
+#define eSTRSTKOVERFLOW ((uint16_t) 0x82)
+#define eILLEGALOPCODE ((uint16_t) 0x83)
+#define eEXIT ((uint16_t) 0x84)
+#define eBADSYSIOFUNC ((uint16_t) 0x85)
+#define eBADSYSLIBCALL ((uint16_t) 0x86)
+#define eBADFPOPCODE ((uint16_t) 0x87)
+#define eINTEGEROVERFLOW ((uint16_t) 0x89)
+#define eFAILEDLIBCALL ((uint16_t) 0x90)
+
+#endif /* __PEDEFS_H */
diff --git a/misc/pascal/include/perr.h b/misc/pascal/include/perr.h
new file mode 100644
index 000000000..a272ce89c
--- /dev/null
+++ b/misc/pascal/include/perr.h
@@ -0,0 +1,56 @@
+/**********************************************************************
+ * perr.h
+ * External Declarations associated with perr.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************************************/
+
+#ifndef __PERR_H
+#define __PERR_H
+
+/***********************************************************************
+ * Included Files
+ ***********************************************************************/
+
+#include <stdint.h>
+
+/***********************************************************************
+ * Public Function Prototypes
+ ***********************************************************************/
+
+extern void errmsg(char *fmt, ...);
+extern void warn(uint16_t errcode);
+extern void error(uint16_t errcode);
+extern void fatal(uint16_t errcode);
+
+#endif /* __PERR_H */
+
diff --git a/misc/pascal/include/pfdefs.h b/misc/pascal/include/pfdefs.h
new file mode 100644
index 000000000..ac861a641
--- /dev/null
+++ b/misc/pascal/include/pfdefs.h
@@ -0,0 +1,93 @@
+/***********************************************************************
+ * pfdefs.h
+ * Floating point operation codes
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************************************/
+
+#ifndef __PFDEFS_H
+#define __PFDEFS_H
+
+/***********************************************************************
+ * FLOATING POINT SUB-OPCODES
+ ***********************************************************************/
+
+/* This bit may be set in the opcode to indicate that the arguments
+ * is(are) type integer and require(s) conversion. */
+
+#define fpARG1 (0x40)
+#define fpARG2 (0x80)
+#define fpMASK (0x3f)
+#define fpSHIFT 6
+
+/* The "INVALID" floating point operation */
+
+#define fpINVLD (0x00)
+
+/* Floating Pointer Conversions (On 16-bit stack argument: FP or Integer) */
+
+#define fpFLOAT (0x01)
+#define fpTRUNC (0x02)
+#define fpROUND (0x03)
+
+/* Floating Point arithmetic instructions (Two FP 16-bit stack arguments) */
+
+#define fpADD (0x04)
+#define fpSUB (0x05)
+#define fpMUL (0x06)
+#define fpDIV (0x07)
+#define fpMOD (0x08)
+
+/* Floating Point Comparisons (Two FP 16-bit stack arguments) */
+
+#define fpEQU (0x0a)
+#define fpNEQ (0x0b)
+#define fpLT (0x0c)
+#define fpGTE (0x0d)
+#define fpGT (0x0e)
+#define fpLTE (0x0f)
+
+/* Floating Point arithmetic instructions (One FP 16-bit stack arguments) */
+
+#define fpNEG (0x10)
+#define fpABS (0x11)
+#define fpSQR (0x12)
+#define fpSQRT (0x13)
+#define fpSIN (0x14)
+#define fpCOS (0x15)
+#define fpATAN (0x16)
+#define fpLN (0x17)
+#define fpEXP (0x18)
+
+#define MAX_FOP (0x19) /* Number of floating point operations */
+
+#endif /* __PFDEFS_H */
diff --git a/misc/pascal/include/pinsn.h b/misc/pascal/include/pinsn.h
new file mode 100644
index 000000000..b2276b099
--- /dev/null
+++ b/misc/pascal/include/pinsn.h
@@ -0,0 +1,82 @@
+/***************************************************************************
+ * pinsn.h
+ * External Declarations associated libinsn.a
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PINSN_H
+#define __PINSN_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+/* Opcode generators */
+
+extern void insn_GenerateSimple(enum pcode_e opcode);
+extern void insn_GenerateDataOperation(enum pcode_e opcode, int32_t data);
+extern void insn_GenerateDataSize(uint32_t dwDataSize);
+extern void insn_GenerateFpOperation(uint8_t fpOpcode);
+extern void insn_GenerateIoOperation(uint16_t ioOpcode, uint16_t fileNumber);
+extern void insn_BuiltInFunctionCall(uint16_t libOpcode);
+extern void insn_GenerateLevelReference(enum pcode_e opcode, uint16_t level,
+ int32_t offset);
+extern void insn_GenerateProcedureCall(uint16_t level, int32_t offset);
+extern void insn_GenerateLineNumber(uint16_t includeNumber, uint32_t lineNumber);
+extern void insn_SetStackLevel(uint32_t level);
+
+/* Opcode relocation */
+
+extern int insn_Relocate(OPTYPE *op, uint32_t pcOffset, uint32_t roOffset);
+extern void insn_FixupProcedureCall(uint8_t *progData, uint32_t symValue);
+
+/* POFF-wrapped INSNS access helpers */
+
+extern uint32_t insn_GetOpCode(poffHandle_t handle, OPTYPE *ptr);
+extern void insn_ResetOpCodeRead(poffHandle_t handle);
+extern void insn_AddOpCode(poffHandle_t handle, OPTYPE *ptr);
+extern void insn_ResetOpCodeWrite(poffHandle_t handle);
+extern void insn_AddTmpOpCode(poffProgHandle_t progHandle, OPTYPE *ptr);
+extern void insn_ResetTmpOpCodeWrite(poffProgHandle_t progHandle);
+
+/* INSN-specific disassembler */
+
+extern void insn_DisassemblePCode(FILE* lfile, OPTYPE *pop);
+
+#endif /* __PINSN_H */
diff --git a/misc/pascal/include/podefs.h b/misc/pascal/include/podefs.h
new file mode 100644
index 000000000..fc25d62a4
--- /dev/null
+++ b/misc/pascal/include/podefs.h
@@ -0,0 +1,204 @@
+/***********************************************************************
+ * podefs.h
+ * Logical P-code operation code definitions
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************************************/
+
+#ifndef __PODEFS_H
+#define __PODEFS_H
+
+/* These definitions represent logical operations as needed by the
+ * the compiler. The specific INSN generation layer must interpret
+ * these requests as is appropriate to the supported INSNS.
+ */
+
+enum pcode_e
+{
+
+ /**-------------------------------------------------------------------
+ * OPCODES WITH NO ARGUMENTS
+ **-------------------------------------------------------------------**/
+
+ /* Program control (No stack arguments) */
+
+ opNOP = 0,
+
+ /* Arithmetic & logical & and integer conversions (One stack argument) */
+
+ opNEG, opABS, opINC, opDEC, opNOT,
+
+ /* Arithmetic & logical (Two stack arguments) */
+
+ opADD, opSUB, opMUL, opDIV, opMOD, opSLL, opSRL, opSRA, opOR, opAND,
+
+ /* Comparisons (One stack argument) */
+
+ opEQUZ, opNEQZ, opLTZ, opGTEZ, opGTZ, opLTEZ,
+
+ /* Comparisons (Two stack arguments) */
+
+ opEQU, opNEQ, opLT, opGTE, opGT, opLTE,
+ opBIT,
+
+ /* Load Immediate */
+
+ opLDI, opLDIB, opLDIM,
+
+ /* Store Immediate */
+
+ opSTI, opSTIB, opSTIM,
+
+ /* Data stack */
+
+ opDUP, opPUSHS, opPOPS,
+
+ /* Program control (No stack arguments)
+ * Behavior:
+ * Pop return address
+ * Pop saved base register (BR)
+ * Discard saved base address
+ * Set program counter (PC) to return address
+ */
+
+ opRET,
+
+ /* System Functions (No stack arguments) */
+
+ opEND,
+
+ /**-------------------------------------------------------------------
+ ** OPCODES WITH ONE ARGUMENT
+ **-------------------------------------------------------------------**/
+
+ /* Floating point operations: arg = FP op-code */
+
+ opFLOAT,
+
+ /* Program control: arg = unsigned label (One stack argument) */
+
+ opJEQUZ, opJNEQZ,
+
+ /* Program control: arg = unsigned label (no stack arguments) */
+
+ opJMP,
+
+ /* Program control: arg = unsigned label (One stack argument) */
+
+ opJEQU, opJNEQ, opJLT, opJGTE, opJGT, opJLTE,
+
+ /* Load: arg = unsigned base offset */
+
+ opLD, opLDH, opLDB, opLDM,
+
+ /* Store: arg = unsigned base offset */
+
+ opST, opSTB, opSTM,
+
+ /* Load Indexed: arg = unsigned base offset */
+
+ opLDX, opLDXB, opLDXM,
+
+ /* Store Indexed: arg16 = unsigned base offset */
+
+ opSTX, opSTXB, opSTXM,
+
+ /* Load address relative to stack base: arg = unsigned offset */
+
+ opLA,
+
+ /* Load absolute stack address: arg = RODATA offset (No stack arguments) */
+
+ opLAC,
+
+ /* Data stack: arg = 16 bit signed data (no stack arguments) */
+
+ opPUSH, opINDS,
+
+ /* Load address relative to stack base: arg1 = unsigned offset, TOS=index */
+
+ opLAX,
+
+ /* System functions: arg = 16-bit library call identifier */
+
+ opLIB,
+
+ /* Program control: arg = unsigned label (no stack arguments) */
+
+ opLABEL,
+
+ /**-------------------------------------------------------------------
+ ** OPCODES WITH TWO ARGUMENTS
+ **-------------------------------------------------------------------**/
+
+ /* Program Control: arg1 = level; arg2 = unsigned label */
+
+ opPCAL,
+
+ /* Load: arg1 = level; arg2 = signed frame offset */
+
+ opLDS, opLDSH, opLDSB, opLDSM,
+
+ /* Store: arg1 = level; arg2 = signed frame offset */
+
+ opSTS, opSTSB, opSTSM,
+
+ /* Load Indexed: arg1 = level; arg2 = signed frame offset */
+
+ opLDSX, opLDSXB, opLDSXM,
+
+ /* Store Indexed: arg1 = level; arg2 = signed frame offset */
+
+ opSTSX, opSTSXB, opSTSXM,
+
+ /* FOR LAS/LASX arg1 = level; arg2 = signed frame offset
+ * (no stack arguments)
+ */
+
+ opLAS, opLASX,
+
+ /* System calls:
+ * For SYSIO: arg1 = file number; arg2 = sub-function code
+ */
+
+ opSYSIO,
+
+ /* Pseudo-operations:
+ * For LINE: arg1 = file number; arg2 = line number
+ */
+
+ opLINE,
+
+ NUM_OPCODES
+};
+
+#endif /* __PODEFS_H */
diff --git a/misc/pascal/include/poff.h b/misc/pascal/include/poff.h
new file mode 100644
index 000000000..7cc33b290
--- /dev/null
+++ b/misc/pascal/include/poff.h
@@ -0,0 +1,429 @@
+/***************************************************************************
+ * poff.h
+ * Definitions for the PCode Object File Format (POFF)
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __POFF_H
+#define __POFF_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+#include "keywords.h"
+#include "config.h"
+
+/***************************************************************************
+ * Pre-processor Definitions
+ ***************************************************************************/
+
+/* Definitions for the fh_ident field of the poffHdr_t */
+
+#define FHI_MAG0 0 /* fh_ident[] indices */
+#define FHI_MAG1 1
+#define FHI_MAG2 2
+#define FHI_MAG3 3
+#define FHI_NIDENT 4
+
+#define FHI_POFF_MAG0 'P'
+#define FHI_POFF_MAG1 'O'
+#define FHI_POFF_MAG2 'F'
+#define FHI_POFF_MAG3 'F'
+#define FHI_POFF_MAG "POFF"
+
+/* Definitions for fh_version */
+
+#define FHV_NONE 0
+#define FHV_CURRENT 1
+
+/* Definitions for the fh_type */
+
+#define FHT_NONE 0 /* Shouldn't happen */
+#define FHT_EXEC 1 /* Pascal program executable */
+#define FHT_SHLIB 2 /* Pascal shared library */
+#define FHT_PROGRAM 3 /* Pascal program object */
+#define FHT_UNIT 4 /* Pascal unit object */
+#define FHT_NTYPES 5
+
+/* Definitions for fh_arch */
+
+#define FHAW_INSN16 0 /* Data width is 16 bits */
+#define FHAW_INSN32 1 /* Data width is 32 bits */
+
+#define FHAC_PCODE 0 /* Stack oriented P-Code machine class */
+#define FHAC_REGM 1 /* Generalized register machine class */
+
+#define MK_FH_ARCH(c,w) (((c)<<4)|(w))
+#define GET_FH_CLASS(fha) ((fha) >> 4)
+#define GET_FH_WIDTH(fha) ((fha) & 0x0f)
+
+#define FHA_PCODE_INSN16 MK_FH_ARCH(FHAC_PCODE,FHAW_INSN16)
+#define FHA_PCODE_INSN32 MK_FH_ARCH(FHAC_PCODE,FHAW_INSN32)
+#define FHA_REGM_INSN16 MK_FH_ARCH(FHAC_REGM,FHAW_INSN16)
+#define FHA_REGM_INSN32 MK_FH_ARCH(FHAC_REGM,FHAW_INSN32)
+
+#ifdef CONFIG_INSN16
+# define FHA_PCODE FHA_PCODE_INSN16
+# define FHA_REGM FHA_REGM_INSN16
+#endif
+#ifdef CONFIG_INSN32
+# define FHA_PCODE FHA_PCODE_INSN32
+# define FHA_REGM FHA_REGM_INSN16
+#endif
+
+/* Definitions for sh_type */
+
+#define SHT_NULL 0 /* Shouldn't happen */
+#define SHT_PROGDATA 1 /* Program data */
+#define SHT_SYMTAB 2 /* Symbol table */
+#define SHT_STRTAB 3 /* String table */
+#define SHT_REL 4 /* Relocation data */
+#define SHT_FILETAB 5 /* File table */
+#define SHT_LINENO 6 /* Line number data */
+#define SHT_DEBUG 7 /* Procedure/Function info */
+#define SHT_NTYPES 8
+
+/* Definitions for sh_flags */
+
+#define SHF_WRITE 0x01 /* Section is write-able */
+#define SHF_ALLOC 0x02 /* Memory must be allocated for setion */
+#define SHF_EXEC 0x04 /* Section contains program data */
+
+/* Values for st_type */
+
+#define STT_NONE 0 /* Should not occur */
+#define STT_DATA 1 /* Stack data section symbol */
+#define STT_RODATA 2 /* Read only data section symbol */
+#define STT_PROC 3 /* Procedure entry point */
+#define STT_FUNC 4 /* Function entry point */
+#define STT_NTYPES 5
+
+/* Values for st_align. Any power of two numeric value can be
+ * used, but the following are defined for convenience.
+ */
+
+#define STA_NONE 0 /* Should not occur */
+#define STA_8BIT 1 /* 8-bit byte alignment */
+#define STA_16BIT 2 /* 16-bit half word alignment */
+#define STA_32BIT 4 /* 32-bit word alignment */
+#define STA_64BIT 8 /* 32-bit double word alignment */
+
+/* Values for st_flags */
+
+#define STF_NONE 0x00
+#define STF_UNDEFINED 0x01 /* Symbol is undefined (imported) */
+
+/* P-Code relocation types (see RLI_type) */
+
+#define RLT_NONE 0 /* Should not occur */
+#define RLT_PCAL 1 /* PCAL to external proc/func */
+#define RLT_LDST 2 /* LA or LAX to external stack loc */
+#define RLT_NTYPES 3
+
+/* The following are used with relocation table rl_info field */
+
+#define RLI_SYM(x) ((x) >> 8) /* Symbol index */
+#define RLI_TYPE(x) ((x) & 0xff) /* Rloc type */
+#define RLI_MAKE(s,t) (((uint32_t)(s) << 8) | ((t) & 0xff))
+
+/***************************************************************************
+ * Public Types
+ ***************************************************************************/
+
+/* POFF file header */
+
+struct poffFileHeader_s
+{
+ /* fh_ident holds the four characters 'P', 'O', 'F', 'F'
+ * See the FHI_ definitions above.
+ */
+
+ uint8_t fh_ident[FHI_NIDENT];
+
+ /* fh_version holds the version of the POFF file format. This should
+ * always be FHV_CURRENT.
+ */
+
+ uint8_t fh_version;
+
+ /* fh_type holds the type of binary carry by the POFF file.
+ * See the FHT_ definitions above.
+ */
+
+ uint8_t fh_type;
+
+ /* fh_arch holds the mach architecture identifier. See the FHA_
+ * definitions above.
+ */
+
+ uint8_t fh_arch;
+
+ /* Pad so that the next field is aligned */
+
+ uint8_t fh_padding;
+
+ /* fh_shsize is the size a section header. This should be
+ * sizeof(poffSectionHeader_t)
+ */
+
+ uint16_t fh_shsize;
+
+ /* fh_num is the number of section headers in section header
+ * list. The total size of the section header block is then
+ * fh_shsize * fh_shnum.
+ */
+
+ uint16_t fh_shnum;
+
+ /* fh_name is an offset into the string table section data.
+ * It refers to a name associated with fh_type that determines
+ * the specific instances of the type.
+ */
+
+ uint32_t fh_name;
+
+ /* For fhi_type = {FHI_EXEC or FHI_PROGRAM}, fh_entry holds the
+ * entry point into the program. For FHI_PROGRAM, this entry point
+ * is a instruction space label. For FHI_EXEC, this entry point
+ * is an instruction space address offset (from address zero).
+ */
+
+ uint32_t fh_entry;
+
+ /* fh_shoff is the file offset to the beginning of the table of file
+ * headers. fh_shoff will most likely be sizeof(poffFileHeader_t).
+ */
+
+ uint32_t fh_shoff;
+};
+typedef struct poffFileHeader_s poffFileHeader_t;
+
+/* POFF section header */
+
+struct poffSectionHeader_s
+{
+ /* sh_type is the type of section described by this header.
+ * See the SHT_ definitions above.
+ */
+
+ uint8_t sh_type;
+
+ /* These flags describe the characteristics of the section. See the
+ * SHF_ definitions above.
+ */
+
+ uint8_t sh_flags;
+
+ /* If the section holds a table of fixed sized entries, sh_entsize
+ * gives the size of one entry. The number of entries can then be
+ * obtained by dividing sh_size by sh_entsize.
+ */
+
+ uint16_t sh_entsize;
+
+ /* sh_name is an offset into the string table section data.
+ * It refers to a name associated with section.
+ */
+
+ uint32_t sh_name;
+
+ /* If the section is loaded into memory (SHF_ALLOC), then this
+ * address holds the address at which the data must be loaded
+ * (if applicable).
+ */
+
+ uint32_t sh_addr;
+
+ /* sh_offset is the offset from the beginning of the file to
+ * beginning of data associated with this section.
+ */
+
+ uint32_t sh_offset;
+
+ /* sh_size provides the total size of the section data in bytes.
+ * If the section holds a table of fixed sized entries, then
+ * sh_size be equal to sh_entsize times the number of entries.
+ */
+
+ uint32_t sh_size;
+};
+typedef struct poffSectionHeader_s poffSectionHeader_t;
+
+/* Structures which may appear as arrays in sections */
+
+/* Relocation data section array entry structure */
+
+struct poffRelocation_s
+ {
+ /* This value includes the symbol table index plus the
+ * relocation type. See the RLI_* macros above.
+ */
+
+ uint32_t rl_info;
+
+ /* This is the section data offset to the instruction/data
+ * to be relocated. The effected section is implicit in the
+ * relocation type.
+ */
+
+ uint32_t rl_offset; /* Offset to pcode */
+};
+typedef struct poffRelocation_s poffRelocation_t;
+
+/* Symbol section array entry structure */
+
+struct poffSymbol_s
+{
+ /* st_type is the type of symbol described by this entry.
+ * See the STT_ definitions above.
+ */
+
+ uint8_t st_type;
+
+ /* For data section symbols, the following provides the required
+ * data space alignment for the symbol memory representation. For
+ * procedures and functions, this value is ignored. See the STT_
+ * definitions above.
+ */
+
+ uint8_t st_align;
+
+ /* These flags describe the characteristics of the symbol. See the
+ * STF_ definitions above.
+ */
+
+ uint8_t st_flags;
+ uint8_t st_pad;
+
+ /* st_name is an offset into the string table section data.
+ * It refers to a name associated with symbol.
+ */
+
+ uint32_t st_name;
+
+ /* st_value is the value associated with symbol. For defined data
+ * section symbols, this is the offset into the initialized data
+ * section data; for defined procedures and functions, this the
+ * offset into program section data. For undefined symbols, this
+ * valid can be used as as addend.
+ */
+
+ uint32_t st_value;
+
+ /* For data section symbols, this is the size of the initialized
+ * data region associated with the symbol.
+ */
+
+ uint32_t st_size;
+};
+typedef struct poffSymbol_s poffSymbol_t;
+
+/* The file table section just consists of a list of offsets
+ * into the string table. The file table index is used elsewhere
+ * (such as in the line number array) to refer to a specific
+ * file.
+ */
+
+typedef uint32_t poffFileTab_t;
+
+/* Line number section array entry structure. Line numbers are
+ * associated with executable program data sections.
+ */
+
+struct poffLineNumber_s
+{
+ /* This is the source file line number */
+
+ uint16_t ln_lineno;
+
+ /* This is an index (not a byte offset) to an entry in the file
+ * section table. This can be used to identify the name of the
+ * file for which the line number applies.
+ */
+
+ uint16_t ln_fileno;
+
+ /* This is an offset to the beginning of the instruction in the
+ * program data section. At present, this is limited to a single
+ * program data section.
+ */
+
+ uint32_t ln_poffset;
+};
+typedef struct poffLineNumber_s poffLineNumber_t;
+
+/* The debug info section consists of a list of poffDebugFuncInfo_t
+ * entries, each following a sublist of poffDebugArgInfo_t entries.
+ */
+
+/* poffDebugFuncInfo_t provides description of function input
+ * parameters and return values.
+ */
+
+struct poffDebugFuncInfo_s
+{
+ /* This is the address or label of the function/procedure entry
+ * point.
+ */
+
+ uint32_t df_value;
+
+ /* This is the size of the value returned by the function in
+ * bytes (zero for procedures).
+ */
+
+ uint32_t df_size;
+
+ /* This is the number of parameters accepted by the function/
+ * procedure.
+ */
+
+ uint32_t df_nparms;
+};
+typedef struct poffDebugFuncInfo_s poffDebugFuncInfo_t;
+
+/* poffDebugArgInfo_t provides description of one function input
+ * parameter.
+ */
+
+struct poffDebugArgInfo_s
+{
+ /* This is the size, in bytes, of one input paramter */
+
+ uint32_t da_size;
+};
+typedef struct poffDebugArgInfo_s poffDebugArgInfo_t;
+
+#endif /* __POFF_H */
diff --git a/misc/pascal/include/pofflib.h b/misc/pascal/include/pofflib.h
new file mode 100644
index 000000000..3547fca60
--- /dev/null
+++ b/misc/pascal/include/pofflib.h
@@ -0,0 +1,313 @@
+/***************************************************************************
+ * pofflib.h
+ * Interfaces to the POFF library
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __POFFLIB_H
+#define __POFFLIB_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+#include "keywords.h"
+#include "poff.h"
+
+/***************************************************************************
+ * Definitions
+ ***************************************************************************/
+
+/***************************************************************************
+ * Public Types
+ ***************************************************************************/
+
+/* The internal form of the POFF data structures are hidden from the caller
+ * in these "handles"
+ */
+
+typedef void *poffHandle_t;
+typedef void *poffProgHandle_t;
+typedef void *poffSymHandle_t;
+
+/* This is a externally visible form of a symbol table entry that is
+ * not entangled in the POFF internal string table logic.
+ */
+
+struct poffLibSymbol_s
+{
+ /* type is the type of symbol described by this entry.
+ * See the STT_ definitions in poff.h.
+ */
+
+ uint8_t type;
+
+ /* For data section symbols, the following provides the required
+ * data space alignment for the symbol memory representation. For
+ * procedures and functions, this value is ignored. See the STT_
+ * definitions in poff.h
+ */
+
+ uint8_t align;
+
+ /* These flags describe the characteristics of the symbol. See the
+ * STF_ definitions above.
+ */
+
+ uint8_t flags;
+
+ /* name is a reference to the symbol name in the string table
+ * section data.
+ */
+
+ const char *name;
+
+ /* value is the value associated with symbol. For defined data
+ * section symbols, this is the offset into the initialized data
+ * section data; for defined procedures and functions, this the
+ * offset into program section data. For undefined symbols, this
+ * valid can be used as as addend.
+ */
+
+ uint32_t value;
+
+ /* For data section symbols, this is the size of the initialized
+ * data region associated with the symbol.
+ */
+
+ uint32_t size;
+};
+typedef struct poffLibSymbol_s poffLibSymbol_t;
+
+/* The externally visible form of a line number structure. Line numbers
+ * are associated with executable program data sections.
+ */
+
+struct poffLibLineNumber_s
+{
+ /* This is the source file line number */
+
+ uint32_t lineno;
+
+ /* This is the full filename of the file containing the line number. */
+
+ const char *filename;
+
+ /* This is an offset to the beginning code in the program data section
+ * associated with this line number.
+ */
+
+ uint32_t offset;
+};
+typedef struct poffLibLineNumber_s poffLibLineNumber_t;
+
+/* The externally visible form of a debug function info structure.
+ */
+
+struct poffLibDebugFuncInfo_s
+{
+ /* For use outside of libpoff so that the allocated debug
+ * information can be retained in a list.
+ */
+
+ struct poffLibDebugFuncInfo_s *next;
+
+ /* This is the address or label of the function/procedure entry
+ * point.
+ */
+
+ uint32_t value;
+
+ /* This is the size of the value returned by the function in
+ * bytes (zero for procedures).
+ */
+
+ uint32_t retsize;
+
+ /* This is the number of parameters accepted by the function/
+ * procedure.
+ */
+
+ uint32_t nparms;
+
+ /* This is the beginning of a table of input parameter sizes
+ * the actually allocate size will be nparms entries.
+ */
+
+ uint32_t argsize[1];
+};
+typedef struct poffLibDebugFuncInfo_s poffLibDebugFuncInfo_t;
+
+#define SIZEOFDEBUFINFO(n) (sizeof(poffLibDebugFuncInfo_t) + ((n)-1)*sizeof(uint32_t))
+
+/***************************************************************************
+ * Public Variables
+ ***************************************************************************/
+
+/***************************************************************************
+ * Public Function Prototypes
+ ***************************************************************************/
+
+/* Functions to create/destroy a handle to POFF file data */
+
+extern poffHandle_t poffCreateHandle(void);
+extern void poffDestroyHandle(poffHandle_t handle);
+extern void poffResetAccess(poffHandle_t handle);
+
+/* Functions to manage writing a POFF file */
+
+extern void poffSetFileType(poffHandle_t handle, uint8_t fh_type,
+ uint16_t nfiles, const char *name);
+extern void poffSetArchitecture(poffHandle_t handle, uint8_t fh_arch);
+extern void poffSetEntryPoint(poffHandle_t handle, uint32_t entryPoint);
+extern int32_t poffFindString(poffHandle_t handle, const char *string);
+extern uint32_t poffAddString(poffHandle_t handle, const char *string);
+extern uint32_t poffAddFileName(poffHandle_t handle, const char *name);
+extern void poffAddProgByte(poffHandle_t handle, uint8_t progByte);
+#if 0 /* not used */
+extern uint32_t poffAddRoDataByte(poffHandle_t handle, uint8_t dataByte);
+#endif
+extern uint32_t poffAddRoDataString(poffHandle_t handle,
+ const char *string);
+extern uint32_t poffAddSymbol(poffHandle_t handle,
+ poffLibSymbol_t *symbol);
+extern uint32_t poffAddLineNumber(poffHandle_t handle,
+ uint16_t lineNumber, uint16_t fileNumber,
+ uint32_t progSectionDataOffset);
+extern uint32_t poffAddDebugFuncInfo(poffHandle_t handle,
+ poffLibDebugFuncInfo_t *pContainer);
+extern uint32_t poffAddRelocation(poffHandle_t handle,
+ uint8_t relocType, uint32_t symIndex,
+ uint32_t sectionDataOffset);
+extern void poffWriteFile(poffHandle_t handle, FILE *poffFile);
+
+/* Functions to manage reading a POFF file */
+
+extern uint16_t poffReadFile(poffHandle_t handle, FILE *poffFile);
+extern uint8_t poffGetFileType(poffHandle_t handle);
+extern uint8_t poffGetArchitecture(poffHandle_t handle);
+extern uint32_t poffGetEntryPoint(poffHandle_t handle);
+extern const char *poffGetFileHdrName(poffHandle_t handle);
+extern uint32_t poffGetRoDataSize(poffHandle_t handle);
+extern int32_t poffGetFileName(poffHandle_t handle, const char **fname);
+extern int poffGetProgByte(poffHandle_t handle);
+extern int32_t poffGetSymbol(poffHandle_t handle,
+ poffLibSymbol_t *symbol);
+extern const char *poffGetString(poffHandle_t handle, uint32_t index);
+extern int32_t poffGetLineNumber(poffHandle_t handle,
+ poffLibLineNumber_t *lineno);
+extern int32_t poffGetRawLineNumber(poffHandle_t handle,
+ poffLineNumber_t *lineno);
+extern int32_t poffGetRawRelocation(poffHandle_t handle,
+ poffRelocation_t *reloc);
+extern poffLibDebugFuncInfo_t *poffGetDebugFuncInfo(poffHandle_t handle);
+extern poffLibDebugFuncInfo_t *poffCreateDebugInfoContainer(uint32_t nparms);
+extern void poffReleaseDebugFuncContainer(poffLibDebugFuncInfo_t *pDebugFuncInfo);
+extern void poffDiscardDebugFuncInfo(poffHandle_t handle);
+extern int32_t poffProgTell(poffHandle_t handle);
+extern int poffProgSeek(poffHandle_t handle, uint32_t offset);
+extern uint32_t poffGetProgSize(poffHandle_t handle);
+extern void poffReleaseProgData(poffHandle_t handle);
+
+/* Functions used to manage modifications to a POFF file using a
+ * temporary container for the new program data.
+ */
+
+extern poffProgHandle_t poffCreateProgHandle(void);
+extern void poffDestroyProgHandle(poffProgHandle_t handle);
+extern void poffResetProgHandle(poffProgHandle_t handle);
+extern uint16_t poffAddTmpProgByte(poffProgHandle_t handle,
+ uint8_t progByte);
+extern uint16_t poffWriteTmpProgBytes(uint8_t *buffer, uint32_t nbyte,
+ poffProgHandle_t handle);
+extern void poffReplaceProgData(poffHandle_t handle,
+ poffProgHandle_t progHandle);
+
+/* Functions used to manage modifications to a POFF file using a
+ * temporary container for the new symbol data.
+ */
+
+extern poffSymHandle_t poffCreateSymHandle(void);
+extern void poffDestroySymHandle(poffSymHandle_t handle);
+extern void poffResetSymHandle(poffSymHandle_t handle);
+extern uint32_t poffAddTmpSymbol(poffHandle_t handle, poffSymHandle_t symHandle,
+ poffLibSymbol_t *symbol);
+extern void poffReplaceSymbolTable(poffHandle_t handle,
+ poffSymHandle_t symHandle);
+
+/* Functions used to extract/insert whole data sections from/into a POFF
+ * file container
+ */
+
+extern uint32_t poffExtractProgramData(poffHandle_t handle,
+ uint8_t **progData);
+extern void poffInsertProgramData(poffHandle_t handle,
+ uint8_t *progData, uint32_t progSize);
+extern uint32_t poffExtractRoData(poffHandle_t handle,
+ uint8_t **roData);
+extern void poffAppendRoData(poffHandle_t handle,
+ uint8_t *roData, uint32_t roDataSize);
+
+/* Functions to manage printing of the POFF file content */
+
+extern void poffDumpFileHeader(poffHandle_t handle, FILE *outFile);
+extern void poffDumpSectionHeaders(poffHandle_t handle, FILE *outFile);
+extern void poffDumpSymbolTable(poffHandle_t handle, FILE *outFile);
+extern void poffDumpRelocTable(poffHandle_t handle, FILE *outFile);
+
+/* Helper functions to manage resolution of labels in POFF files. These
+ * just store and retrieve information by label number.
+ */
+
+extern void poffAddToDefinedLabelTable(uint32_t label, uint32_t pc);
+extern void poffAddToUndefinedLabelTable(uint32_t label,
+ uint32_t symIndex);
+extern int poffGetSymIndexForUndefinedLabel(uint32_t label);
+extern int poffGetPcForDefinedLabel(uint32_t label);
+extern void poffReleaseLabelReferences(void);
+
+/* Helper functions for line numbers */
+
+extern void poffReadLineNumberTable(poffHandle_t handle);
+extern poffLibLineNumber_t *poffFindLineNumber(uint32_t offset);
+extern void poffReleaseLineNumberTable(void);
+
+/* Helper functions for debug information */
+
+extern void poffReadDebugFuncInfoTable(poffHandle_t handle);
+extern poffLibDebugFuncInfo_t *poffFindDebugFuncInfo(uint32_t offset);
+extern void poffReplaceDebugFuncInfo(poffHandle_t handle);
+extern void poffReleaseDebugFuncInfoTable(void);
+
+#endif /* __POFFLIB_H */
diff --git a/misc/pascal/include/pxdefs.h b/misc/pascal/include/pxdefs.h
new file mode 100644
index 000000000..8c9ab834d
--- /dev/null
+++ b/misc/pascal/include/pxdefs.h
@@ -0,0 +1,232 @@
+/***********************************************************************
+ * pxdefs.h
+ * Definitions of the arguments of the oSYSIO opcode
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************************************/
+
+#ifndef __PXDEFS_H
+#define __PXDEFS_H
+
+/***********************************************************************/
+/* Codes for system IO calls associated with standard Pascal procedure
+ * and function calls. These must be confined to the range 0x0000
+ * through 0xffff.
+ */
+
+#define xEOF (0x0001)
+#define xEOLN (0x0002)
+#define xRESET (0x0003)
+#define xREWRITE (0x0004)
+
+#define xREADLN (0x0010)
+#define xREAD_PAGE (0x0011)
+#define xREAD_BINARY (0x0012)
+#define xREAD_INT (0x0013)
+#define xREAD_CHAR (0x0014)
+#define xREAD_STRING (0x0015)
+#define xREAD_REAL (0x0016)
+
+#define xWRITELN (0x0020)
+#define xWRITE_PAGE (0x0021)
+#define xWRITE_BINARY (0x0022)
+#define xWRITE_INT (0x0023)
+#define xWRITE_CHAR (0x0024)
+#define xWRITE_STRING (0x0025)
+#define xWRITE_REAL (0x0026)
+
+#define MAX_XOP (0x0027)
+
+/***********************************************************************/
+/* Codes for runtime library interfaces. These must be confined to the
+ * range 0x0000 through 0xffff.
+ */
+
+/* Get an environment string.
+ * function getent(name : string) : cstring;
+ * ON INPUT:
+ * TOS(0)=length of string
+ * TOS(1)=pointer to string
+ * ON RETURN: actual parameters released
+ * TOS(0,1)=32-bit absolute address of string
+ */
+
+#define lbGETENV (0x0000)
+
+/* Copy pascal string to a pascal string
+ * procedure str2str(src : string; var dest : string)
+ * ON INPUT:
+ * TOS(0)=address of dest string
+ * TOS(1)=length of source string
+ * TOS(2)=pointer to source string
+ * ON RETURN: actual parameters released.
+ */
+
+#define lbSTR2STR (0x0001)
+
+/* Copy C string to a pascal string
+ * procedure cstr2str(src : cstring; var dest : string)
+ * ON INPUT:
+ * TOS(0)=address of dest string
+ * TOS(1,2)=32-bit absolute address of C string
+ * ON RETURN: actual parameters released
+ */
+
+#define lbCSTR2STR (0x0002)
+
+/* Copy pascal string to a pascal string reference
+ * procedure str2rstr(src : string; var dest : rstring)
+ * ON INPUT:
+ * TOS(0)=address of dest string reference
+ * TOS(1)=length of source string
+ * TOS(2)=pointer to source string
+ * ON RETURN: actual parameters released.
+ */
+
+#define lbSTR2RSTR (0x0003)
+
+/* Copy C string to a pascal string reference
+ * procedure cstr2str(src : cstring; var dest : string)
+ * ON INPUT:
+ * TOS(0)=address of dest string reference
+ * TOS(0)=MS 16-bits of 32-bit C source string pointer
+ * TOS(1)=LS 16-bits of 32-bit C source string pointer
+ * ON RETURN: actual parameters released
+ */
+
+#define lbCSTR2RSTR (0x0004)
+
+/* Convert a string to a numeric value
+ * procedure val(const s : string; var v; var code : word);
+ *
+ * Description:
+ * val() converts the value represented in the string S to a numerical
+ * value, and stores this value in the variable V, which can be of type
+ * Longint, Real and Byte. If the conversion isn¡Çt succesfull, then the
+ * parameter Code contains the index of the character in S which
+ * prevented the conversion. The string S is allowed to contain spaces
+ * in the beginning.
+ *
+ * The string S can contain a number in decimal, hexadecimal, binary or
+ * octal format, as described in the language reference.
+ *
+ * Errors:
+ * If the conversion doesn¡Çt succeed, the value of Code indicates the
+ * position where the conversion went wrong.
+ *
+ * ON INPUT
+ * TOS(0)=address of Code
+ * TOS(1)=address of v
+ * TOS(2)=length of source string
+ * TOS(3)=pointer to source string
+ * ON RETURN: actual parameters released
+ */
+
+#define lbVAL (0x0005)
+
+/* Create an empty string
+ * function mkstk : string;
+ * ON INPUT
+ * ON RETURN
+ * TOS(0)=length of new string
+ * TOS(1)=pointer to new string
+ */
+
+#define lbMKSTK (0x0006)
+
+/* Replace a string with a duplicate string residing in allocated
+ * string stack.
+ * function mkstkstr(name : string) : string;
+ * ON INPUT
+ * TOS(0)=length of original string
+ * TOS(1)=pointer to original string
+ * ON RETURN
+ * TOS(0)=length of new string
+ * TOS(1)=pointer to new string
+ */
+
+#define lbMKSTKSTR (0x0007)
+
+/* Replace a character with a string residing in allocated string stack.
+ * function mkstkc(c : char) : string;
+ * ON INPUT
+ * TOS(0)=Character value
+ * ON RETURN
+ * TOS(0)=length of new string
+ * TOS(1)=pointer to new string
+ */
+
+#define lbMKSTKC (0x0008)
+
+/* Concatenate a string to the end of a string.
+ * function strcat(name : string, c : char) : string;
+ * ON INPUT
+ * TOS(0)=length of string
+ * TOS(1)=pointer to string
+ * TOS(2)=length of string
+ * TOS(3)=pointer to string
+ * ON OUTPUT
+ * TOS(1)=new length of string
+ * TOS(2)=pointer to string
+ */
+
+#define lbSTRCAT (0x0009)
+
+/* Concatenate a character to the end of a string.
+ * function strcatc(name : string, c : char) : string;
+ * ON INPUT
+ * TOS(0)=character to concatenate
+ * TOS(1)=length of string
+ * TOS(2)=pointer to string
+ * ON OUTPUT
+ * TOS(1)=new length of string
+ * TOS(2)=pointer to string
+ */
+
+#define lbSTRCATC (0x000a)
+
+/* Compare two pascal strings
+ * function strcmp(name1 : string, name2 : string) : integer;
+ * ON INPUT
+ * TOS(1)=length of string2
+ * TOS(2)=address of string2 data
+ * TOS(3)=length of string1
+ * TOS(4)=address of string1 data
+ * ON OUTPUT
+ * TOS(0)=(-1=less than, 0=equal, 1=greater than}
+ */
+
+#define lbSTRCMP (0x000b)
+
+#define MAX_LBOP (0x000c)
+
+#endif /* __PXDEFS_H */
diff --git a/misc/pascal/insn16/Makefile b/misc/pascal/insn16/Makefile
new file mode 100644
index 000000000..0af4ae13e
--- /dev/null
+++ b/misc/pascal/insn16/Makefile
@@ -0,0 +1,82 @@
+############################################################################
+# insn16/Makefile
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Directories
+#
+INSNDIR = ${shell pwd}
+PASCAL = $(INSNDIR)/..
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+LIBDIR = $(PASCAL)/lib
+BINDIR = $(PASCAL)/bin16
+LIBINSNDIR = $(INSNDIR)/libinsn
+POPTDIR = $(INSNDIR)/popt
+PRUNDIR = $(INSNDIR)/prun
+PLISTDIR = $(INSNDIR)/plist
+
+#
+# Objects and targets
+#
+all: libinsn popt prun plist
+PHONY: all libinsn popt prun plist clean
+
+$(LIBINSNDIR)/libinsn.a:
+ $(MAKE) -C $(LIBINSNDIR)
+
+libinsn.a: $(LIBINSNDIR)/libinsn.a
+
+$(BINDIR)/popt:
+ $(MAKE) -C $(POPTDIR)
+
+popt: $(BINDIR)/popt
+
+$(BINDIR)/prun:
+ $(MAKE) -C $(PRUNDIR)
+
+prun: $(BINDIR)/prun
+
+$(BINDIR)/plist:
+ $(MAKE) -C $(PLISTDIR)
+
+plist: $(BINDIR)/plist
+
+clean:
+ $(RM) libinsn.a core *~
+ $(MAKE) -C $(LIBINSNDIR) clean
+ $(MAKE) -C $(POPTDIR) clean
+ $(MAKE) -C $(PRUNDIR) clean
+ $(MAKE) -C $(PLISTDIR) clean
diff --git a/misc/pascal/insn16/doc/PascalOptimizations.txt b/misc/pascal/insn16/doc/PascalOptimizations.txt
new file mode 100644
index 000000000..d197e73da
--- /dev/null
+++ b/misc/pascal/insn16/doc/PascalOptimizations.txt
@@ -0,0 +1,239 @@
+P-Code optimizations:
+ Let <push-ops> be oPUSH|oPUSHB
+ Let <load-ops> be oLOD|oLODB|PUSH|oLADR|oLCADR
+
+pcopt.c:unaryOptimize
+STEP 1:
+Remove unary operators on constants:
+ <push-op> arg + oNEG -> <push-op> arg
+ <push-op> arg + oABS -> <push-op> |arg|
+ <push-op> arg + oINC -> <push-op> arg+1
+ <push-op> arg + oDEC -> <push-op> arg-1
+ <push-op> arg + oNOT -> <push-op> ~arg
+
+Simplify binary operations on constants
+ <push-op> arg + oADD
+ if arg == 0 -> delete both
+ else if arg == 1 -> oINC
+ else if arg == -1 -> oDEC
+ <push-op> arg + oSUB
+ if arg == 0 -> delete both
+ else if arg == 1 -> oDEC
+ else if arg == -1 -> oINC
+ <push-op> arg + oMUL
+ if arg is power of 2 -> oSLL power
+ <push-op> arg + oDIV
+ if arg is power of 2 -> oSRA power
+ <push-op> arg + oSLL
+ if arg is 0 -> <push-op> arg
+ <push-op> arg + oSRL
+ if arg is 0 -> <push-op> arg
+ <push-op> arg + oSRA
+ if arg is 0 -> <push-op> arg
+ <push-op> arg + oOR
+ if arg is 0 -> <push-op> arg
+ <push-op> arg + oAND
+ if arg is 0xffff -> <push-op> arg
+
+Delete comparisons with zero
+ <push-op> arg + oEQUZ
+ if arg == 0 -> <push-op> true
+ else -> <push-op> false
+ <push-op> arg + oNEQZ
+ if arg != 0 -> <push-op> true
+ else -> <push-op> false
+ <push-op> arg + oLTZ
+ if arg < 0 -> <push-op> true
+ else -> <push-op> false
+ <push-op> arg + oGTEZ
+ if arg >= 0 -> <push-op> true
+ else -> <push-op> false
+ <push-op> arg + oGTZ
+ if arg > 0 -> <push-op> true
+ else -> <push-op> false
+ <push-op> arg + oLTEZ
+ if arg <= 0 -> <push-op> true
+ else -> <push-op> false
+
+Simplify comparisons with certain constants
+ <push-op> arg + oEQU
+ if arg == 0 -> oEQUZ
+ else if arg == 1 -> oDEC + oEQUZ
+ else if arg == -1 -> oINC + oEQUZ
+ <push-op> arg + oNEQ
+ if arg == 0 -> oNEQZ
+ else if arg == 1 -> oDEC + oNEQZ
+ else if arg == -1 -> oINC + oNEQZ
+ <push-op> arg + oLT
+ if arg == 0 -> oLTZ
+ else if arg == 1 -> oDEC + oLTZ
+ else if arg == -1 -> oINC + oLTZ
+ <push-op> arg + oGTE
+ if arg == 0 -> oGTEZ
+ else if arg == 1 -> oDEC + oGTEZ
+ else if arg == -1 -> oINC + oGTEZ
+ <push-op> arg + oGT
+ if arg == 0 -> oGTZ
+ else if arg == 1 -> oDEC + oGTZ
+ else if arg == -1 -> oINC + oGTZ
+ <push-op> arg + oLTE
+ if arg == 0 -> oLTEZ
+ else if arg == 1 -> oDEC + oLTEZ
+ else if arg == -1 -> oINC + oLTEZ
+
+Simplify or delete condition branches on constants
+ <push-op> arg + oJEQUZ
+ if arg == 0 -> oJMP
+ else -> delete both
+ <push-op> arg + oJNEQZ
+ if arg != 0 -> oJMP
+ else -> delete both
+ <push-op> arg + oJLTZ
+ if arg < 0 -> oJMP
+ else -> delete both
+ <push-op> arg + oJGTEZ
+ if arg >= 0 -> oJMP
+ else -> delete both
+ <push-op> arg + oJGTZ
+ if arg > 0 -> oJMP
+ else -> delete both
+ <push-op> arg + oJLTEZ
+ if arg <= 0 -> oJMP
+ else -> delete both
+STEP 1a:
+ <push-op> arg
+ if arg < 256 -> oPUSHB arg
+ else -> oPUSH arg
+
+STEP 2:
+Delete multiple modifications of DSEG pointer
+ INDS arg1 + INDS arg2 -> INDS arg1+arg2
+
+pcopt.c:binaryOptimize
+STEP 1:
+ <push-op> arg1 + <push-op> arg2 + oADD -> oPUSH arg1 + arg2 + STEP 1a
+ <push-op> arg1 + <push-op> arg2 + oSUB -> oPUSH arg1 - arg2 + STEP 1a
+ <push-op> arg1 + <push-op> arg2 + oMUL -> oPUSH arg1 * arg2 + STEP 1a
+ <push-op> arg1 + <push-op> arg2 + oDIV -> oPUSH arg1 / arg2 + STEP 1a
+ <push-op> arg1 + <push-op> arg2 + oMOD -> oPUSH arg1 % arg2 + STEP 1a
+ <push-op> arg1 + <push-op> arg2 + oSLL -> oPUSH arg1 << arg2 + STEP 1a
+ <push-op> arg1 + <push-op> arg2 + oSRL -> oPUSH arg1 >> arg2 + STEP 1a
+ <push-op> arg1 + <push-op> arg2 + oSRA -> oPUSH arg1 >> arg2 + STEP 1a
+ <push-op> arg1 + <push-op> arg2 + oOR -> oPUSH arg1 | arg2 + STEP 1a
+ <push-op> arg1 + <push-op> arg2 + oAND -> oPUSH arg1 & arg2 + STEP 1a
+ <push-op> arg1 + <push-op> arg2 + oEQU -> oPUSH arg1 == arg2 + STEP 1a
+ <push-op> arg1 + <push-op> arg2 + oNEQ -> oPUSH arg1 != arg2 + STEP 1a
+ <push-op> arg1 + <push-op> arg2 + oLT -> oPUSH arg1 < arg2 + STEP 1a
+ <push-op> arg1 + <push-op> arg2 + oGTE -> oPUSH arg1 >= arg2 + STEP 1a
+ <push-op> arg1 + <push-op> arg2 + oGT -> oPUSH arg1 > arg2 + STEP 1a
+ <push-op> arg1 + <push-op> arg2 + oLTE -> oPUSH arg1 <= arg2 + STEP 1a
+STEP 1a:
+ <push-op> arg
+ if arg < 256 -> oPUSHB arg
+ else -> oPUSH arg
+
+STEP 2:
+ <push-op> arg1 + <load-ops> arg2 + oADD
+ if arg1 == 0 -> <load-ops> arg
+ else if arg1 == 1 -> <load-ops> arg + oINC
+ else if arg1 == -1 -> <load-ops> arg + oDEC
+ <push-op> arg1 + <load-ops> arg2 + oSUB
+ if arg1 == 0 -> <load-ops> arg + oNEG
+ <push-op> arg1 + <load-ops> arg2 + oMUL -> <load-ops> arg + oSLL log
+ if arg is a power of 2
+ <push-op> arg1 + <load-ops> arg2 + oOR
+ if arg1 == 0 -> <load-ops> arg
+ <push-op> arg1 + <load-ops> arg2 + oAND
+ if arg1 == 0xffff -> <load-ops> arg
+ <push-op> arg1 + <load-ops> arg2 + oEQU
+ if arg1 == 0 -> <load-ops> arg + oEQUZ
+ <push-op> arg1 + <load-ops> arg2 + oNEQ
+ if arg1 == 0 -> <load-ops> arg + oNEQZ
+ <push-op> arg1 + <load-ops> arg2 + oLT
+ if arg1 == 0 -> <load-ops> arg + oLTZ
+ <push-op> arg1 + <load-ops> arg2 + oGTE
+ if arg1 == 0 -> <load-ops> arg + oGTEZ
+ <push-op> arg1 + <load-ops> arg2 + oGT
+ if arg1 == 0 -> <load-ops> arg + oGTZ
+ <push-op> arg1 + <load-ops> arg2 + oLTE
+ if arg1 == 0 -> <load-ops> arg + oLTEZ
+
+STEP 2a:
+ if the <push-op> op is still there
+ <push-op> arg
+ if arg < 256 -> oPUSHB arg
+ else -> oPUSH arg
+
+STEP 3
+ oNEG + oADD -> oSUB
+ oNEG + oSUB -> oADD
+
+pjopt.c: BranchOptimize
+ oNOT + oJEQUZ -> oJNEQZ
+ oNOT + oJNEQZ -> oJEQUZ
+ oNEG + oJLTZ -> oJGTZ
+ oNEG + oJGTEZ -> oJLTEZ
+ oNEG + oJGTZ -> oJLTZ
+ oNEG + oJLTEZ -> oJGTEZ
+ oEQU + oNOT -> oNEQ
+ oEQU + oJEQUZ -> oJNEQ
+ oEQU + oJNEQZ -> oJEQU
+ oNEQ + oNOT -> oEQU
+ oNEQ + oJEQUZ -> oJEQU
+ oNEQ + oJNEQZ -> oJNEQ
+ oLT + oNOT -> oGTE
+ oLT + oJEQUZ -> oJGTE
+ oLT + oJNEQZ -> oJLT
+ oGTE + oNOT -> oLT
+ oGTE + oJEQUZ -> oJLT
+ oGTE + oJNEQZ -> oJGTE
+ oGT + oNOT -> oLTE
+ oGT + oJEQUZ -> oJLTE
+ oGT + oJNEQZ -> oJGT
+ oLTE + oJNOT -> oGT
+ oLTE + oJEQUZ -> oJGT
+ oLTE + oJNEQZ -> oJLTE
+ oEQUZ + oNOT -> oNEQZ
+ oEQUZ + oJEQUZ -> oJNEQZ
+ oEQUZ + oJNEQZ -> oJEQUZ
+ oNEQZ + oNOT -> oEQUZ
+ oNEQZ + oJEQUZ -> oJEQUZ
+ oNEQZ + oJNEQZ -> oJNEQZ
+ oLTZ + oNOT -> oGTEZ
+ oLTZ + oJEQUZ -> oJGTEZ
+ oLTZ + oJNEQZ -> oJLTZ
+ oGTEZ + oNOT -> oLTZ
+ oGTEZ + oJEQUZ -> oJLTZ
+ oGTEZ + oJNEQZ -> oJGTEZ
+ oGTZ + oNOT -> oLTEZ
+ oGTZ + oJEQUZ -> oJLTEZ
+ oGTZ + oJNEQZ -> oJGTZ
+ oLTEZ + oNOT -> oGTZ
+ oLTEZ + oJEQUZ -> oJGTZ
+ oLTEZ + oJNEQZ -> oJLTEZ
+
+plopt.c:LoadOptimize()
+Eliminate duplicate loads
+ oLOD arg1 + oLOAD arg1 -> oLOD arg1 + oDUP
+
+Convert loads indexed by a constant to unindexed loads
+!!! DISABLED !!! Does not work because arg2 is a label, not an address !!!
+ <push-op> arg1 + oLODX arg2 -> oLOD arg1 + arg2
+ <push-op> arg1 + oLADRX arg2 -> oLADR arg1 + arg2
+ <push-op> arg1 + oLODBX arg2 -> oLODB arg1 + arg2
+ <push-op> arg1 + oLODMX arg2 -> oLODM arg1 + arg2
+ <push-op> arg
+ if arg < 256 -> oPUSHB arg
+
+plopt.c:StoreOptimize()
+Eliminate store followed by load
+ oSTO arg + oLOAD arg -> oSTO arg + oDUP
+
+Convert stores indexed by a constant to unindexed stores
+ <push-op> arg1 + ? + oSTOX arg2 -> ? + oSTO arg1 + arg2
+ <push-op> arg1 + ? + oSTOBX arg2 -> ? + oSTOB arg1 + arg2
+
+Missing local optimization:
+
+Need to check for branches (conditional or unconditional) to the
+next instruction.
diff --git a/misc/pascal/insn16/doc/PascalTestStatus.txt b/misc/pascal/insn16/doc/PascalTestStatus.txt
new file mode 100644
index 000000000..a30470c7d
--- /dev/null
+++ b/misc/pascal/insn16/doc/PascalTestStatus.txt
@@ -0,0 +1,208 @@
+====================================================================
+000-099: Basic functionality
+====================================================================
+
+TEST FILE: 001-beginend.pas
+ Compiles without error
+ Executes without error
+ Output is correct
+
+TEST FILE: 002-writeln.pas
+ Compiles without error
+ Executes without error
+ Output is correct
+
+TEST FILE: 003-for.pas
+ Compiles without error
+ Executes without error
+ Output is correct
+
+TEST FILE: 004-repeat.pas
+ Compiles without error
+ Executes without error
+ Output is correct
+
+TEST FILE: 005-while.pas
+ Compiles without error
+ Executes without error
+ Output is correct
+
+TEST FILE: 006-optconst.pas
+ Compiles without error
+ Executes without error
+ Output...
+
+ You have to use plist to examine the output. All integer constant
+ expressions are correctly optimized EXCEPT the last one. This
+ is most like a problem with the way the optimizer buffers instructions
+ -- i.e., the window is not big enough to capture the full context
+
+ Still need to add logic to verify real expressions.
+
+====================================================================
+100-199: Math and runtime libraries
+====================================================================
+
+TEST FILE: 101-cosine.pas
+ Compiles without error
+ Executes without error
+ Output is correct
+
+TEST FILE: 102-cen2fahr.pas
+ Compiles without error
+ Executes without error
+ Output is correct
+
+TEST FILE: 103-sumharm.pas
+ Compiles without error
+ Executes without error
+ Output is correct
+
+TEST FILE: 104-primes.pas
+Fatal Error 43 -- Compilation aborted
+
+ 0:0013 sieve, primes : array[0..w] of set of 0..maxbit;
+ Line 0:0012 Error 2e Token 0a
+
+TEST FILE: 105-inflation.pas
+ Compiles without error
+ Executes without error
+ Output is correct
+
+====================================================================
+200-299: Strings
+====================================================================
+
+TEST FILE: 201-strcat.pas
+ Compiles without error
+ Executes without error
+ Output is correct
+
+TEST FILE: 202-strcmp.pas
+ Compiles without error
+ Executes without error
+ Output is correct
+
+====================================================================
+500-599: multi-file features: uses, units
+====================================================================
+
+TEST FILE: 501-uses.pas
+ Compiles without error
+ Gets the following runtime errors:
+
+ FILE 0, "src/uses.pas"
+ PRGM 0, "MYPROGRAM"
+ FILE 1, "src/unit.pas"
+ IMPRT 66, L0001, "MYCOSINE"
+ ...
+ Entry is label L0002
+ P-Code label L0002 loaded at iSpace[3]
+ Entry point set to 0x0003
+ Last p-code address: 0x0063
+ ERROR: Could not find code label 0x00000001
+ ERROR: Failed to bind program addresses
+ ERROR: Could not load src/uses.PCD
+
+TEST FILE: 501-unit.pas
+ Compiles without error
+ Executes with error as exepected:
+ ERROR: Cannot execute. Entry Point NOT found
+ Runtime error 0x80 -- Execution Stopped
+ OK!
+ Line 0:0016 Error 36 Token 01 (READKEY)
+
+====================================================================
+800-899: Erie pascal programs
+====================================================================
+
+TEST FILE: 801-cgihello.pas
+ Compiles without error
+ Executes without error
+ Output is correct
+
+TEST FILE: 802-cgiinfo.pas
+ Compiles without error
+ Executes without error
+ Output is correct
+
+TEST FILE: 803-redirect.pas
+Fatal Error 14 -- Compilation aborted
+
+ 0:0031 len : 0..maxint;
+ 0:0039 val(ContentLength, len, err)
+
+ Line 0:0039 Error 42 Token 51
+
+ Error 42: eVARPARMTYPE
+ Token 51: tSUBRANGE
+
+ len is used as output in VAR built-in. Compiler currently won't
+ accept subrange of type for type. It should as an input, but it
+ should not as an output unless there is range checking.
+
+ 0:0061 EncodedVariable, DecodedVariable, name, value : string;
+ 0:0063 procedure ProcessNameValuePair(var name, value : string);
+
+ Line 0:0063 Error 0e Token 4b
+
+ Error 0e: eINDENT
+ Token 4b: sSTRING
+
+ Declared from line 'if (token != tIDENT) error (eIDENT);'
+ in function declare parameter. tkn_strt = 'NAME'
+
+ Problem with scope of names. 'name' already exists in outscope and
+ cannot be redeclared in the innerscope.
+
+TEST FILE: 804-cgiform.pas
+Fatal Error 29 -- Compilation aborted
+
+ Uses 'list of'
+
+ 0:0054 NameValuePairs : list of NameValuePair;
+ Line 0:0054 Error 1e Token 01 (LIST)
+
+TEST FILE: 805-cgimail.pas
+Fatal Error 29 -- Compilation aborted
+
+ Uses type file name
+
+ strErrorLink, strSuccessLink : filename;
+ Line 0:0018 Error 1e Token 01 (FILENAME)
+
+ filename is an Irie pascal type.
+ Also uses Irie pascal specific file IO calls.
+
+TEST FILE: 806-cgicook.pas
+Fatal Error 29 -- Compilation aborted
+
+ Uses 'list of'
+
+ 0:0088 CookieList = list of Cookie;
+ Line 0:0088 Error 1e Token 01 (LIST)
+
+====================================================================
+900-999: Misc. large programs not targeted at any particular feature.
+====================================================================
+
+TEST FILE: 901-pageutils.pas
+Fatal Error 45 -- Compilation aborted
+
+
+Reirects standard input and output:
+
+ CONST
+ ...
+ input = 1;
+ output = 2;
+ Line 0:0654 Error 0f Token 45
+
+ 0f = eIMPLEMENTATION
+ 45 = sFILE
+
+Issues the list_cb_type
+
+ 0:4640 PROCEDURE init_list (VAR list: list_cb_type; max_nol: short) ;
+ Line 0:4640 Error 2c Token 01 (LIST_CB_TYPE)
+
diff --git a/misc/pascal/insn16/include/pdbg.h b/misc/pascal/insn16/include/pdbg.h
new file mode 100644
index 000000000..78c6cb190
--- /dev/null
+++ b/misc/pascal/insn16/include/pdbg.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * pdbg.h
+ * External Declarations associated with the P-Code debugger
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PDBG_H
+#define __PDBG_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include "pexec.h"
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void dbg_run(struct pexec_s *st);
+
+#endif /* __PDBG_H */
diff --git a/misc/pascal/insn16/include/pexec.h b/misc/pascal/insn16/include/pexec.h
new file mode 100644
index 000000000..356757d53
--- /dev/null
+++ b/misc/pascal/insn16/include/pexec.h
@@ -0,0 +1,156 @@
+/****************************************************************************
+ * pexec.h
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __PEXEC_H
+#define __PEXEC_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+#define BPERI 2
+#define ITOBSTACK(i) ((i) << 1)
+#define BTOISTACK(i) ((i) >> 1)
+#define ROUNDBTOI(i) (((i) + 1) >> 1)
+
+/****************************************************************************
+ * Type Definitions
+ ****************************************************************************/
+
+typedef uint16_t ustack_t; /* Stack values are 16-bits in length */
+typedef int16_t sstack_t;
+typedef uint16_t paddr_t; /* Addresses are 16-bits in length */
+typedef uint16_t level_t; /* Limits to MAXUINT16 levels */
+
+union stack_u
+{
+ ustack_t *i;
+ uint8_t *b;
+};
+typedef union stack_u stackType;
+
+/* This structure describes the parameters needed to initialize the p-code
+ * interpreter.
+ */
+
+struct pexec_attr_s
+{
+ /* Instruction space (I-Space) */
+
+ FAR uint8_t *ispace; /* Allocated I-Space containing p-code data */
+ paddr_t entry; /* Entry point */
+ paddr_t maxpc; /* Last valid p-code address */
+
+ /* Read-only data block */
+
+ FAR uint8_t *rodata; /* Address of read-only data block */
+ paddr_t rosize; /* Size of read-only data block */
+
+ /* Allocate for variable storage */
+
+ paddr_t varsize; /* Variable storage size */
+ paddr_t strsize; /* String storage size */
+};
+
+/* This structure defines the current state of the p-code interpreter */
+
+struct pexec_s
+{
+ /* This is the emulated P-Machine stack (D-Space) */
+
+ stackType dstack;
+
+ /* This is the emulated P-Machine instruction space (I-Space) */
+
+ FAR uint8_t *ispace;
+
+ /* Address of last valid P-Code */
+
+ paddr_t maxpc;
+
+ /* These are the emulated P-Machine registers:
+ *
+ * spb: Base of the stack
+ * sp: The Pascal stack pointer
+ * csp: The current top of the stack used to manage string
+ * storage
+ * fp: Base Register of the current stack frame. Holds the address
+ * of the base of the stack frame of the current block.
+ * fop: Pointer to section containing read-only data
+ * pc: Holds the current p-code location
+ */
+
+ paddr_t spb; /* Pascal stack base */
+ paddr_t sp; /* Pascal stack pointer */
+ paddr_t csp; /* Character stack pointer */
+ paddr_t fp; /* Base of the current frame */
+ paddr_t rop; /* Read-only data pointer */
+ paddr_t pc; /* Program counter */
+
+ /* Info needed to perform a simulated reset */
+
+ paddr_t strsize; /* String stack size */
+ paddr_t rosize; /* Read-only stack size */
+ paddr_t entry; /* Entry point */
+ paddr_t stacksize; /* (debug only) */
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+EXTERN FAR struct pexec_s *pload(const char *filename, paddr_t varsize, paddr_t strsize);
+EXTERN FAR struct pexec_s *pexec_init(struct pexec_attr_s *attr);
+EXTERN int pexec(FAR struct pexec_s *st);
+EXTERN void pexec_reset(struct pexec_s *st);
+EXTERN void pexec_release(struct pexec_s *st);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PEXEC_H */
diff --git a/misc/pascal/insn16/include/pinsn16.h b/misc/pascal/insn16/include/pinsn16.h
new file mode 100644
index 000000000..383ba6437
--- /dev/null
+++ b/misc/pascal/insn16/include/pinsn16.h
@@ -0,0 +1,408 @@
+/****************************************************************************
+ * pinsn16.h
+ * 16-bit P-code operation code definitions
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __PINSN16_H
+#define __PINSN16_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* Op-code bit definitions */
+
+#define o16 (0x80)
+#define o8 (0x40)
+
+/* Opcode Encoding Summary:
+ *
+ * NO ARGS arg8 ONLY arg16 ONLY BOTH
+ * 00xx xxxx 01xx xxxx 10xx xxxx 11xx xxxx
+ * xx00 0000 NOP --- --- ---
+ * xx00 0001 NEG --- --- ---
+ * xx00 0010 ABS --- --- ---
+ * xx00 0011 INC --- --- ---
+ * xx00 0100 DEC --- --- ---
+ * xx00 0101 NOT --- --- ---
+ * xx00 0110 ADD --- --- ---
+ * xx00 0111 SUB --- --- ---
+ * xx00 1000 MUL --- --- PCAL l,ilbl
+ * xx00 1001 DIV --- --- ---
+ * xx00 1010 MOD --- --- ---
+ * xx00 1011 SLL --- --- ---
+ * xx00 1100 SRL --- --- ---
+ * xx00 1101 SRA --- --- ---
+ * xx00 1110 OR --- --- ---
+ * xx00 1111 AND --- --- ---
+ *
+ * xx01 0000 EQUZ --- JEQUZ ilbl ---
+ * xx01 0001 NEQZ --- JNEQZ ilbl ---
+ * xx01 0010 LTZ --- JLTZ ilbl ---
+ * xx01 0011 GTEZ --- JGTEZ ilbl ---
+ * xx01 0100 GTZ --- JGTZ ilbl ---
+ * xx01 0101 LTEZ --- JLTEZ ilbl ---
+ * xx01 0110 --- --- JMP ilbl ---
+ * xx01 0111 --- --- --- ---
+ * xx01 1000 EQU --- JEQU ilbl ---
+ * xx01 1001 NEQ --- JNEQ ilbl ---
+ * xx01 1010 LT --- JLT ilbl ---
+ * xx01 1011 GTE --- JGTE ilbl ---
+ * xx01 1100 GT --- JGT ilbl ---
+ * xx01 1101 LTE --- JLTE ilbl ---
+ * xx01 1110 --- --- --- ---
+ * xx01 1111 BIT --- --- ---
+ *
+ * xx10 0000 LDI --- LD uoffs LDS lvl,offs
+ * xx10 0001 LDIH --- LDH uoffs LDSH lvl,offs
+ * xx10 0010 LDIB --- LDB uoffs LDSB lvl,offs
+ * xx10 0011 LDIM --- LDM uoffs LDSM lvl,offs
+ * xx10 0100 STI --- ST uoffs STS lvl,offs
+ * xx10 0101 STIH --- STH uoffs STSH lvl,offs
+ * xx10 0110 STIB --- STB uoffs STSB lvl,offs
+ * xx10 0111 STIM --- STM uoffs STSM lvl,offs
+ * xx10 1000 DUP --- LDX uoffs LDSX lvl,offs
+ * xx10 1001 DUPH --- LDXH uoffs LDSXH lvl,offs
+ * xx10 1010 PUSHS --- LDXB uoffs LDSXB lvl,offs
+ * xx10 1011 POPS --- LDXM uoffs LDSXM lvl,offs
+ * xx10 1100 --- --- STX uoffs STSX lvl,offs
+ * xx10 1101 --- --- STXH uoffs STSXH lvl,offs
+ * xx10 1110 --- --- STXB uoffs STSXB lvl,offs
+ * xx10 1111 RET --- STXM uoffs STSXM lvl,offs
+ *
+ * xx11 0000 --- FLOAT fop LA uoffs LAS lvl,offs
+ * xx11 0001 --- --- LAC dlbl ---
+ * xx11 0010 --- --- --- ---
+ * xx11 0011 --- --- --- ---
+ * xx11 0100 --- PUSHB n PUSH nn ---
+ * xx11 0101 --- --- INDS nn ---
+ * xx11 0110 --- --- --- ---
+ * xx11 0111 --- --- --- ---
+ * xx11 1000 --- --- LAX uoffs LASX lvl,offs
+ * xx11 1001 --- --- LIB lop SYSIO fn,sop
+ * xx11 1010 --- --- --- ---
+ * xx11 1011 --- --- --- ---
+ * xx11 1100 --- --- --- ---
+ * xx11 1101 --- --- --- ---
+ * xx11 1110 --- --- --- ---
+ * xx11 1111 END --- *LABEL ilbl *LINE fn,lineno
+ *
+ * KEY:
+ * n = 8-bit value (unsigned)
+ * lvl = 8-bit static nesting level offset (unsigned)
+ * vt = 8-bit type code (unsigned)
+ * nn = 16-bit value (signed)
+ * fop = 8-bit floating point operation
+ * sop = 16-bit sysio operation
+ * lop = 16-bit library call identifier
+ * fn = 8-bit file number
+ * ilbl = instruction space label
+ * dlbl = stack data label
+ * offs = 16-bit frame offset (signed)
+ * uoffs = 16-bit base offset (unsigned)
+ * c = string follows pseudo-operation
+ * * = Indicates pseudo-operations (these are removed
+ * after final fixup of the object file).
+ */
+
+/** OPCODES WITH NO ARGUMENTS ***********************************************/
+
+/* Program control (No stack arguments) */
+
+#define oNOP (0x00)
+
+/* Arithmetic & logical & and integer conversions (One 16-bit stack argument) */
+
+#define oNEG (0x01)
+#define oABS (0x02)
+#define oINC (0x03)
+#define oDEC (0x04)
+#define oNOT (0x05)
+
+/* Arithmetic & logical (Two 16-bit stack arguments) */
+
+#define oADD (0x06)
+#define oSUB (0x07)
+#define oMUL (0x08)
+#define oDIV (0x09)
+#define oMOD (0x0a)
+#define oSLL (0x0b)
+#define oSRL (0x0c)
+#define oSRA (0x0d)
+#define oOR (0x0e)
+#define oAND (0x0f)
+
+/* Comparisons (One 16-bit stack argument) */
+
+#define oEQUZ (0x10)
+#define oNEQZ (0x11)
+#define oLTZ (0x12)
+#define oGTEZ (0x13)
+#define oGTZ (0x14)
+#define oLTEZ (0x15)
+
+/* 0x16-0x17 -- unassigned */
+
+/* Comparisons (Two 16-bit stack arguments) */
+
+#define oEQU (0x18)
+#define oNEQ (0x19)
+#define oLT (0x1a)
+#define oGTE (0x1b)
+#define oGT (0x1c)
+#define oLTE (0x1d)
+
+/* 0x1e -- unassigned */
+
+#define oBIT (0x1f)
+
+/* Load Immediate */
+
+#define oLDI (0x20) /* (One 16-bit stack argument) */
+#define oLDIH (0x21) /* (One 16-bit stack argument) */
+#define oLDIB (0x22) /* (One 16-bit stack argument) */
+#define oLDIM (0x23) /* (Two 16-bit stack arguments) */
+
+/* Store Immediate */
+
+#define oSTI (0x24) /* (One 32-bit and one 16-bit stack arguments) */
+#define oSTIH (0x25) /* (Two 16-bit stack arguments) */
+#define oSTIB (0x26) /* (Two 16-bit stack arguments) */
+#define oSTIM (0x27) /* (Two + n 16-bit stack arguments) */
+
+/* Data stack */
+
+#define oDUP (0x28) /* (One 32-bit stack argument */
+#define oDUPH (0x29) /* (One 16-bit stack argument) */
+
+/* 0x2a - 0x2b -- unassigned */
+
+#define oPUSHS (0x2a) /* No arguments */
+#define oPOPS (0x2b) /* (One 16-bit stack argument) */
+
+/* 0x2c - 0x2e -- unassigned */
+
+/* Program control (No stack arguments)
+ * Behavior:
+ * Pop return address
+ * Pop saved base register (BR)
+ * Discard saved base address
+ * Set program counter (PC) to return address
+ */
+
+#define oRET (0x2f)
+
+/* 0x30 - 0x3e -- unassigned */
+
+/* System Functions (No stack arguments) */
+
+#define oEND (0x3f)
+
+/** OPCODES WITH SINGLE BYTE ARGUMENT (arg8) ********************************/
+
+/* (o8|0x00)-(o8|0x2f) -- unassigned */
+
+/* Floating point operations: arg8 = FP op-code */
+
+#define oFLOAT (o8|0x30)
+
+/* (o8|0x31)-(o8|0x33) -- unassigned */
+
+/* Data stack: arg8 = 8 bit unsigned data (no stack arguments) */
+
+#define oPUSHB (o8|0x34)
+
+/* (o8|0x35)-(o8|0x3f) -- unassigned */
+
+/** OPCODES WITH SINGLE 16-BIT ARGUMENT (arg16) *****************************/
+
+/* (o16|0x00)-(o16|0x0f) -- unassigned */
+
+/* Program control: arg16 = unsigned label (One 16-bit stack argument) */
+
+#define oJEQUZ (o16|0x10)
+#define oJNEQZ (o16|0x11)
+#define oJLTZ (o16|0x12)
+#define oJGTEZ (o16|0x13)
+#define oJGTZ (o16|0x14)
+#define oJLTEZ (o16|0x15)
+
+/* Program control: arg16 = unsigned label (no stack arguments) */
+
+#define oJMP (o16|0x16)
+
+/* (o16|0x17) -- unassigned */
+
+/* Program control: arg16 = unsigned label (One 16-bit stack argument) */
+
+#define oJEQU (o16|0x18)
+#define oJNEQ (o16|0x19)
+#define oJLT (o16|0x1a)
+#define oJGTE (o16|0x1b)
+#define oJGT (o16|0x1c)
+#define oJLTE (o16|0x1d)
+
+/* (o16|0x1e)-(o16|0x1f) -- unassigned */
+
+/* Load: arg16 = unsigned base offset */
+
+#define oLD (o16|0x20) /* (no stack arguments) */
+#define oLDH (o16|0x21) /* (no stack arguments) */
+#define oLDB (o16|0x22) /* (no stack arguments) */
+#define oLDM (o16|0x23) /* (One 16-bit stack argument) */
+
+/* Store: arg16 = unsigned base offset */
+
+#define oST (o16|0x24) /* (One 32-bit stack argument) */
+#define oSTH (o16|0x25) /* (One 16-bit stack argument) */
+#define oSTB (o16|0x26) /* (One 16-bit stack argument) */
+#define oSTM (o16|0x27) /* (One+n 16-bit stack arguments) */
+
+/* Load Indexed: arg16 = unsigned base offset */
+
+#define oLDX (o16|0x28) /* (One 16-bit stack argument) */
+#define oLDXH (o16|0x29) /* (One 16-bit stack argument) */
+#define oLDXB (o16|0x2a) /* (One 16-bit stack argument) */
+#define oLDXM (o16|0x2b) /* (Two 16-bit stack arguments) */
+
+/* Store Indexed: arg16 = unsigned base offset */
+
+#define oSTX (o16|0x2c) /* (One 32-bit + one 16-bit stack arguments) */
+#define oSTXH (o16|0x2d) /* (Two 16-bit stack arguments) */
+#define oSTXB (o16|0x2e) /* (Two 16-bit stack arguments) */
+#define oSTXM (o16|0x2f) /* (Two+n 16-bit stack arguments) */
+
+/* Load address relative to stack base: arg16 = unsigned offset */
+
+#define oLA (o16|0x30)
+
+/* Load absolute stack address: arg16 = RODATA offset (No stack arguments) */
+
+#define oLAC (o16|0x31)
+
+/* (o16|0x32)-(o16|0x33) -- unassigned */
+
+/* Data stack: arg16 = 16 bit signed data (no stack arguments) */
+
+#define oPUSH (o16|0x34)
+#define oINDS (o16|0x35)
+
+/* (o16|0x34)-(o16|0x37) -- unassigned */
+
+/* Load address relative to stack base: arg16 = unsigned offset, TOS=index */
+
+#define oLAX (o16|0x38)
+
+/* System functions: arg16 = 16-bit library call identifier */
+
+#define oLIB (o16|0x39)
+
+/* (o16|0x3a)-(o16|0x3e) -- unassigned */
+
+/* Program control: arg16 = unsigned label (no stack arguments) */
+
+#define oLABEL (o16|0x3f)
+
+/** OPCODES WITH 24-BITS OF ARGUMENET (arg8 + arg16) ************************/
+
+/* (o16|o8|0x00)-(o8|o16|0x07) -- unassigned */
+
+/* Program Control: arg8 = level; arg16 = unsigned label
+ * (No stack arguments)
+ * Behavior:
+ * Push base address of level
+ * Push base register (BR) value
+ * Set new base register value (BR) as top of stack
+ * Push return address
+ * Set program counter (PC) for address associated with label
+ */
+
+#define oPCAL (o16|o8|0x08)
+
+/* (o16|o8|0x09)-(o8|o16|0x1f) -- unassigned */
+
+/* Load: arg8 = level; arg16 = signed frame offset */
+
+#define oLDS (o16|o8|0x20) /* (no stack arguments) */
+#define oLDSH (o16|o8|0x21) /* (no stack arguments) */
+#define oLDSB (o16|o8|0x22) /* (no stack arguments) */
+#define oLDSM (o16|o8|0x23) /* (One 16-bit stack argument) */
+
+/* Store: arg8 = level; arg16 = signed frame offset */
+
+#define oSTS (o16|o8|0x24) /* (One 32-bit stack argument) */
+#define oSTSH (o16|o8|0x25) /* (One 16-bit stack argument) */
+#define oSTSB (o16|o8|0x26) /* (One 16-bit stack argument) */
+#define oSTSM (o16|o8|0x27) /* (One+n 16-bit stack arguments) */
+
+/* Load Indexed: arg8 = level; arg16 = signed frame offset */
+
+#define oLDSX (o16|o8|0x28) /* (One 16-bit stack argument) */
+#define oLDSXH (o16|o8|0x29) /* (One 16-bit stack argument) */
+#define oLDSXB (o16|o8|0x2a) /* (One 16-bit stack argument) */
+#define oLDSXM (o16|o8|0x2b) /* (Two 16-bit stack arguments) */
+
+/* Store Indexed: arg8 = level; arg16 = signed frame offset */
+
+#define oSTSX (o16|o8|0x2c) /* (One 32-bit + one 16-bit stack arguments) */
+#define oSTSXH (o16|o8|0x2d) /* (Two 16-bit stack arguments) */
+#define oSTSXB (o16|o8|0x2e) /* (Two 16-bit stack arguments) */
+#define oSTSXM (o16|o8|0x2f) /* (Two+n 16-bit stack arguments) */
+
+/* FOR LAS/LASX arg8 = level; arg16 = signed frame offset
+ * (no stack arguments)
+ */
+
+#define oLAS (o16|o8|0x30)
+#define oLASX (o16|o8|0x38)
+
+/* System calls:
+ * For SYSIO: arg8 = file number; arg16 = sub-function code
+ */
+
+#define oSYSIO (o16|o8|0x39)
+
+/* (o16|o8|0x3a)-(o8|o16|0x3e) -- unassigned */
+
+/* Pseudo-operations:
+ * For LINE: arg8 = file number; arg16 = line number
+ */
+
+#define oLINE (o16|o8|0x3f)
+
+#endif /* __PINSN16_H */
diff --git a/misc/pascal/insn16/libinsn/Makefile b/misc/pascal/insn16/libinsn/Makefile
new file mode 100644
index 000000000..ce05f0273
--- /dev/null
+++ b/misc/pascal/insn16/libinsn/Makefile
@@ -0,0 +1,76 @@
+############################################################################
+# insn16/libinsn/Makefile
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Directories
+#
+LIBINSNDIR = ${shell pwd}
+INSNDIR = $(LIBINSNDIR)/..
+PASCAL = $(LIBINSNDIR)/../..
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+INCDIR = $(PASCAL)/include
+LIBDIR = $(PASCAL)/lib
+
+#
+# Tools
+#
+EXTRA_INCLUDES = -I$(INSNDIR)/include
+INCLUDES += $(EXTRA_INCLUDES)
+CFLAGS += $(EXTRA_INCLUDES)
+
+#
+# Objects and targets
+#
+LIBINSNSRCS = paddopcode.c paddtmpopcode.c pdasm.c pgen.c \
+ pgetopcode.c preloc.c
+LIBINSNOBJS = $(LIBINSNSRCS:.c=.o)
+
+OBJS = $(LIBINSNOBJS)
+
+all: libinsn.a
+.PHONY: all libinsn.a clean
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+$(LIBDIR)/libinsn.a: $(LIBINSNOBJS)
+ $(AR) $(ARFLAGS) $@ $^
+
+libinsn.a: $(LIBDIR)/libinsn.a
+
+clean:
+ $(RM) libinsn.a *.o core *~
diff --git a/misc/pascal/insn16/libinsn/paddopcode.c b/misc/pascal/insn16/libinsn/paddopcode.c
new file mode 100644
index 000000000..1384577a9
--- /dev/null
+++ b/misc/pascal/insn16/libinsn/paddopcode.c
@@ -0,0 +1,100 @@
+/**********************************************************************
+ * paddopcode
+ * P-Code access utilities
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include "keywords.h"
+#include "podefs.h"
+#include "pinsn16.h"
+
+#include "paslib.h"
+#include "pofflib.h"
+#include "pinsn.h"
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/**********************************************************************/
+
+void insn_AddOpCode(poffHandle_t handle, OPTYPE *ptr)
+{
+ /* Write the opcode which is always present */
+
+ (void)poffAddProgByte(handle, ptr->op);
+
+ /* Write the 8-bit argument if present */
+
+ if (ptr->op & o8)
+ {
+ (void)poffAddProgByte(handle, ptr->arg1);
+ }
+
+ /* Write the 16-bit argument if present */
+
+ if (ptr->op & o16)
+ {
+ (void)poffAddProgByte(handle, (ptr->arg2 >> 8));
+ (void)poffAddProgByte(handle, (ptr->arg2 & 0xff));
+ }
+}
+
+/**********************************************************************/
+
+void insn_ResetOpCodeWrite(poffHandle_t handle)
+{
+ poffResetAccess(handle);
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/insn16/libinsn/paddtmpopcode.c b/misc/pascal/insn16/libinsn/paddtmpopcode.c
new file mode 100644
index 000000000..a04878d85
--- /dev/null
+++ b/misc/pascal/insn16/libinsn/paddtmpopcode.c
@@ -0,0 +1,100 @@
+/**********************************************************************
+ * paddtmpopcode
+ * P-Code access utilities
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include "keywords.h"
+#include "podefs.h"
+#include "pinsn16.h"
+
+#include "paslib.h"
+#include "pofflib.h"
+#include "pinsn.h"
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/**********************************************************************/
+
+void insn_AddTmpOpCode(poffProgHandle_t progHandle, OPTYPE *ptr)
+{
+ /* Write the opcode which is always present */
+
+ (void)poffAddTmpProgByte(progHandle, ptr->op);
+
+ /* Write the 8-bit argument if present */
+
+ if (ptr->op & o8)
+ {
+ (void)poffAddTmpProgByte(progHandle, ptr->arg1);
+ }
+
+ /* Write the 16-bit argument if present */
+
+ if (ptr->op & o16)
+ {
+ (void)poffAddTmpProgByte(progHandle, (ptr->arg2 >> 8));
+ (void)poffAddTmpProgByte(progHandle, (ptr->arg2 & 0xff));
+ }
+}
+
+/**********************************************************************/
+
+void insn_ResetTmpOpCodeWrite(poffProgHandle_t progHandle)
+{
+ poffResetProgHandle(progHandle);
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/insn16/libinsn/pdasm.c b/misc/pascal/insn16/libinsn/pdasm.c
new file mode 100644
index 000000000..6f37d1a2e
--- /dev/null
+++ b/misc/pascal/insn16/libinsn/pdasm.c
@@ -0,0 +1,569 @@
+/**********************************************************************
+ * pdasm.c
+ * P-Code Disassembler
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/***********************************************************************
+ * Included Files
+ ***********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "keywords.h"
+#include "podefs.h"
+#include "pinsn16.h"
+#include "pfdefs.h"
+#include "pxdefs.h"
+#include "paslib.h"
+
+#include "pinsn.h"
+
+/***********************************************************************
+ * Pre-processor Definitions
+ ***********************************************************************/
+
+/* These are all the format codes that apply to opcodes the an arg16 */
+
+#define NOARG16 0
+#define HEX 1
+#define DECIMAL 2
+#define UDECIMAL 3
+#define LABEL_DEC 4
+#define xOP 5
+#define lbOP 6
+#define fpOP 7
+#define COMMENT 8
+
+/* The following table defines everything that is needed to disassemble
+ * a P-Code. NOTE: The order of definition in this table must exactly
+ * match the declaration sequence in pinsn.h. */
+
+static const char invOp[] = "Invalid Opcode";
+static const struct
+{
+ const char *opName; /* Opcode mnemonics */
+ uint8_t format; /* arg16 format */
+} opTable[256] =
+{
+
+/******************* OPCODES WITH NO ARGUMENTS ************************/
+/* Program control (No stack arguments) */
+
+/* 0x00 */ { "NOP ", NOARG16 },
+
+/* Arithmetic & logical & and integer conversions (One stack argument) */
+
+/* 0x01 */ { "NEG ", NOARG16 },
+/* 0x02 */ { "ABS ", NOARG16 },
+/* 0x03 */ { "INC ", NOARG16 },
+/* 0x04 */ { "DEC ", NOARG16 },
+/* 0x05 */ { "NOT ", NOARG16 },
+
+/* Arithmetic & logical (Two stack arguments) */
+
+/* 0x06 */ { "ADD ", NOARG16 },
+/* 0x07 */ { "SUB ", NOARG16 },
+/* 0x08 */ { "MUL ", NOARG16 },
+/* 0x09 */ { "DIV ", NOARG16 },
+/* 0x0a */ { "MOD ", NOARG16 },
+/* 0x0b */ { "SLL ", NOARG16 },
+/* 0x0c */ { "SRL ", NOARG16 },
+/* 0x0d */ { "SRA ", NOARG16 },
+/* 0x0e */ { "OR ", NOARG16 },
+/* 0x0f */ { "AND ", NOARG16 },
+
+/* Comparisons (One stack argument) */
+
+/* 0x10 */ { "EQUZ ", NOARG16 },
+/* 0x11 */ { "NEQZ ", NOARG16 },
+/* 0x12 */ { "LTZ ", NOARG16 },
+/* 0x13 */ { "GTEZ ", NOARG16 },
+/* 0x14 */ { "GTZ ", NOARG16 },
+/* 0x15 */ { "LTEZ ", NOARG16 },
+/* 0x16 */ { invOp, NOARG16 },
+/* 0x17 */ { invOp, NOARG16 },
+
+/* Comparisons (Two stack arguments) */
+
+/* 0x18 */ { "EQU ", NOARG16 },
+/* 0x19 */ { "NEQ ", NOARG16 },
+/* 0x1a */ { "LT ", NOARG16 },
+/* 0x1b */ { "GTE ", NOARG16 },
+/* 0x1c */ { "GT ", NOARG16 },
+/* 0x1d */ { "LTE ", NOARG16 },
+/* 0x1e */ { invOp, NOARG16 },
+/* 0x1f */ { "BIT ", NOARG16 },
+
+/* Load (One) or Store (Two stack argument) */
+
+/* 0x20 */ { "LDI ", NOARG16 },
+/* 0x21 */ { "LDIH", NOARG16 },
+/* 0x22 */ { "LDIB", NOARG16 },
+/* 0x23 */ { "LDIM", NOARG16 },
+/* 0x24 */ { "STI ", NOARG16 },
+/* 0x25 */ { "STIH", NOARG16 },
+/* 0x26 */ { "STIB", NOARG16 },
+/* 0x27 */ { "STIM", NOARG16 },
+
+/* Data stack operations */
+
+/* 0x29 */ { "DUP ", NOARG16 },
+/* 0x29 */ { "DUPH ", NOARG16 },
+/* 0x2a */ { "PUSHS", NOARG16 },
+/* 0x2b */ { "POPS", NOARG16 },
+/* 0x2c */ { invOp, NOARG16 },
+/* 0x2d */ { invOp, NOARG16 },
+/* 0x2e */ { invOp, NOARG16 },
+/* 0x2f */ { "RET ", NOARG16 },
+
+/* 0x30 */ { invOp, NOARG16 },
+/* 0x31 */ { invOp, NOARG16 },
+/* 0x32 */ { invOp, NOARG16 },
+/* 0x33 */ { invOp, NOARG16 },
+/* 0x34 */ { invOp, NOARG16 },
+/* 0x35 */ { invOp, NOARG16 },
+/* 0x36 */ { invOp, NOARG16 },
+/* 0x37 */ { invOp, NOARG16 },
+/* 0x38 */ { invOp, NOARG16 },
+
+/* System Functions (No stack arguments) */
+
+/* 0x39 */ { invOp, NOARG16 },
+/* 0x3a */ { invOp, NOARG16 },
+/* 0x3b */ { invOp, NOARG16 },
+/* 0x3c */ { invOp, NOARG16 },
+/* 0x3d */ { invOp, NOARG16 },
+/* 0x3e */ { invOp, NOARG16 },
+/* 0x3f */ { "EXIT ", NOARG16 },
+
+/************** OPCODES WITH SINGLE BYTE ARGUMENT (arg8) ***************/
+
+/* 0x40 */ { invOp, NOARG16 },
+/* 0x41 */ { invOp, NOARG16 },
+/* 0x42 */ { invOp, NOARG16 },
+/* 0x43 */ { invOp, NOARG16 },
+/* 0x44 */ { invOp, NOARG16 },
+/* 0x45 */ { invOp, NOARG16 },
+/* 0x46 */ { invOp, NOARG16 },
+/* 0x47 */ { invOp, NOARG16 },
+/* 0x48 */ { invOp, NOARG16 },
+/* 0x49 */ { invOp, NOARG16 },
+/* 0x4a */ { invOp, NOARG16 },
+/* 0x4b */ { invOp, NOARG16 },
+/* 0x4c */ { invOp, NOARG16 },
+/* 0x4d */ { invOp, NOARG16 },
+/* 0x4e */ { invOp, NOARG16 },
+/* 0x4f */ { invOp, NOARG16 },
+
+/* 0x50 */ { invOp, NOARG16 },
+/* 0x51 */ { invOp, NOARG16 },
+/* 0x52 */ { invOp, NOARG16 },
+/* 0x53 */ { invOp, NOARG16 },
+/* 0x54 */ { invOp, NOARG16 },
+/* 0x55 */ { invOp, NOARG16 },
+/* 0x56 */ { invOp, NOARG16 },
+/* 0x57 */ { invOp, NOARG16 },
+/* 0x58 */ { invOp, NOARG16 },
+/* 0x59 */ { invOp, NOARG16 },
+/* 0x5a */ { invOp, NOARG16 },
+/* 0x5b */ { invOp, NOARG16 },
+/* 0x5c */ { invOp, NOARG16 },
+/* 0x5d */ { invOp, NOARG16 },
+/* 0x5e */ { invOp, NOARG16 },
+/* 0x5f */ { invOp, NOARG16 },
+
+/* Data stack: arg8 = 8 bit unsigned data (no stack arguments) */
+
+/* 0x60 */ { invOp, NOARG16 },
+/* 0x61 */ { invOp, NOARG16 },
+/* 0x62 */ { invOp, NOARG16 },
+/* 0x63 */ { invOp, NOARG16 },
+/* 0x64 */ { invOp, NOARG16 },
+/* 0x65 */ { invOp, NOARG16 },
+/* 0x66 */ { invOp, NOARG16 },
+/* 0x67 */ { invOp, NOARG16 },
+/* 0x68 */ { invOp, NOARG16 },
+/* 0x69 */ { invOp, NOARG16 },
+/* 0x6a */ { invOp, NOARG16 },
+/* 0x6b */ { invOp, NOARG16 },
+/* 0x6c */ { invOp, NOARG16 },
+/* 0x6d */ { invOp, NOARG16 },
+/* 0x6e */ { invOp, NOARG16 },
+/* 0x6f */ { invOp, NOARG16 },
+
+/* Floating Point Operations: arg8 = FP op-code */
+
+/* 0x70 */ { "FLOAT", fpOP },
+/* 0x71 */ { invOp, NOARG16 },
+/* 0x72 */ { invOp, NOARG16 },
+/* 0x73 */ { invOp, NOARG16 },
+/* 0x74 */ { "PUSHB", NOARG16 },
+/* 0x75 */ { invOp, NOARG16 },
+/* 0x76 */ { invOp, NOARG16 },
+/* 0x77 */ { invOp, NOARG16 },
+
+/* 0x78 */ { invOp, NOARG16 },
+/* 0x79 */ { invOp, NOARG16 },
+/* 0x7a */ { invOp, NOARG16 },
+/* 0x7b */ { invOp, NOARG16 },
+/* 0x7c */ { invOp, NOARG16 },
+/* 0x7d */ { invOp, NOARG16 },
+/* 0x7e */ { invOp, NOARG16 },
+/* 0x7f */ { invOp, NOARG16 },
+
+/************ OPCODES WITH SINGLE 16-BIT ARGUMENT (arg16) ************/
+
+/* 0x80 */ { invOp, NOARG16 },
+/* 0x81 */ { invOp, NOARG16 },
+/* 0x82 */ { invOp, NOARG16 },
+/* 0x83 */ { invOp, NOARG16 },
+/* 0x84 */ { invOp, NOARG16 },
+/* 0x85 */ { invOp, NOARG16 },
+/* 0x86 */ { invOp, NOARG16 },
+/* 0x87 */ { invOp, NOARG16 },
+/* 0x88 */ { invOp, NOARG16 },
+/* 0x89 */ { invOp, NOARG16 },
+/* 0x8a */ { invOp, NOARG16 },
+/* 0x8b */ { invOp, NOARG16 },
+/* 0x8c */ { invOp, NOARG16 },
+/* 0x8d */ { invOp, NOARG16 },
+/* 0x8e */ { invOp, NOARG16 },
+/* 0x8f */ { invOp, NOARG16 },
+
+/* Program control: arg16 = unsigned label (One stack argument) */
+
+/* 0x90 */ { "JEQUZ", HEX },
+/* 0x91 */ { "JNEQZ", HEX },
+/* 0x92 */ { "JLTZ ", HEX },
+/* 0x93 */ { "JGTEZ", HEX },
+/* 0x94 */ { "JGTZ ", HEX },
+/* 0x95 */ { "JLTEZ", HEX },
+
+/* Program control: arg16 = unsigned label (no stack arguments) */
+
+/* 0x96 */ { "JMP ", HEX },
+/* 0x97 */ { invOp, NOARG16 },
+
+/* Program control: arg16 = unsigned label (One stack argument) */
+
+/* 0x98 */ { "JEQU ", HEX },
+/* 0x99 */ { "JNEQ ", HEX },
+/* 0x9a */ { "JLT ", HEX },
+/* 0x9b */ { "JGTE ", HEX },
+/* 0x9c */ { "JGT ", HEX },
+/* 0x9d */ { "JLTE ", HEX },
+/* 0x9e */ { invOp, NOARG16 },
+/* 0x9f */ { invOp, NOARG16 },
+
+/* Data stack: arg16 = 16 bit signed data (no stack arguments) */
+
+/* Load: arg16 = unsigned base offset (no stack arguments) */
+
+/* 0xa0 */ { "LD ", UDECIMAL },
+/* 0xa1 */ { "LDH ", UDECIMAL },
+/* 0xa2 */ { "LDB ", UDECIMAL },
+/* 0xa3 */ { "LDM ", UDECIMAL },
+
+/* Store: arg16 = unsigned base offset (One stack arguments) */
+
+/* 0xa4 */ { "ST ", UDECIMAL },
+/* 0xa5 */ { "STH ", UDECIMAL },
+/* 0xa6 */ { "STB ", UDECIMAL },
+/* 0xa7 */ { "STM ", UDECIMAL },
+
+/* Load Indexed: arg16 = unsigned base offset (One stack arguments) */
+
+/* 0xa8 */ { "LDX ", UDECIMAL },
+/* 0xa9 */ { "LDXH ", UDECIMAL },
+/* 0xaa */ { "LDXB ", UDECIMAL },
+/* 0xab */ { "LDXM ", UDECIMAL },
+
+/* Store Indexed: arg16 = unsigned base offset (Two stack arguments) */
+
+/* 0xac */ { "STX ", UDECIMAL },
+/* 0xad */ { "STXH ", UDECIMAL },
+/* 0xae */ { "STXB ", UDECIMAL },
+/* 0xaf */ { "STXM ", UDECIMAL },
+
+/* 0xb0 */ { "LA ", UDECIMAL },
+/* 0xb1 */ { "LAC ", HEX, },
+/* 0xb2 */ { invOp, NOARG16 },
+/* 0xb3 */ { invOp, NOARG16 },
+/* 0xb4 */ { "PUSH ", DECIMAL },
+/* 0xb5 */ { "INDS ", DECIMAL },
+/* 0xb6 */ { invOp, NOARG16 },
+/* 0xb7 */ { invOp, NOARG16 },
+/* 0xb8 */ { "LAX ", UDECIMAL },
+
+/* System operations: arg16 = 16-bit library function identifer */
+
+/* 0xb9 */ { "LIB ", lbOP, },
+/* 0xba */ { invOp, NOARG16 },
+/* 0xbb */ { invOp, NOARG16 },
+/* 0xbc */ { invOp, NOARG16 },
+/* 0xbd */ { invOp, NOARG16 },
+/* 0xbe */ { invOp, NOARG16 },
+
+/* Program control: arg16 = unsigned label (no stack arguments) */
+
+/* 0xbf */ { "LABEL", LABEL_DEC },
+
+/**** OPCODES WITH BYTE ARGUMENT (arg8) AND 16-BIT ARGUMENT (arg16) ****/
+
+/* 0xc0 */ { invOp, NOARG16 },
+/* 0xc1 */ { invOp, NOARG16 },
+/* 0xc2 */ { invOp, NOARG16 },
+/* 0xc3 */ { invOp, NOARG16 },
+/* 0xc4 */ { invOp, NOARG16 },
+/* 0xc5 */ { invOp, NOARG16 },
+/* 0xc6 */ { invOp, NOARG16 },
+/* 0xc7 */ { invOp, NOARG16 },
+
+/* Program Control: arg8 = level; arg16 = unsigned label (No stack
+ * arguments */
+
+/* 0xc8 */ { "PCAL ", HEX },
+/* 0xc9 */ { invOp, NOARG16 },
+/* 0xca */ { invOp, NOARG16 },
+/* 0xcb */ { invOp, NOARG16 },
+/* 0xcc */ { invOp, NOARG16 },
+/* 0xcd */ { invOp, NOARG16 },
+/* 0xce */ { invOp, NOARG16 },
+/* 0xcf */ { invOp, NOARG16 },
+
+/* 0xd0 */ { invOp, NOARG16 },
+/* 0xd1 */ { invOp, NOARG16 },
+/* 0xd2 */ { invOp, NOARG16 },
+/* 0xd3 */ { invOp, NOARG16 },
+/* 0xd4 */ { invOp, NOARG16 },
+/* 0xd5 */ { invOp, NOARG16 },
+/* 0xd6 */ { invOp, NOARG16 },
+/* 0xd7 */ { invOp, NOARG16 },
+/* 0xd8 */ { invOp, NOARG16 },
+/* 0xd9 */ { invOp, NOARG16 },
+/* 0xda */ { invOp, NOARG16 },
+/* 0xdb */ { invOp, NOARG16 },
+/* 0xdc */ { invOp, NOARG16 },
+/* 0xdd */ { invOp, NOARG16 },
+/* 0xde */ { invOp, NOARG16 },
+/* 0xdf */ { invOp, NOARG16 },
+
+/* Load: arg8 = level; arg16 = signed frame offset (no stack arguments) */
+
+/* 0xe0 */ { "LDS ", DECIMAL },
+/* 0xe1 */ { "LDSH ", DECIMAL },
+/* 0xe2 */ { "LDSB ", DECIMAL },
+/* 0xe3 */ { "LDSM ", DECIMAL },
+
+/* Store: arg8 = level; arg16 = signed frame offset (One stack arguments) */
+
+/* 0xe4 */ { "STS ", DECIMAL },
+/* 0xe5 */ { "STSH ", DECIMAL },
+/* 0xe6 */ { "STSB ", DECIMAL },
+/* 0xe7 */ { "STSM ", DECIMAL },
+
+/* Load Indexed: arg8 = level; arg16 = signed frame offset (One stack arguments) */
+
+/* 0xe8 */ { "LDSX ", DECIMAL },
+/* 0xe9 */ { "LDSXH", DECIMAL },
+/* 0xea */ { "LDSXB", DECIMAL },
+/* 0xeb */ { "LDSXM", DECIMAL },
+
+/* Store Indexed: arg8 = level; arg16 = signed frame offset (Two stack arguments) */
+
+/* 0xec */ { "STSX ", DECIMAL },
+/* 0xed */ { "STSXH", DECIMAL },
+/* 0xee */ { "STSXB", DECIMAL },
+/* 0xef */ { "STSXM", DECIMAL },
+
+/* Load Address: arg8 = level; arg16 = signed frame offset (no stack arguments) */
+
+/* 0xf0 */ { "LAS ", DECIMAL },
+/* 0xf1 */ { invOp, NOARG16 },
+/* 0xf2 */ { invOp, NOARG16 },
+/* 0xf3 */ { invOp, NOARG16 },
+/* 0xf4 */ { invOp, NOARG16 },
+/* 0xf5 */ { invOp, NOARG16 },
+/* 0xf6 */ { invOp, NOARG16 },
+/* 0xf7 */ { invOp, NOARG16 },
+/* 0xf8 */ { "LASX ", DECIMAL },
+
+/* System Functions: (No stack arguments)
+ * For SYSIO: arg8 = file number; arg16 = sub-function code
+ */
+
+/* 0xf9 */ { "SYSIO", xOP, },
+/* 0xfa */ { invOp, NOARG16 },
+/* 0xfb */ { invOp, NOARG16 },
+/* 0xfc */ { invOp, NOARG16 },
+/* 0xfd */ { invOp, NOARG16 },
+/* 0xfe */ { invOp, NOARG16 },
+
+/* Pseudo-operations:
+ * For LINE: arg8 = file number; arg16 = line number
+ */
+
+/* 0xff */ { "LINE ", COMMENT },
+};
+
+static const char invXOp[] = "Invalid SYSIO";
+static const char *xName[MAX_XOP] = { /* SYSIO opcode mnemonics */
+/* 0x00 */ invXOp, "EOF", "EOLN", "RESET",
+/* 0x04 */ "REWRITE", invXOp, invXOp, invXOp,
+/* 0x08 */ invXOp, invXOp, invXOp, invXOp,
+/* 0x0c */ invXOp, invXOp, invXOp, invXOp,
+/* 0x10 */ "READLN", "READPG", "READBIN", "READINT",
+/* 0x14 */ "READCHR", "READSTR", "READRL", invXOp,
+/* 0x18 */ invXOp, invXOp, invXOp, invXOp,
+/* 0x1c */ invXOp, invXOp, invXOp, invXOp,
+/* 0x20 */ "WRITELN", "WRITEPG", "WRITEBIN", "WRITEINT",
+/* 0x24 */ "WRITECHR", "WRITESTR", "WRITERL" };
+
+static const char invLbOp[] = "Invalid runtime code";
+static const char *lbName[MAX_LBOP] = { /* LIB opcode mnemonics */
+/* 0x00 */ "GETENV", "STR2STR", "CSTR2STR", "STR2RSTR",
+/* 0x04 */ "CSTR2RSTR", "VAL", "MKSTK", "MKSTKSTR",
+/* 0x08 */ "MKSTKC", "STRCAT", "STRCATC", "STRCMP" };
+
+static const char invFpOp[] = "Invalid FP Operation";
+static const char *fpName[MAX_FOP] = {
+/* 0x00 */ invFpOp, "FLOAT", "TRUNC", "ROUND",
+/* 0x04 */ "ADD", "SUB", "MUL", "DIV",
+/* 0x08 */ "MOD", invFpOp, "EQU", "NEQ",
+/* 0x0c */ "LT", "GTE", "GT", "LTE",
+/* 0x10 */ "NEG", "ABS", "SQR", "SQRT",
+/* 0x14 */ "SIN", "COS", "ATAN", "LN",
+/* 0x18 */ "EXP" };
+
+/***********************************************************************/
+
+void insn_DisassemblePCode(FILE* lfile, OPTYPE *pop)
+{
+ /* Indent, comment or label */
+
+ switch (opTable[pop->op].format)
+ {
+ case LABEL_DEC :
+ fprintf(lfile, "L%04x: ", pop->arg2);
+ break;
+ case COMMENT :
+ fprintf(lfile, "; ");
+ break;
+ default :
+ fprintf(lfile, " ");
+ } /* end switch */
+
+ /* Special Case Comment line format */
+
+ if (opTable[pop->op].format == COMMENT)
+ {
+ fprintf(lfile, "%s ", opTable[pop->op].opName);
+ if (pop->op & o8)
+ {
+ fprintf(lfile, "%d", pop->arg1);
+ if (pop->op & o16)
+ fprintf(lfile, ":%d", pop->arg2);
+ } /* end if */
+ else if (pop->op & o16)
+ fprintf(lfile, "%d", pop->arg2);
+ } /* end if */
+
+ /* Print normal opCode mnemonic */
+
+ else
+ {
+ fprintf(lfile, "%s ", opTable[pop->op].opName);
+
+ /* Print pop->arg1 (if present) */
+
+ if (pop->op & o8) fprintf(lfile, "%d", pop->arg1);
+
+ /* Print ar16 (if present) */
+
+ if (pop->op & o16)
+ {
+ switch (opTable[pop->op].format)
+ {
+ case HEX :
+ if (pop->op & o8) fprintf(lfile, ", ");
+ fprintf(lfile, "0x%04x", pop->arg2);
+ break;
+
+ case COMMENT :
+ case DECIMAL :
+ if (pop->op & o8) fprintf(lfile, ", ");
+ fprintf(lfile, "%ld", signExtend16(pop->arg2));
+ break;
+
+ case UDECIMAL :
+ if (pop->op & o8) fprintf(lfile, ", ");
+ fprintf(lfile, "%u", pop->arg2);
+ break;
+
+ case fpOP :
+ if ((pop->arg1 & fpMASK) < MAX_FOP)
+ fprintf(lfile, " %s", fpName[(pop->arg1 & 0x3f)]);
+ else
+ fprintf(lfile, " %s", invFpOp);
+ break;
+
+ case xOP :
+ if (pop->arg2 < MAX_XOP)
+ fprintf(lfile, ", %s", xName[pop->arg2]);
+ else
+ fprintf(lfile, ", %s", invXOp);
+ break;
+
+ case lbOP :
+ if (pop->arg2 < MAX_LBOP)
+ fprintf(lfile, "%s", lbName[pop->arg2]);
+ else
+ fprintf(lfile, "%s", invLbOp);
+ break;
+
+ case LABEL_DEC :
+ default :
+ break;
+ } /* end switch */
+ } /* end if */
+ } /* end else */
+
+ /* Don't forget the newline! */
+
+ fputc('\n', lfile);
+
+} /* end dissassemblePcode */
+
+/***********************************************************************/
diff --git a/misc/pascal/insn16/libinsn/pgen.c b/misc/pascal/insn16/libinsn/pgen.c
new file mode 100644
index 000000000..0ac3b8b1c
--- /dev/null
+++ b/misc/pascal/insn16/libinsn/pgen.c
@@ -0,0 +1,312 @@
+/**********************************************************************
+ * pgen.c
+ * P-Code generation logic
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "config.h" /* Configuration */
+#include "keywords.h" /* Standard types */
+#include "pdefs.h" /* Common types */
+#include "pofflib.h" /* POFF library definitions */
+#include "podefs.h" /* Logical opcode definitions */
+#include "pedefs.h" /* Error codes */
+#include "pinsn16.h" /* 16-bit target INSN opcode definitions */
+#include "perr.h" /* Error handling logic */
+
+#include "pinsn.h" /* (to verify prototypes in this file) */
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+extern poffHandle_t poffHandle; /* Handle to POFF object */
+extern FILE *lstFile; /* LIST file pointer */
+extern int16_t level; /* Static nesting level */
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static const uint16_t opmap[NUM_OPCODES] =
+{
+ oNOP, /* opNOP */
+ oNEG, /* opNEG */
+ oABS, /* opABS */
+ oINC, /* opINC */
+ oDEC, /* opDEC */
+ oNOT, /* opNOT */
+ oADD, /* opADD */
+ oSUB, /* opSUB */
+ oMUL, /* opMUL */
+ oDIV, /* opDIV */
+ oMOD, /* opMOD */
+ oSLL, /* opSLL */
+ oSRL, /* opSRL */
+ oSRA, /* opSRA */
+ oOR, /* opOR */
+ oAND, /* opAND */
+ oEQUZ, /* opEQUZ */
+ oNEQZ, /* opNEQZ */
+ oLTZ, /* opLTZ */
+ oGTEZ, /* opGTEZ */
+ oGTZ, /* opGTZ */
+ oLTEZ, /* opLTEZ */
+ oEQU, /* opEQU */
+ oNEQ, /* opNEQ */
+ oLT, /* opLT */
+ oGTE, /* opGTE */
+ oGT, /* opGT */
+ oLTE, /* opLTE */
+ oBIT, /* opBIT */
+ oLDIH, /* opLDI -- integer load maps to 16-bit load */
+ oLDIB, /* opLDIB */
+ oLDIM, /* opLDIM */
+ oSTIH, /* opSTI - integer store maps to 16-bit store */
+ oSTIB, /* opSTIB */
+ oSTIM, /* opSTIM */
+ oDUPH, /* opDUP -- integer duplicate maps to 16-bit duplicate */
+ oPUSHS, /* opPUSHS */
+ oPOPS, /* opPOPS */
+ oRET, /* opRET */
+ oEND, /* opEND */
+ oFLOAT, /* opFLOAT */
+ oJEQUZ, /* opJEQUZ */
+ oJNEQZ, /* opJNEQZ */
+ oJMP, /* opJMP */
+ oJEQU, /* opJEQU */
+ oJNEQ, /* opJNEQ */
+ oJLT, /* opJLT */
+ oJGTE, /* opJGTE */
+ oJGT, /* opJGT */
+ oJLTE, /* opJLTE */
+ oLDH, /* opLD -- integer load maps to 16-bit load */
+ oLDH, /* opLDH */
+ oLDB, /* opLDB */
+ oLDM, /* opLDM */
+ oSTH, /* opST -- integer store maps to 16-bit store */
+ oSTB, /* opSTB */
+ oSTM, /* opSTM */
+ oLDXH, /* opLDX -- integer load maps to 16-bit load */
+ oLDXB, /* opLDXB */
+ oLDXM, /* opLDXM */
+ oSTXH, /* opSTX -- integer store maps to 16-bit store */
+ oSTXB, /* opSTXB */
+ oSTXM, /* opSTXM */
+ oLA, /* opLA */
+ oLAC, /* opLAC */
+ oPUSH, /* opPUSH */
+ oINDS, /* opINDS */
+ oLAX, /* opLAX */
+ oLIB, /* opLIB */
+ oLABEL, /* opLABEL */
+ oPCAL, /* opPCAL */
+ oLDSH, /* opLDS -- integer store maps to 16-bit load */
+ oLDSH, /* opLDSH */
+ oLDSB, /* opLDSB */
+ oLDSM, /* opLDSM */
+ oSTSH, /* opSTS -- integer store maps to 16-bit store */
+ oSTSB, /* opSTSB */
+ oSTSM, /* opSTSM */
+ oLDSXH, /* opLDSX -- integer load maps to 16-bit load */
+ oLDSXB, /* opLDSXB */
+ oLDSXM, /* opLDSXM */
+ oSTSXH, /* opSTSX -- integer store maps to 16-bit store */
+ oSTSXB, /* opSTSXB */
+ oSTSXM, /* opSTSXM */
+ oLAS, /* opLAS */
+ oLASX, /* opLASX */
+ oSYSIO, /* opSYSIO */
+ oLINE, /* opLINE */
+};
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+static void
+insn16_Generate(enum pcode_e opcode, uint16_t arg1, int32_t arg2);
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Disassemble an Op-code */
+
+#if CONFIG_DEBUG
+static inline void
+insn16_DisassemblePCode(uint8_t opcode, uint8_t arg1, uint16_t arg2)
+{
+ OPTYPE op;
+
+ op.op = opcode;
+ op.arg1 = arg1;
+ op.arg2 = arg2;
+
+ insn_DisassemblePCode(lstFile, &op);
+}
+#else
+# define insn16_DisassemblePCode(op,a1,a2)
+#endif
+
+/***********************************************************************/
+/* Generate an Op-Code */
+
+static void
+insn16_Generate(enum pcode_e opcode, uint16_t arg1, int32_t arg2)
+{
+ uint16_t insn_opcode = opmap[opcode];
+ uint16_t arg16;
+ TRACE(lstFile,"[insn16_Generate:0x%02x->0x%04x]", opcode, insn_opcode);
+
+ poffAddProgByte(poffHandle, insn_opcode);
+ if (insn_opcode & o8)
+ {
+ if (arg1 > 0xff) error(eINTOVF);
+ poffAddProgByte(poffHandle, (uint8_t)arg1);
+ } /* End if */
+
+ if (insn_opcode & o16)
+ {
+ if ((arg2 < -32768) || (arg2 > 65535)) error(eINTOVF);
+ arg16 = (uint16_t)arg2;
+ poffAddProgByte(poffHandle, (uint8_t)(arg16 >> 8));
+ poffAddProgByte(poffHandle, (uint8_t)(arg16 & 0xff));
+ } /* End if */
+
+ /* Now, add the disassembled PCode to the list file. */
+
+ insn16_DisassemblePCode(insn_opcode, arg1, arg2);
+
+} /* end insn16_Generate */
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+void
+insn_GenerateSimple(enum pcode_e opcode)
+{
+ insn16_Generate(opcode, 0, 0);
+}
+
+/***********************************************************************/
+
+void
+insn_GenerateDataOperation(enum pcode_e opcode, int32_t data)
+{
+ insn16_Generate(opcode, 0, data);
+}
+
+/***********************************************************************/
+/* Data size for a multiple register operation (in bytes) is simply
+ * represented by that value at the top of the stack.
+ */
+
+void insn_GenerateDataSize(uint32_t dwDataSize)
+{
+ insn16_Generate(opPUSH, 0, dwDataSize);
+}
+
+/***********************************************************************/
+
+void
+insn_GenerateFpOperation(uint8_t fpOpcode)
+{
+ insn16_Generate(opFLOAT, fpOpcode, 0);
+}
+
+/***********************************************************************/
+
+void
+insn_GenerateIoOperation(uint16_t ioOpcode, uint16_t fileNumber)
+{
+ insn16_Generate(opSYSIO, fileNumber, (int32_t)ioOpcode);
+}
+
+/***********************************************************************/
+
+void
+insn_BuiltInFunctionCall(uint16_t libOpcode)
+{
+ insn16_Generate(opLIB, 0, (int32_t)libOpcode);
+}
+
+/***********************************************************************/
+
+void
+insn_GenerateLevelReference(enum pcode_e opcode, uint16_t level, int32_t offset)
+{
+ insn16_Generate(opcode, level, offset);
+}
+
+/***********************************************************************/
+
+void
+insn_GenerateProcedureCall(uint16_t level, int32_t offset)
+{
+ insn16_Generate(opPCAL, level, offset);
+}
+
+/***********************************************************************/
+
+void
+insn_GenerateLineNumber(uint16_t includeNumber, uint32_t lineNumber)
+{
+ insn16_Generate(opLINE, includeNumber, lineNumber);
+}
+
+/***********************************************************************/
+
+void
+insn_SetStackLevel(uint32_t level)
+{
+ /* Do nothing */
+}
diff --git a/misc/pascal/insn16/libinsn/pgetopcode.c b/misc/pascal/insn16/libinsn/pgetopcode.c
new file mode 100644
index 000000000..c7a7f0a28
--- /dev/null
+++ b/misc/pascal/insn16/libinsn/pgetopcode.c
@@ -0,0 +1,140 @@
+/**********************************************************************
+ * pgetopcode.c
+ * P-Code access utilities
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+
+#include "keywords.h"
+#include "podefs.h"
+#include "pinsn16.h"
+
+#include "paslib.h"
+#include "pofflib.h"
+#include "pinsn.h"
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+static int16_t g_bEndIn = 0; /* 1 = oEND pcode or EOF received */
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/**********************************************************************/
+
+uint32_t insn_GetOpCode(poffHandle_t handle, OPTYPE *ptr)
+{
+ uint32_t opsize = 1;
+ int c;
+
+ TRACE(stderr, "[insn_GetOpCode]");
+
+ /* If we are not already at the EOF, read the next character from
+ * the input stream.
+ */
+
+ if (!g_bEndIn)
+ c = poffGetProgByte(handle);
+ else
+ c = EOF;
+
+ /* Check for end of file. We may have previously parsed oEND which
+ * is a 'logical' end of file for a pascal program (but not a unit)
+ * or we may be at the physical end of the file wihout encountering
+ * oEND (typical for a UNIT file).
+ */
+
+ if ((g_bEndIn) || (c == EOF))
+ {
+ ptr->op = oEND;
+ ptr->arg1 = 0;
+ ptr->arg2 = 0;
+ } /* end if */
+ else
+ {
+ ptr->op = c;
+ g_bEndIn = (ptr->op == oEND);
+
+ if (ptr->op & o8)
+ {
+ ptr->arg1 = poffGetProgByte(handle);
+ opsize++;
+ }
+ else
+ {
+ ptr->arg1 = 0;
+ }
+
+ if (ptr->op & o16)
+ {
+ ptr->arg2 = (poffGetProgByte(handle) << 8);
+ ptr->arg2 |= (poffGetProgByte(handle) & 0xff);
+ opsize += 2;
+ }
+ else
+ {
+ ptr->arg2 = 0;
+ }
+ }
+ return opsize;
+}
+
+/**********************************************************************/
+
+void insn_ResetOpCodeRead(poffHandle_t handle)
+{
+ poffResetAccess(handle);
+ g_bEndIn = 0;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/insn16/libinsn/preloc.c b/misc/pascal/insn16/libinsn/preloc.c
new file mode 100644
index 000000000..7c4701c89
--- /dev/null
+++ b/misc/pascal/insn16/libinsn/preloc.c
@@ -0,0 +1,149 @@
+/**********************************************************************
+ * preloc.c
+ * Perform P-Code relocations
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pedefs.h"
+#include "podefs.h"
+#include "pinsn16.h"
+
+#include "pofflib.h"
+#include "perr.h"
+#include "pinsn.h"
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Type Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+int insn_Relocate(OPTYPE *op, uint32_t pcOffset, uint32_t roOffset)
+{
+ switch (op->op)
+ {
+ /* Catch each instruction that references the read-only data
+ * section.
+ */
+
+ case oLAC:
+ /* Add the offset to the read-only data section */
+
+ op->arg2 += roOffset;
+ break;
+
+ /* Catch each instruction that references the text section
+ * data via an offset.
+ */
+
+ case oPCAL: /* Procedure / Function calls */
+ case oJMP: /* Unconditional jump */
+ case oJEQUZ: /* Jump on unary comparisons with zero */
+ case oJNEQZ:
+ case oJLTZ:
+ case oJGTEZ:
+ case oJGTZ:
+ case oJLTEZ:
+ case oJEQU: /* Jump on binary comparisons */
+ case oJNEQ:
+ case oJLT:
+ case oJGTE:
+ case oJGT:
+ case oJLTE:
+ /* Add the offset to the text section */
+
+ op->arg2 += pcOffset;
+ break;
+
+ /* Return an end of file indication if oEND encountered */
+
+ case oEND:
+ return 1;
+
+ /* Otherwise, it is not an interesting opcode */
+ default:
+ break;
+ }
+
+ /* Return 0 on all opcodes other than oEND */
+
+ return 0;
+}
+
+/***********************************************************************/
+
+void insn_FixupProcedureCall(uint8_t *progData, uint32_t symValue)
+{
+
+ /* Sanity checking */
+
+ if (progData[0] != oPCAL)
+ fatal(ePOFFCONFUSION);
+
+ if (symValue > 0xffff)
+ fatal(eBADSHORTINT);
+
+ /* Perform the relocation */
+
+ progData[2] = symValue >> 8;
+ progData[3] = symValue & 0xff;
+}
+
+
+/***********************************************************************/
diff --git a/misc/pascal/insn16/plist/Makefile b/misc/pascal/insn16/plist/Makefile
new file mode 100644
index 000000000..cd579f040
--- /dev/null
+++ b/misc/pascal/insn16/plist/Makefile
@@ -0,0 +1,90 @@
+############################################################################
+# insn16/plist/Makefile
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Directories
+#
+PLISTDIR = ${shell pwd}
+INSNDIR = $(PLISTDIR)/..
+PASCAL = $(PLISTDIR)/../..
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+INCDIR = $(PASCAL)/include
+LIBDIR = $(PASCAL)/lib
+BINDIR = $(PASCAL)/bin16
+
+#
+# Tools
+#
+EXTRA_INCLUDES = -I$(INSNDIR)/include
+INCLUDES += $(EXTRA_INCLUDES)
+CFLAGS += $(EXTRA_INCLUDES)
+
+#
+# Objects and targets
+#
+PLISTSRCS = plist.c
+PLISTOBJS = $(PLISTSRCS:.c=.o)
+
+OBJS = $(PLISTOBJS)
+
+all: plist
+.PHONY: all plist clean
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+check_libs:
+ @if [ ! -f $(LIBDIR)/libpoff.a ] ; then \
+ echo "$(LIBDIR)/libpoff.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libpas.a ] ; then \
+ echo "$(LIBDIR)/libpas.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libinsn.a ] ; then \
+ echo "$(LIBDIR)/libinsn.a does not exist" ; \
+ exit 1 ; \
+ fi
+
+$(BINDIR)/plist: check_libs $(PLISTOBJS)
+ $(CC) -o $@ $(LDFLAGS) $(PLISTOBJS) -lpoff -linsn -lpas
+
+plist: $(BINDIR)/plist
+
+clean:
+ $(RM) plist *.o core *~
diff --git a/misc/pascal/insn16/plist/plist.c b/misc/pascal/insn16/plist/plist.c
new file mode 100644
index 000000000..18b119e31
--- /dev/null
+++ b/misc/pascal/insn16/plist/plist.c
@@ -0,0 +1,360 @@
+/**********************************************************************
+ * plist.c
+ * POFF file lister
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <string.h>
+
+#define _GNU_SOURCE
+#include <getopt.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "podefs.h"
+#include "pinsn16.h"
+#include "pedefs.h"
+
+#include "pofflib.h"
+
+#include "paslib.h"
+#include "pinsn.h"
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+#define MAX_STRING 80
+
+/**********************************************************************
+ * Private Data
+ **********************************************************************/
+
+static char *poffFileName = NULL;
+static int showFileHeader = 0;
+static int showSectionHeaders = 0;
+static int showSymbols = 0;
+static int showRelocs = 0;
+static int disassemble = 0;
+
+/**********************************************************************
+ * Private Constant Data
+ **********************************************************************/
+
+static const struct option long_options[] =
+{
+ {"all", 0, NULL, 'a'},
+ {"file-header", 0, NULL, 'h'},
+ {"section-headers", 0, NULL, 'S'},
+ {"symbols", 0, NULL, 's'},
+ {"relocs", 0, NULL, 'r'},
+ {"disassemble", 0, NULL, 'd'},
+ {"help", 0, NULL, 'H'},
+ {NULL, 0, NULL, 0}
+};
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static void showUsage (const char *progname);
+static void parseArgs (int argc, char **argv);
+static void dumpProgramData (poffHandle_t poffHandle);
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+int main (int argc, char *argv[], char *envp[])
+{
+ FILE *object; /* Object file pointer */
+ poffHandle_t poffHandle; /* Handle for POFF object */
+ char fileName[FNAME_SIZE+1]; /* Object file name */
+ uint16_t errCode; /* See pedefs.h */
+
+ /* Parse the command line arguments */
+
+ parseArgs(argc, argv);
+
+ /* Open source POFF file -- Use .o or command line extension, if supplied */
+
+ (void) extension (poffFileName, "o", fileName, 0);
+ if (!(object = fopen (fileName, "rb")))
+ {
+ printf ("Error opening %s\n", fileName);
+ exit (1);
+ } /* end if */
+
+ /* Read the POFF file */
+
+ poffHandle = poffCreateHandle();
+ if (poffHandle == NULL)
+ {
+ printf ("Could not get POFF handler\n");
+ exit (1);
+ }
+
+ errCode = poffReadFile(poffHandle, object);
+ if (errCode != eNOERROR)
+ {
+ printf ("Could not read POFF file\n");
+ exit (1);
+ }
+
+ /* Dump the File Header */
+
+ if (showFileHeader)
+ {
+ poffDumpFileHeader(poffHandle, stdout);
+ }
+
+ /* Dump the Section Headers */
+
+ if (showSectionHeaders)
+ {
+ poffDumpSectionHeaders(poffHandle, stdout);
+ }
+
+ /* Dump the symbol table */
+
+ if (showSymbols)
+ {
+ poffDumpSymbolTable(poffHandle, stdout);
+ }
+
+ /* Dump the relocation table */
+
+ if (showRelocs)
+ {
+ poffDumpRelocTable(poffHandle, stdout);
+ }
+
+ /* Dump the program data section -- Main Loop */
+
+ if (disassemble)
+ {
+ dumpProgramData(poffHandle);
+ }
+
+ /* Close files and release objects */
+
+ poffDestroyHandle(poffHandle);
+ (void)fclose(object);
+ return 0;
+} /* end main */
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+static void showUsage(const char *progname)
+{
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s [options] <poff-filename>\n",
+ progname);
+ fprintf(stderr, "options:\n");
+ fprintf(stderr, " -a --all Equivalent to: -h -S -s -r -d\n");
+ fprintf(stderr, " -h --file-header Display the POFF file header\n");
+ fprintf(stderr, " -S --section-headers Display the sections' header\n");
+ fprintf(stderr, " -s --symbols Display the symbol table\n");
+ fprintf(stderr, " -r --relocs Display the relocations\n");
+ fprintf(stderr, " -d --disassemble Display disassembled text\n");
+ fprintf(stderr, " -H --help Display this information\n");
+ exit(1);
+}
+
+/***********************************************************************/
+
+static void parseArgs(int argc, char **argv)
+{
+ int option_index;
+ int c;
+
+ /* Check for existence of filename argument */
+
+ if (argc < 2)
+ {
+ fprintf(stderr, "ERROR: POFF filename required\n");
+ showUsage(argv[0]);
+ } /* end if */
+
+ /* Parse the command line options */
+
+ do
+ {
+ c = getopt_long (argc, argv, "ahSsrdH",
+ long_options, &option_index);
+ if (c != -1)
+ {
+ switch (c)
+ {
+ case 'a' :
+ showFileHeader = 1;
+ showSectionHeaders = 1;
+ showSymbols = 1;
+ showRelocs = 1;
+ disassemble = 1;
+ break;
+
+ case 'h' :
+ showFileHeader = 1;
+ break;
+
+ case 'S' :
+ showSectionHeaders = 1;
+ break;
+
+ case 's' :
+ showSymbols = 1;
+ break;
+
+ case 'r' :
+ showRelocs = 1;
+ break;
+
+ case 'd' :
+ disassemble = 1;
+ break;
+
+ case 'H' :
+ showUsage(argv[0]);
+ break;
+
+ default:
+ /* Shouldn't happen */
+
+ fprintf(stderr, "ERROR: Unrecognized option\n");
+ showUsage(argv[0]);
+ }
+ }
+ }
+ while (c != -1);
+
+ /* Get the name of the p-code file(s) from the last argument(s) */
+
+ if (optind != argc-1)
+ {
+ fprintf(stderr, "ERROR: POFF filename required as final argument\n");
+ showUsage(argv[0]);
+ }
+
+ /* Save the POFF file name */
+
+ poffFileName = argv[argc-1];
+}
+
+/***********************************************************************/
+
+static void dumpProgramData(poffHandle_t poffHandle)
+{
+ poffLibLineNumber_t *lastln; /* Previous line number reference */
+ poffLibLineNumber_t *ln; /* Current line number reference */
+ uint32_t pc; /* Program counter */
+ OPTYPE op; /* Opcode */
+ int opSize; /* Size of the opcode */
+ int inch; /* Input char */
+
+ /* Read the line number entries from the POFF file */
+
+ poffReadLineNumberTable(poffHandle);
+
+ /* Dump the program data section -- DumpProgramData Loop */
+
+ pc = 0;
+ lastln = NULL;
+
+ while ((inch = poffGetProgByte(poffHandle)) != EOF)
+ {
+ /* Get opcode arguments (if any) */
+
+ op.op = (uint8_t) inch;
+ op.arg1 = 0;
+ op.arg2 = 0;
+ opSize = 1;
+
+ if (op.op & o8)
+ {
+ op.arg1 = poffGetProgByte(poffHandle);
+ opSize += 1;
+ }
+
+ if (op.op & o16 )
+ {
+ op.arg2 = poffGetProgByte(poffHandle) << 8;
+ op.arg2 |= poffGetProgByte(poffHandle);
+ opSize += 2;
+ } /* end if */
+
+ /* Find the line number associated with this line */
+
+ ln = poffFindLineNumber(pc);
+ if ((ln) && (ln != lastln))
+ {
+ /* Print the line number line */
+
+ printf("\n%s:%ld\n", ln->filename, ln->lineno);
+
+ /* This will suppress reporting the same line number
+ * repeatedly.
+ */
+
+ lastln = ln;
+ }
+
+ /* Print the address then the opcode on stdout */
+
+ fprintf(stdout, "%08lx ", pc);
+ insn_DisassemblePCode(stdout, &op);
+
+ /* Bump the PC to the next address */
+
+ pc += opSize;
+
+ } /* end while */
+
+ /* Release buffers associated with line number information */
+
+ poffReleaseLineNumberTable();
+
+} /* end dumpProgramData */
+
+/***********************************************************************/
diff --git a/misc/pascal/insn16/popt/Makefile b/misc/pascal/insn16/popt/Makefile
new file mode 100644
index 000000000..cff0ec7fb
--- /dev/null
+++ b/misc/pascal/insn16/popt/Makefile
@@ -0,0 +1,92 @@
+############################################################################
+# insn16/prun/Makefile
+# Host system makefile
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Directories
+#
+POPTDIR = ${shell pwd}
+INSNDIR = $(POPTDIR)/..
+PASCAL = $(POPTDIR)/../..
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+INCDIR = $(PASCAL)/include
+LIBDIR = $(PASCAL)/lib
+BINDIR = $(PASCAL)/bin16
+
+#
+# Tools
+#
+EXTRA_INCLUDES = -I$(INSNDIR)/include
+INCLUDES += $(EXTRA_INCLUDES)
+CFLAGS += $(EXTRA_INCLUDES)
+
+#
+# Objects and targets
+#
+POPTSRCS = popt.c psopt.c polocal.c pcopt.c pjopt.c plopt.c pfopt.c
+POPTOBJS = $(POPTSRCS:.c=.o)
+
+OBJS = $(POPTOBJS)
+LIBS = libpoff.a libpas.a
+
+all: popt
+.PHONY: all check_libs popt clean
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+check_libs:
+ @if [ ! -f $(LIBDIR)/libpoff.a ] ; then \
+ echo "$(LIBDIR)/libpoff.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libpas.a ] ; then \
+ echo "$(LIBDIR)/libpas.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libinsn.a ] ; then \
+ echo "$(LIBDIR)/libinsn.a does not exist" ; \
+ exit 1 ; \
+ fi
+
+$(BINDIR)/popt: check_libs $(POPTOBJS)
+ $(CC) -o $@ $(LDFLAGS) $(POPTOBJS) -lpoff -linsn -lpas
+
+popt: $(BINDIR)/popt
+
+clean:
+ $(RM) popt *.o core *~
diff --git a/misc/pascal/insn16/popt/pcopt.c b/misc/pascal/insn16/popt/pcopt.c
new file mode 100644
index 000000000..e37a2d367
--- /dev/null
+++ b/misc/pascal/insn16/popt/pcopt.c
@@ -0,0 +1,906 @@
+/**********************************************************************
+ * pcopt.c
+ * Constant Expression Optimizations
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pinsn16.h"
+
+#include "paslib.h"
+#include "popt.h"
+#include "polocal.h"
+#include "pcopt.h"
+
+/**********************************************************************/
+
+int16_t unaryOptimize(void)
+{
+ int16_t nchanges = 0;
+ register uint16_t temp;
+ register int16_t i;
+
+ TRACE(stderr, "[unaryOptimize]");
+
+ /* At least two pcodes are need to perform unary optimizations */
+
+ i = 0;
+ while (i < nops-1)
+ {
+ /* Check for a constant value being pushed onto the stack */
+
+ if ((pptr[i]->op == oPUSH) || (pptr[i]->op == oPUSHB))
+ {
+ /* Turn the oPUSHB into an oPUSH op (temporarily) */
+
+ if (pptr[i]->op == oPUSHB)
+ {
+ pptr[i]->op = oPUSH;
+ pptr[i]->arg2 = pptr[i]->arg1;
+ pptr[i]->arg1 = 0;
+ } /* end if */
+
+ switch (pptr[i+1]->op)
+ {
+ /* Delete unary operators on constants */
+ case oNEG :
+ pptr[i]->arg2 = -(pptr[i]->arg2);
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oABS :
+ if (signExtend16(pptr[i]->arg2) < 0)
+ pptr[i]->arg2 = -signExtend16(pptr[i]->arg2);
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oINC :
+ (pptr[i]->arg2)++;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oDEC :
+ (pptr[i]->arg2)--;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oNOT :
+ pptr[i]->arg2 = ~(pptr[i]->arg2);
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ /* Simplify binary operations on constants */
+
+ case oADD :
+ if (pptr[i]->arg2 == 0)
+ {
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ } /* end if */
+ else if (pptr[i]->arg2 == 1)
+ {
+ pptr[i+1]->op = oINC;
+ deletePcode(i);
+ nchanges++;
+ } /* end else if */
+ else if (pptr[i]->arg2 == (uint16_t)-1)
+ {
+ pptr[i+1]->op = oDEC;
+ deletePcode(i);
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oSUB :
+ if (pptr[i]->arg2 == 0)
+ {
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ } /* end if */
+ else if (pptr[i]->arg2 == 1)
+ {
+ pptr[i+1]->op = oDEC;
+ deletePcode(i);
+ nchanges++;
+ } /* end else if */
+ else if (pptr[i]->arg2 == (uint16_t)-1)
+ {
+ pptr[i+1]->op = oINC;
+ deletePcode(i);
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oMUL :
+ case oDIV :
+ temp = 0;
+ switch (pptr[i]->arg2)
+ {
+ case 1 :
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ break;
+ case 16384 : temp++;
+ case 8192 : temp++;
+ case 4096 : temp++;
+ case 2048 : temp++;
+ case 1024 : temp++;
+ case 512 : temp++;
+ case 256 : temp++;
+ case 128 : temp++;
+ case 64 : temp++;
+ case 32 : temp++;
+ case 16 : temp++;
+ case 8 : temp++;
+ case 4 : temp++;
+ case 2 : temp++;
+ pptr[i]->arg2 = temp;
+ if (pptr[i+1]->op == oMUL)
+ pptr[i+1]->op = oSLL;
+ else
+ pptr[i+1]->op = oSRA;
+ nchanges++;
+ i++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oSLL :
+ case oSRL :
+ case oSRA :
+ case oOR :
+ if (pptr[i]->arg2 == 0)
+ {
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oAND :
+ if (pptr[i]->arg2 == 0xffff)
+ {
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ /* Delete comparisons of constants to zero */
+
+ case oEQUZ :
+ if (pptr[i]->arg2 == 0) pptr[i]->arg2 = -1;
+ else pptr[i]->arg2 = 0;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oNEQZ :
+ if (pptr[i]->arg2 != 0)
+ pptr[i]->arg2 = -1;
+ else
+ pptr[i]->arg2 = 0;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oLTZ :
+ if (signExtend16(pptr[i]->arg2) < 0)
+ pptr[i]->arg2 = -1;
+ else
+ pptr[i]->arg2 = 0;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oGTEZ :
+ if (signExtend16(pptr[i]->arg2) >= 0)
+ pptr[i]->arg2 = -1;
+ else
+ pptr[i]->arg2 = 0;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oGTZ :
+ if (pptr[i]->arg2 > 0) pptr[i]->arg2 = -1;
+ else pptr[i]->arg2 = 0;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oLTEZ :
+ if (pptr[i]->arg2 <= 0) pptr[i]->arg2 = -1;
+ else pptr[i]->arg2 = 0;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ /* Simplify comparisons with certain constants */
+
+ case oEQU :
+ if (pptr[i]->arg2 == 0)
+ {
+ pptr[i+1]->op = oEQUZ;
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else if (pptr[i]->arg2 == 1)
+ {
+ pptr[i]->op = oDEC;
+ pptr[i]->arg2 = 0;
+ pptr[i+1]->op = oEQUZ;
+ nchanges++;
+ } /* end else if */
+ else if (signExtend16(pptr[i]->arg2) == -1)
+ {
+ pptr[i]->op = oINC;
+ pptr[i]->arg2 = 0;
+ pptr[i+1]->op = oEQUZ;
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oNEQ :
+ if (pptr[i]->arg2 == 0)
+ {
+ pptr[i+1]->op = oNEQZ;
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else if (pptr[i]->arg2 == 1)
+ {
+ pptr[i]->op = oDEC;
+ pptr[i]->arg2 = 0;
+ pptr[i+1]->op = oNEQZ;
+ nchanges++;
+ } /* end else if */
+ else if (signExtend16(pptr[i]->arg2) == -1)
+ {
+ pptr[i]->op = oINC;
+ pptr[i]->arg2 = 0;
+ pptr[i+1]->op = oNEQZ;
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oLT :
+ if (pptr[i]->arg2 == 0)
+ {
+ pptr[i+1]->op = oLTZ;
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else if (pptr[i]->arg2 == 1)
+ {
+ pptr[i]->op = oDEC;
+ pptr[i]->arg2 = 0;
+ pptr[i+1]->op = oLTZ;
+ nchanges++;
+ } /* end else if */
+ else if (signExtend16(pptr[i]->arg2) == -1)
+ {
+ pptr[i]->op = oINC;
+ pptr[i]->arg2 = 0;
+ pptr[i+1]->op = oLTZ;
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oGTE :
+ if (pptr[i]->arg2 == 0)
+ {
+ pptr[i+1]->op = oGTEZ;
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else if (pptr[i]->arg2 == 1)
+ {
+ pptr[i]->op = oDEC;
+ pptr[i]->arg2 = 0;
+ pptr[i+1]->op = oGTEZ;
+ nchanges++;
+ } /* end else if */
+ else if (signExtend16(pptr[i]->arg2) == -1)
+ {
+ pptr[i]->op = oINC;
+ pptr[i]->arg2 = 0;
+ pptr[i+1]->op = oGTEZ;
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oGT :
+ if (pptr[i]->arg2 == 0)
+ {
+ pptr[i+1]->op = oGTZ;
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else if (pptr[i]->arg2 == 1)
+ {
+ pptr[i]->op = oDEC;
+ pptr[i]->arg2 = 0;
+ pptr[i+1]->op = oGTZ;
+ nchanges++;
+ } /* end else if */
+ else if (signExtend16(pptr[i]->arg2) == -1)
+ {
+ pptr[i]->op = oINC;
+ pptr[i]->arg2 = 0;
+ pptr[i+1]->op = oGTZ;
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oLTE :
+ if (pptr[i]->arg2 == 0)
+ {
+ pptr[i+1]->op = oLTEZ;
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else if (pptr[i]->arg2 == 1)
+ {
+ pptr[i]->op = oDEC;
+ pptr[i]->arg2 = 0;
+ pptr[i+1]->op = oLTEZ;
+ nchanges++;
+ } /* end else if */
+ else if (signExtend16(pptr[i]->arg2) == -1)
+ {
+ pptr[i]->op = oINC;
+ pptr[i]->arg2 = 0;
+ pptr[i+1]->op = oLTEZ;
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ /* Simplify or delete condition branches on constants */
+
+ case oJEQUZ :
+ if (pptr[i]->arg2 == 0)
+ {
+ pptr[i+1]->op = oJMP;
+ deletePcode(i);
+ } /* end if */
+ else
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ if (pptr[i]->arg2 != 0)
+ {
+ pptr[i+1]->op = oJMP;
+ deletePcode(i);
+ } /* end if */
+ else
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ break;
+
+ case oJLTZ :
+ if (signExtend16(pptr[i]->arg2) < 0)
+ {
+ pptr[i+1]->op = oJMP;
+ deletePcode(i);
+ } /* end if */
+ else
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ break;
+
+ case oJGTEZ :
+ if (signExtend16(pptr[i]->arg2) >= 0)
+ {
+ pptr[i+1]->op = oJMP;
+ deletePcode(i);
+ } /* end if */
+ else
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ break;
+
+ case oJGTZ :
+ if (pptr[i]->arg2 > 0)
+ {
+ pptr[i+1]->op = oJMP;
+ deletePcode(i);
+ } /* end if */
+ else
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ break;
+
+ case oJLTEZ :
+ if (pptr[i]->arg2 <= 0)
+ {
+ pptr[i+1]->op = oJMP;
+ deletePcode(i);
+ } /* end if */
+ else
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+
+ /* If the oPUSH instruction is still there, see if we can now */
+ /* represent it with an oPUSHB instruction */
+
+ if ((pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256))
+ {
+ pptr[i]->op = oPUSHB;
+ pptr[i]->arg1 = pptr[i]->arg2;
+ pptr[i]->arg2 = 0;
+ } /* end if */
+ } /* end if */
+
+ /* Delete multiple modifications of DSEG pointer */
+
+ else if (pptr[i]->op == oINDS)
+ {
+ if (pptr[i+1]->op == oINDS)
+ {
+ pptr[i]->arg2 += pptr[i+1]->arg2;
+ deletePcode(i+1);
+ } /* end if */
+ else i++;
+ } /* end else if */
+ else i++;
+ } /* end while */
+
+ return (nchanges);
+
+} /* end unaryOptimize */
+
+/**********************************************************************/
+
+int16_t binaryOptimize(void)
+{
+ int16_t nchanges = 0;
+ register int16_t stmp16;
+ register int16_t i;
+
+ TRACE(stderr, "[binaryOptimize]");
+
+ /* At least two pcodes are needed to perform the following binary */
+ /* operator optimizations */
+
+ i = 0;
+ while (i < nops-2)
+ {
+ if ((pptr[i]->op == oPUSH) || (pptr[i]->op == oPUSHB))
+ {
+ if ((pptr[i+1]->op == oPUSH) || (pptr[i+1]->op == oPUSHB))
+ {
+ /* Turn the oPUSHBs into an oPUSHs op (temporarily) */
+
+ if (pptr[i]->op == oPUSHB)
+ {
+ pptr[i]->op = oPUSH;
+ pptr[i]->arg2 = pptr[i]->arg1;
+ pptr[i]->arg1 = 0;
+ } /* end if */
+
+ if (pptr[i+1]->op == oPUSHB)
+ {
+ pptr[i+1]->op = oPUSH;
+ pptr[i+1]->arg2 = pptr[i+1]->arg1;
+ pptr[i+1]->arg1 = 0;
+ } /* end if */
+
+ switch (pptr[i+2]->op)
+ {
+ case oADD :
+ pptr[i]->arg2 += pptr[i+1]->arg2;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oSUB :
+ pptr[i]->arg2 -= pptr[i+1]->arg2;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oMUL :
+ pptr[i]->arg2 *= pptr[i+1]->arg2;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oDIV :
+ stmp16 = pptr[i]->arg2 / signExtend16(pptr[i+1]->arg2);
+ pptr[i]->arg2 = stmp16;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oMOD :
+ pptr[i]->arg2 %= pptr[i+1]->arg2;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oSLL :
+ pptr[i]->arg2 <<= pptr[i+1]->arg2;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oSRL :
+ pptr[i]->arg2 >>= pptr[i+1]->arg2;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oSRA :
+ stmp16 = (((int16_t)pptr[i]->arg2) >> pptr[i+1]->arg2);
+ pptr[i]->arg2 = (uint16_t)stmp16;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oOR :
+ pptr[i]->arg2 |= pptr[i+1]->arg2;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oAND :
+ pptr[i]->arg2 &= pptr[i+1]->arg2;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oEQU :
+ if (pptr[i]->arg2 == pptr[i+1]->arg2) pptr[i]->arg2 = -1;
+ else pptr[i]->arg2 = 0;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oNEQ :
+ if ((int16_t)pptr[i]->arg2 != (int16_t)pptr[i+1]->arg2)
+ pptr[i]->arg2 = -1;
+ else
+ pptr[i]->arg2 = 0;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oLT :
+ if ((int16_t)pptr[i]->arg2 < (int16_t)pptr[i+1]->arg2)
+ pptr[i]->arg2 = -1;
+ else
+ pptr[i]->arg2 = 0;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oGTE :
+ if ((int16_t)pptr[i]->arg2 >= (int16_t)pptr[i+1]->arg2)
+ pptr[i]->arg2 = -1;
+ else
+ pptr[i]->arg2 = 0;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oGT :
+ if ((int16_t)pptr[i]->arg2 > (int16_t)pptr[i+1]->arg2)
+ pptr[i]->arg2 = -1;
+ else
+ pptr[i]->arg2 = 0;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oLTE :
+ if ((int16_t)pptr[i]->arg2 <= (int16_t)pptr[i+1]->arg2)
+ pptr[i]->arg2 = -1;
+ else
+ pptr[i]->arg2 = 0;
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+
+ /* If the oPUSH instruction is still there, see if we can now */
+ /* represent it with an oPUSHB instruction */
+
+ if (pptr[i] && (pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256))
+ {
+ pptr[i]->op = oPUSHB;
+ pptr[i]->arg1 = pptr[i]->arg2;
+ pptr[i]->arg2 = 0;
+ } /* end if */
+
+ if (pptr[i+1] && (pptr[i+1]->op == oPUSH) && (pptr[i+1]->arg2 < 256))
+ {
+ pptr[i+1]->op = oPUSHB;
+ pptr[i+1]->arg1 = pptr[i+1]->arg2;
+ pptr[i+1]->arg2 = 0;
+ } /* end if */
+ } /* end if */
+
+ /* A single (constant) pcode is sufficient to perform the */
+ /* following binary operator optimizations */
+
+ else if ((pptr[i+1]->op == oLDSH) || (pptr[i+1]->op == oLDSB) ||
+ (pptr[i+1]->op == oLAS) || (pptr[i+1]->op == oLAC))
+ {
+ /* Turn the oPUSHB into a oPUSH op (temporarily) */
+
+ if (pptr[i]->op == oPUSHB)
+ {
+ pptr[i]->op = oPUSH;
+ pptr[i]->arg2 = pptr[i]->arg1;
+ pptr[i]->arg1 = 0;
+ } /* end if */
+
+ switch (pptr[i+2]->op)
+ {
+ case oADD :
+ if (pptr[i]->arg2 == 0)
+ {
+ deletePcodePair(i, (i+2));
+ nchanges++;
+ } /* end if */
+ else if (pptr[i]->arg2 == 1)
+ {
+ pptr[i+2]->op = oINC;
+ deletePcode(i);
+ nchanges++;
+ } /* end else if */
+ else if (pptr[i]->arg2 == (uint16_t)-1)
+ {
+ pptr[i+2]->op = oDEC;
+ deletePcode(i);
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oSUB :
+ if (pptr[i]->arg2 == 0)
+ {
+ pptr[i]->op = oNEG;
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oMUL :
+ stmp16 = 0;
+ switch (pptr[i]->arg2)
+ {
+ case 1 :
+ deletePcodePair(i, (i+2));
+ nchanges++;
+ break;
+ case 16384 : stmp16++;
+ case 8192 : stmp16++;
+ case 4096 : stmp16++;
+ case 2048 : stmp16++;
+ case 1024 : stmp16++;
+ case 512 : stmp16++;
+ case 256 : stmp16++;
+ case 128 : stmp16++;
+ case 64 : stmp16++;
+ case 32 : stmp16++;
+ case 16 : stmp16++;
+ case 8 : stmp16++;
+ case 4 : stmp16++;
+ case 2 : stmp16++;
+ pptr[i]->op = pptr[i+1]->op;
+ pptr[i]->arg1 = pptr[i+1]->arg1;
+ pptr[i]->arg2 = pptr[i+1]->arg2;
+ pptr[i+1]->op = oPUSH;
+ pptr[i+1]->arg1 = 0;
+ pptr[i+1]->arg2 = stmp16;
+ pptr[i+2]->op = oSLL;
+ nchanges++;
+ i++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oOR :
+ if (pptr[i]->arg2 == 0)
+ {
+ deletePcodePair(i, (i+2));
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oAND :
+ if (pptr[i]->arg2 == 0xffff)
+ {
+ deletePcodePair(i, (i+2));
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oEQU :
+ if (pptr[i]->arg2 == 0)
+ {
+ pptr[i+2]->op = oEQUZ;
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oNEQ :
+ if (pptr[i]->arg2 == 0)
+ {
+ pptr[i+2]->op = oNEQZ;
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oLT :
+ if (pptr[i]->arg2 == 0)
+ {
+ pptr[i+2]->op = oGTEZ;
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oGTE :
+ if (pptr[i]->arg2 == 0)
+ {
+ pptr[i+2]->op = oLTZ;
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oGT :
+ if (pptr[i]->arg2 == 0)
+ {
+ pptr[i+2]->op = oLTEZ;
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oLTE :
+ if (pptr[i]->arg2 == 0)
+ {
+ pptr[i+2]->op = oGTZ;
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ default :
+ i++;
+ break;
+
+ } /* end switch */
+
+ /* If the oPUSH instruction is still there, see if we can now */
+ /* represent it with an oPUSHB instruction */
+
+ if ((pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256))
+ {
+ pptr[i]->op = oPUSHB;
+ pptr[i]->arg1 = pptr[i]->arg2;
+ pptr[i]->arg2 = 0;
+ } /* end if */
+ } /* end else if */
+ else i++;
+ } /* end if */
+
+ /* Misc improvements on binary operators */
+
+ else if (pptr[i]->op == oNEG)
+ {
+ /* Negation followed by add is subtraction */
+
+ if (pptr[i+1]->op == oADD)
+ {
+ pptr[i+1]->op = oSUB;
+ deletePcode(i);
+ nchanges++;
+ }
+
+ /* Negation followed by subtraction is addition */
+
+ else if (pptr[i]->op == oSUB)
+ {
+ pptr[i+1]->op = oADD;
+ deletePcode(i);
+ nchanges++;
+ }
+ else i++;
+ }
+ else i++;
+ } /* end while */
+
+ return (nchanges);
+
+} /* end binaryOptimize */
+
+/**********************************************************************/
+
diff --git a/misc/pascal/insn16/popt/pcopt.h b/misc/pascal/insn16/popt/pcopt.h
new file mode 100644
index 000000000..53ea9c040
--- /dev/null
+++ b/misc/pascal/insn16/popt/pcopt.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * pcopt.h
+ * External Declarations associated with PCOPT.C
+ *
+ * Copyright (C) 200-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PCOPT_H
+#define __PCOPT_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern int16_t unaryOptimize(void);
+extern int16_t binaryOptimize(void);
+
+#endif /* __PCOPT_H */
diff --git a/misc/pascal/insn16/popt/pfopt.c b/misc/pascal/insn16/popt/pfopt.c
new file mode 100644
index 000000000..612ceb8f4
--- /dev/null
+++ b/misc/pascal/insn16/popt/pfopt.c
@@ -0,0 +1,473 @@
+/**********************************************************************
+ * pfopt.c
+ * Finalization of optimized image
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "podefs.h"
+#include "pedefs.h"
+#include "pinsn16.h"
+#include "poff.h"
+#include "paslib.h"
+#include "pofflib.h"
+
+#include "popt.h"
+#include "pfopt.h"
+#include "pinsn.h"
+#include "perr.h"
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Types
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Data
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Inline Functions
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/**********************************************************************/
+
+static void pass1(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ OPTYPE op;
+ uint32_t pc;
+ uint32_t opsize;
+
+ /* Build label / line number reference table
+ *
+ * CASE 1: LABEL
+ * Add label number + PC to table
+ * discard
+ * CASE 2: LINE
+ * genereate a line number reference
+ * discard
+ * ELSE:
+ * pass through with no additional action
+ */
+
+ pc = 0;
+ do
+ {
+ opsize = insn_GetOpCode(poffHandle, &op);
+ if (op.op == oLABEL)
+ {
+ poffAddToDefinedLabelTable(op.arg2, pc);
+ }
+ else if (op.op == oLINE)
+ {
+ poffAddLineNumber(poffHandle, op.arg2, op.arg1, pc);
+ }
+ else
+ {
+ insn_AddTmpOpCode(poffProgHandle, &op);
+ pc += opsize;
+ }
+ }
+ while (op.op != oEND);
+
+ /* Replace the original program data with the new program data */
+
+ poffReplaceProgData(poffHandle, poffProgHandle);
+}
+
+/**********************************************************************/
+
+static void pass2(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ poffSymHandle_t poffSymHandle;
+ int32_t symIndex;
+ int32_t nchanges = 0;
+
+ /* Get a container to temporarily hold any modifications that we
+ * make to the symbol table.
+ */
+
+ poffSymHandle = poffCreateSymHandle();
+ if (poffSymHandle == NULL)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* Now read all of the symbols. (1) Add each undefined code reference
+ * to the label reference table, and (2) Change each defined code
+ * reference from a label to a program data section offset.
+ */
+
+ do
+ {
+ poffLibSymbol_t symbol;
+ symIndex = poffGetSymbol(poffHandle, &symbol);
+ if (symIndex >= 0)
+ {
+ if ((symbol.type == STT_PROC) || (symbol.type == STT_FUNC))
+ {
+ /* It is a symbol associated with the program data section.
+ * Has is value been defined?
+ */
+
+ if ((symbol.flags & STF_UNDEFINED) != 0)
+ {
+ /* No... Add it to the list of undefined labels */
+
+ poffAddToUndefinedLabelTable(symbol.value, symIndex);
+ }
+ else
+ {
+ /* It is a defined symbol. In this case, we should have
+ * encountered its LABEL marker in the pass1 processing
+ * and the following look up should not fail.
+ */
+ int32_t value = poffGetPcForDefinedLabel(symbol.value);
+ if (value < 0)
+ {
+ DEBUG(stdout, "Failed to find label L%04lx\n", symbol.value);
+ fatal(ePOFFCONFUSION);
+ }
+ else
+ {
+ /* Replace the label value with the section offset
+ * (pc) value.
+ */
+
+ symbol.value = value;
+ nchanges++;
+ }
+ }
+ }
+
+ /* In either event, we will want to save the symbol in case
+ * we need to re-write the symbol table.
+ */
+
+ (void)poffAddTmpSymbol(poffHandle, poffSymHandle, &symbol);
+ }
+ }
+ while (symIndex >= 0);
+
+ /* We any changes made to the symbol table in the temporary container? */
+
+ if (nchanges != 0)
+ {
+ /* Yes, update the symbol table */
+
+ poffReplaceSymbolTable(poffHandle, poffSymHandle);
+
+ }
+
+ /* Release the symbol container. */
+
+ poffDestroySymHandle(poffSymHandle);
+}
+
+/**********************************************************************/
+
+static void pass3(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ OPTYPE op;
+ uint32_t pc;
+ uint32_t opsize;
+
+ /* Read each opcode, generate relocation information and
+ * replace label references with program section offsets.
+ *
+ * CASE 1: LAC
+ * generate RODATA relocation entry
+ * CASE 2: PCAL instructions
+ * replace label with I-space offset, OR
+ * generate a PROGRAM relocation entry
+ * CASE 3: J* instructions
+ * replace label with I-space offset
+ * CASE 4: LDS*, STS*, and LAS* instructions
+ * generate a STACK relocation (if imported?)
+ * ELSE:
+ * pass through with no additional action
+ */
+
+ pc = 0;
+ do
+ {
+ opsize = insn_GetOpCode(poffHandle, &op);
+ switch (op.op)
+ {
+ /* Load of an address in the rodata section */
+
+ case oLAC:
+ /* We are referencing something from the rodata section.
+ * No special action need be taken.
+ */
+ break;
+
+ /* Call to a procedure or function. */
+
+ case oPCAL:
+ {
+ /* Check if this is a defined label, i.e., a call to
+ * procedure or function in the same file.
+ */
+
+ int32_t value = poffGetPcForDefinedLabel(op.arg2);
+ if (value >= 0)
+ {
+ /* Yes... replace the label reference with
+ * a text section offset. No relocation record
+ * is needed in this case. The only relocation
+ * may be performed is a subsequent program data
+ * section offset.
+ */
+
+ op.arg2 = (uint16_t)value;
+ }
+ else
+ {
+ /* Check if this is a undefined label. This would
+ * occur for a call to a procedure or a function that
+ * is defined in some other unit file.
+ */
+
+ value = poffGetSymIndexForUndefinedLabel(op.arg2);
+ if (value >= 0)
+ {
+ /* Use the value zero now */
+
+ op.arg2 = 0;
+
+ /* And generate a symbol-based relocation */
+
+ (void)poffAddRelocation(poffHandle, RLT_PCAL, value, pc);
+ }
+ else
+ {
+ DEBUG(stdout, "Failed to find call label L%04x\n", op.arg2);
+ fatal(ePOFFCONFUSION);
+ }
+ }
+ }
+ break;
+
+ /* Jumps to "nearby" addresses */
+
+ case oJMP: /* Unconditional */
+ case oJEQUZ: /* Unary comparisons with zero */
+ case oJNEQZ:
+ case oJLTZ:
+ case oJGTEZ:
+ case oJGTZ:
+ case oJLTEZ:
+ case oJEQU: /* Binary comparisons */
+ case oJNEQ:
+ case oJLT:
+ case oJGTE:
+ case oJGT:
+ case oJLTE:
+ {
+ /* Check if this is a defined label. This must be the case
+ * because there can be no jumps into a unit file.
+ */
+
+ int32_t value = poffGetPcForDefinedLabel(op.arg2);
+ if (value >= 0)
+ {
+ /* Yes... replace the label reference with
+ * a text section offset. No relocation record
+ * is needed in this case. The only relocation
+ * may be performed is a subsequent program data
+ * sectioin offset.
+ */
+
+ op.arg2 = (uint16_t)value;
+ }
+ else
+ {
+ DEBUG(stdout, "Failed to find jump label L%04x\n", op.arg2);
+ fatal(ePOFFCONFUSION);
+ }
+ }
+ break;
+
+ /* References to stack via level offset */
+
+ case oLAS: /* Load stack address */
+ case oLASX:
+ case oLDS: /* Load value */
+ case oLDSH:
+ case oLDSB:
+ case oLDSM:
+ case oSTS: /* Store value */
+ case oSTSH:
+ case oSTSB:
+ case oSTSM:
+ case oLDSX:
+ case oLDSXH: /* Load value indexed */
+ case oLDSXB:
+ case oLDSXM:
+ case oSTSX: /* Store value indexed */
+ case oSTSXH:
+ case oSTSXB:
+ case oSTSXM:
+ {
+#warning REVISIT
+ }
+ break;
+
+ /* Otherwise, it is not an interesting opcode */
+ default:
+ break;
+ }
+
+ /* Save the potentially modified opcode in the temporary
+ * program data container.
+ */
+
+ insn_AddTmpOpCode(poffProgHandle, &op);
+ pc += opsize;
+ }
+ while (op.op != oEND);
+
+ /* Replace the original program data with the new program data */
+
+ poffReplaceProgData(poffHandle, poffProgHandle);
+}
+
+/**********************************************************************/
+
+static void pass4(poffHandle_t poffHandle)
+{
+ uint32_t entryLabel;
+ int32_t entryOffset;
+ uint8_t fileType;
+
+ /* What kind of a file did we just process. Was it a program file?
+ * or was it a unit file?
+ */
+
+ fileType = poffGetFileType(poffHandle);
+ if (fileType == FHT_PROGRAM)
+ {
+ /* It is a program file. In this case, it must have a valid
+ * entry point label. Get it.
+ */
+
+ entryLabel = poffGetEntryPoint(poffHandle);
+
+ /* Convert the label into a program data section offset */
+
+ entryOffset = poffGetPcForDefinedLabel(entryLabel);
+ if (entryOffset < 0)
+ {
+ fatal(ePOFFCONFUSION);
+ }
+
+ /* Replace file header entry point with the program data
+ * section offset
+ */
+
+ poffSetEntryPoint(poffHandle, entryOffset);
+ }
+}
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+void optFinalize(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ /* Build label / line number reference table */
+
+ pass1(poffHandle, poffProgHandle);
+
+ /* Reset for next pass */
+
+ insn_ResetOpCodeRead(poffHandle);
+ insn_ResetTmpOpCodeWrite(poffProgHandle);
+
+ /* Now process all of the symbols */
+
+ pass2(poffHandle, poffProgHandle);
+
+ /* We do not use the debug function information so we do not bother
+ * to fixup the label references. Just discard this information.
+ */
+
+ poffDiscardDebugFuncInfo(poffHandle);
+
+ /* Reset for next pass */
+
+ insn_ResetOpCodeRead(poffHandle);
+
+ /* Generate relocation information and replace all label references
+ * in the code with actual program section data offsets.
+ */
+
+ pass3(poffHandle, poffProgHandle);
+
+ /* Reset for next pass */
+
+ insn_ResetOpCodeRead(poffHandle);
+ insn_ResetTmpOpCodeWrite(poffProgHandle);
+
+ /* Finally, replace file header entry point with the I-space offset */
+
+ pass4(poffHandle);
+
+ /* Clean up after ourselves */
+
+ poffReleaseLabelReferences();
+}
+
+/**********************************************************************/
diff --git a/misc/pascal/insn16/popt/pfopt.h b/misc/pascal/insn16/popt/pfopt.h
new file mode 100644
index 000000000..07ce738b1
--- /dev/null
+++ b/misc/pascal/insn16/popt/pfopt.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * pfopt.h
+ * External Declarations associated with pfopt.c
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PFOPT_H
+#define __PFOPT_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include "pofflib.h"
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void optFinalize(poffHandle_t poffHandle,
+ poffProgHandle_t poffProgHandle);
+
+#endif /* __PFOPT_H */
+
diff --git a/misc/pascal/insn16/popt/pjopt.c b/misc/pascal/insn16/popt/pjopt.c
new file mode 100644
index 000000000..16244b5e1
--- /dev/null
+++ b/misc/pascal/insn16/popt/pjopt.c
@@ -0,0 +1,450 @@
+/**********************************************************************
+ * pjopt.c
+ * Branch Optimizations
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pinsn16.h"
+
+#include "popt.h"
+#include "polocal.h"
+#include "pjopt.h"
+
+/**********************************************************************/
+
+int16_t BranchOptimize (void)
+{
+ int16_t nchanges = 0;
+ register int16_t i;
+
+ TRACE(stderr, "[BranchOptimize]");
+
+ /* At least two pcodes are need to perform branch optimizations */
+
+ i = 0;
+ while (i < nops-1)
+ {
+ switch (pptr[i]->op)
+ {
+ case oNOT :
+ switch (pptr[i+1]->op)
+ {
+ case oJEQUZ :
+ pptr[i+1]->op = oJNEQZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJEQUZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oNEG :
+ switch (pptr[i+1]->op)
+ {
+ case oJLTZ :
+ pptr[i+1]->op = oJGTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJGTEZ :
+ pptr[i+1]->op = oJLTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJGTZ :
+ pptr[i+1]->op = oJLTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJLTEZ :
+ pptr[i+1]->op = oJGTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oEQU :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oNEQ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJNEQ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJEQU;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oNEQ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oEQU;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJEQU;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJNEQ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oLT :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oGTE;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJGTE;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJLT;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oGTE :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oLT;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJLT;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJGTE;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oGT :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oLTE;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJLTE;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJGT;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oLTE :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oGT;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJGT;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJLTE;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oEQUZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oNEQZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJNEQZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJEQUZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oNEQZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oEQUZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ case oJNEQZ :
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oLTZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oGTEZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJGTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJLTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oGTEZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oLTZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJLTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJGTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oGTZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oLTEZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJLTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJGTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oLTEZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oGTZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJGTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJLTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ } /* end while */
+ return (nchanges);
+
+} /* end BranchOptimize */
+
+/**********************************************************************/
+
diff --git a/misc/pascal/insn16/popt/pjopt.h b/misc/pascal/insn16/popt/pjopt.h
new file mode 100644
index 000000000..a05082477
--- /dev/null
+++ b/misc/pascal/insn16/popt/pjopt.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * pjopt.h
+ * External Declarations associated with pjopt.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PJOPT_H
+#define __PJOPT_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+
+/***************************************************************************
+ * Public Function Prototypes
+ ***************************************************************************/
+
+int16_t BranchOptimize(void);
+
+#endif /* __PJOPT_H */
diff --git a/misc/pascal/insn16/popt/plopt.c b/misc/pascal/insn16/popt/plopt.c
new file mode 100644
index 000000000..b01449f64
--- /dev/null
+++ b/misc/pascal/insn16/popt/plopt.c
@@ -0,0 +1,250 @@
+/**********************************************************************
+ * plopt.c
+ * Load/Store Optimizations
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pinsn16.h"
+
+#include "popt.h"
+#include "polocal.h"
+#include "plopt.h"
+
+/**********************************************************************/
+
+int16_t LoadOptimize(void)
+{
+ uint16_t val;
+ int16_t nchanges = 0;
+ register int16_t i;
+
+ TRACE(stderr, "[LoadOptimize]");
+
+ /* At least two pcodes are need to perform Load optimizations */
+
+ i = 0;
+ while (i < nops-1)
+ {
+ switch (pptr[i]->op)
+ {
+ /* Eliminate duplicate loads */
+
+ case oLDSH :
+ if ((pptr[i+1]->op == oLDSH) &&
+ (pptr[i+1]->arg1 == pptr[i]->arg1) &&
+ (pptr[i+1]->arg2 == pptr[i]->arg2))
+ {
+ pptr[i+1]->op = oDUPH;
+ pptr[i+1]->arg1 = 0;
+ pptr[i+1]->arg2 = 0;
+ nchanges++;
+ i += 2;
+ } /* end if */
+ else i++;
+ break;
+
+ /* Convert loads indexed by a constant to unindexed loads */
+
+ case oPUSH :
+ case oPUSHB :
+ /* Get the index value */
+
+ if (pptr[i]->op == oPUSH)
+ {
+ val = pptr[i]->arg2;
+ }
+ else
+ {
+ val = pptr[i]->arg1;
+ }
+
+ /* If the following instruction is a load, add the constant
+ * index value to the address and switch the opcode to the
+ * unindexed form.
+ */
+
+ if (pptr[i+1]->op == oLDSXH)
+ {
+ pptr[i+1]->op = oLDSH;
+ pptr[i+1]->arg2 += val;
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else if (pptr[i+1]->op == oLASX)
+ {
+ pptr[i+1]->op = oLAS;
+ pptr[i+1]->arg2 += val;
+ deletePcode (i);
+ nchanges++;
+ } /* end else if */
+ else if (pptr[i+1]->op == oLDSXB)
+ {
+ pptr[i+1]->op = oLDSB;
+ pptr[i+1]->arg2 += val;
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else if (pptr[i+1]->op == oLDSXM)
+ {
+ pptr[i+1]->op = oLDSM;
+ pptr[i+1]->arg2 += val;
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else if (val < 256)
+ {
+ pptr[i]->op = oPUSHB;
+ pptr[i]->arg1 = val;
+ pptr[i]->arg2 = 0;
+ i++;
+ } /* end else if */
+ else i++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ } /* end while */
+ return (nchanges);
+} /* end LoadOptimize */
+
+/**********************************************************************/
+int16_t StoreOptimize (void)
+{
+ uint16_t val;
+ int16_t nchanges = 0;
+ register int16_t i;
+
+ TRACE(stderr, "[StoreOptimize]");
+
+ /* At least two pcodes are need to perform the following Store */
+ /* optimizations */
+
+ i = 0;
+ while (i < nops-1)
+ {
+ switch (pptr[i]->op)
+ {
+ /* Eliminate store followed by load */
+
+ case oSTSH :
+ if ((pptr[i+1]->op == oLDSH) &&
+ (pptr[i+1]->arg1 == pptr[i]->arg1) &&
+ (pptr[i+1]->arg2 == pptr[i]->arg2))
+ {
+ pptr[i+1]->op = oSTSH;
+ pptr[i]->op = oDUPH;
+ pptr[i]->arg1 = 0;
+ pptr[i]->arg2 = 0;
+ nchanges++;
+ i += 2;
+ } /* end if */
+ else i++;
+ break;
+
+ /* Convert stores indexed by a constant to unindexed stores */
+ case oPUSH :
+ /* Get the index value */
+
+ if (pptr[i]->op == oPUSH)
+ {
+ val = pptr[i]->arg2;
+ }
+ else
+ {
+ val = pptr[i]->arg1;
+ }
+
+ /* If the following instruction is a store, add the constant
+ * index value to the address and switch the opcode to the
+ * unindexed form.
+ */
+
+ if (i < nops-2)
+ {
+ if (pptr[i+2]->op == oSTSXH)
+ {
+ pptr[i+2]->op = oSTSH;
+ pptr[i+2]->arg2 += pptr[i]->arg2;
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else if (pptr[i+2]->op == oSTSXB)
+ {
+ pptr[i+2]->op = oSTSB;
+ pptr[i+2]->arg2 += pptr[i]->arg2;
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oPUSHB :
+ if (i < nops-2)
+ {
+ if (pptr[i+2]->op == oSTSXB)
+ {
+ pptr[i+2]->op = oSTSB;
+ pptr[i+2]->arg2 += pptr[i]->arg2;
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ } /* end if */
+ else i++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ } /* end while */
+
+ return (nchanges);
+
+} /* end StoreOptimize */
+
+/**********************************************************************/
+
diff --git a/misc/pascal/insn16/popt/plopt.h b/misc/pascal/insn16/popt/plopt.h
new file mode 100644
index 000000000..43e66af16
--- /dev/null
+++ b/misc/pascal/insn16/popt/plopt.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * plopt.h
+ * External Declarations associated with plopt.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PLOPT_H
+#define __PLOPT_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+
+/***************************************************************************
+ * Public Function Prototypes
+ ***************************************************************************/
+
+extern int16_t LoadOptimize ( void );
+extern int16_t StoreOptimize ( void );
+
+#endif /* __PLOPT_H */
+
diff --git a/misc/pascal/insn16/popt/polocal.c b/misc/pascal/insn16/popt/polocal.c
new file mode 100644
index 000000000..9ef98c1ce
--- /dev/null
+++ b/misc/pascal/insn16/popt/polocal.c
@@ -0,0 +1,301 @@
+/**********************************************************************
+ * polocal.c
+ * P-Code Local Optimizer
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "keywords.h"
+#include "podefs.h"
+#include "pinsn16.h"
+
+#include "pofflib.h"
+#include "paslib.h"
+#include "pinsn.h"
+#include "pcopt.h"
+#include "plopt.h"
+#include "pjopt.h"
+#include "polocal.h"
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static void initPTable (void);
+static void putPCodeFromTable (void);
+static void setupPointer (void);
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+OPTYPE ptable [WINDOW]; /* Pcode Table */
+OPTYPE *pptr [WINDOW]; /* Valid Pcode Pointers */
+
+int16_t nops = 0; /* No. Valid Pcode Pointers */
+int16_t end_out = 0; /* 1 = oEND pcode has been output */
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static poffHandle_t myPoffHandle; /* Handle to POFF object */
+static poffProgHandle_t myPoffProgHandle;/* Handle to temporary POFF object */
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+void localOptimization(poffHandle_t poffHandle,
+ poffProgHandle_t poffProgHandle)
+{
+ int16_t nchanges;
+
+ TRACE(stderr, "[pass2]");
+
+ /* Save the handles for use by other, private functions */
+
+ myPoffHandle = poffHandle;
+ myPoffProgHandle = poffProgHandle;
+
+ /* Initialization */
+
+ initPTable();
+
+ /* Outer loop traverse the file op-code by op-code until the oEND P-Code
+ * has been output. NOTE: it is assumed throughout that oEND is the
+ * final P-Code in the program data section.
+ */
+
+ while (!(end_out))
+ {
+ /* The inner loop optimizes the buffered P-Codes until no further
+ * changes can be made. Then the outer loop will advance the buffer
+ * by one P-Code
+ */
+
+ do
+ {
+ nchanges = unaryOptimize ();
+ nchanges += binaryOptimize();
+ nchanges += BranchOptimize();
+ nchanges += LoadOptimize();
+ nchanges += StoreOptimize();
+ } while (nchanges);
+
+ putPCodeFromTable();
+ }
+}
+
+/***********************************************************************/
+
+void deletePcode(int16_t delIndex)
+{
+ TRACE(stderr, "[deletePcode]");
+
+ pptr[delIndex]->op = oNOP;
+ pptr[delIndex]->arg1 = 0;
+ pptr[delIndex]->arg2 = 0;
+ setupPointer();
+}
+
+/**********************************************************************/
+
+void deletePcodePair(int16_t delIndex1, int16_t delIndex2)
+{
+ TRACE(stderr, "[deletePcodePair]");
+
+ pptr[delIndex1]->op = oNOP;
+ pptr[delIndex1]->arg1 = 0;
+ pptr[delIndex1]->arg2 = 0;
+ pptr[delIndex2]->op = oNOP;
+ pptr[delIndex2]->arg1 = 0;
+ pptr[delIndex2]->arg2 = 0;
+ setupPointer();
+}
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+static void putPCodeFromTable(void)
+{
+ register int16_t i;
+
+ TRACE(stderr, "[putPCodeFromTable]");
+
+ /* Transfer all buffered P-Codes (except NOPs) to the optimized file */
+ do
+ {
+ if ((ptable[0].op != oNOP) && !(end_out))
+ {
+ (void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].op);
+
+ if (ptable[0].op & o8)
+ (void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].arg1);
+
+ if (ptable[0].op & o16)
+ {
+ (void)poffAddTmpProgByte(myPoffProgHandle,
+ (ptable[0].arg2 >> 8));
+ (void)poffAddTmpProgByte(myPoffProgHandle,
+ (ptable[0].arg2 & 0xff));
+ }
+
+ end_out =(ptable[0].op == oEND);
+ }
+
+ /* Move all P-Codes down one slot */
+
+ for (i = 1; i < WINDOW; i++)
+ {
+ ptable[i-1].op = ptable[i].op ;
+ ptable[i-1].arg1 = ptable[i].arg1;
+ ptable[i-1].arg2 = ptable[i].arg2;
+ }
+
+ /* Then fill the end slot with a new P-Code from the input file */
+
+ insn_GetOpCode(myPoffHandle, &ptable[WINDOW-1]);
+
+ } while (ptable[0].op == oNOP);
+ setupPointer();
+}
+
+/**********************************************************************/
+
+static void setupPointer(void)
+{
+ register int16_t pindex;
+
+ TRACE(stderr, "[setupPointer]");
+
+ for (pindex = 0; pindex < WINDOW; pindex++)
+ pptr[pindex] = (OPTYPE *) NULL;
+
+ nops = 0;
+ for (pindex = 0; pindex < WINDOW; pindex++)
+ {
+ switch (ptable[pindex].op)
+ {
+ /* Terminate list when a break from sequential logic is
+ * encountered
+ */
+
+ case oRET :
+ case oEND :
+ case oJMP :
+ case oLABEL :
+ case oPCAL :
+ return;
+
+ /* Terminate list when a condition break from sequential logic is
+ * encountered but include the conditional branch in the list
+ */
+
+ case oJEQUZ :
+ case oJNEQZ :
+ case oJLTZ :
+ case oJGTEZ :
+ case oJGTZ :
+ case oJLTEZ :
+ pptr[nops] = &ptable[pindex];
+ nops++;
+ return;
+
+ /* Skip over NOPs and comment class pcodes */
+
+ case oNOP :
+ case oLINE :
+ break;
+
+ /* Include all other pcodes in the optimization list and continue */
+
+ default :
+ pptr[nops] = &ptable[pindex];
+ nops++;
+ }
+ }
+}
+
+/**********************************************************************/
+
+static void initPTable(void)
+{
+ register int16_t i;
+
+ TRACE(stderr, "[intPTable]");
+
+ /* Skip over leading pcodes. NOTE: assumes executable begins after
+ * the first oLABEL pcode
+ */
+
+ do
+ {
+ insn_GetOpCode(myPoffHandle, &ptable[0]);
+
+ (void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].op);
+
+ if (ptable[0].op & o8)
+ {
+ (void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].arg1);
+ }
+
+ if (ptable[0].op & o16)
+ {
+ (void)poffAddTmpProgByte(myPoffProgHandle, (ptable[0].arg2 >> 8));
+ (void)poffAddTmpProgByte(myPoffProgHandle, (ptable[0].arg2 & 0xff));
+ } /* end if */
+ }
+ while ((ptable[0].op != oLABEL) && (ptable[0].op != oEND));
+
+ /* Fill the pcode window and setup pointers to working section */
+
+ for (i = 0; i < WINDOW; i++)
+ {
+ insn_GetOpCode(myPoffHandle, &ptable[i]);
+ }
+ setupPointer();
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/insn16/popt/polocal.h b/misc/pascal/insn16/popt/polocal.h
new file mode 100644
index 000000000..31bade3af
--- /dev/null
+++ b/misc/pascal/insn16/popt/polocal.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * polocal.h
+ * External Declarations associated with polocal.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __POLOCAL_H
+#define __POLOCAL_H
+
+/***************************************************************************
+* Included Files
+****************************************************************************/
+
+#include <stdint.h>
+#include "keywords.h"
+#include "pdefs.h"
+#include "pofflib.h"
+
+/***************************************************************************
+* Definitions
+****************************************************************************/
+
+#define WINDOW 10 /* size of optimization window */
+
+/***************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+
+extern void localOptimization(poffHandle_t poffHandle,
+ poffProgHandle_t poffProgHandle);
+extern void deletePcode (int16_t delIndex);
+extern void deletePcodePair (int16_t delIndex1, int16_t delIndex2);
+
+/***************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+extern OPTYPE ptable [WINDOW]; /* Pcode Table */
+extern OPTYPE *pptr [WINDOW]; /* Valid Pcode Pointers */
+
+extern int16_t nops; /* No. Valid Pcode Pointers */
+extern int16_t end_out; /* 1 = oEND pcode has been output */
+
+#endif /* __PLOCAL_H */
diff --git a/misc/pascal/insn16/popt/popt.c b/misc/pascal/insn16/popt/popt.c
new file mode 100644
index 000000000..2c47984f1
--- /dev/null
+++ b/misc/pascal/insn16/popt/popt.c
@@ -0,0 +1,289 @@
+/**********************************************************************
+ * popt.c
+ * P-Code Optimizer Main Logic
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "keywords.h"
+#include "podefs.h"
+#include "paslib.h"
+#include "pofflib.h"
+
+#include "pinsn.h"
+#include "popt.h"
+#include "psopt.h"
+#include "polocal.h"
+#include "pfopt.h"
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static void readPoffFile (const char *filename);
+static void pass1 (void);
+static void pass2 (void);
+static void pass3 (void);
+static void writePoffFile (const char *filename);
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static poffHandle_t poffHandle; /* Handle to POFF object */
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+int main(int argc, char *argv[], char *envp[])
+{
+ TRACE(stderr, "[main]");
+
+ /* Check for existence of filename argument */
+
+ if (argc < 2)
+ {
+ printf("Filename Required\n");
+ exit (1);
+ } /* end if */
+
+ /* Read the POFF file into memory */
+
+ readPoffFile(argv[1]);
+
+ /* Performs pass1 optimization */
+
+ pass1();
+
+ /* Performs pass2 optimization */
+
+ insn_ResetOpCodeRead(poffHandle);
+ pass2();
+
+ /* Create final section offsets and relocation entries */
+
+ insn_ResetOpCodeRead(poffHandle);
+ pass3();
+
+ /* Write the POFF file */
+
+ writePoffFile(argv[1]);
+ return 0;
+
+} /* End main */
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+static void readPoffFile(const char *filename)
+{
+ char objname [FNAME_SIZE+1];
+ FILE *objFile;
+ uint16_t errcode;
+
+ TRACE(stderr, "[readPoffFile]");
+
+ /* Open the pass1 POFF object file -- Use .o1 extension */
+
+ (void)extension(filename, "o1", objname, 1);
+ if (!(objFile = fopen(objname, "rb")))
+ {
+ printf("Error Opening %s\n", objname);
+ exit(1);
+ } /* end if */
+
+ /* Get a handle to a POFF input object */
+
+ poffHandle = poffCreateHandle();
+ if (!poffHandle)
+ {
+ printf("Could not get POFF handle\n");
+ exit(1);
+ } /* end if */
+
+ /* Read the POFF file into memory */
+
+ errcode = poffReadFile(poffHandle, objFile);
+ if (errcode != 0)
+ {
+ printf("Could not read POFF file, errcode=0x%02x\n", errcode);
+ exit(1);
+ }
+
+ /* Close the input file */
+
+ fclose(objFile);
+} /* end pass1 */
+
+/***********************************************************************/
+
+static void pass1(void)
+{
+ poffProgHandle_t poffProgHandle; /* Handle to temporary POFF object */
+
+ TRACE(stderr, "[pass1]");
+
+ /* Create a handle to a temporary object to store new POFF program
+ * data.
+ */
+
+ poffProgHandle = poffCreateProgHandle();
+ if (!poffProgHandle)
+ {
+ printf("Could not get POFF handle\n");
+ exit(1);
+ } /* end if */
+
+ /* Clean up garbage left from the wasteful string stack logic */
+
+ stringStackOptimize(poffHandle, poffProgHandle);
+
+ /* Replace the original program data with the new program data */
+
+ poffReplaceProgData(poffHandle, poffProgHandle);
+
+ /* Release the temporary POFF object */
+
+ poffDestroyProgHandle(poffProgHandle);
+} /* end pass1 */
+
+/***********************************************************************/
+
+static void pass2(void)
+{
+ poffProgHandle_t poffProgHandle; /* Handle to temporary POFF object */
+
+ TRACE(stderr, "[pass2]");
+
+ /* Create a handle to a temporary object to store new POFF program
+ * data.
+ */
+
+ poffProgHandle = poffCreateProgHandle();
+ if (!poffProgHandle)
+ {
+ printf("Could not get POFF handle\n");
+ exit(1);
+ } /* end if */
+
+ /* Perform Local Optimizatin Initialization */
+
+ localOptimization(poffHandle, poffProgHandle);
+
+ /* Replace the original program data with the new program data */
+
+ poffReplaceProgData(poffHandle, poffProgHandle);
+
+ /* Release the temporary POFF object */
+
+ poffDestroyProgHandle(poffProgHandle);
+} /* end pass2 */
+
+/***********************************************************************/
+
+static void pass3 (void)
+{
+ poffProgHandle_t poffProgHandle; /* Handle to temporary POFF object */
+ TRACE(stderr, "[pass3]");
+
+ /* Create a handle to a temporary object to store new POFF program
+ * data.
+ */
+
+ poffProgHandle = poffCreateProgHandle();
+ if (!poffProgHandle)
+ {
+ printf("Could not get POFF handle\n");
+ exit(1);
+ } /* end if */
+
+ /* Finalize program section, create relocation and line number
+ * sections.
+ */
+
+ optFinalize(poffHandle, poffProgHandle);
+
+ /* Release the temporary POFF object */
+
+ poffDestroyProgHandle(poffProgHandle);
+}
+
+/***********************************************************************/
+
+static void writePoffFile(const char *filename)
+{
+ char optname [FNAME_SIZE+1];
+ FILE *optFile;
+
+ TRACE(stderr, "[writePoffFile]");
+
+ /* Open optimized p-code file -- Use .o extension */
+
+ (void)extension(filename, "o", optname, 1);
+ if (!(optFile = fopen(optname, "wb")))
+ {
+ printf("Error Opening %s\n", optname);
+ exit(1);
+ } /* end if */
+
+ /* Then write the new POFF file */
+
+ poffWriteFile(poffHandle, optFile);
+
+ /* Destroy the POFF object */
+
+ poffDestroyHandle(poffHandle);
+
+ /* Close the files used on writePoffFile */
+
+ (void)fclose(optFile);
+} /* end writePoffFile */
+
+/***********************************************************************/
diff --git a/misc/pascal/insn16/popt/popt.h b/misc/pascal/insn16/popt/popt.h
new file mode 100644
index 000000000..a3530f75d
--- /dev/null
+++ b/misc/pascal/insn16/popt/popt.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * popt.h
+ * External Declarations associated with popt.c
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __POPT_H
+#define __POPT_H
+
+/***************************************************************************
+* Included Files
+****************************************************************************/
+
+/***************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+
+/***************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+#endif /* __POPT_H */
diff --git a/misc/pascal/insn16/popt/psopt.c b/misc/pascal/insn16/popt/psopt.c
new file mode 100644
index 000000000..0f6a4952e
--- /dev/null
+++ b/misc/pascal/insn16/popt/psopt.c
@@ -0,0 +1,387 @@
+/**********************************************************************
+ * psopt.c
+ * String Stack Optimizaitons
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/* The statement generation logic generates a PUSHS and POPS around
+ * every statement. These instructions save and restore the string
+ * stack pointer registers. However, only some statements actually
+ * modify the string stack. So the first major step in the optimatization
+ * process is to retain only PUSHS and POPS statements that are
+ * actually required.
+ */
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pedefs.h"
+#include "pinsn16.h"
+#include "pxdefs.h"
+
+#include "popt.h"
+#include "psopt.h"
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+#define PBUFFER_SIZE 1024
+#define NPBUFFERS 8
+
+/**********************************************************************
+ * Private Data
+ **********************************************************************/
+
+static uint8_t *pbuffer[NPBUFFERS];
+static int nbytes_in_pbuffer[NPBUFFERS];
+static int current_level = -1;
+static int inch;
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static inline void putbuf(int c, poffProgHandle_t poffProgHandle);
+static inline void flushc(int c, poffProgHandle_t poffProgHandle);
+static inline void flushbuf(poffProgHandle_t poffProgHandle);
+static void dopush(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle);
+static void dopop(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle);
+
+/**********************************************************************
+ * Private Inline Functions
+ **********************************************************************/
+
+static inline void putbuf(int c, poffProgHandle_t poffProgHandle)
+{
+ int dlvl = current_level;
+
+ if (dlvl < 0)
+ {
+ /* No PUSHS encountered. Write byte directly to output */
+
+ poffAddTmpProgByte(poffProgHandle, (uint8_t)c);
+ }
+ else
+ {
+ /* PUSHS encountered. Write byte into buffer associated with
+ * nesting level.
+ */
+
+ int idx = nbytes_in_pbuffer[dlvl];
+ uint8_t *dest = pbuffer[dlvl] + idx;
+ *dest = c;
+ nbytes_in_pbuffer[dlvl] = idx + 1;
+ }
+}
+
+static inline void flushc(int c, poffProgHandle_t poffProgHandle)
+{
+ if (current_level > 0)
+ {
+ /* Nested PUSHS encountered. Write byte into buffer associated
+ * with the previous nesting level.
+ */
+
+ int dlvl = current_level - 1;
+ int idx = nbytes_in_pbuffer[dlvl];
+ uint8_t *dest = pbuffer[dlvl] + idx;
+ *dest = c;
+ nbytes_in_pbuffer[dlvl] = idx + 1;
+ }
+ else
+ {
+ /* Only one PUSHS encountered. Write directly to the output
+ * buffer
+ */
+
+ poffAddTmpProgByte(poffProgHandle, (uint8_t)c);
+ }
+}
+
+static inline void flushbuf(poffProgHandle_t poffProgHandle)
+{
+ uint16_t errCode;
+ int slvl = current_level;
+
+ if (nbytes_in_pbuffer[slvl] > 0)
+ {
+ if (current_level > 0)
+ {
+ /* Nested PUSHS encountered. Flush buffer into buffer associated
+ * with the previous nesting level.
+ */
+
+ int dlvl = slvl - 1;
+ uint8_t *src = pbuffer[slvl];
+ uint8_t *dest = pbuffer[dlvl] + nbytes_in_pbuffer[dlvl];
+
+ memcpy(dest, src, nbytes_in_pbuffer[slvl]);
+ nbytes_in_pbuffer[dlvl] += nbytes_in_pbuffer[slvl];
+ }
+ else
+ {
+ /* Only one PUSHS encountered. Flush directly to the output
+ * buffer
+ */
+
+ errCode = poffWriteTmpProgBytes(pbuffer[0], nbytes_in_pbuffer[0],
+ poffProgHandle);
+
+ if (errCode != eNOERROR)
+ {
+ printf("Error writing to file: %d\n", errCode);
+ exit(1);
+ }
+ }
+ }
+ nbytes_in_pbuffer[slvl] = 0;
+}
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+static void dopush(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ int opcode;
+
+ while (inch != EOF)
+ {
+ /* Search for a PUSHS opcode */
+
+ if (inch != oPUSHS)
+ {
+ /* Its not PUSHS, just echo to the output file/buffer */
+
+ putbuf(inch, poffProgHandle);
+
+ /* Get the next byte from the input stream */
+
+ opcode = inch;
+ inch = poffGetProgByte(poffHandle);
+
+ /* Check for an 8-bit argument */
+
+ if ((opcode & o8) != 0)
+ {
+ /* Echo the 8-bit argument */
+
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ }
+
+ /* Check for a 16-bit argument */
+
+ if ((opcode & o16) != 0)
+ {
+ /* Echo the 16-bit argument */
+
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ }
+ }
+ else
+ {
+ /* We have found PUSHS. No search for the next occurrence
+ * of either and instruction that increments the string
+ * stack or for the matching POPS
+ */
+
+ current_level++;
+ dopop(poffHandle, poffProgHandle);
+ current_level--;
+ }
+ }
+}
+
+static void dopop(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ int opcode;
+ int arg16;
+ int arg16a;
+ int arg16b;
+
+ /* We have found PUSHS. No search for the next occurrence
+ * of either and instruction that increments the string
+ * stack or for the matching POPS
+ */
+
+ /* Skip over the PUSHS for now */
+
+ inch = poffGetProgByte(poffHandle);
+
+ while (inch != EOF)
+ {
+ /* Did we encounter another PUSHS? */
+
+ if (inch == oPUSHS)
+ {
+ /* Yes... recurse to handle it */
+
+ current_level++;
+ dopop(poffHandle, poffProgHandle);
+ current_level--;
+ }
+
+ else if (inch == oPOPS)
+ {
+ /* Flush the buffered data without the PUSHS */
+
+ flushbuf(poffProgHandle);
+
+ /* And discard the matching POPS */
+
+ inch = poffGetProgByte(poffHandle);
+ break;
+ }
+ else if (inch == oLIB)
+ {
+ /* Get the 16-bit argument */
+
+ putbuf(inch, poffProgHandle);
+ arg16a = poffGetProgByte(poffHandle);
+ putbuf(arg16a, poffProgHandle);
+ arg16b = poffGetProgByte(poffHandle);
+ putbuf(arg16b, poffProgHandle);
+ arg16 = (arg16a << 8) | arg16b;
+ inch = poffGetProgByte(poffHandle);
+
+ /* Is it LIB MKSTK? MKSTKSTR? or MKSTKC? */
+
+ if ((arg16 == lbMKSTK) ||
+ (arg16 == lbMKSTKSTR) ||
+ (arg16 == lbMKSTKC))
+ {
+ /* Flush the buffered data with the PUSHS */
+
+ flushc(oPUSHS, poffProgHandle);
+ flushbuf(poffProgHandle);
+
+ /* And break out of the loop to search for
+ * the next PUSHS
+ */
+
+ break;
+ }
+ }
+ else
+ {
+ /* Something else. Put it in the buffer */
+
+ putbuf(inch, poffProgHandle);
+
+ /* Get the next byte from the input stream */
+
+ opcode = inch;
+ inch = poffGetProgByte(poffHandle);
+
+ /* Check for an 8-bit argument */
+
+ if ((opcode & o8) != 0)
+ {
+ /* Buffer the 8-bit argument */
+
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ }
+
+ /* Check for a 16-bit argument */
+
+ if ((opcode & o16) != 0)
+ {
+ /* Buffer the 16-bit argument */
+
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ }
+ }
+ }
+}
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+void stringStackOptimize(poffHandle_t poffHandle,
+ poffProgHandle_t poffProgHandle)
+{
+ int i;
+
+ /* Allocate an array of buffers to hold pcode data */
+
+ for (i = 0; i < NPBUFFERS; i++)
+ {
+ pbuffer[i] = (uint8_t*)malloc(PBUFFER_SIZE);
+ if (pbuffer[i] == NULL)
+ {
+ printf("Failed to allocate pcode buffer\n");
+ exit(1);
+ }
+ nbytes_in_pbuffer[i] = 0;
+ }
+
+ /* Prime the search logic */
+
+ inch = poffGetProgByte(poffHandle);
+ current_level = -1;
+
+ /* And parse the input file to the output file, removing unnecessary string
+ * stack operations.
+ */
+
+ dopush(poffHandle, poffProgHandle);
+
+ /* Release the buffers */
+
+ for (i = 0; i < NPBUFFERS; i++)
+ {
+ free(pbuffer[i]);
+ pbuffer[i] = NULL;
+ nbytes_in_pbuffer[i] = 0;
+ }
+}
+
+/**********************************************************************/
diff --git a/misc/pascal/insn16/popt/psopt.h b/misc/pascal/insn16/popt/psopt.h
new file mode 100644
index 000000000..3ea1ee227
--- /dev/null
+++ b/misc/pascal/insn16/popt/psopt.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * psopt.h
+ * External Declarations associated with psopt.c
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PSOPT_H
+#define __PSOPT_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include "pofflib.h"
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void stringStackOptimize(poffHandle_t poffHandle,
+ poffProgHandle_t poffProgHandle);
+
+#endif /* __PSOPT_H */
+
diff --git a/misc/pascal/insn16/prun/Make.defs b/misc/pascal/insn16/prun/Make.defs
new file mode 100644
index 000000000..1e965e1f7
--- /dev/null
+++ b/misc/pascal/insn16/prun/Make.defs
@@ -0,0 +1,38 @@
+############################################################################
+# insn16/prun/Make.defs
+# NuttX runtime makefile fragment
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+PRUN_ASRCS =
+PRUN_CSRCS = pload.c pexec.c
diff --git a/misc/pascal/insn16/prun/Makefile b/misc/pascal/insn16/prun/Makefile
new file mode 100644
index 000000000..b8fb4d98b
--- /dev/null
+++ b/misc/pascal/insn16/prun/Makefile
@@ -0,0 +1,87 @@
+############################################################################
+# insn16/prun/Makefile
+# Host system makefile
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Directories
+#
+PRUNDIR = ${shell pwd}
+INSNDIR = $(PRUNDIR)/..
+PASCAL = $(PRUNDIR)/../..
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+INCDIR = $(PASCAL)/include
+LIBDIR = $(PASCAL)/lib
+BINDIR = $(PASCAL)/bin16
+
+#
+# Tools
+#
+EXTRA_INCLUDES = -I$(INSNDIR)/include
+INCLUDES += $(EXTRA_INCLUDES)
+CFLAGS += $(EXTRA_INCLUDES)
+
+#
+# Objects and targets
+#
+RUNSRCS = prun.c pdbg.c pload.c pexec.c
+RUNOBJS = $(RUNSRCS:.c=.o)
+
+OBJS = $(RUNOBJS)
+
+all: prun
+.PHONY: all prun clean
+
+$(OBJS): %.o: %.c
+ @$(CC) -c $(CFLAGS) $< -o $@
+
+check_libs:
+ @if [ ! -f $(LIBDIR)/libpoff.a ] ; then \
+ echo "$(LIBDIR)/libpoff.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libpas.a ] ; then \
+ echo "$(LIBDIR)/libpas.a does not exist" ; \
+ exit 1 ; \
+ fi
+
+$(BINDIR)/prun: check_libs $(RUNOBJS)
+ @$(CC) -o $@ $(LDFLAGS) $(RUNOBJS) -linsn -lpoff -lpas -lm
+
+prun: $(BINDIR)/prun
+
+clean:
+ $(RM) prun *.o core *~
diff --git a/misc/pascal/insn16/prun/pdbg.c b/misc/pascal/insn16/prun/pdbg.c
new file mode 100644
index 000000000..d941ebb6f
--- /dev/null
+++ b/misc/pascal/insn16/prun/pdbg.c
@@ -0,0 +1,748 @@
+/**********************************************************************
+ * pdbg.c
+ * P-Code Debugger
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <ctype.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "podefs.h"
+#include "pinsn16.h"
+#include "pxdefs.h"
+#include "pedefs.h"
+
+#include "paslib.h"
+#include "pinsn.h"
+#include "pexec.h"
+#include "pdbg.h"
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+#define TRACE_ARRAY_SIZE 16
+#define MAX_BREAK_POINTS 8
+#define DISPLAY_STACK_SIZE 16
+#define DISPLAY_INST_SIZE 16
+
+/**********************************************************************
+ * Private Type Definitions
+ **********************************************************************/
+
+enum command_e
+{
+ eCMD_NONE = 0,
+ eCMD_RESET,
+ eCMD_RUN,
+ eCMD_STEP,
+ eCMD_NEXT,
+ eCMD_GO,
+ eCMD_BS,
+ eCMD_BC,
+ eCMD_DP,
+ eCMD_DT,
+ eCMD_DS,
+ eCMD_DI,
+ eCMD_DB,
+ eCMD_HELP,
+ eCMD_QUIT
+};
+
+struct trace_s
+{
+ paddr_t pc;
+ paddr_t sp;
+ ustack_t tos;
+};
+typedef struct trace_s trace_t;
+
+/**********************************************************************
+ * Private Constant Data
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Data
+ **********************************************************************/
+
+static enum command_e g_lastcmd = eCMD_NONE;
+static uint32_t g_lastvalue;
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static void pdbg_showcommands(void);
+static void pdbg_execcommand(struct pexec_s *st, enum command_e cmd, uint32_t value);
+static int32_t pdbg_readdecimal(char *ptr);
+static int32_t pdbg_readhex(char *ptr, int32_t defaultvalue);
+static void pdbg_programstatus(struct pexec_s *st);
+static paddr_t pdbg_printpcode(struct pexec_s *st, paddr_t pc, int16_t nitems);
+static paddr_t pdbg_printstack(struct pexec_s *st, paddr_t sp, int16_t nitems);
+static void pdbg_printregisters(struct pexec_s *st);
+static void pdbg_printtracearray(struct pexec_s *st);
+static void pdbg_addbreakpoint(paddr_t pc);
+static void pdbg_deletebreakpoint(int16_t bpno);
+static void pdbg_printbreakpoints(struct pexec_s *st);
+static void pdbg_checkbreakpoint(struct pexec_s *st);
+static void pdbg_initdebugger(void);
+static void pdbg_debugpcode(struct pexec_s *st);
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/* Debugging variables */
+
+static trace_t g_tracearray[TRACE_ARRAY_SIZE];
+ /* Holds execution histor */
+static uint16_t g_tracendx;
+ /* This is the index into the circular g_tracearray */
+static uint16_t g_ntracepoints;
+ /* This is the number of valid enties in g_tracearray */
+static paddr_t g_breakpoint[MAX_BREAK_POINTS];
+ /* Contains address associated with all active */
+ /* break points. */
+static paddr_t g_untilpoint;
+ /* The 'g_untilpoint' is a temporary breakpoint */
+static uint16_t g_nbreakpoints;
+ /* Number of items in breakPoints[] */
+static paddr_t g_displayloc;
+ /* P-code display location display */
+static bool g_bstopexecution;
+ /* true means to stop program execution */
+
+/* I/O variables */
+
+static char g_inline[LINE_SIZE+1];
+ /* Command line buffer */
+
+/**********************************************************************
+ * Public Functions
+ **********************************************************************/
+
+void dbg_run(struct pexec_s *st)
+{
+ paddr_t pc;
+ int i;
+
+ pdbg_showcommands();
+ pdbg_initdebugger();
+ pdbg_programstatus(st);
+
+ while (true)
+ {
+ printf("CMD: ");
+ (void) fgets(g_inline, LINE_SIZE, stdin);
+ switch (toupper(g_inline[0]))
+ {
+ case 'R' :
+ switch (toupper(g_inline[1])) {
+ case 'E' : /* Reset */
+ pdbg_execcommand(st, eCMD_RESET, 0);
+ break;
+ case 'U' : /* Run */
+ pdbg_execcommand(st, eCMD_RUN, 0);
+ break;
+ default :
+ printf("Unrecognized Command\n");
+ pdbg_execcommand(st, eCMD_HELP, 0);
+ break;
+ } /* end switch */
+ break;
+ case 'S' : /* Single Step (into) */
+ pdbg_execcommand(st, eCMD_STEP, 0);
+ break;
+ case 'N' : /* Single Step (over) */
+ pdbg_execcommand(st, eCMD_NEXT, 0);
+ break;
+ case 'G' : /* Go */
+ pdbg_execcommand(st, eCMD_GO, 0);
+ break;
+ case 'B' :
+ switch (toupper(g_inline[1])) {
+ case 'S' : /* Set Breakpoint */
+ pc = pdbg_readhex(&g_inline[2], st->pc);
+ pdbg_execcommand(st, eCMD_BS, pc);
+ break;
+ case 'C' : /* Clear Breakpoint */
+ i = pdbg_readdecimal(&g_inline[2]);
+ pdbg_execcommand(st, eCMD_BC, i);
+ break;
+ default :
+ printf("Unrecognized Command\n");
+ pdbg_execcommand(st, eCMD_HELP, 0);
+ break;
+ } /* end switch */
+ break;
+ case 'D' :
+ switch (toupper(g_inline[1])) {
+ case 'P' : /* Display Program Status */
+ pdbg_execcommand(st, eCMD_DP, 0);
+ break;
+ case 'T' : /* Display Program Trace */
+ pdbg_execcommand(st, eCMD_DT, 0);
+ break;
+ case 'S' : /* Display Stack */
+ pc = pdbg_readhex(&g_inline[2], st->sp);
+ pdbg_execcommand(st, eCMD_DS, pc);
+ break;
+ case 'I' : /* Display Instructions */
+ pc = pdbg_readhex(&g_inline[2], st->pc);
+ pdbg_execcommand(st, eCMD_DI, pc);
+ break;
+ case 'B' : /* Display Breakpoints */
+ pdbg_execcommand(st, eCMD_DB, pc);
+ break;
+ default :
+ printf("Unrecognized Command\n");
+ pdbg_execcommand(st, eCMD_HELP, 0);
+ break;
+ } /* end switch */
+ break;
+ case 'Q' : /* Quit */
+ pdbg_execcommand(st, eCMD_QUIT, pc);
+ break;
+ case 'H' : /* Help */
+ case '?' :
+ pdbg_execcommand(st, eCMD_HELP, 0);
+ break;
+ case '\0' : /* Repeat last command */
+ case '\n' : /* Repeat last command */
+ pdbg_execcommand(st, g_lastcmd, g_lastvalue);
+ break;
+ default :
+ printf("Unrecognized Command\n");
+ pdbg_execcommand(st, eCMD_HELP, 0);
+ break;
+ } /* end switch */
+ } /* end while */
+
+} /* end pdbg_debugpcodeProgram */
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+/* Show command characters */
+
+static void pdbg_showcommands(void)
+{
+ printf("Commands:\n");
+ printf(" RE[set] - Reset\n");
+ printf(" RU[n] - Run\n");
+ printf(" S[tep] - Single Step (Into)\n");
+ printf(" N[ext] - Single Step (Over)\n");
+ printf(" G[o] - Go\n");
+ printf(" BS xxxx - Set Breakpoint\n");
+ printf(" BC n - Clear Breakpoint\n");
+ printf(" DP - Display Program Status\n");
+ printf(" DT - Display Program Trace\n");
+ printf(" DS [xxxx] - Display Stack\n");
+ printf(" DI [xxxx] - Display Instructions\n");
+ printf(" DB - Display Breakpoints\n");
+ printf(" H or ? - Shows this list\n");
+ printf(" Q[uit] - Quit\n");
+
+} /* end pdbg_showcommands */
+
+/***********************************************************************/
+static void pdbg_execcommand(struct pexec_s *st, enum command_e cmd, uint32_t value)
+{
+ /* Save the command to resuse if the user enters nothing */
+
+ g_lastcmd = cmd;
+ g_lastvalue = value;
+
+ switch (cmd)
+ {
+ case eCMD_NONE: /* Do nothing */
+ break;
+ case eCMD_RESET: /* Reset */
+ pexec_reset(st);
+ pdbg_initdebugger();
+ pdbg_programstatus(st);
+ g_lastcmd = eCMD_NONE;
+ break;
+ case eCMD_RUN: /* Run */
+ pexec_reset(st);
+ pdbg_initdebugger();
+ pdbg_debugpcode(st);
+ pdbg_programstatus(st);
+ break;
+ case eCMD_STEP: /* Single Step (into)*/
+ g_bstopexecution = true;
+ pdbg_debugpcode(st);
+ pdbg_programstatus(st);
+ break;
+ case eCMD_NEXT: /* Single Step (over) */
+ if (st->ispace[st->pc] == oPCAL)
+ {
+ g_bstopexecution = false;
+ g_untilpoint = st->pc + 4;
+ }
+ else
+ {
+ g_bstopexecution = true;
+ }
+ pdbg_debugpcode(st);
+ g_untilpoint = 0;
+ pdbg_programstatus(st);
+ break;
+ case eCMD_GO: /* Go */
+ g_bstopexecution = false;
+ pdbg_debugpcode(st);
+ pdbg_programstatus(st);
+ break;
+ case eCMD_BS: /* Set Breakpoint */
+ if (g_nbreakpoints >= MAX_BREAK_POINTS)
+ {
+ printf("Too many breakpoints\n");
+ g_lastcmd = eCMD_NONE;
+ }
+ else if (value >= st->maxpc)
+ {
+ printf("Invalid address for breakpoint\n");
+ g_lastcmd = eCMD_NONE;
+ }
+ else
+ {
+ pdbg_addbreakpoint(value);
+ pdbg_printbreakpoints(st);
+ } /* end else */
+ break;
+ case eCMD_BC: /* Clear Breakpoint */
+ if ((value >= 1) && (value <= g_nbreakpoints))
+ {
+ pdbg_deletebreakpoint(value);
+ }
+ else
+ {
+ printf("Invalid breakpoint number\n");
+ g_lastcmd = eCMD_NONE;
+ }
+ pdbg_printbreakpoints(st);
+ break;
+ case eCMD_DP: /* Display Program Status */
+ pdbg_programstatus(st);
+ break;
+ case eCMD_DT: /* Display Program Trace */
+ pdbg_printtracearray(st);
+ break;
+ case eCMD_DS: /* Display Stack */
+ if (value > st->sp)
+ {
+ printf("Invalid stack address\n");
+ g_lastcmd = eCMD_NONE;
+ }
+ else
+ {
+ g_lastvalue = pdbg_printstack(st, value, DISPLAY_STACK_SIZE);
+ } /* end else */
+ break;
+ case eCMD_DI: /* Display Instructions */
+ if (value >= st->maxpc)
+ {
+ printf("Invalid instruction address\n");
+ g_lastcmd = eCMD_NONE;
+ }
+ else
+ {
+ g_lastvalue = pdbg_printpcode(st, value, DISPLAY_INST_SIZE);
+ } /* end else */
+ break;
+ case eCMD_DB: /* Display Breakpoints */
+ pdbg_printbreakpoints(st);
+ break;
+ case eCMD_QUIT: /* Quit */
+ printf("Goodbye\n");
+ exit(0);
+ break;
+ case eCMD_HELP: /* Help */
+ default: /* Internal error */
+ pdbg_showcommands();
+ g_lastcmd = eCMD_NONE;
+ break;
+ } /* end switch */
+
+} /* end pdbg_execcommand */
+
+/***********************************************************************/
+/* Read a decimal value from the input string */
+
+static int32_t pdbg_readdecimal(char *ptr)
+{
+ int32_t decimal = 0;
+
+ while (!isspace(*ptr)) ptr++;
+ while (isspace(*ptr)) ptr++;
+ for (; ((*ptr >= '0') && (*ptr <= '9')); ptr++)
+ decimal = 10*decimal + (int32_t)*ptr - (int32_t)'0';
+
+ return decimal;
+
+} /* end pdbg_readdecimal */
+/***********************************************************************/
+/* Read a hexadecimal value from the input string */
+
+static int32_t pdbg_readhex(char *ptr, int32_t defaultvalue)
+{
+ char c;
+ int32_t hex = 0;
+ bool found = false;
+
+ while (!isspace(*ptr)) ptr++;
+ while (isspace(*ptr)) ptr++;
+ while (true) {
+
+ c = toupper(*ptr);
+ if ((c >= '0') && (c <= '9')) {
+ hex = ((hex << 4) | ((int32_t)c - (int32_t)'0'));
+ found = true;
+ } /* end if */
+ else if ((c >= 'A') && (c <= 'F')) {
+ hex = ((hex << 4) | ((int32_t)c - (int32_t)'A' + 10));
+ found = true;
+ } /* end else if */
+ else {
+ if (found)
+ return hex;
+ else
+ return defaultvalue;
+ } /* end else */
+ ptr++;
+
+ } /* end while */
+
+} /* end pdbg_readhex */
+
+/***********************************************************************/
+/* Print the disassembled P-Code at PC */
+
+static void pdbg_programstatus(struct pexec_s *st)
+{
+ (void)pdbg_printpcode(st, st->pc, 1);
+ (void)pdbg_printstack(st, st->sp, 2);
+ pdbg_printregisters(st);
+
+} /* end pdbg_programstatus */
+
+/***********************************************************************/
+/* Print the disassembled P-Code at PC */
+
+static paddr_t pdbg_printpcode(struct pexec_s *st, paddr_t pc, int16_t nitems)
+{
+ OPTYPE op;
+ paddr_t opsize;
+ uint8_t *address;
+
+ for (; ((pc < st->maxpc) && (nitems > 0)); nitems--)
+ {
+ address = &st->ispace[pc];
+
+ op.op = *address++;
+ op.arg1 = 0;
+ op.arg2 = 0;
+ opsize = 1;
+ printf("PC:%04x %02x", pc, op.op);
+
+ if ((op.op & o8) != 0)
+ {
+ op.arg1 = *address++;
+ printf("%02x", op.arg1);
+ opsize++;
+ } /* end if */
+ else
+ printf("..");
+
+ if ((op.op & o16) != 0)
+ {
+ op.arg2 = ((*address++) << 8);
+ op.arg2 |= *address++;
+ printf("%04x", op.arg2);
+ opsize += 2;
+ } /* end if */
+ else
+ printf("....");
+
+ /* The disassemble it to stdout */
+
+ printf(" ");
+ insn_DisassemblePCode(stdout, &op);
+
+ /* Get the address of the next P-Code */
+
+ pc += opsize;
+
+ } /* end for */
+
+ return pc;
+
+} /* end pdbg_printpcode */
+
+/***********************************************************************/
+/* Print the stack value at SP */
+
+static paddr_t pdbg_printstack(struct pexec_s *st, paddr_t sp, int16_t nitems)
+{
+ int32_t isp;
+
+ if ((st->sp < st->stacksize) && (sp <= st->sp))
+ {
+ isp = BTOISTACK(sp);
+ printf("SP:%04x %04x\n", sp, st->dstack.i[isp]);
+
+ for (isp--, sp -= BPERI, nitems--;
+ ((isp >= 0) && (nitems > 0));
+ isp--, sp -= BPERI, nitems--)
+ printf(" %04x %04x\n", sp, st->dstack.i[isp] & 0xffff);
+ } /* end if */
+ else
+ {
+ printf("SP:%04x BAD\n", sp);
+ } /* end else */
+
+ return sp;
+} /* end pdbg_printstack */
+
+/***********************************************************************/
+/* Print the base register */
+
+static void pdbg_printregisters(struct pexec_s *st)
+{
+ if (st->fp <= st->sp)
+ printf("FP:%04x ", st->fp);
+
+ printf("CSP:%04x\n", st->csp);
+
+} /* end pdbg_printregisters */
+
+/***********************************************************************/
+/* Print the g_tracearray */
+
+static void pdbg_printtracearray(struct pexec_s *st)
+{
+ int nprinted;
+ int index;
+
+ index = g_tracendx + TRACE_ARRAY_SIZE - g_ntracepoints;
+ if (index >= TRACE_ARRAY_SIZE)
+ index -= TRACE_ARRAY_SIZE;
+
+ for (nprinted = 0; nprinted < g_ntracepoints; nprinted++) {
+
+ printf("SP:%04x %04x ",
+ g_tracearray[ index ].sp, g_tracearray[ index ].tos);
+
+ /* Print the instruction executed at this traced address */
+ (void)pdbg_printpcode(st, g_tracearray[ index ].pc, 1);
+
+ /* Index to the next trace entry */
+ if (++index >= TRACE_ARRAY_SIZE)
+ index = 0;
+
+ } /* end for */
+
+} /* end pdbg_printtracearray */
+
+/***********************************************************************/
+/* Add a breakpoint to the breakpoint array */
+
+static void pdbg_addbreakpoint(paddr_t pc)
+{
+ int i;
+
+ /* Is there room for another breakpoint? */
+
+ if (g_nbreakpoints < MAX_BREAK_POINTS)
+ {
+ /* Yes..Check if the breakpoint already exists */
+
+ for (i = 0; i < g_nbreakpoints; i++)
+ {
+ if (g_breakpoint[i] == pc)
+ {
+ /* It is already set. Return without doing anything */
+
+ return;
+ }
+ }
+
+ /* The breakpoint is not already set -- set it */
+
+ g_breakpoint[g_nbreakpoints++] = pc;
+ } /* end if */
+
+} /* end pdbg_addbreakpoint */
+
+/***********************************************************************/
+/* Remove a breakpoint from the breakpoint array */
+
+static void pdbg_deletebreakpoint(int16_t bpno)
+{
+ if ((bpno >= 1) && (bpno <= g_nbreakpoints)) {
+
+ for (; (bpno < g_nbreakpoints); bpno++)
+ g_breakpoint[bpno-1] = g_breakpoint[bpno];
+
+ g_nbreakpoints--;
+
+ } /* end if */
+
+} /* end pdbg_deletebreakpoint */
+
+/***********************************************************************/
+/* Print the breakpoint array */
+
+static void pdbg_printbreakpoints(struct pexec_s *st)
+{
+ int i;
+
+ printf("BP:# Address P-Code\n");
+ for (i = 0; i < g_nbreakpoints; i++)
+ {
+ printf("BP:%d ", (i+1));
+ (void)pdbg_printpcode(st, g_breakpoint[i], 1);
+ } /* end for */
+
+} /* end pdbg_printbreakpoints */
+
+/***********************************************************************/
+/* Check if a breakpoint is set at the current value of program counter.
+ * If so, print the instruction and stop execution. */
+
+static void pdbg_checkbreakpoint(struct pexec_s *st)
+{
+ uint16_t bpIndex;
+
+ /* Check for a user breakpoint */
+
+ for (bpIndex = 0;
+ ((bpIndex < g_nbreakpoints) && (!g_bstopexecution));
+ bpIndex++)
+ {
+ if (g_breakpoint[bpIndex] == st->pc)
+ {
+ printf("Breakpoint #%d -- Execution Stopped\n", (bpIndex+1));
+ g_bstopexecution = true;
+ return;
+ } /* end if */
+ } /* end for */
+
+} /* end pdbg_checkbreakpoint */
+
+/***********************************************************************/
+/* Initialize Debugger variables */
+
+static void pdbg_initdebugger(void)
+{
+ g_bstopexecution = false;
+ g_displayloc = 0;
+ g_tracendx = 0;
+ g_ntracepoints = 0;
+}
+
+/***********************************************************************/
+/* This function executes the P-Code program until a stopping condition
+ * is encountered. */
+
+static void pdbg_debugpcode(struct pexec_s *st)
+{
+ uint16_t errno;
+
+ do {
+ /* Trace the next instruction execution */
+
+ g_tracearray[g_tracendx].pc = st->pc;
+ g_tracearray[g_tracendx].sp = st->sp;
+ if (st->sp < st->stacksize)
+ g_tracearray[g_tracendx].tos = st->dstack.i[BTOISTACK(st->sp)];
+ else
+ g_tracearray[g_tracendx].tos = 0;
+
+ if (++g_tracendx >= TRACE_ARRAY_SIZE)
+ g_tracendx = 0;
+ if (g_ntracepoints < TRACE_ARRAY_SIZE)
+ g_ntracepoints++;
+
+ /* Execute the instruction */
+
+ errno = pexec(st);
+
+ /* Check for exceptional stopping conditions */
+
+ if (errno != eNOERROR)
+ {
+ if (errno == eEXIT)
+ printf("Normal Termination\n");
+ else
+ printf("Runtime error 0x%02x -- Execution Stopped\n", errno);
+ g_bstopexecution = true;
+ } /* end if */
+
+ /* Check for normal stopping conditions */
+
+ if (!g_bstopexecution)
+ {
+ /* Check for attempt to execute code outside of legal range */
+
+ if (st->pc >= st->maxpc)
+ g_bstopexecution = true;
+
+ /* Check for a temporary breakpoint */
+
+ else if ((g_untilpoint > 0) && (g_untilpoint == st->pc))
+ g_bstopexecution = true;
+
+ /* Check if there is a breakpoint at the next instruction */
+
+ else if (g_nbreakpoints > 0)
+ pdbg_checkbreakpoint(st);
+ }
+
+ } while (!g_bstopexecution);
+
+} /* end pdbg_debugpcode */
diff --git a/misc/pascal/insn16/prun/pexec.c b/misc/pascal/insn16/prun/pexec.c
new file mode 100644
index 000000000..b22e52835
--- /dev/null
+++ b/misc/pascal/insn16/prun/pexec.c
@@ -0,0 +1,2375 @@
+/****************************************************************************
+ * pexec.c
+ *
+ * Copyright (C) 200-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pinsn16.h"
+#include "pfdefs.h"
+#include "pxdefs.h"
+#include "pedefs.h"
+
+#include "paslib.h"
+#include "pexec.h"
+
+#ifdef CONFIG_HAVE_LIBM
+#include <math.h>
+#endif
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+#define PTRUE ((ustack_t)-1)
+#define PFALSE ((ustack_t) 0)
+
+/****************************************************************************
+ * Macros
+ ****************************************************************************/
+
+/* Remove the value from the top of the stack */
+
+#define POP(st, dest) \
+ do { \
+ dest = (st)->dstack.i[BTOISTACK((st)->sp)]; \
+ (st)->sp -= BPERI; \
+ } while (0)
+
+/* Add the value to top of the stack */
+
+#define PUSH(st, src) \
+ do { \
+ (st)->sp += BPERI; \
+ (st)->dstack.i[BTOISTACK((st)->sp)] = src; \
+ } while (0)
+
+/* Return an rvalue for the (word) offset from the top of the stack */
+
+#define TOS(st, off) \
+ (st)->dstack.i[BTOISTACK((st)->sp)-(off)]
+
+/* Save the src (word) at the dest (word) stack position */
+
+#define PUTSTACK(st, src, dest) \
+ do { \
+ (st)->dstack.i[BTOISTACK(dest)] = src; \
+ } while (0)
+
+/* Return an rvalue for the (word) from the absolute stack position */
+
+#define GETSTACK(st, src) \
+ (st)->dstack.i[BTOISTACK(src)]
+
+/* Store a byte to an absolute (byte) stack position */
+
+#define PUTBSTACK(st, src,dest) \
+ do { \
+ (st)->dstack.b[dest] = dest; \
+ } while (0)
+
+/* Return an rvalue for the absolute (byte) stack position */
+
+#define GETBSTACK(st, src) \
+ (st)->dstack.b[src]
+
+/* Return the address for an absolute (byte) stack position. */
+
+#define ATSTACK(st, src) \
+ &(st)->dstack.b[src]
+
+/* Discard n words from the top of the stack */
+
+#define DISCARD(st, n) \
+ do { \
+ (st)->sp -= BPERI*(n); \
+ } while (0)
+
+/* Release a C string */
+
+#define free_cstring(a) \
+ free(a)
+
+/****************************************************************************
+ * Private Type Definitions
+ ****************************************************************************/
+
+union fparg_u
+{
+ double f;
+ uint16_t hw[4];
+};
+
+typedef union fparg_u fparg_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static uint16_t pexec_sysio(struct pexec_s *st, uint8_t fno, uint16_t subfunc);
+static uint16_t pexec_libcall(struct pexec_s *st, uint16_t subfunc);
+static uint16_t pexec_execfp(struct pexec_s *st, uint8_t fpop);
+static void pexec_getfparguments(struct pexec_s *st, uint8_t fpop, fparg_t *arg1, fparg_t *arg2);
+static ustack_t pexec_readinteger(uint8_t *ioptr);
+static void pexec_readreal(uint16_t *dest, uint8_t *ioptr);
+static ustack_t pexec_getbaseaddress(struct pexec_s *st, level_t leveloffset);
+static uint8_t *pexec_mkcstring(uint8_t *buffer, int buflen);
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+static uint8_t ioline[LINE_SIZE+1];
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pexec_sysio
+ *
+ * Description:
+ * This function process a system I/O operation.
+ *
+ ****************************************************************************/
+
+static uint16_t pexec_sysio(struct pexec_s *st, uint8_t fno, uint16_t subfunc)
+{
+ ustack_t uparm1;
+ fparg_t fp;
+
+ uint8_t *ptr;
+
+ switch (subfunc)
+ {
+ case xEOF :
+/* FINISH ME -- > */
+ break;
+ case xEOLN :
+/* FINISH ME -- > */
+ break;
+ case xRESET :
+/* FINISH ME -- > */
+ break;
+ case xREWRITE :
+/* FINISH ME -- > */
+ break;
+
+ case xREADLN :
+/* FINISH ME -- > */
+ break;
+ case xREAD_BINARY :
+/* FINISH ME -- > */
+ break;
+
+ /* xREAD_INT:
+ * STACK INPUTS: TOS(st, 0) = address to store integer */
+ case xREAD_INT :
+ (void)fgets((char*)ioline, LINE_SIZE, stdin);
+ PUTSTACK(st, pexec_readinteger(ioline),TOS(st, 0));
+ break;
+
+ /* xREAD_CHAR:
+ * STACK INPUTS: TOS(st, 0) = address to store integer */
+
+ case xREAD_CHAR:
+ (void)fgets((char*)ioline, LINE_SIZE, stdin);
+ PUTBSTACK(st, ioline[0],TOS(st, 0));
+ break;
+
+ /* XREAD_STRING:
+
+ * STACK INPUTS:
+ * TOS = Number of bytes to read
+ * TOS-1 = Address to store byte(s) */
+ case xREAD_STRING :
+ (void)fgets((char*)ATSTACK(st, TOS(st, 1)), TOS(st, 0), stdin);
+ break;
+
+ /* xREAD_REAL:
+ * STACK INPUTS: TOS = address to store REAL */
+
+ case xREAD_REAL :
+ (void)fgets((char*)ioline, LINE_SIZE, stdin);
+ pexec_readreal((uint16_t*)ATSTACK(st, TOS(st, 0)), ioline);
+ break;
+
+ case xWRITELN :
+ putchar('\n');
+ break;
+ case xWRITE_PAGE :
+ putchar('\f');
+ break;
+ case xWRITE_BINARY :
+/* FINISH ME -- > */
+ break;
+
+ /* xWRITE_INT:
+ * STACK INPUTS: TOS = integer value to write. */
+
+ case xWRITE_INT :
+ printf("%ld", signExtend16(TOS(st, 0)));
+ break;
+
+ /* xWRITE_CHAR:
+ * STACK INPUTS: TOS = char value to write. */
+
+ case xWRITE_CHAR :
+ putchar(TOS(st, 0));
+ break;
+
+ /* xWRITE_STRING:
+ * STACK INPUTS:
+ * TOS = Number of bytes to write
+ * TOS-1 = Address of src data */
+
+ case xWRITE_STRING :
+ uparm1 = TOS(st, 0);
+ for (ptr = (uint8_t*)ATSTACK(st, TOS(st, 1)); uparm1; uparm1--, ptr++)
+ putchar(*ptr);
+ break;
+
+ /* xWRITE_REAL:
+ * STACK INPUTS: TOS = value of double */
+
+ case xWRITE_REAL :
+ fp.hw[0] = TOS(st, 3);
+ fp.hw[1] = TOS(st, 2);
+ fp.hw[2] = TOS(st, 1);
+ fp.hw[3] = TOS(st, 0);;
+ printf("%f", fp.f);
+ break;
+
+ default :
+ return eBADSYSIOFUNC;
+
+ }
+
+ return eNOERROR;
+
+} /* end pexec_sysio */
+
+/****************************************************************************
+ * Name: pexec_libcall
+ *
+ * Description:
+ * This function process a system I/O operation
+ *
+ ****************************************************************************/
+
+static uint16_t pexec_libcall(struct pexec_s *st, uint16_t subfunc)
+{
+ ustack_t uparm1;
+ ustack_t uparm2;
+ paddr_t addr1;
+ paddr_t addr2;
+ uint16_t *tmp;
+ uint16_t *ref;
+ uint8_t *src;
+ uint8_t *dest;
+ uint8_t *name;
+ int len;
+ int32_t value;
+
+ switch (subfunc)
+ {
+ /* Get the value of an environment string
+ *
+ * ON INPUT:
+ * TOS(st, 0) = Number of bytes in environment identifier string
+ * TOS(st, 1) = Address environment identifier string
+ * ON RETURN (above replaced with):
+ * TOS(st, 0) = MS 16-bits of 32-bit C string pointer
+ * TOS(st, 1) = LS 16-bits of 32-bit C string pointer
+ */
+
+ case lbGETENV :
+ len = TOS(st, 0); /* Number of bytes in string */
+ src = (uint8_t*)&GETSTACK(st, TOS(st, 1)); /* Pointer to string */
+
+ /* Make a C string out of the pascal string */
+
+ name = pexec_mkcstring(src, len);
+ if (name == NULL)
+ {
+ return eNOMEMORY;
+ }
+
+ /* Make the C-library call and free the string copy */
+
+ src = (uint8_t*)getenv((char*)name);
+ free_cstring(name);
+
+ /* Save the returned pointer in the stack */
+
+ TOS(st, 0) = (ustack_t)((uint32_t)src >> 16);
+ TOS(st, 1) = (ustack_t)((uint32_t)src & 0x0000ffff);
+ break;
+
+ /* Copy pascal string to a pascal string
+ *
+ * ON INPUT:
+ * TOS(st, 0) = address of dest string hdr
+ * TOS(st, 1) = length of source string
+ * TOS(st, 2) = pointer to source string
+ * ON RETURN (input consumed):
+ */
+
+ case lbSTR2STR :
+ /* "Pop" in the input parameters from the stack */
+
+ POP(st, addr1); /* addr of dest string header */
+ POP(st, uparm1); /* length of source data */
+ POP(st, addr2); /* addr of source string data */
+
+ /* Do nothing if the source and destinations are the same
+ * string. This happens normally on cases like:
+ * string name;
+ * char c;
+ * name := name + c;
+ */
+
+ if (addr1 != addr2)
+ {
+ /* The source and destination strings are different.
+ * Make sure that the string length will fit into the destination.
+ */
+
+ if (uparm1 >= sSTRING_MAX_SIZE)
+ {
+ /* Clip to the maximum size */
+
+ uparm1 = sSTRING_MAX_SIZE;
+ len = sSTRING_MAX_SIZE;
+ }
+ else
+ {
+ /* We have space */
+
+ len = (int)uparm1;
+ }
+
+ /* Get proper string pointers */
+
+ dest = ATSTACK(st, addr1);
+ src = ATSTACK(st, addr2);
+
+ /* Transfer the (16-bit) string length (must be aligned!) */
+
+ tmp = (uint16_t*)dest;
+ *tmp++ = uparm1;
+ dest = (uint8_t*)tmp;
+
+ /* Then transfer the string contents */
+
+ memcpy(dest, src, len);
+ }
+ break;
+
+ /* Copy C string to a pascal string
+ *
+ * ON INPUT:
+ * TOS(st, 0) = address of dest hdr
+ * TOS(st, 1) = MS 16-bits of 32-bit C string pointer
+ * TOS(st, 2) = LS 16-bits of 32-bit C string pointer
+ * ON RETURN (input consumed):
+ */
+ case lbCSTR2STR :
+ /* "Pop" in the input parameters from the stack */
+
+ POP(st, addr1); /* addr of dest string header */
+ POP(st, uparm1); /* MS 16-bits of 32-bit C string pointer */
+ POP(st, uparm2); /* LS 16-bits of 32-bit C string pointer */
+
+ /* Get proper string pointers */
+
+ dest = ATSTACK(st, addr1);
+ src = (uint8_t*)((unsigned long)uparm1 << 16 | (unsigned long)uparm2);
+
+ /* Handle null src pointer */
+
+ if (src == NULL)
+ {
+ *dest = 0;
+ }
+ else
+ {
+ /* Get the length of the string */
+
+ uparm1 = strlen((char*)src);
+
+ /* Make sure that the string length will fit into the
+ * destination. */
+
+ if (uparm1 >= sSTRING_MAX_SIZE)
+ {
+ /* Clip to the maximum size */
+
+ uparm1 = sSTRING_MAX_SIZE;
+ len = sSTRING_MAX_SIZE;
+ }
+ else
+ {
+ /* We have space */
+
+ len = (int)uparm1;
+ }
+
+ /* Transfer the (16-bit) string length (must be aligned!) */
+
+ tmp = (uint16_t*)dest;
+ *tmp++ = uparm1;
+ dest = (uint8_t*)tmp;
+
+ /* Then transfer the string contents */
+
+ memcpy(dest, src, len);
+ }
+ break;
+
+ /* Copy pascal string to a pascal string reference
+ * procedure str2rstr(src : string; var dest : rstring)
+ * ON INPUT:
+ * TOS(st, 0)=address of dest string reference
+ * TOS(st, 1)=length of source string
+ * TOS(st, 2)=pointer to source string
+ * ON RETURN: actual parameters released.
+ */
+
+ case lbSTR2RSTR :
+ /* "Pop" in the input parameters from the stack */
+
+ POP(st, addr1); /* addr of dest string reference */
+ POP(st, uparm1); /* length of source data */
+ POP(st, addr2); /* addr of source string data */
+
+ /* Make sure that the string length will fit into the destination. */
+
+ if (uparm1 >= sSTRING_MAX_SIZE)
+ {
+ return eSTRSTKOVERFLOW;
+ }
+
+ /* Get a pointer to the destination reference */
+
+ ref = (uint16_t*)ATSTACK(st, addr1);
+
+ /* Get proper string pointers */
+
+ dest = ATSTACK(st, ref[0] - 2);
+ src = ATSTACK(st, addr2);
+
+ /* Transfer the (16-bit) string length (must be aligned!) */
+
+ tmp = (uint16_t*)dest;
+ *tmp++ = uparm1;
+ dest = (uint8_t*)tmp;
+
+ /* Then transfer the string contents and save the new size */
+
+ memcpy(dest, src, uparm1);
+ ref[1] = uparm1;
+ break;
+
+ /* Copy C string to a pascal string reference
+ * procedure cstr2str(src : cstring; var dest : string)
+ * ON INPUT:
+ * TOS(st, 0)=address of dest string reference
+ * TOS(st, 0)=MS 16-bits of 32-bit C source string pointer
+ * TOS(st, 1)=LS 16-bits of 32-bit C source string pointer
+ * ON RETURN: actual parameters released
+ */
+
+ case lbCSTR2RSTR :
+ /* "Pop" in the input parameters from the stack */
+
+ POP(st, addr1); /* addr of dest string reference */
+ POP(st, uparm1); /* MS 16-bits of 32-bit C string pointer */
+ POP(st, uparm2); /* LS 16-bits of 32-bit C string pointer */
+
+ /* Get a pointer to the destination reference */
+
+ ref = (uint16_t*)ATSTACK(st, addr1);
+
+ /* Get proper string pointers */
+
+ dest = ATSTACK(st, ref[0] - 2);
+ src = (uint8_t*)((unsigned long)uparm1 << 16 | (unsigned long)uparm2);
+
+ /* Handle null src pointer */
+
+ if (src == NULL)
+ {
+ *dest = 0;
+ }
+ else
+ {
+ /* Get the length of the string */
+
+ uparm1 = strlen((char*)src);
+
+ /* Make sure that the string length will fit into the
+ * destination. */
+
+ if (uparm1 >= sSTRING_MAX_SIZE)
+ {
+ return eSTRSTKOVERFLOW;
+ }
+
+ /* Transfer the (16-bit) string length (must be aligned!) */
+
+ tmp = (uint16_t*)dest;
+ *tmp++ = uparm1;
+ dest = (uint8_t*)tmp;
+
+ /* Then transfer the string contents */
+
+ memcpy(dest, src, uparm1);
+ ref[1] = uparm1;
+ }
+ break;
+
+ /* Convert a string to a numeric value
+ * procedure val(const s : string; var v; var code : word);
+ *
+ * Description:
+ * val() converts the value represented in the string S to a numerical
+ * value, and stores this value in the variable V, which can be of type
+ * Longint, Real and Byte. If the conversion isn't succesfull, then the
+ * parameter Code contains the index of the character in S which
+ * prevented the conversion. The string S is allowed to contain spaces
+ * in the beginning.
+ *
+ * The string S can contain a number in decimal, hexadecimal, binary or
+ * octal format, as described in the language reference.
+ *
+ * Errors:
+ * If the conversion doesn¡Çt succeed, the value of Code indicates the
+ * position where the conversion went wrong.
+ *
+ * ON INPUT
+ * TOS(st, 0)=address of code
+ * TOS(st, 1)=address of value
+ * TOS(st, 2)=length of source string
+ * TOS(st, 3)=pointer to source string
+ * ON RETURN: actual parameters released
+ */
+
+ case lbVAL :
+ /* Get the string information */
+
+ len = TOS(st, 2); /* Number of bytes in string */
+ src = (uint8_t*)&GETSTACK(st, TOS(st, 3)); /* Pointer to string */
+
+ /* Make a C string out of the pascal string */
+
+ name = pexec_mkcstring(src, len);
+ if (name == NULL)
+ {
+ return eNOMEMORY;
+ }
+
+ /* Convert the string to an integer */
+
+ value = atoi((char*)name);
+ if ((value < MININT) || (value > MAXINT))
+ {
+ return eINTEGEROVERFLOW;
+ }
+ PUTSTACK(st, TOS(st, 0), 0);
+ PUTSTACK(st, TOS(st, 1), value);
+ DISCARD(st, 4);
+ break;
+
+ /* Create an empty string
+ * function mkstk : string;
+ * ON INPUT
+ * ON RETURN
+ * TOS(st, 0)=length of new string
+ * TOS(st, 1)=pointer to new string
+ */
+
+ case lbMKSTK :
+ /* Allocate space on the string stack for the new string
+ * FIXME: This logic does not handle strings with other than the
+ * default size!
+ */
+
+ addr1 = ((st->csp + 1) & ~1);
+ st->csp += sSTRING_SIZE; /* Allocate max size */
+
+ /* Save the length at the beginning of the copy */
+
+ tmp = (uint16_t*)&GETSTACK(st, addr1); /* Pointer to new string */
+ *tmp++ = 0; /* Save current size */
+
+ /* Update the stack content */
+
+ PUSH(st, addr1 + sSTRING_HDR_SIZE); /* Pointer to new string */
+ PUSH(st, 0); /* Current size */
+ break;
+
+ /* Replace a string with a duplicate string residing in allocated
+ * string stack.
+ * function mkstkstr(name : string) : string;
+ * ON INPUT
+ * TOS(st, 0)=length of original string
+ * TOS(st, 1)=pointer to original string data
+ * ON RETURN
+ * TOS(st, 0)=length of new string (unchanged)
+ * TOS(st, 1)=pointer to new string data
+ */
+
+ case lbMKSTKSTR :
+ /* Get the parameters from the stack (leaving the string reference
+ * in place.
+ */
+
+ uparm1 = TOS(st, 0); /* Original string size */
+ addr1 = TOS(st, 1); /* Original string data pointer */
+
+ /* Check if there is space on the string stack for the new string
+ * FIXME: This logic does not handle strings with other than the
+ * default size!
+ */
+
+ if (st->csp + sSTRING_SIZE >= st->spb)
+ {
+ return eSTRSTKOVERFLOW;
+ }
+
+ /* Allocate space on the string stack for the new string */
+
+ addr2 = ((st->csp + 1) & ~1);
+ st->csp += sSTRING_SIZE; /* Allocate max size */
+
+ /* Save the length at the beginning of the copy */
+
+ tmp = (uint16_t*)&GETSTACK(st, addr2); /* Pointer to new string */
+ *tmp++ = uparm1; /* Save current size */
+ dest = (uint8_t*)tmp; /* Pointer to string data */
+
+ /* Copy the string into the string stack */
+
+ src = (uint8_t*)&GETSTACK(st, addr1); /* Pointer to original string */
+ memcpy(dest, src, uparm1);
+
+ /* Update the stack content */
+
+ TOS(st, 1) = addr2 + sSTRING_HDR_SIZE;
+ break;
+
+ /* Replace a character with a string residing in allocated string stack.
+ * function mkstkc(c : char) : string;
+ * ON INPUT
+ * TOS(st, 0)=Character value
+ * ON RETURN
+ * TOS(st, 0)=length of new string
+ * TOS(st, 1)=pointer to new string
+ */
+
+ case lbMKSTKC :
+ /* Check if there is space on the string stack for the new string
+ * FIXME: This logic does not handle strings with other than the
+ * default size!
+ */
+
+ if (st->csp + sSTRING_SIZE >= st->spb)
+ {
+ return eSTRSTKOVERFLOW;
+ }
+
+ /* Allocate space on the string stack for the new string */
+
+ addr2 = ((st->csp + 1) & ~1);
+ st->csp += sSTRING_SIZE; /* Allocate max size */
+
+ /* Save the length at the beginning of the copy */
+
+ tmp = (uint16_t*)&GETSTACK(st, addr2); /* Pointer to new string */
+ *tmp++ = 1; /* Save initial size */
+ dest = (uint8_t*)tmp; /* Pointer to string data */
+
+ /* Copy the character into the string stack */
+
+ *dest++ = TOS(st, 0); /* Save character as string */
+
+ /* Update the stack content */
+
+ TOS(st, 0) = addr2 + sSTRING_HDR_SIZE; /* String address */
+ PUSH(st, 1); /* String length */
+ break;
+
+ /* Concatenate a string to the end of a string.
+ * function strcat(name : string, c : char) : string;
+ *
+ * ON INPUT
+ * TOS(st, 0)=length of string1
+ * TOS(st, 1)=pointer to string1 data
+ * TOS(st, 2)=length of string2
+ * TOS(st, 3)=pointer to string2 data
+ * ON OUTPUT
+ * TOS(st, 1)=new length of string2
+ * TOS(st, 2)=pointer to string2
+ */
+
+ case lbSTRCAT :
+ /* Get the parameters from the stack (leaving the string reference
+ * in place.
+ */
+
+ POP(st, uparm1); /* string1 size */
+ POP(st, addr1); /* string1 data stack addr */
+ uparm2 = TOS(st, 0); /* string2 size */
+
+ /* Check for string overflow. FIXME: This logic does not handle
+ * strings with other than the default size!
+ */
+
+ if (uparm1 + uparm2 > sSTRING_MAX_SIZE)
+ return eSTRSTKOVERFLOW;
+ else
+ {
+ /* Get a pointer to string1 data */
+
+ src = ATSTACK(st, addr1);
+
+ /* Get a pointer to string2 header, set new size then, get
+ * a pointer to string2 data.
+ */
+
+ tmp = ((uint16_t*)&GETSTACK(st, TOS(st, 1))) - 1;
+ *tmp++ = uparm1 + uparm2;
+ dest = (uint8_t*)tmp;
+
+ memcpy(&dest[uparm2], src, uparm1); /* cat strings */
+ TOS(st, 0) = uparm1 + uparm2; /* Save new size */
+ }
+ break;
+
+ /* Concatenate a character to the end of a string.
+ * function strcatc(name : string, c : char) : string;
+ *
+ * ON INPUT
+ * TOS(st, 0)=character to concatenate
+ * TOS(st, 1)=length of string
+ * TOS(st, 2)=pointer to string
+ * ON OUTPUT
+ * TOS(st, 1)=new length of string
+ * TOS(st, 2)=pointer to string
+ */
+
+ case lbSTRCATC :
+ /* Get the parameters from the stack (leaving the string reference
+ * in place.
+ */
+
+ POP(st, uparm1); /* Character to concatenate */
+ uparm2 = TOS(st, 0); /* Current length of string */
+
+ /* Check for string overflow. FIXME: This logic does not handle
+ * strings with other than the default size!
+ */
+
+ if (uparm2 >= sSTRING_MAX_SIZE)
+ return eSTRSTKOVERFLOW;
+ else
+ {
+ /* Get a pointer to string header, set size new size then, get
+ * a pointer to string data.
+ */
+
+ tmp = ((uint16_t*)&GETSTACK(st, TOS(st, 1))) - 1;
+ *tmp++ = uparm2 + 1;
+ dest = (uint8_t*)tmp;
+
+ /* Add the new charcter */
+
+ dest[uparm2] = (uint8_t)uparm1;
+
+ /* Save the new string size */
+
+ TOS(st, 0) = uparm2 + 1;
+ }
+ break;
+
+ /* Compare two pascal strings
+ * function strcmp(name1 : string, name2 : string) : integer;
+ * ON INPUT
+ * TOS(st, 1)=length of string2
+ * TOS(st, 2)=address of string2 data
+ * TOS(st, 3)=length of string1
+ * TOS(st, 4)=address of string1 data
+ * ON OUTPUT
+ * TOS(st, 0)=(-1=less than, 0=equal, 1=greater than}
+ */
+
+ case lbSTRCMP :
+ {
+ int result;
+
+ /* Get the parameters from the stack (leaving space for the
+ * return value);
+ */
+
+ POP(st, uparm2); /* length of string2 */
+ POP(st, addr2); /* address of string2 data */
+ POP(st, uparm1); /* length of string1 */
+ addr1 = TOS(st, 0); /* address of string1 data */
+
+ /* Get full address */
+
+ dest = ATSTACK(st, addr1);
+ src = ATSTACK(st, addr2);
+
+ /* If name1 is shorter than name2, then we can only return
+ * -1 (less than) or +1 greater than. If the substrings
+ * of length of name1 are equal, then we return less than.
+ */
+
+ if (uparm1 < uparm2)
+ {
+ result = memcmp(dest, src, uparm1);
+ if (result == 0) result = -1;
+ }
+
+ /* If name1 is longer than name2, then we can only return
+ * -1 (less than) or +1 greater than. If the substrings
+ * of length of name2 are equal, then we return greater than.
+ */
+
+ else if (uparm1 > uparm2)
+ {
+ result = memcmp(dest, src, uparm2);
+ if (result == 0) result = 1;
+ }
+
+ /* The strings are of equal length. Return the result of
+ * the comparison.
+ */
+
+ else
+ {
+ result = memcmp(dest, src, uparm1);
+ }
+ TOS(st, 0) = result;
+ }
+ break;
+
+ default :
+ return eBADSYSLIBCALL;
+
+ }
+
+ return eNOERROR;
+
+} /* end pexec_libcall */
+
+/****************************************************************************
+ * Name: pexec_execfp
+ *
+ * Description:
+ * This function processes a floating point operation.
+ *
+ ****************************************************************************/
+
+static uint16_t pexec_execfp(struct pexec_s *st, uint8_t fpop)
+{
+ int16_t intValue;
+ fparg_t arg1;
+ fparg_t arg2;
+ fparg_t result;
+
+ switch (fpop & fpMASK)
+ {
+ /* Floating Pointer Conversions (On stack argument: FP or Integer) */
+
+ case fpFLOAT :
+ POP(st, intValue);
+ result.f = (double)intValue;
+ PUSH(st, result.hw[0]);
+ PUSH(st, result.hw[1]);
+ PUSH(st, result.hw[2]);
+ PUSH(st, result.hw[3]);
+ break;
+
+ case fpTRUNC :
+ case fpROUND :
+ pexec_getfparguments(st, fpop, &arg1, NULL);
+ intValue = (int16_t)arg1.f;
+ PUSH(st, intValue);
+ break;
+
+ /* Floating Point arithmetic instructions (Two FP stack arguments) */
+
+ case fpADD :
+ pexec_getfparguments(st, fpop, &arg1, &arg2);
+ result.f = arg1.f + arg2.f;
+ PUSH(st, result.hw[0]);
+ PUSH(st, result.hw[1]);
+ PUSH(st, result.hw[2]);
+ PUSH(st, result.hw[3]);
+ break;
+ case fpSUB :
+ pexec_getfparguments(st, fpop, &arg1, &arg2);
+ result.f = arg1.f - arg2.f;
+ PUSH(st, result.hw[0]);
+ PUSH(st, result.hw[1]);
+ PUSH(st, result.hw[2]);
+ PUSH(st, result.hw[3]);
+ break;
+ case fpMUL :
+ pexec_getfparguments(st, fpop, &arg1, &arg2);
+ result.f = arg1.f * arg2.f;
+ PUSH(st, result.hw[0]);
+ PUSH(st, result.hw[1]);
+ PUSH(st, result.hw[2]);
+ PUSH(st, result.hw[3]);
+ break;
+ case fpDIV :
+ pexec_getfparguments(st, fpop, &arg1, &arg2);
+ result.f = arg1.f / arg2.f;
+ PUSH(st, result.hw[0]);
+ PUSH(st, result.hw[1]);
+ PUSH(st, result.hw[2]);
+ PUSH(st, result.hw[3]);
+ break;
+ case fpMOD :
+ return eBADFPOPCODE;
+#if 0 /* Not yet */
+ pexec_getfparguments(st, fpop, &arg1, &arg2);
+ result.f = arg1.f % arg2.f;
+ PUSH(st, result.hw[0]);
+ PUSH(st, result.hw[1]);
+ PUSH(st, result.hw[2]);
+ PUSH(st, result.hw[3]);
+ break;
+#endif
+
+ /* Floating Point Comparisons (Two FP stack arguments) */
+
+ case fpEQU :
+ pexec_getfparguments(st, fpop, &arg1, &arg2);
+ intValue = PFALSE;
+ if (arg1.f == arg2.f)
+ intValue = PTRUE;
+ PUSH(st, intValue);
+ break;
+ case fpNEQ :
+ pexec_getfparguments(st, fpop, &arg1, &arg2);
+ intValue = PFALSE;
+ if (arg1.f != arg2.f)
+ intValue = PTRUE;
+ PUSH(st, intValue);
+ break;
+ case fpLT :
+ pexec_getfparguments(st, fpop, &arg1, &arg2);
+ intValue = PFALSE;
+ if (arg1.f < arg2.f)
+ intValue = PTRUE;
+ PUSH(st, intValue);
+ break;
+ case fpGTE :
+ pexec_getfparguments(st, fpop, &arg1, &arg2);
+ intValue = PFALSE;
+ if (arg1.f >= arg2.f)
+ intValue = PTRUE;
+ PUSH(st, intValue);
+ break;
+ case fpGT :
+ pexec_getfparguments(st, fpop, &arg1, &arg2);
+ intValue = PFALSE;
+ if (arg1.f > arg2.f)
+ intValue = PTRUE;
+ PUSH(st, intValue);
+ break;
+ case fpLTE :
+ pexec_getfparguments(st, fpop, &arg1, &arg2);
+ intValue = PFALSE;
+ if (arg1.f <= arg2.f)
+ intValue = PTRUE;
+ PUSH(st, intValue);
+ break;
+
+ /* Floating Point arithmetic instructions (One FP stack arguments) */
+
+ case fpNEG :
+ pexec_getfparguments(st, fpop, &arg1, NULL);
+ result.f = -arg1.f;
+ PUSH(st, result.hw[0]);
+ PUSH(st, result.hw[1]);
+ PUSH(st, result.hw[2]);
+ PUSH(st, result.hw[3]);
+ break;
+#ifdef CONFIG_HAVE_LIBM
+ case fpABS :
+ pexec_getfparguments(st, fpop, &arg1, NULL);
+ result.f = fabs(arg1.f);
+ PUSH(st, result.hw[0]);
+ PUSH(st, result.hw[1]);
+ PUSH(st, result.hw[2]);
+ PUSH(st, result.hw[3]);
+ break;
+#endif
+ case fpSQR :
+ pexec_getfparguments(st, fpop, &arg1, NULL);
+ result.f = arg1.f * arg1.f;
+ PUSH(st, result.hw[0]);
+ PUSH(st, result.hw[1]);
+ PUSH(st, result.hw[2]);
+ PUSH(st, result.hw[3]);
+ break;
+#ifdef CONFIG_HAVE_LIBM
+ case fpSQRT :
+ pexec_getfparguments(st, fpop, &arg1, NULL);
+ result.f = sqrt(arg1.f);
+ PUSH(st, result.hw[0]);
+ PUSH(st, result.hw[1]);
+ PUSH(st, result.hw[2]);
+ PUSH(st, result.hw[3]);
+ break;
+ case fpSIN :
+ pexec_getfparguments(st, fpop, &arg1, NULL);
+ result.f = sin(arg1.f);
+ PUSH(st, result.hw[0]);
+ PUSH(st, result.hw[1]);
+ PUSH(st, result.hw[2]);
+ PUSH(st, result.hw[3]);
+ break;
+ case fpCOS :
+ pexec_getfparguments(st, fpop, &arg1, NULL);
+ result.f = cos(arg1.f);
+ PUSH(st, result.hw[0]);
+ PUSH(st, result.hw[1]);
+ PUSH(st, result.hw[2]);
+ PUSH(st, result.hw[3]);
+ break;
+ case fpATAN :
+ pexec_getfparguments(st, fpop, &arg1, NULL);
+ result.f = atan(arg1.f);
+ PUSH(st, result.hw[0]);
+ PUSH(st, result.hw[1]);
+ PUSH(st, result.hw[2]);
+ PUSH(st, result.hw[3]);
+ break;
+ case fpLN :
+ pexec_getfparguments(st, fpop, &arg1, NULL);
+ result.f = log(arg1.f);
+ PUSH(st, result.hw[0]);
+ PUSH(st, result.hw[1]);
+ PUSH(st, result.hw[2]);
+ PUSH(st, result.hw[3]);
+ break;
+ case fpEXP :
+ pexec_getfparguments(st, fpop, &arg1, NULL);
+ result.f = exp(arg1.f);
+ PUSH(st, result.hw[0]);
+ PUSH(st, result.hw[1]);
+ PUSH(st, result.hw[2]);
+ PUSH(st, result.hw[3]);
+ break;
+#endif
+
+ default :
+ return eBADFPOPCODE;
+
+ }
+ return eNOERROR;
+
+} /* end pexec_execfp */
+
+/****************************************************************************
+ * Name: pexec_getfparguments
+ *
+ * Description:
+ * This function retrieves the floating point arguments and performs
+ * integer to REAL conversions as necessary
+ *
+ ****************************************************************************/
+
+static void pexec_getfparguments(struct pexec_s *st, uint8_t fpop, fparg_t *arg1, fparg_t *arg2)
+{
+ int16_t sparm;
+
+ /* Extract arg2 from the stack */
+
+ if (arg2)
+ {
+ /* Convert an integer argument to type REAL */
+
+ if ((fpop & fpARG2) != 0)
+ {
+ POP(st, sparm);
+ arg2->f = (double)sparm;
+ }
+ else
+ {
+ POP(st, arg2->hw[3]);
+ POP(st, arg2->hw[2]);
+ POP(st, arg2->hw[1]);
+ POP(st, arg2->hw[0]);
+ }
+ }
+
+ /* Extract arg1 from the stack */
+
+ if (arg1)
+ {
+ /* Convert an integer argument to type REAL */
+
+ if ((fpop & fpARG1) != 0)
+ {
+ POP(st, sparm);
+ arg1->f = (double)sparm;
+ }
+ else
+ {
+ POP(st, arg1->hw[3]);
+ POP(st, arg1->hw[2]);
+ POP(st, arg1->hw[1]);
+ POP(st, arg1->hw[0]);
+ }
+ }
+
+} /* end pexec_getfparguments */
+
+/****************************************************************************
+ * Name: pexec_readinteger
+ *
+ * Description:
+ * This function parses a decimal integer from ioptr
+ ****************************************************************************/
+
+static ustack_t pexec_readinteger(uint8_t *ioptr)
+{
+ sstack_t value = 0;
+
+ while (isspace(*ioptr)) ioptr++;
+ while ((*ioptr >= '0') && (*ioptr <= '9'))
+ {
+ value = 10*value
+ + (sstack_t)(*ioptr)
+ - (sstack_t)'0';
+ ioptr++;
+ }
+
+ return (ustack_t)value;
+
+} /* end pexec_readinteger */
+
+/****************************************************************************
+ * Name: pexec_readreal
+ *
+ * Description:
+ * This function parses a decimal integer from ioptr.
+ *
+ ****************************************************************************/
+
+static void pexec_readreal(uint16_t *dest, uint8_t *inPtr)
+{
+ int32_t intpart;
+ fparg_t result;
+ double fraction;
+ uint8_t unaryop;
+
+ intpart = 0;
+ unaryop = '+';
+
+ /* Check for a leading unary - */
+
+ if ((*inPtr == '-') || (*inPtr == '+'))
+ unaryop = *inPtr++;
+
+ /* Get the integer part of the real */
+
+ while ((*inPtr >= '0') && (*inPtr <= '9'))
+ intpart = 10*intpart + ((int32_t)*inPtr++) - ((int32_t)'0');
+
+ result.f = ((double)intpart);
+
+ /* Check for the a fractional part */
+
+ if (*inPtr == '.')
+ {
+ inPtr++;
+ fraction = 0.1;
+ while ((*inPtr >= '0') && (*inPtr <= '9'))
+ {
+ result.f += fraction * (double)(((int32_t)*inPtr++) - ((int32_t)'0'));
+ fraction /= 10.0;
+ }
+ }
+
+ /* Correct the sign of the result */
+
+ if (unaryop == '-')
+ result.f = -result.f;
+
+ /* Return the value into the P-Machine stack */
+
+ *dest++ = result.hw[0];
+ *dest++ = result.hw[1];
+ *dest++ = result.hw[2];
+ *dest = result.hw[3];
+
+} /* end pexec_readreal */
+
+/****************************************************************************
+ * Name: pexec_getbaseaddress
+ *
+ * Description:
+ * This function binds the base address corresponding to a given level
+ * offset.
+ *
+ ****************************************************************************/
+
+static ustack_t pexec_getbaseaddress(struct pexec_s *st, level_t leveloffset)
+{
+ /* Start with the base register of the current frame */
+
+ ustack_t baseAddress = st->fp;
+
+ /* Search backware "leveloffset" frames until the correct frame is
+ * found
+ */
+
+ while (leveloffset > 0)
+ {
+ baseAddress = st->dstack.i[BTOISTACK(baseAddress)];
+ leveloffset--;
+ }
+
+ /* Offset that value by two words (one for the st->fp and one for the
+ * return value
+ */
+
+ return baseAddress + 2*BPERI;
+
+} /* end pexec_getbaseaddress */
+
+/****************************************************************************
+ * Name: pexec_mkcstring
+ ****************************************************************************/
+
+static uint8_t *pexec_mkcstring(uint8_t *buffer, int buflen)
+{
+ uint8_t *string;
+
+ string = malloc(buflen + 1);
+ if (string != NULL)
+ {
+ memcpy(string, buffer, buflen);
+ string[buflen] = '\0';
+ }
+ return string;
+}
+
+/****************************************************************************
+ * Name: pexec8
+ *
+ * Descripton:
+ * Handle 8-bit instructions with no immediate data
+ *
+ ****************************************************************************/
+
+static inline int pexec8(FAR struct pexec_s *st, uint8_t opcode)
+{
+ sstack_t sparm;
+ ustack_t uparm1;
+ ustack_t uparm2;
+ ustack_t uparm3;
+
+ switch (opcode)
+ {
+ /* Arithmetic & logical & and integer conversions (One stack argument) */
+ case oNEG :
+ TOS(st, 0) = (ustack_t)(-(sstack_t)TOS(st, 0));
+ break;
+ case oABS :
+ if (signExtend16(TOS(st, 0)) < 0)
+ {
+ TOS(st, 0) = (ustack_t)(-signExtend16(TOS(st, 0)));
+ }
+ break;
+ case oINC :
+ TOS(st, 0)++;
+ break;
+ case oDEC :
+ TOS(st, 0)--;
+ break;
+ case oNOT :
+ TOS(st, 0) = ~TOS(st, 0);
+ break;
+
+ /* Arithmetic & logical (Two stack arguments) */
+
+ case oADD :
+ POP(st, sparm);
+ TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) + sparm);
+ break;
+ case oSUB :
+ POP(st, sparm);
+ TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) - sparm);
+ break;
+ case oMUL :
+ POP(st, sparm);
+ TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) * sparm);
+ break;
+ case oDIV :
+ POP(st, sparm);
+ TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) / sparm);
+ break;
+ case oMOD :
+ POP(st, sparm);
+ TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) % sparm);
+ break;
+ case oSLL :
+ POP(st, sparm);
+ TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) << sparm);
+ break;
+ case oSRL :
+ POP(st, sparm);
+ TOS(st, 0) = (TOS(st, 0) >> sparm);
+ break;
+ case oSRA :
+ POP(st, sparm);
+ TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) >> sparm);
+ break;
+ case oOR :
+ POP(st, uparm1);
+ TOS(st, 0) = (TOS(st, 0) | uparm1);
+ break;
+ case oAND :
+ POP(st, uparm1);
+ TOS(st, 0) = (TOS(st, 0) & uparm1);
+ break;
+ case oBIT :
+ POP(st, uparm1);
+ uparm2 = TOS(st, 0);
+ if ((uparm1 & (1 << uparm2)) != 0)
+ {
+ TOS(st, 0) = PTRUE;
+ }
+ else
+ {
+ TOS(st, 0) = PFALSE;
+ }
+ break;
+
+ /* Comparisons (One stack argument) */
+
+ case oEQUZ :
+ POP(st, sparm);
+ uparm1 = PFALSE;
+ if (sparm == 0)
+ {
+ uparm1 = PTRUE;
+ }
+ PUSH(st, uparm1);
+ break;
+ case oNEQZ :
+ POP(st, sparm);
+ uparm1 = PFALSE;
+ if (sparm != 0)
+ {
+ uparm1 = PTRUE;
+ }
+ PUSH(st, uparm1);
+ break;
+ case oLTZ :
+ POP(st, sparm);
+ uparm1 = PFALSE;
+ if (sparm < 0)
+ {
+ uparm1 = PTRUE;
+ }
+ PUSH(st, uparm1);
+ break;
+ case oGTEZ :
+ POP(st, sparm);
+ uparm1 = PFALSE;
+ if (sparm >= 0)
+ {
+ uparm1 = PTRUE;
+ }
+ PUSH(st, uparm1);
+ break;
+ case oGTZ :
+ POP(st, sparm);
+ uparm1 = PFALSE;
+ if (sparm > 0)
+ {
+ uparm1 = PTRUE;
+ }
+ PUSH(st, uparm1);
+ break;
+ case oLTEZ :
+ POP(st, sparm);
+ uparm1 = PFALSE;
+ if (sparm <= 0)
+ {
+ uparm1 = PTRUE;
+ }
+ PUSH(st, uparm1);
+ break;
+
+ /* Comparisons (Two stack arguments) */
+
+ case oEQU :
+ POP(st, sparm);
+ uparm1 = PFALSE;
+ if (sparm == (sstack_t)TOS(st, 0))
+ {
+ uparm1 = PTRUE;
+ }
+ TOS(st, 0) = uparm1;
+ break;
+ case oNEQ :
+ POP(st, sparm);
+ uparm1 = PFALSE;
+ if (sparm != (sstack_t)TOS(st, 0))
+ {
+ uparm1 = PTRUE;
+ }
+ TOS(st, 0) = uparm1;
+ break;
+ case oLT :
+ POP(st, sparm);
+ uparm1 = PFALSE;
+ if (sparm < (sstack_t)TOS(st, 0))
+ {
+ uparm1 = PTRUE;
+ }
+ TOS(st, 0) = uparm1;
+ break;
+ case oGTE :
+ POP(st, sparm);
+ uparm1 = PFALSE;
+ if (sparm >= (sstack_t)TOS(st, 0))
+ {
+ uparm1 = PTRUE;
+ }
+ TOS(st, 0) = uparm1;
+ break;
+ case oGT :
+ POP(st, sparm);
+ uparm1 = PFALSE;
+ if (sparm > (sstack_t)TOS(st, 0))
+ {
+ uparm1 = PTRUE;
+ }
+ TOS(st, 0) = uparm1;
+ break;
+ case oLTE :
+ POP(st, sparm);
+ uparm1 = PFALSE;
+ if (sparm <= (sstack_t)TOS(st, 0))
+ {
+ uparm1 = PTRUE;
+ }
+ TOS(st, 0) = uparm1;
+ break;
+
+ /* Load (One stack argument) */
+
+ case oLDI :
+ POP(st, uparm1); /* Address */
+ PUSH(st, GETSTACK(st, uparm1));
+ PUSH(st, GETSTACK(st, uparm1 + BPERI));
+ break;
+ case oLDIH :
+ TOS(st, 0) = GETSTACK(st, TOS(st, 0));
+ break;
+ case oLDIB :
+ TOS(st, 0) = GETBSTACK(st, TOS(st, 0));
+ break;
+ case oLDIM :
+ /* FIX ME --> Need to handle the unaligned case */
+ POP(st, uparm1); /* Size */
+ POP(st, uparm2); /* Stack offset */
+ while (uparm1 > 0)
+ {
+ if (uparm1 >= BPERI)
+ {
+ PUSH(st, GETSTACK(st, uparm2));
+ uparm2 += BPERI;
+ uparm1 -= BPERI;
+ }
+ else
+ {
+ PUSH(st, GETBSTACK(st, uparm2));
+ uparm2++;
+ uparm1--;
+ }
+ }
+ break;
+ case oDUP :
+ uparm1 = TOS(st, 0);
+ uparm2 = TOS(st, 1);
+ PUSH(st, uparm2);
+ PUSH(st, uparm1);
+ break;
+ case oDUPH :
+ uparm1 = TOS(st, 0);
+ PUSH(st, uparm1);
+ break;
+ case oPUSHS :
+ PUSH(st, st->csp);
+ break;
+ case oPOPS :
+ POP(st, st->csp);
+ break;
+
+ /* Store (Two stack arguments) */
+
+ case oSTIH :
+ POP(st, uparm1);
+ POP(st, uparm2);
+ PUTSTACK(st, uparm1,uparm2);
+ break;
+ case oSTIB :
+ POP(st, uparm1);
+ POP(st, uparm2);
+ PUTBSTACK(st, uparm1, uparm2);
+ break;
+ case oSTIM :
+ /* FIX ME --> Need to handle the unaligned case */
+ POP(st, uparm1); /* Size in bytes */
+ uparm3 = uparm1; /* Save for stack discard */
+ sparm = ROUNDBTOI(uparm1); /* Size in words */
+ uparm2 = TOS(st, sparm); /* Stack offset */
+ sparm--;
+ while (uparm1 > 0)
+ {
+ if (uparm1 >= BPERI)
+ {
+ PUTSTACK(st, TOS(st, sparm), uparm2);
+ uparm2 += BPERI;
+ uparm1 -= BPERI;
+ sparm--;
+ }
+ else
+ {
+ PUTBSTACK(st, TOS(st, sparm), uparm2);
+ uparm2++;
+ uparm1--;
+ }
+ }
+
+ /* Discard the stored data + the stack offset */
+
+ DISCARD(st, (ROUNDBTOI(uparm3) + 1));
+ break;
+
+ /* Program control (No stack arguments) */
+
+ case oNOP :
+ break;
+ case oRET :
+ POP(st, st->pc);
+ POP(st, st->fp);
+ DISCARD(st, 1);
+ return eNOERROR;
+
+ /* System Functions (No stack arguments) */
+
+ case oEND :
+ return eEXIT;
+
+ default :
+ return eILLEGALOPCODE;
+ }
+
+ st->pc += 1;
+ return eNOERROR;
+}
+
+/****************************************************************************
+ * Name: pexec16
+ *
+ * Descripton:
+ * Handle 16-bit instructions with 8-bits of immediate data (imm8)
+ *
+ ****************************************************************************/
+
+static inline int pexec16(FAR struct pexec_s *st, uint8_t opcode, uint8_t imm8)
+{
+ int ret = eNOERROR;
+
+ st->pc += 2;
+ switch (opcode)
+ {
+ /* Data stack: imm8 = 8 bit unsigned data (no stack arguments) */
+
+ case oPUSHB :
+ PUSH(st, imm8);
+ break;
+
+ /* Floating Point: imm8 = FP op-code (varying number of stack arguments) */
+ case oFLOAT :
+ ret = pexec_execfp(st, imm8);
+ break;
+
+ default :
+ ret = eILLEGALOPCODE;
+ break;
+ }
+ return ret;
+}
+
+/****************************************************************************
+ * Name: pexec24
+ *
+ * Descripton:
+ * Handle 24-bit instructions with 16-bits of immediate data (imm16)
+ *
+ ****************************************************************************/
+
+static inline int pexec24(FAR struct pexec_s *st, uint8_t opcode, uint16_t imm16)
+{
+ sstack_t sparm1;
+ sstack_t sparm2;
+ ustack_t uparm1;
+ ustack_t uparm2;
+ ustack_t uparm3;
+ int ret = eNOERROR;
+
+ switch (opcode)
+ {
+ /* Program control: imm16 = unsigned label (no stack arguments) */
+
+ case oJMP :
+ goto branch_out;
+
+ /* Program control: imm16 = unsigned label (One stack argument) */
+
+ case oJEQUZ :
+ POP(st, sparm1);
+ if (sparm1 == 0)
+ {
+ goto branch_out;
+ }
+ break;
+ case oJNEQZ :
+ POP(st, sparm1);
+ if (sparm1 != 0)
+ {
+ goto branch_out;
+ }
+ break;
+ case oJLTZ :
+ POP(st, sparm1);
+ if (sparm1 < 0)
+ {
+ goto branch_out;
+ }
+ break;
+ case oJGTEZ :
+ POP(st, sparm1);
+ if (sparm1 >= 0)
+ {
+ goto branch_out;
+ }
+ break;
+ case oJGTZ :
+ POP(st, sparm1);
+ if (sparm1 > 0)
+ {
+ goto branch_out;
+ }
+ break;
+ case oJLTEZ :
+ POP(st, sparm1);
+ if (sparm1 <= 0)
+ {
+ goto branch_out;
+ }
+ break;
+
+ /* Program control: imm16 = unsigned label (Two stack arguments) */
+
+ case oJEQU :
+ POP(st, sparm1);
+ POP(st, sparm2);
+ if (sparm2 == sparm1)
+ {
+ goto branch_out;
+ }
+ break;
+ case oJNEQ :
+ POP(st, sparm1);
+ POP(st, sparm2);
+ if (sparm2 != sparm1)
+ {
+ goto branch_out;
+ }
+ break;
+ case oJLT :
+ POP(st, sparm1);
+ POP(st, sparm2);
+ if (sparm2 < sparm1)
+ {
+ goto branch_out;
+ }
+ break;
+ case oJGTE :
+ POP(st, sparm1);
+ POP(st, sparm2);
+ if (sparm2 >= sparm1)
+ {
+ goto branch_out;
+ }
+ break;
+ case oJGT :
+ POP(st, sparm1);
+ POP(st, sparm2);
+ if (sparm2 > sparm1)
+ {
+ goto branch_out;
+ }
+ break;
+ case oJLTE :
+ POP(st, sparm1);
+ POP(st, sparm2);
+ if (sparm2 <= sparm1)
+ {
+ goto branch_out;
+ }
+ break;
+
+ /* Load: imm16 = usigned offset (no stack arguments) */
+
+ case oLD :
+ uparm1 = st->spb + imm16;
+ PUSH(st, GETSTACK(st, uparm1));
+ PUSH(st, GETSTACK(st, uparm1 + BPERI));
+ break;
+ case oLDH :
+ uparm1 = st->spb + imm16;
+ PUSH(st, GETSTACK(st, uparm1));
+ break;
+ case oLDB :
+ uparm1 = st->spb + imm16;
+ PUSH(st, GETBSTACK(st, uparm1));
+ break;
+ case oLDM :
+ /* FIX ME --> Need to handle the unaligned case */
+ POP(st, uparm1);
+ uparm2 = st->spb + imm16;
+ while (uparm1 > 0)
+ {
+ if (uparm1 >= BPERI)
+ {
+ PUSH(st, GETSTACK(st, uparm2));
+ uparm2 += BPERI;
+ uparm1 -= BPERI;
+ }
+ else
+ {
+ PUSH(st, GETBSTACK(st, uparm2));
+ uparm2++;
+ uparm1--;
+ }
+ }
+ break;
+
+ /* Load & store: imm16 = unsigned base offset (One stack argument) */
+
+ case oST :
+ uparm1 = st->spb + imm16;
+ POP(st, uparm2);
+ PUTSTACK(st, uparm2, uparm1 + BPERI);
+ POP(st, uparm2);
+ PUTSTACK(st, uparm2, uparm1);
+ break;
+ case oSTH :
+ uparm1 = st->spb + imm16;
+ POP(st, uparm2);
+ PUTSTACK(st, uparm2, uparm1);
+ break;
+ case oSTB :
+ uparm1 = st->spb + imm16;
+ POP(st, uparm2);
+ PUTBSTACK(st, uparm2, uparm1);
+ break;
+ case oSTM :
+ /* FIX ME --> Need to handle the unaligned case */
+ POP(st, uparm1); /* Size */
+ uparm3 = uparm1; /* Save for stack discard */
+ uparm2 = st->spb + imm16;
+ sparm1 = ROUNDBTOI(uparm1) - 1;
+ while (uparm1 > 0)
+ {
+ if (uparm1 >= BPERI)
+ {
+ PUTSTACK(st, TOS(st, sparm1), uparm2);
+ uparm2 += BPERI;
+ uparm1 -= BPERI;
+ sparm1--;
+ }
+ else
+ {
+ PUTBSTACK(st, TOS(st, sparm1), uparm2);
+ uparm2++;
+ uparm1--;
+ }
+ }
+
+ /* Discard the stored data */
+
+ DISCARD(st, ROUNDBTOI(uparm3));
+ break;
+ case oLDX :
+ uparm1 = st->spb + imm16 + TOS(st, 0);
+ TOS(st, 0) = GETSTACK(st, uparm1);
+ PUSH(st, GETSTACK(st, uparm1 + BPERI));
+ break;
+ case oLDXH :
+ uparm1 = st->spb + imm16 + TOS(st, 0);
+ TOS(st, 0) = GETSTACK(st, uparm1);
+ break;
+ case oLDXB :
+ uparm1 = st->spb + imm16 + TOS(st, 0);
+ TOS(st, 0) = GETBSTACK(st, uparm1);
+ break;
+ case oLDXM :
+ /* FIX ME --> Need to handle the unaligned case */
+ POP(st, uparm1);
+ POP(st, uparm2);
+ uparm2 += st->spb + imm16;
+ while (uparm1 > 0)
+ {
+ if (uparm1 >= BPERI)
+ {
+ PUSH(st, GETSTACK(st, uparm2));
+ uparm2 += BPERI;
+ uparm1 -= BPERI;
+ }
+ else
+ {
+ PUSH(st, GETBSTACK(st, uparm2));
+ uparm2++;
+ uparm1--;
+ }
+ }
+ break;
+
+ /* Store: imm16 = unsigned base offset (Two stack arguments) */
+
+ case oSTXH :
+ POP(st, uparm1);
+ POP(st, uparm2);
+ uparm2 += st->spb + imm16;
+ PUTSTACK(st, uparm1,uparm2);
+ break;
+ case oSTXB :
+ POP(st, uparm1);
+ POP(st, uparm2);
+ uparm2 += st->spb + imm16;
+ PUTBSTACK(st, uparm1, uparm2);
+ break;
+ case oSTXM :
+/* FIX ME --> Need to handle the unaligned case */
+ POP(st, uparm1); /* Size */
+ uparm3 = uparm1; /* Save for stack discard */
+ sparm1 = ROUNDBTOI(uparm1); /* Size in 16-bit words */
+ uparm2 = TOS(st, sparm1); /* index */
+ sparm1--;
+ uparm2 += st->spb + imm16;
+ while (uparm1 > 0)
+ {
+ if (uparm1 >= BPERI)
+ {
+ PUTSTACK(st, TOS(st, sparm1), uparm2);
+ uparm2 += BPERI;
+ uparm1 -= BPERI;
+ sparm1--;
+ }
+ else
+ {
+ PUTBSTACK(st, TOS(st, sparm1), uparm2);
+ uparm2++;
+ uparm1--;
+ }
+ }
+
+ /* Discard the stored data + the index */
+
+ DISCARD(st, (ROUNDBTOI(uparm3) + 1));
+ break;
+
+ case oLA :
+ uparm1 = st->spb + imm16;
+ PUSH(st, uparm1);
+ break;
+ case oLAX :
+ TOS(st, 0) = st->spb + imm16 + TOS(st, 0);
+ break;
+
+ /* Data stack: imm16 = 16 bit signed data (no stack arguments) */
+
+ case oPUSH :
+ PUSH(st, imm16);
+ break;
+ case oINDS :
+ st->sp += signExtend16(imm16);
+ break;
+
+ /* System Functions:
+ * For LIB: imm16 = sub-function code
+ */
+
+ case oLIB :
+ ret = pexec_libcall(st, imm16);
+ break;
+
+ /* Program control: imm16 = unsigned label (no stack arguments) */
+
+ case oLAC :
+ uparm1 = imm16 + st->rop;
+ PUSH(st, uparm1);
+ break;
+
+ case oLABEL :
+ default:
+ ret = eILLEGALOPCODE;
+ break;
+ }
+
+ st->pc += 3;
+ return ret;
+
+branch_out:
+ st->pc = (paddr_t)imm16;
+ return ret;
+}
+
+/****************************************************************************
+ * Name: pexec32
+ *
+ * Descripton:
+ * Handle 32-bit instructions with 24-bits of immediate data (imm8+imm16)
+ *
+ ****************************************************************************/
+
+static int pexec32(FAR struct pexec_s *st, uint8_t opcode, uint8_t imm8, uint16_t imm16)
+{
+ sstack_t sparm;
+ ustack_t uparm1;
+ ustack_t uparm2;
+ ustack_t uparm3;
+ int ret = eNOERROR;
+
+ switch (opcode)
+ {
+ /* Load: imm8 = level; imm16 = signed frame offset (no stack arguments) */
+ case oLDS :
+ uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16);
+ PUSH(st, GETSTACK(st, uparm1));
+ PUSH(st, GETSTACK(st, uparm1 + BPERI));
+ break;
+ case oLDSH :
+ uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16);
+ PUSH(st, GETSTACK(st, uparm1));
+ break;
+ case oLDSB :
+ uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16);
+ PUSH(st, GETBSTACK(st, uparm1));
+ break;
+ case oLDSM :
+ /* FIX ME --> Need to handle the unaligned case */
+ POP(st, uparm1);
+ uparm2 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16);
+ while (uparm1 > 0)
+ {
+ if (uparm1 >= BPERI)
+ {
+ PUSH(st, GETSTACK(st, uparm2));
+ uparm2 += BPERI;
+ uparm1 -= BPERI;
+ }
+ else
+ {
+ PUSH(st, GETBSTACK(st, uparm2));
+ uparm2++;
+ uparm1--;
+ }
+ }
+ break;
+
+ /* Load & store: imm8 = level; imm16 = signed frame offset (One stack argument) */
+
+ case oSTSH :
+ uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16);
+ POP(st, uparm2);
+ PUTSTACK(st, uparm2, uparm1);
+ break;
+ case oSTSB :
+ uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16);
+ POP(st, uparm2);
+ PUTBSTACK(st, uparm2, uparm1);
+ break;
+ case oSTSM :
+ /* FIX ME --> Need to handle the unaligned case */
+ POP(st, uparm1); /* Size */
+ uparm3 = uparm1; /* Save for stack discard */
+ uparm2 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16);
+ sparm = ROUNDBTOI(uparm1) - 1;
+ while (uparm1 > 0)
+ {
+ if (uparm1 >= BPERI)
+ {
+ PUTSTACK(st, TOS(st, sparm), uparm2);
+ uparm2 += BPERI;
+ uparm1 -= BPERI;
+ sparm--;
+ }
+ else
+ {
+ PUTBSTACK(st, TOS(st, sparm), uparm2);
+ uparm2++;
+ uparm1--;
+ }
+ }
+
+ /* Discard the stored data */
+
+ DISCARD(st, ROUNDBTOI(uparm3));
+ break;
+ case oLDSX :
+ uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16) + TOS(st, 0);
+ TOS(st, 0) = GETSTACK(st, uparm1);
+ PUSH(st, GETSTACK(st, uparm1 + BPERI));
+ break;
+ case oLDSXH :
+ uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16) + TOS(st, 0);
+ TOS(st, 0) = GETSTACK(st, uparm1);
+ break;
+ case oLDSXB :
+ uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16) + TOS(st, 0);
+ TOS(st, 0) = GETBSTACK(st, uparm1);
+ break;
+ case oLDSXM :
+ /* FIX ME --> Need to handle the unaligned case */
+ POP(st, uparm1);
+ POP(st, uparm2);
+ uparm2 += pexec_getbaseaddress(st, imm8) + signExtend16(imm16);
+ while (uparm1 > 0)
+ {
+ if (uparm1 >= BPERI)
+ {
+ PUSH(st, GETSTACK(st, uparm2));
+ uparm2 += BPERI;
+ uparm1 -= BPERI;
+ }
+ else
+ {
+ PUSH(st, GETBSTACK(st, uparm2));
+ uparm2++;
+ uparm1--;
+ }
+ }
+ break;
+
+ /* Store: imm8 = level; imm16 = signed frame offset (Two stack arguments) */
+
+ case oSTSXH :
+ POP(st, uparm1);
+ POP(st, uparm2);
+ uparm2 += pexec_getbaseaddress(st, imm8) + signExtend16(imm16);
+ PUTSTACK(st, uparm1,uparm2);
+ break;
+ case oSTSXB :
+ POP(st, uparm1);
+ POP(st, uparm2);
+ uparm2 += pexec_getbaseaddress(st, imm8) + signExtend16(imm16);
+ PUTBSTACK(st, uparm1, uparm2);
+ break;
+ case oSTSXM :
+/* FIX ME --> Need to handle the unaligned case */
+ POP(st, uparm1); /* Size */
+ uparm3 = uparm1; /* Save for stack discard */
+ sparm = ROUNDBTOI(uparm1); /* Size in 16-bit words */
+ uparm2 = TOS(st, sparm); /* index */
+ sparm--;
+ uparm2 += pexec_getbaseaddress(st, imm8) + signExtend16(imm16);
+ while (uparm1 > 0)
+ {
+ if (uparm1 >= BPERI)
+ {
+ PUTSTACK(st, TOS(st, sparm), uparm2);
+ uparm2 += BPERI;
+ uparm1 -= BPERI;
+ sparm--;
+ }
+ else
+ {
+ PUTBSTACK(st, TOS(st, sparm), uparm2);
+ uparm2++;
+ uparm1--;
+ }
+ }
+
+ /* Discard the stored data + the index */
+
+ DISCARD(st, (ROUNDBTOI(uparm3) + 1));
+ break;
+
+ case oLAS :
+ uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16);
+ PUSH(st, uparm1);
+ break;
+ case oLASX :
+ TOS(st, 0) = pexec_getbaseaddress(st, imm8) + signExtend16(imm16) + TOS(st, 0);
+ break;
+
+ /* Program Control: imm8 = level; imm16 = unsigned label (No
+ * stack arguments)
+ */
+
+ case oPCAL :
+ PUSH(st, pexec_getbaseaddress(st, imm8));
+ PUSH(st, st->fp);
+ uparm1 = st->sp;
+ PUSH(st, st->pc + 4);
+ st->fp = uparm1;
+ st->pc = (paddr_t)imm16;
+ return eNOERROR;
+
+ /* System Functions:
+ * For SYSIO: imm8 = file number; imm16 = sub-function code
+ */
+
+ case oSYSIO :
+ ret = pexec_sysio(st, imm8, imm16);
+ break;
+
+ /* Pseudo-operations: (No stack arguments)
+ * For LINE: imm8 = file number; imm16 = line number
+ */
+
+ case oLINE :
+ default :
+ ret = eILLEGALOPCODE;
+ break;
+ }
+
+ st->pc += 4;
+ return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pexec_init
+ ****************************************************************************/
+
+FAR struct pexec_s *pexec_init(struct pexec_attr_s *attr)
+{
+ struct pexec_s *st;
+ paddr_t stacksize;
+ paddr_t adjusted_rosize;
+
+ /* Allocate the p-machine state stucture */
+
+ st = (struct pexec_s *)malloc(sizeof(struct pexec_s));
+ if (!st)
+ {
+ return NULL;
+ }
+
+ /* Set up I-Space */
+
+ st->ispace = attr->ispace;
+ st->maxpc = attr->maxpc;
+
+ /* Align size of read-only data to 16-bit boundary. */
+
+ adjusted_rosize = (attr->rosize + 1) & ~1;
+
+ /* Allocate the pascal stack. Organization is string stack, then
+ * constant data, then "normal" pascal stack.
+ */
+
+ stacksize = attr->varsize + adjusted_rosize + attr->strsize;
+ st->dstack.b = (uint8_t*)malloc(stacksize);
+ if (!st->dstack.b)
+ {
+ free(st);
+ return NULL;
+ }
+
+ /* Copy the rodata into the stack */
+
+ if (attr->rodata && attr->rosize)
+ {
+ memcpy(&st->dstack.b[attr->strsize], attr->rodata, attr->rosize);
+ }
+
+ /* Set up info needed to perform a simulated reset */
+
+ st->strsize = attr->strsize;
+ st->rosize = adjusted_rosize;
+ st->entry = attr->entry;
+ st->stacksize = stacksize;
+
+ /* Then perform a simulated reset */
+
+ pexec_reset(st);
+ return st;
+}
+
+/****************************************************************************
+ * Name: pexec
+ ****************************************************************************/
+
+int pexec(FAR struct pexec_s *st)
+{
+ uint8_t opcode;
+ int ret;
+
+ /* Make sure that the program counter is within range */
+
+ if (st->pc >= st->maxpc)
+ {
+ ret = eBADPC;
+ }
+ else
+ {
+ /* Get the instruction to execute */
+
+ opcode = st->ispace[st->pc];
+ if ((opcode & o8) != 0)
+ {
+ /* Get the immediate, 8-bit value */
+
+ uint8_t imm8 = st->ispace[st->pc + 1];
+ if ((opcode & o16) != 0)
+ {
+ /* Get the immediate, big-endian 16-bit value */
+
+ uint16_t imm16 = ((st->ispace[st->pc + 2]) << 8) | st->ispace[st->pc + 3];
+
+ /* Handle 32 bit instructions */
+
+ ret = pexec32(st, opcode, imm8, imm16);
+ }
+ else
+ {
+ /* Handle 16-bit instructions */
+
+ ret = pexec16(st, opcode, imm8);
+ }
+ }
+ else if ((opcode & o16) != 0)
+ {
+ /* Get the immediate, big-endian 16-bit value */
+
+ uint16_t imm16 = ((st->ispace[st->pc + 1]) << 8) | st->ispace[st->pc + 2];
+
+ /* Handle 24-bit instructions */
+
+ ret = pexec24(st, opcode, imm16);
+ }
+ else
+ {
+ /* Handle 8-bit instructions */
+
+ ret = pexec8(st, opcode);
+ }
+ }
+ return ret;
+}
+
+/****************************************************************************
+ * Name: pexec_reset
+ ****************************************************************************/
+
+void pexec_reset(struct pexec_s *st)
+{
+ int dndx;
+
+ /* Setup the bottom of the "normal" pascal stack */
+
+ st->rop = st->strsize;
+ st->spb = st->strsize + st->rosize;
+
+ /* Initialize the emulated P-Machine registers */
+
+ st->csp = 0;
+ st->sp = st->spb + 2*BPERI;
+ st->fp = st->spb + BPERI;
+ st->pc = st->entry;
+
+ /* Initialize the P-Machine stack */
+
+ dndx = BTOISTACK(st->spb);
+ st->dstack.i[dndx] = 0;
+ st->dstack.i[dndx+1] = 0;
+ st->dstack.i[dndx+2] = -1;
+}
+
+/****************************************************************************
+ * Name: pexec_release
+ ****************************************************************************/
+
+void pexec_release(struct pexec_s *st)
+{
+ if (st)
+ {
+ if (st->dstack.i)
+ {
+ free(st->dstack.i);
+ }
+
+ if (st->ispace)
+ {
+ free(st->ispace);
+ }
+
+ free(st);
+ }
+}
diff --git a/misc/pascal/insn16/prun/pload.c b/misc/pascal/insn16/prun/pload.c
new file mode 100644
index 000000000..744d99876
--- /dev/null
+++ b/misc/pascal/insn16/prun/pload.c
@@ -0,0 +1,176 @@
+/****************************************************************************
+ * pload.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "keywords.h"
+#include "pedefs.h"
+#include "pofflib.h"
+#include "perr.h"
+#include "pexec.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Constant Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+FAR struct pexec_s *pload(const char *filename, paddr_t varsize, paddr_t strsize)
+{
+ struct pexec_attr_s attr;
+ struct pexec_s *st;
+ poffHandle_t phandle;
+ FILE *exe;
+ uint16_t err;
+ uint8_t ftype;
+ uint8_t farch;
+
+ /* Create a handle to contain the executable data */
+
+ phandle = poffCreateHandle();
+ if (phandle == NULL) fatal(eNOMEMORY);
+
+ /* Open the executable file */
+
+ if (!(exe = fopen(filename, "rb")))
+ {
+ dbg("ERROR: Error opening '%s': %d\n", filename, errno);
+ goto errout_with_handle;
+ }
+
+ /* Load the POFF file into memory */
+
+ err = poffReadFile(phandle, exe);
+ if (err != eNOERROR)
+ {
+ dbg("ERROR: Could not read %s: %d\n", filename, err);
+ goto errout_with_file;
+ }
+
+ /* Verify that the file is a pascal executable */
+
+ ftype = poffGetFileType(phandle);
+ if (ftype != FHT_EXEC)
+ {
+ dbg("ERROR: File is not a pascal executable: %d\n", ftype);
+ goto errout_with_file;
+ }
+
+ farch = poffGetArchitecture(phandle);
+ if (farch != FHA_PCODE_INSN16)
+ {
+ dbg("ERROR: File is not 16-bit pcode: %d\n", farch);
+ goto errout_with_file;
+ }
+
+ /* Initialize the attribute structure */
+
+ attr.varsize = varsize;
+ attr.strsize = strsize;
+
+ /* Extract the program entry point from the pascal executable */
+
+ attr.entry = poffGetEntryPoint(phandle);
+
+ /* Close the POFF file */
+
+ (void)fclose(exe);
+
+ /* Extract the program data from the POFF image */
+
+ attr.maxpc = poffExtractProgramData(phandle, &attr.ispace);
+
+ /* Extract the read-only data from the POFF image */
+
+ attr.rosize = poffExtractRoData(phandle, &attr.rodata);
+
+ /* Destroy the POFF image */
+
+ poffDestroyHandle(phandle);
+
+ /* Initialize the p-code interpreter */
+
+ st = pexec_init(&attr);
+ if (!st && attr.ispace)
+ {
+ /* Initialization failed, discard the allocated I-Space */
+
+ free(st->ispace);
+ }
+
+ /* Discard the allocated RO data in any event */
+
+ if (attr.rodata)
+ {
+ free(attr.rodata);
+ }
+ return st;
+
+ errout_with_file:
+ (void)fclose(exe);
+
+ errout_with_handle:
+ poffDestroyHandle(phandle);
+ return NULL;
+}
diff --git a/misc/pascal/insn16/prun/prun.c b/misc/pascal/insn16/prun/prun.c
new file mode 100644
index 000000000..4dd33b2c3
--- /dev/null
+++ b/misc/pascal/insn16/prun/prun.c
@@ -0,0 +1,278 @@
+/****************************************************************************
+ * prun.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pinsn16.h"
+#include "pxdefs.h"
+#include "pedefs.h"
+
+#include "paslib.h"
+#include "perr.h"
+#include "pexec.h"
+#include "pdbg.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+#define MIN_STACK_SIZE 1024
+#define DEFAULT_STACK_SIZE 4096
+#define DEFAULT_STKSTR_SIZE 0
+
+/****************************************************************************
+ * Private Type Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Constant Data
+ ****************************************************************************/
+
+static const struct option long_options[] =
+{
+ {"stack", 1, NULL, 's'},
+ {"string", 1, NULL, 't'},
+ {"debug", 0, NULL, 'd'},
+ {"help", 0, NULL, 'h'},
+ {NULL, 0, NULL, 0}
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const char *g_pofffilename;
+static int32_t g_varstacksize = DEFAULT_STACK_SIZE;
+static int32_t g_strstacksize = DEFAULT_STKSTR_SIZE;
+static int g_debug = 0;
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: prun_showusage
+ ****************************************************************************/
+
+static void prun_showusage(const char *progname)
+{
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s [options] <program-filename>\n",
+ progname);
+ fprintf(stderr, "options:\n");
+ fprintf(stderr, " -s <stack-size>\n");
+ fprintf(stderr, " --stack <stack-size>\n");
+ fprintf(stderr, " Memory in bytes to allocate for the pascal program\n");
+ fprintf(stderr, " stack in bytes (minimum is %d; default is %d bytes)\n",
+ MIN_STACK_SIZE, DEFAULT_STACK_SIZE);
+ fprintf(stderr, " -t <stack-size>\n");
+ fprintf(stderr, " --string <string-storage-size>\n");
+ fprintf(stderr, " Memory in bytes to allocate for the pascal program\n");
+ fprintf(stderr, " string storage in bytes (default is %d bytes)\n",
+ DEFAULT_STKSTR_SIZE);
+ fprintf(stderr, " -d\n");
+ fprintf(stderr, " --debug\n");
+ fprintf(stderr, " Enable PCode program debugger\n");
+ fprintf(stderr, " -h\n");
+ fprintf(stderr, " --help\n");
+ fprintf(stderr, " Shows this message\n");
+ exit(1);
+}
+
+/****************************************************************************
+ * Name: prun_parseargs
+ ****************************************************************************/
+
+static void prun_parseargs(int argc, char **argv)
+{
+ int option_index;
+ int size;
+ int c;
+
+ /* Check for existence of filename argument */
+
+ if (argc < 2)
+ {
+ fprintf(stderr, "ERROR: Filename required\n");
+ prun_showusage(argv[0]);
+ } /* end if */
+
+ /* Parse the command line options */
+
+ do
+ {
+ c = getopt_long (argc, argv, "t:s:dh",
+ long_options, &option_index);
+ if (c != -1)
+ {
+ switch (c)
+ {
+ case 's' :
+ size = atoi(optarg);
+ if (size < MIN_STACK_SIZE)
+ {
+ fprintf(stderr, "ERROR: Invalid stack size\n");
+ prun_showusage(argv[0]);
+ }
+ g_varstacksize = (size + 3) & ~3;
+ break;
+
+ case 't' :
+ size = atoi(optarg);
+ if (size < 0)
+ {
+ fprintf(stderr, "ERROR: Invalid string storage size\n");
+ prun_showusage(argv[0]);
+ }
+ g_strstacksize = ((size + 3) & ~3);
+ break;
+
+ case 'd' :
+ g_debug++;
+ break;
+
+ case 'h' :
+ prun_showusage(argv[0]);
+ break;
+
+ default:
+ /* Shouldn't happen */
+
+ fprintf(stderr, "ERROR: Unrecognized option\n");
+ prun_showusage(argv[0]);
+ }
+ }
+ }
+ while (c != -1);
+
+ if (optind != argc-1)
+ {
+ fprintf(stderr, "ERROR: Only one filename permitted on command line\n");
+ prun_showusage(argv[0]);
+ }
+
+ /* Get the name of the p-code file(s) from the last argument(s) */
+
+ g_pofffilename = argv[argc-1];
+}
+
+/****************************************************************************
+ * Name: prun
+ *
+ * Description:
+ * This function executes the P-Code program until a stopping condition
+ * is encountered.
+ *
+ ****************************************************************************/
+
+static void prun(struct pexec_s *st)
+{
+ int errcode;
+
+ for (;;)
+ {
+ /* Execute the instruction; Check for exceptional conditions */
+
+ errcode = pexec(st);
+ if (errcode != eNOERROR) break;
+ }
+
+ if (errcode != eEXIT)
+ {
+ printf("Runtime error 0x%02x -- Execution Stopped\n", errcode);
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: main
+ ****************************************************************************/
+
+int main(int argc, char *argv[], char *envp[])
+{
+ struct pexec_s *st;
+ char fileName[FNAME_SIZE+1]; /* Object file name */
+
+ /* Parse the command line arguments */
+
+ prun_parseargs(argc, argv);
+
+ /* Load the POFF files specified on the command line */
+ /* Use .o or command line extension, if supplied */
+
+ (void)extension(g_pofffilename, "o", fileName, 0);
+
+ /* Load the POFF file */
+
+ st = pload(fileName, g_varstacksize, g_strstacksize);
+ if (!st)
+ {
+ fprintf(stderr, "ERROR: Could not load %s\n", fileName);
+ exit(1);
+ } /* end if */
+ printf("%s Loaded\n", fileName);
+
+ /* And start program execution in the specified mode */
+
+ if (g_debug)
+ dbg_run(st);
+ else
+ prun(st);
+
+ /* Clean up resources used by the interpreter */
+
+ pexec_release(st);
+ return 0;
+
+} /* end main */
diff --git a/misc/pascal/insn32/Makefile b/misc/pascal/insn32/Makefile
new file mode 100644
index 000000000..d02de859b
--- /dev/null
+++ b/misc/pascal/insn32/Makefile
@@ -0,0 +1,92 @@
+############################################################################
+# insn32/Makefile
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Directories
+#
+INSNDIR = ${shell pwd}
+PASCAL = $(INSNDIR)/..
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+LIBDIR = $(PASCAL)/lib
+BINDIR = $(PASCAL)/bin32
+LIBINSNDIR = $(INSNDIR)/libinsn
+POPTDIR = $(INSNDIR)/popt
+REGMDIR = $(INSNDIR)/regm
+PRUNDIR = $(INSNDIR)/prun
+PLISTDIR = $(INSNDIR)/plist
+
+#
+# Objects and targets
+#
+#all: libinsn popt regm prun plist
+all: libinsn popt regm plist
+PHONY: all libinsn popt regm prun plist clean
+
+$(LIBINSNDIR)/libinsn.a:
+ $(MAKE) -C $(LIBINSNDIR)
+
+libinsn.a: $(LIBINSNDIR)/libinsn.a
+
+$(BINDIR)/popt:
+ $(MAKE) -C $(POPTDIR)
+
+popt: $(BINDIR)/popt
+
+$(BINDIR)/regm:
+ $(MAKE) -C $(REGMDIR)
+ @#touch $(BINDIR)/regm
+
+regm: $(BINDIR)/regm
+
+$(BINDIR)/prun:
+ @#$(MAKE) -C $(PRUNDIR)
+ touch $(BINDIR)/prun
+
+prun: $(BINDIR)/prun
+
+$(BINDIR)/plist:
+ $(MAKE) -C $(PLISTDIR)
+
+plist: $(BINDIR)/plist
+
+clean:
+ $(RM) libinsn.a core *~
+ $(MAKE) -C $(LIBINSNDIR) clean
+ $(MAKE) -C $(POPTDIR) clean
+ $(MAKE) -C $(REGMDIR) clean
+ @#$(MAKE) -C $(PRUNDIR) clean
+ $(MAKE) -C $(PLISTDIR) clean
diff --git a/misc/pascal/insn32/doc/insn32.txt b/misc/pascal/insn32/doc/insn32.txt
new file mode 100644
index 000000000..3bb7bc700
--- /dev/null
+++ b/misc/pascal/insn32/doc/insn32.txt
@@ -0,0 +1,119 @@
+32-bit op-code bit definitions
+
+Machine model:
+
+ SPB 32-bit Pascal stack base address
+ SP 32-bit Pascal stack pointer
+ LSP 32-bit Level stack pointer
+ CSB 32-bit Character stack base address
+ CSP 32-bit Character stack pointer
+ DS 32-bit Data size register (for multiple reg transfers)
+ PC 32-bit Program Counter
+ CC Condition code register
+ --- Volatile general purpose registers
+ --- Static general purpose registers
+
+Condition codes: Z(ero), N(egative)
+
+ +=====+=====+
+ | Z | N |
+ +=====+=====+=====+
+ | EQ | 1 | - |
+ | NEQ | 0 | - |
+ | LT | - | 1 |
+ | GTE | - | 0 |
+ | GT | 0 | 0 |
+ | LTE | 1 | 1 |
+ +=====+=====+=====+
+
+Opcode Encoding Summary:
+
+ 0rxx xxxx 1rxxx xxxx
+xr00 0000 NOP LD uoffs4
+xr00 0001 NEG LDH uoffs3
+xr00 0010 ABS LDB uoffs
+xr00 0011 INC LDM uoffs4
+xr00 0100 DEC ST uoffs4
+xr00 0101 NOT STH uoffs2
+xr00 0110 ADD STB uoffs
+xr00 0111 SUB STM uoffs4
+xr00 1000 MUL LDX uoffs4
+xr00 1001 DIV LDXH uoffs2
+xr00 1010 MOD LDXB uoffs
+xr00 1011 SLL LDXM uoffs4
+xr00 1100 SRL STX uoffs4
+xr00 1101 SRA STXH uoffs2
+xr00 1110 OR STXB uoffs
+xr00 1111 AND STXM uoffs
+
+xr01 0000 EQUZ JEQUZ ilbl
+xr01 0001 NEQZ JNEQZ ilbl
+xr01 0010 LTZ JLTZ ilbl
+xr01 0011 GTEZ JGTEZ ilbl
+xr01 0100 GTZ JGTZ ilbl
+xr01 0101 LTEZ JLTEZ ilbl
+xr01 0110 --- JMP ilbl
+xr01 0111 --- PUSH nn
+xr01 1000 EQU JEQU ilbl
+xr01 1001 NEQ JNEQ ilbl
+xr01 1010 LT JLT ilbl
+xr01 1011 GTE JGTE ilbl
+xr01 1100 GT JGT ilbl
+xr01 1101 LTE JLTE ilbl
+xr01 1110 --- ---
+xr01 1111 BIT INDS nn
+
+xr10 0000 LDI LDS offs4
+xr10 0001 LDIH LDSH offs3
+xr10 0010 LDIB LDSB offs
+xr10 0011 LDIM LDSM offs4
+xr10 0100 STI STS offs4
+xr10 0101 STIH STSH offs2
+xr10 0110 STIB STSB offs
+xr10 0111 STIM STSM offs4
+xr10 1000 DUP LDSX offs4
+xr10 1001 --- LDSXH offs2
+xr10 1010 PUSHS LDSXB offs
+xr10 1011 POPS LDSXM offs4
+xr10 1100 --- STSX offs4
+xr10 1101 --- STSXH offs2
+xr10 1110 --- STSXB offs
+xr10 1111 RET STSXM offs
+
+xr11 0000 --- LA uoffs
+xr11 0001 --- LAS offs
+xr11 0010 --- LAC dlbl
+xr11 0011 --- ---
+xr11 0100 --- LAX uoffs
+xr11 0101 --- LASX offs
+xr11 0110 --- SLSP level
+xr11 0111 --- SDC uu
+xr11 1000 --- ---
+xr11 1001 --- PCAL ilbl
+xr11 1010 --- SYSIO fn,sop
+xr11 1011 --- LIB lop
+xr11 1100 --- FLOAT fop
+xr11 1101 --- *LABEL ilbl
+xr11 1110 --- *INCLUDE fn
+xr11 1111 END *LINE lineno
+
+KEY:
+ r = Reserved bit (must be zero)
+ fn = 8-bit file number
+ lvl = 8-bit static nexting level
+ sop = 17-bit sysio operation
+ lineno = 17-bit line number
+ nn = 32-bit constant value (signed)
+ uu = 32-bit constant value (unsigned)
+ fop = 32-bit floating point operation
+ lop = 32-bit library call identifier
+ ilbl = 32-bit Instruction space label number
+ dlbl = 32-stack data label
+ offs4 = 32-bit word offset with respect to LSP (signed)
+ offs2 = 32-bit halfword offset with respect to LSP (signed)
+ offs = 32-bit byte offset with respect to LSP (signed)
+ uoffs4 = 32-bit word offset with respect to SPB (unsigned)
+ uoffs2 = 32-bit halfword offset with respect to SPB (unsigned)
+ uoffs = 32-bit byte offset with respect to SPB (unsigned)
+ c = string follows pseudo-operation
+ = Indicates pseudo-operations (these are removed
diff --git a/misc/pascal/insn32/include/builtins.h b/misc/pascal/insn32/include/builtins.h
new file mode 100644
index 000000000..6fe3dc919
--- /dev/null
+++ b/misc/pascal/insn32/include/builtins.h
@@ -0,0 +1,450 @@
+/***********************************************************************
+ * builtins.h
+ * Definitions of built-in function calls.
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************************************/
+
+#ifndef __BUILTINS_H
+#define __BUILTINS_H
+
+/***********************************************************************
+ * Included Files
+ ***********************************************************************/
+
+#include <stdint.h>
+
+/***********************************************************************
+ * Pre-processor Definitions
+ ***********************************************************************/
+
+#define MAX_BUILTIN_ARGS 3
+
+#define ILLEGAL_BUILTIN_INIT \
+ { NULL, 0, 0, { 0 }}
+
+/* SYSIO built-ins ****************y*************************************/
+
+/* boolean _xeof(fileno); */
+#define xEOF_INIT \
+ { "_xeof", sBOOLEAN_SIZE, 1, { sINT_SIZE }}
+
+/* boolean _xeoln(fileno); */
+#define xEOLN_INIT \
+ { "_xeoln", sBOOLEAN_SIZE, 1, { sINT_SIZE }}
+
+/* void _xreset(int fileno); */
+#define xRESET_INIT \
+ { "_xreset", 0, 1, { sINT_SIZE }}
+
+/* void _xrewrite(int fileno); */
+#define xREWRITE_INIT \
+ { "_xrewrite", 0, 1, { sINT_SIZE }}
+
+/* void _xreadln(int fileno); */
+#define xREADLN_INIT \
+ { "_xreadln", 0, 1, { sINT_SIZE }}
+
+#define xREAD_PAGE_INIT ILLEGAL_BUILTIN_INIT
+
+/* void _xread_binary(int fileno, char *buffer, int buffersize); */
+#define xREAD_BINARY_INIT \
+ { "_xread_binary", 0, 3, { sINT_SIZE, sPTR_SIZE, sINT_SIZE }}
+
+/* void _xread_int(int fileno, int *value); */
+#define xREAD_INT_INIT \
+ { "_xread_int", 0, 2, { sINT_SIZE, sPTR_SIZE }}
+
+/* void _xread_char(int fileno, char *value); */
+#define xREAD_CHAR_INIT \
+ { "_xread_char", 0, 2, { sINT_SIZE, sPTR_SIZE }}
+
+/* void _xread_string(int fileno, char *string, int stringsize); */
+#define xREAD_STRING_INIT \
+ { "_xread_string", 0, 3, { sINT_SIZE, sPTR_SIZE, sINT_SIZE }}
+
+/* void _xread_real(int fileno, real *value); */
+#define xREAD_REAL_INIT \
+ { "_xread_real", 0, 2, { sINT_SIZE, sPTR_SIZE }}
+
+/* void _xwriteln(int fileno); */
+#define xWRITELN_INIT \
+ { "_xwriteln", 0, 1, { sINT_SIZE }}
+
+/* void _xwrite_page(int fileno); */
+#define xWRITE_PAGE_INIT \
+ { "_xwrite_page", 0, 1, { sINT_SIZE }}
+
+/* void _write_binary(int fileno, char *buffer, int buffersize); */
+#define xWRITE_BINARY_INIT \
+ { "_xwrite_binary", 0, 3, { sINT_SIZE, sPTR_SIZE, sINT_SIZE }}
+
+/* void _write_int(int fileno, int value); */
+#define xWRITE_INT_INIT \
+ { "_xwrite_int", 0, 2, { sINT_SIZE, sINT_SIZE }}
+
+/* void _write_char(int fileno, int value); */
+#define xWRITE_CHAR_INIT \
+ { "_xwrite_char", 0, 2, { sINT_SIZE, sINT_SIZE }}
+
+/* void _write_string(int fileno, char *string, int stringsize); */
+#define xWRITE_STRING_INIT \
+ { "_xwrite_string", 0, 3, { sINT_SIZE, sPTR_SIZE, sINT_SIZE }}
+
+/* void _write_real(int fileno, real value); */
+#define xWRITE_REAL_INIT \
+ { "_xwrite_real", 0, 2, { sINT_SIZE, sREAL_SIZE }}
+
+/* Runtime library built-ins *******************************************/
+/* string _lbgetenv(string *name); */
+#define lbGETENV_INIT \
+ { "_lbgetenv", sRSTRING_SIZE, 1, { sRSTRING_SIZE }}
+
+/* void _lbstr2str(string src, string dest); */
+#define lbSTR2STR_INIT \
+ { "_lbstgr2str", 0, 2, { sRSTRING_SIZE, sRSTRING_SIZE }}
+
+/* void _lbcstr2str(string src, string dest); */
+#define lbCSTR2STR_INIT \
+ { "_lbcstr2str", 0, 2, { sRSTRING_SIZE, sRSTRING_SIZE }}
+
+/* void _libstr2rstr(string src, string dest); */
+#define lbSTR2RSTR_INIT \
+ { "_lbstr2rstr", 0, 2, { sRSTRING_SIZE, sRSTRING_SIZE }}
+
+/* void _lbcstr2str(string src, string dest); */
+#define lbCSTR2RSTR_INIT \
+ { "_lbcstr2rstr", 0, 2, { sRSTRING_SIZE, sRSTRING_SIZE }}
+
+/* void _lbval(const string s, int *v, int *code); */
+#define lbVAL_INIT \
+ { "_lbval", 0, 2, { sRSTRING_SIZE, sPTR_SIZE, sPTR_SIZE }}
+
+/* string _lbmkstk(void); */
+#define lbMKSTK_INIT \
+ { "_lbmkstk", sRSTRING_SIZE, 0, { 0 }}
+
+/* string mkstkstr(string name); */
+#define lbMKSTKSTR_INIT \
+ { "_lbmkstkstr", sRSTRING_SIZE, 1, { sRSTRING_SIZE }}
+
+/* string _lbmkstkc(int c); */
+#define lbMKSTKC_INIT \
+ { "_lbmkstkc", sRSTRING_SIZE, 1, { sINT_SIZE }}
+
+/* string _lbstgrcat(string name, int c); */
+#define lbSTRCAT_INIT \
+ { "_lbstrcat", sRSTRING_SIZE, 2, { sRSTRING_SIZE, sINT_SIZE }}
+
+/* string _lbstrcatc(string name, int c); */
+#define lbSTRCATC_INIT \
+ { "_lbstrcatc", sRSTRING_SIZE, 2, { sRSTRING_SIZE, sINT_SIZE }}
+
+/* int _lbstrcmp(string name1, string name2); */
+#define lbSTRCMP_INIT \
+ { "_lbstrcmp", sINT_SIZE, 2, { sRSTRING_SIZE, sRSTRING_SIZE }}
+
+/* Floating point library built-ins ************************************/
+
+/* real _fpfloat(int v); */
+#define fpFLOAT_INIT \
+ { "_fpfloat", sREAL_SIZE, 1, { sINT_SIZE }}
+
+/* int _fptrunc(real v); */
+#define fpTRUNC_INIT \
+ { "_fptrunc", sINT_SIZE, 1, { sREAL_SIZE }}
+
+/* int _fpround(real v); */
+#define fpROUND_INIT \
+ { "_fpround", sINT_SIZE, 1, { sREAL_SIZE }}
+
+/* real _fpadd_rr(real a, real b); */
+#define fpADD_RR_INIT \
+ { "_fpadd_rr", sREAL_SIZE, 2, { sREAL_SIZE, sREAL_SIZE }}
+
+/* real _fpadd_ri(int a, real b); */
+#define fpADD_RI_INIT \
+ { "_fpadd_ri", sREAL_SIZE, 2, { sINT_SIZE, sREAL_SIZE }}
+
+/* real _fpadd_ir(real a, int b); */
+#define fpADD_IR_INIT \
+ { "_fpadd_ir", sREAL_SIZE, 2, { sREAL_SIZE, sINT_SIZE }}
+
+/* real _fpadd_ii(int a, int b); */
+#define fpADD_II_INIT \
+ { "_fpadd_ii", sREAL_SIZE, 2, { sINT_SIZE, sINT_SIZE }}
+
+/* real _fpsub_rr(real a, real b); */
+#define fpSUB_RR_INIT \
+ { "_fpsub_rr", sREAL_SIZE, 2, { sREAL_SIZE, sREAL_SIZE }}
+
+/* real _fpsub_ri(int a, real b); */
+#define fpSUB_RI_INIT \
+ { "_fpsub_ri", sREAL_SIZE, 2, { sINT_SIZE, sREAL_SIZE }}
+
+/* real _fpsub_ir(real a, int b); */
+#define fpSUB_IR_INIT \
+ { "_fpsub_ir", sREAL_SIZE, 2, { sREAL_SIZE, sINT_SIZE }}
+
+/* real _fpsub_ii(int a, int b); */
+#define fpSUB_II_INIT \
+ { "_fpsub_ii", sREAL_SIZE, 2, { sINT_SIZE, sINT_SIZE }}
+
+/* real _fpmul_rr(real a, real b); */
+#define fpMUL_RR_INIT \
+ { "_fpmul_rr", sREAL_SIZE, 2, { sREAL_SIZE, sREAL_SIZE }}
+
+/* real _fpmul_ri(int a, real b); */
+#define fpMUL_RI_INIT \
+ { "_fpmul_ri", sREAL_SIZE, 2, { sINT_SIZE, sREAL_SIZE }}
+
+/* real _fpmul_ir(real a, int b); */
+#define fpMUL_IR_INIT \
+ { "_fpmul_ir",sREAL_SIZE, 2, { sREAL_SIZE, sINT_SIZE }}
+
+/* real _fpmul_ii(int a, int b); */
+#define fpMUL_II_INIT \
+ { "_fpmul_ii", sREAL_SIZE, 2, { sINT_SIZE, sINT_SIZE }}
+
+/* real _fpdiv_rr(real a, real b); */
+#define fpDIV_RR_INIT \
+ { "_fpdiv_rr", sREAL_SIZE, 2, { sREAL_SIZE, sREAL_SIZE }}
+
+/* real _fpdiv_ri(int a, real b); */
+#define fpDIV_RI_INIT \
+ { "_fpdiv_ri",sREAL_SIZE, 2, { sINT_SIZE, sREAL_SIZE }}
+
+/* real _fpdiv_ir(real a, int b); */
+#define fpDIV_IR_INIT \
+ { "_fpdiv_ir",sREAL_SIZE, 2, { sREAL_SIZE, sINT_SIZE }}
+
+/* real _fpdiv_ii(int a, int b); */
+#define fpDIV_II_INIT \
+ { "_fpdiv_ii",sREAL_SIZE, 2, { sINT_SIZE, sINT_SIZE }}
+
+/* real _fpmod_rr(real a, real b); */
+#define fpMOD_RR_INIT \
+ { "_fpmod_rr", sREAL_SIZE, 2, { sREAL_SIZE, sREAL_SIZE }}
+
+/* real _fpmod_ri(int a, real b); */
+#define fpMOD_RI_INIT \
+ { "_fpmod_ri", sREAL_SIZE, 2, { sINT_SIZE, sREAL_SIZE }}
+
+/* real _fpmod_ir(real a, int b); */
+#define fpMOD_IR_INIT \
+ { "_fpmod_ir", sREAL_SIZE, 2, { sREAL_SIZE, sINT_SIZE }}
+
+/* real _fpmod_ii(int a, int b); */
+#define fpMOD_II_INIT \
+ { "_fpmod_ii", sREAL_SIZE, 2, { sINT_SIZE, sINT_SIZE }}
+
+/* boolean _fpequ_rr(real a, real b); */
+#define fpEQU_RR_INIT \
+ { "_fpequ_rr", sBOOLEAN_SIZE, 2, { sREAL_SIZE, sREAL_SIZE }}
+
+/* boolean _fpequ_ri(int a, real b); */
+#define fpEQU_RI_INIT \
+ { "_fpequ_ri", sBOOLEAN_SIZE, 2, { sINT_SIZE, sREAL_SIZE }}
+
+/* boolean _fpequ_ir(real a, int b); */
+#define fpEQU_IR_INIT \
+ { "_fpequ_ir", sBOOLEAN_SIZE, 2, { sREAL_SIZE, sINT_SIZE }}
+
+/* boolean _fpequ_ii(int a, int b); */
+#define fpEQU_II_INIT \
+ { "_fpequ_ii", sBOOLEAN_SIZE, 2, { sINT_SIZE, sINT_SIZE }}
+
+/* boolean _fpneq_rr(real a, real b); */
+#define fpNEQ_RR_INIT \
+ { "_fpneq_rr", sBOOLEAN_SIZE, 2, { sREAL_SIZE, sREAL_SIZE }}
+
+/* boolean _fpneq_ri(int a, real b); */
+#define fpNEQ_RI_INIT \
+ { "_fpneq_ri", sBOOLEAN_SIZE, 2, { sINT_SIZE, sREAL_SIZE }}
+
+/* boolean _fpneq_ir(real a, int b); */
+#define fpNEQ_IR_INIT \
+ { "_fpneq_ir", sBOOLEAN_SIZE, 2, { sREAL_SIZE, sINT_SIZE }}
+
+/* boolean _fpneq_ii(int a, int b); */
+#define fpNEQ_II_INIT \
+ { "_fpneq_ii", sBOOLEAN_SIZE, 2, { sINT_SIZE, sINT_SIZE }}
+
+/* boolean _fplt_rr(real a, real b); */
+#define fpLT_RR_INIT \
+ { "_fplt_rr", sBOOLEAN_SIZE, 2, { sREAL_SIZE, sREAL_SIZE }}
+
+/* boolean _fplt_ri(int a, real b); */
+#define fpLT_RI_INIT \
+ { "_fplt_ri", sBOOLEAN_SIZE, 2, { sINT_SIZE, sREAL_SIZE }}
+
+/* boolean _fplt_ir(real a, int b); */
+#define fpLT_IR_INIT \
+ { "_fplt_ir", sBOOLEAN_SIZE, 2, { sREAL_SIZE, sINT_SIZE }}
+
+/* boolean _fplt_ii(int a, int b); */
+#define fpLT_II_INIT \
+ { "_fplt_ii", sBOOLEAN_SIZE, 2, { sINT_SIZE, sINT_SIZE }}
+
+/* boolean _fpgte_rr(real a, real b); */
+#define fpGTE_RR_INIT \
+ { "_fpgte_rr", sBOOLEAN_SIZE, 2, { sREAL_SIZE, sREAL_SIZE }}
+
+/* boolean _fpgte_ri(int a, real b); */
+#define fpGTE_RI_INIT \
+ { "_fpgte_ri", sBOOLEAN_SIZE, 2, { sINT_SIZE, sREAL_SIZE }}
+
+/* boolean _fpgte_ir(real a, int b); */
+#define fpGTE_IR_INIT \
+ { "_fpgte_ir", sBOOLEAN_SIZE, 2, { sREAL_SIZE, sINT_SIZE }}
+
+/* boolean _fpgte_ii(int a, int b); */
+#define fpGTE_II_INIT \
+ { "_fpgte_ii", sBOOLEAN_SIZE, 2, { sINT_SIZE, sINT_SIZE }}
+
+/* boolean _fpgt_rr(real a, real b); */
+#define fpGT_RR_INIT \
+ { "_fpgt_rr", sBOOLEAN_SIZE, 2, { sREAL_SIZE, sREAL_SIZE }}
+
+/* boolean _fpgt_ri(int a, real b); */
+#define fpGT_RI_INIT \
+ { "_fpgt_ri", sBOOLEAN_SIZE, 2, { sINT_SIZE, sREAL_SIZE }}
+
+/* boolean _fpgt_ir(real a, int b); */
+#define fpGT_IR_INIT \
+ { "_fpgt_ir", sBOOLEAN_SIZE, 2, { sREAL_SIZE, sINT_SIZE }}
+
+/* boolean _fpgt_ii(int a, int b); */
+#define fpGT_II_INIT \
+ { "_fpgt_ii", sBOOLEAN_SIZE, 2, { sINT_SIZE, sINT_SIZE }}
+
+/* boolean _fplte_rr(real a, real b); */
+#define fpLTE_RR_INIT \
+ { "_fplte_rr", sBOOLEAN_SIZE, 2, { sREAL_SIZE, sREAL_SIZE }}
+
+/* boolean _fplte_ri(int a, real b); */
+#define fpLTE_RI_INIT \
+ { "_fplte_ri", sBOOLEAN_SIZE, 2, { sINT_SIZE, sREAL_SIZE }}
+
+/* boolean _fplte_ir(real a, int b); */
+#define fpLTE_IR_INIT \
+ { "_fplte_ir", sBOOLEAN_SIZE, 2, { sREAL_SIZE, sINT_SIZE }}
+
+/* boolean _fplte_ii(int a, int b); */
+#define fpLTE_II_INIT \
+ { "_fplte_ii", sBOOLEAN_SIZE, 2, { sINT_SIZE, sINT_SIZE }}
+
+/* real _fpneg_r(real v); */
+#define fpNEG_R_INIT \
+ { "_fpneg_r", sREAL_SIZE, 1, { sREAL_SIZE }}
+
+/* real _fpneg_i(int v); */
+#define fpNEG_I_INIT \
+ { "_fpneg_i", sREAL_SIZE, 1, { sINT_SIZE }}
+
+/* real _fpabs_r(real v); */
+#define fpABS_R_INIT \
+ { "_fpabs_r", sREAL_SIZE, 1, { sREAL_SIZE }}
+
+/* real _fpabs_i(int v); */
+#define fpABS_I_INIT \
+ { "_fpabs_i", sREAL_SIZE, 1, { sINT_SIZE }}
+
+/* real _fpsqr_r(real v); */
+#define fpSQR_R_INIT \
+ { "_fpsqr_r", sREAL_SIZE, 1, { sREAL_SIZE }}
+
+/* real _fpsqr_i(int v); */
+#define fpSQR_I_INIT \
+ { "_fpsqr_i", sREAL_SIZE, 1, { sINT_SIZE }}
+
+/* real _fpsqrt_r(real v); */
+#define fpSQRT_R_INIT \
+ { "_fpsqrt_r", sREAL_SIZE, 1, { sREAL_SIZE }}
+
+/* real _fpsqrt_i(int v); */
+#define fpSQRT_I_INIT \
+ { "_fpsqrt_i", sREAL_SIZE, 1, { sINT_SIZE }}
+
+/* real _fpsin_r(real v); */
+#define fpSIN_R_INIT \
+ { "_fpsin_r", sREAL_SIZE, 1, { sREAL_SIZE }}
+
+/* real _fpsin_i(int v); */
+#define fpSIN_I_INIT \
+ { "_fpsin_i", sREAL_SIZE, 1, { sINT_SIZE }}
+
+/* real _fpcos_r(real v); */
+#define fpCOS_R_INIT \
+ { "_fpcos_r", sREAL_SIZE, 1, { sREAL_SIZE }}
+
+/* real _fpcos_i(int v); */
+#define fpCOS_I_INIT \
+ { "_fpcos_i", sREAL_SIZE, 1, { sINT_SIZE }}
+
+/* real _fpatan_r(real v); */
+#define fpATAN_R_INIT \
+ { "_fpatan_r", sREAL_SIZE, 1, { sREAL_SIZE }}
+
+/* real _fpatan_i(int v); */
+#define fpATAN_I_INIT \
+ { "_fpatan_i", sREAL_SIZE, 1, { sINT_SIZE }}
+
+/* real _fpln_r(real v); */
+#define fpLN_R_INIT \
+ { "_fpln_r", sREAL_SIZE, 1, { sREAL_SIZE }}
+
+/* real _fpln_i(int v); */
+#define fpLN_I_INIT \
+ { "_fpln_i", sREAL_SIZE, 1, { sINT_SIZE }}
+
+/* real _fpexp_r(real v); */
+#define fpEXP_R_INIT \
+ { "_fpexpr_r", sREAL_SIZE, 1, { sREAL_SIZE }}
+
+/* real _fpexp_i(int v); */
+#define fpEXP_I_INIT \
+ { "_fpexpr_i", sREAL_SIZE, 1, { sINT_SIZE }}
+
+/***********************************************************************
+ * Public Types
+ ***********************************************************************/
+
+struct regm_builtin_s
+{
+ const char *szName;
+ uint32_t wRetSize;
+ uint32_t nParms;
+ uint32_t wArgSize[MAX_BUILTIN_ARGS];
+};
+
+#endif /* __BUILTINS_H */
diff --git a/misc/pascal/insn32/include/pexec.h b/misc/pascal/insn32/include/pexec.h
new file mode 100644
index 000000000..647a1d88c
--- /dev/null
+++ b/misc/pascal/insn32/include/pexec.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+ * pexec.h
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __PEXEC_H
+#define __PEXEC_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+#define BPERI 2
+#define ITOBSTACK(i) ((i) << 1)
+#define BTOISTACK(i) ((i) >> 1)
+#define ROUNDBTOI(i) (((i) + 1) >> 1)
+
+/****************************************************************************
+ * Type Definitions
+ ****************************************************************************/
+
+typedef uint32_t ustack_t; /* Stack values are 16-bits in length */
+typedef int32_t sstack_t;
+typedef uint32_t paddr_t; /* Addresses are 16-bits in length */
+typedef uint16_t level_t; /* Limits to MAXUINT16 levels */
+
+union stack_u
+{
+ ustack_t *i;
+ uint8_t *b;
+};
+typedef union stack_u stackType;
+
+/* This structure describes the parameters needed to initialize the p-code
+ * interpreter.
+ */
+
+struct pexec_attr_s
+{
+ /* Instruction space (I-Space) */
+
+ FAR uint8_t *ispace; /* Allocated I-Space containing p-code data */
+ paddr_t entry; /* Entry point */
+ paddr_t maxpc; /* Last valid p-code address */
+
+ /* Read-only data block */
+
+ FAR uint8_t *rodata; /* Address of read-only data block */
+ paddr_t rosize; /* Size of read-only data block */
+
+ /* Allocate for variable storage */
+
+ paddr_t varsize; /* Variable storage size */
+ paddr_t strsize; /* String storage size */
+};
+
+/* This structure defines the current state of the p-code interpreter */
+
+struct pexec_s
+{
+ /* This is the emulated P-Machine stack (D-Space) */
+
+ stackType dstack;
+
+ /* This is the emulated P-Machine instruction space (I-Space) */
+
+ FAR uint8_t *ispace;
+
+ /* Address of last valid P-Code */
+
+ paddr_t maxpc;
+
+ /* These are the emulated P-Machine registers:
+ *
+ * spb: Base of the stack
+ * sp: The Pascal stack pointer
+ * lsp: Level stack pointer
+ * csp: The current top of the stack used to manage string
+ * storage
+ * fp: Base Register of the current stack frame. Holds the address
+ * of the base of the stack frame of the current block.
+ * fop: Pointer to section containing read-only data
+ * pc: Holds the current p-code location
+ */
+
+ paddr_t spb; /* Pascal stack base */
+ paddr_t sp; /* Pascal stack pointer */
+ paddr_t lsp; /* Level stack pointer */
+ paddr_t csp; /* Character stack pointer */
+ paddr_t fp; /* Base of the current frame */
+ paddr_t rop; /* Read-only data pointer */
+ paddr_t pc; /* Program counter */
+
+ /* Info needed to perform a simulated reset */
+
+ paddr_t strsize; /* String stack size */
+ paddr_t rosize; /* Read-only stack size */
+ paddr_t entry; /* Entry point */
+ paddr_t stacksize; /* (debug only) */
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+EXTERN FAR struct pexec_s *pload(const char *filename, paddr_t varsize, paddr_t strsize);
+EXTERN FAR struct pexec_s *pexec_init(struct pexec_attr_s *attr);
+EXTERN int pexec(FAR struct pexec_s *st);
+EXTERN void pexec_reset(struct pexec_s *st);
+EXTERN void pexec_release(struct pexec_s *st);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PEXEC_H */ \ No newline at end of file
diff --git a/misc/pascal/insn32/include/pinsn32.h b/misc/pascal/insn32/include/pinsn32.h
new file mode 100644
index 000000000..eaceeba7e
--- /dev/null
+++ b/misc/pascal/insn32/include/pinsn32.h
@@ -0,0 +1,426 @@
+/****************************************************************************
+ * pinsn32.h
+ * 32-bit P-code operation code definitions
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __PINSN32_H
+#define __PINSN32_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* 32-bit op-code bit definitions
+ *
+ * Machine model:
+ *
+ * SPB 32-bit Pascal stack base address
+ * SP 32-bit Pascal stack pointer
+ * LSP 32-bit Level stack pointer
+ * CSB 32-bit Character stack base address
+ * CSP 32-bit Character stack pointer
+ * DS 32-bit Data size register (for multiple reg transfers)
+ * PC 32-bit Program Counter
+ * CC Condition code register
+ * --- Volatile general purpose registers
+ * --- Static general purpose registers
+ *
+ * Condition codes: Z(ero), N(egative)
+ *
+ * +=====+=====+
+ * | Z | N |
+ * +=====+=====+=====+
+ * | EQ | 1 | - |
+ * | NEQ | 0 | - |
+ * | LT | - | 1 |
+ * | GTE | - | 0 |
+ * | GT | 0 | 0 |
+ * | LTE | 1 | 1 |
+ * +=====+=====+=====+
+ *
+ * Opcode Encoding Summary:
+ *
+ * 0rxx xxxx 1rxxx xxxx
+ * xr00 0000 NOP LD uoffs4
+ * xr00 0001 NEG LDH uoffs3
+ * xr00 0010 ABS LDB uoffs
+ * xr00 0011 INC LDM uoffs4
+ * xr00 0100 DEC ST uoffs4
+ * xr00 0101 NOT STH uoffs2
+ * xr00 0110 ADD STB uoffs
+ * xr00 0111 SUB STM uoffs4
+ * xr00 1000 MUL LDX uoffs4
+ * xr00 1001 DIV LDXH uoffs2
+ * xr00 1010 MOD LDXB uoffs
+ * xr00 1011 SLL LDXM uoffs4
+ * xr00 1100 SRL STX uoffs4
+ * xr00 1101 SRA STXH uoffs2
+ * xr00 1110 OR STXB uoffs
+ * xr00 1111 AND STXM uoffs
+ *
+ * xr01 0000 EQUZ JEQUZ ilbl
+ * xr01 0001 NEQZ JNEQZ ilbl
+ * xr01 0010 LTZ JLTZ ilbl
+ * xr01 0011 GTEZ JGTEZ ilbl
+ * xr01 0100 GTZ JGTZ ilbl
+ * xr01 0101 LTEZ JLTEZ ilbl
+ * xr01 0110 --- JMP ilbl
+ * xr01 0111 --- PUSH nn
+ * xr01 1000 EQU JEQU ilbl
+ * xr01 1001 NEQ JNEQ ilbl
+ * xr01 1010 LT JLT ilbl
+ * xr01 1011 GTE JGTE ilbl
+ * xr01 1100 GT JGT ilbl
+ * xr01 1101 LTE JLTE ilbl
+ * xr01 1110 --- ---
+ * xr01 1111 BIT INDS nn
+ *
+ * xr10 0000 LDI LDS offs4
+ * xr10 0001 LDIH LDSH offs3
+ * xr10 0010 LDIB LDSB offs
+ * xr10 0011 LDIM LDSM offs4
+ * xr10 0100 STI STS offs4
+ * xr10 0101 STIH STSH offs2
+ * xr10 0110 STIB STSB offs
+ * xr10 0111 STIM STSM offs4
+ * xr10 1000 DUP LDSX offs4
+ * xr10 1001 --- LDSXH offs2
+ * xr10 1010 PUSHS LDSXB offs
+ * xr10 1011 POPS LDSXM offs4
+ * xr10 1100 --- STSX offs4
+ * xr10 1101 --- STSXH offs2
+ * xr10 1110 --- STSXB offs
+ * xr10 1111 RET STSXM offs
+ *
+ * xr11 0000 --- LA uoffs
+ * xr11 0001 --- LAS offs
+ * xr11 0010 --- LAC dlbl
+ * xr11 0011 --- ---
+ * xr11 0100 --- LAX uoffs
+ * xr11 0101 --- LASX offs
+ * xr11 0110 --- SLSP level
+ * xr11 0111 --- SDC uu
+ * xr11 1000 --- ---
+ * xr11 1001 --- PCAL ilbl
+ * xr11 1010 --- SYSIO fn,sop
+ * xr11 1011 --- LIB lop
+ * xr11 1100 --- FLOAT fop
+ * xr11 1101 --- *LABEL ilbl
+ * xr11 1110 --- *INCLUDE fn
+ * xr11 1111 END *LINE lineno
+ *
+ * KEY:
+ * r = Reserved bit (must be zero)
+ * fn = 8-bit file number
+ * lvl = 8-bit static nexting level
+ * sop = 17-bit sysio operation
+ * lineno = 17-bit line number
+ * nn = 32-bit constant value (signed)
+ * uu = 32-bit constant value (unsigned)
+ * fop = 32-bit floating point operation
+ * lop = 32-bit library call identifier
+ * ilbl = 32-bit Instruction space label number
+ * dlbl = 32-stack data label
+ * offs4 = 32-bit word offset with respect to LSP (signed)
+ * offs2 = 32-bit halfword offset with respect to LSP (signed)
+ * offs = 32-bit byte offset with respect to LSP (signed)
+ * uoffs4 = 32-bit word offset with respect to SPB (unsigned)
+ * uoffs2 = 32-bit halfword offset with respect to SPB (unsigned)
+ * uoffs = 32-bit byte offset with respect to SPB (unsigned)
+ * c = string follows pseudo-operation
+ * * = Indicates pseudo-operations (these are removed
+ * after final fixup of the object file).
+ */
+
+#define o32 (0x80)
+
+#define GETOP(o) ((o)->op)
+#define PUTOP(o,v) do { (o)->op = (v); } while (0)
+
+#define GETARG(o) ((o)->arg)
+#define PUTARG(o,a) do { (o)->arg = (a); } while (0)
+
+#define ARGONES 0xffffffff
+
+/* The opcode binary is stored in big endian order (so that the opcode
+ * always comes first). The following definitions simplify ordering
+ * of byte accesses.
+ */
+
+#ifdef CONFIG_ENDIAN_BIG
+# define opB1 0
+# define opB2 1
+# define opB3 2
+# define opB4 3
+#else
+# define opB1 3
+# define opB2 2
+# define opB3 1
+# define opB4 0
+#endif
+
+/** 1-BYTE OPCODES WITH NO ARGUMENTS (other than stack arguments) ***********/
+
+/* Program control (No stack arguments) */
+
+#define oNOP (0x00)
+
+/* Arithmetic & logical & and integer conversions (One 32-bit stack
+ * argument)
+ */
+
+#define oNEG (0x01)
+#define oABS (0x02)
+#define oINC (0x03)
+#define oDEC (0x04)
+#define oNOT (0x05)
+#define oADD (0x06)
+#define oSUB (0x07)
+#define oMUL (0x08)
+#define oDIV (0x09)
+#define oMOD (0x0a)
+#define oSLL (0x0b)
+#define oSRL (0x0c)
+#define oSRA (0x0d)
+#define oOR (0x0e)
+#define oAND (0x0f)
+
+/* Comparisons (One 32-bit stack argument) */
+
+#define oEQUZ (0x10)
+#define oNEQZ (0x11)
+#define oLTZ (0x12)
+#define oGTEZ (0x13)
+#define oGTZ (0x14)
+#define oLTEZ (0x15)
+
+/* Comparisons (Two 32-bit stack arguments) */
+
+#define oEQU (0x18)
+#define oNEQ (0x19)
+#define oLT (0x1a)
+#define oGTE (0x1b)
+#define oGT (0x1c)
+#define oLTE (0x1d)
+#define oBIT (0x1f)
+
+/* Load Immediate */
+
+#define oLDI (0x20) /* (One 32-bit stack argument) */
+#define oLDIH (0x21) /* (One 32-bit stack argument) */
+#define oLDIB (0x22) /* (One 32-bit stack argument) */
+#define oLDIM (0x23) /* (Two 32-bit stack argument) */
+
+/* Store Immediate */
+
+#define oSTI (0x24) /* (Two 32-bit stack argument) */
+#define oSTIH (0x25) /* (Two 32-bit stack argument) */
+#define oSTIB (0x26) /* (Two 32-bit stack argument) */
+#define oSTIM (0x27) /* (Two+n 32-bit stack argument) */
+
+/* Data stack */
+
+#define oDUP (0x28) /* (One 32-bit stack argument) */
+#define oDUPH (0x29) /* (One 32-bit stack argument) */
+#define oPUSHS (0x2a) /* No stack arguments */
+#define oPOPS (0x2b) /* (One 32-bit stack argument) */
+
+/* Program control (No stack arguments)
+ * Behavior:
+ * Pop return address
+ * Pop saved base register (BR)
+ * Discard saved base address
+ * Set program counter (PC) to return address
+ */
+
+#define oRET (0x2f)
+
+/* System Functions (No stack arguments) */
+
+#define oEND (0x3f)
+
+/** 4-BYTE OPCODES INCLUDING ONE 32-BIT ARGUMENT ****************************/
+
+/* Load: arg = unsigned base offset */
+
+#define oLD (o32|0x00) /* No stack arguments */
+#define oLDH (o32|0x01) /* No stack arguments */
+#define oLDB (o32|0x02) /* No stack arguments */
+#define oLDM (o32|0x03) /* One 32-bit stack argument */
+
+/* Store: arg = unsigned base offset */
+
+#define oST (o32|0x04) /* One 32-bit stack argument */
+#define oSTH (o32|0x05) /* One 32-bit stack argument */
+#define oSTB (o32|0x06) /* One 32-bit stack argument */
+#define oSTM (o32|0x07) /* One+n 32-bit stack argument */
+
+/* Load Indexed: arg = unsigned base offset */
+
+#define oLDX (o32|0x08) /* One 32-bit stack argument */
+#define oLDXH (o32|0x09) /* One 32-bit stack argument */
+#define oLDXB (o32|0x0a) /* One 32-bit stack argument */
+#define oLDXM (o32|0x0b) /* Two 32-bit stack argument */
+
+/* Store Indexed: arg = unsigned base offset */
+
+#define oSTX (o32|0x0c) /* Two 32-bit stack argument */
+#define oSTXH (o32|0x0d) /* Two 32-bit stack argument */
+#define oSTXB (o32|0x0e) /* Two 32-bit stack argument */
+#define oSTXM (o32|0x0f) /* Two+n 32-bit stack argument */
+
+/* Program control: arg = unsigned label (One 32-bit stack argument) */
+
+#define oJEQUZ (o32|0x10)
+#define oJNEQZ (o32|0x11)
+#define oJLTZ (o32|0x12)
+#define oJGTEZ (o32|0x13)
+#define oJGTZ (o32|0x14)
+#define oJLTEZ (o32|0x15)
+
+/* Program control: arg = unsigned label (no stack arguments) */
+
+#define oJMP (o32|0x16)
+
+/* Data stack: arg = 32 bit signed data (no stack arguments) */
+
+#define oPUSH (o32|0x17)
+
+/* Program control: arg = unsigned label (One 32-bit stack argument) */
+
+#define oJEQU (o32|0x18)
+#define oJNEQ (o32|0x19)
+#define oJLT (o32|0x1a)
+#define oJGTE (o32|0x1b)
+#define oJGT (o32|0x1c)
+#define oJLTE (o32|0x1d)
+
+/* Data stack: arg = 32 bit signed data (no stack arguments) */
+
+#define oINDS (o32|0x1f)
+
+/* Load: Uses LSP; arg = signed frame offset */
+
+#define oLDS (o32|0x20) /* No stack arguments */
+#define oLDSH (o32|0x21) /* No stack arguments */
+#define oLDSB (o32|0x22) /* No stack arguments */
+#define oLDSM (o32|0x23) /* One 32-bit stack argument */
+
+/* Store: Uses LSP; arg = signed frame offset */
+
+#define oSTS (o32|0x24) /* One 32-bit stack argument */
+#define oSTSH (o32|0x25) /* One 32-bit stack argument */
+#define oSTSB (o32|0x26) /* One 32-bit stack argument */
+#define oSTSM (o32|0x27) /* One+n 32-bit stack argument */
+
+/* Load Indexed: Uses LSP; arg = signed frame offset */
+
+#define oLDSX (o32|0x28) /* One 32-bit stack argument */
+#define oLDSXH (o32|0x29) /* One 32-bit stack argument */
+#define oLDSXB (o32|0x2a) /* One 32-bit stack argument */
+#define oLDSXM (o32|0x2b) /* Two 32-bit stack argument */
+
+/* Store Indexed: Uses LSP; arg = signed frame offset */
+
+#define oSTSX (o32|0x2c) /* Two 32-bit stack argument */
+#define oSTSXH (o32|0x2d) /* Two 32-bit stack argument */
+#define oSTSXB (o32|0x2e) /* Two 32-bit stack argument */
+#define oSTSXM (o32|0x2f) /* Two+n 32-bit stack argument */
+
+/* Load address relative to stack base: arg = unsigned offset */
+
+#define oLA (o32|0x30)
+
+/* Load address: Uses SLP, arg = signed frame offset */
+
+#define oLAS (o32|0x31) /* No stack arguments */
+
+/* Load absolute stack address: arg = RODATA offset (No stack arguments) */
+
+#define oLAC (o32|0x32)
+
+/* Load address relative to stack base: arg = unsigned offset, TOS=index */
+
+#define oLAX (o32|0x34)
+
+/* Load address indexed: Uses SLP, arg = signed frame offset */
+
+#define oLASX (o32|0x35) /* No stack arguments */
+
+/* Set LSP: arg = new level that evaluates to LSP value */
+
+#define oSLSP (o32|0x36)
+
+/* Set DS: arg = new byte count in DS register */
+
+#define oSDC (o32|0x37)
+
+/* Program Control: Uses LSP; arg = unsigned label
+ * (No stack arguments)
+ * Behavior:
+ * Push base address of level
+ * Push base register (BR) value
+ * Set new base register value (BR) as top of stack
+ * Push return address
+ * Set program counter (PC) for address associated with label
+ */
+
+#define oPCAL (o32|0x39)
+
+/* System calls: arg = file number | sub-function code */
+
+#define oSYSIO (o32|0x3a)
+
+/* System functions: arg = 32-bit library call identifier */
+
+#define oLIB (o32|0x3b)
+
+/* Floating point operations: arg = FP op-code */
+
+#define oFLOAT (o32|0x3c)
+
+/* Program control: arg = unsigned label (no stack arguments) */
+
+#define oLABEL (o32|0x3d)
+
+/* Pseudo-operations: arg = file number OR line number */
+
+#define oINCLUDE (o32|0x3e)
+#define oLINE (o32|0x3f)
+
+#endif /* __PINSN32_H */
diff --git a/misc/pascal/insn32/include/rinsn32.h b/misc/pascal/insn32/include/rinsn32.h
new file mode 100644
index 000000000..8826eefb1
--- /dev/null
+++ b/misc/pascal/insn32/include/rinsn32.h
@@ -0,0 +1,226 @@
+/***********************************************************************
+ * rinsn32.h
+ * 32-bit register module instruction definitions
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************************************/
+
+#ifndef __RINSN32_H
+#define __RINSN32_H
+
+/***********************************************************************
+ * Included Files
+ ***********************************************************************/
+
+#include <stdint.h>
+
+/***********************************************************************
+ * Pre-processor Definitions
+ ***********************************************************************/
+
+/* 32-bit op-code bit definitions
+ *
+ * Machine model:
+ *
+ * SPB 32-bit Pascal stack base address
+ * SP 32-bit Pascal stack pointer
+ * LSP 32-bit level stack pointer
+ * CSB 32-bit character stack base address
+ * PC 32-bit program counter
+ * ZRO 32-bit register containing zero (like MIPS)
+ * Rn 32-bit general purpose registers
+ *
+ * Parameters passed in registers up to a limit. Parameters
+ * beyond the limit are passed on the stack. Return values
+ * are provided in these same registers.
+ *
+ * Instruction forms
+ *
+ * FORM 1: <op> <roperand1>, <operand2>
+ * FORM 2: <op> <rdest>, <operand2>
+ * FORM 3: <op> <rdest>, <roperand1>, <operand2>
+ * <rsrc>, <roperand1>, <operand2>
+ * FORM 4: <op> <pc-offset>
+ *
+ * Where
+ * <op> operation code
+ * [cc] optional conditional execution
+ * [S] optional set condition code
+ * <rdest> register holding the result
+ * <rsrc> register holding data to be stored.
+ * <roperand1> register holding the first operand
+ * <operand2> One of <roperand2> or <immediate>
+ * <roperand2> register holding the second operand
+ * <immediate> Immediate constant data (short).
+ * <pc-offset> Word offset from current PC
+ *
+ * NOTE: This instruction set is inspired by the ARM instruction
+ * set, but is intended to be a general register model. It does
+ * not exploit certain ARM-isms such as "flexible" operands, conditional
+ * execution, post-incrementing, pre-incrementing, pc-relative addressing,
+ * optional register writeback, or ldm/stm with register sets, etc.
+ */
+
+#define FORM1(o) (((o) & 0xe0) == 0x00)
+#define FORM1R(o) (((o) & 0xf0) == 0x00)
+#define FORM1I(o) (((o) & 0xf0) == 0x10)
+#define FORM1O(o) ((o) & 0x0f)
+
+#define FORM2(o) (((o) & 0xe0) == 0x20)
+#define FORM2R(o) (((o) & 0xf0) == 0x20)
+#define FORM2I(o) (((o) & 0xf0) == 0x30)
+#define FORM2O(o) ((o) & 0x0f)
+
+#define FORM3(o) (((o) & 0x80) == 0x80)
+#define FORM3R(o) (((o) & 0xc0) == 0x80)
+#define FORM3I(o) (((o) & 0xc0) == 0xc0)
+#define FORM3O(o) ((o) & 0x3f)
+
+#define FORM4(o) (((o) & 0xc0) == 0x40)
+#define FORM3O(o) ((o) & 0x3f)
+
+struct rinsn_u
+{
+ uint8_t opcode;
+ union {
+ struct {
+ uint32_t rop1;
+ uint32_t rop2;
+ } r1;
+ struct {
+ uint32_t rop1;
+ uint32_t im2;
+ } i1;
+ struct {
+ uint32_t rdest;
+ uint32_t rop;
+ } r2;
+ struct {
+ uint32_t rdest;
+ uint32_t im;
+ } i2;
+ struct {
+ uint32_t rdest;
+ uint32_t rop1;
+ uint32_t rop2;
+ } r3;
+ struct {
+ uint32_t rdest;
+ uint32_t rop1;
+ uint32_t im2;
+ } i3;
+ struct {
+ uint32_t offset;
+ } i4;
+ } f;
+};
+typedef struct rinsn_u RINSN32;
+
+/* FORM 1: Comparisons */
+
+#define rCMP (0x00) /* Form 1: set <cc> after <roperand1> - <roperand2> */
+#define rCMPI (0x10) /* Form 1: set <cc> after <roperand1> - <immediate> */
+#define rCMN (0x01) /* Form 1: set <cc> after <roperand1> + <roperand2> */
+#define rCMNI (0x11) /* Form 1: set <cc> after <roperand1> + <immediate> */
+
+/* FORM 2: Data movement */
+
+#define rMOV (0x20) /* Form 1: <rdest> = <roperand2> */
+#define rMOVI (0x30) /* Form 1: <rdist> = <immediate> */
+#define rMVN (0x21) /* Form 1: <rdest> = ~<roperand2> */
+#define rMVNI (0x31) /* Form 1: <rdist> = ~<immediate> */
+
+/* FORM 4: Program control */
+
+#define rB (0x40) /* PC += <pcoffset> << 2 */
+#define rBEQ (0x41) /* if <cc>->EQ, PC += <pcoffset> << 2 */
+#define rBNE (0x42) /* if <cc>->NEQ, PC += <pcoffset> << 2 */
+#define rBLT (0x43) /* if <cc>->LT, PC += <pcoffset> << 2 */
+#define rBGTE (0x44) /* if <cc>->GTE, PC += <pcoffset> << 2 */
+#define rBGT (0x45) /* if <cc>->GT, PC += <pcoffset> << 2 */
+#define rBLTE (0x46) /* if <cc>->KTE, PC += <pcoffset> << 2 */
+#define rBL (0x47) /* LR=next PC, PC += <pcoffset> << 2 */
+
+/* FORM 3: Arithmetic and logical operations */
+
+#define rADD (0x80) /* Form 3: <rdest> = <roperand1> + <roperand2> */
+#define rADDI (0xc0) /* Form 3: <rdest> = <roperand1> + <immediate> */
+#define rSUB (0x81) /* Form 3: <rdest> = <roperand1> - <roperand2> */
+#define rSUBI (0xc1) /* Form 3: <rdest> = <roperand1> - <immediate> */
+#define rRSB (0x82) /* Form 3: <rdest> = -<roperand1> + <roperand2> */
+#define rRSBI (0xc2) /* Form 3: <rdest> = -<roperand2> + <immediate> */
+#define rMUL (0x83) /* Form 3: <rdest> = <roperand1> * <roperand2> */
+#define rMULI (0xc3) /* Form 3: <rdest> = <roperand1> * <immediate> */
+#define rDIV (0x84) /* Form 3: <rdest> = <roperand1> / <roperand2> */
+#define rDIVI (0xc4) /* Form 3: <rdest> = <roperand1> / <immediate> */
+#define rMOD (0x85) /* Form 3: <rdest> = <roperand1> % <roperand2> */
+#define rMODI (0xc5) /* Form 3: <rdest> = <roperand1> % <immediate> */
+#define rSLL (0x86) /* Form 3: <rdest> = <roperand1> << <roperand2> */
+#define rSLLI (0xc6) /* Form 3: <rdest> = <roperand1> << <immediate> */
+#define rSRL (0x87) /* Form 3: <rdest> = <roperand1> >> <roperand2> */
+#define rSRLI (0xc7) /* Form 3: <rdest> = <roperand1> >> <immediate> */
+#define rSRA (0x88) /* Form 3: <rdest> = <roperand1> >> <roperand2> */
+#define rSRAI (0xc8) /* Form 3: <rdest> = <roperand1> >> <immediate> */
+#define rOR (0x89) /* Form 3: <rdest> = <roperand1> | <roperand2> */
+#define rORI (0xc9) /* Form 3: <rdest> = <roperand1> | <immediate> */
+#define rAND (0x8a) /* Form 3: <rdest> = <roperand1> & <roperand2> */
+#define rANDI (0xca) /* Form 3: <rdest> = <roperand1> & <immediate> */
+#define rXOR (0x8b) /* Form 3: <rdest> = <roperand1> xor <roperand2> */
+#define rXORI (0xcb) /* Form 3: <rdest> = <roperand1> xor <immediate> */
+#define rANDN (0x8c) /* Form 3: <rdest> = <roperand1> & ~<roperand2> */
+#define rANDNI (0xcc) /* Form 3: <rdest> = <roperand1> & ~<immediate> */
+
+/* FORM 3: Loads and stores */
+
+#define rLD (0x90) /* Form 3: <rdest> = (<roperand1> + <roperand2>) */
+#define rLDI (0xd0) /* Form 3: <rdest> = (<roperand1> + (<immediate> << 2)) */
+#define rLDH (0x91) /* Form 3: <rdest> = (<roperand1> + <roperand2>) */
+#define rLDIH (0xd1) /* Form 3: <rdest> = (<roperand1> + (<immediate> << 1)) */
+#define rLDB (0x92) /* Form 3: <rdest> = (<roperand1> + <roperand2>) */
+#define rLDIB (0xd2) /* Form 3: <rdest> = (<roperand1> + <immediate>) */
+
+#define rLDM (0xd3) /* Form 3: Load <immediate> registers. Source
+ * address is roperand1, first dest register is
+ * <rdest>, register count is <immediate> */
+
+#define rST (0x94) /* Form 3: (<roperand1> + <roperand2>) = <rsrc> */
+#define rSTI (0xd4) /* Form 3: (<roperand1> + (<immediate> << 2)) = <rsrc> */
+#define rSTH (0x95) /* Form 3: (<roperand1> + <roperand2>) = <rsrc> */
+#define rSTIH (0xd5) /* Form 3: (<roperand1> + (<immediate> << 1)) = <rsrc> */
+#define rSTB (0x96) /* Form 3: (<roperand1> + <roperand2>) = <rsrc> */
+#define rSTIB (0xd6) /* Form 3: (<roperand1> + <immediate>) = <rsrc> */
+
+#define rSTM (0xd7) /* Form 3: Store <immediate> registers. Destination
+ * address is roperand1, first source register is
+ * <rsrc>, register count is <immediate> */
+
+#endif /* __RINSN32_H */
diff --git a/misc/pascal/insn32/libinsn/Makefile b/misc/pascal/insn32/libinsn/Makefile
new file mode 100644
index 000000000..4814bdf9d
--- /dev/null
+++ b/misc/pascal/insn32/libinsn/Makefile
@@ -0,0 +1,76 @@
+############################################################################
+# insn32/libinsn/Makefile
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Directories
+#
+LIBINSNDIR = ${shell pwd}
+INSNDIR = $(LIBINSNDIR)/..
+PASCAL = $(LIBINSNDIR)/../..
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+INCDIR = $(PASCAL)/include
+LIBDIR = $(PASCAL)/lib
+
+#
+# Tools
+#
+EXTRA_INCLUDES = -I$(INSNDIR)/include
+INCLUDES += $(EXTRA_INCLUDES)
+CFLAGS += $(EXTRA_INCLUDES)
+
+#
+# Objects and targets
+#
+LIBINSNSRCS = paddopcode.c paddtmpopcode.c pdasm.c pgen.c \
+ pgetopcode.c preloc.c
+LIBINSNOBJS = $(LIBINSNSRCS:.c=.o)
+
+OBJS = $(LIBINSNOBJS)
+
+all: libinsn.a
+.PHONY: all libinsn.a clean
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+$(LIBDIR)/libinsn.a: $(LIBINSNOBJS)
+ $(AR) $(ARFLAGS) $@ $^
+
+libinsn.a: $(LIBDIR)/libinsn.a
+
+clean:
+ $(RM) libinsn.a *.o core *~
diff --git a/misc/pascal/insn32/libinsn/paddopcode.c b/misc/pascal/insn32/libinsn/paddopcode.c
new file mode 100644
index 000000000..6799fdbc6
--- /dev/null
+++ b/misc/pascal/insn32/libinsn/paddopcode.c
@@ -0,0 +1,99 @@
+/**********************************************************************
+ * paddopcode
+ * P-Code access utilities
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+
+#include "keywords.h"
+#include "podefs.h"
+#include "pinsn32.h"
+
+#include "paslib.h"
+#include "pofflib.h"
+#include "pinsn.h"
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/**********************************************************************/
+
+void insn_AddOpCode(poffHandle_t hProg, OPTYPE *ptr)
+{
+ /* Handle big-endian byte stream */
+
+ (void)poffAddProgByte(hProg, ptr->op);
+
+ /* Write the 32-bit argument if present */
+
+ if (ptr->op & o32)
+ {
+ uint8_t *pb = (uint8_t*)&ptr->arg;
+
+ (void)poffAddProgByte(hProg, pb[opB1]);
+ (void)poffAddProgByte(hProg, pb[opB2]);
+ (void)poffAddProgByte(hProg, pb[opB3]);
+ (void)poffAddProgByte(hProg, pb[opB4]);
+ }
+}
+
+/**********************************************************************/
+
+void insn_ResetOpCodeWrite(poffHandle_t hProg)
+{
+ poffResetAccess(hProg);
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/insn32/libinsn/paddtmpopcode.c b/misc/pascal/insn32/libinsn/paddtmpopcode.c
new file mode 100644
index 000000000..e08cccc51
--- /dev/null
+++ b/misc/pascal/insn32/libinsn/paddtmpopcode.c
@@ -0,0 +1,99 @@
+/**********************************************************************
+ * paddtmpopcode
+ * P-Code access utilities
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+
+#include "keywords.h"
+#include "podefs.h"
+#include "pinsn32.h"
+
+#include "paslib.h"
+#include "pofflib.h"
+#include "pinsn.h"
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/**********************************************************************/
+
+void insn_AddTmpOpCode(poffProgHandle_t hProg, OPTYPE *ptr)
+{
+ /* Write the opcode which is always present */
+
+ (void)poffAddTmpProgByte(hProg, ptr->op);
+
+ /* Write the 32-bit argument if present */
+
+ if (ptr->op & o32)
+ {
+ uint8_t *pb = (uint8_t*)&ptr->arg;
+
+ (void)poffAddTmpProgByte(hProg, pb[opB1]);
+ (void)poffAddTmpProgByte(hProg, pb[opB2]);
+ (void)poffAddTmpProgByte(hProg, pb[opB3]);
+ (void)poffAddTmpProgByte(hProg, pb[opB4]);
+ }
+}
+
+/**********************************************************************/
+
+void insn_ResetTmpOpCodeWrite(poffProgHandle_t hProg)
+{
+ poffResetProgHandle(hProg);
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/insn32/libinsn/pdasm.c b/misc/pascal/insn32/libinsn/pdasm.c
new file mode 100644
index 000000000..e0968b43b
--- /dev/null
+++ b/misc/pascal/insn32/libinsn/pdasm.c
@@ -0,0 +1,436 @@
+/**********************************************************************
+ * pdasm.c
+ * P-Code Disassembler
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "keywords.h"
+#include "podefs.h"
+#include "pinsn32.h"
+#include "pfdefs.h"
+#include "pxdefs.h"
+#include "paslib.h"
+
+#include "pinsn.h"
+
+/**********************************************************************
+ * Private Types
+ **********************************************************************/
+
+/* These are all the format codes that apply to opcodes with an argument */
+
+enum {
+ SIMPLE = 0, /* No argument */
+ HEX, /* Hexadecimal argument */
+ DECIMAL, /* Signed Decimal argument (w/shift) */
+ UDECIMAL, /* Unsigned Decimal argument (w/shift) */
+ LABEL_DEC, /* Label number */
+ xOP, lbOP, fpOP, /* Sub opcode */
+ FILENO, LINENO /* File number, line number */
+};
+
+/* The following table defines everything that is needed to disassemble
+ * a P-Code. NOTE: The order of definition in this table must exactly
+ * match the declaration sequence in pinsn.h. */
+
+static const char invOp[] = "Invalid Opcode";
+struct optab_s
+{
+ const char *opName; /* Opcode mnemonics */
+ uint8_t format; /* arg16 format */
+};
+
+/******************** OPCODES WITH NO ARGUMENTS *************************/
+
+static const struct optab_s g_sNoArgOpTable[64] =
+{
+ /* Program control (No stack arguments) */
+
+ /* 0x00 */ { "NOP ", SIMPLE },
+
+ /* Arithmetic & logical & and integer conversions (One stack argument) */
+
+ /* 0x01 */ { "NEG ", SIMPLE },
+ /* 0x02 */ { "ABS ", SIMPLE },
+ /* 0x03 */ { "INC ", SIMPLE },
+ /* 0x04 */ { "DEC ", SIMPLE },
+ /* 0x05 */ { "NOT ", SIMPLE },
+
+ /* Arithmetic & logical (Two stack arguments) */
+
+ /* 0x06 */ { "ADD ", SIMPLE },
+ /* 0x07 */ { "SUB ", SIMPLE },
+ /* 0x08 */ { "MUL ", SIMPLE },
+ /* 0x09 */ { "DIV ", SIMPLE },
+ /* 0x0a */ { "MOD ", SIMPLE },
+ /* 0x0b */ { "SLL ", SIMPLE },
+ /* 0x0c */ { "SRL ", SIMPLE },
+ /* 0x0d */ { "SRA ", SIMPLE },
+ /* 0x0e */ { "OR ", SIMPLE },
+ /* 0x0f */ { "AND ", SIMPLE },
+
+ /* Comparisons (One stack argument) */
+
+ /* 0x10 */ { "EQUZ ", SIMPLE },
+ /* 0x11 */ { "NEQZ ", SIMPLE },
+ /* 0x12 */ { "LTZ ", SIMPLE },
+ /* 0x13 */ { "GTEZ ", SIMPLE },
+ /* 0x14 */ { "GTZ ", SIMPLE },
+ /* 0x15 */ { "LTEZ ", SIMPLE },
+ /* 0x16 */ { invOp, SIMPLE },
+ /* 0x17 */ { invOp, SIMPLE },
+
+ /* Comparisons (Two stack arguments) */
+
+ /* 0x18 */ { "EQU ", SIMPLE },
+ /* 0x19 */ { "NEQ ", SIMPLE },
+ /* 0x1a */ { "LT ", SIMPLE },
+ /* 0x1b */ { "GTE ", SIMPLE },
+ /* 0x1c */ { "GT ", SIMPLE },
+ /* 0x1d */ { "LTE ", SIMPLE },
+ /* 0x1e */ { invOp, SIMPLE },
+ /* 0x1f */ { "BIT ", SIMPLE },
+
+ /* Load (One) or Store (Two stack argument) */
+
+ /* 0x20 */ { "LDI ", SIMPLE },
+ /* 0x21 */ { "LDIH", SIMPLE },
+ /* 0x22 */ { "LDIB", SIMPLE },
+ /* 0x23 */ { "LDIM", SIMPLE },
+ /* 0x24 */ { "STI ", SIMPLE },
+ /* 0x25 */ { "STIH", SIMPLE },
+ /* 0x26 */ { "STIB", SIMPLE },
+ /* 0x27 */ { "STIM", SIMPLE },
+
+ /* Data stack operations */
+
+ /* 0x28 */ { "DUP ", SIMPLE },
+ /* 0x29 */ { "DUPH ", SIMPLE },
+ /* 0x2a */ { "PUSHS", SIMPLE },
+ /* 0x2b */ { "POPS", SIMPLE },
+ /* 0x2c */ { invOp, SIMPLE },
+ /* 0x2d */ { invOp, SIMPLE },
+ /* 0x2e */ { invOp, SIMPLE },
+ /* 0x2f */ { "RET ", SIMPLE },
+
+ /* 0x30 */ { invOp, SIMPLE },
+ /* 0x31 */ { invOp, SIMPLE },
+ /* 0x32 */ { invOp, SIMPLE },
+ /* 0x33 */ { invOp, SIMPLE },
+ /* 0x34 */ { invOp, SIMPLE },
+ /* 0x35 */ { invOp, SIMPLE },
+ /* 0x36 */ { invOp, SIMPLE },
+ /* 0x37 */ { invOp, SIMPLE },
+
+ /* System Functions (No stack arguments) */
+
+ /* 0x38 */ { invOp, SIMPLE },
+ /* 0x39 */ { invOp, SIMPLE },
+ /* 0x3a */ { invOp, SIMPLE },
+ /* 0x3b */ { invOp, SIMPLE },
+ /* 0x3c */ { invOp, SIMPLE },
+ /* 0x3d */ { invOp, SIMPLE },
+ /* 0x3e */ { invOp, SIMPLE },
+ /* 0x3f */ { "EXIT ", SIMPLE }
+};
+
+/****************** OPCODES WITH 25-BIT ARGUMENT ************************/
+
+static const struct optab_s g_sArg32OpTable[64] =
+{
+ /* Load: arg = unsigned base offset */
+
+ /* 0x80 */ { "LD ", UDECIMAL }, /* No stack arguments */
+ /* 0x81 */ { "LDH ", UDECIMAL }, /* No stack arguments */
+ /* 0x82 */ { "LDB ", UDECIMAL }, /* No stack arguments */
+ /* 0x83 */ { "LDM ", UDECIMAL }, /* One 32-bit stack argument */
+
+ /* Store: arg = unsigned base offset (One stack arguments) */
+
+ /* 0x84 */ { "ST ", UDECIMAL }, /* One 32-bit stack argument */
+ /* 0x85 */ { "STH ", UDECIMAL }, /* One 32-bit stack argument */
+ /* 0x86 */ { "STB ", UDECIMAL }, /* One 32-bit stack argument */
+ /* 0x87 */ { "STM ", UDECIMAL }, /* One+n 32-bit stack argument */
+
+ /* Load Indexed: arg = unsigned base offset */
+
+ /* 0x88 */ { "LDX ", UDECIMAL }, /* One 32-bit stack argument */
+ /* 0x89 */ { "LDXH ", UDECIMAL }, /* One 32-bit stack argument */
+ /* 0x8a */ { "LDXB ", UDECIMAL }, /* One 32-bit stack argument */
+ /* 0x8b */ { "LDXM ", UDECIMAL }, /* Two 32-bit stack argument */
+
+ /* Store Indexed: arg = unsigned base offset */
+
+ /* 0x8c */ { "STX ", UDECIMAL }, /* Two 32-bit stack argument */
+ /* 0x8d */ { "STXH ", UDECIMAL }, /* Two 32-bit stack argument */
+ /* 0x8e */ { "STXB ", UDECIMAL }, /* Two 32-bit stack argument */
+ /* 0x8f */ { "STXM ", UDECIMAL }, /* Two+n 32-bit stack argument */
+
+ /* Program control: arg = unsigned label (One stack argument) */
+
+ /* 0x90 */ { "JEQUZ", HEX },
+ /* 0x91 */ { "JNEQZ", HEX },
+ /* 0x92 */ { "JLTZ ", HEX },
+ /* 0x93 */ { "JGTEZ", HEX },
+ /* 0x94 */ { "JGTZ ", HEX },
+ /* 0x95 */ { "JLTEZ", HEX },
+
+ /* Program control: arg = unsigned label (no stack arguments) */
+
+ /* 0x96 */ { "JMP ", HEX },
+ /* 0x97 */ { "PUSH ", DECIMAL },
+
+ /* Program control: arg = unsigned label (One stack argument) */
+
+ /* 0x98 */ { "JEQU ", HEX },
+ /* 0x99 */ { "JNEQ ", HEX },
+ /* 0x9a */ { "JLT ", HEX },
+ /* 0x9b */ { "JGTE ", HEX },
+ /* 0x9c */ { "JGT ", HEX },
+ /* 0x9d */ { "JLTE ", HEX },
+ /* 0x9e */ { invOp, SIMPLE },
+ /* 0x9f */ { "INDS ", DECIMAL },
+
+ /* Load: Uses LSP; arg = signed frame offset */
+
+ /* 0xa0 */ { "LDS ", DECIMAL }, /* No stack arguments */
+ /* 0xa1 */ { "LDSH ", DECIMAL }, /* No stack arguments */
+ /* 0xa2 */ { "LDSB ", DECIMAL }, /* No stack arguments */
+ /* 0xa3 */ { "LDSM ", DECIMAL }, /* One 32-bit stack argument */
+
+ /* Store: Uses LSP; arg = signed frame offset */
+
+ /* 0xa4 */ { "STS ", DECIMAL }, /* One 32-bit stack argument */
+ /* 0xa5 */ { "STSH ", DECIMAL }, /* One 32-bit stack argument */
+ /* 0xa6 */ { "STSB ", DECIMAL }, /* One 32-bit stack argument */
+ /* 0xa7 */ { "STSM ", DECIMAL }, /* One+n 32-bit stack argument */
+
+ /* Load Indexed: Uses LSP; arg = signed frame offset */
+
+ /* 0xa8 */ { "LDSX ", DECIMAL }, /* One 32-bit stack argument */
+ /* 0xa9 */ { "LDSXH", DECIMAL }, /* One 32-bit stack argument */
+ /* 0xaa */ { "LDSXB", DECIMAL }, /* One 32-bit stack argument */
+ /* 0xab */ { "LDSXM", DECIMAL }, /* Two 32-bit stack argument */
+
+ /* Store Indexed: Uses LSP; arg = signed frame offset */
+
+ /* 0xac */ { "STSX ", DECIMAL }, /* Two 32-bit stack argument */
+ /* 0xad */ { "STSXH", DECIMAL }, /* Two 32-bit stack argument */
+ /* 0xae */ { "STSXB", DECIMAL }, /* Two 32-bit stack argument */
+ /* 0xaf */ { "STSXM", DECIMAL }, /* Two+n 32-bit stack argument */
+
+ /* Load address relative to stack base: arg = unsigned offset */
+
+ /* 0xb0 */ { "LA ", UDECIMAL },
+
+ /* Load address: Uses SLP, arg = signed frame offset */
+
+ /* 0xb1 */ { "LAS ", DECIMAL },
+
+ /* Load absolute stack address: arg = RODATA offset (No stack arguments) */
+
+ /* 0xb2 */ { "LAC ", HEX, },
+ /* 0xb3 */ { invOp, SIMPLE },
+
+ /* Load address relative to stack base: arg = unsigned offset, TOS=index */
+
+ /* 0xb4 */ { "LAX ", UDECIMAL },
+
+ /* Load address indexed: Uses SLP, arg = signed frame offset */
+
+ /* 0xb5 */ { "LASX ", DECIMAL },
+
+ /* Set LSP: arg = new level that evaluates to LSP value */
+
+ /* 0xb6 */ { "SLSP ", UDECIMAL },
+ /* 0xb7 */ { "SDC ", UDECIMAL },
+ /* 0xb8 */ { invOp, SIMPLE },
+
+ /* Program Control: Uses LSP; arg = unsigned label (No stack arguments) */
+
+ /* 0xb9 */ { "PCAL ", HEX },
+
+ /* System calls: arg = file number | sub-function code */
+
+ /* 0xba */ { "SYSIO", xOP },
+
+ /* System functions: arg = 32-bit library call identifier */
+
+ /* 0xbb */ { "LIB ", lbOP },
+
+ /* Floating point operations: arg = FP op-code */
+
+ /* 0xbc */ { "FLOAT", fpOP },
+
+ /* Program control: arg = unsigned label (no stack arguments) */
+
+ /* 0xbd */ { NULL, LABEL_DEC },
+
+ /* Pseudo-operations: arg = file number OR line number */
+
+ /* 0xbe */ { "INCLUDE ", FILENO },
+ /* 0xbf */ { "LINE ", LINENO },
+};
+
+static const char invXOp[] = "Invalid SYSIO";
+static const char *xName[MAX_XOP] = { /* SYSIO opcode mnemonics */
+/* 0x00 */ invXOp, "EOF", "EOLN", "RESET",
+/* 0x04 */ "REWRITE", invXOp, invXOp, invXOp,
+/* 0x08 */ invXOp, invXOp, invXOp, invXOp,
+/* 0x0c */ invXOp, invXOp, invXOp, invXOp,
+/* 0x10 */ "READLN", "READPG", "READBIN", "READINT",
+/* 0x14 */ "READCHR", "READSTR", "READRL", invXOp,
+/* 0x18 */ invXOp, invXOp, invXOp, invXOp,
+/* 0x1c */ invXOp, invXOp, invXOp, invXOp,
+/* 0x20 */ "WRITELN", "WRITEPG", "WRITEBIN", "WRITEINT",
+/* 0x24 */ "WRITECHR", "WRITESTR", "WRITERL" };
+
+static const char invLbOp[] = "Invalid runtime code";
+static const char *lbName[MAX_LBOP] = { /* LIB opcode mnemonics */
+/* 0x00 */ "GETENV", "STR2STR", "CSTR2STR", "STR2RSTR",
+/* 0x04 */ "CSTR2RSTR", "VAL", "MKSTK", "MKSTKSTR",
+/* 0x08 */ "MKSTKC", "STRCAT", "STRCATC", "STRCMP" };
+
+#define MAX_FOP 16
+static const char invFpOp[] = "Invalid FP Operation";
+static const char *fpName[MAX_FOP] = {
+/* 0x00 */ invFpOp, "FLOAT", "TRUNC", "ROUND",
+/* 0x04 */ "NEG", "ADD", "SUB", "MUL",
+/* 0x08 */ "DIV", "MOD", "EQU", "NEQ",
+/* 0x0c */ "LT", "GTE", "GT", "LTE" };
+
+/***********************************************************************/
+
+void insn_DisassemblePCode(FILE* lfile, OPTYPE *pop)
+{
+ const struct optab_s *opTable;
+ int idx;
+
+ /* Select table based upon whether an opcode is included or not */
+
+ if (pop->op & o32)
+ {
+ opTable = g_sArg32OpTable;
+ idx = pop->op & ~o32;
+ }
+ else
+ {
+ opTable = g_sNoArgOpTable;
+ idx = pop->op;
+ }
+
+ /* Indent, comment or label as appropriate */
+
+ switch (opTable[idx].format)
+ {
+ case LABEL_DEC :
+ fprintf(lfile, "L%08lx:\n", pop->arg);
+ return;
+ case FILENO :
+ case LINENO :
+ fprintf(lfile, "; ");
+ break;
+ default :
+ fprintf(lfile, " ");
+ } /* end switch */
+
+ /* Print the opcode mnemonic */
+
+ fprintf(lfile, "%s ", opTable[idx].opName);
+
+ /* Print the argument (if present) */
+
+ if (pop->op & o32)
+ {
+ switch (opTable[idx].format)
+ {
+ case HEX :
+ fprintf(lfile, "0x%08lx", pop->arg);
+ break;
+
+ case FILENO :
+ case LINENO :
+ case DECIMAL :
+ fprintf(lfile, "%ld", (int32_t)pop->arg);
+ break;
+
+ case UDECIMAL :
+ fprintf(lfile, "%1lu", pop->arg);
+ break;
+
+ case fpOP :
+ if ((pop->arg & 0x3f) < MAX_FOP)
+ fprintf(lfile, "%s", fpName[(pop->arg & 0x3f)]);
+ else
+ fprintf(lfile, "%s", invFpOp);
+ break;
+
+ case xOP :
+ {
+ unsigned fileno = pop->arg >> 16;
+ unsigned xop = pop->arg & 0xffff;
+ fprintf(lfile, "%d, ", fileno);
+ if (xop < MAX_XOP)
+ fprintf(lfile, "%s", xName[xop]);
+ else
+ fprintf(lfile, "%s", invXOp);
+ }
+ break;
+
+ case lbOP :
+ if (pop->arg < MAX_LBOP)
+ fprintf(lfile, "%s", lbName[pop->arg]);
+ else
+ fprintf(lfile, "%s", invLbOp);
+ break;
+
+ case LABEL_DEC :
+ default :
+ break;
+ }
+ }
+
+ /* Don't forget the newline! */
+
+ fputc('\n', lfile);
+
+} /* end dissassemblePcode */
+
+/***********************************************************************/
diff --git a/misc/pascal/insn32/libinsn/pgen.c b/misc/pascal/insn32/libinsn/pgen.c
new file mode 100644
index 000000000..e92cc98f4
--- /dev/null
+++ b/misc/pascal/insn32/libinsn/pgen.c
@@ -0,0 +1,383 @@
+/**********************************************************************
+ * pgen.c
+ * P-Code generation logic
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "config.h" /* Configuration */
+#include "keywords.h" /* Standard types */
+#include "pdefs.h" /* Common types */
+#include "pofflib.h" /* POFF library definitions */
+#include "podefs.h" /* Logical opcode definitions */
+#include "pedefs.h" /* Error codes */
+#include "pinsn32.h" /* 32-bit target INSN opcode definitions */
+#include "perr.h" /* Error handling logic */
+
+#include "pinsn.h" /* (to verify prototypes in this file) */
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+#define INVALID_INCLUDE (-1)
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+extern poffHandle_t poffHandle; /* Handle to POFF object */
+extern FILE *lstFile; /* LIST file pointer */
+extern int16_t level; /* Static nesting level */
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static const uint8_t opmap[NUM_OPCODES] =
+{
+ oNOP, /* opNOP */
+ oNEG, /* opNEG */
+ oABS, /* opABS */
+ oINC, /* opINC */
+ oDEC, /* opDEC */
+ oNOT, /* opNOT */
+ oADD, /* opADD */
+ oSUB, /* opSUB */
+ oMUL, /* opMUL */
+ oDIV, /* opDIV */
+ oMOD, /* opMOD */
+ oSLL, /* opSLL */
+ oSRL, /* opSRL */
+ oSRA, /* opSRA */
+ oOR, /* opOR */
+ oAND, /* opAND */
+ oEQUZ, /* opEQUZ */
+ oNEQZ, /* opNEQZ */
+ oLTZ, /* opLTZ */
+ oGTEZ, /* opGTEZ */
+ oGTZ, /* opGTZ */
+ oLTEZ, /* opLTEZ */
+ oEQU, /* opEQU */
+ oNEQ, /* opNEQ */
+ oLT, /* opLT */
+ oGTE, /* opGTE */
+ oGT, /* opGT */
+ oLTE, /* opLTE */
+ oBIT, /* opBIT */
+ oLDI, /* opLDI */
+ oLDIB, /* opLDIB */
+ oLDIM, /* opLDIM */
+ oSTI, /* opSTI */
+ oSTIB, /* opSTIB */
+ oSTIM, /* opSTIM */
+ oDUP, /* opDUP */
+ oPUSHS, /* opPUSHS */
+ oPOPS, /* opPOPS */
+ oRET, /* opRET */
+ oEND, /* opEND */
+ oFLOAT, /* opFLOAT */
+ oJEQUZ, /* opJEQUZ */
+ oJNEQZ, /* opJNEQZ */
+ oJMP, /* opJMP */
+ oJEQU, /* opJEQU */
+ oJNEQ, /* opJNEQ */
+ oJLT, /* opJLT */
+ oJGTE, /* opJGTE */
+ oJGT, /* opJGT */
+ oJLTE, /* opJLTE */
+ oLD, /* opLD */
+ oLDH, /* opLDH */
+ oLDB, /* opLDB */
+ oLDM, /* opLDM */
+ oST, /* opST */
+ oSTB, /* opSTB */
+ oSTM, /* opSTM */
+ oLDX, /* opLDX */
+ oLDXB, /* opLDXB */
+ oLDXM, /* opLDXM */
+ oSTX, /* opSTX */
+ oSTXB, /* opSTXB */
+ oSTXM, /* opSTXM */
+ oLA, /* opLA */
+ oLAC, /* opLAC */
+ oPUSH, /* opPUSH */
+ oINDS, /* opINDS */
+ oLAX, /* opLAX */
+ oLIB, /* opLIB */
+ oLABEL, /* opLABEL */
+ oPCAL, /* opPCAL */
+ oLDS, /* opLDS */
+ oLDSH, /* opLDSH */
+ oLDSB, /* opLDSB */
+ oLDSM, /* opLDSM */
+ oSTS, /* opSTS */
+ oSTSB, /* opSTSB */
+ oSTSM, /* opSTSM */
+ oLDSX, /* opLDSX */
+ oLDSXB, /* opLDSXB */
+ oLDSXM, /* opLDSXM */
+ oSTSX, /* opSTSX */
+ oSTSXB, /* opSTSXB */
+ oSTSXM, /* opSTSXM */
+ oLAS, /* opLAS */
+ oLASX, /* opLASX */
+ oSYSIO, /* opSYSIO */
+ oLINE, /* opLINE */
+};
+
+static uint16_t g_nCurrentIncludeNumber = INVALID_INCLUDE;
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+static void
+insn32_GenerateSimple(uint8_t opcode);
+static void
+insn32_GenerateDataOperation(uint8_t opcode, uint32_t data);
+static void
+insn32_Generate(enum pcode_e opcode, uint32_t arg);
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Disassemble an Op-code */
+
+#if CONFIG_DEBUG
+static inline void
+insn32_DisassemblePCode(uint8_t opcode, uint32_t arg)
+{
+ OPTYPE op;
+
+ op.op = opcode;
+ op.arg = arg;
+
+ insn_DisassemblePCode(lstFile, &op);
+}
+#else
+# define insn32_DisassemblePCode(op,a)
+#endif
+
+/***********************************************************************/
+static inline void
+insn32_DisassembleOpcode(uint8_t opcode, uint32_t data)
+{
+#if CONFIG_DEBUG
+ OPTYPE op;
+ op.op = opcode;
+ op.arg = data;
+ insn32_DisassemblePCode(opcode, 0);
+#endif
+}
+
+/***********************************************************************/
+/* Generate an Op-Code */
+
+static void
+insn32_GenerateSimple(uint8_t opcode)
+{
+ TRACE(lstFile,"[insn32_GenerateSimple:0x%02x]", opcode);
+
+ /* Write the 8-bit opcode */
+
+ poffAddProgByte(poffHandle, opcode);
+
+ /* Now, add the disassembled PCode to the list file. */
+
+ insn32_DisassembleOpcode(opcode, 0);
+}
+
+/***********************************************************************/
+
+static void
+insn32_GenerateDataOperation(uint8_t opcode, uint32_t data)
+{
+ union
+ {
+ uint8_t b[4];
+ uint32_t w;
+ } udata;
+
+ TRACE(lstFile,"[insn32_GenerateDataOperation:0x%02x:0x%07x]", opcode, data);
+
+ /* Write the 8-bit opcode */
+
+ poffAddProgByte(poffHandle, opcode);
+
+ /* Write the 32-bit opcode */
+
+ udata.w = data;
+ (void)poffAddProgByte(poffHandle, udata.b[opB1]);
+ (void)poffAddProgByte(poffHandle, udata.b[opB2]);
+ (void)poffAddProgByte(poffHandle, udata.b[opB3]);
+ (void)poffAddProgByte(poffHandle, udata.b[opB4]);
+
+ /* Now, add the disassembled PCode to the list file. */
+
+ insn32_DisassembleOpcode(opcode, data);
+}
+
+/***********************************************************************/
+
+static void
+insn32_Generate(enum pcode_e opcode, uint32_t arg)
+{
+ uint8_t insn_opcode = opmap[opcode];
+
+ TRACE(lstFile,"[insn32_Generate:0x%02x->0x%02x]", opcode, insn_opcode);
+
+ if (insn_opcode & o32)
+ {
+ insn32_GenerateDataOperation(insn_opcode, arg);
+ }
+ else
+ {
+ insn32_GenerateSimple(insn_opcode);
+
+ /* We ignore the argument... what if one was provided? */
+
+ if (arg != 0)
+ {
+ warn(eARGIGNORED);
+ }
+ }
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+void
+insn_GenerateSimple(enum pcode_e opcode)
+{
+ insn32_Generate(opcode, 0);
+}
+
+/***********************************************************************/
+
+void
+insn_GenerateDataOperation(enum pcode_e opcode, int32_t data)
+{
+ insn32_Generate(opcode, (uint32_t)data);
+}
+
+/***********************************************************************/
+/* Data size for the next multiple register operation (in bytes) is
+ * retained in the DC register.
+ */
+
+void insn_GenerateDataSize(uint32_t dwDataSize)
+{
+ insn32_GenerateDataOperation(oSDC, dwDataSize);
+}
+
+/***********************************************************************/
+
+void
+insn_GenerateFpOperation(uint8_t fpOpcode)
+{
+ insn32_GenerateDataOperation(oFLOAT, fpOpcode);
+}
+
+/***********************************************************************/
+
+void
+insn_GenerateIoOperation(uint16_t ioOpcode, uint16_t fileNumber)
+{
+ uint32_t arg = (uint32_t)fileNumber << 16 | (uint32_t)ioOpcode;
+ insn32_GenerateDataOperation(oSYSIO, arg);
+}
+
+/***********************************************************************/
+
+void
+insn_BuiltInFunctionCall(uint16_t libOpcode)
+{
+ insn32_GenerateDataOperation(oLIB, (uint32_t)libOpcode);
+}
+
+/***********************************************************************/
+
+void
+insn_GenerateLevelReference(enum pcode_e opcode, uint16_t level, int32_t offset)
+{
+ /* Note that level is ignored. We used the level set by the
+ * preceding call to insn_SetStackLevel().
+ */
+
+ insn32_Generate(opcode, (uint32_t)offset);
+}
+
+/***********************************************************************/
+
+void
+insn_GenerateProcedureCall(uint16_t level, int32_t offset)
+{
+ insn32_GenerateDataOperation(oPCAL, (uint32_t)offset);
+}
+
+/***********************************************************************/
+
+void
+insn_GenerateLineNumber(uint16_t includeNumber, uint32_t lineNumber)
+{
+ if (includeNumber != g_nCurrentIncludeNumber)
+ {
+ g_nCurrentIncludeNumber = includeNumber;
+ insn32_GenerateDataOperation(oINCLUDE, includeNumber);
+ }
+ insn32_GenerateDataOperation(oLINE, lineNumber);
+}
+
+/***********************************************************************/
+
+void
+insn_SetStackLevel(uint32_t level)
+{
+ insn32_GenerateDataOperation(oSLSP, level);
+}
diff --git a/misc/pascal/insn32/libinsn/pgetopcode.c b/misc/pascal/insn32/libinsn/pgetopcode.c
new file mode 100644
index 000000000..a6f9507b2
--- /dev/null
+++ b/misc/pascal/insn32/libinsn/pgetopcode.c
@@ -0,0 +1,128 @@
+/**********************************************************************
+ * pgetopcode.c
+ * P-Code access utilities
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+
+#include "keywords.h"
+#include "podefs.h"
+#include "pinsn32.h"
+
+#include "paslib.h"
+#include "pofflib.h"
+#include "pinsn.h"
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+static int16_t g_bEndIn = 0; /* 1 = oEND pcode or EOF received */
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/**********************************************************************/
+
+uint32_t insn_GetOpCode(poffHandle_t handle, OPTYPE *ptr)
+{
+ uint32_t opsize = 1;
+ int c;
+
+ TRACE(stderr, "[insn_GetOpCode]");
+
+ /* If we are not already at the EOF, read the next character from
+ * the input stream.
+ */
+
+ if (!g_bEndIn)
+ c = poffGetProgByte(handle);
+ else
+ c = EOF;
+
+ /* Check for end of file. We may have previously parsed oEND which
+ * is a 'logical' end of file for a pascal program (but not a unit)
+ * or we may be at the physical end of the file wihout encountering
+ * oEND (typical for a UNIT file).
+ */
+
+ if ((g_bEndIn) || (c == EOF))
+ {
+ ptr->op = oEND;
+ }
+ else
+ {
+ ptr->op = c;
+ g_bEndIn = (c == oEND);
+
+ if (c & o32)
+ {
+ uint8_t *pb = (uint8_t*)&ptr->arg;
+ pb[opB1] = poffGetProgByte(handle);
+ pb[opB2] = poffGetProgByte(handle);
+ pb[opB3] = poffGetProgByte(handle);
+ pb[opB4] = poffGetProgByte(handle);
+ opsize += 4;
+ }
+ }
+
+ return opsize;
+}
+
+/**********************************************************************/
+
+void insn_ResetOpCodeRead(poffHandle_t handle)
+{
+ poffResetAccess(handle);
+ g_bEndIn = 0;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/insn32/libinsn/preloc.c b/misc/pascal/insn32/libinsn/preloc.c
new file mode 100644
index 000000000..7c0999219
--- /dev/null
+++ b/misc/pascal/insn32/libinsn/preloc.c
@@ -0,0 +1,149 @@
+/**********************************************************************
+ * preloc.c
+ * Perform P-Code relocations
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pedefs.h"
+#include "podefs.h"
+#include "pinsn32.h"
+
+#include "pofflib.h"
+#include "perr.h"
+#include "pinsn.h"
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Type Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+int insn_Relocate(OPTYPE *op, uint32_t pcOffset, uint32_t roOffset)
+{
+ switch (op->op)
+ {
+ /* Catch each instruction that references the read-only data
+ * section.
+ */
+
+ case oLAC:
+ /* Add the offset to the read-only data section */
+
+ op->arg += roOffset;
+ break;
+
+ /* Catch each instruction that references the text section
+ * data via an offset.
+ */
+
+ case oPCAL: /* Procedure / Function calls */
+ case oJMP: /* Unconditional jump */
+ case oJEQUZ: /* Jump on unary comparisons with zero */
+ case oJNEQZ:
+ case oJLTZ:
+ case oJGTEZ:
+ case oJGTZ:
+ case oJLTEZ:
+ case oJEQU: /* Jump on binary comparisons */
+ case oJNEQ:
+ case oJLT:
+ case oJGTE:
+ case oJGT:
+ case oJLTE:
+ /* Add the offset to the text section */
+
+ op->arg += pcOffset;
+ break;
+
+ /* Return an end of file indication if oEND encountered */
+
+ case oEND:
+ return 1;
+
+ /* Otherwise, it is not an interesting opcode */
+ default:
+ break;
+ }
+
+ /* Return 0 on all opcodes other than oEND */
+
+ return 0;
+}
+
+/***********************************************************************/
+
+void insn_FixupProcedureCall(uint8_t *progData, uint32_t symValue)
+{
+
+ /* Sanity checking */
+
+ if (progData[0] != oPCAL)
+ fatal(ePOFFCONFUSION);
+
+ if (symValue > 0xffff)
+ fatal(eBADSHORTINT);
+
+ /* Perform the relocation */
+
+ progData[2] = symValue >> 8;
+ progData[3] = symValue & 0xff;
+}
+
+
+/***********************************************************************/
diff --git a/misc/pascal/insn32/libinsn/presettmpopcodewrite.c b/misc/pascal/insn32/libinsn/presettmpopcodewrite.c
new file mode 100644
index 000000000..e08cccc51
--- /dev/null
+++ b/misc/pascal/insn32/libinsn/presettmpopcodewrite.c
@@ -0,0 +1,99 @@
+/**********************************************************************
+ * paddtmpopcode
+ * P-Code access utilities
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+
+#include "keywords.h"
+#include "podefs.h"
+#include "pinsn32.h"
+
+#include "paslib.h"
+#include "pofflib.h"
+#include "pinsn.h"
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/**********************************************************************/
+
+void insn_AddTmpOpCode(poffProgHandle_t hProg, OPTYPE *ptr)
+{
+ /* Write the opcode which is always present */
+
+ (void)poffAddTmpProgByte(hProg, ptr->op);
+
+ /* Write the 32-bit argument if present */
+
+ if (ptr->op & o32)
+ {
+ uint8_t *pb = (uint8_t*)&ptr->arg;
+
+ (void)poffAddTmpProgByte(hProg, pb[opB1]);
+ (void)poffAddTmpProgByte(hProg, pb[opB2]);
+ (void)poffAddTmpProgByte(hProg, pb[opB3]);
+ (void)poffAddTmpProgByte(hProg, pb[opB4]);
+ }
+}
+
+/**********************************************************************/
+
+void insn_ResetTmpOpCodeWrite(poffProgHandle_t hProg)
+{
+ poffResetProgHandle(hProg);
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/insn32/plist/Makefile b/misc/pascal/insn32/plist/Makefile
new file mode 100644
index 000000000..d74839878
--- /dev/null
+++ b/misc/pascal/insn32/plist/Makefile
@@ -0,0 +1,90 @@
+############################################################################
+# insn32/plist/Makefile
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Directories
+#
+PLISTDIR = ${shell pwd}
+INSNDIR = $(PLISTDIR)/..
+PASCAL = $(PLISTDIR)/../..
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+INCDIR = $(PASCAL)/include
+LIBDIR = $(PASCAL)/lib
+BINDIR = $(PASCAL)/bin32
+
+#
+# Tools
+#
+EXTRA_INCLUDES = -I$(INSNDIR)/include
+INCLUDES += $(EXTRA_INCLUDES)
+CFLAGS += $(EXTRA_INCLUDES)
+
+#
+# Objects and targets
+#
+PLISTSRCS = plist.c
+PLISTOBJS = $(PLISTSRCS:.c=.o)
+
+OBJS = $(PLISTOBJS)
+
+all: plist
+.PHONY: all plist clean
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+check_libs:
+ @if [ ! -f $(LIBDIR)/libpoff.a ] ; then \
+ echo "$(LIBDIR)/libpoff.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libpas.a ] ; then \
+ echo "$(LIBDIR)/libpas.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libinsn.a ] ; then \
+ echo "$(LIBDIR)/libinsn.a does not exist" ; \
+ exit 1 ; \
+ fi
+
+$(BINDIR)/plist: check_libs $(PLISTOBJS)
+ $(CC) -o $@ $(LDFLAGS) $(PLISTOBJS) -lpoff -linsn -lpas
+
+plist: $(BINDIR)/plist
+
+clean:
+ $(RM) plist *.o core *~
diff --git a/misc/pascal/insn32/plist/plist.c b/misc/pascal/insn32/plist/plist.c
new file mode 100644
index 000000000..a1667c7c2
--- /dev/null
+++ b/misc/pascal/insn32/plist/plist.c
@@ -0,0 +1,388 @@
+/**********************************************************************
+ * plist.c
+ * POFF file lister
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <string.h>
+
+#define _GNU_SOURCE
+#include <getopt.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "podefs.h"
+#include "pinsn32.h"
+#include "pedefs.h"
+
+#include "pofflib.h"
+
+#include "paslib.h"
+#include "pinsn.h"
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+#define MAX_STRING 80
+
+/**********************************************************************
+ * Private Data
+ **********************************************************************/
+
+static char *poffFileName = NULL;
+static int showFileHeader = 0;
+static int showSectionHeaders = 0;
+static int showSymbols = 0;
+static int showRelocs = 0;
+static int disassemble = 0;
+
+/**********************************************************************
+ * Private Constant Data
+ **********************************************************************/
+
+static const struct option long_options[] =
+{
+ {"all", 0, NULL, 'a'},
+ {"file-header", 0, NULL, 'h'},
+ {"section-headers", 0, NULL, 'S'},
+ {"symbols", 0, NULL, 's'},
+ {"relocs", 0, NULL, 'r'},
+ {"disassemble", 0, NULL, 'd'},
+ {"help", 0, NULL, 'H'},
+ {NULL, 0, NULL, 0}
+};
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static void showUsage (const char *progname);
+static void parseArgs (int argc, char **argv);
+static void dumpProgramData (poffHandle_t poffHandle);
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+int main (int argc, char *argv[], char *envp[])
+{
+ FILE *object; /* Object file pointer */
+ poffHandle_t poffHandle; /* Handle for POFF object */
+ char fileName[FNAME_SIZE+1]; /* Object file name */
+ uint16_t errCode; /* See pedefs.h */
+
+ /* Parse the command line arguments */
+
+ parseArgs(argc, argv);
+
+ /* Open source POFF file -- Use .o or command line extension, if supplied */
+
+ (void) extension (poffFileName, "o", fileName, 0);
+ if (!(object = fopen (fileName, "rb")))
+ {
+ printf ("Error opening %s\n", fileName);
+ exit (1);
+ } /* end if */
+
+ /* Read the POFF file */
+
+ poffHandle = poffCreateHandle();
+ if (poffHandle == NULL)
+ {
+ printf ("Could not get POFF handler\n");
+ exit (1);
+ }
+
+ errCode = poffReadFile(poffHandle, object);
+ if (errCode != eNOERROR)
+ {
+ printf ("Could not read POFF file\n");
+ exit (1);
+ }
+
+ /* Dump the File Header */
+
+ if (showFileHeader)
+ {
+ poffDumpFileHeader(poffHandle, stdout);
+ }
+
+ /* Dump the Section Headers */
+
+ if (showSectionHeaders)
+ {
+ poffDumpSectionHeaders(poffHandle, stdout);
+ }
+
+ /* Dump the symbol table */
+
+ if (showSymbols)
+ {
+ poffDumpSymbolTable(poffHandle, stdout);
+ }
+
+ /* Dump the relocation table */
+
+ if (showRelocs)
+ {
+ poffDumpRelocTable(poffHandle, stdout);
+ }
+
+ /* Dump the program data section -- Main Loop */
+
+ if (disassemble)
+ {
+ dumpProgramData(poffHandle);
+ }
+
+ /* Close files and release objects */
+
+ poffDestroyHandle(poffHandle);
+ (void)fclose(object);
+ return 0;
+} /* end main */
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+static void showUsage(const char *progname)
+{
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s [options] <poff-filename>\n",
+ progname);
+ fprintf(stderr, "options:\n");
+ fprintf(stderr, " -a --all Equivalent to: -h -S -s -r -d\n");
+ fprintf(stderr, " -h --file-header Display the POFF file header\n");
+ fprintf(stderr, " -S --section-headers Display the sections' header\n");
+ fprintf(stderr, " -s --symbols Display the symbol table\n");
+ fprintf(stderr, " -r --relocs Display the relocations\n");
+ fprintf(stderr, " -d --disassemble Display disassembled text\n");
+ fprintf(stderr, " -H --help Display this information\n");
+ exit(1);
+}
+
+/***********************************************************************/
+
+static void parseArgs(int argc, char **argv)
+{
+ int option_index;
+ int c;
+
+ /* Check for existence of filename argument */
+
+ if (argc < 2)
+ {
+ fprintf(stderr, "ERROR: POFF filename required\n");
+ showUsage(argv[0]);
+ } /* end if */
+
+ /* Parse the command line options */
+
+ do
+ {
+ c = getopt_long (argc, argv, "ahSsrdH",
+ long_options, &option_index);
+ if (c != -1)
+ {
+ switch (c)
+ {
+ case 'a' :
+ showFileHeader = 1;
+ showSectionHeaders = 1;
+ showSymbols = 1;
+ showRelocs = 1;
+ disassemble = 1;
+ break;
+
+ case 'h' :
+ showFileHeader = 1;
+ break;
+
+ case 'S' :
+ showSectionHeaders = 1;
+ break;
+
+ case 's' :
+ showSymbols = 1;
+ break;
+
+ case 'r' :
+ showRelocs = 1;
+ break;
+
+ case 'd' :
+ disassemble = 1;
+ break;
+
+ case 'H' :
+ showUsage(argv[0]);
+ break;
+
+ default:
+ /* Shouldn't happen */
+
+ fprintf(stderr, "ERROR: Unrecognized option\n");
+ showUsage(argv[0]);
+ }
+ }
+ }
+ while (c != -1);
+
+ /* Get the name of the p-code file(s) from the last argument(s) */
+
+ if (optind != argc-1)
+ {
+ fprintf(stderr, "ERROR: POFF filename required as final argument\n");
+ showUsage(argv[0]);
+ }
+
+ /* Save the POFF file name */
+
+ poffFileName = argv[argc-1];
+}
+
+/***********************************************************************/
+
+static void dumpProgramData(poffHandle_t poffHandle)
+{
+ poffLibLineNumber_t *lastln; /* Previous line number reference */
+ poffLibLineNumber_t *ln; /* Current line number reference */
+ poffLibDebugFuncInfo_t *dfi; /* Current line debug info */
+ uint32_t pc; /* Program counter */
+ int opSize; /* Size of the opcode */
+ int inch; /* Input char */
+ OPTYPE op; /* opcode */
+
+ /* Read the line number entries from the POFF file */
+
+ poffReadLineNumberTable(poffHandle);
+
+ /* Read the debug function information from the POFF file */
+
+ poffReadDebugFuncInfoTable(poffHandle);
+
+ /* Dump the program data section -- DumpProgramData Loop */
+
+ pc = 0;
+ lastln = NULL;
+
+ while ((inch = poffGetProgByte(poffHandle)) != EOF)
+ {
+ /* Get opcode arguments (if any) */
+
+ op.op = inch;
+ opSize = 1;
+
+ if (inch & o32)
+ {
+ uint32_t arg;
+
+ /* Handle 32-bits in big endian byte stream */
+
+ arg = poffGetProgByte(poffHandle) << 24;
+ arg |= poffGetProgByte(poffHandle) << 16;
+ arg |= poffGetProgByte(poffHandle) << 8;
+ arg |= poffGetProgByte(poffHandle);
+
+ op.arg = arg;
+ opSize += 4;
+ }
+
+ /* Check for debug information associated with this line */
+
+ dfi = poffFindDebugFuncInfo(pc);
+ if (dfi)
+ {
+ int i;
+ if (dfi->retsize)
+ {
+ printf("\nFUNCTION ENTRY: return size=%ld nparms=%ld\n",
+ dfi->retsize, dfi->nparms);
+ }
+ else
+ {
+ printf("\nPROCEDURE ENTRY: nparms=%ld\n", dfi->nparms);
+ }
+
+ for (i = 0; i < dfi->nparms; i++)
+ {
+ printf("Argument %2d: size=%ld\n", i, dfi->argsize[i]);
+ }
+ }
+
+ /* Find the line number associated with this line */
+
+ ln = poffFindLineNumber(pc);
+ if ((ln) && (ln != lastln))
+ {
+ /* Print the line number line */
+
+ printf("\n%s:%ld\n", ln->filename, ln->lineno);
+
+ /* This will suppress reporting the same line number
+ * repeatedly.
+ */
+
+ lastln = ln;
+ }
+
+ /* Print the address then the opcode on stdout */
+
+ fprintf(stdout, "%08lx ", pc);
+ insn_DisassemblePCode(stdout, &op);
+
+ /* Bump the PC to the next address */
+
+ pc += opSize;
+
+ } /* end while */
+
+ /* Release buffers associated with line number and debug information */
+
+ poffReleaseLineNumberTable();
+ poffReleaseDebugFuncInfoTable();
+
+} /* end dumpProgramData */
+
+/***********************************************************************/
diff --git a/misc/pascal/insn32/popt/Makefile b/misc/pascal/insn32/popt/Makefile
new file mode 100644
index 000000000..760c18fca
--- /dev/null
+++ b/misc/pascal/insn32/popt/Makefile
@@ -0,0 +1,93 @@
+############################################################################
+# insn32/popt/Makefile
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Directories
+#
+POPTDIR = ${shell pwd}
+INSNDIR = $(POPTDIR)/..
+PASCAL = $(POPTDIR)/../..
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+INCDIR = $(PASCAL)/include
+LIBDIR = $(PASCAL)/lib
+BINDIR = $(PASCAL)/bin32
+
+# ----------------------------------------------------------------------
+# Tools
+
+EXTRA_INCLUDES = -I$(INSNDIR)/include
+INCLUDES += $(EXTRA_INCLUDES)
+CFLAGS += $(EXTRA_INCLUDES)
+
+# ----------------------------------------------------------------------
+# Objects and targets
+
+POPTSRCS = popt.c psopt.c polocal.c pcopt.c pjopt.c plopt.c pfopt.c
+POPTOBJS = $(POPTSRCS:.c=.o)
+
+OBJS = $(POPTOBJS)
+LIBS = libpoff.a libpas.a
+
+all: popt
+.PHONY: all check_libs popt clean
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+check_libs:
+ @if [ ! -f $(LIBDIR)/libpoff.a ] ; then \
+ echo "$(LIBDIR)/libpoff.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libpas.a ] ; then \
+ echo "$(LIBDIR)/libpas.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libinsn.a ] ; then \
+ echo "$(LIBDIR)/libinsn.a does not exist" ; \
+ exit 1 ; \
+ fi
+
+$(BINDIR)/popt: check_libs $(POPTOBJS)
+ $(CC) -o $@ $(LDFLAGS) $(POPTOBJS) -linsn -lpoff -lpas
+
+popt: $(BINDIR)/popt
+
+clean:
+ $(RM) popt *.o core *~
+
+# ----------------------------------------------------------------------
diff --git a/misc/pascal/insn32/popt/pcopt.c b/misc/pascal/insn32/popt/pcopt.c
new file mode 100644
index 000000000..a0c0a0226
--- /dev/null
+++ b/misc/pascal/insn32/popt/pcopt.c
@@ -0,0 +1,840 @@
+/**********************************************************************
+ * pcopt.c
+ * Constant Expression Optimizations
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pinsn32.h"
+
+#include "paslib.h"
+#include "popt.h"
+#include "polocal.h"
+#include "pcopt.h"
+
+/**********************************************************************/
+
+int unaryOptimize(void)
+{
+ register uint32_t temp;
+ register int i;
+ int nchanges = 0;
+
+ TRACE(stderr, "[unaryOptimize]");
+
+ /* At least two pcodes are need to perform unary optimizations */
+
+ i = 0;
+ while (i < nops-1)
+ {
+ /* Check for a constant value being pushed onto the stack */
+
+ if (GETOP(pptr[i]) == oPUSH)
+ {
+ switch (GETOP(pptr[i+1]))
+ {
+ /* Delete unary operators on constants */
+ case oNEG :
+ PUTARG(pptr[i], -GETARG(pptr[i]));
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oABS :
+ if ((int32_t)GETARG(pptr[i]) < 0)
+ PUTARG(pptr[i], -(int32_t)GETARG(pptr[i]));
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oINC :
+ PUTARG(pptr[i], GETARG(pptr[i]) + 1);
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oDEC :
+ PUTARG(pptr[i], GETARG(pptr[i]) - 1);
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oNOT :
+ PUTARG(pptr[i], ~GETARG(pptr[i]));
+ PUTARG(pptr[i], ~(GETARG(pptr[i])));
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ /* Simplify binary operations on constants */
+
+ case oADD :
+ if (GETARG(pptr[i]) == 0)
+ {
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ } /* end if */
+ else if (GETARG(pptr[i]) == 1)
+ {
+ PUTOP(pptr[i+1], oINC);
+ deletePcode(i);
+ nchanges++;
+ } /* end else if */
+ else if (GETARG(pptr[i]) == ARGONES)
+ {
+ PUTOP(pptr[i+1], oDEC);
+ deletePcode(i);
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oSUB :
+ if (GETARG(pptr[i]) == 0)
+ {
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ } /* end if */
+ else if (GETARG(pptr[i]) == 1)
+ {
+ PUTOP(pptr[i+1], oDEC);
+ deletePcode(i);
+ nchanges++;
+ } /* end else if */
+ else if (GETARG(pptr[i]) == ARGONES)
+ {
+ PUTOP(pptr[i+1], oINC);
+ deletePcode(i);
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oMUL :
+ case oDIV :
+ temp = 0;
+ switch (GETARG(pptr[i]))
+ {
+ case 1 :
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ break;
+ case 16384 : temp++;
+ case 8192 : temp++;
+ case 4096 : temp++;
+ case 2048 : temp++;
+ case 1024 : temp++;
+ case 512 : temp++;
+ case 256 : temp++;
+ case 128 : temp++;
+ case 64 : temp++;
+ case 32 : temp++;
+ case 16 : temp++;
+ case 8 : temp++;
+ case 4 : temp++;
+ case 2 : temp++;
+ PUTARG(pptr[i], temp);
+ if (GETOP(pptr[i+1]) == oMUL)
+ PUTOP(pptr[i+1], oSLL);
+ else
+ PUTOP(pptr[i+1], oSRA);
+ nchanges++;
+ i++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oSLL :
+ case oSRL :
+ case oSRA :
+ case oOR :
+ if (GETARG(pptr[i]) == 0)
+ {
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oAND :
+ if (GETARG(pptr[i]) == ARGONES)
+ {
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ /* Delete comparisons of constants to zero */
+
+ case oEQUZ :
+ if (GETARG(pptr[i]) == 0)
+ PUTARG(pptr[i], -1);
+ else
+ PUTARG(pptr[i], 0);
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oNEQZ :
+ if (GETARG(pptr[i]) != 0)
+ PUTARG(pptr[i], -1);
+ else
+ PUTARG(pptr[i], 0);
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oLTZ :
+ if ((int32_t)GETARG(pptr[i]) < 0)
+ PUTARG(pptr[i], -1);
+ else
+ PUTARG(pptr[i], 0);
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oGTEZ :
+ if ((int32_t)GETARG(pptr[i]) >= 0)
+ PUTARG(pptr[i], -1);
+ else
+ PUTARG(pptr[i], 0);
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oGTZ :
+ if (GETARG(pptr[i]) > 0)
+ PUTARG(pptr[i], -1);
+ else
+ PUTARG(pptr[i], 0);
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oLTEZ :
+ if (GETARG(pptr[i]) <= 0)
+ PUTARG(pptr[i], -1);
+ else
+ PUTARG(pptr[i], 0);
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ /* Simplify comparisons with certain constants */
+
+ case oEQU :
+ if (GETARG(pptr[i]) == 0)
+ {
+ PUTOP(pptr[i+1],oEQUZ);
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else if (GETARG(pptr[i]) == 1)
+ {
+ PUTOP(pptr[i], oDEC);
+ PUTARG(pptr[i], 0);
+ PUTOP(pptr[i+1], oEQUZ);
+ nchanges++;
+ } /* end else if */
+ else if ((int32_t)GETARG(pptr[i]) == -1)
+ {
+ PUTOP(pptr[i], oINC);
+ PUTARG(pptr[i], 0);
+ PUTOP(pptr[i+1], oEQUZ);
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oNEQ :
+ if (GETARG(pptr[i]) == 0)
+ {
+ PUTOP(pptr[i+1], oNEQZ);
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else if (GETARG(pptr[i]) == 1)
+ {
+ PUTOP(pptr[i], oDEC);
+ PUTARG(pptr[i], 0);
+ PUTOP(pptr[i+1], oNEQZ);
+ nchanges++;
+ } /* end else if */
+ else if ((int32_t)GETARG(pptr[i]) == -1)
+ {
+ PUTOP(pptr[i], oINC);
+ PUTARG(pptr[i], 0);
+ PUTOP(pptr[i+1], oNEQZ);
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oLT :
+ if (GETARG(pptr[i]) == 0)
+ {
+ PUTOP(pptr[i+1], oLTZ);
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else if (GETARG(pptr[i]) == 1)
+ {
+ PUTOP(pptr[i], oDEC);
+ PUTARG(pptr[i], 0);
+ PUTOP(pptr[i+1], oLTZ);
+ nchanges++;
+ } /* end else if */
+ else if ((int32_t)GETARG(pptr[i]) == -1)
+ {
+ PUTOP(pptr[i], oINC);
+ PUTARG(pptr[i], 0);
+ PUTOP(pptr[i+1], oLTZ);
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oGTE :
+ if (GETARG(pptr[i]) == 0)
+ {
+ PUTOP(pptr[i+1], oGTEZ);
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else if (GETARG(pptr[i]) == 1)
+ {
+ PUTOP(pptr[i], oDEC);
+ PUTARG(pptr[i], 0);
+ PUTOP(pptr[i+1], oGTEZ);
+ nchanges++;
+ } /* end else if */
+ else if ((int32_t)GETARG(pptr[i]) == -1)
+ {
+ PUTOP(pptr[i], oINC);
+ PUTARG(pptr[i], 0);
+ PUTOP(pptr[i+1], oGTEZ);
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oGT :
+ if (GETARG(pptr[i]) == 0)
+ {
+ PUTOP(pptr[i+1], oGTZ);
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else if (GETARG(pptr[i]) == 1)
+ {
+ PUTOP(pptr[i], oDEC);
+ PUTARG(pptr[i], 0);
+ PUTOP(pptr[i+1], oGTZ);
+ nchanges++;
+ } /* end else if */
+ else if ((int32_t)GETARG(pptr[i]) == -1)
+ {
+ PUTOP(pptr[i], oINC);
+ PUTARG(pptr[i], 0);
+ PUTOP(pptr[i+1], oGTZ);
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oLTE :
+ if (GETARG(pptr[i]) == 0)
+ {
+ PUTOP(pptr[i+1], oLTEZ);
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else if (GETARG(pptr[i]) == 1)
+ {
+ PUTOP(pptr[i], oDEC);
+ PUTARG(pptr[i], 0);
+ PUTOP(pptr[i+1], oLTEZ);
+ nchanges++;
+ } /* end else if */
+ else if ((int32_t)GETARG(pptr[i]) == -1)
+ {
+ PUTOP(pptr[i], oINC);
+ PUTARG(pptr[i], 0);
+ PUTOP(pptr[i+1], oLTEZ);
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ /* Simplify or delete condition branches on constants */
+
+ case oJEQUZ :
+ if (GETARG(pptr[i]) == 0)
+ {
+ PUTOP(pptr[i+1], oJMP);
+ deletePcode(i);
+ } /* end if */
+ else
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ if (GETARG(pptr[i]) != 0)
+ {
+ PUTOP(pptr[i+1], oJMP);
+ deletePcode(i);
+ } /* end if */
+ else
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ break;
+
+ case oJLTZ :
+ if ((int32_t)GETARG(pptr[i]) < 0)
+ {
+ PUTOP(pptr[i+1], oJMP);
+ deletePcode(i);
+ } /* end if */
+ else
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ break;
+
+ case oJGTEZ :
+ if ((int32_t)GETARG(pptr[i]) >= 0)
+ {
+ PUTOP(pptr[i+1], oJMP);
+ deletePcode(i);
+ } /* end if */
+ else
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ break;
+
+ case oJGTZ :
+ if (GETARG(pptr[i]) > 0)
+ {
+ PUTOP(pptr[i+1], oJMP);
+ deletePcode(i);
+ } /* end if */
+ else
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ break;
+
+ case oJLTEZ :
+ if (GETARG(pptr[i]) <= 0)
+ {
+ PUTOP(pptr[i+1], oJMP);
+ deletePcode(i);
+ } /* end if */
+ else
+ deletePcodePair(i, (i+1));
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ } /* end if */
+
+ /* Delete multiple modifications of DSEG pointer */
+
+ else if (GETOP(pptr[i]) == oINDS)
+ {
+ if (GETOP(pptr[i+1]) == oINDS)
+ {
+ PUTARG(pptr[i], GETARG(pptr[i] + GETARG(pptr[i+1])));
+ deletePcode(i+1);
+ } /* end if */
+ else i++;
+ } /* end else if */
+ else i++;
+ } /* end while */
+
+ return (nchanges);
+
+} /* end unaryOptimize */
+
+/**********************************************************************/
+
+int binaryOptimize(void)
+{
+ register int i;
+ int nchanges = 0;
+
+ TRACE(stderr, "[binaryOptimize]");
+
+ /* At least two pcodes are needed to perform the following binary */
+ /* operator optimizations */
+
+ i = 0;
+ while (i < nops-2)
+ {
+ if (GETOP(pptr[i]) == oPUSH)
+ {
+ if (GETOP(pptr[i+1]) == oPUSH)
+ {
+ switch (GETOP(pptr[i+2]))
+ {
+ case oADD :
+ PUTARG(pptr[i], GETARG(pptr[i]) + GETARG(pptr[i+1]));
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oSUB :
+ PUTARG(pptr[i], GETARG(pptr[i]) - GETARG(pptr[i+1]));
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oMUL :
+ PUTARG(pptr[i], GETARG(pptr[i]) * GETARG(pptr[i+1]));
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oDIV :
+ PUTARG(pptr[i], GETARG(pptr[i]) / (int32_t)GETARG(pptr[i+1]));
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oMOD :
+ PUTARG(pptr[i], GETARG(pptr[i]) % GETARG(pptr[i+1]));
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oSLL :
+ PUTARG(pptr[i], GETARG(pptr[i]) << GETARG(pptr[i+1]));
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oSRL :
+ PUTARG(pptr[i], GETARG(pptr[i]) >> GETARG(pptr[i+1]));
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oSRA :
+ PUTARG(pptr[i], (int32_t)GETARG(pptr[i]) >> GETARG(pptr[i+1]));
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oOR :
+ PUTARG(pptr[i], GETARG(pptr[i]) | GETARG(pptr[i+1]));
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oAND :
+ PUTARG(pptr[i], GETARG(pptr[i]) & GETARG(pptr[i+1]));
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oEQU :
+ if (GETARG(pptr[i]) == GETARG(pptr[i+1]))
+ PUTARG(pptr[i], -1);
+ else
+ PUTARG(pptr[i], 0);
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oNEQ :
+ if (GETARG(pptr[i]) != GETARG(pptr[i+1]))
+ PUTARG(pptr[i], -1);
+ else
+ PUTARG(pptr[i], 0);
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oLT :
+ if ((int32_t)GETARG(pptr[i]) < (int32_t)GETARG(pptr[i+1]))
+ PUTARG(pptr[i], -1);
+ else
+ PUTARG(pptr[i], 0);
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oGTE :
+ if ((int32_t)GETARG(pptr[i]) >= (int32_t)GETARG(pptr[i+1]))
+ PUTARG(pptr[i], -1);
+ else
+ PUTARG(pptr[i], 0);
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oGT :
+ if ((int32_t)GETARG(pptr[i]) > (int32_t)GETARG(pptr[i+1]))
+ PUTARG(pptr[i], -1);
+ else
+ PUTARG(pptr[i], 0);
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ case oLTE :
+ if ((int32_t)GETARG(pptr[i]) <= (int32_t)GETARG(pptr[i+1]))
+ PUTARG(pptr[i], -1);
+ else
+ PUTARG(pptr[i], 0);
+ deletePcodePair((i+1), (i+2));
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ } /* end if */
+
+ /* A single (constant) pcode is sufficient to perform the */
+ /* following binary operator optimizations */
+
+ else if ((GETOP(pptr[i+1]) == oLDSH) || (GETOP(pptr[i+1]) == oLDSB) ||
+ (GETOP(pptr[i+1]) == oLAS) || (GETOP(pptr[i+1]) == oLAC))
+ {
+ switch (GETOP(pptr[i+2]))
+ {
+ case oADD :
+ if (GETARG(pptr[i]) == 0)
+ {
+ deletePcodePair(i, (i+2));
+ nchanges++;
+ } /* end if */
+ else if (GETARG(pptr[i]) == 1)
+ {
+ PUTOP(pptr[i+2], oINC);
+ deletePcode(i);
+ nchanges++;
+ } /* end else if */
+ else if (GETARG(pptr[i]) == ARGONES)
+ {
+ PUTOP(pptr[i+2], oDEC);
+ deletePcode(i);
+ nchanges++;
+ } /* end else if */
+ else i++;
+ break;
+
+ case oSUB :
+ if (GETARG(pptr[i]) == 0)
+ {
+ PUTOP(pptr[i], oNEG);
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oMUL :
+ {
+ int32_t stmp32 = 0;
+ switch (GETARG(pptr[i]))
+ {
+ case 1 :
+ deletePcodePair(i, (i+2));
+ nchanges++;
+ break;
+ case 16384 : stmp32++;
+ case 8192 : stmp32++;
+ case 4096 : stmp32++;
+ case 2048 : stmp32++;
+ case 1024 : stmp32++;
+ case 512 : stmp32++;
+ case 256 : stmp32++;
+ case 128 : stmp32++;
+ case 64 : stmp32++;
+ case 32 : stmp32++;
+ case 16 : stmp32++;
+ case 8 : stmp32++;
+ case 4 : stmp32++;
+ case 2 : stmp32++;
+ PUTOP(pptr[i], GETOP(pptr[i+1]));
+ PUTARG(pptr[i], GETARG(pptr[i+1]));
+ PUTOP(pptr[i+1], oPUSH);
+ PUTARG(pptr[i+1], stmp32);
+ PUTOP(pptr[i+2], oSLL);
+ nchanges++;
+ i++;
+ break;
+
+ default :
+ i++;
+ break;
+ }
+ }
+ break;
+
+ case oOR :
+ if (GETARG(pptr[i]) == 0)
+ {
+ deletePcodePair(i, (i+2));
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oAND :
+ if (GETARG(pptr[i]) == ARGONES)
+ {
+ deletePcodePair(i, (i+2));
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oEQU :
+ if (GETARG(pptr[i]) == 0)
+ {
+ PUTOP(pptr[i+2], oEQUZ);
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oNEQ :
+ if (GETARG(pptr[i]) == 0)
+ {
+ PUTOP(pptr[i+2], oNEQZ);
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oLT :
+ if (GETARG(pptr[i]) == 0)
+ {
+ PUTOP(pptr[i+2], oGTEZ);
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oGTE :
+ if (GETARG(pptr[i]) == 0)
+ {
+ PUTOP(pptr[i+2], oLTZ);
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oGT :
+ if (GETARG(pptr[i]) == 0)
+ {
+ PUTOP(pptr[i+2], oLTEZ);
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ case oLTE :
+ if (GETARG(pptr[i]) == 0)
+ {
+ PUTOP(pptr[i+2], oGTZ);
+ deletePcode(i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ default :
+ i++;
+ break;
+
+ } /* end switch */
+ } /* end else if */
+ else i++;
+ } /* end if */
+
+ /* Misc improvements on binary operators */
+
+ else if (GETOP(pptr[i]) == oNEG)
+ {
+ /* Negation followed by add is subtraction */
+
+ if (GETOP(pptr[i+1]) == oADD)
+ {
+ PUTOP(pptr[i+1], oSUB);
+ deletePcode(i);
+ nchanges++;
+ }
+
+ /* Negation followed by subtraction is addition */
+
+ else if (GETOP(pptr[i]) == oSUB)
+ {
+ PUTOP(pptr[i+1], oADD);
+ deletePcode(i);
+ nchanges++;
+ }
+ else i++;
+ }
+ else i++;
+ } /* end while */
+
+ return (nchanges);
+
+} /* end binaryOptimize */
+
+/**********************************************************************/
diff --git a/misc/pascal/insn32/popt/pcopt.h b/misc/pascal/insn32/popt/pcopt.h
new file mode 100644
index 000000000..0c3d453b9
--- /dev/null
+++ b/misc/pascal/insn32/popt/pcopt.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * pcopt.h
+ * External Declarations associated with PCOPT.C
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PCOPT_H
+#define __PCOPT_H
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern int unaryOptimize ( void );
+extern int binaryOptimize ( void );
+
+#endif /* __PCOPT_H */
diff --git a/misc/pascal/insn32/popt/pfopt.c b/misc/pascal/insn32/popt/pfopt.c
new file mode 100644
index 000000000..a9f1659c6
--- /dev/null
+++ b/misc/pascal/insn32/popt/pfopt.c
@@ -0,0 +1,544 @@
+/**********************************************************************
+ * pfopt.c
+ * Finalization of optimized image
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "podefs.h"
+#include "pedefs.h"
+#include "pinsn32.h"
+#include "poff.h"
+
+#include "paslib.h"
+#include "pofflib.h"
+#include "popt.h"
+#include "pfopt.h"
+#include "pinsn.h"
+#include "perr.h"
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Types
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Data
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Inline Functions
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/**********************************************************************/
+
+static void pass1(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ OPTYPE op;
+ uint32_t pc;
+ int opsize;
+ int fileno = 0;
+
+ /* Build label / line number reference table
+ *
+ * CASE 1: LABEL
+ * Add label number + PC to table
+ * discard
+ * CASE 2: LINE
+ * genereate a line number reference
+ * discard
+ * ELSE:
+ * pass through with no additional action
+ */
+
+ pc = 0;
+ do
+ {
+ opsize = insn_GetOpCode(poffHandle, &op);
+ if (GETOP(&op) == oLABEL)
+ {
+ poffAddToDefinedLabelTable(GETARG(&op), pc);
+ }
+ else if (GETOP(&op) == oINCLUDE)
+ {
+ fileno = GETARG(&op);
+ }
+ else if (GETOP(&op) == oLINE)
+ {
+ poffAddLineNumber(poffHandle, GETARG(&op), fileno, pc);
+ }
+ else
+ {
+ insn_AddTmpOpCode(poffProgHandle, &op);
+ pc += opsize;
+ }
+ }
+ while (GETOP(&op) != oEND);
+
+ /* Replace the original program data with the new program data */
+
+ poffReplaceProgData(poffHandle, poffProgHandle);
+}
+
+/**********************************************************************/
+
+static void pass2(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ poffSymHandle_t poffSymHandle;
+ int32_t symIndex;
+ int32_t nchanges = 0;
+
+ /* Get a container to temporarily hold any modifications that we
+ * make to the symbol table.
+ */
+
+ poffSymHandle = poffCreateSymHandle();
+ if (poffSymHandle == NULL)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* Now read all of the symbols. (1) Add each undefined code reference
+ * to the label reference table, and (2) Change each defined code
+ * reference from a label to a program data section offset.
+ */
+
+ do
+ {
+ poffLibSymbol_t symbol;
+ symIndex = poffGetSymbol(poffHandle, &symbol);
+ if (symIndex >= 0)
+ {
+ if ((symbol.type == STT_PROC) || (symbol.type == STT_FUNC))
+ {
+ /* It is a symbol associated with the program data section.
+ * Has is value been defined?
+ */
+
+ if ((symbol.flags & STF_UNDEFINED) != 0)
+ {
+ /* No... Add it to the list of undefined labels */
+
+ poffAddToUndefinedLabelTable(symbol.value, symIndex);
+ }
+ else
+ {
+ /* It is a defined symbol. In this case, we should have
+ * encountered its LABEL marker in the pass1 processing
+ * and the following look up should not fail.
+ */
+ int32_t value = poffGetPcForDefinedLabel(symbol.value);
+ if (value < 0)
+ {
+ DEBUG(stdout, "Failed to find label L%04lx\n", symbol.value);
+ fatal(ePOFFCONFUSION);
+ }
+ else
+ {
+ /* Replace the lavel value with the section offset
+ * (pc) value.
+ */
+
+ symbol.value = value;
+ nchanges++;
+ }
+ }
+ }
+
+ /* In either event, we will want to save the symbol in case
+ * we need to re-write the symbol table.
+ */
+
+ (void)poffAddTmpSymbol(poffHandle, poffSymHandle, &symbol);
+ }
+ }
+ while (symIndex >= 0);
+
+ /* We any changes made to the symbol table in the temporary container? */
+
+ if (nchanges != 0)
+ {
+ /* Yes, update the symbol table */
+
+ poffReplaceSymbolTable(poffHandle, poffSymHandle);
+
+ }
+
+ /* Release the symbol container. */
+
+ poffDestroySymHandle(poffSymHandle);
+}
+
+/**********************************************************************/
+
+static void pass3(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ OPTYPE op;
+ uint32_t pc;
+ uint32_t opsize;
+
+ /* Read each opcode, generate relocation information and
+ * replace label references with program section offsets.
+ *
+ * CASE 1: LAC
+ * generate RODATA relocation entry
+ * CASE 2: PCAL instructions
+ * replace label with I-space offset, OR
+ * generate a PROGRAM relocation entry
+ * CASE 3: J* instructions
+ * replace label with I-space offset
+ * CASE 4: LDS*, STS*, and LAS* instructions
+ * generate a STACK relocation (if imported?)
+ * ELSE:
+ * pass through with no additional action
+ */
+
+ pc = 0;
+ do
+ {
+ opsize = insn_GetOpCode(poffHandle, &op);
+ switch (GETOP(&op))
+ {
+ /* Load of an address in the rodata section */
+
+ case oLAC:
+ /* We are referencing something from the rodata section.
+ * No special action need be taken.
+ */
+ break;
+
+ /* Call to a procedure or function. */
+
+ case oPCAL:
+ {
+ /* Check if this is a defined label, i.e., a call to
+ * procedure or function in the same file.
+ */
+
+ int32_t value = poffGetPcForDefinedLabel(GETARG(&op));
+ if (value >= 0)
+ {
+ /* Yes... replace the label reference with
+ * a text section offset. No relocation record
+ * is needed in this case. The only relocation
+ * may be performed is a subsequent program data
+ * section offset.
+ */
+
+ PUTARG(&op, value);
+ }
+ else
+ {
+ /* Check if this is a undefined label. This would
+ * occur for a call to a procedure or a function that
+ * is defined in some other unit file.
+ */
+
+ value = poffGetSymIndexForUndefinedLabel(GETARG(&op));
+ if (value >= 0)
+ {
+ /* Use the value zero now */
+
+ PUTARG(&op, 0);
+
+ /* And generate a symbol-based relocation */
+
+ (void)poffAddRelocation(poffHandle, RLT_PCAL, value, pc);
+ }
+ else
+ {
+ DEBUG(stdout, "Failed to find call label L%04x\n",
+ GETARG(&op));
+ fatal(ePOFFCONFUSION);
+ }
+ }
+ }
+ break;
+
+ /* Jumps to "nearby" addresses */
+
+ case oJMP: /* Unconditional */
+ case oJEQUZ: /* Unary comparisons with zero */
+ case oJNEQZ:
+ case oJLTZ:
+ case oJGTEZ:
+ case oJGTZ:
+ case oJLTEZ:
+ case oJEQU: /* Binary comparisons */
+ case oJNEQ:
+ case oJLT:
+ case oJGTE:
+ case oJGT:
+ case oJLTE:
+ {
+ /* Check if this is a defined label. This must be the case
+ * because there can be no jumps into a unit file.
+ */
+
+ int32_t value = poffGetPcForDefinedLabel(GETARG(&op));
+ if (value >= 0)
+ {
+ /* Yes... replace the label reference with
+ * a text section offset. No relocation record
+ * is needed in this case. The only relocation
+ * may be performed is a subsequent program data
+ * sectioin offset.
+ */
+
+ PUTARG(&op, value);
+ }
+ else
+ {
+ DEBUG(stdout, "Failed to find jump label L%04x\n",
+ GETARG(&op));
+ fatal(ePOFFCONFUSION);
+ }
+ }
+ break;
+
+ /* References to stack via level offset */
+
+ case oLAS: /* Load stack address */
+ case oLASX:
+ case oLDS: /* Load value */
+ case oLDSH:
+ case oLDSB:
+ case oLDSM:
+ case oSTS: /* Store value */
+ case oSTSH:
+ case oSTSB:
+ case oSTSM:
+ case oLDSX:
+ case oLDSXH: /* Load value indexed */
+ case oLDSXB:
+ case oLDSXM:
+ case oSTSX: /* Store value indexed */
+ case oSTSXH:
+ case oSTSXB:
+ case oSTSXM:
+ {
+#warning REVISIT
+ }
+ break;
+
+ /* Otherwise, it is not an interesting opcode */
+ default:
+ break;
+ }
+
+ /* Save the potentially modified opcode in the temporary
+ * program data container.
+ */
+
+ insn_AddTmpOpCode(poffProgHandle, &op);
+ pc += opsize;
+ }
+ while (GETOP(&op) != oEND);
+
+ /* Replace the original program data with the new program data */
+
+ poffReplaceProgData(poffHandle, poffProgHandle);
+}
+
+/**********************************************************************/
+/* Fixed label references in the debug function information */
+
+static void pass4(poffHandle_t poffHandle)
+{
+ poffLibDebugFuncInfo_t *pDebugInfoHead = NULL;
+ poffLibDebugFuncInfo_t *pDebugInfoTail = NULL;
+ poffLibDebugFuncInfo_t *pDebugInfo;
+ poffLibDebugFuncInfo_t *pNextDebugInfo;
+
+ /* Read all function debug information into a link list */
+
+ while ((pDebugInfo = poffGetDebugFuncInfo(poffHandle)) != NULL)
+ {
+ if (!pDebugInfoHead)
+ {
+ pDebugInfoHead = pDebugInfo;
+ }
+ else
+ {
+ pDebugInfoTail->next = pDebugInfo;
+ }
+ pDebugInfoTail = pDebugInfo;
+ }
+
+ /* Convert all of the label references to pcode offsets */
+
+ for (pDebugInfo = pDebugInfoHead; pDebugInfo; pDebugInfo = pDebugInfo->next)
+ {
+ /* Check if this is a defined label. This must be the case
+ * because there can be no jumps into a unit file.
+ */
+
+ int32_t value = poffGetPcForDefinedLabel(pDebugInfo->value);
+ if (value >= 0)
+ {
+ /* Yes... replace the label reference with a text section offset. */
+
+ pDebugInfo->value = value;
+ }
+ else
+ {
+ fatal(ePOFFCONFUSION);
+ }
+ }
+
+ /* Then put all of the debug info back into the POFF object */
+
+ poffDiscardDebugFuncInfo(poffHandle);
+
+ for (pDebugInfo = pDebugInfoHead; pDebugInfo; pDebugInfo = pDebugInfo->next)
+ {
+ poffAddDebugFuncInfo(poffHandle, pDebugInfo);
+ }
+
+ /* Release the bufferred debug information */
+
+ pDebugInfo = pDebugInfoHead;
+ while (pDebugInfo)
+ {
+ pNextDebugInfo = pDebugInfo->next;
+ poffReleaseDebugFuncContainer(pDebugInfo);
+ pDebugInfo = pNextDebugInfo;
+ }
+}
+
+/**********************************************************************/
+
+static void pass5(poffHandle_t poffHandle)
+{
+ uint32_t entryLabel;
+ int32_t entryOffset;
+ uint8_t fileType;
+
+ /* What kind of a file did we just process. Was it a program file?
+ * or was it a unit file?
+ */
+
+ fileType = poffGetFileType(poffHandle);
+ if (fileType == FHT_PROGRAM)
+ {
+ /* It is a program file. In this case, it must have a valid
+ * entry point label. Get it.
+ */
+
+ entryLabel = poffGetEntryPoint(poffHandle);
+
+ /* Convert the label into a program data section offset */
+
+ entryOffset = poffGetPcForDefinedLabel(entryLabel);
+ if (entryOffset < 0)
+ {
+ fatal(ePOFFCONFUSION);
+ }
+
+ /* Replace file header entry point with the program data
+ * section offset
+ */
+
+ poffSetEntryPoint(poffHandle, entryOffset);
+ }
+}
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+void optFinalize(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ /* Build label / line number reference table */
+
+ pass1(poffHandle, poffProgHandle);
+
+ /* Reset for next pass */
+
+ insn_ResetOpCodeRead(poffHandle);
+ insn_ResetTmpOpCodeWrite(poffProgHandle);
+
+ /* Now process all of the symbols */
+
+ pass2(poffHandle, poffProgHandle);
+
+ /* Reset for next pass */
+
+ insn_ResetOpCodeRead(poffHandle);
+
+ /* Generate relocation information and replace all label references
+ * in the code with actual program section data offsets.
+ */
+
+ pass3(poffHandle, poffProgHandle);
+
+ /* Fixed label references in the debug function information */
+
+ pass4(poffHandle);
+
+ /* Reset for next pass */
+
+ insn_ResetOpCodeRead(poffHandle);
+ insn_ResetTmpOpCodeWrite(poffProgHandle);
+
+ /* Finally, replace file header entry point with the I-space offset */
+
+ pass5(poffHandle);
+
+ /* Clean up after ourselves */
+
+ poffReleaseLabelReferences();
+}
+
+/**********************************************************************/
diff --git a/misc/pascal/insn32/popt/pfopt.h b/misc/pascal/insn32/popt/pfopt.h
new file mode 100644
index 000000000..07ce738b1
--- /dev/null
+++ b/misc/pascal/insn32/popt/pfopt.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * pfopt.h
+ * External Declarations associated with pfopt.c
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PFOPT_H
+#define __PFOPT_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include "pofflib.h"
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void optFinalize(poffHandle_t poffHandle,
+ poffProgHandle_t poffProgHandle);
+
+#endif /* __PFOPT_H */
+
diff --git a/misc/pascal/insn32/popt/pjopt.c b/misc/pascal/insn32/popt/pjopt.c
new file mode 100644
index 000000000..17b77c4ef
--- /dev/null
+++ b/misc/pascal/insn32/popt/pjopt.c
@@ -0,0 +1,449 @@
+/**********************************************************************
+ * pjopt.c
+ * Branch Optimizations
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdio.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pinsn32.h"
+
+#include "popt.h"
+#include "polocal.h"
+#include "pjopt.h"
+
+/**********************************************************************/
+
+int BranchOptimize (void)
+{
+ int nchanges = 0;
+ register int i;
+
+ TRACE(stderr, "[BranchOptimize]");
+
+ /* At least two pcodes are need to perform branch optimizations */
+
+ i = 0;
+ while (i < nops-1)
+ {
+ switch (pptr[i]->op)
+ {
+ case oNOT :
+ switch (pptr[i+1]->op)
+ {
+ case oJEQUZ :
+ pptr[i+1]->op = oJNEQZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJEQUZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oNEG :
+ switch (pptr[i+1]->op)
+ {
+ case oJLTZ :
+ pptr[i+1]->op = oJGTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJGTEZ :
+ pptr[i+1]->op = oJLTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJGTZ :
+ pptr[i+1]->op = oJLTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJLTEZ :
+ pptr[i+1]->op = oJGTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oEQU :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oNEQ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJNEQ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJEQU;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oNEQ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oEQU;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJEQU;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJNEQ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oLT :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oGTE;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJGTE;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJLT;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oGTE :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oLT;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJLT;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJGTE;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oGT :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oLTE;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJLTE;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJGT;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oLTE :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oGT;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJGT;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJLTE;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oEQUZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oNEQZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJNEQZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJEQUZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oNEQZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oEQUZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ case oJNEQZ :
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oLTZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oGTEZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJGTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJLTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oGTEZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oLTZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJLTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJGTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oGTZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oLTEZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJLTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJGTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oLTEZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oGTZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJGTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJLTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ } /* end while */
+ return (nchanges);
+
+} /* end BranchOptimize */
+
+/**********************************************************************/
+
diff --git a/misc/pascal/insn32/popt/pjopt.h b/misc/pascal/insn32/popt/pjopt.h
new file mode 100644
index 000000000..75a0b64f2
--- /dev/null
+++ b/misc/pascal/insn32/popt/pjopt.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * pjopt.h
+ * External Declarations associated with pjopt.c
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PJOPT_H
+#define __PJOPT_H
+
+extern int BranchOptimize ( void );
+
+#endif __PJOPT_H
+
+
diff --git a/misc/pascal/insn32/popt/plopt.c b/misc/pascal/insn32/popt/plopt.c
new file mode 100644
index 000000000..05e8559ef
--- /dev/null
+++ b/misc/pascal/insn32/popt/plopt.c
@@ -0,0 +1,215 @@
+/**********************************************************************
+ * plopt.c
+ * Load/Store Optimizations
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pinsn32.h"
+
+#include "popt.h"
+#include "polocal.h"
+#include "plopt.h"
+
+/**********************************************************************/
+
+int LoadOptimize(void)
+{
+ uint32_t val;
+ int nchanges = 0;
+ register int i;
+
+ TRACE(stderr, "[LoadOptimize]");
+
+ /* At least two pcodes are need to perform Load optimizations */
+
+ i = 0;
+ while (i < nops-1)
+ {
+ switch (GETOP(pptr[i]))
+ {
+ /* Eliminate duplicate loads */
+
+ case oLDSH :
+ if ((GETOP(pptr[i+1]) == oLDSH) &&
+ (GETARG(pptr[i+1]) == GETARG(pptr[i])))
+ {
+ PUTOP(pptr[i+1], oDUP);
+ PUTARG(pptr[i+1], 0);
+ nchanges++;
+ i += 2;
+ } /* end if */
+ else i++;
+ break;
+
+ /* Convert loads indexed by a constant to unindexed loads */
+
+ case oPUSH :
+ /* Get the index value */
+
+ val = (int32_t)GETARG(pptr[i]);
+
+ /* If the following instruction is a load, add the constant
+ * index value to the address and switch the opcode to the
+ * unindexed form.
+ */
+
+ if (GETOP(pptr[i+1]) == oLDSXH)
+ {
+ PUTOP(pptr[i+1], oLDSH);
+ val += GETARG(pptr[i+1]);
+ PUTARG(pptr[i+1], val);
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else if (GETOP(pptr[i+1]) == oLASX)
+ {
+ PUTOP(pptr[i+1], oLAS);
+ val += GETARG(pptr[i+1]);
+ PUTARG(pptr[i+1], val);
+ deletePcode (i);
+ nchanges++;
+ } /* end else if */
+ else if (GETOP(pptr[i+1]) == oLDSXB)
+ {
+ PUTOP(pptr[i+1], oLDSB);
+ val += GETARG(pptr[i+1]);
+ PUTARG(pptr[i+1], val);
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else if (GETOP(pptr[i+1]) == oLDSXM)
+ {
+ PUTOP(pptr[i+1], oLDSM);
+ val += GETARG(pptr[i+1]);
+ PUTARG(pptr[i+1], val);
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ } /* end while */
+ return (nchanges);
+} /* end LoadOptimize */
+
+/**********************************************************************/
+int StoreOptimize (void)
+{
+ uint32_t val;
+ int nchanges = 0;
+ register int i;
+
+ TRACE(stderr, "[StoreOptimize]");
+
+ /* At least two pcodes are need to perform the following Store */
+ /* optimizations */
+
+ i = 0;
+ while (i < nops-1)
+ {
+ switch (GETOP(pptr[i]))
+ {
+ /* Eliminate store followed by load */
+
+ case oSTSH :
+ if ((GETOP(pptr[i+1]) == oLDSH) &&
+ (GETARG(pptr[i+1]) == GETARG(pptr[i])))
+ {
+ PUTOP(pptr[i+1], oSTSH);
+ PUTOP(pptr[i], oDUP);
+ PUTARG(pptr[i], 0);
+ nchanges++;
+ i += 2;
+ } /* end if */
+ else i++;
+ break;
+
+ /* Convert stores indexed by a constant to unindexed stores */
+ case oPUSH :
+ /* Get the index value */
+
+ val = (int32_t)GETARG(pptr[i]);
+
+ /* If the following instruction is a store, add the constant
+ * index value to the address and switch the opcode to the
+ * unindexed form.
+ */
+
+ if (i < nops-2)
+ {
+ if (GETOP(pptr[i+2]) == oSTSXH)
+ {
+ PUTOP(pptr[i+2], oSTSH);
+ val += GETARG(pptr[i+2]);
+ PUTARG(pptr[i+2], val);
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else if (GETOP(pptr[i+2]) == oSTSXB)
+ {
+ PUTOP(pptr[i+2], oSTSB);
+ val += GETARG(pptr[i+2]);
+ PUTARG(pptr[i+2], val);
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ } /* end if */
+ else i++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ } /* end while */
+
+ return (nchanges);
+
+} /* end StoreOptimize */
+
+/**********************************************************************/
+
diff --git a/misc/pascal/insn32/popt/plopt.h b/misc/pascal/insn32/popt/plopt.h
new file mode 100644
index 000000000..3783cf400
--- /dev/null
+++ b/misc/pascal/insn32/popt/plopt.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * plopt.h
+ * External Declarations associated with plopt.c
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PLOPT_H
+#define __PLOPT_H
+
+extern int LoadOptimize ( void );
+extern int StoreOptimize ( void );
+
+#endif /* __PLOPT_H */
diff --git a/misc/pascal/insn32/popt/polocal.c b/misc/pascal/insn32/popt/polocal.c
new file mode 100644
index 000000000..036182372
--- /dev/null
+++ b/misc/pascal/insn32/popt/polocal.c
@@ -0,0 +1,271 @@
+/**********************************************************************
+ * polocal.c
+ * P-Code Local Optimizer
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdio.h>
+
+#include "keywords.h"
+#include "podefs.h"
+#include "pinsn32.h"
+
+#include "pofflib.h"
+#include "paslib.h"
+#include "pinsn.h"
+#include "pcopt.h"
+#include "plopt.h"
+#include "pjopt.h"
+#include "polocal.h"
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static void initPTable (void);
+static void putPCodeFromTable (void);
+static void setupPointer (void);
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+OPTYPE ptable [WINDOW]; /* Pcode Table */
+OPTYPE *pptr [WINDOW]; /* Valid Pcode Pointers */
+
+int nops = 0; /* No. Valid Pcode Pointers */
+int end_out = 0; /* 1 = oEND pcode has been output */
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static poffHandle_t myPoffHandle; /* Handle to POFF object */
+static poffProgHandle_t myPoffProgHandle;/* Handle to temporary POFF object */
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+void localOptimization(poffHandle_t poffHandle,
+ poffProgHandle_t poffProgHandle)
+{
+ int nchanges;
+
+ TRACE(stderr, "[pass2]");
+
+ /* Save the handles for use by other, private functions */
+
+ myPoffHandle = poffHandle;
+ myPoffProgHandle = poffProgHandle;
+
+ /* Initialization */
+
+ initPTable();
+
+ /* Outer loop traverse the file op-code by op-code until the oEND P-Code
+ * has been output. NOTE: it is assumed throughout that oEND is the
+ * final P-Code in the program data section.
+ */
+
+ while (!(end_out))
+ {
+ /* The inner loop optimizes the buffered P-Codes until no further
+ * changes can be made. Then the outer loop will advance the buffer
+ * by one P-Code
+ */
+
+ do
+ {
+ nchanges = unaryOptimize ();
+ nchanges += binaryOptimize();
+ nchanges += BranchOptimize();
+ nchanges += LoadOptimize();
+ nchanges += StoreOptimize();
+ } while (nchanges);
+
+ putPCodeFromTable();
+ }
+}
+
+/***********************************************************************/
+
+void deletePcode(int delIndex)
+{
+ TRACE(stderr, "[deletePcode]");
+
+ PUTOP(pptr[delIndex], oNOP);
+ PUTARG(pptr[delIndex], 0);
+ setupPointer();
+}
+
+/**********************************************************************/
+
+void deletePcodePair(int delIndex1, int delIndex2)
+{
+ TRACE(stderr, "[deletePcodePair]");
+
+ PUTOP(pptr[delIndex1], oNOP);
+ PUTARG(pptr[delIndex1], 0);
+ PUTOP(pptr[delIndex2], oNOP);
+ PUTARG(pptr[delIndex2], 0);
+ setupPointer();
+}
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+static void putPCodeFromTable(void)
+{
+ register int i;
+
+ TRACE(stderr, "[putPCodeFromTable]");
+
+ /* Transfer all buffered P-Codes (except NOPs) to the optimized file */
+ do
+ {
+ if ((GETOP(&ptable[0]) != oNOP) && !(end_out))
+ {
+ insn_AddTmpOpCode(myPoffProgHandle, &ptable[0]);
+ end_out = (GETOP(&ptable[0]) == oEND);
+ }
+
+ /* Move all P-Codes down one slot */
+
+ for (i = 1; i < WINDOW; i++)
+ {
+ ptable[i-1] = ptable[i];
+ }
+
+ /* Then fill the end slot with a new P-Code from the input file */
+
+ insn_GetOpCode(myPoffHandle, &ptable[WINDOW-1]);
+
+ } while (GETOP(&ptable[0]) == oNOP);
+ setupPointer();
+}
+
+/**********************************************************************/
+
+static void setupPointer(void)
+{
+ register int pindex;
+
+ TRACE(stderr, "[setupPointer]");
+
+ for (pindex = 0; pindex < WINDOW; pindex++)
+ pptr[pindex] = (OPTYPE *) NULL;
+
+ nops = 0;
+ for (pindex = 0; pindex < WINDOW; pindex++)
+ {
+ switch (GETOP(&ptable[pindex]))
+ {
+ /* Terminate list when a break from sequential logic is
+ * encountered
+ */
+
+ case oRET :
+ case oEND :
+ case oJMP :
+ case oLABEL :
+ case oPCAL :
+ return;
+
+ /* Terminate list when a condition break from sequential logic is
+ * encountered but include the conditional branch in the list
+ */
+
+ case oJEQUZ :
+ case oJNEQZ :
+ case oJLTZ :
+ case oJGTEZ :
+ case oJGTZ :
+ case oJLTEZ :
+ pptr[nops] = &ptable[pindex];
+ nops++;
+ return;
+
+ /* Skip over NOPs and comment class pcodes */
+
+ case oNOP :
+ case oLINE :
+ break;
+
+ /* Include all other pcodes in the optimization list and continue */
+
+ default :
+ pptr[nops] = &ptable[pindex];
+ nops++;
+ }
+ }
+}
+
+/**********************************************************************/
+
+static void initPTable(void)
+{
+ register int i;
+
+ TRACE(stderr, "[intPTable]");
+
+ /* Skip over leading pcodes. NOTE: assumes executable begins after
+ * the first oLABEL pcode
+ */
+
+ do
+ {
+ insn_GetOpCode(myPoffHandle, &ptable[0]);
+ insn_AddTmpOpCode(myPoffProgHandle, &ptable[0]);
+ }
+ while ((GETOP(&ptable[0]) != oLABEL) && (GETOP(&ptable[0]) != oEND));
+
+ /* Fill the pcode window and setup pointers to working section */
+
+ for (i = 0; i < WINDOW; i++)
+ {
+ insn_GetOpCode(myPoffHandle, &ptable[i]);
+ }
+ setupPointer();
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/insn32/popt/polocal.h b/misc/pascal/insn32/popt/polocal.h
new file mode 100644
index 000000000..fc97cb819
--- /dev/null
+++ b/misc/pascal/insn32/popt/polocal.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * polocal.h
+ * External Declarations associated with polocal.c
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __POLOCAL_H
+#define __POLOCAL_H
+
+/***************************************************************************
+* Included Files
+****************************************************************************/
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pofflib.h"
+
+/***************************************************************************
+* Definitions
+****************************************************************************/
+
+#define WINDOW 10 /* size of optimization window */
+
+/***************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+
+extern void localOptimization(poffHandle_t poffHandle,
+ poffProgHandle_t poffProgHandle);
+extern void deletePcode (int delIndex);
+extern void deletePcodePair (int delIndex1, int delIndex2);
+
+/***************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+extern OPTYPE ptable [WINDOW]; /* Pcode Table */
+extern OPTYPE *pptr [WINDOW]; /* Valid Pcode Pointers */
+
+extern int nops; /* No. Valid Pcode Pointers */
+extern int end_out; /* 1 = oEND pcode has been output */
+
+#endif /* __PLOCAL_H */
diff --git a/misc/pascal/insn32/popt/popt.c b/misc/pascal/insn32/popt/popt.c
new file mode 100644
index 000000000..5cf039a16
--- /dev/null
+++ b/misc/pascal/insn32/popt/popt.c
@@ -0,0 +1,327 @@
+/**********************************************************************
+ * popt.c
+ * P-Code Optimizer Main Logic
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "keywords.h"
+#include "podefs.h"
+#include "paslib.h"
+#include "pofflib.h"
+
+#include "pinsn.h"
+#include "popt.h"
+#include "psopt.h"
+#include "polocal.h"
+#include "pfopt.h"
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static void showUsage (const char *progname, int errcode);
+static void readPoffFile (const char *filename);
+static void pass1 (void);
+static void pass2 (void);
+static void pass3 (void);
+static void writePoffFile (const char *filename);
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static poffHandle_t poffHandle; /* Handle to POFF object */
+static int no_resolve = 0;
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+int main(int argc, char *argv[], char *envp[])
+{
+ const char *outfilename;
+ TRACE(stderr, "[main]");
+ int option;
+
+ /* Process command line argruments */
+
+ while ((option = getopt(argc, argv, "rh")) > 0)
+ {
+ switch (option)
+ {
+ case 'r' :
+ no_resolve++;
+ break;
+ case 'h' :
+ showUsage(argv[0], 0);
+ default:
+ fprintf(stderr, "Unrecognized option\n");
+ showUsage(argv[0], -1);
+ }
+ }
+
+ /* Check for existence of filename argument */
+
+ if (optind != argc - 1)
+ {
+ printf("Filename required at end of command line.\n");
+ showUsage(argv[0], -1);
+ } /* end if */
+
+ /* Read the POFF file into memory */
+
+ outfilename = argv[optind];
+ readPoffFile(outfilename);
+
+ /* Performs pass1 optimization */
+
+ pass1();
+
+ /* Performs pass2 optimization */
+
+ insn_ResetOpCodeRead(poffHandle);
+ pass2();
+
+ if (!no_resolve)
+ {
+ /* Create final section offsets and relocation entries */
+
+ insn_ResetOpCodeRead(poffHandle);
+ pass3();
+ }
+
+ /* Write the POFF file */
+
+ writePoffFile(outfilename);
+ return 0;
+
+} /* End main */
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+static void showUsage(const char *progname, int errcode)
+{
+ fprintf(stderr, "USAGE:\n");
+ fprintf(stderr, " %s -h\n", progname);
+ fprintf(stderr, " %s [-r] <poff-filename>\n", progname);
+ fprintf(stderr, "WHERE:\n");
+ fprintf(stderr, " -r: Disables label resolution (default: labels resolved)\n");
+ fprintf(stderr, " -h: Shows this message\n");
+ exit(errcode);
+}
+
+/***********************************************************************/
+
+static void readPoffFile(const char *filename)
+{
+ char objname [FNAME_SIZE+1];
+ FILE *objFile;
+ int errcode;
+
+ TRACE(stderr, "[readPoffFile]");
+
+ /* Open the pass1 POFF object file -- Use .o1 extension */
+
+ (void)extension(filename, "o1", objname, 1);
+ if (!(objFile = fopen(objname, "rb")))
+ {
+ printf("Error Opening %s\n", objname);
+ exit(1);
+ } /* end if */
+
+ /* Get a handle to a POFF input object */
+
+ poffHandle = poffCreateHandle();
+ if (!poffHandle)
+ {
+ printf("Could not get POFF handle\n");
+ exit(1);
+ } /* end if */
+
+ /* Read the POFF file into memory */
+
+ errcode = poffReadFile(poffHandle, objFile);
+ if (errcode != 0)
+ {
+ printf("Could not read POFF file, errcode=0x%02x\n", errcode);
+ exit(1);
+ }
+
+ /* Close the input file */
+
+ fclose(objFile);
+} /* end pass1 */
+
+/***********************************************************************/
+
+static void pass1(void)
+{
+ poffProgHandle_t poffProgHandle; /* Handle to temporary POFF object */
+
+ TRACE(stderr, "[pass1]");
+
+ /* Create a handle to a temporary object to store new POFF program
+ * data.
+ */
+
+ poffProgHandle = poffCreateProgHandle();
+ if (!poffProgHandle)
+ {
+ printf("Could not get POFF handle\n");
+ exit(1);
+ } /* end if */
+
+ /* Clean up garbage left from the wasteful string stack logic */
+
+ stringStackOptimize(poffHandle, poffProgHandle);
+
+ /* Replace the original program data with the new program data */
+
+ poffReplaceProgData(poffHandle, poffProgHandle);
+
+ /* Release the temporary POFF object */
+
+ poffDestroyProgHandle(poffProgHandle);
+} /* end pass1 */
+
+/***********************************************************************/
+
+static void pass2(void)
+{
+ poffProgHandle_t poffProgHandle; /* Handle to temporary POFF object */
+
+ TRACE(stderr, "[pass2]");
+
+ /* Create a handle to a temporary object to store new POFF program
+ * data.
+ */
+
+ poffProgHandle = poffCreateProgHandle();
+ if (!poffProgHandle)
+ {
+ printf("Could not get POFF handle\n");
+ exit(1);
+ } /* end if */
+
+ /* Perform Local Optimizatin Initialization */
+
+ localOptimization(poffHandle, poffProgHandle);
+
+ /* Replace the original program data with the new program data */
+
+ poffReplaceProgData(poffHandle, poffProgHandle);
+
+ /* Release the temporary POFF object */
+
+ poffDestroyProgHandle(poffProgHandle);
+} /* end pass2 */
+
+/***********************************************************************/
+
+static void pass3 (void)
+{
+ poffProgHandle_t poffProgHandle; /* Handle to temporary POFF object */
+ TRACE(stderr, "[pass3]");
+
+ /* Create a handle to a temporary object to store new POFF program
+ * data.
+ */
+
+ poffProgHandle = poffCreateProgHandle();
+ if (!poffProgHandle)
+ {
+ printf("Could not get POFF handle\n");
+ exit(1);
+ } /* end if */
+
+ /* Finalize program section, create relocation and line number
+ * sections.
+ */
+
+ optFinalize(poffHandle, poffProgHandle);
+
+ /* Release the temporary POFF object */
+
+ poffDestroyProgHandle(poffProgHandle);
+}
+
+/***********************************************************************/
+
+static void writePoffFile(const char *filename)
+{
+ char optname [FNAME_SIZE+1];
+ FILE *optFile;
+
+ TRACE(stderr, "[writePoffFile]");
+
+ /* Open optimized p-code file -- Use .o extension */
+
+ (void)extension(filename, "o", optname, 1);
+ if (!(optFile = fopen(optname, "wb")))
+ {
+ printf("Error Opening %s\n", optname);
+ exit(1);
+ } /* end if */
+
+ /* Then write the new POFF file */
+
+ poffWriteFile(poffHandle, optFile);
+
+ /* Destroy the POFF object */
+
+ poffDestroyHandle(poffHandle);
+
+ /* Close the files used on writePoffFile */
+
+ (void)fclose(optFile);
+} /* end writePoffFile */
+
+/***********************************************************************/
diff --git a/misc/pascal/insn32/popt/popt.h b/misc/pascal/insn32/popt/popt.h
new file mode 100644
index 000000000..c7645be9e
--- /dev/null
+++ b/misc/pascal/insn32/popt/popt.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * popt.h
+ * External Declarations associated with popt.c
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __POPT_H
+#define __POPT_H
+
+/***************************************************************************
+* Included Files
+****************************************************************************/
+
+/***************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/***************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+
+#endif /* __POPT_H */
diff --git a/misc/pascal/insn32/popt/psopt.c b/misc/pascal/insn32/popt/psopt.c
new file mode 100644
index 000000000..7ecd3b6a9
--- /dev/null
+++ b/misc/pascal/insn32/popt/psopt.c
@@ -0,0 +1,385 @@
+/**********************************************************************
+ * psopt.c
+ * String Stack Optimizaitons
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/* The statement generation logic generates a PUSHS and POPS around
+ * every statement. These instructions save and restore the string
+ * stack pointer registers. However, only some statements actually
+ * modify the string stack. So the first major step in the optimatization
+ * process is to retain only PUSHS and POPS statements that are
+ * actually required.
+ */
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pedefs.h"
+#include "pinsn32.h"
+#include "pxdefs.h"
+
+#include "popt.h"
+#include "psopt.h"
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+#define PBUFFER_SIZE 1024
+#define NPBUFFERS 8
+
+/**********************************************************************
+ * Private Data
+ **********************************************************************/
+
+static uint8_t *pbuffer[NPBUFFERS];
+static int nbytes_in_pbuffer[NPBUFFERS];
+static int current_level = -1;
+static int inch;
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static inline void putbuf(int c, poffProgHandle_t poffProgHandle);
+static inline void flushc(int c, poffProgHandle_t poffProgHandle);
+static inline void flushbuf(poffProgHandle_t poffProgHandle);
+static void dopush(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle);
+static void dopop(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle);
+
+/**********************************************************************
+ * Private Inline Functions
+ **********************************************************************/
+
+static inline void putbuf(int c, poffProgHandle_t poffProgHandle)
+{
+ int dlvl = current_level;
+
+ if (dlvl < 0)
+ {
+ /* No PUSHS encountered. Write byte directly to output */
+
+ poffAddTmpProgByte(poffProgHandle, (uint8_t)c);
+ }
+ else
+ {
+ /* PUSHS encountered. Write byte into buffer associated with
+ * nesting level.
+ */
+
+ int idx = nbytes_in_pbuffer[dlvl];
+ uint8_t *dest = pbuffer[dlvl] + idx;
+ *dest = c;
+ nbytes_in_pbuffer[dlvl] = idx + 1;
+ }
+}
+
+static inline void flushc(int c, poffProgHandle_t poffProgHandle)
+{
+ if (current_level > 0)
+ {
+ /* Nested PUSHS encountered. Write byte into buffer associated
+ * with the previous nesting level.
+ */
+
+ int dlvl = current_level - 1;
+ int idx = nbytes_in_pbuffer[dlvl];
+ uint8_t *dest = pbuffer[dlvl] + idx;
+ *dest = c;
+ nbytes_in_pbuffer[dlvl] = idx + 1;
+ }
+ else
+ {
+ /* Only one PUSHS encountered. Write directly to the output
+ * buffer
+ */
+
+ poffAddTmpProgByte(poffProgHandle, (uint8_t)c);
+ }
+}
+
+static inline void flushbuf(poffProgHandle_t poffProgHandle)
+{
+ int errCode;
+ int slvl = current_level;
+
+ if (nbytes_in_pbuffer[slvl] > 0)
+ {
+ if (current_level > 0)
+ {
+ /* Nested PUSHS encountered. Flush buffer into buffer associated
+ * with the previous nesting level.
+ */
+
+ int dlvl = slvl - 1;
+ uint8_t *src = pbuffer[slvl];
+ uint8_t *dest = pbuffer[dlvl] + nbytes_in_pbuffer[dlvl];
+
+ memcpy(dest, src, nbytes_in_pbuffer[slvl]);
+ nbytes_in_pbuffer[dlvl] += nbytes_in_pbuffer[slvl];
+ }
+ else
+ {
+ /* Only one PUSHS encountered. Flush directly to the output
+ * buffer
+ */
+
+ errCode = poffWriteTmpProgBytes(pbuffer[0], nbytes_in_pbuffer[0],
+ poffProgHandle);
+
+ if (errCode != eNOERROR)
+ {
+ printf("Error writing to file: %d\n", errCode);
+ exit(1);
+ }
+ }
+ }
+ nbytes_in_pbuffer[slvl] = 0;
+}
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+static void dopush(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ int opcode;
+
+ while (inch != EOF)
+ {
+ /* Search for a PUSHS opcode */
+
+ if (inch != oPUSHS)
+ {
+ /* Its not PUSHS, just echo to the output file/buffer */
+
+ putbuf(inch, poffProgHandle);
+
+ /* Get the next byte from the input stream */
+
+ opcode = inch;
+ inch = poffGetProgByte(poffHandle);
+
+ /* Check for a 32-bit argument */
+
+ if ((opcode & o32) != 0)
+ {
+ /* Echo the 32-bits of the argument */
+
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ }
+ }
+ else
+ {
+ /* We have found PUSHS. No search for the next occurrence
+ * of either and instruction that increments the string
+ * stack or for the matching POPS
+ */
+
+ current_level++;
+ dopop(poffHandle, poffProgHandle);
+ current_level--;
+ }
+ }
+}
+
+static void dopop(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ /* We have found PUSHS. No search for the next occurrence
+ * of either and instruction that increments the string
+ * stack or for the matching POPS
+ */
+
+ /* Skip over the PUSHS for now */
+
+ inch = poffGetProgByte(poffHandle);
+
+ while (inch != EOF)
+ {
+ /* Did we encounter another PUSHS? */
+
+ if (inch == oPUSHS)
+ {
+ /* Yes... recurse to handle it */
+
+ current_level++;
+ dopop(poffHandle, poffProgHandle);
+ current_level--;
+ }
+
+ else if (inch == oPOPS)
+ {
+ /* Flush the buffered data without the PUSHS */
+
+ flushbuf(poffProgHandle);
+
+ /* And discard the matching POPS */
+
+ inch = poffGetProgByte(poffHandle);
+ break;
+ }
+ else if (inch == oLIB)
+ {
+ uint32_t arg32;
+ unsigned int tmp;
+
+ /* Get the 32-bit argument from the big endian data stream */
+
+ tmp = poffGetProgByte(poffHandle);
+ arg32 = tmp << 24;
+ putbuf(tmp, poffProgHandle);
+
+ tmp = poffGetProgByte(poffHandle);
+ arg32 |= tmp << 16;
+ putbuf(tmp, poffProgHandle);
+
+ tmp = poffGetProgByte(poffHandle);
+ arg32 |= tmp << 8;
+ putbuf(tmp, poffProgHandle);
+
+ tmp = poffGetProgByte(poffHandle);
+ arg32 |= tmp;
+ putbuf(tmp, poffProgHandle);
+
+ inch = poffGetProgByte(poffHandle);
+
+ /* Is it LIB MKSTK? MKSTKSTR? or MKSTKC? */
+
+ if ((arg32 == lbMKSTK) ||
+ (arg32 == lbMKSTKSTR) ||
+ (arg32 == lbMKSTKC))
+ {
+ /* Flush the buffered data with the PUSHS */
+
+ flushc(oPUSHS, poffProgHandle);
+ flushbuf(poffProgHandle);
+
+ /* And break out of the loop to search for
+ * the next PUSHS
+ */
+
+ break;
+ }
+ }
+ else
+ {
+ int opcode;
+
+ /* Something else. Put it in the buffer */
+
+ putbuf(inch, poffProgHandle);
+
+ /* Get the next byte from the input stream */
+
+ opcode = inch;
+ inch = poffGetProgByte(poffHandle);
+
+ /* Check for a 32-bit argument */
+
+ if (opcode & o32 != 0)
+ {
+ /* Buffer the remaining 24-bits of the argument */
+
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ }
+ }
+ }
+}
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+void stringStackOptimize(poffHandle_t poffHandle,
+ poffProgHandle_t poffProgHandle)
+{
+ int i;
+
+ /* Allocate an array of buffers to hold pcode data */
+
+ for (i = 0; i < NPBUFFERS; i++)
+ {
+ pbuffer[i] = (uint8_t*)malloc(PBUFFER_SIZE);
+ if (pbuffer[i] == NULL)
+ {
+ printf("Failed to allocate pcode buffer\n");
+ exit(1);
+ }
+ nbytes_in_pbuffer[i] = 0;
+ }
+
+ /* Prime the search logic */
+
+ inch = poffGetProgByte(poffHandle);
+ current_level = -1;
+
+ /* And parse the input file to the output file, removing unnecessary string
+ * stack operations.
+ */
+
+ dopush(poffHandle, poffProgHandle);
+
+ /* Release the buffers */
+
+ for (i = 0; i < NPBUFFERS; i++)
+ {
+ free(pbuffer[i]);
+ pbuffer[i] = NULL;
+ nbytes_in_pbuffer[i] = 0;
+ }
+}
+
+/**********************************************************************/
diff --git a/misc/pascal/insn32/popt/psopt.h b/misc/pascal/insn32/popt/psopt.h
new file mode 100644
index 000000000..3ea1ee227
--- /dev/null
+++ b/misc/pascal/insn32/popt/psopt.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * psopt.h
+ * External Declarations associated with psopt.c
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PSOPT_H
+#define __PSOPT_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include "pofflib.h"
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void stringStackOptimize(poffHandle_t poffHandle,
+ poffProgHandle_t poffProgHandle);
+
+#endif /* __PSOPT_H */
+
diff --git a/misc/pascal/insn32/regm/Makefile b/misc/pascal/insn32/regm/Makefile
new file mode 100644
index 000000000..0dca7196d
--- /dev/null
+++ b/misc/pascal/insn32/regm/Makefile
@@ -0,0 +1,94 @@
+############################################################################
+# insn32/regm/Makefile
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Directories
+#
+REGMDIR = ${shell pwd}
+INSNDIR = $(REGMDIR)/..
+PASCAL = $(REGMDIR)/../..
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+INCDIR = $(PASCAL)/include
+LIBDIR = $(PASCAL)/lib
+BINDIR = $(PASCAL)/bin32
+
+# ----------------------------------------------------------------------
+# Tools
+
+EXTRA_INCLUDES = -I$(INSNDIR)/include
+INCLUDES += $(EXTRA_INCLUDES)
+CFLAGS += $(EXTRA_INCLUDES)
+
+# ----------------------------------------------------------------------
+# Objects and targets
+
+REGMSRCS = regm.c regm_pass1.c regm_pass2.c regm_registers2.c \
+ regm_tree.c
+REGMOBJS = $(REGMSRCS:.c=.o)
+
+OBJS = $(REGMOBJS)
+LIBS = libpoff.a libpas.a
+
+all: regm
+.PHONY: all check_libs regm clean
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+check_libs:
+ @if [ ! -f $(LIBDIR)/libpoff.a ] ; then \
+ echo "$(LIBDIR)/libpoff.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libpas.a ] ; then \
+ echo "$(LIBDIR)/libpas.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libinsn.a ] ; then \
+ echo "$(LIBDIR)/libinsn.a does not exist" ; \
+ exit 1 ; \
+ fi
+
+$(BINDIR)/regm: check_libs $(REGMOBJS)
+ $(CC) -o $@ $(LDFLAGS) $(REGMOBJS) -linsn -lpoff -lpas
+
+regm: $(BINDIR)/regm
+
+clean:
+ $(RM) regm *.o core *~
+
+# ----------------------------------------------------------------------
diff --git a/misc/pascal/insn32/regm/regm.c b/misc/pascal/insn32/regm/regm.c
new file mode 100644
index 000000000..1b8c22fce
--- /dev/null
+++ b/misc/pascal/insn32/regm/regm.c
@@ -0,0 +1,342 @@
+/**********************************************************************
+ * regm.c
+ * Convert 32-bit pcode defintions to a register model
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pedefs.h"
+#include "paslib.h"
+#include "pofflib.h"
+#include "perr.h"
+
+#include "regm.h"
+#include "regm_tree.h"
+#include "regm_pass1.h"
+#include "regm_pass2.h"
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static void regm_ShowUsage(const char *progname, int errcode);
+static int regm_CheckPoffFile(poffHandle_t hPoff);
+static poffHandle_t regm_ReadPoffFile(const char *filename);
+static void regm_Pass3(poffHandle_t hPoff);
+static void regm_Pass4(poffHandle_t hPoff);
+static void regm_Pass5(poffHandle_t hPoff);
+static void regm_WritePoffFile(poffHandle_t hPoff,
+ const char *filename);
+
+/**********************************************************************
+ * Public Variables
+ **********************************************************************/
+
+int vRegmDebug = 0;
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+static void regm_ShowUsage(const char *progname, int errcode)
+{
+ fprintf(stderr, "USAGE:\n");
+ fprintf(stderr, " %s -h\n", progname);
+ fprintf(stderr, " %s [-d] <poff-filename>\n", progname);
+ fprintf(stderr, "WHERE:\n");
+ fprintf(stderr, " -d: Enables debug output\n");
+ fprintf(stderr, " -h: Shows this message\n");
+ exit(errcode);
+}
+
+/***********************************************************************/
+
+static poffHandle_t regm_ReadPoffFile(const char *filename)
+{
+ poffHandle_t hPoff;
+ char objname [FNAME_SIZE+1];
+ FILE *objFile;
+ int errcode;
+
+ TRACE(stderr, "[regm_ReadPoffFile]");
+
+ /* Open the optimized POFF object file -- Use the .o extension */
+
+ (void)extension(filename, "o", objname, 1);
+ if (!(objFile = fopen(objname, "rb")))
+ {
+ printf("Error Opening %s\n", objname);
+ exit(1);
+ }
+
+ /* Get a handle to a POFF input object */
+
+ hPoff = poffCreateHandle();
+ if (!hPoff)
+ {
+ printf("Could not get POFF handle\n");
+ exit(1);
+ }
+
+ /* Read the POFF file into memory */
+
+ errcode = poffReadFile(hPoff, objFile);
+ if (errcode != 0)
+ {
+ printf("Could not read POFF file, errcode=0x%02x\n", errcode);
+ exit(1);
+ }
+
+ /* Close the input file */
+
+ fclose(objFile);
+ return hPoff;
+}
+
+/***********************************************************************/
+
+static int regm_CheckPoffFile(poffHandle_t hPoff)
+{
+ uint8_t fileArch = poffGetArchitecture(hPoff);
+ if (fileArch != FHA_PCODE_INSN32)
+ {
+ fprintf(stderr, "ERROR: File is not 32-bit pcode (%d)\n",
+ fileArch);
+ return -1;
+ }
+ return 0;
+}
+
+/***********************************************************************/
+/* Pass3: Perform local optimization */
+
+static void regm_Pass3(poffHandle_t hPoff)
+{
+ TRACE(stderr, "[regm_Pass3]");
+}
+
+/***********************************************************************/
+/* Pass 4: Fixup register usage, force to use a fixed number of registers
+ * (arguments, static registers, volatile registers, special registers),
+ * and add logic to handle large immediate values.
+ */
+
+static void regm_Pass4(poffHandle_t hPoff)
+{
+ TRACE(stderr, "[regm_Pass4]");
+}
+
+/***********************************************************************/
+/* Pass 5: Fixup BL and B offsets, section headers, relocation entries,
+ * symbol values
+ */
+
+static void regm_Pass5(poffHandle_t hPoff)
+{
+ TRACE(stderr, "[regm_Pass5]");
+}
+
+/***********************************************************************/
+
+static void regm_WritePoffFile(poffHandle_t hPoff, const char *filename)
+{
+#if 0
+ char rexname [FNAME_SIZE+1];
+ FILE *rexFile;
+
+ TRACE(stderr, "[regm_WritePoffFile]");
+
+ /* Open optimized p-code file -- Use .o extension */
+
+ (void)extension(filename, ".rex", rexname, 1);
+ if (!(rexFile = fopen(rexname, "wb")))
+ {
+ printf("Error Opening %s\n", rexname);
+ exit(1);
+ }
+
+ /* Then write the new POFF file */
+
+ poffWritePoffFile(hPoff, rexFile);
+
+ /* Destroy the POFF object */
+
+ poffDestroyHandle(hPoff);
+
+ /* Close the files used on regm_WritePoffFile */
+
+ (void)fclose(rexFile);
+#endif
+}
+
+/**********************************************************************
+ * Public Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+int main(int argc, char *argv[], char *envp[])
+{
+ const char *outfilename;
+ poffHandle_t hPoff;
+ TRACE(stderr, "[main]");
+ int option;
+
+ /* Process command line argruments */
+
+ while ((option = getopt(argc, argv, "dh")) > 0)
+ {
+ switch (option)
+ {
+ case 'd' :
+ vRegmDebug++;
+ break;
+ case 'h' :
+ regm_ShowUsage(argv[0], 0);
+ default:
+ fprintf(stderr, "Unrecognized option\n");
+ regm_ShowUsage(argv[0], -1);
+ }
+ }
+
+ /* Check for existence of filename argument */
+
+ if (optind != argc - 1)
+ {
+ fprintf(stderr, "Filename required at end of command line.\n");
+ regm_ShowUsage(argv[0], -1);
+ }
+
+ /* Read the POFF file into memory */
+
+ outfilename = argv[optind];
+ hPoff = regm_ReadPoffFile(outfilename);
+
+ /* Verify that it is the kind of file that we can handle */
+
+ if (regm_CheckPoffFile(hPoff) != 0)
+ {
+ fprintf(stderr, "File is not the correct type\n");
+ regm_ShowUsage(argv[0], -1);
+ }
+
+ /* Read the debug info into a more usable structure. And release
+ * the debug info in the POFF object (we will be replacing it later)
+ */
+
+ poffReadDebugFuncInfoTable(hPoff);
+ poffDiscardDebugFuncInfo(hPoff);
+
+ /* Pass 1: Break the POFF program data into sections and buffer in
+ * a tree structure.
+ */
+
+ regm_InitTree();
+ regm_Pass1(hPoff);
+ regm_DumpTree();
+
+ /* We can eliminate the buffered pcode data because we have
+ * a copy in the tree and we will be replacing it before we
+ * save the file.
+ */
+
+ poffReleaseProgData(hPoff);
+
+ /* Pass 2: Convert the buffered pcode to the basic register model
+ * with an indefinite number of registers (arguments, general, and
+ * special registers) and with 32-bit immediate size.
+ */
+
+ regm_Pass2(hPoff);
+
+ /* Pass3: Perform local optimization */
+
+ regm_Pass3(hPoff);
+
+ /* Pass 4: Fixup register usage, force to use a fixed number of registers
+ * (arguments, static registers, volatile registers, special registers),
+ * and add logic to handle large immediate values.
+ */
+
+ regm_Pass4(hPoff);
+
+ /* Pass 5: Fixup BL and B offsets, section headers, relocation entries,
+ * symbol values
+ */
+
+ regm_Pass5(hPoff);
+
+ /* Replace the debug info in the POFF object with the debug info
+ * we have modified. We no longer need the buffered debug info after
+ * this point.
+ */
+
+ poffReplaceDebugFuncInfo(hPoff);
+ poffReleaseDebugFuncInfoTable();
+
+ /* Write the REGM POFF file */
+
+ poffSetArchitecture(hPoff, FHA_REGM_INSN32);
+ regm_WritePoffFile(hPoff, outfilename);
+ return 0;
+}
+
+/***********************************************************************/
+
+void regm_ProgSeek(poffHandle_t hPoff, uint32_t dwOffset)
+{
+ insn_ResetOpCodeRead(hPoff);
+ if (poffProgSeek(hPoff, dwOffset) < 0)
+ {
+ fatal(eSEEKFAIL);
+ }
+}
+
+/***********************************************************************/
+
diff --git a/misc/pascal/insn32/regm/regm.h b/misc/pascal/insn32/regm/regm.h
new file mode 100644
index 000000000..dbce7e876
--- /dev/null
+++ b/misc/pascal/insn32/regm/regm.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+ * regm.h
+ * External Declarations associated with regm.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __REGM_H
+#define __REGM_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+
+/***************************************************************************
+ * Definitions
+ ***************************************************************************/
+
+#define dbg(format, arg...) \
+ if (vRegmDebug) printf("%s: " format, __FUNCTION__, ##arg)
+
+#define DEBUG_FILE stdout
+
+/***************************************************************************
+ * Global Variables
+ ***************************************************************************/
+
+extern int vRegmDebug;
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void regm_ProgSeek(poffHandle_t handle, uint32_t dwOffset);
+
+#endif /* __REGM_H */
diff --git a/misc/pascal/insn32/regm/regm_pass1.c b/misc/pascal/insn32/regm/regm_pass1.c
new file mode 100644
index 000000000..dcc7c572c
--- /dev/null
+++ b/misc/pascal/insn32/regm/regm_pass1.c
@@ -0,0 +1,281 @@
+/**********************************************************************
+ * regm_pass1.c
+ * Break the pcode data into sections
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "keywords.h"
+#include "podefs.h"
+#include "pedefs.h"
+#include "paslib.h"
+#include "pofflib.h"
+#include "pinsn.h"
+#include "pinsn32.h"
+#include "perr.h"
+
+#include "regm.h"
+#include "regm_tree.h"
+#include "regm_pass1.h"
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static void regm_Pass1Child(poffHandle_t hPoff,
+ struct procdata_s *pParent,
+ uint32_t dwStartOffset,
+ uint32_t dwEndOffset);
+static void regm_Pass1Peer(poffHandle_t hPoff,
+ struct procdata_s *pPeer,
+ uint32_t dwStartOffset,
+ uint32_t dwEndOffset);
+static struct procdata_s *regm_Pass1Node(poffHandle_t hPoff,
+ uint32_t dwStartOffset,
+ uint32_t pdwEndOffset,
+ uint8_t chTerminator);
+static uint32_t regm_CheckSection1(poffHandle_t hPoff, uint32_t dwOffset);
+static void regm_Pass1Family(poffHandle_t hPoff,
+ struct procdata_s *pNode,
+ uint32_t dwEndOffset);
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+static void regm_Pass1Child(poffHandle_t hPoff, struct procdata_s *pParent,
+ uint32_t dwStartOffset, uint32_t dwEndOffset)
+
+{
+ struct procdata_s *pNode;
+
+ TRACE(stderr, "[regm_Pass1Child]");
+
+ /* Read the proc/func body */
+
+ pNode = regm_Pass1Node(hPoff, dwStartOffset, dwEndOffset, oRET);
+
+ /* Put the func/proc body section into the tree */
+
+ regm_AddProgChild(pParent, pNode);
+
+ /* Handle nested and child proc/func blocks */
+
+ regm_Pass1Family(hPoff, pNode, dwEndOffset);
+}
+
+/***********************************************************************/
+
+static void regm_Pass1Peer(poffHandle_t hPoff, struct procdata_s *pPeer,
+ uint32_t dwStartOffset, uint32_t dwEndOffset)
+
+{
+ struct procdata_s *pNode;
+
+ TRACE(stderr, "[regm_Pass1Peer]");
+
+ /* Read the proc/func body */
+
+ pNode = regm_Pass1Node(hPoff, dwStartOffset, dwEndOffset, oRET);
+
+ /* Put the func/proc body section into the tree */
+
+ regm_AddProgPeer(pPeer, pNode);
+
+ /* Handle nested and child proc/func blocks */
+
+ regm_Pass1Family(hPoff, pNode, dwEndOffset);
+}
+
+/***********************************************************************/
+
+static struct procdata_s *regm_Pass1Node(poffHandle_t hPoff,
+ uint32_t dwStartOffset,
+ uint32_t pdwEndOffset,
+ uint8_t chTerminator)
+
+{
+ struct procdata_s *pNode;
+ uint32_t dwActualEndOffset;
+
+ TRACE(stderr, "[regm_Pass1Node]");
+
+ /* Create a container for the proc/func body, and read the data */
+
+ pNode = regm_CreateProgSection();
+
+ /* Check if there is a jump at the beginning of the segment */
+
+ pNode->section[0].dwOffset = dwStartOffset;
+ pNode->section[1].dwOffset = regm_CheckSection1(hPoff, dwStartOffset);
+
+ /* Read all of the p-codes associated with the node */
+
+ dwActualEndOffset = regm_ReadNodePCodes(pNode, hPoff,
+ pNode->section[1].dwOffset,
+ pdwEndOffset, chTerminator);
+
+ /* Now calculate the size of each part of the program section */
+
+ pNode->section[1].dwSize = dwActualEndOffset - pNode->section[1].dwOffset;
+
+ if (pNode->section[0].dwOffset == pNode->section[1].dwOffset)
+ pNode->section[0].dwSize = 0;
+ else
+ pNode->section[0].dwSize = 5;
+
+ /* Associate debug info with the program section. */
+
+ pNode->pFuncInfo = poffFindDebugFuncInfo(pNode->section[0].dwOffset);
+ if (!pNode->pFuncInfo)
+ {
+ /* This debug information should always be present at this
+ * point. We will need it.
+ */
+
+ fatal(ePOFFCONFUSION);
+ }
+
+ return pNode;
+}
+
+/***********************************************************************/
+
+static uint32_t regm_CheckSection1 (poffHandle_t hPoff, uint32_t dwOffset)
+{
+ OPTYPE op;
+
+ /* Seek to the beginning of the section. */
+
+ regm_ProgSeek(hPoff, dwOffset);
+
+ /* Read the opcode at that position. */
+
+ (void)insn_GetOpCode(hPoff, &op);
+
+ /* Is it a oJMP instruction? This happens when there are nested
+ * functions. The entry point into the parent function is a jump
+ * around the nested functions.
+ */
+
+ if (GETOP(&op) == oJMP)
+ {
+ /* Yes, then the block really begins at the target of the jump */
+
+ return GETARG(&op);
+ }
+ else
+ {
+ /* No, then the block really begins right here */
+
+ return dwOffset;
+ }
+}
+
+/***********************************************************************/
+
+static void regm_Pass1Family(poffHandle_t hPoff, struct procdata_s *pNode,
+ uint32_t dwEndOffset)
+{
+ uint32_t dwSectionEnd;
+
+ /* Process any nested functions */
+
+ if (pNode->section[0].dwOffset != pNode->section[1].dwOffset)
+ {
+ dwSectionEnd = pNode->section[0].dwOffset + pNode->section[0].dwSize;
+ regm_Pass1Child(hPoff, pNode, dwSectionEnd, pNode->section[1].dwOffset);
+ }
+
+ /* Process any peer functions */
+
+ dwSectionEnd = pNode->section[1].dwOffset + pNode->section[1].dwSize;
+ if (dwSectionEnd < dwEndOffset)
+ {
+ regm_Pass1Peer(hPoff, pNode, dwSectionEnd, dwEndOffset);
+ }
+}
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+void regm_Pass1(poffHandle_t hPoff)
+{
+ struct procdata_s *pNode;
+ uint32_t dwEntryPoint;
+
+ TRACE(stderr, "[regm_Pass1]");
+
+ /* Get the program entry point from the poff header */
+
+ dwEntryPoint = poffGetEntryPoint(hPoff);
+
+ /* Read the main program body */
+
+ pNode = regm_Pass1Node(hPoff, dwEntryPoint, 0xffffffff, oEND);
+
+ /* Put the main program section into the tree (at the root) */
+
+ regm_SetProgRoot(pNode);
+
+ /* Then process any nested functions */
+
+ if (dwEntryPoint != 0)
+ {
+ regm_Pass1Child(hPoff, pNode, 0, dwEntryPoint);
+ }
+}
+
+/***********************************************************************/
+
diff --git a/misc/pascal/insn32/regm/regm_pass1.h b/misc/pascal/insn32/regm/regm_pass1.h
new file mode 100644
index 000000000..98fafcb87
--- /dev/null
+++ b/misc/pascal/insn32/regm/regm_pass1.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * regm_pass1.h
+ * External Declarations associated with regm_pass1.c
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __REGM_PASS1_H
+#define __REGM_PASS1_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+/***************************************************************************
+ * Definitions
+ ***************************************************************************/
+
+/***************************************************************************
+ * Global Variables
+ ***************************************************************************/
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void regm_Pass1(poffHandle_t hPoff);
+
+#endif /* __REGM_PASS1_H */
diff --git a/misc/pascal/insn32/regm/regm_pass2.c b/misc/pascal/insn32/regm/regm_pass2.c
new file mode 100644
index 000000000..619d06501
--- /dev/null
+++ b/misc/pascal/insn32/regm/regm_pass2.c
@@ -0,0 +1,1526 @@
+/**********************************************************************
+ * regm_pass2.c
+ * Convert the buffered pcode to the basic register model with an
+ * indefinite number of registers (arguments, general, and special
+ * registers) and with 32-bit immediate size.
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ *********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pxdefs.h"
+#include "pfdefs.h"
+#include "pedefs.h"
+#include "pofflib.h"
+#include "perr.h"
+
+#include "pinsn32.h"
+#include "builtins.h"
+
+#include "regm.h"
+#include "regm_tree.h"
+#include "regm_registers2.h"
+#include "regm_pass2.h"
+
+/************************************a*********************************
+ * Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Types
+ **********************************************************************/
+
+struct regm_opmap_s;
+
+typedef void (*regm_mapper_t)(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode, struct procdata_s *pNode);
+
+struct regm_opmap_s
+{
+ uint8_t chOpCode;
+ int8_t chImmediate;
+ int8_ chSpecial;
+ regm_mapper_t pMapper;
+};
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static void regm_NoOperation(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_UnaryOperation(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_BinaryOperation(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_CompareVsZero(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_BinaryComparison(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_LoadImmediate(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_LoadMultiple(uint32_t dwRDest, uint32_t dwRSrc);
+static void regm_LoadMultipleImmediate(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_StoreMultiple(uint32_t dwRDest, uint32_t dwRSrc);
+static void regm_StoreImmediate(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_StoreMultipleImmediate(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_Duplicate(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_PushImmediate(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_PopSpecial(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_SetDataCount(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_PushSpecial(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_Return(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_LoadOffset(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_LoadMultipleOffset(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_StoreOffset(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_StoreMultipleOffset(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_LoadIndexed(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode, struct procdata_s *pNode);
+static void regm_LoadMultipleIndexed(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_StoreIndexed(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode, struct procdata_s *pNode);
+static void regm_StoreMultipleIndexed(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_ConditionalBranchVsZero(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_ConditionalBranchBinary(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_UnconditionalBranch(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_IncrementSpecial(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_LoadAddress(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode, struct procdata_s *pNode);
+static void regm_LoadAddressIndexed(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_SetupOutArgs(uint32_t nParms, const uint32_t *pwArgSize);
+static void regm_MapInRet(uint32_t wRetSize);
+static void regm_PCal(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_SysIo(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_LibCall(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_Float(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+static void regm_IllegalPCode(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode);
+
+static void regm_GenerateRegm(struct procdata_s *pNode, void *pvArg);
+static int regm_Pass2Node(struct procdata_s *pNode, void *pvArg);
+
+/**********************************************************************
+ * Public Variables
+ **********************************************************************/
+
+/* On the initialize passes, the register number will simply be the offset
+ * from the top of the stack. The following variable keeps trck of the
+ * stack offset.
+ */
+
+uint32_t g_dwStackOffset;
+uint32_t g_dwRegisterCount = 0;
+int g_bRegisterCountValid = 0;
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static const struct regm_opmap_s vrgOpMap1[64] =
+ {
+ /* 0x00: oNOP */ {0, 0, 0, regm_NoOperation},
+ /* 0x01: oNEG */ {rRSBI, 0, 0, regm_UnaryOperation},
+ /* 0x02: oABS */ {rRSB, 0, 0, regm_UnaryOperation},
+ /* 0x03: oINC */ {rADDI, 1, 0, regm_UnaryOperation},
+ /* 0x04: oDEC */ {rSUBI, 1, 0, regm_UnaryOperation},
+ /* 0x05: oNOT */ {rMVN, 0, 0, regm_UnaryOperation},
+ /* 0x06: oADD */ {rADD, 0, 0, regm_BinaryOperation},
+ /* 0x07: oSUB */ {rSUB, 0, 0, regm_BinaryOperation},
+ /* 0x08: oMUL */ {rMUL, 0, 0, regm_BinaryOperation},
+ /* 0x09: oDIV */ {rDIV, 0, 0, regm_BinaryOperation},
+ /* 0x0a: oMOD */ {rMOD, 0, 0, regm_BinaryOperation},
+ /* 0x0b: oSLL */ {rSLL, 0, 0, regm_BinaryOperation},
+ /* 0x0c: oSRL */ {rSRL, 0, 0, regm_BinaryOperation},
+ /* 0x0d: oSRA */ {rSRA, 0, 0, regm_BinaryOperation},
+ /* 0x0e: oOR */ {rOR, 0, 0, regm_BinaryOperation},
+ /* 0x0f: oAND */ {rAND, 0, 0, regm_BinaryOperation},
+
+ /* 0x10: oEQUZ */ {rBEQ, 0, 0, regm_CompareVsZero},
+ /* 0x11: oNEQZ */ {rBNE, 0, 0, regm_CompareVsZero},
+ /* 0x12: oLTZ */ {rBLT, 0, 0, regm_CompareVsZero},
+ /* 0x13: oGTEZ */ {rBGTE, 0, 0, regm_CompareVsZero},
+ /* 0x14: oGTZ */ {rBGT, 0, 0, regm_CompareVsZero},
+ /* 0x15: oLTEZ */ {rBLTE, 0, 0, regm_CompareVsZero},
+ /* 0x16: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x17: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x18: oEQU */ {rBEQ, 0, 0, regm_BinaryComparison},
+ /* 0x19: oNEQ */ {rBNE, 0, 0, regm_BinaryComparison},
+ /* 0x1a: oLT */ {rBLT, 0, 0, regm_BinaryComparison},
+ /* 0x1b: oGTE */ {rBGTE, 0, 0, regm_BinaryComparison},
+ /* 0x1c: oGT */ {rBGT, 0, 0, regm_BinaryComparison},
+ /* 0x1d: oLTE */ {rBLTE, 0, 0, regm_BinaryComparison},
+ /* 0x1e: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x1f: oBIT */ {rBEQ, 0, 0, regm_BinaryComparison},
+
+ /* 0x20: oLDI */ {rLD, 2, SPB, regm_LoadImmediate},
+ /* 0x21: oLDIH */ {rLDH, 1, SPB, regm_LoadImmediate},
+ /* 0x22: oLDIB */ {rLDB, 0, SPB, regm_LoadImmediate},
+ /* 0x23: oLDIM */ {0, 0, SPB, regm_LoadMultipleImmediate},
+ /* 0x24: oSTI */ {rST, 2, SPB, regm_StoreImmediate},
+ /* 0x25: oSTIH */ {rSTH, 1, SPB, regm_StoreImmediate},
+ /* 0x26: oSTIB */ {rSTB, 0, SPB, regm_StoreImmediate},
+ /* 0x27: oSTIM */ {0, 0, SPB, regm_StoreMultipleImmediate},
+ /* 0x28: oDUP */ {0, 0, 0, regm_Duplicate},
+ /* 0x17: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x2a: oPUSHS */ {0, 0, CSP, regm_PushSpecial},
+ /* 0x2b: oPOPS */ {0, 0, CSP, regm_PopSpecial},
+ /* 0x2c: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x2d: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x2e: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x2f: oRET */ {0, 0, 0, regm_Return},
+
+ /* 0x30: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x31: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x32: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x33: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x34: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x35: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x36: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x37: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x38: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x39: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x3a: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x3b: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x3c: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x3d: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x3e: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x3f: oEND */ {0, 0, 0, regm_Return}
+ };
+
+static const struct regm_opmap_s vrgOpMap2[64] =
+ {
+ /* 0x80: oLD */ {rLD, 2, SPB, regm_LoadOffset},
+ /* 0x81: oLDH */ {rLDH, 1, SPB, regm_LoadOffset},
+ /* 0x82: oLDB */ {rLDB, 0, SPB, regm_LoadOffset},
+ /* 0x83: oLDM */ {0, 0, SPB, regm_LoadMultipleOffset},
+ /* 0x84: oST */ {rST, 2, SPB, regm_StoreOffset},
+ /* 0x85: oSTH */ {rSTH, 1, SPB, regm_StoreOffset},
+ /* 0x86: oSTB */ {rSTB, 0, SPB, regm_StoreOffset},
+ /* 0x87: oSTM */ {0, 0, SPB, regm_StoreMultipleOffset},
+ /* 0x88: oLDX */ {rLD, 2, SPB, regm_LoadIndexed},
+ /* 0x89: oLDXH */ {rLDH, 1, SPB, regm_LoadIndexed},
+ /* 0x8a: oLDXB */ {rLDB, 0, SPB, regm_LoadIndexed},
+ /* 0x8b: oLDXM */ {0, 0, SPB, regm_LoadMultipleIndexed},
+ /* 0x8c: oSTX */ {rST, 2, SPB, regm_StoreIndexed},
+ /* 0x8d: oSTXH */ {rSTH, 1, SPB, regm_StoreIndexed},
+ /* 0x8e: oSTXB */ {rSTB, 0, SPB, regm_StoreIndexed},
+ /* 0x8f: oSTXM */ {0, 0, SPB, regm_StoreMultipleIndexed},
+
+ /* 0x90: oJEQUZ */ {rBEQ, 0, 0, regm_ConditionalBranchVsZero},
+ /* 0x91: oJNEQZ */ {rBNE, 0, 0, regm_ConditionalBranchVsZero},
+ /* 0x92: oJLTZ */ {rBLT, 0, 0, regm_ConditionalBranchVsZero},
+ /* 0x93: oJGTEZ */ {rBGTE, 0, 0, regm_ConditionalBranchVsZero},
+ /* 0x94: oJGTZ */ {rBGT, 0, 0, regm_ConditionalBranchVsZero},
+ /* 0x95: oJLTEZ */ {rBLTE, 0, 0, regm_ConditionalBranchVsZero},
+ /* 0x96: oJMP */ {rB, 0, 0, regm_UnconditionalBranch},
+ /* 0x97: oPUSH */ {0, 0, 0, regm_PushImmediate},
+ /* 0x98: oJEQU */ {rBEQ, 0, 0, regm_ConditionalBranchBinary},
+ /* 0x99: oJNEQ */ {rBNE, 0, 0, regm_ConditionalBranchBinary},
+ /* 0x9a: oJLT */ {rBLT, 0, 0, regm_ConditionalBranchBinary},
+ /* 0x9b: oJGTE */ {rBGTE, 0, 0, regm_ConditionalBranchBinary},
+ /* 0x9c: oJGT */ {rBGT, 0, 0, regm_ConditionalBranchBinary},
+ /* 0x9d: oJLTE */ {rBLTE, 0, 0, regm_ConditionalBranchBinary},
+ /* 0x9e: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0x9f: oINDS */ {0, 0, SP, regm_IncrementSpecial},
+
+ /* 0xa0: oLDS */ {rLD, 2, LSP, regm_LoadOffset},
+ /* 0xa1: oLDSH */ {rLDH, 1, LSP, regm_LoadOffset},
+ /* 0xa2: oLDSB */ {rLDB, 0, LSP, regm_LoadOffset},
+ /* 0xa3: oLDSM */ {0, 0, LSP, regm_LoadMultipleOffset},
+ /* 0xa4: oSTS */ {rST, 2, LSP, regm_StoreOffset},
+ /* 0xa5: oSTSH */ {rSTH, 1, LSP, regm_StoreOffset},
+ /* 0xa6: oSTSB */ {rSTB, 0, LSP, regm_StoreOffset},
+ /* 0xa7: oSTSM */ {0, 0, LSP, regm_StoreMultipleOffset},
+ /* 0xa8: oLDSX */ {rLD, 2, LSP, regm_LoadIndexed},
+ /* 0xa9: oLDSXH */ {rLDH, 1, LSP, regm_LoadIndexed},
+ /* 0xaa: oLDSXB */ {rLDB, 0, LSP, regm_LoadIndexed},
+ /* 0xab: oLDSXM */ {0, 0, LSP, regm_LoadMultipleIndexed},
+ /* 0xac: oSTSX */ {rST, 2, LSP, regm_StoreIndexed},
+ /* 0xad: oSTSXH */ {rSTH, 1, LSP, regm_StoreIndexed},
+ /* 0xae: oSTSXB */ {rSTB, 0, LSP, regm_StoreIndexed},
+ /* 0xaf: oSTSXM */ {0, 0, LSP, regm_StoreMultipleIndexed},
+
+ /* 0xb0: oLA */ {0, 0, SPB, regm_LoadAddress},
+ /* 0xb1: oLAS */ {0, 0, LSP, regm_LoadAddress},
+ /* 0xb2: oLAC */ {0, 0, CSB, regm_LoadAddress},
+ /* 0xb3: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0xb4: oLAX */ {0, 0, SPB, regm_LoadAddressIndexed},
+ /* 0xb5: oLASX */ {0, 0, LSP, regm_LoadAddressIndexed},
+ /* 0xb6: oSLSP */ {0, 0, LSP, regm_PopSpecial},
+ /* 0xb7: oSDC */ {0, 0, DC, regm_SetDataCount},
+ /* 0xb8: */ {0, 0, 0, regm_IllegalPCode},
+ /* 0xb9: oPCAL */ {0, 0, 0, regm_PCal},
+ /* 0xba: oSYSIO */ {0, 0, 0, regm_SysIo},
+ /* 0xbb: oLIB */ {0, 0, 0, regm_LibCall},
+ /* 0xbc: oFLOAT */ {0, 0, 0, regm_Float},
+ /* 0xbd: oLABEL */ {0, 0, 0, regm_NoOperation},
+ /* 0xbe: oINCLUDE*/ {0, 0, 0, regm_NoOperation},
+ /* 0xbf: oLINE */ {0, 0, 0, regm_NoOperation}
+ };
+
+static const struct regm_builtin_s g_rgSysIoBuiltIns[MAX_XOP] =
+{
+ /* 0x00 */ ILLEGAL_BUILTIN_INIT, xEOF_INIT,
+ /* 0x02 */ xEOLN_INIT, xRESET_INIT,
+ /* 0x04 */ xREWRITE_INIT, ILLEGAL_BUILTIN_INIT,
+ /* 0x06 */ ILLEGAL_BUILTIN_INIT, ILLEGAL_BUILTIN_INIT,
+ /* 0x08 */ ILLEGAL_BUILTIN_INIT, ILLEGAL_BUILTIN_INIT,
+ /* 0x0a */ ILLEGAL_BUILTIN_INIT, ILLEGAL_BUILTIN_INIT,
+ /* 0x0c */ ILLEGAL_BUILTIN_INIT, ILLEGAL_BUILTIN_INIT,
+ /* 0x0e */ ILLEGAL_BUILTIN_INIT, ILLEGAL_BUILTIN_INIT,
+ /* 0x10 */ xREADLN_INIT, xREAD_PAGE_INIT,
+ /* 0x12 */ xREAD_BINARY_INIT, xREAD_INT_INIT,
+ /* 0x14 */ xREAD_CHAR_INIT, xREAD_STRING_INIT,
+ /* 0x16 */ xREAD_REAL_INIT, ILLEGAL_BUILTIN_INIT,
+ /* 0x18 */ ILLEGAL_BUILTIN_INIT, ILLEGAL_BUILTIN_INIT,
+ /* 0x1a */ ILLEGAL_BUILTIN_INIT, ILLEGAL_BUILTIN_INIT,
+ /* 0x1c */ ILLEGAL_BUILTIN_INIT, ILLEGAL_BUILTIN_INIT,
+ /* 0x1e */ ILLEGAL_BUILTIN_INIT, ILLEGAL_BUILTIN_INIT,
+ /* 0x20 */ xWRITELN_INIT, xWRITE_PAGE_INIT,
+ /* 0x22 */ xWRITE_BINARY_INIT, xWRITE_INT_INIT,
+ /* 0x24 */ xWRITE_CHAR_INIT, xWRITE_STRING_INIT,
+ /* 0x25 */ xWRITE_REAL_INIT
+};
+
+static const struct regm_builtin_s g_rgLibCallBuiltIns[MAX_LBOP] =
+{
+ /* 0x00 */ lbGETENV_INIT, lbSTR2STR_INIT,
+ /* 0x02 */ lbCSTR2STR_INIT, lbSTR2RSTR_INIT,
+ /* 0x04 */ lbCSTR2RSTR_INIT, lbVAL_INIT,
+ /* 0x06 */ lbMKSTK_INIT, lbMKSTKSTR_INIT,
+ /* 0x08 */ lbMKSTKC_INIT, lbSTRCAT_INIT,
+ /* 0x0a */ lbSTRCATC_INIT, lbSTRCMP_INIT
+};
+
+static const struct regm_builtin_s g_rgRrFopBuiltIns[MAX_FOP] =
+{
+ /* 0x00 */ ILLEGAL_BUILTIN_INIT, fpFLOAT_INIT,
+ /* 0x02 */ fpTRUNC_INIT, fpROUND_INIT,
+ /* 0x04 */ fpADD_RR_INIT, fpSUB_RR_INIT,
+ /* 0x06 */ fpMUL_RR_INIT, fpDIV_RR_INIT,
+ /* 0x00 */ fpMOD_RR_INIT, ILLEGAL_BUILTIN_INIT,
+ /* 0x0a */ fpEQU_RR_INIT, fpNEQ_RR_INIT,
+ /* 0x0c */ fpLT_RR_INIT, fpGTE_RR_INIT,
+ /* 0x0e */ fpGT_RR_INIT, fpLTE_RR_INIT,
+ /* 0x10 */ fpNEG_R_INIT, fpABS_R_INIT,
+ /* 0x12 */ fpSQR_R_INIT, fpSQRT_R_INIT,
+ /* 0x14 */ fpSIN_R_INIT, fpCOS_R_INIT,
+ /* 0x16 */ fpATAN_R_INIT, fpLN_R_INIT,
+ /* 0x18 */ fpEXP_R_INIT
+};
+
+static const struct regm_builtin_s g_rgRiFopBuiltIns[MAX_FOP] =
+{
+ /* 0x00 */ ILLEGAL_BUILTIN_INIT, fpFLOAT_INIT,
+ /* 0x02 */ fpTRUNC_INIT, fpROUND_INIT,
+ /* 0x04 */ fpADD_RI_INIT, fpSUB_RI_INIT,
+ /* 0x06 */ fpMUL_RI_INIT, fpDIV_RI_INIT,
+ /* 0x00 */ fpMOD_RI_INIT, ILLEGAL_BUILTIN_INIT,
+ /* 0x0a */ fpEQU_RI_INIT, fpNEQ_RI_INIT,
+ /* 0x0c */ fpLT_RI_INIT, fpGTE_RI_INIT,
+ /* 0x0e */ fpGT_RI_INIT, fpLTE_RI_INIT,
+ /* 0x10 */ fpNEG_I_INIT, fpABS_I_INIT,
+ /* 0x12 */ fpSQR_I_INIT, fpSQRT_I_INIT,
+ /* 0x14 */ fpSIN_I_INIT, fpCOS_I_INIT,
+ /* 0x16 */ fpATAN_I_INIT, fpLN_I_INIT,
+ /* 0x18 */ fpEXP_I_INIT
+};
+
+static const struct regm_builtin_s g_rgIrFopBuiltIns[MAX_FOP] =
+{
+ /* 0x00 */ ILLEGAL_BUILTIN_INIT, fpFLOAT_INIT,
+ /* 0x02 */ fpTRUNC_INIT, fpROUND_INIT,
+ /* 0x04 */ fpADD_IR_INIT, fpSUB_IR_INIT,
+ /* 0x06 */ fpMUL_IR_INIT, fpDIV_IR_INIT,
+ /* 0x00 */ fpMOD_IR_INIT, ILLEGAL_BUILTIN_INIT,
+ /* 0x0a */ fpEQU_IR_INIT, fpNEQ_IR_INIT,
+ /* 0x0c */ fpLT_IR_INIT, fpGTE_IR_INIT,
+ /* 0x0e */ fpGT_IR_INIT, fpLTE_IR_INIT,
+ /* 0x10 */ fpNEG_R_INIT, fpABS_R_INIT,
+ /* 0x12 */ fpSQR_R_INIT, fpSQRT_R_INIT,
+ /* 0x14 */ fpSIN_R_INIT, fpCOS_R_INIT,
+ /* 0x16 */ fpATAN_R_INIT, fpLN_R_INIT,
+ /* 0x18 */ fpEXP_R_INIT
+};
+
+static const struct regm_builtin_s g_rgIiFopBuiltIns[MAX_FOP] =
+{
+ /* 0x00 */ ILLEGAL_BUILTIN_INIT, fpFLOAT_INIT,
+ /* 0x02 */ fpTRUNC_INIT, fpROUND_INIT,
+ /* 0x04 */ fpADD_II_INIT, fpSUB_II_INIT,
+ /* 0x06 */ fpMUL_II_INIT, fpDIV_II_INIT,
+ /* 0x00 */ fpMOD_II_INIT, ILLEGAL_BUILTIN_INIT,
+ /* 0x0a */ fpEQU_II_INIT, fpNEQ_II_INIT,
+ /* 0x0c */ fpLT_II_INIT, fpGTE_II_INIT,
+ /* 0x0e */ fpGT_II_INIT, fpLTE_II_INIT,
+ /* 0x10 */ fpNEG_I_INIT, fpABS_I_INIT,
+ /* 0x12 */ fpSQR_I_INIT, fpSQRT_I_INIT,
+ /* 0x14 */ fpSIN_I_INIT, fpCOS_I_INIT,
+ /* 0x16 */ fpATAN_I_INIT, fpLN_I_INIT,
+ /* 0x18 */ fpEXP_I_INIT
+};
+
+static const struct regm_builtin_s *g_prgFopBuiltIns[4] =
+{
+ /* Real - Real */ g_rgRrFopBuiltIns,
+ /* Integer - Real */ g_rgRiFopBuiltIns,
+ /* Real - Ingeter */ g_rgIrFopBuiltIns,
+ /* Integer - Integer */ g_rgIiFopBuiltIns
+};
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+static void regm_NoOperation(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode, struct procdata_s *pNode)
+{
+ TRACE(stderr, "[regm_NoOperation]");
+
+ /* Do nothing */
+}
+
+/***********************************************************************/
+/* These pcodes are all binary operations in the sense that they take
+ * one input and produce one output:
+ *
+ * INPUT: TOS(0)
+ * OUTPUT: TOS(0)
+ * Stack is unchanged.
+ */
+
+static void regm_UnaryOperation(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode, struct procdata_s *pNode)
+{
+ uint32_t dwUnaryRegister = MKCCREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwCcRegister = MKCCREG(g_dwStackOffset);
+
+ TRACE(stderr, "[regm_UnaryOperation]");
+
+ switch (GETOP(pOpCode))
+ {
+ case oABS:
+ regm_GenerateForm1ICc(rCMPI, dwUnaryRegister, 0, dwCcRegister);
+ regm_GenerateForm4ICc(rBGTE, 2, dwCcRegister);
+
+ default:
+ regm_GenerateForm3I(pEntry->chOpCode, dwUnaryRegister,
+ dwUnaryRegister, pEntry->chImmediate);
+ break;
+ }
+}
+
+/***********************************************************************/
+/* These pcodes are all binary operations in the sense that they take
+ * two input:
+ *
+ * INPUT: TOS(0), TOS(-1)
+ * OUTPUT: TOS(0)
+ * Stack reduced by one.
+ *
+ * These all generate form 3r instructions:
+ */
+
+static void regm_BinaryOperation(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwROperand1 = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwROperand2 = MKREG(g_dwStackOffset - 2*sINT_SIZE);
+ uint32_t dwRDest = dwROperand2;
+
+ TRACE(stderr, "[regm_BinaryOperation]");
+
+ /* Generate the binary operation */
+
+ regm_GenerateForm3R(pEntry->chOpCode, dwRDest, dwROperand1, dwROperand2);
+
+ /* Reduce stack */
+
+ g_dwStackOffset -= sINT_SIZE;
+}
+
+/***********************************************************************/
+/* These pcodes are all boolean unary operations in the sense that
+ * the pcode form takes one input and generates one output:
+ *
+ * INPUT: TOS(0)
+ * OUTPUT: TOS(0)
+ * Stack unchanged
+ *
+ * The complication is that the resulting boolean is not represented by
+ * data in the register model but, rather, as a condition code setting.
+ * For now we can, however, force a large number of condition code
+ * registers; during a later fixup pass, we can force this to a single
+ * condition code register.
+ */
+
+static void regm_CompareVsZero(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwUnaryRegister = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwCcRegister = MKCCREG(g_dwStackOffset);
+
+ TRACE(stderr, "[regm_CompareVsZero]");
+
+ regm_GenerateForm1ICc(rCMPI, dwUnaryRegister, 0, dwCcRegister);
+ regm_GenerateForm2I(rMOVI, dwUnaryRegister, 0);
+ regm_GenerateForm4ICc(pEntry->chOpCode, 2, dwCcRegister);
+ regm_GenerateForm2I(rMOVI, dwUnaryRegister, 1);
+}
+
+/***********************************************************************/
+/* These pcodes are all boolean binary operations in the sense that
+ * the pcode form takes two inputs and generates one output:
+ *
+ * INPUT: TOS(0), TOS(-1)
+ * OUTPUT: TOS(0)
+ * Stack reduced by one.
+ *
+ * The complication is that the resulting boolean not represented by
+ * data in the register model but, rather, as a condition code setting.
+ * For now we can, however, force a large number of condition code
+ * registers; during a later fixup pass, we can force this to a single
+ * condition code register.
+ */
+
+static void regm_BinaryComparison(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwROperand1 = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwROperand2 = MKREG(g_dwStackOffset - 2*sINT_SIZE);
+ uint32_t dwRDest = dwROperand2;
+ uint32_t dwCcRegister = MKCCREG(g_dwStackOffset);
+
+ TRACE(stderr, "[regm_BinaryComparison]");
+
+
+ switch (GETOP(pOpCode))
+ {
+ case oBIT:
+ regm_GenerateForm3R(rAND, dwRDest, dwROperand1, dwROperand2);
+ regm_GenerateForm1ICc(rCMPI, dwRDest, 0, dwCcRegister);
+ break;
+
+ default:
+ regm_GenerateForm1RCc(rCMP, dwROperand1, dwROperand2, dwCcRegister);
+ break;
+ }
+
+ regm_GenerateForm2I(rMOVI, dwRDest, 0);
+ regm_GenerateForm4ICc(pEntry->chOpCode, 2, dwCcRegister);
+ regm_GenerateForm2I(rMOVI, dwRDest, 1);
+
+ /* Reduce stack */
+
+ g_dwStackOffset -= sINT_SIZE;
+}
+
+/***********************************************************************/
+/* Load from the address on the stack. Stack is unchanged */
+
+static void regm_LoadImmediate(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwROperand1 = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwRDest = dwROperand1;
+
+ TRACE(stderr, "[regm_LoadImmediate]");
+
+ /* Use the immediate value as an index against the SPB/LSP */
+
+ regm_GenerateForm3R(pEntry->chOpCode, dwRDest, dwROperand1,
+ MKSPECIAL(pEntry->chSpecial));
+}
+
+/***********************************************************************/
+/* Generic load multiple logic */
+
+static void regm_LoadMultiple(uint32_t dwRDest, uint32_t dwRSrc)
+{
+ TRACE(stderr, "[regm_LoadMultiple]");
+
+ if (g_bRegisterCountValid)
+ {
+ regm_GenerateForm3I(rLDM, dwRDest, dwRSrc, g_dwRegisterCount);
+
+ /* Adjust the stack for the g_dwRegisterCount values added to the
+ * stack.
+ */
+
+ g_dwStackOffset += g_dwRegisterCount * sINT_SIZE;
+ g_bRegisterCountValid = 0;
+ }
+ else
+ {
+ fatal(ePOFFCONFUSION);
+ }
+}
+
+/***********************************************************************/
+/* SPB/LSP relative source offset is on the stack. Stack increase determined
+ * by content of DC register.
+ */
+
+static void regm_LoadMultipleImmediate(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwRSrc = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwRDest = dwRSrc;
+
+ TRACE(stderr, "[regm_LoadMultipleImmediate]");
+
+ /* Adjust the src for the SPB/LSP value and generate the multiple load */
+
+ regm_GenerateForm3R(rADD, dwRSrc, dwRSrc, MKSPECIAL(pEntry->chSpecial));
+ regm_LoadMultiple(dwRSrc, dwRDest);
+
+ /* Stack will be increased by an amount determined by DC in
+ * regm_LoadMultiple. However, we need to also account for the
+ * immediate stack value that we consume here.
+ */
+
+ g_dwStackOffset -= sINT_SIZE;
+}
+
+/***********************************************************************/
+/* Store value on stack to address on stack. Stack is reduced by two */
+
+static void regm_StoreImmediate(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwRSrc = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwROperand1 = MKREG(g_dwStackOffset - 2*sINT_SIZE);
+
+ TRACE(stderr, "[regm_StoreImmediate]");
+
+ /* Use the immediate value as an index against the SPB/LSP */
+
+ regm_GenerateForm3R(pEntry->chOpCode, dwRSrc, dwROperand1,
+ MKSPECIAL(pEntry->chSpecial));
+
+ /* Reduce stack */
+
+ g_dwStackOffset -= 2*sINT_SIZE;
+}
+
+/***********************************************************************/
+/* Generic store multiple logic */
+
+static void regm_StoreMultiple(uint32_t dwRDest, uint32_t dwRSrc)
+{
+ TRACE(stderr, "[regm_StoreMultiple]");
+
+ if (g_bRegisterCountValid)
+ {
+ regm_GenerateForm3I(rSTM, dwRSrc, dwRDest, g_dwRegisterCount);
+
+ /* Adjust the stack for the g_dwRegisterCount values added to the
+ * stack.
+ */
+
+ g_dwStackOffset -= g_dwRegisterCount * sINT_SIZE;
+ g_bRegisterCountValid = 0;
+ }
+ else
+ {
+ fatal(ePOFFCONFUSION);
+ }
+}
+
+/***********************************************************************/
+/* Store multiple values on stack to address on stack. Stack is reduced
+ * by an amount determined by the content of DC.
+ */
+
+static void regm_StoreMultipleImmediate(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwRDest = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwRSrc = MKREG(g_dwStackOffset - (g_dwRegisterCount + 1)*sINT_SIZE);
+
+ TRACE(stderr, "[regm_StoreMultipleImmediate]");
+
+ /* Adjust the src for the SPB/LSP value and generate the multiple load */
+
+ regm_GenerateForm3R(rADD, dwRDest, dwRDest, MKSPECIAL(pEntry->chSpecial));
+ regm_StoreMultiple(dwRSrc, dwRDest);
+
+ /* Stack will be increased by an amount determined by DC in
+ * regm_StoreMultiple. However, we need to also account for the
+ * immediate stack value that we consume here.
+ */
+
+ g_dwStackOffset -= sINT_SIZE;
+}
+
+/***********************************************************************/
+/* Duplicate the TOS. stack increases by one */
+
+static void regm_Duplicate(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwROperand1 = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwRDest = MKREG(g_dwStackOffset);
+
+ TRACE(stderr, "[regm_Duplicate]");
+
+ /* Generate the binary operation */
+
+ regm_GenerateForm2R(rMOV, dwRDest, dwROperand1);
+
+ /* Increment the stack */
+
+ g_dwStackOffset += sINT_SIZE;
+}
+
+/***********************************************************************/
+/* Put the immediate value at the top of the stack. Increment stack */
+
+static void regm_PushImmediate(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwRDest = g_dwStackOffset;
+
+ TRACE(stderr, "[regm_PushImmediate]");
+
+ /* The value may be too large to represent with a MOVI, but we'll handle
+ * that later.
+ */
+
+ regm_GenerateForm2I(rMOVI, dwRDest, GETARG(pOpCode));
+
+ /* Increment the stack */
+
+ g_dwStackOffset += sINT_SIZE;
+}
+
+/***********************************************************************/
+/* Push the special register onto the stack. Stack increments by one */
+
+static void regm_PushSpecial(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwRDest = g_dwStackOffset;
+
+ TRACE(stderr, "[regm_PushSpecial]");
+
+ regm_GenerateForm2R(rMOV, dwRDest, MKSPECIAL(pEntry->chSpecial));
+
+ /* Increment the stack */
+
+ g_dwStackOffset += sINT_SIZE;
+}
+
+/***********************************************************************/
+/* Pop the TOS into the special register. Stack decrements by one */
+
+static void regm_PopSpecial(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwROperand1 = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+
+ TRACE(stderr, "[regm_PopSpecial]");
+
+ regm_GenerateForm2R(rMOV, MKSPECIAL(pEntry->chSpecial), dwROperand1);
+
+ /* Decrement the stack */
+
+ g_dwStackOffset -= sINT_SIZE;
+}
+
+/***********************************************************************/
+/* Save the immediate value in the data count register */
+
+static void regm_SetDataCount(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ /* We don't acutally use the DC register. It is an artifact just
+ * get here. We save the byte count as a even number of registers.
+ */
+
+ g_dwRegisterCount = (GETARG(pOpCode) + 3) >> 2;
+ g_bRegisterCountValid = 1;
+}
+
+/***********************************************************************/
+
+static void regm_Return(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ TRACE(stderr, "[regm_Return]");
+
+ /* This should have been processed by the prologue/epilogue logic */
+
+ fatal(ePOFFCONFUSION);
+}
+
+/***********************************************************************/
+/* Load at offset from SPB/LSP. Stack increases by one */
+
+static void regm_LoadOffset(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwRDest = g_dwStackOffset;
+
+ TRACE(stderr, "[regm_LoadOffset]");
+
+ /* Use the immediate value as an index against the SPB/LSP */
+
+ regm_GenerateForm3I(pEntry->chOpCode, dwRDest, MKSPECIAL(pEntry->chSpecial),
+ GETARG(pOpCode) >> pEntry->chImmediate);
+
+ /* Increment the stack */
+
+ g_dwStackOffset += sINT_SIZE;
+}
+
+/***********************************************************************/
+/* Load multiple registgers at offset from SPB/LSP. Stack increase depends
+ * on value in DC (only)
+ */
+
+static void regm_LoadMultipleOffset(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwRSrc = MKREG(g_dwStackOffset);
+ uint32_t dwRDest = dwRSrc;
+
+ TRACE(stderr, "[regm_LoadMultipleOffset]");
+
+ regm_GenerateForm3R(rADD, dwRSrc, MKSPECIAL(pEntry->chSpecial),
+ GETARG(pOpCode));
+ regm_LoadMultiple(dwRSrc, dwRDest);
+}
+
+/***********************************************************************/
+/* Store at offset from SPB/LSP. Stack decreases by one */
+
+static void regm_StoreOffset(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwRSrc = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+
+ TRACE(stderr, "[regm_StoreOffset]");
+
+ /* Use the immediate value as an index against the SPB/LSP */
+
+ regm_GenerateForm3I(pEntry->chOpCode, dwRSrc,
+ MKSPECIAL(pEntry->chSpecial),
+ GETARG(pOpCode) >> pEntry->chImmediate);
+
+ /* Decrement the stack */
+
+ g_dwStackOffset -= sINT_SIZE;
+}
+
+/***********************************************************************/
+/* Store multiple at offset from SPB/LSP. Stack decreases an amount
+ * determined by the content of the DC regsiter.
+ */
+
+static void regm_StoreMultipleOffset(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwRSrc = MKREG(g_dwStackOffset - g_dwRegisterCount*sINT_SIZE);
+ uint32_t dwRDest;
+
+ TRACE(stderr, "[regm_StoreMultipleOffset]");
+
+ regm_GenerateForm3R(rADD, dwRDest, MKSPECIAL(pEntry->chSpecial),
+ GETARG(pOpCode));
+ regm_StoreMultiple(dwRSrc, dwRDest);
+}
+
+/***********************************************************************/
+/* Load value using index on stack + argument + SPB/LSP. Stack is unchanged */
+
+static void regm_LoadIndexed(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwRIndex = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwRDest = dwRIndex;
+
+ TRACE(stderr, "[regm_LoadIndexed]");
+
+ /* Add the SPB/LSP to the index to make it relative to the stack,
+ * then use this with the immediate values to obtain the data.
+ */
+
+ regm_GenerateForm3R(rADD, dwRIndex, dwRIndex,
+ MKSPECIAL(pEntry->chSpecial));
+ regm_GenerateForm3I(pEntry->chOpCode, dwRDest, dwRDest,
+ GETARG(pOpCode) >> pEntry->chImmediate);
+}
+
+/***********************************************************************/
+/* Load multiple values using index on stack + argument + SPB/LSP. Stack
+ * will increase my an amount that depends on the contents of DC.
+ */
+
+static void regm_LoadMultipleIndexed(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwRIndex = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwRSrc = dwRIndex;
+ uint32_t dwRDest = dwRIndex;
+
+ TRACE(stderr, "[regm_LoadMultipleIndexed]");
+
+ /* Add the SPB/LSP to the index to make it relative to the stack,
+ * add the offset, then generate the multple load.
+ */
+
+ regm_GenerateForm3R(rADD, dwRSrc, dwRIndex,
+ MKSPECIAL(pEntry->chSpecial));
+ regm_GenerateForm3I(rADDI, dwRSrc, dwRSrc, GETARG(pOpCode));
+ regm_LoadMultiple(dwRSrc, dwRDest);
+
+ /* Stack will be increased by an amount determined by DC in
+ * regm_LoadMultiple. However, we need to also account for the
+ * index stack value that we consume here.
+ */
+
+ g_dwStackOffset -= sINT_SIZE;
+}
+
+/***********************************************************************/
+/* Store value at TOS to index + offset + SPB/LSP. Stack decreases by two */
+
+static void regm_StoreIndexed(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwRSrc = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwRIndex = MKREG(g_dwStackOffset - 2*sINT_SIZE);
+
+ TRACE(stderr, "[regm_StoreIndexed]");
+
+ /* Add the LSP to the index to make it relative to the stack,
+ * then use this with the immediate values to obtain the data.
+ */
+
+ regm_GenerateForm3R(rADD, dwRIndex, dwRIndex,
+ MKSPECIAL(pEntry->chSpecial));
+ regm_GenerateForm3I(pEntry->chOpCode, dwRSrc, dwRIndex,
+ GETARG(pOpCode) >> pEntry->chImmediate);
+
+ /* Decrement the stack */
+
+ g_dwStackOffset -= 2*sINT_SIZE;
+}
+
+/***********************************************************************/
+/* Store values at TOS to index + offset + SPB/LSP. Stack decreases by
+ * amount determined by the content of the DC register.
+ */
+
+static void regm_StoreMultipleIndexed(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwRIndex = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwRSrc = MKREG(g_dwStackOffset - (g_dwRegisterCount + 1)*sINT_SIZE);
+ uint32_t dwRDest;
+
+ TRACE(stderr, "[regm_StoreMultipleIndexed]");
+
+ /* Adjust the src for the SPB/LSP value and generate the multiple load */
+
+ regm_GenerateForm3R(rADD, dwRDest, dwRIndex,
+ MKSPECIAL(pEntry->chSpecial));
+ regm_GenerateForm3I(rADDI, dwRDest, dwRDest, GETARG(pOpCode));
+ regm_StoreMultiple(dwRSrc, dwRDest);
+
+ /* Stack will be increased by an amount determined by DC in
+ * regm_StoreMultiple. However, we need to also account for the
+ * immediate stack value that we consume here.
+ */
+
+ g_dwStackOffset -= sINT_SIZE;
+}
+
+/***********************************************************************/
+/* These pcodes are all conditional branch operations. The pcode form
+ * takes one input (that is compared with zero) and branches based
+ * the result. The stack is decremented by one.
+ */
+
+static void regm_ConditionalBranchVsZero(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwUnaryRegister = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwCcRegister = MKCCREG(g_dwStackOffset);
+
+ TRACE(stderr, "[regm_ConditionalBranchVsZero]");
+
+
+ regm_GenerateForm1ICc(rCMPI, dwUnaryRegister, 0, dwCcRegister);
+ regm_GenerateForm4ICc(pEntry->chOpCode, GETARG(pOpCode), dwCcRegister);
+
+ /* Decrement the stack */
+
+ g_dwStackOffset -= sINT_SIZE;
+}
+
+/***********************************************************************/
+/* These pcodes are all conditional branch operations. The pcode form
+ * takes two inputs that are compared. The pcode branches on the result
+ * of the comparison. The stack is reduced by two.
+ */
+
+static void regm_ConditionalBranchBinary(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwROperand1 = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwROperand2 = MKREG(g_dwStackOffset - 2*sINT_SIZE);
+ uint32_t dwCcRegister = MKCCREG(g_dwStackOffset);
+
+ TRACE(stderr, "[regm_BinaryComparison]");
+
+ /* Generate the compare and branch */
+
+ regm_GenerateForm1RCc(rCMP, dwROperand1, dwROperand2, dwCcRegister);
+ regm_GenerateForm4ICc(pEntry->chOpCode, GETARG(pOpCode), dwCcRegister);
+
+ /* Reduce stack */
+
+ g_dwStackOffset -= 2*sINT_SIZE;
+}
+
+/***********************************************************************/
+/* Branch unconditionally. The stack is not changed */
+
+static void regm_UnconditionalBranch(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ TRACE(stderr, "[regm_UnconditionalBranch]");
+ regm_GenerateForm4I(rB, GETARG(pOpCode));
+}
+
+/***********************************************************************/
+/* Add constant value to special register. Stack does not change */
+
+static void regm_IncrementSpecial(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ int32_t dwIncrement = (int32_t)(GETOP(pOpCode));
+ uint32_t dwRSpecial = MKSPECIAL(pEntry->chSpecial);
+ TRACE(stderr, "[regm_IncrementSpecial]");
+
+ /* The value may be too large to represent with a MOVI, but we'll handle
+ * that later.
+ */
+
+ if (dwIncrement < 0)
+ {
+ regm_GenerateForm3I(rSUBI, dwRSpecial, dwRSpecial, -dwIncrement);
+ }
+ else if (dwIncrement > 0)
+ {
+ regm_GenerateForm3I(rADDI, dwRSpecial, dwRSpecial, dwIncrement);
+ }
+
+ if (pEntry->chSpecial == SP)
+ {
+ g_dwStackOffset += dwIncrement;
+ }
+}
+
+/***********************************************************************/
+/* Load address at offset from special register. Stack increases by one */
+
+static void regm_LoadAddress(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwRDest = g_dwStackOffset;
+
+ TRACE(stderr, "[regm_LoadAddress]");
+
+ /* Use the immediate value as an index against the SPB/LSP */
+
+ regm_GenerateForm3I(rADD, dwRDest, MKSPECIAL(pEntry->chSpecial),
+ GETARG(pOpCode));
+
+ /* Increment the stack */
+
+ g_dwStackOffset += sINT_SIZE;
+}
+
+/***********************************************************************/
+/* Load address at indexed offset from special register. Stack is unchanged */
+
+static void regm_LoadAddressIndexed(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ uint32_t dwRIndex = MKREG(g_dwStackOffset - 1*sINT_SIZE);
+ uint32_t dwRDest = dwRIndex;
+
+ TRACE(stderr, "[regm_LoadAddressIndexed]");
+
+ /* Add the LSP or SPB to the index to make it relative to the stack,
+ * then use this with the immediate values to obtain the data.
+ */
+
+ regm_GenerateForm3R(rADD, dwRIndex, dwRIndex,
+ MKSPECIAL(pEntry->chSpecial));
+ regm_GenerateForm3I(rADD, dwRDest, dwRIndex, GETARG(pOpCode));
+}
+
+/***********************************************************************/
+
+static void regm_SetupOutArgs(uint32_t nParms, const uint32_t *pwArgSize)
+{
+ int nArgRegs;
+ int32_t dwOffset;
+ int i;
+
+ for (i = 0, nArgRegs = 0; i < nParms; i++)
+ {
+ nArgRegs += (pwArgSize[i] + 3) >> 2;
+ }
+
+ /* Emit move instructions to handle each */
+
+ dwOffset = g_dwStackOffset - sINT_SIZE;
+ for (i = 0; i < nArgRegs; i++)
+ {
+ uint32_t dwDest = MKOUTARG(i);
+ uint32_t dwSrc = MKREG(dwOffset);
+
+ regm_GenerateForm2R(rMOV, dwDest, dwSrc);
+ dwOffset -= sINT_SIZE;
+ }
+}
+
+/***********************************************************************/
+
+static void regm_MapInRet(uint32_t wRetSize)
+{
+ int nRetRegs;
+ int32_t dwOffset;
+ int i;
+
+ /* Get the number of registers that are returned */
+
+ nRetRegs += (wRetSize + 3) >> 2;
+
+ /* Emit move instructions to handle each */
+#warning "This offset is not correct"
+ dwOffset = g_dwStackOffset - sINT_SIZE;
+ for (i = 0; i < nRetRegs; i++)
+ {
+ uint32_t dwSrc = MKINRET(i);
+ uint32_t dwDest = MKREG(dwOffset);
+
+ regm_GenerateForm2R(rMOV, dwDest, dwSrc);
+ dwOffset -= sINT_SIZE;
+ }
+}
+
+/***********************************************************************/
+
+static void regm_PCal(const struct regm_opmap_s *pEntry, OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ poffLibDebugFuncInfo_t *pFuncInfo = pNode->pFuncInfo;
+
+ TRACE(stderr, "[regm_PCal]");
+
+ if (!pFuncInfo)
+ {
+ fatal(ePOFFCONFUSION);
+ }
+
+ /* Map the "output" parameter stack to a set of "output" argument
+ * registers.
+ */
+
+ regm_SetupOutArgs(pFuncInfo->nparms, pFuncInfo->argsize);
+
+ regm_GenerateForm3I(rADDI, MKSPECIAL(SP), MKSPECIAL(SP), 3*sINT_SIZE);
+ regm_GenerateForm3I(rST, MKSPECIAL(LSP), MKSPECIAL(SP), -3);
+ regm_GenerateForm3I(rST, MKSPECIAL(BRG), MKSPECIAL(SP), -2);
+ regm_GenerateForm4I(rBL, GETARG(pOpCode));
+
+#warning "This is in the wrong place"
+ regm_MapInRet(pFuncInfo->retsize);
+
+ /* Increment the stack */
+
+ g_dwStackOffset += 3*sINT_SIZE;
+}
+
+/***********************************************************************/
+
+static void regm_SysIo(const struct regm_opmap_s *pEntry, OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ const struct regm_builtin_s *pBuiltIn;
+ uint32_t xop;
+
+ TRACE(stderr, "[regm_SysIo]");
+
+ /* Get the function information for this sysio xop */
+
+ xop = GETARG(pOpCode);
+ if (xop >= MAX_XOP)
+ {
+ fatal(ePOFFCONFUSION);
+ }
+
+ pBuiltIn = &g_rgSysIoBuiltIns[xop];
+
+ /* Map the "output" parameter stack to a set of "output" argument
+ * registers.
+ */
+
+ regm_SetupOutArgs(pBuiltIn->nParms, pBuiltIn->wArgSize);
+
+ /* Generate a call to the runtime library */
+
+#warning "Not implemented"
+
+ /* Handled returned values */
+
+ regm_MapInRet(pBuiltIn->wRetSize);
+}
+
+/***********************************************************************/
+
+static void regm_LibCall(const struct regm_opmap_s *pEntry, OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ const struct regm_builtin_s *pBuiltIn;
+ uint32_t lbop;
+
+ TRACE(stderr, "[regm_LibCall]");
+
+ /* Get the function information for this library op */
+
+ lbop = GETARG(pOpCode);
+ if (lbop >= MAX_LBOP)
+ {
+ fatal(ePOFFCONFUSION);
+ }
+
+ pBuiltIn = &g_rgLibCallBuiltIns[lbop];
+
+ /* Map the "output" parameter stack to a set of "output" argument
+ * registers.
+ */
+
+ regm_SetupOutArgs(pBuiltIn->nParms, pBuiltIn->wArgSize);
+
+ /* Generate a call to the runtime library */
+
+#warning "Not implemented"
+
+ /* Handled returned values */
+
+ regm_MapInRet(pBuiltIn->wRetSize);
+}
+
+/***********************************************************************/
+
+static void regm_Float(const struct regm_opmap_s *pEntry, OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ static const struct regm_builtin_s *pFopBuiltIns;
+ const struct regm_builtin_s *pBuiltIn;
+ uint32_t foptab;
+ uint32_t fop;
+
+ TRACE(stderr, "[regm_FLoat]");
+
+ /* Select the correct table for the builtin */
+
+ foptab = (GETARG(pOpCode) & ~fpMASK) >> fpSHIFT;
+ pFopBuiltIns = g_prgFopBuiltIns[foptab];
+
+ /* Select the correct function from the table for this floating
+ * point operation.
+ */
+
+ fop = GETARG(pOpCode) & fpMASK;
+ if (fop >= MAX_FOP)
+ {
+ fatal(ePOFFCONFUSION);
+ }
+ pBuiltIn = &pFopBuiltIns[fop];
+
+ /* Map the "output" parameter stack to a set of "output" argument
+ * registers.
+ */
+
+ regm_SetupOutArgs(pBuiltIn->nParms, pBuiltIn->wArgSize);
+
+ /* Generate a call to the runtime library */
+
+#warning "Not implemented"
+
+ /* Handled returned values */
+
+ regm_MapInRet(pBuiltIn->wRetSize);
+}
+
+/***********************************************************************/
+
+static void regm_IllegalPCode(const struct regm_opmap_s *pEntry,
+ OPTYPE *pOpCode,
+ struct procdata_s *pNode)
+{
+ TRACE(stderr, "[regm_IllegalPCode]");
+ fatal(eILLEGALOPCODE);
+}
+
+/***********************************************************************/
+
+static void regm_GenerateRegm(struct procdata_s *pNode, void *pvArg)
+{
+ int32_t dwFrameSize = 0;
+ int i, j;
+
+ TRACE(stderr, "[regm_GenerateRegm]");
+
+ /* Analyze the proc/func prologue */
+
+ i = 0; j = pNode->nPCodes;
+ if (GETOP(&pNode->pPCode[0]) == oINDS)
+ {
+ dwFrameSize = GETARG(&pNode->pPCode[0]);
+ i++; j--;
+ }
+ regm_GeneratePrologue(dwFrameSize);
+
+ /* Set the initial stack offset. Parameters will look like
+ * negative offsets; local stack will look positive.
+ */
+
+ g_dwStackOffset = dwFrameSize;
+
+ /* Generate regm code for each p-code */
+
+ for (; i < j; i++)
+ {
+ const struct regm_opmap_s *rgOpMap;
+ uint8_t chOpCode = GETOP(&pNode->pPCode[i]);
+
+ /* Select the right decode table */
+
+ if ((chOpCode & o32) != 0)
+ {
+ rgOpMap = vrgOpMap2;
+ chOpCode &= ~o32;
+ }
+ else
+ {
+ rgOpMap = vrgOpMap1;
+ }
+
+ /* Make sure that the table index is within range */
+
+ if (chOpCode > 63)
+ {
+ fatal(eBADSHORTINT);
+ }
+
+ /* Perform the opcode mapping */
+
+ rgOpMap->pMapper(rgOpMap, &pNode->pPCode[i], pNode);
+ }
+
+ /* If a frame was obtained at the beginning, make sure that
+ * there is matching frame release logic at the end.
+ */
+
+ if (dwFrameSize > 0)
+ {
+ if ((GETOP(&pNode->pPCode[i]) != oINDS) ||
+ (dwFrameSize != -(int32_t)GETARG(&pNode->pPCode[i])))
+ {
+ fatal(ePOFFCONFUSION);
+ }
+ i++;
+ }
+
+ /* Analyze the proc/func epilogue */
+
+ if ((GETOP(&pNode->pPCode[i]) != oRET) &&
+ (GETOP(&pNode->pPCode[i]) != oEND))
+ {
+ fatal(ePOFFCONFUSION);
+ }
+ regm_GenerateEpilogue(dwFrameSize);
+}
+
+/***********************************************************************/
+
+static int regm_Pass2Node(struct procdata_s *pNode, void *pvArg)
+{
+ TRACE(stderr, "[regm_Pass2Node]");
+
+ /* Generate code for each child of this proc/func block */
+
+ if (pNode->child)
+ {
+ (void)regm_ForEachChild(pNode->child, regm_Pass2Node, pvArg);
+ }
+
+ /* Generate code for this node */
+
+ regm_GenerateRegm(pNode, pvArg);
+
+ /* Does this node have a peer at the same level? If so, then
+ * do the same for its peer.
+ */
+
+ if (pNode->peer)
+ {
+ (void)regm_Pass2Node(pNode->peer, pvArg);
+ }
+
+ return 0;
+}
+
+/**********************************************************************
+ * Public Functions
+ **********************************************************************/
+
+/***********************************************************************/
+/* Pass 2: Convert the buffered pcode to the basic register model with
+ * an indefinite number of registers (arguments, general, and special
+ * registers) and with 32-bit immediate size.
+ */
+
+void regm_Pass2(poffHandle_t hPoff)
+{
+ TRACE(stderr, "[regm_Pass2]");
+
+ /* Initiate traversal at the root node */
+
+ (void)regm_Pass2Node(regm_GetRootNode(), NULL);
+}
+
+/***********************************************************************/
+
diff --git a/misc/pascal/insn32/regm/regm_pass2.h b/misc/pascal/insn32/regm/regm_pass2.h
new file mode 100644
index 000000000..22d958c27
--- /dev/null
+++ b/misc/pascal/insn32/regm/regm_pass2.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+ * regm_pass2.h
+ * External Declarations associated with regm_pass2.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __REGM_PASS2_H
+#define __REGM_PASS2_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+
+/***************************************************************************
+ * Definitions
+ ***************************************************************************/
+
+/***************************************************************************
+ * Public Types
+ ***************************************************************************/
+
+/***************************************************************************
+ * Public Variables
+ ***************************************************************************/
+
+extern uint32_t g_dwStackOffset;
+extern uint32_t g_dwRegisterCount;
+extern int g_bRegisterCountValid;
+
+/***************************************************************************
+ * Public Function Prototypes
+ ***************************************************************************/
+
+extern void regm_Pass2(poffHandle_t hPoff);
+
+#endif /* __REGM_PASS2_H */
diff --git a/misc/pascal/insn32/regm/regm_registers2.c b/misc/pascal/insn32/regm/regm_registers2.c
new file mode 100644
index 000000000..e4c4212b9
--- /dev/null
+++ b/misc/pascal/insn32/regm/regm_registers2.c
@@ -0,0 +1,542 @@
+/**********************************************************************
+ * regm_registers.c
+ * Pass 2 register management functions
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "keywords.h"
+#include "pofflib.h"
+#include "pedefs.h"
+#include "perr.h"
+
+#include "rinsn32.h"
+
+#include "regm.h"
+#include "regm_pass2.h"
+#include "regm_registers2.h"
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+#define INITIAL_RCODE2_ALLOC 150
+#define RCODE2_REALLOC 50
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Public Variables
+ **********************************************************************/
+
+struct regm_rcode2_s *g_pRCode2 = NULL;
+uint32_t g_nRCode2 = 0;
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static uint32_t g_nRCode2Alloc = 0;
+
+static const char * const g_prgReg2Names[NREGISTER_TYPES] =
+ { "Z", "X", "CC", "A", "R", "V", "V", "S" };
+
+static const char * const g_prgSpecialReg2Names[NSPECIAL_REGISTERS2] =
+ { "SPB", "SP", "BRG", "LSP", "CSB", "CSP", "PC", "DC", "LR", "CC"};
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+static void regm_CheckRCode2Alloc(void)
+{
+ /* If the RCode buffer has never been allocated, allocate it now. */
+
+ if (!g_pRCode2)
+ {
+ /* Allocate an inital buffer to hold the instructions */
+
+ g_pRCode2 = (struct regm_rcode2_s*)
+ malloc(INITIAL_RCODE2_ALLOC*sizeof(struct regm_rcode2_s));
+ if (!g_pRCode2)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ g_nRCode2Alloc = INITIAL_RCODE2_ALLOC;
+ }
+
+ /* The buffer has already been allocated, is there space for one
+ * more RCode?
+ */
+
+ else if (g_nRCode2 >= g_nRCode2Alloc)
+ {
+ /* If not, then reallocate the array */
+
+ g_pRCode2 = (struct regm_rcode2_s*)
+ realloc(g_pRCode2, g_nRCode2Alloc*sizeof(struct regm_rcode2_s));
+ if (!g_pRCode2)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ g_nRCode2Alloc += RCODE2_REALLOC;
+ }
+}
+
+/***********************************************************************/
+
+struct regm_rcode2_s *regm_AllocateRCode2(void)
+{
+ struct regm_rcode2_s *pRetSlot;
+
+ /* Make sure we have memory allocated in the array for another
+ * RCode.
+ */
+
+ regm_CheckRCode2Alloc();
+
+ /* Return the reference to the next RCode slot */
+
+ pRetSlot = &g_pRCode2[g_nRCode2];
+ g_nRCode2++;
+ return pRetSlot;
+}
+
+static void regm_PrintSpecialReg2(FILE *pStream, uint32_t dwRegister)
+{
+ int wRegNo = regm_GetRegNo(dwRegister);
+ if (wRegNo >= NSPECIAL_REGISTERS2)
+ fputc('?', pStream);
+ else
+ fputs(g_prgSpecialRegNames[wRegNo], pStream);
+}
+
+static void regm_PrintReg2(FILE *pStream, uint32_t dwRegister)
+{
+ int wKind = regm_GetKind(dwRegister);
+ int wRegNo = regm_GetRegNo(dwRegister)
+ if (wKind >= REGISTERS_TYPES)
+ fprintf(pStream, "?%d", wRegNo);
+ else if (wKind == SPECIAL_REG)
+ regm_PrintSpecialReg(fg, dwRegister);
+ else
+ fprintf(pStream, "%s%d", g_prgRegNames[wKind], wRegNo);
+}
+
+static void regm_PrintDebugReg(const char *string, uint32_t dwRegister)
+{
+ if (vRegmDebug)
+ {
+ fputs(string, DEBUG_FILE);
+ regm_PrintReg2(DEBUG_FILE, dwRegister);
+ fputc('\n', DEBUG_FILE);
+ }
+}
+
+/***********************************************************************/
+
+static void regm_MarkRegisterUsed(struct regm_rcode2_s *pReg,
+ uint32_t dwRegister)
+{
+ regm_PrintDebugReg("Register used: ", dwRegister);
+
+ switch (regm_GetKind(dwRegister))
+ {
+ case SPECIAL_REG : /* Special "global" registers */
+ break; /* (ignored) */
+
+ case CC_REG : /* Condition code register instance (fake) */
+ break;
+
+ case INARG_REG : /* Volatile register for input arguments */
+ /* and output values from/to callee */
+ break;
+
+ case OUTARG_REG : /* Volatile register for output arguments */
+ /* and input values to/from called */
+ /* function (fake) */
+ break;
+
+ case SCRATCH_REG : /* Volatile register for general usage */
+ break;
+
+ case VOLATILE_REG : /* Volatile registers in general */
+ case STATIC_REG : /* Static register */
+ default:
+ fatal(ePOFFCONFUSION);
+ break;
+ }
+#warning "Not Implemeted"
+}
+
+/***********************************************************************/
+
+static void regm_MarkRegisterModified(struct regm_rcode2_s *pReg,
+ uint32_t dwRegister)
+{
+ regm_PrintDebugReg("Register modified: ", dwRegister);
+
+ switch (regm_GetKind(dwRegister))
+ {
+ case SPECIAL_REG : /* Special "global" registers */
+ break; /* (ignored) */
+
+ case CC_REG : /* Condition code register instance (fake) */
+ break;
+
+ case INARG_REG : /* Volatile register for input arguments */
+ /* and output values from/to callee */
+ break;
+
+ case OUTARG_REG : /* Volatile register for output arguments */
+ /* and input values to/from called */
+ /* function (fake) */
+ break;
+
+ case SCRATCH_REG : /* Volatile register for general usage */
+ break;
+
+ case VOLATILE_REG : /* Volatile registers in general */
+ case STATIC_REG : /* Static register */
+ default:
+ fatal(ePOFFCONFUSION);
+ break;
+ }
+#warning "Not Implemeted"
+}
+
+/**********************************************************************
+ * Public Functions
+ **********************************************************************/
+
+/***********************************************************************/
+/* Generate function prologue: Save return address, create stack frame
+ * for local variables, and save static registers that till be used.
+ */
+
+void regm_GeneratePrologue(uint32_t dwFrameSize)
+{
+#warning "Not implemented"
+}
+
+/***********************************************************************/
+/* Restore static registers, release stack frame and return */
+
+void regm_GenerateEpilogue(uint32_t dwFrameSize)
+{
+#warning "Not implemented"
+}
+
+/***********************************************************************/
+/* Register-to-register comparisons (e.g., cmp r1, r2)
+ *
+ * FORM 1R: <op> <roperand1>, <roperand2>
+ */
+
+void regm_GenerateForm1RCc(uint8_t chOp, uint32_t dwROperand1,
+ uint32_t dwROperand2, uint32_t dwRCc)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_1RCc;
+ pReg->chOp = chOp;
+ pReg->u.f1rcc.dwROperand1 = dwROperand1;
+ pReg->u.f1rcc.dwROperand2 = dwROperand2;
+ pReg->u.f1rcc.dwRCc = dwRCc;
+
+ regm_MarkRegisterUsed(pReg, dwROperand1);
+ regm_MarkRegisterUsed(pReg, dwROperand2);
+ regm_MarkRegisterModified(pReg, dwRCc);
+}
+
+/***********************************************************************/
+/* Register-to-immediate comparisons (e.g., cmpi r1, 1)
+ *
+ * FORM 1I: <op> <roperand1>, <immediate>
+ */
+
+void regm_GenerateForm1ICc(uint8_t chOp, uint32_t dwROperand1,
+ uint32_t dwImmediate, uint32_t dwRCc)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_1ICc;
+ pReg->chOp = chOp;
+ pReg->u.f1icc.dwROperand1 = dwROperand1;
+ pReg->u.f1icc.dwImmediate = dwImmediate;
+ pReg->u.f1icc.dwRCc = dwRCc;
+
+ regm_MarkRegisterUsed(pReg, dwROperand1);
+ regm_MarkRegisterModified(pReg, dwRCc);
+}
+
+/***********************************************************************/
+/* Register-to-register mov instructions (e.g, mov r1, r2)
+ *
+ * FORM 2R: <op> <rdest>, <roperand2>
+ */
+
+void regm_GenerateForm2R(uint8_t chOp, uint32_t dwRDest,
+ uint32_t dwROperand2)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_2R;
+ pReg->chOp = chOp;
+ pReg->u.f2r.dwRDest = dwRDest;
+ pReg->u.f2r.dwROperand2 = dwROperand2;
+
+ regm_MarkRegisterModified(pReg, dwRDest);
+ regm_MarkRegisterUsed(pReg, dwROperand2);
+}
+
+/***********************************************************************/
+/* Immediate-to-register mov instructions (e.g, movi r1, 1)
+ *
+/* FORM 2I: <op> <rdest>, <immediate>
+*/
+
+void regm_GenerateForm2I(uint8_t chOp, uint32_t dwRDest,
+ uint32_t dwImmediate)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_2I;
+ pReg->chOp = chOp;
+ pReg->u.f2i.dwRDest = dwRDest;
+ pReg->u.f2i.dwImmediate = dwImmediate;
+
+ regm_MarkRegisterModified(pReg, dwRDest);
+}
+
+/***********************************************************************/
+/* Binary operations (e.g., add r0, r1, r2)
+ * Load operations (e.g., ld r0, [r1, r2])
+ * Store operations (e.g., st r0, [r1, r2])
+ *
+ * FORM 3R: <op> <rdest>, <roperand1>, <roperand2>
+ * <rsrc>, <roperand1>, <roperand2>
+ */
+
+void regm_GenerateForm3R(uint8_t chOp, uint32_t dwRSrcDest,
+ uint32_t dwROperand1, uint32_t dwROperand2)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_3R;
+ pReg->chOp = chOp;
+ pReg->u.f3r.dwRSrcDest = dwRSrcDest;
+ pReg->u.f3r.dwROperand1 = dwROperand1;
+ pReg->u.f3r.dwROperand2 = dwROperand2;
+
+ switch (chOp)
+ {
+ /* FORM 3: Arithmetic and logical operations */
+ /* FORM 3: Loads */
+
+ case rADD :
+ case rSUB :
+ case rRSB :
+ case rMUL :
+ case rDIV :
+ case rMOD :
+ case rSLL :
+ case rSRL :
+ case rSRA :
+ case rOR :
+ case rAND :
+ case rXOR :
+ case rANDN :
+ case rLD :
+ case rLDH :
+ case rLDB :
+ regm_MarkRegisterModified(pReg, dwRSrcDest);
+ break;
+
+ /* FORM 3: Loads multiple */
+ case rLDM :
+ {
+ uint32_t dwRDest = dwRSrcDest;
+ int i;
+ for (i = 0; i < g_dwRegisterCount; i++)
+ {
+ regm_MarkRegisterModified(pReg, dwRDest);
+ dwRDest++;
+ }
+ }
+ break;
+
+ /* FORM 3: Stores */
+ case rST :
+ case rSTH :
+ case rSTB :
+ regm_MarkRegisterUsed(pReg, dwRSrcDest);
+ break;
+
+ /* FORM 3: Store multipole */
+ case rSTM :
+ {
+ uint32_t dwRSrc = dwRSrcDest;
+ int i;
+ for (i = 0; i < g_dwRegisterCount; i++)
+ {
+ regm_MarkRegisterUsed(pReg, dwRSrc);
+ dwRSrc++;
+ }
+ }
+ break;
+
+ default:
+ fatal(ePOFFCONFUSION);
+ }
+
+ regm_MarkRegisterUsed(pReg, dwROperand1);
+ regm_MarkRegisterUsed(pReg, dwROperand2);
+}
+
+/***********************************************************************/
+/* Binary operations (e.g., addi r0, r1, 1)
+ * Load operations (e.g., ldi r0, [r1, 4])
+ * Store operations (e.g., sti r0, [r1, 4])
+ *
+ * FORM 3I: <op> <rdest>, <roperand1>, <immediate>
+ * <rsrc>, <roperand1>, <immediate>
+ */
+
+void regm_GenerateForm3I(uint8_t chOp, uint32_t dwRSrcDest,
+ uint32_t dwROperand1, uint32_t dwImmediate)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_3I;
+ pReg->chOp = chOp;
+ pReg->u.f3i.dwRSrcDest = dwRSrcDest;
+ pReg->u.f3i.dwROperand1 = dwROperand1;
+ pReg->u.f3i.dwImmediate = dwImmediate;
+
+ switch (chOp)
+ {
+ /* FORM 3: Arithmetic and logical operations */
+ /* FORM 3: Loads */
+
+ case rADDI :
+ case rSUBI :
+ case rRSBI :
+ case rMULI :
+ case rDIVI :
+ case rMODI :
+ case rSLLI :
+ case rSRLI :
+ case rSRAI :
+ case rORI :
+ case rANDI :
+ case rXORI :
+ case rANDNI :
+ case rLDI :
+ case rLDIH :
+ case rLDIB :
+ regm_MarkRegisterModified(pReg, dwRSrcDest);
+ break;
+
+ /* FORM 3: Stores */
+ case rSTI :
+ case rSTIH :
+ case rSTIB :
+ regm_MarkRegisterUsed(pReg, dwRSrcDest);
+ break;
+
+ default:
+ fatal(ePOFFCONFUSION);
+ }
+
+ regm_MarkRegisterUsed(pReg, dwROperand1);
+}
+
+/***********************************************************************/
+/* Unconditional branch operations (b offset, bl offset)
+ *
+ * FORM 4I: <op> <pc-offset>
+ */
+
+void regm_GenerateForm4I(uint8_t chOp, uint32_t dwOffset)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_4I;
+ pReg->chOp = chOp;
+ pReg->u.f4i.dwOffset = dwOffset;
+}
+
+/***********************************************************************/
+/* Conditional branch operations (e.g., beq offset)
+ *
+ * FORM 4I: <op> <pc-offset>
+ */
+
+void regm_GenerateForm4ICc(uint8_t chOp, uint32_t dwOffset,
+ uint32_t dwRCc)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_4ICc;
+ pReg->chOp = chOp;
+ pReg->u.f4icc.dwOffset = dwOffset;
+ pReg->u.f4icc.dwRCc = dwRCc;
+
+ regm_MarkRegisterUsed(pReg, dwRCc);
+}
+
+/***********************************************************************/
+
+int regm_ForEachRCode2(regm_rcode2_node_t pNode, void *arg)
+{
+ int ret;
+ int i;
+ for (i = 0; i < g_nRCode2; i++)
+ {
+ ret = pNode(&g_pRCode2[i], arg);
+ if (ret != 0)
+ {
+ return ret;
+ }
+ }
+ return 0;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/insn32/regm/regm_registers2.h b/misc/pascal/insn32/regm/regm_registers2.h
new file mode 100644
index 000000000..24209082f
--- /dev/null
+++ b/misc/pascal/insn32/regm/regm_registers2.h
@@ -0,0 +1,319 @@
+/***************************************************************************
+ * regm_registers2.h
+ * Definitions for management of registers
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __REGM_REGISTERS2_H
+#define __REGM_REGISTERS2_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+
+/***************************************************************************
+ * Definitions
+ ***************************************************************************/
+
+/* Register types */
+
+#define NULL_REG 0
+#define SPECIAL_REG 1 /* Special "global" registers */
+#define CC_REG 2 /* Condition code register instance (fake) */
+#define ARG_REG 3 /* Volatile register for input arguments */
+#define INARG_REG ARG_REG /* from callee */
+#define OUTARG_REG 4 /* Volatile register for output arguments */
+ /* to called function (fake) */
+#define RET_REG ARG_REG /* Volatile register for output values */
+#define OUTRET_REG ARG_REG /* to callee */
+#define INRET_REG OUTARG_REG /* Volatile register for input return */
+ /* from called functions (fake) */
+#define SCRATCH_REG 5 /* Volatile register for general usage */
+#define VOLATILE_REG 6 /* Volatile registers in general */
+#define STATIC_REG 7 /* Static register */
+
+#define NREGISTER_TYPES 8
+
+/* Special registers */
+
+#define SPB 0 /* 32-bit Pascal stack base address */
+#define SP 1 /* 32-bit Pascal stack pointer */
+#define BRG 2 /* 32-bit base register (related to parent level) */
+#define LSP 3 /* 32-bit Level stack pointer */
+#define CSB 4 /* 32-bit Character stack base address */
+#define CSP 5 /* 32-bit Character stack pointer */
+#define PC 6 /* 32-bit Program counter */
+
+#define NSPECIAL_REGISTERS 7
+
+#define DC 7 /* 32-bit Data count register -- disappears quickly */
+#define LR 8 /* 32-bit Link register -- same as SCRATCH(0) */
+#define CC 9 /* Condition code register -- not a normal register */
+
+#define NSPECIAL_REGISTERS2 10
+
+/* During pass2, we allow an indefinite number of registers. Eventually,
+ * these need to be compressed into a smaller number of registers. These
+ * define the number of registers available in the architecture.
+ */
+
+#define NTOTAL_REGISTERS 32
+#define NGENERAL_REGISTERS (NTOTAL_REGISTERS-NSPECIAL_REGISTERS)
+#define NARGUMENT_REGISTERS 4
+#define NSCRATCH_REGISTERS 4
+#define NVOLATILE_REGISTERS (NARGUMENT_REGISTERS+NSCRATCH_REGISTERS)
+#define NSTATIC_REGISTERS (NGENERAL_REGISTERS-NVOLATILE_REGISTERS)
+
+/* Register creation macros */
+
+#define MKSPECIAL(n) regm_MkRegister(SPECIAL_REG, (n))
+#define MKCC(n) regm_MkRegister(CC_REG, (n))
+#define MKINARG(n) regm_MkRegister(INARG_REG, (n))
+#define MKOUTARG(n) regm_MkRegister(OUTARG_REG, (n))
+#define MKINRET(n) regm_MkRegister(INRET_REG, (n))
+#define MKOUTRET(n) regm_MkRegister(OUTRET_REG, (n))
+#define MKSCRATCH(n) regm_MkRegister(SCRATCH_REG, (n))
+#define MKVOLATILE(n) regm_MkRegister(VOLATILE_REG, (n))
+
+/* Make a register from a stack offset */
+
+#define MKREG(n) MKSCRATCH((n) >> 2)
+#define MKCCREG(n) MKCC((n) >> 2)
+
+/* Check register type */
+
+#define ISSPECIAL(n) regm_IsKind(SPECIAL_REG, (n))
+#define ISCC(n) regm_IsKind(CC_REG, (n))
+#define ISARG(n) regm_IsKind(ARG_REG, (n))
+#define ISSCATCH(n) regm_IsKind(SCRATCH_REG, (n))
+#define ISVOLATILE(n) regm_IsKind(VOLATILE_REG, (n))
+
+/***************************************************************************
+ * Global Types
+ ***************************************************************************/
+
+struct regm32_t
+{
+ uint32_t kind : 3; /* Kind of register */
+ uint32_t regno : 29; /* Register identifier */
+};
+
+union regm32_u
+{
+ struct regm32_t f;
+ uint32_t dw;
+};
+
+enum regm_formtag_e
+{
+ eFORM_1RCc, /* <op> <roperand1>, <roperand2> */
+ eFORM_1ICc, /* <op> <roperand1>, <immediate> */
+ eFORM_2R, /* <op> <rdest>, <roperand2> */
+ eFORM_2I, /* <op> <rdest>, <immediate> */
+ eFORM_3R, /* <op> <rsrc/rdest>, <roperand1>, <roperand2> */
+ eFORM_3I, /* <op> <rsrc/rdest>, <roperand1>, <immediate> */
+ eFORM_4I, /* <op> <pc-offset> */
+ eFORM_4ICc, /* <op> <pc-offset> */
+};
+
+struct regm_form1rcc_s
+{
+ uint32_t dwROperand1, dwROperand2, dwRCc;
+};
+
+struct regm_form1icc_s
+{
+ uint32_t dwROperand1, dwImmediate, dwRCc;
+};
+
+struct regm_form2r_s
+{
+ uint32_t dwRDest, dwROperand2;
+};
+
+struct regm_form2i_s
+{
+ uint32_t dwRDest, dwImmediate;
+};
+
+struct regm_form3r_s
+{
+ uint32_t dwRSrcDest, dwROperand1, dwROperand2;
+};
+
+struct regm_form3i_s
+{
+ uint32_t dwRSrcDest, dwROperand1, dwImmediate;
+};
+
+struct regm_form4i_s
+{
+ uint32_t dwRDest, dwOffset;
+};
+
+struct regm_form4icc_s
+{
+ uint32_t dwRDest, dwOffset, dwRCc;
+};
+
+struct regm_rcode2_s
+{
+ uint8_t eForm; /* See enum regm_formtag_e */
+ uint8_t chOp; /* Regm opcode */
+ union
+ {
+ struct regm_form1rcc_s f1rcc;
+ struct regm_form1icc_s f1icc;
+ struct regm_form2r_s f2r;
+ struct regm_form2i_s f2i;
+ struct regm_form3r_s f3r;
+ struct regm_form3i_s f3i;
+ struct regm_form4i_s f4i;
+ struct regm_form4icc_s f4icc;
+ } u;
+};
+
+typedef int (*regm_rcode2_node_t)(struct regm_rcode2_s*, void*);
+
+/***************************************************************************
+ * Global Variables
+ ***************************************************************************/
+
+extern struct regm_rcode2_s *g_pRCode2;
+extern uint32_t g_nRCode2;
+
+/***************************************************************************
+ * Inline Functions
+ ***************************************************************************/
+
+static inline uint32_t regm_MkRegister(int wKind, int wRegNo)
+{
+ union regm32_u u;
+ u.f.kind = wKind;
+ u.f.regno = wRegNo;
+ return u.dw;
+}
+
+static inline int regm_IsKind(int wKind, uint32_t dwRegister)
+{
+ union regm32_u u;
+ u.dw = dwRegister;
+ return (u.f.kind == wKind);
+}
+
+static inline int regm_GetKind(uint32_t dwRegister)
+{
+ union regm32_u u;
+ u.dw = dwRegister;
+ return u.f.kind;
+}
+
+static inline void regm_SetKind(int wKind, uint32_t *pdwRegister)
+{
+ union regm32_u *pu = (union regm32_u *)pdwRegister;
+ pu->f.kind = wKind;
+}
+
+static inline int regm_GetRegNo(uint32_t dwRegister)
+{
+ union regm32_u u;
+ u.dw = dwRegister;
+ return u.f.regno;
+}
+
+static inline void regm_SetRegNo(int wRegNo, uint32_t *pdwRegister)
+{
+ union regm32_u *pu = (union regm32_u *)pdwRegister;
+ pu->f.regno = wRegNo;
+}
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************C***********************************************/
+
+/* Generate function prologue: Save return address, create stack frame
+ * for local variables, and save static registers that till be used.
+ */
+
+extern void regm_GeneratePrologue(uint32_t dwFrameSize);
+
+/* Restore static registers, release stack frame and return */
+
+extern void regm_GenerateEpilogue(uint32_t dwFrameSize);
+
+/* FORM 1R: <op> <roperand1>, <roperand2> */
+
+extern void regm_GenerateForm1RCc(uint8_t chOp, uint32_t dwROperand1,
+ uint32_t dwROperand2, uint32_t dwRCc);
+
+/* FORM 1I: <op> <roperand1>, <immediate> */
+
+extern void regm_GenerateForm1ICc(uint8_t chOp, uint32_t dwROperand1,
+ uint32_t dwImmediate, uint32_t dwRCc);
+
+/* FORM 2R: <op> <rdest>, <roperand2> */
+
+extern void regm_GenerateForm2R(uint8_t chOp, uint32_t dwRDest,
+ uint32_t dwROperand2);
+
+/* FORM 2I: <op> <rdest>, <immediate> */
+
+extern void regm_GenerateForm2I(uint8_t chOp, uint32_t dwRDest,
+ uint32_t dwImmediate);
+
+/* FORM 3R: <op> <rdest>, <roperand1>, <roperand2>
+ * <rsrc>, <roperand1>, <roperand2>
+ */
+
+extern void regm_GenerateForm3R(uint8_t chOp, uint32_t dwRSrcDest,
+ uint32_t dwROperand1, uint32_t dwROperand2);
+
+/* FORM 3I: <op> <rdest>, <roperand1>, <immediate>
+ * <rsrc>, <roperand1>, <immediate>
+ */
+
+extern void regm_GenerateForm3I(uint8_t chOp, uint32_t dwRSrcDest,
+ uint32_t dwROperand1, uint32_t dwImmediate);
+
+/* FORM 4I: <op> <pc-offset> */
+
+extern void regm_GenerateForm4I(uint8_t chOp, uint32_t dwOffset);
+
+extern void regm_GenerateForm4ICc(uint8_t chOp, uint32_t dwOffset,
+ uint32_t dwRCc);
+
+extern int regm_ForEachRCode2(regm_rcode2_node_t pNode, void *arg);
+
+#endif /* __REGM_REGISTERS2_H */
diff --git a/misc/pascal/insn32/regm/regm_tree.c b/misc/pascal/insn32/regm/regm_tree.c
new file mode 100644
index 000000000..9e2abdaff
--- /dev/null
+++ b/misc/pascal/insn32/regm/regm_tree.c
@@ -0,0 +1,338 @@
+/**********************************************************************
+ * regm_tree.c
+ * Tree managmenet
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "keywords.h"
+#include "pdefs.h" /* Types needed for unused protos in pinsn.h */
+#include "podefs.h" /* Types needed for unused protos in pinsh.h */
+#include "pedefs.h"
+#include "pofflib.h"
+#include "paslib.h"
+#include "pinsn.h" /* Folr insn_GetOpCode */
+#include "perr.h"
+
+#include "pinsn32.h"
+#include "regm.h"
+#include "regm_tree.h"
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+#define INITIAL_PCODE_ALLOC 250
+#define PCODE_RELLALLOC 100
+
+/**********************************************************************
+ * Private Types
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static struct procdata_s *g_pProgramHead = NULL;
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+static inline void regm_DumpIndent(uint32_t dwIndent)
+{
+ while (dwIndent--) putchar(' ');
+}
+
+/***********************************************************************/
+
+void regm_DumpNode(struct procdata_s *pNode, unsigned long dwIndent)
+{
+ if (pNode)
+ {
+ if (pNode->section[0].dwOffset != pNode->section[1].dwOffset)
+ {
+ regm_DumpIndent(dwIndent);
+ printf("%08lx:%08lx\n",
+ pNode->section[0].dwOffset,
+ pNode->section[0].dwOffset + pNode->section[0].dwSize - 1);
+ }
+ regm_DumpIndent(dwIndent);
+ printf("%08lx:%08lx\n",
+ pNode->section[1].dwOffset,
+ pNode->section[1].dwOffset + pNode->section[1].dwSize - 1);
+
+ regm_DumpNode(pNode->child, dwIndent + 3);
+ regm_DumpNode(pNode->peer, dwIndent);
+ }
+}
+
+/***********************************************************************/
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+void regm_InitTree(void)
+{
+ g_pProgramHead = NULL;
+}
+
+/***********************************************************************/
+
+struct procdata_s *regm_CreateProgSection(void)
+{
+ struct procdata_s *pNode;
+ pNode = (struct procdata_s *)malloc(sizeof(struct procdata_s));
+ if (!pNode)
+ {
+ fatal(eNOMEMORY);
+ }
+ memset(pNode, 0, sizeof(struct procdata_s));
+ return pNode;
+}
+
+/***********************************************************************/
+
+void regm_SetProgRoot(struct procdata_s *pNode)
+{
+ g_pProgramHead = pNode;
+ pNode->child = NULL;
+ pNode->peer = NULL;
+}
+
+/***********************************************************************/
+
+void regm_AddProgChild(struct procdata_s *pParent, struct procdata_s *pNode)
+{
+ struct procdata_s *pPrev = pParent;
+
+ /* Go to the end of the list */
+
+ while (pPrev->child != NULL) pPrev = pPrev->child;
+
+ /* Deposit the new node at the end of the list */
+
+ pPrev->child = pNode;
+ pNode->child = NULL;
+ pNode->peer = NULL;
+}
+
+/***********************************************************************/
+
+void regm_AddProgPeer(struct procdata_s *pPeer, struct procdata_s *pNode)
+{
+ struct procdata_s *pPrev = pPeer;
+
+ /* Go to the end of the list */
+
+ while (pPrev->peer != NULL) pPrev = pPrev->peer;
+
+ /* Deposit the new node at the end of the list */
+
+ pPrev->peer = pNode;
+ pNode->child = NULL;
+ pNode->peer = NULL;
+}
+
+/***********************************************************************/
+
+struct procdata_s *regm_GetRootNode(void)
+{
+ return g_pProgramHead;
+}
+
+/***********************************************************************/
+
+int regm_ForEachPeer(struct procdata_s *pPeer,
+ int (*pfPeerFunc)(struct procdata_s*, void*),
+ void *arg)
+{
+ struct procdata_s *pCurr = pPeer;
+ struct procdata_s *pNext;
+ int retval;
+
+ while (pCurr->peer)
+ {
+ pNext = pCurr->peer;
+ retval = pfPeerFunc(pCurr, arg);
+ if (retval)
+ {
+ return retval;
+ }
+ pCurr = pNext;
+ }
+ return 0;
+}
+
+/***********************************************************************/
+
+int regm_ForEachChild(struct procdata_s *pParent,
+ int (*pfChildFunc)(struct procdata_s*, void*),
+ void *arg)
+{
+ struct procdata_s *pCurr = pParent;
+ struct procdata_s *pNext;
+ int retval;
+
+ while (pCurr->child)
+ {
+ pNext = pCurr->child;
+ retval = pfChildFunc(pCurr, arg);
+ if (retval)
+ {
+ return retval;
+ }
+ pCurr = pNext;
+ }
+ return 0;
+}
+
+/***********************************************************************/
+
+uint32_t regm_ReadNodePCodes(struct procdata_s *pNode, poffHandle_t hPoff,
+ uint32_t dwStartOffset, uint32_t dwEndOffset,
+ uint8_t cTerminalOpcode)
+{
+ uint32_t dwOffset = dwStartOffset;
+ long nAlloc = INITIAL_PCODE_ALLOC;
+ long nPCodes;
+ uint8_t bTerminatorFound;
+
+ dbg("Reading Node: %08lx %08lx %02x\n",
+ dwStartOffset, dwEndOffset, cTerminalOpcode);
+
+ /* Allocate an inital buffer to hold the instructions */
+
+ pNode->pPCode = (OPTYPE*)
+ malloc(INITIAL_PCODE_ALLOC*sizeof(struct procinsn_s*));
+ if (!pNode->pPCode)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* Seek to the beginning of the data */
+
+ regm_ProgSeek(hPoff, dwStartOffset);
+
+ /* Read all of the instructions in the main program section */
+
+ nPCodes = 0;
+ bTerminatorFound = 0;
+ do
+ {
+ /* Make sure that there is space for another pcode */
+
+ if (nPCodes > nAlloc)
+ {
+ /* If not, then reallocate the array */
+
+ nAlloc += PCODE_RELLALLOC;
+ pNode->pPCode = (OPTYPE*)
+ realloc(pNode->pPCode, nAlloc*sizeof(OPTYPE));
+ }
+
+ /* Ready the pcode ito the array */
+
+ dwOffset += insn_GetOpCode(hPoff, &pNode->pPCode[nPCodes]);
+
+ /* Check for a terminating pcode */
+
+ if ((GETOP(&pNode->pPCode[nPCodes]) == cTerminalOpcode) ||
+ (GETOP(&pNode->pPCode[nPCodes]) == oEND))
+ {
+ bTerminatorFound++;
+ }
+
+ /* Increment the count of pcodes read */
+
+ nPCodes++;
+ }
+ while (!bTerminatorFound && (dwOffset < dwEndOffset));
+
+ dbg(" %08lx %08lx %02x\n",
+ dwStartOffset, dwOffset, GETOP(&pNode->pPCode[nPCodes-1]));
+
+ /* Save the number of pcodes that we found */
+
+ pNode->nPCodes = nPCodes;
+
+ /* Check for the correct terminator */
+
+ if (GETOP(&pNode->pPCode[nPCodes-1]) != cTerminalOpcode)
+ {
+ fatal(ePOFFCONFUSION);
+ }
+
+ /* Return any unused space in the allocation */
+
+ pNode->pPCode = (OPTYPE*)
+ realloc(pNode->pPCode, nPCodes*sizeof(OPTYPE));
+
+ /* Return the actual end offset */
+
+ return dwOffset;
+}
+
+/***********************************************************************/
+
+void regm_DumpTree(void)
+{
+ if (vRegmDebug)
+ {
+ regm_DumpNode(g_pProgramHead, 0);
+ }
+}
+
+/***********************************************************************/
+
diff --git a/misc/pascal/insn32/regm/regm_tree.h b/misc/pascal/insn32/regm/regm_tree.h
new file mode 100644
index 000000000..9d1bcc0f5
--- /dev/null
+++ b/misc/pascal/insn32/regm/regm_tree.h
@@ -0,0 +1,122 @@
+/***************************************************************************
+ * regm_tree.h
+ * External Declarations associated with regm_tree.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __REGM_TREE_H
+#define __REGM_TREE_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+#include "keywords.h"
+#include "pofflib.h"
+#include "rinsn32.h"
+
+/***************************************************************************
+ * Definitions
+ ***************************************************************************/
+
+/***************************************************************************
+ * Global Types
+ ***************************************************************************/
+
+/* This structure retains information about a specific function */
+
+struct procinsn_s
+{
+ RINSN32 sRegOp;
+ uint32_t dwRegModified;
+ uint32_t dwRegsUsed[2];
+};
+
+/* Each program section is described by an entry point offset, a
+ * file offset, a size in bytes, and a list of instructions (but
+ * we ignore the instructions at the trivial entry point which
+ * will be one or zero pcodes).
+ */
+
+struct procsection_s
+{
+ uint32_t dwOffset; /* File offset to section */
+ uint32_t dwSize; /* Size of section in bytes */
+};
+
+/* But each pascal procedure may contain two program sections:
+ * one before any nested functions/procedures. and one for the
+ * main body.
+ */
+
+struct procdata_s
+{
+ struct procdata_s *peer; /* Next proc/func at this level */
+ struct procdata_s *child; /* First nested proc/func */
+ struct procsection_s section[2];
+ poffLibDebugFuncInfo_t *pFuncInfo;
+ int nPCodes;
+ OPTYPE *pPCode;
+ struct procinsn_s *pRegOps;
+};
+
+/***************************************************************************
+ * Global Variables
+ ***************************************************************************/
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void regm_InitTree(void);
+extern struct procdata_s *regm_CreateProgSection(void);
+extern void regm_SetProgRoot(struct procdata_s *pNode);
+extern void regm_AddProgChild(struct procdata_s *pParent,
+ struct procdata_s *pNode);
+extern void regm_AddProgPeer(struct procdata_s *pPeer,
+ struct procdata_s *pNode);
+extern struct procdata_s *regm_GetRootNode(void);
+extern int regm_ForEachPeer(struct procdata_s *pPeer,
+ int (*pfPeerFunc)(struct procdata_s*, void*),
+ void *arg);
+extern int regm_ForEachChild(struct procdata_s *pParent,
+ int (*pfChildFunc)(struct procdata_s*, void*),
+ void *arg);
+extern uint32_t regm_ReadNodePCodes(struct procdata_s *pNode,
+ poffHandle_t hPoff,
+ uint32_t dwStartOffset, uint32_t dwEndOffset,
+ uint8_t cTerminalOpcode);
+extern void regm_DumpTree(void);
+
+#endif /* __REGM_TREE_H */
diff --git a/misc/pascal/libpas/Make.defs b/misc/pascal/libpas/Make.defs
new file mode 100644
index 000000000..2a0fbed8c
--- /dev/null
+++ b/misc/pascal/libpas/Make.defs
@@ -0,0 +1,38 @@
+############################################################################
+# libpoff/Make.defs
+# NuttX runtime makefile fragment
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+PAS_ASRCS =
+PAS_CSRCS = psignextend16.c pswap.c
diff --git a/misc/pascal/libpas/Makefile b/misc/pascal/libpas/Makefile
new file mode 100644
index 000000000..82ac36ab8
--- /dev/null
+++ b/misc/pascal/libpas/Makefile
@@ -0,0 +1,67 @@
+############################################################################
+# libpas/Makefile
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Directories
+#
+LIBPASDIR = ${shell pwd}
+PASCAL = $(LIBPASDIR)/..
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+INCDIR = $(PASCAL)/include
+LIBDIR = $(PASCAL)/lib
+
+#
+# Objects and targets
+#
+LIBPASSRCS = pextension.c psignextend16.c pswap.c
+LIBPASOBJS = $(LIBPASSRCS:.c=.o)
+
+OBJS = $(LIBPASOBJS)
+
+all: libpas.a
+.PHONY: all libpas.a clean
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+$(LIBDIR)/libpas.a: $(LIBPASOBJS)
+ $(AR) $(ARFLAGS) $@ $^
+
+libpas.a: $(LIBDIR)/libpas.a
+
+clean:
+ $(RM) libpas.a *.o core *~
diff --git a/misc/pascal/libpas/pextension.c b/misc/pascal/libpas/pextension.c
new file mode 100644
index 000000000..bdb2a9acc
--- /dev/null
+++ b/misc/pascal/libpas/pextension.c
@@ -0,0 +1,133 @@
+/**********************************************************************
+ * pextension.c
+ * Manage file extensions
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdbool.h>
+#include <string.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "paslib.h"
+
+/***********************************************************************/
+
+bool extension(const char *inName, const char *ext, char *outName,
+ bool force_default)
+{
+ int namelen = strlen(inName);
+ int extlen;
+ int copylen;
+ char *lastdot;
+
+ /* Find the position of the last occurrence of '.' in inName */
+
+ lastdot = strrchr(inName, '.');
+
+ /* If a file extension is in the input line and no default is forced, then
+ * copy the rest of the input line
+ */
+
+ if ((lastdot != NULL) && (!force_default))
+ {
+ /* Make sure that the string (with its null terminator) will fit in
+ * the allocated buffer.
+ */
+
+ if ((namelen + 1) > FNAME_SIZE)
+ {
+ /* It won't */
+
+ return true;
+ }
+ else
+ {
+ /* Copy the string. */
+
+ strcpy(outName, inName);
+ }
+ }
+ else
+ {
+ /* The name has no extension or we must replace the extension. */
+
+ extlen = strlen(ext) + 1; /* extension + null terminator */
+
+ if (lastdot != NULL)
+ {
+ /* It has an extension. We must copy everything except the
+ * last dot and the following extension.
+ */
+
+ copylen = namelen - strlen(lastdot); /* name - . - terminator */
+ }
+ else
+ {
+ /* It has no extension. We must copy everything */
+
+ copylen = namelen + 1; /* whole name with null termination */
+ }
+
+ /* Make sure that the string (with its null terminator) will fit in
+ * the allocated buffer.
+ */
+
+ if ((copylen + extlen + 1) > FNAME_SIZE)
+ {
+ /* It won't */
+
+ return true;
+ }
+ else
+ {
+ /* It will Copy file name up to, but excluding, the '.' */
+
+ memcpy(outName, inName, copylen);
+
+ /* Then copy the extension */
+
+ outName[copylen] = '.';
+ memcpy(&outName[copylen+1], ext, extlen);
+ }
+ }
+
+ return false;
+
+} /* end extension */
+
+/***********************************************************************/
diff --git a/misc/pascal/libpas/psignextend16.c b/misc/pascal/libpas/psignextend16.c
new file mode 100644
index 000000000..e05d20fc2
--- /dev/null
+++ b/misc/pascal/libpas/psignextend16.c
@@ -0,0 +1,58 @@
+/**********************************************************************
+ * psignextend16.c
+ * 16-bit sign extension
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <string.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "paslib.h"
+
+/***********************************************************************/
+/* This function converts a signed 16-bit value represented as a uint16_t
+ * to a int32_t.
+ */
+
+int32_t signExtend16(uint16_t arg16)
+{
+ int32_t arg32 = (int32_t)arg16 << 16;
+ return arg32 >> 16;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpas/pswap.c b/misc/pascal/libpas/pswap.c
new file mode 100644
index 000000000..035988ff9
--- /dev/null
+++ b/misc/pascal/libpas/pswap.c
@@ -0,0 +1,60 @@
+/**********************************************************************
+ * libpas/pswap.c
+ * Byte swapping to handling endian-ness conversions
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <string.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "paslib.h"
+
+/***********************************************************************/
+
+uint16_t poffSwap16(uint16_t val)
+{
+ return val >> 8 | val << 8;
+}
+
+uint32_t poffSwap32(uint32_t val)
+{
+ return val >> 24 | ((val >> 8) & 0x0000ff00) | ((val << 8) & 0x00ff0000) | val << 24;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/Make.defs b/misc/pascal/libpoff/Make.defs
new file mode 100644
index 000000000..41f0a63f0
--- /dev/null
+++ b/misc/pascal/libpoff/Make.defs
@@ -0,0 +1,48 @@
+############################################################################
+# libpoff/Make.defs
+# NuttX runtime makefile fragment
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+POFF_ASRCS =
+POFF_CSRCS = pfhandle.c pfproghandle.c pftprog.c \
+ pfsymhandle.c pftsymbol.c pofferr.c \
+ pfwhdr.c pfwrodata.c pfwsymbol.c pfwfname.c \
+ pfwprog.c pfwlineno.c pfwdbgfunc.c pfwreloc.c pfwstring.c \
+ pfwrite.c pfrhdr.c pfrsymbol.c pfrfname.c \
+ pfrprog.c pfrlineno.c pfrdbgfunc.c pfrrawlineno.c \
+ pfrrawreloc.c pfrstring.c pfread.c pfrseek.c \
+ pfrelease.c pfdbgcontainer.c pfdbgdiscard.c \
+ pfxprog.c pfxrodata.c pfiprog.c pfirodata.c \
+ pfdhdr.c pfdsymbol.c pfdreloc.c pflabel.c \
+ pfdbginfo.c pfswap.c
diff --git a/misc/pascal/libpoff/Makefile b/misc/pascal/libpoff/Makefile
new file mode 100644
index 000000000..ebbf1e2ac
--- /dev/null
+++ b/misc/pascal/libpoff/Makefile
@@ -0,0 +1,47 @@
+# ----------------------------------------------------------------------
+# libpoff/Makefile
+# ----------------------------------------------------------------------
+
+# ----------------------------------------------------------------------
+# Directories
+
+PASCAL = ${shell pwd}/..
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+INCDIR = $(PASCAL)/include
+LIBDIR = $(PASCAL)/lib
+
+# ----------------------------------------------------------------------
+# Objects and targets
+
+LIBPOFFSRCS = pfhandle.c pfproghandle.c pftprog.c \
+ pfsymhandle.c pftsymbol.c pofferr.c \
+ pfwhdr.c pfwrodata.c pfwsymbol.c pfwfname.c \
+ pfwprog.c pfwlineno.c pfwdbgfunc.c pfwreloc.c pfwstring.c \
+ pfwrite.c pfrhdr.c pfrsymbol.c pfrfname.c \
+ pfrprog.c pfrlineno.c pfrdbgfunc.c pfrrawlineno.c \
+ pfrrawreloc.c pfrstring.c pfread.c pfrseek.c \
+ pfrelease.c pfdbgcontainer.c pfdbgdiscard.c \
+ pfxprog.c pfxrodata.c pfiprog.c pfirodata.c \
+ pfdhdr.c pfdsymbol.c pfdreloc.c pflabel.c \
+ pflineno.c pfdbginfo.c pfswap.c
+LIBPOFFOBJS = $(LIBPOFFSRCS:.c=.o)
+
+all: libpoff.a
+.PHONY: all libpoff.a clean
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+$(LIBDIR)/libpoff.a: $(LIBPOFFOBJS)
+ $(RM) $@
+ $(AR) $(ARFLAGS) $@ $^
+
+libpoff.a: $(LIBDIR)/libpoff.a
+
+clean:
+ $(RM) libpoff.a *.o core *~
+
+# ----------------------------------------------------------------------
diff --git a/misc/pascal/libpoff/pfdbgcontainer.c b/misc/pascal/libpoff/pfdbgcontainer.c
new file mode 100644
index 000000000..8387fa15b
--- /dev/null
+++ b/misc/pascal/libpoff/pfdbgcontainer.c
@@ -0,0 +1,106 @@
+/**********************************************************************
+ * pfrdbgcontainer.c
+ * Create/destroy debug info container.
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+poffLibDebugFuncInfo_t *poffCreateDebugInfoContainer(uint32_t nparms)
+{
+ poffLibDebugFuncInfo_t *pDebugFuncInfo;
+ int wAllocSize = SIZEOFDEBUFINFO(nparms);
+
+ pDebugFuncInfo = (poffLibDebugFuncInfo_t*)malloc(wAllocSize);
+ if (!pDebugFuncInfo)
+ {
+ fatal(eNOMEMORY);
+ return NULL;
+ }
+
+ memset(pDebugFuncInfo, 0, wAllocSize);
+ return pDebugFuncInfo;
+}
+
+/***********************************************************************/
+
+void poffReleaseDebugFuncContainer(poffLibDebugFuncInfo_t *pDebugFuncInfo)
+{
+ if (pDebugFuncInfo)
+ {
+ free(pDebugFuncInfo);
+ }
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfdbgdiscard.c b/misc/pascal/libpoff/pfdbgdiscard.c
new file mode 100644
index 000000000..2574644db
--- /dev/null
+++ b/misc/pascal/libpoff/pfdbgdiscard.c
@@ -0,0 +1,94 @@
+/**********************************************************************
+ * pfdbgdiscard.c
+ * Discard debug function information
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "keywords.h" /* Standard types */
+
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+void poffDiscardDebugFuncInfo(poffHandle_t handle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+
+ /* Deallocate any buffered data */
+
+ if (poffInfo->debugFuncTable)
+ {
+ free(poffInfo->debugFuncTable);
+ }
+
+ /* And erase any knowledge of the debug info */
+
+ poffInfo->debugFuncSection.sh_size = 0;
+ poffInfo->debugFuncTable = NULL;
+ poffInfo->debugFuncTableAlloc = 0;
+ poffInfo->debugFuncIndex = 0;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfdbginfo.c b/misc/pascal/libpoff/pfdbginfo.c
new file mode 100644
index 000000000..1a743f091
--- /dev/null
+++ b/misc/pascal/libpoff/pfdbginfo.c
@@ -0,0 +1,158 @@
+/**********************************************************************
+ * pdbginfo.c
+ * Manage debug information
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static poffLibDebugFuncInfo_t *g_pDebugInfoHead = NULL;
+static poffLibDebugFuncInfo_t *g_pDebugInfoTail = NULL;
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+void poffReadDebugFuncInfoTable(poffHandle_t handle)
+{
+ poffLibDebugFuncInfo_t *pDebugInfo;
+
+ /* Read all function debug information into a link list */
+
+ while ((pDebugInfo = poffGetDebugFuncInfo(handle)) != NULL)
+ {
+ if (!g_pDebugInfoHead)
+ {
+ g_pDebugInfoHead = pDebugInfo;
+ }
+ else
+ {
+ g_pDebugInfoTail->next = pDebugInfo;
+ }
+ g_pDebugInfoTail = pDebugInfo;
+ }
+}
+
+/***********************************************************************/
+
+poffLibDebugFuncInfo_t *poffFindDebugFuncInfo(uint32_t offset)
+{
+ poffLibDebugFuncInfo_t *pDebugInfo;
+
+ /* Search the list for an entry with PC==offset */
+
+ for (pDebugInfo = g_pDebugInfoHead; pDebugInfo;
+ pDebugInfo = pDebugInfo->next)
+ {
+ if (pDebugInfo->value == offset)
+ {
+ return pDebugInfo;
+ }
+ }
+ return NULL;
+}
+
+/***********************************************************************/
+
+void poffReplaceDebugFuncInfo(poffHandle_t handle)
+{
+ poffLibDebugFuncInfo_t *pDebugInfo;
+
+ /* Discard any existing debug info in the POFF object */
+
+ poffDiscardDebugFuncInfo(handle);
+
+ /* Then add all of the buffered debug info into the object */
+
+ for (pDebugInfo = g_pDebugInfoHead; pDebugInfo;
+ pDebugInfo = pDebugInfo->next)
+ {
+ (void)poffAddDebugFuncInfo(handle, pDebugInfo);
+
+ }
+}
+
+/***********************************************************************/
+
+void poffReleaseDebugFuncInfoTable(void)
+{
+ poffLibDebugFuncInfo_t *pDebugInfo;
+ poffLibDebugFuncInfo_t *pNextDebugInfo;
+
+ /* Release the bufferred debug information */
+
+ pDebugInfo = g_pDebugInfoHead;
+ while (pDebugInfo)
+ {
+ pNextDebugInfo = pDebugInfo->next;
+ poffReleaseDebugFuncContainer(pDebugInfo);
+ pDebugInfo = pNextDebugInfo;
+ }
+
+ g_pDebugInfoHead = NULL;
+ g_pDebugInfoTail = NULL;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfdhdr.c b/misc/pascal/libpoff/pfdhdr.c
new file mode 100644
index 000000000..5ac627e10
--- /dev/null
+++ b/misc/pascal/libpoff/pfdhdr.c
@@ -0,0 +1,182 @@
+/**********************************************************************
+ * pfdhdr.c
+ * Dump the contents of POFF file and section headers
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "keywords.h" /* Standard types */
+#include "pfprivate.h" /* POFF private definitions */
+#include "pofflib.h" /* Public interfaces */
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Constant Data
+ **********************************************************************/
+
+static const char *poffFhTypes[FHT_NTYPES] =
+{
+ "NONE ", /* Shouldn't happen */
+ "EXEC ", /* Pascal program executable */
+ "SHLIB ", /* Pascal shared library */
+ "PROGRAM ", /* Pascal program object */
+ "UNIT " /* Pascal unit object */
+};
+
+static const char *poffShTypes[SHT_NTYPES] =
+{
+ "NULL ", /* Shouldn't happen */
+ "PROGDATA", /* Program data */
+ "SYMTAB ", /* Symbol table */
+ "STRTAB ", /* String table */
+ "REL ", /* Relocation data */
+ "FILETAB ", /* File table */
+ "LINENO ", /* Line number data */
+ "DEBUG " /* Func/Proc debug data */
+};
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+static void poffDumpSectionHeader(poffHandle_t handle,
+ poffSectionHeader_t *shdr,
+ FILE *outFile)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+
+ fprintf(outFile, "%-10s %8s 0x%02x 0x%04x 0x%08lx 0x%08lx %ld\n",
+ poffGetString(poffInfo, shdr->sh_name),
+ poffShTypes[shdr->sh_type], shdr->sh_flags,
+ shdr->sh_entsize, shdr->sh_addr, shdr->sh_offset,
+ shdr->sh_size);
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+void poffDumpFileHeader(poffHandle_t handle, FILE *outFile)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+
+ fprintf(outFile, "\nPOFF File Header:\n");
+ fprintf(outFile, " fh_ident: %c%c%c%c\n",
+ poffInfo->fileHeader.fh_ident[0], poffInfo->fileHeader.fh_ident[1],
+ poffInfo->fileHeader.fh_ident[2], poffInfo->fileHeader.fh_ident[3]);
+ fprintf(outFile, " fh_version: %d\n", poffInfo->fileHeader.fh_version);
+ fprintf(outFile, " fh_type: %s\n",
+ poffFhTypes[poffInfo->fileHeader.fh_type]);
+ fprintf(outFile, " fh_shsize: %d\n", poffInfo->fileHeader.fh_shsize);
+ fprintf(outFile, " fh_shnum: %d\n", poffInfo->fileHeader.fh_shnum);
+ fprintf(outFile, " fh_name: %s\n",
+ poffGetString(poffInfo, poffInfo->fileHeader.fh_name));
+ fprintf(outFile, " fh_entry: 0x%08lx\n", poffInfo->fileHeader.fh_entry);
+ fprintf(outFile, " fh_shoff: 0x%08lx\n", poffInfo->fileHeader.fh_shoff);
+}
+
+/***********************************************************************/
+
+void poffDumpSectionHeaders(poffHandle_t handle, FILE *outFile)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+
+ fprintf(outFile, "\nPOFF Section Headers:\n");
+ fprintf(outFile, "NAME TYPE FLAG ENTSZE ADDRESS OFFSET SIZE\n");
+
+ if (poffInfo->progSection.sh_size > 0)
+ {
+ poffDumpSectionHeader(handle, &poffInfo->progSection, outFile);
+ }
+
+ if (poffInfo->roDataSection.sh_size > 0)
+ {
+ poffDumpSectionHeader(handle, &poffInfo->roDataSection, outFile);
+ }
+
+ if (poffInfo->symbolTableSection.sh_size > 0)
+ {
+ poffDumpSectionHeader(handle, &poffInfo->symbolTableSection, outFile);
+ }
+
+ if (poffInfo->stringTableSection.sh_size > 0)
+ {
+ poffDumpSectionHeader(handle, &poffInfo->stringTableSection, outFile);
+ }
+
+ if (poffInfo->relocSection.sh_size > 0)
+ {
+ poffDumpSectionHeader(handle, &poffInfo->relocSection, outFile);
+ }
+
+ if (poffInfo->fileNameTableSection.sh_size > 0)
+ {
+ poffDumpSectionHeader(handle, &poffInfo->fileNameTableSection, outFile);
+ }
+
+ if (poffInfo->lineNumberSection.sh_size > 0)
+ {
+ poffDumpSectionHeader(handle, &poffInfo->lineNumberSection, outFile);
+ }
+
+ if (poffInfo->debugFuncSection.sh_size > 0)
+ {
+ poffDumpSectionHeader(handle, &poffInfo->debugFuncSection, outFile);
+ }
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfdreloc.c b/misc/pascal/libpoff/pfdreloc.c
new file mode 100644
index 000000000..06726e1a1
--- /dev/null
+++ b/misc/pascal/libpoff/pfdreloc.c
@@ -0,0 +1,108 @@
+/**********************************************************************
+ * pfdreloc.c
+ * Dump contents of a POFF file reloc table
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "keywords.h" /* Standard types */
+#include "pfprivate.h" /* POFF private definitions */
+#include "pofflib.h" /* Public interfaces */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Constant Data
+ **********************************************************************/
+
+static const char *poffRelocationTypes[RLT_NTYPES] =
+{
+ "NULL", /* Shouldn't happen */
+ "PCAL", /* Procedure/Function call */
+ "LDST", /* Load from stack base */
+};
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+void poffDumpRelocTable(poffHandle_t handle, FILE *outFile)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ poffRelocation_t *prel;
+ uint32_t index;
+
+ fprintf(outFile, "\nPOFF Relocation Table:\n");
+ fprintf(outFile, "RELO SYMBOL SECTION\n");
+ fprintf(outFile, "TYPE TBL INDEX DATA OFFSET\n");
+
+ for (index = 0;
+ index < poffInfo->relocSection.sh_size;
+ index += poffInfo->relocSection.sh_entsize)
+ {
+ prel = (poffRelocation_t*)&poffInfo->relocTable[index];
+
+ fprintf(outFile, "%-6s 0x%08lx 0x%08lx\n",
+ poffRelocationTypes[RLI_TYPE(prel->rl_info)],
+ RLI_SYM(prel->rl_info),
+ prel->rl_offset);
+ }
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfdsymbol.c b/misc/pascal/libpoff/pfdsymbol.c
new file mode 100644
index 000000000..c65fa7267
--- /dev/null
+++ b/misc/pascal/libpoff/pfdsymbol.c
@@ -0,0 +1,117 @@
+/**********************************************************************
+ * pfdsymbol.c
+ * Dump contents of a POFF file symbol table
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "keywords.h" /* Standard types */
+#include "pfprivate.h" /* POFF private definitions */
+#include "pofflib.h" /* Public interfaces */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Constant Data
+ **********************************************************************/
+
+static const char *poffSymTypes[STT_NTYPES] =
+{
+ "NULL ", /* Shouldn't happen */
+ "DATA ", /* Stack data */
+ "RODATA", /* Read-only data */
+ "PROC ", /* Symbol table */
+ "FUNC " /* String table */
+};
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+void poffDumpSymbolTable(poffHandle_t handle, FILE *outFile)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ poffSymbol_t *psym;
+ uint32_t index;
+
+ fprintf(outFile, "\nPOFF Symbol Table:\n");
+ fprintf(outFile, "NAME "
+ "TYPE "
+ "FLAG "
+ "ALGN "
+ "VALUE "
+ "SIZE\n");
+
+ for (index = 0;
+ index < poffInfo->symbolTableSection.sh_size;
+ index += poffInfo->symbolTableSection.sh_entsize)
+ {
+ psym = (poffSymbol_t*)&poffInfo->symbolTable[index];
+
+ fprintf(outFile, "%-20s %6s 0x%02x 0x%02x 0x%08lx 0x%08lx\n",
+ poffGetString(poffInfo, psym->st_name),
+ poffSymTypes[psym->st_type],
+ psym->st_flags,
+ psym->st_align,
+ psym->st_value,
+ psym->st_size);
+ }
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfhandle.c b/misc/pascal/libpoff/pfhandle.c
new file mode 100644
index 000000000..96d072322
--- /dev/null
+++ b/misc/pascal/libpoff/pfhandle.c
@@ -0,0 +1,195 @@
+/**********************************************************************
+ * pfhandle.c
+ * POFF library global variables
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "keywords.h" /* Standard types */
+#include "pfprivate.h" /* POFF private definitions */
+#include "pofflib.h" /* Public interfaces */
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Set all global data structures to a known state */
+
+poffHandle_t poffCreateHandle(void)
+{
+ poffInfo_t *poffInfo;
+
+ /* Create a new POFF handle */
+
+ poffInfo = (poffInfo_t*)malloc(sizeof(poffInfo_t));
+ if (poffInfo != NULL)
+ {
+ /* Set everthing to zero */
+
+ memset(poffInfo, 0, sizeof(poffInfo_t));
+
+ /* Initialize POFF file header */
+
+ poffInfo->fileHeader.fh_ident[FHI_MAG0] = FHI_POFF_MAG0;
+ poffInfo->fileHeader.fh_ident[FHI_MAG1] = FHI_POFF_MAG1;
+ poffInfo->fileHeader.fh_ident[FHI_MAG2] = FHI_POFF_MAG2;
+ poffInfo->fileHeader.fh_ident[FHI_MAG3] = FHI_POFF_MAG3;
+ poffInfo->fileHeader.fh_version = FHV_CURRENT;
+ poffInfo->fileHeader.fh_shsize = sizeof(poffSectionHeader_t);
+ poffInfo->fileHeader.fh_shoff = sizeof(poffFileHeader_t);
+
+ /* Initialize the program section header */
+
+ poffInfo->progSection.sh_type = SHT_PROGDATA;
+ poffInfo->progSection.sh_flags = SHF_ALLOC | SHF_EXEC;
+
+ /* Initialize the initialized data section header */
+
+ poffInfo->roDataSection.sh_type = SHT_PROGDATA;
+ poffInfo->roDataSection.sh_flags = SHF_WRITE | SHF_ALLOC;
+
+ /* Initialize the symbol table section header */
+
+ poffInfo->symbolTableSection.sh_type = SHT_SYMTAB;
+ poffInfo->symbolTableSection.sh_entsize = sizeof(poffSymbol_t);
+
+ /* Initialize the string table section header */
+
+ poffInfo->stringTableSection.sh_type = SHT_STRTAB;
+
+ /* Initialize the relocation table section header */
+
+ poffInfo->relocSection.sh_type = SHT_REL;
+ poffInfo->relocSection.sh_entsize = sizeof(poffRelocation_t);
+
+ /* Initialize the file table section header */
+
+ poffInfo->fileNameTableSection.sh_type = SHT_FILETAB;
+ poffInfo->fileNameTableSection.sh_entsize = sizeof(poffFileTab_t);
+
+ /* Initialize the line number section header */
+
+ poffInfo->lineNumberSection.sh_type = SHT_LINENO;
+ poffInfo->lineNumberSection.sh_entsize = sizeof(poffLineNumber_t);
+
+ /* Initialize the debug function info section header */
+
+ poffInfo->debugFuncSection.sh_type = SHT_DEBUG;
+ poffInfo->debugFuncSection.sh_entsize = sizeof(poffDebugFuncInfo_t);
+ }
+ return poffInfo;
+}
+
+/***********************************************************************/
+
+void poffDestroyHandle(poffHandle_t handle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+
+ /* Free all of the allocated, in-memory data */
+
+ if (poffInfo->progSectionData)
+ free(poffInfo->progSectionData);
+
+ if (poffInfo->roDataSectionData)
+ free(poffInfo->roDataSectionData);
+
+ if (poffInfo->symbolTable)
+ free(poffInfo->symbolTable);
+
+ if (poffInfo->stringTable)
+ free(poffInfo->stringTable);
+
+ if (poffInfo->relocTable)
+ free(poffInfo->relocTable);
+
+ if (poffInfo->fileNameTable)
+ free(poffInfo->fileNameTable);
+
+ if (poffInfo->lineNumberTable)
+ free(poffInfo->lineNumberTable);
+
+ if (poffInfo->debugFuncTable)
+ free(poffInfo->debugFuncTable);
+
+ /* Free the container */
+
+ free(handle);
+}
+
+/***********************************************************************/
+
+void poffResetAccess(poffHandle_t handle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+
+ /* Reset read/write indices */
+
+ poffInfo->symbolIndex = 0;
+ poffInfo->progSectionIndex = 0;
+ poffInfo->relocIndex = 0;
+ poffInfo->fileNameIndex = 0;
+ poffInfo->lineNumberIndex = 0;
+ poffInfo->debugFuncIndex = 0;
+}
+
+/***********************************************************************/
+
diff --git a/misc/pascal/libpoff/pfiprog.c b/misc/pascal/libpoff/pfiprog.c
new file mode 100644
index 000000000..c2c241f58
--- /dev/null
+++ b/misc/pascal/libpoff/pfiprog.c
@@ -0,0 +1,93 @@
+/**********************************************************************
+ * pfiprog.c
+ * Insert program data int a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+void poffInsertProgramData(poffHandle_t handle,
+ uint8_t *progData, uint32_t progSize)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+
+ /* If there is already program data in the container, discard it. */
+
+ if (poffInfo->progSectionData) free(poffInfo->progSectionData);
+
+ /* Then, insert the new program data */
+
+ poffInfo->progSection.sh_size = progSize;
+ poffInfo->progSectionData = progData;
+ poffInfo->progSectionAlloc = progSize;
+ poffInfo->progSectionIndex = 0;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfirodata.c b/misc/pascal/libpoff/pfirodata.c
new file mode 100644
index 000000000..61600a6ce
--- /dev/null
+++ b/misc/pascal/libpoff/pfirodata.c
@@ -0,0 +1,103 @@
+/**********************************************************************
+ * pfirodata.c
+ * Append program read-only data to a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+void poffAppendRoData(poffHandle_t handle,
+ uint8_t *roData, uint32_t roDataSize)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ uint8_t *tmp;
+ uint32_t newSize;
+
+ if ((roData) && (roDataSize))
+ {
+ /* Reallocate the read-only data */
+
+ newSize = poffInfo->roDataSection.sh_size + roDataSize;
+ tmp = (uint8_t*)realloc(poffInfo->roDataSectionData, newSize);
+ if (!tmp) fatal(eNOMEMORY);
+
+ /* Add the new data to the new allocation */
+
+ memcpy(&tmp[poffInfo->roDataSection.sh_size], roData, roDataSize);
+
+ /* Add the new allocation to the read-only section */
+
+ poffInfo->roDataSection.sh_size = newSize;
+ poffInfo->roDataSectionData = tmp;
+ poffInfo->roDataSectionAlloc = newSize;
+ }
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pflabel.c b/misc/pascal/libpoff/pflabel.c
new file mode 100644
index 000000000..973366466
--- /dev/null
+++ b/misc/pascal/libpoff/pflabel.c
@@ -0,0 +1,285 @@
+/**********************************************************************
+ * pflabel.c
+ * Label resolution logic
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pedefs.h"
+#include "perr.h"
+#include "poff.h"
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+#define INITIAL_DEFINED_ALLOCATION (1024*sizeof(optDefinedLabelRef_t))
+#define DEFINED_INCREMENT (256*sizeof(optDefinedLabelRef_t))
+
+#define INITIAL_UNDEFINED_ALLOCATION (1024*sizeof(optUndefinedLabelRef_t))
+#define UNDEFINED_INCREMENT (256*sizeof(optUndefinedLabelRef_t))
+
+/**********************************************************************
+ * Private Types
+ **********************************************************************/
+
+struct optDefinedLabelRef_s
+{
+ uint32_t label;
+ uint32_t pc;
+};
+typedef struct optDefinedLabelRef_s optDefinedLabelRef_t;
+
+struct optUndefinedLabelRef_s
+{
+ uint32_t label;
+ uint32_t symIndex;
+};
+typedef struct optUndefinedLabelRef_s optUndefinedLabelRef_t;
+
+/**********************************************************************
+ * Private Data
+ **********************************************************************/
+
+static optDefinedLabelRef_t *definedLabelRefs = NULL;
+static uint32_t definedLabelRefAlloc = 0;
+static uint32_t nDefinedLabelRefs = 0;
+
+static optUndefinedLabelRef_t *undefinedLabelRefs = NULL;
+static uint32_t undefinedLabelRefAlloc = 0;
+static uint32_t nUndefinedLabelRefs = 0;
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Inline Functions
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/**********************************************************************/
+
+static void poffCheckDefinedLabelAlloc(void)
+{
+ /* Has the label reference table been allocated */
+
+ if (!definedLabelRefs)
+ {
+ /* No, allocate it now */
+
+ definedLabelRefs = (optDefinedLabelRef_t*)
+ malloc(INITIAL_DEFINED_ALLOCATION);
+
+ if (!definedLabelRefs)
+ {
+ fatal(eNOMEMORY);
+ }
+ definedLabelRefAlloc = INITIAL_DEFINED_ALLOCATION;
+ }
+}
+
+/**********************************************************************/
+
+static void poffCheckDefinedLabelRealloc(void)
+{
+ /* Check if there is room for the new data */
+
+ if (((nDefinedLabelRefs + 1)*sizeof(optDefinedLabelRef_t)) >
+ definedLabelRefAlloc)
+ {
+ uint32_t newAlloc = definedLabelRefAlloc + DEFINED_INCREMENT;
+ void *tmp;
+
+ /* Reallocate the label reference tabel */
+
+ tmp = realloc(definedLabelRefs, newAlloc);
+ if (!tmp)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* And set the new size */
+
+ definedLabelRefAlloc = newAlloc;
+ definedLabelRefs = (optDefinedLabelRef_t*)tmp;
+ }
+}
+
+/**********************************************************************/
+
+static void poffCheckUndefinedLabelAlloc(void)
+{
+ /* Has the label reference table been allocated */
+
+ if (!undefinedLabelRefs)
+ {
+ /* No, allocate it now */
+
+ undefinedLabelRefs = (optUndefinedLabelRef_t*)
+ malloc(INITIAL_UNDEFINED_ALLOCATION);
+
+ if (!undefinedLabelRefs)
+ {
+ fatal(eNOMEMORY);
+ }
+ undefinedLabelRefAlloc = INITIAL_UNDEFINED_ALLOCATION;
+ }
+}
+
+/**********************************************************************/
+
+static void poffCheckUndefinedLabelRealloc(void)
+{
+ /* Check if there is room for the new data */
+
+ if (((nUndefinedLabelRefs + 1)*sizeof(optUndefinedLabelRef_t)) >
+ undefinedLabelRefAlloc)
+ {
+ uint32_t newAlloc = undefinedLabelRefAlloc + UNDEFINED_INCREMENT;
+ void *tmp;
+
+ /* Reallocate the label reference tabel */
+
+ tmp = realloc(undefinedLabelRefs, newAlloc);
+ if (!tmp)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* And set the new size */
+
+ undefinedLabelRefAlloc = newAlloc;
+ undefinedLabelRefs = (optUndefinedLabelRef_t*)tmp;
+ }
+}
+
+/**********************************************************************/
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/**********************************************************************/
+
+void poffAddToDefinedLabelTable(uint32_t label, uint32_t pc)
+{
+ /* Make sure we have memory to do this. If not, we will crash */
+
+ poffCheckDefinedLabelAlloc();
+ poffCheckDefinedLabelRealloc();
+
+ /* Add the label to the table */
+
+ definedLabelRefs[nDefinedLabelRefs].label = label;
+ definedLabelRefs[nDefinedLabelRefs].pc = pc;
+ nDefinedLabelRefs++;
+}
+
+/**********************************************************************/
+
+void poffAddToUndefinedLabelTable(uint32_t label, uint32_t symIndex)
+{
+ /* Make sure we have memory to do this. If not, we will crash */
+
+ poffCheckUndefinedLabelAlloc();
+ poffCheckUndefinedLabelRealloc();
+
+ /* Add the label to the table */
+
+ undefinedLabelRefs[nUndefinedLabelRefs].label = label;
+ undefinedLabelRefs[nUndefinedLabelRefs].symIndex = symIndex;
+ nUndefinedLabelRefs++;
+}
+
+/**********************************************************************/
+
+int poffGetSymIndexForUndefinedLabel(uint32_t label)
+{
+ int i;
+
+ for (i = 0; i < nUndefinedLabelRefs; i++)
+ {
+ if (undefinedLabelRefs[i].label == label)
+ {
+ return undefinedLabelRefs[i].symIndex;
+ }
+ }
+ return -1;
+}
+
+/**********************************************************************/
+
+int poffGetPcForDefinedLabel(uint32_t label)
+{
+ int i;
+
+ for (i = 0; i < nDefinedLabelRefs; i++)
+ {
+ if (definedLabelRefs[i].label == label)
+ {
+ return definedLabelRefs[i].pc;
+ }
+ }
+ return -1;
+}
+
+/**********************************************************************/
+
+void poffReleaseLabelReferences(void)
+{
+ if (definedLabelRefs)
+ {
+ free(definedLabelRefs);
+ }
+ if (undefinedLabelRefs)
+ {
+ free(undefinedLabelRefs);
+ }
+}
+
+/**********************************************************************/
+
diff --git a/misc/pascal/libpoff/pflineno.c b/misc/pascal/libpoff/pflineno.c
new file mode 100644
index 000000000..983a74554
--- /dev/null
+++ b/misc/pascal/libpoff/pflineno.c
@@ -0,0 +1,334 @@
+/**********************************************************************
+ * pflineno.c
+ * Manage line number information
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+#define INITIAL_LINENUMBER_TABLE_SIZE 2048*sizeof(poffLibLineNumber_t)
+#define LINENUMBER_TABLE_INCREMENT 512*sizeof(poffLibLineNumber_t)
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static poffLibLineNumber_t *lineNumberTable;
+static uint32_t nLineNumbers;
+static uint32_t lineNumberTableAlloc;
+static uint32_t prevLineNumberIndex;
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+static inline void poffCheckLineNumberAllocation(void)
+{
+ /* Check if we have allocated a line number buffer yet */
+
+ if (!lineNumberTable)
+ {
+ /* No, allocate it now */
+
+ lineNumberTable = (poffLibLineNumber_t*)
+ malloc(INITIAL_LINENUMBER_TABLE_SIZE);
+
+ if (!lineNumberTable)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ lineNumberTableAlloc = INITIAL_LINENUMBER_TABLE_SIZE;
+ nLineNumbers = 0;
+ }
+}
+
+/***********************************************************************/
+
+static inline void poffCheckLineNumberReallocation(void)
+{
+ if ((nLineNumbers +1) * sizeof(poffLibLineNumber_t) > lineNumberTableAlloc)
+ {
+ uint32_t newAlloc = lineNumberTableAlloc + LINENUMBER_TABLE_INCREMENT;
+ void *tmp;
+
+ /* Reallocate the line number buffer */
+
+ tmp = realloc(lineNumberTable, newAlloc);
+ if (!tmp)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* And set the new size */
+
+ lineNumberTableAlloc = newAlloc;
+ lineNumberTable = (poffLibLineNumber_t*)tmp;
+ }
+}
+
+/***********************************************************************/
+/* Add a line number to the line number table. */
+
+static void poffAddLineNumberToTable(poffLibLineNumber_t *lineno)
+{
+ /* Verify that the line number table has been allocated */
+
+ poffCheckLineNumberAllocation();
+
+ /* Verify that the line number table is large enough to hold
+ * information about another line.
+ */
+
+ poffCheckLineNumberReallocation();
+
+ /* Save the line number information in the line number table */
+
+ memcpy(&lineNumberTable[nLineNumbers], lineno, sizeof(poffLibLineNumber_t));
+ nLineNumbers++;
+}
+
+/***********************************************************************/
+/* Discard any unused memory */
+
+static void poffDiscardUnusedAllocation(void)
+{
+ uint32_t newAlloc = nLineNumbers * sizeof(poffLibLineNumber_t);
+ void *tmp;
+
+ /* Was a line number table allocated? And, if so, are there unused
+ * entries?
+ */
+
+ if ((lineNumberTable) && (nLineNumbers < lineNumberTableAlloc))
+ {
+ /* Reallocate the line number buffer */
+
+ tmp = realloc(lineNumberTable, newAlloc);
+ if (!tmp)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* And set the new size */
+
+ lineNumberTableAlloc = newAlloc;
+ lineNumberTable = (poffLibLineNumber_t*)tmp;
+ }
+}
+
+/***********************************************************************/
+/* "The comparison function must return an integer less than, equal to,
+ * or greater than zero if the first argument is considered to be
+ * respectively less than, equal to, or greater than the second. If two
+ * members compare as equal, their order in the sorted array is undefined."
+ */
+
+static int poffCompareLineNumbers(const void *pv1, const void *pv2)
+{
+ register poffLibLineNumber_t *ln1 = (poffLibLineNumber_t*)pv1;
+ register poffLibLineNumber_t *ln2 = (poffLibLineNumber_t*)pv2;
+
+ if (ln1->offset < ln2->offset) return -1;
+ else if (ln1->offset > ln2->offset) return 1;
+ else return 0;
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+void poffReadLineNumberTable(poffHandle_t handle)
+{
+ poffLibLineNumber_t lineno;
+ int32_t offset;
+
+ /* Initialize global variables */
+
+ prevLineNumberIndex = 0;
+
+ /* Create a table of line number information */
+
+ do
+ {
+ offset = poffGetLineNumber(handle, &lineno);
+ if (offset >= 0)
+ {
+ poffAddLineNumberToTable(&lineno);
+ }
+ }
+ while (offset >= 0);
+
+ /* Discard any memory that is not being used */
+
+ poffDiscardUnusedAllocation();
+
+ /* Sort the table by offset */
+
+ qsort(lineNumberTable, nLineNumbers,
+ sizeof(poffLibLineNumber_t), poffCompareLineNumbers);
+}
+
+/***********************************************************************/
+
+poffLibLineNumber_t *poffFindLineNumber(uint32_t offset)
+{
+ uint32_t firstLineNumberIndex;
+ uint32_t lastLineNumberIndex;
+ uint32_t lineNumberIndex;
+
+ /* Was a line number table allocated? */
+
+ if (!lineNumberTable) return NULL;
+
+ /* We used the last returned line number entry as a hint to speed
+ * up the next search. We don't know how the line numbers will
+ * be searched but most likely, they will be searched ina a sequence
+ * of ascending offsets. In that case, a dumb linear search
+ * would be better than what we are trying to do here. we are
+ * trying to support fast random access.
+ */
+
+ if (lineNumberTable[prevLineNumberIndex].offset <= offset)
+ {
+ firstLineNumberIndex = prevLineNumberIndex;
+ lastLineNumberIndex = nLineNumbers - 1;
+ }
+ else
+ {
+ firstLineNumberIndex = 0;
+ lastLineNumberIndex = prevLineNumberIndex;
+ }
+
+ /* Search until firstLineNumberIndex and firstLineNumberIndex+1
+ * contain the searched for offset. Exact matches may or may
+ * not occur.
+ */
+
+ lineNumberIndex = firstLineNumberIndex;
+ while (firstLineNumberIndex != lastLineNumberIndex)
+ {
+ /* Look at the midpoint index. This will be biased toward
+ * the lower index due to truncation. This means that
+ * can always be assured that as long as firstLineNumberIndex !=
+ * lastLineNumberIndex, then lineNumberIndex+1 is valid. We
+ * exploit this fact below.
+ */
+
+ lineNumberIndex = (firstLineNumberIndex + lastLineNumberIndex) >> 1;
+
+ /* If the offset at the midpoint is greater than the sought
+ * for offset, then we can safely set the upper search index
+ * to the midpoint.
+ */
+
+ if (lineNumberTable[lineNumberIndex].offset > offset)
+ lastLineNumberIndex = lineNumberIndex;
+
+ /* If we have an exact match, we break out of the loop now */
+
+ else if (lineNumberTable[lineNumberIndex].offset == offset)
+ break;
+
+ /* If the next entry is an offset greater then the one we
+ * are searching for, then we can break out of the loop now.
+ * We know that lineNumberIndex+1 is a valid index (see above).
+ */
+
+ else if (lineNumberTable[lineNumberIndex + 1].offset > offset)
+ break;
+
+ /* Otherwise, we safely do the following */
+
+ else
+ firstLineNumberIndex = lineNumberIndex + 1;
+ }
+
+ /* Check that we terminated the loop with a valid line number
+ * match. This should only fail if all of the line numbers in the
+ * table have offsets greater than the one in the table. If we
+ * could not find a match, return NULL.
+ */
+
+ if (lineNumberTable[lineNumberIndex].offset > offset)
+ {
+ prevLineNumberIndex = 0;
+ return NULL;
+ }
+ else
+ {
+ prevLineNumberIndex = lineNumberIndex;
+ return &lineNumberTable[lineNumberIndex];
+ }
+}
+
+/***********************************************************************/
+
+void poffReleaseLineNumberTable(void)
+{
+ if (lineNumberTable)
+ free(lineNumberTable);
+
+ lineNumberTable = NULL;
+ nLineNumbers = 0;
+ lineNumberTableAlloc = 0;
+ prevLineNumberIndex = 0;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfprivate.h b/misc/pascal/libpoff/pfprivate.h
new file mode 100644
index 000000000..560342215
--- /dev/null
+++ b/misc/pascal/libpoff/pfprivate.h
@@ -0,0 +1,190 @@
+/***************************************************************************
+ * pfprivate.h
+ * Contains command, internal, private definitions used by
+ * the POFF library. These were not intended for exportation.
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PFPRIVATE_H
+#define __PFPRIVATE_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+#include "keywords.h"
+#include "poff.h"
+#include "paslib.h" /* Endian-ness support */
+
+/***************************************************************************
+ * Pre-processor Definitions
+ ***************************************************************************/
+
+#define INITIAL_STRING_TABLE_SIZE 4096
+#define STRING_TABLE_INCREMENT 1024
+
+#define INITIAL_SYMBOL_TABLE_SIZE 256*sizeof(poffSymbol_t)
+#define SYMBOL_TABLE_INCREMENT 64*sizeof(poffSymbol_t)
+
+#define INITIAL_FILENAME_TABLE_SIZE 64*sizeof(poffFileTab_t)
+#define FILENAME_TABLE_INCREMENT 64*sizeof(poffFileTab_t)
+
+#define INITIAL_RELOC_TABLE_SIZE 128*sizeof(poffRelocation_t)
+#define RELOC_TABLE_INCREMENT 64*sizeof(poffRelocation_t)
+
+#define INITIAL_LINENUMBER_TABLE_SIZE 2048*sizeof(poffLineNumber_t)
+#define LINENUMBER_TABLE_INCREMENT 512*sizeof(poffLineNumber_t)
+
+#define INITIAL_DEBUGFUNC_TABLE_SIZE 128*sizeof(poffDebugFuncInfo_t)
+#define DEBUGFUNC_TABLE_INCREMENT 64*sizeof(poffDebugFuncInfo_t)
+
+#define INITIAL_PROG_SECTION_SIZE 8096
+#define PROG_SECTION_INCREMENT 2048
+
+#define INITIAL_RODATA_SECTION_SIZE 4096
+#define RODATA_SECTION_INCREMENT 1024
+
+#define HAVE_PROGRAM_SECTION (poffInfo->progSection.sh_size > 0)
+#define HAVE_RODATA_SECTION (poffInfo->roDataSection.sh_size > 0)
+#define HAVE_SYMBOL_TABLE (poffInfo->symbolTableSection.sh_size > 0)
+#define HAVE_STRING_TABLE (poffInfo->stringTableSection.sh_size > 0)
+#define HAVE_RELOC_SECTION (poffInfo->relocSection.sh_size > 0)
+#define HAVE_FILE_TABLE (poffInfo->fileNameTableSection.sh_size > 0)
+#define HAVE_LINE_NUMBER (poffInfo->lineNumberSection.sh_size > 0)
+#define HAVE_DEBUG_SECTION (poffInfo->debugFuncSection.sh_size > 0)
+
+#ifndef CONFIG_POFF_SWAPNEEDED
+# define poffSwapFileHeader(p)
+# define poffSwapSectionHeader(p)
+# define poffSwapSymbolTableData(p)
+# define poffSwapRelocationData(p)
+# define poffSwapFileTableData(p)
+# define poffSwapLineNumberData(p)
+# define poffSwapDebugData(p)
+#endif
+
+/***************************************************************************
+ * Public Types
+ ***************************************************************************/
+
+struct poffInfo_s
+{
+ /* POFF file header */
+
+ poffFileHeader_t fileHeader;
+
+ /* Section headers: */
+
+ poffSectionHeader_t progSection;
+ poffSectionHeader_t roDataSection;
+ poffSectionHeader_t symbolTableSection;
+ poffSectionHeader_t stringTableSection;
+ poffSectionHeader_t relocSection;
+ poffSectionHeader_t fileNameTableSection;
+ poffSectionHeader_t lineNumberSection;
+ poffSectionHeader_t debugFuncSection;
+
+ /* In-memory section data */
+
+ uint8_t *progSectionData;
+ uint8_t *roDataSectionData;
+ uint8_t *symbolTable;
+ char *stringTable;
+ uint8_t *relocTable;
+ poffFileTab_t *fileNameTable;
+ uint8_t *lineNumberTable;
+ uint8_t *debugFuncTable;
+
+ /* Current allocation sizes. Used only on writing to determine if
+ * in-memory has been allocated and how much memory has been allocated
+ * in case the buffer needs to be re-allocated.
+ */
+
+ uint32_t progSectionAlloc;
+ uint32_t roDataSectionAlloc;
+ uint32_t symbolTableAlloc;
+ uint32_t stringTableAlloc;
+ uint32_t relocAlloc;
+ uint32_t fileNameTableAlloc;
+ uint32_t lineNumberTableAlloc;
+ uint32_t debugFuncTableAlloc;
+
+ /* Current buffer indices. These are used on reading data sequentially
+ * from the in-memory section data.
+ */
+
+ uint32_t progSectionIndex;
+ uint32_t symbolIndex;
+ uint32_t relocIndex;
+ uint32_t fileNameIndex;
+ uint32_t lineNumberIndex;
+ uint32_t debugFuncIndex;
+};
+typedef struct poffInfo_s poffInfo_t;
+
+struct poffProgInfo_s
+{
+ uint32_t progSectionSize;
+ uint32_t progSectionAlloc;
+ uint8_t *progSectionData;
+};
+typedef struct poffProgInfo_s poffProgInfo_t;
+
+struct poffSymInfo_s
+{
+ uint32_t symbolTableSize;
+ uint32_t symbolTableAlloc;
+ uint8_t *symbolTable;
+};
+typedef struct poffSymInfo_s poffSymInfo_t;
+
+/***************************************************************************
+ * Public Variables
+ ***************************************************************************/
+
+/***************************************************************************
+ * Public Function Prototypes
+ ***************************************************************************/
+
+#ifdef CONFIG_POFF_SWAPNEEDED
+extern void poffSwapFileHeader(poffFileHeader_t *pFileHeader);
+extern void poffSwapSectionHeader(poffSectionHeader_t *pSectionHeader);
+extern void poffSwapSymbolTableData(poffInfo_t *poffInfo);
+extern void poffSwapRelocationData(poffInfo_t *poffInfo);
+extern void poffSwapFileTableData(poffInfo_t *poffInfo);
+extern void poffSwapLineNumberData(poffInfo_t *poffInfo);
+extern void poffSwapDebugData(poffInfo_t *poffInfo);
+#endif
+
+#endif /* __PFPRIVATE_H */
diff --git a/misc/pascal/libpoff/pfproghandle.c b/misc/pascal/libpoff/pfproghandle.c
new file mode 100644
index 000000000..6dc64c4d8
--- /dev/null
+++ b/misc/pascal/libpoff/pfproghandle.c
@@ -0,0 +1,127 @@
+/**********************************************************************
+ * pfproghandle.c
+ * POFF temporary progdata support
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* Pascal error codes */
+
+#include "pfprivate.h" /* POFF private definitions */
+#include "pofflib.h" /* Public interfaces */
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Set all global data structures to a known state */
+
+poffProgHandle_t poffCreateProgHandle(void)
+{
+ poffProgInfo_t *poffProgInfo;
+
+ /* Create a new POFF handle */
+
+ poffProgInfo = (poffProgInfo_t*)malloc(sizeof(poffProgInfo_t));
+ if (poffProgInfo != NULL)
+ {
+ /* Set everthing to zero */
+
+ memset(poffProgInfo, 0, sizeof(poffProgInfo_t));
+ }
+ return poffProgInfo;
+}
+
+/***********************************************************************/
+
+void poffDestroyProgHandle(poffProgHandle_t handle)
+{
+ /* Free all of the allocated, in-memory data */
+
+ poffResetProgHandle(handle);
+
+ /* Free the container */
+
+ free(handle);
+}
+
+/***********************************************************************/
+
+void poffResetProgHandle(poffProgHandle_t handle)
+{
+ poffProgInfo_t *poffProgInfo = (poffProgInfo_t*)handle;
+
+ /* Free all of the allocated, in-memory data */
+
+ if (poffProgInfo->progSectionData)
+ {
+ free(poffProgInfo->progSectionData);
+ }
+
+ /* Reset everything to the initial state */
+
+ poffProgInfo->progSectionData = NULL;
+ poffProgInfo->progSectionSize = 0;
+ poffProgInfo->progSectionAlloc = 0;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfrdbgfunc.c b/misc/pascal/libpoff/pfrdbgfunc.c
new file mode 100644
index 000000000..5e21aa328
--- /dev/null
+++ b/misc/pascal/libpoff/pfrdbgfunc.c
@@ -0,0 +1,131 @@
+/**********************************************************************
+ * pfrdbgfunc.c
+ * Read debug function information from a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+poffLibDebugFuncInfo_t *poffGetDebugFuncInfo(poffHandle_t handle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ poffDebugFuncInfo_t *pDebugInfo;
+ poffDebugArgInfo_t *pArgInfo;
+ poffLibDebugFuncInfo_t *pRet;
+ uint32_t debugFuncIndex;
+ int i;
+
+ /* Check if there is another debug entgry in the table to be had */
+
+ debugFuncIndex = poffInfo->debugFuncIndex;
+
+ if (debugFuncIndex + sizeof(poffDebugFuncInfo_t) >=
+ poffInfo->debugFuncSection.sh_size)
+ {
+ /* Return NULL to signal the end of the list */
+
+ return NULL;
+ }
+
+ /* Get a reference to the debug function entry */
+
+ pDebugInfo = (poffDebugFuncInfo_t*)&poffInfo->debugFuncTable[debugFuncIndex];
+
+ /* Allocate a container */
+
+ pRet = poffCreateDebugInfoContainer(pDebugInfo->df_nparms);
+
+ /* Return the debug function information */
+
+ pRet->value = pDebugInfo->df_value;
+ pRet->retsize = pDebugInfo->df_size;
+ pRet->nparms = pDebugInfo->df_nparms;
+
+ /* Return the size of each parameter */
+
+ debugFuncIndex += sizeof(poffDebugFuncInfo_t);
+ for (i = 0; i < pRet->nparms; i++)
+ {
+ pArgInfo = (poffDebugArgInfo_t*)&poffInfo->debugFuncTable[debugFuncIndex];
+ pRet->argsize[i] = pArgInfo->da_size;
+ debugFuncIndex += sizeof(poffDebugArgInfo_t);
+ }
+
+ /* Set up for the next read */
+
+ poffInfo->debugFuncIndex = debugFuncIndex;
+ return pRet;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfread.c b/misc/pascal/libpoff/pfread.c
new file mode 100644
index 000000000..850965749
--- /dev/null
+++ b/misc/pascal/libpoff/pfread.c
@@ -0,0 +1,361 @@
+/**********************************************************************
+ * pfread.c
+ * POFF library global variables
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* Pascal error definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+static uint16_t poffReadFileHeader(poffHandle_t handle, FILE *poffFile);
+static uint16_t poffReadSectionHeaders(poffHandle_t handle, FILE *poffFile);
+static uint16_t poffReadSectionData(poffSectionHeader_t *shdr,
+ uint8_t **sdata, FILE *poffFile);
+static uint16_t poffReadAllSectionData(poffHandle_t handle, FILE *poffFile);
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Read and verify the POFF file header */
+
+static uint16_t poffReadFileHeader(poffHandle_t handle, FILE *poffFile)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ size_t entriesRead;
+
+ /* Seek to the beginning of the file */
+
+ if (fseek(poffFile, 0, SEEK_SET) != 0)
+ {
+ return ePOFFREADERROR;
+ }
+
+ /* Read the POFF file header */
+
+ entriesRead = fread(&poffInfo->fileHeader, sizeof(poffFileHeader_t),
+ 1, poffFile);
+ if (entriesRead != 1)
+ {
+ return ePOFFREADERROR;
+ }
+
+ /* The POFF file is retained in big-endian order. Fixup fields as necessary */
+
+ poffSwapFileHeader(&poffInfo->fileHeader);
+
+ /* Verify that this is a valid POFF header */
+
+ if ((poffInfo->fileHeader.fh_ident[FHI_MAG0] != FHI_POFF_MAG0) ||
+ (poffInfo->fileHeader.fh_ident[FHI_MAG1] != FHI_POFF_MAG1) ||
+ (poffInfo->fileHeader.fh_ident[FHI_MAG2] != FHI_POFF_MAG2) ||
+ (poffInfo->fileHeader.fh_ident[FHI_MAG3] != FHI_POFF_MAG3) ||
+ (poffInfo->fileHeader.fh_version != FHV_CURRENT))
+ {
+ return ePOFFBADFORMAT;
+ }
+ return eNOERROR;
+}
+
+/***********************************************************************/
+/* Read and verify all of the POFF section headers */
+
+static uint16_t poffReadSectionHeaders(poffHandle_t handle, FILE *poffFile)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ poffSectionHeader_t sectionHeader;
+ poffSectionHeader_t *dest;
+ long offset;
+ size_t entriesRead;
+ int i;
+
+ offset = poffInfo->fileHeader.fh_shoff;
+
+ for (i = 0; i < poffInfo->fileHeader.fh_shnum; i++)
+ {
+ /* Seek to the beginning of the next section header */
+
+ if (fseek(poffFile, offset, SEEK_SET) != 0)
+ {
+ return ePOFFREADERROR;
+ }
+
+ /* Read the section header */
+
+ entriesRead = fread(&sectionHeader, sizeof(poffSectionHeader_t),
+ 1, poffFile);
+ if (entriesRead != 1)
+ {
+ return ePOFFREADERROR;
+ }
+
+ /* The POFF file is retained in big-endian order. Fixup fields as necessary */
+
+ poffSwapSectionHeader(&sectionHeader);
+
+ /* Copy the section header to the correct location */
+
+ switch (sectionHeader.sh_type)
+ {
+ case SHT_PROGDATA : /* Program data */
+ if ((sectionHeader.sh_flags & SHF_EXEC) != 0)
+ dest = &poffInfo->progSection;
+ else
+ dest = &poffInfo->roDataSection;
+ break;
+
+ case SHT_SYMTAB : /* Symbol table */
+ dest = &poffInfo->symbolTableSection;
+ break;
+
+ case SHT_STRTAB : /* String table */
+ dest = &poffInfo->stringTableSection;
+ break;
+
+ case SHT_REL : /* Relocation data */
+ dest = &poffInfo->relocSection;
+ break;
+
+ case SHT_FILETAB : /* File table */
+ dest = &poffInfo->fileNameTableSection;
+ break;
+
+ case SHT_LINENO : /* Line number data */
+ dest = &poffInfo->lineNumberSection;
+ break;
+
+ case SHT_DEBUG : /* Debug function info data */
+ dest = &poffInfo->debugFuncSection;
+ break;
+
+ default:
+ return ePOFFREADERROR;
+ }
+ memcpy(dest, &sectionHeader, sizeof(poffSectionHeader_t));
+
+ /* Get the offset to the next section */
+
+ offset += poffInfo->fileHeader.fh_shsize;
+ }
+ return eNOERROR;
+}
+
+/***********************************************************************/
+/* Read and buffer all of the POFF section data */
+
+static uint16_t poffReadSectionData(poffSectionHeader_t *shdr,
+ uint8_t **sdata, FILE *poffFile)
+{
+ size_t entriesRead;
+
+ /* Seek to the beginning of the section data */
+
+ if (fseek(poffFile, shdr->sh_offset, SEEK_SET) != 0)
+ {
+ return ePOFFREADERROR;
+ }
+
+ /* Allocate memory to hold the section data */
+
+ *sdata = (uint8_t*)malloc(shdr->sh_size);
+ if (*sdata == NULL)
+ {
+ return eNOMEMORY;
+ }
+
+ /* Read the section data */
+
+ entriesRead = fread(*sdata, 1, shdr->sh_size, poffFile);
+ if (entriesRead != shdr->sh_size)
+ {
+ return ePOFFREADERROR;
+ }
+ return eNOERROR;
+}
+
+/***********************************************************************/
+/* Read and buffer all of the POFF section data */
+
+static uint16_t poffReadAllSectionData(poffHandle_t handle, FILE *poffFile)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ uint16_t retval = eNOERROR;
+
+ if (HAVE_PROGRAM_SECTION)
+ {
+ retval = poffReadSectionData(&poffInfo->progSection,
+ (uint8_t**)&poffInfo->progSectionData,
+ poffFile);
+ }
+
+ if ((retval == eNOERROR) && (HAVE_RODATA_SECTION))
+ {
+ retval = poffReadSectionData(&poffInfo->roDataSection,
+ (uint8_t**)&poffInfo->roDataSectionData,
+ poffFile);
+ }
+
+ if ((retval == eNOERROR) && (HAVE_SYMBOL_TABLE))
+ {
+ retval = poffReadSectionData(&poffInfo->symbolTableSection,
+ (uint8_t**)&poffInfo->symbolTable,
+ poffFile);
+#ifdef CONFIG_POFF_SWAPNEEDED
+ if (retval == eNOERROR)
+ {
+ poffSwapSymbolTableData(poffInfo);
+ }
+#endif
+ }
+
+ if ((retval == eNOERROR) && (HAVE_STRING_TABLE))
+ {
+ retval = poffReadSectionData(&poffInfo->stringTableSection,
+ (uint8_t**)&poffInfo->stringTable,
+ poffFile);
+ }
+
+ if ((retval == eNOERROR) && (HAVE_RELOC_SECTION))
+ {
+ retval = poffReadSectionData(&poffInfo->relocSection,
+ (uint8_t**)&poffInfo->relocTable,
+ poffFile);
+#ifdef CONFIG_POFF_SWAPNEEDED
+ if (retval == eNOERROR)
+ {
+ poffSwapRelocationData(poffInfo);
+ }
+#endif
+ }
+
+ if ((retval == eNOERROR) && (HAVE_FILE_TABLE))
+ {
+ retval = poffReadSectionData(&poffInfo->fileNameTableSection,
+ (uint8_t**)&poffInfo->fileNameTable,
+ poffFile);
+#ifdef CONFIG_POFF_SWAPNEEDED
+ if (retval == eNOERROR)
+ {
+ poffSwapFileTableData(poffInfo);
+ }
+#endif
+ }
+
+ if ((retval == eNOERROR) && (HAVE_LINE_NUMBER))
+ {
+ retval = poffReadSectionData(&poffInfo->lineNumberSection,
+ (uint8_t**)&poffInfo->lineNumberTable,
+ poffFile);
+#ifdef CONFIG_POFF_SWAPNEEDED
+ if (retval == eNOERROR)
+ {
+ poffSwapLineNumberData(poffInfo);
+ }
+#endif
+ }
+
+ if ((retval == eNOERROR) && (HAVE_DEBUG_SECTION))
+ {
+ retval = poffReadSectionData(&poffInfo->debugFuncSection,
+ (uint8_t**)&poffInfo->debugFuncTable,
+ poffFile);
+#ifdef CONFIG_POFF_SWAPNEEDED
+ if (retval == eNOERROR)
+ {
+ poffSwapDebugData(poffInfo);
+ }
+#endif
+ }
+
+ return retval;
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Set all global data structures to a known state */
+
+uint16_t poffReadFile(poffHandle_t handle, FILE *poffFile)
+{
+ uint16_t retVal;
+
+ /* Read the POFF header file */
+
+ retVal = poffReadFileHeader(handle, poffFile);
+ if (retVal == eNOERROR)
+ {
+ retVal = poffReadSectionHeaders(handle, poffFile);
+ if (retVal == eNOERROR)
+ {
+ retVal = poffReadAllSectionData(handle, poffFile);
+ }
+ }
+ return retVal;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfrelease.c b/misc/pascal/libpoff/pfrelease.c
new file mode 100644
index 000000000..72bdf0d10
--- /dev/null
+++ b/misc/pascal/libpoff/pfrelease.c
@@ -0,0 +1,94 @@
+/**********************************************************************
+ * pfrelease.c
+ * Program data manipulations on POFF temporary object
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "keywords.h" /* Standard types */
+
+#include "pfprivate.h" /* POFF private definitions */
+#include "pofflib.h" /* Public interfaces */
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+void poffReleaseProgData(poffHandle_t handle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+
+ /* Discard any existing program section data */
+
+ if (poffInfo->progSectionData)
+ {
+ free(poffInfo->progSectionData);
+ poffInfo->progSectionData = NULL;
+ }
+
+ /* Indicate that there is no program data */
+
+ poffInfo->progSection.sh_size = 0;
+ poffInfo->progSectionAlloc = 0;
+ poffInfo->progSectionIndex = 0;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfrfname.c b/misc/pascal/libpoff/pfrfname.c
new file mode 100644
index 000000000..48a4f10ae
--- /dev/null
+++ b/misc/pascal/libpoff/pfrfname.c
@@ -0,0 +1,117 @@
+/**********************************************************************
+ * pfrfname.c
+ * Read file name data from a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+int32_t poffGetFileName(poffHandle_t handle, const char **fname)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ uint32_t stringTableIndex;
+ uint32_t fileNameIndex;
+
+ /* First, check if there is another file name in the table to be had.
+ * This check is a little sloppy in that it assumes the the size in
+ * in the header is an even multiple of file name table entries
+ */
+
+ fileNameIndex = poffInfo->fileNameIndex;
+ if (fileNameIndex * sizeof(poffFileTab_t) >=
+ poffInfo->fileNameTableSection.sh_size)
+ {
+ /* Return -1 to signal the end of the list */
+
+ *fname = NULL;
+ return -1;
+ }
+ else
+ {
+ /* Get the string table index from the file name table */
+
+ stringTableIndex = (uint32_t)poffInfo->fileNameTable[fileNameIndex];
+
+ /* Return the file name */
+
+ *fname = poffGetString(handle, stringTableIndex);
+
+ /* Set up for the next read */
+
+ poffInfo->fileNameIndex++;
+ return fileNameIndex;
+ }
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfrhdr.c b/misc/pascal/libpoff/pfrhdr.c
new file mode 100644
index 000000000..a1a65a151
--- /dev/null
+++ b/misc/pascal/libpoff/pfrhdr.c
@@ -0,0 +1,118 @@
+/**********************************************************************
+ * pfrhdr.c
+ * Read info from a POFF file header
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Get the type of the file from the POFF file header */
+
+uint8_t poffGetFileType(poffHandle_t handle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ return poffInfo->fileHeader.fh_type;
+}
+
+/***********************************************************************/
+/* Get the machine architecture from the POFF file header */
+
+uint8_t poffGetArchitecture(poffHandle_t handle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ return poffInfo->fileHeader.fh_arch;
+}
+
+/***********************************************************************/
+/* Get the program entry point */
+
+uint32_t poffGetEntryPoint(poffHandle_t handle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ return poffInfo->fileHeader.fh_entry;
+}
+
+/***********************************************************************/
+/* Return the name associated with the file in the file header */
+
+const char *poffGetFileHdrName(poffHandle_t handle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ return poffGetString(handle, poffInfo->fileHeader.fh_name);
+}
+
+/***********************************************************************/
+
+uint32_t poffGetRoDataSize(poffHandle_t handle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ return poffInfo->roDataSection.sh_size;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfrlineno.c b/misc/pascal/libpoff/pfrlineno.c
new file mode 100644
index 000000000..64bb41157
--- /dev/null
+++ b/misc/pascal/libpoff/pfrlineno.c
@@ -0,0 +1,128 @@
+/**********************************************************************
+ * pfrlineno.c
+ * Read line number data from a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+int32_t poffGetLineNumber(poffHandle_t handle, poffLibLineNumber_t *lineno)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ poffLineNumber_t *pln;
+ uint32_t stringTableIndex;
+ uint32_t lineNumberIndex;
+
+ /* First, check if there is another line number in the table to be had.
+ * This check is a little sloppy in that it assumes the the size in
+ * in the header is an even multiple of line number table entries
+ */
+
+ lineNumberIndex = poffInfo->lineNumberIndex;
+ if (lineNumberIndex >= poffInfo->lineNumberSection.sh_size)
+ {
+ /* Return -1 to signal the end of the list */
+
+ memset(lineno, 0, sizeof(poffLibLineNumber_t));
+ return -1;
+ }
+ else
+ {
+ /* Get a reference to the line number record */
+
+ pln = (poffLineNumber_t*)&poffInfo->lineNumberTable[lineNumberIndex];
+
+ /* Get the filename table index */
+
+ if (pln->ln_fileno * sizeof(poffFileTab_t) >
+ poffInfo->fileNameTableSection.sh_size)
+ {
+ fatal(ePOFFCONFUSION);
+ }
+ stringTableIndex = (uint32_t)poffInfo->fileNameTable[pln->ln_fileno];
+
+ /* Return the line number information */
+
+ lineno->lineno = pln->ln_lineno;
+ lineno->offset = pln->ln_poffset;
+ lineno->filename = poffGetString(handle, stringTableIndex);
+
+ /* Set up for the next read */
+
+ poffInfo->lineNumberIndex += poffInfo->lineNumberSection.sh_entsize;
+ return lineNumberIndex;
+ }
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfrprog.c b/misc/pascal/libpoff/pfrprog.c
new file mode 100644
index 000000000..2de3da049
--- /dev/null
+++ b/misc/pascal/libpoff/pfrprog.c
@@ -0,0 +1,91 @@
+/**********************************************************************
+ * pfrprog.c
+ * Read program data from a POFF file
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+int poffGetProgByte(poffHandle_t handle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ int retval = EOF;
+
+ /* Check if there is more data that has not yet been read */
+
+ if ((poffInfo->progSectionIndex < poffInfo->progSection.sh_size) &&
+ (poffInfo->progSectionData != NULL))
+ {
+ retval = (int)poffInfo->progSectionData[poffInfo->progSectionIndex];
+ poffInfo->progSectionIndex++;
+ }
+ return retval;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfrrawlineno.c b/misc/pascal/libpoff/pfrrawlineno.c
new file mode 100644
index 000000000..3268b7fdd
--- /dev/null
+++ b/misc/pascal/libpoff/pfrrawlineno.c
@@ -0,0 +1,111 @@
+/**********************************************************************
+ * pfrrawlineno.c
+ * Read raw line number data from a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+int32_t poffGetRawLineNumber(poffHandle_t handle, poffLineNumber_t *lineno)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ uint32_t lineNumberIndex;
+
+ /* First, check if there is another line number in the table to be had.
+ * This check is a little sloppy in that it assumes the the size in
+ * in the header is an even multiple of line number table entries
+ */
+
+ lineNumberIndex = poffInfo->lineNumberIndex;
+ if (lineNumberIndex >= poffInfo->lineNumberSection.sh_size)
+ {
+ /* Return -1 to signal the end of the list */
+
+ memset(lineno, 0, sizeof(poffLineNumber_t));
+ return -1;
+ }
+ else
+ {
+ /* Copy the raw line number information to the user */
+
+ memcpy(lineno, &poffInfo->lineNumberTable[lineNumberIndex], sizeof(poffLineNumber_t));
+
+ /* Set up for the next read */
+
+ poffInfo->lineNumberIndex += poffInfo->lineNumberSection.sh_entsize;
+ return lineNumberIndex;
+ }
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfrrawreloc.c b/misc/pascal/libpoff/pfrrawreloc.c
new file mode 100644
index 000000000..af4959517
--- /dev/null
+++ b/misc/pascal/libpoff/pfrrawreloc.c
@@ -0,0 +1,108 @@
+/**********************************************************************
+ * pfrrawreloc.c
+ * Read raw relocation data from a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+int32_t poffGetRawRelocation(poffHandle_t handle, poffRelocation_t *lineno)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ uint32_t relocIndex;
+
+ /* First, check if there is another relocation in the table to be had. */
+
+ relocIndex = poffInfo->relocIndex;
+ if (relocIndex >= poffInfo->relocSection.sh_size)
+ {
+ /* Return -1 to signal the end of the list */
+
+ memset(lineno, 0, sizeof(poffRelocation_t));
+ return -1;
+ }
+ else
+ {
+ /* Copy the raw line number information to the user */
+
+ memcpy(lineno, &poffInfo->relocTable[relocIndex], sizeof(poffRelocation_t));
+
+ /* Set up for the next read */
+
+ poffInfo->relocIndex += poffInfo->relocSection.sh_entsize;
+ return relocIndex;
+ }
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfrseek.c b/misc/pascal/libpoff/pfrseek.c
new file mode 100644
index 000000000..7c98323e6
--- /dev/null
+++ b/misc/pascal/libpoff/pfrseek.c
@@ -0,0 +1,116 @@
+/**********************************************************************
+ * pfrseek.c
+ * Seek to a position in buffered program data from a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+int32_t poffProgTell(poffHandle_t handle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ int32_t retval = -1;
+
+ /* Check if there is more data that has not yet been read */
+
+ if (poffInfo->progSectionData != NULL)
+ {
+ retval = poffInfo->progSectionIndex;
+ }
+ return retval;
+}
+
+/***********************************************************************/
+
+int poffProgSeek(poffHandle_t handle, uint32_t offset)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ int retval = -1;
+
+ /* Check if there is more data that has not yet been read */
+
+ if ((offset < poffInfo->progSection.sh_size) &&
+ (poffInfo->progSectionData != NULL))
+ {
+ poffInfo->progSectionIndex = offset;
+ retval = offset;
+ }
+ return retval;
+}
+
+/***********************************************************************/
+
+uint32_t poffGetProgSize(poffHandle_t handle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ return poffInfo->progSection.sh_size;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfrstring.c b/misc/pascal/libpoff/pfrstring.c
new file mode 100644
index 000000000..de7e0e2c1
--- /dev/null
+++ b/misc/pascal/libpoff/pfrstring.c
@@ -0,0 +1,91 @@
+/**********************************************************************
+ * pfrstring.c
+ * Read a string from a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+const char *poffGetString(poffHandle_t handle, uint32_t index)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+
+ if ((index < poffInfo->stringTableSection.sh_size) &&
+ (poffInfo->stringTable != NULL))
+ {
+ return &poffInfo->stringTable[index];
+ }
+ else
+ {
+ return "<NULL>";
+ }
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfrsymbol.c b/misc/pascal/libpoff/pfrsymbol.c
new file mode 100644
index 000000000..592038071
--- /dev/null
+++ b/misc/pascal/libpoff/pfrsymbol.c
@@ -0,0 +1,108 @@
+/**********************************************************************
+ * pfrsymbol
+ * Read symbols from a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+int32_t poffGetSymbol(poffHandle_t handle, poffLibSymbol_t *symbol)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ poffSymbol_t *psym;
+ uint32_t index;
+
+ /* First, check if there is another symbol in the table to be had.
+ * This check is a little sloppy in that it assumes the the size in
+ * in the section header is an even multiple of symbol table entries
+ */
+
+ index = poffInfo->symbolIndex;
+ if (index >= poffInfo->symbolTableSection.sh_size)
+ {
+ memset(symbol, 0, sizeof(poffLibSymbol_t));
+ return -1;
+ }
+ else
+ {
+ psym = (poffSymbol_t*)&poffInfo->symbolTable[index];
+ symbol->type = psym->st_type;
+ symbol->align = psym->st_align;
+ symbol->flags = psym->st_flags;
+ symbol->name = poffGetString(handle, psym->st_name);
+ symbol->value = psym->st_value;
+ symbol->size = psym->st_size;
+
+ poffInfo->symbolIndex += poffInfo->symbolTableSection.sh_entsize;
+ return index / poffInfo->symbolTableSection.sh_entsize;
+ }
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfswap.c b/misc/pascal/libpoff/pfswap.c
new file mode 100644
index 000000000..69174af37
--- /dev/null
+++ b/misc/pascal/libpoff/pfswap.c
@@ -0,0 +1,252 @@
+/**********************************************************************
+ * libpoff/pfswap.c
+ * Handle POFF Endian-ness
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+
+#include "keywords.h" /* Standard types */
+#include "paslib.h" /* Common library */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+#ifdef CONFIG_POFF_SWAPNEEDED
+static inline void poffSwapRelocationEntry(poffRelocation_t *prel)
+{
+ prel->rl_info = poff32(prel->rl_info);
+ prel->rl_offset = poff32(prel->rl_offset);
+}
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_POFF_SWAPNEEDED
+static inline void poffSwapSymbolTableEntry(poffSymbol_t *psym)
+{
+ psym->st_name = poff32(psym->st_name);
+ psym->st_value = poff32(psym->st_value);
+ psym->st_size = poff32(psym->st_size);
+}
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_POFF_SWAPNEEDED
+static inline void poffSwapFileTabEntry(poffFileTab_t *pfile)
+{
+ *pfile = poff32((uint32_t)*pfile);
+}
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_POFF_SWAPNEEDED
+static inline void poffSwaplineno(poffLineNumber_t *plineno)
+{
+ plineno->ln_lineno = poff16(plineno->ln_lineno);
+ plineno->ln_fileno = poff16(plineno->ln_fileno);
+ plineno->ln_poffset = poff32(plineno->ln_poffset);
+}
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_POFF_SWAPNEEDED
+static inline void poffDebugFuncEntry(poffDebugFuncInfo_t *pdbg)
+{
+ pdbg->df_value = poff32(pdbg->df_value);
+ pdbg->df_size = poff32(pdbg->df_size);
+ pdbg->df_nparms = poff32(pdbg->df_nparms);
+}
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_POFF_SWAPNEEDED
+static inline void poffDebugArgEntry(poffDebugArgInfo_t *parg)
+{
+ parg->da_size = poff32(parg->da_size);
+}
+#endif
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+#ifdef CONFIG_POFF_SWAPNEEDED
+void poffSwapFileHeader(poffFileHeader_t *pFileHeader)
+{
+ pFileHeader->fh_shsize = poff16(pFileHeader->fh_shsize);
+ pFileHeader->fh_shnum = poff16(pFileHeader->fh_shnum);
+ pFileHeader->fh_name = poff32(pFileHeader->fh_name);
+ pFileHeader->fh_entry = poff32(pFileHeader->fh_entry);
+ pFileHeader->fh_shoff = poff32(pFileHeader->fh_shoff);
+}
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_POFF_SWAPNEEDED
+void poffSwapSectionHeader(poffSectionHeader_t *pSectionHeader)
+{
+ pSectionHeader->sh_entsize = poff16(pSectionHeader->sh_entsize);
+ pSectionHeader->sh_name = poff32(pSectionHeader->sh_name);
+ pSectionHeader->sh_addr = poff32(pSectionHeader->sh_addr);
+ pSectionHeader->sh_offset = poff32(pSectionHeader->sh_offset);
+ pSectionHeader->sh_size = poff32(pSectionHeader->sh_size);
+}
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_POFF_SWAPNEEDED
+void poffSwapSymbolTableData(poffInfo_t *poffInfo)
+{
+ poffSymbol_t *psym;
+ uint32_t index;
+
+ for (index = 0;
+ index < poffInfo->symbolTableSection.sh_size;
+ index += poffInfo->symbolTableSection.sh_entsize)
+ {
+ psym = (poffSymbol_t*)&poffInfo->symbolTable[index];
+ poffSwapSymbolTableEntry(psym);
+ }
+}
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_POFF_SWAPNEEDED
+void poffSwapRelocationData(poffInfo_t *poffInfo)
+{
+ poffRelocation_t *prel;
+ uint32_t index;
+
+ for (index = 0;
+ index < poffInfo->relocSection.sh_size;
+ index += poffInfo->relocSection.sh_entsize)
+ {
+ prel = (poffRelocation_t*)&poffInfo->relocTable[index];
+ poffSwapRelocationEntry(prel);
+ }
+}
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_POFF_SWAPNEEDED
+void poffSwapFileTableData(poffInfo_t *poffInfo)
+{
+ poffFileTab_t *pfile;
+ uint32_t index;
+
+ for (index = 0;
+ index < poffInfo->relocSection.sh_size;
+ index += poffInfo->relocSection.sh_entsize)
+ {
+ pfile = (poffFileTab_t*)&poffInfo->relocTable[index];
+ poffSwapFileTabEntry(pfile);
+ }
+}
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_POFF_SWAPNEEDED
+void poffSwapLineNumberData(poffInfo_t *poffInfo)
+{
+ poffLineNumber_t *plineno;
+ uint32_t index;
+
+ for (index = 0;
+ index < poffInfo->relocSection.sh_size;
+ index += poffInfo->relocSection.sh_entsize)
+ {
+ plineno = (poffLineNumber_t*)&poffInfo->relocTable[index];
+ poffSwaplineno(plineno);
+ }
+}
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_POFF_SWAPNEEDED
+void poffSwapDebugData(poffInfo_t *poffInfo)
+{
+ poffDebugFuncInfo_t *pdbg;
+ poffDebugArgInfo_t *parg;
+ uint32_t i;
+ int j;
+
+ for (i = 0; i + sizeof(poffDebugFuncInfo_t) < poffInfo->relocSection.sh_size;)
+ {
+ pdbg = (poffDebugFuncInfo_t*)&poffInfo->debugFuncTable[i];
+ poffDebugFuncEntry(pdbg);
+
+ i += sizeof(poffDebugFuncInfo_t);
+ for (j = 0; j < pdbg->df_nparms; j++)
+ {
+ parg = (poffDebugArgInfo_t*)&poffInfo->debugFuncTable[i];
+ poffDebugArgEntry(parg);
+ i += sizeof(poffDebugArgInfo_t);
+ }
+ }
+}
+#endif
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfsymhandle.c b/misc/pascal/libpoff/pfsymhandle.c
new file mode 100644
index 000000000..4d38b286c
--- /dev/null
+++ b/misc/pascal/libpoff/pfsymhandle.c
@@ -0,0 +1,127 @@
+/**********************************************************************
+ * pfsymhandle.c
+ * POFF temporary symdata support
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* Pascal error codes */
+
+#include "pfprivate.h" /* POFF private definitions */
+#include "pofflib.h" /* Public interfaces */
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Set all global data structures to a known state */
+
+poffSymHandle_t poffCreateSymHandle(void)
+{
+ poffSymInfo_t *poffSymInfo;
+
+ /* Create a new POFF handle */
+
+ poffSymInfo = (poffSymInfo_t*)malloc(sizeof(poffSymInfo_t));
+ if (poffSymInfo != NULL)
+ {
+ /* Set everthing to zero */
+
+ memset(poffSymInfo, 0, sizeof(poffSymInfo_t));
+ }
+ return poffSymInfo;
+}
+
+/***********************************************************************/
+
+void poffDestroySymHandle(poffSymHandle_t handle)
+{
+ /* Free all of the allocated, in-memory data */
+
+ poffResetSymHandle(handle);
+
+ /* Free the container */
+
+ free(handle);
+}
+
+/***********************************************************************/
+
+void poffResetSymHandle(poffSymHandle_t handle)
+{
+ poffSymInfo_t *poffSymInfo = (poffSymInfo_t*)handle;
+
+ /* Free all of the allocated, in-memory data */
+
+ if (poffSymInfo->symbolTable)
+ {
+ free(poffSymInfo->symbolTable);
+ }
+
+ /* Reset everything to the initial state */
+
+ poffSymInfo->symbolTable = NULL;
+ poffSymInfo->symbolTableSize = 0;
+ poffSymInfo->symbolTableAlloc = 0;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pftprog.c b/misc/pascal/libpoff/pftprog.c
new file mode 100644
index 000000000..9e7f2818f
--- /dev/null
+++ b/misc/pascal/libpoff/pftprog.c
@@ -0,0 +1,225 @@
+/**********************************************************************
+ * pftprog.c
+ * Program data manipulations on POFF temporary object
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* Pascal error codes */
+
+#include "pfprivate.h" /* POFF private definitions */
+#include "pofflib.h" /* Public interfaces */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+static uint16_t poffCheckProgAlloc(poffProgInfo_t *poffProgInfo)
+{
+ if (!poffProgInfo->progSectionData)
+ {
+ /* No, allocate it now */
+
+ poffProgInfo->progSectionData = (uint8_t*)malloc(INITIAL_PROG_SECTION_SIZE);
+ if (!poffProgInfo->progSectionData)
+ {
+ return eNOMEMORY;
+ }
+
+ poffProgInfo->progSectionSize = 0;
+ poffProgInfo->progSectionAlloc = INITIAL_PROG_SECTION_SIZE;
+ }
+ return eNOERROR;
+}
+
+static uint16_t poffCheckProgRealloc(poffProgInfo_t *poffProgInfo, uint16_t len)
+{
+ /* Check if there is room for the new data */
+
+ if (poffProgInfo->progSectionSize + len > poffProgInfo->progSectionAlloc)
+ {
+ uint32_t newAlloc =
+ poffProgInfo->progSectionAlloc + PROG_SECTION_INCREMENT;
+ void *tmp;
+
+ /* Make certain that this is big enough (it should be) */
+
+ while (poffProgInfo->progSectionSize + len > newAlloc)
+ {
+ newAlloc += PROG_SECTION_INCREMENT;
+ }
+
+ /* Reallocate the program data section buffer */
+
+ tmp = realloc(poffProgInfo->progSectionData, newAlloc);
+ if (!tmp)
+ {
+ return eNOMEMORY;
+ }
+
+ /* And set the new size */
+
+ poffProgInfo->progSectionAlloc = newAlloc;
+ poffProgInfo->progSectionData = (uint8_t*)tmp;
+ }
+ return eNOERROR;
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+uint16_t poffAddTmpProgByte(poffProgHandle_t handle, uint8_t progByte)
+{
+ poffProgInfo_t *poffProgInfo = (poffProgInfo_t*)handle;
+ uint16_t errCode;
+
+ /* Check if we have allocated a program section buffer yet */
+
+ errCode = poffCheckProgAlloc(poffProgInfo);
+ if (errCode != eNOERROR)
+ {
+ return errCode;
+ }
+
+ /* Check if there is room for the new byte */
+
+ errCode = poffCheckProgRealloc(poffProgInfo, 1);
+ if (errCode != eNOERROR)
+ {
+ return errCode;
+ }
+
+ /* Copy program data byte into the program data buffer */
+
+ poffProgInfo->progSectionData[poffProgInfo->progSectionSize] = progByte;
+
+ /* Set the new size of the string table */
+
+ poffProgInfo->progSectionSize++;
+ return eNOERROR;
+}
+
+/***********************************************************************/
+
+uint16_t poffWriteTmpProgBytes(uint8_t *buffer, uint32_t nbytes,
+ poffProgHandle_t handle)
+
+{
+ poffProgInfo_t *poffProgInfo = (poffProgInfo_t*)handle;
+ uint16_t errCode;
+
+ /* Check if we have allocated a program section buffer yet */
+
+ errCode = poffCheckProgAlloc(poffProgInfo);
+ if (errCode != eNOERROR)
+ {
+ return errCode;
+ }
+
+ /* Check if there is room for the new data */
+
+ errCode = poffCheckProgRealloc(poffProgInfo, nbytes);
+ if (errCode != eNOERROR)
+ {
+ return errCode;
+ }
+
+ /* Copy program data byte into the program data buffer */
+
+ memcpy(&poffProgInfo->progSectionData[poffProgInfo->progSectionSize],
+ buffer, nbytes);
+
+ /* Set the new size of the string table */
+
+ poffProgInfo->progSectionSize += nbytes;
+ return eNOERROR;
+}
+
+/***********************************************************************/
+
+void poffReplaceProgData(poffHandle_t handle, poffProgHandle_t progHandle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ poffProgInfo_t *poffProgInfo = (poffProgInfo_t*)progHandle;
+
+ /* Discard any existing program section data */
+
+ if (poffInfo->progSectionData)
+ {
+ free(poffInfo->progSectionData);
+ }
+
+ /* Replace the program section data with the tmp data */
+
+ poffInfo->progSectionData = poffProgInfo->progSectionData;
+ poffInfo->progSection.sh_size = poffProgInfo->progSectionSize;
+ poffInfo->progSectionAlloc = poffProgInfo->progSectionAlloc;
+
+ /* Reset the read index */
+
+ poffInfo->progSectionIndex = 0;
+
+ /* Then nullify the tmp data */
+
+ poffProgInfo->progSectionData = NULL;
+ poffProgInfo->progSectionSize = 0;
+ poffProgInfo->progSectionAlloc = 0;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pftsymbol.c b/misc/pascal/libpoff/pftsymbol.c
new file mode 100644
index 000000000..f7298d8f5
--- /dev/null
+++ b/misc/pascal/libpoff/pftsymbol.c
@@ -0,0 +1,189 @@
+/**********************************************************************
+ * pftsymbol.c
+ * Write symbol information to a temporary container
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Add a symbol to the symbol table section data. Returns index value
+ * associated with the symbol entry in the symbol table section data.
+ */
+
+uint32_t poffAddTmpSymbol(poffHandle_t handle, poffSymHandle_t symHandle,
+ poffLibSymbol_t *symbol)
+{
+ poffSymInfo_t *poffSymInfo = (poffSymInfo_t*)symHandle;
+ poffSymbol_t *psym;
+ uint32_t st_name;
+ uint32_t index;
+
+ /* Add the name to the string table. Note: We are probably re-writing
+ * the string table and so the string probably already exists in the
+ * string table. We are counting of the string table logic's abililty
+ * avoid duplicated strings to keep from adding trash to the string
+ * table.
+ */
+
+ st_name = poffAddString(handle, symbol->name);
+
+ /* Check if we have allocated a symbol table buffer yet */
+
+ if (!poffSymInfo->symbolTable)
+ {
+ /* No, allocate it now */
+
+ poffSymInfo->symbolTable = (uint8_t*)malloc(INITIAL_SYMBOL_TABLE_SIZE);
+ if (!poffSymInfo->symbolTable)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ poffSymInfo->symbolTableSize = 0;
+ poffSymInfo->symbolTableAlloc = INITIAL_SYMBOL_TABLE_SIZE;
+ }
+
+ /* Check if there is room for a new symbol */
+
+ if (poffSymInfo->symbolTableSize + sizeof(poffSymbol_t) >
+ poffSymInfo->symbolTableAlloc)
+ {
+ uint32_t newAlloc = poffSymInfo->symbolTableAlloc + SYMBOL_TABLE_INCREMENT;
+ uint8_t *tmp;
+
+ /* Reallocate the file name buffer */
+
+ tmp = (uint8_t*)realloc(poffSymInfo->symbolTable, newAlloc);
+ if (!tmp)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* And set the new size */
+
+ poffSymInfo->symbolTableAlloc = newAlloc;
+ poffSymInfo->symbolTable = tmp;
+ }
+
+ /* Save the new symbol information in the symbol table data */
+
+ index = poffSymInfo->symbolTableSize;
+ psym = (poffSymbol_t*)&poffSymInfo->symbolTable[index];
+
+ psym->st_type = symbol->type;
+ psym->st_align = symbol->align;
+ psym->st_flags = symbol->flags;
+ psym->st_pad = 0;
+ psym->st_name = st_name;
+ psym->st_value = symbol->value;
+ psym->st_size = symbol->size;
+
+ /* Set the new size of the file name table */
+
+ poffSymInfo->symbolTableSize += sizeof(poffSymbol_t);
+ return index;
+}
+
+/***********************************************************************/
+
+void poffReplaceSymbolTable(poffHandle_t handle, poffSymHandle_t symHandle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ poffSymInfo_t *poffSymInfo = (poffSymInfo_t*)symHandle;
+
+ /* Discard any existing symbol table */
+
+ if (poffInfo->symbolTable)
+ {
+ free(poffInfo->symbolTable);
+ }
+
+ /* Replace the symram section data with the tmp data */
+
+ poffInfo->symbolTable = poffSymInfo->symbolTable;
+ poffInfo->symbolTableSection.sh_size = poffSymInfo->symbolTableSize;
+ poffInfo->symbolTableSection.sh_entsize = sizeof(poffSymbol_t);
+ poffInfo->symbolTableAlloc = poffSymInfo->symbolTableAlloc;
+
+ /* Reset the read index */
+
+ poffInfo->symbolIndex = 0;
+
+ /* Then nullify the tmp data */
+
+ poffSymInfo->symbolTable = NULL;
+ poffSymInfo->symbolTableSize = 0;
+ poffSymInfo->symbolTableAlloc = 0;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfwdbgfunc.c b/misc/pascal/libpoff/pfwdbgfunc.c
new file mode 100644
index 000000000..8f80ff12c
--- /dev/null
+++ b/misc/pascal/libpoff/pfwdbgfunc.c
@@ -0,0 +1,174 @@
+/**********************************************************************
+ * pfwdbgfunc.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ *Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+static void poffCheckDebugFuncInfoAllocation(poffInfo_t *poffInfo)
+{
+ /* Check if we have allocated a line number buffer yet */
+
+ if (!poffInfo->debugFuncTable)
+ {
+ /* No, allocate it now */
+
+ poffInfo->debugFuncTable = (uint8_t*)
+ malloc(INITIAL_DEBUGFUNC_TABLE_SIZE);
+
+ if (!poffInfo->debugFuncTable)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ poffInfo->debugFuncSection.sh_size = 0;
+ poffInfo->debugFuncTableAlloc = INITIAL_DEBUGFUNC_TABLE_SIZE;
+ }
+}
+
+/***********************************************************************/
+
+static void poffCheckDebugFuncInfoReallocation(poffInfo_t *poffInfo, uint32_t nparms)
+{
+ uint32_t needed = sizeof(poffDebugFuncInfo_t) + nparms*sizeof(poffDebugArgInfo_t);
+ if (poffInfo->debugFuncSection.sh_size + needed > poffInfo->debugFuncTableAlloc)
+ {
+ uint32_t newAlloc =
+ poffInfo->debugFuncTableAlloc +
+ DEBUGFUNC_TABLE_INCREMENT;
+
+ void *tmp;
+
+ /* Reallocate the line number buffer */
+
+ tmp = realloc(poffInfo->debugFuncTable, newAlloc);
+ if (!tmp)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* And set the new size */
+
+ poffInfo->debugFuncTableAlloc = newAlloc;
+ poffInfo->debugFuncTable = (uint8_t*)tmp;
+ }
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Add a debug inforamtion to the debug func table. Returns the index
+ * associated with the line number entry in the line number table.
+ */
+
+uint32_t poffAddDebugFuncInfo(poffHandle_t handle,
+ poffLibDebugFuncInfo_t *pContainer)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ poffDebugFuncInfo_t *pFuncInfo;
+ poffDebugArgInfo_t *pArgInfo;
+ uint32_t funcInfoIndex;
+ uint32_t argInfoIndex;
+ int i;
+
+ /* Verify that the debug info table has been allocated */
+
+ poffCheckDebugFuncInfoAllocation(poffInfo);
+
+ /* Verify that the debug infotable is large enough to hold
+ * information about function
+ */
+
+ poffCheckDebugFuncInfoReallocation(poffInfo, pContainer->nparms);
+
+ /* Save the information in the debug func info table */
+
+ funcInfoIndex = poffInfo->debugFuncSection.sh_size;
+ pFuncInfo = (poffDebugFuncInfo_t*)&poffInfo->debugFuncTable[funcInfoIndex];
+
+ pFuncInfo->df_value = pContainer->value;
+ pFuncInfo->df_size = pContainer->retsize;
+ pFuncInfo->df_nparms = pContainer->nparms;
+
+ argInfoIndex = funcInfoIndex + sizeof(poffDebugFuncInfo_t);
+ for (i = 0; i < pContainer->nparms; i++)
+ {
+ pArgInfo = (poffDebugArgInfo_t*)&poffInfo->debugFuncTable[argInfoIndex];
+ pArgInfo->da_size = pContainer->argsize[i];
+ argInfoIndex += sizeof(poffDebugArgInfo_t);
+ }
+
+ /* Set the new size of the debug func info table */
+
+ poffInfo->debugFuncSection.sh_size = argInfoIndex;
+ return funcInfoIndex;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfwfname.c b/misc/pascal/libpoff/pfwfname.c
new file mode 100644
index 000000000..9f6687aae
--- /dev/null
+++ b/misc/pascal/libpoff/pfwfname.c
@@ -0,0 +1,146 @@
+/**********************************************************************
+ * pfwfname.c
+ * Write filename data to a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Add a file name to the file table. Returns file number index value
+ * and NOT the byte offset associated with the file name entry in the
+ * file name section.
+ */
+
+uint32_t poffAddFileName(poffHandle_t handle, const char *name)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ poffFileTab_t ft;
+ uint32_t index;
+
+ /* Add the name to the string table */
+
+ ft = (poffFileTab_t)poffAddString(poffInfo, name);
+
+ /* Add string table offset to the file table
+ *
+ * Check if we have allocated a filename table buffer yet
+ */
+
+ if (!poffInfo->fileNameTable)
+ {
+ /* No, allocate it now */
+
+ poffInfo->fileNameTable = (poffFileTab_t*)malloc(INITIAL_FILENAME_TABLE_SIZE);
+ if (!poffInfo->fileNameTable)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ poffInfo->fileNameTableSection.sh_size = 0;
+ poffInfo->fileNameTableAlloc = INITIAL_FILENAME_TABLE_SIZE;
+ }
+
+ /* Check if there is room for the new file name index */
+
+ if (poffInfo->fileNameTableSection.sh_size + sizeof(poffFileTab_t)>
+ poffInfo->fileNameTableAlloc)
+ {
+ uint32_t newAlloc = poffInfo->fileNameTableAlloc + FILENAME_TABLE_INCREMENT;
+ void *tmp;
+
+ /* Reallocate the file name buffer */
+
+ tmp = realloc(poffInfo->fileNameTable, newAlloc);
+ if (!tmp)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* And set the new size */
+
+ poffInfo->fileNameTableAlloc = newAlloc;
+ poffInfo->fileNameTable = (poffFileTab_t*)tmp;
+ }
+
+ /* Save the index in the file name table */
+
+ index = poffInfo->fileNameTableSection.sh_size / sizeof(poffFileTab_t);
+ poffInfo->fileNameTable[index] = ft;
+
+ /* Set the new size of the file name table */
+
+ poffInfo->fileNameTableSection.sh_size += sizeof(poffFileTab_t);
+ return index;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfwhdr.c b/misc/pascal/libpoff/pfwhdr.c
new file mode 100644
index 000000000..2c8a2feb4
--- /dev/null
+++ b/misc/pascal/libpoff/pfwhdr.c
@@ -0,0 +1,116 @@
+/**********************************************************************
+ * pfwhdr.c
+ * Write to POFF file file and section headers
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Add the type of the file to the POFF file header */
+
+void poffSetFileType(poffHandle_t handle, uint8_t fh_type,
+ uint16_t nfiles, const char *name)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+
+ /* Save the type in the file header */
+
+ poffInfo->fileHeader.fh_type = fh_type;
+
+ /* Save the associated name in the string table */
+
+ poffInfo->fileHeader.fh_name = poffAddString(poffInfo, name);
+}
+
+/***********************************************************************/
+/* Add the machine architecture to the POFF file header */
+
+void poffSetArchitecture(poffHandle_t handle, uint8_t fh_arch)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+
+ /* Save the type in the file header */
+
+ poffInfo->fileHeader.fh_arch = fh_arch;
+}
+
+/***********************************************************************/
+/* Set the program entry point */
+
+void poffSetEntryPoint(poffHandle_t handle, uint32_t entryPoint)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ poffInfo->fileHeader.fh_entry = entryPoint;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfwlineno.c b/misc/pascal/libpoff/pfwlineno.c
new file mode 100644
index 000000000..4765391b9
--- /dev/null
+++ b/misc/pascal/libpoff/pfwlineno.c
@@ -0,0 +1,165 @@
+/**********************************************************************
+ * pfwlineno.c
+ * Write line number data to a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+static void poffCheckLineNumberAllocation(poffInfo_t *poffInfo)
+{
+ /* Check if we have allocated a line number buffer yet */
+
+ if (!poffInfo->lineNumberTable)
+ {
+ /* No, allocate it now */
+
+ poffInfo->lineNumberTable = (uint8_t*)
+ malloc(INITIAL_LINENUMBER_TABLE_SIZE);
+
+ if (!poffInfo->lineNumberTable)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ poffInfo->lineNumberSection.sh_size = 0;
+ poffInfo->lineNumberTableAlloc = INITIAL_LINENUMBER_TABLE_SIZE;
+ }
+}
+
+/***********************************************************************/
+
+static void poffCheckLineNumberReallocation(poffInfo_t *poffInfo)
+{
+ if (poffInfo->lineNumberSection.sh_size + sizeof(poffLineNumber_t) >
+ poffInfo->lineNumberTableAlloc)
+ {
+ uint32_t newAlloc =
+ poffInfo->lineNumberTableAlloc +
+ LINENUMBER_TABLE_INCREMENT;
+
+ void *tmp;
+
+ /* Reallocate the line number buffer */
+
+ tmp = realloc(poffInfo->lineNumberTable, newAlloc);
+ if (!tmp)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* And set the new size */
+
+ poffInfo->lineNumberTableAlloc = newAlloc;
+ poffInfo->lineNumberTable = (uint8_t*)tmp;
+ }
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Add a line number to the line number table. Returns index value
+ * associated with the line number entry in the line number table.
+ */
+
+uint32_t poffAddLineNumber(poffHandle_t handle,
+ uint16_t lineNumber, uint16_t fileNumber,
+ uint32_t progSectionDataOffset)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ poffLineNumber_t *pln;
+ uint32_t index;
+
+ /* Verify that the line number table has been allocated */
+
+ poffCheckLineNumberAllocation(poffInfo);
+
+ /* Verify that the line number table is large enough to hold
+ * information about another line.
+ */
+
+ poffCheckLineNumberReallocation(poffInfo);
+
+ /* Save the line number information in the line number table */
+
+ index = poffInfo->lineNumberSection.sh_size;
+ pln = (poffLineNumber_t*)&poffInfo->lineNumberTable[index];
+
+ pln->ln_lineno = lineNumber;
+ pln->ln_fileno = fileNumber;
+ pln->ln_poffset = progSectionDataOffset;
+
+ /* Set the new size of the line number table */
+
+ poffInfo->lineNumberSection.sh_size += sizeof(poffLineNumber_t);
+ return index;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfwprog.c b/misc/pascal/libpoff/pfwprog.c
new file mode 100644
index 000000000..1ecf70688
--- /dev/null
+++ b/misc/pascal/libpoff/pfwprog.c
@@ -0,0 +1,128 @@
+/**********************************************************************
+ * pfwprog.c
+ * Write program data to a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+void poffAddProgByte(poffHandle_t handle, uint8_t progByte)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+
+ /* Check if we have allocated a program section buffer yet */
+
+ if (!poffInfo->progSectionData)
+ {
+ /* No, allocate it now */
+
+ poffInfo->progSectionData = (uint8_t*)malloc(INITIAL_PROG_SECTION_SIZE);
+ if (!poffInfo->progSectionData)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ poffInfo->progSection.sh_size = 0;
+ poffInfo->progSectionAlloc = INITIAL_STRING_TABLE_SIZE;
+ }
+
+ /* Check if there is room for the new string */
+
+ if (poffInfo->progSection.sh_size + 1 > poffInfo->progSectionAlloc)
+ {
+ uint32_t newAlloc = poffInfo->progSectionAlloc + PROG_SECTION_INCREMENT;
+ void *tmp;
+
+ /* Reallocate the program data section buffer */
+
+ tmp = realloc(poffInfo->progSectionData, newAlloc);
+ if (!tmp)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* And set the new size */
+
+ poffInfo->progSectionAlloc = newAlloc;
+ poffInfo->progSectionData = (uint8_t*)tmp;
+ }
+
+ /* Copy program data byte into the program data buffer */
+
+ poffInfo->progSectionData[poffInfo->progSection.sh_size] = progByte;
+
+ /* Set the new size of the string table */
+
+ poffInfo->progSection.sh_size++;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfwreloc.c b/misc/pascal/libpoff/pfwreloc.c
new file mode 100644
index 000000000..e7b4def24
--- /dev/null
+++ b/misc/pascal/libpoff/pfwreloc.c
@@ -0,0 +1,162 @@
+/**********************************************************************
+ * pfwreloc.c
+ * Write relocation data to a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+static void poffCheckRelocationAllocation(poffInfo_t *poffInfo)
+{
+ /* Check if we have allocated a line number buffer yet */
+
+ if (!poffInfo->relocTable)
+ {
+ /* No, allocate it now */
+
+ poffInfo->relocTable = (uint8_t*)malloc(INITIAL_RELOC_TABLE_SIZE);
+ if (!poffInfo->relocTable)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ poffInfo->relocSection.sh_size = 0;
+ poffInfo->relocAlloc = INITIAL_RELOC_TABLE_SIZE;
+ }
+}
+
+/***********************************************************************/
+
+static void poffCheckRelocationReallocation(poffInfo_t *poffInfo)
+{
+ if (poffInfo->relocSection.sh_size + sizeof(poffRelocation_t) >
+ poffInfo->relocAlloc)
+ {
+ uint32_t newAlloc =
+ poffInfo->relocAlloc +
+ RELOC_TABLE_INCREMENT;
+
+ void *tmp;
+
+ /* Reallocate the line number buffer */
+
+ tmp = realloc(poffInfo->relocTable, newAlloc);
+ if (!tmp)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* And set the new size */
+
+ poffInfo->relocAlloc = newAlloc;
+ poffInfo->relocTable = (uint8_t*)tmp;
+ }
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Add a relocation to the relocation table. Returns index value
+ * associated with the relocation entry in the relocation table.
+ */
+
+uint32_t poffAddRelocation(poffHandle_t handle,
+ uint8_t relocType, uint32_t symIndex,
+ uint32_t sectionDataOffset)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ poffRelocation_t *prl;
+ uint32_t index;
+
+ /* Verify that the relocation table has been allocated */
+
+ poffCheckRelocationAllocation(poffInfo);
+
+ /* Verify that the relocation table is large enough to hold
+ * information about another relocation.
+ */
+
+ poffCheckRelocationReallocation(poffInfo);
+
+ /* Save the relocation information in the relocation table */
+
+ index = poffInfo->relocSection.sh_size;
+ prl = (poffRelocation_t*)&poffInfo->relocTable[index];
+
+ prl->rl_info = RLI_MAKE(symIndex, relocType);
+ prl->rl_offset = sectionDataOffset;
+
+ /* Set the new size of the line number table */
+
+ poffInfo->relocSection.sh_size += sizeof(poffRelocation_t);
+ return index;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfwrite.c b/misc/pascal/libpoff/pfwrite.c
new file mode 100644
index 000000000..984b3511b
--- /dev/null
+++ b/misc/pascal/libpoff/pfwrite.c
@@ -0,0 +1,541 @@
+/**********************************************************************
+ * libpoff/pfwrite.c
+ * Write a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+static uint16_t poffCountSections(poffHandle_t handle);
+static void poffWriteFileHeader(poffHandle_t handle, FILE *poffFile);
+static void poffWriteSectionHeaders(poffHandle_t handle, FILE *poffFile);
+static void poffWriteSectionData(poffHandle_t handle, FILE *poffFile);
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+static uint16_t poffCountSections(poffHandle_t handle)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ uint16_t nSections = 1; /* We always write the string table */
+
+ /* Count each other section that has stored data */
+
+ if (HAVE_PROGRAM_SECTION)
+ nSections++;
+
+ if (HAVE_RODATA_SECTION)
+ nSections++;
+
+ if (HAVE_SYMBOL_TABLE)
+ nSections++;
+
+ if (HAVE_RELOC_SECTION)
+ nSections++;
+
+ if (HAVE_FILE_TABLE)
+ nSections++;
+
+ if (HAVE_LINE_NUMBER)
+ nSections++;
+
+ if (HAVE_DEBUG_SECTION)
+ nSections++;
+
+ return nSections;
+}
+
+/***********************************************************************/
+
+static void poffWriteFileHeader(poffHandle_t handle, FILE *poffFile)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ size_t entriesWritten;
+
+ /* Get the number of section structures following the file header */
+
+ poffInfo->fileHeader.fh_shnum = poffCountSections(handle);
+
+ /* The POFF file is retained in big-endian order. Fixup fields as necessary */
+
+ poffSwapFileHeader(&poffInfo->fileHeader);
+
+ /* Write the POFF file header */
+
+ entriesWritten = fwrite(&poffInfo->fileHeader, sizeof(poffFileHeader_t),
+ 1, poffFile);
+ if (entriesWritten != 1)
+ {
+ errmsg("Failed to write POFF header: %s\n", strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+
+ /* Restore fields to host order */
+
+ poffSwapFileHeader(&poffInfo->fileHeader);
+}
+
+/***********************************************************************/
+
+static size_t poffWriteSectionHeader(poffSectionHeader_t *pheader, FILE *poffFile)
+{
+ size_t entriesWritten;
+
+ /* The POFF file is retained in big-endian order. Fixup fields as necessary */
+
+ poffSwapSectionHeader(pheader);
+
+ /* Write the POFF section header */
+
+ entriesWritten = fwrite(pheader, sizeof(poffSectionHeader_t), 1, poffFile);
+
+ /* Restore fields to host order */
+
+ poffSwapSectionHeader(pheader);
+ return entriesWritten;
+}
+
+/***********************************************************************/
+
+static void poffWriteSectionHeaders(poffHandle_t handle, FILE *poffFile)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+
+ /* The data starts immediately after the file header and the array
+ * of section headers.
+ */
+
+ uint32_t dataOffset = poffInfo->fileHeader.fh_shoff +
+ poffInfo->fileHeader.fh_shnum * poffInfo->fileHeader.fh_shsize;
+ size_t entriesWritten;
+
+ /* Write the program section header (if we have one) */
+
+ if (HAVE_PROGRAM_SECTION)
+ {
+ /* Add the name of the section to the string table */
+
+ poffInfo->progSection.sh_name = poffAddString(handle, ".text");
+ poffInfo->progSection.sh_offset = dataOffset;
+ dataOffset += poffInfo->progSection.sh_size;
+
+ /* Then write the section header to the output file */
+
+ entriesWritten = poffWriteSectionHeader(&poffInfo->progSection, poffFile);
+ if (entriesWritten != 1)
+ {
+ errmsg("Failed to write program section header: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+ }
+
+ /* Write the initialized read-only data section header (if we have one) */
+
+ if (HAVE_RODATA_SECTION)
+ {
+ /* Add the name of the section to the string table */
+
+ poffInfo->roDataSection.sh_name = poffAddString(handle, ".rodata");
+ poffInfo->roDataSection.sh_offset = dataOffset;
+ dataOffset += poffInfo->roDataSection.sh_size;
+
+ /* Then write the section header to the output file */
+
+ entriesWritten = poffWriteSectionHeader(&poffInfo->roDataSection, poffFile);
+ if (entriesWritten != 1)
+ {
+ errmsg("Failed to write data section header: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+ }
+
+ /* Write the symbol table section header (if we have one) */
+
+ if (HAVE_SYMBOL_TABLE)
+ {
+ /* Add the name of the section to the string table */
+
+ poffInfo->symbolTableSection.sh_name = poffAddString(handle, ".symtab");
+ poffInfo->symbolTableSection.sh_offset = dataOffset;
+ dataOffset += poffInfo->symbolTableSection.sh_size;
+
+ /* Then write the section header to the output file */
+
+ entriesWritten = poffWriteSectionHeader(&poffInfo->symbolTableSection, poffFile);
+ if (entriesWritten != 1)
+ {
+ errmsg("Failed to write symbol table section header: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+ }
+
+ /* Write the relocation table section header (if we have one) */
+
+ if (HAVE_RELOC_SECTION)
+ {
+ /* Add the name of the section to the string table */
+
+ poffInfo->relocSection.sh_name = poffAddString(handle, ".rel");
+ poffInfo->relocSection.sh_offset = dataOffset;
+ dataOffset += poffInfo->relocSection.sh_size;
+
+ /* Then write the section header to the output file */
+
+ entriesWritten = poffWriteSectionHeader(&poffInfo->relocSection, poffFile);
+ if (entriesWritten != 1)
+ {
+ errmsg("Failed to write relocation section header: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+ }
+
+ /* Write the file table section header (if we have one) */
+
+ if (HAVE_FILE_TABLE)
+ {
+ /* Add the name of the section to the string table */
+
+ poffInfo->fileNameTableSection.sh_name = poffAddString(handle, ".filetab");
+ poffInfo->fileNameTableSection.sh_offset = dataOffset;
+ dataOffset += poffInfo->fileNameTableSection.sh_size;
+
+ /* Then write the section header to the output file */
+
+ entriesWritten = poffWriteSectionHeader(&poffInfo->fileNameTableSection, poffFile);
+ if (entriesWritten != 1)
+ {
+ errmsg("Failed to write file table section header: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+ }
+
+ /* Write the line number section header (if we have one) */
+
+ if (HAVE_LINE_NUMBER)
+ {
+ /* Add the name of the section to the string table */
+
+ poffInfo->lineNumberSection.sh_name = poffAddString(handle, ".lineno");
+ poffInfo->lineNumberSection.sh_offset = dataOffset;
+ dataOffset += poffInfo->lineNumberSection.sh_size;
+
+ /* Then write the section header to the output file */
+
+ entriesWritten = poffWriteSectionHeader(&poffInfo->lineNumberSection, poffFile);
+ if (entriesWritten != 1)
+ {
+ errmsg("Failed to write line number section header: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+ }
+
+ /* Write the debug function info section header (if we have one) */
+
+ if (HAVE_DEBUG_SECTION)
+ {
+ /* Add the name of the section to the string table */
+
+ poffInfo->debugFuncSection.sh_name = poffAddString(handle, ".dbgfunc");
+ poffInfo->debugFuncSection.sh_offset = dataOffset;
+ dataOffset += poffInfo->debugFuncSection.sh_size;
+
+ /* Then write the section header to the output file */
+
+ entriesWritten = poffWriteSectionHeader(&poffInfo->debugFuncSection, poffFile);
+ if (entriesWritten != 1)
+ {
+ errmsg("Failed to write debug section header: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+ }
+
+ /* Write the string table section header LAST (because we may have
+ * added strings with the above logic.
+ */
+
+ /* Add the name of the section to the string table */
+
+ poffInfo->stringTableSection.sh_name = poffAddString(handle, ".strtab");
+ poffInfo->stringTableSection.sh_offset = dataOffset;
+ dataOffset += poffInfo->stringTableSection.sh_size;
+
+ /* Then write the section header to the output file */
+
+ entriesWritten = poffWriteSectionHeader(&poffInfo->stringTableSection, poffFile);
+ if (entriesWritten != 1)
+ {
+ errmsg("Failed to write string table section header: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+}
+
+/***********************************************************************/
+
+static void poffWriteSectionData(poffHandle_t handle, FILE *poffFile)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ size_t entriesWritten;
+
+ /* Write the program section data (if we have one) */
+
+ if (HAVE_PROGRAM_SECTION)
+ {
+ if (!poffInfo->progSectionData) fatal(ePOFFCONFUSION);
+
+ entriesWritten = fwrite(poffInfo->progSectionData, sizeof(uint8_t),
+ poffInfo->progSection.sh_size, poffFile);
+ if (entriesWritten != poffInfo->progSection.sh_size)
+ {
+ errmsg("Failed to write program data: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+ }
+
+ /* Write the read-only data section data (if we have one) */
+
+ if (HAVE_RODATA_SECTION)
+ {
+ if (!poffInfo->roDataSectionData) fatal(ePOFFCONFUSION);
+
+ entriesWritten = fwrite(poffInfo->roDataSectionData, sizeof(uint8_t),
+ poffInfo->roDataSection.sh_size, poffFile);
+ if (entriesWritten != poffInfo->roDataSection.sh_size)
+ {
+ errmsg("Failed to write initialized data: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+ }
+
+ /* Write the symbol table section data (if we have one) */
+
+ if (HAVE_SYMBOL_TABLE)
+ {
+ if (!poffInfo->symbolTable) fatal(ePOFFCONFUSION);
+
+ /* The POFF file is retained in big-endian order. Fixup fields as necessary */
+
+ poffSwapSymbolTableData(poffInfo);
+
+ /* Write the symbol table entries in big-endian order */
+
+ entriesWritten = fwrite(poffInfo->symbolTable, sizeof(uint8_t),
+ poffInfo->symbolTableSection.sh_size, poffFile);
+ if (entriesWritten != poffInfo->symbolTableSection.sh_size)
+ {
+ errmsg("Failed to write symbol table data: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+
+ /* Restore host data order */
+
+ poffSwapSymbolTableData(poffInfo);
+ }
+
+ /* Write the relocation table section data (if we have one) */
+
+ if (HAVE_RELOC_SECTION)
+ {
+ if (!poffInfo->relocTable) fatal(ePOFFCONFUSION);
+
+ /* The POFF file is retained in big-endian order. Fixup fields as necessary */
+
+ poffSwapRelocationData(poffInfo);
+
+ /* Write the relocation table entries in big-endian order */
+
+ entriesWritten = fwrite(poffInfo->relocTable, sizeof(uint8_t),
+ poffInfo->relocSection.sh_size, poffFile);
+ if (entriesWritten != poffInfo->relocSection.sh_size)
+ {
+ errmsg("Failed to write relocation data: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+
+ /* Restore host data order */
+
+ poffSwapRelocationData(poffInfo);
+ }
+
+ /* Write the file table section data (if we have one) */
+
+ if (HAVE_FILE_TABLE)
+ {
+ if (!poffInfo->fileNameTable) fatal(ePOFFCONFUSION);
+
+ /* The POFF file is retained in big-endian order. Fixup fields as necessary */
+
+ poffSwapFileTableData(poffInfo);
+
+ /* Write the file table entries in big-endian order */
+
+ entriesWritten = fwrite(poffInfo->fileNameTable, sizeof(uint8_t),
+ poffInfo->fileNameTableSection.sh_size,
+ poffFile);
+ if (entriesWritten != poffInfo->fileNameTableSection.sh_size)
+ {
+ errmsg("Failed to write filename table data: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+
+ /* Restore host data order */
+
+ poffSwapFileTableData(poffInfo);
+ }
+
+ /* Write the line number section data (if we have one) */
+
+ if (HAVE_LINE_NUMBER)
+ {
+ if (!poffInfo->lineNumberTable) fatal(ePOFFCONFUSION);
+
+ /* The POFF file is retained in big-endian order. Fixup fields as necessary */
+
+ poffSwapLineNumberData(poffInfo);
+
+ /* Write the line number table entries in big-endian order */
+
+ entriesWritten = fwrite(poffInfo->lineNumberTable, sizeof(uint8_t),
+ poffInfo->lineNumberSection.sh_size,
+ poffFile);
+ if (entriesWritten != poffInfo->lineNumberSection.sh_size)
+ {
+ errmsg("Failed to write line number table data: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+
+ /* Restore host order */
+
+ poffSwapLineNumberData(poffInfo);
+ }
+
+ /* Write the debug section data (if we have one) */
+
+ if (HAVE_DEBUG_SECTION)
+ {
+ if (!poffInfo->debugFuncTable) fatal(ePOFFCONFUSION);
+
+ /* The POFF file is retained in big-endian order. Fixup fields as necessary */
+
+ poffSwapDebugData(poffInfo);
+
+ /* Write the debug entries in big-endian order */
+
+ entriesWritten = fwrite(poffInfo->debugFuncTable, sizeof(uint8_t),
+ poffInfo->debugFuncSection.sh_size,
+ poffFile);
+ if (entriesWritten != poffInfo->debugFuncSection.sh_size)
+ {
+ errmsg("Failed to write debug table data: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+
+ /* Restore host order */
+
+ poffSwapDebugData(poffInfo);
+ }
+
+ /* Write the string table section data LAST (because we may have
+ * added strings with the above logic.
+ */
+
+ if (!poffInfo->stringTable) fatal(ePOFFCONFUSION);
+
+ entriesWritten = fwrite(poffInfo->stringTable, sizeof(uint8_t),
+ poffInfo->stringTableSection.sh_size, poffFile);
+ if (entriesWritten != poffInfo->stringTableSection.sh_size)
+ {
+ errmsg("Failed to write string table data: %s\n",
+ strerror(errno));
+ fatal(ePOFFWRITEERROR);
+ }
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+void poffWriteFile(poffHandle_t handle, FILE *poffFile)
+{
+ poffWriteFileHeader(handle, poffFile);
+ poffWriteSectionHeaders(handle, poffFile);
+ poffWriteSectionData(handle, poffFile);
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfwrodata.c b/misc/pascal/libpoff/pfwrodata.c
new file mode 100644
index 000000000..c6128b9aa
--- /dev/null
+++ b/misc/pascal/libpoff/pfwrodata.c
@@ -0,0 +1,193 @@
+/**********************************************************************
+ * pfwrodata.c
+ * Write to the RODATA section of a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+static uint16_t poffCheckRoDataAlloc(poffInfo_t *poffInfo)
+{
+ if (!poffInfo->roDataSectionData)
+ {
+ /* No, allocate it now */
+
+ poffInfo->roDataSectionData = (uint8_t*)malloc(INITIAL_RODATA_SECTION_SIZE);
+ if (!poffInfo->roDataSectionData)
+ {
+ return eNOMEMORY;
+ }
+
+ poffInfo->roDataSection.sh_size = 0;
+ poffInfo->roDataSectionAlloc = INITIAL_RODATA_SECTION_SIZE;
+ }
+ return eNOERROR;
+}
+
+static uint16_t poffCheckRoDataRealloc(poffInfo_t *poffInfo, uint16_t len)
+{
+ /* Check if there is room for the new data */
+
+ if (poffInfo->roDataSection.sh_size + len > poffInfo->roDataSectionAlloc)
+ {
+ uint32_t newAlloc;
+ void *tmp;
+
+ /* Make certain that this is big enough (it should be) */
+
+ newAlloc = poffInfo->roDataSectionAlloc + RODATA_SECTION_INCREMENT;
+ while (poffInfo->roDataSection.sh_size + len > newAlloc)
+ {
+ newAlloc += RODATA_SECTION_INCREMENT;
+ }
+
+ /* Reallocate the roDataram data section buffer */
+
+ tmp = realloc(poffInfo->roDataSectionData, newAlloc);
+ if (!tmp)
+ {
+ return eNOMEMORY;
+ }
+
+ /* And set the new size */
+
+ poffInfo->roDataSectionAlloc = newAlloc;
+ poffInfo->roDataSectionData = (uint8_t*)tmp;
+ }
+ return eNOERROR;
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+#if 0 /* Not used */
+uint32_t poffAddRoDataByte(poffHandle_t handle, uint8_t dataByte)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ uint32_t offset;
+ uint16_t errCode;
+
+ /* Check if we have allocated a data section buffer yet */
+
+ errCode = poffCheckRoDataAlloc(poffInfo);
+ if (errCode != eNOERROR)
+ {
+ fatal(errCode);
+ }
+
+ /* Check if there is room for a new byte */
+
+ errCode = poffCheckRoDataRealloc(poffInfo, 1);
+
+ /* Copy data section byte into the data section buffer */
+
+ offset = poffInfo->roDataSection.sh_size;
+ poffInfo->roDataSectionData[offset] = dataByte;
+
+ /* Set the new size of the string table */
+
+ poffInfo->roDataSection.sh_size++;
+ return offset;
+}
+#endif
+
+/***********************************************************************/
+
+uint32_t poffAddRoDataString(poffHandle_t handle, const char *string)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ uint32_t len;
+ uint32_t offset;
+ uint16_t errCode;
+
+ /* Check if we have allocated a data section buffer yet */
+
+ errCode = poffCheckRoDataAlloc(poffInfo);
+ if (errCode != eNOERROR)
+ {
+ fatal(errCode);
+ }
+
+ /* Check if there is room for a new byte */
+
+ len = strlen(string) + 1;
+ errCode = poffCheckRoDataRealloc(poffInfo, len);
+
+ /* Copy data section byte into the data section buffer */
+
+ offset = poffInfo->roDataSection.sh_size;
+ memcpy(&poffInfo->roDataSectionData[offset], string, len);
+
+ /* Set the new size of the string table */
+
+ poffInfo->roDataSection.sh_size += len;
+ return offset;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfwstring.c b/misc/pascal/libpoff/pfwstring.c
new file mode 100644
index 000000000..45669576d
--- /dev/null
+++ b/misc/pascal/libpoff/pfwstring.c
@@ -0,0 +1,218 @@
+/**********************************************************************
+ * pfwstring.c
+ * Write string table data a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Search the string table for an occurrence of the indicates string.
+ * If found, return the offset in the string table to the string; if
+ * not found, return -1.
+ */
+
+int32_t poffFindString(poffHandle_t handle, const char *string)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ char *sptr = poffInfo->stringTable;
+ uint32_t offset;
+
+ /* Has the string table been allocated yet? */
+
+ if (!poffInfo->stringTable) return -1;
+
+ /* Handle the NULL string case. Offset zero is reserved for the NULL
+ * string and for the zero-size string.
+ */
+
+ if (!string) return 0;
+
+ /* Okay, we will have to search the table */
+
+ for (offset = 0;
+ offset < poffInfo->stringTableSection.sh_size;
+ offset += (strlen(sptr) + 1))
+ {
+ /* Get a pointer at this offset into the string table */
+
+ sptr = &poffInfo->stringTable[offset];
+
+ /* Check if the strings match. If so, return the offset */
+
+ if (strcmp(sptr, string) == 0) return offset;
+ }
+
+ /* The string does not exist in the string table */
+
+ return -1;
+}
+
+/***********************************************************************/
+/***********************************************************************/
+/* Add a string to the string table and return the offset to the
+ * string storage location in the string table section data.
+ */
+
+uint32_t poffAddString(poffHandle_t handle, const char *string)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ int32_t index;
+ int len;
+
+ /* Check if we have allocated a string table buffer yet */
+
+ if (!poffInfo->stringTable)
+ {
+ /* No, allocate it now */
+
+ poffInfo->stringTable = (char*)malloc(INITIAL_STRING_TABLE_SIZE);
+ if (!poffInfo->stringTable)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* Index 0 is reserved for the NULL string */
+
+ poffInfo->stringTable[0] = '\0';
+ poffInfo->stringTableSection.sh_size = 1;
+ poffInfo->stringTableAlloc = INITIAL_STRING_TABLE_SIZE;
+ }
+
+ /* Check if the string is already defined in the string table.
+ * This is very time consuming, but guaratees that we do not keep
+ * duplicate strings in the string table.
+ */
+
+ index = poffFindString(handle, string);
+ if (index < 0)
+ {
+ /* The string was not found in the string table. Check for the
+ * NULL string. In this case, return index == 0. NOTE: This
+ * check is pointless. If this is any kind of NULL string, then
+ * poffFindString will have returned index == 0.
+ */
+
+ if ((string == NULL) || ((len = strlen(string)) <= 0))
+ {
+ index = 0;
+ }
+ else
+ {
+ /* Increment the length to include the null terminator */
+
+ len++;
+
+ /* Check if there is room for the new string */
+
+ if (poffInfo->stringTableSection.sh_size + len >
+ poffInfo->stringTableAlloc)
+ {
+ uint32_t newAlloc =
+ poffInfo->stringTableAlloc + STRING_TABLE_INCREMENT;
+ void *tmp;
+
+ /* Make sure that the new string will fit in the new allocation
+ * size (shouldn't happen)
+ */
+
+ while (poffInfo->stringTableSection.sh_size + len > newAlloc)
+ newAlloc += STRING_TABLE_INCREMENT;
+
+ /* Reallocate the string buffer */
+
+ tmp = realloc(poffInfo->stringTable, newAlloc);
+ if (!tmp)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* And set the new size */
+
+ poffInfo->stringTableAlloc = newAlloc;
+ poffInfo->stringTable = (char*)tmp;
+ }
+
+ /* Copy the string into the string table */
+
+ index = poffInfo->stringTableSection.sh_size;
+ memcpy(&poffInfo->stringTable[index], string, len);
+
+ /* Set the new size of the string table */
+
+ poffInfo->stringTableSection.sh_size += len;
+ }
+ }
+ return index;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfwsymbol.c b/misc/pascal/libpoff/pfwsymbol.c
new file mode 100644
index 000000000..0a0beb2be
--- /dev/null
+++ b/misc/pascal/libpoff/pfwsymbol.c
@@ -0,0 +1,152 @@
+/**********************************************************************
+ * pfwsymbol.c
+ * Write symbol information to a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Add a symbol to the symbol table section data. Returns index value
+ * associated with the symbol entry in the symbol table section data.
+ */
+
+uint32_t poffAddSymbol(poffHandle_t handle, poffLibSymbol_t *symbol)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ poffSymbol_t *psym;
+ uint32_t st_name;
+ uint32_t index;
+
+ /* Add the name to the string table */
+
+ st_name = poffAddString(poffInfo, symbol->name);
+
+ /* Check if we have allocated a symbol table buffer yet */
+
+ if (!poffInfo->symbolTable)
+ {
+ /* No, allocate it now */
+
+ poffInfo->symbolTable = (uint8_t*)malloc(INITIAL_SYMBOL_TABLE_SIZE);
+ if (!poffInfo->symbolTable)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ poffInfo->symbolTableSection.sh_size = 0;
+ poffInfo->symbolTableAlloc = INITIAL_SYMBOL_TABLE_SIZE;
+ }
+
+ /* Check if there is room for a new symbol */
+
+ if (poffInfo->symbolTableSection.sh_size +
+ poffInfo->symbolTableSection.sh_entsize >
+ poffInfo->symbolTableAlloc)
+ {
+ uint32_t newAlloc = poffInfo->symbolTableAlloc + SYMBOL_TABLE_INCREMENT;
+ uint8_t *tmp;
+
+ /* Reallocate the file name buffer */
+
+ tmp = (uint8_t*)realloc(poffInfo->symbolTable, newAlloc);
+ if (!tmp)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* And set the new size */
+
+ poffInfo->symbolTableAlloc = newAlloc;
+ poffInfo->symbolTable = tmp;
+ }
+
+ /* Save the new symbol information in the symbol table data */
+
+ index = poffInfo->symbolTableSection.sh_size;
+ psym = (poffSymbol_t*)&poffInfo->symbolTable[index];
+
+ psym->st_type = symbol->type;
+ psym->st_align = symbol->align;
+ psym->st_flags = symbol->flags;
+ psym->st_pad = 0;
+ psym->st_name = st_name;
+ psym->st_value = symbol->value;
+ psym->st_size = symbol->size;
+
+ /* Set the new size of the file name table */
+
+ poffInfo->symbolTableSection.sh_size += poffInfo->symbolTableSection.sh_entsize;
+ return index / poffInfo->symbolTableSection.sh_entsize;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfxprog.c b/misc/pascal/libpoff/pfxprog.c
new file mode 100644
index 000000000..238e109be
--- /dev/null
+++ b/misc/pascal/libpoff/pfxprog.c
@@ -0,0 +1,96 @@
+/**********************************************************************
+ * pfxprog.c
+ * Extract program data from a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+uint32_t poffExtractProgramData(poffHandle_t handle, uint8_t **progData)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ uint32_t size;
+
+ /* Give the program data to the caller */
+
+ *progData = poffInfo->progSectionData;
+ size = poffInfo->progSection.sh_size;
+
+ /* Indicate the no program data is owned by the container */
+
+ poffInfo->progSection.sh_size = 0;
+ poffInfo->progSectionData = NULL;
+ poffInfo->progSectionAlloc = 0;
+ poffInfo->progSectionIndex = 0;
+
+ return size;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pfxrodata.c b/misc/pascal/libpoff/pfxrodata.c
new file mode 100644
index 000000000..87ae3c4c6
--- /dev/null
+++ b/misc/pascal/libpoff/pfxrodata.c
@@ -0,0 +1,95 @@
+/**********************************************************************
+ * pfxrodata.c
+ * Extract program read-only data from a POFF file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h" /* Standard types */
+#include "pedefs.h" /* error code definitions */
+
+#include "perr.h" /* error() */
+#include "pofflib.h" /* POFF library interface */
+#include "pfprivate.h" /* POFF private definitions */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+
+uint32_t poffExtractRoData(poffHandle_t handle, uint8_t **roData)
+{
+ poffInfo_t *poffInfo = (poffInfo_t*)handle;
+ uint32_t size;
+
+ /* Give the program data to the caller */
+
+ *roData = poffInfo->roDataSectionData;
+ size = poffInfo->roDataSection.sh_size;
+
+ /* Indicate the no program data is owned by the container */
+
+ poffInfo->roDataSection.sh_size = 0;
+ poffInfo->roDataSectionData = NULL;
+ poffInfo->roDataSectionAlloc = 0;
+
+ return size;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/libpoff/pofferr.c b/misc/pascal/libpoff/pofferr.c
new file mode 100644
index 000000000..3253acdfd
--- /dev/null
+++ b/misc/pascal/libpoff/pofferr.c
@@ -0,0 +1,94 @@
+/**********************************************************************
+ * pofferr.c
+ * Simple error handlers
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "keywords.h"
+
+#include "perr.h"
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+void errmsg(char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
+/***********************************************************************/
+
+void warn(uint16_t errcode)
+{
+ /* Write error record to the error and list files */
+
+ fprintf(stderr, "WARNING: %d\n", errcode);
+} /* end warn */
+
+/***********************************************************************/
+
+void error(uint16_t errcode)
+{
+ fatal(errcode);
+} /* end error */
+
+/***********************************************************************/
+
+void fatal(uint16_t errcode)
+{
+ fprintf(stderr, "Fatal Error %d -- Aborting\n", errcode);
+ exit(errcode);
+} /* end fatal */
+
+/***********************************************************************/
diff --git a/misc/pascal/nuttx/INSTALL.sh b/misc/pascal/nuttx/INSTALL.sh
new file mode 100755
index 000000000..416718632
--- /dev/null
+++ b/misc/pascal/nuttx/INSTALL.sh
@@ -0,0 +1,166 @@
+############################################################################
+# nuttx/INSTALL.sh
+# Install the pascaldirl runtime into the NuttX source tree
+#
+# Copyright (C) 2008, 2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+# Parse command arguments
+
+wd=`pwd`
+
+modeldir=insn16
+unset installdir
+while [ ! -z "$1" ]; do
+ case "$1" in
+ -d )
+ set -x
+ ;;
+ -16 )
+ modeldir=insn16
+ ;;
+ -32 )
+ modeldir=insn32
+ ;;
+ -h )
+ echo "USAGE: $0 [-16|-32] <install-dir>"
+ exit 0
+ ;;
+ *)
+ installdir=$1
+ ;;
+ esac
+ shift
+done
+
+echo "Installing model $modeldir to $installdir"
+
+# Verify that required parameters were provided
+
+if [ -z "${installdir}" ]; then
+ echo "USAGE: $0 [-16|-32] <install-dir>"
+ exit 1
+fi
+
+# Find the directory we were executed from and that things look sane
+
+myname=`basename $0`
+
+if [ -x ${wd}/${myname} ] ; then
+ pascaldir=`dirname ${wd}`
+else
+ if [ -x ${wd}/nuttx/${myname} ] ; then
+ pascaldir=${wd}
+ else
+ echo "You must cd into the pascal directory to execute this script."
+ exit 1
+ fi
+fi
+
+if [ ! -d ${pascaldir}/${modeldir} ]; then
+ echo "Subdirectory ${modeldir} does not exist"
+ exit 1
+fi
+
+if [ ! -d ${installdir} ]; then
+ echo "NuttX apps/ sub-directory ${installdir} does not exist"
+ exit 1
+fi
+
+if [ -d ${installdir}/pcode ]; then
+ echo "${installdir}/pcode already exists. Remove it and try again."
+ exit 1
+fi
+
+# Looks good enough. Create NuttX directories
+
+mkdir ${installdir}/pcode || \
+ { echo "mkdir ${installdir}/pcode failed" ; exit 1 ; }
+
+mkdir ${installdir}/pcode/include || \
+ { echo "mkdir ${installdir}/pcode/include failed" ; exit 1 ; }
+
+mkdir ${installdir}/pcode/insn || \
+ { echo "mkdir ${installdir}/pcode/insn failed" ; exit 1 ; }
+
+mkdir ${installdir}/pcode/insn/include || \
+ { echo "mkdir ${installdir}/pcode/insn/include failed" ; exit 1 ; }
+
+mkdir ${installdir}/pcode/insn/prun || \
+ { echo "mkdir ${installdir}/pcode/insn/prun failed" ; exit 1 ; }
+
+mkdir ${installdir}/pcode/libpoff || \
+ { echo "mkdir ${installdir}/pcode/libpoff failed" ; exit 1 ; }
+
+mkdir ${installdir}/pcode/libpas || \
+ { echo "mkdir ${installdir}/pcode/libpas failed" ; exit 1 ; }
+
+# Copy runtime files
+
+cp -a ${pascaldir}/include/poff.h ${pascaldir}/include/pofflib.h \
+ ${pascaldir}/include/pedefs.h ${pascaldir}/include/perr.h \
+ ${pascaldir}/include/pdefs.h ${pascaldir}/include/pfdefs.h \
+ ${pascaldir}/include/pxdefs.h ${pascaldir}/include/paslib.h \
+ ${installdir}/pcode/include/. || \
+ { echo "Failed to copy ${pascaldir}/include" ; exit 1; }
+
+echo "#ifndef __CONFIG_H" >${installdir}/pcode/include/config.h
+echo "#define __CONFIG_H 1" >>${installdir}/pcode/include/config.h
+echo "" >>${installdir}/pcode/include/config.h
+echo "#undef CONFIG_DEBUG" >>${installdir}/pcode/include/config.h
+echo "#undef CONFIG_TRACE" >>${installdir}/pcode/include/config.h
+echo "#define CONFIG_INSN16 1" >>${installdir}/pcode/include/config.h
+echo "#undef CONFIG_INSN32" >>${installdir}/pcode/include/config.h
+echo "" >>${installdir}/pcode/include/config.h
+echo "#endif /* __CONFIG_H */" >>${installdir}/pcode/include/config.h
+
+cp -a ${pascaldir}/nuttx/Makefile ${installdir}/pcode/. || \
+ { echo "Failed to copy ${pascaldir}/nuttx/Makefile" ; exit 1; }
+
+cp -a ${pascaldir}/nuttx/keywords.h ${installdir}/pcode/include/. || \
+ { echo "Failed to copy ${pascaldir}/nuttx/keywords.h" ; exit 1; }
+
+cp -a ${pascaldir}/libpoff/*.c ${pascaldir}/libpoff/*.h \
+ ${pascaldir}/libpoff/Make.defs ${installdir}/pcode/libpoff/. || \
+ { echo "Failed to copy ${pascaldir}/libpoff" ; exit 1; }
+
+cp -a ${pascaldir}/libpas/psignextend16.c ${pascaldir}/libpas/pswap.c \
+ ${pascaldir}/libpas/Make.defs ${installdir}/pcode/libpas/. || \
+ { echo "Failed to copy ${pascaldir}/libpas" ; exit 1; }
+
+cp -a ${pascaldir}/${modeldir}/include/pexec.h ${pascaldir}/${modeldir}/include/pinsn16.h \
+ ${installdir}/pcode/insn/include/. || \
+ { echo "Failed to copy ${pascaldir}/${modeldir}/include" ; exit 1; }
+
+cp -a ${pascaldir}/${modeldir}/prun/pexec.c ${pascaldir}/${modeldir}/prun/pload.c \
+ ${pascaldir}/${modeldir}/prun/Make.defs ${installdir}/pcode/insn/prun/. || \
+ { echo "Failed to copy ${pascaldir}/${modeldir}/prun" ; exit 1; }
diff --git a/misc/pascal/nuttx/Makefile b/misc/pascal/nuttx/Makefile
new file mode 100644
index 000000000..eb82e48bd
--- /dev/null
+++ b/misc/pascal/nuttx/Makefile
@@ -0,0 +1,138 @@
+############################################################################
+# apps/interpreters/pcode/Makefile
+#
+# Copyright (C) 2008-2009, 2011-2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+PCODEDIR := ${shell pwd | sed -e 's/ /\\ /g'}
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# Default tools
+
+ifeq ($(DIRLINK),)
+DIRLINK = $(TOPDIR)/tools/link.sh
+DIRUNLINK = $(TOPDIR)/tools/unlink.sh
+endif
+INCDIR = $(TOPDIR)/tools/incdir.sh
+
+ifeq ($(WINTOOL),y)
+INCDIROPT = -w
+endif
+
+USRINCLUDES = ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(PCODEDIR)/include $(PCODEDIR)/insn/include}
+
+COMPILER = ${shell basename $(CC)}
+ifeq ($(COMPILER),zneocc.exe)
+INCLUDES = $(ARCHSTDINCLUDES) $(USRINCLUDES)
+else
+INCLUDES = $(ARCHINCLUDES) $(USRINCLUDES)
+endif
+
+CFLAGS = $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(INCLUDES) $(ARCHDEFINES)
+
+include insn/prun/Make.defs
+include libpoff/Make.defs
+include libpas/Make.defs
+
+ASRCS = $(PRUN_ASRCS) $(POFF_ASRCS) $(PAS_ASRCS)
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+
+CSRCS = $(PRUN_CSRCS) $(POFF_CSRCS) $(PAS_CSRCS)
+COBJS = $(CSRCS:.c=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS)
+OBJS = $(AOBJS) $(COBJS)
+
+ifeq ($(WINTOOL),y)
+ BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}"
+else
+ BIN = "$(APPDIR)/libapps$(LIBEXT)"
+endif
+
+ROOTDEPPATH = --dep-path .
+PRUNDEPPATH = --dep-path insn/prun
+POFFDEPPATH = --dep-path libpoff
+PASDEPPATH = --dep-path libpas
+
+VPATH = insn/prun:libpoff:libpas
+
+all: .built
+.PHONY: context depend clean distclean
+
+$(AOBJS): %$(OBJEXT): %.S
+ifeq ($(COMPILER),zneocc.exe)
+ $(call ASSEMBLE, `cygpath -w $<`, $@)
+else
+ $(call ASSEMBLE, $<, $@)
+endif
+
+$(COBJS): %$(OBJEXT): %.c
+ifeq ($(COMPILER),zneocc.exe)
+ $(call COMPILE, `cygpath -w $<`, $@)
+else
+ $(call COMPILE, $<, $@)
+endif
+
+$(APPDIR)/include/pcode: include
+ @$(DIRLINK) $(PCODEDIR)/include $(APPDIR)/include/pcode
+
+$(APPDIR)/include/pcode/insn: $(APPDIR)/include/pcode insn/include
+ @$(DIRLINK) $(PCODEDIR)/insn/include $(APPDIR)/include/pcode/insn
+
+.built: $(APPDIR)/include/pcode $(APPDIR)/include/pcode/insn $(OBJS)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $(BIN), $${obj}); \
+ done ; )
+ @touch .built
+
+context: $(APPDIR)/include/pcode $(APPDIR)/include/pcode/insn
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(ROOTDEPPATH) $(PRUNDEPPATH) $(POFFDEPPATH) $(PASDEPPATH) \
+ $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f *.o *~ .*.swp .built
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+ @$(DIRUNLINK) $(APPDIR)/include/pcode/insn
+ @$(DIRUNLINK) $(APPDIR)/include/pcode
+
+-include Make.dep
diff --git a/misc/pascal/nuttx/README.txt b/misc/pascal/nuttx/README.txt
new file mode 100644
index 000000000..9452d19fa
--- /dev/null
+++ b/misc/pascal/nuttx/README.txt
@@ -0,0 +1,43 @@
+pascal/nuttx/README.txt
+^^^^^^^^^^^^^^^^^^^^^^^
+
+This directory contains miscellaneous files needed to install the pascal
+runtime logic into the NuttX apps/ ource tree. After installation, the NuttX
+apps/ source tree contain the following files
+
+ pcode
+ |-- Makefile
+ |-- include
+ | `-- Common header files
+ |-- libboff
+ | `-- Pascal object format (POFF) library
+ `--insn
+ |-- include
+ | `-- model-specific header files
+ `-- prun
+ `-- model-specific source files
+
+This directory contains:
+
+ INSTALL.sh -- The script that performs the operation. Usage:
+
+ ./INSTALL.sh [-16|-32] <install-dir>
+
+ If you are using the standard NuttX apps/ package, the correct
+ location for the <install-dir> is apps/interpreters. That is
+ where the examples and build logic will expect to find the pcode
+ sub-directory.
+
+ Example:
+
+ ./INSTALL.sh -16 $PWD/../../../apps/interpreters
+
+ Makefile -- The NuttX makefile for the runtime logic. This makefile
+ is customized to work in the standard apps/ package. If you intend
+ to use your own custom apps/ directory, then this Makefile may
+ require some modifications.
+
+ keywords.h -- A version that adjusts build context for the NuttX
+ build environment.
+
+
diff --git a/misc/pascal/nuttx/keywords.h b/misc/pascal/nuttx/keywords.h
new file mode 100644
index 000000000..af84b5707
--- /dev/null
+++ b/misc/pascal/nuttx/keywords.h
@@ -0,0 +1,67 @@
+/*************************************************************
+ * keywords.h
+ * This file defines the pascal compilation environment
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************/
+
+#ifndef __KEYWORDS_H
+#define __KEYWORDS_H
+
+/*************************************************************
+ * Included Files
+ *************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+#include <debug.h>
+
+/*************************************************************
+ * Definitions
+ *************************************************************/
+
+#ifndef CONFIG_DEBUG
+# define CONFIG_DEBUG 0
+#endif
+
+#ifndef CONFIG_TRACE
+# define CONFIG_TRACE 0
+#endif
+
+#ifdef CONFIG_CPP_HAVE_VARARGS
+# define DEBUG(stream, format, arg...) dbg(format, ##arg)
+# define TRACE(stream, format, arg...) dbg(format, ##arg)
+#else
+# define DEBUG dbg
+# define TRACE dbg
+#endif
+
+#endif /* __KEYWORDS_H */
diff --git a/misc/pascal/pascal/Makefile b/misc/pascal/pascal/Makefile
new file mode 100644
index 000000000..3a758f648
--- /dev/null
+++ b/misc/pascal/pascal/Makefile
@@ -0,0 +1,85 @@
+############################################################################
+# pascal/Makefile
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Directories
+#
+PASDIR = ${shell pwd}
+PASCAL = $(PASDIR)/..
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+INCDIR = $(PASCAL)/include
+LIBDIR = $(PASCAL)/lib
+BINDIR-$(CONFIG_INSN16) = $(PASCAL)/bin16
+BINDIR-$(CONFIG_INSN32) = $(PASCAL)/bin32
+
+#
+# Objects and targets
+#
+PASSRCS = pas.c pprgm.c punit.c pblck.c pstm.c pexpr.c \
+ pcexpr.c pproc.c pffunc.c pcfunc.c pgen.c ptkn.c \
+ ptbl.c perr.c
+PASOBJS = $(PASSRCS:.c=.o)
+
+OBJS = $(PASOBJS)
+
+all: pascal
+.PHONY: all pascal clean
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+check_libs:
+ @if [ ! -f $(LIBDIR)/libpoff.a ] ; then \
+ echo "$(LIBDIR)/libpoff.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libpas.a ] ; then \
+ echo "$(LIBDIR)/libpas.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libinsn.a ] ; then \
+ echo "$(LIBDIR)/libinsn.a does not exist" ; \
+ exit 1 ; \
+ fi
+
+$(BINDIR-y)/pascal: check_libs $(PASOBJS)
+ $(CC) -o $@ $(LDFLAGS) $(PASOBJS) -linsn -lpoff -lpas -lm
+
+pascal: $(BINDIR-y)/pascal
+
+clean:
+ $(RM) pascal *.o core *~
diff --git a/misc/pascal/pascal/pas.c b/misc/pascal/pascal/pas.c
new file mode 100644
index 000000000..b0975c42f
--- /dev/null
+++ b/misc/pascal/pascal/pas.c
@@ -0,0 +1,538 @@
+/**********************************************************************
+ * pas.c
+ * Main process
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "config.h"
+#include "keywords.h"
+#include "pasdefs.h"
+#include "ptdefs.h"
+#include "podefs.h"
+#include "pedefs.h"
+
+#include "pas.h"
+#include "paslib.h" /* For extension */
+#include "pproc.h" /* For primeBuiltInProcedures */
+#include "pfunc.h" /* For primeBuiltInFunctions */
+#include "ptkn.h" /* For primeTokenizer */
+#include "ptbl.h" /* For primeSymbolTable */
+#include "pofflib.h" /* For poffInitializeForOutput() */
+#include "poff.h" /* For POFF definitions */
+#include "pprgm.h" /* for program() */
+#include "punit.h" /* for unit() */
+#include "perr.h" /* for error() */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/* Unitialized Global Data */
+
+uint16_t token; /* Current token */
+uint16_t tknSubType; /* Extended token type */
+int32_t tknInt; /* Integer token value */
+double tknReal; /* Real token value */
+STYPE *tknPtr; /* Pointer to symbol token*/
+WTYPE withRecord; /* RECORD used with WITH statement */
+FTYPE files[MAX_FILES+1]; /* File Table */
+fileState_t fileState[MAX_INCL]; /* State of all open files */
+
+/* sourceFileName : Program name from command line
+ * includePath[] : Pathes to search when including file
+ */
+
+char *sourceFileName;
+char *includePath[MAX_INCPATHES];
+
+poffHandle_t poffHandle; /* Handle for POFF object */
+
+FILE *poffFile; /* Pass1 POFF output file */
+FILE *lstFile; /* List File pointer */
+FILE *errFile; /* Error file pointer */
+
+/* Initialized Global Data */
+
+int16_t level = 0; /* Static nesting level */
+int16_t includeIndex = 0; /* Include file index */
+int16_t nIncPathes = 0; /* Number pathes in includePath[] */
+uint16_t label = 0; /* Last label number */
+int16_t nsym = 0; /* Number symbol table entries */
+int16_t nconst = 0; /* Number constant table entries */
+int16_t sym_strt = 0; /* Symbol search start index */
+int16_t const_strt = 0; /* Constant search start index */
+int16_t err_count = 0; /* Error counter */
+int16_t nfiles = 0; /* Program file counter */
+int32_t warn_count = 0; /* Warning counter */
+int32_t dstack = 0; /* data stack size */
+
+/**********************************************************************
+ * Private Type Definitions
+ **********************************************************************/
+
+struct outFileDesc_s
+{
+ const char *extension;
+ const char *flags;
+ FILE **stream;
+};
+typedef struct outFileDesc_s outFileDesc_t;
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static const outFileDesc_t outFiles[] =
+{
+ { "o1", "wb", &poffFile }, /* Pass 1 POFF object file */
+#if LSTTOFILE
+ { "lst", "w", &lstFile }, /* List file */
+#endif
+ { "err", "w", &errFile }, /* Error file */
+ { NULL, NULL } /* (terminates list */
+};
+
+static const char *programName;
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+static void closeFiles(void);
+static void openOutputFiles(void);
+static void showUsage(void);
+static void parseArguments(int argc, char **argv);
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+static void closeFiles(void)
+{
+ const outFileDesc_t *outFile;
+
+ /* Close input source files */
+
+ for(; includeIndex >= 0; includeIndex--)
+ {
+ if (FP->stream)
+ {
+ (void)fclose(FP->stream);
+ FP->stream = NULL;
+ }
+ }
+
+ /* Close output files */
+
+ for (outFile = outFiles; outFile->extension; outFile++)
+ {
+ if (*outFile->stream)
+ {
+ (void)fclose(*outFile->stream);
+ *outFile->stream = NULL;
+ }
+ }
+}
+
+/***********************************************************************/
+
+static void openOutputFiles(void)
+{
+ const outFileDesc_t *outFile;
+ char tmpname[FNAME_SIZE+1];
+
+ /* Open output files */
+
+ for (outFile = outFiles; outFile->extension; outFile++)
+ {
+ /* Generate an output file name from the source file
+ * name and an extension associated with the output file.
+ */
+
+ (void)extension(sourceFileName, outFile->extension, tmpname, 1);
+ *outFile->stream = fopen(tmpname, outFile->flags);
+ if (*outFile->stream == NULL)
+ {
+ fprintf(stderr, "Could not open output file '%s': %s\n",
+ tmpname, strerror(errno));
+ showUsage();
+ }
+ }
+}
+
+/***********************************************************************/
+
+static void signalHandler(int signo)
+{
+#ifdef _GNU_SOURCE
+ fprintf(errFile, "Received signal: %s\n", strsignal(signo));
+ fprintf(lstFile, "Received signal: %s\n", strsignal(signo));
+#else
+ fprintf(errFile, "Received signal %d\n", signo);
+ fprintf(lstFile, "Received signal %d\n", signo);
+#endif
+ closeFiles();
+ error(eRCVDSIGNAL);
+ exit(1);
+}
+
+/***********************************************************************/
+
+static void primeSignalHandlers(void)
+{
+ (void)signal(SIGHUP, signalHandler);
+ (void)signal(SIGINT, signalHandler);
+ (void)signal(SIGQUIT, signalHandler);
+ (void)signal(SIGILL, signalHandler);
+ (void)signal(SIGABRT, signalHandler);
+ (void)signal(SIGSEGV, signalHandler);
+ (void)signal(SIGTERM, signalHandler);
+}
+
+/***********************************************************************/
+
+static void showUsage(void)
+{
+ fprintf(stderr, "USAGE:\n");
+ fprintf(stderr, " %s [options] <filename>\n", programName);
+ fprintf(stderr, "[options]\n");
+ fprintf(stderr, " -I<include-path>\n");
+ fprintf(stderr, " Search in <include-path> for additional file\n");
+ fprintf(stderr, " A maximum of %d pathes may be specified\n",
+ MAX_INCPATHES);
+ fprintf(stderr, " (default is current directory)\n");
+ closeFiles();
+ exit(1);
+} /* end showUsage */
+
+/***********************************************************************/
+
+static void parseArguments(int argc, char **argv)
+{
+ int i;
+
+ programName = argv[0];
+
+ /* Check for existence of at least the filename argument */
+
+ if (argc < 2)
+ {
+ fprintf(stderr, "Invalid number of arguments\n");
+ showUsage();
+ }
+
+ /* Parse any optional command line arguments */
+
+ for (i = 1; i < argc-1; i++)
+ {
+ char *ptr = argv[i];
+ if (ptr[0] == '-')
+ {
+ switch (ptr[1])
+ {
+ case 'I' :
+ if (nIncPathes >= MAX_INCPATHES)
+ {
+ fprintf(stderr, "Unrecognized [option]\n");
+ showUsage();
+ }
+ else
+ {
+ includePath[nIncPathes] = &ptr[2];
+ nIncPathes++;
+ }
+ break;
+ default:
+ fprintf(stderr, "Unrecognized [option]\n");
+ showUsage();
+ }
+ }
+ else
+ {
+ fprintf(stderr, "Unrecognized [option]\n");
+ showUsage();
+ }
+ }
+
+ /* Extract the Pascal program name from the command line */
+
+ sourceFileName = argv[argc-1];
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+int main(int argc, char *argv[])
+{
+ char filename [FNAME_SIZE+1];
+
+ /* Parse command line arguments */
+
+ parseArguments(argc, argv);
+
+ /* Open all output files */
+
+ openOutputFiles();
+
+#if !LSTTOFILE
+ lstFile = stdout;
+#endif
+
+ /* Open source file -- Use .PAS or command line extension, if supplied */
+
+ (void)extension(sourceFileName, "PAS", filename, 0);
+ fprintf(errFile, "%01x=%s\n", FP->include, filename);
+
+ memset(FP, 0, sizeof(fileState_t));
+ FP->stream = fopen(filename, "r");
+ if (!FP->stream)
+ {
+ errmsg("Could not open source file '%s': %s\n",
+ filename, strerror(errno));
+ showUsage();
+ }
+
+ /* Initialization */
+
+ primeSignalHandlers();
+ primeSymbolTable(MAX_SYM);
+ primeBuiltInProcedures();
+ primeBuiltInFunctions();
+ primeTokenizer(MAX_STRINGS);
+
+ /* Initialize the POFF object */
+
+ poffHandle = poffCreateHandle();
+ if (poffHandle == NULL)
+ fatal(eNOMEMORY);
+
+ /* Save the soure file name in the POFF output file */
+
+ FP->include = poffAddFileName(poffHandle, filename);
+
+ /* Define standard input/output file characteristics */
+
+ files[0].defined = -1;
+ files[0].flevel = level;
+ files[0].ftype = sCHAR;
+ files[0].faddr = dstack;
+ files[0].fsize = sCHAR_SIZE;
+ dstack += sCHAR_SIZE;
+
+ /* We need the following in order to calculate relative stack positions. */
+
+ FP->dstack = dstack;
+
+ /* Indicate that no WITH statement has been processed */
+
+ memset(&withRecord, 0, sizeof(WTYPE));
+
+ /* Process the pascal program
+ *
+ * FORM: pascal = program | unit
+ * FORM: program = program-heading ';' [uses-section ] block '.'
+ * FORM: program-heading = 'program' identifier [ '(' identifier-list ')' ]
+ * FORM: unit = unit-heading ';' interface-section implementation-section init-section
+ * FORM: unit-heading = 'unit' identifer
+ */
+
+ getToken();
+ if (token == tPROGRAM)
+ {
+ /* Compile a pascal program */
+
+ FP->kind = eIsProgram;
+ FP->section = eIsProgramSection;
+ getToken();
+ program();
+ }
+ else if (token == tUNIT)
+ {
+ /* Compile a pascal unit */
+
+ FP->kind = eIsUnit;
+ FP->section = eIsOtherSection;
+ getToken();
+ unitImplementation();
+ }
+ else
+ {
+ /* Expected 'program' or 'unit' */
+
+ error(ePROGRAM);
+ }
+
+ /* Dump the symbol table content (debug only) */
+
+#if CONFIG_DEBUG
+ dumpTables();
+#endif
+
+ /* Write the POFF output file */
+
+ poffWriteFile(poffHandle, poffFile);
+ poffDestroyHandle(poffHandle);
+
+ /* Close all output files */
+
+ closeFiles();
+
+ /* Write Closing Message */
+
+ if (warn_count > 0)
+ {
+ printf(" %ld Warnings Issued\n", warn_count);
+ } /* end if */
+
+ if (err_count > 0)
+ {
+ printf(" %d Errors Detected\n\n", err_count);
+ return -1;
+ } /* end if */
+
+ return 0;
+
+} /* end main */
+
+/***********************************************************************/
+
+void openNestedFile(const char *fileName)
+{
+ fileState_t *prev = FP;
+ char fullpath[FNAME_SIZE + 1];
+ int i;
+
+ /* Make sure we can handle another nested file */
+
+ if (++includeIndex >= MAX_INCL) fatal(eOVF);
+ else
+ {
+ /* Clear the file state structure for the new include level */
+
+ memset(FP, 0, sizeof(fileState_t));
+
+ /* Try all source include pathes until we find the file or
+ * until we exhaust the include path list.
+ */
+
+ for (i = 0; ; i++)
+ {
+ /* Open the nested file -- try all possible pathes or
+ * until we successfully open the file.
+ */
+
+ /* The final path that we will try is the current directory */
+
+ if (i == nIncPathes)
+ {
+ sprintf(fullpath, "./%s", fileName);
+ }
+ else
+ {
+ sprintf(fullpath, "%s/%s", includePath[i], fileName);
+ }
+
+ FP->stream = fopen (fullpath, "rb");
+ if (!FP->stream)
+ {
+ /* We failed to open the file. If there are no more
+ * include pathes to examine (including the current directory),
+ * then error out. This is fatal. Otherwise, continue
+ * looping.
+ */
+
+ if (i == nIncPathes)
+ {
+ errmsg("Failed to open '%s': %s\n",
+ fileName, strerror(errno));
+ fatal(eINCLUDE);
+ break; /* Won't get here */
+ }
+ } /* end else if */
+ else
+ break;
+ }
+
+ /* Setup the newly opened file */
+
+ fprintf(errFile, "%01x=%s\n", FP->include, fullpath);
+ FP->include = poffAddFileName(poffHandle, fullpath);
+
+ /* The caller may change this, but the default behavior is
+ * to inherit the kind and section of the including file
+ * and the current data stack offset.
+ */
+
+ FP->kind = prev->kind;
+ FP->section = prev->section;
+ FP->dstack = dstack;
+
+ rePrimeTokenizer();
+
+ /* Get the first token from the file */
+
+ getToken();
+ } /* end else */
+}
+
+/***********************************************************************/
+
+void closeNestedFile(void)
+{
+ if (FP->stream)
+ {
+ (void)fclose(FP->stream);
+ includeIndex--;
+ }
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/pascal/pas.h b/misc/pascal/pascal/pas.h
new file mode 100644
index 000000000..e86676ba1
--- /dev/null
+++ b/misc/pascal/pascal/pas.h
@@ -0,0 +1,116 @@
+/***************************************************************************
+ * pas.h
+ * External Declarations associated with pas.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PAS_H
+#define __PAS_H
+
+/***************************************************************************
+ * Compilation Switches
+ ***************************************************************************/
+
+#define LSTTOFILE 1
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <sys/types.h>
+#include <stdint.h>
+#include "pasdefs.h"
+#include "pofflib.h"
+
+/***************************************************************************
+ * Pre-processor Definitions
+ ***************************************************************************/
+
+/* This is a helper macro just to make things pretty in the source code */
+
+#define FP0 (&fileState[0]) /* Main file description */
+#define FP (&fileState[includeIndex]) /* Current file description */
+#define FPP (&fileState[includeIndex-1]) /* Previous file description */
+#define IS_NESTED_UNIT ((includeIndex > 0) && (FP->kind == eIsUnit))
+
+/***************************************************************************
+ * Global Types
+ ***************************************************************************/
+
+/***************************************************************************
+ * Global Variable
+ ***************************************************************************/
+
+extern uint16_t token; /* Current token */
+extern uint16_t tknSubType; /* Extended token type */
+extern int32_t tknInt; /* Integer token value */
+extern double tknReal; /* Real token value */
+extern STYPE *tknPtr; /* Pointer to symbol token */
+extern FTYPE files[MAX_FILES+1]; /* File Table */
+extern fileState_t fileState[MAX_INCL]; /* State of all open files */
+
+/* sourceFileName : Source file name from command line
+ * includePath[] : Pathes to search when including file
+ */
+
+extern char *sourceFileName;
+extern char *includePath[MAX_INCPATHES];
+
+extern poffHandle_t poffHandle; /* Handle for POFF object */
+
+extern FILE *poffFile; /* POFF output file */
+extern FILE *errFile; /* Error file pointer */
+extern FILE *lstFile; /* List file pointer */
+
+extern WTYPE withRecord; /* RECORD of WITH statement */
+extern int16_t level; /* Static nesting level */
+extern int16_t includeIndex; /* Include file index */
+extern int16_t nIncPathes; /* Number pathes in includePath[] */
+extern uint16_t label; /* Last label number */
+extern int16_t nsym; /* Number symbol table entries */
+extern int16_t nconst; /* Number constant table entries */
+extern int16_t sym_strt; /* Symbol search start index */
+extern int16_t const_strt; /* Constant search start index */
+extern int16_t err_count; /* Error counter */
+extern int16_t nfiles; /* Program file counter */
+extern int32_t warn_count; /* Warning counter */
+extern int32_t dstack; /* data stack size */
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void openNestedFile (const char *fileName);
+extern void closeNestedFile (void);
+
+#endif /* __PAS_H */
diff --git a/misc/pascal/pascal/pasdefs.h b/misc/pascal/pascal/pasdefs.h
new file mode 100644
index 000000000..ade1b7ed0
--- /dev/null
+++ b/misc/pascal/pascal/pasdefs.h
@@ -0,0 +1,284 @@
+/***********************************************************************
+ * pascal/pasdefs.h
+ * General definitions for the Pascal Compiler/Optimizer
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************************************/
+
+#ifndef __PASDEFS_H
+#define __PASDEFS_H
+
+/***********************************************************************
+ * Included Files
+ ***********************************************************************/
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h> /* for FILE */
+#include <config.h>
+#include "pdefs.h" /* Common definitions */
+
+/***********************************************************************
+ * Pre-processor Definitions
+ ***********************************************************************/
+
+/* Size Parameters -- some of these can be overridden from the
+ * command line.
+ */
+
+#define MAX_SYM (4096)
+#define MAX_STRINGS (65536)
+#define MAX_INCL 3 /* Max number of nested include files */
+#define MAX_FILES 8 /* Max number of opened files */
+#define FNAME_SIZE 40 /* Max size file name */
+#define MAX_INCPATHES 8 /* Max number of include pathes */
+
+/* Bit values for the 'flags' field of the symType_t, symProc_t, and
+ * symVar_t (see below)
+ */
+
+#define STYPE_VARSIZE 0x01 /* Type has variable size */
+#define SPROC_EXTERNAL 0x01 /* Proc/func. is defined externally */
+#define SVAR_EXTERNAL 0x01 /* Variable is defined externally */
+
+/***********************************************************************
+ * Public Enumeration Types
+ ***********************************************************************/
+
+/* This enumeration identies what kind of binary object we are creating
+ * with the compilation. At present, we may be generating either a
+ * program binary or a unit binary.
+ */
+
+enum fileKind_e
+{
+ eIsProgram = 0,
+ eIsUnit
+};
+typedef enum fileKind_e fileKind_t;
+
+/* This enumeration determines what part of a file that we are
+ * processing now.
+ */
+
+enum fileSection_e
+{
+ eIsOtherSection = 0, /* Unspecified part of the file */
+ eIsProgramSection, /* Any part of a program file */
+ eIsInterfaceSection, /* INTERFACE section of a unit file */
+ eIsImplementationSection, /* IMPLEMENTATION section of a unit file */
+ eIsInitializationSection, /* INITIALIZATION section of a unit file */
+};
+typedef enum fileSection_e fileSection_t;
+
+/***********************************************************************
+ * Public Structure/Types
+ ***********************************************************************/
+
+/* Reserved word table entry */
+
+struct R
+{
+ char *rname; /* pointer to name in string stack */
+ uint8_t rtype; /* reserved word type */
+ uint8_t subtype; /* reserved word extended type */
+};
+typedef struct R RTYPE;
+
+/* Symbol table entry */
+
+struct symType_s /* for sKind = sTYPE */
+{
+ uint8_t type; /* specific type */
+ uint8_t rtype; /* reference to type */
+ uint8_t subType; /* constant type for subrange types */
+ uint8_t flags; /* flags to customize a type (see above) */
+ uint32_t asize; /* size of allocated instances of this type */
+ uint32_t rsize; /* size of reference to an instances of this type */
+ int32_t minValue; /* minimum value taken subrange */
+ int32_t maxValue; /* maximum value taken by subrange or scalar */
+ struct S *parent; /* pointer to parent type */
+};
+typedef struct symType_s symType_t;
+
+struct symConst_s /* for sKind == constant type */
+{
+ union
+ {
+ double f; /* real value */
+ int32_t i; /* integer value */
+ } val;
+ struct S *parent; /* pointer to parent type */
+};
+typedef struct symConst_s symConst_t;
+
+struct symStringConst_s /* for sKind == sSTRING_CONST */
+{
+ uint32_t offset; /* RO data section offset of string */
+ uint32_t size; /* length of string in bytes */
+};
+typedef struct symStringConst_s symStringConst_t;
+
+struct symVarString_s /* for sKind == sSTRING */
+{
+ uint16_t label; /* label at string declaration */
+ uint16_t size; /* valid length of string in bytes */
+ uint16_t alloc; /* max length of string in bytes */
+};
+typedef struct symVarString_s symVarString_t;
+
+struct symLabel_s /* for sKind == sLABEL */
+{
+ uint16_t label; /* label number */
+ bool unDefined; /* set false when defined */
+};
+typedef struct symLabel_s symLabel_t;
+
+struct symVar_s /* for sKind == type identifier */
+{
+ int32_t offset; /* Data stack offset */
+ uint32_t size; /* Size of variable */
+ uint8_t flags; /* flags to customize a variable (see above) */
+ uint32_t symIndex; /* POFF symbol table index (if undefined) */
+ struct S *parent; /* pointer to parent type */
+};
+typedef struct symVar_s symVar_t;
+
+struct symProc_s /* for sKind == sPROC or sFUNC */
+{
+ uint16_t label; /* entry point label */
+ uint16_t nParms; /* number of parameters that follow */
+ uint8_t flags; /* flags to customize a proc/func (see above) */
+ uint32_t symIndex; /* POFF symbol table index (if undefined) */
+ struct S *parent; /* pointer to parent type (sFUNC only) */
+};
+typedef struct symProc_s symProc_t;
+
+struct symRecord_s /* for sKind == sRECORD_OBJECT */
+{
+ uint32_t size; /* size of this field */
+ uint32_t offset; /* offset into the RECORD */
+ struct S *record; /* pointer to parent sRECORD type */
+ struct S *parent; /* pointer to parent field type */
+};
+typedef struct symRecord_s symRecord_t;
+
+struct S
+{
+ char *sName; /* pointer to name in string stack */
+ uint8_t sKind; /* kind of symbol */
+ uint8_t sLevel; /* static nesting level */
+ union
+ {
+ symType_t t; /* for type definitions */
+ symConst_t c; /* for constants */
+ symStringConst_t s; /* for strings of constant size*/
+ symVarString_t vs; /* for strings of variable size*/
+ uint16_t fileNumber; /* for files */
+ symLabel_t l; /* for labels */
+ symVar_t v; /* for variables */
+ symProc_t p; /* for functions & procedures */
+ symRecord_t r; /* for files of RECORDS */
+ } sParm;
+};
+typedef struct S STYPE;
+
+/* WITH structure */
+
+struct W
+{
+ uint8_t level; /* static nesting level */
+ bool pointer; /* true if offset is to pointer to RECORD */
+ bool varParm; /* true if VAR param (+pointer) */
+ int32_t offset; /* Data stack offset */
+ uint16_t index; /* RECORD offset (if pointer) */
+ STYPE *parent; /* pointer to parent RECORD type */
+};
+typedef struct W WTYPE;
+
+/* File table record */
+
+struct F
+{
+ int16_t defined;
+ int16_t flevel;
+ int16_t ftype;
+ int32_t faddr;
+ int16_t fsize;
+};
+typedef struct F FTYPE;
+
+/* This structure captures the parsing state of the compiler for a particular
+ * file. Since multiple, nested files can be processed, this represents
+ * only level in the "stack" of nested files.
+ */
+
+struct fileState_s
+{
+ /* These fields are managed by the higher level parsing logic
+ *
+ * stream - Stream pointer the input stream associated with this
+ * file.
+ * kind - Kind of file we are processing. If include > 0,
+ * this should be eIsUnit.
+ * section - This is the part of the program that we are parsing
+ * now.
+ * dstack - Level zero dstack offset at the time the unit was
+ * included. This is used to convert absolute program
+ * stack offsets into relative unit stack offsets.
+ * include - Is a unique number that identifies the file. In
+ * POFF ouput file, this would be the index to the
+ * entry in the .files section.
+ */
+
+ FILE *stream;
+ fileKind_t kind;
+ fileSection_t section;
+ int32_t dstack;
+ int16_t include;
+
+ /* These fields are managed by the tokenizer. These are all
+ * initialized by primeTokenizer().
+ *
+ * buffer[] - Holds the current input line
+ * line - Is the line number in this file for the current line
+ * cp - Is the current pointer into buffer[]
+ */
+
+ uint32_t line;
+ unsigned char *cp;
+ unsigned char buffer[LINE_SIZE + 1];
+};
+typedef struct fileState_s fileState_t;
+
+#endif /* __PASDEFS_H */
diff --git a/misc/pascal/pascal/pblck.c b/misc/pascal/pascal/pblck.c
new file mode 100644
index 000000000..b32701cc7
--- /dev/null
+++ b/misc/pascal/pascal/pblck.c
@@ -0,0 +1,2263 @@
+/***************************************************************
+ * pblck.c
+ * Process a Pascal Block
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************/
+
+/***************************************************************
+ * Included Files
+ ***************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+#include "keywords.h"
+#include "pasdefs.h"
+#include "ptdefs.h"
+#include "pedefs.h"
+#include "podefs.h"
+
+#include "pas.h"
+#include "pblck.h"
+#include "pexpr.h"
+#include "pstm.h"
+#include "pgen.h"
+#include "ptkn.h"
+#include "ptbl.h"
+#include "pinsn.h"
+#include "perr.h"
+
+/***************************************************************
+ * Private Definitions
+ ***************************************************************/
+
+/* This macro implements a test for:
+ * FORM: unsigned-constant = integer-number | real-number |
+ * character-literal | string-literal | constant-identifier |
+ * 'nil'
+ */
+
+#define isConstant(x) \
+ ( ((x) == tINT_CONST) \
+ || ((x) == tBOOLEAN_CONST) \
+ || ((x) == tCHAR_CONST) \
+ || ((x) == tREAL_CONST) \
+ || ((x) == sSCALAR_OBJECT))
+
+#define isIntAligned(x) (((x) & (sINT_SIZE-1)) == 0)
+#define intAlign(x) (((x) + (sINT_SIZE-1)) & (~(sINT_SIZE-1)))
+
+/***************************************************************
+ * Private Function Prototypes
+ ***************************************************************/
+
+static void pas_DeclareLabel (void);
+static void pas_DeclareConst (void);
+static STYPE *pas_DeclareType (char *typeName);
+static STYPE *pas_DeclareOrdinalType (char *typeName);
+static STYPE *pas_DeclareVar (void);
+static void pas_DeclareFile (void);
+static void pas_ProcedureDeclaration (void);
+static void pas_FunctionDeclaration (void);
+
+static void pas_SetTypeSize (STYPE *typePtr, bool allocate);
+static STYPE *pas_TypeIdentifier (bool allocate);
+static STYPE *pas_TypeDenoter (char *typeName, bool allocate);
+static STYPE *pas_NewComplexType (char *typeName);
+static STYPE *pas_NewOrdinalType (char *typeName);
+static STYPE *pas_OrdinalTypeIdentifier (bool allocate);
+static STYPE *pas_GetArrayType (void);
+static STYPE *pas_DeclareRecord (char *recordName);
+static STYPE *pas_DeclareField (STYPE *recordPtr);
+static STYPE *pas_DeclareParameter (bool pointerType);
+static bool pas_IntAlignRequired (STYPE *typePtr);
+
+/***************************************************************
+ * Private Global Variables
+ ***************************************************************/
+
+static int32_t g_nParms;
+static int32_t g_dwVarSize;
+
+/***************************************************************
+ * Public Functions
+ ***************************************************************/
+/* Process BLOCK. This function implements:
+ *
+ * block = declaration-group compound-statement
+ *
+ * Where block can appear in the followinging:
+ *
+ * function-block = block
+ * function-declaration =
+ * function-heading ';' directive |
+ * function-heading ';' function-block
+ *
+ * procedure-block = block
+ * procedure-declaration =
+ * procedure-heading ';' directive |
+ * procedure-heading ';' procedure-block
+ *
+ * program = program-heading ';' [ uses-section ] block '.'
+ */
+
+void block()
+{
+ uint16_t beginLabel = ++label; /* BEGIN label */
+ int32_t saveDStack = dstack; /* Save DSEG size */
+ char *saveStringSP = stringSP; /* Save top of string stack */
+ int16_t saveNSym = nsym; /* Save top of symbol table */
+ int16_t saveNConst = nconst; /* Save top of constant table */
+ register int16_t i;
+
+ TRACE(lstFile,"[block]");
+
+ /* When we enter block at level zero, then we must be at the
+ * entry point to the program. Save the entry point label
+ * in the POFF file.
+ */
+
+ if ((level == 0) && (FP0->kind == eIsProgram))
+ {
+ poffSetEntryPoint(poffHandle, label);
+ }
+
+ /* Init size of the new DSEG */
+
+ dstack = 0;
+
+ /* FORM: block = declaration-group compound-statement
+ * Process the declaration-group
+ *
+ * declaration-group =
+ * label-declaration-group |
+ * constant-definition-group |
+ * type-definition-group |
+ * variable-declaration-group |
+ * function-declaration |
+ * procedure-declaration
+ */
+
+ declarationGroup(beginLabel);
+
+ /* Process the compound-statement
+ *
+ * FORM: compound-statement = 'begin' statement-sequence 'end'
+ */
+
+ /* Verify that the compound-statement begins with BEGIN */
+
+ if (token != tBEGIN)
+ {
+ error (eBEGIN);
+ }
+
+ /* It may be necessary to jump around some local functions to
+ * get to the main body of the block. If any jumps are generated,
+ * they will come to the beginLabel emitted here.
+ */
+
+ pas_GenerateDataOperation(opLABEL, (int32_t)beginLabel);
+
+ /* Since we don't know for certain how we got here, invalidate
+ * the level stack pointer (LSP). This is, of course, only
+ * meaningful on architectures that implement an LSP.
+ */
+
+ pas_InvalidateCurrentStackLevel();
+
+ /* Then emit the compoundStatement itself */
+
+ if (dstack)
+ {
+ pas_GenerateDataOperation(opINDS, (int32_t)dstack);
+ }
+
+ compoundStatement();
+
+ if (dstack)
+ {
+ pas_GenerateDataOperation(opINDS, -(int32_t)dstack);
+ }
+
+ /* Make sure all declared labels were defined in the block */
+
+ verifyLabels(saveNSym);
+
+ /* Re-initialize file table -- clear files defined in this level */
+
+ for (i = 0; i <= MAX_FILES; i++)
+ {
+ if ((files [i].defined) && (files [i].flevel >= level)) {
+ files [i].defined = 0;
+ files [i].flevel = 0;
+ files [i].ftype = 0;
+ files [i].faddr = 0;
+ files [i].fsize = 0;
+ }
+ }
+
+ /* "Pop" declarations local to this block */
+
+ dstack = saveDStack; /* Restore old DSEG size */
+ stringSP = saveStringSP; /* Restore top of string stack */
+ nsym = saveNSym; /* Restore top of symbol table */
+ nconst = saveNConst; /* Restore top of constant table */
+}
+
+/***************************************************************/
+/* Process declarative-part */
+
+void declarationGroup(int32_t beginLabel)
+{
+ int16_t notFirst = 0; /* Init count of nested procs */
+ int16_t saveNSym = nsym; /* Save top of symbol table */
+ int16_t saveNConst = nconst; /* Save top of constant table */
+
+ TRACE(lstFile,"[declarationGroup]");
+
+ /* FORM: declarative-part = { declaration-group }
+ * FORM: declaration-group =
+ * label-declaration-group | constant-definition-group |
+ * type-definition-group | variable-declaration-group |
+ * function-declaration | procedure-declaration
+ */
+
+ /* Process label-declaration-group.
+ * FORM: label-declaration-group = 'label' label { ',' label } ';'
+ */
+
+ if (token == tLABEL) pas_DeclareLabel();
+
+ /* Process constant-definition-group.
+ * FORM: constant-definition-group =
+ * 'const' constant-definition ';' { constant-definition ';' }
+ */
+
+ if (token == tCONST)
+ {
+ const_strt = saveNConst; /* Limit search to present level */
+ getToken(); /* Get identifier */
+ const_strt = 0;
+
+ /* Process constant-definition.
+ * FORM: constant-definition = identifier '=' constant
+ */
+
+ constantDefinitionGroup();
+ }
+
+ /* Process type-definition-group
+ * FORM: type-definition-group =
+ * 'type' type-definition ';' { type-definition ';' }
+ */
+
+ if (token == tTYPE)
+ {
+ const_strt = saveNConst; /* Limit search to present level */
+ sym_strt = saveNSym;
+ getToken(); /* Get identifier */
+ const_strt = 0;
+ sym_strt = 0;
+
+ /* Process the type-definitions in the type-definition-group
+ * FORM: type-definition = identifier '=' type-denoter
+ */
+
+ typeDefinitionGroup();
+ }
+
+ /* Process variable-declaration-group
+ * FORM: variable-declaration-group =
+ * 'var' variable-declaration { ';' variable-declaration }
+ */
+
+ if (token == tVAR)
+ {
+ const_strt = saveNConst; /* Limit search to present level */
+ sym_strt = saveNSym;
+ getToken(); /* Get identifier */
+ const_strt = 0;
+ sym_strt = 0;
+
+ /* Process the variable declarations
+ * FORM: variable-declaration = identifier-list ':' type-denoter
+ * FORM: identifier-list = identifier { ',' identifier }
+ */
+
+ variableDeclarationGroup();
+ }
+
+ /* Process procedure/function-declaration(s) if present
+ * FORM: function-declaration =
+ * function-heading ';' directive |
+ * function-heading ';' function-block
+ * FORM: procedure-declaration =
+ * procedure-heading ';' directive |
+ * procedure-heading ';' procedure-block
+ *
+ * NOTE: a JMP to the executable body of this block is generated
+ * if there are nested procedures and this is not level=0
+ */
+
+ for (;;)
+ {
+ /* FORM: function-heading =
+ * 'function' identifier [ formal-parameter-list ] ':' result-type
+ */
+
+ if (token == tFUNCTION)
+ {
+ /* Check if we need to put a jump around the function */
+
+ if ((beginLabel > 0) && !(notFirst) && (level > 0))
+ {
+ pas_GenerateDataOperation(opJMP, (int32_t)beginLabel);
+ }
+
+ /* Get the procedure-identifier */
+
+ const_strt = saveNConst; /* Limit search to present level */
+ sym_strt = saveNSym;
+ getToken(); /* Get identifier */
+ const_strt = 0;
+ sym_strt = 0;
+
+ /* Define the function */
+
+ pas_FunctionDeclaration();
+ notFirst++; /* No JMP next time */
+ }
+
+ /* FORM: procedure-heading =
+ * 'procedure' identifier [ formal-parameter-list ]
+ */
+
+ else if (token == tPROCEDURE)
+ {
+ /* Check if we need to put a jump around the function */
+
+ if ((beginLabel > 0) && !(notFirst) && (level > 0))
+ {
+ pas_GenerateDataOperation(opJMP, (int32_t)beginLabel);
+ }
+
+ /* Get the procedure-identifier */
+
+ const_strt = saveNConst; /* Limit search to present level */
+ sym_strt = saveNSym;
+ getToken(); /* Get identifier */
+ const_strt = 0;
+ sym_strt = 0;
+
+ /* Define the procedure */
+
+ pas_ProcedureDeclaration();
+ notFirst++; /* No JMP next time */
+ }
+ else break;
+ }
+}
+
+/***************************************************************/
+
+void constantDefinitionGroup(void)
+{
+ /* Process constant-definition-group.
+ * FORM: constant-definition-group =
+ * 'const' constant-definition ';' { constant-definition ';' }
+ * FORM: constant-definition = identifier '=' constant
+ *
+ * On entry, token should point to the identifier of the first
+ * constant-definition.
+ */
+
+ for (;;)
+ {
+ if (token == tIDENT)
+ {
+ pas_DeclareConst();
+ if (token != ';') break;
+ else getToken();
+ }
+ else break;
+ }
+}
+
+/***************************************************************/
+
+void typeDefinitionGroup(void)
+{
+ char *typeName;
+
+ /* Process type-definition-group
+ * FORM: type-definition-group =
+ * 'type' type-definition ';' { type-definition ';' }
+ * FORM: type-definition = identifier '=' type-denoter
+ *
+ * On entry, token refers to the first identifier (if any) of
+ * the type-definition list.
+ */
+
+ for (;;)
+ {
+ if (token == tIDENT)
+ {
+ /* Save the type identifier */
+
+ typeName = tkn_strt;
+ getToken();
+
+ /* Verify that '=' follows the type identifier */
+
+ if (token != '=') error (eEQ);
+ else getToken();
+
+ (void)pas_DeclareType(typeName);
+ if (token != ';') break;
+ else getToken();
+
+ }
+ else break;
+ }
+}
+
+/***************************************************************/
+
+void variableDeclarationGroup(void)
+{
+ /* Process variable-declaration-group
+ * FORM: variable-declaration-group =
+ * 'var' variable-declaration { ';' variable-declaration }
+ * FORM: variable-declaration = identifier-list ':' type-denoter
+ * FORM: identifier-list = identifier { ',' identifier }
+ *
+ * Only entry, token holds the first identfier (if any) of the
+ * variable-declaration list.
+ */
+
+ for (;;)
+ {
+ if (token == tIDENT)
+ {
+ (void)pas_DeclareVar();
+ if (token != ';') break;
+ else getToken();
+ }
+ else if (token == sFILE)
+ {
+ pas_DeclareFile();
+ if (token != ';') break;
+ else getToken();
+ }
+ else break;
+ }
+}
+
+/***************************************************************/
+/* Process formal-parameter-list */
+
+int16_t formalParameterList(STYPE *procPtr)
+{
+ int16_t parameterOffset;
+ int16_t i;
+ bool pointerType;
+
+ TRACE(lstFile,"[formalParameterList]");
+
+ /* FORM: formal-parameter-list =
+ * '(' formal-parameter-section { ';' formal-parameter-section } ')'
+ * FORM: formal-parameter-section =
+ * value-parameter-specification |
+ * variable-parameter-specification |
+ * procedure-parameter-specification |
+ * function-parameter-specification
+ * FORM: value-parameter-specification =
+ * identifier-list ':' type-identifier
+ * FORM: variable-parameter-specification =
+ * 'var' identifier-list ':' type-identifier
+ *
+ * On entry token should refer to the '(' at the beginning of the
+ * (optional) formal parameter list.
+ */
+
+ g_nParms = 0;
+
+ /* Check if the formal-parameter-list is present. It is optional in
+ * all contexts in which this function is called.
+ */
+
+ if (token == '(')
+ {
+ /* Process each formal-parameter-section */
+
+ do
+ {
+ getToken();
+
+ /* Check for variable-parameter-specification */
+
+ if (token == tVAR)
+ {
+ pointerType = 1;
+ getToken();
+ }
+ else pointerType = 0;
+
+ /* Process the common part of the variable-parameter-specification
+ * and the value-parameter specification.
+ * NOTE that procedure-parameter-specification and
+ * function-parameter-specification are not yet supported.
+ */
+
+ (void)pas_DeclareParameter(pointerType);
+
+ }
+ while (token == ';');
+
+ /* Verify that the formal parameter list terminates with a
+ * right parenthesis.
+ */
+
+ if (token != ')') error (eRPAREN);
+ else getToken();
+
+ }
+
+ /* Save the number of parameters found in sPROC/sFUNC symbol table entry */
+
+ procPtr->sParm.p.nParms = g_nParms;
+
+ /* Now, calculate the parameter offsets from the size of each parameter */
+
+ parameterOffset = -sRETURN_SIZE;
+ for (i = g_nParms; i > 0; i--)
+ {
+ /* The offset to the next parameter is the offset to the previous
+ * parameter minus the size of the new parameter (aligned to
+ * multiples of size of INTEGER).
+ */
+
+ parameterOffset -= procPtr[i].sParm.v.size;
+ parameterOffset = intAlign(parameterOffset);
+ procPtr[i].sParm.v.offset = parameterOffset;
+ }
+
+ return parameterOffset;
+}
+
+/***************************************************************
+ * Private Functions
+ ***************************************************************/
+/* Process LABEL block */
+
+static void pas_DeclareLabel(void)
+{
+ char *labelname; /* Label symbol table name */
+
+ TRACE(lstFile,"[pas_DeclareLabel]");
+
+ /* FORM: LABEL <integer>[,<integer>[,<integer>][...]]]; */
+
+ do
+ {
+ getToken();
+ if ((token == tINT_CONST) && (tknInt >= 0))
+ {
+ labelname = stringSP;
+ (void)sprintf (labelname, "%ld", tknInt);
+ while (*stringSP++);
+ (void)addLabel(labelname, ++label);
+ getToken();
+ }
+ else error(eINTCONST);
+ }
+ while (token == ',');
+
+ if (token != ';') error (eSEMICOLON);
+ else getToken();
+}
+
+/***************************************************************/
+/* Process constant definition:
+ * FORM: constant-definition = identifier '=' constant
+ * FORM: constant = [ sign ] integer-number |
+ * [ sign ] real-number |
+ * [ sign ] constant-identifier |
+ * character-literal |
+ * string-literal
+ */
+
+static void pas_DeclareConst(void)
+{
+ char *const_name;
+
+ TRACE(lstFile,"[pas_DeclareConst]");
+
+ /* FORM: <identifier> = <numeric constant|string>
+ * NOTE: Only integer constants are supported
+ */
+
+ /* Save the name of the constant */
+
+ const_name = tkn_strt;
+
+ /* Verify that the name is followed by '=' and get the
+ * following constant value.
+ */
+
+ getToken();
+ if (token != '=') error (eEQ);
+ else getToken();
+
+ /* Handle constant expressions */
+
+ constantExpression();
+
+ /* Add the constant to the symbol table based on the type of
+ * the constant found following the '= [ sign ]'
+ */
+
+ switch (constantToken)
+ {
+ case tINT_CONST :
+ case tCHAR_CONST :
+ case tBOOLEAN_CONST :
+ case sSCALAR_OBJECT :
+ (void)addConstant(const_name, constantToken, &constantInt, NULL);
+ break;
+
+ case tREAL_CONST :
+ (void)addConstant(const_name, constantToken, (int32_t*)&constantReal, NULL);
+ break;
+
+ case tSTRING_CONST :
+ {
+ uint32_t offset = poffAddRoDataString(poffHandle, constantStart);
+ (void)addStringConst(const_name, offset, strlen(constantStart));
+ }
+ break;
+
+ default :
+ error(eINVCONST);
+ }
+}
+
+/***************************************************************/
+/* Process TYPE declaration */
+
+static STYPE *pas_DeclareType(char *typeName)
+{
+ STYPE *typePtr;
+
+ TRACE(lstFile,"[pas_DeclareType]");
+
+ /* This function processes the type-denoter in
+ * FORM: type-definition = identifier '=' type-denoter
+ * FORM: array-type = 'array' '[' index-type-list ']' 'of' type-denoter
+ */
+
+ /* FORM: type-denoter = type-identifier | new-type
+ * FORM: new-type = new-ordinal-type | new-complex-type
+ */
+
+ typePtr = pas_NewComplexType(typeName);
+ if (typePtr == NULL)
+ {
+ /* Check for Simple Types */
+
+ typePtr = pas_DeclareOrdinalType(typeName);
+ if (typePtr == NULL)
+ {
+ error(eINVTYPE);
+ }
+ }
+
+ return typePtr;
+}
+
+/***************************************************************/
+/* Process a simple TYPE declaration */
+
+static STYPE *pas_DeclareOrdinalType(char *typeName)
+{
+ STYPE *typePtr;
+ STYPE *typeIdPtr;
+
+ /* Declare a new ordinal type */
+
+ typePtr = pas_NewOrdinalType(typeName);
+
+ /* Otherwise, declare a type equivalent to a previously defined type
+ * NOTE: the following logic is incomplete. Its is only good for
+ * sKind == sType
+ */
+
+ if (typePtr == NULL)
+ {
+ typeIdPtr = pas_TypeIdentifier(1);
+ if (typeIdPtr)
+ {
+ typePtr = addTypeDefine(typeName, typeIdPtr->sParm.t.type,
+ g_dwVarSize, typeIdPtr);
+ }
+ }
+
+ return typePtr;
+}
+
+/***************************************************************/
+/* Process VAR declaration */
+
+static STYPE *pas_DeclareVar(void)
+{
+ STYPE *varPtr;
+ STYPE *typePtr;
+ char *varName;
+
+ TRACE(lstFile,"[pas_DeclareVar]");
+
+ /* FORM: variable-declaration = identifier-list ':' type-denoter
+ * FORM: identifier-list = identifier { ',' identifier }
+ */
+
+ typePtr = NULL;
+
+ /* Save the current identifier */
+
+ varName = tkn_strt;
+ getToken();
+
+ /* A comma indicates that there is another indentifier int the
+ * identifier-list
+ */
+
+ if (token == ',')
+ {
+ /* Yes ..Process the next identifer in the indentifier list
+ * via recursion
+ */
+
+ getToken();
+ if (token != tIDENT) error(eIDENT);
+ else typePtr = pas_DeclareVar();
+ }
+ else
+ {
+ /* No.. verify that the identifer-list is followed by ';' */
+
+ if (token != ':') error(eCOLON);
+ else getToken();
+
+ /* Process the type-denoter */
+
+ typePtr = pas_TypeDenoter(varName, 1);
+ if (typePtr == NULL)
+ {
+ error(eINVTYPE);
+ }
+ }
+
+ if (typePtr)
+ {
+ uint8_t varType = typePtr->sParm.t.type;
+
+ /* Determine if alignment to INTEGER boundaries is necessary */
+
+ if ((!isIntAligned(dstack)) && (pas_IntAlignRequired(typePtr)))
+ dstack = intAlign(dstack);
+
+ /* Add the new variable to the symbol table */
+
+ varPtr = addVariable(varName, varType, dstack, g_dwVarSize, typePtr);
+
+ /* If the variable is declared in an interface section at level zero,
+ * then it is a candidate to imported or exported.
+ */
+
+ if ((!level) && (FP->section == eIsInterfaceSection))
+ {
+ /* Are we importing or exporting the interface?
+ *
+ * PROGRAM EXPORTS:
+ * If we are generating a program binary (i.e., FP0->kind ==
+ * eIsProgram) then the variable memory allocation must appear
+ * on the initial stack allocation; therefore the variable
+ * stack offset myst be exported by the program binary.
+ *
+ * UNIT IMPORTS:
+ * If we are generating a unit binary (i.e., FP0->kind ==
+ * eIsUnit), then we are importing the level 0 stack offset
+ * from the main program.
+ */
+
+ if (FP0->kind == eIsUnit)
+ {
+ /* Mark the symbol as external and replace the absolute
+ * offset with this relative offset.
+ */
+
+ varPtr->sParm.v.flags |= SVAR_EXTERNAL;
+ varPtr->sParm.v.offset = dstack - FP->dstack;
+
+ /* IMPORT the symbol; assign an offset relative to
+ * the dstack at the beginning of this file
+ */
+
+ pas_GenerateStackImport(varPtr);
+ }
+ else /* if (FP0->kind == eIsProgram) */
+ {
+ /* EXPORT the symbol */
+
+ pas_GenerateStackExport(varPtr);
+ }
+ }
+
+ /* In any event, bump the stack offset to include space for
+ * this new symbol. The 'bumped' stack offset will be the
+ * offset for the next variable that is declared.
+ */
+
+ dstack += g_dwVarSize;
+ }
+
+ return typePtr;
+}
+
+/***************************************************************/
+/* Process VAR FILE OF declaration */
+
+static void pas_DeclareFile(void)
+{
+ int16_t fileNumber = tknPtr->sParm.fileNumber;
+ STYPE *filePtr;
+
+ TRACE(lstFile,"[pas_DeclareFile]");
+
+ /* FORM: <file identifier> : FILE OF <type> */
+ /* OR: <file identifier> : <FILE OF type identifier> */
+ if (!(fileNumber)) error(eINVFILE);
+ else if (files [fileNumber].defined) error(eDUPFILE);
+ else {
+
+ /* Skip over the <file identifier> */
+ getToken();
+
+ /* Verify that a colon follows the <file identifier> */
+ if (token != ':') error (eCOLON);
+ else getToken();
+
+ /* Make sure that the data stack is aligned to INTEGER boundaries */
+ dstack = intAlign(dstack);
+
+ /* FORM: <file identifier> : FILE OF <type> */
+ if (token == sFILE_OF) {
+
+ files[fileNumber].defined = -1;
+ files[fileNumber].flevel = level;
+ files[fileNumber].ftype = tknPtr->sParm.t.type;
+ files[fileNumber].faddr = dstack;
+ files[fileNumber].fsize = tknPtr->sParm.t.asize;
+ dstack += (tknPtr->sParm.t.asize);
+ getToken();
+
+ }
+
+ /* FORM: <file identifier> : <FILE OF type identifier> */
+ else {
+ if (token != tFILE) error (eFILE);
+ else getToken();
+ if (token != tOF) error (eOF);
+ else getToken();
+
+ filePtr = pas_TypeIdentifier(1);
+ if (filePtr) {
+
+ files[fileNumber].defined = -1;
+ files[fileNumber].flevel = level;
+ files[fileNumber].ftype = filePtr->sParm.t.type;
+ files[fileNumber].faddr = dstack;
+ files[fileNumber].fsize = g_dwVarSize;
+ dstack += g_dwVarSize;
+
+ }
+ }
+ }
+}
+
+/***************************************************************/
+/* Process Procedure Declaration Block */
+
+static void pas_ProcedureDeclaration(void)
+{
+ uint16_t procLabel = ++label;
+ char *saveStringSP;
+ STYPE *procPtr;
+ register int i;
+
+ TRACE(lstFile,"[pas_ProcedureDeclaration]");
+
+ /* FORM: procedure-declaration =
+ * procedure-heading ';' directive |
+ * procedure-heading ';' procedure-block
+ * FORM: procedure-heading =
+ * 'procedure' identifier [ formal-parameter-list ]
+ * FORM: procedure-identifier = identifier
+ *
+ * On entry, token refers to token AFTER the 'procedure' reserved
+ * word.
+ */
+
+ /* Process the procedure-heading */
+
+ if (token != tIDENT)
+ {
+ error (eIDENT);
+ return;
+ }
+
+ /* Add the procedure to the symbol table */
+
+ procPtr = addProcedure(tkn_strt, sPROC, procLabel, 0, NULL);
+
+ /* Save the string stack pointer so that we can release all
+ * formal parameter strings later. Then get the next token.
+ */
+
+ saveStringSP = stringSP;
+ getToken();
+
+ /* NOTE: The level associated with the PROCEDURE symbol is the level
+ * At which the procedure was declared. Everything declare within the
+ * PROCEDURE is at the next level
+ */
+
+ level++;
+
+ /* Process parameter list */
+
+ (void)formalParameterList(procPtr);
+
+ if (token != ';') error (eSEMICOLON);
+ else getToken();
+
+ /* If we are here then we know that we are either in a program file
+ * or the 'implementation' part of a unit file (see punit.c -- At present,
+ * the procedure declarations of the 'interface' section of a unit file
+ * follow a different path). In the latter case (only), we should export
+ * every procedure declared at level zero.
+ */
+
+ if ((level == 1) && (FP->kind == eIsUnit))
+ {
+ /* EXPORT the procedure symbol. */
+
+ pas_GenerateProcExport(procPtr);
+ }
+
+ /* Save debug information about the procedure */
+
+ pas_GenerateDebugInfo(procPtr, 0);
+
+ /* Process block */
+
+ pas_GenerateDataOperation(opLABEL, (int32_t)procLabel);
+ block();
+
+ /* Destroy formal parameter names */
+
+ for (i = 1; i <= procPtr->sParm.p.nParms; i++)
+ {
+ procPtr[i].sName = NULL;
+ }
+
+ stringSP = saveStringSP;
+
+ /* Generate exit from procedure */
+
+ pas_GenerateSimple(opRET);
+ level--;
+
+ /* Verify that END terminates with a semicolon */
+
+ if (token != ';') error (eSEMICOLON);
+ else getToken();
+}
+
+/***************************************************************/
+/* Process Function Declaration Block */
+
+static void pas_FunctionDeclaration(void)
+{
+ uint16_t funcLabel = ++label;
+ int16_t parameterOffset;
+ char *saveStringSP;
+ STYPE *funcPtr;
+ STYPE *valPtr;
+ STYPE *typePtr;
+ char *funcName;
+ register int i;
+
+ TRACE(lstFile,"[pas_FunctionDeclaration]");
+
+ /* FORM: function-declaration =
+ * function-heading ';' directive |
+ * function-heading ';' function-block
+ * FORM: function-heading =
+ * 'function' function-identifier [ formal-parameter-list ]
+ * ':' result-type
+ *
+ * On entry token should lrefer to the function-identifier.
+ */
+
+ /* Verify function-identifier */
+
+ if (token != tIDENT)
+ {
+ error (eIDENT);
+ return;
+ }
+
+ funcPtr = addProcedure(tkn_strt, sFUNC, funcLabel, 0, NULL);
+
+ /* NOTE: The level associated with the FUNCTION symbol is the level
+ * At which the procedure was declared. Everything declare within the
+ * PROCEDURE is at the next level
+ */
+
+ level++;
+
+ /* Save the string stack pointer so that we can release all
+ * formal parameter strings later. Then get the next token.
+ */
+
+ funcName = tkn_strt;
+ saveStringSP = stringSP;
+ getToken();
+
+ /* Process parameter list */
+
+ parameterOffset = formalParameterList(funcPtr);
+
+ /* Verify that the parameter list is followed by a colon */
+
+ if (token != ':') error (eCOLON);
+ else getToken();
+
+ /* Declare the function return value variable. This variable has
+ * the same name as the function itself. We fill the variable
+ * symbol descriptor with bogus information now (but we fix it
+ * below).
+ */
+
+ valPtr = addVariable(funcName, sINT, 0, sINT_SIZE, NULL);
+
+ /* Get function type, return value type/size and offset to return value */
+
+ typePtr = pas_TypeIdentifier(0);
+ if (typePtr) {
+
+ /* The offset to the return value is the offset to the last
+ * parameter minus the size of the return value (aligned to
+ * multiples of size of INTEGER).
+ */
+
+ parameterOffset -= g_dwVarSize;
+ parameterOffset = intAlign(parameterOffset);
+
+ /* Save the TYPE for the function return value local variable */
+
+ valPtr->sKind = typePtr->sParm.t.rtype;
+ valPtr->sParm.v.offset = parameterOffset;
+ valPtr->sParm.v.size = g_dwVarSize;
+ valPtr->sParm.v.parent = typePtr;
+
+ /* Save the TYPE for the function */
+
+ funcPtr->sParm.p.parent = typePtr;
+
+ /* If we are here then we know that we are either in a program file
+ * or the 'implementation' part of a unit file (see punit.c -- At present,
+ * the function declarations of the 'interface' section of a unit file
+ * follow a different path). In the latter case (only), we should export
+ * every function declared at level zero.
+ */
+
+ if ((level == 1) && (FP->kind == eIsUnit))
+ {
+ /* EXPORT the function symbol. */
+
+ pas_GenerateProcExport(funcPtr);
+ }
+ }
+ else
+ error(eINVTYPE);
+
+ /* Save debug information about the function */
+
+ pas_GenerateDebugInfo(funcPtr, g_dwVarSize);
+
+ /* Process block */
+
+ if (token != ';') error (eSEMICOLON);
+ else getToken();
+
+ pas_GenerateDataOperation(opLABEL, (int32_t)funcLabel);
+ block();
+
+ /* Destroy formal parameter names and the function return value name */
+
+ for (i = 1; i <= funcPtr->sParm.p.nParms; i++)
+ {
+ funcPtr[i].sName = ((char *) NULL);
+ }
+
+ valPtr->sName = ((char *) NULL);
+ stringSP = saveStringSP;
+
+ /* Generate exit from procedure/function */
+
+ pas_GenerateSimple(opRET);
+ level--;
+
+ /* Verify that END terminates with a semicolon */
+
+ if (token != ';') error (eSEMICOLON);
+ else getToken();
+}
+
+/***************************************************************/
+/* Determine the size value to use with this type */
+
+static void pas_SetTypeSize(STYPE *typePtr, bool allocate)
+{
+ TRACE(lstFile,"[pas_SetTypeSize]");
+
+ /* Check for type-identifier */
+
+ g_dwVarSize = 0;
+
+ if (typePtr != NULL)
+ {
+ /* If allocate is true, then we want to return the size of
+ * the type that we would use if we are going to allocate
+ * an instance on the stack.
+ */
+
+ if (allocate)
+ {
+ /* Could it be a storage size value (such as is used for
+ * the enhanced pascal string type?). In an weak attempt to
+ * be compatible with everyone in the world, we will allow
+ * either '[]' or '()' to delimit the size specification.
+ */
+
+ if (((token == '[') || (token == '(')) &&
+ ((typePtr->sParm.t.flags & STYPE_VARSIZE) != 0))
+ {
+ uint16_t term_token;
+ uint16_t errcode;
+
+ /* Yes... we need to parse the size from the input stream.
+ * First, determine which token will terminate the size
+ * specification.
+ */
+
+ if (token == '(')
+ {
+ term_token = ')'; /* Should end with ')' */
+ errcode = eRPAREN; /* If not, this is the error */
+ }
+ else
+ {
+ term_token = ']'; /* Should end with ']' */
+ errcode = eRBRACKET; /* If not, this is the error */
+ }
+
+ /* Now, parse the size specification */
+
+ /* We expect the size to consist of a single integer constant.
+ * We should support any constant integer expression, but this
+ * has not yet been implemented.
+ */
+
+ getToken();
+ if (token != tINT_CONST) error(eINTCONST);
+ /* else if (tknInt <= 0) error(eINVCONST); see below */
+ else if (tknInt <= 2) error(eINVCONST);
+ else
+ {
+ /* Use the value of the integer constant for the size
+ * the allocation. NOTE: There is a problem here in
+ * that for the sSTRING type, it wants the first 2 bytes
+ * for the string length. This means that the actual
+ * length is real two less than the specified length.
+ */
+
+ g_dwVarSize = tknInt;
+ }
+
+ /* Verify that the correct token terminated the size
+ * specification. This could be either ')' or ']'
+ */
+
+ getToken();
+ if (token != term_token) error(errcode);
+ else getToken();
+ }
+ else
+ {
+ /* Return the fixed size of the allocated instance of
+ * this type */
+
+ g_dwVarSize = typePtr->sParm.t.asize;
+ }
+ }
+
+ /* If allocate is false, then we want to return the size of
+ * the type that we would use if we are going to refer to
+ * a reference on the stack. This is really non-standard
+ * and is handle certain optimatizations where we cheat and
+ * pass some types by reference rather than by value. The
+ * enhanced pascal string type is the only example at present.
+ */
+
+ else
+ {
+ /* Return the size to a clone, reference to an instance */
+
+ g_dwVarSize = typePtr->sParm.t.rsize;
+ }
+ }
+}
+
+/***************************************************************/
+/* Verify that the next token is a type identifer
+ * NOTE: This function modifies the global variable g_dwVarSize
+ * as a side-effect
+ */
+
+static STYPE *pas_TypeIdentifier(bool allocate)
+{
+ STYPE *typePtr = NULL;
+
+ TRACE(lstFile,"[pas_TypeIdentifier]");
+
+ /* Check for type-identifier */
+
+ if (token == sTYPE)
+ {
+ /* Return a reference to the type token. */
+
+ typePtr = tknPtr;
+ getToken();
+
+ /* Return the size value associated with this type */
+
+ pas_SetTypeSize(typePtr, allocate);
+ }
+
+ return typePtr;
+}
+
+/***************************************************************/
+
+static STYPE *pas_TypeDenoter(char *typeName, bool allocate)
+{
+ STYPE *typePtr;
+
+ TRACE(lstFile,"[pas_TypeDenoter]");
+
+ /* FORM: type-denoter = type-identifier | new-type
+ *
+ * Check for type-identifier
+ */
+
+ typePtr = pas_TypeIdentifier(allocate);
+ if (typePtr != NULL)
+ {
+ /* Return the type identifier */
+
+ return typePtr;
+ }
+
+ /* Check for new-type
+ * FORM: new-type = new-ordinal-type | new-complex-type
+ */
+
+ /* Check for new-complex-type */
+
+ typePtr = pas_NewComplexType(typeName);
+ if (typePtr == NULL)
+ {
+ /* Check for new-ordinal-type */
+
+ typePtr = pas_NewOrdinalType(typeName);
+ }
+
+ /* Return the size value associated with this type */
+
+ pas_SetTypeSize(typePtr, allocate);
+
+ return typePtr;
+}
+
+/***************************************************************/
+/* Declare is new ordinal type */
+
+static STYPE *pas_NewOrdinalType(char *typeName)
+{
+ STYPE *typePtr = NULL;
+
+ /* Declare a new-ordinal-type
+ * FORM: new-ordinal-type = enumerated-type | subrange-type
+ */
+
+ /* FORM: enumerated-type = '(' enumerated-constant-list ')' */
+
+ if (token == '(')
+ {
+ int32_t nObjects;
+ nObjects = 0;
+ typePtr = addTypeDefine(typeName, sSCALAR, sINT_SIZE, NULL);
+
+ /* Now declare each instance of the scalar */
+
+ do {
+ getToken();
+ if (token != tIDENT) error(eIDENT);
+ else
+ {
+ (void)addConstant(tkn_strt, sSCALAR_OBJECT, &nObjects, typePtr);
+ nObjects++;
+ getToken();
+ }
+ } while (token == ',');
+
+ /* Save the number of objects associated with the scalar type (the
+ * maximum ORD is nObjects - 1). */
+
+ typePtr->sParm.t.maxValue = nObjects - 1;
+
+ if (token != ')') error(eRPAREN);
+ else getToken();
+
+ }
+
+ /* Declare a new subrange type
+ * FORM: subrange-type = constant '..' constant
+ * FORM: constant =
+ * [ sign ] integer-number | [ sign ] real-number |
+ * [ sign ] constant-identifier | character-literal | string-literal
+ *
+ * Case 1: <constant> is INTEGER
+ */
+
+ else if (token == tINT_CONST)
+ {
+ /* Create the new INTEGER subrange type */
+
+ typePtr = addTypeDefine(typeName, sSUBRANGE, sINT_SIZE, NULL);
+ typePtr->sParm.t.subType = sINT;
+ typePtr->sParm.t.minValue = tknInt;
+ typePtr->sParm.t.maxValue = MAXINT;
+
+ /* Verify that ".." separates the two constants */
+
+ getToken();
+ if (token != tSUBRANGE) error(eSUBRANGE);
+ else getToken();
+
+ /* Verify that the ".." is following by an INTEGER constant */
+
+ if ((token != tINT_CONST) || (tknInt < typePtr->sParm.t.minValue))
+ error(eSUBRANGETYPE);
+ else
+ {
+ typePtr->sParm.t.maxValue = tknInt;
+ getToken();
+ }
+ }
+
+ /* Case 2: <constant> is CHAR */
+
+ else if (token == tCHAR_CONST)
+ {
+ /* Create the new CHAR subrange type */
+
+ typePtr = addTypeDefine(typeName, sSUBRANGE, sCHAR_SIZE, NULL);
+ typePtr->sParm.t.subType = sCHAR;
+ typePtr->sParm.t.minValue = tknInt;
+ typePtr->sParm.t.maxValue = MAXCHAR;
+
+ /* Verify that ".." separates the two constants */
+
+ getToken();
+ if (token != tSUBRANGE) error(eSUBRANGE);
+ else getToken();
+
+ /* Verify that the ".." is following by a CHAR constant */
+
+ if ((token != tCHAR_CONST) || (tknInt < typePtr->sParm.t.minValue))
+ error(eSUBRANGETYPE);
+ else
+ {
+ typePtr->sParm.t.maxValue = tknInt;
+ getToken();
+ }
+ }
+
+ /* Case 3: <constant> is a SCALAR type */
+
+ else if (token == sSCALAR_OBJECT)
+ {
+ /* Create the new SCALAR subrange type */
+
+ typePtr = addTypeDefine(typeName, sSUBRANGE, sINT_SIZE, tknPtr);
+ typePtr->sParm.t.subType = token;
+ typePtr->sParm.t.minValue = tknInt;
+ typePtr->sParm.t.maxValue = MAXINT;
+
+ /* Verify that ".." separates the two constants */
+
+ getToken();
+ if (token != tSUBRANGE) error(eSUBRANGE);
+ else getToken();
+
+ /* Verify that the ".." is following by a SCALAR constant of the same
+ * type as the one which preceded it
+ */
+
+ if ((token != sSCALAR_OBJECT) ||
+ (tknPtr != typePtr->sParm.t.parent) ||
+ (tknPtr->sParm.c.val.i < typePtr->sParm.t.minValue))
+ error(eSUBRANGETYPE);
+ else
+ {
+ typePtr->sParm.t.maxValue = tknPtr->sParm.c.val.i;
+ getToken();
+ }
+ }
+
+ return typePtr;
+}
+
+/***************************************************************/
+
+static STYPE *pas_NewComplexType(char *typeName)
+{
+ STYPE *typePtr = NULL;
+ STYPE *typeIdPtr;
+
+ TRACE(lstFile,"[pas_TypeDenoter]");
+
+ /* FORM: new-complex-type = new-structured-type | new-pointer-type */
+
+ switch (token)
+ {
+ /* FORM: new-pointer-type = '^' domain-type | '@' domain-type */
+
+ case '^' :
+ getToken();
+ typeIdPtr = pas_TypeIdentifier(1);
+ if (typeIdPtr)
+ {
+ typePtr = addTypeDefine(typeName, sPOINTER, g_dwVarSize, typeIdPtr);
+ }
+ else
+ {
+ error(eINVTYPE);
+ }
+ break;
+
+ /* FORM: new-structured-type =
+ * [ 'packed' ] array-type | [ 'packed' ] record-type |
+ * [ 'packed' ] set-type | [ 'packed' ] file-type |
+ * [ 'packed' ] list-type | object-type | string-type
+ */
+
+ /* PACKED Types */
+
+ case tPACKED :
+ error (eNOTYET);
+ getToken();
+ if (token != tARRAY) break;
+ /* Fall through to process PACKED ARRAY type */
+
+ /* Array Types
+ * FORM: array-type = 'array' [ index-type-list ']' 'of' type-denoter
+ */
+
+ case tARRAY :
+ getToken();
+ typeIdPtr = pas_GetArrayType();
+ if (typeIdPtr)
+ {
+ typePtr = addTypeDefine(typeName, sARRAY, g_dwVarSize, typeIdPtr);
+ }
+ else
+ {
+ error(eINVTYPE);
+ }
+ break;
+
+ /* RECORD Types
+ * FORM: record-type = 'record' field-list 'end'
+ */
+
+ case tRECORD :
+ getToken();
+ typePtr = pas_DeclareRecord(typeName);
+ break;
+
+ /* Set Types
+ *
+ * FORM: set-type = 'set' 'of' ordinal-type
+ */
+
+ case tSET :
+
+ /* Verify that 'set' is followed by 'of' */
+
+ getToken();
+ if (token != tOF) error (eOF);
+ else getToken();
+
+ /* Verify that 'set of' is followed by an ordinal-type
+ * If not, then declare a new one with no name
+ */
+
+ typeIdPtr = pas_OrdinalTypeIdentifier(1);
+ if (typeIdPtr)
+ getToken();
+ else
+ typeIdPtr = pas_DeclareOrdinalType(NULL);
+
+ /* Verify that the ordinal-type is either a scalar or a
+ * subrange type. These are the only valid types for 'set of'
+ */
+
+ if ((typeIdPtr) &&
+ ((typeIdPtr->sParm.t.type == sSCALAR) ||
+ (typeIdPtr->sParm.t.type == sSUBRANGE)))
+ {
+ /* Declare the SET type */
+
+ typePtr = addTypeDefine(typeName, sSET_OF,
+ typeIdPtr->sParm.t.asize, typeIdPtr);
+
+ if (typePtr)
+ {
+ int16_t nObjects;
+
+ /* Copy the scalar/subrange characteristics for convenience */
+
+ typePtr->sParm.t.subType = typeIdPtr->sParm.t.type;
+ typePtr->sParm.t.minValue = typeIdPtr->sParm.t.minValue;
+ typePtr->sParm.t.maxValue = typeIdPtr->sParm.t.minValue;
+
+ /* Verify that the number of objects associated with the
+ * scalar or subrange type will fit into an integer
+ * representation of a set as a bit-string.
+ */
+
+ nObjects = typeIdPtr->sParm.t.maxValue
+ - typeIdPtr->sParm.t.minValue + 1;
+ if (nObjects > BITS_IN_INTEGER)
+ {
+ error(eSETRANGE);
+ typePtr->sParm.t.maxValue = typePtr->sParm.t.minValue
+ + BITS_IN_INTEGER - 1;
+ }
+ }
+ }
+ else
+ error(eSET);
+ break;
+
+ /* File Types
+ * FORM: file-type = 'file' 'of' type-denoter
+ */
+
+ /* FORM: file-type = 'file' 'of' type-denoter */
+
+ case tFILE :
+
+ /* Make sure that 'file' is followed by 'of' */
+
+ getToken();
+ if (token != tOF) error (eOF);
+ else getToken();
+
+ /* Get the type-denoter */
+
+ typeIdPtr = pas_TypeDenoter(NULL,1);
+ if (typeIdPtr)
+ {
+ typePtr = addTypeDefine(typeName, sFILE_OF, g_dwVarSize, typeIdPtr);
+ if (typePtr)
+ {
+ typePtr->sParm.t.subType = typeIdPtr->sParm.t.type;
+ }
+ }
+ else
+ {
+ error(eINVTYPE);
+ }
+ break;
+
+ /* FORM: string-type = pascal-string-type | c-string-type
+ * FORM: pascal-string-type = 'string' [ max-string-length ]
+ */
+ case sSTRING :
+ error (eNOTYET);
+ getToken();
+ break;
+
+ /* FORM: list-type = 'list' 'of' type-denoter */
+ /* FORM: object-type = 'object' | 'class' */
+ default :
+ break;
+
+ }
+
+ return typePtr;
+}
+
+/***************************************************************/
+/* Verify that the next token is a type identifer
+ */
+
+static STYPE *pas_OrdinalTypeIdentifier(bool allocate)
+{
+ STYPE *typePtr;
+
+ TRACE(lstFile,"[pas_OrdinalTypeIdentifier]");
+
+ /* Get the next type from the input stream */
+
+ typePtr = pas_TypeIdentifier(allocate);
+
+ /* Was a type encountered? */
+
+ if (typePtr != NULL)
+ {
+ switch (typePtr->sParm.t.type)
+ {
+ /* Check for an ordinal type (verify this list!) */
+
+ case sINT :
+ case sBOOLEAN :
+ case sCHAR :
+ case sSCALAR :
+ case sSUBRANGE:
+ /* If it is an ordinal type, then just return the
+ * type pointer.
+ */
+
+ break;
+ default :
+ /* If not, return NULL */
+
+ typePtr = NULL;
+ break;
+ }
+ }
+ return typePtr;
+}
+
+/***************************************************************/
+/* get array type argument for TYPE block or variable declaration */
+
+static STYPE *pas_GetArrayType(void)
+{
+ STYPE *typePtr = NULL;
+
+ TRACE(lstFile,"[pas_GetArrayType]");
+
+ /* FORM: array-type = 'array' '[' index-type-list ']' 'of' type-denoter */
+ /* FORM: [PACKED] ARRAY [<integer>] OF type-denoter
+ * NOTE: Bracketed value is the array size! NONSTANDARD! */
+
+ g_dwVarSize = 0;
+
+ /* Verify that the index-type-list is preceded by '[' */
+
+ if (token != '[') error (eLBRACKET);
+ else
+ {
+ /* FORM: index-type-list = index-type { ',' index-type }
+ * FORM: index-type = ordinal-type
+ */
+
+ getToken();
+ if (token != tINT_CONST) error (eINTCONST);
+ else
+ {
+ g_dwVarSize = tknInt;
+ getToken();
+
+ /* Verify that the index-type-list is followed by ']' */
+
+ if (token != ']') error (eRBRACKET);
+ else getToken();
+
+ /* Verify that 'of' precedes the type-denoter */
+
+ if (token != tOF) error (eOF);
+ else getToken();
+
+ /* We have the array size in elements, not get the type and convert
+ * the size for the type found
+ */
+
+ typePtr = pas_DeclareType(NULL);
+ if (typePtr)
+ {
+ g_dwVarSize *= typePtr->sParm.t.asize;
+ }
+ }
+ }
+
+ return typePtr;
+}
+
+/***************************************************************/
+
+static STYPE *pas_DeclareRecord(char *recordName)
+{
+ STYPE *recordPtr;
+ int16_t recordOffset;
+ int recordCount, symbolIndex;
+
+ TRACE(lstFile,"[pas_DeclareRecord]");
+
+ /* FORM: record-type = 'record' field-list 'end' */
+
+ /* Declare the new RECORD type */
+
+ recordPtr = addTypeDefine(recordName, sRECORD, 0, NULL);
+
+ /* Then declare the field-list associated with the RECORD
+ * FORM: field-list =
+ * [
+ * fixed-part [ ';' ] variant-part [ ';' ] |
+ * fixed-part [ ';' ] |
+ * variant-part [ ';' ] |
+ * ]
+ *
+ * Process the fixed-part first.
+ * FORM: fixed-part = record-section { ';' record-section }
+ * FORM: record-section = identifier-list ':' type-denoter
+ * FORM: identifier-list = identifier { ',' identifier }
+ */
+
+ for (;;)
+ {
+ /* Terminate parsing of the fixed-part when we encounter
+ * 'case' indicating the beginning of the variant part of
+ * the record. If there is no fixed-part, then 'case' will
+ * appear immediately.
+ */
+
+ if (token == tCASE) break;
+
+ /* We now expect to see and indentifier representating the
+ * beginning of the next fixed field.
+ */
+
+ (void)pas_DeclareField(recordPtr);
+
+ /* If the field declaration terminates with a semicolon, then
+ * we expect to see another <fixed part> declaration in the
+ * record.
+ */
+
+ if (token == ';')
+ {
+ /* Skip over the semicolon and process the next fixed
+ * field declaration.
+ */
+
+ getToken();
+
+ /* We will treat this semi colon as optional. If we
+ * hit 'end' or 'case' after the semicolon, then we
+ * will terminate the fixed part with no complaint.
+ */
+
+ if ((token == tEND) || (token == tCASE))
+ break;
+ }
+
+ /* If there is no semicolon after the field declaration,
+ * then 'end' or 'case' is expected. This will be verified
+ * below.
+ */
+
+ else break;
+ }
+
+ /* Get the total size of the RECORD type and the offset of each
+ * field within the RECORD.
+ */
+
+ for (recordOffset = 0, symbolIndex = 1, recordCount = 0;
+ recordCount < recordPtr->sParm.t.maxValue;
+ symbolIndex++)
+ {
+ /* We know that 'maxValue' sRECORD_OBJECT symbols follow the sRECORD
+ * type declaration. However, these may not be sequential due to the
+ * possible declaration of sTYPEs associated with each field.
+ */
+
+ if (recordPtr[symbolIndex].sKind == sRECORD_OBJECT)
+ {
+ /* Align the recordOffset (if necessary) */
+
+ if ((!isIntAligned(recordOffset)) &&
+ (pas_IntAlignRequired(recordPtr[symbolIndex].sParm.r.parent)))
+ recordOffset = intAlign(recordOffset);
+
+ /* Save the offset associated with this field, and determine the
+ * offset to the next field (if there is one)
+ */
+
+ recordPtr[symbolIndex].sParm.r.offset = recordOffset;
+ recordOffset += recordPtr[symbolIndex].sParm.r.size;
+ recordCount++;
+ }
+ }
+
+ /* Update the RECORD entry for the total size of all fields */
+
+ recordPtr->sParm.t.asize = recordOffset;
+
+ /* Now we are ready to process the variant-part.
+ * FORM: variant-part = 'case' variant-selector 'of' variant-body
+ */
+
+ if (token == tCASE)
+ {
+ int16_t variantOffset;
+ uint16_t maxRecordSize;
+
+ /* Skip over the 'case' */
+
+ getToken();
+
+ /* Check for variant-selector
+ * FORM: variant-selector = [ identifier ':' ] ordinal-type-identifer
+ */
+
+ if (token != tIDENT) error(eRECORDDECLARE);
+
+ /* Add a variant-selector to the fixed-part of the record */
+
+ else
+ {
+ STYPE *typePtr;
+ char *fieldName;
+
+ /* Save the field name */
+
+ fieldName = tkn_strt;
+ getToken();
+
+ /* Verify that the identifier is followed by a colon */
+
+ if (token != ':') error(eCOLON);
+ else getToken();
+
+ /* Get the ordinal-type-identifier */
+
+ typePtr = pas_OrdinalTypeIdentifier(1);
+ if (!typePtr) error(eINVTYPE);
+ else
+ {
+ STYPE *fieldPtr;
+
+ /* Declare a <field> with this <identifier> as its name */
+
+ fieldPtr = addField(fieldName, recordPtr);
+
+ /* Increment the number of fields in the record */
+
+ recordPtr->sParm.t.maxValue++;
+
+ /* Copy the size of field from the sTYPE entry into the
+ * <field> type entry. NOTE: This element is not essential
+ * since it can be obtained from the parent type pointer
+ */
+
+ fieldPtr->sParm.r.size = typePtr->sParm.t.asize;
+
+ /* Save a pointer back to the parent field type */
+
+ fieldPtr->sParm.r.parent = typePtr;
+
+ /* Align the recordOffset (if necessary) */
+
+ if ((!isIntAligned(recordOffset)) &&
+ (pas_IntAlignRequired(typePtr)))
+ recordOffset = intAlign(recordOffset);
+
+ /* Save the offset associated with this field, and determine
+ * the offset to the next field (if there is one)
+ */
+
+ fieldPtr->sParm.r.offset = recordOffset;
+ recordOffset += recordPtr[symbolIndex].sParm.r.size;
+ }
+ }
+
+ /* Save the offset to the start of the variant portion of the RECORD */
+
+ variantOffset = recordOffset;
+ maxRecordSize = recordOffset;
+
+ /* Skip over the 'of' following the variant selector */
+
+ if (token != tOF) error(eOF);
+ else getToken();
+
+ /* Loop to process the variant-body
+ * FORM: variant-body =
+ * variant-list [ [ ';' ] variant-part-completer ] |
+ * variant-part-completer
+ * FORM: variant-list = variant { ';' variant }
+ * FORM: variant-part-completer = ( 'otherwise' | 'else' ) ( field-list )
+ */
+
+ for (;;)
+ {
+ /* Now process each variant where:
+ * FORM: variant = case-constant-list ':' '(' field-list ')'
+ * FORM: case-constant-list = case-specifier { ',' case-specifier }
+ * FORM: case-specifier = case-constant [ '..' case-constant ]
+ */
+
+ /* Verify that the case selector begins with a case-constant.
+ * Note that subrange case-specifiers are not yet supported.
+ */
+
+ if (!isConstant(token))
+ {
+ error(eINVCONST);
+ break;
+ }
+
+ /* Just consume the <case selector> for now -- Really need to
+ * verify that each constant is of the same type as the type
+ * identifier (or the type associated with the tag) in the CASE
+ */
+
+ do
+ {
+ getToken();
+ if (token == ',') getToken();
+ }
+ while (isConstant(token));
+
+ /* Make sure a colon separates case-constant-list from the
+ * field-list
+ */
+
+ if (token == ':') getToken();
+ else error(eCOLON);
+
+ /* The field-list must be enclosed in parentheses */
+
+ if (token == '(') getToken();
+ else error(eLPAREN);
+
+ /* Special case the empty variant <field list> */
+
+ if (token != ')')
+ {
+ /* Now process the <field list> for the variant. This works
+ * just like the field list of the fixed part, except the
+ * offset is reset for each variant.
+ * FORM: field-list =
+ * [
+ * fixed-part [ ';' ] variant-part [ ';' ] |
+ * fixed-part [ ';' ] |
+ * variant-part [ ';' ] |
+ * ]
+ */
+
+ for (;;)
+ {
+ /* We now expect to see and indentifier representating the
+ * beginning of the next variablefield.
+ */
+
+ (void)pas_DeclareField(recordPtr);
+
+ /* If the field declaration terminates with a semicolon,
+ * then we expect to see another <variable part>
+ * declaration in the record.
+ */
+
+ if (token == ';')
+ {
+ /* Skip over the semicolon and process the next
+ * variable field declaration.
+ */
+
+ getToken();
+
+ /* We will treat this semi colon as optional. If we
+ * hit 'end' after the semicolon, then we will
+ * terminate the fixed part with no complaint.
+ */
+
+ if (token == tEND)
+ break;
+ }
+ else break;
+ }
+
+ /* Get the total size of the RECORD type and the offset of each
+ * field within the RECORD.
+ */
+
+ for (recordOffset = variantOffset;
+ recordCount < recordPtr->sParm.t.maxValue;
+ symbolIndex++)
+ {
+ /* We know that 'maxValue' sRECORD_OBJECT symbols follow
+ * the sRECORD type declaration. However, these may not
+ * be sequential due to the possible declaration of sTYPEs
+ * associated with each field.
+ */
+
+ if (recordPtr[symbolIndex].sKind == sRECORD_OBJECT)
+ {
+ /* Align the recordOffset (if necessary) */
+
+ if ((!isIntAligned(recordOffset)) &&
+ (pas_IntAlignRequired(recordPtr[symbolIndex].sParm.r.parent)))
+ recordOffset = intAlign(recordOffset);
+
+ /* Save the offset associated with this field, and
+ * determine the offset to the next field (if there
+ * is one)
+ */
+
+ recordPtr[symbolIndex].sParm.r.offset = recordOffset;
+ recordOffset += recordPtr[symbolIndex].sParm.r.size;
+ recordCount++;
+ }
+ }
+
+ /* Check if this is the largest variant that we have found
+ * so far
+ */
+
+ if (recordOffset > maxRecordSize)
+ maxRecordSize = recordOffset;
+ }
+
+ /* Verify that the <field list> is enclosed in parentheses */
+
+ if (token == ')') getToken();
+ else error(eRPAREN);
+
+ /* A semicolon at this position means that another <variant>
+ * follows. Keep looping until all of the variants have been
+ * processed (i.e., no semi-colon)
+ */
+
+ if (token == ';') getToken();
+ else break;
+ }
+
+ /* Update the RECORD entry for the maximum size of all variants */
+
+ recordPtr->sParm.t.asize = maxRecordSize;
+ }
+
+ /* Verify that the RECORD declaration terminates with END */
+
+ if (token != tEND) error(eRECORDDECLARE);
+ else getToken();
+
+ return recordPtr;
+}
+
+/***************************************************************/
+
+static STYPE *pas_DeclareField(STYPE *recordPtr)
+{
+ STYPE *fieldPtr = NULL;
+ STYPE *typePtr;
+
+ TRACE(lstFile,"[pas_DeclareField]");
+
+ /* Declare one record-section with a record.
+ * FORM: record-section = identifier-list ':' type-denoter
+ * FORM: identifier-list = identifier { ',' identifier }
+ */
+
+ if (token != tIDENT) error(eIDENT);
+ else {
+
+ /* Declare a <field> with this <identifier> as its name */
+
+ fieldPtr = addField(tkn_strt, recordPtr);
+ getToken();
+
+ /* Check for multiple fields of this <type> */
+
+ if (token == ',') {
+
+ getToken();
+ typePtr = pas_DeclareField(recordPtr);
+
+ }
+ else {
+
+ if (token != ':') error(eCOLON);
+ else getToken();
+
+ /* Use the existing type or declare a new type with no name */
+
+ typePtr = pas_TypeDenoter(NULL, 1);
+ }
+
+ recordPtr->sParm.t.maxValue++;
+ if (typePtr) {
+
+ /* Copy the size of field from the sTYPE entry into the <field> */
+ /* type entry. NOTE: This element is not essential since it */
+ /* can be obtained from the parent type pointer */
+
+ fieldPtr->sParm.r.size = typePtr->sParm.t.asize;
+
+ /* Save a pointer back to the parent field type */
+
+ fieldPtr->sParm.r.parent = typePtr;
+
+ }
+ }
+
+ return typePtr;
+}
+
+/***************************************************************/
+/* Process VAR/value Parameter Declaration */
+/* NOTE: This function increments the global variable g_nParms */
+/* as a side-effect */
+
+static STYPE *pas_DeclareParameter(bool pointerType)
+{
+ int16_t varType = 0;
+ STYPE *varPtr;
+ STYPE *typePtr;
+
+ TRACE(lstFile,"[pas_DeclareParameter]");
+
+ /* FORM:
+ * <identifier>[,<identifier>[,<identifier>[...]]] : <type identifier>
+ */
+
+ if (token != tIDENT) error (eIDENT);
+ else
+ {
+ varPtr = addVariable(tkn_strt, sINT, 0, sINT_SIZE, NULL);
+ getToken();
+
+ if (token == ',')
+ {
+ getToken();
+ typePtr = pas_DeclareParameter(pointerType);
+ }
+ else
+ {
+ if (token != ':') error (eCOLON);
+ else getToken();
+ typePtr = pas_TypeIdentifier(0);
+ }
+
+ if (pointerType)
+ {
+ varType = sVAR_PARM;
+ g_dwVarSize = sPTR_SIZE;
+ }
+ else
+ {
+ varType = typePtr->sParm.t.rtype;
+ }
+
+ g_nParms++;
+ varPtr->sKind = varType;
+ varPtr->sParm.v.size = g_dwVarSize;
+ varPtr->sParm.v.parent = typePtr;
+ }
+
+ return typePtr;
+}
+
+/***************************************************************/
+
+static bool pas_IntAlignRequired(STYPE *typePtr)
+{
+ bool returnValue = false;
+
+ /* Type CHAR and ARRAYS of CHAR do not require alignment (unless
+ * they are passed as value parameters). Otherwise, alignment
+ * to type INTEGER boundaries is required.
+ */
+
+ if (typePtr)
+ {
+ if (typePtr->sKind == sCHAR)
+ {
+ returnValue = true;
+ }
+ else if (typePtr->sKind == sARRAY)
+ {
+ typePtr = typePtr->sParm.t.parent;
+ if ((typePtr) && (typePtr->sKind == sCHAR))
+ {
+ returnValue = true;
+ }
+ }
+ }
+
+ return returnValue;
+}
+
+/***************************************************************/
diff --git a/misc/pascal/pascal/pblck.h b/misc/pascal/pascal/pblck.h
new file mode 100644
index 000000000..4ff002ff5
--- /dev/null
+++ b/misc/pascal/pascal/pblck.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * pblck.h
+ * External Declarations associated with pblck.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PBLCK_H
+#define __PBLCK_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void block(void);
+extern void declarationGroup(int32_t beginLabel);
+extern void constantDefinitionGroup(void);
+extern void typeDefinitionGroup(void);
+extern void variableDeclarationGroup(void);
+extern int16_t formalParameterList(STYPE *procPtr);
+
+#endif /* __PBLCK_H */
diff --git a/misc/pascal/pascal/pcexpr.c b/misc/pascal/pascal/pcexpr.c
new file mode 100644
index 000000000..c14b6b1ee
--- /dev/null
+++ b/misc/pascal/pascal/pcexpr.c
@@ -0,0 +1,576 @@
+/***************************************************************
+ * pexpr.c
+ * Constant expression evaluation
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************/
+
+/***************************************************************
+ * Included Files
+ ***************************************************************/
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "keywords.h"
+#include "pasdefs.h"
+#include "ptdefs.h"
+#include "pedefs.h"
+
+#include "keywords.h"
+#include "pas.h"
+#include "pstm.h"
+#include "pexpr.h"
+#include "pfunc.h"
+#include "ptkn.h"
+#include "perr.h"
+
+/***************************************************************
+ * Pre-processor Definitions
+ ***************************************************************/
+
+#define ADDRESS_DEREFERENCE 0x01
+#define ADDRESS_FACTOR 0x02
+#define INDEXED_FACTOR 0x04
+#define VAR_PARM_FACTOR 0x08
+
+#define intTrunc(x) ((x) & (~(sINT_SIZE)))
+
+#define isRelationalOperator(t) \
+ (((t) == tEQ) || ((t) == tNE) || \
+ ((t) == tLT) || ((t) == tLE) || \
+ ((t) == tGT) || ((t) == tGE) || \
+ ((t) == tIN))
+
+#define isRelationalType(t) \
+ (((t) == tINT_CONST) || ((t) == tCHAR_CONST) || \
+ (((t) == tBOOLEAN_CONST) || ((t) == tREAL_CONST)))
+
+#define isAdditiveType(t) \
+ (((t) == tINT_CONST) || ((t) == tREAL_CONST))
+
+#define isMultiplicativeType(t) \
+ (((t) == tINT_CONST) || ((t) == tREAL_CONST))
+
+#define isLogicalType(t) \
+ (((t) == tINT_CONST) || ((t) == tBOOLEAN_CONST))
+
+/***************************************************************
+ * Private Type Declarations
+ ***************************************************************/
+
+/***************************************************************
+ * Private Function Prototypes
+ ***************************************************************/
+
+static void constantSimpleExpression(void);
+static void constantTerm(void);
+static void constantFactor(void);
+
+/***************************************************************
+ * Global Variables
+ ***************************************************************/
+
+int constantToken;
+int32_t constantInt;
+double constantReal;
+char *constantStart;
+
+/***************************************************************
+ * Private Variables
+ ***************************************************************/
+
+/***************************************************************/
+/* Evaluate a simple expression of constant values */
+
+void constantExpression(void)
+{
+ TRACE(lstFile,"[constantExpression]");
+
+ /* Get the value of a simple constant expression */
+
+ constantSimpleExpression();
+
+ /* Is it followed by a relational operator? */
+
+ if (isRelationalOperator(token) && isRelationalType(constantToken))
+ {
+ int simple1 = constantToken;
+ int32_t simple1Int = constantInt;
+ double simple1Real = constantReal;
+ int operator = token;
+
+ /* Get the second simple expression */
+
+ constantSimpleExpression();
+ if (simple1 != constantToken)
+ {
+ /* Handle the case where the 1st argument is REAL and the
+ * second is INTEGER. */
+
+ if ((simple1 == tREAL_CONST) && (constantToken == tINT_CONST))
+ {
+ simple1Real = (double)simple1Int;
+ simple1 = tREAL_CONST;
+ }
+
+ /* Handle the case where the 1st argument is Integer and the
+ * second is REAL. */
+
+ else if ((simple1 == tINT_CONST) && (constantToken == tREAL_CONST))
+ {
+ constantReal = (double)constantInt;
+ }
+
+ /* Allow the case of <scalar type> IN <set type>
+ * Otherwise, the two terms must agree in type
+ * -- NOT YET implemented.
+ */
+
+ else
+ {
+ error(eEXPRTYPE);
+ }
+ }
+
+ /* Generate the comparison by type */
+
+ switch (simple1)
+ {
+ case tINT_CONST :
+ case tCHAR_CONST :
+ case tBOOLEAN_CONST :
+ switch (operator)
+ {
+ case tEQ :
+ constantInt = (simple1Int == constantInt);
+ break;
+ case tNE :
+ constantInt = (simple1Int != constantInt);
+ break;
+ case tLT :
+ constantInt = (simple1Int < constantInt);
+ break;
+ case tLE :
+ constantInt = (simple1Int <= constantInt);
+ break;
+ case tGT :
+ constantInt = (simple1Int > constantInt);
+ break;
+ case tGE :
+ constantInt = (simple1Int >= constantInt);
+ break;
+ case tIN :
+ /* Not yet */
+ default :
+ error(eEXPRTYPE);
+ break;
+ }
+ break;
+
+ case tREAL_CONST:
+ switch (operator)
+ {
+ case tEQ :
+ constantInt = (simple1Real == constantReal);
+ break;
+ case tNE :
+ constantInt = (simple1Real != constantReal);
+ break;
+ case tLT :
+ constantInt = (simple1Real < constantReal);
+ break;
+ case tLE :
+ constantInt = (simple1Real <= constantReal);
+ break;
+ case tGT :
+ constantInt = (simple1Real > constantReal);
+ break;
+ case tGE :
+ constantInt = (simple1Real >= constantReal);
+ break;
+ case tIN :
+ /* Not yet */
+ default :
+ error(eEXPRTYPE);
+ break;
+ }
+ break;
+
+ default :
+ error(eEXPRTYPE);
+ break;
+ }
+
+ /* The type resulting from these operations becomes BOOLEAN */
+
+ constantToken = tBOOLEAN_CONST;
+ }
+}
+
+/***************************************************************/
+/* Process Simple Expression */
+
+static void constantSimpleExpression(void)
+{
+ int16_t unary = ' ';
+ int term;
+ int32_t termInt;
+ double termReal;
+
+ TRACE(lstFile,"[constantSimpleExpression]");
+
+ /* FORM: [+|-] <term> [{+|-} <term> [{+|-} <term> [...]]] */
+ /* get +/- unary operation */
+
+ if ((token == '+') || (token == '-'))
+ {
+ unary = token;
+ getToken();
+ }
+
+ /* Process first (non-optional) term and apply unary operation */
+
+ constantTerm();
+ term = constantToken;
+ if ((unary != ' ') && !isAdditiveType(term))
+ {
+ error(eINVSIGNEDCONST);
+ }
+ else if (unary == '-')
+ {
+ termInt = -constantInt;
+ termReal = -constantReal;
+ }
+ else
+ {
+ termInt = constantInt;
+ termReal = constantReal;
+ }
+
+ /* Process subsequent (optional) terms and binary operations */
+
+ for (;;)
+ {
+ int operator;
+
+ /* Check for binary operator */
+
+ if ((((token == '+') || (token == '-')) )&& isAdditiveType(term))
+ operator = token;
+ else if ((token == tOR) && isLogicalType(term))
+ operator = token;
+ else
+ break;
+
+ /* Get the 2nd term */
+
+ getToken();
+ constantTerm();
+
+ /* Before generating the operation, verify that the types match.
+ * Perform automatic type conversion from INTEGER to REAL as
+ * necessary.
+ */
+
+ if (term != constantToken)
+ {
+ /* Handle the case where the 1st argument is REAL and the
+ * second is INTEGER. */
+
+ if ((term == tREAL_CONST) && (constantToken == tINT_CONST))
+ {
+ constantReal = (double)constantInt;
+ constantToken = tREAL_CONST;
+ }
+
+ /* Handle the case where the 1st argument is Integer and the
+ * second is REAL. */
+
+ else if ((term == tINT_CONST) && (constantToken == tREAL_CONST))
+ {
+ termReal = (double)termInt;
+ term = tREAL_CONST;
+ }
+
+ /* Otherwise, the two terms must agree in type */
+
+ else
+ {
+ error(eTERMTYPE);
+ }
+ } /* end if */
+
+
+ /* Perform the selected binary operation */
+
+ switch (term)
+ {
+ case tINT_CONST :
+ if (operator == '+')
+ {
+ termInt += constantInt;
+ }
+ else
+ {
+ termInt -= constantInt;
+ }
+ break;
+
+ case tREAL_CONST :
+ if (operator == '+')
+ {
+ termReal += constantReal;
+ }
+ else
+ {
+ termReal -= constantReal;
+ }
+ break;
+
+ case tBOOLEAN_CONST :
+ termInt |= constantInt;
+ break;
+
+ default :
+ error(eEXPRTYPE);
+ break;
+ }
+ }
+
+ constantToken = term;
+ constantInt = termInt;
+ constantReal = termReal;
+}
+
+/***************************************************************/
+/* Evaluate a TERM */
+
+void constantTerm(void)
+{
+ int operator;
+ int factor;
+ int32_t factorInt;
+ double factorReal;
+
+ TRACE(lstFile,"[constantTerm]");
+
+ /* FORM: <factor> [<operator> <factor>[<operator><factor>[...]]] */
+
+ constantFactor();
+ factor = constantToken;
+ factorInt = constantInt;
+ factorReal = constantReal;
+ for (;;) {
+ /* Check for binary operator */
+
+ if (((token == tMUL) || (token == tMOD)) &&
+ (isMultiplicativeType(factor)))
+ operator = token;
+ else if (((token == tDIV) || (token == tSHL) || (token == tSHR)) &&
+ (factor == tINT_CONST))
+ operator = token;
+ else if ((token == tFDIV) && (factor == tREAL_CONST))
+ operator = token;
+#if 0
+ else if ((token == tFDIV) && (factor == tINT_CONST))
+ {
+ factorReal = (double)factorInt;
+ factor = tREAL_CONST;
+ operator = token;
+ }
+#endif
+ else if ((token == tAND) && isLogicalType(factor))
+ operator = token;
+ else
+ {
+ constantToken = factor;
+ constantInt = factorInt;
+ constantReal = factorReal;
+ break;
+ }
+
+ /* Get the next factor */
+
+ getToken();
+ constantFactor();
+
+ /* Before generating the operation, verify that the types match.
+ * Perform automatic type conversion from INTEGER to REAL as
+ * necessary.
+ */
+
+ if (factor != constantToken)
+ {
+ /* Handle the case where the 1st argument is REAL and the
+ * second is INTEGER. */
+
+ if ((factor == tREAL_CONST) && (constantToken == tINT_CONST))
+ {
+ constantReal = (double)constantInt;
+ }
+
+ /* Handle the case where the 1st argument is Integer and the
+ * second is REAL. */
+
+ else if ((factor == tINT_CONST) && (constantToken == tREAL_CONST))
+ {
+ factorReal = (double)factorInt;
+ factor = tREAL_CONST;
+ }
+
+ /* Otherwise, the two factors must agree in type */
+
+ else
+ {
+ error(eFACTORTYPE);
+ }
+ } /* end if */
+
+ /* Generate code to perform the selected binary operation */
+
+ switch (operator)
+ {
+ case tMUL :
+ if (factor == tINT_CONST)
+ factorInt *= constantInt;
+ else if (factor == tREAL_CONST)
+ factorReal *= constantReal;
+ else
+ error(eFACTORTYPE);
+ break;
+
+ case tDIV :
+ if (factor == tINT_CONST)
+ factorInt /= constantInt;
+ else
+ error(eFACTORTYPE);
+ break;
+
+ case tFDIV :
+ if (factor == tREAL_CONST)
+ factorReal /= constantReal;
+ else
+ error(eFACTORTYPE);
+ break;
+
+ case tMOD :
+ if (factor == tINT_CONST)
+ factorInt %= constantInt;
+ else if (factor == tREAL_CONST)
+ factorReal = fmod(factorReal, constantReal);
+ else
+ error(eFACTORTYPE);
+ break;
+
+ case tAND :
+ if ((factor == tINT_CONST) || (factor == tBOOLEAN_CONST))
+ factorInt &= constantInt;
+ else
+ error(eFACTORTYPE);
+ break;
+
+ case tSHL :
+ if (factor == tINT_CONST)
+ factorInt <<= constantInt;
+ else
+ error(eFACTORTYPE);
+ break;
+
+ case tSHR :
+ if (factor == tINT_CONST)
+ factorInt >>= constantInt;
+ else
+ error(eFACTORTYPE);
+ break;
+
+ }
+ }
+}
+
+/***************************************************************/
+/* Process a FACTOR */
+
+static void constantFactor(void)
+{
+ TRACE(lstFile,"[constantFactor]");
+
+ /* Process by token type */
+
+ switch (token)
+ {
+ case tINT_CONST :
+ case tBOOLEAN_CONST :
+ case tCHAR_CONST :
+ constantToken = token;
+ constantInt = tknInt;
+ getToken();
+ break;
+
+ case tREAL_CONST :
+ constantToken = token;
+ constantReal = tknReal;
+ getToken();
+ break;
+
+ case tSTRING_CONST :
+ constantToken = token;
+ constantStart = tkn_strt;
+ getToken();
+ break;
+
+ /* Highest Priority Operators */
+
+ case tNOT:
+ getToken();
+ constantFactor();
+ if ((constantToken != tINT_CONST) && (constantToken != tBOOLEAN_CONST))
+ error(eFACTORTYPE);
+ constantInt = ~constantInt;
+ break;
+
+ /* Built-in function? */
+
+ case tFUNC:
+ builtInFunctionOfConstant();
+ break;
+
+ /* Hmmm... Try the standard functions */
+
+ default :
+ error(eINVFACTOR);
+ break;
+ }
+}
diff --git a/misc/pascal/pascal/pcfunc.c b/misc/pascal/pascal/pcfunc.c
new file mode 100644
index 000000000..c4188ca2b
--- /dev/null
+++ b/misc/pascal/pascal/pcfunc.c
@@ -0,0 +1,341 @@
+/***************************************************************
+ * pcfunc.c
+ * Standard Function operating on constant values
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************/
+
+/***************************************************************
+ * Included Files
+ ***************************************************************/
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "keywords.h"
+#include "pasdefs.h"
+#include "ptdefs.h"
+#include "podefs.h"
+#include "pfdefs.h"
+#include "pedefs.h"
+#include "pxdefs.h"
+
+#include "pas.h"
+#include "pexpr.h"
+#include "pfunc.h"
+#include "ptkn.h"
+#include "perr.h"
+
+/***************************************************************
+ * Private Function Prototypes
+ ***************************************************************/
+
+/* Standard Pascal Functions */
+
+static void constantAbsFunc(void); /* Integer absolute value */
+static void constantPredFunc(void);
+static void constantOrdFunc(void); /* Convert scalar to integer */
+static void constantSqrFunc(void);
+static void constantRealFunc(uint8_t fpCode);
+static void constantSuccFunc(void);
+static void constantOddFunc(void);
+static void constantChrFunc(void);
+static void constantReal2IntFunc(int kind);
+static void isOrdinalConstant(void);
+
+/***************************************************************/
+/* Process a standard Pascal function call */
+
+void builtInFunctionOfConstant(void)
+{
+ TRACE(lstFile,"[builtInFunctionFactor]");
+
+ /* Is the token a function? */
+
+ if (token == tFUNC)
+ {
+ /* Yes, process it procedure according to the extended token type */
+
+ switch (tknSubType)
+ {
+ /* Functions which return the same type as their argument */
+ case txABS :
+ constantAbsFunc();
+ break;
+ case txSQR :
+ constantSqrFunc();
+ break;
+ case txPRED :
+ constantPredFunc();
+ break;
+ case txSUCC :
+ constantSuccFunc();
+ break;
+
+ /* Functions returning INTEGER with REAL arguments */
+
+ case txROUND :
+ constantReal2IntFunc(fpROUND);
+ break;
+ case txTRUNC :
+ constantReal2IntFunc(fpTRUNC);
+ break;
+
+ /* Functions returning CHARACTER with INTEGER arguments. */
+
+ case txCHR :
+ constantChrFunc();
+ break;
+
+ /* Function returning integer with scalar arguments */
+
+ case txORD :
+ constantOrdFunc();
+ break;
+
+ /* Functions returning BOOLEAN */
+ case txODD :
+ constantOddFunc();
+ break;
+
+ /* Functions returning REAL with REAL/INTEGER arguments */
+
+ case txSQRT :
+ constantRealFunc(fpSQRT);
+ break;
+ case txSIN :
+ constantRealFunc(fpSIN);
+ break;
+ case txCOS :
+ constantRealFunc(fpCOS);
+ break;
+ case txARCTAN :
+ constantRealFunc(fpATAN);
+ break;
+ case txLN :
+ constantRealFunc(fpLN);
+ break;
+ case txEXP :
+ constantRealFunc(fpEXP);
+ break;
+
+ case txGETENV : /* Non-standard C library interfaces */
+ case txEOLN :
+ case txEOF :
+ default :
+ error(eINVALIDPROC);
+ break;
+ }
+ }
+}
+
+/**********************************************************************/
+
+static void constantAbsFunc(void)
+{
+ TRACE(lstFile,"[constantAbsFunc]");
+
+ /* FORM: ABS (<simple integer/real expression>) */
+
+ checkLParen();
+ constantExpression();
+
+ if (constantToken == tINT_CONST)
+ {
+ if (constantInt < 0)
+ constantInt = -constantInt;
+ }
+ else if (constantToken == tREAL_CONST)
+ {
+ if (constantReal < 0)
+ constantReal = -constantInt;
+ }
+ else
+ error(eINVARG);
+
+ checkRParen();
+}
+
+/**********************************************************************/
+
+static void constantOrdFunc(void)
+{
+ TRACE(lstFile,"[constantOrdFunc]");
+
+ /* FORM: ORD (<scalar type>) */
+
+ checkLParen();
+ constantExpression();
+ isOrdinalConstant();
+ checkRParen();
+}
+
+/**********************************************************************/
+
+static void constantPredFunc(void)
+{
+ TRACE(lstFile,"[constantPredFunc]");
+
+ /* FORM: PRED (<simple integer expression>) */
+
+ checkLParen();
+ constantExpression();
+ isOrdinalConstant();
+ constantInt--;
+ checkRParen();
+}
+
+/**********************************************************************/
+
+static void constantSqrFunc(void)
+{
+ TRACE(lstFile,"[constantSqrFunc]");
+
+ /* FORM: SQR (<simple integer OR real expression>) */
+
+ checkLParen();
+ constantExpression();
+ if (constantToken == tINT_CONST)
+ {
+ constantInt *= constantInt;
+ }
+ else if (constantToken == tREAL_CONST)
+ {
+ constantReal *= constantReal;
+ }
+ else
+ {
+ error(eINVARG);
+ }
+
+ checkRParen();
+}
+
+/**********************************************************************/
+
+static void constantRealFunc(uint8_t fpOpCode)
+{
+ TRACE(lstFile,"[constantRealFunc]");
+
+ /* FORM: <function identifier> (<real/integer expression>) */
+
+ checkLParen();
+ constantExpression();
+ if (constantToken == tINT_CONST)
+ constantReal = (double)constantInt;
+ else
+ error(eINVARG);
+
+ checkRParen();
+}
+
+/**********************************************************************/
+
+static void constantSuccFunc(void)
+{
+ TRACE(lstFile,"[constantSuccFunc]");
+
+ /* FORM: SUCC (<simple integer expression>) */
+
+ checkLParen();
+ constantExpression();
+ isOrdinalConstant();
+ constantInt++;
+ checkRParen();
+}
+
+/***********************************************************************/
+
+static void constantOddFunc(void)
+{
+ TRACE(lstFile,"[constantOddFunc]");
+
+ /* FORM: ODD (<simple integer expression>) */
+
+ checkLParen();
+ constantExpression();
+ isOrdinalConstant();
+ constantInt &= 1;
+ expression(exprAnyOrdinal, NULL);
+ checkRParen();
+}
+
+/***********************************************************************/
+/* Process the standard chr function */
+
+static void constantChrFunc(void)
+{
+ TRACE(lstFile,"[constantCharFunc]");
+
+ /* Form: chr(integer expression).
+ *
+ * char(val) is only defined if there exists a character ch such
+ * that ord(ch) = val. If this is not the case, we will simply
+ * let the returned value exceed the range of type char. */
+
+ checkLParen();
+ constantExpression();
+ if (constantToken == tINT_CONST)
+ {
+ constantToken = tCHAR_CONST;
+ }
+ else
+ {
+ error(eINVARG);
+ }
+
+ checkRParen();
+}
+
+/***********************************************************************/
+
+static void constantReal2IntFunc(int kind)
+{
+ error(eNOTYET);
+}
+
+/***********************************************************************/
+
+static void isOrdinalConstant(void)
+{
+ if ((constantToken == tINT_CONST) || /* integer value */
+ (constantToken == tCHAR_CONST) || /* character value */
+ (constantToken == tBOOLEAN_CONST))
+ return;
+ else
+ error(eINVARG);
+}
+
+/***********************************************************************/
+
diff --git a/misc/pascal/pascal/perr.c b/misc/pascal/pascal/perr.c
new file mode 100644
index 000000000..3e1153739
--- /dev/null
+++ b/misc/pascal/pascal/perr.c
@@ -0,0 +1,191 @@
+/**********************************************************************
+ * perr.c
+ * Error Handlers
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "config.h"
+#include "keywords.h"
+#include "pasdefs.h"
+#include "pedefs.h"
+
+#include "pas.h"
+#include "ptkn.h"
+#include "perr.h"
+#if CONFIG_DEBUG
+# include "ptbl.h"
+#endif
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+#if CONFIG_DEBUG
+#define DUMPTABLES dumpTables()
+#else
+#define DUMPTABLES
+#endif
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static const char fmtErrNoToken[] =
+ "Line %d:%04ld Error %02x Token %02x\n";
+static const char fmtErrWithToken[] =
+ "Line %d:%04ld Error %02x Token %02x (%s)\n";
+static const char fmtErrAbort[] =
+ "Fatal Error %d -- Compilation aborted\n";
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static void printError(uint16_t errcode);
+
+/***********************************************************************/
+
+void errmsg(char *fmt, ...)
+{
+ char buffer[1024];
+ va_list ap;
+
+ /* Get the full string */
+
+ va_start(ap, fmt);
+ (void)vsprintf(buffer, fmt, ap);
+
+ /* Then output the string to stderr, the err file, and the list file */
+
+ fputs(buffer, stderr);
+ fputs(buffer, errFile);
+ fputs(buffer, lstFile);
+
+ va_end(ap);
+}
+
+/***********************************************************************/
+
+void warn(uint16_t errcode)
+{
+ TRACE(lstFile,"[warn:%04x]", errcode);
+
+ /* Write error record to the error and list files */
+
+ printError(errcode);
+
+ /* Increment the count of warning */
+
+ warn_count++;
+} /* end warn */
+
+/***********************************************************************/
+
+void error(uint16_t errcode)
+{
+ TRACE(lstFile,"[error:%04x]", errcode);
+
+#if CONFIG_DEBUG
+ fatal(errcode);
+#else
+ /* Write error record to the error and list files */
+
+ printError(errcode);
+
+ /* Check if err_count has been execeeded the max allowable */
+
+ if ((++err_count) > MAX_ERRORS)
+ {
+ fatal(eCOUNT);
+ }
+#endif
+
+} /* end error */
+
+/***********************************************************************/
+
+void fatal(uint16_t errcode)
+{
+ TRACE(lstFile,"[fatal:%04x]", errcode);
+
+ /* Write error record to the error and list files */
+
+ printError( errcode );
+
+ /* Dump the tables (if CONFIG_DEBUG) */
+
+ DUMPTABLES;
+
+ /* And say goodbye */
+
+ printf(fmtErrAbort, errcode);
+ fprintf(lstFile, fmtErrAbort, errcode);
+
+ exit(1);
+
+} /* end fatal */
+
+/***********************************************************************/
+
+static void printError(uint16_t errcode)
+{
+ /* Write error record to the error and list files */
+
+ if ((tkn_strt) && (tkn_strt < stringSP))
+ {
+ fprintf (errFile, fmtErrWithToken,
+ FP->include, FP->line, errcode, token, tkn_strt);
+ fprintf (lstFile, fmtErrWithToken,
+ FP->include, FP->line, errcode, token, tkn_strt);
+ stringSP = tkn_strt; /* Clean up string stack */
+ } /* end if */
+ else
+ {
+ fprintf (errFile, fmtErrNoToken,
+ FP->include, FP->line, errcode, token);
+ fprintf (lstFile, fmtErrNoToken,
+ FP->include, FP->line, errcode, token);
+ } /* end else */
+} /* end printError */
+
+/***********************************************************************/
+
diff --git a/misc/pascal/pascal/pexpr.c b/misc/pascal/pascal/pexpr.c
new file mode 100644
index 000000000..855e519f3
--- /dev/null
+++ b/misc/pascal/pascal/pexpr.c
@@ -0,0 +1,2737 @@
+/***************************************************************
+ * pexpr.c
+ * Integer Expression
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************/
+
+/***************************************************************
+ * Included Files
+ ***************************************************************/
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "keywords.h"
+#include "pasdefs.h"
+#include "ptdefs.h"
+#include "podefs.h" /* general operation codes */
+#include "pfdefs.h" /* floating point operations */
+#include "pxdefs.h" /* library operations */
+#include "pedefs.h"
+
+#include "keywords.h"
+#include "pas.h"
+#include "pstm.h"
+#include "pexpr.h"
+#include "pproc.h" /* for actualParameterList */
+#include "pfunc.h"
+#include "pgen.h" /* for pas_Generate*() */
+#include "ptkn.h"
+#include "pinsn.h"
+#include "perr.h"
+
+/***************************************************************
+ * Private Definitions
+ ***************************************************************/
+
+#define ADDRESS_DEREFERENCE 0x01
+#define ADDRESS_FACTOR 0x02
+#define INDEXED_FACTOR 0x04
+#define VAR_PARM_FACTOR 0x08
+
+#define intTrunc(x) ((x) & (~(sINT_SIZE)))
+
+/***************************************************************
+ * Private Type Declarations
+ ***************************************************************/
+
+typedef struct {
+ uint8_t setType;
+ bool typeFound;
+ int16_t minValue;
+ int16_t maxValue;
+ STYPE *typePtr;
+} setTypeStruct;
+
+/***************************************************************
+ * Private Function Prototypes
+ ***************************************************************/
+
+static exprType simpleExpression (exprType findExprType);
+static exprType term (exprType findExprType);
+static exprType factor (exprType findExprType);
+static exprType complexFactor (void);
+static exprType simpleFactor (STYPE *varPtr, uint8_t factorFlags);
+static exprType ptrFactor (void);
+static exprType complexPtrFactor (void);
+static exprType simplePtrFactor (STYPE *varPtr, uint8_t factorFlags);
+static exprType functionDesignator(void);
+static void setAbstractType (STYPE *sType);
+static void getSetFactor (void);
+static void getSetElement (setTypeStruct *s);
+static bool isOrdinalType (exprType testExprType);
+static bool isAnyStringType (exprType testExprType);
+static bool isStringReference (exprType testExprType);
+
+/***************************************************************
+ * Private Variables
+ ***************************************************************/
+
+ /* The abstract types - SETs, RECORDS, etc - require an exact */
+ /* match in type. This variable points to the symbol table */
+ /* sTYPE entry associated with the expression. */
+
+ static STYPE *abstractType;
+
+/***************************************************************/
+/* Evaluate (boolean) Expression */
+
+exprType expression(exprType findExprType, STYPE *typePtr)
+{
+ uint8_t operation;
+ uint16_t intOpCode;
+ uint16_t fpOpCode;
+ uint16_t strOpCode;
+ exprType simple1Type;
+ exprType simple2Type;
+
+ TRACE(lstFile,"[expression]");
+
+ /* The abstract types - SETs, RECORDS, etc - require an exact */
+ /* match in type. Save the symbol table sTYPE entry associated */
+ /* with the expression. */
+
+ if ((typePtr) && (typePtr->sKind != sTYPE)) error(eINVTYPE);
+ abstractType = typePtr;
+
+ /* FORM <simple expression> [<relational operator> <simple expression>] */
+ /* Get the first <simple expression> */
+
+ simple1Type = simpleExpression(findExprType);
+
+ /* Get the optional <relational operator> which may follow */
+
+ operation = token;
+ switch (operation)
+ {
+ case tEQ :
+ intOpCode = opEQU;
+ fpOpCode = fpEQU;
+ strOpCode = opEQUZ;
+ break;
+ case tNE :
+ intOpCode = opNEQ;
+ fpOpCode = fpNEQ;
+ strOpCode = opNEQZ;
+ break;
+ case tLT :
+ intOpCode = opLT;
+ fpOpCode = fpLT;
+ strOpCode = opLTZ;
+ break;
+ case tLE :
+ intOpCode = opLTE;
+ fpOpCode = fpLTE;
+ strOpCode = opLTEZ;
+ break;
+ case tGT :
+ intOpCode = opGT;
+ fpOpCode = fpGT;
+ strOpCode = opGTZ;
+ break;
+ case tGE :
+ intOpCode = opGTE;
+ fpOpCode = fpGTE;
+ strOpCode = opGTEZ;
+ break;
+ case tIN :
+ if ((!abstractType) ||
+ ((abstractType->sParm.t.type != sSCALAR) &&
+ (abstractType->sParm.t.type != sSUBRANGE)))
+ error(eEXPRTYPE);
+ else if (abstractType->sParm.t.minValue)
+ {
+ pas_GenerateDataOperation(opPUSH, abstractType->sParm.t.minValue);
+ pas_GenerateSimple(opSUB);
+ } /* end else if */
+ intOpCode = opBIT;
+ fpOpCode = fpINVLD;
+ strOpCode = opNOP;
+ break;
+ default :
+ intOpCode = opNOP;
+ fpOpCode = fpINVLD;
+ strOpCode = opNOP;
+ break;
+ } /* end switch */
+
+ /* Check if there is a 2nd simple expression needed */
+
+ if (intOpCode != opNOP)
+ {
+ /* Get the second simple expression */
+
+ getToken();
+ simple2Type = simpleExpression(findExprType);
+
+ /* Perform automatic type conversion from INTEGER to REAL
+ * for integer vs. real comparisons.
+ */
+
+ if (simple1Type != simple2Type)
+ {
+ /* Handle the case where the 1st argument is REAL and the
+ * second is INTEGER. */
+
+ if ((simple1Type == exprReal) &&
+ (simple2Type == exprInteger) &&
+ (fpOpCode != fpINVLD))
+ {
+ fpOpCode |= fpARG2;
+ simple2Type = exprReal;
+ } /* end if */
+
+ /* Handle the case where the 1st argument is Integer and the
+ * second is REAL. */
+
+ else if ((simple1Type == exprInteger) &&
+ (simple2Type == exprReal) &&
+ (fpOpCode != fpINVLD))
+ {
+ fpOpCode |= fpARG1;
+ simple1Type = exprReal;
+ } /* end else if */
+
+ /* Allow the case of <scalar type> IN <set type> */
+ /* Otherwise, the two terms must agree in type */
+
+ else if ((operation != tIN) || (simple2Type != exprSet))
+ {
+ error(eEXPRTYPE);
+ }
+ } /* end if */
+
+ /* Generate the comparison */
+
+ if (simple1Type == exprReal)
+ {
+ if (fpOpCode == fpINVLD)
+ error(eEXPRTYPE);
+ else
+ pas_GenerateFpOperation(fpOpCode);
+ } /* end if */
+ else if ((simple1Type == exprString) || (simple1Type == exprString))
+ {
+ if (strOpCode != opNOP)
+ {
+ pas_BuiltInFunctionCall(lbSTRCMP);
+ pas_GenerateSimple(strOpCode);
+ }
+ else
+ {
+ error(eEXPRTYPE);
+ }
+ }
+ else
+ {
+ pas_GenerateSimple(intOpCode);
+ }
+
+ /* The type resulting from these operations becomes BOOLEAN */
+
+ simple1Type = exprBoolean;
+
+ } /* end if */
+
+ /* Verify that the expression is of the requested type.
+ * The following are okay:
+ *
+ * 1. We were told to find any kind of expression
+ *
+ * 2. We were told to find a specific kind of expression and
+ * we found just that type.
+ *
+ * 3. We were told to find any kind of ordinal expression and
+ * we found a ordinal expression. This is what is needed, for
+ * example, as an argument to ord(), pred(), succ(), or odd().
+ * This is the kind of expression we need in a CASE statement
+ * as well.
+ *
+ * 4. We were told to find any kind of string expression and
+ * we found a string expression. This is a hack to handle
+ * calls to system functions that return exprCString pointers
+ * that must be converted to exprString records upon assignment.
+ *
+ * 5. We have a hack in the name space. You use a bogus name
+ * to represent a string reference that has string stack
+ * allocated with it. For expression processing purposes,
+ * exprString and exprStkString are the same thing. The
+ * difference is that we have to clean up the string stack
+ * for the latter.
+ *
+ * Special case:
+ *
+ * We will perform automatic conversions to real from integer
+ * if the requested type is a real expression.
+ */
+
+ if ((findExprType != exprUnknown) && /* 1)NOT Any expression */
+
+ (findExprType != simple1Type) && /* 2)NOT Matched expression */
+
+ ((findExprType != exprAnyOrdinal) || /* 3)NOT any ordinal type */
+ (!isOrdinalType(simple1Type))) && /* OR type is not ordinal */
+
+ ((findExprType != exprAnyString) || /* 4)NOT any string type */
+ (!isAnyStringType(simple1Type))) && /* OR type is not string */
+
+ ((findExprType != exprString) || /* 5)Not looking for string ref */
+ (!isStringReference(simple1Type)))) /* OR type is not string ref */
+ {
+ /* Automatic conversions from INTEGER to REAL will be performed */
+
+ if ((findExprType == exprReal) && (simple1Type == exprInteger))
+ {
+ pas_GenerateFpOperation(fpFLOAT);
+ simple1Type = exprReal;
+ }
+
+ /* Any other type mismatch is an error */
+
+ else
+ {
+ error(eEXPRTYPE);
+ }
+ } /* end if */
+
+ return simple1Type;
+
+} /* end expression */
+
+/***************************************************************/
+/* Provide VAR parameter assignments */
+
+exprType varParm (exprType varExprType, STYPE *typePtr)
+{
+ exprType factorType;
+
+ /* The abstract types - SETs, RECORDS, etc - require an exact
+ * match in type. Save the symbol table sTYPE entry associated
+ * with the expression.
+ */
+
+ if ((typePtr) && (typePtr->sKind != sTYPE)) error(eINVTYPE);
+ abstractType = typePtr;
+
+ /* This function is really just an interface to the
+ * static function ptrFactor with some extra error
+ * checking.
+ */
+
+ factorType = ptrFactor();
+ if ((varExprType != exprUnknown) && (factorType != varExprType))
+ error(eINVVARPARM);
+
+ return factorType;
+
+} /* end varParm */
+
+/**********************************************************************/
+/* Process Array Index */
+void arrayIndex (int32_t size)
+{
+ TRACE(lstFile,"[arrayIndex]");
+
+ /* FORM: [<integer expression>] */
+ getToken();
+ if (token != '[') error (eLBRACKET);
+ else {
+
+ /* Evaluate index expression */
+ /* FIX ME: Need to allow any scalar type */
+ getToken();
+ expression(exprInteger, NULL);
+
+ /* Correct for size of array element */
+ if (size > 1) {
+ pas_GenerateDataOperation(opPUSH, size);
+ pas_GenerateSimple(opMUL);
+ } /* end if */
+
+ /* Verify right bracket */
+ if (token != ']') error (eRBRACKET);
+ else getToken();
+
+ } /* end else */
+
+} /* end arrayIndex */
+
+/*************************************************************************/
+/* Determine the expression type associated with a pointer to a type */
+/* symbol */
+
+exprType getExprType(STYPE *sType)
+{
+ exprType factorType = sINT;
+
+ TRACE(lstFile,"[getExprType]");
+
+ if ((sType) && (sType->sKind == sTYPE))
+ {
+ switch (sType->sParm.t.type)
+ {
+ case sINT :
+ factorType = exprInteger;
+ break;
+ case sBOOLEAN :
+ factorType = exprBoolean;
+ break;
+ case sCHAR :
+ factorType = exprChar;
+ break;
+ case sREAL :
+ factorType = exprReal;
+ break;
+ case sSCALAR :
+ factorType = exprScalar;
+ break;
+ case sSTRING :
+ case sRSTRING :
+ factorType = exprString;
+ break;
+ case sSUBRANGE :
+ switch (sType->sParm.t.subType)
+ {
+ case sINT :
+ factorType = exprInteger;
+ break;
+ case sCHAR :
+ factorType = exprChar;
+ break;
+ case sSCALAR :
+ factorType = exprScalar;
+ break;
+ default :
+ error(eSUBRANGETYPE);
+ break;
+ } /* end switch */
+ break;
+ case sPOINTER :
+ sType = sType->sParm.t.parent;
+ if (sType)
+ {
+ switch (sType->sKind)
+ {
+ case sINT :
+ factorType = exprIntegerPtr;
+ break;
+ case sBOOLEAN :
+ factorType = exprBooleanPtr;
+ break;
+ case sCHAR :
+ factorType = exprCharPtr;
+ break;
+ case sREAL :
+ factorType = exprRealPtr;
+ break;
+ case sSCALAR :
+ factorType = exprScalarPtr;
+ break;
+ default :
+ error(eINVTYPE);
+ break;
+ } /* end switch */
+ } /* end if */
+ break;
+ default :
+ error(eINVTYPE);
+ break;
+ } /* end switch */
+ } /* end if */
+
+ return factorType;
+
+} /* end getExprType */
+
+/***************************************************************/
+/* Process Simple Expression */
+
+static exprType simpleExpression(exprType findExprType)
+{
+ int16_t operation = '+';
+ uint16_t arg8FpBits;
+ exprType term1Type;
+ exprType term2Type;
+
+ TRACE(lstFile,"[simpleExpression]");
+
+ /* FORM: [+|-] <term> [{+|-} <term> [{+|-} <term> [...]]] */
+ /* get +/- unary operation */
+
+ if ((token == '+') || (token == '-'))
+ {
+ operation = token;
+ getToken();
+ } /* end if */
+
+ /* Process first (non-optional) term and apply unary operation */
+
+ term1Type = term(findExprType);
+ if (operation == '-')
+ {
+ if (term1Type == exprInteger)
+ pas_GenerateSimple(opNEG);
+ else if (term1Type == exprReal)
+ pas_GenerateFpOperation(fpNEG);
+ else
+ error(eTERMTYPE);
+ } /* end if */
+
+ /* Process subsequent (optional) terms and binary operations */
+
+ for (;;)
+ {
+ /* Check for binary operator */
+
+ if ((token == '+') || (token == '-') || (token == tOR))
+ operation = token;
+ else
+ break;
+
+ /* Special case for string types. So far, we have parsed
+ * '<string> +' At this point, it is safe to assume we
+ * going to modified string. So, if the string has not
+ * been copied to the string stack, we will have to do that
+ * now.
+ */
+
+ if ((term1Type == exprString) && (operation == '+'))
+ {
+ /* Duplicate the string on the string stack. And
+ * change the expression type to reflect this.
+ */
+
+ pas_BuiltInFunctionCall(lbMKSTKSTR);
+ term1Type = exprStkString;
+ }
+
+ /* If we are going to add something to a char, then the
+ * result must be a string. We will similarly have to
+ * convert the character to a string.
+ */
+
+ else if ((term1Type == exprChar) && (operation == '+'))
+ {
+ /* Duplicate the string on the string stack. And
+ * change the expression type to reflect this.
+ */
+
+ pas_BuiltInFunctionCall(lbMKSTKC);
+ term1Type = exprStkString;
+ }
+
+ /* Get the 2nd term */
+
+ getToken();
+ term2Type = term(findExprType);
+
+ /* Before generating the operation, verify that the types match.
+ * Perform automatic type conversion from INTEGER to REAL as
+ * necessary.
+ */
+
+ arg8FpBits = 0;
+
+ /* Skip over string types. These will be handled below */
+
+ if (!isStringReference(term1Type))
+ {
+ /* Handle the case where the type of the terms differ. */
+
+ if (term1Type != term2Type)
+ {
+ /* Handle the case where the 1st argument is REAL and the
+ * second is INTEGER. */
+
+ if ((term1Type == exprReal) && (term2Type == exprInteger))
+ {
+ arg8FpBits = fpARG2;
+ term2Type = exprReal;
+ } /* end if */
+
+ /* Handle the case where the 1st argument is Integer and the
+ * second is REAL. */
+
+ else if ((term1Type == exprInteger) && (term2Type == exprReal))
+ {
+ arg8FpBits = fpARG1;
+ term1Type = exprReal;
+ } /* end if */
+
+ /* Otherwise, the two terms must agree in type */
+
+ else
+ {
+ error(eTERMTYPE);
+ }
+ } /* end if */
+
+ /* We do not perform conversions for the cases where the two
+ * terms agree in type. There is only one interesting case:
+ * When the expected expression is real and both arguments are
+ * integer. Since addition an subtraction are exact, it would,
+ * in general, be more efficient to perform the conversion
+ * AFTER the operation (at the the risk of possible overflow
+ * conditions due to the limited range of integers).
+ */
+ }
+
+ /* Generate code to perform the selected binary operation */
+
+ switch (operation)
+ {
+ case '+' :
+ switch (term1Type)
+ {
+ /* Integer addition */
+
+ case exprInteger :
+ pas_GenerateSimple(opADD);
+ break;
+
+ /* Floating point addition */
+
+ case exprReal :
+ pas_GenerateFpOperation(fpADD | arg8FpBits);
+ break;
+
+ /* Set 'addition' */
+
+ case exprSet :
+ pas_GenerateSimple(opOR);
+ break;
+
+ /* Handle the special cases where '+' indicates that we are
+ * concatenating a string or a character to the end of a
+ * string. Note that these operations can only be performed
+ * on stack copies of the strings. Logic above should have
+ * made the conversion for the case of exprString.
+ */
+
+ case exprStkString :
+ if ((term2Type == exprString) || (term2Type == exprStkString))
+ {
+ /* We are concatenating one string with another.*/
+
+ pas_BuiltInFunctionCall(lbSTRCAT);
+ }
+ else if (term2Type == exprChar)
+ {
+ /* We are concatenating a character to the end of a string */
+
+ pas_BuiltInFunctionCall(lbSTRCATC);
+ }
+ else
+ {
+ error(eTERMTYPE);
+ }
+ break;
+
+ /* Otherwise, the '+' operation is not permitted */
+
+ default :
+ error(eTERMTYPE);
+ break;
+ }
+ break;
+
+ case '-' :
+ /* Integer subtraction */
+
+ if (term1Type == exprInteger)
+ pas_GenerateSimple(opSUB);
+
+ /* Floating point subtraction */
+
+ else if (term1Type == exprReal)
+ pas_GenerateFpOperation(fpSUB | arg8FpBits);
+
+ /* Set 'subtraction' */
+
+ else if (term1Type == exprSet)
+ {
+ pas_GenerateSimple(opNOT);
+ pas_GenerateSimple(opAND);
+ } /* end else if */
+
+ /* Otherwise, the '-' operation is not permitted */
+
+ else
+ error(eTERMTYPE);
+ break;
+
+ case tOR :
+ /* Integer/boolean 'OR' */
+
+ if ((term1Type == exprInteger) || (term1Type == exprBoolean))
+ pas_GenerateSimple(opOR);
+
+ /* Otherwise, the 'OR' operation is not permitted */
+
+ else
+ error(eTERMTYPE);
+ break;
+
+ } /* end switch */
+ } /* end for */
+
+ return term1Type;
+
+} /* end simpleExpression */
+
+/***************************************************************/
+/* Evaluate a TERM */
+
+static exprType term(exprType findExprType)
+{
+ uint8_t operation;
+ uint16_t arg8FpBits;
+ exprType factor1Type;
+ exprType factor2Type;
+
+ TRACE(lstFile,"[term]");
+
+ /* FORM: <factor> [<operator> <factor>[<operator><factor>[...]]] */
+
+ factor1Type = factor(findExprType);
+ for (;;) {
+
+ /* Check for binary operator */
+
+ if ((token == tMUL) || (token == tDIV) ||
+ (token == tFDIV) || (token == tMOD) ||
+ (token == tAND) || (token == tSHL) ||
+ (token == tSHR))
+ operation = token;
+ else
+ break;
+
+ /* Get the next factor */
+
+ getToken();
+ factor2Type = factor(findExprType);
+
+ /* Before generating the operation, verify that the types match.
+ * Perform automatic type conversion from INTEGER to REAL as
+ * necessary.
+ */
+
+ arg8FpBits = 0;
+
+ /* Handle the case where the type of the terms differ. */
+
+ if (factor1Type != factor2Type)
+ {
+ /* Handle the case where the 1st argument is REAL and the
+ * second is INTEGER. */
+
+ if ((factor1Type == exprReal) && (factor2Type == exprInteger))
+ {
+ arg8FpBits = fpARG2;
+ } /* end if */
+
+ /* Handle the case where the 1st argument is Integer and the
+ * second is REAL. */
+
+ else if ((factor1Type == exprInteger) && (factor2Type == exprReal))
+ {
+ arg8FpBits = fpARG1;
+ factor1Type = exprReal;
+ } /* end if */
+
+ /* Otherwise, the two factors must agree in type */
+
+ else
+ {
+ error(eFACTORTYPE);
+ }
+ } /* end if */
+
+ /* Handle the cases for conversions when the two string
+ * type are the same type.
+ */
+
+ else
+ {
+ /* There is only one interesting case: When the
+ * expected expression is real and both arguments are
+ * integer. In this case, for example, 1/2 must yield
+ * 0.5, not 0.
+ */
+
+ if ((factor1Type == exprInteger) && (findExprType == exprReal))
+ {
+ /* However, we will perform this conversin only for the
+ * arithmetic operations: tMUL, tDIV/tFDIV, and tMOD.
+ * The logical operations must be performed on integer
+ * types with the result converted to a real type afterward.
+ */
+
+ if ((operation == tMUL) || (operation == tDIV) ||
+ (operation == tFDIV) || (operation == tMOD))
+ {
+ /* Perform the conversion of both terms */
+
+ arg8FpBits = fpARG1 | fpARG2;
+ factor1Type = exprReal;
+
+ /* We will also have to switch the operation in
+ * the case of tDIV: We'll have to used tFDIV.
+ */
+
+ if (operation == tDIV) operation = tFDIV;
+ }
+ }
+ }
+
+ /* Generate code to perform the selected binary operation */
+
+ switch (operation)
+ {
+ case tMUL :
+ if (factor1Type == exprInteger)
+ pas_GenerateSimple(opMUL);
+ else if (factor1Type == exprReal)
+ pas_GenerateFpOperation(fpMUL | arg8FpBits);
+ else if (factor1Type == exprSet)
+ pas_GenerateSimple(opAND);
+ else
+ error(eFACTORTYPE);
+ break;
+
+ case tDIV :
+ if (factor1Type == exprInteger)
+ pas_GenerateSimple(opDIV);
+ else
+ error(eFACTORTYPE);
+ break;
+
+ case tFDIV :
+ if (factor1Type == exprReal)
+ pas_GenerateFpOperation(fpDIV | arg8FpBits);
+ else
+ error(eFACTORTYPE);
+ break;
+
+ case tMOD :
+ if (factor1Type == exprInteger)
+ pas_GenerateSimple(opMOD);
+ else if (factor1Type == exprReal)
+ pas_GenerateFpOperation(fpMOD | arg8FpBits);
+ else
+ error(eFACTORTYPE);
+ break;
+
+ case tAND :
+ if ((factor1Type == exprInteger) || (factor1Type == exprBoolean))
+ pas_GenerateSimple(opAND);
+ else
+ error(eFACTORTYPE);
+ break;
+
+ case tSHL :
+ if (factor1Type == exprInteger)
+ pas_GenerateSimple(opSLL);
+ else
+ error(eFACTORTYPE);
+ break;
+
+ case tSHR :
+ if (factor1Type == exprInteger)
+ pas_GenerateSimple(opSRA);
+ else
+ error(eFACTORTYPE);
+ break;
+
+ } /* end switch */
+ } /* end for */
+
+ return factor1Type;
+
+} /* end term */
+
+/***************************************************************/
+/* Process a FACTOR */
+
+static exprType factor(exprType findExprType)
+{
+ exprType factorType = exprUnknown;
+
+ TRACE(lstFile,"[factor]");
+
+ /* Process by token type */
+
+ switch (token)
+ {
+ /* User defined tokens */
+
+ case tIDENT :
+ error(eUNDEFSYM);
+ stringSP = tkn_strt;
+ factorType = exprUnknown;
+ break;
+
+ /* Constant factors */
+
+ case tINT_CONST :
+ pas_GenerateDataOperation(opPUSH, tknInt);
+ getToken();
+ factorType = exprInteger;
+ break;
+
+ case tBOOLEAN_CONST :
+ pas_GenerateDataOperation(opPUSH, tknInt);
+ getToken();
+ factorType = exprBoolean;
+ break;
+
+ case tCHAR_CONST :
+ pas_GenerateDataOperation(opPUSH, tknInt);
+ getToken();
+ factorType = exprChar;
+ break;
+
+ case tREAL_CONST :
+ pas_GenerateDataOperation(opPUSH, (int32_t)*(((uint16_t*)&tknReal)+0));
+ pas_GenerateDataOperation(opPUSH, (int32_t)*(((uint16_t*)&tknReal)+1));
+ pas_GenerateDataOperation(opPUSH, (int32_t)*(((uint16_t*)&tknReal)+2));
+ pas_GenerateDataOperation(opPUSH, (int32_t)*(((uint16_t*)&tknReal)+3));
+ getToken();
+ factorType = exprReal;
+ break;
+
+ case sSCALAR_OBJECT :
+ if (abstractType)
+ {
+ if (tknPtr->sParm.c.parent != abstractType) error(eSCALARTYPE);
+ } /* end if */
+ else
+ abstractType = tknPtr->sParm.c.parent;
+
+ pas_GenerateDataOperation(opPUSH, tknPtr->sParm.c.val.i);
+ getToken();
+ factorType = exprScalar;
+ break;
+
+ /* Simple Factors */
+
+ case sINT :
+ pas_GenerateStackReference(opLDS, tknPtr);
+ getToken();
+ factorType = exprInteger;
+ break;
+
+ case sBOOLEAN :
+ pas_GenerateStackReference(opLDS, tknPtr);
+ getToken();
+ factorType = exprBoolean;
+ break;
+
+ case sCHAR :
+ pas_GenerateStackReference(opLDSB, tknPtr);
+ getToken();
+ factorType = exprChar;
+ break;
+
+ case sREAL :
+ pas_GenerateDataSize(sREAL_SIZE);
+ pas_GenerateStackReference(opLDSM, tknPtr);
+ getToken();
+ factorType = exprReal;
+ break;
+
+ /* Strings -- constant and variable */
+
+ case tSTRING_CONST :
+ {
+ /* Final stack representation is:
+ * TOS(0) : size in bytes
+ * TOS(1) : pointer to string
+ *
+ * Add the string to the RO data section of the output
+ * and get the offset to the string location.
+ */
+
+ uint32_t offset = poffAddRoDataString(poffHandle, tkn_strt);
+
+ /* Get the offset then size of the string on the stack */
+
+ pas_GenerateDataOperation(opLAC, offset);
+ pas_GenerateDataOperation(opPUSH, strlen(tkn_strt));
+
+ /* Release the tokenized string */
+
+ stringSP = tkn_strt;
+ getToken();
+ factorType = exprString;
+ }
+ break;
+
+ case sSTRING_CONST :
+ /* Final stack representation is:
+ * TOS(0) : size in bytes
+ * TOS(1) : pointer to string
+ */
+
+ pas_GenerateDataOperation(opLAC, tknPtr->sParm.s.offset);
+ pas_GenerateDataOperation(opPUSH, tknPtr->sParm.s.size);
+ getToken();
+ factorType = exprString;
+ break;
+
+ case sSTRING :
+ /* Final stack representation is:
+ * TOS(0) = size in bytes
+ * TOS(1) = pointer to string data
+ */
+
+ pas_GenerateDataOperation(opPUSH, sSTRING_HDR_SIZE);
+ pas_GenerateStackReference(opLASX, tknPtr);
+ pas_GenerateStackReference(opLDSH, tknPtr);
+
+ getToken();
+ factorType = exprString;
+ break;
+
+ case sRSTRING :
+ /* Final stack representation is:
+ * TOS(0) : size in bytes
+ * TOS(1) : pointer to string data
+ *
+ * We get that by just cloning the reference on the top of the stack
+ */
+ pas_GenerateDataSize(tknPtr->sParm.v.size);
+ pas_GenerateStackReference(opLDSM, tknPtr);
+ getToken();
+ factorType = exprString;
+ break;
+
+ case sSCALAR :
+ if (abstractType)
+ {
+ if (tknPtr->sParm.v.parent != abstractType) error(eSCALARTYPE);
+ } /* end if */
+ else
+ abstractType = tknPtr->sParm.v.parent;
+
+ pas_GenerateStackReference(opLDS, tknPtr);
+ getToken();
+ factorType = exprScalar;
+ break;
+
+ case sSET_OF :
+ /* If an abstractType is specified then it should either be the */
+ /* same SET OF <object> -OR- the same <object> */
+
+ if (abstractType)
+ {
+ if ((tknPtr->sParm.v.parent != abstractType) &&
+ (tknPtr->sParm.v.parent->sParm.t.parent != abstractType))
+ error(eSET);
+ } /* end if */
+ else
+ abstractType = tknPtr->sParm.v.parent;
+
+ pas_GenerateStackReference(opLDS, tknPtr);
+ getToken();
+ factorType = exprSet;
+ break;
+
+ /* SET factors */
+
+ case '[' : /* Set constant */
+ getToken();
+ getSetFactor();
+ if (token != ']') error(eRBRACKET);
+ else getToken();
+ factorType = exprSet;
+ break;
+
+ /* Complex factors */
+
+ case sSUBRANGE :
+ case sRECORD :
+ case sRECORD_OBJECT :
+ case sVAR_PARM :
+ case sPOINTER :
+ case sARRAY :
+ factorType = complexFactor();
+ break;
+
+ /* Functions */
+
+ case sFUNC :
+ factorType = functionDesignator();
+ break;
+
+ /* Nested Expression */
+
+ case '(' :
+ getToken();
+ factorType = expression(exprUnknown, abstractType);
+ if (token == ')') getToken();
+ else error (eRPAREN);
+ break;
+
+ /* Address references */
+
+ case '^' :
+ getToken();
+ factorType = ptrFactor();
+ break;
+
+ /* Highest Priority Operators */
+
+ case tNOT:
+ getToken();
+ factorType = factor(findExprType);
+ if ((factorType != exprInteger) && (factorType != exprBoolean))
+ error(eFACTORTYPE);
+ pas_GenerateSimple(opNOT);
+ break;
+
+ /* Built-in function? */
+
+ case tFUNC:
+ factorType = builtInFunction();
+ break;
+
+ /* Hmmm... Try the standard functions */
+
+ default :
+ error(eINVFACTOR);
+ break;
+
+ } /* end switch */
+
+ return factorType;
+
+} /* end factor */
+
+/***********************************************************************/
+/* Process a complex factor */
+
+static exprType complexFactor(void)
+{
+ STYPE symbolSave;
+
+ TRACE(lstFile,"[complexFactor]");
+
+ /* First, make a copy of the symbol table entry because the call to */
+ /* simpleFactor() will modify it. */
+
+ symbolSave = *tknPtr;
+ getToken();
+
+ /* Then process the complex factor until it is reduced to a simple */
+ /* factor (like int, char, etc.) */
+
+ return simpleFactor(&symbolSave, 0);
+
+} /* end complexFactor */
+
+/***********************************************************************/
+/* Process a complex factor (recursively) until it becomes a */
+/* simple factor */
+
+static exprType simpleFactor(STYPE *varPtr, uint8_t factorFlags)
+{
+ STYPE *typePtr;
+ exprType factorType;
+
+ TRACE(lstFile,"[simpleFactor]");
+
+ /* Process according to the current variable sKind */
+
+ typePtr = varPtr->sParm.v.parent;
+ switch (varPtr->sKind)
+ {
+ /* Check if we have reduced the complex factor to a simple factor */
+
+ case sINT :
+ if ((factorFlags & INDEXED_FACTOR) != 0)
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ pas_GenerateSimple(opLDI);
+ factorType = exprInteger;
+ } /* end if */
+ else if ((factorFlags & ADDRESS_FACTOR) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ factorType = exprIntegerPtr;
+ } /* end else if */
+ else
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ factorType = exprInteger;
+ } /* end else */
+ } /* end if */
+ else
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_GenerateSimple(opLDI);
+ factorType = exprInteger;
+ } /* end if */
+ else if ((factorFlags & ADDRESS_FACTOR) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ factorType = exprIntegerPtr;
+ } /* end else if */
+ else
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ factorType = exprInteger;
+ } /* end else */
+ } /* end else */
+ break;
+ case sCHAR :
+ if ((factorFlags & INDEXED_FACTOR) != 0)
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ pas_GenerateSimple(opLDIB);
+ factorType = exprChar;
+ } /* end if */
+ else if ((factorFlags & ADDRESS_FACTOR) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ factorType = exprCharPtr;
+ } /* end else if */
+ else
+ {
+ pas_GenerateStackReference(opLDSXB, varPtr);
+ factorType = exprChar;
+ } /* end else */
+ } /* end if */
+ else
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_GenerateSimple(opLDIB);
+ factorType = exprChar;
+ } /* end if */
+ else if ((factorFlags & ADDRESS_FACTOR) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ factorType = exprCharPtr;
+ } /* end else if */
+ else
+ {
+ pas_GenerateStackReference(opLDSB, varPtr);
+ factorType = exprChar;
+ } /* end else */
+ } /* end else */
+ break;
+ case sBOOLEAN :
+ if ((factorFlags & INDEXED_FACTOR) != 0)
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ pas_GenerateSimple(opLDI);
+ factorType = exprBoolean;
+ } /* end if */
+ else if ((factorFlags & ADDRESS_FACTOR) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ factorType = exprBooleanPtr;
+ } /* end else if */
+ else
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ factorType = exprBoolean;
+ } /* end else */
+ } /* end if */
+ else
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_GenerateSimple(opLDI);
+ factorType = exprBoolean;
+ } /* end if */
+ else if ((factorFlags & ADDRESS_FACTOR) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ factorType = exprBooleanPtr;
+ } /* end else if */
+ else
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ factorType = exprBoolean;
+ } /* end else */
+ } /* end else */
+ break;
+ case sREAL :
+ if ((factorFlags & INDEXED_FACTOR) != 0)
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ pas_GenerateDataSize(varPtr->sParm.v.size);
+ pas_GenerateSimple(opLDIM);
+ factorType = exprReal;
+ } /* end if */
+ else if ((factorFlags & ADDRESS_FACTOR) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ factorType = exprRealPtr;
+ } /* end else if */
+ else
+ {
+ pas_GenerateDataSize(varPtr->sParm.v.size);
+ pas_GenerateStackReference(opLDSXM, varPtr);
+ factorType = exprReal;
+ } /* end else */
+ } /* end if */
+ else
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_GenerateDataSize(varPtr->sParm.v.size);
+ pas_GenerateSimple(opLDIM);
+ factorType = exprReal;
+ } /* end if */
+ else if ((factorFlags & ADDRESS_FACTOR) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ factorType = exprRealPtr;
+ } /* end else if */
+ else
+ {
+ pas_GenerateDataSize(varPtr->sParm.v.size);
+ pas_GenerateStackReference(opLDSM, varPtr);
+ factorType = exprReal;
+ } /* end else */
+ } /* end else */
+ break;
+ case sSCALAR :
+ if (!abstractType)
+ abstractType = typePtr;
+ else if (typePtr != abstractType)
+ error(eSCALARTYPE);
+
+ if ((factorFlags & INDEXED_FACTOR) != 0)
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ pas_GenerateSimple(opLDI);
+ factorType = exprScalar;
+ } /* end if */
+ else if ((factorFlags & ADDRESS_FACTOR) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ factorType = exprScalarPtr;
+ } /* end else if */
+ else
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ factorType = exprScalar;
+ } /* end else */
+ } /* end if */
+ else
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_GenerateSimple(opLDI);
+ factorType = exprScalar;
+ } /* end if */
+ else if ((factorFlags & ADDRESS_FACTOR) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ factorType = exprScalarPtr;
+ } /* end else if */
+ else
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ factorType = exprScalar;
+ } /* end else */
+ } /* end else */
+ break;
+ case sSET_OF :
+ if (!abstractType)
+ abstractType = typePtr;
+ else if ((typePtr != abstractType) &&
+ (typePtr->sParm.v.parent != abstractType))
+ error(eSCALARTYPE);
+
+ if ((factorFlags & INDEXED_FACTOR) != 0)
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ pas_GenerateSimple(opLDI);
+ factorType = exprSet;
+ } /* end if */
+ else if ((factorFlags & ADDRESS_FACTOR) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ factorType = exprSetPtr;
+ } /* end else if */
+ else
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ factorType = exprSet;
+ } /* end else */
+ } /* end if */
+ else
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_GenerateSimple(opLDI);
+ factorType = exprSet;
+ } /* end if */
+ else if ((factorFlags & ADDRESS_FACTOR) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ factorType = exprSetPtr;
+ } /* end else if */
+ else
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ factorType = exprSet;
+ } /* end else */
+ } /* end else */
+ break;
+
+ /* NOPE... recurse until it becomes a simple factor */
+
+ case sSUBRANGE :
+ if (!abstractType) abstractType = typePtr;
+ varPtr->sKind = typePtr->sParm.t.subType;
+ factorType = simpleFactor(varPtr, factorFlags);
+ break;
+
+ case sRECORD :
+ /* Check if this is a pointer to a record */
+
+ if ((factorFlags & ADDRESS_FACTOR) != 0)
+ {
+ if (token == '.') error(ePOINTERTYPE);
+
+ if ((factorFlags & INDEXED_FACTOR) != 0)
+ pas_GenerateStackReference(opLDSX, varPtr);
+ else
+ pas_GenerateStackReference(opLDS, varPtr);
+
+ factorType = exprRecordPtr;
+ } /* end if */
+
+ /* Verify that a period separates the RECORD identifier from the */
+ /* record field identifier */
+
+ else if (token == '.')
+ {
+ if (((factorFlags & ADDRESS_DEREFERENCE) != 0) &&
+ ((factorFlags & VAR_PARM_FACTOR) == 0))
+ error(ePOINTERTYPE);
+
+ /* Skip over the period. */
+
+ getToken();
+
+ /* Verify that a field identifier associated with this record */
+ /* follows the period. */
+
+ if ((token != sRECORD_OBJECT) ||
+ (tknPtr->sParm.r.record != typePtr))
+ {
+ error(eRECORDOBJECT);
+ factorType = exprInteger;
+ } /* end if */
+ else
+ {
+ /* Modify the variable so that it has the characteristics of the */
+ /* the field but with level and offset associated with the record */
+
+ typePtr = tknPtr->sParm.r.parent;
+ varPtr->sKind = typePtr->sParm.t.type;
+ varPtr->sParm.v.parent = typePtr;
+
+ /* Special case: The record is a VAR parameter. */
+
+ if (factorFlags == (INDEXED_FACTOR | ADDRESS_DEREFERENCE | VAR_PARM_FACTOR))
+ {
+ pas_GenerateDataOperation(opPUSH, tknPtr->sParm.r.offset);
+ pas_GenerateSimple(opADD);
+ } /* end if */
+ else
+ varPtr->sParm.v.offset += tknPtr->sParm.r.offset;
+
+ getToken();
+ factorType = simpleFactor(varPtr, factorFlags);
+ } /* end else */
+ } /* end else if */
+
+ /* A RECORD name name be a valid factor -- as the input */
+ /* parameter of a function or in an assignment */
+
+ else if (abstractType == typePtr)
+ {
+ /* Special case: The record is a VAR parameter. */
+
+ if (factorFlags == (INDEXED_FACTOR | ADDRESS_DEREFERENCE | VAR_PARM_FACTOR))
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_GenerateSimple(opADD);
+ pas_GenerateDataSize(varPtr->sParm.v.size);
+ pas_GenerateSimple(opLDIM);
+ } /* end if */
+ else
+ {
+ pas_GenerateDataSize(varPtr->sParm.v.size);
+ pas_GenerateStackReference(opLDSM, varPtr);
+ } /* end else */
+
+ factorType = exprRecord;
+ } /* end else if */
+ else error(ePERIOD);
+ break;
+
+ case sRECORD_OBJECT :
+ /* NOTE: This must have been preceeded with a WITH statement */
+ /* defining the RECORD type */
+
+ if (!withRecord.parent)
+ error(eINVTYPE);
+ else if ((factorFlags && (ADDRESS_DEREFERENCE | ADDRESS_FACTOR)) != 0)
+ error(ePOINTERTYPE);
+ else if ((factorFlags && INDEXED_FACTOR) != 0)
+ error(eARRAYTYPE);
+
+ /* Verify that a field identifier is associated with the RECORD */
+ /* specified by the WITH statement. */
+
+ else if (varPtr->sParm.r.record != withRecord.parent)
+ error(eRECORDOBJECT);
+ else
+ {
+ int16_t tempOffset;
+
+ /* Now there are two cases to consider: (1) the withRecord is a */
+ /* pointer to a RECORD, or (2) the withRecord is the RECOR itself */
+
+ if (withRecord.pointer)
+ {
+ /* If the pointer is really a VAR parameter, then other syntax */
+ /* rules will apply */
+
+ if (withRecord.varParm)
+ factorFlags |= (INDEXED_FACTOR | ADDRESS_DEREFERENCE | VAR_PARM_FACTOR);
+ else
+ factorFlags |= (INDEXED_FACTOR | ADDRESS_DEREFERENCE);
+
+ pas_GenerateDataOperation(opPUSH, (varPtr->sParm.r.offset + withRecord.index));
+ tempOffset = withRecord.offset;
+ } /* end if */
+ else
+ {
+ tempOffset = varPtr->sParm.r.offset + withRecord.offset;
+ } /* end else */
+
+ /* Modify the variable so that it has the characteristics of the */
+ /* the field but with level and offset associated with the record */
+ /* NOTE: We have to be careful here because the structure */
+ /* associated with sRECORD_OBJECT is not the same as for */
+ /* variables! */
+
+ typePtr = varPtr->sParm.r.parent;
+ tempOffset = varPtr->sParm.r.offset;
+
+ varPtr->sKind = typePtr->sParm.t.type;
+ varPtr->sLevel = withRecord.level;
+ varPtr->sParm.v.size = typePtr->sParm.t.asize;
+ varPtr->sParm.v.offset = tempOffset + withRecord.offset;
+ varPtr->sParm.v.parent = typePtr;
+
+ factorType = simpleFactor(varPtr, factorFlags);
+ } /* end else */
+ break;
+
+ case sPOINTER :
+ if (token == '^')
+ {
+ getToken();
+ factorFlags |= ADDRESS_DEREFERENCE;
+ } /* end if */
+ else
+ factorFlags |= ADDRESS_FACTOR;
+
+ varPtr->sKind = typePtr->sParm.t.type;
+ factorType = simpleFactor(varPtr, factorFlags);
+ break;
+
+ case sVAR_PARM :
+ if (factorFlags != 0) error(eVARPARMTYPE);
+ factorFlags |= (ADDRESS_DEREFERENCE | VAR_PARM_FACTOR);
+
+ varPtr->sKind = typePtr->sParm.t.type;
+ factorType = simpleFactor(varPtr, factorFlags);
+ break;
+
+ case sARRAY :
+ if (factorFlags != 0) error(eARRAYTYPE);
+
+ if (token == '[')
+ {
+ factorFlags |= INDEXED_FACTOR;
+ arrayIndex(typePtr->sParm.t.asize);
+ varPtr->sKind = typePtr->sParm.t.type;
+ varPtr->sParm.v.size = typePtr->sParm.t.asize;
+ factorType = simpleFactor(varPtr, factorFlags);
+ } /* end if */
+
+ /* An ARRAY name name be a valid factor -- only as the input */
+ /* parameter of a function */
+
+ else if (abstractType == varPtr)
+ {
+ pas_GenerateDataSize(varPtr->sParm.v.size);
+ pas_GenerateStackReference(opLDSM, varPtr);
+ factorType = exprArray;
+ } /* end else if */
+ else error(eLBRACKET);
+ break;
+
+ default :
+ error(eINVTYPE);
+ factorType = exprInteger;
+ break;
+ } /* end switch */
+
+ return factorType;
+
+} /* end simpleFactor */
+
+/**********************************************************************/
+/* Process a factor of the for ^variable OR a VAR parameter (where the
+ * ^ is implicit. */
+
+static exprType ptrFactor(void)
+{
+ exprType factorType;
+
+ TRACE(lstFile,"[ptrFactor]");
+
+ /* Process by token type */
+
+ switch (token) {
+
+ /* Pointers to simple types */
+
+ case sINT :
+ pas_GenerateStackReference(opLAS, tknPtr);
+ getToken();
+ factorType = exprIntegerPtr;
+ break;
+ case sBOOLEAN :
+ pas_GenerateStackReference(opLAS, tknPtr);
+ getToken();
+ factorType = exprBooleanPtr;
+ break;
+ case sCHAR :
+ pas_GenerateStackReference(opLAS, tknPtr);
+ getToken();
+ factorType = exprCharPtr;
+ break;
+ case sREAL :
+ pas_GenerateStackReference(opLAS, tknPtr);
+ getToken();
+ factorType = exprRealPtr;
+ break;
+ case sSCALAR :
+ if (abstractType)
+ {
+ if (tknPtr->sParm.v.parent != abstractType) error(eSCALARTYPE);
+ } /* end if */
+ else
+ abstractType = tknPtr->sParm.v.parent;
+
+ pas_GenerateStackReference(opLAS, tknPtr);
+ getToken();
+ factorType = exprScalarPtr;
+ break;
+ case sSET_OF :
+ /* If an abstractType is specified then it should either be the */
+ /* same SET OF <object> -OR- the same <object> */
+
+ if (abstractType) {
+ if ((tknPtr->sParm.v.parent != abstractType)
+ && (tknPtr->sParm.v.parent->sParm.t.parent != abstractType))
+ error(eSET);
+ } /* end if */
+ else
+ abstractType = tknPtr->sParm.v.parent;
+ pas_GenerateStackReference(opLAS, tknPtr);
+ getToken();
+ factorType = exprSetPtr;
+ break;
+
+ /* Complex factors */
+
+ case sSUBRANGE :
+ case sRECORD :
+ case sRECORD_OBJECT :
+ case sVAR_PARM :
+ case sPOINTER :
+ case sARRAY :
+ factorType = complexPtrFactor();
+ break;
+
+ /* References to address of a pointer */
+
+ case '^' :
+ error(eNOTYET);
+ getToken();
+ factorType = ptrFactor();
+ break;
+
+ case '(' :
+ getToken();
+ factorType = ptrFactor();
+ if (token != ')') error (eRPAREN);
+ else getToken();
+ break;
+
+ default :
+ error(ePTRADR);
+ break;
+
+ } /* end switch */
+
+ return factorType;
+
+} /* end ptrFactor */
+
+/***********************************************************************/
+/* Process a complex factor */
+
+static exprType complexPtrFactor(void)
+{
+ STYPE symbolSave;
+
+ TRACE(lstFile,"[complexPtrFactor]");
+
+ /* First, make a copy of the symbol table entry because the call to */
+ /* simplePtrFactor() will modify it. */
+
+ symbolSave = *tknPtr;
+ getToken();
+
+ /* Then process the complex factor until it is reduced to a simple */
+ /* factor (like int, char, etc.) */
+
+ return simplePtrFactor(&symbolSave, 0);
+
+} /* end complexPtrFactor */
+
+/***********************************************************************/
+/* Process a complex factor (recursively) until it becomes a */
+/* simple simple */
+
+static exprType simplePtrFactor(STYPE *varPtr, uint8_t factorFlags)
+{
+ STYPE *typePtr;
+ exprType factorType;
+
+ TRACE(lstFile,"[simplePtrFactor]");
+
+ /* Process according to the current variable sKind */
+
+ typePtr = varPtr->sParm.v.parent;
+ switch (varPtr->sKind)
+ {
+ /* Check if we have reduced the complex factor to a simple factor */
+ case sINT :
+ if ((factorFlags & INDEXED_FACTOR) != 0)
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ } /* end if */
+ else
+ {
+ pas_GenerateStackReference(opLASX, varPtr);
+ } /* end else */
+ factorType = exprIntegerPtr;
+ } /* end if */
+ else
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ } /* end if */
+ else
+ {
+ pas_GenerateStackReference(opLAS, varPtr);
+ } /* end else */
+ factorType = exprIntegerPtr;
+ } /* end else */
+ break;
+ case sCHAR :
+ if ((factorFlags & INDEXED_FACTOR) != 0)
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ } /* end if */
+ else
+ {
+ pas_GenerateStackReference(opLASX, varPtr);
+ } /* end else */
+ factorType = exprCharPtr;
+ } /* end if */
+ else
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ } /* end if */
+ else
+ {
+ pas_GenerateStackReference(opLAS, varPtr);
+ } /* end else */
+ factorType = exprCharPtr;
+ } /* end else */
+ break;
+ case sBOOLEAN :
+ if ((factorFlags & INDEXED_FACTOR) != 0)
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ } /* end if */
+ else
+ {
+ pas_GenerateStackReference(opLASX, varPtr);
+ } /* end else */
+ factorType = exprBooleanPtr;
+ } /* end if */
+ else
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ } /* end if */
+ else
+ {
+ pas_GenerateStackReference(opLAS, varPtr);
+ } /* end else */
+ factorType = exprBooleanPtr;
+ } /* end else */
+ break;
+ case sREAL :
+ if ((factorFlags & INDEXED_FACTOR) != 0)
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ } /* end if */
+ else
+ {
+ pas_GenerateStackReference(opLASX, varPtr);
+ } /* end else */
+ factorType = exprRealPtr;
+ } /* end if */
+ else
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ } /* end if */
+ else
+ {
+ pas_GenerateStackReference(opLAS, varPtr);
+ } /* end else */
+ factorType = exprRealPtr;
+ } /* end else */
+ break;
+ case sSCALAR :
+ if (!abstractType)
+ abstractType = typePtr;
+ else if (typePtr != abstractType)
+ error(eSCALARTYPE);
+
+ if ((factorFlags & INDEXED_FACTOR) != 0)
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ } /* end if */
+ else
+ {
+ pas_GenerateStackReference(opLASX, varPtr);
+ } /* end else */
+ factorType = exprScalarPtr;
+ } /* end if */
+ else
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ } /* end if */
+ else
+ {
+ pas_GenerateStackReference(opLAS, varPtr);
+ } /* end else */
+ factorType = exprScalarPtr;
+ } /* end else */
+ break;
+ case sSET_OF :
+ if (!abstractType)
+ abstractType = typePtr;
+ else if ((typePtr != abstractType) &&
+ (typePtr->sParm.v.parent != abstractType))
+ error(eSCALARTYPE);
+
+ if ((factorFlags & INDEXED_FACTOR) != 0)
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ } /* end if */
+ else
+ {
+ pas_GenerateStackReference(opLASX, varPtr);
+ } /* end else */
+ factorType = exprSetPtr;
+ } /* end if */
+ else
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ } /* end if */
+ else
+ {
+ pas_GenerateStackReference(opLAS, varPtr);
+ } /* end else */
+ factorType = exprSetPtr;
+ } /* end else */
+ break;
+
+ /* NOPE... recurse until it becomes a simple factor */
+
+ case sSUBRANGE :
+ if (!abstractType) abstractType = typePtr;
+ varPtr->sKind = typePtr->sParm.t.subType;
+ factorType = simplePtrFactor(varPtr, factorFlags);
+ break;
+
+ case sRECORD :
+ /* Check if this is a pointer to a record */
+
+ if (token != '.')
+ {
+ if ((factorFlags & ADDRESS_DEREFERENCE) != 0)
+ error(ePOINTERTYPE);
+
+ if ((factorFlags & INDEXED_FACTOR) != 0)
+ pas_GenerateStackReference(opLASX, varPtr);
+ else
+ pas_GenerateStackReference(opLAS, varPtr);
+
+ factorType = exprRecordPtr;
+ } /* end if */
+ else
+ {
+ /* Verify that a period separates the RECORD identifier from the
+ * record field identifier
+ */
+
+ if (token != '.') error(ePERIOD);
+ else getToken();
+
+ /* Verify that a field identifier associated with this record
+ * follows the period.
+ */
+
+ if ((token != sRECORD_OBJECT) ||
+ (tknPtr->sParm.r.record != typePtr))
+ {
+ error(eRECORDOBJECT);
+ factorType = exprInteger;
+ } /* end if */
+ else
+ {
+ /* Modify the variable so that it has the characteristics
+ * of the field but with level and offset associated with
+ * the record
+ */
+
+ typePtr = tknPtr->sParm.r.parent;
+ varPtr->sKind = typePtr->sParm.t.type;
+ varPtr->sParm.v.offset += tknPtr->sParm.r.offset;
+ varPtr->sParm.v.parent = typePtr;
+
+ getToken();
+ factorType = simplePtrFactor(varPtr, factorFlags);
+
+ } /* end else */
+ } /* end else */
+ break;
+
+ case sRECORD_OBJECT :
+ /* NOTE: This must have been preceeded with a WITH statement
+ * defining the RECORD type
+ */
+
+ if (!withRecord.parent)
+ error(eINVTYPE);
+ else if ((factorFlags && ADDRESS_DEREFERENCE) != 0)
+ error(ePOINTERTYPE);
+ else if ((factorFlags && INDEXED_FACTOR) != 0)
+ error(eARRAYTYPE);
+
+ /* Verify that a field identifier is associated with the RECORD
+ * specified by the WITH statement.
+ */
+
+ else if (varPtr->sParm.r.record != withRecord.parent)
+ error(eRECORDOBJECT);
+ else
+ {
+ int16_t tempOffset;
+
+ /* Now there are two cases to consider: (1) the withRecord is a
+ * pointer to a RECORD, or (2) the withRecord is the RECOR itself
+ */
+
+ if (withRecord.pointer)
+ {
+ pas_GenerateDataOperation(opPUSH, (varPtr->sParm.r.offset + withRecord.index));
+ factorFlags |= (INDEXED_FACTOR | ADDRESS_DEREFERENCE);
+ tempOffset = withRecord.offset;
+ } /* end if */
+ else
+ {
+ tempOffset = varPtr->sParm.r.offset + withRecord.offset;
+ } /* end else */
+
+ /* Modify the variable so that it has the characteristics of the
+ * the field but with level and offset associated with the record
+ * NOTE: We have to be careful here because the structure
+ * associated with sRECORD_OBJECT is not the same as for
+ * variables!
+ */
+
+ typePtr = varPtr->sParm.r.parent;
+ tempOffset = varPtr->sParm.r.offset;
+
+ varPtr->sKind = typePtr->sParm.t.type;
+ varPtr->sLevel = withRecord.level;
+ varPtr->sParm.v.size = typePtr->sParm.t.asize;
+ varPtr->sParm.v.offset = tempOffset + withRecord.offset;
+ varPtr->sParm.v.parent = typePtr;
+
+ factorType = simplePtrFactor(varPtr, factorFlags);
+ } /* end else */
+ break;
+
+ case sPOINTER :
+ if (token == '^') error(ePTRADR);
+ else getToken();
+
+ factorFlags |= ADDRESS_DEREFERENCE;
+ varPtr->sKind = typePtr->sParm.t.type;
+ factorType = simplePtrFactor(varPtr, factorFlags);
+ break;
+
+ case sVAR_PARM :
+ if (factorFlags != 0) error(eVARPARMTYPE);
+ factorFlags |= ADDRESS_DEREFERENCE;
+
+ varPtr->sKind = typePtr->sParm.t.type;
+ factorType = simplePtrFactor(varPtr, factorFlags);
+ break;
+
+ case sARRAY :
+ if (factorFlags != 0) error(eARRAYTYPE);
+ if (token == '[')
+ {
+ factorFlags |= INDEXED_FACTOR;
+
+ arrayIndex(typePtr->sParm.t.asize);
+ varPtr->sKind = typePtr->sParm.t.type;
+ varPtr->sParm.v.size = typePtr->sParm.t.asize;
+ factorType = simplePtrFactor(varPtr, factorFlags);
+ } /* end if */
+ else
+ {
+ pas_GenerateStackReference(opLAS, varPtr);
+ factorType = exprArrayPtr;
+ } /* end else */
+ break;
+
+ default :
+ error(eINVTYPE);
+ factorType = exprInteger;
+ break;
+
+ } /* end switch */
+
+ return factorType;
+
+} /* end simplePtrFactor */
+
+/***********************************************************************/
+
+static exprType functionDesignator(void)
+{
+ STYPE *funcPtr = tknPtr;
+ STYPE *typePtr = funcPtr->sParm.p.parent;
+ exprType factorType;
+ int size = 0;
+
+ TRACE(lstFile,"[functionDesignator]");
+
+ /* FORM: function-designator =
+ * function-identifier [ actual-parameter-list ]
+ */
+
+ /* Allocate stack space for a reference instance of the type
+ * returned by the function. This is an uninitalized "container"
+ * that will catch the valued returned by the function.
+ *
+ * Check for the special case of a string value. In this case,
+ * the container cannot be empty. Rather, it must refer to an
+ * empty string allocated on the string strack
+ */
+
+ if (typePtr->sParm.t.rtype == sRSTRING)
+ {
+ /* Create and empty string reference */
+
+ pas_BuiltInFunctionCall(lbMKSTK);
+ }
+ else
+ {
+ /* Okay, create the empty container */
+
+ pas_GenerateDataOperation(opINDS, typePtr->sParm.t.rsize);
+ }
+
+ /* Get the type of the function */
+
+ factorType = getExprType(typePtr);
+ setAbstractType(typePtr);
+
+ /* Skip over the function-identifier */
+
+ getToken();
+
+ /* Get the actual parameters (if any) associated with the procedure
+ * call. This will lie in the stack "above" the function return
+ * value container.
+ */
+
+ size = actualParameterList(funcPtr);
+
+ /* Generate function call and stack adjustment (if required) */
+
+ pas_GenerateProcedureCall(funcPtr);
+
+ /* Release the actual parameter list (if any). */
+
+ if (size)
+ {
+ pas_GenerateDataOperation(opINDS, -size);
+ }
+
+ return factorType;
+
+} /* end functionDesignator */
+
+/*************************************************************************/
+/* Determine the expression type associated with a pointer to a type */
+/* symbol */
+
+static void setAbstractType(STYPE *sType)
+{
+ TRACE(lstFile,"[setAbstractType]");
+
+ if ((sType) && (sType->sKind == sTYPE)
+ && (sType->sParm.t.type == sPOINTER))
+ sType = sType->sParm.t.parent;
+
+ if ((sType) && (sType->sKind == sTYPE)) {
+ switch (sType->sParm.t.type) {
+ case sSCALAR :
+ if (abstractType) {
+ if (sType != abstractType) error(eSCALARTYPE);
+ } /* end if */
+ else
+ abstractType = sType;
+ break;
+ case sSUBRANGE :
+ if (!abstractType)
+ abstractType = sType;
+ else if ((abstractType->sParm.t.type != sSUBRANGE)
+ || (abstractType->sParm.t.subType != sType->sParm.t.subType))
+ error(eSUBRANGETYPE);
+ switch (sType->sParm.t.subType) {
+ case sINT :
+ case sCHAR :
+ break;
+ case sSCALAR :
+ if (abstractType != sType) error(eSUBRANGETYPE);
+ break;
+ default :
+ error(eSUBRANGETYPE);
+ break;
+ } /* end switch */
+ break;
+ } /* end switch */
+ } /* end if */
+ else error(eINVTYPE);
+
+} /* end setAbstractType */
+
+/***************************************************************/
+static void getSetFactor(void)
+{
+ setTypeStruct s;
+
+ TRACE(lstFile,"[getSetFactor]");
+
+ /* FORM: [[<constant>[,<constant>[, ...]]]] */
+ /* ASSUMPTION: The first '[' has already been processed */
+
+ /* First, verify that a scalar expression type has been specified */
+ /* If the abstractType is a SET, then we will need to get the TYPE */
+ /* that it is a SET OF */
+
+ if (abstractType) {
+ if (abstractType->sParm.t.type == sSET_OF)
+ s.typePtr = abstractType->sParm.t.parent;
+ else
+ s.typePtr = abstractType;
+ } /* end if */
+ else
+ s.typePtr = NULL;
+
+ /* Now, get the associated type and MIN/MAX values */
+
+ if ((s.typePtr) && (s.typePtr->sParm.t.type == sSCALAR)) {
+ s.typeFound = true;
+ s.setType = sSCALAR;
+ s.minValue = s.typePtr->sParm.t.minValue;
+ s.maxValue = s.typePtr->sParm.t.maxValue;
+ } /* end else if */
+ else if ((s.typePtr) && (s.typePtr->sParm.t.type == sSUBRANGE)) {
+ s.typeFound = true;
+ s.setType = s.typePtr->sParm.t.subType;
+ s.minValue = s.typePtr->sParm.t.minValue;
+ s.maxValue = s.typePtr->sParm.t.maxValue;
+ } /* end else if */
+ else {
+ error(eSET);
+ s.typeFound = false;
+ s.typePtr = NULL;
+ s.minValue = 0;
+ s.maxValue = BITS_IN_INTEGER-1;
+ } /* end else */
+
+ /* Get the first element of the set */
+
+ getSetElement(&s);
+
+ /* Incorporate each additional element into the set */
+ /* NOTE: The optimizer will combine sets of constant elements into a */
+ /* single PUSH! */
+
+ while (token == ',') {
+
+ /* Get the next element of the set */
+ getToken();
+ getSetElement(&s);
+
+ /* OR it with the previous element */
+ pas_GenerateSimple(opOR);
+
+ } /* end while */
+
+} /* end getSetFactor */
+
+/***************************************************************/
+static void getSetElement(setTypeStruct *s)
+{
+ uint16_t setValue;
+ int16_t firstValue;
+ int16_t lastValue;
+ STYPE *setPtr;
+
+ TRACE(lstFile,"[getSetElement]");
+
+ switch (token) {
+ case sSCALAR_OBJECT : /* A scalar or scalar subrange constant */
+ firstValue = tknPtr->sParm.c.val.i;
+ if (!s->typeFound) {
+ s->typeFound = true;
+ s->typePtr = tknPtr->sParm.c.parent;
+ s->setType = sSCALAR;
+ s->minValue = s->typePtr->sParm.t.minValue;
+ s->maxValue = s->typePtr->sParm.t.maxValue;
+ } /* end if */
+ else if ((s->setType != sSCALAR)
+ || (s->typePtr != tknPtr->sParm.c.parent))
+ error(eSET);
+ goto addBit;
+
+ case tINT_CONST : /* An integer subrange constant ? */
+ firstValue = tknInt;
+ if (!s->typeFound) {
+ s->typeFound = true;
+ s->setType = sINT;
+ } /* end if */
+ else if (s->setType != sINT)
+ error(eSET);
+ goto addBit;
+
+ case tCHAR_CONST : /* A character subrange constant */
+ firstValue = tknInt;
+ if (!s->typeFound) {
+ s->typeFound = true;
+ s->setType = sCHAR;
+ } /* end if */
+ else if (s->setType != sCHAR)
+ error(eSET);
+
+ addBit:
+ /* Check if the constant set element is the first value in a */
+ /* subrange of values */
+
+ getToken();
+ if (token != tSUBRANGE) {
+
+ /* Verify that the new value is in range */
+
+ if ((firstValue < s->minValue) || (firstValue > s->maxValue)) {
+ error(eSETRANGE);
+ setValue = 0;
+ } /* end if */
+ else
+ setValue = (1 << (firstValue - s->minValue));
+
+ /* Now, generate P-Code to push the set value onto the stack */
+
+ pas_GenerateDataOperation(opPUSH, setValue);
+
+ } /* end if */
+ else {
+ if (!s->typeFound) error(eSUBRANGETYPE);
+
+ /* Skip over the tSUBRANGE token */
+
+ getToken();
+
+ /* TYPE check */
+
+ switch (token) {
+ case sSCALAR_OBJECT : /* A scalar or scalar subrange constant */
+ lastValue = tknPtr->sParm.c.val.i;
+ if ((s->setType != sSCALAR)
+ || (s->typePtr != tknPtr->sParm.c.parent))
+ error(eSET);
+ goto addLottaBits;
+
+ case tINT_CONST : /* An integer subrange constant ? */
+ lastValue = tknInt;
+ if (s->setType != sINT) error(eSET);
+ goto addLottaBits;
+
+ case tCHAR_CONST : /* A character subrange constant */
+ lastValue = tknInt;
+ if (s->setType != sCHAR) error(eSET);
+
+ addLottaBits :
+ /* Verify that the first value is in range */
+ if (firstValue < s->minValue) {
+ error(eSETRANGE);
+ firstValue = s->minValue;
+ } /* end if */
+ else if (firstValue > s->maxValue) {
+ error(eSETRANGE);
+ firstValue = s->maxValue;
+ } /* end else if */
+
+ /* Verify that the last value is in range */
+ if (lastValue < firstValue) {
+ error(eSETRANGE);
+ lastValue = firstValue;
+ } /* end if */
+ else if (lastValue > s->maxValue) {
+ error(eSETRANGE);
+ lastValue = s->maxValue;
+ } /* end else if */
+
+ /* Set all bits from firstValue through lastValue */
+
+ setValue = (0xffff << (firstValue - s->minValue));
+ setValue &= (0xffff >> ((BITS_IN_INTEGER-1) - (lastValue - s->minValue)));
+
+ /* Now, generate P-Code to push the set value onto the stack */
+
+ pas_GenerateDataOperation(opPUSH, setValue);
+ break;
+
+ case sSCALAR :
+ if ((!s->typePtr)
+ || (s->typePtr != tknPtr->sParm.v.parent)) {
+ error(eSET);
+
+ if (!s->typePtr) {
+ s->typeFound = true;
+ s->typePtr = tknPtr->sParm.v.parent;
+ s->setType = sSCALAR;
+ s->minValue = s->typePtr->sParm.t.minValue;
+ s->maxValue = s->typePtr->sParm.t.maxValue;
+ } /* end if */
+ } /* end if */
+ goto addVarToBits;
+
+ case sINT : /* An integer subrange variable ? */
+ case sCHAR : /* A character subrange variable? */
+ if (s->setType != token) error(eSET);
+ goto addVarToBits;
+
+ case sSUBRANGE :
+ if ((!s->typePtr)
+ || (s->typePtr != tknPtr->sParm.v.parent)) {
+
+ if ((tknPtr->sParm.v.parent->sParm.t.subType == sSCALAR)
+ || (tknPtr->sParm.v.parent->sParm.t.subType != s->setType))
+ error(eSET);
+
+ if (!s->typePtr) {
+ s->typeFound = true;
+ s->typePtr = tknPtr->sParm.v.parent;
+ s->setType = s->typePtr->sParm.t.subType;
+ s->minValue = s->typePtr->sParm.t.minValue;
+ s->maxValue = s->typePtr->sParm.t.maxValue;
+ } /* end if */
+ } /* end if */
+
+ addVarToBits:
+ /* Verify that the first value is in range */
+
+ if (firstValue < s->minValue) {
+ error(eSETRANGE);
+ firstValue = s->minValue;
+ } /* end if */
+ else if (firstValue > s->maxValue) {
+ error(eSETRANGE);
+ firstValue = s->maxValue;
+ } /* end else if */
+
+ /* Set all bits from firstValue through maxValue */
+
+ setValue = (0xffff >> ((BITS_IN_INTEGER-1) - (s->maxValue - s->minValue)));
+ setValue &= (0xffff << (firstValue - s->minValue));
+
+ /* Generate run-time logic to get all bits from firstValue */
+ /* through last value, i.e., need to generate logic to get: */
+ /* 0xffff >> ((BITS_IN_INTEGER-1)-(lastValue-minValue)) */
+
+ pas_GenerateDataOperation(opPUSH, 0xffff);
+ pas_GenerateDataOperation(opPUSH, ((BITS_IN_INTEGER-1) + s->minValue));
+ pas_GenerateStackReference(opLDS, tknPtr);
+ pas_GenerateSimple(opSUB);
+ pas_GenerateSimple(opSRL);
+
+ /* Then AND this with the setValue */
+
+ if (setValue != 0xffff) {
+ pas_GenerateDataOperation(opPUSH, setValue);
+ pas_GenerateSimple(opAND);
+ } /* end if */
+
+ getToken();
+ break;
+
+ default :
+ error(eSET);
+ pas_GenerateDataOperation(opPUSH, 0);
+ break;
+
+ } /* end switch */
+ } /* end else */
+ break;
+
+ case sSCALAR :
+ if (s->typeFound) {
+ if ((!s->typePtr) || (s->typePtr != tknPtr->sParm.v.parent))
+ error(eSET);
+ } /* end if */
+ else {
+ s->typeFound = true;
+ s->typePtr = tknPtr->sParm.v.parent;
+ s->setType = sSCALAR;
+ s->minValue = s->typePtr->sParm.t.minValue;
+ s->maxValue = s->typePtr->sParm.t.maxValue;
+ } /* end if */
+ goto addVar;
+
+ case sINT : /* An integer subrange variable ? */
+ case sCHAR : /* A character subrange variable? */
+ if (!s->typeFound) {
+ s->typeFound = true;
+ s->setType = token;
+ } /* end if */
+ else if (s->setType != token)
+ error(eSET);
+ goto addVar;
+
+ case sSUBRANGE :
+ if (s->typeFound) {
+ if ((!s->typePtr) || (s->typePtr != tknPtr->sParm.v.parent))
+ error(eSET);
+ } /* end if */
+ else {
+ s->typeFound = true;
+ s->typePtr = tknPtr->sParm.v.parent;
+ s->setType = s->typePtr->sParm.t.subType;
+ s->minValue = s->typePtr->sParm.t.minValue;
+ s->maxValue = s->typePtr->sParm.t.maxValue;
+ } /* end if */
+
+ addVar:
+ /* Check if the variable set element is the first value in a */
+ /* subrange of values */
+
+ setPtr = tknPtr;
+ getToken();
+ if (token != tSUBRANGE) {
+
+ /* Generate P-Code to push the set value onto the stack */
+ /* FORM: 1 << (firstValue - minValue) */
+
+ pas_GenerateDataOperation(opPUSH, 1);
+ pas_GenerateStackReference(opLDS, setPtr);
+ pas_GenerateDataOperation(opPUSH, s->minValue);
+ pas_GenerateSimple(opSUB);
+ pas_GenerateSimple(opSLL);
+
+ } /* end if */
+ else {
+ if (!s->typeFound) error(eSUBRANGETYPE);
+
+ /* Skip over the tSUBRANGE token */
+
+ getToken();
+
+ /* TYPE check */
+
+ switch (token) {
+ case sSCALAR_OBJECT : /* A scalar or scalar subrange constant */
+ lastValue = tknPtr->sParm.c.val.i;
+ if ((s->setType != sSCALAR)
+ || (s->typePtr != tknPtr->sParm.c.parent))
+ error(eSET);
+ goto addBitsToVar;
+
+ case tINT_CONST : /* An integer subrange constant ? */
+ lastValue = tknInt;
+ if (s->setType != sINT) error(eSET);
+ goto addBitsToVar;
+
+ case tCHAR_CONST : /* A character subrange constant */
+ lastValue = tknInt;
+ if (s->setType != sCHAR) error(eSET);
+
+ addBitsToVar :
+ /* Verify that the last value is in range */
+
+ if (lastValue < s->minValue) {
+ error(eSETRANGE);
+ lastValue = s->minValue;
+ } /* end if */
+ else if (lastValue > s->maxValue) {
+ error(eSETRANGE);
+ lastValue = s->maxValue;
+ } /* end else if */
+
+ /* Set all bits from minValue through lastValue */
+
+ setValue = (0xffff >> ((BITS_IN_INTEGER-1) - (lastValue - s->minValue)));
+
+ /* Now, generate P-Code to push the set value onto the stack */
+ /* First generate: 0xffff << (firstValue-minValue) */
+
+ pas_GenerateDataOperation(opPUSH, 0xffff);
+ pas_GenerateStackReference(opLDS, setPtr);
+ if (s->minValue) {
+ pas_GenerateDataOperation(opPUSH, s->minValue);
+ pas_GenerateSimple(opSUB);
+ } /* end if */
+ pas_GenerateSimple(opSLL);
+
+ /* Then and this with the pre-computed constant set value */
+
+ if (setValue != 0xffff) {
+ pas_GenerateDataOperation(opPUSH, setValue);
+ pas_GenerateSimple(opAND);
+ } /* end if */
+
+ getToken();
+ break;
+
+ case sINT : /* An integer subrange variable ? */
+ case sCHAR : /* A character subrange variable? */
+ if (s->setType != token) error(eSET);
+ goto addVarToVar;
+
+ case sSCALAR :
+ if (s->typePtr != tknPtr->sParm.v.parent) error(eSET);
+ goto addVarToVar;
+
+ case sSUBRANGE :
+ if ((s->typePtr != tknPtr->sParm.v.parent)
+ && ((tknPtr->sParm.v.parent->sParm.t.subType == sSCALAR)
+ || (tknPtr->sParm.v.parent->sParm.t.subType != s->setType)))
+ error(eSET);
+
+ addVarToVar:
+
+ /* Generate run-time logic to get all bits from firstValue */
+ /* through lastValue */
+ /* First generate: 0xffff << (firstValue-minValue) */
+
+ pas_GenerateDataOperation(opPUSH, 0xffff);
+ pas_GenerateStackReference(opLDS, setPtr);
+ if (s->minValue) {
+ pas_GenerateDataOperation(opPUSH, s->minValue);
+ pas_GenerateSimple(opSUB);
+ } /* end if */
+ pas_GenerateSimple(opSLL);
+
+ /* Generate logic to get: */
+ /* 0xffff >> ((BITS_IN_INTEGER-1)-(lastValue-minValue)) */
+
+ pas_GenerateDataOperation(opPUSH, 0xffff);
+ pas_GenerateDataOperation(opPUSH, ((BITS_IN_INTEGER-1) + s->minValue));
+ pas_GenerateStackReference(opLDS, tknPtr);
+ pas_GenerateSimple(opSUB);
+ pas_GenerateSimple(opSRL);
+
+ /* Then AND the two values */
+
+ pas_GenerateSimple(opAND);
+
+ getToken();
+ break;
+
+ default :
+ error(eSET);
+ pas_GenerateDataOperation(opPUSH, 0);
+ break;
+
+ } /* end switch */
+ } /* end else */
+ break;
+
+ default :
+ error(eSET);
+ pas_GenerateDataOperation(opPUSH, 0);
+ break;
+
+ } /* end switch */
+
+} /* end getSetElement */
+
+/***************************************************************/
+
+/* Check if this is a ordinal type. This is what is needed, for
+ * example, as an argument to ord(), pred(), succ(), or odd().
+ * This is the kind of expression we need in a CASE statement
+ * as well.
+ */
+
+static bool isOrdinalType(exprType testExprType)
+{
+ if ((testExprType == exprInteger) || /* integer value */
+ (testExprType == exprChar) || /* character value */
+ (testExprType == exprBoolean) || /* boolean(integer) value */
+ (testExprType == exprScalar)) /* scalar(integer) value */
+ return true;
+ else
+ return false;
+}
+
+/***************************************************************/
+/* This is a hack to handle calls to system functions that return
+ * exprCString pointers that must be converted to exprString
+ * records upon assignment.
+ */
+
+static bool isAnyStringType(exprType testExprType)
+{
+ if ((testExprType == exprString) ||
+ (testExprType == exprStkString) ||
+ (testExprType == exprCString))
+ return true;
+ else
+ return false;
+}
+
+static bool isStringReference (exprType testExprType)
+{
+ if ((testExprType == exprString) ||
+ (testExprType == exprStkString))
+ return true;
+ else
+ return false;
+}
+
diff --git a/misc/pascal/pascal/pexpr.h b/misc/pascal/pascal/pexpr.h
new file mode 100644
index 000000000..cca0595cd
--- /dev/null
+++ b/misc/pascal/pascal/pexpr.h
@@ -0,0 +1,98 @@
+/***********************************************************************
+ * pexpr.h
+ * External Declarations associated with pexpr.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************************************/
+
+#ifndef __PEXPR_H
+#define __PEXPR_H
+
+/***********************************************************************
+ * Included Files
+ ***********************************************************************/
+
+#include <stdint.h>
+
+/***********************************************************************
+ * Type Definitions
+ ***********************************************************************/
+
+typedef enum exprEnum
+{
+ exprUnknown = 0, /* TOS value unknown */
+ exprAnyOrdinal, /* TOS = any ordinal type */
+ exprAnyString, /* TOS = any string type */
+
+ exprInteger, /* TOS = integer value */
+ exprReal, /* TOS = real value */
+ exprChar, /* TOS = character value */
+ exprBoolean, /* TOS = boolean(integer) value */
+ exprScalar, /* TOS = scalar(integer) value */
+ exprString, /* TOS = variable length string reference */
+ exprStkString, /* TOS = reference to string on string stack */
+ exprCString, /* TOS = pointer to C string */
+ exprSet, /* TOS = set(integer) value */
+ exprArray, /* TOS = array */
+ exprRecord, /* TOS = record */
+
+ exprIntegerPtr, /* TOS = pointer to integer value */
+ exprRealPtr, /* TOS = pointer to a real value */
+ exprCharPtr, /* TOS = pointer to a character value */
+ exprBooleanPtr, /* TOS = pointer to a boolean value */
+ exprScalarPtr, /* TOS = pointer to a scalar value */
+ exprSetPtr, /* TOS = pointer to a set value */
+ exprArrayPtr, /* TOS = pointer to an array */
+ exprRecordPtr /* TOS = pointer to a record */
+} exprType;
+
+/***********************************************************************
+ * Global Variables
+ ***********************************************************************/
+
+extern int constantToken;
+extern int32_t constantInt;
+extern double constantReal;
+extern char *constantStart;
+
+/***********************************************************************
+ * Global Function Protypes
+ ***********************************************************************/
+
+extern exprType expression ( exprType findExprType, STYPE *typePtr );
+extern exprType varParm ( exprType varExprType, STYPE *typePtr );
+extern void arrayIndex ( int32_t size );
+extern exprType getExprType( STYPE *sType );
+
+extern void constantExpression(void);
+
+#endif /* __PEXPR_H */
diff --git a/misc/pascal/pascal/pffunc.c b/misc/pascal/pascal/pffunc.c
new file mode 100644
index 000000000..0820272ae
--- /dev/null
+++ b/misc/pascal/pascal/pffunc.c
@@ -0,0 +1,452 @@
+/***************************************************************
+ * pfunc.c
+ * Standard Functions
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************/
+
+/***************************************************************
+ * Included Files
+ ***************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "keywords.h"
+#include "pasdefs.h"
+#include "ptdefs.h"
+#include "podefs.h"
+#include "pfdefs.h"
+#include "pedefs.h"
+#include "pxdefs.h"
+
+#include "pas.h"
+#include "pexpr.h"
+#include "pfunc.h"
+#include "pgen.h" /* for pas_Generate*() */
+#include "ptkn.h"
+#include "pinsn.h"
+#include "perr.h"
+
+/***************************************************************
+ * Private Function Prototypes
+ ***************************************************************/
+
+/* Standard Pascal Functions */
+
+static exprType absFunc (void); /* Integer absolute value */
+static exprType predFunc (void);
+static void ordFunc (void); /* Convert scalar to integer */
+static exprType sqrFunc (void);
+static void realFunc (uint8_t fpCode);
+static exprType succFunc (void);
+static void oddFunc (void);
+static void chrFunc (void);
+static void fileFunc (uint16_t opcode);
+
+/* Enhanced Pascal functions */
+
+/* Non-standard C-library interface functions */
+
+static exprType getenvFunc (void); /* Get environment string value */
+
+/***************************************************************
+ * Public Functions
+ ***************************************************************/
+
+void primeBuiltInFunctions(void)
+{
+}
+
+/***************************************************************/
+/* Process a standard Pascal function call */
+
+exprType builtInFunction(void)
+{
+ exprType funcType = exprUnknown;
+
+ TRACE(lstFile,"[builtInFunction]");
+
+ /* Is the token a function? */
+
+ if (token == tFUNC)
+ {
+ /* Yes, process it procedure according to the extended token type */
+
+ switch (tknSubType)
+ {
+ /* Functions which return the same type as their argument */
+ case txABS :
+ funcType = absFunc();
+ break;
+ case txSQR :
+ funcType = sqrFunc();
+ break;
+ case txPRED :
+ funcType = predFunc();
+ break;
+ case txSUCC :
+ funcType = succFunc();
+ break;
+
+ case txGETENV : /* Non-standard C library interfaces */
+ funcType = getenvFunc();
+ break;
+
+ /* Functions returning INTEGER with REAL arguments */
+
+ case txROUND :
+ getToken(); /* Skip over 'round' */
+ expression(exprReal, NULL);
+ pas_GenerateFpOperation(fpROUND);
+ funcType = exprInteger;
+ break;
+ case txTRUNC :
+ getToken(); /* Skip over 'trunc' */
+ expression(exprReal, NULL);
+ pas_GenerateFpOperation(fpTRUNC);
+ funcType = exprInteger;
+ break;
+
+ /* Functions returning CHARACTER with INTEGER arguments. */
+
+ case txCHR :
+ chrFunc();
+ funcType = exprChar;
+ break;
+
+ /* Function returning integer with scalar arguments */
+
+ case txORD :
+ ordFunc();
+ funcType = exprInteger;
+ break;
+
+ /* Functions returning BOOLEAN */
+ case txODD :
+ oddFunc();
+ funcType = exprBoolean;
+ break;
+ case txEOF :
+ fileFunc(xEOF);
+ funcType = exprBoolean;
+ break;
+ case txEOLN :
+ fileFunc(xEOLN);
+ funcType = exprBoolean;
+ break;
+
+ /* Functions returning REAL with REAL/INTEGER arguments */
+
+ case txSQRT :
+ realFunc(fpSQRT);
+ funcType = exprReal;
+ break;
+ case txSIN :
+ realFunc(fpSIN);
+ funcType = exprReal;
+ break;
+ case txCOS :
+ realFunc(fpCOS);
+ funcType = exprReal;
+ break;
+ case txARCTAN :
+ realFunc(fpATAN);
+ funcType = exprReal;
+ break;
+ case txLN :
+ realFunc(fpLN);
+ funcType = exprReal;
+ break;
+ case txEXP :
+ realFunc(fpEXP);
+ funcType = exprReal;
+ break;
+
+ default :
+ error(eINVALIDPROC);
+ break;
+ } /* end switch */
+ } /* end if */
+
+ return funcType;
+
+} /* end builtInFunction */
+
+void checkLParen(void)
+{
+ getToken(); /* Skip over function name */
+ if (token != '(') error(eLPAREN); /* Check for '(' */
+ else getToken();
+}
+
+void checkRParen(void)
+{
+ if (token != ')') error(eRPAREN); /* Check for ')') */
+ else getToken();
+}
+
+/***************************************************************
+ * Private Functions
+ ***************************************************************/
+
+static exprType absFunc(void)
+{
+ exprType absType;
+
+ TRACE(lstFile,"[absFunc]");
+
+ /* FORM: ABS (<simple integer/real expression>) */
+
+ checkLParen();
+
+ absType = expression(exprUnknown, NULL);
+ if (absType == exprInteger)
+ pas_GenerateSimple(opABS);
+ else if (absType == exprReal)
+ pas_GenerateFpOperation(fpABS);
+ else
+ error(eINVARG);
+
+ checkRParen();
+ return absType;
+
+} /* end absFunc */
+
+/**********************************************************************/
+
+static void ordFunc(void)
+{
+ TRACE(lstFile,"[ordFunc]");
+
+ /* FORM: ORD (<scalar type>) */
+
+ checkLParen();
+ expression(exprAnyOrdinal, NULL); /* Get any ordinal type */
+ checkRParen();
+
+} /* end ordFunc */
+
+/**********************************************************************/
+
+static exprType predFunc(void)
+{
+ exprType predType;
+
+ TRACE(lstFile,"[predFunc]");
+
+ /* FORM: PRED (<simple integer expression>) */
+
+ checkLParen();
+
+ /* Process any ordinal expression */
+
+ predType = expression(exprAnyOrdinal, NULL);
+ checkRParen();
+ pas_GenerateSimple(opDEC);
+ return predType;
+
+} /* end predFunc */
+
+/**********************************************************************/
+
+static exprType sqrFunc(void)
+{
+ exprType sqrType;
+
+ TRACE(lstFile,"[sqrFunc]");
+
+/* FORM: SQR (<simple integer OR real expression>) */
+
+ checkLParen();
+
+ sqrType = expression(exprUnknown, NULL); /* Process any expression */
+ if (sqrType == exprInteger) {
+
+ pas_GenerateSimple(opDUP);
+ pas_GenerateSimple(opMUL);
+
+ } /* end if */
+ else if (sqrType == exprReal)
+ pas_GenerateFpOperation(fpSQR);
+
+ else
+ error(eINVARG);
+
+ checkRParen();
+ return sqrType;
+
+} /* end sqrFunc */
+
+/**********************************************************************/
+static void realFunc (uint8_t fpOpCode)
+{
+ exprType realType;
+
+ TRACE(lstFile,"[realFunc]");
+
+ /* FORM: <function identifier> (<real/integer expression>) */
+
+ checkLParen();
+
+ realType = expression(exprUnknown, NULL); /* Process any expression */
+ if (realType == exprInteger)
+ pas_GenerateFpOperation((fpOpCode | fpARG1));
+ else if (realType == exprReal)
+ pas_GenerateFpOperation(fpOpCode);
+ else
+ error(eINVARG);
+
+ checkRParen();
+
+} /* end realFunc */
+
+/**********************************************************************/
+
+static exprType succFunc(void)
+{
+ exprType succType;
+
+ TRACE(lstFile,"[succFunc]");
+
+ /* FORM: SUCC (<simple integer expression>) */
+
+ checkLParen();
+
+ /* Process any ordinal expression */
+
+ succType = expression(exprAnyOrdinal, NULL);
+
+ checkRParen();
+ pas_GenerateSimple(opINC);
+ return succType;
+
+} /* end succFunc */
+
+/***********************************************************************/
+
+static void oddFunc(void)
+{
+ TRACE(lstFile,"[oddFunc]");
+
+ /* FORM: ODD (<simple integer expression>) */
+
+ checkLParen();
+
+ /* Process any ordinal expression */
+
+ expression(exprAnyOrdinal, NULL);
+ checkRParen();
+ pas_GenerateDataOperation(opPUSH, 1);
+ pas_GenerateSimple(opAND);
+ pas_GenerateSimple(opNEQZ);
+
+} /* end oddFunc */
+
+/***********************************************************************/
+/* Process the standard chr function */
+
+static void chrFunc(void)
+{
+ TRACE(lstFile,"[charFactor]");
+
+ /* Form: chr(integer expression).
+ *
+ * char(val) is only defined if there exists a character ch such
+ * that ord(ch) = val. If this is not the case, we will simply
+ * let the returned value exceed the range of type char. */
+
+ checkLParen();
+ expression(exprInteger, NULL);
+ checkRParen();
+
+} /* end chrFunc */
+
+/****************************************************************************/
+/* EOF/EOLN function */
+
+static void fileFunc(uint16_t opcode)
+{
+ TRACE(lstFile,"[fileFunc]");
+
+ /* FORM: EOF|EOLN (<file number>) */
+
+ checkLParen();
+ if (token != sFILE)
+ {
+ error(eFILE);
+ }
+ else
+ {
+ pas_GenerateDataOperation(opINDS, sBOOLEAN_SIZE);
+ pas_GenerateIoOperation(opcode, tknPtr->sParm.fileNumber);
+ getToken();
+ checkRParen();
+ } /* end else */
+
+} /* end fileFunc */
+
+/**********************************************************************/
+/* C library getenv interface */
+
+static exprType getenvFunc(void)
+{
+ exprType stringType;
+
+ TRACE(lstFile, "[getenvFunc]");
+
+ /* FORM: <string_var> = getenv(<string>) */
+
+ checkLParen();
+
+ /* Get the string expression representing the environment variable
+ * name.
+ */
+
+ stringType = expression(exprString, NULL);
+
+ /* Two possible kinds of strings could be returned.
+ * Anything else other then 'exprString' would be an error (but
+ * should happen).
+ */
+
+ if ((stringType != exprString) && (stringType != exprStkString))
+ {
+ error(eINVARG);
+ }
+
+ pas_BuiltInFunctionCall(lbGETENV);
+ checkRParen();
+ return exprCString;
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/pascal/pfunc.h b/misc/pascal/pascal/pfunc.h
new file mode 100644
index 000000000..a317fb440
--- /dev/null
+++ b/misc/pascal/pascal/pfunc.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * pfunc.h
+ * External Declarations associated with pfunc.c
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PFUNC_H
+#define __PFUNC_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include "pexpr.h" /* For exprType */
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void primeBuiltInFunctions(void);
+extern exprType builtInFunction(void);
+extern void builtInFunctionOfConstant(void);
+
+extern void checkLParen(void);
+extern void checkRParen(void);
+
+#endif /* __PFUNC_H */
diff --git a/misc/pascal/pascal/pgen.c b/misc/pascal/pascal/pgen.c
new file mode 100644
index 000000000..e77582ad9
--- /dev/null
+++ b/misc/pascal/pascal/pgen.c
@@ -0,0 +1,641 @@
+/**********************************************************************
+ * pgen.c
+ * P-Code generation logic
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "config.h" /* Configuration */
+#include "keywords.h" /* Standard types */
+#include "pasdefs.h" /* Common types */
+#include "ptdefs.h" /* Token / symbol table definitions */
+#include "podefs.h" /* Logical opcode definitions */
+#include "pedefs.h" /* error code definitions */
+
+#include "pas.h" /* Global variables */
+#include "poff.h" /* For POFF file format */
+#include "pofflib.h" /* For poff*() functions*/
+#include "pinsn.h" /* (DEBUG only) */
+#include "perr.h" /* error() */
+
+#include "pproc.h" /* for actualParameterSize */
+#include "pgen.h" /* (to verify prototypes in this file) */
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+#define UNDEFINED_LEVEL (-1)
+#define INVALID_PCODE (-1)
+
+#define LEVEL_DEFINED(l) ((int32_t)(l) >= 0)
+#define PCODE_VALID(p) ((int32_t)(p) >= 0)
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static int32_t g_currentStackLevelReference = UNDEFINED_LEVEL;
+static uint32_t g_nStackLevelReferenceChanges = 0;
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Generate a stack reference opcode to a global variable residing at
+ * static nesting level zero.
+ */
+
+static void
+pas_GenerateLevel0StackReference(enum pcode_e eOpCode, STYPE *pVar)
+{
+ /* Sanity checking. Double check nesting level and also since this is
+ * a level zero reference, then the offset must be positive
+ */
+
+ if ((pVar->sLevel != 0) || (pVar->sParm.v.offset < 0))
+ {
+ error(eHUH);
+ }
+ else
+ {
+ /* Generate the P-code */
+
+ insn_GenerateDataOperation(eOpCode, pVar->sParm.v.offset);
+
+ /* If the variable is undefined, also generate a relocation
+ * record.
+ */
+
+ if ((pVar->sParm.v.flags & SVAR_EXTERNAL) != 0)
+ {
+ (void)poffAddRelocation(poffHandle, RLT_LDST,
+ pVar->sParm.v.symIndex, 0);
+ }
+ }
+}
+
+/***********************************************************************/
+/* There are some special P-codes for accessing stack data at static
+ * nesting level 0. Check if the specified opcode is one of those. If
+ * so, return the mapped opcode. Otherwise, return INVALID_PCODE.
+ */
+
+static int32_t
+pas_GetLevel0Opcode(enum pcode_e eOpCode)
+{
+ switch (eOpCode)
+ {
+ case opLDS: return opLD;
+ case opLDSH: return opLDH;
+ case opLDSB: return opLDB;
+ case opLDSM: return opLDM;
+ case opSTS: return opST;
+ case opSTSB: return opSTB;
+ case opSTSM: return opSTM;
+ case opLDSX: return opLDX;
+ case opLDSXB: return opLDXB;
+ case opLDSXM: return opLDXM;
+ case opSTSX: return opSTX;
+ case opSTSXB: return opSTXB;
+ case opSTSXM: return opSTXM;
+ case opLAS: return opLA;
+ case opLASX: return opLAX;
+ default: return INVALID_PCODE;
+ }
+}
+
+/***********************************************************************/
+/* A new static nesting level has been encountered. Check if we need
+ * to reset the level stack pointer (LSP) register (assuming that the
+ * architecutre has one).
+ */
+
+static void
+pas_SetLevelStackPointer(uint32_t dwLevel)
+{
+ if (dwLevel != g_currentStackLevelReference)
+ {
+ /* Set the level stack pointer (LSP) register */
+
+ insn_SetStackLevel(dwLevel);
+
+ /* Remember the setting so that we do not reset the LSP until
+ * the level changes (or it is invalidated).
+ */
+
+ g_currentStackLevelReference = dwLevel;
+ g_nStackLevelReferenceChanges++;
+ }
+}
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+/***********************************************************************/
+/* Return the current setting of the level stack pointer (LSP) register
+ * -- assuming that the underlying architecure may have one.
+ */
+
+int32_t pas_GetCurrentStackLevel(void)
+{
+ return g_currentStackLevelReference;
+}
+
+/***********************************************************************/
+/* Invalidate the current stack level register setting. This will cause
+ * us to reset the LSP when the next stack level reference is encountered.
+ */
+
+void pas_InvalidateCurrentStackLevel(void)
+{
+ g_currentStackLevelReference = UNDEFINED_LEVEL;
+ g_nStackLevelReferenceChanges++;
+}
+
+/***********************************************************************/
+/* Set the stack level pointer to known value. This is done when in
+ * while and for loop processing. The value of the LSP will be that
+ * as sampled at the top of the lop not necessarily the value at the
+ * bottom of the loop.
+ */
+
+void pas_SetCurrentStackLevel(int32_t dwLsp)
+{
+ g_currentStackLevelReference = dwLsp;
+ g_nStackLevelReferenceChanges++;
+}
+
+/***********************************************************************/
+/* Get the number of changes made to the level stack pointer. This is
+ * useful by compiler logic to determine if the stack level pointer was
+ * ever changed by any logic path.
+ */
+
+uint32_t pas_GetNStackLevelChanges(void)
+{
+ return g_nStackLevelReferenceChanges;
+}
+
+/***********************************************************************/
+/* Generate the most simple of all P-codes */
+
+void pas_GenerateSimple(enum pcode_e eOpCode)
+{
+ insn_GenerateSimple(eOpCode);
+}
+
+/***********************************************************************/
+/* Generate a P-code with a single data argument */
+
+void pas_GenerateDataOperation(enum pcode_e eOpCode, int32_t dwData)
+{
+ insn_GenerateDataOperation(eOpCode, dwData);
+}
+
+/***********************************************************************/
+/* This function is called just before a multiple register operation is
+ * is generated. This should generate logic to specify the size of the
+ * multiple register operation (in bytes, not registers). This may translate
+ * into different operations on different architectures. Typically,
+ * this would generate a push of the size onto the stack or, perhaps,
+ * setting of a dedicated count register.
+ */
+
+void pas_GenerateDataSize(int32_t dwDataSize)
+{
+ insn_GenerateDataSize(dwDataSize);
+}
+
+/***********************************************************************/
+/* Generate a floating point operation */
+
+void pas_GenerateFpOperation(uint8_t fpOpcode)
+{
+ insn_GenerateFpOperation(fpOpcode);
+}
+
+/***********************************************************************/
+/* Generate an IO operation */
+
+void pas_GenerateIoOperation(uint16_t ioOpcode, uint16_t fileNumber)
+{
+ insn_GenerateIoOperation(ioOpcode, fileNumber);
+}
+
+/***********************************************************************/
+/* Generate a pseudo call to a built-in, standard pascal function */
+
+void pas_BuiltInFunctionCall(uint16_t libOpcode)
+{
+ insn_BuiltInFunctionCall(libOpcode);
+}
+
+/***********************************************************************/
+/* Generate a reference to data on the data stack using the specified
+ * level and offset.
+ */
+
+void pas_GenerateLevelReference(enum pcode_e eOpCode, uint16_t wLevel,
+ int32_t dwOffset)
+{
+ /* Is this variable declared at level 0 (i.e., it has global scope)
+ * that is being offset via a nesting level?
+ */
+
+ if (wLevel == 0)
+ {
+ int32_t level0Opcode = pas_GetLevel0Opcode(eOpCode);
+ if (PCODE_VALID(level0Opcode))
+ {
+ insn_GenerateDataOperation(level0Opcode, dwOffset);
+ return;
+ }
+ }
+
+ /* We get here if the reference is at some static nesting level
+ * other that zero OR if there is no special PCode to reference
+ * data at static nesting level 0 for this operation.
+ *
+ * Check if we have to change the level stack pointer (LSP) register
+ * (assuming that the architecture has one).
+ */
+
+ pas_SetLevelStackPointer(wLevel);
+
+ /* Then generate the opcode passing the level in the event that the
+ * architecture does not have an LSP.
+ */
+
+ insn_GenerateLevelReference(eOpCode, wLevel, dwOffset);
+}
+
+/***********************************************************************/
+/* Generate a stack reference opcode, handling references to undefined
+ * stack offsets.
+ */
+
+void pas_GenerateStackReference(enum pcode_e eOpCode, STYPE *pVar)
+{
+ /* Is this variable declared at level 0 (i.e., it has global scope)
+ * that is being offset via a nesting level?
+ */
+
+ if (pVar->sLevel == 0)
+ {
+ int32_t level0Opcode = pas_GetLevel0Opcode(eOpCode);
+ if (PCODE_VALID(level0Opcode))
+ {
+ pas_GenerateLevel0StackReference(level0Opcode, pVar);
+ return;
+ }
+ }
+
+ /* We get here if the reference is at some static nesting level
+ * other that zero OR if there is no special PCode to reference
+ * data at static nesting level 0 for this operation.
+ *
+ * Check if we have to change the level stack pointer (LSP) register
+ * (assuming that the architecture has one).
+ */
+
+ pas_SetLevelStackPointer(pVar->sLevel);
+
+ /* Generate the P-Code at the defined offset and with the specified
+ * static level offset (in case that the architecture does not have
+ * an LSP)
+ */
+
+ insn_GenerateLevelReference(eOpCode, (level - pVar->sLevel),
+ pVar->sParm.v.offset);
+}
+
+/***********************************************************************/
+/* Generate a procedure call and an associated relocation record if the
+ * called procedure is external.
+ */
+
+void
+pas_GenerateProcedureCall(STYPE *pProc)
+{
+ /* sLevel is the level at which the procedure was declared. We need
+ * to set the SLP to this value prior to the call (on some architectures
+ * where the SLP is pushed onto the stack by the procedure
+ * call).
+ */
+
+ pas_SetLevelStackPointer(pProc->sLevel);
+
+ /* Then generate the procedure call (passing the level again for those
+ * architectures that do not support the SLP.
+ */
+
+ insn_GenerateProcedureCall(pProc->sLevel, pProc->sParm.p.label);
+
+ /* If the variable is undefined, also generate a relocation
+ * record.
+ */
+
+#if 0 /* Not yet */
+ if ((pVar->sParm.p.flags & SVAR_EXTERNAL) != 0)
+ {
+ /* For now */
+# error "Don't know what last parameter should be"
+ (void)poffAddRelocation(poffHandle, RLT_PCAL,
+ pVar->sParm.p.symIndex,
+ 0);
+ }
+#endif
+
+ /* Any logic after the procedure/function call return must assume
+ * that the last level reference is unknown.
+ */
+
+ pas_InvalidateCurrentStackLevel();
+}
+
+/***********************************************************************/
+
+void pas_GenerateLineNumber(uint16_t wIncludeNumber, uint32_t dwLineNumber)
+{
+ insn_GenerateLineNumber(wIncludeNumber, dwLineNumber);
+}
+
+/***********************************************************************/
+
+void pas_GenerateDebugInfo(STYPE *pProc, uint32_t dwReturnSize)
+{
+ int i;
+
+ /* Allocate a container to pass the proc information to the library */
+
+ uint32_t nparms = pProc->sParm.p.nParms;
+ poffLibDebugFuncInfo_t *pContainer = poffCreateDebugInfoContainer(nparms);
+
+ /* Put the proc information into the container */
+
+ pContainer->value = pProc->sParm.p.label;
+ pContainer->retsize = dwReturnSize;
+ pContainer->nparms = nparms;
+
+ /* Add the argument information to the container */
+
+ for (i = 0; i < nparms; i++)
+ {
+ pContainer->argsize[i] = actualParameterSize(pProc, i+1);
+ }
+
+ /* Add the contained information to the library */
+
+ poffAddDebugFuncInfo(poffHandle, pContainer);
+
+ /* Release the container */
+
+ poffReleaseDebugFuncContainer(pContainer);
+}
+
+/***********************************************************************/
+/* Generate description of a level 0 stack variable that can be
+ * exported by a unit.
+ */
+
+void pas_GenerateStackExport(STYPE *pVar)
+{
+ poffLibSymbol_t symbol;
+
+#if CONFIG_DEBUG
+ /* Get the parent type of the variable */
+
+ STYPE *typePtr = pVar->sParm.v.parent;
+
+ /* Perform some sanity checking:
+ * - Must have a parent type
+ * - Must not be declared external
+ * - Must be declared at static nesting level zero
+ */
+
+ if ((!typePtr) ||
+ ((pVar->sParm.v.flags & SVAR_EXTERNAL) != 0) ||
+ (pVar->sLevel != 0))
+ {
+ error(eSYMTABINTERNAL);
+ }
+#endif
+
+ /* Create the symbol structure */
+
+ symbol.type = STT_DATA;
+ symbol.align = STA_8BIT; /* for now */
+ symbol.flags = STF_NONE;
+ symbol.name = pVar->sName;
+ symbol.value = pVar->sParm.v.offset;
+ symbol.size = pVar->sParm.v.size;
+
+ /* Add the symbol to the symbol table */
+
+ (void)poffAddSymbol(poffHandle, &symbol);
+}
+
+/***********************************************************************/
+/* Generate description of a level 0 stack variable that must be
+ * imported by a program or unit from a unit.
+ */
+
+void pas_GenerateStackImport(STYPE *pVar)
+{
+ poffLibSymbol_t symbol;
+
+#if CONFIG_DEBUG
+ /* Get the parent type of the variable */
+
+ STYPE *typePtr = pVar->sParm.v.parent;
+
+ /* Perform some sanity checking
+ * - Must have a parent type
+ * - Must be declared external
+ * - Must be declared at static nesting level zero
+ */
+
+ if ((!typePtr) ||
+ ((pVar->sParm.v.flags & SVAR_EXTERNAL) == 0) ||
+ (pVar->sLevel != 0))
+ {
+ error(eSYMTABINTERNAL);
+ }
+#endif
+
+ /* Create the symbol structure */
+
+ symbol.type = STT_DATA;
+ symbol.align = STA_8BIT; /* for now */
+ symbol.flags = STF_UNDEFINED;
+ symbol.name = pVar->sName;
+ symbol.value = pVar->sParm.v.offset; /* for now */
+ symbol.size = pVar->sParm.v.size;
+
+ /* Add the symbol to the symbol table */
+
+ pVar->sParm.v.symIndex = poffAddSymbol(poffHandle, &symbol);
+}
+
+/***********************************************************************/
+/* Generate description of a level 0 procedure or function that can be
+ * exported by a unit.
+ */
+
+void pas_GenerateProcExport(STYPE *pProc)
+{
+ poffLibSymbol_t symbol;
+
+#if CONFIG_DEBUG
+ /* Get the parent type of the function (assuming it is a function) */
+
+ STYPE *typePtr = pProc->sParm.p.parent;
+
+ /* Perform some sanity checking */
+
+ /* Check for a function reference which must have a valid parent type */
+
+ if ((pProc->sKind == sFUNC) && (typePtr != NULL));
+
+ /* Check for a procedure reference which must not have a valid type */
+
+ else if ((pProc->sKind == sPROC) && (typePtr == NULL));
+
+ /* Anything else is an error */
+
+ else
+ error(eSYMTABINTERNAL);
+
+ /* The function / procedure should NOT be declared external and
+ * only procedures declared at static nesting level zero can
+ * be exported.
+ */
+
+ if (((pProc->sParm.p.flags & SPROC_EXTERNAL) != 0) ||
+ (pProc->sLevel != 0))
+ error(eSYMTABINTERNAL);
+#endif
+
+ /* Everthing looks okay. Create the symbol structure */
+
+ if (pProc->sKind == sPROC)
+ symbol.type = STT_PROC;
+ else
+ symbol.type = STT_FUNC;
+
+ symbol.align = STA_NONE;
+ symbol.flags = STF_NONE;
+ symbol.name = pProc->sName;
+ symbol.value = pProc->sParm.p.label;
+ symbol.size = 0;
+
+ /* Add the symbol to the symbol table */
+
+ (void)poffAddSymbol(poffHandle, &symbol);
+}
+
+/***********************************************************************/
+/* Generate description of a level 0 procedure or function that must be
+ * imported by a program or unit from a unit.
+ */
+
+void pas_GenerateProcImport(STYPE *pProc)
+{
+ poffLibSymbol_t symbol;
+
+#if CONFIG_DEBUG
+ /* Get the parent type of the function (assuming it is a function) */
+
+ STYPE *typePtr = pProc->sParm.p.parent;
+
+ /* Perform some sanity checking */
+
+ /* Check for a function reference which must have a valid parent type */
+
+ if ((pProc->sKind == sFUNC) && (typePtr != NULL));
+
+ /* Check for a procedure reference which must not have a valid type */
+
+ else if ((pProc->sKind == sPROC) && (typePtr == NULL));
+
+ /* Anything else is an error */
+
+ else
+ error(eSYMTABINTERNAL);
+
+ /* The function / procedure should also be declared external and
+ * only procedures declared at static nesting level zero can
+ * be exported.
+ */
+
+ if (((pProc->sParm.p.flags & SPROC_EXTERNAL) == 0) ||
+ (pProc->sLevel != 0))
+ error(eSYMTABINTERNAL);
+#endif
+
+ /* Everthing looks okay. Create the symbol structure */
+
+ if (pProc->sKind == sPROC)
+ symbol.type = STT_PROC;
+ else
+ symbol.type = STT_FUNC;
+
+ symbol.align = STA_NONE;
+ symbol.flags = STF_UNDEFINED;
+ symbol.name = pProc->sName;
+ symbol.value = pProc->sParm.p.label;
+ symbol.size = 0;
+
+ /* Add the symbol to the symbol table */
+
+ pProc->sParm.p.symIndex = poffAddSymbol(poffHandle, &symbol);
+}
diff --git a/misc/pascal/pascal/pgen.h b/misc/pascal/pascal/pgen.h
new file mode 100644
index 000000000..aac6f8e58
--- /dev/null
+++ b/misc/pascal/pascal/pgen.h
@@ -0,0 +1,89 @@
+/***************************************************************************
+ * pgen.h
+ * External Declarations associated with pgen.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PGEN_H
+#define __PGEN_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+#include "podefs.h"
+
+/***************************************************************************
+ * Pre-processor Definitions
+ ***************************************************************************/
+
+/***************************************************************************
+ * Global Types
+ ***************************************************************************/
+
+/***************************************************************************
+ * Global Variable Prototypes
+ ***************************************************************************/
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern int32_t pas_GetCurrentStackLevel(void);
+extern void pas_InvalidateCurrentStackLevel(void);
+extern void pas_SetCurrentStackLevel(int32_t dwLsp);
+extern uint32_t pas_GetNStackLevelChanges(void);
+
+extern void pas_GenerateSimple(enum pcode_e eOpCode);
+extern void pas_GenerateDataOperation(enum pcode_e eOpCode, int32_t dwData);
+extern void pas_GenerateDataSize(int32_t dwDataSize);
+extern void pas_GenerateFpOperation(uint8_t fpOpcode);
+extern void pas_GenerateIoOperation(uint16_t ioOpcode, uint16_t fileNumber);
+extern void pas_BuiltInFunctionCall(uint16_t libOpcode);
+extern void pas_GenerateLevelReference(enum pcode_e eOpCode, uint16_t wLevel,
+ int32_t dwOffset);
+extern void pas_GenerateStackReference(enum pcode_e eOpCode, STYPE *pVarPtr);
+extern void pas_GenerateProcedureCall(STYPE *pProcPtr);
+extern void pas_GenerateLineNumber(uint16_t wIncludeNumber,
+ uint32_t dwLineNumber);
+extern void pas_GenerateStackExport(STYPE *pVarPtr);
+extern void pas_GenerateStackImport(STYPE *pVarPtr);
+extern void pas_GenerateProcedureCall(STYPE *pProcPtr);
+extern void pas_GenerateDebugInfo(STYPE *pProcPtr, uint32_t dwReturnSize);
+extern void pas_GenerateProcExport(STYPE *pProcPtr);
+extern void pas_GenerateProcImport(STYPE *pProcPtr);
+extern void pas_GeneratePoffOutput(void);
+
+#endif /* __PGEN_H */
+
diff --git a/misc/pascal/pascal/pprgm.c b/misc/pascal/pascal/pprgm.c
new file mode 100644
index 000000000..f1aa5528b
--- /dev/null
+++ b/misc/pascal/pascal/pprgm.c
@@ -0,0 +1,265 @@
+/**********************************************************************
+ * pas.c
+ * main - process PROGRAM
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h"
+#include "pasdefs.h"
+#include "ptdefs.h"
+#include "podefs.h"
+#include "pedefs.h"
+#include "poff.h" /* FHT_ definitions */
+
+#include "pas.h" /* for globals + openNestedFile */
+#include "pblck.h" /* for block() */
+#include "pgen.h" /* for pas_Generate*() */
+#include "ptkn.h" /* for getToken() */
+#include "ptbl.h" /* for addFile() */
+#include "pofflib.h" /* For poff*() functions*/
+#include "paslib.h" /* for extension() */
+#include "perr.h" /* for error() */
+#include "punit.h" /* for unit() */
+#include "pprgm.h"
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+void program(void)
+{
+ char *pgmname = NULL;
+
+ TRACE(lstFile, "[program]");
+
+ /* FORM: program = program-heading ';' [uses-section ] block '.'
+ * FORM: program-heading = 'program' identifier [ '(' identifier-list ')' ]
+ *
+ * On entry, 'program' has already been identified and token refers to
+ * the next token after 'program'
+ */
+
+ if (token != tIDENT) error(eIDENT); /* Verify <program name> */
+ else
+ {
+ pgmname = tkn_strt; /* Save program name */
+ getToken();
+ } /* end else */
+
+ /* Process optional file list (allow re-declaration of INPUT & OUTPUT) */
+
+ if (token == '(')
+ {
+ do
+ {
+ getToken();
+ if (token == tIDENT)
+ {
+ if ((++nfiles) > MAX_FILES) fatal(eOVF);
+ (void)addFile(tkn_strt, nfiles);
+ stringSP = tkn_strt;
+ getToken();
+ } /* end if */
+ else if ((token == sFILE) && !(tknPtr->sParm.fileNumber))
+ getToken();
+ else
+ error(eIDENT);
+ }
+ while (token == ',');
+ if (token != ')') error(eRPAREN);
+ else getToken();
+ } /* End if */
+
+ /* Make sure that a semicolon follows the program-heading */
+
+ if (token != ';') error(eSEMICOLON);
+ else getToken();
+
+ /* Set the POFF file header type */
+
+ poffSetFileType(poffHandle, FHT_PROGRAM, nfiles, pgmname);
+ poffSetArchitecture(poffHandle, FHA_PCODE);
+
+ /* Discard the program name string */
+
+ stringSP = pgmname;
+
+ /* Process the optional 'uses-section'
+ * FORM: uses-section = 'uses' [ uses-unit-list ] ';'
+ */
+
+ if (token == tUSES)
+ {
+ getToken();
+ usesSection();
+ }
+
+ /* Process the block */
+
+ block();
+ if (token != '.') error(ePERIOD);
+ pas_GenerateSimple(opEND);
+} /* end program */
+
+/***********************************************************************/
+
+void usesSection(void)
+{
+ uint16_t saveToken;
+ char defaultUnitFileName[FNAME_SIZE + 1];
+ char *unitFileName = NULL;
+ char *saveTknStrt;
+ char *unitName;
+
+ TRACE(lstFile, "[usesSection]");
+
+ /* FORM: uses-section = 'uses' [ uses-unit-list ] ';'
+ * FORM: uses-unit-list = unit-import {';' uses-unit-list }
+ * FORM: unit-import = identifier ['in' non-empty-string ]
+ *
+ * On entry, token will point to the token just after
+ * the 'uses' reservers word.
+ */
+
+ while (token == tIDENT)
+ {
+ /* Save the unit name identifier and skip over the identifier */
+
+ unitName = tkn_strt;
+ getToken();
+
+ /* Check for the optional 'in' */
+
+ saveTknStrt = tkn_strt;
+ if (token == tIN)
+ {
+ /* Skip over 'in' and verify that a string constant representing
+ * the file name follows.
+ */
+
+ getToken();
+ if (token != tSTRING_CONST) error(eSTRING);
+ else
+ {
+ /* Save the unit file name and skip to the
+ * next token.
+ */
+
+ unitFileName = tkn_strt;
+ saveTknStrt = tkn_strt;
+ getToken();
+ }
+ }
+
+ /* In any event, make sure that we have a non-NULL unit
+ * file name.
+ */
+
+ if (!unitFileName)
+ {
+ /* Create a default filename */
+
+ (void)extension(unitName, ".pas", defaultUnitFileName, 1);
+ unitFileName = defaultUnitFileName;
+ }
+
+ /* Open the unit file */
+
+ saveToken = token;
+ openNestedFile(unitFileName);
+ FP->kind = eIsUnit;
+ FP->section = eIsOtherSection;
+
+ /* Verify that this is a unit file */
+
+ if (token != tUNIT) error(eUNIT);
+ else getToken();
+
+ /* Release the file name from the string stack */
+
+ stringSP = saveTknStrt;
+
+ /* Verify that the file provides the unit that we are looking
+ * for (only one unit per file is supported)
+ */
+
+ if (token != tIDENT) error(eIDENT);
+ else if (strcmp(unitName, tkn_strt) != 0) error(eUNITNAME);
+
+ /* Parse the interface from the unit file (token must refer
+ * to the unit name on entry into unit().
+ */
+
+ unitInterface();
+ closeNestedFile();
+
+ /* Verify the terminating semicolon */
+
+ token = saveToken;
+ if (token != ';') error(eSEMICOLON);
+ else getToken();
+ }
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/pascal/pprgm.h b/misc/pascal/pascal/pprgm.h
new file mode 100644
index 000000000..226a879fd
--- /dev/null
+++ b/misc/pascal/pascal/pprgm.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * pprgm.h
+ * External Declarations associated with pprgm.c
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PPRGM_H
+#define __PPRGM_H
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void program(void);
+extern void usesSection(void);
+
+#endif /* __PPRGM_H */
diff --git a/misc/pascal/pascal/pproc.c b/misc/pascal/pascal/pproc.c
new file mode 100644
index 000000000..df02e11a1
--- /dev/null
+++ b/misc/pascal/pascal/pproc.c
@@ -0,0 +1,736 @@
+/****************************************************************************
+ * pproc.c
+ * Standard procedures (all called in pstm.c)
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "keywords.h"
+#include "pasdefs.h"
+#include "ptdefs.h"
+#include "podefs.h"
+#include "pedefs.h"
+#include "pxdefs.h"
+
+#include "pas.h"
+#include "pexpr.h"
+#include "pproc.h"
+#include "pgen.h" /* for pas_Generate*() */
+#include "ptkn.h"
+#include "ptbl.h" /* For parent symbol references */
+#include "perr.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helpers for standard procedures */
+
+static int16_t readProc (void); /* READ procedure */
+static void readText (uint16_t fileNumber); /* READ text file */
+static void readlnProc (void); /* READLN procedure */
+static void fileProc (uint16_t opcode); /* RESET/REWRITE/PAGE procedure */
+static int16_t writeProc (void); /* WRITE procedure */
+static void writeText (uint16_t fileNumber); /* WRITE text file */
+static void writelnProc (void); /* WRITELN procedure */
+
+/* Helpers for less-than-standard procedures */
+
+static void valProc (void); /* VAL procedure */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* procedure val(const S : string; var V; var Code : word); */
+
+static STYPE valSymbol[4];
+
+/****************************************************************************/
+
+void primeBuiltInProcedures(void)
+{
+ /* procedure val(const S : string; var V; var Code : word); */
+
+ valSymbol[0].sParm.p.nParms = 3;
+ valSymbol[1].sKind = sSTRING;
+ valSymbol[1].sParm.p.parent = parentString;
+ valSymbol[2].sKind = sVAR_PARM;
+ valSymbol[2].sParm.p.parent = parentInteger;
+ valSymbol[3].sKind = sVAR_PARM;
+ valSymbol[3].sParm.p.parent = parentInteger;
+}
+
+/***********************************************************************/
+
+void builtInProcedure(void)
+{
+ TRACE(lstFile, "[builtInProcedure]");
+
+ /* Is the token a procedure? */
+
+
+ if (token == tPROC)
+ {
+ /* Yes, process it procedure according to the extended token type */
+
+ switch (tknSubType)
+ {
+ /* Standard Procedures & Functions */
+
+ case txPAGE :
+ fileProc(xWRITE_PAGE);
+ break;
+
+ case txREAD :
+ getToken();
+ (void)readProc();
+ break;
+
+ case txREADLN :
+ readlnProc();
+ break;
+
+ case txRESET :
+ fileProc(xRESET);
+ break;
+
+ case txREWRITE :
+ fileProc(xREWRITE);
+ break;
+
+ case txWRITE :
+ getToken();
+ (void)writeProc();
+ break;
+
+ case txWRITELN :
+ writelnProc();
+ break;
+
+ case txGET :
+ case txNEW :
+ case txPACK :
+ case txPUT :
+ case txUNPACK :
+ error(eNOTYET);
+ getToken();
+ break;
+
+ /* less-than-standard procedures */
+ case txVAL :
+ valProc();
+ break;
+
+ /* Its not a recognized procedure */
+
+ default :
+ error(eINVALIDPROC);
+ break;
+
+ } /* end switch */
+ } /* end if */
+} /* end builtInProcedure */
+
+/***********************************************************************/
+
+int actualParameterSize(STYPE *procPtr, int parmNo)
+{
+ /* These sizes must agree with the sizes used in actualParameterListg()
+ * below.
+ */
+
+ STYPE *typePtr = procPtr[parmNo].sParm.v.parent;
+ switch (typePtr->sKind)
+ {
+ case sINT :
+ case sSUBRANGE :
+ case sSCALAR :
+ case sSET_OF :
+ default:
+ return sINT_SIZE;
+ break;
+ case sCHAR :
+ return sCHAR_SIZE;
+ break;
+ case sREAL :
+ return sREAL_SIZE;
+ break;
+ case sSTRING :
+ case sRSTRING :
+ return sRSTRING_SIZE;
+ break;
+ case sARRAY :
+ case sRECORD :
+ return typePtr->sParm.t.asize;
+ break;
+ case sVAR_PARM :
+ return sPTR_SIZE;
+ break;
+ }
+}
+
+/***********************************************************************/
+
+int actualParameterList(STYPE *procPtr)
+{
+ STYPE *typePtr;
+ register int nParms = 0;
+ int size = 0;
+
+ TRACE(lstFile,"[actualParameterList]");
+
+ /* Processes the (optional) actual-parameter-list associated with
+ * a function or procedure call:
+ *
+ * FORM: procedure-method-statement =
+ * procedure-method-specifier [ actual-parameter-list ]
+ * FORM: function-designator = function-identifier [ actual-parameter-list ]
+ *
+ *
+ * On entry, 'token' refers to the token just AFTER the procedure
+ * function identifier.
+ *
+ * FORM: actual-parameter-list =
+ * '(' actual-parameter { ',' actual-parameter } ')'
+ * FORM: actual-parameter =
+ * expression | variable-access |
+ * procedure-identifier | function-identifier
+ */
+
+ /* If this procedure requires parameters, get them and make sure that
+ * they match in type and number
+ */
+
+ if (procPtr->sParm.p.nParms)
+ {
+ /* If it requires parameters, then the actual-parameter-list must
+ * be present and must begin with '('
+ */
+
+ if (token != '(') error (eLPAREN);
+ else getToken();
+
+ /* Loop to process the expected number of parameters. The formal
+ * argument descriptions follow the procedure/function description
+ * as an array of variable declarations. (These sizes below must
+ * agree with actualParameterSize() above);
+ */
+
+ for (nParms = 1; nParms <= procPtr->sParm.p.nParms; nParms++)
+ {
+ typePtr = procPtr[nParms].sParm.v.parent;
+ switch (procPtr[nParms].sKind)
+ {
+ case sINT :
+ expression(exprInteger, typePtr);
+ size += sINT_SIZE;
+ break;
+ case sCHAR :
+ expression(exprChar, typePtr);
+ size += sCHAR_SIZE;
+ break;
+ case sREAL :
+ expression(exprReal, typePtr);
+ size += sREAL_SIZE;
+ break;
+ case sSTRING :
+ case sRSTRING :
+ expression(exprString, typePtr);
+ size += sRSTRING_SIZE;
+ break;
+ case sSUBRANGE :
+ expression(exprInteger, typePtr);
+ size += sINT_SIZE;
+ break;
+ case sSCALAR :
+ expression(exprScalar, typePtr);
+ size += sINT_SIZE;
+ break;
+ case sSET_OF :
+ expression(exprSet, typePtr);
+ size += sINT_SIZE;
+ break;
+ case sARRAY :
+ expression(exprArray, typePtr);
+ size += typePtr->sParm.t.asize;
+ break;
+ case sRECORD :
+ expression(exprRecord, typePtr);
+ size += typePtr->sParm.t.asize;
+ break;
+ case sVAR_PARM :
+ if (typePtr)
+ {
+ switch (typePtr->sParm.t.type)
+ {
+ case sINT :
+ varParm(exprIntegerPtr, typePtr);
+ size += sPTR_SIZE;
+ break;
+ case sBOOLEAN :
+ varParm(exprBooleanPtr, typePtr);
+ size += sPTR_SIZE;
+ break;
+ case sCHAR :
+ varParm(exprCharPtr, typePtr);
+ size += sPTR_SIZE;
+ break;
+ case sREAL :
+ varParm(exprRealPtr, typePtr);
+ size += sPTR_SIZE;
+ break;
+ case sARRAY :
+ varParm(exprArrayPtr, typePtr);
+ size += sPTR_SIZE;
+ break;
+ case sRECORD :
+ varParm(exprRecordPtr, typePtr);
+ size += sPTR_SIZE;
+ break;
+ default :
+ error(eVARPARMTYPE);
+ break;
+ } /* end switch */
+ } /* end if */
+ else
+ error(eVARPARMTYPE);
+ break;
+ default :
+ error (eNPARMS);
+ } /* end switch */
+
+ if (nParms < procPtr->sParm.p.nParms)
+ {
+ if (token != ',') error (eCOMMA);
+ else getToken();
+ } /* end if */
+ } /* end for */
+
+ if (token != ')') error (eRPAREN);
+ else getToken();
+
+ } /* end if */
+
+ return size;
+
+} /* end actualParameterList */
+
+/***********************************************************************/
+
+static int16_t readProc(void)
+{
+ uint16_t fileNumber = 0;
+
+ TRACE(lstFile, "[readProc]");
+
+ /* FORM:
+ * (1) Binary READ: read '(' file-variable ')'
+ * (2) Test READ: read read-parameter-list
+ * FORM: read-parameter-list =
+ * '(' [ file-variable ',' ] variable-access { ',' variable-access } ')'
+ */
+
+ if (token != '(') error (eLPAREN); /* Skip over '(' */
+ else getToken();
+
+ /* Get file number */
+
+ if (token == sFILE)
+ {
+ fileNumber = tknPtr->sParm.fileNumber;
+ getToken();
+ } /* end if */
+ if (token == ',') getToken();
+
+ /* Determine if this is a text or binary file */
+
+ if (!(files [fileNumber].defined)) error (eUNDEFILE);
+ else if (files [fileNumber].ftype == sCHAR)
+ {
+ readText (fileNumber);
+ }
+ else
+ {
+ pas_GenerateLevelReference(opLAS, files[fileNumber].flevel, files [fileNumber].faddr);
+ pas_GenerateDataOperation(opPUSH, files[fileNumber].fsize);
+ pas_GenerateIoOperation(xREAD_BINARY, fileNumber);
+ } /* end else */
+
+ if (token != ')') error (eRPAREN);
+ else getToken();
+
+ return (fileNumber);
+} /* end readProc */
+
+/***********************************************************************/
+
+static void readText (uint16_t fileNumber)
+{
+ STYPE *rPtr;
+
+ TRACE(lstFile, "[readText]");
+
+ /* The general form is <VAR parm>, <VAR parm>,... */
+
+ for (;;)
+ {
+ switch (token)
+ {
+ /* SPECIAL CASE: Array of type CHAR without indexing */
+
+ case sARRAY :
+ rPtr = tknPtr->sParm.v.parent;
+ if (((rPtr) && (rPtr->sKind == sTYPE)) &&
+ (rPtr->sParm.t.type == sCHAR) &&
+ (getNextCharacter(true) != '['))
+ {
+ pas_GenerateStackReference(opLAS, rPtr);
+ pas_GenerateDataOperation(opPUSH, rPtr->sParm.v.size);
+ pas_GenerateIoOperation(xREAD_STRING, fileNumber);
+ pas_GenerateDataOperation(opINDS, -(sPTR_SIZE+sINT_SIZE));
+ } /* end if */
+
+ /* Otherwise, we fall through to process the ARRAY like any */
+ /* expression */
+
+ default :
+
+ switch (varParm(exprUnknown, NULL))
+ {
+ case exprIntegerPtr :
+ pas_GenerateIoOperation(xREAD_INT, fileNumber);
+ pas_GenerateDataOperation(opINDS, -sPTR_SIZE);
+ break;
+
+ case exprCharPtr :
+ pas_GenerateIoOperation(xREAD_CHAR, fileNumber);
+ pas_GenerateDataOperation(opINDS, -sPTR_SIZE);
+ break;
+
+ case exprRealPtr :
+ pas_GenerateIoOperation(xREAD_REAL, fileNumber);
+ pas_GenerateDataOperation(opINDS, -sPTR_SIZE);
+ break;
+
+ default :
+ error(eINVARG);
+ break;
+ } /* end switch */
+ break;
+
+ } /* end switch */
+
+ if (token == ',') getToken();
+ else return;
+
+ } /* end for */
+
+} /* end readText */
+
+/****************************************************************************/
+
+static void readlnProc(void) /* READLN procedure */
+{
+ int32_t fileNumber;
+
+ TRACE(lstFile, "[readlnProc]");
+
+ /* FORM: Just like READ */
+
+ getToken();
+ if (token == '(')
+ fileNumber = readProc();
+
+ /* skip to end-of-line mark in the file (NOTE: No check is made,
+ * but this is meaningful only for a test file).
+ */
+
+ pas_GenerateIoOperation(xREADLN, fileNumber);
+
+} /* end readlnProc */
+
+/****************************************************************************/
+/* REWRITE/RESET/PAGE procedure call -- REWRITE sets the file pointer to the
+ * beginning of the file and prepares the file for write access; RESET is
+ * similar except that it prepares the file for read access; PAGE simply
+ * writes a form-feed to the file (no check is made, but is meaningful only
+ * for a text file). */
+
+static void fileProc (uint16_t opcode)
+{
+ TRACE(lstFile, "[fileProc]");
+
+ /* FORM: RESET|REWRITE(<file number>) */
+
+ getToken();
+ if (token != '(') error(eLPAREN);
+ else getToken();
+ if (token != sFILE) error(eFILE);
+ else {
+ pas_GenerateIoOperation(opcode, tknPtr->sParm.fileNumber);
+ getToken();
+ if (token != ')') error(eRPAREN);
+ else getToken();
+ } /* end else */
+
+} /* End fileProc */
+
+/***********************************************************************/
+
+static int16_t writeProc(void)
+{
+ uint16_t fileNumber = 0;
+
+ TRACE(lstFile, "[writeProc]");
+
+ /* FORM: (1) Binary WRITE: WRITE(<fileNumber>);
+ * (2) Test WRITE: WRITE([<fileNumber>], arg1 [,arg2 [...]]) */
+
+ if (token != '(') error(eLPAREN); /* Skip over '(' */
+ else getToken();
+
+ /* Get file number */
+
+ if (token == sFILE) {
+ fileNumber = tknPtr->sParm.fileNumber;
+ getToken();
+ } /* end if */
+ if (token == ',') getToken();
+
+ /* Determine if this is a text or binary file */
+
+ if (!(files [fileNumber].defined)) error(eUNDEFILE);
+ else if (files [fileNumber].ftype == sCHAR)
+ writeText(fileNumber);
+ else {
+ pas_GenerateLevelReference(opLAS, files[fileNumber].flevel, files [fileNumber].faddr);
+ pas_GenerateDataOperation(opPUSH, files[fileNumber].fsize);
+ pas_GenerateIoOperation(xWRITE_BINARY, fileNumber);
+ } /* end else */
+
+ if (token != ')') error(eRPAREN);
+ else getToken();
+ return(fileNumber);
+} /* end writeProc */
+
+/***********************************************************************/
+
+static void writeText (uint16_t fileNumber)
+{
+ exprType writeType;
+ STYPE *wPtr;
+
+ TRACE(lstFile, "[writeText]");
+
+ for (;;)
+ {
+ /* The general form is <expression>, <expression>, ... However,
+ * there are a few unique things that must be handled as special
+ * cases
+ */
+
+ switch (token)
+ {
+ /* const strings -- either literal constants (tSTRING_CONST)
+ * or defined string constant symbols (sSTRING_CONST)
+ */
+
+ case tSTRING_CONST :
+ {
+ /* Add the literal string constant to the RO data section
+ * and receive the offset to the data.
+ */
+
+ uint32_t offset = poffAddRoDataString(poffHandle, tkn_strt);
+
+ /* Set the offset and size on the stack (order is important) */
+
+ pas_GenerateDataOperation(opLAC, (uint16_t)offset);
+ pas_GenerateDataOperation(opPUSH, strlen(tkn_strt));
+
+ pas_GenerateIoOperation(xWRITE_STRING, fileNumber);
+ pas_GenerateDataOperation(opINDS, -(sPTR_SIZE + sINT_SIZE));
+ stringSP = tkn_strt;
+ getToken();
+ }
+ break;
+
+ case sSTRING_CONST :
+ pas_GenerateDataOperation(opLAC, (uint16_t)tknPtr->sParm.s.offset);
+ pas_GenerateDataOperation(opPUSH, (uint16_t)tknPtr->sParm.s.size);
+ pas_GenerateIoOperation(xWRITE_STRING, fileNumber);
+ pas_GenerateDataOperation(opINDS, -(sPTR_SIZE + sINT_SIZE));
+ getToken();
+ break;
+
+ /* Array of type CHAR without indexing */
+
+ case sARRAY :
+ wPtr = tknPtr->sParm.v.parent;
+ if (((wPtr) && (wPtr->sKind == sTYPE)) &&
+ (wPtr->sParm.t.type == sCHAR) &&
+ (getNextCharacter(true) != '['))
+ {
+ pas_GenerateStackReference(opLAS, wPtr);
+ pas_GenerateDataOperation(opPUSH, wPtr->sParm.v.size);
+ pas_GenerateIoOperation(xWRITE_STRING, fileNumber);
+ pas_GenerateDataOperation(opINDS, -(sPTR_SIZE + sINT_SIZE));
+ break;
+ } /* end if */
+
+ /* Otherwise, we fall through to process the ARRAY like any */
+ /* expression */
+
+ default :
+ writeType = expression(exprUnknown, NULL);
+ switch (writeType)
+ {
+ case exprInteger :
+ pas_GenerateIoOperation(xWRITE_INT, fileNumber);
+ pas_GenerateDataOperation(opINDS, -sINT_SIZE);
+ break;
+
+ case exprBoolean :
+ error(eNOTYET);
+ break;
+
+ case exprChar :
+ pas_GenerateIoOperation(xWRITE_CHAR, fileNumber);
+ pas_GenerateDataOperation(opINDS, -sINT_SIZE);
+ break;
+
+ case exprReal :
+ pas_GenerateIoOperation(xWRITE_REAL, fileNumber);
+ pas_GenerateDataOperation(opINDS, -sREAL_SIZE);
+ break;
+
+ case exprString :
+ case exprStkString :
+ pas_GenerateIoOperation(xWRITE_STRING, fileNumber);
+ pas_GenerateDataOperation(opINDS, -sRSTRING_SIZE);
+ break;
+
+ default :
+ error(eWRITEPARM);
+ break;
+
+ } /* end switch */
+ break;
+
+ } /* end switch */
+
+ if (token == ',') getToken();
+ else return;
+
+ } /* end for */
+
+} /* end writeText */
+
+/****************************************************************************/
+
+static void writelnProc(void) /* WRITELN procedure */
+{
+ int32_t fileNumber = 0;
+
+ TRACE(lstFile, "[writelnProc]");
+
+ /* FORM: Just like WRITE */
+
+ getToken();
+ if (token == '(')
+ {
+ fileNumber = writeProc();
+ }
+
+ /* Skip to past end-of-line mark in the file (NOTE: No check is made, but
+ * this is meaningful only for a test file).
+ */
+
+ pas_GenerateIoOperation(xWRITELN, fileNumber);
+
+} /* end writelnProc */
+
+/****************************************************************************/
+
+static void valProc(void) /* VAL procedure */
+{
+ int size;
+
+ TRACE(lstFile, "[valProc]");
+
+ /* Declaration:
+ * procedure val(const S : string; var V; var Code : word);
+ *
+ * Description:
+ * val() converts the value represented in the string S to a numerical
+ * value, and stores this value in the variable V, which can be of type
+ * Longint, Real and Byte. If the conversion isn��t succesfull, then the
+ * parameter Code contains the index of the character in S which
+ * prevented the conversion. The string S is allowed to contain spaces
+ * in the beginning.
+ *
+ * The string S can contain a number in decimal, hexadecimal, binary or
+ * octal format, as described in the language reference.
+ *
+ * Errors:
+ * If the conversion doesn��t succeed, the value of Code indicates the
+ * position where the conversion went wrong.
+ */
+
+ /* Skip over the 'val' identifer */
+
+ getToken();
+
+ /* Setup the actual-parameter-list */
+
+ size = actualParameterList(valSymbol);
+
+ /* Generate the built-in procedure call. NOTE the procedure call
+ * logic will release the parameters from the stack saving us from
+ * having to generate the INDS here.
+ */
+
+ pas_BuiltInFunctionCall(lbVAL);
+
+} /* end writelnProc */
+
+/***********************************************************************/
diff --git a/misc/pascal/pascal/pproc.h b/misc/pascal/pascal/pproc.h
new file mode 100644
index 000000000..946611e86
--- /dev/null
+++ b/misc/pascal/pascal/pproc.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * pproc.h
+ * External Declarations associated with PPROC.C
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PPROC_H
+#define __PPROC_H
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void primeBuiltInProcedures(void);
+extern void builtInProcedure(void);
+extern int actualParameterSize(STYPE *procPtr, int parmNo);
+extern int actualParameterList(STYPE *procPtr);
+
+#endif /* __PPROC_H */
diff --git a/misc/pascal/pascal/pstm.c b/misc/pascal/pascal/pstm.c
new file mode 100644
index 000000000..ee3730800
--- /dev/null
+++ b/misc/pascal/pascal/pstm.c
@@ -0,0 +1,1683 @@
+/****************************************************************************
+ * pstm.c
+ * Pascal Statements
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include "keywords.h"
+#include "pasdefs.h"
+#include "ptdefs.h"
+#include "podefs.h"
+#include "pedefs.h"
+#include "pxdefs.h"
+
+#include "pas.h"
+#include "pstm.h"
+#include "pproc.h"
+#include "pexpr.h"
+#include "pgen.h"
+#include "ptkn.h"
+#include "ptbl.h"
+#include "pinsn.h"
+#include "perr.h"
+
+/****************************************************************************
+ * Private Definitions
+ ****************************************************************************/
+
+#define ADDRESS_DEREFERENCE 0x01
+#define ADDRESS_ASSIGNMENT 0x02
+#define INDEXED_ASSIGNMENT 0x04
+#define VAR_PARM_ASSIGNMENT 0x08
+
+#define isConstant(x) \
+ ( ((x) == tINT_CONST) \
+ || ((x) == tBOOLEAN_CONST) \
+ || ((x) == tCHAR_CONST) \
+ || ((x) == tREAL_CONST) \
+ || ((x) == sSCALAR_OBJECT))
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Assignment Statements */
+
+static void pas_ComplexAssignment(void);
+static void pas_SimpleAssignment (STYPE *varPtr, uint8_t assignFlags);
+static void pas_Assignment (uint16_t storeOp, exprType assignType, STYPE *varPtr, STYPE *typePtr);
+static void pas_StringAssignment (STYPE *varPtr, STYPE *typePtr);
+static void pas_LargeAssignment (uint16_t storeOp, exprType assignType, STYPE *varPtr, STYPE *typePtr);
+
+/* Other Statements */
+
+static void pas_GotoStatement (void); /* GOTO statement */
+static void pas_LabelStatement (void); /* Label statement */
+static void pas_ProcStatement (void); /* Procedure method statement */
+static void pas_IfStatement (void); /* IF-THEN[-ELSE] statement */
+static void pas_CaseStatement (void); /* Case statement */
+static void pas_RepeatStatement (void); /* Repeat statement */
+static void pas_WhileStatement (void); /* While statement */
+static void pas_ForStatement (void); /* For statement */
+static void pas_WithStatement (void); /* With statement */
+
+/****************************************************************************/
+
+void statement(void)
+{
+ STYPE *symPtr; /* Save Symbol Table pointer to token */
+
+ TRACE(lstFile,"[statement");
+
+ /* Generate file/line number pseudo-operation to facilitate P-Code testing */
+
+ pas_GenerateLineNumber(FP->include, FP->line);
+
+ /* We will push the string stack pointer at the beginning of each
+ * statement and pop the string stack pointer at the end of each
+ * statement. Subsequent optimization logic will scan the generated
+ * pcode to ascertain if the push and pops were necessary. They
+ * would be necessary if expression parsing generated temporary usage
+ * of string stack storage. In this case, the push will save the
+ * value before the temporary usage and the pop will release the
+ * temporaray storage.
+ */
+
+ pas_GenerateSimple(opPUSHS);
+
+ /* Process the statement according to the type of the leading token */
+
+ switch (token)
+ {
+ /* Simple assignment statements */
+
+ case sINT :
+ symPtr = tknPtr;
+ getToken();
+ pas_Assignment(opSTS, exprInteger, symPtr, symPtr->sParm.v.parent);
+ break;
+ case sCHAR :
+ symPtr = tknPtr;
+ getToken();
+ pas_Assignment(opSTSB, exprChar, symPtr, symPtr->sParm.v.parent);
+ break;
+ case sBOOLEAN :
+ symPtr = tknPtr;
+ getToken();
+ pas_Assignment(opSTSB, exprBoolean, symPtr, NULL);
+ break;
+ case sREAL :
+ symPtr = tknPtr;
+ getToken();
+ pas_LargeAssignment(opSTSM, exprReal, symPtr, symPtr->sParm.v.parent);
+ break;
+ case sSCALAR :
+ symPtr = tknPtr;
+ getToken();
+ pas_Assignment(opSTS, exprScalar, symPtr, symPtr->sParm.v.parent);
+ break;
+ case sSET_OF :
+ symPtr = tknPtr;
+ getToken();
+ pas_Assignment(opSTS, exprSet, symPtr, symPtr->sParm.v.parent);
+ break;
+ case sSTRING :
+ case sRSTRING :
+ symPtr = tknPtr;
+ getToken();
+ pas_StringAssignment(symPtr, symPtr->sParm.v.parent);
+ break;
+
+ /* Complex assignments statements */
+
+ case sSUBRANGE :
+ case sRECORD :
+ case sRECORD_OBJECT :
+ case sPOINTER :
+ case sVAR_PARM :
+ case sARRAY :
+ pas_ComplexAssignment();
+ break;
+
+ /* Branch, Call and Label statements */
+
+ case sPROC : pas_ProcStatement(); break;
+ case tGOTO : pas_GotoStatement(); break;
+ case tINT_CONST : pas_LabelStatement(); break;
+
+ /* Conditional Statements */
+
+ case tIF : pas_IfStatement(); break;
+ case tCASE : pas_CaseStatement(); break;
+
+ /* Loop Statements */
+
+ case tREPEAT : pas_RepeatStatement(); break;
+ case tWHILE : pas_WhileStatement(); break;
+ case tFOR : pas_ForStatement(); break;
+
+ /* Other Statements */
+
+ case tBEGIN : compoundStatement(); break;
+ case tWITH : pas_WithStatement(); break;
+
+ /* None of the above, try standard procedures */
+ default : builtInProcedure(); break;
+
+ } /* end switch */
+
+ /* Generate the POPS that matches the PUSHS generated at the begining
+ * of this function (see comments above).
+ */
+
+ pas_GenerateSimple(opPOPS);
+
+ TRACE(lstFile,"]");
+
+} /* end statement */
+
+/***********************************************************************/
+/* Process a complex assignment statement */
+
+static void pas_ComplexAssignment(void)
+{
+ STYPE symbolSave;
+ TRACE(lstFile,"[pas_ComplexAssignment]");
+
+ /* FORM: <variable OR function identifer> := <expression>
+ * First, make a copy of the symbol table entry because the call to
+ * pas_SimpleAssignment() will modify it.
+ */
+
+ symbolSave = *tknPtr;
+ getToken();
+
+ /* Then process the complex assignment until it is reduced to a simple
+ * assignment (like int, char, etc.)
+ */
+
+ pas_SimpleAssignment(&symbolSave, 0);
+}
+
+/***********************************************************************/
+/* Process a complex assignment (recursively) until it becomes a
+ * simple assignment statement
+ */
+
+static void pas_SimpleAssignment(STYPE *varPtr, uint8_t assignFlags)
+{
+ STYPE *typePtr;
+ TRACE(lstFile,"[pas_SimpleAssignment]");
+
+ /* FORM: <variable OR function identifer> := <expression> */
+
+ typePtr = varPtr->sParm.v.parent;
+ switch (varPtr->sKind)
+ {
+ /* Check if we have reduce the complex assignment to a simple
+ * assignment yet
+ */
+
+ case sINT :
+ if ((assignFlags & INDEXED_ASSIGNMENT) != 0)
+ {
+ if ((assignFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ pas_Assignment(opSTI, exprInteger, varPtr, typePtr);
+ } /* end if */
+ else if ((assignFlags & ADDRESS_ASSIGNMENT) != 0)
+ pas_Assignment(opSTSX, exprIntegerPtr, varPtr, typePtr);
+ else
+ pas_Assignment(opSTSX, exprInteger, varPtr, typePtr);
+ } /* end if */
+ else
+ {
+ if ((assignFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_Assignment(opSTI, exprInteger, varPtr, typePtr);
+ } /* end if */
+ else if ((assignFlags & ADDRESS_ASSIGNMENT) != 0)
+ pas_Assignment(opSTS, exprIntegerPtr, varPtr, typePtr);
+ else
+ pas_Assignment(opSTS, exprInteger, varPtr, typePtr);
+ } /* end else */
+ break;
+ case sCHAR :
+ if ((assignFlags & INDEXED_ASSIGNMENT) != 0)
+ {
+ if ((assignFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ pas_Assignment(opSTIB, exprChar, varPtr, typePtr);
+ } /* end if */
+ else if ((assignFlags & ADDRESS_ASSIGNMENT) != 0)
+ pas_Assignment(opSTSX, exprCharPtr, varPtr, typePtr);
+ else
+ pas_Assignment(opSTSXB, exprChar, varPtr, typePtr);
+ } /* end if */
+ else
+ {
+ if ((assignFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_Assignment(opSTIB, exprChar, varPtr, typePtr);
+ } /* end if */
+ else if ((assignFlags & ADDRESS_ASSIGNMENT) != 0)
+ pas_Assignment(opSTS, exprCharPtr, varPtr, typePtr);
+ else
+ pas_Assignment(opSTSB, exprChar, varPtr, typePtr);
+ } /* end else */
+ break;
+ case sBOOLEAN :
+ if ((assignFlags & INDEXED_ASSIGNMENT) != 0)
+ {
+ if ((assignFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ pas_Assignment(opSTI, exprBoolean, varPtr, NULL);
+ } /* end if */
+ else if ((assignFlags & ADDRESS_ASSIGNMENT) != 0)
+ pas_Assignment(opSTSX, exprBooleanPtr, varPtr, typePtr);
+ else
+ pas_Assignment(opSTSX, exprBoolean, varPtr, NULL);
+ } /* end if */
+ else
+ {
+ if ((assignFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_Assignment(opSTI, exprBoolean, varPtr, NULL);
+ } /* end if */
+ else if ((assignFlags & ADDRESS_ASSIGNMENT) != 0)
+ pas_Assignment(opSTS, exprBooleanPtr, varPtr, typePtr);
+ else
+ pas_Assignment(opSTS, exprBoolean, varPtr, NULL);
+ } /* end else */
+ break;
+ case sREAL :
+ if ((assignFlags & INDEXED_ASSIGNMENT) != 0)
+ {
+ if ((assignFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ pas_LargeAssignment(opSTIM, exprReal, varPtr, typePtr);
+ } /* end if */
+ else if ((assignFlags & ADDRESS_ASSIGNMENT) != 0)
+ pas_Assignment(opSTSX, exprRealPtr, varPtr, typePtr);
+ else
+ pas_LargeAssignment(opSTSXM, exprReal, varPtr, typePtr);
+ } /* end if */
+ else
+ {
+ if ((assignFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_LargeAssignment(opSTIM, exprReal, varPtr, typePtr);
+ } /* end if */
+ else if ((assignFlags & ADDRESS_ASSIGNMENT) != 0)
+ pas_Assignment(opSTS, exprRealPtr, varPtr, typePtr);
+ else
+ pas_LargeAssignment(opSTSM, exprReal, varPtr, typePtr);
+ } /* end else */
+ break;
+ case sSCALAR :
+ if ((assignFlags & INDEXED_ASSIGNMENT) != 0)
+ {
+ if ((assignFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ pas_Assignment(opSTI, exprScalar, varPtr, typePtr);
+ } /* end if */
+ else if ((assignFlags & ADDRESS_ASSIGNMENT) != 0)
+ pas_Assignment(opSTSX, exprScalarPtr, varPtr, typePtr);
+ else
+ pas_Assignment(opSTSX, exprScalar, varPtr, typePtr);
+ } /* end if */
+ else
+ {
+ if ((assignFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_Assignment(opSTI, exprScalar, varPtr, typePtr);
+ } /* end if */
+ else if ((assignFlags & ADDRESS_ASSIGNMENT) != 0)
+ pas_Assignment(opSTS, exprScalarPtr, varPtr, typePtr);
+ else
+ pas_Assignment(opSTS, exprScalar, varPtr, typePtr);
+ } /* end else */
+ break;
+ case sSET_OF :
+ if ((assignFlags & INDEXED_ASSIGNMENT) != 0)
+ {
+ if ((assignFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDSX, varPtr);
+ pas_Assignment(opSTI, exprSet, varPtr, typePtr);
+ } /* end if */
+ else if ((assignFlags & ADDRESS_ASSIGNMENT) != 0)
+ pas_Assignment(opSTSX, exprSetPtr, varPtr, typePtr);
+ else
+ pas_Assignment(opSTSX, exprSet, varPtr, typePtr);
+ } /* end if */
+ else
+ {
+ if ((assignFlags & ADDRESS_DEREFERENCE) != 0)
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_Assignment(opSTI, exprSet, varPtr, typePtr);
+ } /* end if */
+ else if ((assignFlags & ADDRESS_ASSIGNMENT) != 0)
+ pas_Assignment(opSTS, exprSetPtr, varPtr, typePtr);
+ else
+ pas_Assignment(opSTS, exprSet, varPtr, typePtr);
+ } /* end else */
+ break;
+
+ /* NOPE... recurse until it becomes a simple assignment */
+
+ case sSUBRANGE :
+ varPtr->sKind = typePtr->sParm.t.subType;
+ pas_SimpleAssignment(varPtr, assignFlags);
+ break;
+
+ case sRECORD :
+ /* FORM: <record identifier>.<field> := <expression>
+ * OR: <record pointer identifier> := <pointer expression>
+ */
+
+ /* Check if this is a pointer to a record */
+
+ if ((assignFlags & ADDRESS_ASSIGNMENT) != 0)
+ {
+ if (token == '.') error(ePOINTERTYPE);
+
+ if ((assignFlags & INDEXED_ASSIGNMENT) != 0)
+ pas_Assignment(opSTSX, exprRecordPtr, varPtr, typePtr);
+ else
+ pas_Assignment(opSTS, exprRecordPtr, varPtr, typePtr);
+ } /* end if */
+ else if (((assignFlags & ADDRESS_DEREFERENCE) != 0) &&
+ ((assignFlags & VAR_PARM_ASSIGNMENT) == 0))
+ error(ePOINTERTYPE);
+
+ /* Check if a period separates the RECORD identifier from the
+ * record field identifier
+ */
+
+ else if (token == '.')
+ {
+ /* Skip over the period */
+
+ getToken();
+
+ /* Verify that a field identifier associated with this record
+ * follows the period.
+ */
+
+ if ((token != sRECORD_OBJECT) ||
+ (tknPtr->sParm.r.record != typePtr))
+ error(eRECORDOBJECT);
+ else
+ {
+ /* Modify the variable so that it has the characteristics of the
+ * the field but with level and offset associated with the record
+ */
+
+ typePtr = tknPtr->sParm.r.parent;
+ varPtr->sKind = typePtr->sParm.t.type;
+ varPtr->sParm.v.parent = typePtr;
+
+ /* Special case: The record is a VAR parameter. */
+
+ if (assignFlags == (INDEXED_ASSIGNMENT | ADDRESS_DEREFERENCE | VAR_PARM_ASSIGNMENT))
+ {
+ pas_GenerateDataOperation(opPUSH, tknPtr->sParm.r.offset);
+ pas_GenerateSimple(opADD);
+ } /* end if */
+ else
+ varPtr->sParm.v.offset += tknPtr->sParm.r.offset;
+
+ getToken();
+ pas_SimpleAssignment(varPtr, assignFlags);
+
+ } /* end else if */
+ } /* end else */
+
+ /* It must be a RECORD assignment */
+
+ else
+ {
+ /* Special case: The record is a VAR parameter. */
+
+ if (assignFlags == (INDEXED_ASSIGNMENT | ADDRESS_DEREFERENCE | VAR_PARM_ASSIGNMENT))
+ {
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_GenerateSimple(opADD);
+ pas_LargeAssignment(opSTIM, exprRecord, varPtr, typePtr);
+ } /* end if */
+ else
+ pas_LargeAssignment(opSTSM, exprRecord, varPtr, typePtr);
+ } /* end else */
+ break;
+
+ case sRECORD_OBJECT :
+ /* FORM: <field> := <expression>
+ * NOTE: This must have been preceeded with a WITH statement
+ * defining the RECORD type
+ */
+
+ if (!withRecord.parent)
+ error(eINVTYPE);
+ else if ((assignFlags && (ADDRESS_DEREFERENCE | ADDRESS_ASSIGNMENT)) != 0)
+ error(ePOINTERTYPE);
+ else if ((assignFlags && INDEXED_ASSIGNMENT) != 0)
+ error(eARRAYTYPE);
+
+ /* Verify that a field identifier is associated with the RECORD
+ * specified by the WITH statement.
+ */
+
+ else if (varPtr->sParm.r.record != withRecord.parent)
+ error(eRECORDOBJECT);
+
+ else
+ {
+ int16_t tempOffset;
+
+ /* Now there are two cases to consider: (1) the withRecord is a
+ * pointer to a RECORD, or (2) the withRecord is the RECORD itself
+ */
+
+ if (withRecord.pointer)
+ {
+ /* If the pointer is really a VAR parameter, then other syntax
+ * rules will apply
+ */
+
+ if (withRecord.varParm)
+ assignFlags |= (INDEXED_ASSIGNMENT | ADDRESS_DEREFERENCE | VAR_PARM_ASSIGNMENT);
+ else
+ assignFlags |= (INDEXED_ASSIGNMENT | ADDRESS_DEREFERENCE);
+
+ pas_GenerateDataOperation(opPUSH, (varPtr->sParm.r.offset + withRecord.index));
+ tempOffset = withRecord.offset;
+ } /* end if */
+ else
+ {
+ tempOffset = varPtr->sParm.r.offset + withRecord.offset;
+ } /* end else */
+
+ /* Modify the variable so that it has the characteristics of the
+ * the field but with level and offset associated with the record
+ * NOTE: We have to be careful here because the structure
+ * associated with sRECORD_OBJECT is not the same as for
+ * variables!
+ */
+
+ typePtr = varPtr->sParm.r.parent;
+
+ varPtr->sKind = typePtr->sParm.t.type;
+ varPtr->sLevel = withRecord.level;
+ varPtr->sParm.v.size = typePtr->sParm.t.asize;
+ varPtr->sParm.v.offset = tempOffset;
+ varPtr->sParm.v.parent = typePtr;
+
+ pas_SimpleAssignment(varPtr, assignFlags);
+
+ } /* end else */
+ break;
+
+ case sPOINTER :
+ /* FORM: <pointer identifier>^ := <expression>
+ * OR: <pointer identifier> := <pointer expression>
+ */
+
+ if (token == '^') /* value assignment? */
+ {
+ getToken();
+ assignFlags |= ADDRESS_DEREFERENCE;
+ } /* end if */
+ else
+ assignFlags |= ADDRESS_ASSIGNMENT;
+
+ varPtr->sKind = typePtr->sParm.t.type;
+ pas_SimpleAssignment(varPtr, assignFlags);
+ break;
+
+ case sVAR_PARM :
+ if (assignFlags != 0) error(eVARPARMTYPE);
+ assignFlags |= (ADDRESS_DEREFERENCE | VAR_PARM_ASSIGNMENT);
+
+ varPtr->sKind = typePtr->sParm.t.type;
+ pas_SimpleAssignment(varPtr, assignFlags);
+ break;
+
+ case sARRAY :
+ /* FORM: <array identifier> := <expression>
+ * OR: <pointer array identifier>[<index>]^ := <expression>
+ * OR: <pointer array identifier>[<index>] := <pointer expression>
+ * OR: <record array identifier>[<index>].<field identifier> := <expression>
+ * OR: etc., etc., etc.
+ */
+
+ if (assignFlags != 0) error(eARRAYTYPE);
+ assignFlags |= INDEXED_ASSIGNMENT;
+
+ arrayIndex(typePtr->sParm.t.asize);
+ varPtr->sKind = typePtr->sParm.t.type;
+ varPtr->sParm.v.size = typePtr->sParm.t.asize;
+ pas_SimpleAssignment(varPtr, assignFlags);
+ break;
+
+ default :
+ error(eINVTYPE);
+ break;
+
+ }
+}
+
+/***********************************************************************/
+/* Process simple assignment statement */
+
+static void pas_Assignment(uint16_t storeOp, exprType assignType,
+ STYPE *varPtr, STYPE *typePtr)
+{
+ TRACE(lstFile,"[pas_Assignment]");
+
+ /* FORM: <variable OR function identifer> := <expression> */
+
+ if (token != tASSIGN) error (eASSIGN);
+ else getToken();
+
+ expression(assignType, typePtr);
+ pas_GenerateStackReference(storeOp, varPtr);
+}
+
+/***********************************************************************/
+/* Process the assignment to a variable length string record */
+
+static void pas_StringAssignment(STYPE *varPtr, STYPE *typePtr)
+{
+ exprType stringKind;
+
+ TRACE(lstFile,"[pas_StringAssignment]");
+
+ /* FORM: <variable OR function identifer> := <expression> */
+
+ /* Verify that the assignment token follows the indentifier */
+
+ if (token != tASSIGN) error (eASSIGN);
+ else getToken();
+
+ /* Get the expression after assignment token. We'll take any kind
+ * of string expression. This is a hack to handle calls to system
+ * functions that return exprCString pointers that must be converted
+ * to exprString records upon assignment.
+ */
+
+ stringKind = expression(exprAnyString, typePtr);
+
+ /* Place the address of the destination string structure instance on the
+ * stack.
+ */
+
+ pas_GenerateStackReference(opLAS, varPtr);
+
+ /* Check if this is an assignment to a global allocated string, or
+ * to a stack reference to an allocated string.
+ */
+
+ if (varPtr->sKind == sRSTRING)
+ {
+ /* It is an assignment to a string reference --
+ * Generate a runtime library call to copy the destination
+ * string string into the pascal string instance. The particular
+ * runtime call will account for any necesary string type conversion.
+ */
+
+ if ((stringKind == exprString) || (stringKind == exprStkString))
+ {
+ /* It is a pascal string type. Current stack representation is:
+ *
+ * TOS(0)=address of dest string reference
+ * TOS(1)=length of source string
+ * TOS(2)=pointer to source string
+ */
+
+ pas_BuiltInFunctionCall(lbSTR2RSTR);
+ }
+ else if (stringKind == exprCString)
+ {
+ /* It is a 32-bit C string point. Current stack representation is:
+ *
+ * TOS(0)=address of dest string reference
+ * TOS(1)=MS 16-bits of 32-bit C source string pointer
+ * TOS(2)=LS 16-bits of 32-bit C source string pointer
+ */
+
+ pas_BuiltInFunctionCall(lbCSTR2RSTR);
+ }
+ }
+ else
+ {
+ /* It is an assignment to a allocated Pascal string --
+ * Generate a runtime library call to copy the destination
+ * string string into the pascal string instance. The particular
+ * runtime call will account for any necesary string type conversion.
+ */
+
+ if ((stringKind == exprString) || (stringKind == exprStkString))
+ {
+ /* It is a pascal string type. Current stack representation is:
+ *
+ * TOS(0)=address of dest string hdr
+ * TOS(1)=length of source string
+ * TOS(2)=pointer to source string
+ */
+
+ pas_BuiltInFunctionCall(lbSTR2STR);
+ }
+ else if (stringKind == exprCString)
+ {
+ /* It is a 32-bit C string point. Current stack representation is:
+ *
+ * TOS(0)=address of dest string hdr
+ * TOS(1)=MS 16-bits of 32-bit C source string pointer
+ * TOS(2)=LS 16-bits of 32-bit C source string pointer
+ */
+
+ pas_BuiltInFunctionCall(lbCSTR2STR);
+ }
+ }
+
+ /* else ... type mismatch error already reported by expression() */
+}
+
+/***********************************************************************/
+/* Process a multiple word assignment statement */
+
+static void pas_LargeAssignment(uint16_t storeOp, exprType assignType,
+ STYPE *varPtr, STYPE *typePtr)
+{
+ TRACE(lstFile,"[pas_LargeAssignment]");
+
+ /* FORM: <variable OR function identifer> := <expression> */
+
+ if (token != tASSIGN) error (eASSIGN);
+ else getToken();
+
+ expression(assignType, typePtr);
+ pas_GenerateDataSize(varPtr->sParm.v.size);
+ pas_GenerateStackReference(storeOp, varPtr);
+}
+
+/***********************************************************************/
+
+static void pas_GotoStatement(void)
+{
+ char labelname [8]; /* Label symbol table name */
+ STYPE *label_ptr; /* Pointer to Label Symbol */
+
+ TRACE(lstFile,"[pas_GotoStatement]");
+
+ /* FORM: GOTO <integer> */
+
+ /* Get the token after the goto reserved word. It should be an <integer> */
+
+ getToken();
+ if (token != tINT_CONST)
+ {
+ /* Token following the goto is not an integer */
+
+ error(eINVLABEL);
+ }
+ else
+ {
+ /* The integer label must be non-negative */
+
+ if (tknInt < 0)
+ {
+ error(eINVLABEL);
+ }
+ else
+ {
+ /* Find and verify the symbol associated with the label */
+
+ (void)sprintf (labelname, "%ld", tknInt);
+ if (!(label_ptr = findSymbol(labelname)))
+ {
+ error(eUNDECLABEL);
+ }
+ else if (label_ptr->sKind != sLABEL)
+ {
+ error(eINVLABEL);
+ }
+ else
+ {
+ /* Generate the branch to the label */
+
+ pas_GenerateDataOperation(opJMP, label_ptr->sParm.l.label);
+ }
+ }
+
+ /* Get the token after the <integer> value */
+
+ getToken();
+ }
+}
+
+/***********************************************************************/
+
+static void pas_LabelStatement(void)
+{
+ char labelName [8]; /* Label symbol table name */
+ STYPE *labelPtr; /* Pointer to Label Symbol */
+
+ TRACE(lstFile,"[pas_LabelStatement]");
+
+ /* FORM: <integer> : */
+
+ /* Verify that the integer is a label name */
+
+ (void)sprintf (labelName, "%ld", tknInt);
+ if (!(labelPtr = findSymbol(labelName)))
+ {
+ error(eUNDECLABEL);
+ }
+ else if(labelPtr->sKind != sLABEL)
+ {
+ error(eINVLABEL);
+ }
+
+ /* And also verify that the label symbol has not been previously
+ * defined.
+ */
+
+ else if(!(labelPtr->sParm.l.unDefined))
+ {
+ error(eMULTLABEL);
+ }
+ else
+ {
+ /* Generate the label and indicate that it has been defined */
+
+ pas_GenerateDataOperation(opLABEL, labelPtr->sParm.l.label);
+ labelPtr->sParm.l.unDefined = false;
+
+ /* We have to assume that we got here via a goto statement.
+ * We don't have logic in place to track changes to the level
+ * stack pointer (LSP) register, so we have no choice but to
+ * invalidate that register now.
+ */
+
+ pas_InvalidateCurrentStackLevel();
+ }
+
+ /* Skip over the label integer */
+
+ getToken();
+
+ /* Make sure that the label is followed by a colon */
+
+ if (token != ':') error (eCOLON);
+ else getToken();
+}
+
+/***********************************************************************/
+
+static void pas_ProcStatement(void)
+{
+ STYPE *procPtr = tknPtr;
+ int size = 0;
+
+ TRACE(lstFile,"[pas_ProcStatement]");
+
+ /* FORM: procedure-method-statement =
+ * procedure-method-specifier [ actual-parameter-list ]
+ *
+ * Skip over the procedure-method-statement
+ */
+
+ getToken();
+
+ /* Get the actual parameters (if any) associated with the procedure
+ * call.
+ */
+
+ size = actualParameterList(procPtr);
+
+ /* Generate procedure call and stack adjustment (if required)
+ * Upon return from the procedure, the level stack pointer (LSP)
+ * may also be invalid. However, we rely on level level logic in
+ * pgen.c to manage this case (as well as the function call case).
+ */
+
+ pas_GenerateProcedureCall(procPtr);
+ if (size)
+ {
+ pas_GenerateDataOperation(opINDS, -size);
+ }
+}
+
+/***********************************************************************/
+
+static void pas_IfStatement(void)
+{
+ uint16_t else_label = ++label;
+ uint16_t endif_label = else_label;
+ int32_t thenLSP;
+ int32_t elseLSP;
+
+ TRACE(lstFile,"[pas_IfStatement]");
+
+ /* FORM: IF <expression> THEN <statement> [ELSE <statement>] */
+
+ /* Skip over the IF token */
+
+ getToken();
+
+ /* Evaluate the boolean expression */
+
+ expression(exprBoolean, NULL);
+
+ /* Make sure that the boolean expression is followed by the THEN token */
+
+ if (token != tTHEN)
+ error (eTHEN);
+ else
+ {
+ /* Skip over the THEN token */
+
+ getToken();
+
+ /* Generate a conditional branch to the "else_label." This will be a
+ * branch to either the ENDIF or to the ELSE location (if present).
+ */
+
+ pas_GenerateDataOperation(opJEQUZ, else_label);
+
+ /* Save the value of the Level Stack Pointer (LSP) here. This will be
+ * the value of the LSP at the ENDIF label if there is no ELSE <statement>
+ * presentl. We will compare the elseLSP to the thenLSP at that point.
+ */
+
+ elseLSP = pas_GetCurrentStackLevel();
+
+ /* Parse the <statment> following the THEN token */
+
+ statement();
+
+ /* Save the LSP after generating the THEN <statement>. We will compare the
+ * elseLSP to the thenLSP below.
+ */
+
+ thenLSP = pas_GetCurrentStackLevel();
+
+ /* Check for optional ELSE <statement> */
+
+ if (token == tELSE)
+ {
+ /* Change the ENDIF label. Now instead of branching to
+ * the ENDIF, the logic above will branch to the ELSE
+ * logic generated here.
+ */
+
+ endif_label = ++label;
+
+ /* Skip over the ELSE token */
+
+ getToken();
+
+ /* Generate Jump to ENDIF label after the THEN <statement> */
+
+ pas_GenerateDataOperation(opJMP, endif_label);
+
+ /* Generate the ELSE label here. This is where we will go if
+ * the IF <expression> evaluates to false.
+ */
+
+ pas_GenerateDataOperation(opLABEL, else_label);
+
+ /* Generate the ELSE <statement> then fall through to the
+ * ENDIF label.
+ */
+
+ statement();
+
+ /* Save the LSP after generating the ELSE <statement>. We will
+ * compare elseLSP to the thenLSP below.
+ */
+
+ elseLSP = pas_GetCurrentStackLevel();
+ }
+
+ /* Generate the ENDIF label here. Note that if no ELSE <statement>
+ * is present, this will be the same as the else_label.
+ */
+
+ pas_GenerateDataOperation(opLABEL, endif_label);
+
+ /* We can get to this location through two of three pathes: (1) through the
+ * THEN <statement>, (2) from the IF <expression> if no ELSE <statement>
+ * is present, or (3) from the ELSE <statement>. If the LSP is different
+ * through these two pathes, then we will have to invalidate it.
+ */
+
+ if (thenLSP != elseLSP)
+ {
+ pas_InvalidateCurrentStackLevel();
+ }
+ }
+}
+
+/***********************************************************************/
+
+void compoundStatement(void)
+{
+ TRACE(lstFile,"[compoundStatement]");
+
+ /* Process statements until END encountered */
+ do
+ {
+ getToken();
+ statement();
+ }
+ while (token == ';');
+
+ /* Verify that it really was END */
+
+ if (token != tEND) error (eEND);
+ else getToken();
+}
+
+/***********************************************************************/
+
+void pas_RepeatStatement ()
+{
+ uint16_t rpt_label = ++label;
+
+ TRACE(lstFile,"[pas_RepeatStatement]");
+
+ /* REPEAT <statement[;statement[statement...]]> UNTIL <expression> */
+
+ /* Generate top of loop label */
+
+ pas_GenerateDataOperation(opLABEL, rpt_label);
+ do
+ {
+ getToken();
+
+ /* Process <statement> */
+
+ statement();
+ }
+ while (token == ';');
+
+ /* Verify UNTIL follows */
+
+ if (token != tUNTIL) error (eUNTIL);
+ else getToken();
+
+ /* Generate UNTIL <expression> */
+
+ expression(exprBoolean, NULL);
+
+ /* Generate conditional branch to the top of loop */
+
+ pas_GenerateDataOperation(opJEQUZ, rpt_label);
+
+ /* NOTE: The current LSP setting will be correct after the repeat
+ * loop because we fall through from the bottom of the loop after
+ * executing the body at least once.
+ */
+}
+
+/***********************************************************************/
+
+static void pas_WhileStatement(void)
+{
+ uint16_t while_label = ++label; /* Top of loop label */
+ uint16_t endwhile_label = ++label; /* End of loop label */
+ uint32_t nLspChanges;
+ int32_t topOfLoopLSP;
+ bool bCheckLSP = false;
+
+ TRACE(lstFile,"[pas_WhileStatement]");
+
+ /* Generate WHILE <expression> DO <statement> */
+
+ /* Skip over WHILE token */
+
+ getToken();
+
+ /* Set top of loop label */
+
+ pas_GenerateDataOperation(opLABEL, while_label);
+
+ /* Evaluate the WHILE <expression> */
+
+ nLspChanges = pas_GetNStackLevelChanges();
+ expression(exprBoolean, NULL);
+
+ /* Generate a conditional jump to the end of the loop */
+
+ pas_GenerateDataOperation(opJEQUZ, endwhile_label);
+
+ /* Save the level stack pointer (LSP) at the top of the
+ * loop. When first executed, this value will depend on
+ * logic prior to the loop or on values set in the
+ * WHILE <expression>. On subsequent loops, this value
+ * may be determined by logic within the loop body or
+ * have to restore this value when the loop terminates.
+ */
+
+ topOfLoopLSP = pas_GetCurrentStackLevel();
+
+ /* Does the WHILE <expression> logic set the LSP? */
+
+ if (nLspChanges == pas_GetNStackLevelChanges())
+ {
+ /* Yes, then the value set in the WHILE <expression>
+ * is the one that will be in effect at the end_while
+ * label.
+ */
+
+ bCheckLSP = true;
+ }
+
+ /* Verify that the DO token follows the expression */
+
+ if (token != tDO) error(eDO);
+ else getToken();
+
+ /* Generate the <statement> following the DO token */
+
+ statement();
+
+ /* Generate a branch to the top of the loop */
+
+ pas_GenerateDataOperation(opJMP, while_label);
+
+ /* Set the bottom of loop label */
+
+ pas_GenerateDataOperation(opLABEL, endwhile_label);
+
+ /* We always get here from the check at the top of the loop.
+ * Normally this will be from the branch from the bottom of
+ * the loop to the top of the loop. Then from the conditional
+ * branch at the top of the loop to here.
+ *
+ * But, we need to allow for the special case when the body
+ * of the while loop never executed. The flag bCheckLSP is
+ * set true if the conditional expression evaluation does not
+ * set the LSP. In the case, the current LSP will be either
+ * the LSP at the top of the loop (if he body was never executed)
+ * or the current LSP (the body executes at least once).
+ */
+
+ if (bCheckLSP)
+ {
+ if (topOfLoopLSP != pas_GetCurrentStackLevel())
+ {
+ /* In thise case, there is uncertainty in the value of the
+ * LSP and we must invalidate it. It will be reset to the
+ * correct the next time that a level stack reference is
+ * performed.
+ */
+
+ pas_InvalidateCurrentStackLevel();
+ }
+ }
+ else
+ {
+ /* Otherwise, make sure that the code generation logic knows
+ * the correct value of the LSP at this point.
+ */
+
+ pas_SetCurrentStackLevel(topOfLoopLSP);
+ }
+}
+
+/***********************************************************************/
+/* This is helper function for pas_CaseStatement */
+
+static bool pas_CheckInvalidateLSP(int32_t *pTerminalLSP)
+{
+ /* Check the LSP after evaluating the case <statement>. */
+
+ int32_t caseLSP = pas_GetCurrentStackLevel();
+ if (caseLSP < 0)
+ {
+ /* If the LSP is invalid after any case <statement>, then it could
+ * be invalid at the end_case label as well.
+ */
+
+ return true;
+ }
+ else if (*pTerminalLSP < 0)
+ {
+ /* The value of the LSP at the end_case label has not
+ * yet been determined. It must be the value at the
+ * end of this case <statement> (or else it is invalid)
+ */
+
+ *pTerminalLSP = caseLSP;
+ }
+ else if (*pTerminalLSP != caseLSP)
+ {
+ /* The value of the LSP at the end of this case <statement> is
+ * different from the value of the LSP at the end of some other
+ * case <statement>. The value of the LSP at the end_case label
+ * will be indeterminate and must be invalidated.
+ */
+
+ return true;
+ }
+ /* So far so good */
+
+ return false;
+}
+
+static void pas_CaseStatement(void)
+{
+ uint16_t this_case;
+ uint16_t next_case = ++label;
+ uint16_t end_case = ++label;
+ int32_t terminalLSP = -1;
+ bool bInvalidateLSP = false;
+
+ TRACE(lstFile,"[pas_CaseStatement]");
+
+ /* Process "CASE <expression> OF" */
+
+ /* Skip over the CASE token */
+
+ getToken();
+
+ /* Evaluate the CASE <expression> */
+
+ expression(exprAnyOrdinal, NULL);
+
+ /* Verify that CASE <expression> is followed with the OF token */
+
+ if (token != tOF) error (eOF);
+ else getToken();
+
+ /* Loop to process each case until END encountered */
+
+ for (;;)
+ {
+ this_case = next_case;
+ next_case = ++label;
+
+ /* Process NON-STANDARD ELSE <statement> END */
+
+ if (token == tELSE)
+ {
+ getToken();
+
+ /* Set ELSE statement label */
+
+ pas_GenerateDataOperation(opLABEL, this_case);
+
+ /* Evaluate ELSE statement */
+
+ statement();
+
+ /* Check the LSP after evaluating the ELSE <statement>. */
+
+ if (pas_CheckInvalidateLSP(&terminalLSP))
+ {
+ /* The LSP will be invalid at the end case label. Set
+ * a flag so that we can handle invalidation of the LSP when
+ * we get to the end case label.
+ */
+
+ bInvalidateLSP = true;
+ }
+
+ /* Verify that END follows the ELSE <statement> */
+
+ if (token != tEND) error(eEND);
+ else getToken();
+
+ /* Terminate FOR loop */
+
+ break;
+ }
+
+ /* Process "<constant>[,<constant>[,...]] : <statement>"
+ * NOTE: We accept any kind of constant for the case selector; there
+ * really should be some check to assure that the constant is of the
+ * same type as the expression!
+ */
+
+ else
+ {
+ /* Loop for each <constant> in the case list */
+
+ for(;;)
+ {
+ /* Verify that we have a constant */
+
+ if (!isConstant(token))
+ {
+ error(eINTCONST);
+ break;
+ }
+
+ /* Generate a comparison of the CASE expression and the constant.
+ *
+ * First duplicate the value to be compared (from the CASE <expression>)
+ * and push the comparison value (from the <constant>:)
+ */
+
+ pas_GenerateSimple(opDUP);
+ pas_GenerateDataOperation(opPUSH, tknInt);
+
+ /* The kind of comparison we generate depends on if we have to
+ * jump over other case selector comparsions to the statement
+ * or if we can just fall through to the statement
+ */
+
+ /* Skip over the constant */
+
+ getToken();
+
+ /* If there are multiple constants, they will be separated with
+ * commas.
+ */
+
+ if (token == ',')
+ {
+ /* Generate jump to <statement> */
+
+ pas_GenerateDataOperation(opJEQUZ, this_case);
+
+ /* Skip over comma */
+
+ getToken();
+ }
+ else
+ {
+ /* else jump to the next case */
+
+ pas_GenerateDataOperation(opJNEQZ, next_case);
+ break;
+ }
+ }
+
+ /* Then process ... : <statement> */
+
+ /* Verify colon presence */
+
+ if (token != ':') error(eCOLON);
+ else getToken();
+
+ /* Set CASE label */
+
+ pas_GenerateDataOperation(opLABEL, this_case);
+
+ /* Evaluate <statement> */
+
+ statement();
+
+ /* Jump to exit CASE */
+
+ pas_GenerateDataOperation(opJMP, end_case);
+
+ /* Check the LSP after evaluating the case <statement>. */
+
+ if (pas_CheckInvalidateLSP(&terminalLSP))
+ {
+ /* If the LSP will be invalid at the end case label. Set
+ * a flag so that we can handle invalidation of the LSP when
+ * we get to the end case label.
+ */
+
+ bInvalidateLSP = true;
+ }
+ }
+
+ /* Check if there are more statements. If not, verify END present */
+
+ if (token == ';')
+ {
+ getToken();
+ }
+ else if (token == tEND)
+ {
+ getToken();
+ break;
+ }
+ else
+ {
+ error (eEND);
+ break;
+ }
+ }
+
+ /* Generate ENDCASE label and Pop CASE <expression> from stack */
+
+ pas_GenerateDataOperation(opLABEL, end_case);
+ pas_GenerateDataOperation(opINDS, -sINT_SIZE);
+
+ /* We may have gotten to this point from many different case <statements>.
+ * The flag bInvalidateLSP will be set if the LSP is not the same for
+ * each of these pathes. Invalidating the LSP will force it to be reloaded
+ * when the next level stack access is done.
+ */
+
+ if (bInvalidateLSP)
+ {
+ pas_InvalidateCurrentStackLevel();
+ }
+}
+
+/***********************************************************************/
+static void pas_ForStatement(void)
+{
+ STYPE *varPtr;
+ uint16_t forLabel = ++label;
+ uint16_t endForLabel = ++label;
+ uint16_t jmpOp;
+ uint16_t modOp;
+ int32_t topOfLoopLSP;
+
+ TRACE(lstFile,"[pas_ForStatement]");
+
+ /* FOR <assigment statement> <TO, DOWNTO> <expression> DO <statement> */
+
+ /* Skip over the FOR token */
+
+ getToken();
+
+ /* Get and verify the left side of the assignment. */
+ if ((token != sINT) && (token != sSUBRANGE))
+ error(eINTVAR);
+ else
+ {
+ /* Save the token associated with the left side of the assignment
+ * and evaluate the integer assignment.
+ */
+
+ varPtr = tknPtr;
+ getToken();
+
+ /* Generate the assignment to the integer variable */
+
+ pas_Assignment(opSTS, exprInteger, tknPtr, tknPtr->sParm.v.parent);
+
+ /* Determine if this is a TO or a DOWNTO loop and set up the opCodes
+ * to generate appropriately.
+ */
+
+ if (token == tDOWNTO)
+ {
+ jmpOp = opJGT;
+ modOp = opDEC;
+ getToken();
+ }
+ else if (token == tTO)
+ {
+ jmpOp = opJLT;
+ modOp = opINC;
+ getToken();
+ }
+ else
+ error (eTOorDOWNTO);
+
+ /* Evaluate <expression> DO */
+
+ expression(exprInteger, varPtr->sParm.v.parent);
+
+ /* Verify that the <expression> is followed by the DO token */
+
+ if (token != tDO) error (eDO);
+ else getToken();
+
+ /* Generate top of loop label */
+
+ pas_GenerateDataOperation(opLABEL, forLabel);
+
+ /* Generate the top of loop comparison. Duplicate the end of loop
+ * value, push the current value, and perform the comparison.
+ */
+
+ pas_GenerateSimple(opDUP);
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_GenerateDataOperation(jmpOp, endForLabel);
+
+ /* Save the level stack pointer (LSP) at the top of the FOR
+ * loop. When first executed, this value will depend on
+ * logic prior to the loop body. On subsequent loops, this
+ * value may be determined by logic within the loop body.
+ */
+
+ topOfLoopLSP = pas_GetCurrentStackLevel();
+
+ /* Evaluate the for statement <statement> */
+
+ statement();
+
+ /* Generate end of loop logic: Load the variable, modify the
+ * variable, store the variable, and jump unconditionally to the
+ * top of the loop.
+ */
+
+ pas_GenerateStackReference(opLDS, varPtr);
+ pas_GenerateSimple(modOp);
+ pas_GenerateStackReference(opSTS, varPtr);
+ pas_GenerateDataOperation(opJMP, forLabel);
+
+ /* Generate the end of loop label. This is where the conditional
+ * branch at the top of the loop will come to.
+ */
+
+ pas_GenerateDataOperation(opLABEL, endForLabel);
+ pas_GenerateDataOperation(opINDS, -sINT_SIZE);
+
+ /* We always get here from the check at the top of the loop.
+ * Normally this will be from the branch from the bottom of
+ * the loop to the top of the loop. Then from the conditional
+ * branch at the top of the loop to here.
+ *
+ * But, we need to allow for the special case when the body
+ * of the for loop never executed. In this case, the LSP at
+ * the first time into the loop may differ from the LSP at
+ * subsequent times into the loop. If this is the case, then
+ * will will have to invalidate the LSP.
+ */
+
+ if (topOfLoopLSP != pas_GetCurrentStackLevel())
+ {
+ /* In thise case, there is uncertainty in the value of the
+ * LSP and we must invalidate it. It will be reset to the
+ * correct the next time that a level stack reference is
+ * performed.
+ */
+
+ pas_InvalidateCurrentStackLevel();
+ }
+ }
+}
+
+/***********************************************************************/
+static void pas_WithStatement(void)
+{
+ WTYPE saveWithRecord;
+
+ TRACE(lstFile,"[pas_WithStatement]");
+
+ /* Generate WITH <variable[,variable[...]] DO <statement> */
+
+ /* Save the current WITH pointer. Only one WITH can be active at
+ * any given time.
+ */
+
+ saveWithRecord = withRecord;
+
+ /* Process each RECORD or RECORD OBJECT in the <variable> list */
+
+ getToken();
+ for(;;)
+ {
+ /* A RECORD type variable may be used in the WITH statement only if
+ * there is no other WITH active
+ */
+
+ if ((token == sRECORD) && (!withRecord.parent))
+ {
+ /* Save the RECORD variable as the new withRecord */
+
+ withRecord.level = tknPtr->sLevel;
+ withRecord.pointer = false;
+ withRecord.varParm = false;
+ withRecord.offset = tknPtr->sParm.v.offset;
+ withRecord.parent = tknPtr->sParm.v.parent;
+
+ /* Skip over the RECORD variable */
+
+ getToken();
+ }
+
+ /* A RECORD VAR parameter may also be used in the WITH statement
+ * (again only if there is no other WITH active)
+ */
+
+ else if ((token == sVAR_PARM) &&
+ (!withRecord.parent) &&
+ (tknPtr->sParm.v.parent->sParm.t.type == sRECORD))
+ {
+ /* Save the RECORD VAR parameter as the new withRecord */
+
+ withRecord.level = tknPtr->sLevel;
+ withRecord.pointer = true;
+ withRecord.varParm = true;
+ withRecord.offset = tknPtr->sParm.v.offset;
+ withRecord.parent = tknPtr->sParm.v.parent;
+
+ /* Skip over the RECORD VAR parameter */
+
+ getToken();
+ }
+
+ /* A pointer to a RECORD may also be used in the WITH statement
+ * (again only if there is no other WITH active)
+ */
+
+ else if ((token == sPOINTER) &&
+ (!withRecord.parent) &&
+ (tknPtr->sParm.v.parent->sParm.t.type == sRECORD))
+ {
+ /* Save the RECORD pointer as the new withRecord */
+
+ withRecord.level = tknPtr->sLevel;
+ withRecord.pointer = true;
+ withRecord.pointer = false;
+ withRecord.offset = tknPtr->sParm.v.offset;
+ withRecord.parent = tknPtr->sParm.v.parent;
+
+ /* Skip over the RECORD pointer */
+
+ getToken();
+
+ /* Verify that deferencing is specified! */
+
+ if (token != '^') error(eRECORDVAR);
+ else getToken();
+ }
+
+ /* A RECORD_OBJECT may be used in the WITH statement if the field
+ * is from the same sRECORD type and is itself of type RECORD.
+ */
+
+ else if ((token == sRECORD_OBJECT) &&
+ (tknPtr->sParm.r.record == withRecord.parent) &&
+ (tknPtr->sParm.r.parent->sParm.t.type == sRECORD))
+ {
+ /* Okay, update the withRecord to use this record field */
+
+ if (withRecord.pointer)
+ withRecord.index += tknPtr->sParm.r.offset;
+ else
+ withRecord.offset += tknPtr->sParm.r.offset;
+
+ withRecord.parent = tknPtr->sParm.r.parent;
+
+ /* Skip over the sRECORD_OBJECT */
+
+ getToken();
+ }
+
+ /* Anything else is an error */
+
+ else
+ {
+ error(eRECORDVAR);
+ break;
+ }
+
+
+ /* Check if there are multiple variables in the WITH statement */
+
+ if (token == ',') getToken();
+ else break;
+ }
+
+ /* Verify that the RECORD list is terminated with DO */
+
+ if (token != tDO) error (eDO);
+ else getToken();
+
+ /* Then process the statement following the WITH */
+
+ statement();
+
+ /* Restore the previous value of the withRecord */
+
+ withRecord = saveWithRecord;
+}
+
+/***********************************************************************/
+
diff --git a/misc/pascal/pascal/pstm.h b/misc/pascal/pascal/pstm.h
new file mode 100644
index 000000000..5215b7a10
--- /dev/null
+++ b/misc/pascal/pascal/pstm.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * pstm.h
+ * External Declarations associated with pstm.c
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PSTM_H
+#define __PSTM_H
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void statement (void); /* Process Statement */
+extern void compoundStatement (void); /* Compound statement */
+
+#endif /* __PSTM_H */
diff --git a/misc/pascal/pascal/ptbl.c b/misc/pascal/pascal/ptbl.c
new file mode 100644
index 000000000..e77652aec
--- /dev/null
+++ b/misc/pascal/pascal/ptbl.c
@@ -0,0 +1,692 @@
+/***************************************************************
+ * ptbl.c
+ * Table Management Package
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************/
+
+/***************************************************************
+ * Included Files
+ ***************************************************************/
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "keywords.h"
+#include "pasdefs.h"
+#include "ptdefs.h"
+#include "pedefs.h"
+
+#include "pas.h"
+#include "ptbl.h"
+#include "perr.h"
+
+/***************************************************************
+ * Private Function Prototypes
+ ***************************************************************/
+
+static STYPE *addSymbol(char *name, int16_t type);
+
+/***************************************************************
+ * Public Variables
+ ***************************************************************/
+
+STYPE *parentInteger = NULL;
+STYPE *parentString = NULL;
+
+/***************************************************************
+ * Private Variables
+ ***************************************************************/
+/* NOTES in the following:
+ * (1) Standard Pascal reserved word
+ * (2) Standard Pascal Function
+ * (3) Standard Pascal Procedure
+ * (4) Extended (or non-standard) Pascal reserved word
+ * (5) Extended (or non-standard) Pascal function
+ * (6) Extended (or non-standard) Pascal procedure
+ */
+
+static const RTYPE rsw[] = /* Reserved word list */
+{
+ {"ABS", tFUNC, txABS}, /* (2) */
+ {"AND", tAND, txNONE}, /* (1) */
+ {"ARCTAN", tFUNC, txARCTAN}, /* (2) */
+ {"ARRAY", tARRAY, txNONE}, /* (1) */
+ {"BEGIN", tBEGIN, txNONE}, /* (1) */
+ {"CASE", tCASE, txNONE}, /* (1) */
+ {"CHR", tFUNC, txCHR}, /* (2) */
+ {"CONST", tCONST, txNONE}, /* (1) */
+ {"COS", tFUNC, txCOS}, /* (2) */
+ {"DIV", tDIV, txNONE}, /* (1) */
+ {"DO", tDO, txNONE}, /* (1) */
+ {"DOWNTO", tDOWNTO, txNONE}, /* (1) */
+ {"ELSE", tELSE, txNONE}, /* (1) */
+ {"END", tEND, txNONE}, /* (1) */
+ {"EOF", tFUNC, txEOF}, /* (2) */
+ {"EOLN", tFUNC, txEOLN}, /* (2) */
+ {"EXP", tFUNC, txEXP}, /* (2) */
+ {"FILE", tFILE, txNONE}, /* (1) */
+ {"FOR", tFOR, txNONE}, /* (1) */
+ {"FUNCTION", tFUNCTION, txNONE}, /* (1) */
+ {"GET", tPROC, txGET}, /* (3) */
+ {"GETENV", tFUNC, txGETENV}, /* (5) */
+ {"GOTO", tGOTO, txNONE}, /* (1) */
+ {"IF", tIF, txNONE}, /* (1) */
+ {"IMPLEMENTATION", tIMPLEMENTATION, txNONE}, /* (4) */
+ {"IN", tIN, txNONE}, /* (1) */
+ {"INTERFACE", tINTERFACE, txNONE}, /* (4) */
+ {"LABEL", tLABEL, txNONE}, /* (1) */
+ {"LN", tFUNC, txLN}, /* (2) */
+ {"MOD", tMOD, txNONE}, /* (1) */
+ {"NEW", tPROC, txNEW}, /* (3) */
+ {"NOT", tNOT, txNONE}, /* (1) */
+ {"ODD", tFUNC, txODD}, /* (2) */
+ {"OF", tOF, txNONE}, /* (1) */
+ {"OR", tOR, txNONE}, /* (1) */
+ {"ORD", tFUNC, txORD}, /* (2) */
+ {"PACK", tPROC, txPACK}, /* (3) */
+ {"PACKED", tPACKED, txNONE}, /* (1) */
+ {"PAGE", tPROC, txPAGE}, /* (3) */
+ {"PRED", tFUNC, txPRED}, /* (2) */
+ {"PROCEDURE", tPROCEDURE, txNONE}, /* (1) */
+ {"PROGRAM", tPROGRAM, txNONE}, /* (1) */
+ {"PUT", tPROC, txPUT}, /* (3) */
+ {"READ", tPROC, txREAD}, /* (3) */
+ {"READLN", tPROC, txREADLN}, /* (3) */
+ {"RECORD", tRECORD, txNONE}, /* (1) */
+ {"REPEAT", tREPEAT, txNONE}, /* (1) */
+ {"RESET", tPROC, txRESET}, /* (3) */
+ {"REWRITE", tPROC, txREWRITE}, /* (3) */
+ {"ROUND", tFUNC, txROUND}, /* (2) */
+ {"SET", tSET, txNONE}, /* (1) */
+ {"SHL", tSHL, txNONE}, /* (4) */
+ {"SHR", tSHR, txNONE}, /* (4) */
+ {"SIN", tFUNC, txSIN}, /* (2) */
+ {"SQR", tFUNC, txSQR}, /* (2) */
+ {"SQRT", tFUNC, txSQRT}, /* (2) */
+ {"SUCC", tFUNC, txSUCC}, /* (2) */
+ {"THEN", tTHEN, txNONE}, /* (1) */
+ {"TO", tTO, txNONE}, /* (1) */
+ {"TRUNC", tFUNC, txTRUNC}, /* (2) */
+ {"TYPE", tTYPE, txNONE}, /* (1) */
+ {"UNIT", tUNIT, txNONE}, /* (4) */
+ {"UNPACK", tPROC, txUNPACK}, /* (3) */
+ {"UNTIL", tUNTIL, txNONE}, /* (1) */
+ {"USES", tUSES, txNONE}, /* (4) */
+ {"VAL", tPROC, txVAL}, /* (6) */
+ {"VAR", tVAR, txNONE}, /* (1) */
+ {"WHILE", tWHILE, txNONE}, /* (1) */
+ {"WITH", tWITH, txNONE}, /* (1) */
+ {"WRITE", tPROC, txWRITE}, /* (3) */
+ {"WRITELN", tPROC, txWRITELN}, /* (3) */
+ {NULL, 0, txNONE} /* List terminator */
+};
+
+static STYPE *symbolTable; /* Symbol Table */
+
+/**************************************************************/
+
+const RTYPE *findReservedWord (char *name)
+{
+ register const RTYPE *ptr; /* Point into reserved word list */
+ register int16_t cmp; /* 0=equal; >0=past it */
+
+ for (ptr = rsw; (ptr->rname); ptr++) /* Try each each reserved word */
+ {
+ cmp = strcmp(ptr->rname, name); /* Check if names match */
+ if (!cmp) /* Check if names match */
+ return ptr; /* Return pointer to entry if match */
+ else if (cmp > 0) /* Exit early if we are past it */
+ break;
+ } /* end for */
+
+ return (RTYPE*)NULL; /* return NULL pointer if no match */
+
+} /* fnd findReservedWord */
+
+/***************************************************************/
+
+STYPE *findSymbol (char *inName)
+{
+ register int16_t i; /* loop index */
+
+ for (i=nsym-1; i>=sym_strt; i--)
+ if (symbolTable[i].sName)
+ if (!strcmp(symbolTable[i].sName, inName))
+ return &symbolTable[i];
+ return (STYPE*)NULL;
+
+} /* end findSymbol */
+
+/***************************************************************/
+
+static STYPE *addSymbol(char *name, int16_t type)
+{
+ TRACE(lstFile,"[addSymbol]");
+
+ /* Check for Symbol Table overflow */
+ if (nsym >= MAX_SYM) {
+
+ fatal(eOVF);
+ return (STYPE *)NULL;
+
+ } /* end if */
+ else {
+
+ /* Clear all elements of the symbol table entry */
+ memset(&symbolTable[nsym], 0, sizeof(STYPE));
+
+ /* Set the elements which are independent of sKind */
+ symbolTable[nsym].sName = name;
+ symbolTable[nsym].sKind = type;
+ symbolTable[nsym].sLevel = level;
+
+ return &symbolTable[nsym++];
+
+ } /* end else */
+
+} /* end addSymbol */
+
+/***************************************************************/
+
+STYPE *addTypeDefine(char *name, uint8_t type, uint16_t size, STYPE *parent)
+{
+ STYPE *typePtr;
+
+ TRACE(lstFile,"[addTypeDefine]");
+
+ /* Get a slot in the symbol table */
+
+ typePtr = addSymbol(name, sTYPE);
+ if (typePtr)
+ {
+ /* Add the type definition to the symbol table
+ * NOTES:
+ * 1. The minValue and maxValue fields (for scalar and subrange)
+ * types must be set external to this function
+ * 2. For most variables, allocated size/type (rsize/rtype) and
+ * the clone size/type are the same. If this is not the case,
+ * external logic will need to clarify this as well.
+ * 3. We assume that there are no special flags associated with
+ * the type.
+ */
+
+ typePtr->sParm.t.type = type;
+ typePtr->sParm.t.rtype = type;
+ typePtr->sParm.t.flags = 0;
+ typePtr->sParm.t.asize = size;
+ typePtr->sParm.t.rsize = size;
+ typePtr->sParm.t.parent = parent;
+
+ } /* end if */
+
+ /* Return a pointer to the new constant symbol */
+
+ return typePtr;
+
+} /* end addTypeDefine */
+
+/***************************************************************/
+
+STYPE *addConstant(char *name, uint8_t type, int32_t *value, STYPE *parent)
+{
+ STYPE *constPtr;
+
+ TRACE(lstFile,"[addConstant]");
+
+ /* Get a slot in the symbol table */
+ constPtr = addSymbol(name, type);
+ if (constPtr) {
+
+ /* Add the value of the constant to the symbol table */
+ if (type == tREAL_CONST)
+ constPtr->sParm.c.val.f = *((double*) value);
+ else
+ constPtr->sParm.c.val.i = *value;
+ constPtr->sParm.c.parent = parent;
+
+ } /* end if */
+
+ /* Return a pointer to the new constant symbol */
+
+ return constPtr;
+
+} /* end addConstant */
+
+/***************************************************************/
+
+STYPE *addStringConst(char *name, uint32_t offset, uint32_t size)
+{
+ STYPE *stringPtr;
+
+ TRACE(lstFile,"[addStringConst]");
+
+ /* Get a slot in the symbol table */
+
+ stringPtr = addSymbol(name, sSTRING_CONST);
+ if (stringPtr)
+ {
+ /* Add the value of the constant to the symbol table */
+
+ stringPtr->sParm.s.offset = offset;
+ stringPtr->sParm.s.size = size;
+ } /* end if */
+
+ /* Return a pointer to the new string symbol */
+
+ return stringPtr;
+
+} /* end addString */
+
+/***************************************************************/
+
+STYPE *addFile(char *name, uint16_t fileNumber)
+{
+ STYPE *filePtr;
+
+ TRACE(lstFile,"[addFile]");
+
+ /* Get a slot in the symbol table */
+ filePtr = addSymbol(name, sFILE);
+ if (filePtr) {
+
+ /* Add the fileNumber to the symbol table */
+ filePtr->sParm.fileNumber = fileNumber;
+
+ } /* end if */
+
+ /* Return a pointer to the new file symbol */
+
+ return filePtr;
+
+} /* end addFile */
+
+/***************************************************************/
+
+STYPE *addProcedure(char *name, uint8_t type, uint16_t label,
+ uint16_t nParms, STYPE *parent)
+{
+ STYPE *procPtr;
+
+ TRACE(lstFile,"[addProcedure]");
+
+ /* Get a slot in the symbol table */
+ procPtr = addSymbol(name, type);
+ if (procPtr)
+ {
+ /* Add the procedure/function definition to the symbol table */
+
+ procPtr->sParm.p.label = label;
+ procPtr->sParm.p.nParms = nParms;
+ procPtr->sParm.p.flags = 0;
+ procPtr->sParm.p.symIndex = 0;
+ procPtr->sParm.p.parent = parent;
+ } /* end if */
+
+ /* Return a pointer to the new procedure/function symbol */
+
+ return procPtr;
+
+} /* end addProcedure */
+
+/***************************************************************/
+
+STYPE *addVariable(char *name, uint8_t type, uint16_t offset,
+ uint16_t size, STYPE *parent)
+{
+ STYPE *varPtr;
+
+ TRACE(lstFile,"[addVariable]");
+
+ /* Get a slot in the symbol table */
+
+ varPtr = addSymbol(name, type);
+ if (varPtr)
+ {
+ /* Add the variable to the symbol table */
+
+ varPtr->sParm.v.offset = offset;
+ varPtr->sParm.v.size = size;
+ varPtr->sParm.v.flags = 0;
+ varPtr->sParm.v.symIndex = 0;
+ varPtr->sParm.v.parent = parent;
+ } /* end if */
+
+ /* Return a pointer to the new variable symbol */
+
+ return varPtr;
+
+} /* end addFile */
+
+/***************************************************************/
+
+STYPE *addLabel(char *name, uint16_t label)
+{
+ STYPE *labelPtr;
+
+ TRACE(lstFile,"[addLabel]");
+
+ /* Get a slot in the symbol table */
+
+ labelPtr = addSymbol(name, sLABEL);
+ if (labelPtr)
+ {
+ /* Add the label to the symbol table */
+
+ labelPtr->sParm.l.label = label;
+ labelPtr->sParm.l.unDefined = true;
+ } /* end if */
+
+ /* Return a pointer to the new label symbol */
+
+ return labelPtr;
+
+} /* end addFile */
+
+/***************************************************************/
+
+STYPE *addField(char *name, STYPE *record)
+{
+ STYPE *fieldPtr;
+
+ TRACE(lstFile,"[addField]");
+
+ /* Get a slot in the symbol table */
+ fieldPtr = addSymbol(name, sRECORD_OBJECT);
+ if (fieldPtr) {
+
+ /* Add the field to the symbol table */
+ fieldPtr->sParm.r.record = record;
+
+ } /* end if */
+
+ /* Return a pointer to the new variable symbol */
+
+ return fieldPtr;
+
+} /* end addField */
+
+/***************************************************************/
+
+void primeSymbolTable(unsigned long symbolTableSize)
+{
+ int32_t trueValue = -1;
+ int32_t falseValue = 0;
+ int32_t maxintValue = MAXINT;
+ STYPE *typePtr;
+ register int16_t i;
+
+ TRACE(lstFile,"[primeSymbolTable]");
+
+ /* Allocate and initialize symbol table */
+
+ symbolTable = malloc(symbolTableSize * sizeof(STYPE));
+ if (!symbolTable)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ nsym = 0;
+
+ /* Add the standard constants to the symbol table */
+
+ (void)addConstant("TRUE", tBOOLEAN_CONST, &trueValue, NULL);
+ (void)addConstant("FALSE", tBOOLEAN_CONST, &falseValue, NULL);
+ (void)addConstant("MAXINT", tINT_CONST, &maxintValue, NULL);
+ (void)addConstant("NIL", tNIL, &falseValue, NULL);
+
+ /* Add the standard types to the symbol table */
+
+ typePtr = addTypeDefine("INTEGER", sINT, sINT_SIZE, NULL);
+ if (typePtr)
+ {
+ parentInteger = typePtr;
+ typePtr->sParm.t.minValue = MININT;
+ typePtr->sParm.t.maxValue = MAXINT;
+ } /* end if */
+
+ typePtr = addTypeDefine("BOOLEAN", sBOOLEAN, sBOOLEAN_SIZE, NULL);
+ if (typePtr)
+ {
+ typePtr->sParm.t.minValue = falseValue;
+ typePtr->sParm.t.maxValue = trueValue;
+ } /* end if */
+
+ typePtr = addTypeDefine("REAL", sREAL, sREAL_SIZE, NULL);
+
+ typePtr = addTypeDefine("CHAR", sCHAR, sCHAR_SIZE, NULL);
+ if (typePtr)
+ {
+ typePtr->sParm.t.minValue = MINCHAR;
+ typePtr->sParm.t.maxValue = MAXCHAR;
+ } /* end if */
+
+ typePtr = addTypeDefine("TEXT", sFILE_OF, sCHAR_SIZE, NULL);
+ if (typePtr)
+ {
+ typePtr->sParm.t.subType = sCHAR;
+ typePtr->sParm.t.minValue = MINCHAR;
+ typePtr->sParm.t.maxValue = MAXCHAR;
+ } /* end if */
+
+ /* Add some enhanced Pascal standard" types to the symbol table
+ *
+ * string is represent by a 256 byte memory regions consisting of
+ * one byte for the valid string length plus 255 bytes for string
+ * storage
+ */
+
+ typePtr = addTypeDefine("STRING", sSTRING, sSTRING_SIZE, NULL);
+ if (typePtr)
+ {
+ parentString = typePtr;
+ typePtr->sParm.t.rtype = sRSTRING;
+ typePtr->sParm.t.subType = sCHAR;
+ typePtr->sParm.t.rsize = sRSTRING_SIZE;
+ typePtr->sParm.t.flags = STYPE_VARSIZE;
+ typePtr->sParm.t.minValue = MINCHAR;
+ typePtr->sParm.t.maxValue = MAXCHAR;
+ } /* end if */
+
+ /* Add the standard files to the symbol table */
+
+ (void)addFile("INPUT", 0);
+ (void)addFile("OUTPUT", 0);
+
+ /* Initialize files table */
+
+ for (i = 0; i <= MAX_FILES; i++)
+ {
+ files [i].defined = 0;
+ files [i].flevel = 0;
+ files [i].ftype = 0;
+ files [i].faddr = 0;
+ files [i].fsize = 0;
+ } /* end for */
+} /* end primeSymbolTable */
+
+/***************************************************************/
+
+void verifyLabels(int32_t symIndex)
+{
+ register int16_t i; /* loop index */
+
+ for (i=symIndex; i < nsym; i++)
+ if ((symbolTable[i].sKind == sLABEL)
+ && (symbolTable[i].sParm.l.unDefined))
+ error (eUNDEFLABEL);
+} /* end verifyLabels */
+
+/***************************************************************/
+
+#if CONFIG_DEBUG
+const char noName[] = "********";
+void dumpTables(void)
+{
+ register int16_t i;
+
+ fprintf(lstFile,"\nSYMBOL TABLE:\n");
+ fprintf(lstFile,"[ Addr ] NAME KIND LEVL\n");
+
+ for (i = 0; i < nsym; i++)
+ {
+ fprintf(lstFile,"[%08lx] ", (uint32_t)&symbolTable[i]);
+
+ if (symbolTable[i].sName)
+ fprintf(lstFile, "%8s", symbolTable[i].sName);
+ else
+ fprintf(lstFile, "%8s", noName);
+
+ fprintf(lstFile," %04x %04x ",
+ symbolTable[i].sKind,
+ symbolTable[i].sLevel);
+
+ switch (symbolTable[i].sKind)
+ {
+ /* Constants */
+
+ case tINT_CONST :
+ case tCHAR_CONST :
+ case tBOOLEAN_CONST :
+ case tNIL :
+ case sSCALAR :
+ fprintf(lstFile, "val=%ld parent=[%08lx]\n",
+ symbolTable[i].sParm.c.val.i,
+ (unsigned long)symbolTable[i].sParm.c.parent);
+ break;
+ case tREAL_CONST :
+ fprintf(lstFile, "val=%f parent=[%08lx]\n",
+ symbolTable[i].sParm.c.val.f,
+ (unsigned long)symbolTable[i].sParm.c.parent);
+ break;
+
+ /* Types */
+
+ case sTYPE :
+ fprintf(lstFile,
+ "type=%02x rtype=%02x subType=%02x flags=%02x "
+ "asize=%ld rsize=%ld minValue=%ld maxValue=%ld "
+ "parent=[%08lx]\n",
+ symbolTable[i].sParm.t.type,
+ symbolTable[i].sParm.t.rtype,
+ symbolTable[i].sParm.t.subType,
+ symbolTable[i].sParm.t.flags,
+ symbolTable[i].sParm.t.asize,
+ symbolTable[i].sParm.t.rsize,
+ symbolTable[i].sParm.t.minValue,
+ symbolTable[i].sParm.t.maxValue,
+ (unsigned long)symbolTable[i].sParm.t.parent);
+ break;
+
+ /* Procedures/Functions */
+
+ /* Procedures and Functions */
+
+ case sPROC :
+ case sFUNC :
+ fprintf(lstFile,
+ "label=L%04x nParms=%d flags=%02x parent=[%08lx]\n",
+ symbolTable[i].sParm.p.label,
+ symbolTable[i].sParm.p.nParms,
+ symbolTable[i].sParm.p.flags,
+ (unsigned long)symbolTable[i].sParm.p.parent);
+ break;
+
+ /* Labels */
+
+ case sLABEL :
+ fprintf(lstFile, "label=L%04x unDefined=%d\n",
+ symbolTable[i].sParm.l.label,
+ symbolTable[i].sParm.l.unDefined);
+ break;
+
+ /* Files */
+
+ case sFILE :
+ fprintf(lstFile, "fileNumber=%d\n",
+ symbolTable[i].sParm.fileNumber);
+ break;
+
+ /* Variables */
+
+ case sINT :
+ case sBOOLEAN :
+ case sCHAR :
+ case sREAL :
+ case sTEXT :
+ case sARRAY :
+ case sPOINTER :
+ case sVAR_PARM :
+ case sRECORD :
+ case sFILE_OF :
+ fprintf(lstFile, "offset=%ld size=%ld flags=%02x parent=[%08lx]\n",
+ symbolTable[i].sParm.v.offset,
+ symbolTable[i].sParm.v.size,
+ symbolTable[i].sParm.v.flags,
+ (unsigned long)symbolTable[i].sParm.v.parent);
+ break;
+
+ /* Record objects */
+
+ case sRECORD_OBJECT :
+ fprintf(lstFile,
+ "offset=%ld size=%ld record=[%08lx] parent=[%08lx]\n",
+ symbolTable[i].sParm.r.offset,
+ symbolTable[i].sParm.r.size,
+ (unsigned long)symbolTable[i].sParm.r.record,
+ (unsigned long)symbolTable[i].sParm.r.parent);
+ break;
+
+ /* Constant strings */
+
+ case sSTRING_CONST :
+ fprintf(lstFile, "offset=%04lx size=%ld\n",
+ symbolTable[i].sParm.s.offset,
+ symbolTable[i].sParm.s.size);
+ break;
+
+ default :
+ fprintf(lstFile, "Unknown sKind\n");
+ break;
+
+ } /* end switch */
+ } /* end for */
+
+} /* end dumpTables */
+#endif
+
+/***************************************************************/
+
diff --git a/misc/pascal/pascal/ptbl.h b/misc/pascal/pascal/ptbl.h
new file mode 100644
index 000000000..906a3d9ee
--- /dev/null
+++ b/misc/pascal/pascal/ptbl.h
@@ -0,0 +1,79 @@
+/***************************************************************************
+ * ptbl.h
+ * External Declarations associated with ptbl.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PTBL_H
+#define __PTBL_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+#include "config.h"
+
+/***************************************************************************
+ * Global Variables
+ ***************************************************************************/
+
+extern STYPE *parentInteger;
+extern STYPE *parentString;
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern const RTYPE *findReservedWord (char *name);
+extern STYPE *findSymbol (char *inName);
+extern STYPE *addTypeDefine (char *name, uint8_t type, uint16_t size,
+ STYPE *parent);
+extern STYPE *addConstant (char *name, uint8_t type, int32_t *value,
+ STYPE *parent);
+extern STYPE *addStringConst (char *name, uint32_t offset, uint32_t size);
+extern STYPE *addFile (char *name, uint16_t fileNumber);
+extern STYPE *addLabel (char *name, uint16_t label);
+extern STYPE *addProcedure (char *name, uint8_t type, uint16_t label,
+ uint16_t nParms, STYPE *parent);
+extern STYPE *addVariable (char *name, uint8_t type, uint16_t offset,
+ uint16_t size, STYPE *parent);
+extern STYPE *addField (char *name, STYPE *record);
+extern void primeSymbolTable (unsigned long symbolTableSize);
+extern void verifyLabels (int32_t symIndex);
+
+#if CONFIG_DEBUG
+extern void dumpTables (void);
+#endif
+
+#endif /* __PTBL_H */
diff --git a/misc/pascal/pascal/ptdefs.h b/misc/pascal/pascal/ptdefs.h
new file mode 100644
index 000000000..7d3ce55c1
--- /dev/null
+++ b/misc/pascal/pascal/ptdefs.h
@@ -0,0 +1,209 @@
+/***********************************************************************
+ * ptdefs.h
+ * Token and Symbol Table Definitions
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************************************/
+
+#ifndef __PTDEFS_H
+#define __PTDEFS_H
+
+/***********************************************************************/
+/* Token Values 0-0x20 reserved for get_token identification */
+
+#define tIDENT 0x01
+#define tINT_CONST 0x02
+#define tCHAR_CONST 0x03
+#define tBOOLEAN_CONST 0x04
+#define tREAL_CONST 0x05
+#define tSTRING_CONST 0x06
+
+#define tLE 0x07
+#define tGE 0x08
+#define tASSIGN 0x09
+#define tSUBRANGE 0x0A
+
+/* Token Values 0x21-0x2F (except 0x24) are for ASCII character tokens */
+
+#define tNE ('#')
+#define SQUOTE 0x27
+#define tMUL ('*')
+#define tFDIV ('/')
+
+/* Token Values 0x30-0x39 are spare */
+/* Token Values 0x3A-0x40 are for ASCII character tokens */
+
+#define tLT ('<')
+#define tEQ ('=')
+#define tGT ('>')
+
+/* Token Values 0x41-0x5A are SYMBOL TABLE definitions */
+
+#define sPROC 0x41
+#define sFUNC 0x42
+#define sLABEL 0x43
+#define sTYPE 0x44
+#define sFILE 0x45
+#define sINT 0x46
+#define sBOOLEAN 0x47
+#define sCHAR 0x48
+#define sREAL 0x49
+#define sTEXT 0x4a
+#define sSTRING 0x4b /* String storage type */
+#define sRSTRING 0x4c /* String reference type */
+#define sSTRING_CONST 0x4d
+#define sPOINTER 0x4e
+#define sSCALAR 0x4f
+#define sSCALAR_OBJECT 0x50
+#define sSUBRANGE 0x51
+#define sSET_OF 0x52
+#define sARRAY 0x53
+#define sRECORD 0x54
+#define sRECORD_OBJECT 0x55
+#define sFILE_OF 0x56
+#define sVAR_PARM 0x57
+
+/* Token Values 0x5B-0x60 (except 0x5F) are for ASCII character tokens */
+/* Token Values 0x61-0x7a are SYMBOL TABLE definitions */
+
+/* Token Values 0x7b-0x7f are for ASCII character tokens */
+/* Token Value 0x7f is spare */
+
+/* Token Values 0x80-0xef are for RESERVED WORDS */
+
+/* Standard constants (TRUE, FALSE, MAXINT) and standard files (INPUT, OUTPUT)
+ * are hard initialized into the constant/symbol table and are transparent
+ * to the compiler */
+
+/* Reserved Words 0x80-0xaf*/
+
+#define tAND 0x80
+#define tARRAY 0x81
+#define tBEGIN 0x82
+#define tCASE 0x83
+#define tCONST 0x84
+#define tDIV 0x85
+#define tDO 0x86
+#define tDOWNTO 0x87
+#define tELSE 0x88
+#define tEND 0x89
+#define tFILE 0x8a
+#define tFOR 0x8b
+#define tFUNCTION 0x8c
+#define tGOTO 0x8d
+#define tIF 0x8e
+#define tIMPLEMENTATION 0x08f /* Extended pascal */
+#define tIN 0x90
+#define tINTERFACE 0x91 /* Extended pascal */
+#define tLABEL 0x92
+#define tMOD 0x93
+#define tNIL 0x94
+#define tNOT 0x95
+#define tOF 0x96
+#define tOR 0x97
+#define tPACKED 0x98
+#define tPROCEDURE 0x99
+#define tPROGRAM 0x9a
+#define tRECORD 0x9b
+#define tREPEAT 0x9c
+#define tSET 0x9d
+#define tSHL 0x9e
+#define tSHR 0x9f
+#define tTHEN 0xa0
+#define tTO 0xa1
+#define tTYPE 0xa2
+#define tUNIT 0xa3 /* Extended pascal */
+#define tUNTIL 0xa4
+#define tUSES 0xa5 /* Extended pascal */
+#define tVAR 0xa6
+#define tWHILE 0xa7
+#define tWITH 0xa8
+
+/* The following codes indicate that the token is a built-in procedure
+ * or function recognized by the compiler. An additional code will be
+ * place in tknSubType by the tokenizer to indicate which built-in
+ * procedure or function applies.
+ */
+
+#define tFUNC 0xb0
+#define tPROC 0xb1
+
+/***********************************************************************/
+/* Codes to indentify built-in functions and procedures */
+
+#define txNONE 0x00
+
+/* Standard Functions 0x01-0x1f*/
+
+#define txABS 0x01
+#define txARCTAN 0x02
+#define txCHR 0x03
+#define txCOS 0x04
+#define txEOF 0x05
+#define txEOLN 0x06
+#define txEXP 0x07
+#define txLN 0x08
+#define txODD 0x09
+#define txORD 0x0a
+#define txPRED 0x0b
+#define txROUND 0x0c
+#define txSIN 0x0d
+#define txSQR 0x0e
+#define txSQRT 0x0f
+#define txSUCC 0x10
+#define txTRUNC 0x11
+
+/* "Less than standard" Functions 0x20-0x7f */
+
+#define txGETENV 0x20
+
+/* Standard Procedures 0x81-0xbf */
+
+#define txGET 0x80
+#define txNEW 0x81
+#define txPACK 0x82
+#define txPAGE 0x83
+#define txPUT 0x84
+#define txREAD 0x85
+#define txREADLN 0x86
+#define txRESET 0x87
+#define txREWRITE 0x88
+#define txUNPACK 0x89
+#define txWRITE 0x8a
+#define txWRITELN 0x8b
+
+/* "Less than standard" Procedures 0xc0-0xff */
+
+#define txVAL 0xc0
+
+#endif /* __PTDEFS_H */
+
diff --git a/misc/pascal/pascal/ptkn.c b/misc/pascal/pascal/ptkn.c
new file mode 100644
index 000000000..192f5f817
--- /dev/null
+++ b/misc/pascal/pascal/ptkn.c
@@ -0,0 +1,899 @@
+/***************************************************************
+ * ptkn.c
+ * Tokenization Package
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************/
+
+/***************************************************************
+ * Included Functions
+ ***************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "keywords.h"
+#include "pasdefs.h"
+#include "ptdefs.h"
+#include "pedefs.h"
+
+#include "pas.h"
+#include "ptkn.h"
+#include "ptbl.h"
+#include "perr.h"
+
+/***************************************************************
+ * Private Function Prototypes
+ ***************************************************************/
+
+static void getCharacter (void);
+static void skipLine (void);
+static bool getLine (void);
+static void identifier (void);
+static void string (void);
+static void unsignedNumber (void);
+static void unsignedRealNumber (void);
+static void unsignedExponent (void);
+static void unsignedHexadecimal (void);
+static void unsignedBinary (void);
+
+/***************************************************************
+ * Private Variables
+ ***************************************************************/
+
+static char *strStack; /* String Stack */
+static uint16_t inChar; /* last gotten character */
+
+/***************************************************************
+ * Public Variables
+ ***************************************************************/
+
+char *tkn_strt; /* Start of token in string stack */
+char *stringSP; /* Top of string stack */
+
+/***************************************************************
+ * Public Functions
+ ***************************************************************/
+
+int16_t primeTokenizer(unsigned long stringStackSize)
+{
+ TRACE(lstFile,"[primeTokenizer]");
+
+ /* Allocate and initialize the string stack and stack pointers */
+
+ strStack = malloc(stringStackSize);
+ if (!strStack)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* Initially, everything points to the bottom of the
+ * string stack.
+ */
+
+ tkn_strt = strStack;
+ stringSP = strStack;
+
+ /* Set up for input at the initial level of file parsing */
+
+ rePrimeTokenizer();
+ return 0;
+}
+
+/***************************************************************/
+
+int16_t rePrimeTokenizer(void)
+{
+ TRACE(lstFile,"[rePrimeTokenizer]");
+
+ /* (Re-)set the char pointer to the beginning of the line */
+
+ FP->cp = FP->buffer;
+
+ /* Read the next line from the input stream */
+
+ if (!fgets(FP->cp, LINE_SIZE, FP->stream))
+ {
+ /* EOF.. close file */
+
+ return 1;
+ }
+
+ /* Initialize the line nubmer */
+
+ FP->line = 1;
+
+ /* Get the first character from the new file */
+
+ getCharacter();
+ return 0;
+}
+
+/***************************************************************/
+/* Tell 'em what what the next character will be (if they should
+ * choose to get it). This is similar to getCharacter(), except that
+ * the character pointer is not incremented past the character. The
+ * next time that getCharacter() is called, it will get the character
+ * again.
+ */
+
+char getNextCharacter(bool skipWhiteSpace)
+{
+ /* Get the next character from the line buffer. */
+
+ inChar = *(FP->cp);
+
+ /* If it is the EOL then read the next line from the input file */
+
+ if (!inChar)
+ {
+ /* We have used all of the characters on this line. Read the next
+ * line of data
+ */
+
+ if (getLine())
+ {
+ /* Uh-oh, we are out of data! Just return some bogus value. */
+ inChar = '?';
+
+ } /* end if */
+ else
+ {
+ /* Otherwise, recurse to try again. */
+
+ return getNextCharacter(skipWhiteSpace);
+
+ } /* end else */
+ } /* end if */
+
+ /* If it is a space and we have been told to skip spaces then consume
+ * the input line until a non-space or the EOL is encountered.
+ */
+
+ else if (skipWhiteSpace)
+ {
+ while ((isspace(inChar)) && (inChar))
+ {
+ /* Skip over the space */
+
+ (FP->cp)++;
+
+ /* A get the character after the space */
+
+ inChar = *(FP->cp);
+
+ } /* end while */
+
+ /* If we hit the EOL while searching for the next non-space, then
+ * recurse to try again on the next line
+ */
+
+ if (!inChar)
+ {
+ return getNextCharacter(skipWhiteSpace);
+ }
+ } /* end else if */
+
+ return inChar;
+
+} /* end getNextCharacter */
+
+/***************************************************************/
+
+void getToken(void)
+{
+ /* Skip over leading spaces and comments */
+
+ while (isspace(inChar)) getCharacter();
+
+ /* Point to the beginning of the next token */
+
+ tkn_strt = stringSP;
+
+ /* Process Identifier, Symbol, or Reserved Word */
+
+ if ((isalpha(inChar)) || (inChar == '_'))
+ identifier();
+
+ /* Process Numeric */
+
+ else if (isdigit(inChar))
+ unsignedNumber();
+
+ /* Process string */
+
+ else if (inChar == SQUOTE)
+ string(); /* process string type */
+
+ /* Process ':' or assignment */
+
+ else if (inChar == ':')
+ {
+ getCharacter();
+ if (inChar == '=') {token = tASSIGN; getCharacter();}
+ else token = ':';
+ } /* end else if */
+
+ /* Process '.' or subrange or real-number */
+
+ else if (inChar == '.')
+ {
+ /* Get the character after the '.' */
+
+ getCharacter();
+
+ /* ".." indicates a subrange */
+
+ if (inChar == '.')
+ {
+ token = tSUBRANGE;
+ getCharacter();
+ }
+
+ /* '.' digit is a real number */
+
+ else if (isdigit(inChar))
+ unsignedRealNumber();
+
+ /* Otherwise, it is just a '.' */
+
+ else token = '.';
+ } /* end else if */
+
+ /* Process '<' or '<=' or '<>' or '<<' */
+
+ else if (inChar == '<')
+ {
+ getCharacter();
+ if (inChar == '>') {token = tNE; getCharacter();}
+ else if (inChar == '=') {token = tLE; getCharacter();}
+ else if (inChar == '<') {token = tSHL; getCharacter();}
+ else token = tLT;
+ } /* end else if */
+
+ /* Process '>' or '>=' or '><' or '>>' */
+
+ else if (inChar == '>')
+ {
+ getCharacter();
+ if (inChar == '<') {token = tNE; getCharacter();}
+ else if (inChar == '=') {token = tGE; getCharacter();}
+ else if (inChar == '>') {token = tSHR; getCharacter();}
+ else token = tGT;
+ } /* end else if */
+
+ /* Get Comment -- form { .. } */
+
+ else if (inChar == '{')
+ {
+ do getCharacter(); /* get the next character */
+ while (inChar != '}'); /* loop until end of comment */
+ getCharacter(); /* skip over end of comment */
+ getToken(); /* get the next real token */
+ } /* end else if */
+
+ /* Get comment -- form (* .. *) */
+
+ else if (inChar == '(')
+ {
+ getCharacter(); /* skip over comment character */
+ if (inChar != '*') /* is this a comment? */
+ {
+ token = '('; /* No return '(' leaving the
+ * unprocessed char in inChar */
+ }
+ else
+ {
+ uint16_t lastChar = ' '; /* YES... prime the look behind */
+ for (;;) /* look for end of comment */
+ {
+ getCharacter(); /* get the next character */
+ if ((lastChar == '*') && /* Is it '*)' ? */
+ (inChar == ')'))
+ {
+ break; /* Yes... break out */
+ }
+ lastChar = inChar; /* save the last character */
+ } /* end for */
+
+ getCharacter(); /* skip over the comment end char */
+ getToken(); /* and get the next real token */
+ } /* end else */
+ } /* end else if */
+
+ /* NONSTANDARD: All C/C++-style comments */
+
+ else if (inChar == '/')
+ {
+ getCharacter(); /* skip over comment character */
+ if (inChar == '/') /* C++ style comment? */
+ {
+ skipLine(); /* Yes, skip rest of line */
+ getToken(); /* and get the next real token */
+ }
+ else if (inChar != '*') /* is this a C-style comment? */
+ {
+ token = '/'; /* No return '/' leaving the
+ * unprocessed char in inChar */
+ }
+ else
+ {
+ uint16_t lastChar = ' '; /* YES... prime the look behind */
+ for (;;) /* look for end of comment */
+ {
+ getCharacter(); /* get the next character */
+ if ((lastChar == '*') && /* Is it '*)' ? */
+ (inChar == '/'))
+ {
+ break; /* Yes... break out */
+ }
+ lastChar = inChar; /* save the last character */
+ } /* end for */
+
+ getCharacter(); /* skip over the comment end char */
+ getToken(); /* and get the next real token */
+ } /* end else */
+ } /* end else if */
+
+ /* Check for $XXXX (hex) */
+
+ else if (inChar == '%')
+ unsignedHexadecimal();
+
+ /* Check for $BBBB (binary) */
+
+ else if (inChar == '%')
+ unsignedBinary();
+
+ /* if inChar is an ASCII character then return token = character */
+
+ else if (isascii(inChar))
+ {
+ token = inChar;
+ getCharacter();
+ } /* end else if */
+
+ /* Otherwise, discard the character and try again */
+
+ else
+ {
+ getCharacter();
+ getToken();
+ } /* end else */
+
+ DEBUG(lstFile,"[%02x]", token);
+
+} /* End getToken */
+
+/***************************************************************
+ * Private Functions
+ ***************************************************************/
+
+static void identifier(void)
+{
+ const RTYPE *rptr; /* Pointer to reserved word */
+
+ tknSubType = txNONE; /* Initialize */
+
+ /* Concatenate identifier */
+
+ do
+ {
+ *stringSP++ = toupper(inChar); /* concatenate char */
+ getCharacter(); /* get next character */
+ }
+ while ((isalnum(inChar)) || (inChar == '_'));
+ *stringSP++ = '\0'; /* make ASCIIZ string */
+
+ /* Check if the identifier is a reserved word */
+
+ rptr = findReservedWord(tkn_strt);
+ if (rptr)
+ {
+ token = rptr->rtype; /* get type from rsw table */
+ tknSubType = rptr->subtype; /* get subtype from rsw table */
+ stringSP = tkn_strt; /* pop token from stack */
+ } /* End if */
+
+ /* Check if the identifier is a symbol */
+
+ else
+ {
+ tknPtr = findSymbol(tkn_strt);
+ if (tknPtr)
+ {
+ token = tknPtr->sKind; /* get type from symbol table */
+ stringSP = tkn_strt; /* pop token from stack */
+
+ /* The following assignments only apply to constants. However it
+ * is simpler just to make the assignments than it is to determine
+ * if is appropriate to do so
+ */
+
+ if (token == tREAL_CONST)
+ tknReal = tknPtr->sParm.c.val.f;
+ else
+ tknInt = tknPtr->sParm.c.val.i;
+ } /* End if */
+
+ /* Otherwise, the token is an identifier */
+ else
+ token = tIDENT;
+
+ } /* end else */
+
+} /* End identifier */
+
+/***************************************************************/
+/* Process string */
+
+static void string(void)
+{
+ register int16_t count = 0; /* # chars in string */
+
+ token = tSTRING_CONST; /* indicate string constant type */
+ getCharacter(); /* skip over 1st single quote */
+
+ while (inChar != SQUOTE) /* loop until next single quote */
+ {
+ if (inChar == '\n') /* check for EOL in string */
+ {
+ error(eNOSQUOTE); /* ERROR, terminate string */
+ break;
+ } /* end if */
+ else
+ {
+ *stringSP++ = inChar; /* concatenate character */
+ count++; /* bump count of chars */
+ } /* end else */
+ getCharacter(); /* get the next character */
+ } /* end while */
+ *stringSP++ = '\0'; /* terminate ASCIIZ string */
+
+ getCharacter(); /* skip over last single quote */
+ if (count == 1) /* Check for char constant */
+ {
+ token = tCHAR_CONST; /* indicate char constant type */
+ tknInt = *tkn_strt; /* (integer) value = single char */
+ stringSP = tkn_strt; /* "pop" from string stack */
+ } /* end if */
+} /* end string */
+
+/***************************************************************/
+
+static void getCharacter(void)
+{
+ /* Get the next character from the line buffer. If EOL, get next line */
+
+ inChar = *(FP->cp)++;
+ if (!inChar)
+ {
+ /* We have used all of the characters on this line. Read the next
+ * line of data
+ */
+
+ skipLine();
+ }
+}
+
+/***************************************************************/
+
+static void skipLine(void)
+{
+ if (getLine())
+ {
+ /* Uh-oh, we are out of data! Just return some bogus value. */
+
+ inChar = '?';
+ } /* end if */
+ else
+ {
+ /* Otherwise, get the first character from the line */
+
+ getCharacter();
+ }
+}
+
+/***************************************************************/
+
+static bool getLine(void)
+{
+ bool endOfFile = false;
+
+ /* Reset the character pointer to the start of the new line */
+
+ FP->cp = FP->buffer;
+
+ /* Read the next line from the currently active file */
+
+ if (!fgets(FP->cp, LINE_SIZE, FP->stream))
+ {
+ /* We are at an EOF for this file. Check if we are processing an
+ * included file
+ */
+
+ if (includeIndex > 0)
+ {
+ /* Yes. Close the file */
+
+ closeNestedFile();
+
+ /* Indicate that there is no data on the input line. NOTE:
+ * that FP now refers to the previous file at the next lower
+ * level of nesting.
+ */
+
+ FP->buffer[0] = '\0';
+ } /* end if */
+ else
+ {
+ /* No. We are completely out of data. Return true in this case. */
+
+ endOfFile = true;
+ } /* end else */
+ } /* end if */
+ else
+ {
+ /* We have a new line of data. Increment the line number, then echo
+ * the new line to the list file.
+ */
+
+ (FP->line)++;
+ fprintf(lstFile, "%d:%04ld %s", FP->include, FP->line, FP->buffer);
+ } /* end else */
+
+ return endOfFile;
+
+} /* end getLine */
+
+/***************************************************************/
+
+static void unsignedNumber(void)
+{
+ /* This logic (along with with unsignedRealNumber, and
+ * unsignedRealExponent) handles:
+ *
+ * FORM: integer-number = decimal-integer | hexadecimal-integer |
+ * binary-integer
+ * FORM: decimal-integer = digit-sequence
+ * FORM: real-number =
+ * digit-sequence '.' [digit-sequence] [ exponent scale-factor ] |
+ * '.' digit-sequence [ exponent scale-factor ] |
+ * digit-sequence exponent scale-factor
+ * FORM: exponent = 'e' | 'E'
+ *
+ * When called, inChar is equal to the leading digit of a
+ * digit-sequence. NOTE that the real-number form beginning with
+ * '.' does not use this logic.
+ */
+
+ /* Assume an integer type (might be real) */
+
+ token = tINT_CONST;
+
+ /* Concatenate all digits until an non-digit is found */
+
+ do
+ {
+ *stringSP++ = inChar;
+ getCharacter();
+ }
+ while (isdigit(inChar));
+
+ /* If it is a digit-sequence followed by 'e' (or 'E'), then
+ * continue processing this token as a real number.
+ */
+
+ if ((inChar == 'e') || (inChar == 'E'))
+ {
+ unsignedExponent();
+ }
+
+ /* If the digit-sequence is followed by '.' but not by ".." (i.e.,
+ * this is not a subrange), then switch we are parsing a real time.
+ * Otherwise, convert the integer string to binary.
+ */
+
+ else if ((inChar != '.') || (getNextCharacter(false) == '.'))
+ {
+ /* Terminate the integer string and convert it using sscanf */
+
+ *stringSP++ = '\0';
+ (void)sscanf(tkn_strt, "%ld", &tknInt);
+
+ /* Remove the integer string from the character identifer stack */
+
+ stringSP = tkn_strt;
+ } /* end if */
+ else
+ {
+ /* Its a real value! Now really get the next character and
+ * after the decimal point (this will work whether or not
+ * getNextCharacter() was called). Then process the real number.
+ */
+
+ getCharacter();
+ unsignedRealNumber();
+ } /* end if */
+}
+
+/***************************************************************/
+
+static void unsignedRealNumber(void)
+{
+ /* This logic (along with with unsignedNumber and unsignedExponent)
+ * handles:
+ *
+ * FORM: real-number =
+ * digit-sequence '.' [digit-sequence] [ exponent scale-factor ] |
+ * '.' digit-sequence [ exponent scale-factor ] |
+ * digit-sequence exponent scale-factor
+ * FORM: exponent = 'e' | 'E'
+ *
+ * When called:
+ * - inChar is the character AFTER the '.'.
+ * - Any leading digit-sequence is already in the character stack
+ * - the '.' is not in the character stack.
+ */
+
+ /* Its a real constant */
+
+ token = tREAL_CONST;
+
+ /* Save the decimal point (inChar points to the character after
+ * the decimal point).
+ */
+
+ *stringSP++ = '.';
+
+ /* Now, loop to process the optional digit-sequence after the
+ * decimal point.
+ */
+
+ while (isdigit(inChar))
+ {
+ *stringSP++ = inChar;
+ getCharacter();
+ }
+
+ /* If it is a digit-sequence followed by 'e' (or 'E'), then
+ * continue processing this token as a real number.
+ */
+
+ if ((inChar == 'e') || (inChar == 'E'))
+ {
+ unsignedExponent();
+ }
+ else
+ {
+ /* There is no exponent...
+ * Terminate the real number string and convert it to binay
+ * using sscanf.
+ */
+
+ *stringSP++ = '\0';
+ (void) sscanf(tkn_strt, "%lf", &tknReal);
+ } /* end if */
+
+ /* Remove the number string from the character identifer stack */
+
+ stringSP = tkn_strt;
+}
+
+/***************************************************************/
+
+static void unsignedExponent(void)
+{
+ /* This logic (along with with unsignedNumber and unsignedRealNumber)
+ * handles:
+ *
+ * FORM: real-number =
+ * digit-sequence '.' [digit-sequence] [ exponent scale-factor ] |
+ * '.' digit-sequence [ exponent scale-factor ] |
+ * digit-sequence exponent scale-factor
+ * FORM: exponent = 'e'
+ * FORM: scale-factor = [ sign ] digit-sequence
+ *
+ * When called:
+ * - inChar holds the 'E' (or 'e') exponent
+ * - Any leading digit-sequences or decimal points are already in the
+ * character stack
+ * - the 'E' (or 'e') is not in the character stack.
+ */
+
+ /* Its a real constant */
+
+ token = tREAL_CONST;
+
+ /* Save the decimal point (inChar points to the character after
+ * the decimal point).
+ */
+
+ *stringSP++ = inChar;
+ getCharacter();
+
+ /* Check for an optional sign before the exponent value */
+
+ if ((inChar == '-') || (inChar == '+'))
+ {
+ /* Add the sign to the stack */
+
+ *stringSP++ = inChar;
+ getCharacter();
+ }
+ else
+ {
+ /* Add a '+' sign to the stack */
+
+ *stringSP++ = '+';
+ }
+
+ /* A digit sequence must appear after the exponent and optional
+ * sign.
+ */
+
+ if (!isdigit(inChar))
+ {
+ error(eEXPONENT);
+ tknReal = 0.0;
+ }
+ else
+ {
+ /* Now, loop to process the required digit-sequence */
+
+ do
+ {
+ *stringSP++ = inChar;
+ getCharacter();
+ }
+ while (isdigit(inChar));
+
+ /* Terminate the real number string and convert it to binay
+ * using sscanf.
+ */
+
+ *stringSP++ = '\0';
+ (void) sscanf(tkn_strt, "%lf", &tknReal);
+ }
+
+ /* Remove the number string from the character identifer stack */
+
+ stringSP = tkn_strt;
+}
+
+/***************************************************************/
+
+static void unsignedHexadecimal(void)
+{
+ /* FORM: integer-number = decimal-integer | hexadecimal-integer |
+ * binary-integer
+ * FORM: hexadecimal-integer = '$' hex-digit-sequence
+ * FORM: hex-digit-sequence = hex-digit { hex-digit }
+ * FORM: hex-digit = digit | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
+ *
+ * On entry, inChar is '$'
+ */
+
+ /* This is another representation for an integer */
+
+ token = tINT_CONST;
+
+ /* Loop to process each hex 'digit' */
+
+ for (;;)
+ {
+ /* Get the next character */
+
+ getCharacter();
+
+ /* Is it a decimal digit? */
+
+ if (isdigit(inChar))
+ *stringSP++ = inChar;
+
+ /* Is it a hex 'digit'? */
+
+ else if ((inChar >= 'A') && (inChar <= 'F'))
+ *stringSP++ = inChar;
+
+ else if ((inChar >= 'a') && (inChar <= 'f'))
+ *stringSP++ = _toupper(inChar);
+
+ /* Otherwise, that must be the end of the hex value */
+
+ else break;
+ }
+
+ /* Terminate the hex string and convert to binary using sscanf */
+
+ *stringSP++ = '\0';
+ (void)sscanf(tkn_strt, "%lx", &tknInt);
+
+ /* Remove the hex string from the character identifer stack */
+
+ stringSP = tkn_strt;
+}
+
+/***************************************************************/
+
+static void unsignedBinary(void)
+{
+ uint32_t value;
+
+ /* FORM: integer-number = decimal-integer | hexadecimal-integer |
+ * binary-integer
+ * FORM: binary-integer = '%' binary-digit-sequence
+ * FORM: binary-digit-sequence = binary-digit { binary-digit }
+ * FORM: binary-digit = '0' | '1'
+ *
+ * On entry, inChar is '%'
+ */
+
+ /* This is another representation for an integer */
+
+ token = tINT_CONST;
+
+ /* Loop to process each hex 'digit' */
+
+ value = 0;
+
+ for (;;)
+ {
+ /* Get the next character */
+
+ getCharacter();
+
+ /* Is it a binary 'digit'? */
+
+ if (inChar == '0')
+ value <<= 1;
+
+ else if (inChar == '1')
+ {
+ value <<= 1;
+ value |= 1;
+ }
+
+ /* Otherwise, that must be the end of the binary value */
+
+ else break;
+ }
+
+ /* I don't there there is an sscanf conversion for binary, that's
+ * why we did it above.
+ */
+
+ tknInt = (int32_t)value;
+}
+
+/***************************************************************/
diff --git a/misc/pascal/pascal/ptkn.h b/misc/pascal/pascal/ptkn.h
new file mode 100644
index 000000000..b68533f1f
--- /dev/null
+++ b/misc/pascal/pascal/ptkn.h
@@ -0,0 +1,65 @@
+/***************************************************************************
+ * ptkn.h
+ * External Declarations associated with ptkn.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PTKN_H
+#define __PTKN_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/***************************************************************************
+ * Public Variables
+ ***************************************************************************/
+
+/* String stack access variables */
+
+extern char *tkn_strt; /* Start of token in string stack */
+extern char *stringSP; /* Top of string stack */
+
+/***************************************************************************
+ * Public Function Prototypes
+ ***************************************************************************/
+
+extern void getToken (void);
+extern char getNextCharacter (bool skipWhiteSpace);
+extern int16_t primeTokenizer (unsigned long stringStackSize);
+extern int16_t rePrimeTokenizer (void);
+
+#endif /* __PTKN_H */
diff --git a/misc/pascal/pascal/punit.c b/misc/pascal/pascal/punit.c
new file mode 100644
index 000000000..00b74e18b
--- /dev/null
+++ b/misc/pascal/pascal/punit.c
@@ -0,0 +1,599 @@
+/**********************************************************************
+ * punit.c
+ * Parse a pascal unit file
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h"
+#include "pasdefs.h"
+#include "ptdefs.h"
+#include "podefs.h"
+#include "pedefs.h"
+#include "poff.h" /* FHT_ definitions */
+
+#include "pas.h" /* for globals */
+#include "pblck.h" /* for block(), constantDefinitionGroup(), etc. */
+#include "pgen.h" /* for pas_Generate*() */
+#include "ptkn.h" /* for getToken() */
+#include "ptbl.h" /* for addFile() */
+#include "pofflib.h" /* For poff*() functions*/
+#include "perr.h" /* for error() */
+#include "pprgm.h" /* for usesSection() */
+#include "punit.h"
+
+/***********************************************************************
+ * Pre-processor Definitions
+ ***********************************************************************/
+
+#define intAlign(x) (((x) + (sINT_SIZE-1)) & (~(sINT_SIZE-1)))
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+static void interfaceSection (void);
+static void exportedProcedureHeading (void);
+static void exportedFunctionHeading (void);
+
+/***********************************************************************
+ * Global Functions
+ ***********************************************************************/
+/* This function is called only main() when the first token parsed out
+ * the specified file is 'unit'. In this case, we are parsing a unit file
+ * and generating a unit binary.
+ */
+
+void unitImplementation(void)
+{
+ char *saveTknStart = tkn_strt;
+
+ TRACE(lstFile, "[unitImplementation]");
+
+ /* FORM: unit =
+ * unit-heading ';' interface-section implementation-section
+ * init-section '.'
+ * FORM: unit-heading = 'unit' identifer
+ * FORM: interface-section =
+ * 'interface' [ uses-section ] interface-declaration
+ * FORM: implementation-section =
+ * 'implementation' [ uses-section ] declaration-group
+ * FORM: init-section =
+ * 'initialization statement-sequence
+ * ['finalization' statement-sequence] 'end' |
+ * compound-statement | 'end'
+ *
+ * On entry, the 'unit' keyword has already been parsed. The
+ * current token should point to the identifier following unit.
+ */
+
+ /* Skip over the unit identifier (the caller has already verified
+ * that we are processing the correct unit).
+ */
+
+ if (token != tIDENT) error(eIDENT);
+
+ /* Set a UNIT indication in the output poff file header */
+
+ poffSetFileType(poffHandle, FHT_UNIT, 0, tkn_strt);
+ poffSetArchitecture(poffHandle, FHA_PCODE);
+
+ /* Discard the unit name and get the next token */
+
+ stringSP = saveTknStart;
+ getToken();
+
+ /* Skip over the semicolon separating the unit-heading from the
+ * interface-section.
+ */
+
+ if (token != ';') error(eSEMICOLON);
+ else getToken();
+
+ /* Verify that the interface-section is present
+ * FORM: interface-section =
+ * 'interface' [ uses-section ] interface-declaration
+ */
+
+ interfaceSection();
+
+ /* Verify that the implementation section is present
+ * FORM: implementation-section =
+ * 'implementation' [ uses-section ] declaration-group
+ */
+
+ if (token != tIMPLEMENTATION) error(eIMPLEMENTATION);
+ else getToken();
+
+ FP->section = eIsImplementationSection;
+
+ /* Check for the presence of an optional uses-section */
+
+ if (token == tUSES)
+ {
+ /* Process the uses-section */
+
+ getToken();
+ usesSection();
+ }
+
+ /* Now, process the declaration-group
+ *
+ * FORM: implementation-section =
+ * 'implementation' [ uses-section ] declaration-group
+ * FORM: init-section =
+ * 'initialization statement-sequence
+ * ['finalization' statement-sequence] 'end' |
+ * compound-statement | 'end'
+ */
+
+ declarationGroup(0);
+
+ /* Process the init-section
+ * FORM: init-section =
+ * 'initialization statement-sequence
+ * ['finalization' statement-sequence] 'end' |
+ * compound-statement | 'end'
+ *
+ * Not yet... for now, we only require the 'end'
+ */
+
+ FP->section = eIsInitializationSection;
+ if (token != tEND) error(eEND);
+ else getToken();
+
+ FP->section = eIsOtherSection;
+
+ /* Verify that the unit file ends with a period */
+
+ if (token != '.') error(ePERIOD);
+}
+
+/***********************************************************************/
+/* This logic is called from usersSection after any a uses-section is
+ * encountered in any file at any level. In this case, we are only
+ * going to parse the interface section from the unit file.
+ */
+
+void unitInterface(void)
+{
+ int32_t savedDStack = dstack;
+ TRACE(lstFile, "[unitInterface]");
+
+ /* FORM: unit =
+ * unit-heading ';' interface-section implementation-section
+ * init-section
+ * FORM: unit-heading = 'unit' identifer
+ *
+ * On entry, the 'unit' keyword has already been parsed. The
+ * current token should point to the identifier following unit.
+ */
+
+ /* Skip over the unit identifier (the caller has already verified
+ * that we are processing the correct unit).
+ */
+
+ if (token != tIDENT) error(eIDENT);
+ else getToken();
+
+ /* Skip over the semicolon separating the unit-heading from the
+ * interface-section.
+ */
+
+ if (token != ';') error(eSEMICOLON);
+ else getToken();
+
+ /* Process the interface-section
+ * FORM: interface-section =
+ * 'interface' [ uses-section ] interface-declaration
+ */
+
+ interfaceSection();
+
+ /* Verify that the implementation section is present
+ * FORM: implementation-section =
+ * 'implementation' [ uses-section ] declaration-group
+ */
+
+ if (token != tIMPLEMENTATION) error(eIMPLEMENTATION);
+
+ /* Then just ignore the rest of the file. We'll let the compilation
+ * of the unit file check the correctness of the implementation.
+ */
+
+ FP->section = eIsOtherSection;
+
+ /* If we are generating a program binary, then all variables declared
+ * by this logic a bonafide. But if are generating UNIT binary, then
+ * all variables declared as imported with a relative stack offset.
+ * In this case, we must release any data stack allocated in this
+ * process.
+ */
+
+ dstack = savedDStack;
+}
+
+/***********************************************************************
+ * Private Functions
+ ***********************************************************************/
+
+static void interfaceSection(void)
+{
+ int16_t saveNSym = nsym; /* Save top of symbol table */
+ int16_t saveNConst = nconst; /* Save top of constant table */
+
+ TRACE(lstFile, "[interfaceSection]");
+
+ /* FORM: interface-section =
+ * 'interface' [ uses-section ] interface-declaration
+ *
+ * On entry, the unit-heading keyword has already been parsed. The
+ * current token should point to the identifier following unit.
+ */
+
+ if (token != tINTERFACE) error(eINTERFACE);
+ else getToken();
+
+ FP->section = eIsInterfaceSection;
+
+ /* Check for the presence of an optional uses-section */
+
+ if (token == tUSES)
+ {
+ /* Process the uses-section */
+
+ getToken();
+ usesSection();
+ }
+
+ /* Process the interface-declaration
+ *
+ * FORM: interface-declaration =
+ * [ constant-definition-group ] [ type-definition-group ]
+ * [ variable-declaration-group ] exported-heading
+ */
+
+ /* Process optional constant-definition-group.
+ * FORM: constant-definition-group =
+ * 'const' constant-definition ';' { constant-definition ';' }
+ */
+
+ if (token == tCONST)
+ {
+ const_strt = saveNConst; /* Limit search to present level */
+ getToken(); /* Get identifier */
+ const_strt = 0;
+
+ /* Process constant-definition.
+ * FORM: constant-definition = identifier '=' constant
+ */
+
+ constantDefinitionGroup();
+
+ } /* end if */
+
+ /* Process type-definition-group
+ * FORM: type-definition-group =
+ * 'type' type-definition ';' { type-definition ';' }
+ */
+
+ if (token == tTYPE)
+ {
+ const_strt = saveNConst; /* Limit search to present level */
+ sym_strt = saveNSym;
+ getToken(); /* Get identifier */
+ const_strt = 0;
+ sym_strt = 0;
+
+ /* Process the type-definitions in the type-definition-group
+ * FORM: type-definition = identifier '=' type-denoter
+ */
+
+ typeDefinitionGroup();
+ } /* end if */
+
+ /* Process the optional variable-declaration-group
+ * FORM: variable-declaration-group =
+ * 'var' variable-declaration { ';' variable-declaration }
+ */
+
+ if (token == tVAR)
+ {
+ const_strt = saveNConst; /* Limit search to present level */
+ sym_strt = saveNSym;
+ getToken(); /* Get identifier */
+ const_strt = 0;
+ sym_strt = 0;
+
+ /* Process the variable declarations
+ * FORM: variable-declaration = identifier-list ':' type-denoter
+ * FORM: identifier-list = identifier { ',' identifier }
+ */
+
+ variableDeclarationGroup();
+ } /* end if */
+
+ /* Process the exported-heading
+ *
+ * FORM: exported-heading =
+ * procedure-heading ';' [ directive ] |
+ * function-heading ';' [ directive ]
+ */
+
+ for (;;)
+ {
+ /* FORM: function-heading =
+ * 'function' function-identifier [ formal-parameter-list ]
+ * ':' result-type
+ */
+
+ if (token == tFUNCTION)
+ {
+ const_strt = saveNConst; /* Limit search to present level */
+ sym_strt = saveNSym;
+ getToken(); /* Get identifier */
+ const_strt = 0;
+ sym_strt = 0;
+
+ /* Process the interface declaration */
+
+ exportedFunctionHeading();
+ } /* end if */
+
+ /* FORM: procedure-heading =
+ * 'procedure' procedure-identifier [ formal-parameter-list ]
+ */
+
+ else if (token == tPROCEDURE)
+ {
+ const_strt = saveNConst; /* Limit search to present level */
+ sym_strt = saveNSym;
+ getToken(); /* Get identifier */
+ const_strt = 0;
+ sym_strt = 0;
+
+ /* Process the interface declaration */
+
+ exportedProcedureHeading();
+ } /* end else if */
+ else break;
+ } /* end for */
+
+ /* We are finished with the interface section */
+
+ FP->section = eIsOtherSection;
+}
+
+/* Process Procedure Declaration Block */
+
+static void exportedProcedureHeading(void)
+{
+ uint16_t procLabel = ++label;
+ char *saveChSp;
+ STYPE *procPtr;
+ register int i;
+
+ TRACE(lstFile,"[exportedProcedureHeading]");
+
+ /* FORM: procedure-heading =
+ * 'procedure' identifier [ formal-parameter-list ]
+ * FORM: procedure-identifier = identifier
+ *
+ * On entry, token refers to token AFTER the 'procedure' reserved
+ * word.
+ */
+
+ /* Process the procedure-heading */
+
+ if (token != tIDENT)
+ {
+ error (eIDENT);
+ return;
+ } /* endif */
+
+ procPtr = addProcedure(tkn_strt, sPROC, procLabel, 0, NULL);
+
+ /* Mark the procedure as external */
+
+ procPtr->sParm.p.flags |= SPROC_EXTERNAL;
+
+ /* Save the string stack pointer so that we can release all
+ * formal parameter strings later. Then get the next token.
+ */
+
+ saveChSp = stringSP;
+ getToken();
+
+ /* NOTE: The level associated with the PROCEDURE symbol is the level
+ * At which the procedure was declared. Everything declare within the
+ * PROCEDURE is at the next level
+ */
+
+ level++;
+
+ /* Process parameter list */
+
+ (void)formalParameterList(procPtr);
+
+ if (token != ';') error (eSEMICOLON);
+ else getToken();
+
+ /* If we are compiling a program or unit that "imports" the
+ * procedure then generate the appropriate symbol table entries
+ * in the output file to support relocation when the external
+ * procedure is called.
+ */
+
+ if (includeIndex > 0)
+ {
+ pas_GenerateProcImport(procPtr);
+ }
+
+ /* Destroy formal parameter names */
+
+ for (i = 1; i <= procPtr->sParm.p.nParms; i++)
+ {
+ procPtr[i].sName = NULL;
+ }
+ stringSP = saveChSp;
+
+ /* Drop the level back to where it was */
+
+ level--;
+
+} /* end exportedProcedureHeading */
+
+/***************************************************************/
+/* Process Function Declaration Block */
+
+static void exportedFunctionHeading(void)
+{
+ uint16_t funcLabel = ++label;
+ int16_t parameterOffset;
+ char *saveChSp;
+ STYPE *funcPtr;
+ register int i;
+
+ TRACE(lstFile,"[exportedFunctionHeading]");
+
+ /* FORM: function-declaration =
+ * function-heading ';' directive |
+ * function-heading ';' function-block
+ * FORM: function-heading =
+ * 'function' function-identifier [ formal-parameter-list ]
+ * ':' result-type
+ *
+ * On entry token should lrefer to the function-identifier.
+ */
+
+ /* Verify function-identifier */
+
+ if (token != tIDENT)
+ {
+ error (eIDENT);
+ return;
+ } /* endif */
+
+ funcPtr = addProcedure(tkn_strt, sFUNC, funcLabel, 0, NULL);
+
+ /* Mark the procedure as external */
+
+ funcPtr->sParm.p.flags |= SPROC_EXTERNAL;
+
+ /* NOTE: The level associated with the FUNCTION symbol is the level
+ * At which the procedure was declared. Everything declare within the
+ * PROCEDURE is at the next level
+ */
+
+ level++;
+
+ /* Save the string stack pointer so that we can release all
+ * formal parameter strings later. Then get the next token.
+ */
+
+ saveChSp = stringSP;
+ getToken();
+
+ /* Process parameter list */
+
+ parameterOffset = formalParameterList(funcPtr);
+
+ /* Verify that the parameter list is followed by a colon */
+
+ if (token != ':') error (eCOLON);
+ else getToken();
+
+ /* Get function type, return value type/size and offset to return value */
+
+ if (token == sTYPE)
+ {
+ /* The offset to the return value is the offset to the last
+ * parameter minus the size of the return value (aligned to
+ * multiples of size of INTEGER).
+ */
+
+ parameterOffset -= tknPtr->sParm.t.rsize;
+ parameterOffset = intAlign(parameterOffset);
+
+ /* Save the TYPE for the function */
+
+ funcPtr->sParm.p.parent = tknPtr;
+
+ /* Skip over the result-type token */
+
+ getToken();
+ } /* end if */
+ else
+ {
+ error(eINVTYPE);
+ }
+
+ /* Verify the final semicolon */
+
+ if (token != ';') error (eSEMICOLON);
+ else getToken();
+
+ /* If we are compiling a program or unit that "imports" the
+ * function then generate the appropriate symbol table entries
+ * in the output file to support relocation when the external
+ * function is called.
+ */
+
+ if (includeIndex > 0)
+ {
+ pas_GenerateProcImport(funcPtr);
+ }
+
+ /* Destroy formal parameter names and the function return value name */
+
+ for (i = 1; i <= funcPtr->sParm.p.nParms; i++)
+ {
+ funcPtr[i].sName = ((char *) NULL);
+ }
+ stringSP = saveChSp;
+
+ /* Restore the original level */
+
+ level--;
+
+} /* end exportedFunctionHeading */
diff --git a/misc/pascal/pascal/punit.h b/misc/pascal/pascal/punit.h
new file mode 100644
index 000000000..9a29dd19d
--- /dev/null
+++ b/misc/pascal/pascal/punit.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * punit.h
+ * External Declarations associated with punit.c
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PUNIT_H
+#define __PUNIT_H
+
+/***************************************************************************
+ * Public Types
+ ***************************************************************************/
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void unitImplementation(void);
+extern void unitInterface(void);
+
+#endif /* __PUNIT_H */
diff --git a/misc/pascal/plink/Makefile b/misc/pascal/plink/Makefile
new file mode 100644
index 000000000..d469df559
--- /dev/null
+++ b/misc/pascal/plink/Makefile
@@ -0,0 +1,83 @@
+############################################################################
+# plink/Makefile
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#
+# Directories
+#
+PLINKDIR = ${shell pwd}
+PASCAL = $(PLINKDIR)/..
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+INCDIR = $(PASCAL)/include
+LIBDIR = $(PASCAL)/lib
+BINDIR-$(CONFIG_INSN16) = $(PASCAL)/bin16
+BINDIR-$(CONFIG_INSN32) = $(PASCAL)/bin32
+
+#
+# Objects and targets
+#
+PLINKSRCS = plink.c plsym.c plreloc.c
+PLINKOBJS = $(PLINKSRCS:.c=.o)
+
+OBJS = $(PLINKOBJS)
+
+all: plink
+.PHONY: all plink clean
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+check_libs:
+ @if [ ! -f $(LIBDIR)/libpoff.a ] ; then \
+ echo "$(LIBDIR)/libpoff.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libpas.a ] ; then \
+ echo "$(LIBDIR)/libpas.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libinsn.a ] ; then \
+ echo "$(LIBDIR)/libinsn.a does not exist" ; \
+ exit 1 ; \
+ fi
+
+$(BINDIR-y)/plink: check_libs $(PLINKOBJS)
+ $(CC) -o $@ $(LDFLAGS) $(PLINKOBJS) -linsn -lpoff -lpas
+
+plink: $(BINDIR-y)/plink
+
+clean:
+ $(RM) plink *.o core *~
diff --git a/misc/pascal/plink/plink.c b/misc/pascal/plink/plink.c
new file mode 100644
index 000000000..0e9c15078
--- /dev/null
+++ b/misc/pascal/plink/plink.c
@@ -0,0 +1,551 @@
+/**********************************************************************
+ * plink.c
+ * P-Code Linker
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "podefs.h"
+#include "pedefs.h"
+
+#include "paslib.h"
+#include "perr.h"
+#include "plsym.h"
+#include "plreloc.h"
+#include "pinsn.h"
+#include "plink.h"
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+#define MAX_POFF_FILES 8
+
+/**********************************************************************
+ * Private Type Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Constant Data
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Data
+ **********************************************************************/
+
+static const char *outFileName;
+static const char *inFileName[MAX_POFF_FILES];
+static int nPoffFiles = 0;
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static void showUsage (const char *progname);
+static void parseArgs (int argc, char **argv);
+static void loadInputFiles (poffHandle_t outHandle);
+static void checkFileHeader (poffHandle_t inHandle, poffHandle_t outHandle,
+ uint32_t pcOffset, bool *progFound);
+static uint32_t mergeRoData (poffHandle_t inHandle, poffHandle_t outHandle);
+static uint32_t mergeProgramData (poffHandle_t inHandle, poffHandle_t outHandle,
+ uint32_t pcOffset, uint32_t roOffset);
+static uint32_t mergeFileNames (poffHandle_t inHandle, poffHandle_t outHandle);
+static uint32_t mergeLineNumbers (poffHandle_t inHandle, poffHandle_t outHandle,
+ uint32_t pcOffset, uint32_t fnOffset);
+static void writeOutputFile (poffHandle_t outHandle);
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Public Functions
+ **********************************************************************/
+
+int main(int argc, char *argv[], char *envp[])
+{
+ poffHandle_t outHandle;
+
+ /* Parse the command line arguments */
+
+ parseArgs(argc, argv);
+
+ /* Create a handle to hold the output file data */
+
+ outHandle = poffCreateHandle();
+ if (outHandle == NULL) fatal(eNOMEMORY);
+
+ /* Load the POFF files specified on the command line */
+
+ loadInputFiles(outHandle);
+
+ /* Verify that all symbols were processed correctly */
+
+ verifySymbols();
+
+ /* Apply the relocation data to the program data */
+
+ applyRelocations(outHandle);
+
+ /* Write the symbol table information to the output file */
+
+ writeSymbols(outHandle);
+
+ /* Write the output file */
+
+ writeOutputFile(outHandle);
+
+ /* Release bufferred symbol/relocation informtion */
+
+ releaseSymbols();
+ releaseRelocations();
+
+ /* Release the input file data */
+
+ poffDestroyHandle(outHandle);
+
+ return 0;
+
+} /* end main */
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+static void showUsage(const char *progname)
+{
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s <in-file-name> {<in-file-name>} <out-file-name>\n",
+ progname);
+}
+
+/***********************************************************************/
+
+static void parseArgs(int argc, char **argv)
+{
+ int i;
+
+ /* Check for existence of filename argument */
+
+ if (argc < 3)
+ {
+ fprintf(stderr,
+ "ERROR: <in-file-name> and one <out-file-name> required\n");
+ showUsage(argv[0]);
+ } /* end if */
+
+ /* Get the name of the p-code file(s) from the last argument(s) */
+
+ for (i = 1; i < argc-1; i++)
+ {
+ inFileName[nPoffFiles] = argv[i];
+ nPoffFiles++;
+ }
+
+ /* The last thing on the command line is the output file name */
+
+ outFileName = argv[argc-1];
+}
+
+/***********************************************************************/
+/* This function loads each POFF file specified on the command line,
+ * merges the input POFF data, and generates intermediate structures
+ * to be used in the final link.
+ */
+
+static void loadInputFiles(poffHandle_t outHandle)
+{
+ poffHandle_t inHandle;
+ FILE *instream;
+ char fileName[FNAME_SIZE+1]; /* Object file name */
+ uint32_t pcOffset = 0;
+ uint32_t fnOffset = 0;
+ uint32_t symOffset = 0;
+ uint32_t roOffset = 0;
+ uint32_t pcEnd = 0;
+ uint32_t fnEnd = 0;
+ uint32_t symEnd = 0;
+ uint16_t errCode;
+ bool progFound = false;
+ int i;
+
+ /* Load the POFF files specified on the command line */
+
+ for (i = 0; i < nPoffFiles; i++)
+ {
+ /* Create a handle to hold the input file data */
+
+ inHandle = poffCreateHandle();
+ if (inHandle == NULL) fatal(eNOMEMORY);
+
+ /* Use .o or command line extension, if supplied, to get the
+ * input file name.
+ */
+
+ (void)extension(inFileName[i], "o", fileName, 0);
+
+ /* Open the input file */
+
+ instream = fopen(fileName, "rb");
+ if (instream == NULL)
+ {
+ fprintf(stderr, "ERROR: Could not open %s: %s\n",
+ fileName, strerror(errno));
+ exit(1);
+ }
+
+ /* Load the POFF file */
+
+ errCode = poffReadFile(inHandle, instream);
+ if (errCode != eNOERROR)
+ {
+ fprintf(stderr, "ERROR: Could not read %s (%d)\n",
+ fileName, errCode);
+ exit(1);
+ }
+
+ /* Check file header for critical settings */
+
+ checkFileHeader(inHandle, outHandle, pcOffset, &progFound);
+
+ /* Merge the read-only data sections */
+
+ roOffset = mergeRoData(inHandle, outHandle);
+
+ /* Merge program section data from the new input file into the
+ * output file container.
+ */
+
+ pcEnd = mergeProgramData(inHandle, outHandle, pcOffset, roOffset);
+
+ /* Merge the file name data from the new input file into the
+ * output file container.
+ */
+
+ fnEnd = mergeFileNames(inHandle, outHandle);
+
+ /* Merge the line number data from the new input file into the
+ * output file container.
+ */
+
+ (void)mergeLineNumbers(inHandle, outHandle, pcOffset, fnOffset);
+
+ /* On this pass, we just want to collect all symbol table in a
+ * local list where we can resolve all undefined symbols (later)
+ */
+
+ symEnd = mergeSymbols(inHandle, pcOffset, symOffset);
+
+ /* On this pass, we will also want to buffer all relocation data,
+ * adjusting only the program section offset and sym table
+ * offsets.
+ */
+
+ mergeRelocations(inHandle, pcOffset, symOffset);
+
+ /* Release the input file data */
+
+ insn_ResetOpCodeRead(inHandle);
+ poffDestroyHandle(inHandle);
+
+ /* Close the input file */
+
+ fclose(instream);
+
+ /* Set the offsest to be used for the next file equal
+ * to the end values found from processing this file
+ */
+
+ pcOffset = pcEnd;
+ fnOffset = fnEnd;
+ symOffset = symEnd;
+ }
+
+ /* Did we find exactly one program file? */
+
+ if (!progFound)
+ {
+ /* No! We have to have a program file to generate an executable */
+
+ fprintf(stderr, "ERROR: No program file found in input files\n");
+ exit(1);
+ }
+
+} /* end loadInputFiles */
+
+/***********************************************************************/
+
+static void checkFileHeader(poffHandle_t inHandle, poffHandle_t outHandle,
+ uint32_t pcOffset, bool *progFound)
+{
+ uint8_t fileType;
+
+ /* What kind of file are we processing? */
+
+ fileType = poffGetFileType(inHandle);
+ if (fileType == FHT_PROGRAM)
+ {
+ /* We can handle only one pascal program file */
+
+ if (*progFound)
+ {
+ fprintf(stderr,
+ "ERROR: Only one compiled pascal program file "
+ "may appear in input file list\n");
+ exit(1);
+ }
+ else
+ {
+ /* Get the entry point from the pascal file, apply any
+ * necessary offsets, and store the entry point in the
+ * linked output file's file header.
+ */
+
+ poffSetEntryPoint(outHandle,
+ poffGetEntryPoint(inHandle) + pcOffset);
+
+ /* Copy the program name from the pascal file to the linked
+ * output file's file header and mark the output file as
+ * a pascal executable.
+ */
+
+ poffSetFileType(outHandle, FHT_EXEC, 0,
+ poffGetFileHdrName(inHandle));
+
+ /* Indicate that we have found the program file */
+
+ *progFound = true;
+ }
+ }
+ else if (fileType != FHT_UNIT)
+ {
+ /* It is something other than a compiled pascal program or unit
+ * file.
+ */
+
+ fprintf(stderr,
+ "ERROR: Only compiled pascal program and unit files "
+ "may appear in input file list\n");
+ exit(1);
+ }
+}
+
+/***********************************************************************/
+
+static uint32_t mergeRoData(poffHandle_t inHandle, poffHandle_t outHandle)
+{
+ uint8_t *newRoData;
+ uint32_t oldRoDataSize;
+ uint32_t newRoDataSize;
+
+ /* Get the size of the read-only data section before we add the
+ * new data. This is the offset that must be applied to any
+ * references to the new data.
+ */
+
+ oldRoDataSize = poffGetRoDataSize(outHandle);
+
+ /* Remove the read-only data from new input file */
+
+ newRoDataSize = poffExtractRoData(inHandle, &newRoData);
+
+ /* And append the new read-only data to output file */
+
+ poffAppendRoData(outHandle, newRoData, newRoDataSize);
+
+ return oldRoDataSize;
+}
+
+/***********************************************************************/
+/* This function merges the program data section of a new file into the
+ * program data section of the output file, relocating simple program
+ * section references as they are encountered.
+ */
+
+static uint32_t mergeProgramData(poffHandle_t inHandle,
+ poffHandle_t outHandle,
+ uint32_t pcOffset, uint32_t roOffset)
+{
+ OPTYPE op;
+ uint32_t pc;
+ uint32_t opSize;
+ int endOp;
+
+ /* Read each opcode from the input file, add pcOffset to each program
+ * section address, and add each opcode to the output file.
+ */
+
+ pc = pcOffset;
+ do
+ {
+ /* Read the next opcode (with its size) */
+
+ opSize = insn_GetOpCode(inHandle, &op);
+
+ /* Perform any necessary relocations */
+
+ endOp = insn_Relocate(&op, pcOffset, roOffset);
+
+ /* Save the potentially modified opcode in the temporary
+ * program data container.
+ */
+
+ insn_AddOpCode(outHandle, &op);
+ pc += opSize;
+ }
+ while (endOp == 0);
+
+ return pc;
+}
+
+/***********************************************************************/
+/* This function merges the file name section of a new file into the
+ * file name section of the output file, relocating simple program
+ * section references as they are encountered.
+ */
+
+static uint32_t mergeFileNames(poffHandle_t inHandle,
+ poffHandle_t outHandle)
+{
+ int32_t inOffset;
+ uint32_t outOffset;
+ const char *fname;
+
+ do
+ {
+ /* Read each file name from the input File */
+
+ inOffset = poffGetFileName(inHandle, &fname);
+ if (inOffset >= 0)
+ {
+ /* And write it to the output file */
+
+ outOffset = poffAddFileName(outHandle, fname);
+ }
+ }
+ while (inOffset >= 0);
+
+ /* Return the offset to the last file name written to the
+ * output file
+ */
+
+ return outOffset;
+}
+
+/***********************************************************************/
+/* This function merges the line number section of a new file into the
+ * line number section of the output file, relocating simple program
+ * section references as they are encountered.
+ */
+
+static uint32_t mergeLineNumbers(poffHandle_t inHandle,
+ poffHandle_t outHandle,
+ uint32_t pcOffset,
+ uint32_t fnOffset)
+{
+ poffLineNumber_t lineno;
+ int32_t inOffset;
+ uint32_t outOffset;
+
+ do
+ {
+ /* Read each line number from the input File */
+
+ inOffset = poffGetRawLineNumber(inHandle, &lineno);
+ if (inOffset >= 0)
+ {
+ /* And write it to the output file */
+
+ outOffset = poffAddLineNumber(outHandle, lineno.ln_lineno,
+ lineno.ln_fileno + fnOffset,
+ lineno.ln_poffset + pcOffset);
+ }
+ }
+ while (inOffset >= 0);
+
+ /* Return the offset to the last line number written to the
+ * output file
+ */
+
+ return outOffset;
+}
+
+/***********************************************************************/
+
+static void writeOutputFile(poffHandle_t outHandle)
+{
+ FILE *outstream;
+ char fileName[FNAME_SIZE+1]; /* Output file name */
+
+ /* Use .pex or command line extension, if supplied, to get the
+ * input file name.
+ */
+
+ (void)extension(outFileName, "pex", fileName, 0);
+
+ /* Open the output file */
+
+ outstream = fopen(fileName, "wb");
+ if (outstream == NULL)
+ {
+ fprintf(stderr, "ERROR: Could not open %s: %s\n",
+ fileName, strerror(errno));
+ exit(1);
+ }
+
+ /* Write the POFF file */
+
+ (void)poffWriteFile(outHandle, outstream);
+
+ /* Close the output file */
+
+ fclose(outstream);
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/plink/plink.h b/misc/pascal/plink/plink.h
new file mode 100644
index 000000000..d4e88a1f6
--- /dev/null
+++ b/misc/pascal/plink/plink.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * plink.h
+ * External Declarations associated with plink.c
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PLINK_H
+#define __PLINK_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+/***************************************************************************
+ * Global Variables
+ ***************************************************************************/
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+#endif /* __PLINK_H */
diff --git a/misc/pascal/plink/plreloc.c b/misc/pascal/plink/plreloc.c
new file mode 100644
index 000000000..4b9e7e032
--- /dev/null
+++ b/misc/pascal/plink/plreloc.c
@@ -0,0 +1,255 @@
+/**********************************************************************
+ * plreloc.c
+ * Relocation management for the P-Code Linker
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "podefs.h"
+#include "pedefs.h"
+
+#include "pofflib.h"
+#include "paslib.h"
+#include "pinsn.h"
+#include "perr.h"
+#include "plsym.h"
+#include "plreloc.h"
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+#define INITIAL_RELOC_LIST_SIZE (1024*sizeof(poffRelocation_t*))
+#define RELOC_LIST_INCREMENT (256*sizeof(poffRelocation_t*))
+
+/**********************************************************************
+ * Private Types
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static poffRelocation_t *relocList = NULL;
+static uint32_t relocListAlloc = 0;
+static uint32_t nRelocs = 0;
+
+/**********************************************************************
+ * Private Function Prototypes
+
+ **********************************************************************/
+
+static void offsetRelocation(poffRelocation_t *reloc,
+ uint32_t pcOffset, uint32_t symOffset);
+static void addRelocToList(poffRelocation_t *reloc);
+
+/**********************************************************************
+ * Public Functions
+ **********************************************************************/
+
+void mergeRelocations(poffHandle_t inHandle,
+ uint32_t pcOffset, uint32_t symOffset)
+{
+ poffRelocation_t reloc;
+ int32_t index;
+
+ do
+ {
+ /* Read each relocation record from the input File */
+
+ index = poffGetRawRelocation(inHandle, &reloc);
+ if (index >= 0)
+ {
+ /* If the rellocation carries a "payload" that is a program
+ * section offset, then apply the pcOffset value to
+ * that "payload"
+ */
+
+ offsetRelocation(&reloc, pcOffset, symOffset);
+
+ /* Add the relocation to the in-memory relocation list */
+
+ addRelocToList(&reloc);
+ }
+ }
+ while (index >= 0);
+}
+
+/***********************************************************************/
+
+void applyRelocations(poffHandle_t outHandle)
+{
+ uint8_t *progData;
+ uint32_t progSize;
+ int i;
+
+ /* Take ownership of the program data image for a little while */
+
+ progSize = poffExtractProgramData(outHandle, &progData);
+
+ /* Process each text data section reloation */
+
+ for (i = 0; i < nRelocs; i++)
+ {
+ poffRelocation_t *reloc = &relocList[i];
+ uint32_t symIndex = RLI_SYM(reloc->rl_info);
+ uint32_t relType = RLI_TYPE(reloc->rl_info);
+ poffLibSymbol_t *sym;
+ uint32_t progIndex;
+
+ switch (relType)
+ {
+ case RLT_PCAL:
+ /* Get the symbol referenced by the relocation. At this
+ * point, we assume that the system has already verified
+ * that there are no undefined symbols.
+ */
+
+ sym = getSymbolByIndex(symIndex);
+
+ /* Get the index to the oPCAL instruction */
+
+ progIndex = reloc->rl_offset;
+
+ /* Sanity checking */
+
+ if (((sym->flags & STF_UNDEFINED) != 0) ||
+ (progIndex > progSize-4))
+ fatal(ePOFFCONFUSION);
+
+ /* Perform the relocation */
+
+ insn_FixupProcedureCall(&progData[progIndex], sym->value);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+
+ /* Return ownership of the program data to the container */
+
+ poffInsertProgramData(outHandle, progData, progSize);
+}
+
+/***********************************************************************/
+
+void releaseRelocations(void)
+{
+ if (relocList) free(relocList);
+ relocList = NULL;
+}
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+static void offsetRelocation(poffRelocation_t *reloc,
+ uint32_t pcOffset, uint32_t symOffset)
+{
+ uint32_t symIndex = RLI_SYM(reloc->rl_info);
+ uint32_t relType = RLI_TYPE(reloc->rl_info);
+
+ switch (relType)
+ {
+ case RLT_PCAL:
+ symIndex += symOffset;
+ reloc->rl_info = RLI_MAKE(symIndex, relType);
+ reloc->rl_offset += pcOffset;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/***********************************************************************/
+/* Add to the linear relocation list. */
+
+static void addRelocToList(poffRelocation_t *reloc)
+{
+ /* Check if we have allocated a relocation buffer yet */
+
+ if (!relocList)
+ {
+ /* No, allocate it now */
+
+ relocList = (poffRelocation_t*)malloc(INITIAL_RELOC_LIST_SIZE);
+ if (!relocList)
+ {
+ fatal(eNOMEMORY);
+ }
+ relocListAlloc = INITIAL_RELOC_LIST_SIZE;
+ }
+
+ /* Check if there is room for a new symbol */
+
+ if ((nRelocs + 1) * sizeof(poffRelocation_t) > relocListAlloc)
+ {
+ uint32_t newAlloc = relocListAlloc + RELOC_LIST_INCREMENT;
+ poffRelocation_t *tmp;
+
+ /* Reallocate the file name buffer */
+
+ tmp = (poffRelocation_t*)realloc(relocList, newAlloc);
+ if (!tmp)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* And set the new size */
+
+ relocListAlloc = newAlloc;
+ relocList = tmp;
+ }
+
+ /* Save the new symbol information in the relocation data */
+
+ relocList[nRelocs] = *reloc;
+ nRelocs++;
+}
+
+/***********************************************************************/
+
diff --git a/misc/pascal/plink/plreloc.h b/misc/pascal/plink/plreloc.h
new file mode 100644
index 000000000..abdb393b1
--- /dev/null
+++ b/misc/pascal/plink/plreloc.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+ * plreloc.h
+ * External Declarations associated with plreloc.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PLRELOC_H
+#define __PLRELOC_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+#include "pofflib.h"
+
+/***************************************************************************
+ * Global Variables
+ ***************************************************************************/
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void mergeRelocations(poffHandle_t inHandle,
+ uint32_t pcOffset, uint32_t symOffset);
+extern void applyRelocations(poffHandle_t outHandle);
+extern void releaseRelocations(void);
+
+#endif /* __PLRELOC_H */
diff --git a/misc/pascal/plink/plsym.c b/misc/pascal/plink/plsym.c
new file mode 100644
index 000000000..3f27f512b
--- /dev/null
+++ b/misc/pascal/plink/plsym.c
@@ -0,0 +1,469 @@
+/**********************************************************************
+ * plsym.c
+ * Symbol management for the P-Code Linker
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "podefs.h"
+#include "pedefs.h"
+
+#include "pofflib.h"
+#include "paslib.h"
+#include "perr.h"
+#include "plsym.h"
+
+/**********************************************************************
+ * Pre-processor Definitions
+ **********************************************************************/
+
+#define INITIAL_SYMBOL_LIST_SIZE (1024*sizeof(symContainer_t*))
+#define SYMBOL_LIST_INCREMENT (256*sizeof(symContainer_t*))
+
+/**********************************************************************
+ * Private Types
+ **********************************************************************/
+
+/* This structure just contains a POFF library symbol */
+
+struct symContainer_s
+{
+ struct symContainer_s *next;
+ struct symContainer_s *prev;
+ poffLibSymbol_t s;
+};
+typedef struct symContainer_s symContainer_t;
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static symContainer_t *symHead = NULL;
+static symContainer_t *symTail = NULL;
+static symContainer_t **symList = NULL;
+static uint32_t symListAlloc = 0;
+
+static int nUndefined = 0;
+static int nMultiplyDefined = 0;
+
+/**********************************************************************
+ * Private Function Prototypes
+
+ **********************************************************************/
+
+static void offsetSymbolValue(poffLibSymbol_t *sym,
+ uint32_t pcOffset);
+static symContainer_t *insertSymbol(poffLibSymbol_t *sym);
+static void addSymbolToList(symContainer_t *symbol,
+ uint32_t index);
+
+/**********************************************************************
+ * Public Functions
+ **********************************************************************/
+
+uint32_t mergeSymbols(poffHandle_t inHandle, uint32_t pcOffset, uint32_t symOffset)
+{
+ poffLibSymbol_t symbol;
+ symContainer_t *container;
+ int32_t inIndex;
+ uint32_t outIndex;
+
+ do
+ {
+ /* Read each symbol from the input File */
+
+ inIndex = poffGetSymbol(inHandle, &symbol);
+ if (inIndex >= 0)
+ {
+ /* If the symbol carries a "payload" that is a program
+ * section offset, then apply the pcOffset value to
+ * that "payload"
+ */
+
+ offsetSymbolValue(&symbol, pcOffset);
+
+ /* Create a container for the symbol information */
+
+ container = insertSymbol(&symbol);
+
+ /* Add the symbol to the linearly indexed list */
+
+ outIndex = inIndex + symOffset;
+ addSymbolToList(container, outIndex);
+ }
+ }
+ while (inIndex >= 0);
+
+ /* Return the offset to the last symbol inserted */
+
+ return outIndex;
+}
+
+/***********************************************************************/
+
+void verifySymbols(void)
+{
+ symContainer_t *sym;
+
+ /* At the conclusion the link, there should be no undefined symbols.
+ * This function simply asserts that condition. It traverses the
+ * symbol container list and if any undefined symbol is found, it
+ * errors out.
+ */
+
+ for (sym = symHead; (sym); sym = sym->next)
+ {
+ if ((sym->s.flags & STF_UNDEFINED) != 0)
+ {
+ fprintf(stderr, "ERROR: Undefined symbol '%s'\n",
+ sym->s.name);
+ nUndefined++;
+ }
+ }
+
+ if (nUndefined) fatal(eUNDEFINEDSYMBOL);
+ if (nMultiplyDefined) fatal(eMULTIDEFSYMBOL);
+}
+
+/***********************************************************************/
+
+void writeSymbols(poffHandle_t outHandle)
+{
+ symContainer_t *sym;
+
+ /* Transfer all buffered symbol information to the output file */
+
+ for (sym = symHead; (sym); sym = sym->next)
+ {
+ (void)poffAddSymbol(outHandle, &sym->s);
+ }
+}
+
+/***********************************************************************/
+
+poffLibSymbol_t *getSymbolByIndex(uint32_t symIndex)
+{
+ if (symIndex * sizeof(symContainer_t*) >= symListAlloc)
+ fatal(ePOFFCONFUSION);
+ return &symList[symIndex]->s;
+}
+
+/***********************************************************************/
+
+void releaseSymbols(void)
+{
+ static symContainer_t *curr;
+ static symContainer_t *next;
+
+ for (curr = symHead; (curr); curr = next)
+ {
+ /* Get the next pointer from the container -- we are going
+ * to deallocate the container!
+ */
+
+ next = curr->next;
+
+ /* Deallocate the name string copy */
+
+ if (curr->s.name) free((void*)curr->s.name);
+
+ /* Free the container */
+
+ free(curr);
+ }
+
+ /* Free the index-able symbol list */
+
+ if (symList) free((void*)symList);
+
+ symHead = NULL;
+ symTail = NULL;
+ symList = NULL;
+}
+
+/**********************************************************************/
+
+static void offsetSymbolValue(poffLibSymbol_t *sym, uint32_t pcOffset)
+{
+ /* Don't do anything with undefined symbols. By definition, these
+ * cannot cannot any meaning values.
+ */
+
+ if ((sym->flags & STF_UNDEFINED) == 0)
+ {
+ switch (sym->type)
+ {
+ case STT_PROC:
+ case STT_FUNC:
+ sym->value += pcOffset;
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+/**********************************************************************/
+
+static inline symContainer_t *makeSymContainer(poffLibSymbol_t *psym)
+{
+ symContainer_t *sym;
+ sym = (symContainer_t*)malloc(sizeof(symContainer_t));
+ if (sym == NULL)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* The next container is not linked to anything yet */
+
+ sym->next = NULL;
+ sym->prev = NULL;
+
+ /* Copy the whole symbol record */
+
+ sym->s = *psym;
+
+ /* Duplicate the symbol name -- the reference in the symbol entry
+ * belongs to the input file and will be lost if/when the input file
+ * is released.
+ */
+
+ if (psym->name)
+ {
+ sym->s.name = strdup(psym->name);
+ }
+ return sym;
+}
+
+static symContainer_t *insertSymbol(poffLibSymbol_t *sym)
+{
+ symContainer_t *prev;
+ symContainer_t *curr;
+ symContainer_t *newsym;
+ int compare;
+
+ /* Find where to insert the symbol */
+
+ for (prev = NULL, curr = symHead; (curr); prev = curr, curr = curr->next)
+ {
+ /* Compare the names of the symbols */
+
+ compare = strcmp(curr->s.name, sym->name);
+
+ /* Break out of the loop if curr->name > sym_name or
+ * if curr->name == sym_name AND the types of the
+ * symbols are the same.
+ */
+
+ if (compare > 0)
+ {
+ /* Break out... curr refers to a symbol AFTER the position
+ * where we want to put the new symbol.
+ */
+
+ break;
+ }
+ else if (compare == 0)
+ {
+ /* The symbols are the same. break out only if the types
+ * are the same or this is where we need to insert the new
+ * symbol (same name different type)
+ */
+
+ if (curr->s.type > sym->type)
+ {
+ compare = 1;
+ break;
+ }
+ else if (curr->s.type == sym->type)
+ {
+ break;
+ }
+ }
+ }
+
+ /* We get here if:
+ * a. curr == NULL meaning that the symbol goes at the end of the
+ * list. (special case, prev == NULL as well. This happens when
+ * the list is empty).
+ * b. curr != NULL mean that the symbol goes between prev and curr
+ * (special cases: (i) compare == 0 meaning that the symbol is
+ * already in the list, or (ii) compare > 0 with prev == NULL
+ * meaning that the new entry goes at the beginning of the list).
+ */
+
+ if (curr == NULL)
+ {
+ /* The symbol goes at the end of the list */
+
+ newsym = makeSymContainer(sym);
+ newsym->next = NULL;
+ newsym->prev = prev;
+ symTail = newsym;
+
+ if (prev)
+ prev->next = newsym;
+ else
+ symHead = newsym;
+ }
+ else if (compare == 0)
+ {
+ /* curr is non-NULL and refers to the same symbol (of the same
+ * type). If both are undefined, then just discard the new
+ * symbol.
+ */
+
+ if ((curr->s.flags & STF_UNDEFINED) != 0)
+ {
+ /* The symbol in the table is undefined */
+
+ if ((sym->flags & STF_UNDEFINED) != 0)
+ {
+ /* Both symbols are undefined. Just ignore the new one */
+ }
+ else
+ {
+ /* The symbol in the table is undefined, but the new
+ * one is defined. Replace the one in the table (retaining
+ * the allocated symbol name).
+ */
+ const char *save = curr->s.name;
+ curr->s = *sym;
+ curr->s.name = save;
+ }
+ }
+ else
+ {
+ /* The symbol in the table is defined */
+
+ if ((sym->flags & STF_UNDEFINED) != 0)
+ {
+ /* But the new symbol is undefined. Just ignore the
+ * new symbol
+ */
+ }
+ else
+ {
+ /* OOPS! both symbols are defined */
+
+ fprintf(stderr,
+ "ERROR: Multiply defined symbol: '%s'\n",
+ sym->name);
+ nMultiplyDefined++;
+ }
+
+ /* In any case, return the pointer to the old container */
+
+ newsym = curr;
+ }
+ }
+ else
+ {
+ /* curr is non-NULL and the symbol goes between prev and curr */
+
+ newsym = makeSymContainer(sym);
+ newsym->next = curr;
+ newsym->prev = prev;
+
+ if (prev)
+ prev->next = newsym;
+ else
+ symHead = newsym;
+ }
+
+ return newsym;
+}
+
+/***********************************************************************/
+/* Add a symbol to the linear symbol table list. This list is necessary
+ * to quickly mapped a symbol index value (as might be found in the
+ * relocation data) to the unique representation of the symbol as
+ * deterimed by insertSymbol().
+ */
+
+static void addSymbolToList(symContainer_t *symbol, uint32_t index)
+{
+ /* Check if we have allocated a symbol table buffer yet */
+
+ if (!symList)
+ {
+ /* No, allocate it now */
+
+ symList = (symContainer_t**)malloc(INITIAL_SYMBOL_LIST_SIZE);
+ if (!symList)
+ {
+ fatal(eNOMEMORY);
+ }
+ symListAlloc = INITIAL_SYMBOL_LIST_SIZE;
+ }
+
+ /* Check if there is room for a new symbol */
+
+ if ((index + 1) * sizeof(symContainer_t*) > symListAlloc)
+ {
+ uint32_t newAlloc = symListAlloc + SYMBOL_LIST_INCREMENT;
+ symContainer_t **tmp;
+
+ /* Reallocate the file name buffer */
+
+ tmp = (symContainer_t**)realloc(symList, newAlloc);
+ if (!tmp)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* And set the new size */
+
+ symListAlloc = newAlloc;
+ symList = tmp;
+ }
+
+ /* Save the new symbol information in the symbol table data */
+
+ symList[index] = symbol;
+}
+
+/***********************************************************************/
+
diff --git a/misc/pascal/plink/plsym.h b/misc/pascal/plink/plsym.h
new file mode 100644
index 000000000..95f047e9d
--- /dev/null
+++ b/misc/pascal/plink/plsym.h
@@ -0,0 +1,62 @@
+/***************************************************************************
+ * plsym.h
+ * External Declarations associated with plsym.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+#ifndef __PLSYM_H
+#define __PLSYM_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <stdint.h>
+#include "pofflib.h"
+
+/***************************************************************************
+ * Global Variables
+ ***************************************************************************/
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern uint32_t mergeSymbols(poffHandle_t inHandle,
+ uint32_t pcOffset, uint32_t symOffset);
+extern void verifySymbols(void);
+extern void writeSymbols(poffHandle_t outHandle);
+extern poffLibSymbol_t *getSymbolByIndex(uint32_t symIndex);
+extern void releaseSymbols(void);
+
+#endif /* __PLSYM_H */
diff --git a/misc/pascal/tests/501-uses.sh b/misc/pascal/tests/501-uses.sh
new file mode 100755
index 000000000..27e105524
--- /dev/null
+++ b/misc/pascal/tests/501-uses.sh
@@ -0,0 +1,84 @@
+#!/bin/sh
+############################################################################
+# tests/501-uses.sh
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#set -x
+
+source ../.config
+
+if [ "${CONFIG_INSN16}" == "y" ]; then
+ BINDIR=bin16
+fi
+if [ "${CONFIG_INSN32}" == "y" ]; then
+ BINDIR=bin32
+fi
+
+PASCAL=../${BINDIR}/pascal
+POPT=../${BINDIR}/popt
+PLINK=../${BINDIR}/plink
+PRUN=../${BINDIR}/prun
+
+PASOPTS=-Isrc
+PRUNOPTS="-t 1024"
+
+FILE1=src/501-unit-cosine
+FILE2=src/501-unit-sine
+FILE3=src/501-unit-data
+FILE4=src/501-uses
+
+FILES="${FILE1}.pas ${FILE2}.pas ${FILE3}.pas ${FILE4}.pas"
+PROG=src/501-uses.pex
+
+for file in ${FILES}; do
+ echo "########${file}########";
+ basefile=`basename ${file} .pas`
+ ${PASCAL} ${PASOPTS} ${file} 2>&1 || rm -f src/${basefile}.o1
+ if [ -f src/${basefile}.o1 ] ; then
+ ${POPT} src/${basefile}.o1 2>&1 || rm -f src/${basefile}.o*
+ fi
+ cat src/${basefile}.err | grep Line
+done
+
+if [ -f ${FILE1}.o ] ; then
+ if [ -f ${FILE2}.o ] ; then
+ if [ -f ${FILE3}.o ] ; then
+ if [ -f ${FILE4}.o ] ; then
+ echo "########${PROG}########";
+ ${PLINK} ${FILE1}.o ${FILE2}.o ${FILE3}.o ${FILE4}.o ${PROG} 2>&1
+ ${PRUN} ${PRUNOPTS} ${PROG} 2>&1 <src/501-uses.inp
+ fi
+ fi
+ fi
+fi
+exit
diff --git a/misc/pascal/tests/debug.sh b/misc/pascal/tests/debug.sh
new file mode 100755
index 000000000..91857853f
--- /dev/null
+++ b/misc/pascal/tests/debug.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+############################################################################
+# debug.sh
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#set -x
+
+source ../.config
+
+if [ "${CONFIG_INSN16}" == "y" ]; then
+ BINDIR=bin16
+fi
+if [ "${CONFIG_INSN32}" == "y" ]; then
+ BINDIR=bin32
+fi
+
+# Tell them how they are supposed to use this script
+function show_usage ()
+{
+ echo "USAGE:"
+ echo " ${0} [OPTION] <pex-file-basename>"
+ echo "OPTIONS:"
+ echo " -t <strstksz>: Select string stack size"
+ echo " -h: Show this text"
+ exit 1
+}
+
+STRSTKSZ=1024
+PEXFILENAME=
+
+# Parse command line
+while [ -n "$1" ]; do
+ case "$1" in
+ -t )
+ STRSTKSZ=$2
+ shift
+ ;;
+ -h )
+ show_usage
+ ;;
+ * )
+ PEXFILENAME=$1
+ ;;
+ esac
+ shift
+done
+
+echo "Using string stack size = ${STRSTKSZ}"
+PRUN=../${BINDIR}/prun
+PRUNOPTS="-d -t ${STRSTKSZ}"
+
+if [ -z "${PEXFILENAME}" ]; then
+ echo "ERROR: No file name provided"
+ exit 1
+fi
+
+PEXBASENAME=`basename ${PEXFILENAME} .pas`
+PEXDIRNAME=`dirname ${PEXFILENAME}`
+if [ "${PEXDIRNAME}" == "." ]; then
+ PEXDIRNAME=src
+fi
+
+PEXFILENAME=${PEXDIRNAME}/${PEXBASENAME}.pex
+if [ ! -f "${PEXFILENAME}" ]; then
+ echo "ERROR: ${PEXFILENAME} does not exist"
+ exit 1
+fi
+
+if [ -f ${PEXDIRNAME}/${PEXBASENAME}.inp ] ; then
+ echo "Test command line arguments:"
+ echo " \"`cat ${PEXDIRNAME}/${PEXBASENAME}.inp`\""
+fi
+
+${PRUN} ${PRUNOPTS} src/${PEXBASENAME}.pex 2>&1
diff --git a/misc/pascal/tests/list.sh b/misc/pascal/tests/list.sh
new file mode 100755
index 000000000..8d599d66e
--- /dev/null
+++ b/misc/pascal/tests/list.sh
@@ -0,0 +1,73 @@
+#!/bin/sh
+############################################################################
+# list.sh
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#set -x
+
+source ../.config
+
+if [ "${CONFIG_INSN16}" == "y" ]; then
+ BINDIR=bin16
+fi
+if [ "${CONFIG_INSN32}" == "y" ]; then
+ BINDIR=bin32
+fi
+
+PLIST=../${BINDIR}/plist
+PLISTOPTS="-d"
+
+PEXFILENAME=${1}
+if [ -z "${PEXFILENAME}" ]; then
+ echo "ERROR: No file name provided"
+ exit 1
+fi
+
+PEXBASENAME=`basename ${PEXFILENAME} .pas`
+PEXDIRNAME=`dirname ${PEXFILENAME}`
+if [ "${PEXDIRNAME}" == "." ]; then
+ PEXDIRNAME=src
+fi
+
+PEXFILENAME=${PEXDIRNAME}/${PEXBASENAME}.pex
+if [ ! -f "${PEXFILENAME}" ]; then
+ echo "ERROR: ${PEXFILENAME} does not exist"
+ exit 1
+fi
+
+if [ -f ${PEXDIRNAME}/${PEXBASENAME}.inp ] ; then
+ echo "Test command line arguments:"
+ echo " \"`cat ${PEXDIRNAME}/${PEXBASENAME}.inp`\""
+fi
+
+${PLIST} ${PLISTOPTS} src/${PEXBASENAME}.pex 2>&1
diff --git a/misc/pascal/tests/src/001-beginend.pas b/misc/pascal/tests/src/001-beginend.pas
new file mode 100644
index 000000000..6f7a97958
--- /dev/null
+++ b/misc/pascal/tests/src/001-beginend.pas
@@ -0,0 +1,11 @@
+{ the compound statement }
+
+program beginend(output);
+
+var
+ sum : integer;
+
+begin
+ sum := 3 + 5;
+ writeln('sum=', sum, ' -sum=', -sum);
+end.
diff --git a/misc/pascal/tests/src/002-writeln.pas b/misc/pascal/tests/src/002-writeln.pas
new file mode 100644
index 000000000..ccdc249fc
--- /dev/null
+++ b/misc/pascal/tests/src/002-writeln.pas
@@ -0,0 +1,17 @@
+{ writeln with a variety of arguments }
+
+program check_writeln(output);
+
+const
+ floater = 1.8;
+ low = 37;
+ high = 492;
+ range_string = ' range=';
+
+var
+ range : low..high;
+
+begin
+ range := (low + high) div 2;
+ writeln('A', range_string, range, ' B floater=', floater);
+end.
diff --git a/misc/pascal/tests/src/003-for.inp b/misc/pascal/tests/src/003-for.inp
new file mode 100644
index 000000000..51d7b8d16
--- /dev/null
+++ b/misc/pascal/tests/src/003-for.inp
@@ -0,0 +1,2 @@
+5
+
diff --git a/misc/pascal/tests/src/003-for.pas b/misc/pascal/tests/src/003-for.pas
new file mode 100644
index 000000000..531437e0a
--- /dev/null
+++ b/misc/pascal/tests/src/003-for.pas
@@ -0,0 +1,16 @@
+{ compute h(n) = 1 + 1/2 + 1/3 +...+ 1/n }
+
+program egfor(input, output);
+
+var
+ i, n : integer;
+ h : real;
+
+begin
+ read(n);
+ writeln(n);
+ h := 0;
+ for i:= n downto 1 do
+ h := h + 1/i;
+ writeln(h);
+end.
diff --git a/misc/pascal/tests/src/004-repeat.inp b/misc/pascal/tests/src/004-repeat.inp
new file mode 100644
index 000000000..51d7b8d16
--- /dev/null
+++ b/misc/pascal/tests/src/004-repeat.inp
@@ -0,0 +1,2 @@
+5
+
diff --git a/misc/pascal/tests/src/004-repeat.pas b/misc/pascal/tests/src/004-repeat.pas
new file mode 100644
index 000000000..10e909fea
--- /dev/null
+++ b/misc/pascal/tests/src/004-repeat.pas
@@ -0,0 +1,18 @@
+{ compute h(n) = 1 + 1/2 + 1/3 +...+ 1/n }
+
+program egrepeat(input, output);
+
+var
+ n : integer;
+ h : real;
+
+begin
+ read(n);
+ writeln(n);
+ h := 0;
+ repeat
+ h := h + 1/n;
+ n := n - 1;
+ until n=0;
+ writeln(h);
+end.
diff --git a/misc/pascal/tests/src/005-while.inp b/misc/pascal/tests/src/005-while.inp
new file mode 100644
index 000000000..51d7b8d16
--- /dev/null
+++ b/misc/pascal/tests/src/005-while.inp
@@ -0,0 +1,2 @@
+5
+
diff --git a/misc/pascal/tests/src/005-while.pas b/misc/pascal/tests/src/005-while.pas
new file mode 100644
index 000000000..aceb5f4fa
--- /dev/null
+++ b/misc/pascal/tests/src/005-while.pas
@@ -0,0 +1,19 @@
+{ compute h(n) = 1 + 1/2 + 1/3 +...+ 1/n }
+
+program egwhile(input, output);
+
+var
+ n : integer;
+ h : real;
+
+begin
+ read(n);
+ writeln(n);
+ h := 0;
+ while n>0 do
+ begin
+ h := h + 1/n;
+ n := n - 1;
+ end;
+ writeln(h);
+end.
diff --git a/misc/pascal/tests/src/006-optconst.pas b/misc/pascal/tests/src/006-optconst.pas
new file mode 100644
index 000000000..511d807eb
--- /dev/null
+++ b/misc/pascal/tests/src/006-optconst.pas
@@ -0,0 +1,43 @@
+{ A test of constant optimiztion }
+
+program constopt;
+var
+ i1, i2, i3 : integer;
+ b1 : boolean
+begin
+ { integer operations:
+ 1. =, <>, <, <=, >, >=
+ 2. +, -, OR
+ 3. *, DIV, AND, SHL, SHR
+ 4. -, NOT
+ }
+
+ i1 := -2; { -2 }
+ i1 := 3 * 2; { 6 }
+ i1 := 3 * (-2); { -6 }
+ i1 := 3 div 2; { 1 }
+ i1 := 3 div (-2); { -1 }
+ i1 := 4 * 3 div (-2); { -6 }
+ i1 := 4 * (3 div (-2)); { -4 }
+ i1 := (4 * 3) div (-2); { -6 }
+
+ i1 := 3 + 2; { 5 }
+ i1 := 3 - 2; { 1 }
+ i1 := 3 + (-2); { 1 }
+ i1 := 4 + 3 - 2; { 5 }
+ i1 := 4 + (3 - 2); { 5 }
+ i1 := (4 + 3) - 2; { 5 }
+
+ b1 := -2 = 3 + 2; { -2 = 5 0 }
+ b1 := 3 * 2 <> 3 - 2; { 6 <> 1 -1 }
+ b1 := 3 * (-2) < 3 + (-2); { -6 < 1 -1 }
+ b1 := 3 div 2 <= 4 + 3 - 2; { 1 <= 5 -1 }
+ b1 := 3 div (-2) > 4 + (3 - 2); { -1 > 5 0 }
+ b1 := 4 * 3 div (-2) >= (4 + 3) - 2; { -6 >= 5 0 }
+
+ { floating point operations }
+ { to be provided }
+
+ { string operations }
+ { to be provided }
+end.
diff --git a/misc/pascal/tests/src/007-function.pas b/misc/pascal/tests/src/007-function.pas
new file mode 100644
index 000000000..4c5a3c75d
--- /dev/null
+++ b/misc/pascal/tests/src/007-function.pas
@@ -0,0 +1,16 @@
+{ a simple nested function }
+
+program simplefunc(output);
+
+function addmul(term1a, term1b, term2a, term2b: integer ) : integer;
+ function factor(terma, termb: integer ) : integer;
+ begin
+ factor := terma + termb;
+ end;
+begin
+ addmul := factor(term1a, term1b) * factor(term2a, term2b);
+end;
+
+begin
+ writeln('(1 + 2) * (3 + 4) =', addmul(1, 2, 3, 4));
+end.
diff --git a/misc/pascal/tests/src/101-cosine.inp b/misc/pascal/tests/src/101-cosine.inp
new file mode 100644
index 000000000..db2a68721
--- /dev/null
+++ b/misc/pascal/tests/src/101-cosine.inp
@@ -0,0 +1,2 @@
+1
+0.78539815
diff --git a/misc/pascal/tests/src/101-cosine.pas b/misc/pascal/tests/src/101-cosine.pas
new file mode 100644
index 000000000..b2797fcb9
--- /dev/null
+++ b/misc/pascal/tests/src/101-cosine.pas
@@ -0,0 +1,29 @@
+{ compute the cosine using the expansion:
+ cos(x) = 1 - x**2/(2*1) + x**4/(4*3*2*1) - ... }
+
+program cosine(input, output);
+
+const
+ eps = 1e-14;
+
+var
+ x, sx, s, t : real;
+ i, k, n : integer;
+
+begin
+ write('Number of cosines: ');
+ read(n);
+ for i:=1 to n do
+ begin
+ write(n, '. Enter radians: ');
+ read(x);
+ t := 1; k := 0; s := 1; sx := sqr(x);
+ while abs(t) > eps*abs(s) do
+ begin
+ k := k+2;
+ t := -t*sx/(k*(k-1));
+ s := s+t;
+ writeln(' cos(', x, ')=', s, ' interation=', k div 2)
+ end
+ end
+end.
diff --git a/misc/pascal/tests/src/102-cen2fahr.pas b/misc/pascal/tests/src/102-cen2fahr.pas
new file mode 100644
index 000000000..c53c5fb0e
--- /dev/null
+++ b/misc/pascal/tests/src/102-cen2fahr.pas
@@ -0,0 +1,22 @@
+{ example of constant definition part }
+
+program convert(output);
+
+const
+ addin = 32;
+ mulby = 1.8;
+ low = 0;
+ high = 39;
+ seperator = '------------';
+
+var
+ degree : low..high;
+
+begin
+ writeln(seperator);
+ for degree := low to high do
+ begin
+ writeln(degree, 'c', round(degree * mulby + addin), 'f');
+ end;
+ writeln(seperator)
+end.
diff --git a/misc/pascal/tests/src/103-sumharm.inp b/misc/pascal/tests/src/103-sumharm.inp
new file mode 100644
index 000000000..51d7b8d16
--- /dev/null
+++ b/misc/pascal/tests/src/103-sumharm.inp
@@ -0,0 +1,2 @@
+5
+
diff --git a/misc/pascal/tests/src/103-sumharm.pas b/misc/pascal/tests/src/103-sumharm.pas
new file mode 100644
index 000000000..5031ab7bb
--- /dev/null
+++ b/misc/pascal/tests/src/103-sumharm.pas
@@ -0,0 +1,46 @@
+PROGRAM sumharmonics (input, output);
+ CONST
+ firstterm = 2;
+ VAR
+ numerator, denominator,
+ lastterm, termcount : integer;
+
+ PROCEDURE lowterm (VAR num, den : integer);
+ VAR
+ numcopy, dencopy, remainder : integer;
+ BEGIN
+ numcopy := num;
+ dencopy := den;
+ WHILE dencopy <> 0 DO
+ BEGIN
+ remainder := numcopy MOD dencopy;
+ numcopy := dencopy;
+ dencopy := remainder;
+ END; { while }
+ IF numcopy > 1
+ THEN
+ BEGIN
+ num := num DIV numcopy;
+ den := den DIV numcopy;
+ END
+ END; { lowterm }
+
+ PROCEDURE addrationals (VAR num1, den1 : integer;
+ num2, den2 : integer);
+ BEGIN
+ num1 := num1 * den2 + num2 * den1;
+ den1 := den1 * den2;
+ END; { addrationals }
+
+ BEGIN { sumharmonics }
+ numerator := 1;
+ denominator := 1;
+ READ (lastterm);
+ FOR termcount := firstterm TO lastterm DO
+ BEGIN
+ addrationals (numerator, denominator, 1, termcount);
+ lowterm (numerator, denominator);
+ WRITELN (numerator, '/', denominator)
+ END; { for }
+ END. {sumharmonics}
+
diff --git a/misc/pascal/tests/src/104-primes.pas b/misc/pascal/tests/src/104-primes.pas
new file mode 100644
index 000000000..15adaabf3
--- /dev/null
+++ b/misc/pascal/tests/src/104-primes.pas
@@ -0,0 +1,43 @@
+{ generate the primes between 3..10000 using a
+ sieve containing odd integers in this range. }
+
+program primes(output);
+
+const
+ wdlength = 59; {implementation dependent}
+ maxbit = 58;
+ w = 84; {w=n div wdlength div 2}
+
+var
+ sieve, primes : array[0..w] of set of 0..maxbit;
+ next : record word,bit : integer
+ end;
+ j,k,t,c : integer; empty:boolean;
+
+begin {initialize}
+ for t:=0 to w do
+ begin sieve[t] := [0..maxbit]; primes[t] := [] end;
+ sieve[0] := sieve[0]-[0]; next.word := 0;
+ next.bit := 1; empty := false;
+
+ with next do
+ repeat {find next prime}
+ while not(bit in sieve[word]) do bit := succ(bit);
+ primes[word] := primes[word] + [bit];
+ c := 2*bit + 1;
+ j := bit; k := word;
+ while k<=w do {eliminate}
+ begin sieve[k] := sieve[k] - [j];
+ k := k + word*2; j := j + c;
+ while j>maxbit do
+ begin k := k+1; j := j - wdlength
+ end
+ end;
+ if sieve[word]=[] then
+ begin empty := true; bit := 0
+ end;
+ while empty and (word<w) do
+ begin word := word+1; empty := sieve[word]=[]
+ end
+ until empty; {ends with}
+end.
diff --git a/misc/pascal/tests/src/105-inflation.pas b/misc/pascal/tests/src/105-inflation.pas
new file mode 100644
index 000000000..479f0651a
--- /dev/null
+++ b/misc/pascal/tests/src/105-inflation.pas
@@ -0,0 +1,27 @@
+{ assuming annual inflation rates of 7, 8, and 10 per cent,
+ find the factor by which the frank, dollar, pound
+ sterlinh, mark, or guilder will have been devalued in
+ 1, 2, ... n years.}
+
+program inflation(output);
+
+const
+ n = 10;
+var
+ i : integer;
+ w1, w2, w3 : real;
+
+begin
+ i := 0;
+ w1 := 1.0;
+ w2 := 1.0;
+ w3 := 1.0;
+
+ repeat
+ i := i + 1;
+ w1 := w1 * 1.07;
+ w2 := w2 * 1.08;
+ w3 := w3 * 1.10;
+ writeln(i, '. ', w1, ', ', w2, ', ', w3);
+ until i=n
+end.
diff --git a/misc/pascal/tests/src/201-strcat.pas b/misc/pascal/tests/src/201-strcat.pas
new file mode 100644
index 000000000..fd7a67684
--- /dev/null
+++ b/misc/pascal/tests/src/201-strcat.pas
@@ -0,0 +1,36 @@
+PROGRAM stringcat;
+VAR
+ string1, string2 : string
+
+FUNCTION inquote(instring : string) : string;
+BEGIN
+ inquote := '"' + instring + '"'
+END;
+
+BEGIN
+ WRITELN(string1);
+
+ string1 := 'Now ';
+ WRITELN(inquote(string1));
+
+ string2 := 'is the time ';
+ WRITELN(inquote(string2));
+
+ string1 := string1 + string2 + 'for all good men ';
+ WRITELN(inquote(string1));
+
+ string2 := 'to come ' + 'to ';
+ WRITELN(inquote(string2));
+
+ string1 := string1 + string2;
+ WRITELN(inquote(string1));
+
+ string2 := 'of their party';
+ WRITELN(inquote(string2));
+
+ string2 := 'the aid ' + string2;
+ WRITELN(inquote(string2));
+
+ string1 := string1 + string2 + '.';
+ WRITELN(inquote(string1));
+END.
diff --git a/misc/pascal/tests/src/202-strcmp.pas b/misc/pascal/tests/src/202-strcmp.pas
new file mode 100644
index 000000000..cff214403
--- /dev/null
+++ b/misc/pascal/tests/src/202-strcmp.pas
@@ -0,0 +1,47 @@
+PROGRAM stringops;
+CONST
+ lexbig = 'zzzLexically Great';
+ lexmiddle1 = 'ZZZLexically Middle+';
+ lexmiddle = 'ZZZLexically Middle';
+ lexmiddle2 = 'ZZZLexically Middl';
+ lexsmall = 'AAALexically Small';
+ lexnothing = ''
+VAR
+ string1, string2 : string;
+BEGIN
+ IF (lexbig <= lexmiddle) THEN
+ writeln('ERROR: ', lexbig, ' <= ', lexmiddle)
+ else
+ writeln('OKAY: ', lexbig, ' > ', lexmiddle);
+
+ IF (lexmiddle > lexmiddle1) THEN
+ writeln('ERROR: ', lexmiddle, ' > ', lexmiddle1)
+ else
+ writeln('OKAY: ', lexmiddle, ' <= ', lexmiddle1);
+
+ IF (lexmiddle <> lexmiddle) THEN
+ writeln('ERROR: ', lexmiddle, ' <> ', lexmiddle)
+ else
+ writeln('OKAY: ', lexmiddle, ' = ', lexmiddle);
+
+ IF (lexmiddle = lexnothing) THEN
+ writeln('ERROR: ', lexmiddle, ' = ', lexnothing)
+ else
+ writeln('OKAY: ', lexmiddle, ' <> ', lexnothing);
+
+ IF (lexnothing <> lexnothing) THEN
+ writeln('ERROR: ', lexnothing, ' <> ', lexnothing)
+ else
+ writeln('OKAY: ', lexnothing, ' = ', lexnothing);
+
+ IF (lexmiddle < lexmiddle2) THEN
+ writeln('ERROR: ', lexmiddle, ' < ', lexmiddle2)
+ else
+ writeln('OKAY: ', lexmiddle, ' >= ', lexmiddle2);
+
+ IF (lexsmall >= lexmiddle) THEN
+ writeln('ERROR: ', lexsmall, ' >= ', lexmiddle)
+ else
+ writeln('OKAY: ', lexsmall, ' < ', lexmiddle)
+
+END.
diff --git a/misc/pascal/tests/src/501-unit-cosine.pas b/misc/pascal/tests/src/501-unit-cosine.pas
new file mode 100644
index 000000000..5f79be4a2
--- /dev/null
+++ b/misc/pascal/tests/src/501-unit-cosine.pas
@@ -0,0 +1,36 @@
+{ Compute the cosine using the expansion:
+ cos(x) = 1 - x**2/(2*1) + x**4/(4*3*2*1) - ...
+ This file verifies a simple unit that exports one function.
+}
+
+unit MyCosineUnit;
+
+interface
+
+function mycosine(x : real) : real;
+
+implementation
+
+function mycosine(x : real) : real;
+const
+ eps = 1e-14;
+
+var
+ sx, s, t : real;
+ i, k : integer;
+
+begin
+ t := 1;
+ k := 0;
+ s := 1;
+ sx := sqr(x);
+ while abs(t) > eps*abs(s) do
+ begin
+ k := k + 2;
+ t := -t * sx / (k * (k - 1));
+ s := s + t;
+ end;
+ mycosine := s
+end; { mycosine }
+end.
+
diff --git a/misc/pascal/tests/src/501-unit-data.pas b/misc/pascal/tests/src/501-unit-data.pas
new file mode 100644
index 000000000..23ffeb494
--- /dev/null
+++ b/misc/pascal/tests/src/501-unit-data.pas
@@ -0,0 +1,21 @@
+{ This file tests only that data can be shared correctly between units }
+
+unit MyDataUnit;
+
+interface
+
+var
+ mycosx : real;
+ mysinx : real;
+ myone : real;
+
+procedure checkvars;
+
+implementation
+
+procedure checkvars;
+begin
+ myone := sqr(mycosx) + sqr(mysinx)
+end; { checkvars }
+end.
+
diff --git a/misc/pascal/tests/src/501-unit-sine.pas b/misc/pascal/tests/src/501-unit-sine.pas
new file mode 100644
index 000000000..944e70774
--- /dev/null
+++ b/misc/pascal/tests/src/501-unit-sine.pas
@@ -0,0 +1,24 @@
+{ Compute the sine using: sqrt(1 - cosine**2)
+ This file verifies a unit that uses another unit
+}
+
+unit MySineUnit;
+
+interface
+
+function mysine(x : real) : real;
+
+implementation
+
+uses
+ MyCosineUnit in '501-unit-cosine.pas';
+
+function mysine(x : real) : real;
+var
+ mycos : real
+begin
+ mycos := mycosine(x);
+ mysine := sqrt(1.0 - sqr(mycos))
+end; { mysine }
+end.
+
diff --git a/misc/pascal/tests/src/501-uses.inp b/misc/pascal/tests/src/501-uses.inp
new file mode 100644
index 000000000..f912cec5c
--- /dev/null
+++ b/misc/pascal/tests/src/501-uses.inp
@@ -0,0 +1 @@
+0.78539815
diff --git a/misc/pascal/tests/src/501-uses.pas b/misc/pascal/tests/src/501-uses.pas
new file mode 100644
index 000000000..49c3cdaac
--- /dev/null
+++ b/misc/pascal/tests/src/501-uses.pas
@@ -0,0 +1,20 @@
+program MyProgram;
+
+uses
+ MyCosineUnit in '501-unit-cosine.pas';
+ MySineUnit in '501-unit-sine.pas';
+ MyDataUnit in '501-unit-data.pas';
+
+var
+ x : real;
+
+begin
+ write('Enter radians : ');
+ read(x);
+ mycosx := mycosine(x);
+ writeln('cos(', x, ')=', mycosx);
+ mysinx := mysine(x);
+ writeln('sin(', x, ')=', mysinx);
+ checkvars;
+ writeln('sin(', x, ')**2 + cos(', x, ')**2=', myone)
+end.
diff --git a/misc/pascal/tests/src/801-cgihello.pas b/misc/pascal/tests/src/801-cgihello.pas
new file mode 100644
index 000000000..54170e34e
--- /dev/null
+++ b/misc/pascal/tests/src/801-cgihello.pas
@@ -0,0 +1,20 @@
+program hello(output);
+
+ procedure WriteResponseHeader;
+ begin
+ writeln('content-type: text/html');
+ writeln
+ end;
+
+begin
+ WriteResponseHeader;
+ writeln('<HTML>');
+ writeln('<HEAD>');
+ writeln('<TITLE>IriePascal Hello World Program</TITLE>');
+ writeln('</HEAD>');
+ writeln('<BODY>');
+ writeln('<BIG> Hello world!!! </BIG>');
+ writeln('</BODY>');
+ writeln('</HTML>')
+end.
+
diff --git a/misc/pascal/tests/src/802-cgiinfo.pas b/misc/pascal/tests/src/802-cgiinfo.pas
new file mode 100644
index 000000000..ba5cfdffa
--- /dev/null
+++ b/misc/pascal/tests/src/802-cgiinfo.pas
@@ -0,0 +1,67 @@
+program info(output);
+
+procedure WriteHeader;
+begin
+writeln('Content-type: text/html');
+writeln;
+writeln('<html>');
+writeln('<head>');
+writeln('<title>Irie Pascal sample CGI application</title>');
+writeln('<h1>CGI environment variables.</h1>');
+writeln('</head>')
+end;
+
+procedure WriteBody;
+
+procedure DisplayEnvVar(name : string);
+var
+value : string;
+begin
+value := getenv(name);
+writeln(name, ' = ', value, '<br>')
+end;
+
+begin
+writeln('<body>');
+DisplayEnvVar('HTTP_ACCEPT');
+DisplayEnvVar('HTTP_ACCEPT_ENCODING');
+DisplayEnvVar('HTTP_ACCEPT_LANGUAGE');
+DisplayEnvVar('HTTP_AUTHORIZATION');
+DisplayEnvVar('HTTP_CHARGE_TO');
+DisplayEnvVar('HTTP_FROM');
+DisplayEnvVar('HTTP_IF_MODIFIED_SINCE');
+DisplayEnvVar('HTTP_PRAGMA');
+DisplayEnvVar('HTTP_REFERER');
+DisplayEnvVar('HTTP_USER_AGENT');
+writeln('<hr>');
+DisplayEnvVar('AUTH_TYPE');
+DisplayEnvVar('CONTENT_LENGTH');
+DisplayEnvVar('CONTENT_TYPE');
+DisplayEnvVar('GATEWAY_INTERFACE');
+DisplayEnvVar('PATH_INFO');
+DisplayEnvVar('PATH_TRANSLATED');
+DisplayEnvVar('QUERY_STRING');
+DisplayEnvVar('REMOTE_ADDR');
+DisplayEnvVar('REMOTE_HOST');
+DisplayEnvVar('REMOTE_IDENT');
+DisplayEnvVar('REMOTE_USER');
+DisplayEnvVar('REQUEST_METHOD');
+DisplayEnvVar('SCRIPT_NAME');
+DisplayEnvVar('SERVER_NAME');
+DisplayEnvVar('SERVER_PORT');
+DisplayEnvVar('SERVER_PROTOCOL');
+DisplayEnvVar('SERVER_SOFTWARE');
+writeln('</body>')
+end;
+
+procedure WriteFooter;
+begin
+writeln('</html>')
+end;
+
+begin
+WriteHeader;
+WriteBody;
+WriteFooter
+end.
+
diff --git a/misc/pascal/tests/src/803-redirect.pas b/misc/pascal/tests/src/803-redirect.pas
new file mode 100644
index 000000000..d53acc1e1
--- /dev/null
+++ b/misc/pascal/tests/src/803-redirect.pas
@@ -0,0 +1,137 @@
+program prices(input, output);
+const
+ MaxBuffer = 256;
+ BASE = 'http://www.irietools.com/';
+var
+ buffer : string[MaxBuffer];
+ NewLocation : string;
+
+ procedure Init;
+ begin
+ NewLocation := BASE
+ end;
+
+ procedure GenerateHTTPHeader;
+ begin
+ writeln('Content-type: text/html');
+ writeln;
+ end;
+
+ procedure GetCGIData;
+ var
+ RequestMethod : string;
+
+ procedure GetRequest;
+ begin (* GetRequest *)
+ buffer := getenv('QUERY_STRING')
+ end; (* GetRequest *)
+
+ procedure PostRequest;
+ var
+ len, i : 0..maxint;
+ err : integer;
+ ContentLength : string;
+ c : char;
+ begin (* PostRequest *)
+ buffer := '';
+ ContentLength := getenv('CONTENT_LENGTH');
+ if ContentLength <> '' then
+ val(ContentLength, len, err)
+ else
+ len := 0;
+ if len <= MaxBuffer then
+ for i := 1 to len do
+ begin
+ read(c);
+ buffer := buffer + c
+ end
+ end; (* PostRequest *)
+
+ begin (* GetCGIData *)
+ RequestMethod := getenv('REQUEST_METHOD');
+ if RequestMethod = 'GET' then
+ GetRequest
+ else
+ PostRequest
+ end; (* GetCGIData *)
+
+ procedure ProcessCGIData;
+ var
+ i, num, p : integer;
+ EncodedVariable, DecodedVariable, name, value : string;
+
+ procedure ProcessNameValuePair(var name, value : string);
+ begin
+ if (name = 'lstnavigation') or (name = 'navigation') or (name = 'goto') then
+ begin
+ if value <> '[none]' then
+ if lowercase(copy(value, 1, 5)) = 'http:' then
+ NewLocation := value
+ else
+ NewLocation := BASE + value
+ end
+ else
+ ; (* do nothing we have an undefined form element *)
+ end;
+
+ begin (* ProcessCGIData *)
+ num := CountWords(buffer, '&');
+ for i := 1 to num do
+ begin
+ EncodedVariable := CopyWord(buffer, i, '&');
+ DecodedVariable := URLDecode(EncodedVariable);
+ p := pos('=', DecodedVariable);
+ if p > 0 then
+ begin
+ name := lowercase(trim(copy(DecodedVariable, 1, p-1)));
+ value := lowercase(trim(copy(DecodedVariable, p+1)));
+ ProcessNameValuePair(name, value);
+ end
+ end
+ end; (* ProcessCGIData *)
+
+ procedure GenerateResponse;
+
+ procedure GenerateHTMLHeader;
+ begin
+ writeln('<html>');
+ writeln('<head>');
+ writeln('<meta name="Description" content="Redirect New Location">');
+
+ writeln('<meta http-equiv="Refresh" content="0;URL=', NewLocation, '">');
+
+ writeln('<title>Redirect to New Location</title>');
+ writeln('</head>');
+ end;
+
+ procedure GenerateHTMLFooter;
+ begin
+ writeln('<hr>');
+ writeln('<p>');
+ writeln('Redirect 1.0 Copyright &copy; 1999-2001, Stuart King<br>');
+ writeln('Home page <a href="http://www.irietools.com/">www.irietools.com</a>');
+ writeln('</p>');
+ writeln('</body>');
+ writeln('</html>');
+ end;
+
+ begin (* GenerateResponse *)
+ GenerateHTMLHeader;
+ writeln('<body bgcolor="#FFE8E8">');
+ writeln('<p>You should be automatically taken to the next page.</p>');
+ writeln('<p>However if your browser does not support redirection ');
+ writeln('click <a href="', NewLocation, '">here</a></p>');
+ GenerateHTMLFooter;
+ end; (* GenerateResponse *)
+
+begin
+ GenerateHTTPHeader;
+
+ Init;
+
+ GetCGIData;
+
+ ProcessCGIData;
+
+ GenerateResponse;
+end.
diff --git a/misc/pascal/tests/src/804-cgiform.pas b/misc/pascal/tests/src/804-cgiform.pas
new file mode 100644
index 000000000..e3043f548
--- /dev/null
+++ b/misc/pascal/tests/src/804-cgiform.pas
@@ -0,0 +1,322 @@
+(********************************************************************************************
+** PROGRAM : cgiform
+** VERSION : 1.0.0
+** DESCRIPTION : Demonstrates how to process HTML forms in CGI programs.
+** AUTHOR : Stuart King
+** COPYRIGHT : Copyright (c) Irie Tools, 2002. All Rights Reserved.
+** NOTES :
+** This sample program is distributed with Irie Pascal, and was written to illustrate
+** how to process HTML forms. To make best use of this sample you should have a basic
+** understanding of Pascal as well as a basic understanding of the Common Gateway Interface
+** (CGI).
+**
+** HTML forms provide a way for websites to receive input from visitors, and to process
+** this input in some way. HTML forms contain different kinds of input elements in order
+** to conveniently receive different kinds of visitor input. The most common kinds of
+** input elements are:
+** 1. One line text entry boxes
+** 2. Multi-line text entry boxes
+** 3. Checkboxes
+** 4. Radio buttons
+** 5. Hidden fields
+** 6. Selection lists (Drop-down menus and List boxes).
+** 7. Reset button
+** 8. Submit button
+**
+** HTML forms have action attributes that indicate what should happen when the submit
+** button is clicked. It is very common for the action attribute to point at the URL of
+** a CGI program. In this case when the submit button is pressed the CGI program is executed
+** and the form's input is passed to the program for processing. Each input element in the
+** form has a name and the form's input is sent to the CGI program in the form of name/value
+** pairs, where the values are the input received by the input elements.
+**
+** What this program actually does is retrieve any form input passed to it. If it receives
+** form input then this program just displays the name/value pairs, along with a link that
+** can be used to execute the program again. If the program does not receive any form input
+** then it displays a form with a variaty of input elements. The form's action element points
+** back to the program, so that the program will receive the input from the form when the
+** submit button is pressed.
+**********************************************************************************************)
+program cgiform;
+const
+ MAX_BUFFER = 8000;
+ MAX_NAME = 20;
+ MAX_VALUE = 400;
+type
+ positive = 0..maxint;
+ BufferType = string[MAX_BUFFER];
+ NameValuePair = record
+ Name : string[MAX_NAME];
+ Value : string[MAX_VALUE]
+ end;
+var
+ buffer : BufferType;
+ NameValuePairs : list of NameValuePair;
+ ScriptName : filename;
+
+ function EscapeCharacters(s : string) : string; forward;
+
+ //PURPOSE: Initializes the program
+ //NOTES:
+ // Initializes the list that will be used to store the name/value pairs
+ //passed to the program. The program also retrieves it's name so that it can
+ //refer to itself in the generated response.
+ procedure Initialize;
+ begin (* Initialize *)
+ new(NameValuePairs);
+ ScriptName := getenv('SCRIPT_NAME');
+ end; (* Initialize *)
+
+ //PURPOSE: Retrieves the information passed to the CGI applications.
+ //GLOBAL(s) - buffer - Used to store the GET or POST information passed to the CGI program
+ procedure GetCGIData;
+ var
+ RequestMethod : string;
+
+ //PURPOSE: Retrieves information sent to by a GET request (i.e. in the QUERY_STRING
+ // environment variable).
+ procedure GetRequest;
+ begin (* GetRequest *)
+ buffer := getenv('QUERY_STRING')
+ end; (* GetRequest *)
+
+ //PURPOSE: Retrieves information sent to by a POST request (i.e. through the standard
+ // input stream, with the length of the data in the environment variable
+ // CONTENT_LENGTH).
+ procedure PostRequest;
+ var
+ len, i : positive;
+ err : integer;
+ ContentLength : string;
+ c : char;
+ begin (* PostRequest *)
+ buffer := '';
+ ContentLength := getenv('CONTENT_LENGTH');
+ if ContentLength <> '' then
+ val(ContentLength, len, err)
+ else
+ len := 0;
+ if len <= MAX_BUFFER then
+ for i := 1 to len do
+ begin
+ read(c);
+ buffer := buffer + c
+ end
+ end; (* PostRequest *)
+
+ begin (* GetCGIData *)
+ RequestMethod := getenv('REQUEST_METHOD');
+ if RequestMethod = 'GET' then
+ GetRequest
+ else
+ PostRequest
+ end; (* GetCGIData *)
+
+ //PURPOSE: Process the data passed to the program.
+ //NOTES: This is the main part of the program. After retreiving
+ // the information passed to the program this procedure is
+ // called to perform the required processing.
+ procedure ProcessCGIData;
+ var
+ i, num, p : integer;
+ EncodedVariable, DecodedVariable, name, value : string;
+
+ //PURPOSE: Processes the named value pairs sent with the GET or POST request.
+ // Which in this case is the information entered by the user about the
+ // cookie to add or delete.
+ //ARGUMENT(s): name - name part of the name/value pair
+ // value - value part of name/value pair
+ //NOTES:
+ // The information entered by the user is sent as name/value pairs (i.e. name-value)
+ //with the name part being the name of the form element holding the information and
+ //the value part being the actual information held by the form element.
+ procedure ProcessNameValuePair(var name, value : string);
+ var
+ pair : NameValuePair;
+ begin (* ProcessNameValuePair *)
+ pair.name := name;
+ pair.value := value;
+ insert(pair, NameValuePairs);
+ end; (* ProcessNameValuePair *)
+
+ begin (* ProcessCGIData *)
+ //Retrieve each name/value pair from the form and processes them.
+ num := CountWords(buffer, '&');
+ for i := 1 to num do
+ begin
+ EncodedVariable := CopyWord(buffer, i, '&');
+ DecodedVariable := URLDecode(EncodedVariable);
+ p := pos('=', DecodedVariable);
+ if p > 0 then
+ begin
+ name := lowercase(trim(copy(DecodedVariable, 1, p-1)));
+ value := trim(copy(DecodedVariable, p+1));
+ ProcessNameValuePair(name, value);
+ end
+ end;
+ end; (* ProcessCGIData *)
+
+ //PURPOSE: Generates the response to send back to the browser.
+ procedure GenerateResponse;
+
+ procedure GenerateHeader;
+ begin (* GenerateHeader *)
+ //Generate the response headers (including the blank line at the end).
+ writeln('content-type: text/html');
+ writeln;
+
+ writeln('<html>');
+ writeln('<head>');
+ writeln('<title>Irie Pascal sample CGI application</title>');
+ writeln('<h1>CGIFORM</h1>');
+ writeln('<h2>This program displays the data entered into a form.</h2>');
+ writeln('</head>');
+ writeln(' <hr>');
+ end; (* GenerateHeader *)
+
+ procedure GenerateBody;
+
+ procedure WriteForm;
+ begin (* WriteForm *)
+ writeln('<form method="POST" action="', ScriptName, '">');
+ writeln(' <h2>One Line Text Box:</h2>');
+ writeln(' <p>OneLine <input type="text" name="OneLine" size="20"></p>');
+ writeln(' <hr>');
+ writeln(' <h2>Scrolling Text Box:</h2>');
+ writeln(' <p>Scrolling <textarea rows="2" name="Scrolling" cols="20"></textarea></p>');
+ writeln(' <hr>');
+ writeln(' <h2>Check Boxes</h2>');
+ writeln(' <p>Box1 <input type="checkbox" name="Box1" value="1">');
+ writeln(' &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Box2 <input type="checkbox" name="Box2"');
+ writeln(' value="1"></p>');
+ writeln(' <p>Box3 <input type="checkbox" name="Box3" value="1">');
+ writeln(' &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Box4 <input type="checkbox" name="Box4"');
+ writeln(' value="1"></p>');
+ writeln(' <hr>');
+ writeln(' <h2>Radio Buttons</h2>');
+ writeln(' <p>Radio1 <input type="radio" value="1" checked name="Radio1">');
+ writeln(' &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Radio2 <input type="radio" name="Radio2"');
+ writeln(' value="2"></p>');
+ writeln(' <p>Radio3 <input type="radio" name="Radio3" value="3">');
+ writeln(' &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Radio4 <input type="radio" name="Radio4"');
+ writeln(' value="4"></p>');
+ writeln(' <hr>');
+ writeln(' <h2>Drop-Down Menu</h2>');
+ writeln(' <p>DropDown <select name="DropDown" size="1">');
+ writeln(' <option value="Choice1">Choice1</option>');
+ writeln(' <option value="Choice2">Choice2</option>');
+ writeln(' <option value="Choice3">Choice3</option>');
+ writeln(' <option value="Choice4">Choice4</option>');
+ writeln(' <option value="Choice5">Choice5</option>');
+ writeln(' <option value="Choice6">Choice6</option>');
+ writeln(' </select></p>');
+ writeln(' <hr>');
+ writeln(' <p><input type="submit" value="Submit" name="Submit"><input type="reset" value="Reset"');
+ writeln(' name="Reset"></p>');
+ writeln('</form>');
+ end; (* WriteForm *)
+
+ procedure WriteFormData;
+ var
+ pair : NameValuePair;
+ i : positive;
+ begin (* WriteFormData *)
+ writeln('<h1>Form Data</h1>');
+ for i := 1 to length(NameValuePairs) do
+ begin
+ pair := NameValuePairs[i];
+ writeln('<h3>', EscapeCharacters(pair.name), ' = ', EscapeCharacters(pair.value), '</h3>');
+ end;
+ writeln('<hr>');
+ writeln('<p>Click <a href="', ScriptName, '">here</a> to go back to the form.</p>');
+ end; (* WriteFormData *)
+
+ begin (* GenerateBody *)
+ writeln('<body>');
+
+ if length(NameValuePairs) = 0 then
+ begin
+ //Generate the HTML for the form
+ WriteForm;
+ end
+ else
+ begin
+ //Generate the HTML that displays the form data
+ WriteFormData;
+ end;
+
+ writeln('</body>');
+ end; (* GenerateBody *)
+
+ procedure GenerateFooter;
+ begin (* GenerateFooter *)
+ writeln('</html>');
+ end; (* GenerateFooter *)
+
+ begin (* GenerateResponse *)
+ GenerateHeader;
+ GenerateBody;
+ GenerateFooter;
+ end; (* GenerateResponse *)
+
+ procedure Shutdown;
+ begin (* Shutdown *)
+ dispose(NameValuePairs);
+ end; (* Shutdown *)
+
+ //*************************************************************************
+ //PURPOSE: This function converts certain characters that have a
+ // special meaning in HTML documents to their HTML representation.
+ //ARGUMENT(s): s - The string to be escaped.
+ //RETURNS: The string with all special characters escaped.
+ //NOTES: The characters converted are < > "
+ function EscapeCharacters;
+ const
+ LessThanChar = '<';
+ GreaterThanChar = '>';
+ QuoteChar = '"';
+ HTMLLessThan = '&lt;';
+ HTMLGreaterThan = '&gt;';
+ HTMLQuote = '&quot;';
+ var
+ i : positive;
+
+ procedure ReplaceChar(var strBuffer : string; strReplace : string; i : positive);
+ begin (* ReplaceChar *)
+ delete(strBuffer, i, 1);
+ insert(strReplace, strBuffer, i)
+ end; (* ReplaceChar *)
+
+ begin (* EscapeCharacters *)
+ repeat
+ i := pos(LessThanChar, s, 1);
+ if i > 0 then
+ ReplaceChar(s, HTMLLessThan, i)
+ until i = 0;
+
+ repeat
+ i := pos(GreaterThanChar, s, 1);
+ if i > 0 then
+ ReplaceChar(s, HTMLGreaterThan, i)
+ until i = 0;
+
+ repeat
+ i := pos(QuoteChar, s, 1);
+ if i > 0 then
+ ReplaceChar(s, HTMLQuote, i)
+ until i = 0;
+
+ EscapeCharacters := s;
+ end; (* EscapeCharacters *)
+
+begin
+ Initialize;
+
+ GetCGIData;
+
+ ProcessCGIData;
+
+ GenerateResponse;
+
+ Shutdown;
+end.
diff --git a/misc/pascal/tests/src/805-cgimail.pas b/misc/pascal/tests/src/805-cgimail.pas
new file mode 100644
index 000000000..5b16f8d52
--- /dev/null
+++ b/misc/pascal/tests/src/805-cgimail.pas
@@ -0,0 +1,553 @@
+//***********************************************************************
+//CGIMAIL Version 1.0
+//Copyright (c) 2001, Stuart King. All rights reserved.
+//PURPOSE: This program is a Common Gateway Interface (CGI) application
+// that sends email messages.
+//***********************************************************************
+program cgimail(input, output);
+const
+ MaxBuffer = 2400; //Size of the buffer used to store the data from GET and POST requests
+ DEFAULT_SENDMAIL = '/usr/lib/sendmail'; //Default fullpathname to the sendmail program
+ DEFAULT_SUCCESS_MESSAGE = '<p>Thank you. Your email message has been sent successfully.</p>';
+ CONFIG_FILENAME = 'cgimail.cfg'; //name of the configuration file
+type
+ Buffer = string[MaxBuffer];
+var
+ strCGIData : Buffer; //Stores the data from the GET or POST request
+ strFrom, strTo, strSubject, strBody : Buffer;
+ strErrorLink, strSuccessLink : filename;
+ strSuccessMessage : Buffer;
+ SendMail : filename;
+
+ procedure DisplayError(strMsg : string);
+ begin //DisplayError
+ writeln('ERROR: ', strMsg);
+ halt
+ end; //DisplayError
+
+ //*************************************************************
+ //PURPOSE: Returns the directory containing the application
+ //NOTES: Used in this particular program to help locate the
+ // configuration file.
+ //*************************************************************
+ function AppDir : filename;
+ var
+ fdir : filename;
+ begin
+ fsplit(paramstr(0), fdir,,);
+ AppDir := fdir
+ end;
+
+ //*****************************************************************
+ //PURPOSE: Returns an output string (strOut) that is generated
+ // from an input string (strIn), by replacing all
+ // occurrences of one string (strOld) with another
+ // string (strNew).
+ //NOTE: No error checking is done so it is up to the caller to
+ // ensure that the replacing string does not contain the
+ // string being replaced.
+ //*****************************************************************
+ function Replace(strIn : Buffer; strOld, strNew : string) : Buffer;
+ var
+ strOut : Buffer;
+ i : 0..MaxBuffer;
+ begin
+ strOut := strIn;
+ i := 1;
+ repeat
+ i := pos(strOld, strOut, i);
+ if i > 0 then
+ begin
+ delete(strOut, i, length(strOld));
+ insert(strNew, strOut, i);
+ end
+ until i = 0;
+ Replace := strOut
+ end;
+
+ (***************************************************************
+ ** PURPOSE: This procedure converts certain characters that
+ ** have a special meaning in HTML documents to
+ ** their HTML representation.
+ ** The characters converted are < > "
+ *)
+ function EscapeCharacters(str : Buffer) : Buffer;
+ const
+ LessThanChar = '<';
+ GreaterThanChar = '>';
+ QuoteChar = '"';
+ HTMLLessThan = '&lt;';
+ HTMLGreaterThan = '&gt;';
+ HTMLQuote = '&quot;';
+
+ begin
+ str := Replace(str, LessThanChar, HTMLLessThan);
+ str := Replace(str, GreaterThanChar, HTMLGreaterThan);
+ str := Replace(str, QuoteChar, HTMLQuote);
+ EscapeCharacters := str
+ end;
+
+ procedure Initialize;
+ begin //Initialize
+ strFrom := '';
+ strTo := '';
+ strSubject := '';
+ strBody := '';
+ SendMail := DEFAULT_SENDMAIL;
+ strSuccessMessage := DEFAULT_SUCCESS_MESSAGE;
+ strErrorLink := '';
+ strSuccessLink := '';
+ end; //Initialize
+
+ //****************************************************************
+ //PURPOSE: Looks for the configuration file in the application
+ // directory, and if found prcesses the commands inside.
+ //****************************************************************
+ procedure ReadConfigFile;
+ var
+ ConfigFile : filename;
+ f : text;
+ line : string;
+
+ //**********************************************************
+ //PURPOSE: Processes a line in the configuration file
+ //NOTE: The line is assumed to look like
+ // command=value
+ // where "command" is a valid configuration command
+ // and "value" is a valid configuration value
+ // for example
+ //
+ // sendmail=/usr/lib/sendmail
+ //
+ //**********************************************************
+ procedure ProcessConfigLine(line : string);
+ const
+ SENDMAIL_COMMAND = 'sendmail';
+ TO_COMMAND = 'to';
+ SUBJECT_COMMAND = 'subject';
+ FROM_COMMAND = 'from';
+ BODY_COMMAND = 'body';
+ ERROR_LINK_COMMAND = 'error_link';
+ SUCCESS_LINK_COMMAND = 'success_link';
+ SUCCESS_MESSAGE_COMMAND = 'success_message';
+ var
+ command, value : string;
+ begin //ProcessConfigLine
+ if CountWords(line, '=') = 2 then
+ begin
+ command := lowercase(trim(CopyWord(line, 1, '=')));
+ value := trim(CopyWord(line, 2, '='));
+ if command = SENDMAIL_COMMAND then
+ SendMail := value
+ else if command = TO_COMMAND then
+ strTo := value
+ else if command = SUBJECT_COMMAND then
+ strSubject := value
+ else if command = FROM_COMMAND then
+ strFrom := value
+ else if command = BODY_COMMAND then
+ strBody := value
+ else if command = ERROR_LINK_COMMAND then
+ strErrorLink := value
+ else if command = SUCCESS_LINK_COMMAND then
+ strSuccessLink := value
+ else if command = SUCCESS_MESSAGE_COMMAND then
+ strSuccessMessage := value
+ end;
+ end; //ProcessConfigLine
+
+ begin //ReadConfigFile
+ ConfigFile := AppDir; //Look for configuration file in the Application directory
+ if ConfigFile <> '' then
+ begin
+ //Ensure that the Application directory ends with a directory seperator
+ if ConfigFile[length(ConfigFile)] <> dirsep then
+ ConfigFile := ConfigFile + dirsep;
+ //Append the name of the configuration file to the application directory
+ ConfigFile := ConfigFile + CONFIG_FILENAME;
+ end
+ else //this shouldn't happen but just in case look for configuration file in current directory.
+ ConfigFile := CONFIG_FILENAME;
+
+ traperrors(false); //Turn off error trapping
+ reset(f, ConfigFile); //Attempt to open configuaration file
+ traperrors(true); //Turn on error trapping
+ if getlasterror = 0 then //if the configuration file was successfully opened read it and process it
+ begin
+ while not eof(f) do
+ begin
+ readln(f, line);
+ ProcessConfigLine(line);
+ end;
+ close(f);
+ end;
+ end; //ReadConfigFile
+
+ //***************************************************************
+ //PURPOSE: Checks whether the input string (strAddress) is a
+ // valid email address.
+ //NOTE: This function does not perform a bullet-proof check
+ // for the validity of the email address. It just ensures
+ // that the address has at least one '@' and the first '@' is
+ // not at the beginning of the address. This function also
+ // checks to make sure that a '.' follows somewhere after the '@'.
+ //***************************************************************
+ function IsValidEmailAddress(strAddress : Buffer) : boolean;
+ var
+ i : integer;
+ begin //IsValidEmailAddress
+ i := pos('@', strAddress);
+ if (i > 1) and (pos('.', strAddress, i+1) > 0) then
+ IsValidEmailAddress := true
+ else
+ IsValidEmailAddress := false;
+ end; //IsValidEmailAddress
+
+ //*********************************************************************
+ //PURPOSE: Sends an email message using "sendmail" or the CDONTS object
+ //*********************************************************************
+ procedure SendEmail(strFrom, strTo, strSubject, strBody : Buffer);
+
+ //********************************************************
+ //PURPOSE: Sends and email message using "sendmail"
+ //NOTE:
+ //The built-in procedure "popen" is used to execute "sendmail" and
+ // open a pipe to the "sendmail" process. The email message is then
+ // written to this pipe and the "sendmail" process reads the email
+ // message and sends it to the recipients.
+ //The "-t" option is passed to "sendmail" to cause it to examine the
+ // email message for To:, Cc:, and Bcc: headers which it will then
+ // use to find out who are the intended recipients of the message.
+ //The configuration file (cgimail.cfg) can be used to specify where
+ // "sendmail" is located or even that another program be used
+ // instead of "sendmail". See the constant DEFAULT_SENDMAIL at the
+ // top of this program for the default location of "sendmail".
+ //If "sendmail" is not in the default location then use a command like
+ //
+ // sendmail=pathname
+ //
+ // in the configuration file to specify the correct location.
+ //You can also use the "sendmail" command in the configuration file
+ // to specify that a program other than "sendmail" be used
+ // to send email (under Unix-like operating systems), as long
+ // as the substitute email program has a similar interface to
+ // "sendmail", (i.e. it can take the -t option, and it will examine
+ // the email message for (at minimum) a To: header).
+ //The configuration file (cgimail.cfg) should be placed in the same
+ // directory as this program.
+ //********************************************************
+ procedure SendEmailWithSendMail;
+ const
+ SENDMAIL_OPTIONS = '-t'; //Make sendmail examine To:, Cc:, and Bcc: in message
+ var
+ pipe : text;
+ begin //SendEmailWithSendMail
+ popen(pipe, SendMail + ' ' + SENDMAIL_OPTIONS, writemode);
+ writeln(pipe, 'To: ', strTo);
+ if strFrom <> '' then
+ writeln(pipe, 'From: ', strFrom);
+ if strSubject <> '' then
+ writeln(pipe, 'Subject: ', strSubject);
+ writeln(pipe);
+ if strBody <> '' then
+ writeln(pipe, strBody);
+ writeln(pipe, '.');
+ close(pipe);
+ end; //SendEmailWithSendMail
+
+ //***************************************************************
+ //PURPOSE: Sends and email message using the CDONTS components
+ //NOTE: The CDONTS components were created by Microsoft to
+ // simplify the process of sending email. These components
+ // are distributed with IIS so if IIS is your webserver
+ // you can probably use these components.
+ //***************************************************************
+ procedure SendEmailWithCDONTS;
+ const
+ NORMAL = 1;
+ //LOW = 0;
+ //HIGH = 2;
+ var
+ objMail : object;
+ iLastError : integer;
+ strError : string;
+ begin //SendEmailWithCDONTS
+ traperrors(false);
+ objMail := CreateObject('CDONTS.NewMail');
+ traperrors(true);
+ iLastError := getlasterror;
+ if iLastError <> 0 then
+ begin
+ str(iLastError:1, strError);
+ strError := strError+' ' + errors[1].description;
+ DisplayError('#'+strError);
+ end;
+ objMail.Send(strFrom , strTo, strSubject, strBody, NORMAL);
+ dispose(objMail);
+ end; //SendEmailWithCDONTS
+
+ begin //SendEmail
+ //If this application is running under a Unix-Like platform then
+ // use sendmail to send email message
+ //If not use the CDONTS object
+ if UnixPlatform then
+ SendEmailWithSendMail
+ else
+ SendEmailWithCDONTS
+ end; //SendEmail
+
+ //********************************************************************
+ //PURPOSE: Reads the CGI request information and stores it in a buffer
+ //NOTE: The environment variable "REQUEST_METHOD" is used to determine
+ // whether a GET or POST request was made, and calls the
+ // appropriate procedure to read the data.
+ //This procedure is generic and can probably be used in almost any
+ //CGI application. The only thing likely to change is the size of the
+ // buffer used to store the CGI request information.
+ //********************************************************************
+ procedure GetCGIData(var strData : Buffer);
+ var
+ RequestMethod : string;
+
+ procedure GetRequest(var strData : Buffer);
+ begin // GetRequest
+ strData := getenv('QUERY_STRING')
+ end; // GetRequest
+
+ procedure PostRequest(var strData : Buffer);
+ var
+ len, i : 0..maxint;
+ err : integer;
+ ContentLength : string;
+ c : char;
+ begin // PostRequest
+ strData := '';
+ ContentLength := getenv('CONTENT_LENGTH');
+ if ContentLength <> '' then
+ val(ContentLength, len, err)
+ else
+ len := 0;
+ if err > 0 then
+ len := 0;
+ if len <= MaxBuffer then
+ for i := 1 to len do
+ begin
+ read(c);
+ strData := strData + c
+ end
+ end; // PostRequest
+
+ begin // GetCGIData
+ RequestMethod := getenv('REQUEST_METHOD');
+ if RequestMethod = 'GET' then
+ GetRequest(strData)
+ else
+ PostRequest(strData);
+ end; // GetCGIData
+
+ //********************************************************************
+ //PURPOSE: Processes the CGI request information that was earlier
+ // stored in the buffer. This involves seperating the information
+ // in the buffer into name/value pairs and then decoding them.
+ // CGI request information is passed to applications in the following
+ // form:
+ // name=value
+ // called name/value pairs. Each name/value pair is encoded, and then
+ // joined together in one big block of data seperated by '&'.
+ // So to process the name/value pairs the process is reversed.
+ // The individual name/value pairs are seperated from the block and
+ // then decoded, then the "name" part is seperated from the "value"
+ // part, and finally the procedure ProcessNameValuePair is called to
+ // do something with the the name/value pair.
+ //Most of this procedure is generic and can be used in almost any
+ // CGI application, the only part of this procedure that is
+ // specific to this application is what goes on inside
+ // "ProcessNameValuePair". In this case some values get assigned to
+ // some global variables.
+ //********************************************************************
+ procedure ProcessCGIData(var strData : Buffer);
+ var
+ i, num, p : integer;
+ EncodedVariable, DecodedVariable, name, value : Buffer;
+
+ procedure ProcessNameValuePair;
+ begin //ProcessNameValuePair
+ if name = 'to' then
+ strTo := value
+ else if name = 'subject' then
+ strSubject := value
+ else if name = 'from' then
+ strFrom := value
+ else if name = 'body' then
+ strBody := value
+ else if name = 'error_link' then
+ strErrorLink := value
+ else if name = 'success_link' then
+ strSuccessLink := value
+ else if name = 'success_message' then
+ strSuccessMessage := value
+ end; //ProcessNameValuePair
+
+ begin // ProcessCGIData
+ num := CountWords(strData, '&');
+ for i := 1 to num do
+ begin
+ EncodedVariable := CopyWord(strData, i, '&');
+ DecodedVariable := URLDecode(EncodedVariable);
+ p := pos('=', DecodedVariable);
+ if p > 0 then
+ begin
+ name := lowercase(trim(copy(DecodedVariable, 1, p-1)));
+ value := trim(copy(DecodedVariable, p+1));
+ ProcessNameValuePair;
+ end
+ end
+ end; // ProcessCGIData
+
+ //*******************************************************
+ //PURPOSE: Writes the HTTP response header
+ //*******************************************************
+ procedure WriteResponseHeader;
+ begin //WriteResponseHeader
+ writeln('Content-type: text/html');
+ writeln;
+ end; //WriteResponseHeader
+
+ //**************************************************************
+ //PURPOSE: Generates the HTML response and possibly send
+ // the email message.
+ //**************************************************************
+ procedure GenerateResponse;
+ var
+ i : integer;
+ InvalidTo : boolean;
+
+ procedure GenerateHTMLHeader;
+ begin
+ writeln('<html>');
+ writeln('<head>');
+ writeln('<title>CGIMail 1.0</title>');
+ writeln('<meta name="GENERATOR" content="CGIMail 1.0">');
+ writeln('<meta name="COPYRIGHT" content="Copyright (c) 2001, Stuart King.">');
+ writeln('</head>');
+ end;
+
+ procedure GenerateHTMLFooter;
+ begin
+ writeln('<hr>');
+ writeln('<p>');
+ writeln('CGIMail 1.0 Copyright &copy; 2001, Stuart King<br>');
+ writeln('Home page <a href="http://www.irietools.com/">www.irietools.com</a>');
+ writeln('</p>');
+ writeln('</body>');
+ writeln('</html>');
+ end;
+
+ //*******************************************************************
+ //PURPOSE: Generates the response when the email recipient (in strTo)
+ // is not specified.
+ //*******************************************************************
+ procedure GenerateNoTo;
+ begin
+ GenerateHTMLHeader;
+ writeln('<body>');
+ writeln('<h1>');
+ writeln('Email Address (Recipient) Required');
+ writeln('</h1>');
+ writeln('<p>The address of the email recipient was not specified.</p>');
+ if strErrorLink <> '' then
+ writeln('<p>Please click <a href="', EscapeCharacters(strErrorLink), '">here</a> to continue.</p>');
+ GenerateHTMLFooter;
+ end;
+
+ //*******************************************************************
+ //PURPOSE: Generates the response when the email recipient (in strTo)
+ // is invalid.
+ //*******************************************************************
+ procedure GenerateInvalidTo(strTo : string);
+ begin
+ GenerateHTMLHeader;
+ writeln('<body>');
+ writeln('<h1>');
+ writeln('Invalid Email Address (Recipient)');
+ writeln('</h1>');
+ writeln('<p>The following email address (', EscapeCharacters(strTo), ') is invalid.</p>');
+ if strErrorLink <> '' then
+ writeln('<p>Please click <a href="', EscapeCharacters(strErrorLink), '">here</a> to continue.</p>');
+ GenerateHTMLFooter;
+ end;
+
+ //*******************************************************************
+ //PURPOSE: Generates the response when the email sender (in strFrom)
+ // is invalid.
+ //*******************************************************************
+ procedure GenerateInvalidFrom;
+ begin
+ GenerateHTMLHeader;
+ writeln('<body>');
+ writeln('<h1>');
+ writeln('Invalid Email Address (Sender)');
+ writeln('</h1>');
+ writeln('<p>The following email address (', EscapeCharacters(strFrom), ') is invalid.</p>');
+ if strErrorLink <> '' then
+ writeln('<p>Please click <a href="', EscapeCharacters(strErrorLink), '">here</a> to continue.</p>');
+ GenerateHTMLFooter;
+ end;
+
+ //*******************************************************************
+ //PURPOSE: Generates the response when everything is OK and the email
+ // message has been sent.
+ //*******************************************************************
+ procedure GenerateEmailSent;
+ begin
+ GenerateHTMLHeader;
+ writeln('<body>');
+ writeln(strSuccessMessage);
+ if strSuccessLink <> '' then
+ writeln('<p>Please click <a href="', EscapeCharacters(strSuccessLink), '">here</a> to continue.</p>');
+ GenerateHTMLFooter;
+ end;
+
+ begin // GenerateResponse
+ if strTo = '' then
+ GenerateNoTo
+ else
+ begin
+ InvalidTo := false;
+ //Check each recipient address, if an invalid recipient is found
+ // generate the invalid recipient reponse and set the InValidTo
+ // flag so that no other responses get generated.
+ for i := 1 to CountWords(strTo, ',') do
+ if (not InvalidTo) and (not IsValidEmailAddress(CopyWord(strTo, i, ','))) then
+ begin
+ GenerateInvalidTo(CopyWord(strTo, i, ','));
+ InvalidTo := true
+ end;
+ //If thr InvalidTo flag has not been set then check the
+ // sender's email address if it was specified.
+ if not InvalidTo then
+ if (strFrom <> '') and (not IsValidEmailAddress(strFrom)) then
+ GenerateInvalidFrom
+ else
+ begin
+ //Everything is OK so send the email and generate
+ //the email send response.
+ SendEmail(strFrom, strTo, strSubject, strBody);
+ GenerateEmailSent
+ end
+ end;
+ end; // GenerateResponse
+
+begin
+ WriteResponseHeader;
+
+ Initialize;
+
+ ReadConfigFile;
+
+ GetCGIData(strCGIData);
+
+ ProcessCGIData(strCGIData);
+
+ GenerateResponse;
+end.
diff --git a/misc/pascal/tests/src/806-cgicook.pas b/misc/pascal/tests/src/806-cgicook.pas
new file mode 100644
index 000000000..7da5ecffd
--- /dev/null
+++ b/misc/pascal/tests/src/806-cgicook.pas
@@ -0,0 +1,771 @@
+(********************************************************************************************
+** PROGRAM : cgicook
+** VERSION : 1.0.0
+** DESCRIPTION : Demonstrates how to use cookies in CGI programs.
+** AUTHOR : Stuart King
+** COPYRIGHT : Copyright (c) Irie Tools, 2002. All Rights Reserved.
+** NOTES :
+** This sample program is distributed with Irie Pascal, and was written to illustrate
+** how to use cookies (i.e. how to read, write, and delete cookies). To make best use of
+** this sample you should have a basic understanding of Pascal as well as a basic
+** understanding of the Common Gateway Interface (CGI).
+**
+** Before describing how to use cookies, here is a very brief description of what
+** cookies are and what they are used for. Cookies are named pieces of information that a
+** website can ask a client (usually a browser) to store on its behalf. This information
+** can be sent back to the website (and any other website in the cookies domain) whenever
+** the browser sends a request to the website. Cookies are usually stored on the client's
+** hard drive and can persist for weeks, months, or even years. This makes cookies very
+** useful for 'remembering' information about website visitors.
+** IMPORTANT: The cookies sent between the client and the website are sent in text format
+** and are visible to any snooper, so sensitive information should either be encrypted
+** or sent only over a secure connection.
+**
+** Cookies are written by sending a "Set-Cookie" response header back to the client. The
+** syntax for the "Set-Cookie" header is given below:
+**
+** Set-Cookie: name=value; domain=.domain.com; path=/path;
+** expires=Day, dd-Mon-yyyy hh:mm:ss GMT; secure
+** Where
+** "name" is the name of the cookie.
+** "value" is the information stored by the cookie and must be specified. If you want
+** to delete a cookie then specify an expiry date that has already passed.
+** "domain" restricts the domains that will receive the cookie. The client should only send
+** the cookie to matching domains. Domains are matched from right to left. So
+** "domain=.irietools.com" matches "www.irietools.com" and "info.irietools.com".
+** If "domain" is specified it must match the domain of the website setting the
+** cookie. "domain" can't specify a top-level domain like ".com" or ".edu.jm".
+** If "domain" is not specified then the domain name of the website setting
+** the cookie is used.
+** "path" restricts the URLs within a domain that will receive the cookie. Paths are
+** matched from left to right and trailing /'s are ignored. If "path" is not
+** specified then the full path of the request is used.
+** "expires" specifies when the cookie should expire. The format of the expiry info
+** must be exactly as shown above:
+** "Day" is the three letter day of the week (Mon, Tue, Wed, Thu, Fri, Sat, or Sun).
+** "dd" is the two digit day of the month (01-31).
+** "Mon" is the three letter abbreviated month name
+** (Jan, Feb, Mar, Apr, Jun, Jul, Aug, Sep, Oct, Nov, Dec).
+** For example: "Mon, 16-Sep-2002 17:03:48 GMT".
+** If "expire" is not specified then the cookie is stored memory until the client
+** exits.
+** "secure" indicates that the cookie should only be sent over a secure connection.
+**
+** The browser sends cookies back to the website in the form of Cookie headers. The
+** format for Cookie headers is given below:
+**
+** Cookie: Cookie1; ...; CookieN
+** Where
+** each Cookiue is given as: name=value
+**
+** Only the "name" and the "value" of the cookies is returned, the other information
+** such as the "domain" is not returned. CGI programs can't read the Cookie headers
+** directly, so the webserver will make the Cookie header information available to the
+** CGI program in the HTTP_COOKIE environment variable.
+**********************************************************************************************)
+program cookies;
+const
+ MAX_BUFFER = 4096;
+ MAX_COOKIE_DATA = 200;
+ //SCRIPT_NAME = '/irietools/cgibin/cookies.exe';
+type
+ positive = 0..maxint;
+ BufferType = string[MAX_BUFFER];
+ CookieDataType = string[MAX_COOKIE_DATA];
+ DayOfWeek = 1..7;
+ Days = 1..31;
+ Months = 1..12;
+ date = record
+ day : Days;
+ month : Months;
+ year : integer;
+ dow : DayOfWeek
+ end;
+ Cookie = record
+ name : string;
+ value : CookieDataType
+ end;
+ CookieList = list of Cookie;
+var
+ buffer : BufferType;
+ strSetCookie : BufferType;
+ DaysInMonth : array[Months] of Days;
+ DaysElapsed : array[Months] of integer;
+ DayOfWeekShortNames : array[DayOfWeek] of string[3];
+ MonthShortNames : array[Months] of string[3];
+ Cookies : CookieList;
+
+ procedure DateToInt(dt : date; var iDays : integer); forward;
+ procedure IntToDate(iDays : integer; var dt : date); forward;
+ procedure CalculateDayOfWeek(var dt : date); forward;
+ function urlencode(strIn : string) : string; forward;
+ function EscapeCharacters(s : string) : string; forward;
+
+ //PURPOSE: Performs program initialization
+ procedure Initialize;
+ var
+ m : months;
+ begin (* Initialize *)
+ DaysInMonth[1] := 31;
+ DaysInMonth[2] := 28;
+ DaysInMonth[3] := 31;
+ DaysInMonth[4] := 30;
+ DaysInMonth[5] := 31;
+ DaysInMonth[6] := 30;
+ DaysInMonth[7] := 31;
+ DaysInMonth[8] := 31;
+ DaysInMonth[9] := 30;
+ DaysInMonth[10] := 31;
+ DaysInMonth[11] := 30;
+ DaysInMonth[12] := 31;
+
+ DaysElapsed[1] := 0;
+ for m := 2 to 12 do
+ DaysElapsed[m] := DaysElapsed[m-1]+DaysInMonth[m-1];
+
+ DayOfWeekShortNames[1] := 'Sun';
+ DayOfWeekShortNames[2] := 'Mon';
+ DayOfWeekShortNames[3] := 'Tue';
+ DayOfWeekShortNames[4] := 'Wed';
+ DayOfWeekShortNames[5] := 'Thu';
+ DayOfWeekShortNames[6] := 'Fri';
+ DayOfWeekShortNames[7] := 'Sat';
+
+ MonthShortNames[1] := 'Jan';
+ MonthShortNames[2] := 'Feb';
+ MonthShortNames[3] := 'Mar';
+ MonthShortNames[4] := 'Apr';
+ MonthShortNames[5] := 'May';
+ MonthShortNames[6] := 'Jun';
+ MonthShortNames[7] := 'Jul';
+ MonthShortNames[8] := 'Aug';
+ MonthShortNames[9] := 'Sep';
+ MonthShortNames[10] := 'Oct';
+ MonthShortNames[11] := 'Nov';
+ MonthShortNames[12] := 'Dec';
+
+ new(Cookies); //initialize the list of cookies
+ end; (* Initialize *)
+
+ //PURPOSE: Retrieves the information passed to the CGI applications.
+ //PARAMETER(s): cl - Used to store all the cookies that were passed to the CGI program
+ //GLOBAL(s) - buffer - Used to store the GET or POST information passed to the CGI program
+ procedure GetCGIData(var cl : CookieList);
+ var
+ RequestMethod : string;
+
+ //PURPOSE: Retrieves the cookies passed to the CGI program and puts then in the list.
+ //PARAMETER(s): cl - Used to store all the cookies that were passed to the CGI program
+ procedure GetCookieInfo(var cl : CookieList);
+ var
+ data : BufferType;
+ iNumCookies, iCurrCookie : positive;
+ iPos, iLen : positive;
+ strCurrCookie : CookieDataType;
+ c : Cookie;
+ begin (* GetCookieInfo *)
+ //The cookies are stored in the environment variable HTTP_COOKIE as space
+ // deliminated words with trailing semi-colons after each word (except the last word).
+ //Each word being a single cookie.
+ //Retrieve the cookies
+ data := getenv('HTTP_COOKIE');
+
+ //Retrieve the number words/cookies.
+ iNumCookies := countwords(data);
+
+ //Retrieve each cookie and use the "=" to seperate the name from the value
+ //then insert the cookie into the list.
+ for iCurrCookie := 1 to iNumCookies do
+ begin
+ strCurrCookie := copyword(data, iCurrCookie);
+ iPos := pos('=', strCurrCookie);
+ if iPos <> 0 then
+ begin
+ c.name := trim(copy(strCurrCookie, 1, iPos-1));
+ c.value := trim(copy(strCurrCookie, iPos+1));
+ iLen := length(c.value);
+ if (iLen<>0) and (c.value[iLen]=';') then
+ c.value := copy(c.value, 1, iLen-1);
+ insert(c, cl);
+ end;
+ end;
+ end; (* GetCookieInfo *)
+
+ //PURPOSE: Retrieves information sent to by a GET request (i.e. in the QUERY_STRING
+ // environment variable).
+ procedure GetRequest;
+ begin (* GetRequest *)
+ buffer := getenv('QUERY_STRING')
+ end; (* GetRequest *)
+
+ //PURPOSE: Retrieves information sent to by a POST request (i.e. through the standard
+ // input stream, with the length of the data in the environment variable
+ // CONTENT_LENGTH).
+ procedure PostRequest;
+ var
+ len, i : positive;
+ err : integer;
+ ContentLength : string;
+ c : char;
+ begin (* PostRequest *)
+ buffer := '';
+ ContentLength := getenv('CONTENT_LENGTH');
+ if ContentLength <> '' then
+ val(ContentLength, len, err)
+ else
+ len := 0;
+ if len <= MAX_BUFFER then
+ for i := 1 to len do
+ begin
+ read(c);
+ buffer := buffer + c
+ end
+ end; (* PostRequest *)
+
+ begin (* GetCGIData *)
+ GetCookieInfo(cl);
+ RequestMethod := getenv('REQUEST_METHOD');
+ if RequestMethod = 'GET' then
+ GetRequest
+ else
+ PostRequest
+ end; (* GetCGIData *)
+
+ //PURPOSE: Process the data passed to the program.
+ //NOTES: This is the main part of the program. After retreiving
+ // the information passed to the program this procedure is
+ // called to perform the required processing. This program receives to kinds
+ // of information:
+ // 1. Cookies sent back by the brower. These have already been retrieved by the
+ // the procedure "GetCGIData" and do not require further processing here.
+ // The procedure 'GenerateResponse' will display the retrieved cookies.
+ // 2. Information entered by the user about a cookie to add or delete. This
+ // information needs to formated and put in the global 'strSetCookie', so that
+ // it can be included in the response by the procedure 'GenerateResponse'.
+ procedure ProcessCGIData;
+ var
+ i, num, p : integer;
+ EncodedVariable, DecodedVariable, name, value : string;
+ strName : string;
+ strValue : string;
+ strExpiry : string;
+ blnDelete : boolean;
+
+ //PURPOSE: Converts a expiry date into a string in the format required
+ // by the Set-Cookie header (i.e. Day, dd-Mon-yyyy hh:mm:ss GMT
+ //ARGUMENT(s): dt - Expire date to convert.
+ //RETURNS: The expiry date/time in Set-Cookie format
+ //NOTES:
+ // This function just hard-codes the last second in the day "23:59:59"
+ // instead of using the current time or allowing the expiry time to be specified.
+ //This is done because
+ // 1. It is easier and this is just a sample program
+ // 2. Usually cookie will be set to expire either when the browser closes
+ // or after many days have passed, so the exact time is not important.
+ function FormatCookieExpiryString(dt : date) : string;
+ var
+ s : string;
+
+ //PURPOSE: Converts an integer into a zero-padded string
+ //ARGUMENT(s):
+ // 1. i - The integer to convert
+ // 2. len - The length of the string to return
+ //RETURNS:
+ // The zero padded string
+ function Int2String(i : integer; len : integer) : string;
+ var
+ S : string;
+ begin (* Int2String *)
+ str(i:1, s);
+ while length(s) < len do
+ s := '0' + s;
+ Int2String := s
+ end; (* Int2String *)
+
+ begin (* FormatCookieExpiryString *)
+ CalculateDayOfWeek(dt);
+ s := DayOfWeekShortNames[dt.dow]+', ';
+ s := s + Int2String(dt.day, 2)+'-'+MonthShortNames[dt.month]+'-'+Int2String(dt.year, 4)+' ';
+ s := s + '23:59:59 GMT';
+ FormatCookieExpiryString := s;
+ end; (* FormatCookieExpiryString *)
+
+ //PURPOSE: Processes the named value pairs sent with the GET or POST request.
+ // Which in this case is the information entered by the user about the
+ // cookie to add or delete.
+ //ARGUMENT(s): name - name part of the name/value pair
+ // value - value part of name/value pair
+ //NOTES:
+ // The information entered by the user is sent as name/value pairs (i.e. name-value)
+ //with the name part being the name of the form element holding the information and
+ //the value part being the actual information held by the form element.
+ procedure ProcessNameValuePair(var name, value : string);
+ var
+ dt : date;
+ dow : integer;
+ iDays, iErr : integer;
+ iDate : integer;
+ begin
+ //If the name is 'txtname' then this is the name of the cookie.
+ //The name is urlencoded in case it contains special characters
+ if name='txtname' then
+ strName := urlencode(value)
+ //If the name is 'txtvalue' then this is the value of the cookie.
+ //The value is urlencoded in case it contains special characters
+ else if name='txtvalue' then
+ strValue := urlencode(value)
+ //If the name is 'txtdays' then this is the number of days before the cookie
+ //expires. The value is converted to an integer and if the conversion is
+ //successful the value is added to the current date to get the expiry date
+ //and this date is formatted for use in a Set-Cookie header.
+ else if name='txtdays' then
+ begin
+ val(value, iDays, iErr);
+ if iErr=0 then
+ begin
+ getdate(dt.year, dt.month, dt.day, dow);//Get current date
+ DateToInt(dt, iDate); //Convert current date to number of days since Jan 1, 0001 AD
+ iDate := iDate + iDays; //Add in the number of days to expire
+ IntToDate(iDate, dt); //Convert the result back into a date
+ strExpiry := FormatCookieExpiryString(dt); //Format date
+ end;
+ end
+ //If the name is 'cmddelete' then the cookie should be deleted not added.
+ //The cookie is deleted by setting an expiry date that has already passed.
+ else if name='cmddelete' then
+ begin
+ getdate(dt.year, dt.month, dt.day, dow);
+ DateToInt(dt, iDate);
+ iDate := iDate - 2;
+ IntToDate(iDate, dt);
+ strExpiry := FormatCookieExpiryString(dt);
+ blnDelete := true
+ end
+ else
+ ;
+ end;
+
+ begin (* ProcessCGIData *)
+ strSetCookie := '';
+ strName := '';
+ strValue := '';
+ strExpiry := '';
+ blnDelete := false;
+
+ //Retrieve each name/value pair from the form and processes them.
+ num := CountWords(buffer, '&');
+ for i := 1 to num do
+ begin
+ EncodedVariable := CopyWord(buffer, i, '&');
+ DecodedVariable := URLDecode(EncodedVariable);
+ p := pos('=', DecodedVariable);
+ if p > 0 then
+ begin
+ name := lowercase(trim(copy(DecodedVariable, 1, p-1)));
+ value := trim(copy(DecodedVariable, p+1));
+ ProcessNameValuePair(name, value);
+ end
+ end;
+
+ //If after processing each name/value pair we have enough data for a
+ //"Set-Cookie" header then generate a "Set-Cookie" header in the global
+ //"strSetCookie".
+ //if (strName<>'') and ((strValue<>'') or blnDelete) and (strExpiry<>'') then
+ if (strName<>'') and ((strValue='') or (strExpiry<>'')) then
+ begin
+ //Set-Cookie: name=value; domain=.irietools.com; path=/cgibin;
+ // expires=Tue, 03-Sep-2002 20:42:19 GMT; secure
+ strSetCookie := 'Set-Cookie: ' + strName + '=' + strValue + ';';
+ if strExpiry<>'' then
+ strSetCookie := strSetCookie + ' expires=' + strExpiry;
+ end;
+ end; (* ProcessCGIData *)
+
+ //PURPOSE: Generates the response to send back to the browser.
+ //NOTES:
+ // Most of the HTML generated by this procedure actually comes from a template file.
+ //The HTML from the template file is common to almost all the pages on this website.
+ //The HTML specific to this program (i.e. the form that accepts the cookie information
+ //from the user), is generated by the local procedure 'GenerateBodyData'. So this procedure
+ //basically reads the template file and sends most of it to the webserver except for
+ //a small section which it repalces with the output of the procedure 'GenerateBodyData'.
+ //The template file is divided into sections using HTML comments. The start of a section
+ //is marked by the following
+ //
+ // <!--section SectionName-->
+ //
+ //Where "SectionName" is the name of the section.
+ //
+ //The end of a section is marked by
+ //
+ // <!--/section-->
+ //
+ //What this procedure actually does is read the template file and write the contents
+ //of all the sections except one to the webserver. The section not written to the webserver
+ //is called "bodydata". Instead of writing the contents of the section "bodydata" to the
+ //webserver the ouput of the procedure "GenerateBodyData" is sent to the webserver.
+ //This is done because it is much easier to work with HTML using an HTML editor rather
+ //than using embedded writeln's inside a CGI program. So an HTML editor is used to
+ //create and update the template file and the portion of the generated output that
+ //is specific to this program is generated by "GenerateBodyData". You will notice
+ //when you run this program that the page generated looks alot like the other pages
+ //on the website because most of it comes from the template file.
+ procedure GenerateResponse;
+ const
+ TEMPLATE_FILE = 'template.html';
+ START_SECTION = '<!--section';
+ END_SECTION = '<!--/section-->';
+ SECTION_NAME = 'bodydata';
+ var
+ f : text;
+ line : BufferType;
+ blnSkipping : boolean;
+
+ //PURPOSE: Generates the portion of the response page that is specific to this
+ // program (the rest of the response page comes from the template file).
+ //NOTES:
+ // Tables are used to organise the layout of the generated pages on this website.
+ //The portion of the response page generated by this procedure is a single row of
+ //a table. Unless you are an HTML expert the easiest way to understand the HTML
+ //generated by this procedure is probably to run this program and view the
+ //response pages generated.
+ procedure GenerateBodyData;
+ var
+ iNumCookies, iCurrCookie : positive;
+ c : Cookie;
+ begin (* GenerateBodyData *)
+ writeln('<tr>');
+ writeln('<td width="100%">');
+
+ //Generate the HTML to display the cookies returned by the browser.
+ writeln('<h1>Current Cookies</h1>');
+ iNumCookies := length(Cookies); //Number of cookies returned by the browser
+ if iNumCookies=0 then
+ writeln('<p>None</p>')
+ else
+ //For each cookie returned write it's name and value
+ //NOTE: The name and value are escaped in case they contain
+ //special characters.
+ for iCurrCookie := 1 to iNumCookies do
+ begin
+ c := Cookies[iCurrCookie];
+ writeln('<p>', EscapeCharacters(urldecode(c.name)), '=', EscapeCharacters(urldecode(c.value)),'</p>');
+ end;
+ writeln('<hr>');
+ writeln('<p>', getenv('SCRIPT_NAME'), '</p>');
+ writeln('<hr>');
+
+ //Generate the HTML for the form
+ writeln('<form method="POST" action="', getenv('SCRIPT_NAME'), '">');
+ writeln('<p><big><strong>Name:</strong></big> <input type="text" name="txtName" size="25"></p>');
+ writeln('<p><big><strong>Value:</strong></big> <input type="text" name="txtValue" size="56"></p>');
+ writeln('<p><big><strong>Expiries in:</strong></big> <input type="text" name="txtDays" size="5"> <big><strong>Days</strong></big></p>');
+ writeln('<p><input type="submit" value=" Add Cookie " name="cmdAdd">');
+ writeln('<input type="submit" value=" Delete Cookie " name="cmdDelete">');
+ writeln('<input type="reset" value=" Reset " name="cmdReset"></p>');
+ writeln('</form>');
+
+ writeln('</td>');
+ writeln('</tr>');
+ end; (* GenerateBodyData *)
+
+ begin (* GenerateResponse *)
+ //Generate the response headers (including the blank line at the end).
+ writeln('content-type: text/html');
+ if strSetCookie <> '' then
+ writeln(strSetCookie);
+ writeln;
+
+ blnSkipping := false;
+ reset(f, TEMPLATE_FILE);
+
+ //Read each line in the template file and search for section markers
+ //If a target section marker is found then call 'GenerateBodyData' to
+ //generate the HTML for that section and set 'blnSkipping' to true so
+ //that the contents of that section, from the template file, will be skipped.
+ while not eof(f) do
+ begin
+ readln(f, line);
+ line := trim(line);
+ if pos(START_SECTION, line) > 0 then
+ begin
+ if pos(SECTION_NAME, line) > 0 then
+ begin
+ GenerateBodyData;
+ blnSkipping := true;
+ end
+ end
+ else if line=END_SECTION then
+ blnSkipping := false
+ else if not blnSkipping then
+ writeln(line);
+ end;
+ close(f);
+ end; (* GenerateResponse *)
+
+ procedure Shutdown;
+ begin (* Shutdown *)
+ dispose(Cookies);
+ end; (* Shutdown *)
+
+ //PUPOSE: Determines if a year was a leap year.
+ function IsLeapYear(year : integer) : boolean;
+ begin (* IsLeapYear *)
+ IsLeapYear :=
+ ((year mod 4)=0)
+ and
+ (
+ ((year mod 100)<>0)
+ or
+ ((year mod 400)=0)
+ );
+ end; (* IsLeapYear *)
+
+ //PURPOSE: Converts a date into an integer. The integer represents the
+ // number of days since 'Jan 1, 0001 AD'. Negative values present
+ // the number of days before 'Jan 1, 0001 AD' (i.e. BC dates).
+ //ARGUMENT(s): dt - The date to convert to an integer
+ // iDays - The converted date as an integer.
+ procedure DateToInt;
+ var
+ i, year : integer;
+
+ //PURPOSE: Used to help adjust for the leap years when calulating the number
+ // of days that have already elapsed since the year began.
+ //RETURNS: +1 if the date is a leap year and the month of february
+ // has already passed.
+ // or
+ // 0 otherwise
+ function LeapYearAdjustment(dt : date) : integer;
+ var
+ iAdjustment : integer;
+
+ begin (* LeapYearAdjustment *)
+ iAdjustment := 0;
+
+ if (IsLeapYear(dt.year)) and (dt.month >= 3) then
+ iAdjustment := 1;
+
+ LeapYearAdjustment := iAdjustment;
+ end; (* LeapYearAdjustment *)
+
+ begin (* DateToInt *)
+ if dt.year < 0 then
+ year := dt.year+1 //Adjust for the fact that there was no year 0.
+ else
+ year := dt.year;
+ //Calculate days since Jan 1, 0001 AD ignoring leap years.
+ i := (year-1)*365 + DaysElapsed[dt.month] + (dt.day-1);
+
+ //Adjust for leap years except the final year
+ i := i + ((year-1) div 4) - ((year-1) div 100) + ((year-1) div 400);
+
+ //Add 1 if the final year is a leap year and february has passed.
+ iDays := i + LeapYearAdjustment(dt);
+ end; (* DateToInt *)
+
+ //PURPOSE: Coverts an integer, representing the number of days since Jan 1, 0001 AD
+ // to a date.
+ //ARGUMENT(s): iDays - The integer to convert to a date.
+ // dt - The converted date.
+ //NOTE: There are 365.2425 days in the year adjusting for leap years.
+ procedure IntToDate;
+ var
+ m : Months;
+ d : integer;
+ iError, iTemp : integer;
+ begin
+ //First calculate an approximation of the correct answer
+ if iDays >= 0 then
+ begin
+ dt.year := trunc(idays / 365.2425)+1;
+ iTemp := iDays - trunc((dt.year-1)*365.2425);
+ end
+ else
+ begin
+ dt.year := -(trunc(abs(idays) / 365.2425)+1);
+ iTemp := abs(abs(iDays) - trunc((abs(dt.year)-1)*365.2425));
+ end;
+
+ dt.month := 12;
+ for m := 1 to 12 do
+ if iTemp >= DaysElapsed[m] then
+ dt.month := m;
+
+ iTemp := iTemp - DaysElapsed[dt.month];
+
+ d := iTemp+1;
+ if d > DaysInMonth[dt.month] then
+ dt.day := DaysInMonth[dt.month]
+ else
+ dt.day := d;
+
+ //Now to keep adjusting our approximation until it is exact
+ DateToInt(dt, iTemp);
+ while iTemp<>iDays do
+ begin
+ //Number of days that need to be added to the approximation to make it correct.
+ iError := iDays-iTemp;
+
+ //If adding the days would make the day of the month negative then
+ // then move the approximation to the beginning of the previous month.
+ // Adjusting the year if necessary (i.e. it is the first month of the year).
+ if (dt.day + iError) < 1 then
+ begin
+ if dt.month=1 then
+ begin
+ dt.month := 12;
+ dt.year := dt.year - 1;
+ if dt.year = 0 then
+ dt.year := -1;
+ end
+ else
+ dt.month := dt.month - 1;
+ dt.day := 1;
+ end
+ //If adding the days might take the date into the next month then
+ // check if adding the days actually takes the date to Feb 29 on a leap year
+ // if so then adjust the date to Feb 29
+ //otherwise move the date to the beginning of the next month.
+ else if (dt.day + iError) > DaysInMonth[dt.month] then
+ begin
+ if (dt.month=2) and (IsLeapYear(dt.year)) and (dt.day+iError=DaysInMonth[dt.month]+1) then
+ dt.day := DaysInMonth[dt.month]+1
+ else
+ begin
+ if dt.month=12 then
+ begin
+ dt.month := 1;
+ dt.year := dt.year + 1;
+ if dt.year = 0 then
+ dt.year := 1;
+ end
+ else
+ dt.month := dt.month + 1;
+ dt.day := 1
+ end
+ end
+ //else adding the days results in a valid day of the month then
+ // just add the days.
+ else
+ dt.day := dt.day + iError;
+
+ DateToInt(dt, iTemp);
+ end;
+ end;
+
+ //PURPOSE: Calculates the day of the week of a given date
+ //ARGUMENT(s): dt - The date to calculate the day of the week of.
+ //NOTES:
+ // First the date is converted into the number of days since (Jan 1, 0001 AD)
+ //Next this value is adjusted with the day of the week of Jan 1, 0001 AD.
+ //Next mod 7 is used to give a value in the range 0..6 that repeats every
+ //seven days (like the days of the week).
+ //Finally the value is incremented by 1 to give a value in the range 1..7
+ //
+ //The most interesting part of this algorithm is probably the adjustment for the
+ //first day of the week. Suppose this adjustment was not made then of the date
+ //was Jan 1, 0001 AD then 'DateToInt' would calculate the number of days as 0.
+ //Then (0 mod 7) + 1 would give the value 1 or Sunday. But Jan 1, 0001 AD was a
+ //Monday, so we need to add a 1 to adjust for this fact. How do I know that
+ //Jan 1, 0001 AD was a Monday? I don't, but I do know that day of the week of
+ //today. So what I did was calculate the day of the week for today without the
+ //adjustment and then added an adjustment that resulted in the correct value.
+ procedure CalculateDayOfWeek;
+ const
+ ADJUST_FOR_FIRST_DAY = 1; //Apparently Jan 1, 0001 AD was a Monday
+ var
+ iDays : integer;
+ begin (* CalculateDayOfWeek *)
+ DateToInt(dt, iDays);
+ dt.dow := ((iDays+ADJUST_FOR_FIRST_DAY) mod 7) + 1;
+ end; (* CalculateDayOfWeek *)
+
+ //PURPOSE: Returns the URL encoded version of a string.
+ //ARGUMENT(s): strIn - The string to be encoded.
+ //NOTES:
+ // Spaces are converted to '-' and non-alphanumeric characters are converted
+ //to %NN, where NN is the hexidecimal value of the chacters ordinal value. This
+ //is the reverse of the built-in function 'urldecode'.
+ function urlencode;
+ var
+ strOut : string;
+ i : positive;
+ c : char;
+ sTemp : string[3];
+ begin (* urlencode *)
+ strOut := '';
+ for i := 1 to length(strIn) do
+ begin
+ c := strIn[i];
+ if c = ' ' then
+ strOut := strOut + '+'
+ else if isalphanum(c) then
+ strOut := strOut + c
+ else
+ begin
+ sTemp := hex(ord(c));
+ if length(sTemp)=1 then
+ sTemp := '0' + sTemp;
+ strOut := strOut + '%' + sTemp
+ end;
+ end;
+ urlencode := strOut;
+ end; (* urlencode *)
+
+ //*************************************************************************
+ //PURPOSE: This function converts certain characters that have a
+ // special meaning in HTML documents to their HTML representation.
+ //ARGUMENT(s): s - The string to be escaped.
+ //RETURNS: The string with all special characters escaped.
+ //NOTES: The characters converted are < > "
+ function EscapeCharacters;
+ const
+ LessThanChar = '<';
+ GreaterThanChar = '>';
+ QuoteChar = '"';
+ HTMLLessThan = '&lt;';
+ HTMLGreaterThan = '&gt;';
+ HTMLQuote = '&quot;';
+ var
+ i : positive;
+
+ procedure ReplaceChar(var strBuffer : string; strReplace : string; i : positive);
+ begin
+ delete(strBuffer, i, 1);
+ insert(strReplace, strBuffer, i)
+ end;
+
+ begin (* EscapeCharacters *)
+ repeat
+ i := pos(LessThanChar, s, 1);
+ if i > 0 then
+ ReplaceChar(s, HTMLLessThan, i)
+ until i = 0;
+
+ repeat
+ i := pos(GreaterThanChar, s, 1);
+ if i > 0 then
+ ReplaceChar(s, HTMLGreaterThan, i)
+ until i = 0;
+
+ repeat
+ i := pos(QuoteChar, s, 1);
+ if i > 0 then
+ ReplaceChar(s, HTMLQuote, i)
+ until i = 0;
+
+ EscapeCharacters := s;
+ end; (* EscapeCharacters *)
+
+begin
+ Initialize;
+
+ GetCGIData(Cookies);
+
+ ProcessCGIData;
+
+ GenerateResponse;
+
+ Shutdown;
+end.
diff --git a/misc/pascal/tests/src/901-pageutils.pas b/misc/pascal/tests/src/901-pageutils.pas
new file mode 100644
index 000000000..855620b1c
--- /dev/null
+++ b/misc/pascal/tests/src/901-pageutils.pas
@@ -0,0 +1,5651 @@
+UNIT pageutls;
+
+INTERFACE
+
+CONST
+emp_logonid = '$own$';
+flag_on = 'y';
+flag_off = 'n';
+pcs_phys_termtype = 'PCS';
+min_integer = -2100000000;
+max_integer = 2100000000;
+invalid_integer = 2147483647;
+invalid_timestamp = invalid_integer;
+invalid_saldo = invalid_integer;
+invalid_short = 32767;
+invalid_duration = invalid_short;
+undefined_sreal = -32767;
+invalid_taris_time = -9999;
+no_time = -9998;
+no_allowance = no_time;
+min_year = 25;
+no_year_high = 2100;
+only_valid_blockid = 6309;
+sign_offset = 128;
+seconds_per_day = 86400;
+max_allowance = 2880;
+empty_integer = -2147483647;
+empty_short = -32767;
+no_variable = empty_integer;
+keydata_len = 60;
+break_add_on = 64;
+first_search_char = 32;
+last_search_char = 255;
+type_char = 256;
+type_unsigned_byte = 257;
+type_short = 512;
+type_mod = 513;
+type_duration = 514;
+type_dduration = 515;
+type_allowance = 516;
+type_long = 768;
+type_saldo = 769;
+type_dsaldo = 770;
+type_balance = 771;
+type_date = 1024;
+type_time = 1025;
+type_emplno = -32512;
+type_deptno = -32511;
+type_costid = -32510;
+tyoe_employcat = -32509;
+type_commtype = -32508;
+emplno_len = 10;
+deptno_len = 10;
+employcat_len = 4;
+adjustcat_len = 4;
+firstname_len = 20;
+surname_len = 30;
+badgeno_len = 10;
+long_badgeno_len = 20;
+objectid_len = 8;
+logonid_len = 8;
+chapter_len = 10;
+objecttype_len = 8;
+phys_filename_len = 32;
+processname_len = 32;
+code_len = 4;
+long_record_len = 32000;
+exit_code_len = 6;
+error_text_len = 60;
+perror_text_len = 80;
+part_of_error_text_len = 57;
+vos_modulename_len = 32;
+time_zone_len = 3;
+tmon_command_line_len = 300;
+input_line_len = 1024;
+comm_buffer_len = 4096;
+double_comm_buffer_len = 8192;
+cci_header_len = 4;
+long_text_len = 30;
+time_array_len = 5;
+rpoolid_len = 12;
+max_no_of_attributes = 8;
+attribid_len = 12;
+parproid_len = 12;
+projectid_len = 12;
+taskid_len = 12;
+versionid_len = 4;
+export_data_len = 249;
+pcs_request_len = 200;
+costid_type_len = 20;
+costid_ext_type_len = 22;
+search_set_len = 20;
+cust_conv_table_common_type_len = 16001;
+tstat_tab_len = 36;
+max_repvar_len = 16;
+userid_len = 16;
+recid_len = 8;
+fieldid_len = 16;
+queryid_len = 8;
+maxaccesses = 400;
+maxallowances = 5;
+maxalt_wpats = 8;
+maxbreaks = 6;
+maxdaytypes = 10;
+maxdiffs_from_plan = 12;
+maxseverity_codes = 8;
+maxshifts_per_cycle = 64;
+maxacmasks = 96;
+maxaccodes = 48;
+maxtermcats = 4;
+max_menue_lines = 12;
+max_select_options = 16;
+maxacsel = 48;
+maxclients = 5;
+maxmethods = 26;
+maxdaysloaded = 5;
+max_search_sets_in_list = 24;
+max_prcon2_printers = 20;
+max_costno_grupps = 178;
+maxtp = 50;
+maxtimepairs = 16;
+maxtimepairs_per_record = 4;
+maxtimepair_records = 4;
+maxtimes_booked = 32;
+max_daily_inc_corrections = 40;
+maxtimes = 64;
+maxcodes = 32;
+maxrecords = 8;
+maxcorr_incomes = 10;
+maxvacations = 4;
+maxzones = 64;
+max_no_of_balances = 24;
+max_no_of_oem_balances = 8;
+max_no_of_inc_groups = 8;
+max_inc_per_group = 5;
+first_no_basic_bal_ids = 33;
+max_no_basic_bal_ids = 48;
+max_sel_inc_per_group = 10;
+max_no_sel_inc_bal_ids = 98;
+max_empl_corr_values = 4;
+max_comp_balances = 40;
+adjust_rule_tab_len = 72;
+mcconf_rule_tab_len = 5;
+first_memory = 224;
+last_memory = 233;
+rule_applies = 'y';
+rule_applies_not = 'n';
+rule_applies_possibly = ' ';
+max_query_records = 15;
+query_def_len = 200;
+queryt_def_len = 3000;
+max_fields_per_record = 234;
+max_selected_fields = 500;
+selection_line_len = 2000;
+max_winc_incomes = 36;
+max_winc_codeids = 70;
+max_winc2_codeids = 109;
+max_winc_dayincs = 10;
+max_standard_cols = 10;
+no_value = chr (3);
+total_value = chr (4);
+planned_days_value = chr (5);
+current_value = chr (6);
+target_value = chr (7);
+created_until_value = chr (8);
+vl_max_cols = 32;
+vl_dinfo_string_len = 30;
+vl_output_line_len = 78;
+vl_index_output_line_len = 75;
+vl_filler_var_len = 3000;
+dslang_key_len = 64;
+dslang_year_offset = 2000;
+dbg_option_default = 0;
+dbg_append = 1;
+dbg_timestamp = 2;
+dbg_header = 4;
+dbg_force_flush = 8;
+dbg_indent = 16;
+dbg_lineheader = 32;
+dbg_max_sessions = 100;
+dbg_max_levels = 10;
+dbg_max_progs = 100;
+dbg_default = 1;
+dbg_debug = 2;
+dbg_dump = 3;
+dbg_deep_dump = 4;
+dbg_special = 5;
+maxprogs = 250;
+awtime_max_projects_per_day = 69;
+select_emplno = 'e';
+select_deptno = 'd';
+select_employcat = 'E';
+select_name = 'n';
+select_factory = 'f';
+select_costid = 'c';
+select_no_sort = 'q';
+select_mach_job = 'm';
+max_installations = 32;
+max_zones = 200;
+tps_per_access_range = 3;
+startup_string_len = 512;
+parm_tab_len = 24;
+parm_tab_line_len = 60;
+no_export = 'n';
+pids = 'y';
+siport = 's';
+siport_badgeno_len = 14;
+CreateTimeZone = 'c';
+DeleteTimeZone = 'd';
+CreatePers = 'p';
+DeletePers = 'l';
+SetPersInfo = 'i';
+SetDayType = 's';
+AccessPers = 'a';
+RefreshAllTimeZones = 'r';
+RefreshAllDayType = 't';
+RefreshAllPers = 'f';
+NoAction = ' ';
+maxdefault_time_incomes = 4;
+maxcostbookings = 32;
+maxcostbookingst = 64;
+center = 'c';
+right = 'r';
+left = 'l';
+justify_center = 'c';
+justify_right = 'r';
+justify_left = 'l';
+prt_messages = 'p';
+prt_errors = 'q';
+ret_errors = 'r';
+lm_normal = 'n';
+lm_change = 'c';
+lm_update = 'u';
+lm_insert = 'i';
+lm_old = ' ';
+lm_lsg = 'd';
+orderno_len = 16;
+fault_reasonid_len = 4;
+prod_operationid_len = 4;
+piece_work_type_len = 4;
+fkey_maxpages = 3;
+fkey_maxlines = 6;
+fkey_maxcols = 4;
+fkey_max_per_page = 8;
+unused_return_value = 0;
+request_ok = 1;
+request_error = 2;
+invalid_badgeno = 3;
+invalid_costid = 4;
+booking_in_core_time = 5;
+last_going_automatic = 6;
+invalid_pin_code = 7;
+invalid_terminal = 8;
+unsufficient_allowance = 9;
+invalid_emplno = 10;
+rc_dummy5 = 11;
+rc_dummy6 = 12;
+rc_dummy7 = 13;
+rc_dummy8 = 14;
+rc_dummy9 = 15;
+rc_dummy10 = 16;
+unknown_error = 17;
+not_valid_input = 18;
+not_valid_master_data = 19;
+no_sfc_error = 20;
+more_employees_than_planned = 21;
+more_prod_steps_than_planned = 22;
+no_next_pstep_found = 23;
+not_in_tolerances = 24;
+unexpected_machine = 25;
+booking_forced = 26;
+less_employees_than_planned = 27;
+prod_step_overlap = 28;
+cost_booking_failed = 29;
+employee_already_registrated = 30;
+not_all_employees_have_completed = 31;
+not_interrupted = 32;
+no_timestamp_found = 33;
+prod_step_not_active = 34;
+prod_step_already_registrated = 35;
+prod_step_already_completed = 36;
+prod_step_not_registrated = 37;
+sequence_error = 38;
+tolerance_exceeded = 39;
+employee_has_already_completed = 40;
+too_many_prod_steps = 41;
+too_many_employees = 42;
+employee_not_on_prod_step = 43;
+unknown_machine = 44;
+unknown_message_type = 45;
+unknown_request_type = 46;
+wrong_machine = 47;
+unknown_sfc_badgeno = 48;
+unknown_prod_step = 49;
+unknown_order = 50;
+too_less_employees = 51;
+prod_status_is_hold = 52;
+sfc_queue_error = 53;
+employee_not_registrated = 54;
+sfc_file_error = 55;
+already_interrupted = 56;
+already_resumed = 57;
+sfc_booking_ignored = 58;
+unknown_fault_reason = 59;
+too_many_messages_per_second = 60;
+undefined_sfc_code = 61;
+employee_on_too_many_machines = 62;
+no_sfc_permission = 63;
+created_employee_completion = 64;
+auto_empl_completion_failed = 65;
+machine_overlap = 66;
+sfc_booking_while_absent = 67;
+employee_on_too_many_psteps = 68;
+special_interruption = 69;
+no_sfc_info_error = 70;
+inherit_quantity_active = 71;
+predecessors_not_completed = 72;
+predecessors_completed = 73;
+unknown_machine_order = 74;
+undefined_parallelity = 75;
+quantity_changed = 76;
+no_space_for_splitting = 77;
+msg_type_not_allowed = 78;
+employee_not_valid = 79;
+auto_empl_registration_failed = 80;
+employee_not_startup_registrated = 81;
+employee_already_startup_registrated = 82;
+quantity_change_failed = 83;
+quantity_too_small = 84;
+more_costtypes = 85;
+other_msg_type_expected = 86;
+offline_booking = 87;
+no_answer_from_terminal = 88;
+responsibility_change_request = 89;
+responsibility_change_successful = 90;
+responsibility_table_error = 91;
+sfc_custom_error = 100;
+check_balance_base = 2140000000;
+ts_req_msgno = 1;
+ts_rpl_msgno = 2;
+read_reqno = 1;
+more_reqno = 2;
+change_reqno = 3;
+print_reqno = 4;
+demp_download_reqno = 5;
+delete_reqno = 6;
+get_codeid_reqno = 10;
+get_wpatid_reqno = 11;
+get_special_service_reqno = 12;
+load_abbr_list_reqno = 13;
+get_vemp_reqno = 14;
+get_mach_job_reqno = 15;
+get_cycleid_reqno = 16;
+fill_timepair_info_reqno = 17;
+update_dscalen_tab_reqno = 18;
+read_abilities_reqno = 19;
+read_requirements_reqno = 20;
+load_empl_data_reqno = 21;
+load_external_empl_reqno = 22;
+load_empl_list_reqno = 23;
+load_reassigned_empls_reqno = 24;
+write_schedule_reqno = 25;
+get_accesses_reqno = 26;
+load_staff_list_reqno = 27;
+get_wpatid_from_cycle_reqno = 28;
+load_empl_djob_data_reqno = 29;
+write_djob_tab_reqno = 30;
+load_squal_list_reqno = 31;
+nvvlist_reqno = 32;
+get_caschid_reqno = 33;
+write_staff_tab_reqno = 34;
+save_cascw_tab_reqno = 35;
+save_cascj_tab_reqno = 36;
+get_cascjid_reqno = 37;
+get_cascwid_reqno = 38;
+get_dscols_reqno = 39;
+get_ruleid_reqno = 40;
+get_casceid_reqno = 41;
+read_dscalen_reqno = 42;
+read_dssgnoff_reqno = 43;
+write_dssgnoff_reqno = 44;
+update_comms_reqno = 46;
+dkeys_abbr_tab_len = 500;
+function_code_len = 1;
+change_insert = 'i';
+change_update = 'u';
+change_delete = 'd';
+change_copy = 'c';
+change_rename = 'r';
+change_copy_new = 'n';
+change_insert_new = 'w';
+variants_current = 'c';
+variants_newest = 'n';
+variants_future = 'f';
+variants_all = 'a';
+variants_oneday = 'h';
+variants_onlyone = 'o';
+acalen_msg_ct = 80;
+acalen_max_lines = 160;
+accemp_rpl_ct = 30;
+anlbal_rpl_ct = 221;
+atcomp_rpl_ct = 39;
+awtime_rpl_ct = 31;
+awtime_comment_rpl_ct = 44;
+awtime_task_rpl_ct = 78;
+bookmsg_rpl_ct = 16;
+bmsg_rpl_ct = bookmsg_rpl_ct;
+ccomp_rpl_ct = 45;
+comm_rpl_ct = 36;
+comm_update_ct = 50;
+corder_rpl_ct = 11;
+cols_rpl_ct = 18;
+cplan_rpl_ct = 27;
+cplane_rpl_ct = cplan_rpl_ct;
+cplanm_rpl_ct = cplan_rpl_ct;
+cplanp_rpl_ct = 28;
+cusers_rpl_ct = 11;
+dabsemp_rpl_ct = 14;
+dabsgrp_rpl_ct = 12;
+dacce_rpl_ct = 100;
+daccv_rpl_ct = 30;
+daccz_rpl_ct = 49;
+dcbal_rpl_ct = 22;
+dcost_rpl_ct = 45;
+demp_rpl_ct = 18;
+demp_download_ct = 225;
+derrors_rpl_ct = 16;
+dfrsn_rpl_ct = 49;
+dkeys_rpl_ct = 20;
+dmonth_rpl_ct = 40;
+dmsg_rpl_ct = 26;
+dorder_rpl_ct = 44;
+dperror_rpl_ct = 39;
+dpres_rpl_ct = 19;
+dprint_rpl_ct = 12;
+dprint2_rpl_ct = 3540;
+dpsopn_rpl_ct = 60;
+dpstep_rpl_ct = 66;
+dpwarn_rpl_ct = 22;
+dscom_rpl_ct = 50;
+dscom_update_ct = 50;
+dsplan_rpl_ct = 28;
+dstatus_rpl_ct = 58;
+dswarn_rpl_ct = 12;
+dvisit_rpl_ct = 34;
+dwarn_rpl_ct = 12;
+dzone_rpl_ct = 45;
+empvar_rpl_ct = 59;
+emplac_rpl_ct = 60;
+lmsg_rpl_ct = bookmsg_rpl_ct;
+lpstep_rpl_ct = 48;
+ltime_rpl_ct = 17;
+ltime_update_ct = 60;
+mcbal_rpl_ct = 15;
+menue_rpl_ct = 40;
+monov_rpl_ct = 40;
+msg_rpl_ct = 8;
+order_rpl_ct = 50;
+pbar_rpl_ct = 30;
+plan_rpl_ct = 13;
+plan_tab_max = 27;
+pconf_rpl_ct = 12;
+pconf_update_ct = 24;
+pnet_rpl_ct = pbar_rpl_ct;
+ppbook_line_ct = 130;
+ppbook2_line_ct = 59;
+ppord_rpl_ct = 64;
+prstat_rpl_ct = 17;
+prstat_dsp_rpl_ct = 3660;
+pscap_rpl_ct = 80;
+psprod_rpl_ct = 80;
+pstruc_rpl_ct = 23;
+pwbal_rpl_ct = 12;
+query_rpl_ct = 25;
+queryd_rpl_ct = 36;
+dscost_rpl_ct = 18;
+tstat_rpl_ct = 36;
+upstep_rpl_ct = 50;
+vds_rpl_ct = 49;
+recobh_rpl_ct = 58;
+smsg_rpl_ct = 75;
+time_rpl_ct = 1;
+ttline_rpl_ct = 13;
+wcycst_rpl_ct = 30;
+chlog_rpl_ct = 70;
+rcalen_rpl_ct = 12;
+mplace_rpl_ct = 2;
+comm_text_buffer_len = 1080;
+max_fields_per_mask = 200;
+term_ct = 10;
+job_rpl_ct = 20;
+pemploy_rpl_ct = 10;
+reass_rpl_ct = 24;
+reass_rpl3_ct = 10;
+reass_upd_ct = 15;
+reass_cqg_ct = 199;
+aemploy_rpl_ct = 10;
+avemp_rpl_ct = 60;
+res_rpl_ct = 57;
+profil_rpl_ct = 59;
+max_pmreq_tab_len = 68;
+statusid_len = 8;
+schedu_rpl_ct = 2;
+opspla_rpl_ct = 2;
+emsche_rpl_ct = 10;
+ts_schedu_load_abbr_list_ct = 25;
+ts_schedu_read_able_ct = 40;
+ts_schedu_read_reqs_ct = 10;
+ts_schedu_load_empl_list_ct = 8;
+ts_schedu_load_emplno_list_ct = 200;
+ts_schedu_max_empls_ct = 250;
+ts_schedu_max_jobs_ct = 64;
+ts_schedu_load_reass_empls_ct = 7;
+ts_schedu_load_empl_data_ct = 20;
+ts_schedu_write_schedule_ct = 10;
+schedu_max_conflicts = 20;
+ts_schedu_max_staff_ct = 10;
+schedu_sums_tab_len = 403;
+ts_schedu_load_djob_ct = 140;
+ts_scheds_max = 96;
+max_comms_for_opspla = 18;
+casch_rpl_ct = 50;
+wasc_rpl_ct = 19;
+wasc_page_length = 50;
+cascj_tab_len = 200;
+cascw_tab_len = 300;
+NUMBERBALANCE = 8;
+numbalance = 8;
+numb_breaks = 3;
+MAX_ADP_VALUE = 1000;
+ADP_ERROR_BASIC_VALUE = 600;
+ADP_MESSAGE_BASIC_VALUE = 600;
+ADP_WARNING_BASIC_VALUE = 69;
+MAX_CHAR_REASON_OF_ABSENCE = 2;
+djob_rpl_ct = 0;
+ts_schedu_write_djob_tab_ct = 100;
+squal_rpl_ct = 10;
+nvvlist_rpl_ct = 128;
+nvvlist_req_ct = 875;
+mode_dkeys = 'k';
+mode_prog = 'p';
+action_getinfo = 'g';
+action_dinfo = '0';
+action_new = '1';
+action_unselect = 'u';
+action_dkeys = 'k';
+action_saved = 'a';
+action_quit = 'v';
+action_select = 's';
+action_update = '2';
+action_copy = '3';
+action_delete = '4';
+action_info = '5';
+action_print = '6';
+action_rename = '7';
+action_modify = '8';
+action_mpdata = 'm';
+action_change_all = '9';
+action_plan = 'p';
+action_cancel = 'q';
+action_smach = 'S';
+action_restore = 'r';
+action_copy_order = 'z';
+action_booktime = 't';
+action_msg = 'i';
+action_dpstep = 'd';
+action_add_pstep = 'e';
+action_remove_pstep = 'f';
+action_start = 'w';
+action_ppbook = 'P';
+action_startterm = 'b';
+action_stopterm = 'c';
+action_download = 'h';
+action_balload = 'j';
+action_starttrace = 'l';
+action_stoptrace = 'n';
+action_timesync = 'o';
+action_dmsg = 'D';
+action_line_len = 76;
+attribute_normal = 'n';
+attribute_hide = 'h';
+attribute_grey = 'g';
+attribute_selected = 's';
+attribute_gridlines = 'q';
+attribute_colored = 'c';
+attribute_noedit = 'e';
+invert_flag = 'i';
+cit_yesterday = 0;
+cit_today = 1;
+modify_deleted = 0;
+modify_original = 1;
+modify_inserted = 2;
+modify_by_empl = 3;
+modify_changed = 4;
+modify_by_job = 10;
+modify_by_timepairs = 11;
+deptno_error_index = 32766;
+employcat_error_index = 32765;
+costid_error_index = 32764;
+select_options_error_index = 32763;
+short_table_len = 64000;
+index_table_len = 4000;
+dscode_key_primary = 'p';
+dscode_key_scodeid_holiday = 'h';
+dscode_key_scodeid_day_off = 'd';
+dscode_key_scodeid_workday = 'w';
+dscode_key_holiday_keys = 'H';
+dscode_key_day_off_keys = 'D';
+dscode_key_workday_keys = 'W';
+dscode_key_all_keys = 'A';
+max_cwrp_days = 400;
+cusers_name_len = 30;
+max_cols = 4096;
+max_bytes_per_table = 5000;
+clientno_tab_len = 256;
+language_tab_len = 32;
+codepage_tab_len = 256;
+local_printername = 'LPT';
+ul_block_len = 4096;
+ul_read_first = 1;
+ul_read_last = 2;
+ul_read_next = 3;
+ul_read_prev = 4;
+ul_read_new_pos = 5;
+ul_append = 6;
+ul_delete_first = 7;
+ul_delete_last = 8;
+ul_change = 9;
+ul_change_new_pos = 10;
+ul_create = 11;
+ul_destroy = 12;
+ix_keys_in_block = 10;
+ix_hashtab_mod = 11;
+ix_hashtab_max = 10;
+ix_position = 1;
+ix_read_next = 2;
+ix_insert = 3;
+ix_create = 4;
+ix_destroy = 5;
+ix_delete = 6;
+open_file_dc = 01;
+close_file_dc = 02;
+seq_read_dc = 10;
+seq_write_dc = 11;
+seq_position_dc = 12;
+seq_delete_dc = 13;
+keyed_read_dc = 20;
+keyed_write_dc = 21;
+keyed_position_dc = 22;
+keyed_delete_dc = 23;
+keyed_rewrite_dc = 24;
+maxfiles = 200;
+minkey_short = -9999;
+input = 1;
+output = 2;
+value_undefined_char = 128;
+taris_time_array_len = 8;
+no_year_low = 1900;
+no_month_low = 1;
+no_day_low = 1;
+root_year = 1980;
+seconds_per_year = 31536000;
+seconds_per_hour = 3600;
+sysname_len = 10;
+min_chars_for_move = 0;
+eend_of_file = 1025;
+erecord_too_long = 1026;
+eobject_not_found = 1032;
+einvalid_io_operation = 1040;
+eusage_given = 1044;
+einvalid_io_type = 1070;
+etimeout = 1081;
+einvalid_duplicate_key = 1111;
+erecord_not_found = 1112;
+ealready_locked = 1206;
+ecaller_must_wait = 1277;
+einvalid_arg = 1371;
+eform_aborted = 1453;
+ebeginning_of_file = 1773;
+erecord_in_use = 2408;
+DiskReadError = 100;
+DiskWriteError = 101;
+FileNotAssignedError = 102;
+FileNotOpenError = 103;
+FileNotOpenForInputError = 104;
+FileNotOpenForOutputError = 105;
+InvalidNumericFormatError = 106;
+tm_CopyLine = 101;
+tm_AppendWin = 102;
+tm_RemoveWin = 103;
+tm_DKeysReturn = 104;
+tm_DeleteRecord = 105;
+tm_ReReadList = 106;
+tm_Keyboard = 107;
+tm_Escape = 108;
+tm_Arrows = 109;
+tm_GetCurEmplno = 110;
+tm_GetPrevEmplno = 111;
+tm_GetNextEmplno = 112;
+tm_Read = 113;
+tm_setFocus = 114;
+tm_FkeyPressed = 115;
+tm_UpdateData = 116;
+tm_SetWinProgno = 117;
+tm_WindowsOpen = 118;
+tm_MultipleSel = 119;
+tm_UpdateMask = 120;
+tm_UnselectList = 121;
+tm_NewLogon = 122;
+tm_SqualReturn = 123;
+tm_GetPrognoHandle = 124;
+tm_WriteStatic = 125;
+tm_SetColor = 126;
+tm_GetColor = 127;
+tm_OtherKeys = 128;
+tm_GetProgno = 129;
+tm_ReadStatic = 130;
+tm_CloseDemp = 131;
+tm_CallDemp = 132;
+tm_MsgCustLeitz = 133;
+tm_PingPong = 199;
+OkId = 101;
+MoreId = 102;
+CancelId = 103;
+LessId = 104;
+ExecuteId = 104;
+DuplicateId = 105;
+SkipId = 105;
+DeleteId = 106;
+SelectId = 107;
+NewId = 108;
+UpdateId = 109;
+AuswahlId = 110;
+FarbId = 111;
+AktualisierenId = 112;
+ReadId = 113;
+PrinterId = 114;
+AllOkId = 115;
+AllSkipId = 116;
+tarisAllok = 101;
+tarisAllSkip = 102;
+PrevEmplnoId = 801;
+CurEmplnoId = 802;
+NextEmplnoId = 803;
+error_text_fname = 'errtxt.dat';
+error_index_fname = 'errtxt.ind';
+max_message_code = 21999;
+index_step = 10;
+MCTEntriesPerTable = 21000;
+MaxMCTEntries = 80000;
+user_opts_versionno = 2;
+user_opts_filename = 'Useropt.dat';
+bt_alpha = 'a';
+bt_short = 'n';
+bt_mod_type = 't';
+bt_duration = 'p';
+bt_dduration = 'v';
+bt_long = 'N';
+bt_saldo = 's';
+bt_dsaldo = 'V';
+bt_date = 'd';
+bt_time = 'u';
+bt_costid = 'c';
+bt_flag_type = 'f';
+bt_cycle = 'F';
+bt_allowance = 'w';
+bt_char = 'C';
+bt_unsigned_byte = 'b';
+bt_balance = 'B';
+bt_mptime = 'm';
+bt_dbalance = 'D';
+bt_sreal = 'S';
+bt_ireal = 'I';
+bt_prod_stepno = 'P';
+bt_timearray = '[';
+bt_ogpdraw = ']';
+bt_dcbal = 'l';
+bt_owndraw = 'o';
+bt_color = 'r';
+bt_percentage = 'G';
+bt_emplcorrvalue = 'H';
+bt_specialsaldo = 'J';
+bt_effort = 'K';
+bt_pduration = 'L';
+max_intervals = 80;
+nii = -10001;
+LptDev = 1;
+ScreenDev = 2;
+FileDev = 3;
+NoDongle = 1000;
+time_apply = 240;
+first_allowance_apply = 241;
+last_allowance_apply = 245;
+max_gacce_emplnos = 240;
+matchcode_table_size = 4;
+matchcode_table_text_len = 100;
+max_no_of_bal_rec = 13;
+tree_plus = '+';
+tree_minus = '-';
+tree_blank = ' ';
+indentation_const = 12;
+benz_did_len = 200;
+general_base_module = 1;
+taris_base_module = 2;
+tse_base_module = 3;
+general_income_module = 11;
+taris_income_module = 12;
+tse_income_module = 13;
+general_access_module = 21;
+taris_access_module = 22;
+tse_access_module = 23;
+general_pop_module = 31;
+taris_pop_module = 32;
+tse_pop_module = 33;
+general_cost_module = 41;
+taris_cost_module = 42;
+tse_cost_module = 43;
+general_ttbal_module = 51;
+taris_ttbal_module = 52;
+tse_ttbal_module = 53;
+general_statistik_module = 61;
+taris_statistik_module = 62;
+tse_statistik_module = 63;
+general_bde1_module = 71;
+taris_bde1_module = 72;
+tse_bde1_module = 73;
+general_bde2_module = 81;
+taris_bde2_module = 82;
+tse_bde2_module = 83;
+general_canteen_module = 91;
+taris_canteen_module = 92;
+tse_canteen_module = 93;
+general_bde3_module = 101;
+taris_bde3_module = 102;
+tse_bde3_module = 103;
+general_win_module = 111;
+taris_win_module = 112;
+tse_win_module = 113;
+general_time_acc_module = 121;
+taris_time_acc_module = 122;
+tse_time_acc_module = 123;
+general_screen_module = 131;
+taris_screen_module = 132;
+tse_screen_module = 133;
+general_online_module = 141;
+taris_online_module = 142;
+tse_online_module = 143;
+general_web_module = 151;
+taris_web_module = 152;
+tse_web_module = 153;
+general_telefon_module = 161;
+taris_telefon_module = 162;
+tse_telefon_module = 163;
+general_time_acc2_module = 171;
+taris_time_acc2_module = 172;
+tse_time_acc2_module = 173;
+general_planner_module = 181;
+taris_planner_module = 182;
+tse_planner_module = 183;
+general_analysis_module = 191;
+taris_analysis_module = 192;
+tse_analysis_module = 193;
+general_mobile_module = 201;
+taris_mobile_module = 202;
+tse_mobile_module = 203;
+general_aeneis_module = 211;
+taris_aeneis_module = 212;
+tse_aeneis_module = 213;
+tse_multi_clients_addon = 223;
+tse_cycle_addon = 233;
+tse_income_addon = 243;
+tse_adjust_addon = 253;
+tse_apply_and_grant_addon = 263;
+taris_installation = 271;
+ase_installation = 272;
+test_installation = 273;
+oem_installation = 274;
+botime_installation = 280;
+botime_standard_installation = 281;
+botime_extended_installation = 282;
+botime_enterprise_installation = 283;
+palmOk = 0;
+palmGeneralError = -1;
+palmNoSequence = -2;
+palmWrongSequence = -3;
+palmNotConnected = -4;
+palmUnknownCommand = -5;
+palmNoCommand = -6;
+palmLoginWithoutUser = -7;
+palmLoginConnectionFailed = -8;
+palmLogoutDisconnectFailed = -9;
+palmBookingFailed = -10;
+palmWrongAnswerFromServer = -11;
+palmTimeout = -12;
+palmFatalError = -13;
+palmUnknownEntity = -14;
+palm_str_array_len = 16;
+palm_act_array_len = 8;
+palm_id_array_len = 1024;
+palm_flag_del = 1;
+palm_flag_sync = 2;
+palm_flag_mode = 4;
+palm_flag_bearb = 8;
+module_table_len = 30;
+moduleid_text_len = 40;
+start_moduleid_taris231 = 1;
+end_moduleid_taris231 = 25;
+start_moduleid_ase231 = 32;
+end_moduleid_ase231 = 50;
+pin_flag_on = 'l';
+pin_flag_off = 'a';
+NO_SAP = 'n';
+KK1 = 'y';
+HR_PDC = 'h';
+SAP_BC = HR_PDC;
+UNKNOWN_DB = 0;
+AIX_DB2 = 1;
+AIX_ORACLE = 2;
+AS400_DB2 = 10;
+AS400_DB2_ESQL = 11;
+LINUX_DB2 = 20;
+LINUX_ORACLE = 21;
+NT_DB2 = 30;
+NT_ORACLE = 31;
+NT_SQLSERVER = 32;
+participant_array_len = 32;
+dsmdlptp_code_len = 1;
+dsmdsum_code_len = 17;
+hex_block_len = 16;
+byte_block_len = 8;
+minutes_per_day = 1440;
+tslicence_read_dsmdsum = 1;
+tslicence_read_key = 2;
+tslicence_read_timer = 3;
+tslicence_get_debug = 4;
+tslicence_set_debug = 5;
+tslicence_kill_server = 6;
+tslicence_for_javaproxy = 7;
+no_of_readers = 24;
+benz_readers = 16;
+max_conv_tab_value = 16364;
+
+max_conv_tab_value_short = 8182;
+maxctcustbuffersize = 32000;
+
+
+TYPE
+
+{pspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspsp}
+ {short.inc}
+short = -32768..32767;
+ulong = longword;
+
+{pspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspsp}
+ {types.inc}
+long_text_type = ARRAY [1..long_text_len] OF char;
+very_long_text_type = ARRAY [1..60] OF char;
+objectid_type = ARRAY [1..objectid_len] OF char;
+objecttype_type = ARRAY [1..objecttype_len] OF char;
+flag_type = char;
+indexname_type = ARRAY [1..32] OF char;
+sqlstate_type = ARRAY [1..6] OF char;
+error_text_type = ARRAY [1..error_text_len] OF char;
+perror_text_type = ARRAY [1..perror_text_len] OF char;
+repvar_type = ARRAY [1..max_repvar_len] OF char;
+timer_text_type = ARRAY [1..80] OF char;
+languageid_type = ARRAY [1..2] OF char;
+packed_1_type = ARRAY [1..1] OF char;
+packed_2_type = ARRAY [1..2] OF char;
+packed_3_type = ARRAY [1..3] OF char;
+packed_4_type = ARRAY [1..4] OF char;
+packed_5_type = ARRAY [1..5] OF char;
+packed_6_type = ARRAY [1..6] OF char;
+packed_7_type = ARRAY [1..7] OF char;
+packed_8_type = ARRAY [1..8] OF char;
+packed_9_type = ARRAY [1..9] OF char;
+packed_10_type = ARRAY [1..10] OF char;
+packed_11_type = ARRAY [1..11] OF char;
+packed_12_type = ARRAY [1..12] OF char;
+packed_13_type = ARRAY [1..13] OF char;
+packed_14_type = ARRAY [1..14] OF char;
+packed_15_type = ARRAY [1..15] OF char;
+packed_16_type = ARRAY [1..16] OF char;
+packed_20_type = ARRAY [1..20] OF char;
+packed_21_type = ARRAY [1..21] OF char;
+packed_22_type = ARRAY [1..22] OF char;
+packed_23_type = ARRAY [1..23] OF char;
+packed_24_type = ARRAY [1..24] OF char;
+packed_25_type = ARRAY [1..25] OF char;
+packed_26_type = ARRAY [1..26] OF char;
+packed_27_type = ARRAY [1..27] OF char;
+packed_28_type = ARRAY [1..28] OF char;
+packed_29_type = ARRAY [1..29] OF char;
+packed_30_type = ARRAY [1..30] OF char;
+packed_32_type = ARRAY [1..32] OF char;
+packed_40_type = ARRAY [1..40] OF char;
+packed_42_type = ARRAY [1..42] OF char;
+packed_48_type = ARRAY [1..48] OF char;
+packed_50_type = ARRAY [1..50] OF char;
+packed_52_type = ARRAY [1..52] OF char;
+packed_60_type = ARRAY [1..60] OF char;
+packed_64_type = ARRAY [1..64] OF char;
+packed_75_type = ARRAY [1..75] OF char;
+packed_80_type = ARRAY [1..80] OF char;
+packed_120_type = ARRAY [1..120] OF char;
+packed_252_type = ARRAY [1..252] OF char;
+packed_256_type = ARRAY [1..256] OF char;
+packed_32000_type = ARRAY [1..32000] OF char;
+pc_date_time_type = ARRAY [1..17] OF char;
+a_char = char;
+wpatid_type = ARRAY [1..4] OF char;
+codeid_type = packed_2_type;
+long = LongInt;
+SYSNAME = ARRAY [1..sysname_len] OF char;
+dummy_type = short;
+fkey_mask_type = ARRAY [1..32] OF char;
+message_type = ARRAY [1..80] OF char;
+dcindexname_type = indexname_type;
+function_type = RECORD
+{ 1} operation_id: short;
+{ 3} position_id: short;
+{ 5} read_type: char
+{= 5} END;
+qcode_type = ARRAY [1..2] OF char;
+status_type = ARRAY [1..76] OF char;
+index_array = ARRAY [0..2199] OF RECORD
+{ 1} first: short;
+{ 3} pos: short
+{=8800} END;
+PCopyLineRec = ^TCopyLineRec;
+TCopyLineRec = RECORD
+{ 1} Id: short;
+{ 3} FormatNo: short;
+{ 5} RecAddr: long
+{= 8} END;
+mct_pt = ^mct_type;
+mct_entry = RECORD
+{ 1} n: short;
+{ 3} t: char
+{= 3} END;
+mct_type = ARRAY [1..MCTEntriesPerTable] OF mct_entry;
+ccb_type = RECORD
+{ 1} timeout_used: long;
+{ 5} rc: short;
+{ 7} time_array: ARRAY [1..8] OF char;
+{ 15} alignment1: ARRAY [1..2] OF char;
+{ 17} timeout_planned: long;
+{ 21} portid: short;
+{ 23} event_flag: flag_type;
+{ 24} commtype: char;
+{ 25} used_protocol: char;
+{ 26} charset_conv_flag: flag_type;
+{ 27} buflen: short;
+{ 29} hostname: ARRAY [1..32] OF char;
+{ 61} programname: ARRAY [1..32] OF char;
+{ 93} conversationid: long;
+{ 97} rc1: long;
+{ 101} rc2: long;
+{ 105} timeout_std: long;
+{ 109} {event_handle: hWnd;}
+{ 110} cci_status: char;
+{ 111} use_cci_header_flag: flag_type;
+{ 112} clientname: ARRAY [1..32] OF char;
+{ 144}{ svc_stop_evt: THandle;}
+{ 145}{ cci_stop_evt: THandle;}
+{ 146}{ cci_write_evt: THandle;}
+{ 147}{ cci_read_pending_evt: THandle;}
+{ 148}{ read_thread: THandle;}
+{ 149} cci_id: long
+{= 152} END;
+user_opts_type = RECORD
+{ 1} version: short;
+{ 3} debug_flag: flag_type;
+{ 4} mask_names_flag: flag_type;
+{ 5} old_menu_flag: flag_type;
+{ 6} alignment1: char;
+{ 7} debug_level: short
+{= 8} END;
+objectid_s_type = string;
+objecttype_s_type = string;
+long_text_s_type = string;
+indexname_s_type = string;
+repvar_s_type = string;
+error_text_s_type = string;
+wpatid_s_type = string;
+codeid_s_type = string;
+frsn_index_type = STRING [20];
+search_set_type = STRING [search_set_len];
+pcb_type = RECORD
+{ 1} line_cnt: long;
+{ 5} page_cnt: long;
+{ 9} page_len: short;
+{ 11} after: short;
+{ 13} f: file
+{= 13} END;
+order_by_type = ARRAY [1..256] OF char;
+interval_range = INTEGER;
+interval_type = ARRAY [1..2] OF interval_range;
+TIntervalData = ARRAY [0..max_intervals] OF interval_type;
+TColorData = ARRAY [1..max_intervals] OF long;
+processid_type = ulong;
+buffer_type = ARRAY [1..2] OF char;
+timestamp = long;
+rec_header_type = RECORD
+{ 1} byte: buffer_type;
+{ 3} reference_count: short;
+{ 5} last_modified: timestamp
+{= 8} END;
+fcb_type = RECORD
+{ 1} accessno: short;
+{ 3} last_error: short;
+{ 5} last_msgid: long;
+{ 9} io_type: short;
+{ 11} filename: objectid_type;
+{ 19} filler: short
+{= 20} END;
+schedu_abbr_type = ARRAY [1..2] OF char;
+vl_cols_dinfo_tab_type = RECORD
+{ 1} pos: short;
+{ 3} len: short;
+{ 5} col_dist: short;
+{ 7} dinfo: short
+{= 8} END;
+vl_cols_dinfo_type = RECORD
+{ 1} tab: ARRAY [1..vl_max_cols] OF vl_cols_dinfo_tab_type;
+{ 257} no_cols: short
+{= 258} END;
+vl_output_line_type = ARRAY [1..vl_output_line_len] OF char;
+vl_index_output_line_type = ARRAY [1..vl_index_output_line_len] OF char;
+vl_rec_type_tab_record_type = RECORD
+{ 1} rec_type: char;
+{ 2} justification: char
+{= 2} END;
+vl_rec_type_tab_type = ARRAY [1..vl_max_cols] OF vl_rec_type_tab_record_type;
+vl_filler_var = ARRAY [1..vl_filler_var_len] OF char;
+vl_colsusage_type = ARRAY [1..vl_max_cols] OF boolean;
+unsigned_byte = char;
+signed_byte = char;
+filler_type = unsigned_byte;
+color_type = long;
+color_attr_type = RECORD
+{ 1} color: color_type;
+{ 5} attr: unsigned_byte;
+{ 6} filler_ca: ARRAY [1..3] OF filler_type
+{= 8} END;
+one_masks_colors_type = ARRAY [1..10] OF color_attr_type;
+special_colors_type = ARRAY [1..16] OF color_attr_type;
+emplcorrvalue_type = long;
+specialsaldo_type = short;
+percentage_type = short;
+phoneno_type = ARRAY [1..24] OF char;
+url_type = ARRAY [1..254] OF char;
+alias_type = ARRAY [1..15] OF char;
+commtype_type = ARRAY [1..4] OF char;
+firstname_type = ARRAY [1..firstname_len] OF char;
+surname_type = ARRAY [1..surname_len] OF char;
+email_address_type = ARRAY [1..32] OF char;
+m_timestamp = long;
+mod_type = short;
+duration_type = short;
+dduration_type = short;
+dbalance_type = duration_type;
+allowance_type = duration_type;
+saldo_type = long;
+dsaldo_type = long;
+balance_type = saldo_type;
+chapter_type = ARRAY [1..chapter_len] OF char;
+phys_filename_type = ARRAY [1..phys_filename_len] OF char;
+print_queue_name_type = ARRAY [1..32] OF char;
+expanded_filename_type = ARRAY [1..256] OF char;
+processname_type = ARRAY [1..processname_len] OF char;
+code_type = ARRAY [1..code_len] OF char;
+exit_code_type = ARRAY [1..exit_code_len] OF char;
+vos_modulename_type = ARRAY [1..vos_modulename_len] OF char;
+userid_type = ARRAY [1..userid_len] OF char;
+time_zone_type = ARRAY [1..time_zone_len] OF char;
+fkey_mask_array = ARRAY [1..32] OF char;
+fkey_set_type = SET OF 1..32;
+fkey_subst_type = ARRAY [1..32] OF short;
+fkey_tab_type = ARRAY [-1..32] OF short;
+char_set_type = SET OF char;
+operator_type = (add, subtract);
+encode_decode_type = (encode, decode);
+return_value_type = (undefined, good_value, bad_value);
+pcs_request_type = ARRAY [1..pcs_request_len] OF char;
+codetype_type = char;
+termcat_type = packed_8_type;
+logonid_type = ARRAY [1..logonid_len] OF char;
+username_type = ARRAY [1..32] OF char;
+menue_title_type = ARRAY [1..46] OF char;
+menue_line_type = ARRAY [1..50] OF char;
+menue_info_type = ARRAY [1..10] OF char;
+operationid_type = ARRAY [1..8] OF char;
+deptno_type = ARRAY [1..deptno_len] OF char;
+emplno_type = ARRAY [1..emplno_len] OF char;
+badgeno_type = ARRAY [1..badgeno_len] OF char;
+long_badgeno_type = ARRAY [1..long_badgeno_len] OF char;
+select_options_type = ARRAY [1..max_select_options] OF char;
+input_line_type = ARRAY [1..input_line_len] OF char;
+startup_type = ARRAY [1..startup_string_len] OF char;
+cb_state_type = (cb_uninitialized, cb_initialized, cb_open, cb_connected);
+object_state_type = short;
+object_enum_type = short;
+conv_table_type_pointer = ^conv_table_type;
+conv_table_type = RECORD
+{ 1} int_len: short;
+{ 3} ext_len: short;
+{ 5} no_of_values: short;
+{ 7} cust_start_pos: short;
+{ 9} CASE dummy: short OF
+{+ 2} 0: (value_tab: ARRAY [1..max_conv_tab_value] OF char);
+{+ 2} 1: (short_tab: ARRAY [1..max_conv_tab_value_short] OF short);
+{=16374} END;
+conv_table_common_type = RECORD
+{ 1} no_of_tables: short;
+{ 3} CASE max_no_of_tables: short OF
+{+ 2} 0: (index_table: ARRAY [1..index_table_len] OF RECORD
+{+ 2} table_name: long_text_type;
+{+ 32} filler: short;
+{+ 34} start_pos: long
+{=14400} END;);
+{+ 2} 1: (short_table: ARRAY [1..short_table_len] OF short);
+{=14400} END;
+half_conv_table_common_type = RECORD
+{ 1} info: ARRAY [1..16000] OF short;
+{32001} conv_key: short
+{=32002} END;
+whole_conv_table_common_type = RECORD
+{ 1} CASE dummy: long OF
+{+ 4} 0: (split: ARRAY [1..2] OF half_conv_table_common_type);
+{+ 4} 1: (normal: conv_table_common_type);
+{=14400} END;
+cust_conv_table_common_type = ARRAY [1..cust_conv_table_common_type_len] OF short;
+cust_conv_table_type = RECORD
+{ 1} no_of_cust_values: short;
+{ 3} CASE switch: short OF
+{+ 2} 0: (value_tab: ARRAY [1..max_conv_tab_value] OF char);
+{+ 2} 1: (short_tab: ARRAY [1..max_conv_tab_value_short] OF short);
+{=16368} END;
+short_pointer = ^short;
+convert_pointer_type = RECORD
+{ 1} CASE useless: short OF
+{+ 2} 0: (p1: short_pointer);
+{+ 2} 1: (p2: conv_table_type_pointer);
+{= 8} END;
+cust_conv_table_type_ptr = ^cust_conv_table_type;
+cust_convert_pointer_type = RECORD
+{ 1} CASE useless: short OF
+{+ 2} 0: (p1: short_pointer);
+{+ 2} 1: (p2: cust_conv_table_type_ptr);
+{= 8} END;
+video_attributes_type = RECORD
+{ 1} mask_title_color: ARRAY [1..1] OF char;
+{ 2} title_color: ARRAY [1..1] OF char;
+{ 3} input_color: ARRAY [1..1] OF char;
+{ 4} help_text_color: ARRAY [1..1] OF char;
+{ 5} background_color: ARRAY [1..1] OF char;
+{ 6} mask_title_inv_flag: flag_type;
+{ 7} mask_title_ul_flag: flag_type;
+{ 8} title_ul_flag: flag_type;
+{ 9} input_high_flag: flag_type;
+{ 10} error_inv_flag: flag_type;
+{ 11} filler: ARRAY [1..6] OF char
+{= 16} END;
+codes_table_record_type = RECORD
+{ 1} color: long;
+{ 5} codeid: codeid_type;
+{ 7} attr: unsigned_byte;
+{ 8} filler: char
+{= 8} END;
+codes_table_type = ARRAY [1..31] OF codes_table_record_type;
+acccatid_type = ARRAY [1..4] OF char;
+accpatid_type = ARRAY [1..4] OF char;
+jobid_type = objectid_type;
+qualificationid_type = objectid_type;
+mach_job_type = RECORD
+{ 1} machineid: objectid_type;
+{ 9} jobid: objectid_type
+{= 16} END;
+abbr_type = ARRAY [1..2] OF char;
+abbr_key_type = RECORD
+{ 1} deptno: deptno_type;
+{ 11} abbr: abbr_type
+{= 12} END;
+importance_type = ARRAY [1..1] OF char;
+costid_type = ARRAY [1..costid_type_len] OF char;
+costid_ext_type = ARRAY [1..costid_ext_type_len] OF char;
+cost_bookings_record_type = RECORD
+{ 1} switch_time: mod_type;
+{ 3} costid: costid_type
+{= 22} END;
+cost_bookings_type = ARRAY [1..maxcostbookings] OF cost_bookings_record_type;
+cycleid_type = ARRAY [1..4] OF char;
+shiftid_type = ARRAY [1..4] OF char;
+ruleid_type = ARRAY [1..2] OF char;
+employcat_type = ARRAY [1..employcat_len] OF char;
+rcalenid_type = ARRAY [1..4] OF char;
+event_type = ARRAY [1..2] OF char;
+tariffarea_type = ARRAY [1..4] OF char;
+costno_type = ARRAY [1..10] OF char;
+adjustcat_type = ARRAY [1..adjustcat_len] OF char;
+chain_balance_tab_type = ARRAY [1..max_no_of_balances] OF short;
+continued_pay_len_type = short;
+msg_header_type = RECORD
+{ 1} byte: buffer_type;
+{ 3} reqno: short;
+{ 5} error_code: code_type;
+{ 9} vos_error: short;
+{ 11} queue_name: ARRAY [1..10] OF char;
+{ 21} callerno: short;
+{ 23} notify_flag: flag_type;
+{ 24} filler1: char;
+{ 25} queue_timestamp: timestamp;
+{ 29} reserved: short
+{= 30} END;
+switch_msg = RECORD
+{ 1} taskid: short;
+{ 3} objectid: objectid_type;
+{ 11} objecttype: objecttype_type
+{= 18} END;
+long_msg_header_type = RECORD
+{ 1} byte: buffer_type;
+{ 3} reqno: short;
+{ 5} error_code: code_type;
+{ 9} vos_error: short;
+{ 11} reserved: ARRAY [1..10] OF short;
+{ 31} msgtype: short;
+{ 33} switchmsg: switch_msg
+{= 50} END;
+file_param_type = RECORD
+{ 1} phys_filename: phys_filename_type;
+{ 33} organization: short;
+{ 35} maxreclen: short;
+{ 37} logging_flag: flag_type;
+{ 38} logging_align: char;
+{ 39} length_in_pages: short;
+{ 41} starting_recordno: short;
+{ 43} time_limit: long
+{= 46} END;
+open_param_type = RECORD
+{ 1} io_type: short;
+{ 3} locking_mode: short;
+{ 5} access_mode: short
+{= 6} END;
+string_date_type = ARRAY [1..8] OF char;
+string_time_type = ARRAY [1..5] OF char;
+date_type = RECORD
+{ 1} yy: short;
+{ 3} mo: short;
+{ 5} dd: short
+{= 6} END;
+time_type = RECORD
+{ 1} hh: short;
+{ 3} mi: short;
+{ 5} ss: short
+{= 6} END;
+date_and_time_type = RECORD
+{ 1} date: date_type;
+{ 7} time: time_type
+{= 12} END;
+task_context_type = RECORD
+{ 1} byte: ARRAY [1..100] OF char
+{= 100} END;
+income_type = ARRAY [1..4] OF char;
+wrk_code_type = RECORD
+{ 1} codeid: codeid_type;
+{ 3} codetype: codetype_type
+{= 3} END;
+error_log_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} date_and_time: date_and_time_type;
+{ 21} millisec: short;
+{ 23} error_code: code_type;
+{ 27} severity_code: char;
+{ 28} filler1: ARRAY [1..1] OF filler_type;
+{ 29} userid: userid_type;
+{ 45} processname: processname_type;
+{ 77} versionno: short;
+{ 79} vos_error: short;
+{ 81} fileid: objectid_type;
+{ 89} error_text: error_text_type;
+{ 149} exit_code: exit_code_type;
+{ 155} filler: ARRAY [1..2] OF filler_type;
+{ 157} counter: long;
+{ 161} emplno: emplno_type;
+{ 171} filler2: ARRAY [1..20] OF filler_type
+{= 190} END;
+error_text_rec = RECORD
+{ 1} error_code: code_type;
+{ 5} severity_code: char;
+{ 6} error_text: error_text_type
+{= 65} END;
+recid_type = ARRAY [1..recid_len] OF char;
+fieldid_type = ARRAY [1..fieldid_len] OF char;
+fieldtype_type = short;
+queryid_type = ARRAY [1..queryid_len] OF char;
+selection_line_type = ARRAY [1..selection_line_len] OF char;
+selected_fields_type = ARRAY [1..max_selected_fields] OF fieldid_type;
+month_unsigned_byte_type = ARRAY [1..31] OF unsigned_byte;
+month_char_type = ARRAY [1..31] OF char;
+month_codes_type = ARRAY [1..31] OF codeid_type;
+month_short_type = ARRAY [1..31] OF short;
+abs_table_pointer = ^abs_table_type;
+abs_table_type = RECORD
+{ 1} tab_start: date_type;
+{ 7} tab_months: short;
+{ 9} offduty_reasons: ARRAY [1..24] OF month_codes_type;
+{ 1497} ondutytypes: ARRAY [1..24] OF month_char_type
+{=2240} END;
+ccbal_rule_display_type = RECORD
+{ 1} d_method: unsigned_byte;
+{ 2} d_corr_value_1: packed_8_type;
+{ 10} d_transbalanceid_1: unsigned_byte;
+{ 11} d_corr_value_2: packed_8_type;
+{ 19} d_transbalanceid_2: unsigned_byte
+{= 19} END;
+adjust_date_tab_type = ARRAY [1..adjust_rule_tab_len] OF date_type;
+chain_step_tab_type = ARRAY [1..max_no_of_balances] OF short;
+memory_tab_type = ARRAY [1..10] OF balance_type;
+balance_index_tab_type = ARRAY [1..max_no_of_balances] OF short;
+balance_set_type = SET OF 1..max_no_of_balances;
+mcbal_sections_type = RECORD
+{ 1} first: balance_index_tab_type;
+{ 49} last: balance_index_tab_type;
+{ 97} mcbal_balances: balance_set_type
+{= 97} END;
+rule_apply_type = flag_type;
+rule_apply_tab_type = ARRAY [1..adjust_rule_tab_len] OF rule_apply_type;
+return_code_type = short;
+record_no_type = short;
+empl_corr_values_type = ARRAY [1..max_empl_corr_values] OF saldo_type;
+cwrp_result_tab_type = RECORD
+{ 1} wpatid: wpatid_type;
+{ 5} codeid: codeid_type;
+{ 7} ruleid: ruleid_type
+{= 8} END;
+cwrp_period_result_tab_type = ARRAY [1..max_cwrp_days] OF cwrp_result_tab_type;
+attribid_type = ARRAY [1..attribid_len] OF char;
+attributes_type = ARRAY [1..max_no_of_attributes] OF attribid_type;
+parproid_type = ARRAY [1..parproid_len] OF char;
+projectid_type = ARRAY [1..projectid_len] OF char;
+rpoolid_type = ARRAY [1..rpoolid_len] OF char;
+taskid_type = ARRAY [1..taskid_len] OF char;
+versionid_type = ARRAY [1..versionid_len] OF char;
+balancetype_array_type = ARRAY [1..4] OF unsigned_byte;
+search_list_type = RECORD
+{ 1} length: short;
+{ 3} search_sets: ARRAY [1..max_search_sets_in_list] OF search_set_type
+{= 26} END;
+scb_type = RECORD
+{ 1} dsaempfcb: fcb_type;
+{ 21} dsvempfcb: fcb_type;
+{ 41} last_error: short;
+{ 43} best_search_list_length: short;
+{ 45} current_search_set: short;
+{ 47} key_len: short;
+{ 49} last_invalid_from: date_type;
+{ 55} last_key: ARRAY [1..30] OF char;
+{ 85} last_emplno: emplno_type;
+{ 95} use_last_key: flag_type;
+{ 96} first_pattern: ARRAY [1..30] OF char;
+{ 126} last_pattern: ARRAY [1..30] OF char;
+{ 156} best_key: char;
+{ 157} sorted_by_name: flag_type;
+{ 158} subkey_used: flag_type;
+{ 159} filler: ARRAY [1..14] OF char
+{= 172} END;
+semp_type = RECORD
+{ 1} variant_no: short;
+{ 3} from_date: date_type;
+{ 9} to_date: date_type;
+{ 15} deptno: deptno_type;
+{ 25} employcat: employcat_type;
+{ 29} costid: costid_type;
+{ 49} badgeno: long_badgeno_type;
+{ 69} emplno: emplno_type;
+{ 79} surname: surname_type;
+{ 109} select_options: select_options_type;
+{ 125} get_all_selected_variants: flag_type;
+{ 126} check_permission: flag_type;
+{ 127} employcat_filled: char;
+{ 128} check_interval: flag_type;
+{ 129} factory: packed_12_type;
+{ 141} mach_job: mach_job_type;
+{ 157} adjustcat: adjustcat_type;
+{ 161} tariffarea: tariffarea_type;
+{ 165} cycleid: cycleid_type;
+{ 169} cycle_start: short;
+{ 171} rpoolid: rpoolid_type;
+{ 183} accesscat: acccatid_type;
+{ 187} filler: ARRAY [1..14] OF char
+{= 200} END;
+sreal_type = short;
+ireal_type = long;
+prod_stepno_type = long;
+orderno_type = ARRAY [1..orderno_len] OF char;
+fault_reasonid_type = ARRAY [1..fault_reasonid_len] OF char;
+prod_status_type = char;
+prod_operationid_type = ARRAY [1..prod_operationid_len] OF char;
+piece_work_type_type = ARRAY [1..piece_work_type_len] OF char;
+prod_step_key_type = RECORD
+{ 1} orderno: orderno_type;
+{ 17} prod_stepno: prod_stepno_type;
+{ 21} prod_stepno_var: prod_stepno_type
+{= 24} END;
+pwtype_key_type = RECORD
+{ 1} piece_work_type: piece_work_type_type;
+{ 5} invalid_from: date_type
+{= 10} END;
+dsinst_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} flags: RECORD
+{+ 0} customer_code: char;
+{+ 1} costid_to_next_day: flag_type;
+{+ 2} update_dsttraf_flag: flag_type;
+{+ 3} pcsstat_flag: flag_type;
+{+ 4} saldo_ztariff_flag: flag_type;
+{+ 5} adj_income_flag: flag_type;
+{+ 6} dabsemp_calculation: char;
+{+ 7} monthly_schedu: flag_type;
+{+ 8} more_costbookings: flag_type;
+{+ 9} dabs_change_past: flag_type;
+{+ 10} use_3hour_guaranty: flag_type;
+{+ 11} scodeid_mtbal: flag_type;
+{+ 12} dsaldo_two_digits: flag_type;
+{+ 13} unique_badgeno_over_all_clients: flag_type;
+{+ 14} plan_info: char;
+{+ 15} holiday_single: flag_type;
+{+ 16} schedu_info: char;
+{+ 17} export_available: char;
+{+ 18} zdel_quick: flag_type;
+{+ 19} SAP_interface: char;
+{+ 20} flag1: flag_type;
+{+ 21} flag2: flag_type;
+{+ 22} flag3: flag_type;
+{+ 23} filler: ARRAY [1..9] OF filler_type
+{= 32} END;
+{ 41} country: char;
+{ 42} overtime_1_2_method: char;
+{ 43} auto_badgeno: long_badgeno_type;
+{ 63} sfc_installed: flag_type;
+{ 64} prw_installed: flag_type;
+{ 65} medical_solution_installed: flag_type;
+{ 66} canteen_installed: flag_type;
+{ 67} sfm_installed: flag_type;
+{ 68} client_installed: flag_type;
+{ 69} proj_management_installed: flag_type;
+{ 70} timeclt_installed: flag_type;
+{ 71} type_of_pps: char;
+{ 72} sfc_costid_usage: char;
+{ 73} absence_balance: short;
+{ 75} time_lost_balance: short;
+{ 77} missing_coretime_balance: short;
+{ 79} fkey_tab: fkey_tab_type;
+{ 147} companyname: ARRAY [1..70] OF char;
+{ 217} basis_module_installed: flag_type;
+{ 218} income_calc_installed: flag_type;
+{ 219} access_control_installed: flag_type;
+{ 220} pop_installed: flag_type;
+{ 221} cost_acc_installed: flag_type;
+{ 222} ttbal_installed: flag_type;
+{ 223} p3_installed: flag_type;
+{ 224} statistic_installed: flag_type;
+{ 225} severity_codes: ARRAY [1..maxseverity_codes] OF char;
+{ 233} beep_severity_codes: ARRAY [1..maxseverity_codes] OF char;
+{ 241} timer: ARRAY [1..8] OF char;
+{ 249} balance_type_tab: ARRAY [1..max_no_of_balances] OF char;
+{ 273} sfc_auto_registration: char;
+{ 274} sfc_auto_completion: char;
+{ 275} install_flag17: flag_type;
+{ 276} install_flag18: flag_type;
+{ 277} install_flag19: flag_type;
+{ 278} install_flag20: flag_type;
+{ 279} keep_time: short;
+{ 281} aemp_time: short;
+{ 283} past_income_change_flag: flag_type;
+{ 284} ztariff_v130_mode: char;
+{ 285} today_date: date_type;
+{ 291} dabsgrp_display_mode: char;
+{ 292} ztariff_optimization: char;
+{ 293} cost_pos_to_no: ARRAY [1..3] OF short;
+{ 299} cost_no_to_pos: ARRAY [1..3] OF short;
+{ 305} cost_maxlen: ARRAY [1..3] OF short;
+{ 311} cost_prestype: ARRAY [1..3] OF char;
+{ 314} sfc_variable_registration_mode: char;
+{ 315} sfc_auto_completion_mode: char;
+{ 316} flag4: flag_type;
+{ 317} cost_delimiter: ARRAY [1..2] OF char;
+{ 319} cost_alt_delimiter: ARRAY [1..2] OF char;
+{ 321} install_flag21: flag_type;
+{ 322} install_flag22: flag_type;
+{ 323} install_flag23: flag_type;
+{ 324} valid_for_overtime: flag_type;
+{ 325} real_worktime: flag_type;
+{ 326} sickness_codeid2: codeid_type;
+{ 328} install_flag24: flag_type;
+{ 329} sfc_apply_pwtype_daily: flag_type;
+{ 330} cost_checks: ARRAY [1..3] OF flag_type;
+{ 333} menue_mode: char;
+{ 334} codeid_worked: codeid_type;
+{ 336} codeid_day_off: codeid_type;
+{ 338} day_filler: codeid_type;
+{ 340} day_invalid: codeid_type;
+{ 342} real_delimiter: char;
+{ 343} video_attributes: video_attributes_type;
+{ 359} week_first_day_ztariff: char;
+{ 360} codeid_no_permission: codeid_type;
+{ 362} sickness_codeid: codeid_type;
+{ 364} sfc_parallelity_mode: char;
+{ 365} sfc_cost_priority: flag_type;
+{ 366} sfc_send_time_to_pps: char;
+{ 367} sfc_calc_partial_ps: flag_type;
+{ 368} change_from_date_text: packed_16_type;
+{ 384} tm_change_from_date_text: packed_16_type;
+{ 400} tarislib1: ARRAY [1..10] OF char;
+{ 410} tarislib2: ARRAY [1..10] OF char;
+{ 420} tarislib3: ARRAY [1..10] OF char;
+{ 430} use_prtempday: flag_type;
+{ 431} digits_from_orderno: short;
+{ 433} digits_from_prod_stepno: short;
+{ 435} pos_from_orderno: short;
+{ 437} basic_income: income_type;
+{ 441} prw_costtype: costid_type;
+{ 461} sfc_time: short;
+{ 463} v180_inst_date: date_type;
+{ 469} v220_inst_stamp: timestamp;
+{ 473} v230_inst_stamp: timestamp;
+{ 477} v240_inst_stamp: timestamp;
+{ 481} bankholtype: ARRAY [3..maxdaytypes] OF char;
+{ 489} balance_calc_tab: ARRAY [1..max_no_of_balances] OF char;
+{ 513} plan_time: short;
+{ 515} warn_time: short;
+{ 517} acclog_time: short;
+{ 519} errlog_time: short;
+{ 521} daily_delimiter: char;
+{ 522} unit_continued_payment: char;
+{ 523} duration_continued_payment: short;
+{ 525} codes_continued_payment: ARRAY [1..5] OF codeid_type;
+{ 535} vacation_balance: short;
+{ 537} negative_time_border: mod_type;
+{ 539} primary_languageid: languageid_type;
+{ 541} balance_order_tab: ARRAY [1..max_no_of_balances] OF short;
+{ 589} empl_corr_values_type_tab: ARRAY [1..8] OF char;
+{ 597} lang_timer: packed_8_type;
+{ 605} custdata: long;
+{ 609} custdata1: ARRAY [1..96] OF unsigned_byte;
+{ 705} min_pwd_len: short;
+{ 707} max_logon_tries: short;
+{ 709} email_on_request: flag_type;
+{ 710} email_on_approval: flag_type;
+{ 711} use_break_for_schedu: flag_type;
+{ 712} use_break_for_schedud: flag_type;
+{ 713} picture_url: url_type;
+{ 967} filler3: ARRAY [1..1] OF filler_type;
+{ 968} proj_time_acc_installed: flag_type;
+{ 969} dsmtbix_projno_flag: flag_type;
+{ 970} dsmtbix_costno_flag: flag_type;
+{ 971} dsmtbix_cttype_flag: flag_type;
+{ 972} dsmtbix_costid_flag: flag_type;
+{ 973} regular_worktime: duration_type;
+{ 975} empl_cost_factor: sreal_type;
+{ 977} commtype_wasc: commtype_type;
+{ 981} schedu_balance: short;
+{ 983} dsabs_future_months: short;
+{ 985} emplnotime_to_pps: char;
+{ 986} new_timer: timer_text_type;
+{ 1066} filler1: ARRAY [1..1] OF filler_type;
+{ 1067} pin_valid_len: short;
+{ 1069} max_pin_try: short;
+{ 1071} duration_form: char;
+{ 1072} filler2: ARRAY [1..79] OF filler_type
+{=1150} END;
+allowances_type = ARRAY [1..maxallowances] OF allowance_type;
+timepairs_record_type = RECORD
+{ 1} time_in: mod_type;
+{ 3} time_out: mod_type;
+{ 5} timepair_code: codeid_type
+{= 6} END;
+timepairs_type = ARRAY [1..maxtimepairs] OF timepairs_record_type;
+balance_rounding_type = RECORD
+{ 1} min_unit: short;
+{ 3} round_up: short;
+{ 5} minimum: short;
+{ 7} filler: short
+{= 8} END;
+l_form_type = ARRAY [1..7] OF char;
+l_data_type = ARRAY [1..1910] OF char;
+l_modes_type = ARRAY [1..500] OF short;
+l_message_type = ARRAY [1..78] OF char;
+day_emplno_type = RECORD
+{ 1} date: date_type;
+{ 7} emplno: emplno_type
+{= 16} END;
+emplno_day_seq_type = RECORD
+{ 1} emplno: emplno_type;
+{ 11} date: date_type;
+{ 17} sequenceno: short
+{= 18} END;
+emplno_day_type = RECORD
+{ 1} emplno: emplno_type;
+{ 11} date: date_type
+{= 16} END;
+emplno_year_type = RECORD
+{ 1} emplno: emplno_type;
+{ 11} year: short
+{= 12} END;
+breakusage_ext_type = ARRAY [1..maxbreaks] OF boolean;
+filter_result_type = (yes, no, abort);
+progname_type = short;
+parm_tab_line_type = ARRAY [1..parm_tab_line_len] OF char;
+parm_tab_type = ARRAY [1..parm_tab_len] OF parm_tab_line_type;
+pin_code_type = ARRAY [1..4] OF char;
+break_pattern_type = RECORD
+{ 1} time_from: mod_type;
+{ 3} time_to: mod_type;
+{ 5} paid_breaklen: duration_type;
+{ 7} unpaid_breaklen: duration_type
+{= 8} END;
+fkey_line_type = ARRAY [1..78] OF char;
+fkcb_type = RECORD
+{ 1} pageno: short;
+{ 3} no_of_pages: short;
+{ 5} fkey_line: ARRAY [1..fkey_maxlines] OF fkey_line_type;
+{ 473} line1: fkey_line_type;
+{ 551} line2: fkey_line_type
+{= 628} END;
+long_record_type = ARRAY [1..long_record_len] OF char;
+long_record_ptr_type = ^long_record_type;
+mode_type = char;
+action_type = char;
+action_ctab_type = ARRAY [1..32] OF char;
+action_subst_type = ARRAY [1..32] OF short;
+action_set_type = SET OF char;
+action_line_type = ARRAY [1..action_line_len] OF char;
+action_mask_type = RECORD
+{ 1} line1: action_line_type;
+{ 77} line2: action_line_type
+{= 152} END;
+keydata_type = ARRAY [1..keydata_len] OF char;
+prog_param_type = RECORD
+{ 1} CASE action: action_type OF
+{+ 1} action_getinfo: (fileid: ARRAY [1..10] OF char;
+{+ 11} title_ctab: long_text_type;
+{+ 41} keylen: short;
+{+ 43} total_keylen: short;
+{+ 45} progno: short;
+{+ 47} variants: flag_type;
+{+ 48} org_value: keydata_type;
+{+ 108} alignment1: char);
+{+ 1} action_update: (keydata: keydata_type;
+{+ 61} itemid: short);
+{+ 1} action_rename: (old_keydata: keydata_type;
+{+ 61} new_keydata: keydata_type);
+{= 122} END;
+buffer_pointer = ^buffer_type;
+comm_buffer_pointer = ^comm_buffer_type;
+comm_buffer_type = ARRAY [1..comm_buffer_len] OF char;
+time_array_type = ARRAY [1..time_array_len] OF char;
+date_array_type = ARRAY [1..8] OF char;
+taris_time_array_type = ARRAY [1..taris_time_array_len] OF char;
+cci_header_type = RECORD
+{ 1} data_len: long
+{= 4} END;
+cusers_name_type = ARRAY [1..cusers_name_len] OF char;
+mcb_type = RECORD
+{ 1} reserved: short;
+{ 3} getcursorpos: short;
+{ 5} key_code: short;
+{ 7} f4_window: short;
+{ 9} redisplay_flag: boolean
+{= 9} END;
+mc_param_type = RECORD
+{ 1} status: short;
+{ 3} message: message_type;
+{ 83} beep_flag: boolean
+{= 83} END;
+dschlog_data_type = ARRAY [1..4000] OF unsigned_byte;
+dschlog_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} date_and_time: date_and_time_type;
+{ 21} millisec: short;
+{ 23} emplno: emplno_type;
+{ 33} recno: record_no_type;
+{ 35} first_reclen: short;
+{ 37} second_reclen: short;
+{ 39} logonid: logonid_type;
+{ 47} os_logonid: packed_16_type;
+{ 63} terminalname: objectid_type;
+{ 71} updatetype: char;
+{ 72} filler: ARRAY [1..27] OF char;
+{ 99} rec_data_len: short;
+{ 101} rec_data: dschlog_data_type
+{=4100} END;
+tstat_tabline_type = RECORD
+{ 1} termid: objectid_type;
+{ 9} termno: short;
+{ 11} state: unsigned_byte;
+{ 12} term_code: char;
+{ 13} phys_termtype: objectid_type;
+{ 21} location: ARRAY [1..16] OF char;
+{ 37} error: code_type;
+{ 41} number_in: long;
+{ 45} error_in: long;
+{ 49} number_out: long;
+{ 53} error_out: long
+{= 56} END;
+tstat_tab_type = ARRAY [1..tstat_tab_len] OF tstat_tabline_type;
+terminal_state_type = ARRAY [1..2] OF char;
+pcs_term_state_type = RECORD
+{ 1} serialnumber: ARRAY [1..11] OF char;
+{ 12} align1: char;
+{ 13} driver: ARRAY [1..4] OF char;
+{ 17} bb: ARRAY [1..4] OF char;
+{ 21} dispcontrol: ARRAY [1..4] OF char;
+{ 25} rtk: ARRAY [1..4] OF char;
+{ 29} tcl: ARRAY [1..4] OF char;
+{ 33} sterminal: terminal_state_type;
+{ 35} sbb: terminal_state_type;
+{ 37} sdispcontrol: terminal_state_type;
+{ 39} sbbm: ARRAY [1..8] OF terminal_state_type;
+{ 55} display: ARRAY [1..80] OF char
+{= 134} END;
+print_msg_type = RECORD
+{ 1} msg_header: msg_header_type;
+{ 31} msgtype: short;
+{ 33} command: ARRAY [1..512] OF char;
+{ 545} logonid: logonid_type;
+{ 553} start_datetime: date_and_time_type;
+{ 565} priority: packed_2_type;
+{ 567} printerid: objectid_type;
+{ 575} printerfile: phys_filename_type;
+{ 607} outfile: phys_filename_type;
+{ 639} clientno: buffer_type;
+{ 641} languageid: languageid_type
+{= 642} END;
+staff_key_type = RECORD
+{ 1} mach_job: mach_job_type;
+{ 17} time_from: mod_type;
+{ 19} time_to: mod_type;
+{ 21} whole_day: flag_type;
+{ 22} link: alias_type;
+{ 37} invalid_from: date_type
+{= 42} END;
+djob_key_type = RECORD
+{ 1} emplno: emplno_type;
+{ 11} date: date_type;
+{ 17} time: mod_type
+{= 18} END;
+table_col_record_type = RECORD
+{ 1} datatype: char;
+{ 2} alignment1: ARRAY [1..3] OF char;
+{ 5} len: long
+{= 8} END;
+table_col_type = ARRAY [1..MAX_COLS] OF table_col_record_type;
+clientno_tab_type = ARRAY [1..clientno_tab_len] OF buffer_type;
+language_tab_type = ARRAY [1..language_tab_len] OF languageid_type;
+codepage_tab_type = ARRAY [0..255] OF char;
+ul_block_ptr_type = ^ul_block_type;
+ul_block_type = RECORD
+{ 1} chars: ARRAY [1..ul_block_len] OF char;
+{ 4097} nextpt: ul_block_ptr_type;
+{ 4101} prevpt: ul_block_ptr_type
+{=4104} END;
+ul_pos_type = RECORD
+{ 1} blockpt: ul_block_ptr_type;
+{ 5} recordno: short
+{= 6} END;
+ulcb_type = RECORD
+{ 1} last_error: short;
+{ 3} reclen: short;
+{ 5} new_cur_pos: ul_pos_type;
+{ 11} filler1: ARRAY [1..2] OF char;
+{ 13} no_of_records: long;
+{ 17} first_pos: ul_pos_type;
+{ 23} filler2: ARRAY [1..2] OF char;
+{ 25} last_pos: ul_pos_type;
+{ 31} filler3: ARRAY [1..2] OF char;
+{ 33} cur_pos: ul_pos_type
+{= 38} END;
+ix_block_ptr_type = ^ix_block_type;
+ix_pos_type = RECORD
+{ 1} blockpt: ix_block_ptr_type;
+{ 5} recordno: short
+{= 6} END;
+ix_block_type_keytab = RECORD
+{ 1} keyno: long;
+{ 5} next_pos: ix_pos_type;
+{ 11} alignment1: ARRAY [1..2] OF char;
+{ 13} data_pos: ul_pos_type
+{= 18} END;
+ix_block_type = RECORD
+{ 1} keytab: ARRAY [1..ix_keys_in_block] OF ix_block_type_keytab;
+{ 181} nextpt: ix_block_ptr_type;
+{ 185} prevpt: ix_block_ptr_type
+{= 188} END;
+ixcb_type = RECORD
+{ 1} last_error: short;
+{ 3} alignment1: ARRAY [1..2] OF char;
+{ 5} first_pos: ix_pos_type;
+{ 11} alignment2: ARRAY [1..2] OF char;
+{ 13} last_pos: ix_pos_type;
+{ 19} alignment3: ARRAY [1..2] OF char;
+{ 21} cur_pos: ix_pos_type;
+{ 27} alignment6: ARRAY [1..2] OF char;
+{ 29} hashtab: ARRAY [0..ix_hashtab_max] OF RECORD
+{+ 0} h_first_pos: ix_pos_type;
+{+ 6} alignment4: ARRAY [1..2] OF char;
+{+ 8} h_last_pos: ix_pos_type;
+{+ 14} alignment5: ARRAY [1..2] OF char
+{= 176} END;
+{ 205} free_first_pos: ix_pos_type;
+{ 211} alignment7: ARRAY [1..2] OF char;
+{ 213} free_last_pos: ix_pos_type
+{= 218} END;
+matchcode_table_element = RECORD
+{ 1} input_code: ARRAY [1..matchcode_table_text_len] OF char;
+{ 101} is_blank: boolean;
+{ 102} has_matchcode: boolean;
+{ 103} matchcode_pos: short;
+{ 105} matchcode_char: char;
+{ 106} index: indexname_type;
+{ 138} alignment1: char;
+{ 139} priority: short
+{= 140} END;
+matchcode_table_type = ARRAY [1..matchcode_table_size] OF matchcode_table_element;
+benzing_req = RECORD
+{ 1} dbgid: char;
+{ 2} dbdid: char;
+{ 3} dbbzus: char;
+{ 4} dbsaum: ARRAY [1..2] OF char;
+{ 6} dbuhrk: char;
+{ 7} dbyear: ARRAY [1..2] OF char;
+{ 9} dbmon: ARRAY [1..2] OF char;
+{ 11} dbday: ARRAY [1..2] OF char;
+{ 13} dbhh: ARRAY [1..2] OF char;
+{ 15} dbmm: ARRAY [1..2] OF char;
+{ 17} dbss: ARRAY [1..2] OF char;
+{ 19} dbfiller: char;
+{ 20} dbid: ARRAY [1..benz_did_len] OF char
+{= 219} END;
+benzing_reply = RECORD
+{ 1} awsaum: ARRAY [1..2] OF char;
+{ 3} awinat: ARRAY [1..42] OF char
+{= 44} END;
+var_balance_type = RECORD
+{ 1} start_pos: short;
+{ 3} max_len: short;
+{ 5} no_of_bal: short;
+{ 7} offset: short
+{= 8} END;
+var_balance_tab_type = ARRAY [1..max_no_of_bal_rec] OF var_balance_type;
+var_balance_type_tab = ARRAY [1..max_no_of_balances] OF char;
+tse_rec = RECORD
+{ 1} tse_installed: boolean;
+{ 2} tse_multi_clients_installed: boolean;
+{ 3} tse_cycle_installed: boolean;
+{ 4} tse_income_installed: boolean;
+{ 5} tse_adjust_installed: boolean;
+{ 6} tse_apply_and_grant_installed: boolean;
+{ 7} tse_cost_installed: boolean;
+{ 8} tse_proj_installed: boolean;
+{ 9} tse_pop_installed: boolean;
+{ 10} tse_access_installed: boolean
+{= 10} END;
+pntoln_badgeno_type = ARRAY [1..20] OF char;
+pntoln_key_type = char;
+token_type = short;
+Ptree_node_type = ^tree_node_type;
+tree_node_type = RECORD
+{ 1} next_child_left: Ptree_node_type;
+{ 5} next_child_right: Ptree_node_type;
+{ 9} token: token_type;
+{ 11} fieldid: fieldid_type;
+{ 27} condition_value: ARRAY [1..32] OF char
+{= 58} END;
+moduleid_text_type = ARRAY [1..moduleid_text_len] OF char;
+module_table_elem_type = RECORD
+{ 1} moduleid: short;
+{ 3} moduleid_text: moduleid_text_type;
+{ 43} alignment1: ARRAY [1..2] OF char;
+{ 45} maxemplno: long;
+{ 49} db_size: long;
+{ 53} db_all_size: long;
+{ 57} participant: char
+{= 57} END;
+project_time_type = RECORD
+{ 1} costid: costid_type;
+{ 21} duration: duration_type;
+{ 23} comment: long_text_type
+{= 52} END;
+project_tab_type = ARRAY [1..awtime_max_projects_per_day] OF project_time_type;
+licence_elem_type = RECORD
+{ 1} moduleid: short;
+{ 3} filler: ARRAY [1..2] OF filler_type;
+{ 5} used: long;
+{ 9} in_clientno: long;
+{ 13} in_all: long
+{= 16} END;
+licence_table_type = ARRAY [1..participant_array_len] OF licence_elem_type;
+short_block_type = ARRAY [1..8] OF short;
+hex_block_type = ARRAY [1..16] OF char;
+flag_block_type = ARRAY [1..64] OF flag_type;
+dsmdlptp_code_type = ARRAY [1..dsmdlptp_code_len] OF hex_block_type;
+dsmdsum_code_type = ARRAY [1..dsmdsum_code_len] OF hex_block_type;
+participant_flag_array_type = ARRAY [1..participant_array_len] OF flag_type;
+participant_long_array_type = ARRAY [1..participant_array_len] OF long;
+uemploy_table_elem_type = RECORD
+{ 1} ind_module: char;
+{ 2} alignment1: char;
+{ 3} old_moduleid: short;
+{ 5} old_moduleid_text: moduleid_text_type;
+{ 45} new_moduleid: short;
+{ 47} new_moduleid_text: moduleid_text_type
+{= 86} END;
+tsuemploy_table_elem_type = RECORD
+{ 1} ind_module: char;
+{ 2} filler: filler_type;
+{ 3} old_moduleid: short;
+{ 5} new_moduleid: short
+{= 6} END;
+tsuemploy_table_type = ARRAY [1..module_table_len] OF tsuemploy_table_elem_type;
+eload_table_elem_type = RECORD
+{ 1} moduleid: short;
+{ 3} moduleid_text: moduleid_text_type;
+{ 43} position: short
+{= 44} END;
+tseload_table_elem_type = RECORD
+{ 1} moduleid: short;
+{ 3} position: short
+{= 4} END;
+eload_table_type = ARRAY [1..module_table_len] OF eload_table_elem_type;
+tseload_table_type = ARRAY [1..module_table_len] OF tseload_table_elem_type;
+input_pduration_type = ARRAY [1..9] OF char;
+pduration_type = long;
+byte_8_type = ARRAY [1..8] OF byte;
+byte_28_type = ARRAY [1..28] OF byte;
+byte_32_type = ARRAY [1..32] OF byte;
+byte_48_type = ARRAY [1..48] OF byte;
+byte_56_type = ARRAY [1..56] OF byte;
+byte_64_type = ARRAY [1..64] OF byte;
+licence_module_type = RECORD
+{ 1} installed: boolean;
+{ 2} ase: boolean;
+{ 3} number: byte;
+{ 4} alignment1: char;
+{ 5} size: long
+{= 8} END;
+licencerec_type = RECORD
+{ 1} clientno: buffer_type;
+{ 3} ok: boolean;
+{ 4} client_depend: boolean;
+{ 5} test_timer: boolean;
+{ 6} alignment1: char;
+{ 7} number: short;
+{ 9} max_clientnos: short;
+{ 11} test_end_date: date_type;
+{ 17} test_max: long;
+{ 21} ASE_timer: boolean;
+{ 22} timer: timer_text_type;
+{ 102} ckey: packed_8_type;
+{ 110} as400bib: packed_10_type;
+{ 120} alignment2: char;
+{ 121} module_table: ARRAY [1..26] OF licence_module_type
+{= 328} END;
+pduration_positions_type = RECORD
+{ 1} total_no_of_positions: short;
+{ 3} positions: ARRAY [1..10] OF short
+{= 22} END;
+awtime_text_type = ARRAY [1..26] OF char;
+ccsid_tab_type = RECORD
+{ 1} visible_on_as400: char;
+{ 2} ord_ebcdic: packed_3_type;
+{ 5} ord_uppercase: packed_3_type;
+{ 8} ord_unmodified: packed_3_type;
+{ 11} ord_ansi: packed_3_type;
+{ 14} ord_pcsterminal: packed_3_type;
+{ 17} ord_ascii: packed_3_type;
+{ 20} special1_ord: packed_3_type;
+{ 23} special2_ord: packed_3_type;
+{ 26} special3_ord: packed_3_type;
+{ 29} special4_ord: packed_3_type;
+{ 32} special5_ord: packed_3_type
+{= 34} END;
+clientvalues_elem_ptr = ^clientvalues_elem_type;
+clientvalues_elem_type = RECORD
+{ 1} check: boolean;
+{ 2} clientno: buffer_type;
+{ 4} alignment1: char;
+{ 5} dsinstrec: dsinst_rec;
+{ 1155} alignment2: ARRAY [1..2] OF char;
+{ 1157} licencerec: licencerec_type;
+{ 1485} next: clientvalues_elem_ptr
+{=1488} END;
+siport_badgeno_type = ARRAY [1..siport_badgeno_len] OF char;
+zone_range_tab_type = RECORD
+{ 1} clientno: buffer_type;
+{ 3} termid: objectid_type;
+{ 11} from_zone: short;
+{ 13} to_zone: short;
+{ 15} tariffarea: tariffarea_type;
+{ 19} zexport_termid: objectid_type
+{= 26} END;
+zone_range_pointer = ^zone_range_list_type;
+zone_range_list_type = RECORD
+{ 1} next_pt: zone_range_pointer;
+{ 5} zone_range_tab: zone_range_tab_type
+{= 30} END;
+mask_cost_tab_rec_type = RECORD
+{ 1} costid: costid_type;
+{ 21} switch_time: mod_type;
+{ 23} termno: short;
+{ 25} modify_code: short;
+{ 27} to_time: mod_type;
+{ 29} filler1: ARRAY [1..4] OF filler_type
+{= 32} END;
+projno_array_type = RECORD
+{ 1} projno: ARRAY [1..20] OF char
+{= 20} END;
+projno_tab_type = ARRAY [1..max_costno_grupps] OF projno_array_type;
+statusid_type = ARRAY [1..statusid_len] OF char;
+statustype_type = char;
+wrk_status_type = RECORD
+{ 1} statusid: statusid_type;
+{ 9} statustype: statustype_type
+{= 9} END;
+
+{comdecl2} {CONST lens12.inc ???}
+ {dbrecs.inc was?}
+accat_type = ARRAY [1..8] OF char;
+pensum_type = ARRAY [1..4] OF char;
+emplno_qual_type = RECORD
+{ 1} emplno: emplno_type;
+{ 11} qualificationid: qualificationid_type
+{= 18} END;
+alt_wpatids_type = ARRAY [1..maxalt_wpats] OF wpatid_type;
+alt_wpatids_flag_type = ARRAY [1..maxalt_wpats] OF flag_type;
+zone_perm_tab_type = ARRAY [1..max_zones] OF char;
+calenid_type = RECORD
+{ 1} tariffarea: tariffarea_type;
+{ 5} year: short
+{= 6} END;
+dtimeid_type = RECORD
+{ 1} day_emplno: day_emplno_type;
+{ 17} sequenceno: char
+{= 17} END;
+income_group_type = ARRAY [1..max_inc_per_group] OF income_type;
+income_group_tab_type = ARRAY [1..max_no_of_inc_groups] OF income_group_type;
+adjust_key_type = RECORD
+{ 1} adjustcat: adjustcat_type;
+{ 5} invalid_from: date_type;
+{ 11} sequenceno: short
+{= 12} END;
+selopt_key_type = RECORD
+{ 1} seloptno: char;
+{ 2} selopt: char
+{= 2} END;
+balance_adj_type = RECORD
+{ 1} balance: unsigned_byte;
+{ 2} bal_unit: char;
+{ 3} count: short;
+{ 5} adjust_day: date_type;
+{ 11} method: short;
+{ 13} transbalanceid_1: short;
+{ 15} transbalanceid_2: short;
+{ 17} corr_value_1: saldo_type;
+{ 21} corr_value_2: saldo_type
+{= 24} END;
+balance_cbal_type = RECORD
+{ 1} balance: balance_type;
+{ 5} cycle_terminated: flag_type;
+{ 6} alignment1: filler_type;
+{ 7} sum_of_positive: short
+{= 8} END;
+adjust_rule_tab_type = ARRAY [1..adjust_rule_tab_len] OF balance_adj_type;
+cbal_balance_tab_type = ARRAY [1..max_no_of_balances] OF balance_cbal_type;
+add_value_tab_type = ARRAY [1..max_no_of_balances] OF balance_type;
+plan_key_type = RECORD
+{ 1} emplno: emplno_type;
+{ 11} date_to: date_type
+{= 16} END;
+rule_key_type = RECORD
+{ 1} ruleid: ruleid_type;
+{ 3} invalid_from: date_type
+{= 8} END;
+timepair_type = RECORD
+{ 1} codeid: codeid_type;
+{ 3} time_in: mod_type;
+{ 5} terminal_in: short;
+{ 7} modify_in: short;
+{ 9} time_out: mod_type;
+{ 11} terminal_out: short;
+{ 13} modify_out: short
+{= 14} END;
+wpat_key_type = RECORD
+{ 1} wpatid: wpatid_type;
+{ 5} invalid_from: date_type
+{= 10} END;
+dsabs_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} absid: emplno_day_type;
+{ 25} codeid_tab: month_codes_type;
+{ 87} last_filled_day: short;
+{ 89} ondutytype_tab: month_char_type;
+{ 120} filler1: ARRAY [1..1] OF filler_type;
+{ 121} ondutylen_tab: month_short_type;
+{ 183} filler: ARRAY [1..18] OF filler_type
+{= 200} END;
+dsaccat_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} catid: accat_type;
+{ 17} default_perm: char;
+{ 18} cat: ARRAY [1..24] OF RECORD
+{+ 0} employcat: employcat_type;
+{+ 4} perm: char
+{= 120} END;
+{ 138} filler: ARRAY [1..43] OF char
+{= 180} END;
+dsaccomm_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} catid: accat_type;
+{ 17} default_perm: char;
+{ 18} comm: ARRAY [1..24] OF RECORD
+{+ 0} commtype: commtype_type;
+{+ 4} perm: char
+{= 120} END;
+{ 138} filler: ARRAY [1..23] OF unsigned_byte
+{= 160} END;
+dsaccop_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} catid: accat_type;
+{ 17} default_perm: char;
+{ 18} cop: ARRAY [1..24] OF RECORD
+{+ 0} operationid: operationid_type;
+{+ 8} perm: char
+{= 216} END;
+{ 234} filler: ARRAY [1..27] OF unsigned_byte
+{= 260} END;
+dsaccost_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} catid: accat_type;
+{ 17} default_perm: char;
+{ 18} cost: ARRAY [1..24] OF RECORD
+{+ 0} costid: costid_type;
+{+ 20} perm: char
+{= 504} END;
+{ 522} filler: ARRAY [1..28] OF char
+{= 549} END;
+deptno_permission_type = RECORD
+{ 1} deptno: deptno_type;
+{ 11} perm: char
+{= 11} END;
+dsacdept_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} catid: accat_type;
+{ 17} default_perm: char;
+{ 18} dept: ARRAY [1..48] OF deptno_permission_type;
+{ 546} filler: ARRAY [1..15] OF char
+{= 560} END;
+accode_perm_type = RECORD
+{ 1} codeid: codeid_type;
+{ 3} codetype: codetype_type;
+{ 4} perm: char
+{= 4} END;
+dsaccode_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} catid: accat_type;
+{ 17} sequenceno: short;
+{ 19} default_perm: char;
+{ 20} codeid: codeid_type;
+{ 22} codetype: codetype_type;
+{ 23} perm: char;
+{ 24} filler: ARRAY [1..1] OF char
+{= 24} END;
+dsacinc_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} catid: accat_type;
+{ 17} default_perm: char;
+{ 18} inc: ARRAY [1..24] OF RECORD
+{+ 0} income: income_type;
+{+ 4} perm: char
+{= 120} END;
+{ 138} filler: ARRAY [1..39] OF char
+{= 176} END;
+acmask_perm_type = RECORD
+{ 1} maskid: objectid_type;
+{ 9} perm: char;
+{ 10} permission_code: char
+{= 10} END;
+dsacmask_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} catid: accat_type;
+{ 17} sequenceno: short;
+{ 19} default_perm: char;
+{ 20} mask: acmask_perm_type;
+{ 30} filler: ARRAY [1..3] OF char
+{= 32} END;
+dsacprog_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} catid: accat_type;
+{ 17} default_perm: char;
+{ 18} filler1: ARRAY [1..3] OF a_char;
+{ 21} prog: ARRAY [1..24] OF RECORD
+{+ 0} progid: objectid_type;
+{+ 8} perm: char;
+{+ 9} filler: char
+{= 240} END;
+{ 261} filler: ARRAY [1..40] OF char
+{= 300} END;
+dsacsel_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} catid: accat_type;
+{ 17} sequenceno: short;
+{ 19} default_perm: char;
+{ 20} selopt_key: selopt_key_type;
+{ 22} perm: char
+{= 22} END;
+acsel_perm_type = RECORD
+{ 1} seloptno: char;
+{ 2} selopt: char;
+{ 3} perm: char
+{= 3} END;
+dsacterm_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} catid: accat_type;
+{ 17} default_perm: char;
+{ 18} term: ARRAY [1..24] OF RECORD
+{+ 0} termid: objectid_type;
+{+ 8} perm: char
+{= 216} END;
+{ 234} filler: ARRAY [1..67] OF char
+{= 300} END;
+dsaczone_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} catid: accat_type;
+{ 17} default_perm: char;
+{ 18} zone_perm_tab: zone_perm_tab_type;
+{ 218} filler: ARRAY [1..23] OF filler_type
+{= 240} END;
+dsadjusr_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} adjust_key: adjust_key_type;
+{ 21} balance_adj: balance_adj_type;
+{ 45} filler: ARRAY [1..16] OF filler_type
+{= 60} END;
+dsadjust_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} adjust_key: adjust_key_type;
+{ 21} valid_from: date_type;
+{ 27} adjust_text: long_text_type;
+{ 57} chain_balance_tab: chain_balance_tab_type;
+{ 105} income_group: income_group_tab_type;
+{ 265} useable: flag_type;
+{ 266} filler: ARRAY [1..35] OF filler_type
+{= 300} END;
+dsadjustt_rec = RECORD
+{ 1} dsadjustrec: dsadjust_rec;
+{ 301} rule_tab: adjust_rule_tab_type
+{=2028} END;
+dsccbal_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} ccbalid: emplno_day_type;
+{ 25} add_value_tab: add_value_tab_type;
+{ 121} filler: ARRAY [1..40] OF filler_type
+{= 160} END;
+dsccbalr_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} ccbalrid: emplno_day_seq_type;
+{ 27} filler1: ARRAY [1..2] OF filler_type;
+{ 29} balance_adj: balance_adj_type;
+{ 53} filler: ARRAY [1..28] OF filler_type
+{= 80} END;
+dsccbalt_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} ccbalid: emplno_day_type;
+{ 25} add_value_tab: add_value_tab_type;
+{ 121} rule_tab: adjust_rule_tab_type;
+{ 1849} use_method_tab: rule_apply_tab_type;
+{ 1921} balance_numbers: ARRAY [1..max_no_of_balances] OF unsigned_byte
+{=1944} END;
+dsadmbno_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} date_and_time: date_and_time_type;
+{ 21} millisec: short;
+{ 23} badgeno: badgeno_type;
+{ 33} physical_key: ARRAY [1..20] OF char;
+{ 53} key_type: char;
+{ 54} key_state: char;
+{ 55} logonid: logonid_type;
+{ 63} owner: ARRAY [1..10] OF char;
+{ 73} filler: ARRAY [1..18] OF char
+{= 90} END;
+dsaemp_const_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} emplno: emplno_type;
+{ 19} deptno: deptno_type;
+{ 29} employcat: employcat_type;
+{ 33} filler3: ARRAY [1..1] OF filler_type;
+{ 34} factory: packed_12_type;
+{ 46} tariffarea: tariffarea_type;
+{ 50} pin_code: pin_code_type;
+{ 54} manager_emplno: emplno_type;
+{ 64} firstname: firstname_type;
+{ 84} surname: surname_type;
+{ 114} vacation_method: unsigned_byte;
+{ 115} vacation: ARRAY [1..maxvacations] OF dbalance_type;
+{ 123} allowances_workdays: allowances_type;
+{ 133} allowances_freedays: allowances_type;
+{ 143} accesscat: packed_4_type;
+{ 147} hometerm: objectid_type;
+{ 155} termcats: ARRAY [1..maxtermcats] OF termcat_type;
+{ 187} dist_deduct_on_call: ARRAY [1..2] OF duration_type;
+{ 191} v_invalid_from: date_type;
+{ 197} v_valid_from: date_type;
+{ 203} start_date: date_type;
+{ 209} ref_period_work_time: saldo_type;
+{ 213} ref_period_len: short;
+{ 215} phoneno: packed_14_type;
+{ 229} auto_cost_switch: flag_type;
+{ 230} individual_distance: flag_type;
+{ 231} valid_from: date_type;
+{ 237} valid_to: date_type;
+{ 243} cycleid: cycleid_type;
+{ 247} cycle_start: short;
+{ 249} std_effect_rate: sreal_type;
+{ 251} dist_deduct: ARRAY [1..2] OF duration_type;
+{ 255} adjustcat: adjustcat_type;
+{ 259} mean_std_worktime: duration_type;
+{ 261} mean_std_worktime_week: duration_type;
+{ 263} continued_pay_len: continued_pay_len_type;
+{ 265} filler4: ARRAY [1..7] OF filler_type;
+{ 272} working_location: unsigned_byte;
+{ 273} costid: costid_type;
+{ 293} sfc_participant: flag_type;
+{ 294} multi_machine_user: char;
+{ 295} birthdate: date_type;
+{ 301} mach_job: mach_job_type;
+{ 317} badgeno: long_badgeno_type;
+{ 337} select_options: select_options_type;
+{ 353} empl_corr_values: empl_corr_values_type;
+{ 369} empl_corr_values_add: empl_corr_values_type;
+{ 385} filler5: packed_16_type
+{= 400} END;
+dsaemp_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} emplno: emplno_type;
+{ 19} deptno: deptno_type;
+{ 29} employcat: employcat_type;
+{ 33} filler3: ARRAY [1..1] OF filler_type;
+{ 34} factory: packed_12_type;
+{ 46} tariffarea: tariffarea_type;
+{ 50} pin_code: pin_code_type;
+{ 54} manager_emplno: emplno_type;
+{ 64} firstname: firstname_type;
+{ 84} surname: surname_type;
+{ 114} vacation_method: unsigned_byte;
+{ 115} vacation: ARRAY [1..maxvacations] OF dbalance_type;
+{ 123} allowances_workdays: allowances_type;
+{ 133} allowances_freedays: allowances_type;
+{ 143} accesscat: acccatid_type;
+{ 147} hometerm: objectid_type;
+{ 155} termcats: ARRAY [1..maxtermcats] OF termcat_type;
+{ 187} dist_deduct_on_call: ARRAY [1..2] OF duration_type;
+{ 191} v_invalid_from: date_type;
+{ 197} v_valid_from: date_type;
+{ 203} start_date: date_type;
+{ 209} ref_period_work_time: saldo_type;
+{ 213} ref_period_len: short;
+{ 215} phoneno: packed_14_type;
+{ 229} auto_cost_switch: flag_type;
+{ 230} individual_distance: flag_type;
+{ 231} valid_from: date_type;
+{ 237} valid_to: date_type;
+{ 243} cycleid: cycleid_type;
+{ 247} cycle_start: short;
+{ 249} std_effect_rate: sreal_type;
+{ 251} dist_deduct: ARRAY [1..2] OF duration_type;
+{ 255} adjustcat: adjustcat_type;
+{ 259} mean_std_worktime: duration_type;
+{ 261} mean_std_worktime_week: duration_type;
+{ 263} continued_pay_len: continued_pay_len_type;
+{ 265} filler4: ARRAY [1..7] OF filler_type;
+{ 272} working_location: unsigned_byte;
+{ 273} costid: costid_type;
+{ 293} sfc_participant: flag_type;
+{ 294} multi_machine_user: char;
+{ 295} birthdate: date_type;
+{ 301} mach_job: mach_job_type;
+{ 317} badgeno: long_badgeno_type;
+{ 337} select_options: select_options_type;
+{ 353} empl_corr_values: empl_corr_values_type;
+{ 369} email_address: email_address_type;
+{ 401} postal_code: ARRAY [1..8] OF char;
+{ 409} home_town: ARRAY [1..32] OF char;
+{ 441} street: ARRAY [1..40] OF char;
+{ 481} phoneno1: phoneno_type;
+{ 505} handyno1: phoneno_type;
+{ 529} phoneno2: phoneno_type;
+{ 553} handyno2: phoneno_type;
+{ 577} photo_location: url_type;
+{ 831} filler6: ARRAY [1..1] OF filler_type;
+{ 832} user_template: logonid_type;
+{ 840} password: ARRAY [1..8] OF unsigned_byte;
+{ 848} alias: alias_type;
+{ 863} no_of_blank_lines: short;
+{ 865} position_number: short;
+{ 867} rpoolid: rpoolid_type;
+{ 879} hourly_wage: sreal_type;
+{ 881} last_change_pin: date_type;
+{ 887} last_change_pwd: date_type;
+{ 893} pin_locked: flag_type;
+{ 894} pwd_locked: flag_type;
+{ 895} filler5: ARRAY [1..106] OF filler_type
+{=1000} END;
+dsaltpat_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} emplno: emplno_type;
+{ 19} first_day: date_type;
+{ 25} altpat_tab: ARRAY [1..7] OF alt_wpatids_type;
+{ 249} warn_altpat_tab: ARRAY [1..7] OF alt_wpatids_flag_type;
+{ 305} filler: ARRAY [1..36] OF filler_type
+{= 340} END;
+dsacalen_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} tariffarea: tariffarea_type;
+{ 13} special_day: date_type;
+{ 19} special_day_text: long_text_type;
+{ 49} cal_function: char;
+{ 50} daytype: unsigned_byte;
+{ 51} date_offset: short;
+{ 53} time_difference: mod_type;
+{ 55} filler: ARRAY [1..26] OF filler_type
+{= 80} END;
+special_day_daytype_type = ARRAY [1..31] OF unsigned_byte;
+dscalen_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} calenid: calenid_type;
+{ 15} calen_text: long_text_type;
+{ 45} industry_day_1: short;
+{ 47} special_day_daytype: ARRAY [1..12] OF special_day_daytype_type;
+{ 419} time_difference: mod_type;
+{ 421} filler: ARRAY [1..30] OF char
+{= 450} END;
+dscant_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} emplno: emplno_type;
+{ 19} datetime: date_and_time_type;
+{ 31} modify_id: short;
+{ 33} termid: objectid_type;
+{ 41} amount: long;
+{ 45} termno: short;
+{ 47} articleno: objectid_type;
+{ 55} quantity: short;
+{ 57} filler: ARRAY [1..44] OF char
+{= 100} END;
+dscbal_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} cbalid: emplno_day_type;
+{ 25} prev_section_date: date_type;
+{ 31} next_section_date: date_type;
+{ 37} balance_tab: cbal_balance_tab_type;
+{ 229} filler: ARRAY [1..12] OF filler_type
+{= 240} END;
+dsccsid_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} ccsid_tab: ccsid_tab_type
+{= 42} END;
+dsccalen_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} tariffarea: tariffarea_type;
+{ 13} date: date_type;
+{ 19} sequenceno: short;
+{ 21} commt_text: long_text_type
+{= 50} END;
+dscemp_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} emplno: emplno_type;
+{ 19} working_location: unsigned_byte;
+{ 20} filler1: ARRAY [1..1] OF filler_type;
+{ 21} manager_emplno: emplno_type;
+{ 31} email_address: email_address_type;
+{ 63} filler2: ARRAY [1..26] OF filler_type;
+{ 89} rpoolid: rpoolid_type;
+{ 101} postal_code: ARRAY [1..8] OF char;
+{ 109} home_town: ARRAY [1..32] OF char;
+{ 141} street: ARRAY [1..40] OF char;
+{ 181} phoneno1: phoneno_type;
+{ 205} handyno1: phoneno_type;
+{ 229} phoneno2: phoneno_type;
+{ 253} handyno2: phoneno_type;
+{ 277} photo_location: url_type;
+{ 531} filler5: ARRAY [1..1] OF filler_type;
+{ 532} alias: alias_type;
+{ 547} no_of_blank_lines: short;
+{ 549} position_number: short;
+{ 551} hourly_wage: sreal_type;
+{ 553} filler3: ARRAY [1..54] OF filler_type;
+{ 607} text_1: ARRAY [1..60] OF char;
+{ 667} text_2: ARRAY [1..60] OF char;
+{ 727} last_date_auto_schedu: date_type;
+{ 733} last_closing: date_type;
+{ 739} qual_for_job: flag_type;
+{ 740} reserved01: char;
+{ 741} planned_until: date_type;
+{ 747} filler4: ARRAY [1..54] OF filler_type;
+{ 801} last_change_pin: date_type;
+{ 807} pin_locked: flag_type;
+{ 808} pwd_locked: flag_type;
+{ 809} last_change_pwd: date_type;
+{ 815} user_template: logonid_type;
+{ 823} filler: ARRAY [1..1178] OF filler_type
+{=2000} END;
+dscitem_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} articleno: objectid_type;
+{ 17} price: ARRAY [1..3] OF long;
+{ 29} article_text: long_text_type;
+{ 59} kind: char;
+{ 60} incomeid: income_type;
+{ 64} filler1: ARRAY [1..1] OF char;
+{ 65} invalid_from: date_type;
+{ 71} valid_from: date_type;
+{ 77} filler: ARRAY [1..4] OF char
+{= 80} END;
+dscode_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} wrk_code: wrk_code_type;
+{ 12} wrk_codetype_long: char;
+{ 13} wrk_codetext: long_text_type;
+{ 43} vacation_code: flag_type;
+{ 44} warning_if_absence: flag_type;
+{ 45} balanceid: short;
+{ 47} free_shift: flag_type;
+{ 48} worktime: char;
+{ 49} valid_for_overtime: flag_type;
+{ 50} overtime_allowance_possible: flag_type;
+{ 51} allowance_possible: flag_type;
+{ 52} real_worktime: flag_type;
+{ 53} valid_on_free_day: flag_type;
+{ 54} continue_code: char;
+{ 55} combination_code: char;
+{ 56} sv_day_flag: flag_type;
+{ 57} u_day_flag: flag_type;
+{ 58} debit_time_deduct_flag: flag_type;
+{ 59} note_break: flag_type;
+{ 60} flextime_allowed_flag: flag_type;
+{ 61} incomeid: income_type;
+{ 65} priority: short;
+{ 67} scodeid_day_off: codeid_type;
+{ 69} scodeid_holiday: codeid_type;
+{ 71} invalid_from: date_type;
+{ 77} valid_from: date_type;
+{ 83} scodeid_workday: codeid_type;
+{ 85} costid: costid_type;
+{ 105} color: color_attr_type;
+{ 113} wizard_mark: char;
+{ 114} standby_as_planned: flag_type;
+{ 115} useable: flag_type;
+{ 116} inside_normaltime: flag_type;
+{ 117} filler: ARRAY [1..24] OF filler_type
+{= 140} END;
+cols_key_type = RECORD
+{ 1} filetype: ARRAY [1..10] OF char;
+{ 11} logonid: logonid_type;
+{ 19} formatno: short;
+{ 21} col_no: short
+{= 22} END;
+dscols_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} cols_key: cols_key_type;
+{ 31} rec_pos: short;
+{ 33} rec_type: ARRAY [1..1] OF char;
+{ 34} title_one_line_flag: flag_type;
+{ 35} col_len: short;
+{ 37} title1: ARRAY [1..15] OF char;
+{ 52} title2: ARRAY [1..15] OF char;
+{ 67} col_dist: short;
+{ 69} conv_table_name: long_text_type;
+{ 99} justify: char;
+{ 100} fieldid: fieldid_type;
+{ 116} filler: ARRAY [1..21] OF char
+{= 136} END;
+commid_type = RECORD
+{ 1} emplno: emplno_type;
+{ 11} date: date_type;
+{ 17} commtype: commtype_type;
+{ 21} sequenceno: short
+{= 22} END;
+dscomm_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} commid: commid_type;
+{ 31} modify_code: short;
+{ 33} comment: ARRAY [1..60] OF char;
+{ 93} following_line: flag_type;
+{ 94} filler: ARRAY [1..7] OF unsigned_byte
+{= 100} END;
+dscommt_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} commtype: commtype_type;
+{ 13} commt_text: long_text_type;
+{ 43} filler: ARRAY [1..18] OF unsigned_byte
+{= 60} END;
+dscusers_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} jobid: cusers_name_type;
+{ 39} logonid: logonid_type;
+{ 47} os_username: cusers_name_type;
+{ 77} login_time: date_and_time_type;
+{ 89} clientname: cusers_name_type;
+{ 119} servername: cusers_name_type;
+{ 149} clientadr: cusers_name_type;
+{ 179} serveradr: cusers_name_type;
+{ 209} filler1: ARRAY [1..2] OF filler_type;
+{ 211} clientport: short;
+{ 213} serverport: short;
+{ 215} last_planner: char;
+{ 216} tcp_serverjob: cusers_name_type;
+{ 246} filler: ARRAY [1..35] OF unsigned_byte
+{= 280} END;
+dscycle_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} cycleid: cycleid_type;
+{ 13} cycle_text: long_text_type;
+{ 43} begin_date: date_type;
+{ 49} filler1: ARRAY [1..1] OF filler_type;
+{ 50} wizard_mark: char;
+{ 51} length: short;
+{ 53} shiftid: ARRAY [1..maxshifts_per_cycle] OF shiftid_type;
+{ 309} filler: ARRAY [1..42] OF filler_type
+{= 350} END;
+dsdbal_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} dbalid: emplno_day_type;
+{ 25} dbal: ARRAY [1..max_no_of_balances] OF dbalance_type;
+{ 73} auto_break: duration_type;
+{ 75} filler: ARRAY [1..6] OF filler_type
+{= 80} END;
+dsdept_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} deptno: deptno_type;
+{ 19} dept_text: long_text_type;
+{ 49} filler: ARRAY [1..12] OF char
+{= 60} END;
+dsdic_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} recid: recid_type;
+{ 17} fieldid: fieldid_type;
+{ 33} dic_text: long_text_type;
+{ 63} keyfield: short;
+{ 65} pos: short;
+{ 67} fieldtype: fieldtype_type;
+{ 69} len: short;
+{ 71} conv_table_name: long_text_type;
+{ 101} filler: ARRAY [1..40] OF filler_type
+{= 140} END;
+record_definition_type = ARRAY [1..max_fields_per_record] OF dsdic_rec;
+dist_deduct_tab_type = ARRAY [1..11] OF short;
+dsdist_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} dist_deduct_tabid: ARRAY [1..4] OF char;
+{ 13} dist_deduct_tab: ARRAY [1..10] OF dist_deduct_tab_type;
+{ 233} filler: ARRAY [1..168] OF char
+{= 400} END;
+dsdtime_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} dtimeid: dtimeid_type;
+{ 26} record_locked: char;
+{ 27} no_of_timepairs: short;
+{ 29} no_of_del_timepairs: short;
+{ 31} timepair_tab: ARRAY [1..maxtimepairs_per_record] OF timepair_type;
+{ 87} filler: ARRAY [1..14] OF char
+{= 100} END;
+all_timepairs_tab_type = ARRAY [1..maxtimepairs] OF timepair_type;
+dsdtimet_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} dtimet_key: day_emplno_type;
+{ 25} filler1: char;
+{ 26} record_locked: char;
+{ 27} no_of_timepairs: short;
+{ 29} no_of_del_timepairs: short;
+{ 31} timepair_tab: all_timepairs_tab_type;
+{ 255} del_timepair_tab: all_timepairs_tab_type;
+{ 479} filler: ARRAY [1..22] OF char
+{= 500} END;
+dsecalen_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} mach_job: mach_job_type;
+{ 25} date: date_type;
+{ 31} event: event_type;
+{ 33} del_flag: flag_type;
+{ 34} filler1: filler_type;
+{ 35} from_time: mod_type;
+{ 37} to_time: mod_type;
+{ 39} filler2: ARRAY [1..12] OF filler_type
+{= 50} END;
+dseload_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} parametername: ARRAY [1..8] OF char;
+{ 17} eload_text: long_text_type;
+{ 47} emplno_pos: short;
+{ 49} input_emplno_len: short;
+{ 51} manager_emplno_pos: short;
+{ 53} input_manager_emplno_len: short;
+{ 55} badgeno_pos: short;
+{ 57} input_badgeno_len: short;
+{ 59} costid_pos: short;
+{ 61} input_costid_len: short;
+{ 63} v_valid_from_yy_pos: short;
+{ 65} v_valid_from_mo_pos: short;
+{ 67} v_valid_from_dd_pos: short;
+{ 69} valid_from_yy_pos: short;
+{ 71} valid_from_mo_pos: short;
+{ 73} valid_from_dd_pos: short;
+{ 75} valid_to_yy_pos: short;
+{ 77} valid_to_mo_pos: short;
+{ 79} valid_to_dd_pos: short;
+{ 81} start_date_pos: ARRAY [1..3] OF short;
+{ 87} birthdate_pos: ARRAY [1..3] OF short;
+{ 93} select_options_pos: ARRAY [1..max_select_options] OF short;
+{ 125} empl_corr_values_pos: ARRAY [1..max_empl_corr_values] OF short;
+{ 133} input_empl_corr_values_len: short;
+{ 135} vacation_pos: ARRAY [1..maxvacations] OF short;
+{ 143} input_vacation_len: short;
+{ 145} allowances_pos: ARRAY [1..10] OF short;
+{ 165} input_allowances_len: short;
+{ 167} name_pos: short;
+{ 169} input_name_len: short;
+{ 171} surname_pos: short;
+{ 173} input_surname_len: short;
+{ 175} firstname_pos: short;
+{ 177} input_firstname_len: short;
+{ 179} deptno_pos: short;
+{ 181} input_deptno_len: short;
+{ 183} hometerm_pos: short;
+{ 185} input_hometerm_len: short;
+{ 187} tariffarea_pos: short;
+{ 189} input_tariffarea_len: short;
+{ 191} termcats_pos: short;
+{ 193} input_termcats_len: short;
+{ 195} pincode_pos: short;
+{ 197} input_pincode_len: short;
+{ 199} employcat_pos: short;
+{ 201} input_employcat_len: short;
+{ 203} phoneno_pos: short;
+{ 205} input_phoneno_len: short;
+{ 207} factory_pos: short;
+{ 209} input_factory_len: short;
+{ 211} accesscat_pos: short;
+{ 213} input_accesscat_len: short;
+{ 215} cycleid_pos: short;
+{ 217} input_cycleid_len: short;
+{ 219} cycle_start_pos: short;
+{ 221} ref_p_len_pos: short;
+{ 223} ref_p_work_time_pos: short;
+{ 225} adjustcat_pos: short;
+{ 227} input_adjustcat_len: short;
+{ 229} mean_std_w_pos: short;
+{ 231} input_mean_std_w_len: short;
+{ 233} mean_std_w_w_pos: short;
+{ 235} inp_mean_std_w_w_len: short;
+{ 237} cont_pay_len_pos: short;
+{ 239} inp_cont_pay_len_len: short;
+{ 241} machineid_pos: short;
+{ 243} input_machineid_len: short;
+{ 245} jobid_pos: short;
+{ 247} input_jobid_len: short;
+{ 249} working_location_pos: short;
+{ 251} input_working_location_len: short;
+{ 253} email_address_pos: short;
+{ 255} input_email_address_len: short;
+{ 257} position_number_pos: short;
+{ 259} input_position_number_len: short;
+{ 261} no_of_blank_lines_pos: short;
+{ 263} input_no_of_blank_lines_len: short;
+{ 265} alias_pos: short;
+{ 267} input_alias_len: short;
+{ 269} text_1_pos: short;
+{ 271} input_text_1_len: short;
+{ 273} text_2_pos: short;
+{ 275} input_text_2_len: short;
+{ 277} street_pos: short;
+{ 279} input_street_len: short;
+{ 281} postal_code_pos: short;
+{ 283} input_postal_code_len: short;
+{ 285} home_town_pos: short;
+{ 287} input_home_town_len: short;
+{ 289} telephoneno_pos: short;
+{ 291} input_telephoneno_len: short;
+{ 293} auto_cost_switch_pos: short;
+{ 295} dist_from_terminal_pos: short;
+{ 297} sfc_participant_pos: short;
+{ 299} multi_machine_user_pos: short;
+{ 301} vacation_method_pos: short;
+{ 303} input_vacation_method_len: short;
+{ 305} phoneno1_pos: short;
+{ 307} input_phoneno1_len: short;
+{ 309} phoneno2_pos: short;
+{ 311} input_phoneno2_len: short;
+{ 313} handyno1_pos: short;
+{ 315} input_handyno1_len: short;
+{ 317} handyno2_pos: short;
+{ 319} input_handyno2_len: short;
+{ 321} photo_location_pos: short;
+{ 323} input_photo_location_len: short;
+{ 325} user_template_pos: short;
+{ 327} input_user_template_len: short;
+{ 329} password_pos: short;
+{ 331} input_password_len: short;
+{ 333} rpoolid_pos: short;
+{ 335} input_rpoolid_len: short;
+{ 337} hourly_wage_pos: short;
+{ 339} module: ARRAY [1..32] OF tseload_table_elem_type;
+{ 467} v_valid_to_yy_pos: short;
+{ 469} v_valid_to_mo_pos: short;
+{ 471} v_valid_to_dd_pos: short;
+{ 473} filler: ARRAY [1..54] OF filler_type
+{= 526} END;
+dsevent_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} event: event_type;
+{ 11} event_text: long_text_type;
+{ 41} invalid_from: date_type;
+{ 47} valid_from: date_type;
+{ 53} event_percent: long;
+{ 57} event_absolute: long;
+{ 61} event_delay: short;
+{ 63} no_of_days: short;
+{ 65} allocation: char;
+{ 66} filler1: ARRAY [1..3] OF filler_type;
+{ 69} manual_allocation: ARRAY [1..7] OF long;
+{ 97} color: color_attr_type;
+{ 105} filler2: ARRAY [1..6] OF filler_type
+{= 110} END;
+dsfbadge_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} badgeno: long_badgeno_type;
+{ 29} hostno: short;
+{ 31} host_clientno: buffer_type;
+{ 33} host_termid: objectid_type;
+{ 41} host_termno: short;
+{ 43} host_termcat: termcat_type;
+{ 51} filler: ARRAY [1..30] OF filler_type
+{= 80} END;
+dsff10_rec = RECORD
+{ 1} key10: ARRAY [1..10] OF unsigned_byte;
+{ 11} data90: ARRAY [1..90] OF unsigned_byte
+{= 100} END;
+dsff16_rec = RECORD
+{ 1} key16: ARRAY [1..16] OF unsigned_byte;
+{ 17} data64: ARRAY [1..64] OF unsigned_byte
+{= 80} END;
+export_interface_type = ARRAY [1..2] OF char;
+export_line_type = ARRAY [1..2] OF char;
+export_status_type = ARRAY [1..2] OF char;
+export_data_type = ARRAY [1..export_data_len] OF char;
+export_key_type = RECORD
+{ 1} export_interface: export_interface_type;
+{ 3} line_type: export_line_type;
+{ 5} date_time_written: date_and_time_type;
+{ 17} millisec: short
+{= 18} END;
+dsexport_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} export_key: export_key_type;
+{ 27} export_status: export_status_type;
+{ 29} export_data: export_data_type;
+{ 278} filler: ARRAY [1..123] OF char
+{= 400} END;
+dsfsick_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} emplno: emplno_type;
+{ 19} date_to: date_type;
+{ 25} date_from: date_type;
+{ 31} codeid: codeid_type;
+{ 33} ref_date: date_type;
+{ 39} filler: ARRAY [1..22] OF char
+{= 60} END;
+dsjobflg_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} jobflag: ARRAY [1..3] OF char;
+{ 12} jobflg_txt: ARRAY [1..50] OF char;
+{ 62} filler: ARRAY [1..9] OF filler_type
+{= 70} END;
+dslang_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} tableno: record_no_type;
+{ 11} languageid: languageid_type;
+{ 13} foreign_key: ARRAY [1..dslang_key_len] OF char;
+{ 77} long_key1: long;
+{ 81} long_key2: long;
+{ 85} unsigned_key1: ARRAY [1..8] OF unsigned_byte;
+{ 93} date: date_type;
+{ 99} foreign_text: long_text_type;
+{ 129} filler: ARRAY [1..12] OF filler_type
+{= 140} END;
+lodist_deduct_tab_type = ARRAY [1..10] OF short;
+dslodist_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} lodist_deduct_tabid: ARRAY [1..4] OF char;
+{ 13} lodist_deduct_tab: ARRAY [1..50] OF lodist_deduct_tab_type;
+{ 1013} filler: ARRAY [1..188] OF filler_type
+{=1200} END;
+dslogatt_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} userid: packed_20_type;
+{ 29} login_time: date_and_time_type;
+{ 41} jobid: cusers_name_type;
+{ 71} os_username: cusers_name_type;
+{ 101} clientname: cusers_name_type;
+{ 131} access_granted: flag_type
+{= 131} END;
+dsltime_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} ltimeid: date_and_time_type;
+{ 21} termid: objectid_type;
+{ 29} termno: short;
+{ 31} req_code: char;
+{ 32} cost_req_code: char;
+{ 33} costid: costid_type;
+{ 53} badgeno: long_badgeno_type;
+{ 73} codeid: codeid_type;
+{ 75} book_date_time: date_and_time_type;
+{ 87} ignore_time: short;
+{ 89} reason: short;
+{ 91} codeidtype: char;
+{ 92} filler1: filler_type;
+{ 93} amount: long;
+{ 97} quantity: short;
+{ 99} citemno: objectid_type;
+{ 107} millisec: short;
+{ 109} emplno: emplno_type;
+{ 119} filler: ARRAY [1..2] OF filler_type
+{= 120} END;
+booklog_rec = dsltime_rec;
+dsmasks_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} menuename: objectid_type;
+{ 17} menue_title: menue_title_type;
+{ 63} languageid: languageid_type;
+{ 65} prog_tab: ARRAY [1..max_menue_lines] OF RECORD
+{+ 0} menue_line: menue_line_type;
+{+ 50} progname: objectid_type;
+{+ 58} info_field: menue_info_type
+{= 816} END;
+{ 881} filler: ARRAY [1..70] OF filler_type
+{= 950} END;
+short_adjust_rule_type = RECORD
+{ 1} method: short;
+{ 3} transbalanceid_1: short;
+{ 5} transbalanceid_2: short;
+{ 7} filler: ARRAY [1..2] OF filler_type;
+{ 9} corr_value_1: saldo_type;
+{ 13} corr_value_2: saldo_type
+{= 16} END;
+dsmcconf_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} operationid: operationid_type;
+{ 17} operation_text: long_text_type;
+{ 47} balanceid: short;
+{ 49} add_value: saldo_type;
+{ 53} rule_tab: ARRAY [1..mcconf_rule_tab_len] OF short_adjust_rule_type;
+{ 133} value_suggestion: saldo_type;
+{ 137} show_cond_min: saldo_type;
+{ 141} show_cond_max: saldo_type;
+{ 145} check_cond_min: saldo_type;
+{ 149} check_cond_max: saldo_type;
+{ 153} filler: ARRAY [1..48] OF char
+{= 200} END;
+dsperror_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} logonid: logonid_type;
+{ 17} start_datetime: date_and_time_type;
+{ 29} rowno: short;
+{ 31} date_time_written: date_and_time_type;
+{ 43} error_code: code_type;
+{ 47} vos_error: short;
+{ 49} error_text: error_text_type;
+{ 109} severity_code: char;
+{ 110} emplno: emplno_type;
+{ 120} exit_code: exit_code_type;
+{ 126} filler: ARRAY [1..25] OF unsigned_byte
+{= 150} END;
+dsplan_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} plan_key: plan_key_type;
+{ 25} date_from: date_type;
+{ 31} allowances: allowances_type;
+{ 41} wpatid: wpatid_type;
+{ 45} ruleid: ruleid_type;
+{ 47} codeid: codeid_type;
+{ 49} employcat: employcat_type;
+{ 53} tariffarea: tariffarea_type;
+{ 57} costid: costid_type;
+{ 77} cycleid: cycleid_type;
+{ 81} cycle_start: short;
+{ 83} special_service: codeid_type;
+{ 85} from_time: mod_type;
+{ 87} to_time: mod_type;
+{ 89} ondutylen_from_cur_wpat: char;
+{ 90} filler: ARRAY [1..31] OF unsigned_byte
+{= 120} END;
+apply_key_type = RECORD
+{ 1} emplno: emplno_type;
+{ 11} date_to: date_type;
+{ 17} apptype: short;
+{ 19} time: mod_type
+{= 20} END;
+dsapply_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} apply_key: apply_key_type;
+{ 29} date_from: date_type;
+{ 35} allowance: allowance_type;
+{ 37} allowance_remainder: allowance_type;
+{ 39} date_applied: date_type;
+{ 45} date_granted: date_type;
+{ 51} state: char;
+{ 52} granted_by_head: flag_type;
+{ 53} granted_by_pd: flag_type;
+{ 54} filler: ARRAY [1..15] OF filler_type
+{= 68} END;
+dsprstat_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} username: username_type;
+{ 41} logonid: logonid_type;
+{ 49} jobname: packed_10_type;
+{ 59} filler1: ARRAY [1..2] OF char;
+{ 61} processno: ulong;
+{ 65} start_datetime: date_and_time_type;
+{ 77} end_datetime: date_and_time_type;
+{ 89} print_file: phys_filename_type;
+{ 121} printerid: objectid_type;
+{ 129} jobstatus: char;
+{ 130} filler: ARRAY [1..31] OF unsigned_byte
+{= 160} END;
+dsquery_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} queryid: queryid_type;
+{ 17} sequenceno: short;
+{ 19} query_text: long_text_type;
+{ 49} root_recid: recid_type;
+{ 57} query_definition: ARRAY [1..query_def_len] OF char;
+{ 257} filler: ARRAY [1..44] OF filler_type
+{= 300} END;
+dsqueryt_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} queryid: queryid_type;
+{ 17} query_text: long_text_type;
+{ 47} root_recid: recid_type;
+{ 55} query_definition: ARRAY [1..queryt_def_len] OF char
+{=3054} END;
+dsrcalen_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} rcalenid: rcalenid_type;
+{ 13} rcalen_text: long_text_type;
+{ 43} tariffarea: tariffarea_type;
+{ 47} date: date_type;
+{ 53} date_last_year: date_type;
+{ 59} modified: char;
+{ 60} first_day: flag_type;
+{ 61} filler: ARRAY [1..20] OF filler_type
+{= 80} END;
+dsrcalls_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} mach_job: mach_job_type;
+{ 25} date: date_type;
+{ 31} time_from: mod_type;
+{ 33} no_calls: long;
+{ 37} time_to: mod_type;
+{ 39} average_time: short;
+{ 41} no_lost_calls: long;
+{ 45} filler: ARRAY [1..18] OF filler_type
+{= 62} END;
+dsrooms_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} roomnumber: ARRAY [1..4] OF char;
+{ 13} mpoint: char;
+{ 14} room_text: ARRAY [1..100] OF char;
+{ 114} filler: ARRAY [1..7] OF filler_type
+{= 120} END;
+dsrule_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} rule_key: rule_key_type;
+{ 17} valid_from: date_type;
+{ 23} rule_text: long_text_type;
+{ 53} offduty_code: codeid_type;
+{ 55} auto_time_come: char;
+{ 56} break_code: codeid_type;
+{ 58} auto_time_go: char;
+{ 59} calculation_rule: short;
+{ 61} code_come_auto_time: char;
+{ 62} code_come_warn_flag: flag_type;
+{ 63} code_go_auto_time: char;
+{ 64} code_go_warn_flag: flag_type;
+{ 65} balance_less_employment: char;
+{ 66} allowance_1_absolute: flag_type;
+{ 67} interval_go: short;
+{ 69} balance_priority: ARRAY [1..3] OF char;
+{ 72} round_point_of_time: char;
+{ 73} balance_rounding_tab: ARRAY [1..3] OF balance_rounding_type;
+{ 97} interval_come: short;
+{ 99} round_up_come: short;
+{ 101} round_up_go: short;
+{ 103} late_arrival: short;
+{ 105} early_leave: short;
+{ 107} late_arrive_code: codeid_type;
+{ 109} early_leave_code: codeid_type;
+{ 111} abs_warn_flag: flag_type;
+{ 112} closed_model_flag: flag_type;
+{ 113} time_of_rest: duration_type;
+{ 115} oncall_overtime_min: duration_type;
+{ 117} ondutylen_from_cur_wpat: flag_type;
+{ 118} wizard_mark: char;
+{ 119} useable: flag_type;
+{ 120} filler: ARRAY [1..21] OF filler_type
+{= 140} END;
+dsselopt_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} selopt_key: selopt_key_type;
+{ 11} selopt_text: long_text_type;
+{ 41} filler: ARRAY [1..20] OF char
+{= 60} END;
+dsshift_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} shiftid: shiftid_type;
+{ 13} shift_text: long_text_type;
+{ 43} ruleid: ruleid_type;
+{ 45} shift_unit: char;
+{ 46} alt_wpatid_for_type: flag_type;
+{ 47} count: short;
+{ 49} wpatid_dayno: ARRAY [1..maxdaytypes] OF wpatid_type;
+{ 89} wpatid_daytype: ARRAY [1..maxdaytypes] OF wpatid_type;
+{ 129} alt_wpatid: ARRAY [1..maxdaytypes] OF alt_wpatids_type;
+{ 449} warn_alt_wpatid: ARRAY [1..maxdaytypes] OF alt_wpatids_flag_type;
+{ 529} codeid: ARRAY [1..maxdaytypes] OF codeid_type;
+{ 549} wizard_mark: char;
+{ 550} filler: ARRAY [1..91] OF filler_type
+{= 640} END;
+ttraf_key_type = RECORD
+{ 1} termno: short;
+{ 3} dd: short
+{= 4} END;
+dsttraf_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} ttraf_key: ttraf_key_type;
+{ 13} number_in: long;
+{ 17} error_in: long;
+{ 21} number_out: long;
+{ 25} error_out: long;
+{ 29} filler: ARRAY [1..12] OF char
+{= 40} END;
+dsuser_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} logonid: logonid_type;
+{ 17} emplno: emplno_type;
+{ 27} password: objectid_type;
+{ 35} menuename: objectid_type;
+{ 43} acterm_cat: accat_type;
+{ 51} acmask_cat: accat_type;
+{ 59} acdept_cat: accat_type;
+{ 67} accat_cat: accat_type;
+{ 75} acinc_cat: accat_type;
+{ 83} accode_cat: accat_type;
+{ 91} username: username_type;
+{ 123} password_check_flag: flag_type;
+{ 124} change_old_data_flag: flag_type;
+{ 125} acprog_cat: accat_type;
+{ 133} own_data_perm: char;
+{ 134} video_attributes: video_attributes_type;
+{ 150} aczone_cat: accat_type;
+{ 158} accost_cat: accat_type;
+{ 166} time_manager: flag_type;
+{ 167} accop_cat: accat_type;
+{ 175} accomm_cat: accat_type;
+{ 183} printerid: objectid_type;
+{ 191} password_locked: flag_type;
+{ 192} password_overall: flag_type;
+{ 193} password_timestamp: long;
+{ 197} password_validity: short;
+{ 199} acsel_cat: accat_type;
+{ 207} accost_enter_cat: accat_type;
+{ 215} project_planer: flag_type;
+{ 216} master_proj_perm: char;
+{ 217} emplno_pattern: flag_type;
+{ 218} filler1: ARRAY [1..3] OF filler_type;
+{ 221} special_colors: special_colors_type;
+{ 349} mask_colors: ARRAY [1..20] OF one_masks_colors_type;
+{ 1949} filler: ARRAY [1..12] OF filler_type
+{=1960} END;
+dsusers_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} logonid: logonid_type;
+{ 17} prog_init: ARRAY [1..300] OF unsigned_byte;
+{ 317} emplno: emplno_type;
+{ 327} filler1: ARRAY [1..2] OF filler_type;
+{ 329} dmonth_date: date_type;
+{ 335} dmonth_balanceid: ARRAY [1..4] OF short;
+{ 343} dmonth_printerid: objectid_type;
+{ 351} dmonth_display_daily_incomes: flag_type;
+{ 352} filler2: ARRAY [1..1] OF filler_type;
+{ 353} dpres_date: date_type;
+{ 359} dpres_time: mod_type;
+{ 361} dpres_deptno: costid_type;
+{ 381} dpres_wpatid: ARRAY [1..3] OF wpatid_type;
+{ 393} dpres_select_options: select_options_type;
+{ 409} dpres_printerid: objectid_type;
+{ 417} dpres_selection: char;
+{ 418} dpres_org_type: char;
+{ 419} dpres_codeid: ARRAY [1..5] OF codeid_type;
+{ 429} dabsemp_date: date_type;
+{ 435} dabsemp_no_of_months: short;
+{ 437} dabsemp_fix_code: ARRAY [1..4] OF codeid_type;
+{ 445} dabsemp_printerid: objectid_type;
+{ 453} dabsgrp_date: date_type;
+{ 459} dabsgrp_deptno: deptno_type;
+{ 469} dabsgrp_costid: costid_type;
+{ 489} dabsgrp_select_options: select_options_type;
+{ 505} dabsgrp_printerid: objectid_type;
+{ 513} dabsgrp_mark_warning_flags: flag_type;
+{ 514} dabsgrp_mark_presence_flags: flag_type;
+{ 515} dabsgrp_offduty_char: char;
+{ 516} dabsgrp_codeid: ARRAY [1..5] OF codeid_type;
+{ 526} filler3: ARRAY [1..3] OF filler_type;
+{ 529} dcbal_deptno: deptno_type;
+{ 539} dcbal_balanceid: ARRAY [1..4] OF short;
+{ 547} dcbal_costid: costid_type;
+{ 567} dcbal_select_options: select_options_type;
+{ 583} dcbal_bal_type: char;
+{ 584} dcbal_sort: char;
+{ 585} dcbal_balance_min: long;
+{ 589} dcbal_balance_max: long;
+{ 593} dcbal_target_date: date_type;
+{ 599} dcbal_created_until_date: date_type;
+{ 605} dcbal_printerid: objectid_type;
+{ 613} dcbal_employcat: employcat_type;
+{ 617} dcbal_cols_extension: char;
+{ 618} dcbal_adj_balance_flags: ARRAY [1..4] OF flag_type;
+{ 622} filler4: ARRAY [1..3] OF filler_type;
+{ 625} derrors_date_time: date_and_time_type;
+{ 637} derrors_severity_codes: ARRAY [1..8] OF char;
+{ 645} derrors_jobnames: ARRAY [1..60] OF char;
+{ 705} derrors_username: userid_type;
+{ 721} derrors_no_of_days: short;
+{ 723} derrors_printerid: objectid_type;
+{ 731} filler5: ARRAY [1..2] OF filler_type;
+{ 733} tstat_date: date_type;
+{ 739} tstat_terminalid: objectid_type;
+{ 747} filler6: ARRAY [1..2] OF filler_type;
+{ 749} dwarn_date_time: date_and_time_type;
+{ 761} dwarn_no_of_days: short;
+{ 763} dwarn_warningtype: char;
+{ 764} dwarn_status: char;
+{ 765} dwarn_emplno: emplno_type;
+{ 775} dwarn_deptno: deptno_type;
+{ 785} dwarn_employcat: employcat_type;
+{ 789} dwarn_badgeno: long_badgeno_type;
+{ 809} dwarn_costid: costid_type;
+{ 829} dwarn_select_options: select_options_type;
+{ 845} dwarn_printerid: objectid_type;
+{ 853} demp_printerid: objectid_type;
+{ 861} dcost_date_from: date_type;
+{ 867} dcost_date_to: date_type;
+{ 873} dcost_sum_1: char;
+{ 874} dcost_sum_2: char;
+{ 875} dcost_deptno: deptno_type;
+{ 885} dcost_employcat: employcat_type;
+{ 889} dcost_select_options: select_options_type;
+{ 905} dcost_costid: costid_type;
+{ 925} dcost_income: income_type;
+{ 929} dcost_printerid: objectid_type;
+{ 937} dcost_regular_costid: costid_type;
+{ 957} schedu_deptno: deptno_type;
+{ 967} schedu_start_date: date_type;
+{ 973} schedu_no_of_weeks: short;
+{ 975} schedu_printerid: objectid_type;
+{ 983} schedu_quote: short;
+{ 985} schedu_unit: char;
+{ 986} filler7: ARRAY [1..3] OF filler_type;
+{ 989} daccz_zoneid: short;
+{ 991} daccz_from_date_and_time: date_and_time_type;
+{ 1003} daccz_to_date_and_time: date_and_time_type;
+{ 1015} daccz_deptno: deptno_type;
+{ 1025} daccz_printerid: objectid_type;
+{ 1033} dacce_zoneid: short;
+{ 1035} dacce_from_date_and_time: date_and_time_type;
+{ 1047} dacce_to_date_and_time: date_and_time_type;
+{ 1059} dacce_printerid: objectid_type;
+{ 1067} filler8: ARRAY [1..2] OF filler_type;
+{ 1069} dzone_zoneid: short;
+{ 1071} dzone_start_dat: date_and_time_type;
+{ 1083} dzone_deptno: deptno_type;
+{ 1093} dzone_pres_time: duration_type;
+{ 1095} dzone_duration: duration_type;
+{ 1097} dzone_printerid: objectid_type;
+{ 1105} dvisit_update_table: flag_type;
+{ 1106} filler9: ARRAY [1..3] OF filler_type;
+{ 1109} pstep_orderno: orderno_type;
+{ 1125} pstep_prod_stepno: ARRAY [1..5] OF char;
+{ 1130} pstep_prod_stepno_var: ARRAY [1..5] OF char;
+{ 1135} pstep_formno: ARRAY [1..10] OF char;
+{ 1145} pstep_machid: objectid_type;
+{ 1153} pstep_coll_orderid: orderno_type;
+{ 1169} dmsg_orderno: orderno_type;
+{ 1185} dmsg_date_time: date_and_time_type;
+{ 1197} dmsg_prod_stepno: prod_stepno_type;
+{ 1201} dmsg_prod_stepno_var: prod_stepno_type;
+{ 1205} dmsg_emplno: emplno_type;
+{ 1215} dmsg_machid: objectid_type;
+{ 1223} filler10: ARRAY [1..2] OF filler_type;
+{ 1225} dstatus_orderno: orderno_type;
+{ 1241} dstatus_prod_stepno: prod_stepno_type;
+{ 1245} dstatus_prod_stepno_var: prod_stepno_type;
+{ 1249} dstatus_prod_operationid: prod_operationid_type;
+{ 1253} dstatus_emplno: emplno_type;
+{ 1263} dstatus_date_time: date_and_time_type;
+{ 1275} dstatus_machid: objectid_type;
+{ 1283} dstatus_fault_reasonid: fault_reasonid_type;
+{ 1287} dstatus_status: char;
+{ 1288} filler11: ARRAY [1..1] OF filler_type;
+{ 1289} dswarn_prod_stepno: prod_stepno_type;
+{ 1293} dswarn_prod_stepno_var: prod_stepno_type;
+{ 1297} dswarn_date_time: date_and_time_type;
+{ 1309} dswarn_no_of_days: short;
+{ 1311} dswarn_state: char;
+{ 1312} dswarn_warning_type: char;
+{ 1313} dswarn_emplno: emplno_type;
+{ 1323} dswarn_orderno: orderno_type;
+{ 1339} dswarn_machid: objectid_type;
+{ 1347} dswarn_printerid: objectid_type;
+{ 1355} filler12: ARRAY [1..2] OF filler_type;
+{ 1357} dpsopn_begin_date_time: date_and_time_type;
+{ 1369} dpsopn_end_date_time: date_and_time_type;
+{ 1381} dpsopn_machid: objectid_type;
+{ 1389} dpsopn_prod_operationid: prod_operationid_type;
+{ 1393} dpsopn_only_ready: flag_type;
+{ 1394} dpsopn_printerid: objectid_type;
+{ 1402} filler13: ARRAY [1..3] OF filler_type;
+{ 1405} lpstep_orderno: orderno_type;
+{ 1421} lpstep_machid: objectid_type;
+{ 1429} lpstep_prod_operationid: prod_operationid_type;
+{ 1433} lpstep_begin_date_time: date_and_time_type;
+{ 1445} lpstep_end_date_time: date_and_time_type;
+{ 1457} lpstep_pstep_status: char;
+{ 1458} lpstep_printerid: objectid_type;
+{ 1466} filler14: ARRAY [1..3] OF filler_type;
+{ 1469} dorder_orderno: orderno_type;
+{ 1485} dorder_text: long_text_type;
+{ 1515} dorder_articleno: ARRAY [1..16] OF char;
+{ 1531} dorder_order_state: char;
+{ 1532} dorder_state: char;
+{ 1533} dorder_planned_begin: date_and_time_type;
+{ 1545} dorder_planned_end: date_and_time_type;
+{ 1557} dorder_current_data: char;
+{ 1558} filler15: ARRAY [1..3] OF filler_type;
+{ 1561} dfrsn_from_date: date_type;
+{ 1567} dfrsn_to_date: date_type;
+{ 1573} dfrsn_machid: objectid_type;
+{ 1581} dfrsn_fault_reasonid: fault_reasonid_type;
+{ 1585} dfrsn_emplno: emplno_type;
+{ 1595} dfrsn_sum1: char;
+{ 1596} dfrsn_sum2: char;
+{ 1597} dfrsn_printerid: objectid_type;
+{ 1605} reass_date: date_type;
+{ 1611} reass_printerid: objectid_type;
+{ 1619} filler16: ARRAY [1..2] OF filler_type;
+{ 1621} corder_orderno: orderno_type;
+{ 1637} corder_machid: objectid_type;
+{ 1645} corder_prod_operationid: prod_operationid_type;
+{ 1649} corder_pstep_state: char;
+{ 1650} corder_additional_psteps: char;
+{ 1651} filler17: ARRAY [1..2] OF filler_type;
+{ 1653} ccomp_orderno: orderno_type;
+{ 1669} ccomp_machid: objectid_type;
+{ 1677} ccomp_prod_operationid: prod_operationid_type;
+{ 1681} pwbal_date: date_type;
+{ 1687} pwbal_emplno: emplno_type;
+{ 1697} upstep_orderno: orderno_type;
+{ 1713} upstep_machid: objectid_type;
+{ 1721} upstep_pw_type: piece_work_type_type;
+{ 1725} upstep_state: char;
+{ 1726} upstep_prod_operationid: prod_operationid_type;
+{ 1730} filler18: ARRAY [1..3] OF filler_type;
+{ 1733} ltime_begin_date_time: date_and_time_type;
+{ 1745} ltime_end_date_time: date_and_time_type;
+{ 1757} ltime_badgeno: long_badgeno_type;
+{ 1777} ltime_function_code: unsigned_byte;
+{ 1778} filler19: ARRAY [1..3] OF filler_type;
+{ 1781} anlbal_balanceid: short;
+{ 1783} anlbal_target_date: date_type;
+{ 1789} anlbal_created_until_date: date_type;
+{ 1795} filler20: ARRAY [1..2] OF filler_type;
+{ 1797} cplanm_deptno: deptno_type;
+{ 1807} cplanm_costid: costid_type;
+{ 1827} cplanm_select_options: select_options_type;
+{ 1843} cplanm_state: char;
+{ 1844} cplanm_sort_char: char;
+{ 1845} comm_commtype: commtype_type;
+{ 1849} comm_printerid: objectid_type;
+{ 1857} comm_cover: flag_type;
+{ 1858} filler21: ARRAY [1..3] OF filler_type;
+{ 1861} monov_date: date_type;
+{ 1867} monov_balanceid: ARRAY [1..3] OF short;
+{ 1873} filler22: ARRAY [1..4] OF filler_type;
+{ 1877} dscost_emplno: emplno_type;
+{ 1887} dscost_date_from: date_type;
+{ 1893} dscost_date_to: date_type;
+{ 1899} dscost_deptno: deptno_type;
+{ 1909} dscost_select_options: select_options_type;
+{ 1925} dscost_costid: costid_type;
+{ 1945} dscost_machid: objectid_type;
+{ 1953} dscost_orderno: orderno_type;
+{ 1969} dscost_prod_stepno: ARRAY [1..5] OF char;
+{ 1974} dscost_prod_stepno_var: ARRAY [1..5] OF char;
+{ 1979} dscost_articleno: ARRAY [1..16] OF char;
+{ 1995} dscost_summation1: char;
+{ 1996} dscost_summation2: char;
+{ 1997} dscost_summation3: char;
+{ 1998} dscost_printerid: objectid_type;
+{ 2006} filler23: ARRAY [1..3] OF filler_type;
+{ 2009} pscap_machid: objectid_type;
+{ 2017} pscap_costid: costid_type;
+{ 2037} pscap_date_from: date_type;
+{ 2043} pscap_date_to: date_type;
+{ 2049} pscap_cw: ARRAY [1..2] OF char;
+{ 2051} filler24: ARRAY [1..2] OF filler_type;
+{ 2053} psprod_machid: objectid_type;
+{ 2061} psprod_costid: costid_type;
+{ 2081} psprod_date_from: date_type;
+{ 2087} psprod_date_to: date_type;
+{ 2093} psprod_cw: ARRAY [1..2] OF char;
+{ 2095} pspord_orderno: orderno_type;
+{ 2111} psprod_printerid: objectid_type;
+{ 2119} filler25: ARRAY [1..2] OF filler_type;
+{ 2121} accemp_emplno: emplno_type;
+{ 2131} accemp_zoneid: short;
+{ 2133} accemp_printerid: objectid_type;
+{ 2141} schedu_schedsid: objectid_type;
+{ 2149} schedu_select_options: select_options_type;
+{ 2165} schedu_use_prtempday: flag_type;
+{ 2166} schedu_filter_sort_char1: char;
+{ 2167} schedu_filter_sort_char2: char;
+{ 2168} schedu_filter_sort_char3: char;
+{ 2169} schedu_filter_sort_char4: char;
+{ 2170} schedu_ascid: objectid_type;
+{ 2178} filler26: ARRAY [1..3] OF filler_type;
+{ 2181} plan_printerid: objectid_type;
+{ 2189} stpgm_printerid: objectid_type;
+{ 2197} ppord_printerid: objectid_type;
+{ 2205} pscap_printerid: objectid_type;
+{ 2213} pstruc_projectid: projectid_type;
+{ 2225} pstruc_versionid: versionid_type;
+{ 2229} pstruc_parproid: parproid_type;
+{ 2241} pnet_projectid: projectid_type;
+{ 2253} pnet_versionid: versionid_type;
+{ 2257} pnet_taskid: taskid_type;
+{ 2269} pnet_attributes: attributes_type;
+{ 2365} pnet_rpool_assigned: rpoolid_type;
+{ 2377} pnet_emplno_assigned: emplno_type;
+{ 2387} pnet_processing_rate_min: sreal_type;
+{ 2389} pnet_processing_rate_max: sreal_type;
+{ 2391} filler27: ARRAY [1..2] OF filler_type;
+{ 2393} pbar_projectid: projectid_type;
+{ 2405} pbar_versionid: versionid_type;
+{ 2409} pbar_taskid: taskid_type;
+{ 2421} pbar_attributes: attributes_type;
+{ 2517} pbar_rpool_assigned: rpoolid_type;
+{ 2529} pbar_emplno_assigned: emplno_type;
+{ 2539} pbar_processing_rate_min: sreal_type;
+{ 2541} pbar_processing_rate_max: sreal_type;
+{ 2543} filler28: ARRAY [1..6] OF filler_type;
+{ 2549} res_start_date: date_type;
+{ 2555} res_unitlen: short;
+{ 2557} res_unittype: char;
+{ 2558} res_rpoolid: rpoolid_type;
+{ 2570} res_emplno: emplno_type;
+{ 2580} res_projectid: projectid_type;
+{ 2592} res_versionid: versionid_type;
+{ 2596} filler29: ARRAY [1..7] OF filler_type;
+{ 2603} dpwarn_start_date: date_type;
+{ 2609} dpwarn_start_time: time_type;
+{ 2615} dpwarn_projectid: projectid_type;
+{ 2627} dpwarn_versionid: versionid_type;
+{ 2631} dpwarn_parproid: parproid_type;
+{ 2643} dpwarn_taskid: taskid_type;
+{ 2655} dpwarn_rpoolid: rpoolid_type;
+{ 2667} dpwarn_emplno: emplno_type;
+{ 2677} dpwarn_state: char;
+{ 2678} dpwarn_pmwarn_char: char;
+{ 2679} filler30: ARRAY [1..2] OF filler_type;
+{ 2681} dsplan_printerid: objectid_type;
+{ 2689} dsplan_from: date_type;
+{ 2695} dsplan_to: date_type;
+{ 2701} cplane_outlook: flag_type;
+{ 2702} filler31: ARRAY [1..3] OF filler_type;
+{ 2705} awtime_pm_kontierungen: flag_type;
+{ 2706} filler32: ARRAY [1..3] OF filler_type;
+{ 2709} filler: ARRAY [1..792] OF filler_type
+{=3500} END;
+dsvisit_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} emplno: emplno_type;
+{ 19} surname: surname_type;
+{ 49} firstname: firstname_type;
+{ 69} company: long_text_type;
+{ 99} badgeno: long_badgeno_type;
+{ 119} accesscat: acccatid_type;
+{ 123} filler1: ARRAY [1..2] OF filler_type;
+{ 125} valid_from_date: date_type;
+{ 131} valid_from_time: mod_type;
+{ 133} valid_to_date: date_type;
+{ 139} valid_to_time: mod_type;
+{ 141} carlicid: ARRAY [1..12] OF char;
+{ 153} contact: long_text_type;
+{ 183} pin_code: pin_code_type;
+{ 187} factory: packed_12_type;
+{ 199} filler: ARRAY [1..62] OF filler_type
+{= 260} END;
+warn_log_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} req_code: char;
+{ 10} book_code: char;
+{ 11} emplno: emplno_type;
+{ 21} old_badgeno: badgeno_type;
+{ 31} state: char;
+{ 32} seqno: unsigned_byte;
+{ 33} date_time_written: date_and_time_type;
+{ 45} work_day: date_type;
+{ 51} time: mod_type;
+{ 53} termid: objectid_type;
+{ 61} logonid: logonid_type;
+{ 69} warntype: short;
+{ 71} warnparameter: ARRAY [1..20] OF char;
+{ 91} badgeno: long_badgeno_type;
+{ 111} filler: ARRAY [1..20] OF filler_type
+{= 130} END;
+special_service_type = RECORD
+{ 1} special_code: codeid_type;
+{ 3} from_time: mod_type;
+{ 5} to_time: mod_type
+{= 6} END;
+dswopen_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} wopenid: emplno_day_type;
+{ 25} wpatid: wpatid_type;
+{ 29} ruleid: ruleid_type;
+{ 31} allowances: allowances_type;
+{ 41} daily_codeid: codeid_type;
+{ 43} reass_flag: flag_type;
+{ 44} ondutylen_from_cur_wpat: flag_type;
+{ 45} alt_wpatids_flag: flag_type;
+{ 46} tariffarea: tariffarea_type;
+{ 50} employcat: employcat_type;
+{ 54} breakusage: unsigned_byte;
+{ 55} auto_break_tot_max: allowance_type;
+{ 57} cycle_wpatid: wpatid_type;
+{ 61} original_wpatid: wpatid_type;
+{ 65} costid: costid_type;
+{ 85} special_service: ARRAY [1..3] OF special_service_type;
+{ 103} filler: ARRAY [1..8] OF filler_type
+{= 110} END;
+dswpat_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} wpat_key: wpat_key_type;
+{ 19} valid_from: date_type;
+{ 25} wpat_text: long_text_type;
+{ 55} wpat: ARRAY [1..3] OF RECORD
+{+ 0} time_from: mod_type;
+{+ 2} time_to: mod_type;
+{+ 4} ondutylen: duration_type
+{= 18} END;
+{ 73} freeshift: duration_type;
+{ 75} break_pattern: ARRAY [1..maxbreaks] OF break_pattern_type;
+{ 123} break_tot_min: duration_type;
+{ 125} break_tot_max: duration_type;
+{ 127} break_time: mod_type;
+{ 129} work_min_break: duration_type;
+{ 131} onduty_inc: duration_type;
+{ 133} break_inc: duration_type;
+{ 135} break_percent: short;
+{ 137} break_interval: RECORD
+{+ 0} time_come: mod_type;
+{+ 2} time_go: mod_type
+{= 4} END;
+{ 141} day_allowance: RECORD
+{+ 0} time_from: mod_type;
+{+ 2} time_to: mod_type
+{= 4} END;
+{ 145} daybreak: mod_type;
+{ 147} daybreak_tariff: mod_type;
+{ 149} open_checkout: mod_type;
+{ 151} work_mean_break: duration_type;
+{ 153} break_tot_mean: duration_type;
+{ 155} interval_ind_come: char;
+{ 156} interval_ind_go: char;
+{ 157} charge_break_flag: flag_type;
+{ 158} break_limit_on_worktime: flag_type;
+{ 159} sliding_break: flag_type;
+{ 160} wizard_mark: char;
+{ 161} min_work_length: duration_type;
+{ 163} selid: ARRAY [1..2] OF char;
+{ 165} block_break_time: duration_type;
+{ 167} break_tot_block: duration_type;
+{ 169} useable: flag_type;
+{ 170} filler: ARRAY [1..11] OF filler_type
+{= 180} END;
+placeno_type = ARRAY [1..2] OF char;
+roomnumber_type = ARRAY [1..4] OF char;
+mpoint_type = char;
+jobflag_type = ARRAY [1..3] OF char;
+dswplace_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} emplno: emplno_type;
+{ 19} work_day: date_type;
+{ 25} placeno: placeno_type;
+{ 27} climno: char;
+{ 28} mpoint: char;
+{ 29} jobflag: jobflag_type;
+{ 32} roomnumber: roomnumber_type;
+{ 36} district_payment: ARRAY [1..3] OF char;
+{ 39} pay_method: char;
+{ 40} gedingeno: ARRAY [1..2] OF char;
+{ 42} bpu: char;
+{ 43} worker_rank: ARRAY [1..4] OF char;
+{ 47} journey: char;
+{ 48} bonus1: ARRAY [1..3] OF char;
+{ 51} filler1: ARRAY [1..2] OF filler_type;
+{ 53} amount1: long;
+{ 57} bonus2: ARRAY [1..3] OF char;
+{ 60} filler2: filler_type;
+{ 61} amount2: long;
+{ 65} bonus3: ARRAY [1..3] OF char;
+{ 68} filler3: filler_type;
+{ 69} amount3: long;
+{ 73} Info1: ARRAY [1..10] OF char;
+{ 83} Info2: ARRAY [1..10] OF char;
+{ 93} Info3: ARRAY [1..10] OF char;
+{ 103} Info4: ARRAY [1..10] OF char;
+{ 113} Info5: ARRAY [1..10] OF char
+{= 122} END;
+fmsglog_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} date_time_written: date_and_time_type;
+{ 21} millisec: short;
+{ 23} termid: objectid_type;
+{ 31} termno: short;
+{ 33} badgeno: badgeno_type;
+{ 43} emplno: emplno_type;
+{ 53} filler: ARRAY [1..18] OF unsigned_byte;
+{ 71} data: ARRAY [1..40] OF char
+{= 110} END;
+fmsglog2_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} date_time_written: date_and_time_type;
+{ 21} millisec: short;
+{ 23} termid: objectid_type;
+{ 31} termno: short;
+{ 33} badgeno: long_badgeno_type;
+{ 53} emplno: emplno_type;
+{ 63} filler: ARRAY [1..8] OF filler_type;
+{ 71} data: ARRAY [1..100] OF char
+{= 170} END;
+help_page_line_rec = ARRAY [1..78] OF char;
+help_page_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} chapter: chapter_type;
+{ 19} sequenceno: short;
+{ 21} line_tab: ARRAY [1..18] OF help_page_line_rec
+{=1424} END;
+helptable_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} maskname: objectid_type;
+{ 17} chapter: chapter_type
+{= 26} END;
+spiinf_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} pgmname: packed_10_type;
+{ 19} std_spi: packed_10_type;
+{ 29} subpgm01: packed_10_type;
+{ 39} subpgm02: packed_10_type;
+{ 49} subpgm03: packed_10_type;
+{ 59} subpgm04: packed_10_type;
+{ 69} subpgm05: packed_10_type;
+{ 79} subpgm06: packed_10_type;
+{ 89} subpgm07: packed_10_type;
+{ 99} subpgm08: packed_10_type;
+{ 109} subpgm09: packed_10_type;
+{ 119} subpgm10: packed_10_type;
+{ 129} subpgm11: packed_10_type;
+{ 139} subpgm12: packed_10_type;
+{ 149} subpgm13: packed_10_type;
+{ 159} subpgm14: packed_10_type;
+{ 169} subpgm15: packed_10_type;
+{ 179} subpgm16: packed_10_type;
+{ 189} subpgm17: packed_10_type;
+{ 199} subpgm18: packed_10_type;
+{ 209} subpgm19: packed_10_type;
+{ 219} subpgm20: packed_10_type;
+{ 229} subpgm21: packed_10_type;
+{ 239} subpgm22: packed_10_type;
+{ 249} subpgm23: packed_10_type;
+{ 259} subpgm24: packed_10_type;
+{ 269} subpgm25: packed_10_type;
+{ 279} subpgm26: packed_10_type;
+{ 289} subpgm27: packed_10_type;
+{ 299} subpgm28: packed_10_type;
+{ 309} subpgm29: packed_10_type;
+{ 319} subpgm30: packed_10_type;
+{ 329} subpgm31: packed_10_type;
+{ 339} subpgm32: packed_10_type;
+{ 349} subpgm33: packed_10_type;
+{ 359} subpgm34: packed_10_type;
+{ 369} subpgm35: packed_10_type;
+{ 379} subpgm36: packed_10_type;
+{ 389} subpgm37: packed_10_type;
+{ 399} subpgm38: packed_10_type;
+{ 409} subpgm39: packed_10_type;
+{ 419} subpgm40: packed_10_type;
+{ 429} subpgm41: packed_10_type;
+{ 439} subpgm42: packed_10_type;
+{ 449} subpgm43: packed_10_type;
+{ 459} subpgm44: packed_10_type;
+{ 469} subpgm45: packed_10_type;
+{ 479} subpgm46: packed_10_type;
+{ 489} subpgm47: packed_10_type;
+{ 499} subpgm48: packed_10_type;
+{ 509} subpgm49: packed_10_type;
+{ 519} subpgm50: packed_10_type;
+{ 529} subpgm51: packed_10_type;
+{ 539} subpgm52: packed_10_type;
+{ 549} subpgm53: packed_10_type;
+{ 559} subpgm54: packed_10_type;
+{ 569} subpgm55: packed_10_type;
+{ 579} subpgm56: packed_10_type;
+{ 589} subpgm57: packed_10_type;
+{ 599} subpgm58: packed_10_type;
+{ 609} subpgm59: packed_10_type;
+{ 619} subpgm60: packed_10_type;
+{ 629} subpgm61: packed_10_type;
+{ 639} subpgm62: packed_10_type;
+{ 649} subpgm63: packed_10_type;
+{ 659} subpgm64: packed_10_type;
+{ 669} subpgm65: packed_10_type;
+{ 679} subpgm66: packed_10_type;
+{ 689} subpgm67: packed_10_type;
+{ 699} subpgm68: packed_10_type;
+{ 709} subpgm69: packed_10_type;
+{ 719} subpgm70: packed_10_type;
+{ 729} subpgm71: packed_10_type;
+{ 739} subpgm72: packed_10_type;
+{ 749} subpgm73: packed_10_type;
+{ 759} subpgm74: packed_10_type;
+{ 769} subpgm75: packed_10_type;
+{ 779} subpgm76: packed_10_type;
+{ 789} subpgm77: packed_10_type;
+{ 799} subpgm78: packed_10_type;
+{ 809} subpgm79: packed_10_type;
+{ 819} subpgm80: packed_10_type;
+{ 829} subpgm81: packed_10_type;
+{ 839} subpgm82: packed_10_type;
+{ 849} subpgm83: packed_10_type;
+{ 859} subpgm84: packed_10_type;
+{ 869} subpgm85: packed_10_type;
+{ 879} subpgm86: packed_10_type;
+{ 889} subpgm87: packed_10_type;
+{ 899} subpgm88: packed_10_type;
+{ 909} subpgm89: packed_10_type;
+{ 919} subpgm90: packed_10_type;
+{ 929} subpgm91: packed_10_type;
+{ 939} subpgm92: packed_10_type;
+{ 949} subpgm93: packed_10_type;
+{ 959} subpgm94: packed_10_type;
+{ 969} subpgm95: packed_10_type;
+{ 979} subpgm96: packed_10_type;
+{ 989} subpgm97: packed_10_type;
+{ 999} subpgm98: packed_10_type;
+{ 1009} subpgm99: packed_10_type;
+{ 1019} subpgm100: packed_10_type;
+{ 1029} subpgm101: packed_10_type;
+{ 1039} subpgm102: packed_10_type;
+{ 1049} subpgm103: packed_10_type;
+{ 1059} subpgm104: packed_10_type;
+{ 1069} subpgm105: packed_10_type;
+{ 1079} subpgm106: packed_10_type;
+{ 1089} subpgm107: packed_10_type;
+{ 1099} subpgm108: packed_10_type;
+{ 1109} subpgm109: packed_10_type;
+{ 1119} subpgm110: packed_10_type;
+{ 1129} subpgm111: packed_10_type;
+{ 1139} subpgm112: packed_10_type;
+{ 1149} subpgm113: packed_10_type;
+{ 1159} subpgm114: packed_10_type;
+{ 1169} subpgm115: packed_10_type;
+{ 1179} subpgm116: packed_10_type;
+{ 1189} subpgm117: packed_10_type;
+{ 1199} subpgm118: packed_10_type;
+{ 1209} subpgm119: packed_10_type;
+{ 1219} subpgm120: packed_10_type;
+{ 1229} heapsize_first: long;
+{ 1233} heapsize_max: long;
+{ 1237} stacksize: long;
+{ 1241} cobolcaps: packed_10_type;
+{ 1251} cmdname: packed_10_type;
+{ 1261} originalname: packed_30_type;
+{ 1291} qtcpneeded: flag_type;
+{ 1292} reserved_01: packed_10_type;
+{ 1302} reserved_02: packed_10_type;
+{ 1312} reserved_03: packed_10_type;
+{ 1322} reserved_04: packed_10_type;
+{ 1332} reserved_05: packed_10_type;
+{ 1342} reserved: ARRAY [1..100] OF char
+{=1441} END;
+ipcb_type = RECORD
+{ 1} dsabsfcb: fcb_type;
+{ 21} dsadjustfcb: fcb_type;
+{ 41} dscalenfcb: fcb_type;
+{ 61} dscodefcb: fcb_type;
+{ 81} dsdtimefcb: fcb_type;
+{ 101} dsplanfcb: fcb_type;
+{ 121} dsshiftfcb: fcb_type;
+{ 141} dsvempfcb: fcb_type;
+{ 161} dswopenfcb: fcb_type;
+{ 181} dswpatfcb: fcb_type;
+{ 201} dsrulefcb: fcb_type;
+{ 221} logonid: logonid_type;
+{ 229} dsinstrec: dsinst_rec;
+{ 1379} ask_user: boolean;
+{ 1380} codes_only: boolean;
+{ 1381} is_plan: boolean;
+{ 1382} consider_code_priorities: boolean;
+{ 1383} dsabsrec: dsabs_rec;
+{ 1583} dsabsrec_read: boolean;
+{ 1584} dsabsrec_changed: boolean;
+{ 1585} no_new: short;
+{ 1587} no_changed: short;
+{ 1589} dsvemprec: dsaemp_rec;
+{ 2589} version_number: short
+{=2590} END;
+chosen_day_type = cit_yesterday..cit_today;
+chosen_day_set = SET OF chosen_day_type;
+info_rec_type = (dswopen, dsdtime, dswpat);
+info_rec_set = SET OF info_rec_type;
+common_info_pointer = ^common_info_type;
+common_info_type = RECORD
+{ 1} dswopen_read: boolean;
+{ 2} dsdtime_read: boolean;
+{ 3} dswpat_read: boolean;
+{ 4} write_dswopen: boolean;
+{ 5} org_dswopenrec: dswopen_rec;
+{ 115} dswopenrec: dswopen_rec;
+{ 225} org_dsdtimetrec: dsdtimet_rec;
+{ 725} dsdtimetrec: dsdtimet_rec;
+{ 1225} dswpatrec: dswpat_rec;
+{ 1405} old_no_of_timepairs: short;
+{ 1407} old_no_of_del_timepairs: short;
+{ 1409} current_index: short;
+{ 1411} current_is_coming: boolean;
+{ 1412} alt_wpat_chosen: boolean
+{=1412} END;
+common_info_tab = ARRAY [cit_yesterday..cit_today] OF common_info_pointer;
+vl_dscolsrec_tab_tab_type = RECORD
+{ 1} dscolsrec: dscols_rec;
+{ 137} conv_table_pos: short;
+{ 139} filler: ARRAY [1..2] OF char
+{= 140} END;
+vl_dscolsrec_tab_type = RECORD
+{ 1} cols: ARRAY [1..vl_max_cols] OF vl_dscolsrec_tab_tab_type;
+{ 4481} no_cols: short
+{=4482} END;
+dsdocno_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} emplno: emplno_type;
+{ 19} date_from: date_type;
+{ 25} documentno: long;
+{ 29} codeid: codeid_type;
+{ 31} time_from: mod_type;
+{ 33} time_to: mod_type;
+{ 35} income: income_type;
+{ 39} costid: costid_type;
+{ 59} filler: ARRAY [1..2] OF filler_type
+{= 60} END;
+info_text_type = ARRAY [1..13] OF char;
+sapid_type = RECORD
+{ 1} badgeno: badgeno_type;
+{ 11} valid_from: date_type
+{= 16} END;
+dssap_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} sapid: sapid_type;
+{ 25} valid_to: date_type;
+{ 31} info: ARRAY [1..10] OF info_text_type;
+{ 161} filler: ARRAY [1..30] OF char
+{= 190} END;
+booklog_sap_rec = RECORD
+{ 1} satza: ARRAY [1..3] OF char;
+{ 4} terid: ARRAY [1..4] OF char;
+{ 8} ldate: ARRAY [1..8] OF char;
+{ 16} ltime: ARRAY [1..6] OF char;
+{ 22} erdat: ARRAY [1..8] OF char;
+{ 30} ertim: ARRAY [1..6] OF char;
+{ 36} zausw: ARRAY [1..8] OF char;
+{ 44} abwgr: ARRAY [1..4] OF char;
+{ 48} exlga: ARRAY [1..4] OF char;
+{ 52} hrazl: ARRAY [1..9] OF char;
+{ 61} zeinh: ARRAY [1..3] OF char;
+{ 64} hrbet: ARRAY [1..9] OF char;
+{ 73} cr: char;
+{ 74} lf: char
+{= 74} END;
+lhzzma_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} emplno: emplno_type;
+{ 19} date: date_type;
+{ 25} worked_time: short;
+{ 27} balance_3: short;
+{ 29} balance_9: short;
+{ 31} filler: ARRAY [1..10] OF char
+{= 40} END;
+taris_rec = RECORD
+{ 1} clientno: buffer_type;
+{ 3} termid: objectid_type;
+{ 11} year: packed_2_type;
+{ 13} month: packed_2_type;
+{ 15} day: packed_2_type;
+{ 17} hour: packed_2_type;
+{ 19} minute: packed_2_type;
+{ 21} second: packed_2_type;
+{ 23} badgeno: badgeno_type;
+{ 33} req_code: char;
+{ 34} access_req_code: char;
+{ 35} codeidtype: char;
+{ 36} codeid: codeid_type;
+{ 38} citemno: objectid_type;
+{ 46} amount: packed_11_type;
+{ 57} quantity: packed_6_type;
+{ 63} costid: costid_type;
+{ 83} long_badgeno: long_badgeno_type
+{= 102} END;
+dspntoln_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} physical_key: pntoln_badgeno_type;
+{ 29} logical_key: pntoln_badgeno_type;
+{ 49} key_type: pntoln_key_type;
+{ 50} filler: ARRAY [1..10] OF filler_type
+{= 59} END;
+dsqual_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} qualificationid: qualificationid_type;
+{ 17} qualification_text: long_text_type;
+{ 47} delete_period: short;
+{ 49} qual_refresh: short;
+{ 51} qual_warn: short;
+{ 53} filler: ARRAY [1..18] OF filler_type
+{= 70} END;
+dsable_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} able_key: emplno_qual_type;
+{ 27} first_date: date_type;
+{ 33} last_date: date_type;
+{ 39} no_of_days: short;
+{ 41} no_of_days_corr: short;
+{ 43} filler: ARRAY [1..28] OF char
+{= 70} END;
+dsmdlptp_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} emplno: emplno_type;
+{ 19} badgeno: long_badgeno_type;
+{ 39} code: dsmdlptp_code_type;
+{ 55} filler: ARRAY [1..40] OF filler_type
+{= 94} END;
+dsmdsum_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} code: dsmdsum_code_type;
+{ 281} filler: ARRAY [1..40] OF filler_type
+{= 320} END;
+dscostgr_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} costid_grp: costid_type;
+{ 29} costid_grp_text: long_text_type;
+{ 59} seq_no: short;
+{ 61} costno: costid_type;
+{ 81} projno: costid_type;
+{ 101} cttype: costid_type;
+{ 121} filler: ARRAY [1..20] OF filler_type
+{= 140} END;
+dspmstat_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} wrk_status: wrk_status_type;
+{ 18} status_committed: wrk_status_type;
+{ 27} status_rejected: wrk_status_type;
+{ 36} status_text: long_text_type;
+{ 66} catid: accat_type;
+{ 74} wrk_code: wrk_code_type;
+{ 77} filler: ARRAY [1..24] OF filler_type
+{= 100} END;
+
+
+{pspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspsp}
+ {dbconf.inc}
+mod_objecttype_type = RECORD
+{ 1} moduleid: objectid_type;
+{ 9} objecttype: objecttype_type
+{= 16} END;
+dsfconf_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} fileid: objectid_type;
+{ 17} file_text: long_text_type;
+{ 47} logging_flag: flag_type;
+{ 48} standard_file: flag_type;
+{ 49} maskid: objectid_type;
+{ 57} record_length: short;
+{ 59} fileno: short;
+{ 61} transaction_flag: flag_type;
+{ 62} filler: ARRAY [1..39] OF filler_type
+{= 100} END;
+dspconf_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} programid: objectid_type;
+{ 17} programname: phys_filename_type;
+{ 49} print_file: phys_filename_type;
+{ 81} priority: short;
+{ 83} no_of_parameters: short;
+{ 85} privileged_flag: flag_type;
+{ 86} pconf_text: long_text_type;
+{ 116} filler: ARRAY [1..35] OF unsigned_byte
+{= 150} END;
+parameter_type = RECORD
+{ 1} parm_text: ARRAY [1..16] OF char;
+{ 17} parmname: ARRAY [1..16] OF char;
+{ 33} parmtype: char;
+{ 34} form_flag: flag_type;
+{ 35} minimum: short;
+{ 37} maximum: short;
+{ 39} max_length: short;
+{ 41} max_occurrences: short;
+{ 43} required_flag: flag_type;
+{ 44} parm_default: parm_tab_line_type;
+{ 104} conv_table_name: long_text_type;
+{ 134} filler: ARRAY [1..3] OF filler_type
+{= 136} END;
+dspconfp_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} programid: objectid_type;
+{ 17} sequenceno: short;
+{ 19} parameter: parameter_type;
+{ 155} filler: ARRAY [1..26] OF filler_type
+{= 180} END;
+dspconft_rec = RECORD
+{ 1} dspconfrec: dspconf_rec;
+{ 151} parameter_tab: ARRAY [1..parm_tab_len] OF parameter_type
+{=3414} END;
+dsprconf_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} printerid: objectid_type;
+{ 17} print_queue_name: print_queue_name_type;
+{ 49} printer_text: long_text_type;
+{ 79} printerfile: phys_filename_type;
+{ 111} filler: ARRAY [1..90] OF char
+{= 200} END;
+dstconf_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} termid: objectid_type;
+{ 17} termno: short;
+{ 19} termtype: objecttype_type;
+{ 27} term_code: char;
+{ 28} term_address: objecttype_type;
+{ 36} phys_termtype: objecttype_type;
+{ 44} download_fileid: objectid_type;
+{ 52} moduleid: objectid_type;
+{ 60} filler3: filler_type;
+{ 61} dist_deduct_grp: short;
+{ 63} termname_in: phys_filename_type;
+{ 95} termname_out: phys_filename_type;
+{ 127} filler1: ARRAY [1..1] OF filler_type;
+{ 128} location: long_text_type;
+{ 158} telno: ARRAY [1..16] OF char;
+{ 174} deptno: deptno_type;
+{ 184} user: long_text_type;
+{ 214} termcat: termcat_type;
+{ 222} perm_download: flag_type;
+{ 223} telno_modem: ARRAY [1..14] OF char;
+{ 237} info_path: objectid_type;
+{ 245} entry_pointname: phys_filename_type;
+{ 277} ignore_time: short;
+{ 279} forms_input: flag_type;
+{ 280} printerid: objectid_type;
+{ 288} costid: costid_type;
+{ 308} exit_allowed: flag_type;
+{ 309} tariffarea: tariffarea_type;
+{ 313} life_check_interval: short;
+{ 315} life_check_timeout: short;
+{ 317} time_sync_interval: short;
+{ 319} from_zoneid: short;
+{ 321} to_zoneid: short;
+{ 323} door_open_time: short;
+{ 325} door_signal_time: short;
+{ 327} log_entry: flag_type;
+{ 328} log_exit: flag_type;
+{ 329} log_rejected: flag_type;
+{ 330} count_entry: flag_type;
+{ 331} count_exit: flag_type;
+{ 332} auto_booking: char;
+{ 333} log_storno_entry: flag_type;
+{ 334} log_storno_exit: flag_type;
+{ 335} pin_code: flag_type;
+{ 336} off_line_mode: char;
+{ 337} entry_from_any_zone: flag_type;
+{ 338} filler2: ARRAY [1..11] OF filler_type;
+{ 349} dist_deduct_come: duration_type;
+{ 351} dist_deduct_go: duration_type;
+{ 353} filler: ARRAY [1..8] OF filler_type
+{= 360} END;
+dstmasks_rec = RECORD
+{ 1} rec_header: rec_header_type;
+{ 9} progno: short;
+{ 11} maskname: objectid_type;
+{ 19} masktitle: menue_line_type
+{= 68} END;
+
+
+{pspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspsp}
+ {tsvrmsg.inc}
+ts_msg_header_type = RECORD
+{ 1} byte: buffer_type;
+{ 3} msgno: short;
+{ 5} queue_name: ARRAY [1..1] OF char;
+{ 6} filler: ARRAY [1..1] OF unsigned_byte;
+{ 7} logonid: logonid_type;
+{ 15} sessionid: short;
+{ 17} seqno: long;
+{ 21} reqno: short;
+{ 23} progno: short;
+{ 25} old_key: keydata_type
+{= 84} END;
+line_flags_type = RECORD
+{ 1} selected: char;
+{ 2} attribute: char
+{= 2} END;
+mask_perm_array = ARRAY [1..maxacmasks] OF acmask_perm_type;
+mask_accesses_type = RECORD
+{ 1} catid: accat_type;
+{ 9} default_perm: char;
+{ 10} filler: ARRAY [1..3] OF char;
+{ 13} mask: mask_perm_array
+{= 972} END;
+selopt_perm_array = ARRAY [1..maxacsel] OF acsel_perm_type;
+selopt_accesses_type = RECORD
+{ 1} catid: accat_type;
+{ 9} default_perm: char;
+{ 10} selopt_tab: selopt_perm_array
+{= 153} END;
+common_type = RECORD
+{ 1} menuename: objectid_type;
+{ 9} termno: short;
+{ 11} termname: phys_filename_type;
+{ 43} own_data_perm: char;
+{ 44} default_perm: char;
+{ 45} dept_accesses: dsacdept_rec;
+{ 605} no_dept_exceptions: short;
+{ 607} no_mask_exceptions: short;
+{ 609} mask_accesses: mask_accesses_type;
+{ 1581} dsusersrec: dsusers_rec;
+{ 5081} logonid_emplno: emplno_type;
+{ 5091} logonid_surname: surname_type;
+{ 5121} logonid_firstname: firstname_type;
+{ 5141} logonid_email: email_address_type;
+{ 5173} emplno: emplno_type;
+{ 5183} date: date_type;
+{ 5189} project_planer: flag_type;
+{ 5190} filler1: ARRAY [1..1] OF char;
+{ 5191} alignment1: ARRAY [1..2] OF char;
+{ 5193} mask_colors: ARRAY [1..20] OF one_masks_colors_type;
+{ 6793} special_colors: special_colors_type;
+{ 6921} color_masks: ARRAY [1..20] OF menue_line_type;
+{ 7921} printer_name: objectid_type;
+{ 7929} logonid: logonid_type;
+{ 7937} deptno: deptno_type;
+{ 7947} employcat: employcat_type;
+{ 7951} no_selopt_exceptions: short;
+{ 7953} selopt_accesses: selopt_accesses_type;
+{ 8106} programname: ARRAY [1..20] OF objectid_type
+{=8265} END;
+code_perm_array = ARRAY [1..maxaccodes] OF accode_perm_type;
+code_accesses_type = RECORD
+{ 1} catid: accat_type;
+{ 9} default_perm: char;
+{ 10} code: code_perm_array
+{= 201} END;
+accesses_type = RECORD
+{ 1} logonid: logonid_type;
+{ 9} logonid_emplno: emplno_type;
+{ 19} logonid_surname: surname_type;
+{ 49} logonid_firstname: firstname_type;
+{ 69} logonid_email: email_address_type;
+{ 101} ownid: objectid_type;
+{ 109} own_taskid: short;
+{ 111} own_data_perm: char;
+{ 112} default_perm: char;
+{ 113} time_manager: flag_type;
+{ 114} change_old_data: flag_type;
+{ 115} master_proj_perm: char;
+{ 116} filler1: ARRAY [1..1] OF char;
+{ 117} no_cat_exceptions: short;
+{ 119} cat_accesses: dsaccat_rec;
+{ 299} code_accesses: code_accesses_type;
+{ 500} filler5: ARRAY [1..1] OF char;
+{ 501} no_code_exceptions: short;
+{ 503} comm_accesses: dsaccomm_rec;
+{ 663} no_comm_exceptions: short;
+{ 665} no_cop_exceptions: short;
+{ 667} cop_accesses: dsaccop_rec;
+{ 927} cost_accesses: dsaccost_rec;
+{ 1476} filler2: ARRAY [1..1] OF char;
+{ 1477} no_cost_exceptions: short;
+{ 1479} dept_accesses: dsacdept_rec;
+{ 2039} no_dept_exceptions: short;
+{ 2041} no_inc_exceptions: short;
+{ 2043} inc_accesses: dsacinc_rec;
+{ 2219} filler3: ARRAY [1..2] OF char;
+{ 2221} no_mask_exceptions: short;
+{ 2223} mask_accesses: mask_accesses_type;
+{ 3195} prog_accesses: dsacprog_rec;
+{ 3495} no_prog_exceptions: short;
+{ 3497} no_zone_exceptions: short;
+{ 3499} zone_accesses: dsaczone_rec;
+{ 3739} search_list_acdept: search_list_type;
+{ 3765} search_list_accat: search_list_type;
+{ 3791} search_list_accost: search_list_type;
+{ 3817} search_list_acsel: search_list_type;
+{ 3843} no_selopt_exceptions: short;
+{ 3845} selopt_accesses: selopt_accesses_type;
+{ 3998} filler4: ARRAY [1..1] OF char;
+{ 3999} no_cost_enter_exceptions: short;
+{ 4001} cost_enter_accesses: dsaccost_rec
+{=4549} END;
+ts_req_msg_pointer = ^ts_req_msg_type;
+ts_req_msg_type = RECORD
+{ 1} msg_header: ts_msg_header_type;
+{ 85} indexname: indexname_type;
+{ 117} function_code: ARRAY [1..function_code_len] OF char;
+{ 118} filler: ARRAY [1..15] OF char;
+{ 133} reqdata: buffer_type
+{= 134} END;
+ts_copy_pointer = ^ts_copy_type;
+ts_copy_type = RECORD
+{ 1} old_key: keydata_type;
+{ 61} new_key: keydata_type
+{= 120} END;
+ts_print_pointer = ^ts_print_type;
+ts_print_type = RECORD
+{ 1} byte: buffer_type;
+{ 3} programid: objectid_type;
+{ 11} printerid: objectid_type;
+{ 19} parm_tab: parm_tab_type;
+{ 1459} prstatkey: packed_30_type
+{=1488} END;
+prt_zone_type = short;
+mask_timepair_tab_type = ARRAY [1..64] OF RECORD
+{ 1} timepair: timepair_type;
+{ 15} modify_in: char;
+{ 16} modify_out: char;
+{ 17} time_in_hrec: ARRAY [1..7] OF char;
+{ 24} time_out_hrec: ARRAY [1..7] OF char
+{=1920} END;
+ts_cplan_pointer = ^ts_cplan_type;
+ts_cplan_type = RECORD
+{ 1} calling_client: short;
+{ 3} emplno: emplno_type;
+{ 13} deptno: deptno_type;
+{ 23} costid: costid_type;
+{ 43} select_options: select_options_type;
+{ 59} state: unsigned_byte;
+{ 60} sort_char: char;
+{ 61} indexname: indexname_type;
+{ 93} cur_deptno: deptno_type;
+{ 103} cur_costid: costid_type;
+{ 123} cur_firstname: firstname_type;
+{ 143} cur_surname: surname_type;
+{ 173} cur_emplno: emplno_type;
+{ 183} cur_date: date_type;
+{ 189} cur_date_to: date_type;
+{ 195} cur_time: mod_type;
+{ 197} cur_apptype: short;
+{ 199} last_deptno: deptno_type;
+{ 209} last_costid: costid_type;
+{ 229} emplno_apply_read: emplno_type;
+{ 239} filler: ARRAY [1..2] OF filler_type;
+{ 241} scb: scb_type
+{= 412} END;
+ts_next_page_type = ARRAY [1..8] OF unsigned_byte;
+ts_rpl_msg_pointer = ^ts_rpl_msg_type;
+ts_rpl_msg_type = RECORD
+{ 1} msg_header: ts_msg_header_type;
+{ 85} error_code: code_type;
+{ 89} sys_error: short;
+{ 91} error_index: short;
+{ 93} error_text: error_text_type;
+{ 153} no_of_lines: short;
+{ 155} more_flag: flag_type;
+{ 156} filler: ARRAY [1..1] OF char;
+{ 157} next_page: ts_next_page_type;
+{ 165} rpldata: buffer_type
+{= 166} END;
+ts_rpl_line_pointer = ^ts_rpl_line_type;
+ts_rpl_line_type = RECORD
+{ 1} formatno: long;
+{ 5} line_flags: line_flags_type;
+{ 7} line_data: buffer_type
+{= 8} END;
+ts_cplan_lpt = ^ts_cplan_rpl_line;
+ts_cplan_rpl_line = RECORD
+{ 1} formatno: long;
+{ 5} line_flags: line_flags_type;
+{ 7} emplno: emplno_type;
+{ 17} name: ARRAY [1..15] OF char;
+{ 32} filler: ARRAY [1..3] OF char;
+{ 35} deptno: deptno_type;
+{ 45} plantype: unsigned_byte;
+{ 46} state: char;
+{ 47} date_from: date_type;
+{ 53} date_to: date_type;
+{ 59} days: short;
+{ 61} time: mod_type;
+{ 63} allowance_days: short;
+{ 65} allowance: allowance_type;
+{ 67} allowance_remainder: allowance_type;
+{ 69} date_applied: date_type;
+{ 75} date_granted: date_type;
+{ 81} email_employee: email_address_type
+{= 112} END;
+ts_cplan_rpl_pointer = ^ts_cplan_rpl_type;
+ts_cplan_rpl_type = RECORD
+{ 1} vacation_claim: balance_type;
+{ 5} old_vacation: balance_type;
+{ 9} vacation_taken: balance_type;
+{ 13} vacation_planned: balance_type;
+{ 17} vacation_to_plan: balance_type;
+{ 21} balance1: balance_type;
+{ 25} balance2: balance_type;
+{ 29} balance3: balance_type;
+{ 33} balance_date: date_type;
+{ 39} indexname: indexname_type;
+{ 71} cur_deptno: deptno_type;
+{ 81} cur_costid: costid_type;
+{ 101} cur_firstname: firstname_type;
+{ 121} cur_surname: surname_type;
+{ 151} cur_emplno: emplno_type;
+{ 161} cur_date: date_type;
+{ 167} cur_date_to: date_type;
+{ 173} cur_apptype: short;
+{ 175} cur_time: mod_type;
+{ 177} email_self: email_address_type;
+{ 209} email_manager: email_address_type;
+{ 241} firstname_manager: firstname_type;
+{ 261} surname_manager: surname_type;
+{ 291} emplno_apply_read: emplno_type;
+{ 301} last_deptno: deptno_type;
+{ 311} last_costid: costid_type;
+{ 331} self_inquiry_flag: flag_type;
+{ 332} manager_flag: flag_type;
+{ 333} read_all_flag: flag_type;
+{ 334} low_vacation: flag_type;
+{ 335} scb: scb_type;
+{ 507} alignment1: ARRAY [1..2] OF char;
+{ 509} line_tab: ARRAY [1..cplan_rpl_ct] OF ts_cplan_rpl_line
+{=3532} END;
+ts_cplan_update_pointer = ^ts_cplan_update_type;
+ts_cplan_update_type = RECORD
+{ 1} old_line: ts_cplan_rpl_line;
+{ 113} new_line: ts_cplan_rpl_line;
+{ 225} vacation_claim: balance_type;
+{ 229} old_vacation: balance_type;
+{ 233} vacation_taken: balance_type;
+{ 237} vacation_planned: balance_type;
+{ 241} vacation_to_plan: balance_type;
+{ 245} balance1: balance_type;
+{ 249} balance2: balance_type;
+{ 253} balance3: balance_type;
+{ 257} balance_date: date_type;
+{ 263} calling_client: short;
+{ 265} self_inquiry_flag: flag_type;
+{ 266} update_apply_type: char;
+{ 267} read_new_flag: flag_type;
+{ 268} low_vacation: flag_type
+{= 268} END;
+comm_buffer_conv_pointer = ^comm_buffer_conv_type;
+comm_buffer_conv_type = RECORD
+{ 1} CASE cb_type: long OF
+{+ 4} 1: (byte: buffer_type);
+{+ 4} 2: (buffer: comm_buffer_type);
+{+ 4} 3: (req: ts_req_msg_type;
+{+ 138} alignment1: ARRAY [1..2] OF char);
+{+ 4} 4: (rpl: ts_rpl_msg_type;
+{+ 170} alignment2: ARRAY [1..2] OF char);
+{=4100} END;
+page_pointer = ^page_type;
+page_type = RECORD
+{ 1} prev_page: page_pointer;
+{ 5} next_page: page_pointer;
+{ 9} page: comm_buffer_conv_type
+{=4108} END;
+list_cb_pointer = ^list_cb_type;
+list_cb_type = RECORD
+{ 1} current_line: short;
+{ 3} selected: short;
+{ 5} no_of_lines: short;
+{ 7} max_nol_in_page: short;
+{ 9} first_page: page_pointer;
+{ 13} last_page: page_pointer;
+{ 17} no_of_top_lines: short;
+{ 19} no_of_bottom_lines: short;
+{ 21} const_page: page_pointer;
+{ 25} use_attributes: boolean;
+{ 26} filler1: ARRAY [1..1] OF char;
+{ 27} selected_col: short;
+{ 29} user_cursor: short;
+{ 31} reserved_cursor: short
+{= 32} END;
+
+
+{pspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspsp}
+ {ts_demp-inc}
+ts_demp_pointer = ^ts_demp_type;
+ts_demp_type = RECORD
+{ 1} byte: buffer_type;
+{ 3} emplno: emplno_type;
+{ 13} start_emplno: emplno_type;
+{ 23} deptno: deptno_type;
+{ 33} start_deptno: deptno_type;
+{ 43} surname: surname_type;
+{ 73} start_surname: surname_type;
+{ 103} badgeno: long_badgeno_type;
+{ 123} start_badgeno: long_badgeno_type;
+{ 143} costid: costid_type;
+{ 163} start_costid: costid_type;
+{ 183} select_options: select_options_type;
+{ 199} accesscat: acccatid_type;
+{ 203} employcat: employcat_type;
+{ 207} start_employcat: employcat_type;
+{ 211} jobid: jobid_type;
+{ 219} start_jobid: jobid_type;
+{ 227} machineid: jobid_type;
+{ 235} start_machineid: jobid_type;
+{ 243} adjustcat: adjustcat_type;
+{ 247} tariffarea: tariffarea_type;
+{ 251} cycleid: cycleid_type;
+{ 255} cycle_start: short;
+{ 257} variants: char;
+{ 258} fileid: ARRAY [1..10] OF char;
+{ 268} first_page: flag_type;
+{ 269} date_from: date_type;
+{ 275} date_to: date_type;
+{ 281} start_date: date_type;
+{ 287} is_first_variant: flag_type;
+{ 288} employ_flag: flag_type;
+{ 289} visit_flag: flag_type;
+{ 290} femp_flag: flag_type;
+{ 291} company: long_text_type;
+{ 321} carlicid: ARRAY [1..12] OF char;
+{ 333} factory: packed_12_type;
+{ 345} foreign_clientno: buffer_type;
+{ 347} foreign_emplno: emplno_type;
+{ 357} rpoolid: rpoolid_type;
+{ 369} scb: scb_type
+{= 540} END;
+ts_demp_download_lpt = ^ts_demp_download_line;
+ts_demp_download_line = RECORD
+{ 1} emplno: emplno_type;
+{ 11} clientno: buffer_type;
+{ 13} sign: char;
+{ 14} filler: ARRAY [1..3] OF char
+{= 16} END;
+ts_demp_download_pointer = ^ts_demp_download_type;
+ts_demp_download_type = RECORD
+{ 1} no_of_lines: short;
+{ 3} no_of_ok_lines: short;
+{ 5} more_flag: flag_type;
+{ 6} first_call: flag_type;
+{ 7} filler: ARRAY [1..2] OF char;
+{ 9} line_tab: ARRAY [1..demp_download_ct] OF ts_demp_download_line
+{=3608} END;
+ts_demp_lpt = ^ts_demp_rpl_line;
+ts_demp_rpl_line = RECORD
+{ 1} formatno: long;
+{ 5} line: line_flags_type;
+{ 7} emplno: emplno_type;
+{ 17} pseudo_date: date_type;
+{ 23} deptno: deptno_type;
+{ 33} line_data: ARRAY [1..75] OF char;
+{ 108} sfc_participant: flag_type;
+{ 109} v_valid_from: date_type;
+{ 115} employee: ARRAY [1..34] OF char;
+{ 149} clientno: buffer_type;
+{ 151} sign: char;
+{ 152} position: signed_byte
+{= 152} END;
+ts_demp_rpl_pointer = ^ts_demp_rpl_type;
+ts_demp_rpl_type = RECORD
+{ 1} byte: buffer_type;
+{ 3} last_emplno: emplno_type;
+{ 13} last_deptno: deptno_type;
+{ 23} last_surname: surname_type;
+{ 53} last_badgeno: long_badgeno_type;
+{ 73} last_costid: costid_type;
+{ 93} last_employcat: employcat_type;
+{ 97} last_machineid: jobid_type;
+{ 105} last_jobid: jobid_type;
+{ 113} indexname: indexname_type;
+{ 145} scb: scb_type;
+{ 317} next_date: date_type;
+{ 323} is_first_variant: flag_type;
+{ 324} title1: vl_index_output_line_type;
+{ 399} title2: vl_index_output_line_type;
+{ 474} filler: ARRAY [1..9] OF char;
+{ 483} cols_dinfo_tab: vl_cols_dinfo_type;
+{ 741} vl_rec_type_tab: vl_rec_type_tab_type;
+{ 805} line_tab: ARRAY [1..demp_rpl_ct] OF ts_demp_rpl_line
+{=3540} END;
+
+
+{pspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspsp}
+ get_line_pointer_type = FUNCTION (page: page_pointer; ind: short):
+ ts_rpl_line_pointer;
+ copy_line_to_page_type = PROCEDURE (line: ts_rpl_line_pointer;
+ page: page_pointer; ind: short);
+
+VAR
+{pspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspsp}
+demp_list : list_cb_type;
+message_code : code_type;
+
+FUNCTION get_demp_line (page: page_pointer; line: short): ts_rpl_line_pointer;
+
+{$I pageutlsH.inc}
+
+IMPLEMENTATION
+
+CONST
+ versionno = 230;
+
+{ *********************** init_list *************************************** }
+
+PROCEDURE init_list (VAR list: list_cb_type; max_nol: short) ;
+
+{ initialisiert 'list_cb_type' }
+
+BEGIN WITH list DO BEGIN
+current_line := 1;
+no_of_lines := 0;
+first_page := nil;
+last_page := nil;
+max_nol_in_page := max_nol;
+no_of_top_lines := 0;
+no_of_bottom_lines := 0;
+const_page := nil;
+END; END; { init_list }
+
+{ *********************** dispose_list ************************************ }
+
+PROCEDURE dispose_list (VAR list: list_cb_type) ;
+
+{ gibt den Speicher der Liste frei und initialisiert 'list_cb_type' }
+
+VAR
+ page_temp: page_pointer;
+
+BEGIN WITH list DO BEGIN
+WHILE first_page <> nil DO
+ BEGIN
+ page_temp := first_page;
+ first_page := first_page^.next_page;
+ DISPOSE (page_temp);
+ END;
+WHILE const_page <> nil DO
+ BEGIN
+ page_temp := const_page;
+ const_page := const_page^.next_page;
+ DISPOSE (page_temp);
+ END;
+init_list (list, max_nol_in_page);
+END; END; { dispose_list }
+
+{ *********************** copy_list *************************************** }
+
+PROCEDURE copy_list (source: list_cb_type; VAR dest: list_cb_type) ;
+
+{ erstellt eine identische Kopie der Liste source }
+
+VAR
+ p, source_ptr, dest_ptr: page_pointer;
+
+BEGIN
+
+dispose_list (dest);
+dest := source;
+dest.first_page := nil;
+dest.last_page := nil;
+dest.const_page := nil;
+
+source_ptr := source.first_page;
+dest_ptr := nil;
+WHILE source_ptr <> nil DO
+ BEGIN
+ new (p);
+ IF p = nil THEN
+ EXIT(**); { memory allocation failure }
+ p^.prev_page := dest_ptr;
+ p^.next_page := nil;
+ p^.page := source_ptr^.page;
+ IF dest_ptr = nil THEN
+ dest.first_page := p
+ ELSE
+ dest_ptr^.next_page := p;
+ dest.last_page := p;
+ dest_ptr := p;
+ source_ptr := source_ptr^.next_page;
+ END;
+
+source_ptr := source.const_page;
+dest_ptr := nil;
+WHILE source_ptr <> nil DO
+ BEGIN
+ new (p);
+ IF p = nil THEN
+ EXIT(**); { memory allocation failure }
+ p^.prev_page := dest_ptr;
+ p^.next_page := nil;
+ p^.page := source_ptr^.page;
+ IF dest_ptr = nil THEN
+ dest.const_page := p
+ ELSE
+ dest_ptr^.next_page := p;
+ dest_ptr := p;
+ source_ptr := source_ptr^.next_page;
+ END;
+
+END; { copy_list }
+
+{ ************************ get_line *************************************** }
+
+PROCEDURE get_line (list: list_cb_type; line: short; VAR page: page_pointer;
+ VAR ind: short) ;
+
+{ setzt page/ind auf Zeile Nummer 'line' (fortlaufend) }
+
+BEGIN
+page := list.first_page;
+ind := line;
+IF line < 1 THEN
+ page := nil;
+WHILE page <> nil DO
+ BEGIN
+ IF ind <= page^.page.rpl.no_of_lines THEN
+ EXIT(**);
+ ind := ind - page^.page.rpl.no_of_lines;
+ page := page^.next_page;
+ END;
+END; { get_line }
+
+{ ************************ get_const_line ********************************* }
+
+PROCEDURE get_const_line (list: list_cb_type; line: short; VAR page: page_pointer;
+ VAR ind: short) ;
+
+{ setzt page/ind auf Zeile Nummer 'line' (fortlaufend) in den festen Zeilen }
+
+BEGIN
+page := list.const_page;
+ind := line;
+IF line < 1 THEN
+ page := nil;
+WHILE page <> nil DO
+ BEGIN
+ IF ind <= page^.page.rpl.no_of_lines THEN
+ EXIT(**);
+ ind := ind - page^.page.rpl.no_of_lines;
+ page := page^.next_page;
+ END;
+END; { get_const_line }
+
+{ ************************ get_next_line ********************************** }
+
+PROCEDURE get_next_line (list: list_cb_type; VAR page: page_pointer;
+ VAR ind: short) ;
+
+{ holt den Nachfolger von page/ind }
+{ Parameter 'list' obsolete }
+
+VAR
+ cur_last_line: short;
+
+BEGIN
+IF page = nil THEN
+ EXIT(**);
+ind := ind + 1;
+cur_last_line := page^.page.rpl.no_of_lines;
+WHILE (page <> nil) AND (ind > cur_last_line) DO
+ BEGIN
+ page := page^.next_page;
+ ind := 1;
+ IF page <> nil THEN
+ cur_last_line := page^.page.rpl.no_of_lines;
+ END;
+END; { get_next_line }
+
+{ ************************ get_prev_line ********************************** }
+
+PROCEDURE get_prev_line (list: list_cb_type; VAR page: page_pointer;
+ VAR ind: short) ;
+
+{ holt den Vorgaenger von page/ind }
+{ Parameter 'list' obsolete }
+
+BEGIN
+IF page = nil THEN
+ EXIT(**);
+ind := ind - 1;
+WHILE (page <> nil) AND (ind < 1) DO
+ BEGIN
+ page := page^.prev_page;
+ IF page <> nil THEN
+ ind := page^.page.rpl.no_of_lines;
+ END;
+END; { get_prev_line }
+
+{ ************************ get_next_visible_line ************************** }
+
+PROCEDURE get_next_visible_line (list: list_cb_type;
+ VAR page: page_pointer; VAR ind: short; VAR line: short;
+ get_line_pointer: get_line_pointer_type) ;
+
+{ holt den naechsten sichtbaren Nachfolger von page/ind;
+ erhoeht 'line' um die bis dahin ueberlesenen versteckten Zeilen }
+
+VAR
+ attribute: char;
+ selection: char;
+
+BEGIN
+REPEAT
+ get_next_line (list, page, ind);
+ get_line_flags (page, ind, selection, attribute, get_line_pointer);
+ IF attribute = attribute_hide THEN
+ line := line + 1;
+ UNTIL (page = nil) OR (attribute <> attribute_hide);
+END; { get_next_visible_line }
+
+
+{ ************************ get_first_visible_line ************************** }
+PROCEDURE get_first_visible_line (list: list_cb_type;
+ VAR cur: short; VAR page: page_pointer; VAR ind: short;
+ VAR line: short; get_line_pointer: get_line_pointer_type);
+
+
+VAR
+ attribute: char;
+ selection: char;
+ hidden: short;
+
+BEGIN
+hidden := 0;
+get_line (list, cur, page, ind);
+get_line_flags (page, ind, selection, attribute, get_line_pointer);
+IF attribute = attribute_hide THEN
+ BEGIN
+ hidden := 1;
+ get_next_visible_line (list, page, ind, hidden, get_line_pointer);
+ END;
+line := line + hidden;
+cur := cur + hidden;
+END;
+
+
+{ ************************ get_prev_visible_line ************************** }
+
+PROCEDURE get_prev_visible_line (list: list_cb_type;
+ VAR page: page_pointer; VAR ind: short; VAR line: short;
+ get_line_pointer: get_line_pointer_type) ;
+
+{ holt den naechsten sichtbaren Vorgaenger von page/ind;
+ erniedrigt 'line' um die bis dahin ueberlesenen versteckten Zeilen }
+
+VAR
+ attribute: char;
+ selection: char;
+
+BEGIN
+REPEAT
+ get_prev_line (list, page, ind);
+ get_line_flags (page, ind, selection, attribute, get_line_pointer);
+ IF attribute = attribute_hide THEN
+ line := line - 1;
+ UNTIL (page = nil) OR (attribute <> attribute_hide);
+END; { get_prev_visible_line }
+
+{ ************************* append_page *********************************** }
+
+PROCEDURE append_page (VAR list: list_cb_type;
+ buffer_ptr: ts_rpl_msg_pointer; to_page: page_pointer) ;
+
+{ haengt die Reply 'buffer_ptr' als Seite an 'to_page' an }
+
+VAR
+ p: page_pointer;
+
+BEGIN
+NEW (p);
+IF p = nil THEN
+ EXIT(**); { memory allocation failure }
+MOVE (buffer_ptr^.msg_header.byte[1], p^.page.byte[1], comm_buffer_len);
+list.no_of_lines := list.no_of_lines + buffer_ptr^.no_of_lines;
+
+IF to_page = nil THEN
+ BEGIN
+ p^.prev_page := nil;
+ p^.next_page := nil;
+ END
+ELSE
+ BEGIN
+ p^.prev_page := to_page;
+ p^.next_page := to_page^.next_page;
+ to_page^.next_page := p;
+ IF p^.next_page <> nil THEN
+ p^.next_page^.prev_page := p;
+ END;
+
+IF list.first_page = nil THEN
+ BEGIN
+ list.first_page := p;
+ list.last_page := p;
+ END
+ELSE
+ IF list.last_page = to_page THEN
+ list.last_page := p;
+END; { append_page }
+
+{ ************************* append_const_page ***************************** }
+
+PROCEDURE append_const_page (VAR list: list_cb_type;
+ buffer_ptr: ts_rpl_msg_pointer; to_page: page_pointer) ;
+
+{ haengt die Reply 'buffer_ptr' als Seite an 'to_page' der festen Zeilen an }
+
+VAR
+ p: page_pointer;
+
+BEGIN
+NEW (p);
+IF p = nil THEN
+ EXIT(**); { memory allocation failure }
+MOVE (buffer_ptr^.msg_header.byte[1], p^.page.byte[1], comm_buffer_len);
+list.no_of_bottom_lines := list.no_of_bottom_lines + buffer_ptr^.no_of_lines;
+
+IF to_page = nil THEN
+ BEGIN
+ p^.prev_page := nil;
+ p^.next_page := nil;
+ END
+ELSE
+ BEGIN
+ p^.prev_page := to_page;
+ p^.next_page := to_page^.next_page;
+ to_page^.next_page := p;
+ IF p^.next_page <> nil THEN
+ p^.next_page^.prev_page := p;
+ END;
+
+IF list.const_page = nil THEN
+ BEGIN
+ list.const_page := p;
+ list.const_page := p;
+ END;
+END; { append_const_page }
+
+{ ************************* create_const_page ***************************** }
+
+PROCEDURE create_const_page (VAR list: list_cb_type; notl, nobl: short;
+ buffer_ptr: ts_rpl_msg_pointer) ;
+
+{ erzeugt die Seite fuer Anzeige konstanter Zeilen in der display_logic;
+ die Seite wird mit 'notl' (no_of_top_lines), 'nobl' (no_of_bottom_lines)
+ und 'buffer_ptr' initialisiert; eine Aufruf mit 0,0,nil ist erlaubt }
+
+BEGIN
+{ erzeuge konstante Seite }
+IF list.const_page <> nil THEN
+ EXIT(**);
+NEW (list.const_page);
+IF list.const_page = nil THEN
+ EXIT(**); { memory allocation failure }
+
+{ fuelle Seite }
+IF buffer_ptr <> nil THEN
+ MOVE (buffer_ptr^.msg_header.byte[1], list.const_page^.page.byte[1],
+ comm_buffer_len);
+list.const_page^.prev_page := nil;
+list.const_page^.next_page := nil;
+list.no_of_top_lines := notl;
+list.no_of_bottom_lines := nobl;
+END; { create_const_page }
+
+{ ************************* more ****************************************** }
+
+FUNCTION more (list: list_cb_type): boolean ;
+
+{ gibt das more_flag der Liste zurueck }
+
+BEGIN
+IF list.last_page = nil THEN
+ more := false
+ELSE
+ more := (list.last_page^.page.rpl.more_flag = flag_on);
+END; { more }
+
+{ ************************* nol_in_page *********************************** }
+
+FUNCTION nol_in_page (page: page_pointer): short ;
+
+{ no of lines in page }
+
+BEGIN
+IF page = nil THEN
+ nol_in_page := 0
+ELSE
+ nol_in_page := page^.page.rpl.no_of_lines;
+END; { nol_in_page }
+
+{ ************************* set_nol_in_list ******************************* }
+
+PROCEDURE set_nol_in_page (page: page_pointer; nol: short) ;
+
+{ Setze 'no of lines in page' auf einen neuen Wert }
+
+BEGIN
+IF page <> nil THEN
+ page^.page.rpl.no_of_lines := nol;
+END; { set_nol_in_page }
+
+{ ************************* change_line *********************************** }
+
+PROCEDURE change_line (VAR list: list_cb_type; mode: char;
+ lpt: ts_rpl_line_pointer; dest_page: page_pointer; dest_ind: short;
+ get_line_pointer: get_line_pointer_type;
+ copy_line_to_page: copy_line_to_page_type
+ ) ;
+
+{ Kopieren, Loeschen und Einfuegen einer Zeile in eine Seite:
+ Kopieren : kopiere lpt nach dest
+ change_line (list, change_copy, $ADDR (line), dest_page, dest_ind);
+ Loeschen : loesche dest
+ change_line (list, change_delete, nil, dest_page, dest_ind);
+ Einfuegen: fuege lpt vor dest ein
+ change_line (list, change_insert, $ADDR (line), dest_page, dest_ind); }
+
+VAR
+ i: short;
+ nol : short;
+ buffer: comm_buffer_conv_type;
+
+BEGIN
+
+CASE mode OF
+
+ change_delete:
+ { loescht eine Zeile }
+ BEGIN
+ FOR i := dest_ind + 1 TO nol_in_page (dest_page) DO
+ copy_line_to_page (get_line_pointer (dest_page, i), dest_page, i - 1);
+ list.no_of_lines := list.no_of_lines - 1;
+ set_nol_in_page (dest_page, nol_in_page (dest_page) - 1);
+ END;
+
+ change_insert:
+ { fuegt eine Zeile vor 'dest' ein;
+ falls die Zeile auf der geforderten Seite keinen Platz hat, wird
+ eine neue Seite eingefuegt }
+ BEGIN
+ IF dest_page = nil THEN
+ IF (list.first_page <> nil) AND (list.no_of_lines = 0) THEN
+ BEGIN
+ { Liste enthaelt nur leere Seiten }
+ dest_page := list.first_page;
+ dest_ind := 1;
+ END
+ ELSE
+ BEGIN
+ { die angesprochene Seite existiert nicht: fuege leere Seite an;
+ falls bereits eine existiert, dann verwende diese bereits
+ initialisierte Seite }
+ IF list.first_page <> nil THEN
+ buffer.buffer := list.first_page^.page.buffer;
+ buffer.rpl.no_of_lines := 0;
+ buffer.rpl.more_flag := flag_off;
+ append_page (list, @buffer.rpl , list.last_page);
+ dest_page := list.last_page;
+ dest_ind := 1;
+ IF dest_page = nil THEN
+ EXIT(**);
+ END;
+
+ IF nol_in_page (dest_page) = list.max_nol_in_page THEN
+ { es musz eine neue Seite eingefuegt werden }
+ BEGIN
+ nol := list.no_of_lines; { merke Anzahl Zeilen }
+
+ { dupliziere dest_page und fuege sie hinter dest_page ein }
+ append_page (list, @dest_page^.page.rpl , dest_page);
+
+ { ueberschreibe dest_ind mit neuer Zeile }
+ copy_line_to_page (lpt, dest_page, dest_ind);
+
+ { loesche alle weiteren Zeilen in dieser Seite }
+ set_nol_in_page (dest_page, dest_ind);
+
+ { loesche die Zeilen 1 bis dest_ind - 1 in zweiter Seite }
+ FOR i := 1 TO dest_ind - 1 DO
+ change_line (list, change_delete, nil, dest_page^.next_page, 1,
+ get_line_pointer, copy_line_to_page);
+
+ list.no_of_lines := nol + 1; { restauriere Anzahl Zeilen }
+ END
+ ELSE
+ BEGIN
+ { verschiebe nachfolgende Zeilen }
+ FOR i := nol_in_page (dest_page) DOWNTO dest_ind DO
+ copy_line_to_page (get_line_pointer (dest_page, i), dest_page, i + 1);
+
+ { kopiere Zeile in freigewordenen Platz }
+ copy_line_to_page (lpt, dest_page, dest_ind);
+
+ { erhoehe Anzahl Zeilen }
+ list.no_of_lines := list.no_of_lines + 1;
+ set_nol_in_page (dest_page, nol_in_page (dest_page) + 1);
+ END;
+ END;
+
+ change_copy:
+ { kopiert die Zeile lpt nach dest }
+ copy_line_to_page (lpt, dest_page, dest_ind);
+
+ ELSE(**)
+ END;
+
+END; { change_line }
+
+{ ************************ get_last_const_page **************************** }
+
+FUNCTION get_last_const_page (list: list_cb_type): page_pointer;
+
+{ holt letzte Seite in den 'festen' Zeilen }
+
+VAR
+ page: page_pointer;
+
+BEGIN
+page := list.const_page;
+IF page <> nil THEN
+ WHILE page^.next_page <> nil DO
+ page := page^.next_page;
+get_last_const_page := page;
+END; { get_last_const_page }
+
+{ ************************* change_const_line ***************************** }
+
+PROCEDURE change_const_line (VAR list: list_cb_type; mode: char;
+ lpt: ts_rpl_line_pointer; dest_page: page_pointer; dest_ind: short;
+ get_line_pointer: get_line_pointer_type;
+ copy_line_to_page: copy_line_to_page_type
+ ) ;
+
+{ Version fuer 'feste Zeilen' }
+
+{ Kopieren, Loeschen und Einfuegen einer Zeile in eine Seite:
+ Kopieren : kopiere lpt nach dest
+ change_line (list, change_copy, $ADDR (line), dest_page, dest_ind);
+ Loeschen : loesche dest
+ change_line (list, change_delete, nil, dest_page, dest_ind);
+ Einfuegen: fuege lpt vor dest ein
+ change_line (list, change_insert, $ADDR (line), dest_page, dest_ind); }
+
+VAR
+ i: short;
+ nol : short;
+ buffer: comm_buffer_conv_type;
+
+BEGIN
+
+CASE mode OF
+
+ change_delete:
+ { loescht eine Zeile }
+ BEGIN
+ FOR i := dest_ind + 1 TO nol_in_page (dest_page) DO
+ copy_line_to_page (get_line_pointer (dest_page, i), dest_page, i - 1);
+ list.no_of_bottom_lines := list.no_of_bottom_lines - 1;
+ set_nol_in_page (dest_page, nol_in_page (dest_page) - 1);
+ END;
+
+ change_insert:
+ { fuegt eine Zeile vor 'dest' ein;
+ falls die Zeile auf der geforderten Seite keinen Platz hat, wird
+ eine neue Seite eingefuegt }
+ BEGIN
+ IF dest_page = nil THEN
+ IF (list.const_page <> nil) AND (list.no_of_bottom_lines = 0) THEN
+ BEGIN
+ { Liste enthaelt nur leere Seiten }
+ dest_page := list.const_page;
+ dest_ind := 1;
+ END
+ ELSE
+ BEGIN
+ { die angesprochene Seite existiert nicht: fuege leere Seite an;
+ falls bereits eine existiert, dann verwende diese bereits
+ initialisierte Seite }
+ IF list.const_page <> nil THEN
+ buffer.buffer := list.const_page^.page.buffer;
+ buffer.rpl.no_of_lines := 0;
+ buffer.rpl.more_flag := flag_off;
+ append_const_page (list, @buffer.rpl , get_last_const_page (list));
+ dest_page := get_last_const_page (list);
+ dest_ind := 1;
+ IF dest_page = nil THEN
+ EXIT(**);
+ END;
+
+ IF nol_in_page (dest_page) = list.max_nol_in_page THEN
+ { es musz eine neue Seite eingefuegt werden }
+ BEGIN
+ nol := list.no_of_bottom_lines; { merke Anzahl Zeilen }
+
+ { dupliziere dest_page und fuege sie hinter dest_page ein }
+ append_const_page (list, @dest_page^.page.rpl , dest_page);
+
+ { ueberschreibe dest_ind mit neuer Zeile }
+ copy_line_to_page (lpt, dest_page, dest_ind);
+
+ { loesche alle weiteren Zeilen in dieser Seite }
+ set_nol_in_page (dest_page, dest_ind);
+
+ { loesche die Zeilen 1 bis dest_ind - 1 in zweiter Seite }
+ FOR i := 1 TO dest_ind - 1 DO
+ change_const_line (list, change_delete, nil, dest_page^.next_page, 1,
+ get_line_pointer, copy_line_to_page);
+
+ list.no_of_bottom_lines := nol + 1; { restauriere Anzahl Zeilen }
+ END
+ ELSE
+ BEGIN
+ { verschiebe nachfolgende Zeilen }
+ FOR i := nol_in_page (dest_page) DOWNTO dest_ind DO
+ copy_line_to_page (get_line_pointer (dest_page, i), dest_page, i + 1);
+
+ { kopiere Zeile in freigewordenen Platz }
+ copy_line_to_page (lpt, dest_page, dest_ind);
+
+ { erhoehe Anzahl Zeilen }
+ list.no_of_bottom_lines := list.no_of_bottom_lines + 1;
+ set_nol_in_page (dest_page, nol_in_page (dest_page) + 1);
+ END;
+ END;
+
+ change_copy:
+ { kopiert die Zeile lpt nach dest }
+ copy_line_to_page (lpt, dest_page, dest_ind);
+
+ ELSE(**)
+ END;
+
+END; { change_const_line }
+
+{ ************************* set_line_flags ******************************** }
+
+PROCEDURE set_line_flags
+ (page: page_pointer; ind: short; select, attribute: char;
+ get_line_pointer: get_line_pointer_type) ;
+
+{ Setze Zeilenattribute der Zeile page/ind auf select/attribute:
+ select = ' ' keine Aenderung
+ select = invert_flag, dann invertiere 'selected'
+ attribute = ' ' keine Aenderung }
+
+VAR
+ lpt: ts_rpl_line_pointer;
+
+BEGIN
+lpt := get_line_pointer (page, ind);
+IF lpt <> nil THEN
+ BEGIN
+ IF select <> ' ' THEN
+ IF select = invert_flag THEN
+ IF (lpt^.line_flags.selected = flag_on) OR
+ (lpt^.line_flags.selected = action_select) OR
+ (lpt^.line_flags.selected = chr(1)) THEN
+ lpt^.line_flags.selected := flag_off
+ ELSE
+ lpt^.line_flags.selected := flag_on
+ ELSE
+ lpt^.line_flags.selected := select;
+ IF attribute <> ' ' THEN
+ lpt^.line_flags.attribute := attribute;
+ END;
+END; { set_line_flags }
+
+{ ************************* get_line_flags ******************************** }
+
+PROCEDURE get_line_flags
+ (page: page_pointer; ind: short; VAR select, attribute: char;
+ get_line_pointer: get_line_pointer_type) ;
+
+{ holt die Attribute der Zeile }
+
+VAR
+ lpt: ts_rpl_line_pointer;
+
+BEGIN
+lpt := get_line_pointer (page, ind);
+IF lpt = nil THEN
+ BEGIN
+ select := flag_off;
+ attribute := attribute_normal;
+ END
+ELSE
+ BEGIN
+ select := lpt^.line_flags.selected;
+ attribute := lpt^.line_flags.attribute;
+ END;
+END; { get_line_flags }
+
+{ ************************* is_selected *********************************** }
+
+FUNCTION is_selected
+ (list: list_cb_type; page: page_pointer; ind: short;
+ get_line_pointer: get_line_pointer_type): boolean ;
+
+{ prueft auf Selektion einer Zeile:
+ eine Zeile ist selektiert, wenn
+ 'line_flags.selected' = flag_on oder action_selected oder chr(1)
+ oder 'liste.selected' auf dieser Zeile steht }
+
+VAR
+ selpage : page_pointer;
+ selind : short;
+ selected : char;
+ attribute: char;
+
+BEGIN
+get_line (list, list.selected, selpage, selind);
+IF (page = nil) OR (selpage = nil) THEN
+ BEGIN
+ is_selected := false;
+ EXIT(**)
+ END;
+IF (page = selpage) AND (ind = selind) THEN
+ is_selected := true
+ELSE
+ BEGIN
+ get_line_flags (page, ind, selected, attribute, get_line_pointer);
+ is_selected := (selected = flag_on) OR (selected = action_select) OR
+ (selected = chr(1));
+ END;
+END; { is_selected }
+
+{ ************************* set_list_line_flags *************************** }
+
+PROCEDURE set_list_line_flags
+ (VAR list: list_cb_type; select, attribute: char;
+ get_line_pointer: get_line_pointer_type
+ ) ;
+
+{ Setze alle Zeilenattribute der Liste auf die neuen Werte
+ (siehe 'set_line_flags') }
+
+VAR
+ page: page_pointer;
+ ind : short;
+
+BEGIN
+page := list.first_page;
+ind := 1;
+WHILE page <> nil DO
+ BEGIN
+ set_line_flags (page, ind, select, attribute, get_line_pointer);
+ get_next_line (list, page, ind);
+ END;
+END; { set_list_line_flags }
+
+{ ************************* get_next_selected_line ************************ }
+
+PROCEDURE get_next_selected_line
+ (VAR list: list_cb_type; VAR page: page_pointer; VAR ind: short;
+ get_line_pointer: get_line_pointer_type) ;
+
+{ holt den naechsten selektierten Nachfolger von page/ind }
+
+VAR
+ selected : char;
+ attribute: char;
+
+BEGIN
+REPEAT
+ get_next_line (list, page, ind);
+ list.selected := list.selected + 1;
+ IF page = nil THEN
+ EXIT(**);
+ get_line_flags (page, ind, selected, attribute, get_line_pointer);
+ IF (selected = flag_on) OR (selected = action_select) OR (selected = chr(1)) THEN
+ EXIT(**);
+ UNTIL false;
+END; { get_next_selected_line }
+
+{ ************************* get_prev_selected_line ************************ }
+
+PROCEDURE get_prev_selected_line
+ (VAR list: list_cb_type; VAR page: page_pointer; VAR ind: short;
+ get_line_pointer: get_line_pointer_type) ;
+
+{ holt den naechsten selektierten Vorgaenger von page/ind }
+
+VAR
+ selected : char;
+ attribute: char;
+
+BEGIN
+REPEAT
+ get_prev_line (list, page, ind);
+ list.selected := list.selected - 1;
+ IF page = nil THEN
+ EXIT(**);
+ get_line_flags (page, ind, selected, attribute, get_line_pointer);
+ IF (selected = flag_on) OR (selected = action_select) OR (selected = chr(1)) THEN
+ EXIT(**);
+ UNTIL false;
+END; { get_prev_selected_line }
+
+{ ************************* get_first_selected_line_m *********************** }
+
+PROCEDURE get_first_selected_line_m
+ (VAR list: list_cb_type; VAR page: page_pointer; VAR ind: short;
+ get_line_pointer: get_line_pointer_type) ;
+
+{ holt die erste selektierte Zeile der Liste }
+
+VAR
+ selected : char;
+ attribute: char;
+
+BEGIN
+list.selected := 1;
+get_line (list, 1, page, ind);
+get_line_flags (page, ind, selected, attribute, get_line_pointer);
+IF (selected = flag_on) OR (selected = action_select) OR (selected = chr(1)) THEN
+ EXIT(**);
+get_next_selected_line (list, page, ind, get_line_pointer);
+END; { get_first_selected_line_m }
+
+{ ************************* get_first_selected_line ************************ }
+
+PROCEDURE get_first_selected_line
+ (VAR list: list_cb_type; VAR page: page_pointer; VAR ind: short;
+ get_line_pointer: get_line_pointer_type) ;
+
+{ holt die erste selektierte Zeile der Liste }
+
+BEGIN
+get_line (list, 1, page, ind);
+IF page = nil THEN
+ EXIT(**);
+IF is_selected (list, page, ind, get_line_pointer) THEN
+ EXIT(**);
+list.selected := 1;
+get_next_selected_line (list, page, ind, get_line_pointer);
+END; { get_first_selected_line }
+
+{ ************************* get_selected_emplno *************************** }
+
+CONST
+ cur_emplno = 1;
+ next_emplno = 2;
+ prev_emplno = 3;
+
+TYPE
+{hie war $I tsdemp.inc}
+
+ conv_demp_type = RECORD
+ CASE ptr_type: integer OF
+ 1: (buffer_ptr: buffer_pointer);
+ 2: (req_ptr : ts_demp_pointer);
+ 3: (rpl_ptr : ts_demp_rpl_pointer);
+ END;
+ lpt_demp_ptr_type = RECORD
+ CASE ptr_type: integer OF
+ 1: (lpt : ts_demp_lpt);
+ 2: (rpl_lpt : ts_rpl_line_pointer);
+ END;
+
+FUNCTION get_demp_line (page: page_pointer; line: short): ts_rpl_line_pointer;
+
+VAR
+ c1: conv_demp_type;
+ c2: lpt_demp_ptr_type;
+
+BEGIN
+get_demp_line := nil;
+IF (line < 1) OR (line > demp_rpl_ct) THEN
+ page := nil;
+IF page = nil THEN
+ EXIT(**);
+c1.buffer_ptr := @page^.page.rpl.rpldata ;
+c2.lpt := @c1.rpl_ptr^.line_tab(.line.) ;
+get_demp_line := c2.rpl_lpt;
+END; { get_demp_line }
+
+FUNCTION get_selected_emplno (which_emplno: short): string;
+
+VAR
+ c1: lpt_demp_ptr_type;
+ page: page_pointer;
+ line: short;
+ old_selected : short;
+
+BEGIN
+
+get_selected_emplno := '';
+old_selected := demp_list.selected;
+
+get_line (demp_list, demp_list.selected, page, line);
+IF page = nil THEN
+ BEGIN
+ message_code := '6601';
+ EXIT(**)
+ END;
+
+IF which_emplno = next_emplno THEN
+ get_next_selected_line (demp_list, page, line, get_demp_line);
+IF which_emplno = prev_emplno THEN
+ get_prev_selected_line (demp_list, page, line, get_demp_line);
+
+IF page = nil THEN
+ BEGIN
+ demp_list.selected := old_selected;
+ IF which_emplno = prev_emplno THEN
+ message_code := '6602';
+ IF which_emplno = next_emplno THEN
+ message_code := '6603';
+ END
+ELSE
+ BEGIN
+ c1.rpl_lpt := get_demp_line (page, line);
+
+{pspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspspsp}
+{ get_selected_emplno := STRI (@c1.lpt^.emplno, SizeOf (c1.lpt^.emplno)) ;}
+ END;
+
+END; { get_selected_emplno }
+
+{ ************************* get_next_selected_emplno *********************** }
+
+FUNCTION get_next_selected_emplno : string ;
+
+BEGIN
+get_next_selected_emplno := get_selected_emplno (next_emplno);
+END; { get_next_selected_emplno }
+
+{ ************************* get_prev_selected_emplno *********************** }
+
+FUNCTION get_prev_selected_emplno : string ;
+
+BEGIN
+get_prev_selected_emplno := get_selected_emplno (prev_emplno);
+END; { get_prev_selected_emplno }
+
+BEGIN
+END;
+
+PROCEDURE timestamp_to_date
+ (at_timestamp : long; VAR date: date_type)
+ ;
+
+{ converts a number of days (where 1.1.1901 is 1) into a date }
+
+LABEL 1;
+
+{ number of days passed, when the i+1-st month starts }
+
+
+(*
+CONST month_days : ARRAY [0..11] of short =
+ (0,31,59,90,120,151,181,212,243,273,304,334);
+*)
+
+
+
+VAR
+ i, no_of_leap_years: short;
+
+BEGIN
+
+IF at_timestamp <= 0 THEN WITH date DO
+ BEGIN
+ yy := 0; mo := 0; dd := 0;
+ EXIT(**)
+ END;
+
+date.yy := (at_timestamp DIV 365) + 1901;
+no_of_leap_years := (date.yy - 1901) DIV 4;
+IF no_of_leap_years >= (at_timestamp MOD 365) THEN
+ BEGIN
+ date.yy := date.yy - 1;
+ at_timestamp := 365 - (no_of_leap_years - (at_timestamp MOD 365));
+ IF ((date.yy MOD 4) = 0) THEN
+ at_timestamp := at_timestamp + 1; {leap year is not yet completed, but
+ one day has already been subtracted before}
+ END
+ELSE
+ at_timestamp := (at_timestamp MOD 365) - no_of_leap_years;
+
+IF ((date.yy MOD 4) = 0) AND (at_timestamp = 60) THEN
+ BEGIN
+ date.mo := 2;
+ date.dd := 29;
+ EXIT(**)
+ END
+ELSE
+ BEGIN
+ FOR i := 1 TO 11 DO
+ IF at_timestamp <= month_days[i] THEN
+ BEGIN
+ date.mo := i;
+ date.dd := at_timestamp - month_days[i-1];
+ GOTO 1;
+ END;
+ date.mo := 12;
+ date.dd := at_timestamp - month_days[11];
+ END;
+
+1:
+IF ((date.yy MOD 4) = 0) AND (date.mo > 2) THEN
+ {subtract one day}
+ IF date.dd = 1 THEN
+ BEGIN
+ date.mo := date.mo - 1;
+ {last day of date.mo}
+ date.dd := month_days[date.mo] - month_days[date.mo - 1];
+ END
+ ELSE
+ date.dd := date.dd - 1;
+
+END; { timestamp_to_date }
+
+(* end of location *)
+
+BEGIN
+END.
diff --git a/misc/pascal/tests/src/README b/misc/pascal/tests/src/README
new file mode 100644
index 000000000..88a4693fa
--- /dev/null
+++ b/misc/pascal/tests/src/README
@@ -0,0 +1,38 @@
+README
+^^^^^^
+
+Naming Conventions
+^^^^^^^^^^^^^^^^^^
+
+This directory contains miscellaneous Pascal test files.
+All test fils are prefixed with a number. The number is only to
+control the order of execution: From the most simple to the
+most complex tests.
+
+XXX-name.pas and (optional XXX-name.inp)
+
+XXX-name.pas is the program under test XXX follows the numbering
+conventions below. 'name' helps humans to remember what is
+being testged.
+
+XXX-name.inp contains optional inparameter for the program
+under test.
+
+General numbering conventions:
+
+000-099: Basic functionality
+100-199: Math and runtime libraries
+200-299: Strings
+500-599: multi-file features: uses, units
+800-899: Erie pascal programs
+900-999: Misc. large programs not targeted at any particular feature.
+
+Sources/Licensing
+^^^^^^^^^^^^^^^^^
+
+Some of these pascal files were collected from the internet
+and their original sources are lost to memory. Since they are
+included here only for testing purposes, I suspect that there
+are no licensing issues... However, I would avoid using any of
+these files as part of a pascal application!
+
diff --git a/misc/pascal/tests/testall.sh b/misc/pascal/tests/testall.sh
new file mode 100755
index 000000000..7d3f74557
--- /dev/null
+++ b/misc/pascal/tests/testall.sh
@@ -0,0 +1,124 @@
+#!/bin/sh
+############################################################################
+# testall.sh
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#set -x
+
+TSTLST="\
+./501-uses.sh\
+"
+
+# Parse command line
+DOLIST=A
+if [ -n "$1" ]; then
+ case "$1" in
+ [0,1,2,5,8,9,A] )
+ DOLIST=${1}
+ ;;
+ a )
+ DOLIST=A
+ ;;
+ * )
+ echo ""; echo "Unrecognized filter option"
+ show_usage
+ ;;
+ esac
+fi
+
+# Tell them how they are supposed to use this script
+function show_usage ()
+{
+ echo "USAGE:"
+ echo " ${0} [FILTER]"
+ echo "WHERE:"
+ echo " FILTER=0: Execute on basic functionaly tests"
+ echo " FILTER=1: Execute only math and runtime libraries"
+ echo " FILTER=2: Execute only string tests"
+ echo " FILTER=5: Execute only multi-file tests"
+ echo " FILTER=8: Execute only Erie pascal programs"
+ echo " FILTER=9: Execute only miscellaneous large programs"
+ echo " FILTER=A: Execute all tests"
+ echo " Default: Execute all tests"
+ exit 1
+}
+
+# Check if the following test should be executed
+function check_dolist ()
+{
+ BASEFILE=`basename ${1}`
+ FILECHAR=`echo "${BASEFILE}" | cut -b1`
+ if [ "${DONTLIST}" == "${FILECHAR}" ]; then
+ echo "YES"
+ else
+ if [ "${DOLIST}" == "A" ]; then
+ echo "NO"
+ else
+ if [ "${DOLIST}" == "${FILECHAR}" ]; then
+ echo "NO"
+ else
+ echo "YES"
+ fi
+ fi
+ fi
+}
+
+# Clean up
+rm -f src/*.o src/*.o1 src/*.pex src/*.err src/*.lst
+
+# Compile and execute all of the selected tests in the src
+# directory. Skip the multiple scripts; they must be handled
+# by custom scripts
+DONTLIST=5
+for file in `ls -1 src/*.pas`; do
+
+ SKIPPING=`check_dolist $file`
+ if [ "${SKIPPING}" == "YES" ]; then
+ echo "SKIPPING $file"
+ else
+ echo "########${file}########";
+ ./testone.sh ${file}
+ fi
+done
+
+# Special tests performed by custom scripts
+DONTLIST=X
+for file in ${TSTLST}; do
+ SKIPPING=`check_dolist $file`
+ if [ "${SKIPPING}" == "YES" ]; then
+ echo "SKIPPING $file"
+ else
+ ${file}
+ fi
+done
+exit
diff --git a/misc/pascal/tests/testone.sh b/misc/pascal/tests/testone.sh
new file mode 100755
index 000000000..10eb999cb
--- /dev/null
+++ b/misc/pascal/tests/testone.sh
@@ -0,0 +1,166 @@
+#!/bin/sh
+############################################################################
+# testone.sh
+#
+# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+#set -x
+
+source ../.config
+
+if [ "${CONFIG_INSN16}" == "y" ]; then
+ BINDIR=bin16
+fi
+if [ "${CONFIG_INSN32}" == "y" ]; then
+ BINDIR=bin32
+fi
+
+PASCAL=../${BINDIR}/pascal
+POPT=../${BINDIR}/popt
+REGM=../${BINDIR}/regm
+PLINK=../${BINDIR}/plink
+PRUN=../${BINDIR}/prun
+
+# Tell them how they are supposed to use this script
+
+function show_usage ()
+{
+ echo "USAGE:"
+ echo " ${0} [OPTION] <pas-file-basename>"
+ echo "OPTIONS:"
+ echo " -t <strstksz>: Select string stack size"
+ echo " -h: Show this text"
+ exit 1
+}
+
+# Get the source file name and path
+
+function get_sourcename ()
+{
+ PASBASENAME=`basename ${PASFILENAME} .pas`
+ PASDIRNAME=`dirname ${PASFILENAME}`
+ if [ "${PASDIRNAME}" == "." ]; then
+ PASDIRNAME=src
+ fi
+
+ PASFILENAME=${PASDIRNAME}/${PASBASENAME}.pas
+ if [ ! -f "${PASFILENAME}" ]; then
+ echo "ERROR: ${PASFILENAME} does not exist"
+ exit 1
+ fi
+}
+
+# Compile source file
+
+function compile_source ()
+{
+ if [ ! -f ${PASFILENAME} ]; then
+ echo "No source file"
+ else
+ PASOPTS=-Isrc
+ ${PASCAL} ${PASOPTS} ${PASFILENAME} 2>&1 || rm -f src/${PASBASENAME}.o1
+ if [ -f src/${PASBASENAME}.err ] ; then
+ cat src/${PASBASENAME}.err | grep Line
+ fi
+ if [ ! -f src/${PASBASENAME}.o1 ] ; then
+ echo "Compilation failed"
+ else
+
+ if [ "${CONFIG_REGM}" == "y" ]; then
+ POPTOPTS=-r
+ ${POPT} ${POPTOPTS} src/${PASBASENAME}.o1 2>&1
+ ${REGM} src/${PASBASENAME}.o1 2>&1
+ else
+ POPTOPTS=
+ ${POPT} ${POPTOPTS} src/${PASBASENAME}.o1 2>&1
+ ${PLINK} src/${PASBASENAME}.o src/${PASBASENAME}.pex 2>&1
+ fi
+ fi
+ fi
+}
+
+# Run test
+
+function test_program ()
+{
+ if [ "${CONFIG_REGM}" == "y" ]; then
+ echo "Don't know how to run REGM programs yet"
+ else
+ echo "Using string stack size = ${STRSTKSZ}"
+ PRUNOPTS="-t ${STRSTKSZ}"
+
+ if [ ! -f src/${PASBASENAME}.pex ]; then
+ echo "No p-code executable"
+ else
+ if [ -f src/${PASBASENAME}.inp ] ; then
+ ${PRUN} ${PRUNOPTS} src/${PASBASENAME}.pex 2>&1 <src/${PASBASENAME}.inp
+ else
+ ${PRUN} ${PRUNOPTS} src/${PASBASENAME}.pex 2>&1
+ fi
+ fi
+ fi
+}
+
+
+# Parse command line
+
+STRSTKSZ=1024
+PASFILENAME=
+
+while [ -n "$1" ]; do
+ case "$1" in
+ -t )
+ STRSTKSZ=$2
+ shift
+ ;;
+ -h )
+ show_usage
+ ;;
+ * )
+ PASFILENAME=$1
+ ;;
+ esac
+ shift
+done
+
+if [ -z "${PASFILENAME}" ]; then
+ echo "ERROR: No file name provided"
+ show_usage
+ exit 1
+fi
+
+# Get the source file name and path
+
+get_sourcename
+compile_source
+test_program
+
diff --git a/misc/pascal/zipme b/misc/pascal/zipme
new file mode 100755
index 000000000..06017df52
--- /dev/null
+++ b/misc/pascal/zipme
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+#set -x
+
+DATECODE=$1
+
+TAR="tar cvf"
+ZIP=gzip
+
+# Move up one directory
+
+cd ..
+HOME=`pwd`
+DIR=${HOME}/pascal
+SUBDIR=pascal-${DATECODE}
+
+# Make sure we know what is going on
+
+if [ -z ${DATECODE} ] ; then
+ echo "You must supply a date code like a.b.c as a parameter"
+ exit 1;
+fi
+
+if [ ! -d ${SUBDIR} ] ; then
+ echo "Directory ${SUBDIR} does not exist."
+ exit 1;
+fi
+
+if [ ! -x ${SUBDIR}/$0 ] ; then
+ echo "You must cd to the directory containing this script."
+ exit 1;
+fi
+
+# Define the ZIP file pathes
+
+TAR_NAME=${SUBDIR}.tar
+ZIP_NAME=${TAR_NAME}.gz
+
+# Prepare the directory
+
+make -C ${SUBDIR} deep-clean
+
+find ${SUBDIR} -name \*~ -exec rm -f {} \; || \
+ { echo "Removal of emacs garbage failed!" ; exit 1 ; }
+
+find ${SUBDIR} -name \#\* -exec rm -f {} \; || \
+ { echo "Removal of emacs garbage failed!" ; exit 1 ; }
+
+find ${SUBDIR} -name .\*swp\* -exec rm -f {} \; || \
+ { echo "Removal of vi garbage failed!" ; exit 1 ; }
+
+# Remove any previous tarballs
+
+if [ -f ${TAR_NAME} ] ; then
+ echo "Removing ${HOME}/${TAR_NAME}"
+ rm -f ${TAR_NAME} || \
+ { echo "rm ${TAR_NAME} failed!" ; exit 1 ; }
+fi
+
+if [ -f ${ZIP_NAME} ] ; then
+ echo "Removing ${HOME}/${ZIP_NAME}"
+ rm -f ${ZIP_NAME} || \
+ { echo "rm ${ZIP_NAME} failed!" ; exit 1 ; }
+fi
+
+# Then zip it
+
+${TAR} ${TAR_NAME} ${SUBDIR} || \
+ { echo "tar of ${DIR} failed!" ; exit 1 ; }
+${ZIP} ${TAR_NAME} || \
+ { echo "zip of ${TAR_NAME} failed!" ; exit 1 ; }
diff --git a/misc/sims/README.txt b/misc/sims/README.txt
new file mode 100644
index 000000000..a7a902e59
--- /dev/null
+++ b/misc/sims/README.txt
@@ -0,0 +1,35 @@
+README.txt
+^^^^^^^^^^
+
+This directory contains instruction set simulators that were
+used to verify NuttX and which are not readily available elsewhere.
+
+These tools were cobbled together using bits and pieces of software
+from all over the internet. Licensing is unknown and you are
+certainly at risk if you distribute these in a commercial product.
+My recommendation: For your personal use only.
+
+z80sim
+^^^^^^
+
+ This is an emulator for the Z80 instruction set. It is based
+ on the instruction set emulator by Marat Fayzullin but has
+ been extended to load Intel hex format files as produced by
+ the SDCC toolchain.
+
+ Sources and licensing
+ ^^^^^^^^^^^^^^^^^^^^^
+
+ Marat Fayzullin's Z80 instruction set simulator is available
+ here: http://fms.komkon.org/EMUL8/ . Licensing information
+ is available at that site as well. I am not permitted to
+ distribute that package on the internet, but the Makefile
+ will automatically download the package.
+
+ Most of the Intel hex logic was copied from some
+ http://www.pjrc.com/tech/8051/pm2_docs/intel-hex.html .
+ Licensing requires only that I include the authors name
+ (Paul Stoffregen) and contact information (paul@ece.orst.edu)
+ in the source code.
+
+
diff --git a/misc/sims/z80sim/README.txt b/misc/sims/z80sim/README.txt
new file mode 100644
index 000000000..2c813510d
--- /dev/null
+++ b/misc/sims/z80sim/README.txt
@@ -0,0 +1,24 @@
+z80sim
+^^^^^^
+
+ This is an emulator for the Z80 instruction set. It is based
+ on the instruction set emulator by Marat Fayzullin but has
+ been extended to load Intel hex format files as produced by
+ the SDCC toolchain.
+
+ Sources and licensing
+ ^^^^^^^^^^^^^^^^^^^^^
+
+ Marat Fayzullin's Z80 instruction set simulator is available
+ here: http://fms.komkon.org/EMUL8/ . Licensing information
+ is available at that site as well. I am not permitted to
+ distribute that package on the internet, but the Makefile
+ will automatically download the package.
+
+ Most of the Intel hex logic was copied from some
+ http://www.pjrc.com/tech/8051/pm2_docs/intel-hex.html .
+ Licensing requires only that I include the authors name
+ (Paul Stoffregen) and contact information (paul@ece.orst.edu)
+ in the source code.
+
+
diff --git a/misc/sims/z80sim/example/Makefile b/misc/sims/z80sim/example/Makefile
new file mode 100644
index 000000000..1b12d3d75
--- /dev/null
+++ b/misc/sims/z80sim/example/Makefile
@@ -0,0 +1,44 @@
+AS = /usr/local/bin/as-z80
+ASFLAGS = -xlosp
+
+CPP = /usr/local/bin/sdcpp
+CPPFLAGS = -D__ASSEMBLY__
+
+CC = /usr/local/bin/sdcc
+CFLAGS = -mz80 --stack-auto --int-long-reent --float-reent
+
+LD = /usr/local/bin/link-z80
+LDFLAGS =
+
+ASMEXT = .asm
+OBJEXT = .rel
+LIBEXT = .lib
+EXEEXT = .hex
+
+ASRCS = example.asm
+AOBJS = $(ASRCS:$(ASMEXT)=$(OBJEXT))
+
+CSRCS =
+COBJS = $(CSRCS:.c=$(OBJEXT))
+
+SRCS = $(SSRCS) $(CSRCS)
+OBJS = $(AOBJS) $(COBJS)
+
+BIN = example$(EXEEXT)
+
+all: $(BIN)
+default: $(BIN)
+
+$(AOBJS): $(ASRCS)
+ $(AS) $(ASFLAGS) $@ $<
+
+$(COBJS) $(TESTOBJS): %$(OBJEXT): %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+$(BIN): $(OBJS)
+ $(CC) $(LDFLAGS) $< -o $@
+
+clean:
+ @rm -f $(BIN) *.o *.rel *.lst *.sym *.adb *.ihx *.map *.mem *.rst *.lnk *~
+
+distclean: clean
diff --git a/misc/sims/z80sim/example/example.asm b/misc/sims/z80sim/example/example.asm
new file mode 100644
index 000000000..ae0fc4f41
--- /dev/null
+++ b/misc/sims/z80sim/example/example.asm
@@ -0,0 +1,84 @@
+;************************************************************************
+; example.s
+;************************************************************************
+
+ .title z80sim Test
+ .module example
+
+;************************************************************************
+; Constants
+;************************************************************************
+
+ STACKBASE == 0xFFFF
+
+;************************************************************************
+; Data
+;************************************************************************
+
+ .area DATA (ABS,OVR)
+ .org 0x8000
+hello:
+ .ascii "Hello, World!\n\0"
+
+;************************************************************************
+; Reset entry point
+;************************************************************************
+
+ .area TEXT (ABS,OVR)
+ .org 0x0000
+ di ; Disable interrupts
+ ld SP, #STACKBASE ; Set stack pointer
+ im 1 ; Set interrupt mode 1
+ jp start ; jump to start of program
+
+;************************************************************************
+; Interrupt handler
+;************************************************************************
+
+ .org 0x0038 ; Int mode 1
+ reti ; return from interrupt
+
+;************************************************************************
+; NMI interrupt handler
+;************************************************************************
+
+ .org 0x0066
+ retn
+
+;************************************************************************
+; Start of program
+;************************************************************************
+
+ .org 0x0100
+start:
+ ;ei ; Enable interrrupts
+ ld hl, #hello ; Say hello
+ call print
+
+forever: ; Then stop execution
+ jp forever
+
+;******************************************************************
+; print *
+; Funktion....: Sen tekst and data with serielport *
+; Input.......: hl points at text start adr *
+; Output......: Text to serielport *
+; uses........: a,hl*
+; call........: TX_BUSY tst 28-4-1994 *
+;******************************************************************
+
+print:
+ push af
+loop:
+ ld a, (hl) ; Get character to print
+ cp #0 ; Null terminates the string
+ jp z, done
+
+ out (0xbe), a ; Send character
+ inc hl ; Increment to next character
+ jp loop ; Loop til done
+done:
+ pop af
+ ret
+
+
diff --git a/misc/sims/z80sim/src/Makefile b/misc/sims/z80sim/src/Makefile
new file mode 100644
index 000000000..0b68816c7
--- /dev/null
+++ b/misc/sims/z80sim/src/Makefile
@@ -0,0 +1,39 @@
+Z80SITE = http://fms.komkon.org/EMUL8
+Z80SOURCE = Z80-081707.zip
+Z80UNZIP = /usr/bin/unzip
+Z80WGET = /usr/bin/wget
+
+CC = gcc
+CFLAGS = -g -Wall -IZ80 -DLSB_FIRST=1 -DDEBUG=1 -DJUMPZ80
+
+LD = gcc
+LDFLAGS =
+
+SRCS = main.c Debug.c Z80.c
+OBJS = $(SRCS:.c=.o)
+
+BIN = z80sim
+
+VPATH = Z80
+
+all: $(BIN)
+default: $(BIN)
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+Z80-081707.zip:
+ $(Z80WGET) $(Z80SITE)/$(Z80SOURCE)
+
+Z80: Z80-081707.zip
+ $(Z80UNZIP) Z80-081707.zip
+
+z80sim: Z80 $(OBJS)
+ $(LD) $(LDFLAGS) $(OBJS) -o $@
+
+clean:
+ @rm -f $(BIN) *.o *.rel *.asm *.lst *.sym *.adb *~
+
+distclean: clean
+ rm -rf Z80 Z80-081707.zip
+
diff --git a/misc/sims/z80sim/src/main.c b/misc/sims/z80sim/src/main.c
new file mode 100644
index 000000000..9312b7509
--- /dev/null
+++ b/misc/sims/z80sim/src/main.c
@@ -0,0 +1,485 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "Z80.h"
+
+/* This is the simulated z80 16-bit address space */
+
+static unsigned char memory[65536];
+
+/* This is the simulatin execution context */
+
+static Z80 gR;
+
+/* Command line options */
+
+static int gtrace = 0;
+static const char *gfilename = NULL;
+
+/* Name: RdZ80 and WrZ80
+ * Description: These functions are called when access to RAM occurs.
+ * They allow to control memory access.
+ */
+
+void WrZ80(register word Addr, register byte Value)
+{
+ memory[Addr] = Value;
+}
+
+byte RdZ80(register word Addr)
+{
+ return memory[Addr];
+}
+
+/* Name: InZ80 and OutZ80
+ * Description: Z80 emulation calls these functions to read/write from
+ * I/O ports. There can be 65536 I/O ports, but only first
+ * 256 are usually used.
+ */
+
+void OutZ80(register word Port,register byte Value)
+{
+ /* We recognize only one port, 0xbe, which is mapped to stdout */
+
+ if ((Port & 0x00ff) == 0xbe)
+ {
+ putchar(Value);
+ fflush(stdout);
+ }
+}
+
+byte InZ80(register word Port)
+{
+ /* We recognize only one port, 0xbe, which is mapped to stdin */
+
+ if ((Port & 0x00ff) == 0xbe)
+ {
+ return getchar();
+ }
+ return 0;
+}
+
+/* Name: PatchZ80
+ * Description: Z80 emulation calls this function when it encounters a
+ * special patch command (ED FE) provided for user needs.
+ * For example, it can be called to emulate BIOS calls,
+ * such as disk and tape access. Replace it with an empty
+ * macro for no patching.
+ */
+
+void PatchZ80(register Z80 *R)
+{
+}
+
+/* Name: LoopZ80
+ * Description: Z80 emulation calls this function periodically to check
+ * if the system hardware requires any interrupts. This
+ * function must return an address of the interrupt vector
+ * (0x0038, 0x0066, etc.) or INT_NONE for no interrupt.
+ * Return INT_QUIT to exit the emulation loop.
+ */
+
+word LoopZ80(register Z80 *R)
+{
+ return INT_NONE;
+}
+
+/* Name: JumpZ80
+ * Description: Z80 emulation calls this function when it executes a
+ * JP, JR, CALL, RST, or RET. You can use JumpZ80() to
+ * trap these opcodes and switch memory layout.
+ */
+
+#ifdef JUMPZ80
+void JumpZ80(word PC)
+{
+ if (gtrace)
+ {
+ printf("PC: %04X [%02X] HL: %04X SP: %04X [%04X, %04X, ...]\n",
+ gR.PC.W, memory[gR.PC.W], gR.HL.W, gR.SP.W,
+ ((int)memory[gR.SP.W] | ((int)memory[gR.SP.W+1]) << 8),
+ ((int)memory[gR.SP.W+2] | ((int)memory[gR.SP.W+3]) << 8));
+ }
+}
+#endif
+
+/* Intel hex code based largely on code taken from the PJRC website.
+ * Licensing requires the following:
+ *
+ * Author: Paul Stoffregen
+ * Contact: paul@ece.orst.edu
+ */
+
+/* Name: parse_hex
+ * Description: Parse one line from an Intel hex file
+ */
+
+static int parse_hex(const char *hex, unsigned char *binary, int *addr, int *nbytes, int *code)
+{
+ const char *ptr;
+ int accum;
+ int chksum;
+ int len;
+
+ *nbytes = 0;
+
+ /* Each valid hex begins with a colon */
+
+ ptr = hex;
+ if (*hex != ':')
+ {
+ return 0;
+ }
+ ptr++;
+
+ /* The minimun size is ':'(1) + (0) + addr(4) + type(2) + data(2) + chechksum(2) = 11 */
+
+ if (strlen(hex) < 11)
+ {
+ return 0;
+ }
+
+ /* Get the length byte */
+
+ if (!sscanf(ptr, "%02x", &len))
+ {
+ return 0;
+ }
+ ptr += 2;
+
+ /* Now verify the length is ':'(1) + l2*len + addr(4) + type(2) + data(2) + chechksum(2) */
+
+ if (strlen(hex) < (11 + (2*len)))
+ {
+ return 0;
+ }
+
+ /* Get the address */
+
+ if (!sscanf(ptr, "%04x", addr))
+ {
+ return 0;
+ }
+ ptr += 4;
+
+ /* Get the code byte */
+
+ if (!sscanf(ptr, "%02x", code))
+ {
+ return 0;
+ }
+ ptr += 2;
+
+ /* Copy the data and calculate the chechksum */
+
+ accum = len + (*addr >> 8) + *addr + *code;
+ while (*nbytes < len)
+ {
+ int tmp;
+
+ /* Get the next data byte */
+
+ if (!sscanf(ptr, "%02x", &tmp))
+ {
+ return 0;
+ }
+ ptr += 2;
+
+ /* Transfer the data to the user binary */
+
+ binary[*nbytes] = tmp;
+
+ /* Update the accum */
+
+ accum += binary[*nbytes];
+ (*nbytes)++;
+ }
+
+ /* Get the checksum */
+
+ if (!sscanf(ptr, "%02x", &chksum))
+ {
+ return 0;
+ }
+
+ /* Verify the checksum */
+
+ if (((accum + chksum) & 0xff) != 0)
+ {
+ return 0;
+ }
+ return 1;
+}
+
+/* Name: load_file
+ * Description: Read an entire Intel hex file into (simulated) z80 memory
+ */
+
+int load_file(const char *filename)
+{
+ char hex[1000];
+ FILE *stream;
+ unsigned char binary[256];
+ int i;
+ int total = 0;
+ int lineno = 1;
+ int minaddr = 65536;
+ int maxaddr = 0;
+ int addr;
+ int nbytes;
+ int status;
+
+ /* Open the ascii hex file */
+
+ stream = fopen(filename, "r");
+ if (stream == NULL)
+ {
+ printf("ERROR: Failed to open file '%s' for reading: %s\n", filename, strerror(errno));
+ return 0;
+ }
+
+ /* Loop until every line has been read */
+
+ while (!feof(stream) && !ferror(stream))
+ {
+ /* Read the next line from the Intel hex file */
+
+ hex[0] = '\0';
+ fgets(hex, 1000, stream);
+
+ /* Remove any trailing CR/LF */
+
+ if (hex[strlen(hex)-1] == '\n')
+ {
+ hex[strlen(hex)-1] = '\0';
+ }
+
+ if (hex[strlen(hex)-1] == '\r')
+ {
+ hex[strlen(hex)-1] = '\0';
+ }
+
+ /* Parse the hex line */
+
+ if (parse_hex(hex, binary, &addr, &nbytes, &status))
+ {
+ /* Valid data? */
+
+ if (status == 0)
+ {
+ /* Yes.. move it into the z80 memory image */
+
+ for (i = 0; i <= (nbytes-1); i++)
+ {
+ memory[addr] = binary[i];
+ total++;
+
+ /* Keep track of the highest and lowest addresses written */
+
+ if (addr < minaddr)
+ {
+ minaddr = addr;
+ }
+
+ if (addr > maxaddr)
+ {
+ maxaddr = addr;
+ }
+ addr++;
+ }
+ }
+
+ /* End of file? */
+
+ else if (status == 1)
+ {
+ fclose(stream);
+ printf("Loaded %d bytes between %04x to %04x\n", total, minaddr, maxaddr);
+ return 1;
+ }
+ else if (status != 2) /* begin of file */
+ {
+ printf("ERROR: Unrecognized status=%d at line=%d\n", status, lineno);
+ return 0;
+ }
+ }
+ else
+ {
+ printf("ERROR: Failed to parse %s at line: %d\n", filename, lineno);
+ return 0;
+ }
+ lineno++;
+ }
+ printf("ERROR: No end of file marker encountered in %s\n", filename);
+ return 0;
+}
+
+/* Name: sighandler
+ * Description: Catch program termination via control-C
+ */
+
+void sighandler(int signo)
+{
+ sigset_t set;
+ char command[80];
+ int i;
+ int j;
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGINT);
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
+ signal(SIGINT, SIG_DFL);
+
+ printf("AF:%04X HL:%04X DE:%04X BC:%04X PC:%04X SP:%04X IX:%04X IY:%04X I:%02X\n",
+ gR.AF.W, gR.HL.W, gR.DE.W, gR.BC.W, gR.PC.W, gR.SP.W, gR.IX.W, gR.IY.W, gR.I);
+
+ printf("AT PC: [%02X] AT SP: [%04X] %s: %s\n",
+ RdZ80(gR.PC.W), RdZ80(gR.SP.W) + RdZ80(gR.SP.W+1) * 256,
+ gR.IFF & 0x04? "IM2" : gR.IFF & 0x02? "IM1" : "IM0",
+ gR.IFF & 0x01? "EI" : "DI");
+
+ for (;;)
+ {
+ printf("\n[Command,'?']-> ");
+ fflush(stdout);
+ fflush(stdin);
+
+ fgets(command, 50, stdin);
+
+ switch(command[0])
+ {
+ case 'H':
+ case 'h':
+ case '?':
+ puts("\n***** Built-in Z80 Debugger Commands *****");
+ puts("m <addr> : Memory dump at addr");
+ puts("?,h : Show this help text");
+ puts("q : Exit Z80 emulation");
+ break;
+
+ case 'M':
+ case 'm':
+ {
+ unsigned short addr;
+
+ if (strlen(command) > 1)
+ {
+ sscanf(command+1, "%hX", &addr);
+ }
+ else
+ {
+ addr = gR.PC.W;
+ }
+
+ puts("");
+ for (j = 0; j < 16; j++)
+ {
+ printf("%04X: ",addr);
+ for (i = 0; i < 16; i++, addr++)
+ {
+ printf("%02X ", memory[addr]);
+ }
+ printf(" | ");
+ addr -= 16;
+ for (i = 0; i < 16; i++, addr++)
+ {
+ putchar(isprint(memory[addr])? memory[addr]:'.');
+ }
+ puts("");
+ }
+ }
+ break;
+
+ case 'Q':
+ case 'q':
+ exit(0);
+ }
+ }
+ exit(0);
+}
+
+static void show_usage(const char *progname, int exitcode)
+{
+ fprintf(stderr, "\nUSAGE: %s [OPTIONS] <Intel-Hex-File>\n", progname);
+ fprintf(stderr, "\nWhere [OPTIONS] include:\n");
+ fprintf(stderr, "\n\t-t\tEnable trace output\n");
+ fprintf(stderr, "\t-h\tShow this message\n");
+ exit(exitcode);
+}
+
+static void parse_commandline(int argc, char **argv)
+{
+ int opt;
+
+ while ((opt = getopt(argc, argv, ":th")) != -1)
+ {
+ switch (opt)
+ {
+ case 't':
+ gtrace++;
+ break;
+ case 'h':
+ show_usage(argv[0], 0);
+ break;
+ case '?':
+ fprintf(stderr, "ERROR: Unrecognized option: %c\n", optopt);
+ show_usage(argv[0], 1);
+ break;
+ case ':':
+ fprintf(stderr, "ERROR: Missing argument to option: %c\n", optopt);
+ show_usage(argv[0], 1);
+ break;
+ }
+ }
+
+ if (optind >= argc)
+ {
+ fprintf(stderr, "ERROR: Missing filename argument\n");
+ show_usage(argv[0], 1);
+ }
+
+ gfilename = argv[optind];
+ optind++;
+
+ if (optind < argc)
+ {
+ fprintf(stderr, "ERROR: Extra stuff on command line after filename\n");
+ show_usage(argv[0], 1);
+ }
+}
+
+/* Name: main
+ * Description: Program entry point
+ */
+
+int main(int argc, char **argv, char **envp)
+{
+ /* Parse the command line options */
+
+ parse_commandline(argc, argv);
+
+ /* Set all simulated z80 memory to a known value and load the Intel hex file */
+
+ memset(memory, 0, 65536);
+ load_file(gfilename);
+
+ /* Configure the simulation */
+
+ memset(&gR, 0, sizeof(Z80));
+ gR.IPeriod = 10000; /* 100Hz at 10MHz */
+ gR.IAutoReset = 1;
+
+ /* Set up to catch SIGINT (control-C from console) */
+
+ (void)signal(SIGINT, sighandler);
+
+ /* Then start the simulation */
+
+ RunZ80(&gR);
+ return 0;
+}
diff --git a/misc/tools/README.txt b/misc/tools/README.txt
new file mode 100644
index 000000000..ebda8b160
--- /dev/null
+++ b/misc/tools/README.txt
@@ -0,0 +1,46 @@
+misc/tools/README.txt
+=====================
+
+genromfs-0.5.2.tar.gz
+
+ This is a snapshot of the genromfs tarball taken from
+ http://sourceforge.net/projects/romfs/. This snapshot is provided to
+ assure that a working version of genromfs is always available for NuttX.
+
+ This tool is also include in the buildroot and can be built automatically
+ from the buildroot.
+
+kconfig-frontends-3.3.0-1.tar.gz
+
+ This is a snapshot of the kconfig-frontends tarball taken from
+ http://ymorin.is-a-geek.org/projects/kconfig-frontends on April 5, 2012.
+ This snapshot is provided so that a working version of the mconf
+ utility is always available.
+
+ General build instructions:
+
+ ./configure
+ make
+ make install
+
+ To suppress the graphical interfaces:
+
+ ./configure --disable-gconf --disable-qconf
+ make
+ make install
+
+kconfig-frontends-3.3.0-1-libintl.patch
+
+ The above build instructions did not work for me under my Cygwin
+ installation. This patch is a awful hack but will successfully
+ build 'mconf' under Cygwin.
+
+ cat kconfig-frontends-3.3.0-1-libintl.patch | patch -p0
+ cd kconfig-frontends-3.3.0-1
+ ./configure --disable-gconf --disable-qconf
+ make
+ make install
+
+kconfig-macos.path
+
+ This is a patch to make the kconfig-frontends build on Mac OS X.
diff --git a/misc/tools/genromfs-0.5.2.tar.gz b/misc/tools/genromfs-0.5.2.tar.gz
new file mode 100644
index 000000000..d928707f4
--- /dev/null
+++ b/misc/tools/genromfs-0.5.2.tar.gz
Binary files differ
diff --git a/misc/tools/kconfig-frontends-3.3.0-1-libintl.patch b/misc/tools/kconfig-frontends-3.3.0-1-libintl.patch
new file mode 100644
index 000000000..3fe3f8163
--- /dev/null
+++ b/misc/tools/kconfig-frontends-3.3.0-1-libintl.patch
@@ -0,0 +1,72 @@
+diff -ru kconfig-frontends-3.3.0-1.orig//frontends/nconf/nconf.c kconfig-frontends-3.3.0-1/frontends/nconf/nconf.c
+--- kconfig-frontends-3.3.0-1.orig//frontends/nconf/nconf.c 2012-03-20 16:07:45.000000000 -0600
++++ kconfig-frontends-3.3.0-1/frontends/nconf/nconf.c 2012-04-05 15:16:06.590563200 -0600
+@@ -1503,7 +1503,7 @@
+ }
+
+ notimeout(stdscr, FALSE);
+- ESCDELAY = 1;
++ //ESCDELAY = 1;
+
+ /* set btns menu */
+ curses_menu = new_menu(curses_menu_items);
+diff -ru kconfig-frontends-3.3.0-1.orig//frontends/nconf/nconf.h kconfig-frontends-3.3.0-1/frontends/nconf/nconf.h
+--- kconfig-frontends-3.3.0-1.orig//frontends/nconf/nconf.h 2012-03-20 16:07:45.000000000 -0600
++++ kconfig-frontends-3.3.0-1/frontends/nconf/nconf.h 2012-04-05 15:13:36.189960800 -0600
+@@ -15,7 +15,6 @@
+ #include <string.h>
+ #include <unistd.h>
+ #include <locale.h>
+-#include <curses.h>
+ #include <menu.h>
+ #include <panel.h>
+ #include <form.h>
+diff -ru kconfig-frontends-3.3.0-1.orig//libs/lxdialog/dialog.h kconfig-frontends-3.3.0-1/libs/lxdialog/dialog.h
+--- kconfig-frontends-3.3.0-1.orig//libs/lxdialog/dialog.h 2012-03-20 16:07:45.000000000 -0600
++++ kconfig-frontends-3.3.0-1/libs/lxdialog/dialog.h 2012-04-05 14:58:35.010416300 -0600
+@@ -26,11 +26,7 @@
+ #include <string.h>
+ #include <stdbool.h>
+
+-#ifndef KBUILD_NO_NLS
+-# include <libintl.h>
+-#else
+ # define gettext(Msgid) ((const char *) (Msgid))
+-#endif
+
+ #ifdef __sun__
+ #define CURS_MACROS
+diff -ru kconfig-frontends-3.3.0-1.orig//libs/parser/lkc.h kconfig-frontends-3.3.0-1/libs/parser/lkc.h
+--- kconfig-frontends-3.3.0-1.orig//libs/parser/lkc.h 2012-03-20 16:07:45.000000000 -0600
++++ kconfig-frontends-3.3.0-1/libs/parser/lkc.h 2012-04-05 14:59:02.969015400 -0600
+@@ -8,14 +8,10 @@
+
+ #include "expr.h"
+
+-#ifndef KBUILD_NO_NLS
+-# include <libintl.h>
+-#else
+ static inline const char *gettext(const char *txt) { return txt; }
+ static inline void textdomain(const char *domainname) {}
+ static inline void bindtextdomain(const char *name, const char *dir) {}
+ static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; }
+-#endif
+
+ #ifdef __cplusplus
+ extern "C" {
+diff -ru kconfig-frontends-3.3.0-1.orig//libs/parser/yconf.c kconfig-frontends-3.3.0-1/libs/parser/yconf.c
+--- kconfig-frontends-3.3.0-1.orig//libs/parser/yconf.c 2012-03-22 16:34:21.000000000 -0600
++++ kconfig-frontends-3.3.0-1/libs/parser/yconf.c 2012-04-05 14:59:40.732175300 -0600
+@@ -285,12 +285,6 @@
+ #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+ #ifndef YY_
+-# if YYENABLE_NLS
+-# if ENABLE_NLS
+-# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+-# define YY_(msgid) dgettext ("bison-runtime", msgid)
+-# endif
+-# endif
+ # ifndef YY_
+ # define YY_(msgid) msgid
+ # endif
diff --git a/misc/tools/kconfig-frontends-3.3.0-1.tar.gz b/misc/tools/kconfig-frontends-3.3.0-1.tar.gz
new file mode 100644
index 000000000..2f2f4eb9c
--- /dev/null
+++ b/misc/tools/kconfig-frontends-3.3.0-1.tar.gz
Binary files differ
diff --git a/misc/tools/kconfig-language.txt b/misc/tools/kconfig-language.txt
new file mode 100644
index 000000000..44e2649fb
--- /dev/null
+++ b/misc/tools/kconfig-language.txt
@@ -0,0 +1,413 @@
+Introduction
+------------
+
+The configuration database is a collection of configuration options
+organized in a tree structure:
+
+ +- Code maturity level options
+ | +- Prompt for development and/or incomplete code/drivers
+ +- General setup
+ | +- Networking support
+ | +- System V IPC
+ | +- BSD Process Accounting
+ | +- Sysctl support
+ +- Loadable module support
+ | +- Enable loadable module support
+ | +- Set version information on all module symbols
+ | +- Kernel module loader
+ +- ...
+
+Every entry has its own dependencies. These dependencies are used
+to determine the visibility of an entry. Any child entry is only
+visible if its parent entry is also visible.
+
+Menu entries
+------------
+
+Most entries define a config option; all other entries help to organize
+them. A single configuration option is defined like this:
+
+config MODVERSIONS
+ bool "Set version information on all module symbols"
+ depends on MODULES
+ help
+ Usually, modules have to be recompiled whenever you switch to a new
+ kernel. ...
+
+Every line starts with a key word and can be followed by multiple
+arguments. "config" starts a new config entry. The following lines
+define attributes for this config option. Attributes can be the type of
+the config option, input prompt, dependencies, help text and default
+values. A config option can be defined multiple times with the same
+name, but every definition can have only a single input prompt and the
+type must not conflict.
+
+Menu attributes
+---------------
+
+A menu entry can have a number of attributes. Not all of them are
+applicable everywhere (see syntax).
+
+- type definition: "bool"/"tristate"/"string"/"hex"/"int"
+ Every config option must have a type. There are only two basic types:
+ tristate and string; the other types are based on these two. The type
+ definition optionally accepts an input prompt, so these two examples
+ are equivalent:
+
+ bool "Networking support"
+ and
+ bool
+ prompt "Networking support"
+
+- input prompt: "prompt" <prompt> ["if" <expr>]
+ Every menu entry can have at most one prompt, which is used to display
+ to the user. Optionally dependencies only for this prompt can be added
+ with "if".
+
+- default value: "default" <expr> ["if" <expr>]
+ A config option can have any number of default values. If multiple
+ default values are visible, only the first defined one is active.
+ Default values are not limited to the menu entry where they are
+ defined. This means the default can be defined somewhere else or be
+ overridden by an earlier definition.
+ The default value is only assigned to the config symbol if no other
+ value was set by the user (via the input prompt above). If an input
+ prompt is visible the default value is presented to the user and can
+ be overridden by him.
+ Optionally, dependencies only for this default value can be added with
+ "if".
+
+- type definition + default value:
+ "def_bool"/"def_tristate" <expr> ["if" <expr>]
+ This is a shorthand notation for a type definition plus a value.
+ Optionally dependencies for this default value can be added with "if".
+
+- dependencies: "depends on" <expr>
+ This defines a dependency for this menu entry. If multiple
+ dependencies are defined, they are connected with '&&'. Dependencies
+ are applied to all other options within this menu entry (which also
+ accept an "if" expression), so these two examples are equivalent:
+
+ bool "foo" if BAR
+ default y if BAR
+ and
+ depends on BAR
+ bool "foo"
+ default y
+
+- reverse dependencies: "select" <symbol> ["if" <expr>]
+ While normal dependencies reduce the upper limit of a symbol (see
+ below), reverse dependencies can be used to force a lower limit of
+ another symbol. The value of the current menu symbol is used as the
+ minimal value <symbol> can be set to. If <symbol> is selected multiple
+ times, the limit is set to the largest selection.
+ Reverse dependencies can only be used with boolean or tristate
+ symbols.
+ Note:
+ select should be used with care. select will force
+ a symbol to a value without visiting the dependencies.
+ By abusing select you are able to select a symbol FOO even
+ if FOO depends on BAR that is not set.
+ In general use select only for non-visible symbols
+ (no prompts anywhere) and for symbols with no dependencies.
+ That will limit the usefulness but on the other hand avoid
+ the illegal configurations all over.
+
+- limiting menu display: "visible if" <expr>
+ This attribute is only applicable to menu blocks, if the condition is
+ false, the menu block is not displayed to the user (the symbols
+ contained there can still be selected by other symbols, though). It is
+ similar to a conditional "prompt" attribude for individual menu
+ entries. Default value of "visible" is true.
+
+- numerical ranges: "range" <symbol> <symbol> ["if" <expr>]
+ This allows to limit the range of possible input values for int
+ and hex symbols. The user can only input a value which is larger than
+ or equal to the first symbol and smaller than or equal to the second
+ symbol.
+
+- help text: "help" or "---help---"
+ This defines a help text. The end of the help text is determined by
+ the indentation level, this means it ends at the first line which has
+ a smaller indentation than the first line of the help text.
+ "---help---" and "help" do not differ in behaviour, "---help---" is
+ used to help visually separate configuration logic from help within
+ the file as an aid to developers.
+
+- misc options: "option" <symbol>[=<value>]
+ Various less common options can be defined via this option syntax,
+ which can modify the behaviour of the menu entry and its config
+ symbol. These options are currently possible:
+
+ - "defconfig_list"
+ This declares a list of default entries which can be used when
+ looking for the default configuration (which is used when the main
+ .config doesn't exists yet.)
+
+ - "modules"
+ This declares the symbol to be used as the MODULES symbol, which
+ enables the third modular state for all config symbols.
+
+ - "env"=<value>
+ This imports the environment variable into Kconfig. It behaves like
+ a default, except that the value comes from the environment, this
+ also means that the behaviour when mixing it with normal defaults is
+ undefined at this point. The symbol is currently not exported back
+ to the build environment (if this is desired, it can be done via
+ another symbol).
+
+Menu dependencies
+-----------------
+
+Dependencies define the visibility of a menu entry and can also reduce
+the input range of tristate symbols. The tristate logic used in the
+expressions uses one more state than normal boolean logic to express the
+module state. Dependency expressions have the following syntax:
+
+<expr> ::= <symbol> (1)
+ <symbol> '=' <symbol> (2)
+ <symbol> '!=' <symbol> (3)
+ '(' <expr> ')' (4)
+ '!' <expr> (5)
+ <expr> '&&' <expr> (6)
+ <expr> '||' <expr> (7)
+
+Expressions are listed in decreasing order of precedence.
+
+(1) Convert the symbol into an expression. Boolean and tristate symbols
+ are simply converted into the respective expression values. All
+ other symbol types result in 'n'.
+(2) If the values of both symbols are equal, it returns 'y',
+ otherwise 'n'.
+(3) If the values of both symbols are equal, it returns 'n',
+ otherwise 'y'.
+(4) Returns the value of the expression. Used to override precedence.
+(5) Returns the result of (2-/expr/).
+(6) Returns the result of min(/expr/, /expr/).
+(7) Returns the result of max(/expr/, /expr/).
+
+An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2
+respectively for calculations). A menu entry becomes visible when its
+expression evaluates to 'm' or 'y'.
+
+There are two types of symbols: constant and non-constant symbols.
+Non-constant symbols are the most common ones and are defined with the
+'config' statement. Non-constant symbols consist entirely of alphanumeric
+characters or underscores.
+Constant symbols are only part of expressions. Constant symbols are
+always surrounded by single or double quotes. Within the quote, any
+other character is allowed and the quotes can be escaped using '\'.
+
+Menu structure
+--------------
+
+The position of a menu entry in the tree is determined in two ways. First
+it can be specified explicitly:
+
+menu "Network device support"
+ depends on NET
+
+config NETDEVICES
+ ...
+
+endmenu
+
+All entries within the "menu" ... "endmenu" block become a submenu of
+"Network device support". All subentries inherit the dependencies from
+the menu entry, e.g. this means the dependency "NET" is added to the
+dependency list of the config option NETDEVICES.
+
+The other way to generate the menu structure is done by analyzing the
+dependencies. If a menu entry somehow depends on the previous entry, it
+can be made a submenu of it. First, the previous (parent) symbol must
+be part of the dependency list and then one of these two conditions
+must be true:
+- the child entry must become invisible, if the parent is set to 'n'
+- the child entry must only be visible, if the parent is visible
+
+config MODULES
+ bool "Enable loadable module support"
+
+config MODVERSIONS
+ bool "Set version information on all module symbols"
+ depends on MODULES
+
+comment "module support disabled"
+ depends on !MODULES
+
+MODVERSIONS directly depends on MODULES, this means it's only visible if
+MODULES is different from 'n'. The comment on the other hand is always
+visible when MODULES is visible (the (empty) dependency of MODULES is
+also part of the comment dependencies).
+
+
+Kconfig syntax
+--------------
+
+The configuration file describes a series of menu entries, where every
+line starts with a keyword (except help texts). The following keywords
+end a menu entry:
+- config
+- menuconfig
+- choice/endchoice
+- comment
+- menu/endmenu
+- if/endif
+- source
+The first five also start the definition of a menu entry.
+
+config:
+
+ "config" <symbol>
+ <config options>
+
+This defines a config symbol <symbol> and accepts any of above
+attributes as options.
+
+menuconfig:
+ "menuconfig" <symbol>
+ <config options>
+
+This is similar to the simple config entry above, but it also gives a
+hint to front ends, that all suboptions should be displayed as a
+separate list of options.
+
+choices:
+
+ "choice" [symbol]
+ <choice options>
+ <choice block>
+ "endchoice"
+
+This defines a choice group and accepts any of the above attributes as
+options. A choice can only be of type bool or tristate, while a boolean
+choice only allows a single config entry to be selected, a tristate
+choice also allows any number of config entries to be set to 'm'. This
+can be used if multiple drivers for a single hardware exists and only a
+single driver can be compiled/loaded into the kernel, but all drivers
+can be compiled as modules.
+A choice accepts another option "optional", which allows to set the
+choice to 'n' and no entry needs to be selected.
+If no [symbol] is associated with a choice, then you can not have multiple
+definitions of that choice. If a [symbol] is associated to the choice,
+then you may define the same choice (ie. with the same entries) in another
+place.
+
+comment:
+
+ "comment" <prompt>
+ <comment options>
+
+This defines a comment which is displayed to the user during the
+configuration process and is also echoed to the output files. The only
+possible options are dependencies.
+
+menu:
+
+ "menu" <prompt>
+ <menu options>
+ <menu block>
+ "endmenu"
+
+This defines a menu block, see "Menu structure" above for more
+information. The only possible options are dependencies and "visible"
+attributes.
+
+if:
+
+ "if" <expr>
+ <if block>
+ "endif"
+
+This defines an if block. The dependency expression <expr> is appended
+to all enclosed menu entries.
+
+source:
+
+ "source" <prompt>
+
+This reads the specified configuration file. This file is always parsed.
+
+mainmenu:
+
+ "mainmenu" <prompt>
+
+This sets the config program's title bar if the config program chooses
+to use it. It should be placed at the top of the configuration, before any
+other statement.
+
+
+Kconfig hints
+-------------
+This is a collection of Kconfig tips, most of which aren't obvious at
+first glance and most of which have become idioms in several Kconfig
+files.
+
+Adding common features and make the usage configurable
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+It is a common idiom to implement a feature/functionality that are
+relevant for some architectures but not all.
+The recommended way to do so is to use a config variable named HAVE_*
+that is defined in a common Kconfig file and selected by the relevant
+architectures.
+An example is the generic IOMAP functionality.
+
+We would in lib/Kconfig see:
+
+# Generic IOMAP is used to ...
+config HAVE_GENERIC_IOMAP
+
+config GENERIC_IOMAP
+ depends on HAVE_GENERIC_IOMAP && FOO
+
+And in lib/Makefile we would see:
+obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
+
+For each architecture using the generic IOMAP functionality we would see:
+
+config X86
+ select ...
+ select HAVE_GENERIC_IOMAP
+ select ...
+
+Note: we use the existing config option and avoid creating a new
+config variable to select HAVE_GENERIC_IOMAP.
+
+Note: the use of the internal config variable HAVE_GENERIC_IOMAP, it is
+introduced to overcome the limitation of select which will force a
+config option to 'y' no matter the dependencies.
+The dependencies are moved to the symbol GENERIC_IOMAP and we avoid the
+situation where select forces a symbol equals to 'y'.
+
+Build as module only
+~~~~~~~~~~~~~~~~~~~~
+To restrict a component build to module-only, qualify its config symbol
+with "depends on m". E.g.:
+
+config FOO
+ depends on BAR && m
+
+limits FOO to module (=m) or disabled (=n).
+
+Kconfig symbol existence
+~~~~~~~~~~~~~~~~~~~~~~~~
+The following two methods produce the same kconfig symbol dependencies
+but differ greatly in kconfig symbol existence (production) in the
+generated config file.
+
+case 1:
+
+config FOO
+ tristate "about foo"
+ depends on BAR
+
+vs. case 2:
+
+if BAR
+config FOO
+ tristate "about foo"
+endif
+
+In case 1, the symbol FOO will always exist in the config file (given
+no other dependencies). In case 2, the symbol FOO will only exist in
+the config file if BAR is enabled.
diff --git a/misc/tools/kconfig-macos.diff b/misc/tools/kconfig-macos.diff
new file mode 100755
index 000000000..10e21bb85
--- /dev/null
+++ b/misc/tools/kconfig-macos.diff
@@ -0,0 +1,22 @@
+diff -ru orig/kconfig-frontends-3.3.0-1/libs/parser/yconf.c kconfig-frontends-3.3.0-1/libs/parser/yconf.c
+--- orig/kconfig-frontends-3.3.0-1/libs/parser/yconf.c 2012-04-13 23:37:32.000000000 -0700
++++ kconfig-frontends-3.3.0-1/libs/parser/yconf.c 2012-04-13 23:38:36.000000000 -0700
+@@ -87,6 +87,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <stdbool.h>
++#include <stddef.h>
+
+ #include "lkc.h"
+
+diff -ru orig/kconfig-frontends-3.3.0-1/libs/parser/yconf.y kconfig-frontends-3.3.0-1/libs/parser/yconf.y
+--- orig/kconfig-frontends-3.3.0-1/libs/parser/yconf.y 2012-03-20 15:07:45.000000000 -0700
++++ kconfig-frontends-3.3.0-1/libs/parser/yconf.y 2012-04-13 23:38:22.000000000 -0700
+@@ -10,6 +10,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <stdbool.h>
++#include <stddef.h>
+
+ #include "lkc.h"
+