Merge branch 'devel-stable' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git...
Linus Torvalds [Fri, 28 Oct 2011 19:02:27 +0000 (12:02 -0700)]
* 'devel-stable' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm: (178 commits)
  ARM: 7139/1: fix compilation with CONFIG_ARM_ATAG_DTB_COMPAT and large TEXT_OFFSET
  ARM: gic, local timers: use the request_percpu_irq() interface
  ARM: gic: consolidate PPI handling
  ARM: switch from NO_MACH_MEMORY_H to NEED_MACH_MEMORY_H
  ARM: mach-s5p64x0: remove mach/memory.h
  ARM: mach-s3c64xx: remove mach/memory.h
  ARM: plat-mxc: remove mach/memory.h
  ARM: mach-prima2: remove mach/memory.h
  ARM: mach-zynq: remove mach/memory.h
  ARM: mach-bcmring: remove mach/memory.h
  ARM: mach-davinci: remove mach/memory.h
  ARM: mach-pxa: remove mach/memory.h
  ARM: mach-ixp4xx: remove mach/memory.h
  ARM: mach-h720x: remove mach/memory.h
  ARM: mach-vt8500: remove mach/memory.h
  ARM: mach-s5pc100: remove mach/memory.h
  ARM: mach-tegra: remove mach/memory.h
  ARM: plat-tcc: remove mach/memory.h
  ARM: mach-mmp: remove mach/memory.h
  ARM: mach-cns3xxx: remove mach/memory.h
  ...

Fix up mostly pretty trivial conflicts in:
 - arch/arm/Kconfig
 - arch/arm/include/asm/localtimer.h
 - arch/arm/kernel/Makefile
 - arch/arm/mach-shmobile/board-ap4evb.c
 - arch/arm/mach-u300/core.c
 - arch/arm/mm/dma-mapping.c
 - arch/arm/mm/proc-v7.S
 - arch/arm/plat-omap/Kconfig
largely due to some CONFIG option renaming (ie CONFIG_PM_SLEEP ->
CONFIG_ARM_CPU_SUSPEND for the arm-specific suspend code etc) and
addition of NEED_MACH_MEMORY_H next to HAVE_IDE.

524 files changed:
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/boot/compressed/.gitignore
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/atags_to_fdt.c [new file with mode: 0644]
arch/arm/boot/compressed/head.S
arch/arm/boot/compressed/libfdt_env.h [new file with mode: 0644]
arch/arm/boot/compressed/misc.c
arch/arm/boot/compressed/string.c [new file with mode: 0644]
arch/arm/boot/compressed/vmlinux.lds.in
arch/arm/common/gic.c
arch/arm/include/asm/dma-mapping.h
arch/arm/include/asm/entry-macro-multi.S
arch/arm/include/asm/hardirq.h
arch/arm/include/asm/hardware/entry-macro-gic.S
arch/arm/include/asm/hardware/gic.h
arch/arm/include/asm/hw_breakpoint.h
arch/arm/include/asm/localtimer.h
arch/arm/include/asm/mach/arch.h
arch/arm/include/asm/mach/map.h
arch/arm/include/asm/memory.h
arch/arm/include/asm/pgtable.h
arch/arm/include/asm/pmu.h
arch/arm/include/asm/proc-fns.h
arch/arm/include/asm/smp.h
arch/arm/include/asm/smp_twd.h
arch/arm/include/asm/suspend.h
arch/arm/kernel/Makefile
arch/arm/kernel/debug.S
arch/arm/kernel/head.S
arch/arm/kernel/hw_breakpoint.c
arch/arm/kernel/irq.c
arch/arm/kernel/kprobes-arm.c
arch/arm/kernel/kprobes-test-arm.c [new file with mode: 0644]
arch/arm/kernel/kprobes-test-thumb.c [new file with mode: 0644]
arch/arm/kernel/kprobes-test.c [new file with mode: 0644]
arch/arm/kernel/kprobes-test.h [new file with mode: 0644]
arch/arm/kernel/kprobes-thumb.c
arch/arm/kernel/kprobes.h
arch/arm/kernel/perf_event.c
arch/arm/kernel/perf_event_v6.c
arch/arm/kernel/perf_event_v7.c
arch/arm/kernel/perf_event_xscale.c
arch/arm/kernel/pmu.c
arch/arm/kernel/setup.c
arch/arm/kernel/sleep.S
arch/arm/kernel/smp.c
arch/arm/kernel/smp_twd.c
arch/arm/kernel/suspend.c [new file with mode: 0644]
arch/arm/mach-at91/at91sam9g45.c
arch/arm/mach-at91/include/mach/at91sam9g45.h
arch/arm/mach-at91/include/mach/debug-macro.S
arch/arm/mach-bcmring/include/mach/hardware.h
arch/arm/mach-bcmring/include/mach/memory.h [deleted file]
arch/arm/mach-bcmring/mm.c
arch/arm/mach-clps711x/autcpu12.c
arch/arm/mach-clps711x/cdb89712.c
arch/arm/mach-clps711x/ceiva.c
arch/arm/mach-clps711x/clep7312.c
arch/arm/mach-clps711x/edb7211-arch.c
arch/arm/mach-clps711x/fortunet.c
arch/arm/mach-clps711x/include/mach/debug-macro.S
arch/arm/mach-clps711x/p720t.c
arch/arm/mach-cns3xxx/cns3420vb.c
arch/arm/mach-cns3xxx/include/mach/debug-macro.S
arch/arm/mach-cns3xxx/include/mach/memory.h [deleted file]
arch/arm/mach-davinci/board-da830-evm.c
arch/arm/mach-davinci/board-da850-evm.c
arch/arm/mach-davinci/board-dm355-evm.c
arch/arm/mach-davinci/board-dm355-leopard.c
arch/arm/mach-davinci/board-dm365-evm.c
arch/arm/mach-davinci/board-dm644x-evm.c
arch/arm/mach-davinci/board-dm646x-evm.c
arch/arm/mach-davinci/board-mityomapl138.c
arch/arm/mach-davinci/board-neuros-osd2.c
arch/arm/mach-davinci/board-omapl138-hawk.c
arch/arm/mach-davinci/board-sffsdr.c
arch/arm/mach-davinci/board-tnetv107x-evm.c
arch/arm/mach-davinci/common.c
arch/arm/mach-davinci/cpuidle.c
arch/arm/mach-davinci/include/mach/ddr2.h [new file with mode: 0644]
arch/arm/mach-davinci/include/mach/debug-macro.S
arch/arm/mach-davinci/include/mach/memory.h [deleted file]
arch/arm/mach-davinci/include/mach/serial.h
arch/arm/mach-davinci/include/mach/uncompress.h
arch/arm/mach-davinci/sleep.S
arch/arm/mach-dove/cm-a510.c
arch/arm/mach-dove/dove-db-setup.c
arch/arm/mach-dove/include/mach/debug-macro.S
arch/arm/mach-dove/include/mach/memory.h [deleted file]
arch/arm/mach-ebsa110/core.c
arch/arm/mach-ebsa110/include/mach/debug-macro.S
arch/arm/mach-ep93xx/adssphere.c
arch/arm/mach-ep93xx/edb93xx.c
arch/arm/mach-ep93xx/gesbc9312.c
arch/arm/mach-ep93xx/include/mach/debug-macro.S
arch/arm/mach-ep93xx/micro9.c
arch/arm/mach-ep93xx/simone.c
arch/arm/mach-ep93xx/snappercl15.c
arch/arm/mach-ep93xx/ts72xx.c
arch/arm/mach-exynos4/include/mach/debug-macro.S
arch/arm/mach-exynos4/include/mach/entry-macro.S
arch/arm/mach-exynos4/mach-armlex4210.c
arch/arm/mach-exynos4/mach-nuri.c
arch/arm/mach-exynos4/mach-smdkc210.c
arch/arm/mach-exynos4/mach-smdkv310.c
arch/arm/mach-exynos4/mach-universal_c210.c
arch/arm/mach-exynos4/mct.c
arch/arm/mach-footbridge/cats-hw.c
arch/arm/mach-footbridge/ebsa285.c
arch/arm/mach-footbridge/include/mach/debug-macro.S
arch/arm/mach-footbridge/netwinder-hw.c
arch/arm/mach-footbridge/personal.c
arch/arm/mach-gemini/board-nas4220b.c
arch/arm/mach-gemini/board-rut1xx.c
arch/arm/mach-gemini/board-wbd111.c
arch/arm/mach-gemini/board-wbd222.c
arch/arm/mach-gemini/include/mach/debug-macro.S
arch/arm/mach-gemini/include/mach/memory.h [deleted file]
arch/arm/mach-h720x/h7201-eval.c
arch/arm/mach-h720x/h7202-eval.c
arch/arm/mach-h720x/include/mach/debug-macro.S
arch/arm/mach-h720x/include/mach/memory.h [deleted file]
arch/arm/mach-imx/mach-armadillo5x0.c
arch/arm/mach-imx/mach-cpuimx27.c
arch/arm/mach-imx/mach-cpuimx35.c
arch/arm/mach-imx/mach-eukrea_cpuimx25.c
arch/arm/mach-imx/mach-imx27_visstrim_m10.c
arch/arm/mach-imx/mach-imx27ipcam.c
arch/arm/mach-imx/mach-imx27lite.c
arch/arm/mach-imx/mach-kzm_arm11_01.c
arch/arm/mach-imx/mach-mx1ads.c
arch/arm/mach-imx/mach-mx21ads.c
arch/arm/mach-imx/mach-mx25_3ds.c
arch/arm/mach-imx/mach-mx27_3ds.c
arch/arm/mach-imx/mach-mx27ads.c
arch/arm/mach-imx/mach-mx31_3ds.c
arch/arm/mach-imx/mach-mx31ads.c
arch/arm/mach-imx/mach-mx31lilly.c
arch/arm/mach-imx/mach-mx31lite.c
arch/arm/mach-imx/mach-mx31moboard.c
arch/arm/mach-imx/mach-mx35_3ds.c
arch/arm/mach-imx/mach-mxt_td60.c
arch/arm/mach-imx/mach-pca100.c
arch/arm/mach-imx/mach-pcm037.c
arch/arm/mach-imx/mach-pcm038.c
arch/arm/mach-imx/mach-pcm043.c
arch/arm/mach-imx/mach-qong.c
arch/arm/mach-imx/mach-scb9328.c
arch/arm/mach-integrator/include/mach/debug-macro.S
arch/arm/mach-integrator/integrator_ap.c
arch/arm/mach-integrator/integrator_cp.c
arch/arm/mach-iop13xx/include/mach/debug-macro.S
arch/arm/mach-iop13xx/iq81340mc.c
arch/arm/mach-iop13xx/iq81340sc.c
arch/arm/mach-iop32x/em7210.c
arch/arm/mach-iop32x/glantank.c
arch/arm/mach-iop32x/include/mach/debug-macro.S
arch/arm/mach-iop32x/include/mach/memory.h [deleted file]
arch/arm/mach-iop32x/iq31244.c
arch/arm/mach-iop32x/iq80321.c
arch/arm/mach-iop32x/n2100.c
arch/arm/mach-iop33x/include/mach/debug-macro.S
arch/arm/mach-iop33x/include/mach/memory.h [deleted file]
arch/arm/mach-iop33x/iq80331.c
arch/arm/mach-iop33x/iq80332.c
arch/arm/mach-ixp2000/enp2611.c
arch/arm/mach-ixp2000/include/mach/debug-macro.S
arch/arm/mach-ixp2000/ixdp2400.c
arch/arm/mach-ixp2000/ixdp2800.c
arch/arm/mach-ixp2000/ixdp2x01.c
arch/arm/mach-ixp23xx/espresso.c
arch/arm/mach-ixp23xx/include/mach/debug-macro.S
arch/arm/mach-ixp23xx/ixdp2351.c
arch/arm/mach-ixp23xx/roadrunner.c
arch/arm/mach-ixp4xx/avila-setup.c
arch/arm/mach-ixp4xx/coyote-setup.c
arch/arm/mach-ixp4xx/dsmg600-setup.c
arch/arm/mach-ixp4xx/fsg-setup.c
arch/arm/mach-ixp4xx/gateway7001-setup.c
arch/arm/mach-ixp4xx/goramo_mlr.c
arch/arm/mach-ixp4xx/gtwx5715-setup.c
arch/arm/mach-ixp4xx/include/mach/debug-macro.S
arch/arm/mach-ixp4xx/include/mach/memory.h [deleted file]
arch/arm/mach-ixp4xx/ixdp425-setup.c
arch/arm/mach-ixp4xx/nas100d-setup.c
arch/arm/mach-ixp4xx/nslu2-setup.c
arch/arm/mach-ixp4xx/vulcan-setup.c
arch/arm/mach-ixp4xx/wg302v2-setup.c
arch/arm/mach-kirkwood/d2net_v2-setup.c
arch/arm/mach-kirkwood/db88f6281-bp-setup.c
arch/arm/mach-kirkwood/dockstar-setup.c
arch/arm/mach-kirkwood/guruplug-setup.c
arch/arm/mach-kirkwood/include/mach/debug-macro.S
arch/arm/mach-kirkwood/include/mach/memory.h [deleted file]
arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
arch/arm/mach-kirkwood/netspace_v2-setup.c
arch/arm/mach-kirkwood/netxbig_v2-setup.c
arch/arm/mach-kirkwood/openrd-setup.c
arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
arch/arm/mach-kirkwood/rd88f6281-setup.c
arch/arm/mach-kirkwood/sheevaplug-setup.c
arch/arm/mach-kirkwood/t5325-setup.c
arch/arm/mach-kirkwood/ts219-setup.c
arch/arm/mach-kirkwood/ts41x-setup.c
arch/arm/mach-ks8695/board-acs5k.c
arch/arm/mach-ks8695/board-dsm320.c
arch/arm/mach-ks8695/board-micrel.c
arch/arm/mach-ks8695/include/mach/debug-macro.S
arch/arm/mach-l7200/include/mach/debug-macro.S
arch/arm/mach-lpc32xx/include/mach/debug-macro.S
arch/arm/mach-lpc32xx/include/mach/memory.h [deleted file]
arch/arm/mach-lpc32xx/phy3250.c
arch/arm/mach-mmp/include/mach/debug-macro.S
arch/arm/mach-mmp/include/mach/memory.h [deleted file]
arch/arm/mach-msm/board-halibut.c
arch/arm/mach-msm/board-mahimahi.c
arch/arm/mach-msm/board-msm7x27.c
arch/arm/mach-msm/board-msm7x30.c
arch/arm/mach-msm/board-msm8x60.c
arch/arm/mach-msm/board-qsd8x50.c
arch/arm/mach-msm/board-sapphire.c
arch/arm/mach-msm/board-trout.c
arch/arm/mach-msm/include/mach/debug-macro.S
arch/arm/mach-msm/include/mach/entry-macro-qgic.S
arch/arm/mach-msm/include/mach/memory.h [deleted file]
arch/arm/mach-msm/timer.c
arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
arch/arm/mach-mv78xx0/db78x00-bp-setup.c
arch/arm/mach-mv78xx0/include/mach/debug-macro.S
arch/arm/mach-mv78xx0/include/mach/memory.h [deleted file]
arch/arm/mach-mv78xx0/rd78x00-masa-setup.c
arch/arm/mach-mx5/board-cpuimx51.c
arch/arm/mach-mx5/board-cpuimx51sd.c
arch/arm/mach-mx5/board-mx51_3ds.c
arch/arm/mach-mx5/board-mx51_babbage.c
arch/arm/mach-mx5/board-mx51_efikamx.c
arch/arm/mach-mx5/board-mx51_efikasb.c
arch/arm/mach-mxs/include/mach/debug-macro.S
arch/arm/mach-mxs/include/mach/memory.h [deleted file]
arch/arm/mach-netx/include/mach/debug-macro.S
arch/arm/mach-netx/include/mach/memory.h [deleted file]
arch/arm/mach-netx/nxdb500.c
arch/arm/mach-netx/nxdkn.c
arch/arm/mach-netx/nxeb500hmi.c
arch/arm/mach-nomadik/board-nhk8815.c
arch/arm/mach-nomadik/include/mach/debug-macro.S
arch/arm/mach-nomadik/include/mach/memory.h [deleted file]
arch/arm/mach-nuc93x/include/mach/memory.h [deleted file]
arch/arm/mach-nuc93x/mach-nuc932evb.c
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/mach-omap1/board-fsample.c
arch/arm/mach-omap1/board-generic.c
arch/arm/mach-omap1/board-h2.c
arch/arm/mach-omap1/board-h3.c
arch/arm/mach-omap1/board-htcherald.c
arch/arm/mach-omap1/board-innovator.c
arch/arm/mach-omap1/board-nokia770.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/board-palmte.c
arch/arm/mach-omap1/board-palmtt.c
arch/arm/mach-omap1/board-palmz71.c
arch/arm/mach-omap1/board-perseus2.c
arch/arm/mach-omap1/board-sx1.c
arch/arm/mach-omap1/board-voiceblue.c
arch/arm/mach-omap1/include/mach/debug-macro.S
arch/arm/mach-omap1/include/mach/memory.h
arch/arm/mach-omap1/io.c
arch/arm/mach-omap2/board-2430sdp.c
arch/arm/mach-omap2/board-3430sdp.c
arch/arm/mach-omap2/board-3630sdp.c
arch/arm/mach-omap2/board-4430sdp.c
arch/arm/mach-omap2/board-am3517crane.c
arch/arm/mach-omap2/board-am3517evm.c
arch/arm/mach-omap2/board-apollon.c
arch/arm/mach-omap2/board-cm-t35.c
arch/arm/mach-omap2/board-cm-t3517.c
arch/arm/mach-omap2/board-devkit8000.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-h4.c
arch/arm/mach-omap2/board-igep0020.c
arch/arm/mach-omap2/board-ldp.c
arch/arm/mach-omap2/board-n8x0.c
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/board-omap3evm.c
arch/arm/mach-omap2/board-omap3logic.c
arch/arm/mach-omap2/board-omap3pandora.c
arch/arm/mach-omap2/board-omap3stalker.c
arch/arm/mach-omap2/board-omap3touchbook.c
arch/arm/mach-omap2/board-omap4panda.c
arch/arm/mach-omap2/board-overo.c
arch/arm/mach-omap2/board-rm680.c
arch/arm/mach-omap2/board-rx51.c
arch/arm/mach-omap2/board-ti8168evm.c
arch/arm/mach-omap2/board-zoom.c
arch/arm/mach-omap2/include/mach/debug-macro.S
arch/arm/mach-omap2/include/mach/entry-macro.S
arch/arm/mach-omap2/include/mach/memory.h [deleted file]
arch/arm/mach-omap2/io.c
arch/arm/mach-orion5x/d2net-setup.c
arch/arm/mach-orion5x/db88f5281-setup.c
arch/arm/mach-orion5x/dns323-setup.c
arch/arm/mach-orion5x/edmini_v2-setup.c
arch/arm/mach-orion5x/include/mach/debug-macro.S
arch/arm/mach-orion5x/include/mach/memory.h [deleted file]
arch/arm/mach-orion5x/kurobox_pro-setup.c
arch/arm/mach-orion5x/ls-chl-setup.c
arch/arm/mach-orion5x/ls_hgl-setup.c
arch/arm/mach-orion5x/lsmini-setup.c
arch/arm/mach-orion5x/mss2-setup.c
arch/arm/mach-orion5x/mv2120-setup.c
arch/arm/mach-orion5x/net2big-setup.c
arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
arch/arm/mach-orion5x/rd88f5182-setup.c
arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
arch/arm/mach-orion5x/terastation_pro2-setup.c
arch/arm/mach-orion5x/ts209-setup.c
arch/arm/mach-orion5x/ts409-setup.c
arch/arm/mach-orion5x/ts78xx-setup.c
arch/arm/mach-orion5x/wnr854t-setup.c
arch/arm/mach-orion5x/wrt350n-v2-setup.c
arch/arm/mach-pnx4008/core.c
arch/arm/mach-pnx4008/include/mach/debug-macro.S
arch/arm/mach-pnx4008/include/mach/memory.h [deleted file]
arch/arm/mach-prima2/include/mach/debug-macro.S
arch/arm/mach-prima2/include/mach/memory.h [deleted file]
arch/arm/mach-prima2/l2x0.c
arch/arm/mach-prima2/prima2.c
arch/arm/mach-pxa/balloon3.c
arch/arm/mach-pxa/capc7117.c
arch/arm/mach-pxa/cm-x2xx.c
arch/arm/mach-pxa/cm-x300.c
arch/arm/mach-pxa/colibri-pxa270.c
arch/arm/mach-pxa/colibri-pxa300.c
arch/arm/mach-pxa/colibri-pxa320.c
arch/arm/mach-pxa/csb726.c
arch/arm/mach-pxa/em-x270.c
arch/arm/mach-pxa/eseries.c
arch/arm/mach-pxa/ezx.c
arch/arm/mach-pxa/gumstix.c
arch/arm/mach-pxa/h5000.c
arch/arm/mach-pxa/himalaya.c
arch/arm/mach-pxa/hx4700.c
arch/arm/mach-pxa/icontrol.c
arch/arm/mach-pxa/include/mach/debug-macro.S
arch/arm/mach-pxa/include/mach/memory.h [deleted file]
arch/arm/mach-pxa/littleton.c
arch/arm/mach-pxa/lpd270.c
arch/arm/mach-pxa/magician.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/mioa701.c
arch/arm/mach-pxa/mp900.c
arch/arm/mach-pxa/palmld.c
arch/arm/mach-pxa/palmt5.c
arch/arm/mach-pxa/palmtc.c
arch/arm/mach-pxa/palmte2.c
arch/arm/mach-pxa/palmtreo.c
arch/arm/mach-pxa/palmtx.c
arch/arm/mach-pxa/palmz72.c
arch/arm/mach-pxa/pcm027.c
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-pxa/saar.c
arch/arm/mach-pxa/saarb.c
arch/arm/mach-pxa/stargate2.c
arch/arm/mach-pxa/tavorevb.c
arch/arm/mach-pxa/tavorevb3.c
arch/arm/mach-pxa/trizeps4.c
arch/arm/mach-pxa/viper.c
arch/arm/mach-pxa/vpac270.c
arch/arm/mach-pxa/xcep.c
arch/arm/mach-pxa/z2.c
arch/arm/mach-pxa/zeus.c
arch/arm/mach-pxa/zylonite.c
arch/arm/mach-realview/include/mach/debug-macro.S
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-realview/realview_pb1176.c
arch/arm/mach-realview/realview_pb11mp.c
arch/arm/mach-realview/realview_pba8.c
arch/arm/mach-realview/realview_pbx.c
arch/arm/mach-rpc/include/mach/debug-macro.S
arch/arm/mach-rpc/riscpc.c
arch/arm/mach-s3c2400/include/mach/memory.h [deleted file]
arch/arm/mach-s3c2410/include/mach/debug-macro.S
arch/arm/mach-s3c2410/include/mach/memory.h [deleted file]
arch/arm/mach-s3c2410/mach-amlm5900.c
arch/arm/mach-s3c2410/mach-bast.c
arch/arm/mach-s3c2410/mach-h1940.c
arch/arm/mach-s3c2410/mach-n30.c
arch/arm/mach-s3c2410/mach-otom.c
arch/arm/mach-s3c2410/mach-qt2410.c
arch/arm/mach-s3c2410/mach-smdk2410.c
arch/arm/mach-s3c2410/mach-tct_hammer.c
arch/arm/mach-s3c2410/mach-vr1000.c
arch/arm/mach-s3c2412/mach-jive.c
arch/arm/mach-s3c2412/mach-smdk2413.c
arch/arm/mach-s3c2412/mach-vstms.c
arch/arm/mach-s3c2416/mach-smdk2416.c
arch/arm/mach-s3c2440/mach-anubis.c
arch/arm/mach-s3c2440/mach-at2440evb.c
arch/arm/mach-s3c2440/mach-gta02.c
arch/arm/mach-s3c2440/mach-mini2440.c
arch/arm/mach-s3c2440/mach-nexcoder.c
arch/arm/mach-s3c2440/mach-osiris.c
arch/arm/mach-s3c2440/mach-rx1950.c
arch/arm/mach-s3c2440/mach-rx3715.c
arch/arm/mach-s3c2440/mach-smdk2440.c
arch/arm/mach-s3c2443/mach-smdk2443.c
arch/arm/mach-s3c64xx/cpu.c
arch/arm/mach-s3c64xx/include/mach/debug-macro.S
arch/arm/mach-s3c64xx/include/mach/memory.h [deleted file]
arch/arm/mach-s3c64xx/mach-anw6410.c
arch/arm/mach-s3c64xx/mach-crag6410.c
arch/arm/mach-s3c64xx/mach-hmt.c
arch/arm/mach-s3c64xx/mach-mini6410.c
arch/arm/mach-s3c64xx/mach-ncp.c
arch/arm/mach-s3c64xx/mach-real6410.c
arch/arm/mach-s3c64xx/mach-smartq5.c
arch/arm/mach-s3c64xx/mach-smartq7.c
arch/arm/mach-s3c64xx/mach-smdk6400.c
arch/arm/mach-s3c64xx/mach-smdk6410.c
arch/arm/mach-s5p64x0/cpu.c
arch/arm/mach-s5p64x0/include/mach/debug-macro.S
arch/arm/mach-s5p64x0/include/mach/memory.h [deleted file]
arch/arm/mach-s5p64x0/mach-smdk6440.c
arch/arm/mach-s5p64x0/mach-smdk6450.c
arch/arm/mach-s5pc100/include/mach/debug-macro.S
arch/arm/mach-s5pc100/include/mach/memory.h [deleted file]
arch/arm/mach-s5pc100/mach-smdkc100.c
arch/arm/mach-s5pv210/cpu.c
arch/arm/mach-s5pv210/include/mach/debug-macro.S
arch/arm/mach-s5pv210/include/mach/memory.h
arch/arm/mach-s5pv210/mach-aquila.c
arch/arm/mach-s5pv210/mach-goni.c
arch/arm/mach-s5pv210/mach-smdkc110.c
arch/arm/mach-s5pv210/mach-smdkv210.c
arch/arm/mach-s5pv210/mach-torbreck.c
arch/arm/mach-sa1100/assabet.c
arch/arm/mach-sa1100/badge4.c
arch/arm/mach-sa1100/h3100.c
arch/arm/mach-sa1100/h3600.c
arch/arm/mach-sa1100/hackkit.c
arch/arm/mach-sa1100/include/mach/debug-macro.S
arch/arm/mach-sa1100/jornada720.c
arch/arm/mach-sa1100/lart.c
arch/arm/mach-sa1100/nanoengine.c
arch/arm/mach-sa1100/shannon.c
arch/arm/mach-sa1100/simpad.c
arch/arm/mach-shark/core.c
arch/arm/mach-shark/include/mach/debug-macro.S
arch/arm/mach-shmobile/board-ag5evm.c
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/board-g3evm.c
arch/arm/mach-shmobile/board-g4evm.c
arch/arm/mach-shmobile/board-mackerel.c
arch/arm/mach-shmobile/entry-intc.S
arch/arm/mach-shmobile/include/mach/entry-macro.S
arch/arm/mach-shmobile/include/mach/memory.h
arch/arm/mach-spear3xx/include/mach/memory.h [deleted file]
arch/arm/mach-spear3xx/spear300_evb.c
arch/arm/mach-spear3xx/spear310_evb.c
arch/arm/mach-spear3xx/spear320_evb.c
arch/arm/mach-spear6xx/include/mach/memory.h [deleted file]
arch/arm/mach-spear6xx/spear600_evb.c
arch/arm/mach-tcc8k/board-tcc8000-sdk.c
arch/arm/mach-tegra/board-harmony.c
arch/arm/mach-tegra/board-paz00.c
arch/arm/mach-tegra/board-seaboard.c
arch/arm/mach-tegra/board-trimslice.c
arch/arm/mach-tegra/include/mach/debug-macro.S
arch/arm/mach-tegra/include/mach/memory.h [deleted file]
arch/arm/mach-u300/core.c
arch/arm/mach-u300/include/mach/debug-macro.S
arch/arm/mach-u300/include/mach/memory.h
arch/arm/mach-u300/u300.c
arch/arm/mach-ux500/board-mop500.c
arch/arm/mach-ux500/board-u5500.c
arch/arm/mach-ux500/include/mach/debug-macro.S
arch/arm/mach-ux500/include/mach/memory.h [deleted file]
arch/arm/mach-versatile/include/mach/debug-macro.S
arch/arm/mach-versatile/include/mach/memory.h [deleted file]
arch/arm/mach-versatile/versatile_ab.c
arch/arm/mach-versatile/versatile_pb.c
arch/arm/mach-vexpress/include/mach/debug-macro.S
arch/arm/mach-vexpress/include/mach/memory.h [deleted file]
arch/arm/mach-vexpress/v2m.c
arch/arm/mach-vt8500/bv07.c
arch/arm/mach-vt8500/include/mach/debug-macro.S
arch/arm/mach-vt8500/include/mach/memory.h [deleted file]
arch/arm/mach-vt8500/wm8505_7in.c
arch/arm/mach-w90x900/include/mach/memory.h [deleted file]
arch/arm/mach-w90x900/mach-nuc910evb.c
arch/arm/mach-w90x900/mach-nuc950evb.c
arch/arm/mach-w90x900/mach-nuc960evb.c
arch/arm/mach-zynq/include/mach/debug-macro.S
arch/arm/mach-zynq/include/mach/memory.h [deleted file]
arch/arm/mm/dma-mapping.c
arch/arm/mm/init.c
arch/arm/mm/mmu.c
arch/arm/mm/proc-arm920.S
arch/arm/mm/proc-arm926.S
arch/arm/mm/proc-sa1100.S
arch/arm/mm/proc-v6.S
arch/arm/mm/proc-v7.S
arch/arm/mm/proc-xsc3.S
arch/arm/mm/proc-xscale.S
arch/arm/plat-mxc/include/mach/debug-macro.S
arch/arm/plat-mxc/include/mach/memory.h [deleted file]
arch/arm/plat-omap/Kconfig
arch/arm/plat-omap/include/plat/io.h
arch/arm/plat-omap/include/plat/memory.h [deleted file]
arch/arm/plat-omap/include/plat/serial.h
arch/arm/plat-omap/include/plat/uncompress.h
arch/arm/plat-omap/io.c
arch/arm/plat-spear/include/plat/debug-macro.S
arch/arm/plat-spear/include/plat/memory.h [deleted file]
arch/arm/plat-tcc/include/mach/debug-macro.S
arch/arm/plat-tcc/include/mach/memory.h [deleted file]
arch/arm/vfp/vfpmodule.c
drivers/usb/musb/musb_debugfs.c
include/linux/cpu_pm.h [new file with mode: 0644]
kernel/Makefile
kernel/cpu_pm.c [new file with mode: 0644]
kernel/power/Kconfig

index e91cec4..5ca86e7 100644 (file)
@@ -29,6 +29,7 @@ config ARM
        select HAVE_GENERIC_HARDIRQS
        select HAVE_SPARSE_IRQ
        select GENERIC_IRQ_SHOW
+       select CPU_PM if (SUSPEND || CPU_IDLE)
        help
          The ARM series is a line of low-power-consumption RISC chip designs
          licensed by ARM Ltd and targeted at embedded applications and
@@ -211,6 +212,19 @@ config ARM_PATCH_PHYS_VIRT
          this feature (eg, building a kernel for a single machine) and
          you need to shrink the kernel to the minimal size.
 
+config NEED_MACH_MEMORY_H
+       bool
+       help
+         Select this when mach/memory.h is required to provide special
+         definitions for this platform.  The need for mach/memory.h should
+         be avoided when possible.
+
+config PHYS_OFFSET
+       hex "Physical address of main memory"
+       depends on !ARM_PATCH_PHYS_VIRT && !NEED_MACH_MEMORY_H
+       help
+         Please provide the physical address corresponding to the
+         location of main memory in your system.
 
 config GENERIC_BUG
        def_bool y
@@ -247,6 +261,7 @@ config ARCH_INTEGRATOR
        select GENERIC_CLOCKEVENTS
        select PLAT_VERSATILE
        select PLAT_VERSATILE_FPGA_IRQ
+       select NEED_MACH_MEMORY_H
        help
          Support for ARM's Integrator platform.
 
@@ -262,6 +277,7 @@ config ARCH_REALVIEW
        select PLAT_VERSATILE_CLCD
        select ARM_TIMER_SP804
        select GPIO_PL061 if GPIOLIB
+       select NEED_MACH_MEMORY_H
        help
          This enables support for ARM Ltd RealView boards.
 
@@ -322,6 +338,7 @@ config ARCH_CLPS711X
        bool "Cirrus Logic CLPS711x/EP721x-based"
        select CPU_ARM720T
        select ARCH_USES_GETTIMEOFFSET
+       select NEED_MACH_MEMORY_H
        help
          Support for Cirrus Logic 711x/721x based boards.
 
@@ -361,6 +378,7 @@ config ARCH_EBSA110
        select ISA
        select NO_IOPORT
        select ARCH_USES_GETTIMEOFFSET
+       select NEED_MACH_MEMORY_H
        help
          This is an evaluation board for the StrongARM processor available
          from Digital. It has limited hardware on-board, including an
@@ -376,6 +394,7 @@ config ARCH_EP93XX
        select ARCH_REQUIRE_GPIOLIB
        select ARCH_HAS_HOLES_MEMORYMODEL
        select ARCH_USES_GETTIMEOFFSET
+       select NEED_MEMORY_H
        help
          This enables support for the Cirrus EP93xx series of CPUs.
 
@@ -385,6 +404,7 @@ config ARCH_FOOTBRIDGE
        select FOOTBRIDGE
        select GENERIC_CLOCKEVENTS
        select HAVE_IDE
+       select NEED_MACH_MEMORY_H
        help
          Support for systems based on the DC21285 companion chip
          ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
@@ -434,6 +454,7 @@ config ARCH_IOP13XX
        select PCI
        select ARCH_SUPPORTS_MSI
        select VMSPLIT_1G
+       select NEED_MACH_MEMORY_H
        help
          Support for Intel's IOP13XX (XScale) family of processors.
 
@@ -464,6 +485,7 @@ config ARCH_IXP23XX
        select CPU_XSC3
        select PCI
        select ARCH_USES_GETTIMEOFFSET
+       select NEED_MACH_MEMORY_H
        help
          Support for Intel's IXP23xx (XScale) family of processors.
 
@@ -473,6 +495,7 @@ config ARCH_IXP2000
        select CPU_XSCALE
        select PCI
        select ARCH_USES_GETTIMEOFFSET
+       select NEED_MACH_MEMORY_H
        help
          Support for Intel's IXP2400/2800 (XScale) family of processors.
 
@@ -565,6 +588,7 @@ config ARCH_KS8695
        select CPU_ARM922T
        select ARCH_REQUIRE_GPIOLIB
        select ARCH_USES_GETTIMEOFFSET
+       select NEED_MACH_MEMORY_H
        help
          Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
          System-on-Chip devices.
@@ -657,6 +681,7 @@ config ARCH_SHMOBILE
        select SPARSE_IRQ
        select MULTI_IRQ_HANDLER
        select PM_GENERIC_DOMAINS if PM
+       select NEED_MACH_MEMORY_H
        help
          Support for Renesas's SH-Mobile and R-Mobile ARM platforms.
 
@@ -672,6 +697,7 @@ config ARCH_RPC
        select ARCH_SPARSEMEM_ENABLE
        select ARCH_USES_GETTIMEOFFSET
        select HAVE_IDE
+       select NEED_MACH_MEMORY_H
        help
          On the Acorn Risc-PC, Linux can support the internal IDE disk and
          CD-ROM interface, serial and parallel port, and the floppy drive.
@@ -691,6 +717,7 @@ config ARCH_SA1100
        select TICK_ONESHOT
        select ARCH_REQUIRE_GPIOLIB
        select HAVE_IDE
+       select NEED_MACH_MEMORY_H
        help
          Support for StrongARM 11x0 based boards.
 
@@ -782,6 +809,7 @@ config ARCH_S5PV210
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C_RTC if RTC_CLASS
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
+       select NEED_MACH_MEMORY_H
        help
          Samsung S5PV210/S5PC110 series based systems
 
@@ -798,6 +826,7 @@ config ARCH_EXYNOS4
        select HAVE_S3C_RTC if RTC_CLASS
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
+       select NEED_MACH_MEMORY_H
        help
          Samsung EXYNOS4 series based systems
 
@@ -809,6 +838,7 @@ config ARCH_SHARK
        select ZONE_DMA
        select PCI
        select ARCH_USES_GETTIMEOFFSET
+       select NEED_MACH_MEMORY_H
        help
          Support for the StrongARM based Digital DNARD machine, also known
          as "Shark" (<http://www.shark-linux.de/shark.html>).
@@ -837,6 +867,7 @@ config ARCH_U300
        select HAVE_MACH_CLKDEV
        select GENERIC_GPIO
        select ARCH_REQUIRE_GPIOLIB
+       select NEED_MACH_MEMORY_H
        help
          Support for ST-Ericsson U300 series mobile platforms.
 
@@ -1835,6 +1866,38 @@ config ZBOOT_ROM_SH_MOBILE_SDHI
 
 endchoice
 
+config ARM_APPENDED_DTB
+       bool "Use appended device tree blob to zImage (EXPERIMENTAL)"
+       depends on OF && !ZBOOT_ROM && EXPERIMENTAL
+       help
+         With this option, the boot code will look for a device tree binary
+         (DTB) appended to zImage
+         (e.g. cat zImage <filename>.dtb > zImage_w_dtb).
+
+         This is meant as a backward compatibility convenience for those
+         systems with a bootloader that can't be upgraded to accommodate
+         the documented boot protocol using a device tree.
+
+         Beware that there is very little in terms of protection against
+         this option being confused by leftover garbage in memory that might
+         look like a DTB header after a reboot if no actual DTB is appended
+         to zImage.  Do not leave this option active in a production kernel
+         if you don't intend to always append a DTB.  Proper passing of the
+         location into r2 of a bootloader provided DTB is always preferable
+         to this option.
+
+config ARM_ATAG_DTB_COMPAT
+       bool "Supplement the appended DTB with traditional ATAG information"
+       depends on ARM_APPENDED_DTB
+       help
+         Some old bootloaders can't be updated to a DTB capable one, yet
+         they provide ATAGs with memory configuration, the ramdisk address,
+         the kernel cmdline string, etc.  Such information is dynamically
+         provided by the bootloader and can't always be stored in a static
+         DTB.  To allow a device tree enabled kernel to be used with such
+         bootloaders, this option allows zImage to extract the information
+         from the ATAG list and store it at run time into the appended DTB.
+
 config CMDLINE
        string "Default kernel command string"
        default ""
index df3eb3c..f283938 100644 (file)
@@ -158,4 +158,10 @@ config DEBUG_S3C_UART
          The uncompressor code port configuration is now handled
          by CONFIG_S3C_LOWLEVEL_UART_PORT.
 
+config ARM_KPROBES_TEST
+       tristate "Kprobes test module"
+       depends on KPROBES && MODULES
+       help
+         Perform tests of kprobes API and instruction set simulation.
+
 endmenu
index c602896..e0936a1 100644 (file)
@@ -5,3 +5,12 @@ piggy.lzo
 piggy.lzma
 vmlinux
 vmlinux.lds
+
+# borrowed libfdt files
+fdt.c
+fdt.h
+fdt_ro.c
+fdt_rw.c
+fdt_wip.c
+libfdt.h
+libfdt_internal.h
index a6b30b3..21f56ff 100644 (file)
@@ -26,6 +26,10 @@ HEAD = head.o
 OBJS   += misc.o decompress.o
 FONTC  = $(srctree)/drivers/video/console/font_acorn_8x8.c
 
+# string library code (-Os is enforced to keep it much smaller)
+OBJS           += string.o
+CFLAGS_string.o        := -Os
+
 #
 # Architecture dependencies
 #
@@ -89,21 +93,41 @@ suffix_$(CONFIG_KERNEL_GZIP) = gzip
 suffix_$(CONFIG_KERNEL_LZO)  = lzo
 suffix_$(CONFIG_KERNEL_LZMA) = lzma
 
+# Borrowed libfdt files for the ATAG compatibility mode
+
+libfdt         := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c
+libfdt_hdrs    := fdt.h libfdt.h libfdt_internal.h
+
+libfdt_objs    := $(addsuffix .o, $(basename $(libfdt)))
+
+$(addprefix $(obj)/,$(libfdt) $(libfdt_hdrs)): $(obj)/%: $(srctree)/scripts/dtc/libfdt/%
+       $(call cmd,shipped)
+
+$(addprefix $(obj)/,$(libfdt_objs) atags_to_fdt.o): \
+       $(addprefix $(obj)/,$(libfdt_hdrs))
+
+ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
+OBJS   += $(libfdt_objs) atags_to_fdt.o
+endif
+
 targets       := vmlinux vmlinux.lds \
                 piggy.$(suffix_y) piggy.$(suffix_y).o \
-                font.o font.c head.o misc.o $(OBJS)
+                lib1funcs.o lib1funcs.S font.o font.c head.o misc.o $(OBJS)
 
 # Make sure files are removed during clean
-extra-y       += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S
+extra-y       += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S $(libfdt) $(libfdt_hdrs)
 
 ifeq ($(CONFIG_FUNCTION_TRACER),y)
 ORIG_CFLAGS := $(KBUILD_CFLAGS)
 KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
 endif
 
-ccflags-y := -fpic -fno-builtin
+ccflags-y := -fpic -fno-builtin -I$(obj)
 asflags-y := -Wa,-march=all
 
+# Supply kernel BSS size to the decompressor via a linker symbol.
+KBSS_SZ = $(shell size $(obj)/../../../../vmlinux | awk 'END{print $$3}')
+LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
 # Supply ZRELADDR to the decompressor via a linker symbol.
 ifneq ($(CONFIG_AUTO_ZRELADDR),y)
 LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR)
@@ -123,7 +147,7 @@ LDFLAGS_vmlinux += -T
 # For __aeabi_uidivmod
 lib1funcs = $(obj)/lib1funcs.o
 
-$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE
+$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
        $(call cmd,shipped)
 
 # We need to prevent any GOTOFF relocs being used with references
diff --git a/arch/arm/boot/compressed/atags_to_fdt.c b/arch/arm/boot/compressed/atags_to_fdt.c
new file mode 100644 (file)
index 0000000..6ce11c4
--- /dev/null
@@ -0,0 +1,97 @@
+#include <asm/setup.h>
+#include <libfdt.h>
+
+static int node_offset(void *fdt, const char *node_path)
+{
+       int offset = fdt_path_offset(fdt, node_path);
+       if (offset == -FDT_ERR_NOTFOUND)
+               offset = fdt_add_subnode(fdt, 0, node_path);
+       return offset;
+}
+
+static int setprop(void *fdt, const char *node_path, const char *property,
+                  uint32_t *val_array, int size)
+{
+       int offset = node_offset(fdt, node_path);
+       if (offset < 0)
+               return offset;
+       return fdt_setprop(fdt, offset, property, val_array, size);
+}
+
+static int setprop_string(void *fdt, const char *node_path,
+                         const char *property, const char *string)
+{
+       int offset = node_offset(fdt, node_path);
+       if (offset < 0)
+               return offset;
+       return fdt_setprop_string(fdt, offset, property, string);
+}
+
+static int setprop_cell(void *fdt, const char *node_path,
+                       const char *property, uint32_t val)
+{
+       int offset = node_offset(fdt, node_path);
+       if (offset < 0)
+               return offset;
+       return fdt_setprop_cell(fdt, offset, property, val);
+}
+
+/*
+ * Convert and fold provided ATAGs into the provided FDT.
+ *
+ * REturn values:
+ *    = 0 -> pretend success
+ *    = 1 -> bad ATAG (may retry with another possible ATAG pointer)
+ *    < 0 -> error from libfdt
+ */
+int atags_to_fdt(void *atag_list, void *fdt, int total_space)
+{
+       struct tag *atag = atag_list;
+       uint32_t mem_reg_property[2 * NR_BANKS];
+       int memcount = 0;
+       int ret;
+
+       /* make sure we've got an aligned pointer */
+       if ((u32)atag_list & 0x3)
+               return 1;
+
+       /* if we get a DTB here we're done already */
+       if (*(u32 *)atag_list == fdt32_to_cpu(FDT_MAGIC))
+              return 0;
+
+       /* validate the ATAG */
+       if (atag->hdr.tag != ATAG_CORE ||
+           (atag->hdr.size != tag_size(tag_core) &&
+            atag->hdr.size != 2))
+               return 1;
+
+       /* let's give it all the room it could need */
+       ret = fdt_open_into(fdt, fdt, total_space);
+       if (ret < 0)
+               return ret;
+
+       for_each_tag(atag, atag_list) {
+               if (atag->hdr.tag == ATAG_CMDLINE) {
+                       setprop_string(fdt, "/chosen", "bootargs",
+                                       atag->u.cmdline.cmdline);
+               } else if (atag->hdr.tag == ATAG_MEM) {
+                       if (memcount >= sizeof(mem_reg_property)/4)
+                               continue;
+                       mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start);
+                       mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size);
+               } else if (atag->hdr.tag == ATAG_INITRD2) {
+                       uint32_t initrd_start, initrd_size;
+                       initrd_start = atag->u.initrd.start;
+                       initrd_size = atag->u.initrd.size;
+                       setprop_cell(fdt, "/chosen", "linux,initrd-start",
+                                       initrd_start);
+                       setprop_cell(fdt, "/chosen", "linux,initrd-end",
+                                       initrd_start + initrd_size);
+               }
+       }
+
+       if (memcount)
+               setprop(fdt, "/memory", "reg", mem_reg_property, 4*memcount);
+
+       return fdt_pack(fdt);
+}
index e95a598..c2effc9 100644 (file)
@@ -216,6 +216,104 @@ restart:  adr     r0, LC0
                mov     r10, r6
 #endif
 
+               mov     r5, #0                  @ init dtb size to 0
+#ifdef CONFIG_ARM_APPENDED_DTB
+/*
+ *   r0  = delta
+ *   r2  = BSS start
+ *   r3  = BSS end
+ *   r4  = final kernel address
+ *   r5  = appended dtb size (still unknown)
+ *   r6  = _edata
+ *   r7  = architecture ID
+ *   r8  = atags/device tree pointer
+ *   r9  = size of decompressed image
+ *   r10 = end of this image, including  bss/stack/malloc space if non XIP
+ *   r11 = GOT start
+ *   r12 = GOT end
+ *   sp  = stack pointer
+ *
+ * if there are device trees (dtb) appended to zImage, advance r10 so that the
+ * dtb data will get relocated along with the kernel if necessary.
+ */
+
+               ldr     lr, [r6, #0]
+#ifndef __ARMEB__
+               ldr     r1, =0xedfe0dd0         @ sig is 0xd00dfeed big endian
+#else
+               ldr     r1, =0xd00dfeed
+#endif
+               cmp     lr, r1
+               bne     dtb_check_done          @ not found
+
+#ifdef CONFIG_ARM_ATAG_DTB_COMPAT
+               /*
+                * OK... Let's do some funky business here.
+                * If we do have a DTB appended to zImage, and we do have
+                * an ATAG list around, we want the later to be translated
+                * and folded into the former here.  To be on the safe side,
+                * let's temporarily move  the stack away into the malloc
+                * area.  No GOT fixup has occurred yet, but none of the
+                * code we're about to call uses any global variable.
+               */
+               add     sp, sp, #0x10000
+               stmfd   sp!, {r0-r3, ip, lr}
+               mov     r0, r8
+               mov     r1, r6
+               sub     r2, sp, r6
+               bl      atags_to_fdt
+
+               /*
+                * If returned value is 1, there is no ATAG at the location
+                * pointed by r8.  Try the typical 0x100 offset from start
+                * of RAM and hope for the best.
+                */
+               cmp     r0, #1
+               sub     r0, r4, #TEXT_OFFSET
+               add     r0, r0, #0x100
+               mov     r1, r6
+               sub     r2, sp, r6
+               blne    atags_to_fdt
+
+               ldmfd   sp!, {r0-r3, ip, lr}
+               sub     sp, sp, #0x10000
+#endif
+
+               mov     r8, r6                  @ use the appended device tree
+
+               /*
+                * Make sure that the DTB doesn't end up in the final
+                * kernel's .bss area. To do so, we adjust the decompressed
+                * kernel size to compensate if that .bss size is larger
+                * than the relocated code.
+                */
+               ldr     r5, =_kernel_bss_size
+               adr     r1, wont_overwrite
+               sub     r1, r6, r1
+               subs    r1, r5, r1
+               addhi   r9, r9, r1
+
+               /* Get the dtb's size */
+               ldr     r5, [r6, #4]
+#ifndef __ARMEB__
+               /* convert r5 (dtb size) to little endian */
+               eor     r1, r5, r5, ror #16
+               bic     r1, r1, #0x00ff0000
+               mov     r5, r5, ror #8
+               eor     r5, r5, r1, lsr #8
+#endif
+
+               /* preserve 64-bit alignment */
+               add     r5, r5, #7
+               bic     r5, r5, #7
+
+               /* relocate some pointers past the appended dtb */
+               add     r6, r6, r5
+               add     r10, r10, r5
+               add     sp, sp, r5
+dtb_check_done:
+#endif
+
 /*
  * Check to see if we will overwrite ourselves.
  *   r4  = final kernel address
@@ -223,15 +321,14 @@ restart:  adr     r0, LC0
  *   r10 = end of this image, including  bss/stack/malloc space if non XIP
  * We basically want:
  *   r4 - 16k page directory >= r10 -> OK
- *   r4 + image length <= current position (pc) -> OK
+ *   r4 + image length <= address of wont_overwrite -> OK
  */
                add     r10, r10, #16384
                cmp     r4, r10
                bhs     wont_overwrite
                add     r10, r4, r9
-   ARM(                cmp     r10, pc         )
- THUMB(                mov     lr, pc          )
- THUMB(                cmp     r10, lr         )
+               adr     r9, wont_overwrite
+               cmp     r10, r9
                bls     wont_overwrite
 
 /*
@@ -285,14 +382,16 @@ wont_overwrite:
  *   r2  = BSS start
  *   r3  = BSS end
  *   r4  = kernel execution address
+ *   r5  = appended dtb size (0 if not present)
  *   r7  = architecture ID
  *   r8  = atags pointer
  *   r11 = GOT start
  *   r12 = GOT end
  *   sp  = stack pointer
  */
-               teq     r0, #0
+               orrs    r1, r0, r5
                beq     not_relocated
+
                add     r11, r11, r0
                add     r12, r12, r0
 
@@ -307,12 +406,21 @@ wont_overwrite:
 
                /*
                 * Relocate all entries in the GOT table.
+                * Bump bss entries to _edata + dtb size
                 */
 1:             ldr     r1, [r11, #0]           @ relocate entries in the GOT
-               add     r1, r1, r0              @ table.  This fixes up the
-               str     r1, [r11], #4           @ C references.
+               add     r1, r1, r0              @ This fixes up C references
+               cmp     r1, r2                  @ if entry >= bss_start &&
+               cmphs   r3, r1                  @       bss_end > entry
+               addhi   r1, r1, r5              @    entry += dtb size
+               str     r1, [r11], #4           @ next entry
                cmp     r11, r12
                blo     1b
+
+               /* bump our bss pointers too */
+               add     r2, r2, r5
+               add     r3, r3, r5
+
 #else
 
                /*
diff --git a/arch/arm/boot/compressed/libfdt_env.h b/arch/arm/boot/compressed/libfdt_env.h
new file mode 100644 (file)
index 0000000..1f4e718
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef _ARM_LIBFDT_ENV_H
+#define _ARM_LIBFDT_ENV_H
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <asm/byteorder.h>
+
+#define fdt16_to_cpu(x)                be16_to_cpu(x)
+#define cpu_to_fdt16(x)                cpu_to_be16(x)
+#define fdt32_to_cpu(x)                be32_to_cpu(x)
+#define cpu_to_fdt32(x)                cpu_to_be32(x)
+#define fdt64_to_cpu(x)                be64_to_cpu(x)
+#define cpu_to_fdt64(x)                cpu_to_be64(x)
+
+#endif
index 832d372..8e2a8fc 100644 (file)
 
 unsigned int __machine_arch_type;
 
-#define _LINUX_STRING_H_
-
 #include <linux/compiler.h>    /* for inline */
-#include <linux/types.h>       /* for size_t */
-#include <linux/stddef.h>      /* for NULL */
+#include <linux/types.h>
 #include <linux/linkage.h>
-#include <asm/string.h>
-
 
 static void putstr(const char *ptr);
 extern void error(char *x);
@@ -101,41 +96,6 @@ static void putstr(const char *ptr)
        flush();
 }
 
-
-void *memcpy(void *__dest, __const void *__src, size_t __n)
-{
-       int i = 0;
-       unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
-
-       for (i = __n >> 3; i > 0; i--) {
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-       }
-
-       if (__n & 1 << 2) {
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-       }
-
-       if (__n & 1 << 1) {
-               *d++ = *s++;
-               *d++ = *s++;
-       }
-
-       if (__n & 1)
-               *d++ = *s++;
-
-       return __dest;
-}
-
 /*
  * gzip declarations
  */
diff --git a/arch/arm/boot/compressed/string.c b/arch/arm/boot/compressed/string.c
new file mode 100644 (file)
index 0000000..36e53ef
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * arch/arm/boot/compressed/string.c
+ *
+ * Small subset of simple string routines
+ */
+
+#include <linux/string.h>
+
+void *memcpy(void *__dest, __const void *__src, size_t __n)
+{
+       int i = 0;
+       unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
+
+       for (i = __n >> 3; i > 0; i--) {
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+       }
+
+       if (__n & 1 << 2) {
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+       }
+
+       if (__n & 1 << 1) {
+               *d++ = *s++;
+               *d++ = *s++;
+       }
+
+       if (__n & 1)
+               *d++ = *s++;
+
+       return __dest;
+}
+
+void *memmove(void *__dest, __const void *__src, size_t count)
+{
+       unsigned char *d = __dest;
+       const unsigned char *s = __src;
+
+       if (__dest == __src)
+               return __dest;
+
+       if (__dest < __src)
+               return memcpy(__dest, __src, count);
+
+       while (count--)
+               d[count] = s[count];
+       return __dest;
+}
+
+size_t strlen(const char *s)
+{
+       const char *sc = s;
+
+       while (*sc != '\0')
+               sc++;
+       return sc - s;
+}
+
+int memcmp(const void *cs, const void *ct, size_t count)
+{
+       const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;
+       int res = 0;
+
+       while (su1 < end) {
+               res = *su1++ - *su2++;
+               if (res)
+                       break;
+       }
+       return res;
+}
+
+int strcmp(const char *cs, const char *ct)
+{
+       unsigned char c1, c2;
+       int res = 0;
+
+       do {
+               c1 = *cs++;
+               c2 = *ct++;
+               res = c1 - c2;
+               if (res)
+                       break;
+       } while (c1);
+       return res;
+}
+
+void *memchr(const void *s, int c, size_t count)
+{
+       const unsigned char *p = s;
+
+       while (count--)
+               if ((unsigned char)c == *p++)
+                       return (void *)(p - 1);
+       return NULL;
+}
+
+char *strchr(const char *s, int c)
+{
+       while (*s != (char)c)
+               if (*s++ == '\0')
+                       return NULL;
+       return (char *)s;
+}
+
+#undef memset
+
+void *memset(void *s, int c, size_t count)
+{
+       char *xs = s;
+       while (count--)
+               *xs++ = c;
+       return s;
+}
+
+void __memzero(void *s, size_t count)
+{
+       memset(s, 0, count);
+}
index 4e72883..4919f2a 100644 (file)
@@ -51,6 +51,10 @@ SECTIONS
   _got_start = .;
   .got                 : { *(.got) }
   _got_end = .;
+
+  /* ensure the zImage file size is always a multiple of 64 bits */
+  /* (without a dummy byte, ld just ignores the empty section) */
+  .pad                 : { BYTE(0); . = ALIGN(8); }
   _edata = .;
 
   . = BSS_START;
index bdbb3f7..a8fc6b2 100644 (file)
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/smp.h>
+#include <linux/cpu_pm.h>
 #include <linux/cpumask.h>
 #include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
@@ -262,6 +266,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
        u32 cpumask;
        void __iomem *base = gic->dist_base;
        u32 cpu = 0;
+       u32 nrppis = 0, ppi_base = 0;
 
 #ifdef CONFIG_SMP
        cpu = cpu_logical_map(smp_processor_id());
@@ -282,6 +287,25 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
        if (gic_irqs > 1020)
                gic_irqs = 1020;
 
+       gic->gic_irqs = gic_irqs;
+
+       /*
+        * Nobody would be insane enough to use PPIs on a secondary
+        * GIC, right?
+        */
+       if (gic == &gic_data[0]) {
+               nrppis = (32 - irq_start) & 31;
+
+               /* The GIC only supports up to 16 PPIs. */
+               if (nrppis > 16)
+                       BUG();
+
+               ppi_base = gic->irq_offset + 32 - nrppis;
+       }
+
+       pr_info("Configuring GIC with %d sources (%d PPIs)\n",
+               gic_irqs, (gic == &gic_data[0]) ? nrppis : 0);
+
        /*
         * Set all global interrupts to be level triggered, active low.
         */
@@ -317,7 +341,17 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
        /*
         * Setup the Linux IRQ subsystem.
         */
-       for (i = irq_start; i < irq_limit; i++) {
+       for (i = 0; i < nrppis; i++) {
+               int ppi = i + ppi_base;
+
+               irq_set_percpu_devid(ppi);
+               irq_set_chip_and_handler(ppi, &gic_chip,
+                                        handle_percpu_devid_irq);
+               irq_set_chip_data(ppi, gic);
+               set_irq_flags(ppi, IRQF_VALID | IRQF_NOAUTOEN);
+       }
+
+       for (i = irq_start + nrppis; i < irq_limit; i++) {
                irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq);
                irq_set_chip_data(i, gic);
                set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
@@ -349,6 +383,189 @@ static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
        writel_relaxed(1, base + GIC_CPU_CTRL);
 }
 
+#ifdef CONFIG_CPU_PM
+/*
+ * Saves the GIC distributor registers during suspend or idle.  Must be called
+ * with interrupts disabled but before powering down the GIC.  After calling
+ * this function, no interrupts will be delivered by the GIC, and another
+ * platform-specific wakeup source must be enabled.
+ */
+static void gic_dist_save(unsigned int gic_nr)
+{
+       unsigned int gic_irqs;
+       void __iomem *dist_base;
+       int i;
+
+       if (gic_nr >= MAX_GIC_NR)
+               BUG();
+
+       gic_irqs = gic_data[gic_nr].gic_irqs;
+       dist_base = gic_data[gic_nr].dist_base;
+
+       if (!dist_base)
+               return;
+
+       for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
+               gic_data[gic_nr].saved_spi_conf[i] =
+                       readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
+
+       for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
+               gic_data[gic_nr].saved_spi_target[i] =
+                       readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4);
+
+       for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
+               gic_data[gic_nr].saved_spi_enable[i] =
+                       readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
+}
+
+/*
+ * Restores the GIC distributor registers during resume or when coming out of
+ * idle.  Must be called before enabling interrupts.  If a level interrupt
+ * that occured while the GIC was suspended is still present, it will be
+ * handled normally, but any edge interrupts that occured will not be seen by
+ * the GIC and need to be handled by the platform-specific wakeup source.
+ */
+static void gic_dist_restore(unsigned int gic_nr)
+{
+       unsigned int gic_irqs;
+       unsigned int i;
+       void __iomem *dist_base;
+
+       if (gic_nr >= MAX_GIC_NR)
+               BUG();
+
+       gic_irqs = gic_data[gic_nr].gic_irqs;
+       dist_base = gic_data[gic_nr].dist_base;
+
+       if (!dist_base)
+               return;
+
+       writel_relaxed(0, dist_base + GIC_DIST_CTRL);
+
+       for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
+               writel_relaxed(gic_data[gic_nr].saved_spi_conf[i],
+                       dist_base + GIC_DIST_CONFIG + i * 4);
+
+       for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
+               writel_relaxed(0xa0a0a0a0,
+                       dist_base + GIC_DIST_PRI + i * 4);
+
+       for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
+               writel_relaxed(gic_data[gic_nr].saved_spi_target[i],
+                       dist_base + GIC_DIST_TARGET + i * 4);
+
+       for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
+               writel_relaxed(gic_data[gic_nr].saved_spi_enable[i],
+                       dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+       writel_relaxed(1, dist_base + GIC_DIST_CTRL);
+}
+
+static void gic_cpu_save(unsigned int gic_nr)
+{
+       int i;
+       u32 *ptr;
+       void __iomem *dist_base;
+       void __iomem *cpu_base;
+
+       if (gic_nr >= MAX_GIC_NR)
+               BUG();
+
+       dist_base = gic_data[gic_nr].dist_base;
+       cpu_base = gic_data[gic_nr].cpu_base;
+
+       if (!dist_base || !cpu_base)
+               return;
+
+       ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_enable);
+       for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
+               ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+       ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_conf);
+       for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
+               ptr[i] = readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
+
+}
+
+static void gic_cpu_restore(unsigned int gic_nr)
+{
+       int i;
+       u32 *ptr;
+       void __iomem *dist_base;
+       void __iomem *cpu_base;
+
+       if (gic_nr >= MAX_GIC_NR)
+               BUG();
+
+       dist_base = gic_data[gic_nr].dist_base;
+       cpu_base = gic_data[gic_nr].cpu_base;
+
+       if (!dist_base || !cpu_base)
+               return;
+
+       ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_enable);
+       for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
+               writel_relaxed(ptr[i], dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+       ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_conf);
+       for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
+               writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
+
+       for (i = 0; i < DIV_ROUND_UP(32, 4); i++)
+               writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4);
+
+       writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK);
+       writel_relaxed(1, cpu_base + GIC_CPU_CTRL);
+}
+
+static int gic_notifier(struct notifier_block *self, unsigned long cmd,        void *v)
+{
+       int i;
+
+       for (i = 0; i < MAX_GIC_NR; i++) {
+               switch (cmd) {
+               case CPU_PM_ENTER:
+                       gic_cpu_save(i);
+                       break;
+               case CPU_PM_ENTER_FAILED:
+               case CPU_PM_EXIT:
+                       gic_cpu_restore(i);
+                       break;
+               case CPU_CLUSTER_PM_ENTER:
+                       gic_dist_save(i);
+                       break;
+               case CPU_CLUSTER_PM_ENTER_FAILED:
+               case CPU_CLUSTER_PM_EXIT:
+                       gic_dist_restore(i);
+                       break;
+               }
+       }
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block gic_notifier_block = {
+       .notifier_call = gic_notifier,
+};
+
+static void __init gic_pm_init(struct gic_chip_data *gic)
+{
+       gic->saved_ppi_enable = __alloc_percpu(DIV_ROUND_UP(32, 32) * 4,
+               sizeof(u32));
+       BUG_ON(!gic->saved_ppi_enable);
+
+       gic->saved_ppi_conf = __alloc_percpu(DIV_ROUND_UP(32, 16) * 4,
+               sizeof(u32));
+       BUG_ON(!gic->saved_ppi_conf);
+
+       cpu_pm_register_notifier(&gic_notifier_block);
+}
+#else
+static void __init gic_pm_init(struct gic_chip_data *gic)
+{
+}
+#endif
+
 void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
        void __iomem *dist_base, void __iomem *cpu_base)
 {
@@ -364,8 +581,10 @@ void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
        if (gic_nr == 0)
                gic_cpu_base_addr = cpu_base;
 
+       gic_chip.flags |= gic_arch_extn.flags;
        gic_dist_init(gic, irq_start);
        gic_cpu_init(gic);
+       gic_pm_init(gic);
 }
 
 void __cpuinit gic_secondary_init(unsigned int gic_nr)
@@ -375,16 +594,6 @@ void __cpuinit gic_secondary_init(unsigned int gic_nr)
        gic_cpu_init(&gic_data[gic_nr]);
 }
 
-void __cpuinit gic_enable_ppi(unsigned int irq)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-       irq_set_status_flags(irq, IRQ_NOPROBE);
-       gic_unmask_irq(irq_get_irq_data(irq));
-       local_irq_restore(flags);
-}
-
 #ifdef CONFIG_SMP
 void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
 {
index 28b7ee8..cb3b7c9 100644 (file)
@@ -205,6 +205,13 @@ extern void *dma_alloc_writecombine(struct device *, size_t, dma_addr_t *,
 int dma_mmap_writecombine(struct device *, struct vm_area_struct *,
                void *, dma_addr_t, size_t);
 
+/*
+ * This can be called during boot to increase the size of the consistent
+ * DMA region above it's default value of 2MB. It must be called before the
+ * memory allocator is initialised, i.e. before any core_initcall.
+ */
+extern void __init init_consistent_dma_size(unsigned long size);
+
 
 #ifdef CONFIG_DMABOUNCE
 /*
index 2f1e209..88d6181 100644 (file)
        movne   r1, sp
        adrne   lr, BSYM(1b)
        bne     do_IPI
-
-#ifdef CONFIG_LOCAL_TIMERS
-       test_for_ltirq r0, r2, r6, lr
-       movne   r0, sp
-       adrne   lr, BSYM(1b)
-       bne     do_local_timer
-#endif
 #endif
 9997:
        .endm
index 89ad180..ddf07a9 100644 (file)
@@ -9,9 +9,6 @@
 
 typedef struct {
        unsigned int __softirq_pending;
-#ifdef CONFIG_LOCAL_TIMERS
-       unsigned int local_timer_irqs;
-#endif
 #ifdef CONFIG_SMP
        unsigned int ipi_irqs[NR_IPI];
 #endif
index c115b82..74ebc80 100644 (file)
  * interrupt controller spec.  To wit:
  *
  * Interrupts 0-15 are IPI
- * 16-28 are reserved
- * 29-31 are local.  We allow 30 to be used for the watchdog.
+ * 16-31 are local.  We allow 30 to be used for the watchdog.
  * 32-1020 are global
  * 1021-1022 are reserved
  * 1023 is "spurious" (no interrupt)
  *
- * For now, we ignore all local interrupts so only return an interrupt if it's
- * between 30 and 1020.  The test_for_ipi routine below will pick up on IPIs.
- *
  * A simple read from the controller will tell us the number of the highest
  * priority enabled interrupt.  We then just need to check whether it is in the
  * valid range for an IRQ (30-1020 inclusive).
@@ -43,7 +39,7 @@
 
        ldr     \tmp, =1021
        bic     \irqnr, \irqstat, #0x1c00
-       cmp     \irqnr, #29
+       cmp     \irqnr, #15
        cmpcc   \irqnr, \irqnr
        cmpne   \irqnr, \tmp
        cmpcs   \irqnr, \irqnr
        strcc   \irqstat, [\base, #GIC_CPU_EOI]
        cmpcs   \irqnr, \irqnr
        .endm
-
-/* As above, this assumes that irqstat and base are preserved.. */
-
-       .macro test_for_ltirq, irqnr, irqstat, base, tmp
-       bic     \irqnr, \irqstat, #0x1c00
-       mov     \tmp, #0
-       cmp     \irqnr, #29
-       moveq   \tmp, #1
-       streq   \irqstat, [\base, #GIC_CPU_EOI]
-       cmp     \tmp, #0
-       .endm
index 435d3f8..14867e1 100644 (file)
@@ -40,12 +40,19 @@ void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
 void gic_secondary_init(unsigned int);
 void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
 void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
-void gic_enable_ppi(unsigned int);
 
 struct gic_chip_data {
        unsigned int irq_offset;
        void __iomem *dist_base;
        void __iomem *cpu_base;
+#ifdef CONFIG_CPU_PM
+       u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)];
+       u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)];
+       u32 saved_spi_target[DIV_ROUND_UP(1020, 4)];
+       u32 __percpu *saved_ppi_enable;
+       u32 __percpu *saved_ppi_conf;
+#endif
+       unsigned int gic_irqs;
 };
 #endif
 
index f389b27..c190bc9 100644 (file)
@@ -50,6 +50,7 @@ static inline void decode_ctrl_reg(u32 reg,
 #define ARM_DEBUG_ARCH_V6_1    2
 #define ARM_DEBUG_ARCH_V7_ECP14        3
 #define ARM_DEBUG_ARCH_V7_MM   4
+#define ARM_DEBUG_ARCH_V7_1    5
 
 /* Breakpoint */
 #define ARM_BREAKPOINT_EXECUTE 0
@@ -57,6 +58,7 @@ static inline void decode_ctrl_reg(u32 reg,
 /* Watchpoints */
 #define ARM_BREAKPOINT_LOAD    1
 #define ARM_BREAKPOINT_STORE   2
+#define ARM_FSR_ACCESS_MASK    (1 << 11)
 
 /* Privilege Levels */
 #define ARM_BREAKPOINT_PRIV    1
index 6fd955d..c6a1842 100644 (file)
@@ -11,6 +11,7 @@
 #define __ASM_ARM_LOCALTIMER_H
 
 #include <linux/errno.h>
+#include <linux/interrupt.h>
 
 struct clock_event_device;
 
@@ -19,31 +20,20 @@ struct clock_event_device;
  */
 void percpu_timer_setup(void);
 
-/*
- * Called from assembly, this is the local timer IRQ handler
- */
-asmlinkage void do_local_timer(struct pt_regs *);
-
-/*
- * Called from C code
- */
-void handle_local_timer(struct pt_regs *);
-
 #ifdef CONFIG_LOCAL_TIMERS
 
 #ifdef CONFIG_HAVE_ARM_TWD
 
 #include "smp_twd.h"
 
-#define local_timer_ack()      twd_timer_ack()
+#define local_timer_stop(c)    twd_timer_stop((c))
 
 #else
 
 /*
- * Platform provides this to acknowledge a local timer IRQ.
- * Returns true if the local timer IRQ is to be processed.
+ * Stop the local timer
  */
-int local_timer_ack(void);
+void local_timer_stop(struct clock_event_device *);
 
 #endif
 
@@ -58,6 +48,10 @@ static inline int local_timer_setup(struct clock_event_device *evt)
 {
        return -ENXIO;
 }
+
+static inline void local_timer_stop(struct clock_event_device *evt)
+{
+}
 #endif
 
 #endif
index c569998..7d19425 100644 (file)
@@ -17,7 +17,7 @@ struct sys_timer;
 struct machine_desc {
        unsigned int            nr;             /* architecture number  */
        const char              *name;          /* architecture name    */
-       unsigned long           boot_params;    /* tagged list          */
+       unsigned long           atag_offset;    /* tagged list (relative) */
        const char              **dt_compat;    /* array of device tree
                                                 * 'compatible' strings */
 
index d2fedb5..b36f365 100644 (file)
@@ -29,6 +29,7 @@ struct map_desc {
 #define MT_MEMORY_NONCACHED    11
 #define MT_MEMORY_DTCM         12
 #define MT_MEMORY_ITCM         13
+#define MT_MEMORY_SO           14
 
 #ifdef CONFIG_MMU
 extern void iotable_init(struct map_desc *, int);
index 441fc4f..a8997d7 100644 (file)
 #include <linux/compiler.h>
 #include <linux/const.h>
 #include <linux/types.h>
-#include <mach/memory.h>
 #include <asm/sizes.h>
 
+#ifdef CONFIG_NEED_MACH_MEMORY_H
+#include <mach/memory.h>
+#endif
+
 /*
  * Allow for constants defined here to be used from assembly code
  * by prepending the UL suffix only with actual C code compilation.
  */
 #define IOREMAP_MAX_ORDER      24
 
-/*
- * Size of DMA-consistent memory region.  Must be multiple of 2M,
- * between 2MB and 14MB inclusive.
- */
-#ifndef CONSISTENT_DMA_SIZE
-#define CONSISTENT_DMA_SIZE    SZ_2M
-#endif
-
 #define CONSISTENT_END         (0xffe00000UL)
-#define CONSISTENT_BASE                (CONSISTENT_END - CONSISTENT_DMA_SIZE)
 
 #else /* CONFIG_MMU */
 
@@ -193,7 +187,11 @@ static inline unsigned long __phys_to_virt(unsigned long x)
 #endif
 
 #ifndef PHYS_OFFSET
+#ifdef PLAT_PHYS_OFFSET
 #define PHYS_OFFSET    PLAT_PHYS_OFFSET
+#else
+#define PHYS_OFFSET    UL(CONFIG_PHYS_OFFSET)
+#endif
 #endif
 
 /*
index 8ade184..9451dce 100644 (file)
@@ -101,6 +101,9 @@ extern pgprot_t             pgprot_kernel;
 #define pgprot_writecombine(prot) \
        __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
 
+#define pgprot_stronglyordered(prot) \
+       __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
+
 #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
 #define pgprot_dmacoherent(prot) \
        __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE | L_PTE_XN)
index b7e82c4..71d99b8 100644 (file)
 #define __ARM_PMU_H__
 
 #include <linux/interrupt.h>
+#include <linux/perf_event.h>
 
+/*
+ * Types of PMUs that can be accessed directly and require mutual
+ * exclusion between profiling tools.
+ */
 enum arm_pmu_type {
        ARM_PMU_DEVICE_CPU      = 0,
        ARM_NUM_PMU_DEVICES,
@@ -37,21 +42,17 @@ struct arm_pmu_platdata {
  * reserve_pmu() - reserve the hardware performance counters
  *
  * Reserve the hardware performance counters in the system for exclusive use.
- * The platform_device for the system is returned on success, ERR_PTR()
- * encoded error on failure.
+ * Returns 0 on success or -EBUSY if the lock is already held.
  */
-extern struct platform_device *
+extern int
 reserve_pmu(enum arm_pmu_type type);
 
 /**
  * release_pmu() - Relinquish control of the performance counters
  *
  * Release the performance counters and allow someone else to use them.
- * Callers must have disabled the counters and released IRQs before calling
- * this. The platform_device returned from reserve_pmu() must be passed as
- * a cookie.
  */
-extern int
+extern void
 release_pmu(enum arm_pmu_type type);
 
 /**
@@ -68,24 +69,78 @@ init_pmu(enum arm_pmu_type type);
 
 #include <linux/err.h>
 
-static inline struct platform_device *
-reserve_pmu(enum arm_pmu_type type)
-{
-       return ERR_PTR(-ENODEV);
-}
-
 static inline int
-release_pmu(enum arm_pmu_type type)
+reserve_pmu(enum arm_pmu_type type)
 {
        return -ENODEV;
 }
 
-static inline int
-init_pmu(enum arm_pmu_type type)
-{
-       return -ENODEV;
-}
+static inline void
+release_pmu(enum arm_pmu_type type)    { }
 
 #endif /* CONFIG_CPU_HAS_PMU */
 
+#ifdef CONFIG_HW_PERF_EVENTS
+
+/* The events for a given PMU register set. */
+struct pmu_hw_events {
+       /*
+        * The events that are active on the PMU for the given index.
+        */
+       struct perf_event       **events;
+
+       /*
+        * A 1 bit for an index indicates that the counter is being used for
+        * an event. A 0 means that the counter can be used.
+        */
+       unsigned long           *used_mask;
+
+       /*
+        * Hardware lock to serialize accesses to PMU registers. Needed for the
+        * read/modify/write sequences.
+        */
+       raw_spinlock_t          pmu_lock;
+};
+
+struct arm_pmu {
+       struct pmu      pmu;
+       enum arm_perf_pmu_ids id;
+       enum arm_pmu_type type;
+       cpumask_t       active_irqs;
+       const char      *name;
+       irqreturn_t     (*handle_irq)(int irq_num, void *dev);
+       void            (*enable)(struct hw_perf_event *evt, int idx);
+       void            (*disable)(struct hw_perf_event *evt, int idx);
+       int             (*get_event_idx)(struct pmu_hw_events *hw_events,
+                                        struct hw_perf_event *hwc);
+       int             (*set_event_filter)(struct hw_perf_event *evt,
+                                           struct perf_event_attr *attr);
+       u32             (*read_counter)(int idx);
+       void            (*write_counter)(int idx, u32 val);
+       void            (*start)(void);
+       void            (*stop)(void);
+       void            (*reset)(void *);
+       int             (*map_event)(struct perf_event *event);
+       int             num_events;
+       atomic_t        active_events;
+       struct mutex    reserve_mutex;
+       u64             max_period;
+       struct platform_device  *plat_device;
+       struct pmu_hw_events    *(*get_hw_events)(void);
+};
+
+#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
+
+int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type);
+
+u64 armpmu_event_update(struct perf_event *event,
+                       struct hw_perf_event *hwc,
+                       int idx, int overflow);
+
+int armpmu_event_set_period(struct perf_event *event,
+                           struct hw_perf_event *hwc,
+                           int idx);
+
+#endif /* CONFIG_HW_PERF_EVENTS */
+
 #endif /* __ARM_PMU_H__ */
index 633d1cb..9e92cb2 100644 (file)
@@ -81,6 +81,10 @@ extern void cpu_dcache_clean_area(void *, int);
 extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
 extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
+
+/* These three are private to arch/arm/kernel/suspend.c */
+extern void cpu_do_suspend(void *);
+extern void cpu_do_resume(void *);
 #else
 #define cpu_proc_init                  processor._proc_init
 #define cpu_proc_fin                   processor._proc_fin
@@ -89,6 +93,10 @@ extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
 #define cpu_dcache_clean_area          processor.dcache_clean_area
 #define cpu_set_pte_ext                        processor.set_pte_ext
 #define cpu_do_switch_mm               processor.switch_mm
+
+/* These three are private to arch/arm/kernel/suspend.c */
+#define cpu_do_suspend                 processor.do_suspend
+#define cpu_do_resume                  processor.do_resume
 #endif
 
 extern void cpu_resume(void);
index 0a17b62..1e5717a 100644 (file)
@@ -99,9 +99,4 @@ extern void platform_cpu_enable(unsigned int cpu);
 extern void arch_send_call_function_single_ipi(int cpu);
 extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
 
-/*
- * show local interrupt info
- */
-extern void show_local_irqs(struct seq_file *, int);
-
 #endif /* ifndef __ASM_ARM_SMP_H */
index fed9981..ef9ffba 100644 (file)
@@ -22,7 +22,7 @@ struct clock_event_device;
 
 extern void __iomem *twd_base;
 
-int twd_timer_ack(void);
 void twd_timer_setup(struct clock_event_device *);
+void twd_timer_stop(struct clock_event_device *);
 
 #endif
index b0e4e1a..1c0a551 100644 (file)
@@ -1,22 +1,7 @@
 #ifndef __ASM_ARM_SUSPEND_H
 #define __ASM_ARM_SUSPEND_H
 
-#include <asm/memory.h>
-#include <asm/tlbflush.h>
-
 extern void cpu_resume(void);
-
-/*
- * Hide the first two arguments to __cpu_suspend - these are an implementation
- * detail which platform code shouldn't have to know about.
- */
-static inline int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
-{
-       extern int __cpu_suspend(int, long, unsigned long,
-                                int (*)(unsigned long));
-       int ret = __cpu_suspend(0, PHYS_OFFSET - PAGE_OFFSET, arg, fn);
-       flush_tlb_all();
-       return ret;
-}
+extern int cpu_suspend(unsigned long, int (*)(unsigned long));
 
 #endif
index 68036ee..16eed6a 100644 (file)
@@ -29,7 +29,7 @@ obj-$(CONFIG_MODULES)         += armksyms.o module.o
 obj-$(CONFIG_ARTHUR)           += arthur.o
 obj-$(CONFIG_ISA_DMA)          += dma-isa.o
 obj-$(CONFIG_PCI)              += bios32.o isa.o
-obj-$(CONFIG_ARM_CPU_SUSPEND)  += sleep.o
+obj-$(CONFIG_ARM_CPU_SUSPEND)  += sleep.o suspend.o
 obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
 obj-$(CONFIG_SMP)              += smp.o smp_tlb.o
 obj-$(CONFIG_HAVE_ARM_SCU)     += smp_scu.o
@@ -43,6 +43,13 @@ obj-$(CONFIG_KPROBES)                += kprobes-thumb.o
 else
 obj-$(CONFIG_KPROBES)          += kprobes-arm.o
 endif
+obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o
+test-kprobes-objs              := kprobes-test.o
+ifdef CONFIG_THUMB2_KERNEL
+test-kprobes-objs              += kprobes-test-thumb.o
+else
+test-kprobes-objs              += kprobes-test-arm.o
+endif
 obj-$(CONFIG_ATAGS_PROC)       += atags.o
 obj-$(CONFIG_OABI_COMPAT)      += sys_oabi-compat.o
 obj-$(CONFIG_ARM_THUMBEE)      += thumbee.o
index 0f852d0..204e216 100644 (file)
@@ -22,7 +22,7 @@
 #if defined(CONFIG_DEBUG_ICEDCC)
                @@ debug using ARM EmbeddedICE DCC channel
 
-               .macro  addruart, rp, rv
+               .macro  addruart, rp, rv, tmp
                .endm
 
 #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
 
 #ifdef CONFIG_MMU
                .macro  addruart_current, rx, tmp1, tmp2
-               addruart        \tmp1, \tmp2
+               addruart        \tmp1, \tmp2, \rx
                mrc             p15, 0, \rx, c1, c0
                tst             \rx, #1
                moveq           \rx, \tmp1
index 239703d..566c54c 100644 (file)
@@ -99,7 +99,7 @@ ENTRY(stext)
        sub     r4, r3, r4                      @ (PHYS_OFFSET - PAGE_OFFSET)
        add     r8, r8, r4                      @ PHYS_OFFSET
 #else
-       ldr     r8, =PLAT_PHYS_OFFSET
+       ldr     r8, =PHYS_OFFSET                @ always constant in this case
 #endif
 
        /*
@@ -238,7 +238,7 @@ __create_page_tables:
         * This allows debug messages to be output
         * via a serial console before paging_init.
         */
-       addruart r7, r3
+       addruart r7, r3, r0
 
        mov     r3, r3, lsr #SECTION_SHIFT
        mov     r3, r3, lsl #PMD_ORDER
index a927ca1..814a52a 100644 (file)
@@ -45,7 +45,6 @@ static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[ARM_MAX_WRP]);
 
 /* Number of BRP/WRP registers on this CPU. */
 static int core_num_brps;
-static int core_num_reserved_brps;
 static int core_num_wrps;
 
 /* Debug architecture version. */
@@ -137,10 +136,11 @@ static u8 get_debug_arch(void)
        u32 didr;
 
        /* Do we implement the extended CPUID interface? */
-       if (WARN_ONCE((((read_cpuid_id() >> 16) & 0xf) != 0xf),
-           "CPUID feature registers not supported. "
-           "Assuming v6 debug is present.\n"))
+       if (((read_cpuid_id() >> 16) & 0xf) != 0xf) {
+               pr_warning("CPUID feature registers not supported. "
+                          "Assuming v6 debug is present.\n");
                return ARM_DEBUG_ARCH_V6;
+       }
 
        ARM_DBG_READ(c0, 0, didr);
        return (didr >> 16) & 0xf;
@@ -154,10 +154,21 @@ u8 arch_get_debug_arch(void)
 static int debug_arch_supported(void)
 {
        u8 arch = get_debug_arch();
-       return arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14;
+
+       /* We don't support the memory-mapped interface. */
+       return (arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14) ||
+               arch >= ARM_DEBUG_ARCH_V7_1;
+}
+
+/* Determine number of WRP registers available. */
+static int get_num_wrp_resources(void)
+{
+       u32 didr;
+       ARM_DBG_READ(c0, 0, didr);
+       return ((didr >> 28) & 0xf) + 1;
 }
 
-/* Determine number of BRP register available. */
+/* Determine number of BRP registers available. */
 static int get_num_brp_resources(void)
 {
        u32 didr;
@@ -176,9 +187,10 @@ static int core_has_mismatch_brps(void)
 static int get_num_wrps(void)
 {
        /*
-        * FIXME: When a watchpoint fires, the only way to work out which
-        * watchpoint it was is by disassembling the faulting instruction
-        * and working out the address of the memory access.
+        * On debug architectures prior to 7.1, when a watchpoint fires, the
+        * only way to work out which watchpoint it was is by disassembling
+        * the faulting instruction and working out the address of the memory
+        * access.
         *
         * Furthermore, we can only do this if the watchpoint was precise
         * since imprecise watchpoints prevent us from calculating register
@@ -192,36 +204,17 @@ static int get_num_wrps(void)
         * [the ARM ARM states that the DFAR is UNKNOWN, but experience shows
         * that it is set on some implementations].
         */
+       if (get_debug_arch() < ARM_DEBUG_ARCH_V7_1)
+               return 1;
 
-#if 0
-       int wrps;
-       u32 didr;
-       ARM_DBG_READ(c0, 0, didr);
-       wrps = ((didr >> 28) & 0xf) + 1;
-#endif
-       int wrps = 1;
-
-       if (core_has_mismatch_brps() && wrps >= get_num_brp_resources())
-               wrps = get_num_brp_resources() - 1;
-
-       return wrps;
-}
-
-/* We reserve one breakpoint for each watchpoint. */
-static int get_num_reserved_brps(void)
-{
-       if (core_has_mismatch_brps())
-               return get_num_wrps();
-       return 0;
+       return get_num_wrp_resources();
 }
 
 /* Determine number of usable BRPs available. */
 static int get_num_brps(void)
 {
        int brps = get_num_brp_resources();
-       if (core_has_mismatch_brps())
-               brps -= get_num_reserved_brps();
-       return brps;
+       return core_has_mismatch_brps() ? brps - 1 : brps;
 }
 
 /*
@@ -239,7 +232,7 @@ static int enable_monitor_mode(void)
 
        /* Ensure that halting mode is disabled. */
        if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN,
-                       "halting debug mode enabled. Unable to access hardware resources.\n")) {
+               "halting debug mode enabled. Unable to access hardware resources.\n")) {
                ret = -EPERM;
                goto out;
        }
@@ -255,6 +248,7 @@ static int enable_monitor_mode(void)
                ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN));
                break;
        case ARM_DEBUG_ARCH_V7_ECP14:
+       case ARM_DEBUG_ARCH_V7_1:
                ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN));
                break;
        default:
@@ -346,24 +340,10 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
                val_base = ARM_BASE_BVR;
                slots = (struct perf_event **)__get_cpu_var(bp_on_reg);
                max_slots = core_num_brps;
-               if (info->step_ctrl.enabled) {
-                       /* Override the breakpoint data with the step data. */
-                       addr = info->trigger & ~0x3;
-                       ctrl = encode_ctrl_reg(info->step_ctrl);
-               }
        } else {
                /* Watchpoint */
-               if (info->step_ctrl.enabled) {
-                       /* Install into the reserved breakpoint region. */
-                       ctrl_base = ARM_BASE_BCR + core_num_brps;
-                       val_base = ARM_BASE_BVR + core_num_brps;
-                       /* Override the watchpoint data with the step data. */
-                       addr = info->trigger & ~0x3;
-                       ctrl = encode_ctrl_reg(info->step_ctrl);
-               } else {
-                       ctrl_base = ARM_BASE_WCR;
-                       val_base = ARM_BASE_WVR;
-               }
+               ctrl_base = ARM_BASE_WCR;
+               val_base = ARM_BASE_WVR;
                slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
                max_slots = core_num_wrps;
        }
@@ -382,6 +362,17 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
                goto out;
        }
 
+       /* Override the breakpoint data with the step data. */
+       if (info->step_ctrl.enabled) {
+               addr = info->trigger & ~0x3;
+               ctrl = encode_ctrl_reg(info->step_ctrl);
+               if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE) {
+                       i = 0;
+                       ctrl_base = ARM_BASE_BCR + core_num_brps;
+                       val_base = ARM_BASE_BVR + core_num_brps;
+               }
+       }
+
        /* Setup the address register. */
        write_wb_reg(val_base + i, addr);
 
@@ -405,10 +396,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
                max_slots = core_num_brps;
        } else {
                /* Watchpoint */
-               if (info->step_ctrl.enabled)
-                       base = ARM_BASE_BCR + core_num_brps;
-               else
-                       base = ARM_BASE_WCR;
+               base = ARM_BASE_WCR;
                slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
                max_slots = core_num_wrps;
        }
@@ -426,6 +414,13 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
        if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n"))
                return;
 
+       /* Ensure that we disable the mismatch breakpoint. */
+       if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE &&
+           info->step_ctrl.enabled) {
+               i = 0;
+               base = ARM_BASE_BCR + core_num_brps;
+       }
+
        /* Reset the control register. */
        write_wb_reg(base + i, 0);
 }
@@ -632,10 +627,9 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
         * we can use the mismatch feature as a poor-man's hardware
         * single-step, but this only works for per-task breakpoints.
         */
-       if (WARN_ONCE(!bp->overflow_handler &&
-               (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps()
-                || !bp->hw.bp_target),
-                       "overflow handler required but none found\n")) {
+       if (!bp->overflow_handler && (arch_check_bp_in_kernelspace(bp) ||
+           !core_has_mismatch_brps() || !bp->hw.bp_target)) {
+               pr_warning("overflow handler required but none found\n");
                ret = -EINVAL;
        }
 out:
@@ -666,34 +660,62 @@ static void disable_single_step(struct perf_event *bp)
        arch_install_hw_breakpoint(bp);
 }
 
-static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs)
+static void watchpoint_handler(unsigned long addr, unsigned int fsr,
+                              struct pt_regs *regs)
 {
-       int i;
+       int i, access;
+       u32 val, ctrl_reg, alignment_mask;
        struct perf_event *wp, **slots;
        struct arch_hw_breakpoint *info;
+       struct arch_hw_breakpoint_ctrl ctrl;
 
        slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
 
-       /* Without a disassembler, we can only handle 1 watchpoint. */
-       BUG_ON(core_num_wrps > 1);
-
        for (i = 0; i < core_num_wrps; ++i) {
                rcu_read_lock();
 
                wp = slots[i];
 
-               if (wp == NULL) {
-                       rcu_read_unlock();
-                       continue;
-               }
+               if (wp == NULL)
+                       goto unlock;
 
+               info = counter_arch_bp(wp);
                /*
-                * The DFAR is an unknown value. Since we only allow a
-                * single watchpoint, we can set the trigger to the lowest
-                * possible faulting address.
+                * The DFAR is an unknown value on debug architectures prior
+                * to 7.1. Since we only allow a single watchpoint on these
+                * older CPUs, we can set the trigger to the lowest possible
+                * faulting address.
                 */
-               info = counter_arch_bp(wp);
-               info->trigger = wp->attr.bp_addr;
+               if (debug_arch < ARM_DEBUG_ARCH_V7_1) {
+                       BUG_ON(i > 0);
+                       info->trigger = wp->attr.bp_addr;
+               } else {
+                       if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
+                               alignment_mask = 0x7;
+                       else
+                               alignment_mask = 0x3;
+
+                       /* Check if the watchpoint value matches. */
+                       val = read_wb_reg(ARM_BASE_WVR + i);
+                       if (val != (addr & ~alignment_mask))
+                               goto unlock;
+
+                       /* Possible match, check the byte address select. */
+                       ctrl_reg = read_wb_reg(ARM_BASE_WCR + i);
+                       decode_ctrl_reg(ctrl_reg, &ctrl);
+                       if (!((1 << (addr & alignment_mask)) & ctrl.len))
+                               goto unlock;
+
+                       /* Check that the access type matches. */
+                       access = (fsr & ARM_FSR_ACCESS_MASK) ? HW_BREAKPOINT_W :
+                                HW_BREAKPOINT_R;
+                       if (!(access & hw_breakpoint_type(wp)))
+                               goto unlock;
+
+                       /* We have a winner. */
+                       info->trigger = addr;
+               }
+
                pr_debug("watchpoint fired: address = 0x%x\n", info->trigger);
                perf_bp_event(wp, regs);
 
@@ -705,6 +727,7 @@ static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs)
                if (!wp->overflow_handler)
                        enable_single_step(wp, instruction_pointer(regs));
 
+unlock:
                rcu_read_unlock();
        }
 }
@@ -717,7 +740,7 @@ static void watchpoint_single_step_handler(unsigned long pc)
 
        slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
 
-       for (i = 0; i < core_num_reserved_brps; ++i) {
+       for (i = 0; i < core_num_wrps; ++i) {
                rcu_read_lock();
 
                wp = slots[i];
@@ -820,7 +843,7 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
        case ARM_ENTRY_ASYNC_WATCHPOINT:
                WARN(1, "Asynchronous watchpoint exception taken. Debugging results may be unreliable\n");
        case ARM_ENTRY_SYNC_WATCHPOINT:
-               watchpoint_handler(addr, regs);
+               watchpoint_handler(addr, fsr, regs);
                break;
        default:
                ret = 1; /* Unhandled fault. */
@@ -834,11 +857,31 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
 /*
  * One-time initialisation.
  */
-static void reset_ctrl_regs(void *info)
+static cpumask_t debug_err_mask;
+
+static int debug_reg_trap(struct pt_regs *regs, unsigned int instr)
 {
-       int i, cpu = smp_processor_id();
+       int cpu = smp_processor_id();
+
+       pr_warning("Debug register access (0x%x) caused undefined instruction on CPU %d\n",
+                  instr, cpu);
+
+       /* Set the error flag for this CPU and skip the faulting instruction. */
+       cpumask_set_cpu(cpu, &debug_err_mask);
+       instruction_pointer(regs) += 4;
+       return 0;
+}
+
+static struct undef_hook debug_reg_hook = {
+       .instr_mask     = 0x0fe80f10,
+       .instr_val      = 0x0e000e10,
+       .fn             = debug_reg_trap,
+};
+
+static void reset_ctrl_regs(void *unused)
+{
+       int i, raw_num_brps, err = 0, cpu = smp_processor_id();
        u32 dbg_power;
-       cpumask_t *cpumask = info;
 
        /*
         * v7 debug contains save and restore registers so that debug state
@@ -848,38 +891,57 @@ static void reset_ctrl_regs(void *info)
         * Access Register to avoid taking undefined instruction exceptions
         * later on.
         */
-       if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) {
+       switch (debug_arch) {
+       case ARM_DEBUG_ARCH_V6:
+       case ARM_DEBUG_ARCH_V6_1:
+               /* ARMv6 cores just need to reset the registers. */
+               goto reset_regs;
+       case ARM_DEBUG_ARCH_V7_ECP14:
                /*
                 * Ensure sticky power-down is clear (i.e. debug logic is
                 * powered up).
                 */
                asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power));
-               if ((dbg_power & 0x1) == 0) {
-                       pr_warning("CPU %d debug is powered down!\n", cpu);
-                       cpumask_or(cpumask, cpumask, cpumask_of(cpu));
-                       return;
-               }
-
+               if ((dbg_power & 0x1) == 0)
+                       err = -EPERM;
+               break;
+       case ARM_DEBUG_ARCH_V7_1:
                /*
-                * Unconditionally clear the lock by writing a value
-                * other than 0xC5ACCE55 to the access register.
+                * Ensure the OS double lock is clear.
                 */
-               asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0));
-               isb();
+               asm volatile("mrc p14, 0, %0, c1, c3, 4" : "=r" (dbg_power));
+               if ((dbg_power & 0x1) == 1)
+                       err = -EPERM;
+               break;
+       }
 
-               /*
-                * Clear any configured vector-catch events before
-                * enabling monitor mode.
-                */
-               asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0));
-               isb();
+       if (err) {
+               pr_warning("CPU %d debug is powered down!\n", cpu);
+               cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu));
+               return;
        }
 
+       /*
+        * Unconditionally clear the lock by writing a value
+        * other than 0xC5ACCE55 to the access register.
+        */
+       asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0));
+       isb();
+
+       /*
+        * Clear any configured vector-catch events before
+        * enabling monitor mode.
+        */
+       asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0));
+       isb();
+
+reset_regs:
        if (enable_monitor_mode())
                return;
 
        /* We must also reset any reserved registers. */
-       for (i = 0; i < core_num_brps + core_num_reserved_brps; ++i) {
+       raw_num_brps = get_num_brp_resources();
+       for (i = 0; i < raw_num_brps; ++i) {
                write_wb_reg(ARM_BASE_BCR + i, 0UL);
                write_wb_reg(ARM_BASE_BVR + i, 0UL);
        }
@@ -895,6 +957,7 @@ static int __cpuinit dbg_reset_notify(struct notifier_block *self,
 {
        if (action == CPU_ONLINE)
                smp_call_function_single((int)cpu, reset_ctrl_regs, NULL, 1);
+
        return NOTIFY_OK;
 }
 
@@ -905,7 +968,6 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = {
 static int __init arch_hw_breakpoint_init(void)
 {
        u32 dscr;
-       cpumask_t cpumask = { CPU_BITS_NONE };
 
        debug_arch = get_debug_arch();
 
@@ -916,28 +978,31 @@ static int __init arch_hw_breakpoint_init(void)
 
        /* Determine how many BRPs/WRPs are available. */
        core_num_brps = get_num_brps();
-       core_num_reserved_brps = get_num_reserved_brps();
        core_num_wrps = get_num_wrps();
 
-       pr_info("found %d breakpoint and %d watchpoint registers.\n",
-               core_num_brps + core_num_reserved_brps, core_num_wrps);
-
-       if (core_num_reserved_brps)
-               pr_info("%d breakpoint(s) reserved for watchpoint "
-                               "single-step.\n", core_num_reserved_brps);
+       /*
+        * We need to tread carefully here because DBGSWENABLE may be
+        * driven low on this core and there isn't an architected way to
+        * determine that.
+        */
+       register_undef_hook(&debug_reg_hook);
 
        /*
         * Reset the breakpoint resources. We assume that a halting
         * debugger will leave the world in a nice state for us.
         */
-       on_each_cpu(reset_ctrl_regs, &cpumask, 1);
-       if (!cpumask_empty(&cpumask)) {
+       on_each_cpu(reset_ctrl_regs, NULL, 1);
+       unregister_undef_hook(&debug_reg_hook);
+       if (!cpumask_empty(&debug_err_mask)) {
                core_num_brps = 0;
-               core_num_reserved_brps = 0;
                core_num_wrps = 0;
                return 0;
        }
 
+       pr_info("found %d " "%s" "breakpoint and %d watchpoint registers.\n",
+               core_num_brps, core_has_mismatch_brps() ? "(+1 reserved) " :
+               "", core_num_wrps);
+
        ARM_DBG_READ(c1, 0, dscr);
        if (dscr & ARM_DSCR_HDBGEN) {
                max_watchpoint_len = 4;
index 53919b2..7cb2926 100644 (file)
@@ -59,9 +59,6 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 #ifdef CONFIG_SMP
        show_ipi_list(p, prec);
 #endif
-#ifdef CONFIG_LOCAL_TIMERS
-       show_local_irqs(p, prec);
-#endif
        seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
        return 0;
 }
index 79203ee..9fe8910 100644 (file)
@@ -60,6 +60,7 @@
 
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
+#include <linux/module.h>
 
 #include "kprobes.h"
 
@@ -971,6 +972,9 @@ const union decode_item kprobe_decode_arm_table[] = {
 
        DECODE_END
 };
+#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
+EXPORT_SYMBOL_GPL(kprobe_decode_arm_table);
+#endif
 
 static void __kprobes arm_singlestep(struct kprobe *p, struct pt_regs *regs)
 {
diff --git a/arch/arm/kernel/kprobes-test-arm.c b/arch/arm/kernel/kprobes-test-arm.c
new file mode 100644 (file)
index 0000000..fc82de8
--- /dev/null
@@ -0,0 +1,1323 @@
+/*
+ * arch/arm/kernel/kprobes-test-arm.c
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "kprobes-test.h"
+
+
+#define TEST_ISA "32"
+
+#define TEST_ARM_TO_THUMB_INTERWORK_R(code1, reg, val, code2)  \
+       TESTCASE_START(code1 #reg code2)                        \
+       TEST_ARG_REG(reg, val)                                  \
+       TEST_ARG_REG(14, 99f)                                   \
+       TEST_ARG_END("")                                        \
+       "50:    nop                     \n\t"                   \
+       "1:     "code1 #reg code2"      \n\t"                   \
+       "       bx      lr              \n\t"                   \
+       ".thumb                         \n\t"                   \
+       "3:     adr     lr, 2f          \n\t"                   \
+       "       bx      lr              \n\t"                   \
+       ".arm                           \n\t"                   \
+       "2:     nop                     \n\t"                   \
+       TESTCASE_END
+
+#define TEST_ARM_TO_THUMB_INTERWORK_P(code1, reg, val, code2)  \
+       TESTCASE_START(code1 #reg code2)                        \
+       TEST_ARG_PTR(reg, val)                                  \
+       TEST_ARG_REG(14, 99f)                                   \
+       TEST_ARG_MEM(15, 3f+1)                                  \
+       TEST_ARG_END("")                                        \
+       "50:    nop                     \n\t"                   \
+       "1:     "code1 #reg code2"      \n\t"                   \
+       "       bx      lr              \n\t"                   \
+       ".thumb                         \n\t"                   \
+       "3:     adr     lr, 2f          \n\t"                   \
+       "       bx      lr              \n\t"                   \
+       ".arm                           \n\t"                   \
+       "2:     nop                     \n\t"                   \
+       TESTCASE_END
+
+
+void kprobe_arm_test_cases(void)
+{
+       kprobe_test_flags = 0;
+
+       TEST_GROUP("Data-processing (register), (register-shifted register), (immediate)")
+
+#define _DATA_PROCESSING_DNM(op,s,val)                                         \
+       TEST_RR(  op "eq" s "   r0,  r",1, VAL1,", r",2, val, "")               \
+       TEST_RR(  op "ne" s "   r1,  r",1, VAL1,", r",2, val, ", lsl #3")       \
+       TEST_RR(  op "cs" s "   r2,  r",3, VAL1,", r",2, val, ", lsr #4")       \
+       TEST_RR(  op "cc" s "   r3,  r",3, VAL1,", r",2, val, ", asr #5")       \
+       TEST_RR(  op "mi" s "   r4,  r",5, VAL1,", r",2, N(val),", asr #6")     \
+       TEST_RR(  op "pl" s "   r5,  r",5, VAL1,", r",2, val, ", ror #7")       \
+       TEST_RR(  op "vs" s "   r6,  r",7, VAL1,", r",2, val, ", rrx")          \
+       TEST_R(   op "vc" s "   r6,  r",7, VAL1,", pc, lsl #3")                 \
+       TEST_R(   op "vc" s "   r6,  r",7, VAL1,", sp, lsr #4")                 \
+       TEST_R(   op "vc" s "   r6,  pc, r",7, VAL1,", asr #5")                 \
+       TEST_R(   op "vc" s "   r6,  sp, r",7, VAL1,", ror #6")                 \
+       TEST_RRR( op "hi" s "   r8,  r",9, VAL1,", r",14,val, ", lsl r",0, 3,"")\
+       TEST_RRR( op "ls" s "   r9,  r",9, VAL1,", r",14,val, ", lsr r",7, 4,"")\
+       TEST_RRR( op "ge" s "   r10, r",11,VAL1,", r",14,val, ", asr r",7, 5,"")\
+       TEST_RRR( op "lt" s "   r11, r",11,VAL1,", r",14,N(val),", asr r",7, 6,"")\
+       TEST_RR(  op "gt" s "   r12, r13"       ", r",14,val, ", ror r",14,7,"")\
+       TEST_RR(  op "le" s "   r14, r",0, val, ", r13"       ", lsl r",14,8,"")\
+       TEST_RR(  op s "        r12, pc"        ", r",14,val, ", ror r",14,7,"")\
+       TEST_RR(  op s "        r14, r",0, val, ", pc"        ", lsl r",14,8,"")\
+       TEST_R(   op "eq" s "   r0,  r",11,VAL1,", #0xf5")                      \
+       TEST_R(   op "ne" s "   r11, r",0, VAL1,", #0xf5000000")                \
+       TEST_R(   op s "        r7,  r",8, VAL2,", #0x000af000")                \
+       TEST(     op s "        r4,  pc"        ", #0x00005a00")
+
+#define DATA_PROCESSING_DNM(op,val)            \
+       _DATA_PROCESSING_DNM(op,"",val)         \
+       _DATA_PROCESSING_DNM(op,"s",val)
+
+#define DATA_PROCESSING_NM(op,val)                                             \
+       TEST_RR(  op "ne        r",1, VAL1,", r",2, val, "")                    \
+       TEST_RR(  op "eq        r",1, VAL1,", r",2, val, ", lsl #3")            \
+       TEST_RR(  op "cc        r",3, VAL1,", r",2, val, ", lsr #4")            \
+       TEST_RR(  op "cs        r",3, VAL1,", r",2, val, ", asr #5")            \
+       TEST_RR(  op "pl        r",5, VAL1,", r",2, N(val),", asr #6")          \
+       TEST_RR(  op "mi        r",5, VAL1,", r",2, val, ", ror #7")            \
+       TEST_RR(  op "vc        r",7, VAL1,", r",2, val, ", rrx")               \
+       TEST_R (  op "vs        r",7, VAL1,", pc, lsl #3")                      \
+       TEST_R (  op "vs        r",7, VAL1,", sp, lsr #4")                      \
+       TEST_R(   op "vs        pc, r",7, VAL1,", asr #5")                      \
+       TEST_R(   op "vs        sp, r",7, VAL1,", ror #6")                      \
+       TEST_RRR( op "ls        r",9, VAL1,", r",14,val, ", lsl r",0, 3,"")     \
+       TEST_RRR( op "hi        r",9, VAL1,", r",14,val, ", lsr r",7, 4,"")     \
+       TEST_RRR( op "lt        r",11,VAL1,", r",14,val, ", asr r",7, 5,"")     \
+       TEST_RRR( op "ge        r",11,VAL1,", r",14,N(val),", asr r",7, 6,"")   \
+       TEST_RR(  op "le        r13"       ", r",14,val, ", ror r",14,7,"")     \
+       TEST_RR(  op "gt        r",0, val, ", r13"       ", lsl r",14,8,"")     \
+       TEST_RR(  op "  pc"        ", r",14,val, ", ror r",14,7,"")             \
+       TEST_RR(  op "  r",0, val, ", pc"        ", lsl r",14,8,"")             \
+       TEST_R(   op "eq        r",11,VAL1,", #0xf5")                           \
+       TEST_R(   op "ne        r",0, VAL1,", #0xf5000000")                     \
+       TEST_R(   op "  r",8, VAL2,", #0x000af000")
+
+#define _DATA_PROCESSING_DM(op,s,val)                                  \
+       TEST_R(   op "eq" s "   r0,  r",1, val, "")                     \
+       TEST_R(   op "ne" s "   r1,  r",1, val, ", lsl #3")             \
+       TEST_R(   op "cs" s "   r2,  r",3, val, ", lsr #4")             \
+       TEST_R(   op "cc" s "   r3,  r",3, val, ", asr #5")             \
+       TEST_R(   op "mi" s "   r4,  r",5, N(val),", asr #6")           \
+       TEST_R(   op "pl" s "   r5,  r",5, val, ", ror #7")             \
+       TEST_R(   op "vs" s "   r6,  r",10,val, ", rrx")                \
+       TEST(     op "vs" s "   r7,  pc, lsl #3")                       \
+       TEST(     op "vs" s "   r7,  sp, lsr #4")                       \
+       TEST_RR(  op "vc" s "   r8,  r",7, val, ", lsl r",0, 3,"")      \
+       TEST_RR(  op "hi" s "   r9,  r",9, val, ", lsr r",7, 4,"")      \
+       TEST_RR(  op "ls" s "   r10, r",9, val, ", asr r",7, 5,"")      \
+       TEST_RR(  op "ge" s "   r11, r",11,N(val),", asr r",7, 6,"")    \
+       TEST_RR(  op "lt" s "   r12, r",11,val, ", ror r",14,7,"")      \
+       TEST_R(   op "gt" s "   r14, r13"       ", lsl r",14,8,"")      \
+       TEST_R(   op "le" s "   r14, pc"        ", lsl r",14,8,"")      \
+       TEST(     op "eq" s "   r0,  #0xf5")                            \
+       TEST(     op "ne" s "   r11, #0xf5000000")                      \
+       TEST(     op s "        r7,  #0x000af000")                      \
+       TEST(     op s "        r4,  #0x00005a00")
+
+#define DATA_PROCESSING_DM(op,val)             \
+       _DATA_PROCESSING_DM(op,"",val)          \
+       _DATA_PROCESSING_DM(op,"s",val)
+
+       DATA_PROCESSING_DNM("and",0xf00f00ff)
+       DATA_PROCESSING_DNM("eor",0xf00f00ff)
+       DATA_PROCESSING_DNM("sub",VAL2)
+       DATA_PROCESSING_DNM("rsb",VAL2)
+       DATA_PROCESSING_DNM("add",VAL2)
+       DATA_PROCESSING_DNM("adc",VAL2)
+       DATA_PROCESSING_DNM("sbc",VAL2)
+       DATA_PROCESSING_DNM("rsc",VAL2)
+       DATA_PROCESSING_NM("tst",0xf00f00ff)
+       DATA_PROCESSING_NM("teq",0xf00f00ff)
+       DATA_PROCESSING_NM("cmp",VAL2)
+       DATA_PROCESSING_NM("cmn",VAL2)
+       DATA_PROCESSING_DNM("orr",0xf00f00ff)
+       DATA_PROCESSING_DM("mov",VAL2)
+       DATA_PROCESSING_DNM("bic",0xf00f00ff)
+       DATA_PROCESSING_DM("mvn",VAL2)
+
+       TEST("mov       ip, sp") /* This has special case emulation code */
+
+       TEST_SUPPORTED("mov     pc, #0x1000");
+       TEST_SUPPORTED("mov     sp, #0x1000");
+       TEST_SUPPORTED("cmp     pc, #0x1000");
+       TEST_SUPPORTED("cmp     sp, #0x1000");
+
+       /* Data-processing with PC as shift*/
+       TEST_UNSUPPORTED(".word 0xe15c0f1e      @ cmp   r12, r14, asl pc")
+       TEST_UNSUPPORTED(".word 0xe1a0cf1e      @ mov   r12, r14, asl pc")
+       TEST_UNSUPPORTED(".word 0xe08caf1e      @ add   r10, r12, r14, asl pc")
+
+       /* Data-processing with PC as shift*/
+       TEST_UNSUPPORTED("movs  pc, r1")
+       TEST_UNSUPPORTED("movs  pc, r1, lsl r2")
+       TEST_UNSUPPORTED("movs  pc, #0x10000")
+       TEST_UNSUPPORTED("adds  pc, lr, r1")
+       TEST_UNSUPPORTED("adds  pc, lr, r1, lsl r2")
+       TEST_UNSUPPORTED("adds  pc, lr, #4")
+
+       /* Data-processing with SP as target */
+       TEST("add       sp, sp, #16")
+       TEST("sub       sp, sp, #8")
+       TEST("bic       sp, sp, #0x20")
+       TEST("orr       sp, sp, #0x20")
+       TEST_PR( "add   sp, r",10,0,", r",11,4,"")
+       TEST_PRR("add   sp, r",10,0,", r",11,4,", asl r",12,1,"")
+       TEST_P(  "mov   sp, r",10,0,"")
+       TEST_PR( "mov   sp, r",10,0,", asl r",12,0,"")
+
+       /* Data-processing with PC as target */
+       TEST_BF(   "add pc, pc, #2f-1b-8")
+       TEST_BF_R ("add pc, pc, r",14,2f-1f-8,"")
+       TEST_BF_R ("add pc, r",14,2f-1f-8,", pc")
+       TEST_BF_R ("mov pc, r",0,2f,"")
+       TEST_BF_RR("mov pc, r",0,2f,", asl r",1,0,"")
+       TEST_BB(   "sub pc, pc, #1b-2b+8")
+#if __LINUX_ARM_ARCH__ >= 6
+       TEST_BB(   "sub pc, pc, #1b-2b+8-2") /* UNPREDICTABLE before ARMv6 */
+#endif
+       TEST_BB_R( "sub pc, pc, r",14, 1f-2f+8,"")
+       TEST_BB_R( "rsb pc, r",14,1f-2f+8,", pc")
+       TEST_RR(   "add pc, pc, r",10,-2,", asl r",11,1,"")
+#ifdef CONFIG_THUMB2_KERNEL
+       TEST_ARM_TO_THUMB_INTERWORK_R("add      pc, pc, r",0,3f-1f-8+1,"")
+       TEST_ARM_TO_THUMB_INTERWORK_R("sub      pc, r",0,3f+8+1,", #8")
+#endif
+       TEST_GROUP("Miscellaneous instructions")
+
+       TEST("mrs       r0, cpsr")
+       TEST("mrspl     r7, cpsr")
+       TEST("mrs       r14, cpsr")
+       TEST_UNSUPPORTED(".word 0xe10ff000      @ mrs r15, cpsr")
+       TEST_UNSUPPORTED("mrs   r0, spsr")
+       TEST_UNSUPPORTED("mrs   lr, spsr")
+
+       TEST_UNSUPPORTED("msr   cpsr, r0")
+       TEST_UNSUPPORTED("msr   cpsr_f, lr")
+       TEST_UNSUPPORTED("msr   spsr, r0")
+
+       TEST_BF_R("bx   r",0,2f,"")
+       TEST_BB_R("bx   r",7,2f,"")
+       TEST_BF_R("bxeq r",14,2f,"")
+
+       TEST_R("clz     r0, r",0, 0x0,"")
+       TEST_R("clzeq   r7, r",14,0x1,"")
+       TEST_R("clz     lr, r",7, 0xffffffff,"")
+       TEST(  "clz     r4, sp")
+       TEST_UNSUPPORTED(".word 0x016fff10      @ clz pc, r0")
+       TEST_UNSUPPORTED(".word 0x016f0f1f      @ clz r0, pc")
+
+#if __LINUX_ARM_ARCH__ >= 6
+       TEST_UNSUPPORTED("bxj   r0")
+#endif
+
+       TEST_BF_R("blx  r",0,2f,"")
+       TEST_BB_R("blx  r",7,2f,"")
+       TEST_BF_R("blxeq        r",14,2f,"")
+       TEST_UNSUPPORTED(".word 0x0120003f      @ blx pc")
+
+       TEST_RR(   "qadd        r0, r",1, VAL1,", r",2, VAL2,"")
+       TEST_RR(   "qaddvs      lr, r",9, VAL2,", r",8, VAL1,"")
+       TEST_R(    "qadd        lr, r",9, VAL2,", r13")
+       TEST_RR(   "qsub        r0, r",1, VAL1,", r",2, VAL2,"")
+       TEST_RR(   "qsubvs      lr, r",9, VAL2,", r",8, VAL1,"")
+       TEST_R(    "qsub        lr, r",9, VAL2,", r13")
+       TEST_RR(   "qdadd       r0, r",1, VAL1,", r",2, VAL2,"")
+       TEST_RR(   "qdaddvs     lr, r",9, VAL2,", r",8, VAL1,"")
+       TEST_R(    "qdadd       lr, r",9, VAL2,", r13")
+       TEST_RR(   "qdsub       r0, r",1, VAL1,", r",2, VAL2,"")
+       TEST_RR(   "qdsubvs     lr, r",9, VAL2,", r",8, VAL1,"")
+       TEST_R(    "qdsub       lr, r",9, VAL2,", r13")
+       TEST_UNSUPPORTED(".word 0xe101f050      @ qadd pc, r0, r1")
+       TEST_UNSUPPORTED(".word 0xe121f050      @ qsub pc, r0, r1")
+       TEST_UNSUPPORTED(".word 0xe141f050      @ qdadd pc, r0, r1")
+       TEST_UNSUPPORTED(".word 0xe161f050      @ qdsub pc, r0, r1")
+       TEST_UNSUPPORTED(".word 0xe16f2050      @ qdsub r2, r0, pc")
+       TEST_UNSUPPORTED(".word 0xe161205f      @ qdsub r2, pc, r1")
+
+       TEST_UNSUPPORTED("bkpt  0xffff")
+       TEST_UNSUPPORTED("bkpt  0x0000")
+
+       TEST_UNSUPPORTED(".word 0xe1600070 @ smc #0")
+
+       TEST_GROUP("Halfword multiply and multiply-accumulate")
+
+       TEST_RRR(    "smlabb    r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"")
+       TEST_RRR(    "smlabbge  r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+       TEST_RR(     "smlabb    lr, r",1, VAL2,", r",2, VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe10f3281 @ smlabb pc, r1, r2, r3")
+       TEST_RRR(    "smlatb    r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"")
+       TEST_RRR(    "smlatbge  r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+       TEST_RR(     "smlatb    lr, r",1, VAL2,", r",2, VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe10f32a1 @ smlatb pc, r1, r2, r3")
+       TEST_RRR(    "smlabt    r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"")
+       TEST_RRR(    "smlabtge  r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+       TEST_RR(     "smlabt    lr, r",1, VAL2,", r",2, VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe10f32c1 @ smlabt pc, r1, r2, r3")
+       TEST_RRR(    "smlatt    r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"")
+       TEST_RRR(    "smlattge  r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+       TEST_RR(     "smlatt    lr, r",1, VAL2,", r",2, VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe10f32e1 @ smlatt pc, r1, r2, r3")
+
+       TEST_RRR(    "smlawb    r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"")
+       TEST_RRR(    "smlawbge  r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+       TEST_RR(     "smlawb    lr, r",1, VAL2,", r",2, VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe12f3281 @ smlawb pc, r1, r2, r3")
+       TEST_RRR(    "smlawt    r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"")
+       TEST_RRR(    "smlawtge  r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+       TEST_RR(     "smlawt    lr, r",1, VAL2,", r",2, VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe12f32c1 @ smlawt pc, r1, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe12032cf @ smlawt r0, pc, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe1203fc1 @ smlawt r0, r1, pc, r3")
+       TEST_UNSUPPORTED(".word 0xe120f2c1 @ smlawt r0, r1, r2, pc")
+
+       TEST_RR(    "smulwb     r0, r",1, VAL1,", r",2, VAL2,"")
+       TEST_RR(    "smulwbge   r7, r",8, VAL3,", r",9, VAL1,"")
+       TEST_R(     "smulwb     lr, r",1, VAL2,", r13")
+       TEST_UNSUPPORTED(".word 0xe12f02a1 @ smulwb pc, r1, r2")
+       TEST_RR(    "smulwt     r0, r",1, VAL1,", r",2, VAL2,"")
+       TEST_RR(    "smulwtge   r7, r",8, VAL3,", r",9, VAL1,"")
+       TEST_R(     "smulwt     lr, r",1, VAL2,", r13")
+       TEST_UNSUPPORTED(".word 0xe12f02e1 @ smulwt pc, r1, r2")
+
+       TEST_RRRR(  "smlalbb    r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+       TEST_RRRR(  "smlalbble  r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+       TEST_RRR(   "smlalbb    r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+       TEST_UNSUPPORTED(".word 0xe14f1382 @ smlalbb pc, r1, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe141f382 @ smlalbb r1, pc, r2, r3")
+       TEST_RRRR(  "smlaltb    r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+       TEST_RRRR(  "smlaltble  r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+       TEST_RRR(   "smlaltb    r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+       TEST_UNSUPPORTED(".word 0xe14f13a2 @ smlaltb pc, r1, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe141f3a2 @ smlaltb r1, pc, r2, r3")
+       TEST_RRRR(  "smlalbt    r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+       TEST_RRRR(  "smlalbtle  r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+       TEST_RRR(   "smlalbt    r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+       TEST_UNSUPPORTED(".word 0xe14f13c2 @ smlalbt pc, r1, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe141f3c2 @ smlalbt r1, pc, r2, r3")
+       TEST_RRRR(  "smlaltt    r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+       TEST_RRRR(  "smlalttle  r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+       TEST_RRR(   "smlaltt    r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+       TEST_UNSUPPORTED(".word 0xe14f13e2 @ smlalbb pc, r1, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe140f3e2 @ smlalbb r0, pc, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe14013ef @ smlalbb r0, r1, pc, r3")
+       TEST_UNSUPPORTED(".word 0xe1401fe2 @ smlalbb r0, r1, r2, pc")
+
+       TEST_RR(    "smulbb     r0, r",1, VAL1,", r",2, VAL2,"")
+       TEST_RR(    "smulbbge   r7, r",8, VAL3,", r",9, VAL1,"")
+       TEST_R(     "smulbb     lr, r",1, VAL2,", r13")
+       TEST_UNSUPPORTED(".word 0xe16f0281 @ smulbb pc, r1, r2")
+       TEST_RR(    "smultb     r0, r",1, VAL1,", r",2, VAL2,"")
+       TEST_RR(    "smultbge   r7, r",8, VAL3,", r",9, VAL1,"")
+       TEST_R(     "smultb     lr, r",1, VAL2,", r13")
+       TEST_UNSUPPORTED(".word 0xe16f02a1 @ smultb pc, r1, r2")
+       TEST_RR(    "smulbt     r0, r",1, VAL1,", r",2, VAL2,"")
+       TEST_RR(    "smulbtge   r7, r",8, VAL3,", r",9, VAL1,"")
+       TEST_R(     "smulbt     lr, r",1, VAL2,", r13")
+       TEST_UNSUPPORTED(".word 0xe16f02c1 @ smultb pc, r1, r2")
+       TEST_RR(    "smultt     r0, r",1, VAL1,", r",2, VAL2,"")
+       TEST_RR(    "smulttge   r7, r",8, VAL3,", r",9, VAL1,"")
+       TEST_R(     "smultt     lr, r",1, VAL2,", r13")
+       TEST_UNSUPPORTED(".word 0xe16f02e1 @ smultt pc, r1, r2")
+       TEST_UNSUPPORTED(".word 0xe16002ef @ smultt r0, pc, r2")
+       TEST_UNSUPPORTED(".word 0xe1600fe1 @ smultt r0, r1, pc")
+
+       TEST_GROUP("Multiply and multiply-accumulate")
+
+       TEST_RR(    "mul        r0, r",1, VAL1,", r",2, VAL2,"")
+       TEST_RR(    "mulls      r7, r",8, VAL2,", r",9, VAL2,"")
+       TEST_R(     "mul        lr, r",4, VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe00f0291 @ mul pc, r1, r2")
+       TEST_UNSUPPORTED(".word 0xe000029f @ mul r0, pc, r2")
+       TEST_UNSUPPORTED(".word 0xe0000f91 @ mul r0, r1, pc")
+       TEST_RR(    "muls       r0, r",1, VAL1,", r",2, VAL2,"")
+       TEST_RR(    "mullss     r7, r",8, VAL2,", r",9, VAL2,"")
+       TEST_R(     "muls       lr, r",4, VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe01f0291 @ muls pc, r1, r2")
+
+       TEST_RRR(    "mla       r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"")
+       TEST_RRR(    "mlahi     r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+       TEST_RR(     "mla       lr, r",1, VAL2,", r",2, VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe02f3291 @ mla pc, r1, r2, r3")
+       TEST_RRR(    "mlas      r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"")
+       TEST_RRR(    "mlahis    r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+       TEST_RR(     "mlas      lr, r",1, VAL2,", r",2, VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe03f3291 @ mlas pc, r1, r2, r3")
+
+#if __LINUX_ARM_ARCH__ >= 6
+       TEST_RR(  "umaal        r0, r1, r",2, VAL1,", r",3, VAL2,"")
+       TEST_RR(  "umaalls      r7, r8, r",9, VAL2,", r",10, VAL1,"")
+       TEST_R(   "umaal        lr, r12, r",11,VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe041f392 @ umaal pc, r1, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe04f0392 @ umaal r0, pc, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe0500090 @ undef")
+       TEST_UNSUPPORTED(".word 0xe05fff9f @ undef")
+
+       TEST_RRR(  "mls         r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"")
+       TEST_RRR(  "mlshi       r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
+       TEST_RR(   "mls         lr, r",1, VAL2,", r",2, VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe06f3291 @ mls pc, r1, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe060329f @ mls r0, pc, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe0603f91 @ mls r0, r1, pc, r3")
+       TEST_UNSUPPORTED(".word 0xe060f291 @ mls r0, r1, r2, pc")
+#endif
+
+       TEST_UNSUPPORTED(".word 0xe0700090 @ undef")
+       TEST_UNSUPPORTED(".word 0xe07fff9f @ undef")
+
+       TEST_RR(  "umull        r0, r1, r",2, VAL1,", r",3, VAL2,"")
+       TEST_RR(  "umullls      r7, r8, r",9, VAL2,", r",10, VAL1,"")
+       TEST_R(   "umull        lr, r12, r",11,VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe081f392 @ umull pc, r1, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe08f1392 @ umull r1, pc, r2, r3")
+       TEST_RR(  "umulls       r0, r1, r",2, VAL1,", r",3, VAL2,"")
+       TEST_RR(  "umulllss     r7, r8, r",9, VAL2,", r",10, VAL1,"")
+       TEST_R(   "umulls       lr, r12, r",11,VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe091f392 @ umulls pc, r1, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe09f1392 @ umulls r1, pc, r2, r3")
+
+       TEST_RRRR(  "umlal      r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+       TEST_RRRR(  "umlalle    r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+       TEST_RRR(   "umlal      r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+       TEST_UNSUPPORTED(".word 0xe0af1392 @ umlal pc, r1, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe0a1f392 @ umlal r1, pc, r2, r3")
+       TEST_RRRR(  "umlals     r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+       TEST_RRRR(  "umlalles   r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+       TEST_RRR(   "umlals     r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+       TEST_UNSUPPORTED(".word 0xe0bf1392 @ umlals pc, r1, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe0b1f392 @ umlals r1, pc, r2, r3")
+
+       TEST_RR(  "smull        r0, r1, r",2, VAL1,", r",3, VAL2,"")
+       TEST_RR(  "smullls      r7, r8, r",9, VAL2,", r",10, VAL1,"")
+       TEST_R(   "smull        lr, r12, r",11,VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe0c1f392 @ smull pc, r1, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe0cf1392 @ smull r1, pc, r2, r3")
+       TEST_RR(  "smulls       r0, r1, r",2, VAL1,", r",3, VAL2,"")
+       TEST_RR(  "smulllss     r7, r8, r",9, VAL2,", r",10, VAL1,"")
+       TEST_R(   "smulls       lr, r12, r",11,VAL3,", r13")
+       TEST_UNSUPPORTED(".word 0xe0d1f392 @ smulls pc, r1, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe0df1392 @ smulls r1, pc, r2, r3")
+
+       TEST_RRRR(  "smlal      r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+       TEST_RRRR(  "smlalle    r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+       TEST_RRR(   "smlal      r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+       TEST_UNSUPPORTED(".word 0xe0ef1392 @ smlal pc, r1, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe0e1f392 @ smlal r1, pc, r2, r3")
+       TEST_RRRR(  "smlals     r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4)
+       TEST_RRRR(  "smlalles   r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3)
+       TEST_RRR(   "smlals     r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13")
+       TEST_UNSUPPORTED(".word 0xe0ff1392 @ smlals pc, r1, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe0f0f392 @ smlals r0, pc, r2, r3")
+       TEST_UNSUPPORTED(".word 0xe0f0139f @ smlals r0, r1, pc, r3")
+       TEST_UNSUPPORTED(".word 0xe0f01f92 @ smlals r0, r1, r2, pc")
+
+       TEST_GROUP("Synchronization primitives")
+
+       /*
+        * Use hard coded constants for SWP instructions to avoid warnings
+        * about deprecated instructions.
+        */
+       TEST_RP( ".word 0xe108e097 @ swp        lr, r",7,VAL2,", [r",8,0,"]")
+       TEST_R(  ".word 0x610d0091 @ swpvs      r0, r",1,VAL1,", [sp]")
+       TEST_RP( ".word 0xe10cd09e @ swp        sp, r",14,VAL2,", [r",12,13*4,"]")
+       TEST_UNSUPPORTED(".word 0xe102f091 @ swp pc, r1, [r2]")
+       TEST_UNSUPPORTED(".word 0xe102009f @ swp r0, pc, [r2]")
+       TEST_UNSUPPORTED(".word 0xe10f0091 @ swp r0, r1, [pc]")
+       TEST_RP( ".word 0xe148e097 @ swpb       lr, r",7,VAL2,", [r",8,0,"]")
+       TEST_R(  ".word 0x614d0091 @ swpvsb     r0, r",1,VAL1,", [sp]")
+       TEST_UNSUPPORTED(".word 0xe142f091 @ swpb pc, r1, [r2]")
+
+       TEST_UNSUPPORTED(".word 0xe1100090") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe1200090") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe1300090") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe1500090") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe1600090") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe1700090") /* Unallocated space */
+#if __LINUX_ARM_ARCH__ >= 6
+       TEST_UNSUPPORTED("ldrex r2, [sp]")
+       TEST_UNSUPPORTED("strexd        r0, r2, r3, [sp]")
+       TEST_UNSUPPORTED("ldrexd        r2, r3, [sp]")
+       TEST_UNSUPPORTED("strexb        r0, r2, [sp]")
+       TEST_UNSUPPORTED("ldrexb        r2, [sp]")
+       TEST_UNSUPPORTED("strexh        r0, r2, [sp]")
+       TEST_UNSUPPORTED("ldrexh        r2, [sp]")
+#endif
+       TEST_GROUP("Extra load/store instructions")
+
+       TEST_RPR(  "strh        r",0, VAL1,", [r",1, 48,", -r",2, 24,"]")
+       TEST_RPR(  "streqh      r",14,VAL2,", [r",13,0, ", r",12, 48,"]")
+       TEST_RPR(  "strh        r",1, VAL1,", [r",2, 24,", r",3,  48,"]!")
+       TEST_RPR(  "strneh      r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
+       TEST_RPR(  "strh        r",2, VAL1,", [r",3, 24,"], r",4, 48,"")
+       TEST_RPR(  "strh        r",10,VAL2,", [r",9, 48,"], -r",11,24,"")
+       TEST_UNSUPPORTED(".word 0xe1afc0ba      @ strh r12, [pc, r10]!")
+       TEST_UNSUPPORTED(".word 0xe089f0bb      @ strh pc, [r9], r11")
+       TEST_UNSUPPORTED(".word 0xe089a0bf      @ strh r10, [r9], pc")
+
+       TEST_PR(   "ldrh        r0, [r",0,  48,", -r",2, 24,"]")
+       TEST_PR(   "ldrcsh      r14, [r",13,0, ", r",12, 48,"]")
+       TEST_PR(   "ldrh        r1, [r",2,  24,", r",3,  48,"]!")
+       TEST_PR(   "ldrcch      r12, [r",11,48,", -r",10,24,"]!")
+       TEST_PR(   "ldrh        r2, [r",3,  24,"], r",4, 48,"")
+       TEST_PR(   "ldrh        r10, [r",9, 48,"], -r",11,24,"")
+       TEST_UNSUPPORTED(".word 0xe1bfc0ba      @ ldrh r12, [pc, r10]!")
+       TEST_UNSUPPORTED(".word 0xe099f0bb      @ ldrh pc, [r9], r11")
+       TEST_UNSUPPORTED(".word 0xe099a0bf      @ ldrh r10, [r9], pc")
+
+       TEST_RP(   "strh        r",0, VAL1,", [r",1, 24,", #-2]")
+       TEST_RP(   "strmih      r",14,VAL2,", [r",13,0, ", #2]")
+       TEST_RP(   "strh        r",1, VAL1,", [r",2, 24,", #4]!")
+       TEST_RP(   "strplh      r",12,VAL2,", [r",11,24,", #-4]!")
+       TEST_RP(   "strh        r",2, VAL1,", [r",3, 24,"], #48")
+       TEST_RP(   "strh        r",10,VAL2,", [r",9, 64,"], #-48")
+       TEST_UNSUPPORTED(".word 0xe1efc3b0      @ strh r12, [pc, #48]!")
+       TEST_UNSUPPORTED(".word 0xe0c9f3b0      @ strh pc, [r9], #48")
+
+       TEST_P(    "ldrh        r0, [r",0,  24,", #-2]")
+       TEST_P(    "ldrvsh      r14, [r",13,0, ", #2]")
+       TEST_P(    "ldrh        r1, [r",2,  24,", #4]!")
+       TEST_P(    "ldrvch      r12, [r",11,24,", #-4]!")
+       TEST_P(    "ldrh        r2, [r",3,  24,"], #48")
+       TEST_P(    "ldrh        r10, [r",9, 64,"], #-48")
+       TEST(      "ldrh        r0, [pc, #0]")
+       TEST_UNSUPPORTED(".word 0xe1ffc3b0      @ ldrh r12, [pc, #48]!")
+       TEST_UNSUPPORTED(".word 0xe0d9f3b0      @ ldrh pc, [r9], #48")
+
+       TEST_PR(   "ldrsb       r0, [r",0,  48,", -r",2, 24,"]")
+       TEST_PR(   "ldrhisb     r14, [r",13,0,", r",12,  48,"]")
+       TEST_PR(   "ldrsb       r1, [r",2,  24,", r",3,  48,"]!")
+       TEST_PR(   "ldrlssb     r12, [r",11,48,", -r",10,24,"]!")
+       TEST_PR(   "ldrsb       r2, [r",3,  24,"], r",4, 48,"")
+       TEST_PR(   "ldrsb       r10, [r",9, 48,"], -r",11,24,"")
+       TEST_UNSUPPORTED(".word 0xe1bfc0da      @ ldrsb r12, [pc, r10]!")
+       TEST_UNSUPPORTED(".word 0xe099f0db      @ ldrsb pc, [r9], r11")
+
+       TEST_P(    "ldrsb       r0, [r",0,  24,", #-1]")
+       TEST_P(    "ldrgesb     r14, [r",13,0, ", #1]")
+       TEST_P(    "ldrsb       r1, [r",2,  24,", #4]!")
+       TEST_P(    "ldrltsb     r12, [r",11,24,", #-4]!")
+       TEST_P(    "ldrsb       r2, [r",3,  24,"], #48")
+       TEST_P(    "ldrsb       r10, [r",9, 64,"], #-48")
+       TEST(      "ldrsb       r0, [pc, #0]")
+       TEST_UNSUPPORTED(".word 0xe1ffc3d0      @ ldrsb r12, [pc, #48]!")
+       TEST_UNSUPPORTED(".word 0xe0d9f3d0      @ ldrsb pc, [r9], #48")
+
+       TEST_PR(   "ldrsh       r0, [r",0,  48,", -r",2, 24,"]")
+       TEST_PR(   "ldrgtsh     r14, [r",13,0, ", r",12, 48,"]")
+       TEST_PR(   "ldrsh       r1, [r",2,  24,", r",3,  48,"]!")
+       TEST_PR(   "ldrlesh     r12, [r",11,48,", -r",10,24,"]!")
+       TEST_PR(   "ldrsh       r2, [r",3,  24,"], r",4, 48,"")
+       TEST_PR(   "ldrsh       r10, [r",9, 48,"], -r",11,24,"")
+       TEST_UNSUPPORTED(".word 0xe1bfc0fa      @ ldrsh r12, [pc, r10]!")
+       TEST_UNSUPPORTED(".word 0xe099f0fb      @ ldrsh pc, [r9], r11")
+
+       TEST_P(    "ldrsh       r0, [r",0,  24,", #-1]")
+       TEST_P(    "ldreqsh     r14, [r",13,0 ,", #1]")
+       TEST_P(    "ldrsh       r1, [r",2,  24,", #4]!")
+       TEST_P(    "ldrnesh     r12, [r",11,24,", #-4]!")
+       TEST_P(    "ldrsh       r2, [r",3,  24,"], #48")
+       TEST_P(    "ldrsh       r10, [r",9, 64,"], #-48")
+       TEST(      "ldrsh       r0, [pc, #0]")
+       TEST_UNSUPPORTED(".word 0xe1ffc3f0      @ ldrsh r12, [pc, #48]!")
+       TEST_UNSUPPORTED(".word 0xe0d9f3f0      @ ldrsh pc, [r9], #48")
+
+#if __LINUX_ARM_ARCH__ >= 7
+       TEST_UNSUPPORTED("strht r1, [r2], r3")
+       TEST_UNSUPPORTED("ldrht r1, [r2], r3")
+       TEST_UNSUPPORTED("strht r1, [r2], #48")
+       TEST_UNSUPPORTED("ldrht r1, [r2], #48")
+       TEST_UNSUPPORTED("ldrsbt        r1, [r2], r3")
+       TEST_UNSUPPORTED("ldrsbt        r1, [r2], #48")
+       TEST_UNSUPPORTED("ldrsht        r1, [r2], r3")
+       TEST_UNSUPPORTED("ldrsht        r1, [r2], #48")
+#endif
+
+       TEST_RPR(  "strd        r",0, VAL1,", [r",1, 48,", -r",2,24,"]")
+       TEST_RPR(  "strccd      r",8, VAL2,", [r",13,0, ", r",12,48,"]")
+       TEST_RPR(  "strd        r",4, VAL1,", [r",2, 24,", r",3, 48,"]!")
+       TEST_RPR(  "strcsd      r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
+       TEST_RPR(  "strd        r",2, VAL1,", [r",3, 24,"], r",4,48,"")
+       TEST_RPR(  "strd        r",10,VAL2,", [r",9, 48,"], -r",7,24,"")
+       TEST_UNSUPPORTED(".word 0xe1afc0fa      @ strd r12, [pc, r10]!")
+
+       TEST_PR(   "ldrd        r0, [r",0, 48,", -r",2,24,"]")
+       TEST_PR(   "ldrmid      r8, [r",13,0, ", r",12,48,"]")
+       TEST_PR(   "ldrd        r4, [r",2, 24,", r",3, 48,"]!")
+       TEST_PR(   "ldrpld      r6, [r",11,48,", -r",10,24,"]!")
+       TEST_PR(   "ldrd        r2, [r",5, 24,"], r",4,48,"")
+       TEST_PR(   "ldrd        r10, [r",9,48,"], -r",7,24,"")
+       TEST_UNSUPPORTED(".word 0xe1afc0da      @ ldrd r12, [pc, r10]!")
+       TEST_UNSUPPORTED(".word 0xe089f0db      @ ldrd pc, [r9], r11")
+       TEST_UNSUPPORTED(".word 0xe089e0db      @ ldrd lr, [r9], r11")
+       TEST_UNSUPPORTED(".word 0xe089c0df      @ ldrd r12, [r9], pc")
+
+       TEST_RP(   "strd        r",0, VAL1,", [r",1, 24,", #-8]")
+       TEST_RP(   "strvsd      r",8, VAL2,", [r",13,0, ", #8]")
+       TEST_RP(   "strd        r",4, VAL1,", [r",2, 24,", #16]!")
+       TEST_RP(   "strvcd      r",12,VAL2,", [r",11,24,", #-16]!")
+       TEST_RP(   "strd        r",2, VAL1,", [r",4, 24,"], #48")
+       TEST_RP(   "strd        r",10,VAL2,", [r",9, 64,"], #-48")
+       TEST_UNSUPPORTED(".word 0xe1efc3f0      @ strd r12, [pc, #48]!")
+
+       TEST_P(    "ldrd        r0, [r",0, 24,", #-8]")
+       TEST_P(    "ldrhid      r8, [r",13,0, ", #8]")
+       TEST_P(    "ldrd        r4, [r",2, 24,", #16]!")
+       TEST_P(    "ldrlsd      r6, [r",11,24,", #-16]!")
+       TEST_P(    "ldrd        r2, [r",5, 24,"], #48")
+       TEST_P(    "ldrd        r10, [r",9,6,"], #-48")
+       TEST_UNSUPPORTED(".word 0xe1efc3d0      @ ldrd r12, [pc, #48]!")
+       TEST_UNSUPPORTED(".word 0xe0c9f3d0      @ ldrd pc, [r9], #48")
+       TEST_UNSUPPORTED(".word 0xe0c9e3d0      @ ldrd lr, [r9], #48")
+
+       TEST_GROUP("Miscellaneous")
+
+#if __LINUX_ARM_ARCH__ >= 7
+       TEST("movw      r0, #0")
+       TEST("movw      r0, #0xffff")
+       TEST("movw      lr, #0xffff")
+       TEST_UNSUPPORTED(".word 0xe300f000      @ movw pc, #0")
+       TEST_R("movt    r",0, VAL1,", #0")
+       TEST_R("movt    r",0, VAL2,", #0xffff")
+       TEST_R("movt    r",14,VAL1,", #0xffff")
+       TEST_UNSUPPORTED(".word 0xe340f000      @ movt pc, #0")
+#endif
+
+       TEST_UNSUPPORTED("msr   cpsr, 0x13")
+       TEST_UNSUPPORTED("msr   cpsr_f, 0xf0000000")
+       TEST_UNSUPPORTED("msr   spsr, 0x13")
+
+#if __LINUX_ARM_ARCH__ >= 7
+       TEST_SUPPORTED("yield")
+       TEST("sev")
+       TEST("nop")
+       TEST("wfi")
+       TEST_SUPPORTED("wfe")
+       TEST_UNSUPPORTED("dbg #0")
+#endif
+
+       TEST_GROUP("Load/store word and unsigned byte")
+
+#define LOAD_STORE(byte)                                                       \
+       TEST_RP( "str"byte"     r",0, VAL1,", [r",1, 24,", #-2]")               \
+       TEST_RP( "str"byte"     r",14,VAL2,", [r",13,0, ", #2]")                \
+       TEST_RP( "str"byte"     r",1, VAL1,", [r",2, 24,", #4]!")               \
+       TEST_RP( "str"byte"     r",12,VAL2,", [r",11,24,", #-4]!")              \
+       TEST_RP( "str"byte"     r",2, VAL1,", [r",3, 24,"], #48")               \
+       TEST_RP( "str"byte"     r",10,VAL2,", [r",9, 64,"], #-48")              \
+       TEST_RPR("str"byte"     r",0, VAL1,", [r",1, 48,", -r",2, 24,"]")       \
+       TEST_RPR("str"byte"     r",14,VAL2,", [r",13,0, ", r",12, 48,"]")       \
+       TEST_RPR("str"byte"     r",1, VAL1,", [r",2, 24,", r",3,  48,"]!")      \
+       TEST_RPR("str"byte"     r",12,VAL2,", [r",11,48,", -r",10,24,"]!")      \
+       TEST_RPR("str"byte"     r",2, VAL1,", [r",3, 24,"], r",4, 48,"")        \
+       TEST_RPR("str"byte"     r",10,VAL2,", [r",9, 48,"], -r",11,24,"")       \
+       TEST_RPR("str"byte"     r",0, VAL1,", [r",1, 24,", r",2,  32,", asl #1]")\
+       TEST_RPR("str"byte"     r",14,VAL2,", [r",13,0, ", r",12, 32,", lsr #2]")\
+       TEST_RPR("str"byte"     r",1, VAL1,", [r",2, 24,", r",3,  32,", asr #3]!")\
+       TEST_RPR("str"byte"     r",12,VAL2,", [r",11,24,", r",10, 4,", ror #31]!")\
+       TEST_P(  "ldr"byte"     r0, [r",0,  24,", #-2]")                        \
+       TEST_P(  "ldr"byte"     r14, [r",13,0, ", #2]")                         \
+       TEST_P(  "ldr"byte"     r1, [r",2,  24,", #4]!")                        \
+       TEST_P(  "ldr"byte"     r12, [r",11,24,", #-4]!")                       \
+       TEST_P(  "ldr"byte"     r2, [r",3,  24,"], #48")                        \
+       TEST_P(  "ldr"byte"     r10, [r",9, 64,"], #-48")                       \
+       TEST_PR( "ldr"byte"     r0, [r",0,  48,", -r",2, 24,"]")                \
+       TEST_PR( "ldr"byte"     r14, [r",13,0, ", r",12, 48,"]")                \
+       TEST_PR( "ldr"byte"     r1, [r",2,  24,", r",3, 48,"]!")                \
+       TEST_PR( "ldr"byte"     r12, [r",11,48,", -r",10,24,"]!")               \
+       TEST_PR( "ldr"byte"     r2, [r",3,  24,"], r",4, 48,"")                 \
+       TEST_PR( "ldr"byte"     r10, [r",9, 48,"], -r",11,24,"")                \
+       TEST_PR( "ldr"byte"     r0, [r",0,  24,", r",2,  32,", asl #1]")        \
+       TEST_PR( "ldr"byte"     r14, [r",13,0, ", r",12, 32,", lsr #2]")        \
+       TEST_PR( "ldr"byte"     r1, [r",2,  24,", r",3,  32,", asr #3]!")       \
+       TEST_PR( "ldr"byte"     r12, [r",11,24,", r",10, 4,", ror #31]!")       \
+       TEST(    "ldr"byte"     r0, [pc, #0]")                                  \
+       TEST_R(  "ldr"byte"     r12, [pc, r",14,0,"]")
+
+       LOAD_STORE("")
+       TEST_P(   "str  pc, [r",0,0,", #15*4]")
+       TEST_R(   "str  pc, [sp, r",2,15*4,"]")
+       TEST_BF(  "ldr  pc, [sp, #15*4]")
+       TEST_BF_R("ldr  pc, [sp, r",2,15*4,"]")
+
+       TEST_P(   "str  sp, [r",0,0,", #13*4]")
+       TEST_R(   "str  sp, [sp, r",2,13*4,"]")
+       TEST_BF(  "ldr  sp, [sp, #13*4]")
+       TEST_BF_R("ldr  sp, [sp, r",2,13*4,"]")
+
+#ifdef CONFIG_THUMB2_KERNEL
+       TEST_ARM_TO_THUMB_INTERWORK_P("ldr      pc, [r",0,0,", #15*4]")
+#endif
+       TEST_UNSUPPORTED(".word 0xe5af6008      @ str r6, [pc, #8]!")
+       TEST_UNSUPPORTED(".word 0xe7af6008      @ str r6, [pc, r8]!")
+       TEST_UNSUPPORTED(".word 0xe5bf6008      @ ldr r6, [pc, #8]!")
+       TEST_UNSUPPORTED(".word 0xe7bf6008      @ ldr r6, [pc, r8]!")
+       TEST_UNSUPPORTED(".word 0xe788600f      @ str r6, [r8, pc]")
+       TEST_UNSUPPORTED(".word 0xe798600f      @ ldr r6, [r8, pc]")
+
+       LOAD_STORE("b")
+       TEST_UNSUPPORTED(".word 0xe5f7f008      @ ldrb pc, [r7, #8]!")
+       TEST_UNSUPPORTED(".word 0xe7f7f008      @ ldrb pc, [r7, r8]!")
+       TEST_UNSUPPORTED(".word 0xe5ef6008      @ strb r6, [pc, #8]!")
+       TEST_UNSUPPORTED(".word 0xe7ef6008      @ strb r6, [pc, r3]!")
+       TEST_UNSUPPORTED(".word 0xe5ff6008      @ ldrb r6, [pc, #8]!")
+       TEST_UNSUPPORTED(".word 0xe7ff6008      @ ldrb r6, [pc, r3]!")
+
+       TEST_UNSUPPORTED("ldrt  r0, [r1], #4")
+       TEST_UNSUPPORTED("ldrt  r1, [r2], r3")
+       TEST_UNSUPPORTED("strt  r2, [r3], #4")
+       TEST_UNSUPPORTED("strt  r3, [r4], r5")
+       TEST_UNSUPPORTED("ldrbt r4, [r5], #4")
+       TEST_UNSUPPORTED("ldrbt r5, [r6], r7")
+       TEST_UNSUPPORTED("strbt r6, [r7], #4")
+       TEST_UNSUPPORTED("strbt r7, [r8], r9")
+
+#if __LINUX_ARM_ARCH__ >= 7
+       TEST_GROUP("Parallel addition and subtraction, signed")
+
+       TEST_UNSUPPORTED(".word 0xe6000010") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe60fffff") /* Unallocated space */
+
+       TEST_RR(    "sadd16     r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "sadd16     r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe61cff1a      @ sadd16        pc, r12, r10")
+       TEST_RR(    "sasx       r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "sasx       r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe61cff3a      @ sasx  pc, r12, r10")
+       TEST_RR(    "ssax       r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "ssax       r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe61cff5a      @ ssax  pc, r12, r10")
+       TEST_RR(    "ssub16     r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "ssub16     r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe61cff7a      @ ssub16        pc, r12, r10")
+       TEST_RR(    "sadd8      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "sadd8      r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe61cff9a      @ sadd8 pc, r12, r10")
+       TEST_UNSUPPORTED(".word 0xe61000b0") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe61fffbf") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe61000d0") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe61fffdf") /* Unallocated space */
+       TEST_RR(    "ssub8      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "ssub8      r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe61cfffa      @ ssub8 pc, r12, r10")
+
+       TEST_RR(    "qadd16     r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "qadd16     r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe62cff1a      @ qadd16        pc, r12, r10")
+       TEST_RR(    "qasx       r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "qasx       r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe62cff3a      @ qasx  pc, r12, r10")
+       TEST_RR(    "qsax       r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "qsax       r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe62cff5a      @ qsax  pc, r12, r10")
+       TEST_RR(    "qsub16     r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "qsub16     r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe62cff7a      @ qsub16        pc, r12, r10")
+       TEST_RR(    "qadd8      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "qadd8      r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe62cff9a      @ qadd8 pc, r12, r10")
+       TEST_UNSUPPORTED(".word 0xe62000b0") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe62fffbf") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe62000d0") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe62fffdf") /* Unallocated space */
+       TEST_RR(    "qsub8      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "qsub8      r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe62cfffa      @ qsub8 pc, r12, r10")
+
+       TEST_RR(    "shadd16    r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "shadd16    r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe63cff1a      @ shadd16       pc, r12, r10")
+       TEST_RR(    "shasx      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "shasx      r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe63cff3a      @ shasx pc, r12, r10")
+       TEST_RR(    "shsax      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "shsax      r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe63cff5a      @ shsax pc, r12, r10")
+       TEST_RR(    "shsub16    r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "shsub16    r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe63cff7a      @ shsub16       pc, r12, r10")
+       TEST_RR(    "shadd8     r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "shadd8     r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe63cff9a      @ shadd8        pc, r12, r10")
+       TEST_UNSUPPORTED(".word 0xe63000b0") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe63fffbf") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe63000d0") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe63fffdf") /* Unallocated space */
+       TEST_RR(    "shsub8     r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "shsub8     r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe63cfffa      @ shsub8        pc, r12, r10")
+
+       TEST_GROUP("Parallel addition and subtraction, unsigned")
+
+       TEST_UNSUPPORTED(".word 0xe6400010") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe64fffff") /* Unallocated space */
+
+       TEST_RR(    "uadd16     r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uadd16     r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe65cff1a      @ uadd16        pc, r12, r10")
+       TEST_RR(    "uasx       r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uasx       r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe65cff3a      @ uasx  pc, r12, r10")
+       TEST_RR(    "usax       r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "usax       r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe65cff5a      @ usax  pc, r12, r10")
+       TEST_RR(    "usub16     r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "usub16     r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe65cff7a      @ usub16        pc, r12, r10")
+       TEST_RR(    "uadd8      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uadd8      r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe65cff9a      @ uadd8 pc, r12, r10")
+       TEST_UNSUPPORTED(".word 0xe65000b0") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe65fffbf") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe65000d0") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe65fffdf") /* Unallocated space */
+       TEST_RR(    "usub8      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "usub8      r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe65cfffa      @ usub8 pc, r12, r10")
+
+       TEST_RR(    "uqadd16    r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uqadd16    r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe66cff1a      @ uqadd16       pc, r12, r10")
+       TEST_RR(    "uqasx      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uqasx      r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe66cff3a      @ uqasx pc, r12, r10")
+       TEST_RR(    "uqsax      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uqsax      r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe66cff5a      @ uqsax pc, r12, r10")
+       TEST_RR(    "uqsub16    r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uqsub16    r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe66cff7a      @ uqsub16       pc, r12, r10")
+       TEST_RR(    "uqadd8     r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uqadd8     r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe66cff9a      @ uqadd8        pc, r12, r10")
+       TEST_UNSUPPORTED(".word 0xe66000b0") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe66fffbf") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe66000d0") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe66fffdf") /* Unallocated space */
+       TEST_RR(    "uqsub8     r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uqsub8     r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe66cfffa      @ uqsub8        pc, r12, r10")
+
+       TEST_RR(    "uhadd16    r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uhadd16    r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe67cff1a      @ uhadd16       pc, r12, r10")
+       TEST_RR(    "uhasx      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uhasx      r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe67cff3a      @ uhasx pc, r12, r10")
+       TEST_RR(    "uhsax      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uhsax      r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe67cff5a      @ uhsax pc, r12, r10")
+       TEST_RR(    "uhsub16    r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uhsub16    r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe67cff7a      @ uhsub16       pc, r12, r10")
+       TEST_RR(    "uhadd8     r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uhadd8     r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe67cff9a      @ uhadd8        pc, r12, r10")
+       TEST_UNSUPPORTED(".word 0xe67000b0") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe67fffbf") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe67000d0") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe67fffdf") /* Unallocated space */
+       TEST_RR(    "uhsub8     r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uhsub8     r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe67cfffa      @ uhsub8        pc, r12, r10")
+       TEST_UNSUPPORTED(".word 0xe67feffa      @ uhsub8        r14, pc, r10")
+       TEST_UNSUPPORTED(".word 0xe67cefff      @ uhsub8        r14, r12, pc")
+#endif /* __LINUX_ARM_ARCH__ >= 7 */
+
+#if __LINUX_ARM_ARCH__ >= 6
+       TEST_GROUP("Packing, unpacking, saturation, and reversal")
+
+       TEST_RR(    "pkhbt      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "pkhbt      r14,r",12, HH1,", r",10,HH2,", lsl #2")
+       TEST_UNSUPPORTED(".word 0xe68cf11a      @ pkhbt pc, r12, r10, lsl #2")
+       TEST_RR(    "pkhtb      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "pkhtb      r14,r",12, HH1,", r",10,HH2,", asr #2")
+       TEST_UNSUPPORTED(".word 0xe68cf15a      @ pkhtb pc, r12, r10, asr #2")
+       TEST_UNSUPPORTED(".word 0xe68fe15a      @ pkhtb r14, pc, r10, asr #2")
+       TEST_UNSUPPORTED(".word 0xe68ce15f      @ pkhtb r14, r12, pc, asr #2")
+       TEST_UNSUPPORTED(".word 0xe6900010") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe69fffdf") /* Unallocated space */
+
+       TEST_R(     "ssat       r0, #24, r",0,   VAL1,"")
+       TEST_R(     "ssat       r14, #24, r",12, VAL2,"")
+       TEST_R(     "ssat       r0, #24, r",0,   VAL1,", lsl #8")
+       TEST_R(     "ssat       r14, #24, r",12, VAL2,", asr #8")
+       TEST_UNSUPPORTED(".word 0xe6b7f01c      @ ssat  pc, #24, r12")
+
+       TEST_R(     "usat       r0, #24, r",0,   VAL1,"")
+       TEST_R(     "usat       r14, #24, r",12, VAL2,"")
+       TEST_R(     "usat       r0, #24, r",0,   VAL1,", lsl #8")
+       TEST_R(     "usat       r14, #24, r",12, VAL2,", asr #8")
+       TEST_UNSUPPORTED(".word 0xe6f7f01c      @ usat  pc, #24, r12")
+
+       TEST_RR(    "sxtab16    r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "sxtab16    r14,r",12, HH2,", r",10,HH1,", ror #8")
+       TEST_R(     "sxtb16     r8, r",7,  HH1,"")
+       TEST_UNSUPPORTED(".word 0xe68cf47a      @ sxtab16       pc,r12, r10, ror #8")
+
+       TEST_RR(    "sel        r0, r",0,  VAL1,", r",1, VAL2,"")
+       TEST_RR(    "sel        r14, r",12,VAL1,", r",10, VAL2,"")
+       TEST_UNSUPPORTED(".word 0xe68cffba      @ sel   pc, r12, r10")
+       TEST_UNSUPPORTED(".word 0xe68fefba      @ sel   r14, pc, r10")
+       TEST_UNSUPPORTED(".word 0xe68cefbf      @ sel   r14, r12, pc")
+
+       TEST_R(     "ssat16     r0, #12, r",0,   HH1,"")
+       TEST_R(     "ssat16     r14, #12, r",12, HH2,"")
+       TEST_UNSUPPORTED(".word 0xe6abff3c      @ ssat16        pc, #12, r12")
+
+       TEST_RR(    "sxtab      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "sxtab      r14,r",12, HH2,", r",10,HH1,", ror #8")
+       TEST_R(     "sxtb       r8, r",7,  HH1,"")
+       TEST_UNSUPPORTED(".word 0xe6acf47a      @ sxtab pc,r12, r10, ror #8")
+
+       TEST_R(     "rev        r0, r",0,   VAL1,"")
+       TEST_R(     "rev        r14, r",12, VAL2,"")
+       TEST_UNSUPPORTED(".word 0xe6bfff3c      @ rev   pc, r12")
+
+       TEST_RR(    "sxtah      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "sxtah      r14,r",12, HH2,", r",10,HH1,", ror #8")
+       TEST_R(     "sxth       r8, r",7,  HH1,"")
+       TEST_UNSUPPORTED(".word 0xe6bcf47a      @ sxtah pc,r12, r10, ror #8")
+
+       TEST_R(     "rev16      r0, r",0,   VAL1,"")
+       TEST_R(     "rev16      r14, r",12, VAL2,"")
+       TEST_UNSUPPORTED(".word 0xe6bfffbc      @ rev16 pc, r12")
+
+       TEST_RR(    "uxtab16    r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uxtab16    r14,r",12, HH2,", r",10,HH1,", ror #8")
+       TEST_R(     "uxtb16     r8, r",7,  HH1,"")
+       TEST_UNSUPPORTED(".word 0xe6ccf47a      @ uxtab16       pc,r12, r10, ror #8")
+
+       TEST_R(     "usat16     r0, #12, r",0,   HH1,"")
+       TEST_R(     "usat16     r14, #12, r",12, HH2,"")
+       TEST_UNSUPPORTED(".word 0xe6ecff3c      @ usat16        pc, #12, r12")
+       TEST_UNSUPPORTED(".word 0xe6ecef3f      @ usat16        r14, #12, pc")
+
+       TEST_RR(    "uxtab      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uxtab      r14,r",12, HH2,", r",10,HH1,", ror #8")
+       TEST_R(     "uxtb       r8, r",7,  HH1,"")
+       TEST_UNSUPPORTED(".word 0xe6ecf47a      @ uxtab pc,r12, r10, ror #8")
+
+#if __LINUX_ARM_ARCH__ >= 7
+       TEST_R(     "rbit       r0, r",0,   VAL1,"")
+       TEST_R(     "rbit       r14, r",12, VAL2,"")
+       TEST_UNSUPPORTED(".word 0xe6ffff3c      @ rbit  pc, r12")
+#endif
+
+       TEST_RR(    "uxtah      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(    "uxtah      r14,r",12, HH2,", r",10,HH1,", ror #8")
+       TEST_R(     "uxth       r8, r",7,  HH1,"")
+       TEST_UNSUPPORTED(".word 0xe6fff077      @ uxth  pc, r7")
+       TEST_UNSUPPORTED(".word 0xe6ff807f      @ uxth  r8, pc")
+       TEST_UNSUPPORTED(".word 0xe6fcf47a      @ uxtah pc, r12, r10, ror #8")
+       TEST_UNSUPPORTED(".word 0xe6fce47f      @ uxtah r14, r12, pc, ror #8")
+
+       TEST_R(     "revsh      r0, r",0,   VAL1,"")
+       TEST_R(     "revsh      r14, r",12, VAL2,"")
+       TEST_UNSUPPORTED(".word 0xe6ffff3c      @ revsh pc, r12")
+       TEST_UNSUPPORTED(".word 0xe6ffef3f      @ revsh r14, pc")
+
+       TEST_UNSUPPORTED(".word 0xe6900070") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe69fff7f") /* Unallocated space */
+
+       TEST_UNSUPPORTED(".word 0xe6d00070") /* Unallocated space */
+       TEST_UNSUPPORTED(".word 0xe6dfff7f") /* Unallocated space */
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
+#if __LINUX_ARM_ARCH__ >= 6
+       TEST_GROUP("Signed multiplies")
+
+       TEST_RRR(   "smlad      r0, r",0,  HH1,", r",1, HH2,", r",2, VAL1,"")
+       TEST_RRR(   "smlad      r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"")
+       TEST_UNSUPPORTED(".word 0xe70f8a1c      @ smlad pc, r12, r10, r8")
+       TEST_RRR(   "smladx     r0, r",0,  HH1,", r",1, HH2,", r",2, VAL1,"")
+       TEST_RRR(   "smladx     r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"")
+       TEST_UNSUPPORTED(".word 0xe70f8a3c      @ smladx        pc, r12, r10, r8")
+
+       TEST_RR(   "smuad       r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(   "smuad       r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe70ffa1c      @ smuad pc, r12, r10")
+       TEST_RR(   "smuadx      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(   "smuadx      r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe70ffa3c      @ smuadx        pc, r12, r10")
+
+       TEST_RRR(   "smlsd      r0, r",0,  HH1,", r",1, HH2,", r",2, VAL1,"")
+       TEST_RRR(   "smlsd      r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"")
+       TEST_UNSUPPORTED(".word 0xe70f8a5c      @ smlsd pc, r12, r10, r8")
+       TEST_RRR(   "smlsdx     r0, r",0,  HH1,", r",1, HH2,", r",2, VAL1,"")
+       TEST_RRR(   "smlsdx     r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"")
+       TEST_UNSUPPORTED(".word 0xe70f8a7c      @ smlsdx        pc, r12, r10, r8")
+
+       TEST_RR(   "smusd       r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(   "smusd       r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe70ffa5c      @ smusd pc, r12, r10")
+       TEST_RR(   "smusdx      r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR(   "smusdx      r14, r",12,HH2,", r",10,HH1,"")
+       TEST_UNSUPPORTED(".word 0xe70ffa7c      @ smusdx        pc, r12, r10")
+
+       TEST_RRRR( "smlald      r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2)
+       TEST_RRRR( "smlald      r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1)
+       TEST_UNSUPPORTED(".word 0xe74af819      @ smlald        pc, r10, r9, r8")
+       TEST_UNSUPPORTED(".word 0xe74fb819      @ smlald        r11, pc, r9, r8")
+       TEST_UNSUPPORTED(".word 0xe74ab81f      @ smlald        r11, r10, pc, r8")
+       TEST_UNSUPPORTED(".word 0xe74abf19      @ smlald        r11, r10, r9, pc")
+
+       TEST_RRRR( "smlaldx     r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2)
+       TEST_RRRR( "smlaldx     r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1)
+       TEST_UNSUPPORTED(".word 0xe74af839      @ smlaldx       pc, r10, r9, r8")
+       TEST_UNSUPPORTED(".word 0xe74fb839      @ smlaldx       r11, pc, r9, r8")
+
+       TEST_RRR(  "smmla       r0, r",0,  VAL1,", r",1, VAL2,", r",2, VAL1,"")
+       TEST_RRR(  "smmla       r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"")
+       TEST_UNSUPPORTED(".word 0xe75f8a1c      @ smmla pc, r12, r10, r8")
+       TEST_RRR(  "smmlar      r0, r",0,  VAL1,", r",1, VAL2,", r",2, VAL1,"")
+       TEST_RRR(  "smmlar      r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"")
+       TEST_UNSUPPORTED(".word 0xe75f8a3c      @ smmlar        pc, r12, r10, r8")
+
+       TEST_RR(   "smmul       r0, r",0,  VAL1,", r",1, VAL2,"")
+       TEST_RR(   "smmul       r14, r",12,VAL2,", r",10,VAL1,"")
+       TEST_UNSUPPORTED(".word 0xe75ffa1c      @ smmul pc, r12, r10")
+       TEST_RR(   "smmulr      r0, r",0,  VAL1,", r",1, VAL2,"")
+       TEST_RR(   "smmulr      r14, r",12,VAL2,", r",10,VAL1,"")
+       TEST_UNSUPPORTED(".word 0xe75ffa3c      @ smmulr        pc, r12, r10")
+
+       TEST_RRR(  "smmls       r0, r",0,  VAL1,", r",1, VAL2,", r",2, VAL1,"")
+       TEST_RRR(  "smmls       r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"")
+       TEST_UNSUPPORTED(".word 0xe75f8adc      @ smmls pc, r12, r10, r8")
+       TEST_RRR(  "smmlsr      r0, r",0,  VAL1,", r",1, VAL2,", r",2, VAL1,"")
+       TEST_RRR(  "smmlsr      r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"")
+       TEST_UNSUPPORTED(".word 0xe75f8afc      @ smmlsr        pc, r12, r10, r8")
+       TEST_UNSUPPORTED(".word 0xe75e8aff      @ smmlsr        r14, pc, r10, r8")
+       TEST_UNSUPPORTED(".word 0xe75e8ffc      @ smmlsr        r14, r12, pc, r8")
+       TEST_UNSUPPORTED(".word 0xe75efafc      @ smmlsr        r14, r12, r10, pc")
+
+       TEST_RR(   "usad8       r0, r",0,  VAL1,", r",1, VAL2,"")
+       TEST_RR(   "usad8       r14, r",12,VAL2,", r",10,VAL1,"")
+       TEST_UNSUPPORTED(".word 0xe75ffa1c      @ usad8 pc, r12, r10")
+       TEST_UNSUPPORTED(".word 0xe75efa1f      @ usad8 r14, pc, r10")
+       TEST_UNSUPPORTED(".word 0xe75eff1c      @ usad8 r14, r12, pc")
+
+       TEST_RRR(  "usada8      r0, r",0,  VAL1,", r",1, VAL2,", r",2, VAL3,"")
+       TEST_RRR(  "usada8      r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL3,"")
+       TEST_UNSUPPORTED(".word 0xe78f8a1c      @ usada8        pc, r12, r10, r8")
+       TEST_UNSUPPORTED(".word 0xe78e8a1f      @ usada8        r14, pc, r10, r8")
+       TEST_UNSUPPORTED(".word 0xe78e8f1c      @ usada8        r14, r12, pc, r8")
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
+#if __LINUX_ARM_ARCH__ >= 7
+       TEST_GROUP("Bit Field")
+
+       TEST_R(     "sbfx       r0, r",0  , VAL1,", #0, #31")
+       TEST_R(     "sbfxeq     r14, r",12, VAL2,", #8, #16")
+       TEST_R(     "sbfx       r4, r",10,  VAL1,", #16, #15")
+       TEST_UNSUPPORTED(".word 0xe7aff45c      @ sbfx  pc, r12, #8, #16")
+
+       TEST_R(     "ubfx       r0, r",0  , VAL1,", #0, #31")
+       TEST_R(     "ubfxcs     r14, r",12, VAL2,", #8, #16")
+       TEST_R(     "ubfx       r4, r",10,  VAL1,", #16, #15")
+       TEST_UNSUPPORTED(".word 0xe7eff45c      @ ubfx  pc, r12, #8, #16")
+       TEST_UNSUPPORTED(".word 0xe7efc45f      @ ubfx  r12, pc, #8, #16")
+
+       TEST_R(     "bfc        r",0, VAL1,", #4, #20")
+       TEST_R(     "bfcvs      r",14,VAL2,", #4, #20")
+       TEST_R(     "bfc        r",7, VAL1,", #0, #31")
+       TEST_R(     "bfc        r",8, VAL2,", #0, #31")
+       TEST_UNSUPPORTED(".word 0xe7def01f      @ bfc   pc, #0, #31");
+
+       TEST_RR(    "bfi        r",0, VAL1,", r",0  , VAL2,", #0, #31")
+       TEST_RR(    "bfipl      r",12,VAL1,", r",14 , VAL2,", #4, #20")
+       TEST_UNSUPPORTED(".word 0xe7d7f21e      @ bfi   pc, r14, #4, #20")
+
+       TEST_UNSUPPORTED(".word 0x07f000f0")  /* Permanently UNDEFINED */
+       TEST_UNSUPPORTED(".word 0x07ffffff")  /* Permanently UNDEFINED */
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
+       TEST_GROUP("Branch, branch with link, and block data transfer")
+
+       TEST_P(   "stmda        r",0, 16*4,", {r0}")
+       TEST_P(   "stmeqda      r",4, 16*4,", {r0-r15}")
+       TEST_P(   "stmneda      r",8, 16*4,"!, {r8-r15}")
+       TEST_P(   "stmda        r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+       TEST_P(   "stmda        r",13,0,   "!, {pc}")
+
+       TEST_P(   "ldmda        r",0, 16*4,", {r0}")
+       TEST_BF_P("ldmcsda      r",4, 15*4,", {r0-r15}")
+       TEST_BF_P("ldmccda      r",7, 15*4,"!, {r8-r15}")
+       TEST_P(   "ldmda        r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+       TEST_BF_P("ldmda        r",14,15*4,"!, {pc}")
+
+       TEST_P(   "stmia        r",0, 16*4,", {r0}")
+       TEST_P(   "stmmiia      r",4, 16*4,", {r0-r15}")
+       TEST_P(   "stmplia      r",8, 16*4,"!, {r8-r15}")
+       TEST_P(   "stmia        r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+       TEST_P(   "stmia        r",14,0,   "!, {pc}")
+
+       TEST_P(   "ldmia        r",0, 16*4,", {r0}")
+       TEST_BF_P("ldmvsia      r",4, 0,   ", {r0-r15}")
+       TEST_BF_P("ldmvcia      r",7, 8*4, "!, {r8-r15}")
+       TEST_P(   "ldmia        r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+       TEST_BF_P("ldmia        r",14,15*4,"!, {pc}")
+
+       TEST_P(   "stmdb        r",0, 16*4,", {r0}")
+       TEST_P(   "stmhidb      r",4, 16*4,", {r0-r15}")
+       TEST_P(   "stmlsdb      r",8, 16*4,"!, {r8-r15}")
+       TEST_P(   "stmdb        r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+       TEST_P(   "stmdb        r",13,4,   "!, {pc}")
+
+       TEST_P(   "ldmdb        r",0, 16*4,", {r0}")
+       TEST_BF_P("ldmgedb      r",4, 16*4,", {r0-r15}")
+       TEST_BF_P("ldmltdb      r",7, 16*4,"!, {r8-r15}")
+       TEST_P(   "ldmdb        r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+       TEST_BF_P("ldmdb        r",14,16*4,"!, {pc}")
+
+       TEST_P(   "stmib        r",0, 16*4,", {r0}")
+       TEST_P(   "stmgtib      r",4, 16*4,", {r0-r15}")
+       TEST_P(   "stmleib      r",8, 16*4,"!, {r8-r15}")
+       TEST_P(   "stmib        r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+       TEST_P(   "stmib        r",13,-4,  "!, {pc}")
+
+       TEST_P(   "ldmib        r",0, 16*4,", {r0}")
+       TEST_BF_P("ldmeqib      r",4, -4,", {r0-r15}")
+       TEST_BF_P("ldmneib      r",7, 7*4,"!, {r8-r15}")
+       TEST_P(   "ldmib        r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+       TEST_BF_P("ldmib        r",14,14*4,"!, {pc}")
+
+       TEST_P(   "stmdb        r",13,16*4,"!, {r3-r12,lr}")
+       TEST_P(   "stmeqdb      r",13,16*4,"!, {r3-r12}")
+       TEST_P(   "stmnedb      r",2, 16*4,", {r3-r12,lr}")
+       TEST_P(   "stmdb        r",13,16*4,"!, {r2-r12,lr}")
+       TEST_P(   "stmdb        r",0, 16*4,", {r0-r12}")
+       TEST_P(   "stmdb        r",0, 16*4,", {r0-r12,lr}")
+
+       TEST_BF_P("ldmia        r",13,5*4, "!, {r3-r12,pc}")
+       TEST_P(   "ldmccia      r",13,5*4, "!, {r3-r12}")
+       TEST_BF_P("ldmcsia      r",2, 5*4, "!, {r3-r12,pc}")
+       TEST_BF_P("ldmia        r",13,4*4, "!, {r2-r12,pc}")
+       TEST_P(   "ldmia        r",0, 16*4,", {r0-r12}")
+       TEST_P(   "ldmia        r",0, 16*4,", {r0-r12,lr}")
+
+#ifdef CONFIG_THUMB2_KERNEL
+       TEST_ARM_TO_THUMB_INTERWORK_P("ldmplia  r",0,15*4,", {pc}")
+       TEST_ARM_TO_THUMB_INTERWORK_P("ldmmiia  r",13,0,", {r0-r15}")
+#endif
+       TEST_BF("b      2f")
+       TEST_BF("bl     2f")
+       TEST_BB("b      2b")
+       TEST_BB("bl     2b")
+
+       TEST_BF("beq    2f")
+       TEST_BF("bleq   2f")
+       TEST_BB("bne    2b")
+       TEST_BB("blne   2b")
+
+       TEST_BF("bgt    2f")
+       TEST_BF("blgt   2f")
+       TEST_BB("blt    2b")
+       TEST_BB("bllt   2b")
+
+       TEST_GROUP("Supervisor Call, and coprocessor instructions")
+
+       /*
+        * We can't really test these by executing them, so all
+        * we can do is check that probes are, or are not allowed.
+        * At the moment none are allowed...
+        */
+#define TEST_COPROCESSOR(code) TEST_UNSUPPORTED(code)
+
+#define COPROCESSOR_INSTRUCTIONS_ST_LD(two,cc)                                 \
+       TEST_COPROCESSOR("stc"two"      0, cr0, [r13, #4]")                     \
+       TEST_COPROCESSOR("stc"two"      0, cr0, [r13, #-4]")                    \
+       TEST_COPROCESSOR("stc"two"      0, cr0, [r13, #4]!")                    \
+       TEST_COPROCESSOR("stc"two"      0, cr0, [r13, #-4]!")                   \
+       TEST_COPROCESSOR("stc"two"      0, cr0, [r13], #4")                     \
+       TEST_COPROCESSOR("stc"two"      0, cr0, [r13], #-4")                    \
+       TEST_COPROCESSOR("stc"two"      0, cr0, [r13], {1}")                    \
+       TEST_COPROCESSOR("stc"two"l     0, cr0, [r13, #4]")                     \
+       TEST_COPROCESSOR("stc"two"l     0, cr0, [r13, #-4]")                    \
+       TEST_COPROCESSOR("stc"two"l     0, cr0, [r13, #4]!")                    \
+       TEST_COPROCESSOR("stc"two"l     0, cr0, [r13, #-4]!")                   \
+       TEST_COPROCESSOR("stc"two"l     0, cr0, [r13], #4")                     \
+       TEST_COPROCESSOR("stc"two"l     0, cr0, [r13], #-4")                    \
+       TEST_COPROCESSOR("stc"two"l     0, cr0, [r13], {1}")                    \
+       TEST_COPROCESSOR("ldc"two"      0, cr0, [r13, #4]")                     \
+       TEST_COPROCESSOR("ldc"two"      0, cr0, [r13, #-4]")                    \
+       TEST_COPROCESSOR("ldc"two"      0, cr0, [r13, #4]!")                    \
+       TEST_COPROCESSOR("ldc"two"      0, cr0, [r13, #-4]!")                   \
+       TEST_COPROCESSOR("ldc"two"      0, cr0, [r13], #4")                     \
+       TEST_COPROCESSOR("ldc"two"      0, cr0, [r13], #-4")                    \
+       TEST_COPROCESSOR("ldc"two"      0, cr0, [r13], {1}")                    \
+       TEST_COPROCESSOR("ldc"two"l     0, cr0, [r13, #4]")                     \
+       TEST_COPROCESSOR("ldc"two"l     0, cr0, [r13, #-4]")                    \
+       TEST_COPROCESSOR("ldc"two"l     0, cr0, [r13, #4]!")                    \
+       TEST_COPROCESSOR("ldc"two"l     0, cr0, [r13, #-4]!")                   \
+       TEST_COPROCESSOR("ldc"two"l     0, cr0, [r13], #4")                     \
+       TEST_COPROCESSOR("ldc"two"l     0, cr0, [r13], #-4")                    \
+       TEST_COPROCESSOR("ldc"two"l     0, cr0, [r13], {1}")                    \
+                                                                               \
+       TEST_COPROCESSOR( "stc"two"     0, cr0, [r15, #4]")                     \
+       TEST_COPROCESSOR( "stc"two"     0, cr0, [r15, #-4]")                    \
+       TEST_UNSUPPORTED(".word 0x"cc"daf0001   @ stc"two"      0, cr0, [r15, #4]!")    \
+       TEST_UNSUPPORTED(".word 0x"cc"d2f0001   @ stc"two"      0, cr0, [r15, #-4]!")   \
+       TEST_UNSUPPORTED(".word 0x"cc"caf0001   @ stc"two"      0, cr0, [r15], #4")     \
+       TEST_UNSUPPORTED(".word 0x"cc"c2f0001   @ stc"two"      0, cr0, [r15], #-4")    \
+       TEST_COPROCESSOR( "stc"two"     0, cr0, [r15], {1}")                    \
+       TEST_COPROCESSOR( "stc"two"l    0, cr0, [r15, #4]")                     \
+       TEST_COPROCESSOR( "stc"two"l    0, cr0, [r15, #-4]")                    \
+       TEST_UNSUPPORTED(".word 0x"cc"def0001   @ stc"two"l     0, cr0, [r15, #4]!")    \
+       TEST_UNSUPPORTED(".word 0x"cc"d6f0001   @ stc"two"l     0, cr0, [r15, #-4]!")   \
+       TEST_UNSUPPORTED(".word 0x"cc"cef0001   @ stc"two"l     0, cr0, [r15], #4")     \
+       TEST_UNSUPPORTED(".word 0x"cc"c6f0001   @ stc"two"l     0, cr0, [r15], #-4")    \
+       TEST_COPROCESSOR( "stc"two"l    0, cr0, [r15], {1}")                    \
+       TEST_COPROCESSOR( "ldc"two"     0, cr0, [r15, #4]")                     \
+       TEST_COPROCESSOR( "ldc"two"     0, cr0, [r15, #-4]")                    \
+       TEST_UNSUPPORTED(".word 0x"cc"dbf0001   @ ldc"two"      0, cr0, [r15, #4]!")    \
+       TEST_UNSUPPORTED(".word 0x"cc"d3f0001   @ ldc"two"      0, cr0, [r15, #-4]!")   \
+       TEST_UNSUPPORTED(".word 0x"cc"cbf0001   @ ldc"two"      0, cr0, [r15], #4")     \
+       TEST_UNSUPPORTED(".word 0x"cc"c3f0001   @ ldc"two"      0, cr0, [r15], #-4")    \
+       TEST_COPROCESSOR( "ldc"two"     0, cr0, [r15], {1}")                    \
+       TEST_COPROCESSOR( "ldc"two"l    0, cr0, [r15, #4]")                     \
+       TEST_COPROCESSOR( "ldc"two"l    0, cr0, [r15, #-4]")                    \
+       TEST_UNSUPPORTED(".word 0x"cc"dff0001   @ ldc"two"l     0, cr0, [r15, #4]!")    \
+       TEST_UNSUPPORTED(".word 0x"cc"d7f0001   @ ldc"two"l     0, cr0, [r15, #-4]!")   \
+       TEST_UNSUPPORTED(".word 0x"cc"cff0001   @ ldc"two"l     0, cr0, [r15], #4")     \
+       TEST_UNSUPPORTED(".word 0x"cc"c7f0001   @ ldc"two"l     0, cr0, [r15], #-4")    \
+       TEST_COPROCESSOR( "ldc"two"l    0, cr0, [r15], {1}")
+
+#define COPROCESSOR_INSTRUCTIONS_MC_MR(two,cc)                                 \
+                                                                               \
+       TEST_COPROCESSOR( "mcrr"two"    0, 15, r0, r14, cr0")                   \
+       TEST_COPROCESSOR( "mcrr"two"    15, 0, r14, r0, cr15")                  \
+       TEST_UNSUPPORTED(".word 0x"cc"c4f00f0   @ mcrr"two"     0, 15, r0, r15, cr0")   \
+       TEST_UNSUPPORTED(".word 0x"cc"c40ff0f   @ mcrr"two"     15, 0, r15, r0, cr15")  \
+       TEST_COPROCESSOR( "mrrc"two"    0, 15, r0, r14, cr0")                   \
+       TEST_COPROCESSOR( "mrrc"two"    15, 0, r14, r0, cr15")                  \
+       TEST_UNSUPPORTED(".word 0x"cc"c5f00f0   @ mrrc"two"     0, 15, r0, r15, cr0")   \
+       TEST_UNSUPPORTED(".word 0x"cc"c50ff0f   @ mrrc"two"     15, 0, r15, r0, cr15")  \
+       TEST_COPROCESSOR( "cdp"two"     15, 15, cr15, cr15, cr15, 7")           \
+       TEST_COPROCESSOR( "cdp"two"     0, 0, cr0, cr0, cr0, 0")                \
+       TEST_COPROCESSOR( "mcr"two"     15, 7, r15, cr15, cr15, 7")             \
+       TEST_COPROCESSOR( "mcr"two"     0, 0, r0, cr0, cr0, 0")                 \
+       TEST_COPROCESSOR( "mrc"two"     15, 7, r15, cr15, cr15, 7")             \
+       TEST_COPROCESSOR( "mrc"two"     0, 0, r0, cr0, cr0, 0")
+
+       COPROCESSOR_INSTRUCTIONS_ST_LD("","e")
+       COPROCESSOR_INSTRUCTIONS_MC_MR("","e")
+       TEST_UNSUPPORTED("svc   0")
+       TEST_UNSUPPORTED("svc   0xffffff")
+
+       TEST_UNSUPPORTED("svc   0")
+
+       TEST_GROUP("Unconditional instruction")
+
+#if __LINUX_ARM_ARCH__ >= 6
+       TEST_UNSUPPORTED("srsda sp, 0x13")
+       TEST_UNSUPPORTED("srsdb sp, 0x13")
+       TEST_UNSUPPORTED("srsia sp, 0x13")
+       TEST_UNSUPPORTED("srsib sp, 0x13")
+       TEST_UNSUPPORTED("srsda sp!, 0x13")
+       TEST_UNSUPPORTED("srsdb sp!, 0x13")
+       TEST_UNSUPPORTED("srsia sp!, 0x13")
+       TEST_UNSUPPORTED("srsib sp!, 0x13")
+
+       TEST_UNSUPPORTED("rfeda sp")
+       TEST_UNSUPPORTED("rfedb sp")
+       TEST_UNSUPPORTED("rfeia sp")
+       TEST_UNSUPPORTED("rfeib sp")
+       TEST_UNSUPPORTED("rfeda sp!")
+       TEST_UNSUPPORTED("rfedb sp!")
+       TEST_UNSUPPORTED("rfeia sp!")
+       TEST_UNSUPPORTED("rfeib sp!")
+       TEST_UNSUPPORTED(".word 0xf81d0a00      @ rfeda pc")
+       TEST_UNSUPPORTED(".word 0xf91d0a00      @ rfedb pc")
+       TEST_UNSUPPORTED(".word 0xf89d0a00      @ rfeia pc")
+       TEST_UNSUPPORTED(".word 0xf99d0a00      @ rfeib pc")
+       TEST_UNSUPPORTED(".word 0xf83d0a00      @ rfeda pc!")
+       TEST_UNSUPPORTED(".word 0xf93d0a00      @ rfedb pc!")
+       TEST_UNSUPPORTED(".word 0xf8bd0a00      @ rfeia pc!")
+       TEST_UNSUPPORTED(".word 0xf9bd0a00      @ rfeib pc!")
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
+#if __LINUX_ARM_ARCH__ >= 6
+       TEST_X( "blx    __dummy_thumb_subroutine_even",
+               ".thumb                         \n\t"
+               ".space 4                       \n\t"
+               ".type __dummy_thumb_subroutine_even, %%function \n\t"
+               "__dummy_thumb_subroutine_even: \n\t"
+               "mov    r0, pc                  \n\t"
+               "bx     lr                      \n\t"
+               ".arm                           \n\t"
+       )
+       TEST(   "blx    __dummy_thumb_subroutine_even")
+
+       TEST_X( "blx    __dummy_thumb_subroutine_odd",
+               ".thumb                         \n\t"
+               ".space 2                       \n\t"
+               ".type __dummy_thumb_subroutine_odd, %%function \n\t"
+               "__dummy_thumb_subroutine_odd:  \n\t"
+               "mov    r0, pc                  \n\t"
+               "bx     lr                      \n\t"
+               ".arm                           \n\t"
+       )
+       TEST(   "blx    __dummy_thumb_subroutine_odd")
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
+       COPROCESSOR_INSTRUCTIONS_ST_LD("2","f")
+#if __LINUX_ARM_ARCH__ >= 6
+       COPROCESSOR_INSTRUCTIONS_MC_MR("2","f")
+#endif
+
+       TEST_GROUP("Miscellaneous instructions, memory hints, and Advanced SIMD instructions")
+
+#if __LINUX_ARM_ARCH__ >= 6
+       TEST_UNSUPPORTED("cps   0x13")
+       TEST_UNSUPPORTED("cpsie i")
+       TEST_UNSUPPORTED("cpsid i")
+       TEST_UNSUPPORTED("cpsie i,0x13")
+       TEST_UNSUPPORTED("cpsid i,0x13")
+       TEST_UNSUPPORTED("setend        le")
+       TEST_UNSUPPORTED("setend        be")
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 7
+       TEST_P("pli     [r",0,0b,", #16]")
+       TEST(  "pli     [pc, #0]")
+       TEST_RR("pli    [r",12,0b,", r",0, 16,"]")
+       TEST_RR("pli    [r",0, 0b,", -r",12,16,", lsl #4]")
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 5
+       TEST_P("pld     [r",0,32,", #-16]")
+       TEST(  "pld     [pc, #0]")
+       TEST_PR("pld    [r",7, 24, ", r",0, 16,"]")
+       TEST_PR("pld    [r",8, 24, ", -r",12,16,", lsl #4]")
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 7
+       TEST_SUPPORTED(  ".word 0xf590f000      @ pldw [r0, #0]")
+       TEST_SUPPORTED(  ".word 0xf797f000      @ pldw  [r7, r0]")
+       TEST_SUPPORTED(  ".word 0xf798f18c      @ pldw  [r8, r12, lsl #3]");
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 7
+       TEST_UNSUPPORTED("clrex")
+       TEST_UNSUPPORTED("dsb")
+       TEST_UNSUPPORTED("dmb")
+       TEST_UNSUPPORTED("isb")
+#endif
+
+       verbose("\n");
+}
+
diff --git a/arch/arm/kernel/kprobes-test-thumb.c b/arch/arm/kernel/kprobes-test-thumb.c
new file mode 100644 (file)
index 0000000..5e726c3
--- /dev/null
@@ -0,0 +1,1187 @@
+/*
+ * arch/arm/kernel/kprobes-test-thumb.c
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "kprobes-test.h"
+
+
+#define TEST_ISA "16"
+
+#define DONT_TEST_IN_ITBLOCK(tests)                    \
+       kprobe_test_flags |= TEST_FLAG_NO_ITBLOCK;      \
+       tests                                           \
+       kprobe_test_flags &= ~TEST_FLAG_NO_ITBLOCK;
+
+#define CONDITION_INSTRUCTIONS(cc_pos, tests)          \
+       kprobe_test_cc_position = cc_pos;               \
+       DONT_TEST_IN_ITBLOCK(tests)                     \
+       kprobe_test_cc_position = 0;
+
+#define TEST_ITBLOCK(code)                             \
+       kprobe_test_flags |= TEST_FLAG_FULL_ITBLOCK;    \
+       TESTCASE_START(code)                            \
+       TEST_ARG_END("")                                \
+       "50:    nop                     \n\t"           \
+       "1:     "code"                  \n\t"           \
+       "       mov r1, #0x11           \n\t"           \
+       "       mov r2, #0x22           \n\t"           \
+       "       mov r3, #0x33           \n\t"           \
+       "2:     nop                     \n\t"           \
+       TESTCASE_END                                    \
+       kprobe_test_flags &= ~TEST_FLAG_FULL_ITBLOCK;
+
+#define TEST_THUMB_TO_ARM_INTERWORK_P(code1, reg, val, code2)  \
+       TESTCASE_START(code1 #reg code2)                        \
+       TEST_ARG_PTR(reg, val)                                  \
+       TEST_ARG_REG(14, 99f+1)                                 \
+       TEST_ARG_MEM(15, 3f)                                    \
+       TEST_ARG_END("")                                        \
+       "       nop                     \n\t" /* To align 1f */ \
+       "50:    nop                     \n\t"                   \
+       "1:     "code1 #reg code2"      \n\t"                   \
+       "       bx      lr              \n\t"                   \
+       ".arm                           \n\t"                   \
+       "3:     adr     lr, 2f+1        \n\t"                   \
+       "       bx      lr              \n\t"                   \
+       ".thumb                         \n\t"                   \
+       "2:     nop                     \n\t"                   \
+       TESTCASE_END
+
+
+void kprobe_thumb16_test_cases(void)
+{
+       kprobe_test_flags = TEST_FLAG_NARROW_INSTR;
+
+       TEST_GROUP("Shift (immediate), add, subtract, move, and compare")
+
+       TEST_R(    "lsls        r7, r",0,VAL1,", #5")
+       TEST_R(    "lsls        r0, r",7,VAL2,", #11")
+       TEST_R(    "lsrs        r7, r",0,VAL1,", #5")
+       TEST_R(    "lsrs        r0, r",7,VAL2,", #11")
+       TEST_R(    "asrs        r7, r",0,VAL1,", #5")
+       TEST_R(    "asrs        r0, r",7,VAL2,", #11")
+       TEST_RR(   "adds        r2, r",0,VAL1,", r",7,VAL2,"")
+       TEST_RR(   "adds        r5, r",7,VAL2,", r",0,VAL2,"")
+       TEST_RR(   "subs        r2, r",0,VAL1,", r",7,VAL2,"")
+       TEST_RR(   "subs        r5, r",7,VAL2,", r",0,VAL2,"")
+       TEST_R(    "adds        r7, r",0,VAL1,", #5")
+       TEST_R(    "adds        r0, r",7,VAL2,", #2")
+       TEST_R(    "subs        r7, r",0,VAL1,", #5")
+       TEST_R(    "subs        r0, r",7,VAL2,", #2")
+       TEST(      "movs.n      r0, #0x5f")
+       TEST(      "movs.n      r7, #0xa0")
+       TEST_R(    "cmp.n       r",0,0x5e, ", #0x5f")
+       TEST_R(    "cmp.n       r",5,0x15f,", #0x5f")
+       TEST_R(    "cmp.n       r",7,0xa0, ", #0xa0")
+       TEST_R(    "adds.n      r",0,VAL1,", #0x5f")
+       TEST_R(    "adds.n      r",7,VAL2,", #0xa0")
+       TEST_R(    "subs.n      r",0,VAL1,", #0x5f")
+       TEST_R(    "subs.n      r",7,VAL2,", #0xa0")
+
+       TEST_GROUP("16-bit Thumb data-processing instructions")
+
+#define DATA_PROCESSING16(op,val)                      \
+       TEST_RR(   op"  r",0,VAL1,", r",7,val,"")       \
+       TEST_RR(   op"  r",7,VAL2,", r",0,val,"")
+
+       DATA_PROCESSING16("ands",0xf00f00ff)
+       DATA_PROCESSING16("eors",0xf00f00ff)
+       DATA_PROCESSING16("lsls",11)
+       DATA_PROCESSING16("lsrs",11)
+       DATA_PROCESSING16("asrs",11)
+       DATA_PROCESSING16("adcs",VAL2)
+       DATA_PROCESSING16("sbcs",VAL2)
+       DATA_PROCESSING16("rors",11)
+       DATA_PROCESSING16("tst",0xf00f00ff)
+       TEST_R("rsbs    r",0,VAL1,", #0")
+       TEST_R("rsbs    r",7,VAL2,", #0")
+       DATA_PROCESSING16("cmp",0xf00f00ff)
+       DATA_PROCESSING16("cmn",0xf00f00ff)
+       DATA_PROCESSING16("orrs",0xf00f00ff)
+       DATA_PROCESSING16("muls",VAL2)
+       DATA_PROCESSING16("bics",0xf00f00ff)
+       DATA_PROCESSING16("mvns",VAL2)
+
+       TEST_GROUP("Special data instructions and branch and exchange")
+
+       TEST_RR(  "add  r",0, VAL1,", r",7,VAL2,"")
+       TEST_RR(  "add  r",3, VAL2,", r",8,VAL3,"")
+       TEST_RR(  "add  r",8, VAL3,", r",0,VAL1,"")
+       TEST_R(   "add  sp"        ", r",8,-8,  "")
+       TEST_R(   "add  r",14,VAL1,", pc")
+       TEST_BF_R("add  pc"        ", r",0,2f-1f-8,"")
+       TEST_UNSUPPORTED(".short 0x44ff @ add pc, pc")
+
+       TEST_RR(  "cmp  r",3,VAL1,", r",8,VAL2,"")
+       TEST_RR(  "cmp  r",8,VAL2,", r",0,VAL1,"")
+       TEST_R(   "cmp  sp"       ", r",8,-8,  "")
+
+       TEST_R(   "mov  r0, r",7,VAL2,"")
+       TEST_R(   "mov  r3, r",8,VAL3,"")
+       TEST_R(   "mov  r8, r",0,VAL1,"")
+       TEST_P(   "mov  sp, r",8,-8,  "")
+       TEST(     "mov  lr, pc")
+       TEST_BF_R("mov  pc, r",0,2f,  "")
+
+       TEST_BF_R("bx   r",0, 2f+1,"")
+       TEST_BF_R("bx   r",14,2f+1,"")
+       TESTCASE_START("bx      pc")
+               TEST_ARG_REG(14, 99f+1)
+               TEST_ARG_END("")
+               "       nop                     \n\t" /* To align the bx pc*/
+               "50:    nop                     \n\t"
+               "1:     bx      pc              \n\t"
+               "       bx      lr              \n\t"
+               ".arm                           \n\t"
+               "       adr     lr, 2f+1        \n\t"
+               "       bx      lr              \n\t"
+               ".thumb                         \n\t"
+               "2:     nop                     \n\t"
+       TESTCASE_END
+
+       TEST_BF_R("blx  r",0, 2f+1,"")
+       TEST_BB_R("blx  r",14,2f+1,"")
+       TEST_UNSUPPORTED(".short 0x47f8 @ blx pc")
+
+       TEST_GROUP("Load from Literal Pool")
+
+       TEST_X( "ldr    r0, 3f",
+               ".align                                 \n\t"
+               "3:     .word   "__stringify(VAL1))
+       TEST_X( "ldr    r7, 3f",
+               ".space 128                             \n\t"
+               ".align                                 \n\t"
+               "3:     .word   "__stringify(VAL2))
+
+       TEST_GROUP("16-bit Thumb Load/store instructions")
+
+       TEST_RPR("str   r",0, VAL1,", [r",1, 24,", r",2,  48,"]")
+       TEST_RPR("str   r",7, VAL2,", [r",6, 24,", r",5,  48,"]")
+       TEST_RPR("strh  r",0, VAL1,", [r",1, 24,", r",2,  48,"]")
+       TEST_RPR("strh  r",7, VAL2,", [r",6, 24,", r",5,  48,"]")
+       TEST_RPR("strb  r",0, VAL1,", [r",1, 24,", r",2,  48,"]")
+       TEST_RPR("strb  r",7, VAL2,", [r",6, 24,", r",5,  48,"]")
+       TEST_PR( "ldrsb r0, [r",1, 24,", r",2,  48,"]")
+       TEST_PR( "ldrsb r7, [r",6, 24,", r",5,  50,"]")
+       TEST_PR( "ldr   r0, [r",1, 24,", r",2,  48,"]")
+       TEST_PR( "ldr   r7, [r",6, 24,", r",5,  48,"]")
+       TEST_PR( "ldrh  r0, [r",1, 24,", r",2,  48,"]")
+       TEST_PR( "ldrh  r7, [r",6, 24,", r",5,  50,"]")
+       TEST_PR( "ldrb  r0, [r",1, 24,", r",2,  48,"]")
+       TEST_PR( "ldrb  r7, [r",6, 24,", r",5,  50,"]")
+       TEST_PR( "ldrsh r0, [r",1, 24,", r",2,  48,"]")
+       TEST_PR( "ldrsh r7, [r",6, 24,", r",5,  50,"]")
+
+       TEST_RP("str    r",0, VAL1,", [r",1, 24,", #120]")
+       TEST_RP("str    r",7, VAL2,", [r",6, 24,", #120]")
+       TEST_P( "ldr    r0, [r",1, 24,", #120]")
+       TEST_P( "ldr    r7, [r",6, 24,", #120]")
+       TEST_RP("strb   r",0, VAL1,", [r",1, 24,", #30]")
+       TEST_RP("strb   r",7, VAL2,", [r",6, 24,", #30]")
+       TEST_P( "ldrb   r0, [r",1, 24,", #30]")
+       TEST_P( "ldrb   r7, [r",6, 24,", #30]")
+       TEST_RP("strh   r",0, VAL1,", [r",1, 24,", #60]")
+       TEST_RP("strh   r",7, VAL2,", [r",6, 24,", #60]")
+       TEST_P( "ldrh   r0, [r",1, 24,", #60]")
+       TEST_P( "ldrh   r7, [r",6, 24,", #60]")
+
+       TEST_R( "str    r",0, VAL1,", [sp, #0]")
+       TEST_R( "str    r",7, VAL2,", [sp, #160]")
+       TEST(   "ldr    r0, [sp, #0]")
+       TEST(   "ldr    r7, [sp, #160]")
+
+       TEST_RP("str    r",0, VAL1,", [r",0, 24,"]")
+       TEST_P( "ldr    r0, [r",0, 24,"]")
+
+       TEST_GROUP("Generate PC-/SP-relative address")
+
+       TEST("add       r0, pc, #4")
+       TEST("add       r7, pc, #1020")
+       TEST("add       r0, sp, #4")
+       TEST("add       r7, sp, #1020")
+
+       TEST_GROUP("Miscellaneous 16-bit instructions")
+
+       TEST_UNSUPPORTED( "cpsie        i")
+       TEST_UNSUPPORTED( "cpsid        i")
+       TEST_UNSUPPORTED( "setend       le")
+       TEST_UNSUPPORTED( "setend       be")
+
+       TEST("add       sp, #"__stringify(TEST_MEMORY_SIZE)) /* Assumes TEST_MEMORY_SIZE < 0x400 */
+       TEST("sub       sp, #0x7f*4")
+
+DONT_TEST_IN_ITBLOCK(
+       TEST_BF_R(  "cbnz       r",0,0, ", 2f")
+       TEST_BF_R(  "cbz        r",2,-1,", 2f")
+       TEST_BF_RX( "cbnz       r",4,1, ", 2f",0x20)
+       TEST_BF_RX( "cbz        r",7,0, ", 2f",0x40)
+)
+       TEST_R("sxth    r0, r",7, HH1,"")
+       TEST_R("sxth    r7, r",0, HH2,"")
+       TEST_R("sxtb    r0, r",7, HH1,"")
+       TEST_R("sxtb    r7, r",0, HH2,"")
+       TEST_R("uxth    r0, r",7, HH1,"")
+       TEST_R("uxth    r7, r",0, HH2,"")
+       TEST_R("uxtb    r0, r",7, HH1,"")
+       TEST_R("uxtb    r7, r",0, HH2,"")
+       TEST_R("rev     r0, r",7, VAL1,"")
+       TEST_R("rev     r7, r",0, VAL2,"")
+       TEST_R("rev16   r0, r",7, VAL1,"")
+       TEST_R("rev16   r7, r",0, VAL2,"")
+       TEST_UNSUPPORTED(".short 0xba80")
+       TEST_UNSUPPORTED(".short 0xbabf")
+       TEST_R("revsh   r0, r",7, VAL1,"")
+       TEST_R("revsh   r7, r",0, VAL2,"")
+
+#define TEST_POPPC(code, offset)       \
+       TESTCASE_START(code)            \
+       TEST_ARG_PTR(13, offset)        \
+       TEST_ARG_END("")                \
+       TEST_BRANCH_F(code,0)           \
+       TESTCASE_END
+
+       TEST("push      {r0}")
+       TEST("push      {r7}")
+       TEST("push      {r14}")
+       TEST("push      {r0-r7,r14}")
+       TEST("push      {r0,r2,r4,r6,r14}")
+       TEST("push      {r1,r3,r5,r7}")
+       TEST("pop       {r0}")
+       TEST("pop       {r7}")
+       TEST("pop       {r0,r2,r4,r6}")
+       TEST_POPPC("pop {pc}",15*4)
+       TEST_POPPC("pop {r0-r7,pc}",7*4)
+       TEST_POPPC("pop {r1,r3,r5,r7,pc}",11*4)
+       TEST_THUMB_TO_ARM_INTERWORK_P("pop      {pc}    @ ",13,15*4,"")
+       TEST_THUMB_TO_ARM_INTERWORK_P("pop      {r0-r7,pc}      @ ",13,7*4,"")
+
+       TEST_UNSUPPORTED("bkpt.n        0")
+       TEST_UNSUPPORTED("bkpt.n        255")
+
+       TEST_SUPPORTED("yield")
+       TEST("sev")
+       TEST("nop")
+       TEST("wfi")
+       TEST_SUPPORTED("wfe")
+       TEST_UNSUPPORTED(".short 0xbf50") /* Unassigned hints */
+       TEST_UNSUPPORTED(".short 0xbff0") /* Unassigned hints */
+
+#define TEST_IT(code, code2)                   \
+       TESTCASE_START(code)                    \
+       TEST_ARG_END("")                        \
+       "50:    nop                     \n\t"   \
+       "1:     "code"                  \n\t"   \
+       "       "code2"                 \n\t"   \
+       "2:     nop                     \n\t"   \
+       TESTCASE_END
+
+DONT_TEST_IN_ITBLOCK(
+       TEST_IT("it     eq","moveq r0,#0")
+       TEST_IT("it     vc","movvc r0,#0")
+       TEST_IT("it     le","movle r0,#0")
+       TEST_IT("ite    eq","moveq r0,#0\n\t  movne r1,#1")
+       TEST_IT("itet   vc","movvc r0,#0\n\t  movvs r1,#1\n\t  movvc r2,#2")
+       TEST_IT("itete  le","movle r0,#0\n\t  movgt r1,#1\n\t  movle r2,#2\n\t  movgt r3,#3")
+       TEST_IT("itttt  le","movle r0,#0\n\t  movle r1,#1\n\t  movle r2,#2\n\t  movle r3,#3")
+       TEST_IT("iteee  le","movle r0,#0\n\t  movgt r1,#1\n\t  movgt r2,#2\n\t  movgt r3,#3")
+)
+
+       TEST_GROUP("Load and store multiple")
+
+       TEST_P("ldmia   r",4, 16*4,"!, {r0,r7}")
+       TEST_P("ldmia   r",7, 16*4,"!, {r0-r6}")
+       TEST_P("stmia   r",4, 16*4,"!, {r0,r7}")
+       TEST_P("stmia   r",0, 16*4,"!, {r0-r7}")
+
+       TEST_GROUP("Conditional branch and Supervisor Call instructions")
+
+CONDITION_INSTRUCTIONS(8,
+       TEST_BF("beq    2f")
+       TEST_BB("bne    2b")
+       TEST_BF("bgt    2f")
+       TEST_BB("blt    2b")
+)
+       TEST_UNSUPPORTED(".short 0xde00")
+       TEST_UNSUPPORTED(".short 0xdeff")
+       TEST_UNSUPPORTED("svc   #0x00")
+       TEST_UNSUPPORTED("svc   #0xff")
+
+       TEST_GROUP("Unconditional branch")
+
+       TEST_BF(  "b    2f")
+       TEST_BB(  "b    2b")
+       TEST_BF_X("b    2f", 0x400)
+       TEST_BB_X("b    2b", 0x400)
+
+       TEST_GROUP("Testing instructions in IT blocks")
+
+       TEST_ITBLOCK("subs.n r0, r0")
+
+       verbose("\n");
+}
+
+
+void kprobe_thumb32_test_cases(void)
+{
+       kprobe_test_flags = 0;
+
+       TEST_GROUP("Load/store multiple")
+
+       TEST_UNSUPPORTED("rfedb sp")
+       TEST_UNSUPPORTED("rfeia sp")
+       TEST_UNSUPPORTED("rfedb sp!")
+       TEST_UNSUPPORTED("rfeia sp!")
+
+       TEST_P(   "stmia        r",0, 16*4,", {r0,r8}")
+       TEST_P(   "stmia        r",4, 16*4,", {r0-r12,r14}")
+       TEST_P(   "stmia        r",7, 16*4,"!, {r8-r12,r14}")
+       TEST_P(   "stmia        r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+
+       TEST_P(   "ldmia        r",0, 16*4,", {r0,r8}")
+       TEST_P(   "ldmia        r",4, 0,   ", {r0-r12,r14}")
+       TEST_BF_P("ldmia        r",5, 8*4, "!, {r6-r12,r15}")
+       TEST_P(   "ldmia        r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+       TEST_BF_P("ldmia        r",14,14*4,"!, {r4,pc}")
+
+       TEST_P(   "stmdb        r",0, 16*4,", {r0,r8}")
+       TEST_P(   "stmdb        r",4, 16*4,", {r0-r12,r14}")
+       TEST_P(   "stmdb        r",5, 16*4,"!, {r8-r12,r14}")
+       TEST_P(   "stmdb        r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+
+       TEST_P(   "ldmdb        r",0, 16*4,", {r0,r8}")
+       TEST_P(   "ldmdb        r",4, 16*4,", {r0-r12,r14}")
+       TEST_BF_P("ldmdb        r",5, 16*4,"!, {r6-r12,r15}")
+       TEST_P(   "ldmdb        r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}")
+       TEST_BF_P("ldmdb        r",14,16*4,"!, {r4,pc}")
+
+       TEST_P(   "stmdb        r",13,16*4,"!, {r3-r12,lr}")
+       TEST_P(   "stmdb        r",13,16*4,"!, {r3-r12}")
+       TEST_P(   "stmdb        r",2, 16*4,", {r3-r12,lr}")
+       TEST_P(   "stmdb        r",13,16*4,"!, {r2-r12,lr}")
+       TEST_P(   "stmdb        r",0, 16*4,", {r0-r12}")
+       TEST_P(   "stmdb        r",0, 16*4,", {r0-r12,lr}")
+
+       TEST_BF_P("ldmia        r",13,5*4, "!, {r3-r12,pc}")
+       TEST_P(   "ldmia        r",13,5*4, "!, {r3-r12}")
+       TEST_BF_P("ldmia        r",2, 5*4, "!, {r3-r12,pc}")
+       TEST_BF_P("ldmia        r",13,4*4, "!, {r2-r12,pc}")
+       TEST_P(   "ldmia        r",0, 16*4,", {r0-r12}")
+       TEST_P(   "ldmia        r",0, 16*4,", {r0-r12,lr}")
+
+       TEST_THUMB_TO_ARM_INTERWORK_P("ldmia    r",0,14*4,", {r12,pc}")
+       TEST_THUMB_TO_ARM_INTERWORK_P("ldmia    r",13,2*4,", {r0-r12,pc}")
+
+       TEST_UNSUPPORTED(".short 0xe88f,0x0101  @ stmia pc, {r0,r8}")
+       TEST_UNSUPPORTED(".short 0xe92f,0x5f00  @ stmdb pc!, {r8-r12,r14}")
+       TEST_UNSUPPORTED(".short 0xe8bd,0xc000  @ ldmia r13!, {r14,pc}")
+       TEST_UNSUPPORTED(".short 0xe93e,0xc000  @ ldmdb r14!, {r14,pc}")
+       TEST_UNSUPPORTED(".short 0xe8a7,0x3f00  @ stmia r7!, {r8-r12,sp}")
+       TEST_UNSUPPORTED(".short 0xe8a7,0x9f00  @ stmia r7!, {r8-r12,pc}")
+       TEST_UNSUPPORTED(".short 0xe93e,0x2010  @ ldmdb r14!, {r4,sp}")
+
+       TEST_GROUP("Load/store double or exclusive, table branch")
+
+       TEST_P(  "ldrd  r0, r1, [r",1, 24,", #-16]")
+       TEST(    "ldrd  r12, r14, [sp, #16]")
+       TEST_P(  "ldrd  r1, r0, [r",7, 24,", #-16]!")
+       TEST(    "ldrd  r14, r12, [sp, #16]!")
+       TEST_P(  "ldrd  r1, r0, [r",7, 24,"], #16")
+       TEST(    "ldrd  r7, r8, [sp], #-16")
+
+       TEST_X( "ldrd   r12, r14, 3f",
+               ".align 3                               \n\t"
+               "3:     .word   "__stringify(VAL1)"     \n\t"
+               "       .word   "__stringify(VAL2))
+
+       TEST_UNSUPPORTED(".short 0xe9ff,0xec04  @ ldrd  r14, r12, [pc, #16]!")
+       TEST_UNSUPPORTED(".short 0xe8ff,0xec04  @ ldrd  r14, r12, [pc], #16")
+       TEST_UNSUPPORTED(".short 0xe9d4,0xd800  @ ldrd  sp, r8, [r4]")
+       TEST_UNSUPPORTED(".short 0xe9d4,0xf800  @ ldrd  pc, r8, [r4]")
+       TEST_UNSUPPORTED(".short 0xe9d4,0x7d00  @ ldrd  r7, sp, [r4]")
+       TEST_UNSUPPORTED(".short 0xe9d4,0x7f00  @ ldrd  r7, pc, [r4]")
+
+       TEST_RRP("strd  r",0, VAL1,", r",1, VAL2,", [r",1, 24,", #-16]")
+       TEST_RR( "strd  r",12,VAL2,", r",14,VAL1,", [sp, #16]")
+       TEST_RRP("strd  r",1, VAL1,", r",0, VAL2,", [r",7, 24,", #-16]!")
+       TEST_RR( "strd  r",14,VAL2,", r",12,VAL1,", [sp, #16]!")
+       TEST_RRP("strd  r",1, VAL1,", r",0, VAL2,", [r",7, 24,"], #16")
+       TEST_RR( "strd  r",7, VAL2,", r",8, VAL1,", [sp], #-16")
+       TEST_UNSUPPORTED(".short 0xe9ef,0xec04  @ strd  r14, r12, [pc, #16]!")
+       TEST_UNSUPPORTED(".short 0xe8ef,0xec04  @ strd  r14, r12, [pc], #16")
+
+       TEST_RX("tbb    [pc, r",0, (9f-(1f+4)),"]",
+               "9:                     \n\t"
+               ".byte  (2f-1b-4)>>1    \n\t"
+               ".byte  (3f-1b-4)>>1    \n\t"
+               "3:     mvn     r0, r0  \n\t"
+               "2:     nop             \n\t")
+
+       TEST_RX("tbb    [pc, r",4, (9f-(1f+4)+1),"]",
+               "9:                     \n\t"
+               ".byte  (2f-1b-4)>>1    \n\t"
+               ".byte  (3f-1b-4)>>1    \n\t"
+               "3:     mvn     r0, r0  \n\t"
+               "2:     nop             \n\t")
+
+       TEST_RRX("tbb   [r",1,9f,", r",2,0,"]",
+               "9:                     \n\t"
+               ".byte  (2f-1b-4)>>1    \n\t"
+               ".byte  (3f-1b-4)>>1    \n\t"
+               "3:     mvn     r0, r0  \n\t"
+               "2:     nop             \n\t")
+
+       TEST_RX("tbh    [pc, r",7, (9f-(1f+4))>>1,"]",
+               "9:                     \n\t"
+               ".short (2f-1b-4)>>1    \n\t"
+               ".short (3f-1b-4)>>1    \n\t"
+               "3:     mvn     r0, r0  \n\t"
+               "2:     nop             \n\t")
+
+       TEST_RX("tbh    [pc, r",12, ((9f-(1f+4))>>1)+1,"]",
+               "9:                     \n\t"
+               ".short (2f-1b-4)>>1    \n\t"
+               ".short (3f-1b-4)>>1    \n\t"
+               "3:     mvn     r0, r0  \n\t"
+               "2:     nop             \n\t")
+
+       TEST_RRX("tbh   [r",1,9f, ", r",14,1,"]",
+               "9:                     \n\t"
+               ".short (2f-1b-4)>>1    \n\t"
+               ".short (3f-1b-4)>>1    \n\t"
+               "3:     mvn     r0, r0  \n\t"
+               "2:     nop             \n\t")
+
+       TEST_UNSUPPORTED(".short 0xe8d1,0xf01f  @ tbh [r1, pc]")
+       TEST_UNSUPPORTED(".short 0xe8d1,0xf01d  @ tbh [r1, sp]")
+       TEST_UNSUPPORTED(".short 0xe8dd,0xf012  @ tbh [sp, r2]")
+
+       TEST_UNSUPPORTED("strexb        r0, r1, [r2]")
+       TEST_UNSUPPORTED("strexh        r0, r1, [r2]")
+       TEST_UNSUPPORTED("strexd        r0, r1, [r2]")
+       TEST_UNSUPPORTED("ldrexb        r0, [r1]")
+       TEST_UNSUPPORTED("ldrexh        r0, [r1]")
+       TEST_UNSUPPORTED("ldrexd        r0, [r1]")
+
+       TEST_GROUP("Data-processing (shifted register) and (modified immediate)")
+
+#define _DATA_PROCESSING32_DNM(op,s,val)                                       \
+       TEST_RR(op s".w r0,  r",1, VAL1,", r",2, val, "")                       \
+       TEST_RR(op s"   r1,  r",1, VAL1,", r",2, val, ", lsl #3")               \
+       TEST_RR(op s"   r2,  r",3, VAL1,", r",2, val, ", lsr #4")               \
+       TEST_RR(op s"   r3,  r",3, VAL1,", r",2, val, ", asr #5")               \
+       TEST_RR(op s"   r4,  r",5, VAL1,", r",2, N(val),", asr #6")             \
+       TEST_RR(op s"   r5,  r",5, VAL1,", r",2, val, ", ror #7")               \
+       TEST_RR(op s"   r8,  r",9, VAL1,", r",10,val, ", rrx")                  \
+       TEST_R( op s"   r0,  r",11,VAL1,", #0x00010001")                        \
+       TEST_R( op s"   r11, r",0, VAL1,", #0xf5000000")                        \
+       TEST_R( op s"   r7,  r",8, VAL2,", #0x000af000")
+
+#define DATA_PROCESSING32_DNM(op,val)          \
+       _DATA_PROCESSING32_DNM(op,"",val)       \
+       _DATA_PROCESSING32_DNM(op,"s",val)
+
+#define DATA_PROCESSING32_NM(op,val)                                   \
+       TEST_RR(op".w   r",1, VAL1,", r",2, val, "")                    \
+       TEST_RR(op"     r",1, VAL1,", r",2, val, ", lsl #3")            \
+       TEST_RR(op"     r",3, VAL1,", r",2, val, ", lsr #4")            \
+       TEST_RR(op"     r",3, VAL1,", r",2, val, ", asr #5")            \
+       TEST_RR(op"     r",5, VAL1,", r",2, N(val),", asr #6")          \
+       TEST_RR(op"     r",5, VAL1,", r",2, val, ", ror #7")            \
+       TEST_RR(op"     r",9, VAL1,", r",10,val, ", rrx")               \
+       TEST_R( op"     r",11,VAL1,", #0x00010001")                     \
+       TEST_R( op"     r",0, VAL1,", #0xf5000000")                     \
+       TEST_R( op"     r",8, VAL2,", #0x000af000")
+
+#define _DATA_PROCESSING32_DM(op,s,val)                                \
+       TEST_R( op s".w r0,  r",14, val, "")                    \
+       TEST_R( op s"   r1,  r",12, val, ", lsl #3")            \
+       TEST_R( op s"   r2,  r",11, val, ", lsr #4")            \
+       TEST_R( op s"   r3,  r",10, val, ", asr #5")            \
+       TEST_R( op s"   r4,  r",9, N(val),", asr #6")           \
+       TEST_R( op s"   r5,  r",8, val, ", ror #7")             \
+       TEST_R( op s"   r8,  r",7,val, ", rrx")                 \
+       TEST(   op s"   r0,  #0x00010001")                      \
+       TEST(   op s"   r11, #0xf5000000")                      \
+       TEST(   op s"   r7,  #0x000af000")                      \
+       TEST(   op s"   r4,  #0x00005a00")
+
+#define DATA_PROCESSING32_DM(op,val)           \
+       _DATA_PROCESSING32_DM(op,"",val)        \
+       _DATA_PROCESSING32_DM(op,"s",val)
+
+       DATA_PROCESSING32_DNM("and",0xf00f00ff)
+       DATA_PROCESSING32_NM("tst",0xf00f00ff)
+       DATA_PROCESSING32_DNM("bic",0xf00f00ff)
+       DATA_PROCESSING32_DNM("orr",0xf00f00ff)
+       DATA_PROCESSING32_DM("mov",VAL2)
+       DATA_PROCESSING32_DNM("orn",0xf00f00ff)
+       DATA_PROCESSING32_DM("mvn",VAL2)
+       DATA_PROCESSING32_DNM("eor",0xf00f00ff)
+       DATA_PROCESSING32_NM("teq",0xf00f00ff)
+       DATA_PROCESSING32_DNM("add",VAL2)
+       DATA_PROCESSING32_NM("cmn",VAL2)
+       DATA_PROCESSING32_DNM("adc",VAL2)
+       DATA_PROCESSING32_DNM("sbc",VAL2)
+       DATA_PROCESSING32_DNM("sub",VAL2)
+       DATA_PROCESSING32_NM("cmp",VAL2)
+       DATA_PROCESSING32_DNM("rsb",VAL2)
+
+       TEST_RR("pkhbt  r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR("pkhbt  r14,r",12, HH1,", r",10,HH2,", lsl #2")
+       TEST_RR("pkhtb  r0, r",0,  HH1,", r",1, HH2,"")
+       TEST_RR("pkhtb  r14,r",12, HH1,", r",10,HH2,", asr #2")
+
+       TEST_UNSUPPORTED(".short 0xea17,0x0f0d  @ tst.w r7, sp")
+       TEST_UNSUPPORTED(".short 0xea17,0x0f0f  @ tst.w r7, pc")
+       TEST_UNSUPPORTED(".short 0xea1d,0x0f07  @ tst.w sp, r7")
+       TEST_UNSUPPORTED(".short 0xea1f,0x0f07  @ tst.w pc, r7")
+       TEST_UNSUPPORTED(".short 0xf01d,0x1f08  @ tst sp, #0x00080008")
+       TEST_UNSUPPORTED(".short 0xf01f,0x1f08  @ tst pc, #0x00080008")
+
+       TEST_UNSUPPORTED(".short 0xea97,0x0f0d  @ teq.w r7, sp")
+       TEST_UNSUPPORTED(".short 0xea97,0x0f0f  @ teq.w r7, pc")
+       TEST_UNSUPPORTED(".short 0xea9d,0x0f07  @ teq.w sp, r7")
+       TEST_UNSUPPORTED(".short 0xea9f,0x0f07  @ teq.w pc, r7")
+       TEST_UNSUPPORTED(".short 0xf09d,0x1f08  @ tst sp, #0x00080008")
+       TEST_UNSUPPORTED(".short 0xf09f,0x1f08  @ tst pc, #0x00080008")
+
+       TEST_UNSUPPORTED(".short 0xeb17,0x0f0d  @ cmn.w r7, sp")
+       TEST_UNSUPPORTED(".short 0xeb17,0x0f0f  @ cmn.w r7, pc")
+       TEST_P("cmn.w   sp, r",7,0,"")
+       TEST_UNSUPPORTED(".short 0xeb1f,0x0f07  @ cmn.w pc, r7")
+       TEST(  "cmn     sp, #0x00080008")
+       TEST_UNSUPPORTED(".short 0xf11f,0x1f08  @ cmn pc, #0x00080008")
+
+       TEST_UNSUPPORTED(".short 0xebb7,0x0f0d  @ cmp.w r7, sp")
+       TEST_UNSUPPORTED(".short 0xebb7,0x0f0f  @ cmp.w r7, pc")
+       TEST_P("cmp.w   sp, r",7,0,"")
+       TEST_UNSUPPORTED(".short 0xebbf,0x0f07  @ cmp.w pc, r7")
+       TEST(  "cmp     sp, #0x00080008")
+       TEST_UNSUPPORTED(".short 0xf1bf,0x1f08  @ cmp pc, #0x00080008")
+
+       TEST_UNSUPPORTED(".short 0xea5f,0x070d  @ movs.w r7, sp")
+       TEST_UNSUPPORTED(".short 0xea5f,0x070f  @ movs.w r7, pc")
+       TEST_UNSUPPORTED(".short 0xea5f,0x0d07  @ movs.w sp, r7")
+       TEST_UNSUPPORTED(".short 0xea4f,0x0f07  @ mov.w  pc, r7")
+       TEST_UNSUPPORTED(".short 0xf04f,0x1d08  @ mov sp, #0x00080008")
+       TEST_UNSUPPORTED(".short 0xf04f,0x1f08  @ mov pc, #0x00080008")
+
+       TEST_R("add.w   r0, sp, r",1, 4,"")
+       TEST_R("adds    r0, sp, r",1, 4,", asl #3")
+       TEST_R("add     r0, sp, r",1, 4,", asl #4")
+       TEST_R("add     r0, sp, r",1, 16,", ror #1")
+       TEST_R("add.w   sp, sp, r",1, 4,"")
+       TEST_R("add     sp, sp, r",1, 4,", asl #3")
+       TEST_UNSUPPORTED(".short 0xeb0d,0x1d01  @ add sp, sp, r1, asl #4")
+       TEST_UNSUPPORTED(".short 0xeb0d,0x0d71  @ add sp, sp, r1, ror #1")
+       TEST(  "add.w   r0, sp, #24")
+       TEST(  "add.w   sp, sp, #24")
+       TEST_UNSUPPORTED(".short 0xeb0d,0x0f01  @ add pc, sp, r1")
+       TEST_UNSUPPORTED(".short 0xeb0d,0x000f  @ add r0, sp, pc")
+       TEST_UNSUPPORTED(".short 0xeb0d,0x000d  @ add r0, sp, sp")
+       TEST_UNSUPPORTED(".short 0xeb0d,0x0d0f  @ add sp, sp, pc")
+       TEST_UNSUPPORTED(".short 0xeb0d,0x0d0d  @ add sp, sp, sp")
+
+       TEST_R("sub.w   r0, sp, r",1, 4,"")
+       TEST_R("subs    r0, sp, r",1, 4,", asl #3")
+       TEST_R("sub     r0, sp, r",1, 4,", asl #4")
+       TEST_R("sub     r0, sp, r",1, 16,", ror #1")
+       TEST_R("sub.w   sp, sp, r",1, 4,"")
+       TEST_R("sub     sp, sp, r",1, 4,", asl #3")
+       TEST_UNSUPPORTED(".short 0xebad,0x1d01  @ sub sp, sp, r1, asl #4")
+       TEST_UNSUPPORTED(".short 0xebad,0x0d71  @ sub sp, sp, r1, ror #1")
+       TEST_UNSUPPORTED(".short 0xebad,0x0f01  @ sub pc, sp, r1")
+       TEST(  "sub.w   r0, sp, #24")
+       TEST(  "sub.w   sp, sp, #24")
+
+       TEST_UNSUPPORTED(".short 0xea02,0x010f  @ and r1, r2, pc")
+       TEST_UNSUPPORTED(".short 0xea0f,0x0103  @ and r1, pc, r3")
+       TEST_UNSUPPORTED(".short 0xea02,0x0f03  @ and pc, r2, r3")
+       TEST_UNSUPPORTED(".short 0xea02,0x010d  @ and r1, r2, sp")
+       TEST_UNSUPPORTED(".short 0xea0d,0x0103  @ and r1, sp, r3")
+       TEST_UNSUPPORTED(".short 0xea02,0x0d03  @ and sp, r2, r3")
+       TEST_UNSUPPORTED(".short 0xf00d,0x1108  @ and r1, sp, #0x00080008")
+       TEST_UNSUPPORTED(".short 0xf00f,0x1108  @ and r1, pc, #0x00080008")
+       TEST_UNSUPPORTED(".short 0xf002,0x1d08  @ and sp, r8, #0x00080008")
+       TEST_UNSUPPORTED(".short 0xf002,0x1f08  @ and pc, r8, #0x00080008")
+
+       TEST_UNSUPPORTED(".short 0xeb02,0x010f  @ add r1, r2, pc")
+       TEST_UNSUPPORTED(".short 0xeb0f,0x0103  @ add r1, pc, r3")
+       TEST_UNSUPPORTED(".short 0xeb02,0x0f03  @ add pc, r2, r3")
+       TEST_UNSUPPORTED(".short 0xeb02,0x010d  @ add r1, r2, sp")
+       TEST_SUPPORTED(  ".short 0xeb0d,0x0103  @ add r1, sp, r3")
+       TEST_UNSUPPORTED(".short 0xeb02,0x0d03  @ add sp, r2, r3")
+       TEST_SUPPORTED(  ".short 0xf10d,0x1108  @ add r1, sp, #0x00080008")
+       TEST_UNSUPPORTED(".short 0xf10d,0x1f08  @ add pc, sp, #0x00080008")
+       TEST_UNSUPPORTED(".short 0xf10f,0x1108  @ add r1, pc, #0x00080008")
+       TEST_UNSUPPORTED(".short 0xf102,0x1d08  @ add sp, r8, #0x00080008")
+       TEST_UNSUPPORTED(".short 0xf102,0x1f08  @ add pc, r8, #0x00080008")
+
+       TEST_UNSUPPORTED(".short 0xeaa0,0x0000")
+       TEST_UNSUPPORTED(".short 0xeaf0,0x0000")
+       TEST_UNSUPPORTED(".short 0xeb20,0x0000")
+       TEST_UNSUPPORTED(".short 0xeb80,0x0000")
+       TEST_UNSUPPORTED(".short 0xebe0,0x0000")
+
+       TEST_UNSUPPORTED(".short 0xf0a0,0x0000")
+       TEST_UNSUPPORTED(".short 0xf0c0,0x0000")
+       TEST_UNSUPPORTED(".short 0xf0f0,0x0000")
+       TEST_UNSUPPORTED(".short 0xf120,0x0000")
+       TEST_UNSUPPORTED(".short 0xf180,0x0000")
+       TEST_UNSUPPORTED(".short 0xf1e0,0x0000")
+
+       TEST_GROUP("Coprocessor instructions")
+
+       TEST_UNSUPPORTED(".short 0xec00,0x0000")
+       TEST_UNSUPPORTED(".short 0xeff0,0x0000")
+       TEST_UNSUPPORTED(".short 0xfc00,0x0000")
+       TEST_UNSUPPORTED(".short 0xfff0,0x0000")
+
+       TEST_GROUP("Data-processing (plain binary immediate)")
+
+       TEST_R("addw    r0,  r",1, VAL1,", #0x123")
+       TEST(  "addw    r14, sp, #0xf5a")
+       TEST(  "addw    sp, sp, #0x20")
+       TEST(  "addw    r7,  pc, #0x888")
+       TEST_UNSUPPORTED(".short 0xf20f,0x1f20  @ addw pc, pc, #0x120")
+       TEST_UNSUPPORTED(".short 0xf20d,0x1f20  @ addw pc, sp, #0x120")
+       TEST_UNSUPPORTED(".short 0xf20f,0x1d20  @ addw sp, pc, #0x120")
+       TEST_UNSUPPORTED(".short 0xf200,0x1d20  @ addw sp, r0, #0x120")
+
+       TEST_R("subw    r0,  r",1, VAL1,", #0x123")
+       TEST(  "subw    r14, sp, #0xf5a")
+       TEST(  "subw    sp, sp, #0x20")
+       TEST(  "subw    r7,  pc, #0x888")
+       TEST_UNSUPPORTED(".short 0xf2af,0x1f20  @ subw pc, pc, #0x120")
+       TEST_UNSUPPORTED(".short 0xf2ad,0x1f20  @ subw pc, sp, #0x120")
+       TEST_UNSUPPORTED(".short 0xf2af,0x1d20  @ subw sp, pc, #0x120")
+       TEST_UNSUPPORTED(".short 0xf2a0,0x1d20  @ subw sp, r0, #0x120")
+
+       TEST("movw      r0, #0")
+       TEST("movw      r0, #0xffff")
+       TEST("movw      lr, #0xffff")
+       TEST_UNSUPPORTED(".short 0xf240,0x0d00  @ movw sp, #0")
+       TEST_UNSUPPORTED(".short 0xf240,0x0f00  @ movw pc, #0")
+
+       TEST_R("movt    r",0, VAL1,", #0")
+       TEST_R("movt    r",0, VAL2,", #0xffff")
+       TEST_R("movt    r",14,VAL1,", #0xffff")
+       TEST_UNSUPPORTED(".short 0xf2c0,0x0d00  @ movt sp, #0")
+       TEST_UNSUPPORTED(".short 0xf2c0,0x0f00  @ movt pc, #0")
+
+       TEST_R(     "ssat       r0, #24, r",0,   VAL1,"")
+       TEST_R(     "ssat       r14, #24, r",12, VAL2,"")
+       TEST_R(     "ssat       r0, #24, r",0,   VAL1,", lsl #8")
+       TEST_R(     "ssat       r14, #24, r",12, VAL2,", asr #8")
+       TEST_UNSUPPORTED(".short 0xf30c,0x0d17  @ ssat  sp, #24, r12")
+       TEST_UNSUPPORTED(".short 0xf30c,0x0f17  @ ssat  pc, #24, r12")
+       TEST_UNSUPPORTED(".short 0xf30d,0x0c17  @ ssat  r12, #24, sp")
+       TEST_UNSUPPORTED(".short 0xf30f,0x0c17  @ ssat  r12, #24, pc")
+
+       TEST_R(     "usat       r0, #24, r",0,   VAL1,"")
+       TEST_R(     "usat       r14, #24, r",12, VAL2,"")
+       TEST_R(     "usat       r0, #24, r",0,   VAL1,", lsl #8")
+       TEST_R(     "usat       r14, #24, r",12, VAL2,", asr #8")
+       TEST_UNSUPPORTED(".short 0xf38c,0x0d17  @ usat  sp, #24, r12")
+       TEST_UNSUPPORTED(".short 0xf38c,0x0f17  @ usat  pc, #24, r12")
+       TEST_UNSUPPORTED(".short 0xf38d,0x0c17  @ usat  r12, #24, sp")
+       TEST_UNSUPPORTED(".short 0xf38f,0x0c17  @ usat  r12, #24, pc")
+
+       TEST_R(     "ssat16     r0, #12, r",0,   HH1,"")
+       TEST_R(     "ssat16     r14, #12, r",12, HH2,"")
+       TEST_UNSUPPORTED(".short 0xf32c,0x0d0b  @ ssat16        sp, #12, r12")
+       TEST_UNSUPPORTED(".short 0xf32c,0x0f0b  @ ssat16        pc, #12, r12")
+       TEST_UNSUPPORTED(".short 0xf32d,0x0c0b  @ ssat16        r12, #12, sp")
+       TEST_UNSUPPORTED(".short 0xf32f,0x0c0b  @ ssat16        r12, #12, pc")
+
+       TEST_R(     "usat16     r0, #12, r",0,   HH1,"")
+       TEST_R(     "usat16     r14, #12, r",12, HH2,"")
+       TEST_UNSUPPORTED(".short 0xf3ac,0x0d0b  @ usat16        sp, #12, r12")
+       TEST_UNSUPPORTED(".short 0xf3ac,0x0f0b  @ usat16        pc, #12, r12")
+       TEST_UNSUPPORTED(".short 0xf3ad,0x0c0b  @ usat16        r12, #12, sp")
+       TEST_UNSUPPORTED(".short 0xf3af,0x0c0b  @ usat16        r12, #12, pc")
+
+       TEST_R(     "sbfx       r0, r",0  , VAL1,", #0, #31")
+       TEST_R(     "sbfx       r14, r",12, VAL2,", #8, #16")
+       TEST_R(     "sbfx       r4, r",10,  VAL1,", #16, #15")
+       TEST_UNSUPPORTED(".short 0xf34c,0x2d0f  @ sbfx  sp, r12, #8, #16")
+       TEST_UNSUPPORTED(".short 0xf34c,0x2f0f  @ sbfx  pc, r12, #8, #16")
+       TEST_UNSUPPORTED(".short 0xf34d,0x2c0f  @ sbfx  r12, sp, #8, #16")
+       TEST_UNSUPPORTED(".short 0xf34f,0x2c0f  @ sbfx  r12, pc, #8, #16")
+
+       TEST_R(     "ubfx       r0, r",0  , VAL1,", #0, #31")
+       TEST_R(     "ubfx       r14, r",12, VAL2,", #8, #16")
+       TEST_R(     "ubfx       r4, r",10,  VAL1,", #16, #15")
+       TEST_UNSUPPORTED(".short 0xf3cc,0x2d0f  @ ubfx  sp, r12, #8, #16")
+       TEST_UNSUPPORTED(".short 0xf3cc,0x2f0f  @ ubfx  pc, r12, #8, #16")
+       TEST_UNSUPPORTED(".short 0xf3cd,0x2c0f  @ ubfx  r12, sp, #8, #16")
+       TEST_UNSUPPORTED(".short 0xf3cf,0x2c0f  @ ubfx  r12, pc, #8, #16")
+
+       TEST_R(     "bfc        r",0, VAL1,", #4, #20")
+       TEST_R(     "bfc        r",14,VAL2,", #4, #20")
+       TEST_R(     "bfc        r",7, VAL1,", #0, #31")
+       TEST_R(     "bfc        r",8, VAL2,", #0, #31")
+       TEST_UNSUPPORTED(".short 0xf36f,0x0d1e  @ bfc   sp, #0, #31")
+       TEST_UNSUPPORTED(".short 0xf36f,0x0f1e  @ bfc   pc, #0, #31")
+
+       TEST_RR(    "bfi        r",0, VAL1,", r",0  , VAL2,", #0, #31")
+       TEST_RR(    "bfi        r",12,VAL1,", r",14 , VAL2,", #4, #20")
+       TEST_UNSUPPORTED(".short 0xf36e,0x1d17  @ bfi   sp, r14, #4, #20")
+       TEST_UNSUPPORTED(".short 0xf36e,0x1f17  @ bfi   pc, r14, #4, #20")
+       TEST_UNSUPPORTED(".short 0xf36d,0x1e17  @ bfi   r14, sp, #4, #20")
+
+       TEST_GROUP("Branches and miscellaneous control")
+
+CONDITION_INSTRUCTIONS(22,
+       TEST_BF("beq.w  2f")
+       TEST_BB("bne.w  2b")
+       TEST_BF("bgt.w  2f")
+       TEST_BB("blt.w  2b")
+       TEST_BF_X("bpl.w        2f",0x1000)
+)
+
+       TEST_UNSUPPORTED("msr   cpsr, r0")
+       TEST_UNSUPPORTED("msr   cpsr_f, r1")
+       TEST_UNSUPPORTED("msr   spsr, r2")
+
+       TEST_UNSUPPORTED("cpsie.w       i")
+       TEST_UNSUPPORTED("cpsid.w       i")
+       TEST_UNSUPPORTED("cps   0x13")
+
+       TEST_SUPPORTED("yield.w")
+       TEST("sev.w")
+       TEST("nop.w")
+       TEST("wfi.w")
+       TEST_SUPPORTED("wfe.w")
+       TEST_UNSUPPORTED("dbg.w #0")
+
+       TEST_UNSUPPORTED("clrex")
+       TEST_UNSUPPORTED("dsb")
+       TEST_UNSUPPORTED("dmb")
+       TEST_UNSUPPORTED("isb")
+
+       TEST_UNSUPPORTED("bxj   r0")
+
+       TEST_UNSUPPORTED("subs  pc, lr, #4")
+
+       TEST("mrs       r0, cpsr")
+       TEST("mrs       r14, cpsr")
+       TEST_UNSUPPORTED(".short 0xf3ef,0x8d00  @ mrs   sp, spsr")
+       TEST_UNSUPPORTED(".short 0xf3ef,0x8f00  @ mrs   pc, spsr")
+       TEST_UNSUPPORTED("mrs   r0, spsr")
+       TEST_UNSUPPORTED("mrs   lr, spsr")
+
+       TEST_UNSUPPORTED(".short 0xf7f0,0x8000 @ smc #0")
+
+       TEST_UNSUPPORTED(".short 0xf7f0,0xa000 @ undefeined")
+
+       TEST_BF(  "b.w  2f")
+       TEST_BB(  "b.w  2b")
+       TEST_BF_X("b.w  2f", 0x1000)
+
+       TEST_BF(  "bl.w 2f")
+       TEST_BB(  "bl.w 2b")
+       TEST_BB_X("bl.w 2b", 0x1000)
+
+       TEST_X( "blx    __dummy_arm_subroutine",
+               ".arm                           \n\t"
+               ".align                         \n\t"
+               ".type __dummy_arm_subroutine, %%function \n\t"
+               "__dummy_arm_subroutine:        \n\t"
+               "mov    r0, pc                  \n\t"
+               "bx     lr                      \n\t"
+               ".thumb                         \n\t"
+       )
+       TEST(   "blx    __dummy_arm_subroutine")
+
+       TEST_GROUP("Store single data item")
+
+#define SINGLE_STORE(size)                                                     \
+       TEST_RP( "str"size"     r",0, VAL1,", [r",11,-1024,", #1024]")          \
+       TEST_RP( "str"size"     r",14,VAL2,", [r",1, -1024,", #1080]")          \
+       TEST_RP( "str"size"     r",0, VAL1,", [r",11,256,  ", #-120]")          \
+       TEST_RP( "str"size"     r",14,VAL2,", [r",1, 256,  ", #-128]")          \
+       TEST_RP( "str"size"     r",0, VAL1,", [r",11,24,  "], #120")            \
+       TEST_RP( "str"size"     r",14,VAL2,", [r",1, 24,  "], #128")            \
+       TEST_RP( "str"size"     r",0, VAL1,", [r",11,24,  "], #-120")           \
+       TEST_RP( "str"size"     r",14,VAL2,", [r",1, 24,  "], #-128")           \
+       TEST_RP( "str"size"     r",0, VAL1,", [r",11,24,   ", #120]!")          \
+       TEST_RP( "str"size"     r",14,VAL2,", [r",1, 24,   ", #128]!")          \
+       TEST_RP( "str"size"     r",0, VAL1,", [r",11,256,  ", #-120]!")         \
+       TEST_RP( "str"size"     r",14,VAL2,", [r",1, 256,  ", #-128]!")         \
+       TEST_RPR("str"size".w   r",0, VAL1,", [r",1, 0,", r",2, 4,"]")          \
+       TEST_RPR("str"size"     r",14,VAL2,", [r",10,0,", r",11,4,", lsl #1]")  \
+       TEST_R(  "str"size".w   r",7, VAL1,", [sp, #24]")                       \
+       TEST_RP( "str"size".w   r",0, VAL2,", [r",0,0, "]")                     \
+       TEST_UNSUPPORTED("str"size"t    r0, [r1, #4]")
+
+       SINGLE_STORE("b")
+       SINGLE_STORE("h")
+       SINGLE_STORE("")
+
+       TEST("str       sp, [sp]")
+       TEST_UNSUPPORTED(".short 0xf8cf,0xe000  @ str   r14, [pc]")
+       TEST_UNSUPPORTED(".short 0xf8ce,0xf000  @ str   pc, [r14]")
+
+       TEST_GROUP("Advanced SIMD element or structure load/store instructions")
+
+       TEST_UNSUPPORTED(".short 0xf900,0x0000")
+       TEST_UNSUPPORTED(".short 0xf92f,0xffff")
+       TEST_UNSUPPORTED(".short 0xf980,0x0000")
+       TEST_UNSUPPORTED(".short 0xf9ef,0xffff")
+
+       TEST_GROUP("Load single data item and memory hints")
+
+#define SINGLE_LOAD(size)                                              \
+       TEST_P( "ldr"size"      r0, [r",11,-1024, ", #1024]")           \
+       TEST_P( "ldr"size"      r14, [r",1, -1024,", #1080]")           \
+       TEST_P( "ldr"size"      r0, [r",11,256,   ", #-120]")           \
+       TEST_P( "ldr"size"      r14, [r",1, 256,  ", #-128]")           \
+       TEST_P( "ldr"size"      r0, [r",11,24,   "], #120")             \
+       TEST_P( "ldr"size"      r14, [r",1, 24,  "], #128")             \
+       TEST_P( "ldr"size"      r0, [r",11,24,   "], #-120")            \
+       TEST_P( "ldr"size"      r14, [r",1,24,   "], #-128")            \
+       TEST_P( "ldr"size"      r0, [r",11,24,    ", #120]!")           \
+       TEST_P( "ldr"size"      r14, [r",1, 24,   ", #128]!")           \
+       TEST_P( "ldr"size"      r0, [r",11,256,   ", #-120]!")          \
+       TEST_P( "ldr"size"      r14, [r",1, 256,  ", #-128]!")          \
+       TEST_PR("ldr"size".w    r0, [r",1, 0,", r",2, 4,"]")            \
+       TEST_PR("ldr"size"      r14, [r",10,0,", r",11,4,", lsl #1]")   \
+       TEST_X( "ldr"size".w    r0, 3f",                                \
+               ".align 3                               \n\t"           \
+               "3:     .word   "__stringify(VAL1))                     \
+       TEST_X( "ldr"size".w    r14, 3f",                               \
+               ".align 3                               \n\t"           \
+               "3:     .word   "__stringify(VAL2))                     \
+       TEST(   "ldr"size".w    r7, 3b")                                \
+       TEST(   "ldr"size".w    r7, [sp, #24]")                         \
+       TEST_P( "ldr"size".w    r0, [r",0,0, "]")                       \
+       TEST_UNSUPPORTED("ldr"size"t    r0, [r1, #4]")
+
+       SINGLE_LOAD("b")
+       SINGLE_LOAD("sb")
+       SINGLE_LOAD("h")
+       SINGLE_LOAD("sh")
+       SINGLE_LOAD("")
+
+       TEST_BF_P("ldr  pc, [r",14, 15*4,"]")
+       TEST_P(   "ldr  sp, [r",14, 13*4,"]")
+       TEST_BF_R("ldr  pc, [sp, r",14, 15*4,"]")
+       TEST_R(   "ldr  sp, [sp, r",14, 13*4,"]")
+       TEST_THUMB_TO_ARM_INTERWORK_P("ldr      pc, [r",0,0,", #15*4]")
+       TEST_SUPPORTED("ldr     sp, 99f")
+       TEST_SUPPORTED("ldr     pc, 99f")
+
+       TEST_UNSUPPORTED(".short 0xf854,0x700d  @ ldr   r7, [r4, sp]")
+       TEST_UNSUPPORTED(".short 0xf854,0x700f  @ ldr   r7, [r4, pc]")
+       TEST_UNSUPPORTED(".short 0xf814,0x700d  @ ldrb  r7, [r4, sp]")
+       TEST_UNSUPPORTED(".short 0xf814,0x700f  @ ldrb  r7, [r4, pc]")
+       TEST_UNSUPPORTED(".short 0xf89f,0xd004  @ ldrb  sp, 99f")
+       TEST_UNSUPPORTED(".short 0xf814,0xd008  @ ldrb  sp, [r4, r8]")
+    &nbs